All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] cfg80211 updates
@ 2007-02-15 14:42 Johannes Berg
  2007-02-15 14:42 ` [PATCH 01/10] remove cfg80211/wext-nl compatibility Johannes Berg
                   ` (10 more replies)
  0 siblings, 11 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This series updates/changes cfg80211 and associated things a
lot and finally introduces the wiphy stuff we've talked about
a long time ago. Also a number of bugfixes.

It's not perfect, it seems to for example that bcm43xx's debugfs
stuff doesn't work afterwards (but I haven't checked if it worked
before and I think it may be broken before too). Also, the wiphy
concept patch contains a few notes.

I'd like to ask that you merge it anyway, it's getting unwieldy
to maintain it as-is because there are quite large interdependencies
here. Besides, until the code is in the tree nobody apparently
bothers looking at it, only after they complain...

johannes


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

* [PATCH 01/10] remove cfg80211/wext-nl compatibility
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 14:42 ` [PATCH 02/10] update cfg80211/wext and wext code Johannes Berg
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

Wireless extensions over netlink can't reliably be used anyway (and probably
never will be used...) so remove the code that would allow cfg80211 to be
compatible with that.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 include/net/cfg80211.h     |    5 
 net/Kconfig                |   14 -
 net/core/rtnetlink.c       |   42 -----
 net/wireless/wext-compat.c |  333 ---------------------------------------------
 4 files changed, 1 insertion(+), 393 deletions(-)

--- wireless-dev.orig/net/Kconfig	2007-02-15 12:28:31.167940064 +0100
+++ wireless-dev/net/Kconfig	2007-02-15 12:28:34.637940064 +0100
@@ -244,20 +244,6 @@ config CFG80211_WEXT_COMPAT
 
 	If unsure, say Y.
 
-config CFG80211_WEXTNL_COMPAT
-	bool "cfg80211 WE-netlink compatibility"
-	depends CFG80211 && CFG80211_WEXT_COMPAT
-	---help---
-	This option allows using devices whose drivers have been
-	converted to use the new cfg80211 with wireless extensions
-	over rtnetlink, providing WE-20 compatibility. Note that
-	cfg80211's "native" interface is nl80211 using generic netlink.
-	The wireless extensions are being deprecated and the netlink
-	based API for WE was never configured by default, nor do any
-	userspace tools use this feature.
-
-	This option exists only to make Jean happy. Say N.
-
 endif   # if NET
 endmenu # Networking
 
--- wireless-dev.orig/net/wireless/wext-compat.c	2007-02-15 12:28:31.207940064 +0100
+++ wireless-dev/net/wireless/wext-compat.c	2007-02-15 12:28:34.647940064 +0100
@@ -1126,339 +1126,6 @@ static int iw_handler_get_iwstats(struct
 		return -EOPNOTSUPP;
 }
 
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
-/*
- * Wrapper to call a standard Wireless Extension GET handler.
- * We do various checks and call the handler with the proper args.
- */
-static int rtnetlink_standard_get(struct net_device *	dev,
-				  struct iw_event *	request,
-				  int			request_len,
-				  iw_handler		handler,
-				  char **		p_buf,
-				  int *			p_len)
-{
-	const struct iw_ioctl_description *	descr = NULL;
-	unsigned int				cmd;
-	union iwreq_data *			wrqu;
-	int					hdr_len;
-	struct iw_request_info			info;
-	char *					buffer = NULL;
-	int					buffer_size = 0;
-	int					ret = -EINVAL;
-
-	/* Get the description of the Request */
-	cmd = request->cmd;
-	if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-		return -EOPNOTSUPP;
-	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-
-	/* Check if wrqu is complete */
-	hdr_len = event_type_size[descr->header_type];
-	if(request_len < hdr_len)
-		return -EINVAL;
-
-	/* Prepare the call */
-	info.cmd = cmd;
-	info.flags = 0;
-
-	/* Check if we have extra data in the reply or not */
-	if(descr->header_type != IW_HEADER_TYPE_POINT) {
-
-		/* Create the kernel buffer that we will return.
-		 * It's at an offset to match the TYPE_POINT case... */
-		buffer_size = request_len + IW_EV_POINT_OFF;
-		buffer = kmalloc(buffer_size, GFP_KERNEL);
-		if (buffer == NULL) {
-			return -ENOMEM;
-		}
-		/* Copy event data */
-		memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
-		/* Use our own copy of wrqu */
-		wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
-					     + IW_EV_LCP_LEN);
-
-		/* No extra arguments. Trivial to handle */
-		ret = handler(dev, &info, wrqu, NULL);
-
-	} else {
-		union iwreq_data	wrqu_point;
-		char *			extra = NULL;
-		int			extra_size = 0;
-
-		/* Get a temp copy of wrqu (skip pointer) */
-		memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       ((char *) request) + IW_EV_LCP_LEN,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
-
-		/* Calculate space needed by arguments. Always allocate
-		 * for max space. Easier, and won't last long... */
-		extra_size = descr->max_tokens * descr->token_size;
-		/* Support for very large requests */
-		if((descr->flags & IW_DESCR_FLAG_NOMAX) &&
-		   (wrqu_point.data.length > descr->max_tokens))
-			extra_size = (wrqu_point.data.length
-				      * descr->token_size);
-		buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
-
-		/* Create the kernel buffer that we will return */
-		buffer = kmalloc(buffer_size, GFP_KERNEL);
-		if (buffer == NULL) {
-			return -ENOMEM;
-		}
-
-		/* Put wrqu in the right place (just before extra).
-		 * Leave space for IWE header and dummy pointer...
-		 * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
-		 */
-		memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
-		       ((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
-		wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
-
-		/* Extra comes logically after that. Offset +12 bytes. */
-		extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
-
-		/* Call the handler */
-		ret = handler(dev, &info, wrqu, extra);
-
-		/* Calculate real returned length */
-		extra_size = (wrqu->data.length * descr->token_size);
-		/* Re-adjust reply size */
-		request->len = extra_size + IW_EV_POINT_LEN;
-
-		/* Put the iwe header where it should, i.e. scrap the
-		 * dummy pointer. */
-		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
-
-		/* Check if there is enough buffer up there */
-		if(wrqu_point.data.length < wrqu->data.length)
-			ret = -E2BIG;
-	}
-
-	/* Return the buffer to the caller */
-	if (!ret) {
-		*p_buf = buffer;
-		*p_len = request->len;
-	} else {
-		/* Cleanup */
-		if(buffer)
-			kfree(buffer);
-	}
-
-	return ret;
-}
-
-/*
- * Wrapper to call a standard Wireless Extension SET handler.
- * We do various checks and call the handler with the proper args.
- */
-static inline int rtnetlink_standard_set(struct net_device *	dev,
-					 struct iw_event *	request,
-					 int			request_len,
-					 iw_handler		handler)
-{
-	const struct iw_ioctl_description *	descr = NULL;
-	unsigned int				cmd;
-	union iwreq_data *			wrqu;
-	union iwreq_data			wrqu_point;
-	int					hdr_len;
-	char *					extra = NULL;
-	int					extra_size = 0;
-	struct iw_request_info			info;
-	int					ret = -EINVAL;
-
-	/* Get the description of the Request */
-	cmd = request->cmd;
-	if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-		return -EOPNOTSUPP;
-	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-
-	/* Extract fixed header from request. This is properly aligned. */
-	wrqu = &request->u;
-
-	/* Check if wrqu is complete */
-	hdr_len = event_type_size[descr->header_type];
-	if(request_len < hdr_len)
-		return -EINVAL;
-
-	/* Prepare the call */
-	info.cmd = cmd;
-	info.flags = 0;
-
-	/* Check if we have extra data in the request or not */
-	if(descr->header_type != IW_HEADER_TYPE_POINT) {
-
-		/* No extra arguments. Trivial to handle */
-		ret = handler(dev, &info, wrqu, NULL);
-
-	} else {
-		int	extra_len;
-
-		/* Put wrqu in the right place (skip pointer) */
-		memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
-		/* Don't forget about the event code... */
-		wrqu = &wrqu_point;
-
-		/* Check if number of token fits within bounds */
-		if(wrqu_point.data.length > descr->max_tokens)
-			return -E2BIG;
-		if(wrqu_point.data.length < descr->min_tokens)
-			return -EINVAL;
-
-		/* Real length of payload */
-		extra_len = wrqu_point.data.length * descr->token_size;
-
-		/* Check if request is self consistent */
-		if((request_len - hdr_len) < extra_len)
-			return -EINVAL;
-
-		/* Always allocate for max space. Easier, and won't last
-		 * long... */
-		extra_size = descr->max_tokens * descr->token_size;
-		extra = kmalloc(extra_size, GFP_KERNEL);
-		if (extra == NULL)
-			return -ENOMEM;
-
-		/* Copy extra in aligned buffer */
-		memcpy(extra, ((char *) request) + hdr_len, extra_len);
-
-		/* Call the handler */
-		ret = handler(dev, &info, &wrqu_point, extra);
-	}
-
-        /* Generate an event to notify listeners of the change */
-	if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
-	    ((ret == 0) || (ret == -EIWCOMMIT))) {
-		if(descr->flags & IW_DESCR_FLAG_RESTRICT)
-			/* If the event is restricted, don't
-			 * export the payload */
-			wireless_send_event(dev, cmd, wrqu, NULL);
-		else
-			wireless_send_event(dev, cmd, wrqu, extra);
-	}
-
-	/* Cleanup - I told you it wasn't that long ;-) */
-	if(extra)
-		kfree(extra);
-
-	return ret;
-}
-
-/*
- * Main RtNetlink dispatcher. Called from the main networking code
- * (do_getlink() in net/core/rtnetlink.c).
- * Check the type of Request and call the appropriate wrapper...
- */
-int cfg80211_wext_nl_get(struct net_device *	dev,
-			 char *			data,
-			 int			len,
-			 char **		p_buf,
-			 int *			p_len)
-{
-	struct iw_event *	request = (struct iw_event *) data;
-	iw_handler		handler;
-
-	/* Check length */
-	if(len < IW_EV_LCP_LEN) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
-		       dev->name, len);
-		return -EINVAL;
-	}
-
-	/* ReCheck length (len may have padding) */
-	if(request->len > len) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request len invalid (%d-%d)\n",
-		       dev->name, request->len, len);
-		return -EINVAL;
-	}
-
-	/* Only accept GET requests in here */
-	if(!IW_IS_GET(request->cmd))
-		return -EOPNOTSUPP;
-
-	/* If command is `get the encoding parameters', check if
-	 * the user has the right to do it */
-	if (request->cmd == SIOCGIWENCODE ||
-	    request->cmd == SIOCGIWENCODEEXT) {
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-	}
-
-	/* Special cases */
-	if(request->cmd == SIOCGIWSTATS)
-		/* Get Wireless Stats */
-		return rtnetlink_standard_get(dev,
-					      request,
-					      request->len,
-					      &iw_handler_get_iwstats,
-					      p_buf, p_len);
-	if(request->cmd == SIOCGIWPRIV)
-		return -EOPNOTSUPP;
-
-	/* Basic check */
-	if (!netif_device_present(dev))
-		return -ENODEV;
-
-	/* Try to find the handler */
-	handler = get_handler(dev, request->cmd);
-	if (handler != NULL && request->cmd < SIOCIWFIRSTPRIV)
-		return rtnetlink_standard_get(dev,
-					      request,
-					      request->len,
-					      handler,
-					      p_buf, p_len);
-
-	return -EOPNOTSUPP;
-}
-
-/*
- * Main RtNetlink dispatcher. Called from the main networking code
- * (do_setlink() in net/core/rtnetlink.c).
- * Check the type of Request and call the appropriate wrapper...
- */
-int cfg80211_wext_nl_set(struct net_device *	dev,
-			 char *			data,
-			 int			len)
-{
-	struct iw_event *	request = (struct iw_event *) data;
-	iw_handler		handler;
-
-	/* Check length */
-	if(len < IW_EV_LCP_LEN) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
-		       dev->name, len);
-		return -EINVAL;
-	}
-
-	/* ReCheck length (len may have padding) */
-	if(request->len > len) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request len invalid (%d-%d)\n",
-		       dev->name, request->len, len);
-		return -EINVAL;
-	}
-
-	/* Only accept SET requests in here */
-	if(!IW_IS_SET(request->cmd))
-		return -EOPNOTSUPP;
-
-	/* Basic check */
-	if (!netif_device_present(dev))
-		return -ENODEV;
-
-	/* New driver API : try to find the handler */
-	handler = get_handler(dev, request->cmd);
-	if(handler != NULL && request->cmd < SIOCIWFIRSTPRIV)
-		return rtnetlink_standard_set(dev,
-					      request,
-					      request->len,
-					      handler);
-
-	return -EOPNOTSUPP;
-}
-#endif
-
 /*
  * Wrapper to call a standard Wireless Extension handler.
  * We do various checks and also take care of moving data between
--- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 12:28:31.317940064 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-15 12:28:34.647940064 +0100
@@ -195,11 +195,6 @@ extern void *nl80211msg_new(struct sk_bu
 
 #ifdef CONFIG_CFG80211_WEXT_COMPAT
 extern int cfg80211_wext_ioctl(struct ifreq *ifr, unsigned int cmd);
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
-int cfg80211_wext_nl_set(struct net_device *dev, char *data, int len);
-int cfg80211_wext_nl_get(struct net_device *dev, char *data, int len,
-			 char **p_buf, int *p_len);
-#endif
 #endif
 
 #endif /* __NET_CFG80211_H */
--- wireless-dev.orig/net/core/rtnetlink.c	2007-02-15 12:28:31.257940064 +0100
+++ wireless-dev/net/core/rtnetlink.c	2007-02-15 12:28:34.647940064 +0100
@@ -56,9 +56,6 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #endif	/* CONFIG_NET_WIRELESS_RTNETLINK */
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
-#include <net/cfg80211.h>
-#endif
 
 static DEFINE_MUTEX(rtnl_mutex);
 static struct sock *rtnl;
@@ -539,20 +536,6 @@ static int rtnl_setlink(struct sk_buff *
 		modified = 1;
 	}
 
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
-	if (tb[IFLA_WIRELESS]) {
-		/* Call cfg80211 WE backward compat code.
-		 * Various stuff checked in there... */
-		err = cfg80211_wext_nl_set(dev, nla_data(tb[IFLA_WIRELESS]),
-					   nla_len(tb[IFLA_WIRELESS]));
-		if (err < 0 && err != -ENOSYS)
-			goto errout_dev;
-#ifdef CONFIG_NET_WIRELESS_RTNETLINK
-		if (err == 0)
-			goto skip_old_wext_nl;
-#endif
-	}
-#endif
 #ifdef CONFIG_NET_WIRELESS_RTNETLINK
 	if (tb[IFLA_WIRELESS]) {
 		/* Call Wireless Extensions.
@@ -562,10 +545,8 @@ static int rtnl_setlink(struct sk_buff *
 		if (err < 0)
 			goto errout_dev;
 	}
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
- skip_old_wext_nl:
-#endif
 #endif	/* CONFIG_NET_WIRELESS_RTNETLINK */
+
 	if (tb[IFLA_BROADCAST]) {
 		nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
 		send_addr_notify = 1;
@@ -630,24 +611,6 @@ static int rtnl_getlink(struct sk_buff *
 		return -EINVAL;
 
 
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
-	if (tb[IFLA_WIRELESS]) {
-		/* Call Wireless Extensions. We need to know the size before
-		 * we can alloc. Various stuff checked in there... */
-		err = cfg80211_wext_nl_get(dev, nla_data(tb[IFLA_WIRELESS]),
-					   nla_len(tb[IFLA_WIRELESS]),
-					   &iw_buf, &iw_buf_len);
-		if (err < 0 && err != -ENOSYS)
-			goto errout;
-
-		iw += IW_EV_POINT_OFF;
-#ifdef CONFIG_NET_WIRELESS_RTNETLINK
-		if (err == 0)
-			goto skip_old_wext_nl;
-		iw -= IW_EV_POINT_OFF;
-#endif
-	}
-#endif
 #ifdef CONFIG_NET_WIRELESS_RTNETLINK
 	if (tb[IFLA_WIRELESS]) {
 		/* Call Wireless Extensions. We need to know the size before
@@ -660,9 +623,6 @@ static int rtnl_getlink(struct sk_buff *
 
 		iw += IW_EV_POINT_OFF;
 	}
-#ifdef CONFIG_CFG80211_WEXTNL_COMPAT
- skip_old_wext_nl:
-#endif
 #endif	/* CONFIG_NET_WIRELESS_RTNETLINK */
 
 	nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);

--


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

* [PATCH 02/10] update cfg80211/wext and wext code
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
  2007-02-15 14:42 ` [PATCH 01/10] remove cfg80211/wext-nl compatibility Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 14:42 ` [PATCH 03/10] introduce wiphy concept Johannes Berg
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This patch updates the cfg80211/wext compat code as well as the original
wext code. To ease development/testing, it allows having cfg80211 including
all the compat code as a module, only a registration hook for the wext
ioctls needs to be built-in.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 include/linux/netdevice.h  |    4 
 include/net/cfg80211.h     |    4 
 include/net/iw_handler.h   |    3 
 include/net/wireless.h     |   23 +
 net/core/dev.c             |   67 ---
 net/wireless/Makefile      |   24 -
 net/wireless/core.c        |   28 -
 net/wireless/core.h        |   25 -
 net/wireless/wext-common.c |   67 ++-
 net/wireless/wext-compat.c |  923 +++++++++++----------------------------------
 net/wireless/wext-export.c |   29 +
 net/wireless/wext-mod.c    |   20 
 net/wireless/wext-old.c    |   13 
 net/wireless/wext.h        |   42 +-
 14 files changed, 445 insertions(+), 827 deletions(-)

--- wireless-dev.orig/net/wireless/wext-compat.c	2007-02-15 12:28:34.647940064 +0100
+++ wireless-dev/net/wireless/wext-compat.c	2007-02-15 12:28:35.637940064 +0100
@@ -4,7 +4,7 @@
  * Lots of code from the original wireless.c:
  * Copyright 1997-2006	Jean Tourrilhes <jt@hpl.hp.com>
  *
- * Copyright 2006	Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006,2007	Johannes Berg <johannes@sipsolutions.net>
  *
  * GPLv2.
  *
@@ -45,7 +45,6 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
-#include <net/iw_handler.h>
 #include <net/netlink.h>
 #include <asm/uaccess.h>
 #include <net/cfg80211.h>
@@ -53,29 +52,6 @@
 #include "core.h"
 #include "wext.h"
 
-/* The cfg80211 driver assigns callbacks in this
- * if it is loaded. If not, then we can't config
- * anything anyway... */
-struct cfg80211_core_ops cfg80211_core_ops;
-EXPORT_SYMBOL_GPL(cfg80211_core_ops);
-
-static struct cfg80211_registered_driver *cfg80211_wx_setup(int ifindex)
-{
-	if (!cfg80211_core_ops.loaded)
-		return ERR_PTR(-ENOSYS);
-	if (!try_module_get(cfg80211_core_ops.module))
-		return ERR_PTR(-ENOSYS);
-
-	return cfg80211_core_ops.get_drv_from_ifidx(ifindex);
-}
-
-static void cfg80211_wx_teardown(struct cfg80211_registered_driver *drv)
-{
-	if (!IS_ERR(drv))
-		cfg80211_core_ops.put_drv(drv);
-	module_put(cfg80211_core_ops.module);
-}
-
 /* internal API: use this function when changing
  * some parameter that needs to be committed */
 static void cfg80211_wx_start_commit_timer(int ifindex)
@@ -91,302 +67,170 @@ static void cfg80211_wx_start_commit_tim
 	 * as well as taking the rtnl lock (due to wext)! */
 }
 
-static void cfg80211_ensure_netdev_pending_cfg(struct net_device *dev)
+static struct cfg80211_config *cfg80211_ensure_pending_cfg(
+	struct cfg80211_registered_driver *drv)
 {
-	struct cfg80211_config *cfg = dev->cfg80211_wext_pending_config;
-	if (!cfg) {
+	struct cfg80211_config *cfg = drv->wext_pending_config;
+	if (!cfg)
 		cfg = kmalloc(sizeof(*cfg)+32, GFP_KERNEL);
+	if (cfg) {
 		cfg->ssid = (char*)cfg + sizeof(*cfg);
-		dev->cfg80211_wext_pending_config = cfg;
+		drv->wext_pending_config = cfg;
 	}
+	return cfg;
 }
 
-/* operations we implement. whew, I machine-generated these */
-static int cfg80211_wx_set_commit(struct net_device *net_dev,
+static int cfg80211_wx_set_commit(struct cfg80211_registered_driver *drv,
+				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
 				  char *extra)
 {
-	struct cfg80211_registered_driver *drv;
 	int err;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	if (!net_dev->cfg80211_wext_pending_config) {
+	if (!drv->wext_pending_config) {
 		err = 0;
 		goto out;
 	}
 
-	err = drv->ops->configure(drv->priv, net_dev,
-				  net_dev->cfg80211_wext_pending_config);
+	err = drv->ops->configure(&drv->wiphy, net_dev,
+				  drv->wext_pending_config);
 
-	kfree(net_dev->cfg80211_wext_pending_config);
-	net_dev->cfg80211_wext_pending_config = NULL;
+	kfree(drv->wext_pending_config);
+	drv->wext_pending_config = NULL;
 
  out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_name(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_name(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_nwid(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_nwid(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_nwid(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_nwid(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_freq(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_freq(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_freq(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_freq(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_mode(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_mode(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_mode(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_mode(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_sens(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_sens(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_sens(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_sens(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_range(struct net_device *net_dev,
+static int cfg80211_wx_set_range(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_range(struct net_device *net_dev,
+static int cfg80211_wx_get_range(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_ap(struct net_device *net_dev,
+static int cfg80211_wx_set_ap(struct cfg80211_registered_driver *drv,
+			      struct net_device *net_dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *data,
 			      char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
 	/* TODO: DO SOMETHING */
 	/* SIOCSIWAP
@@ -394,150 +238,86 @@ static int cfg80211_wx_set_ap(struct net
 	 *   -> if bssid is all-zeroes: set roaming to kernel
 	 *   -> otherwise: set roaming to userspace, set bssid
 	 */
-	err = -ENOSYS;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_ap(struct net_device *net_dev,
+static int cfg80211_wx_get_ap(struct cfg80211_registered_driver *drv,
+			      struct net_device *net_dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *data,
 			      char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
 	/* TODO: DO SOMETHING */
 	/* SIOCGIWAP
 	 *   -> get association parameters and fill return bssid appropriately
 	 */
-	err = -ENOSYS;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_mlme(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_mlme(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_waplist(struct net_device *net_dev,
+static int cfg80211_wx_get_waplist(struct cfg80211_registered_driver *drv,
+				   struct net_device *net_dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *data,
 				   char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_scan(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_scan(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_scan(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_scan(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_essid(struct net_device *net_dev,
+static int cfg80211_wx_set_essid(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 	struct cfg80211_config *cfg;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	err = -ENOSYS;
 	if (!drv->ops->configure || !drv->ops->get_config_valid)
 		goto out;
-	if (!(drv->ops->get_config_valid(drv->priv, net_dev)
+	if (!(drv->ops->get_config_valid(&drv->wiphy, net_dev)
 			& CFG80211_CFG_VALID_SSID))
 		goto out;
 
-	cfg80211_ensure_netdev_pending_cfg(net_dev);
-	cfg = net_dev->cfg80211_wext_pending_config;
+	cfg = cfg80211_ensure_pending_cfg(drv);
 	if (!cfg) {
 		err = -ENOMEM;
 		goto out;
@@ -550,502 +330,264 @@ static int cfg80211_wx_set_essid(struct 
 	cfg80211_wx_start_commit_timer(net_dev->ifindex);
 	err = 0;
  out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_essid(struct net_device *net_dev,
+static int cfg80211_wx_get_essid(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_rate(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_rate(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_rate(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_rate(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_rts(struct net_device *net_dev,
+static int cfg80211_wx_set_rts(struct cfg80211_registered_driver *drv,
+			       struct net_device *net_dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *data,
 			       char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_rts(struct net_device *net_dev,
+static int cfg80211_wx_get_rts(struct cfg80211_registered_driver *drv,
+			       struct net_device *net_dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *data,
 			       char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_frag(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_frag(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_frag(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_frag(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_txpow(struct net_device *net_dev,
+static int cfg80211_wx_set_txpow(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_txpow(struct net_device *net_dev,
+static int cfg80211_wx_get_txpow(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_retry(struct net_device *net_dev,
+static int cfg80211_wx_set_retry(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_retry(struct net_device *net_dev,
+static int cfg80211_wx_get_retry(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_encode(struct net_device *net_dev,
+static int cfg80211_wx_set_encode(struct cfg80211_registered_driver *drv,
+				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
 				  char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_encode(struct net_device *net_dev,
+static int cfg80211_wx_get_encode(struct cfg80211_registered_driver *drv,
+				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
 				  char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_power(struct net_device *net_dev,
+static int cfg80211_wx_set_power(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_power(struct net_device *net_dev,
+static int cfg80211_wx_get_power(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_genie(struct net_device *net_dev,
+static int cfg80211_wx_set_genie(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_genie(struct net_device *net_dev,
+static int cfg80211_wx_get_genie(struct cfg80211_registered_driver *drv,
+				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
 				 char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_auth(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_set_auth(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_auth(struct net_device *net_dev,
-			        struct iw_request_info *info,
-			        union iwreq_data *data,
-			        char *extra)
+static int cfg80211_wx_get_auth(struct cfg80211_registered_driver *drv,
+				struct net_device *net_dev,
+				struct iw_request_info *info,
+				union iwreq_data *data,
+				char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_encodeext(struct net_device *net_dev,
+static int cfg80211_wx_set_encodeext(struct cfg80211_registered_driver *drv,
+				     struct net_device *net_dev,
 				     struct iw_request_info *info,
 				     union iwreq_data *data,
 				     char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_get_encodeext(struct net_device *net_dev,
+static int cfg80211_wx_get_encodeext(struct cfg80211_registered_driver *drv,
+				     struct net_device *net_dev,
 				     struct iw_request_info *info,
 				     union iwreq_data *data,
 				     char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
-
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
-static int cfg80211_wx_set_wpmksa(struct net_device *net_dev,
+static int cfg80211_wx_set_wpmksa(struct cfg80211_registered_driver *drv,
+				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
 				  char *extra)
 {
-	struct cfg80211_registered_driver *drv;
-	int err;
+	int err = -EOPNOTSUPP;
 
-	drv = cfg80211_wx_setup(net_dev->ifindex);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
-		goto out;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- out:
-	cfg80211_wx_teardown(drv);
 	return err;
 }
 
 
+typedef int (*iw_compat_handler)(struct cfg80211_registered_driver *drv,
+				 struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu,
+				 char *extra);
 
 /* operations array */
 #ifdef WX
 # undef WX
 #endif
 #define WX(ioctl)  [(ioctl) - SIOCIWFIRST]
-static const iw_handler cfg80211_wx_handlers[] = {
+static const iw_compat_handler cfg80211_wx_handlers[] = {
 	WX(SIOCSIWCOMMIT)	= cfg80211_wx_set_commit,
 	WX(SIOCGIWNAME)		= cfg80211_wx_get_name,
 	WX(SIOCSIWNWID)		= cfg80211_wx_set_nwid,
@@ -1090,7 +632,7 @@ static const iw_handler cfg80211_wx_hand
 };
 
 /* dummy so I didn't have to change that much code... */
-static iw_handler get_handler(struct net_device *dev, unsigned int cmd)
+static iw_compat_handler get_handler(unsigned int cmd)
 {
 	int idx = cmd - SIOCIWFIRST;
 	if (idx < ARRAY_SIZE(cfg80211_wx_handlers))
@@ -1102,10 +644,11 @@ static iw_handler get_handler(struct net
  * this is sort of backwards and wouldn't need to call
  * get_wireless_stats, but it was easier to just copy the code...
  */
-static int iw_handler_get_iwstats(struct net_device *		dev,
-				  struct iw_request_info *	info,
-				  union iwreq_data *		wrqu,
-				  char *			extra)
+static int iw_handler_get_iwstats(struct cfg80211_registered_driver *drv,
+				  struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu,
+				  char *extra)
 {
 	/* Get stats from the driver */
 	struct iw_statistics stats_buf;
@@ -1131,10 +674,11 @@ static int iw_handler_get_iwstats(struct
  * We do various checks and also take care of moving data between
  * user space and kernel space.
  */
-static int ioctl_standard_call(struct net_device *	dev,
-			       struct ifreq *		ifr,
-			       unsigned int		cmd,
-			       iw_handler		handler)
+static int ioctl_standard_call(struct cfg80211_registered_driver *drv,
+			       struct net_device *dev,
+			       struct ifreq *ifr,
+			       unsigned int cmd,
+			       iw_compat_handler handler)
 {
 	struct iwreq *				iwr = (struct iwreq *) ifr;
 	const struct iw_ioctl_description *	descr;
@@ -1142,9 +686,9 @@ static int ioctl_standard_call(struct ne
 	int					ret = -EINVAL;
 
 	/* Get the description of the IOCTL */
-	if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
+	if((cmd - SIOCIWFIRST) >= wext_standard_ioctl_num)
 		return -EOPNOTSUPP;
-	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
 	/* Prepare the call */
 	info.cmd = cmd;
@@ -1154,7 +698,7 @@ static int ioctl_standard_call(struct ne
 	if(descr->header_type != IW_HEADER_TYPE_POINT) {
 
 		/* No extra arguments. Trivial to handle */
-		ret = handler(dev, &info, &(iwr->u), NULL);
+		ret = handler(drv, dev, &info, &(iwr->u), NULL);
 
 		/* Generate an event to notify listeners of the change */
 		if((descr->flags & IW_DESCR_FLAG_EVENT) &&
@@ -1224,7 +768,7 @@ static int ioctl_standard_call(struct ne
 		}
 
 		/* Call the handler */
-		ret = handler(dev, &info, &(iwr->u), extra);
+		ret = handler(drv, dev, &info, &(iwr->u), extra);
 
 		/* If we have something to return to the user */
 		if (!ret && IW_IS_GET(cmd)) {
@@ -1264,37 +808,46 @@ static int ioctl_standard_call(struct ne
 int cfg80211_wext_ioctl(struct ifreq *ifr, unsigned int cmd)
 {
 	struct net_device *dev;
-	iw_handler	handler;
+	iw_compat_handler handler;
+	struct cfg80211_registered_driver *drv;
+	int err;
 
 	/* Permissions are already checked in dev_ioctl() before calling us.
 	 * The copy_to/from_user() of ifr is also dealt with in there */
 
-	/* Make sure the device exist */
-	if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
+	dev = dev_get_by_name(ifr->ifr_name);
+	if (!dev)
 		return -ENODEV;
 
+	drv = cfg80211_get_drv_from_ifindex(dev->ifindex);
+	if (IS_ERR(drv)) {
+		err = PTR_ERR(drv);
+		goto out_put_dev;
+	}
+
 	/* A bunch of special cases, then the generic case...
 	 * Note that 'cmd' is already filtered in dev_ioctl() with
 	 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
 	switch(cmd) {
 		case SIOCGIWSTATS:
 			/* Get Wireless Stats */
-			return ioctl_standard_call(dev,
-						   ifr,
-						   cmd,
-						   &iw_handler_get_iwstats);
-
+			err = ioctl_standard_call(drv, dev, ifr, cmd,
+						  &iw_handler_get_iwstats);
+			break;
 		case SIOCGIWPRIV:
-			return -EOPNOTSUPP;
+			err = -EOPNOTSUPP;
+			break;
 		default:
-			/* Basic check */
-			if (!netif_device_present(dev))
-				return -ENODEV;
-			handler = get_handler(dev, cmd);
+			handler = get_handler(cmd);
 			if(cmd < SIOCIWFIRSTPRIV && handler != NULL)
-				return ioctl_standard_call(dev, ifr, cmd,
-							   handler);
-			return -EOPNOTSUPP;
+				err = ioctl_standard_call(drv, dev, ifr, cmd,
+							  handler);
+			else
+				err = -EOPNOTSUPP;
 	}
-	return -EINVAL;
+
+	cfg80211_put_drv(drv);
+ out_put_dev:
+	dev_put(dev);
+	return err;
 }
--- wireless-dev.orig/include/linux/netdevice.h	2007-02-15 12:28:30.597940064 +0100
+++ wireless-dev/include/linux/netdevice.h	2007-02-15 12:28:35.637940064 +0100
@@ -355,10 +355,6 @@ struct net_device
 	/* Instance data managed by the core of Wireless Extensions. */
 	struct iw_public_data *	wireless_data;
 #endif
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-	/* pending config used by cfg80211/wext compat code only */
-	void *cfg80211_wext_pending_config;
-#endif
 	const struct ethtool_ops *ethtool_ops;
 
 	/*
--- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 12:28:34.647940064 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-15 12:28:35.647940064 +0100
@@ -193,8 +193,4 @@ extern void *nl80211hdr_put(struct sk_bu
 extern void *nl80211msg_new(struct sk_buff **skb, u32 pid,
 			    u32 seq, int flags, u8 cmd);
 
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-extern int cfg80211_wext_ioctl(struct ifreq *ifr, unsigned int cmd);
-#endif
-
 #endif /* __NET_CFG80211_H */
--- wireless-dev.orig/include/net/iw_handler.h	2007-02-15 12:28:30.677940064 +0100
+++ wireless-dev/include/net/iw_handler.h	2007-02-15 12:28:35.647940064 +0100
@@ -433,9 +433,6 @@ struct iw_public_data {
 extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
 				 int length);
 
-/* Handle IOCTLs, called in net/core/dev.c */
-extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-
 /* Handle RtNetlink requests, called in net/core/rtnetlink.c */
 extern int wireless_rtnetlink_set(struct net_device *	dev,
 				  char *		data,
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/include/net/wireless.h	2007-02-15 12:28:35.647940064 +0100
@@ -0,0 +1,23 @@
+#ifndef __NET_WIRELESS_H
+#define __NET_WIRELESS_H
+
+/*
+ * internal definitions for wireless
+ */
+
+#if defined(CONFIG_CFG80211_WEXT_COMPAT) || defined(CONFIG_WIRELESS_EXT)
+int wext_ioctl(unsigned int cmd, struct ifreq *ifreq, void __user *arg);
+int wireless_proc_init(void);
+#else
+static inline
+int wext_ioctl(unsigned int cmd, struct ifreq *ifreq, void __user *arg)
+{
+	return -EINVAL;
+}
+static inline int wireless_proc_init(void)
+{
+	return 0;
+}
+#endif
+
+#endif /* __NET_WIRELESS_H */
--- wireless-dev.orig/net/core/dev.c	2007-02-15 12:28:30.577940064 +0100
+++ wireless-dev/net/core/dev.c	2007-02-15 12:28:35.647940064 +0100
@@ -116,7 +116,7 @@
 #include <linux/dmaengine.h>
 #include <linux/err.h>
 #include <linux/ctype.h>
-#include <net/cfg80211.h>
+#include <net/wireless.h>
 
 /*
  *	The list of packet types we will receive (as opposed to discard)
@@ -2229,12 +2229,6 @@ static struct file_operations softnet_se
 	.release = seq_release,
 };
 
-#if defined(CONFIG_WIRELESS_EXT) || defined(CFG80211_WEXT_COMPAT)
-extern int wireless_proc_init(void);
-#else
-#define wireless_proc_init() 0
-#endif
-
 static int __init dev_proc_init(void)
 {
 	int rc = -ENOMEM;
@@ -2799,62 +2793,9 @@ int dev_ioctl(unsigned int cmd, void __u
 					ret = -EFAULT;
 				return ret;
 			}
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-			/* Take care of cfg80211 WE compatibility */
-			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-				/* If command is `set a parameter', or
-				 * `get the encoding parameters', check if
-				 * the user has the right to do it */
-				if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE
-				    || cmd == SIOCGIWENCODEEXT) {
-					if (!capable(CAP_NET_ADMIN))
-						return -EPERM;
-				}
-				dev_load(ifr.ifr_name);
-				rtnl_lock();
-				/* Follow me in net/wireless/wext-compat.c */
-				ret = cfg80211_wext_ioctl(&ifr, cmd);
-				rtnl_unlock();
-				if (ret == 0 && IW_IS_GET(cmd) &&
-				    copy_to_user(arg, &ifr,
-					    	 sizeof(struct ifreq)))
-					ret = -EFAULT;
-				/* haha, I cheat here by allowing a driver or
-				 * stack to have both WE or CFG80211-WE for
-				 * a little while during conversion... hope that
-				 * ENOSYS is only used to indicate not implemented
-				 *
-				 * if wireless extensions are not configured
-				 * then this is the last thing here so that
-				 * if we fall through we return -EINVAL
-				 */
-				if (ret != -ENOSYS)
-					return ret;
-			}
-#endif
-#ifdef CONFIG_WIRELESS_EXT
-			/* Take care of Wireless Extensions */
-			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-				/* If command is `set a parameter', or
-				 * `get the encoding parameters', check if
-				 * the user has the right to do it */
-				if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE
-				    || cmd == SIOCGIWENCODEEXT) {
-					if (!capable(CAP_NET_ADMIN))
-						return -EPERM;
-				}
-				dev_load(ifr.ifr_name);
-				rtnl_lock();
-				/* Follow me in net/wireless/wext-old.c */
-				ret = wireless_process_ioctl(&ifr, cmd);
-				rtnl_unlock();
-				if (ret == 0 && IW_IS_GET(cmd) &&
-				    copy_to_user(arg, &ifr,
-					    	 sizeof(struct ifreq)))
-					ret = -EFAULT;
-				return ret;
-			}
-#endif	/* CONFIG_WIRELESS_EXT */
+			/* Take care of wireless extensions */
+			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
+				return wext_ioctl(cmd, &ifr, arg);
 			return -EINVAL;
 	}
 }
--- wireless-dev.orig/net/wireless/core.c	2007-02-15 12:28:30.257940064 +0100
+++ wireless-dev/net/wireless/core.c	2007-02-15 12:28:35.647940064 +0100
@@ -1,21 +1,24 @@
 /*
- * This is the new wireless configuration interface.
+ * This is the linux wireless configuration interface.
  *
- * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006, 2007		Johannes Berg <johannes@sipsolutions.net>
  */
 
-#include "core.h"
-#include "nl80211.h"
 #include <linux/if.h>
 #include <linux/module.h>
 #include <linux/err.h>
-#include <net/genetlink.h>
-#include <net/cfg80211.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
+#include <linux/nl80211.h>
+#include <net/genetlink.h>
+#include <net/cfg80211.h>
+#include "nl80211.h"
+#include "core.h"
+#include "wext.h"
 
 MODULE_AUTHOR("Johannes Berg");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("wireless configuration support");
 
 /* RCU might be appropriate here since we usually
  * only read the list, and that can happen quite
@@ -116,7 +119,6 @@ cfg80211_get_drv_from_info(struct genl_i
 	return drv;
 }
 
-/* wext will need this */
 struct cfg80211_registered_driver *
 cfg80211_get_drv_from_ifindex(int ifindex)
 {
@@ -221,23 +223,11 @@ EXPORT_SYMBOL_GPL(cfg80211_unregister);
 
 static int cfg80211_init(void)
 {
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-	cfg80211_core_ops.get_drv_from_ifidx = cfg80211_get_drv_from_ifindex;
-	cfg80211_core_ops.put_drv = cfg80211_put_drv;
-	cfg80211_core_ops.module = THIS_MODULE;
-	cfg80211_core_ops.loaded = 1;
-#endif
 	return nl80211_init();
 }
 
 static void cfg80211_exit(void)
 {
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-	cfg80211_core_ops.loaded = 0;
-	cfg80211_core_ops.module = NULL;
-	cfg80211_core_ops.get_drv_from_ifidx = NULL;
-	cfg80211_core_ops.put_drv = NULL;
-#endif
 	nl80211_exit();
 }
 
--- wireless-dev.orig/net/wireless/wext-common.c	2007-02-15 12:28:30.297940064 +0100
+++ wireless-dev/net/wireless/wext-common.c	2007-02-15 12:28:35.657940064 +0100
@@ -1,4 +1,12 @@
-/* common wext support routines, proc interface and events */
+/*
+ * common wext support routines, proc interface and events
+ *
+ *
+ * Most code is from the original wireless.c:
+ * Copyright 1997-2006  Jean Tourrilhes <jt@hpl.hp.com>
+ *
+ * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
+ */
 
 #include <linux/proc_fs.h>
 #include <linux/netdevice.h>
@@ -16,7 +24,7 @@
  * Meta-data about all the standard Wireless Extension request we
  * know about.
  */
-const struct iw_ioctl_description standard_ioctl[] = {
+const struct iw_ioctl_description wext_standard_ioctl[] = {
 	[SIOCSIWCOMMIT	- SIOCIWFIRST] = {
 		.header_type	= IW_HEADER_TYPE_NULL,
 	},
@@ -243,8 +251,7 @@ const struct iw_ioctl_description standa
 		.max_tokens	= sizeof(struct iw_pmksa),
 	},
 };
-const unsigned standard_ioctl_num = (sizeof(standard_ioctl) /
-					sizeof(struct iw_ioctl_description));
+const unsigned wext_standard_ioctl_num = ARRAY_SIZE(wext_standard_ioctl);
 
 /*
  * Meta-data about all the additional standard Wireless Extension events
@@ -545,8 +552,8 @@ void wireless_send_event(struct net_devi
 	/* Get the description of the Event */
 	if(cmd <= SIOCIWLAST) {
 		cmd_index = cmd - SIOCIWFIRST;
-		if(cmd_index < standard_ioctl_num)
-			descr = &(standard_ioctl[cmd_index]);
+		if(cmd_index < wext_standard_ioctl_num)
+			descr = &(wext_standard_ioctl[cmd_index]);
 	} else {
 		cmd_index = cmd - IWEVFIRST;
 		if(cmd_index < standard_event_num)
@@ -608,3 +615,51 @@ void wireless_send_event(struct net_devi
 
 	return;		/* Always success, I guess ;-) */
 }
+EXPORT_SYMBOL(wireless_send_event);
+
+/* common code to handle wireless extension ioctls */
+int wext_ioctl(unsigned int cmd, struct ifreq *ifr, void __user *arg)
+{
+	int ret = -EINVAL;
+
+	/* If command is `set a parameter', or `get the encoding parameters',
+	 * check if the user is allowed to do it */
+	if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE || cmd == SIOCGIWENCODEEXT)
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+#ifdef CONFIG_WIRELESS_EXT
+	dev_load(ifr->ifr_name);
+
+	/* we could change the code to not hold the rtnl but
+	 * some callees might require it held */
+	rtnl_lock();
+
+	/* Follow me in wext-old.c */
+	ret = wireless_process_ioctl(ifr, cmd);
+
+	rtnl_unlock();
+
+	if (IW_IS_GET(cmd) && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+		ret = -EFAULT;
+
+	/* haha, I cheat here by allowing a driver or stack to have both WE and
+	 * CFG80211-WE for a little while during conversion... wext returns
+	 * -EOPNOTSUPP if a handler is not assigned, so we can in that case try
+	 * calling cfg80211's compat code instead.
+	 */
+	if (ret != -EOPNOTSUPP)
+		return ret;
+#endif
+
+#ifdef CONFIG_CFG80211_WEXT_COMPAT
+	/* no need to hold rtnl lock here for the new stuff,
+	 * we properly use dev_get_by_name() and dev_put() */
+	ret = call_cfg80211_wext_ioctl(ifr, cmd);
+
+	if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct ifreq)))
+		ret = -EFAULT;
+#endif
+
+	return ret;
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/wext-export.c	2007-02-15 12:28:35.657940064 +0100
@@ -0,0 +1,29 @@
+/*
+ * things we only need in the kernel when cfg80211 is modular.
+ *
+ * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include "wext.h"
+
+EXPORT_SYMBOL_GPL(wext_standard_ioctl);
+EXPORT_SYMBOL_GPL(wext_standard_ioctl_num);
+EXPORT_SYMBOL_GPL(get_wireless_stats);
+
+struct cfg80211_ioctl_ops cfg80211_ioctl_ops;
+EXPORT_SYMBOL_GPL(cfg80211_ioctl_ops);
+
+int call_cfg80211_wext_ioctl(struct ifreq *ifr, unsigned int cmd)
+{
+	int err = -ENOSYS;
+
+	if (!try_module_get(cfg80211_ioctl_ops.module))
+		return -ENOSYS;
+
+	if (cfg80211_ioctl_ops.do_wext_ioctl)
+		err = cfg80211_ioctl_ops.do_wext_ioctl(ifr, cmd);
+
+	module_put(cfg80211_ioctl_ops.module);
+
+	return err;
+}
--- wireless-dev.orig/net/wireless/wext.h	2007-02-15 12:28:30.347940064 +0100
+++ wireless-dev/net/wireless/wext.h	2007-02-15 12:28:35.657940064 +0100
@@ -3,11 +3,45 @@
  */
 #ifndef _WEXT_H
 #define _WEXT_H
+#include <linux/netdevice.h>
+#include <linux/if.h>
 #include <linux/wireless.h>
-extern struct iw_statistics *get_wireless_stats(struct net_device *dev,
-						struct iw_statistics *out);
-extern const struct iw_ioctl_description standard_ioctl[];
-extern const unsigned standard_ioctl_num;
+#include <net/iw_handler.h>
+
+/* wext compatibility must be compiled in...
+ * this extern is in wext-compat.c */
+struct cfg80211_ioctl_ops {
+	/* used to make sure the module isn't going away
+	 * can't really happen, except if no driver has cfg80211
+	 * in use, but in that case  */
+	struct module *module;
+
+	/* and finally this is used to do work */
+	int (*do_wext_ioctl)(struct ifreq *ifr, unsigned int cmd);
+};
+extern struct cfg80211_ioctl_ops cfg80211_ioctl_ops;
+
+
+struct iw_statistics *get_wireless_stats(struct net_device *dev,
+					 struct iw_statistics *out);
+int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
+
+int cfg80211_wext_ioctl(struct ifreq *ifr, unsigned int cmd);
+#ifdef CFG80211_MODULE
+int call_cfg80211_wext_ioctl(struct ifreq *ifr, unsigned int cmd);
+int cfg80211_wext_init(void);
+void cfg80211_wext_exit(void);
+#else
+#define call_cfg80211_wext_ioctl cfg80211_wext_ioctl
+static inline int cfg80211_wext_init(void)
+{
+	return 0;
+}
+static inline void cfg80211_wext_exit(void) {}
+#endif
+
+extern const struct iw_ioctl_description wext_standard_ioctl[];
+extern const unsigned wext_standard_ioctl_num;
 extern const struct iw_ioctl_description standard_event[];
 extern const int event_type_size[];
 #endif /* _WEXT_H */
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/wext-mod.c	2007-02-15 12:28:35.657940064 +0100
@@ -0,0 +1,20 @@
+/*
+ * things we only need in cfg80211 when it is modular.
+ *
+ * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include "wext.h"
+
+int cfg80211_wext_init(void)
+{
+	cfg80211_ioctl_ops.do_wext_ioctl = cfg80211_wext_ioctl;
+	cfg80211_ioctl_ops.module = THIS_MODULE;
+	return 0;
+}
+
+void cfg80211_wext_exit(void)
+{
+	cfg80211_ioctl_ops.module = NULL;
+	cfg80211_ioctl_ops.do_wext_ioctl = NULL;
+}
--- wireless-dev.orig/net/wireless/wext-old.c	2007-02-15 12:28:30.397940064 +0100
+++ wireless-dev/net/wireless/wext-old.c	2007-02-15 12:28:35.657940064 +0100
@@ -308,9 +308,9 @@ static int ioctl_standard_call(struct ne
 	int					ret = -EINVAL;
 
 	/* Get the description of the IOCTL */
-	if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
+	if((cmd - SIOCIWFIRST) >= wext_standard_ioctl_num)
 		return -EOPNOTSUPP;
-	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
 #ifdef WE_IOCTL_DEBUG
 	printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
@@ -769,9 +769,9 @@ static int rtnetlink_standard_get(struct
 
 	/* Get the description of the Request */
 	cmd = request->cmd;
-	if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
+	if((cmd - SIOCIWFIRST) >= wext_standard_ioctl_num)
 		return -EOPNOTSUPP;
-	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
 #ifdef WE_RTNETLINK_DEBUG
 	printk(KERN_DEBUG "%s (WE.r) : Found standard handler for 0x%04X\n",
@@ -911,9 +911,9 @@ static inline int rtnetlink_standard_set
 
 	/* Get the description of the Request */
 	cmd = request->cmd;
-	if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
+	if((cmd - SIOCIWFIRST) >= wext_standard_ioctl_num)
 		return -EOPNOTSUPP;
-	descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
 #ifdef WE_RTNETLINK_DEBUG
 	printk(KERN_DEBUG "%s (WE.r) : Found standard SET handler for 0x%04X\n",
@@ -1726,5 +1726,4 @@ EXPORT_SYMBOL(iw_handler_get_spy);
 EXPORT_SYMBOL(iw_handler_get_thrspy);
 EXPORT_SYMBOL(iw_handler_set_spy);
 EXPORT_SYMBOL(iw_handler_set_thrspy);
-EXPORT_SYMBOL(wireless_send_event);
 EXPORT_SYMBOL(wireless_spy_update);
--- wireless-dev.orig/net/wireless/core.h	2007-02-15 12:28:30.457940064 +0100
+++ wireless-dev/net/wireless/core.h	2007-02-15 12:28:35.657940064 +0100
@@ -21,31 +21,16 @@ struct cfg80211_registered_driver {
 	 * to avoid the deregister call to proceed while
 	 * any call is in progress */
 	struct mutex mtx;
+
+#ifdef CONFIG_CFG80211_WEXT_COMPAT
+	/* wext compat */
+	struct cfg80211_config *wext_pending_config;
+#endif
 };
 
 extern struct mutex cfg80211_drv_mutex;
 extern struct list_head cfg80211_drv_list;
 
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-/* wext compatibility must be compiled in...
- * this extern is in wext-compat.c */
-struct cfg80211_core_ops {
-	/* flag to see if cfg80211 is there.
-	 * FIXME: isn't that racy? */
-	int loaded;
-
-	/* used to make sure the module isn't going away
-	 * can't really happen, except if no driver has cfg80211
-	 * in use, but in that case  */
-	struct module *module;
-
-	/* and finally these are used to do work */
-	struct cfg80211_registered_driver *(*get_drv_from_ifidx)(int ifidx);
-	void (*put_drv)(struct cfg80211_registered_driver *drv);
-};
-extern struct cfg80211_core_ops cfg80211_core_ops;
-#endif
-
 /*
  * This function returns a pointer to the driver
  * that the genl_info item that is passed refers to.
--- wireless-dev.orig/net/wireless/Makefile	2007-02-15 12:28:30.477940064 +0100
+++ wireless-dev/net/wireless/Makefile	2007-02-15 12:28:35.657940064 +0100
@@ -1,16 +1,16 @@
 obj-$(CONFIG_CFG80211) += cfg80211.o
 
-cfg80211-objs := \
-	core.o nl80211.o
+cfg80211-y += core.o nl80211.o
+cfg80211-$(CONFIG_CFG80211_WEXT_COMPAT) += wext-compat.o
 
-obj-$(CONFIG_WIRELESS_EXT) += wext-old.o
+ifeq ($(CONFIG_CFG80211),m)
+obj-$(CONFIG_CFG80211_WEXT_COMPAT) += wext-export.o
+cfg80211-$(CONFIG_CFG80211_WEXT_COMPAT) += wext-mod.o
+# we need something to tell us what's up...
+# but we can't use #ifdef MODULE because we also need to
+# know in the part that is built in (namely wext-common.c)
+CFLAGS += -DCFG80211_MODULE
+endif
 
-obj-nn :=
-obj-yy :=
-obj-yn :=
-obj-ny :=
-
-# this needs to be compiled in...
-obj-$(CONFIG_CFG80211_WEXT_COMPAT) += wext-compat.o
-obj-$(CONFIG_CFG80211_WEXT_COMPAT)$(CONFIG_NET_WIRELESS) += wext-common.o
-obj-y += $(obj-yy) $(obj-yn) $(obj-ny)
+obj-$(CONFIG_WIRELESS_EXT) += wext-common.o wext-old.o
+obj-$(CONFIG_CFG80211_WEXT_COMPAT) += wext-common.o

--


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

* [PATCH 03/10] introduce wiphy concept
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
  2007-02-15 14:42 ` [PATCH 01/10] remove cfg80211/wext-nl compatibility Johannes Berg
  2007-02-15 14:42 ` [PATCH 02/10] update cfg80211/wext and wext code Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-19 20:37   ` Jiri Benc
  2007-02-15 14:42 ` [PATCH 04/10] cfg/nl80211: make association explicit Johannes Berg
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This patch introduces struct wiphy and struct wireless_dev. The latter
is added to struct net_device as ieee80211_ptr and keeps wireless per-netdev
state, the wiphy keeps wireless per-device (hardware) state and is
accessible from struct wireless_dev.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
I think we should go with this for now. I've tested it quite a bit and
it all seems to work pretty well.

For the future:

Maybe instead of having ieee80211_ptr point to a struct wireless_dev
(which can be allocated along with the netdev) we should mandate that
each wireless netdev is allocated via a new function that puts the
wireless_dev struct as the first part of the private area of the netdev,
that way getting to it is just a simple addition instead of following
a pointer... and we can also drop ieee80211_ptr from struct net_device.

We'd provide functions to go from netdev to wdev and from wdev to
priv. Also, we could then keep track of all wdevs that have been added
to a certain wiphy and get rid of the cfg80211 list_interfaces callback.
And we could pass a wdev to all calls there...

Another thing to do is allowing renaming of the wiphy via cfg80211...

Well, if anybody read this far I'd appreciate comments, if not, well,
who cares? :)

---
 include/linux/netdevice.h  |    4 
 include/net/cfg80211.h     |   73 +++++------------
 include/net/wireless.h     |  124 ++++++++++++++++++++++++++++++
 net/wireless/Makefile      |    2 
 net/wireless/core.c        |  184 ++++++++++++++++++++++++++-------------------
 net/wireless/core.h        |   39 ++++++---
 net/wireless/nl80211.c     |  115 ++++++++++++++--------------
 net/wireless/sysfs.c       |   85 ++++++++++++++++++++
 net/wireless/sysfs.h       |   10 ++
 net/wireless/wext-compat.c |   96 +++++++++++------------
 10 files changed, 489 insertions(+), 243 deletions(-)

--- wireless-dev.orig/net/wireless/core.h	2007-02-15 14:29:54.467629166 +0100
+++ wireless-dev/net/wireless/core.h	2007-02-15 15:32:22.534331360 +0100
@@ -5,16 +5,15 @@
  */
 #ifndef __NET_WIRELESS_CORE_H
 #define __NET_WIRELESS_CORE_H
-#include <net/cfg80211.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
+#include <linux/netdevice.h>
 #include <net/genetlink.h>
-#include <linux/module.h>
+#include <net/wireless.h>
+#include <net/cfg80211.h>
 
-struct cfg80211_registered_driver {
+struct cfg80211_registered_device {
 	struct cfg80211_ops *ops;
-	int wiphy;
-	void *priv;
 	struct list_head list;
 	/* we hold this mutex during any call so that
 	 * we cannot do multiple calls at once, and also
@@ -22,12 +21,25 @@ struct cfg80211_registered_driver {
 	 * any call is in progress */
 	struct mutex mtx;
 
+	/* wiphy index, internal only */
+	int idx;
+
 #ifdef CONFIG_CFG80211_WEXT_COMPAT
 	/* wext compat */
 	struct cfg80211_config *wext_pending_config;
 #endif
+
+	/* must be last because of the way we do wiphy_priv(),
+	 * and it should at least be aligned to NETDEV_ALIGN */
+	struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
 };
 
+static inline struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
+{
+	BUG_ON(!wiphy);
+	return container_of(wiphy, struct cfg80211_registered_device, wiphy);
+}
+
 extern struct mutex cfg80211_drv_mutex;
 extern struct list_head cfg80211_drv_list;
 
@@ -37,7 +49,7 @@ extern struct list_head cfg80211_drv_lis
  * If successful, it returns non-NULL and also locks
  * the driver's mutex!
  *
- * This means that you need to call cfg80211_put_drv()
+ * This means that you need to call cfg80211_put_dev()
  * before being allowed to acquire &cfg80211_drv_mutex!
  *
  * This is necessary because we need to lock the global
@@ -51,13 +63,16 @@ extern struct list_head cfg80211_drv_lis
  * The result of this can be a PTR_ERR and hence must
  * be checked with IS_ERR() for errors.
  */
-extern struct cfg80211_registered_driver *
-cfg80211_get_drv_from_info(struct genl_info *info);
+extern struct cfg80211_registered_device *
+cfg80211_get_dev_from_info(struct genl_info *info);
+
+/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
+extern struct cfg80211_registered_device *
+cfg80211_get_dev_from_ifindex(int ifindex);
 
-/* identical to cfg80211_get_drv_from_info but only operate on ifindex */
-extern struct cfg80211_registered_driver *
-cfg80211_get_drv_from_ifindex(int ifindex);
+extern void cfg80211_put_dev(struct cfg80211_registered_device *drv);
 
-extern void cfg80211_put_drv(struct cfg80211_registered_driver *drv);
+/* free object */
+extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
 
 #endif /* __NET_WIRELESS_CORE_H */
--- wireless-dev.orig/include/linux/netdevice.h	2007-02-15 14:29:54.437629166 +0100
+++ wireless-dev/include/linux/netdevice.h	2007-02-15 14:29:54.557629166 +0100
@@ -42,6 +42,8 @@
 struct vlan_group;
 struct ethtool_ops;
 struct netpoll_info;
+/* 802.11 specific */
+struct wireless_dev;
 					/* source back-compat hooks */
 #define SET_ETHTOOL_OPS(netdev,ops) \
 	( (netdev)->ethtool_ops = (ops) )
@@ -399,7 +401,7 @@ struct net_device
 	void                    *ip6_ptr;       /* IPv6 specific data */
 	void			*ec_ptr;	/* Econet specific data	*/
 	void			*ax25_ptr;	/* AX.25 specific data */
-	void			*ieee80211_ptr;	/* IEEE 802.11 specific data */
+	struct wireless_dev	*ieee80211_ptr;	/* IEEE 802.11 specific data */
 
 /*
  * Cache line mostly used on receive path (including eth_type_trans())
--- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 14:29:54.437629166 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-15 15:32:26.034331360 +0100
@@ -2,11 +2,8 @@
 #define __NET_CFG80211_H
 
 #include <linux/netlink.h>
-#include <linux/nl80211.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <net/genetlink.h>
-#include <linux/wireless.h>
 
 /*
  * 802.11 configuration in-kernel interface
@@ -57,22 +54,21 @@ struct scan_params {
 	struct scan_channel *channels;
 };
 
+/* from net/wireless.h */
+struct wiphy;
+
 /**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
  * in order to handle configuration requests on their interfaces.
  *
- * The priv pointer passed to each call is the pointer that was
- * registered in cfg80211_register_driver().
- *
  * All callbacks except where otherwise noted should return 0
  * on success or a negative error code.
  *
- * @list_interfaces: for each interfaces belonging to the wiphy identified
- *		     by the priv pointer, call the one() function with the
- *		     given data and the ifindex. This callback is required.
- *
+ * @list_interfaces: Call the one() function with the given data and the
+ *                   ifindex for each interface belonging to the wiphy.
+ *		     This callback is required.
  * @inject_packet: inject the given frame with the NL80211_FLAG_*
  *		   flags onto the given queue.
  *
@@ -118,74 +114,53 @@ struct scan_params {
  *		   is to be passed to that callback
  */
 struct cfg80211_ops {
-	int	(*list_interfaces)(void *priv, void *data,
+	int	(*list_interfaces)(struct wiphy *wiphy, void *data,
 				   int (*one)(void *data, int ifindex));
 
 
-	int	(*inject_packet)(void *priv, void *frame, int framelen,
+	int	(*inject_packet)(struct wiphy *wiphy, void *frame, int framelen,
 				 u32 flags, int queue);
 
 
-	int	(*add_virtual_intf)(void *priv, char *name,
+	int	(*add_virtual_intf)(struct wiphy *wiphy, char *name,
 				    unsigned int type);
-	int	(*del_virtual_intf)(void *priv, int ifindex);
+	int	(*del_virtual_intf)(struct wiphy *wiphy, int ifindex);
 
 
-	int	(*configure)(void *priv, struct net_device *dev,
+	int	(*configure)(struct wiphy *wiphy, struct net_device *dev,
 			     struct cfg80211_config *cfg);
-	void	(*get_config)(void *priv, struct net_device *dev,
+	void	(*get_config)(struct wiphy *wiphy, struct net_device *dev,
 			      struct cfg80211_config *cfg);
-	u32	(*get_config_valid)(void *priv, struct net_device *dev);
+	u32	(*get_config_valid)(struct wiphy *wiphy,
+				    struct net_device *dev);
 
 
-	int	(*reassociate)(void *priv, struct net_device *dev);
-	int	(*disassociate)(void *priv, struct net_device *dev);
-	int	(*deauth)(void *priv, struct net_device *dev);
+	int	(*reassociate)(struct wiphy *wiphy, struct net_device *dev);
+	int	(*disassociate)(struct wiphy *wiphy, struct net_device *dev);
+	int	(*deauth)(struct wiphy *wiphy, struct net_device *dev);
 
 
-	int	(*initiate_scan)(void *priv, struct net_device *dev,
+	int	(*initiate_scan)(struct wiphy *wiphy, struct net_device *dev,
 				 struct scan_params *params);
 
 
-	int	(*set_roaming)(void *priv, struct net_device *dev,
+	int	(*set_roaming)(struct wiphy *wiphy, struct net_device *dev,
 			       int roaming_control);
-	int	(*get_roaming)(void *priv, struct net_device *dev);
-	int	(*set_fixed_bssid)(void *priv, struct net_device *dev,
+	int	(*get_roaming)(struct wiphy *wiphy, struct net_device *dev);
+	int	(*set_fixed_bssid)(struct wiphy *wiphy, struct net_device *dev,
 				   u8 *bssid);
-	int	(*get_fixed_bssid)(void *priv, struct net_device *dev,
+	int	(*get_fixed_bssid)(struct wiphy *wiphy, struct net_device *dev,
 				   u8 *bssid);
 
 
-	int	(*get_association)(void *priv, struct net_device *dev,
+	int	(*get_association)(struct wiphy *wiphy, struct net_device *dev,
 				   u8 *bssid);
 
-	int	(*get_auth_list)(void *priv, struct net_device *dev,
+	int	(*get_auth_list)(struct wiphy *wiphy, struct net_device *dev,
 				 void *data,
 				 int (*next_bssid)(void *data, u8 *bssid));
 };
 
-/**
- * cfg80211_register - register a wiphy with cfg80211
- *
- * register a given method structure with the cfg80211 system
- * and associate the 'priv' pointer with it.
- *
- * Returns a non-negative wiphy index or a negative error code.
- *
- * NOTE: for proper operation, this priv pointer MUST also be
- * assigned to each &struct net_device's @ieee80211_ptr member!
- */
-extern int cfg80211_register(struct cfg80211_ops *ops, void *priv);
-
-/**
- * cfg80211_unregister - deregister a wiphy from cfg80211
- *
- * unregister a device with the given priv pointer.
- * After this call, no more requests can be made with this priv
- * pointer, but the call may sleep to wait for an outstanding
- * request that is being handled.
- */
-extern void cfg80211_unregister(void *priv);
 
 /* helper functions specific to nl80211 */
 extern void *nl80211hdr_put(struct sk_buff *skb, u32 pid,
--- wireless-dev.orig/net/wireless/core.c	2007-02-15 14:29:54.457629166 +0100
+++ wireless-dev/net/wireless/core.c	2007-02-15 15:35:42.484331360 +0100
@@ -10,11 +10,14 @@
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/nl80211.h>
+#include <linux/debugfs.h>
 #include <net/genetlink.h>
 #include <net/cfg80211.h>
+#include <net/wireless.h>
 #include "nl80211.h"
 #include "core.h"
 #include "wext.h"
+#include "sysfs.h"
 
 MODULE_AUTHOR("Johannes Berg");
 MODULE_LICENSE("GPL");
@@ -27,31 +30,16 @@ LIST_HEAD(cfg80211_drv_list);
 DEFINE_MUTEX(cfg80211_drv_mutex);
 static int wiphy_counter;
 
-/* requires nl80211_drv_mutex to be held! */
-static struct cfg80211_registered_driver *cfg80211_drv_by_priv(void *priv)
-{
-	struct cfg80211_registered_driver *result = NULL, *drv;
-
-	if (!priv)
-		return NULL;
-
-	list_for_each_entry(drv, &cfg80211_drv_list, list) {
-		if (drv->priv == priv) {
-			result = drv;
-			break;
-		}
-	}
-
-	return result;
-}
+/* for debugfs */
+static struct dentry *ieee80211_debugfs_dir;
 
 /* requires cfg80211_drv_mutex to be held! */
-static struct cfg80211_registered_driver *cfg80211_drv_by_wiphy(int wiphy)
+static struct cfg80211_registered_device *cfg80211_drv_by_wiphy(int wiphy)
 {
-	struct cfg80211_registered_driver *result = NULL, *drv;
+	struct cfg80211_registered_device *result = NULL, *drv;
 
 	list_for_each_entry(drv, &cfg80211_drv_list, list) {
-		if (drv->wiphy == wiphy) {
+		if (drv->idx == wiphy) {
 			result = drv;
 			break;
 		}
@@ -61,11 +49,11 @@ static struct cfg80211_registered_driver
 }
 
 /* requires cfg80211_drv_mutex to be held! */
-static struct cfg80211_registered_driver *
+static struct cfg80211_registered_device *
 __cfg80211_drv_from_info(struct genl_info *info)
 {
 	int ifindex;
-	struct cfg80211_registered_driver *bywiphy = NULL, *byifidx = NULL;
+	struct cfg80211_registered_device *bywiphy = NULL, *byifidx = NULL;
 	struct net_device *dev;
 	int err = -EINVAL;
 
@@ -79,7 +67,9 @@ __cfg80211_drv_from_info(struct genl_inf
 		ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
 		dev = dev_get_by_index(ifindex);
 		if (dev) {
-			byifidx = cfg80211_drv_by_priv(dev->ieee80211_ptr);
+			if (dev->ieee80211_ptr)
+				byifidx =
+					wiphy_to_dev(dev->ieee80211_ptr->wiphy);
 			dev_put(dev);
 		}
 		err = -ENODEV;
@@ -100,10 +90,10 @@ __cfg80211_drv_from_info(struct genl_inf
 	return ERR_PTR(err);
 }
 
-struct cfg80211_registered_driver *
-cfg80211_get_drv_from_info(struct genl_info *info)
+struct cfg80211_registered_device *
+cfg80211_get_dev_from_info(struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 
 	mutex_lock(&cfg80211_drv_mutex);
 	drv = __cfg80211_drv_from_info(info);
@@ -119,28 +109,28 @@ cfg80211_get_drv_from_info(struct genl_i
 	return drv;
 }
 
-struct cfg80211_registered_driver *
-cfg80211_get_drv_from_ifindex(int ifindex)
+struct cfg80211_registered_device *
+cfg80211_get_dev_from_ifindex(int ifindex)
 {
-	struct cfg80211_registered_driver *drv = ERR_PTR(-ENODEV);
+	struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV);
 	struct net_device *dev;
 
 	mutex_lock(&cfg80211_drv_mutex);
 	dev = dev_get_by_index(ifindex);
 	if (!dev)
 		goto out;
-	drv = cfg80211_drv_by_priv(dev->ieee80211_ptr);
-	if (drv)
+	if (dev->ieee80211_ptr) {
+		drv = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
 		mutex_lock(&drv->mtx);
-	else
-		drv = ERR_PTR(-ENOSYS);
+	} else
+		drv = ERR_PTR(-ENODEV);
 	dev_put(dev);
  out:
 	mutex_unlock(&cfg80211_drv_mutex);
 	return drv;
 }
 
-void cfg80211_put_drv(struct cfg80211_registered_driver *drv)
+void cfg80211_put_dev(struct cfg80211_registered_device *drv)
 {
 	BUG_ON(IS_ERR(drv));
 	mutex_unlock(&drv->mtx);
@@ -148,63 +138,78 @@ void cfg80211_put_drv(struct cfg80211_re
 
 /* exported functions */
 
-int cfg80211_register(struct cfg80211_ops *ops, void *priv)
+struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
 {
-	struct cfg80211_registered_driver *drv;
-	int res;
+	struct cfg80211_registered_device *result;
+	int alloc_size;
 
-	if (!priv || !ops->list_interfaces)
-		return -EINVAL;
+	if (!ops->list_interfaces)
+		return NULL;
 
-	mutex_lock(&cfg80211_drv_mutex);
+	alloc_size = sizeof(*result) + sizeof_priv;
 
-	if (cfg80211_drv_by_priv(priv)) {
-		res = -EALREADY;
-		goto out_unlock;
-	}
+	result = kzalloc(alloc_size, GFP_KERNEL);
+	if (!result)
+		return NULL;
 
-	drv = kzalloc(sizeof(struct cfg80211_registered_driver), GFP_KERNEL);
-	if (!drv) {
-		res = -ENOMEM;
-		goto out_unlock;
-	}
+	result->ops = ops;
 
-	drv->ops = ops;
-	drv->priv = priv;
+	mutex_lock(&cfg80211_drv_mutex);
 
 	if (unlikely(wiphy_counter<0)) {
 		/* ugh, wrapped! */
-		kfree(drv);
-		res = -ENOSPC;
-		goto out_unlock;
+		kfree(result);
+		return NULL;
 	}
-	mutex_init(&drv->mtx);
-	drv->wiphy = wiphy_counter;
-	list_add(&drv->list, &cfg80211_drv_list);
-	/* return wiphy number */
-	res = drv->wiphy;
+	drv->idx = wiphy_counter;
+
+	/* give it a proper name */
+	snprintf(drv->wiphy.class_dev.class_id, BUS_ID_SIZE,
+		 "wiphy%d", drv->idx);
 
 	/* now increase counter for the next time */
 	wiphy_counter++;
+	mutex_unlock(&cfg80211_drv_mutex);
+
+	mutex_init(&result->mtx);
+
+	class_device_initialize(&result->wiphy.class_dev);
+
+	return &result->wiphy;
+}
+EXPORT_SYMBOL(wiphy_new);
+
+int wiphy_register(struct wiphy *wiphy)
+{
+	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	int res;
 
+	mutex_lock(&cfg80211_drv_mutex);
+
+
+	res = wiphy_sysfs_add(&drv->wiphy);
+	if (res)
+		goto out_unlock;
+
+	list_add(&drv->list, &cfg80211_drv_list);
+
+	/* add to debugfs */
+	drv->wiphy.debugfsdir =
+		debugfs_create_dir(wiphy_name(&drv->wiphy),
+				   ieee80211_debugfs_dir);
+
+	res = 0;
  out_unlock:
 	mutex_unlock(&cfg80211_drv_mutex);
 	return res;
 }
-EXPORT_SYMBOL_GPL(cfg80211_register);
+EXPORT_SYMBOL(wiphy_register);
 
-void cfg80211_unregister(void *priv)
+void wiphy_unregister(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
 
 	mutex_lock(&cfg80211_drv_mutex);
-	drv = cfg80211_drv_by_priv(priv);
-	if (!drv) {
-		printk(KERN_ERR "deregistering cfg80211 backend that "
-		       " was never registered!\n");
-		mutex_unlock(&cfg80211_drv_mutex);
-		return;
-	}
 
 	/* hold registered driver mutex during list removal as well
 	 * to make sure no commands are in progress at the moment */
@@ -212,24 +217,53 @@ void cfg80211_unregister(void *priv)
 	list_del(&drv->list);
 	mutex_unlock(&drv->mtx);
 
+	wiphy_sysfs_del(wiphy);
+	debugfs_remove(drv->wiphy.debugfsdir);
+
 	mutex_unlock(&cfg80211_drv_mutex);
+}
+EXPORT_SYMBOL(wiphy_unregister);
 
+void cfg80211_dev_free(struct cfg80211_registered_device *drv)
+{
 	mutex_destroy(&drv->mtx);
 	kfree(drv);
 }
-EXPORT_SYMBOL_GPL(cfg80211_unregister);
 
-/* module initialisation/exit functions */
+void wiphy_free(struct wiphy *wiphy)
+{
+	class_device_put(&wiphy->class_dev);
+}
+EXPORT_SYMBOL(wiphy_free);
+
 
 static int cfg80211_init(void)
 {
-	return nl80211_init();
+	int err = wiphy_sysfs_init();
+
+	if (err)
+		return err;
+
+	err = cfg80211_wext_init();
+
+	if (err)
+		goto out_exit_sysfs;
+
+	ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL);
+
+	return 0;
+
+ out_exit_sysfs:
+ 	wiphy_sysfs_exit();
+
+	return err;
 }
+module_init(cfg80211_init);
 
 static void cfg80211_exit(void)
 {
-	nl80211_exit();
+	debugfs_remove(ieee80211_debugfs_dir);
+	cfg80211_wext_exit();
+	wiphy_sysfs_exit();
 }
-
-module_init(cfg80211_init);
 module_exit(cfg80211_exit);
--- wireless-dev.orig/net/wireless/nl80211.c	2007-02-15 14:29:49.667629166 +0100
+++ wireless-dev/net/wireless/nl80211.c	2007-02-15 15:32:26.134331360 +0100
@@ -7,11 +7,12 @@
 #include <linux/if.h>
 #include <linux/module.h>
 #include <linux/err.h>
-#include <net/genetlink.h>
-#include <net/cfg80211.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/if_ether.h>
+#include <linux/nl80211.h>
+#include <net/genetlink.h>
+#include <net/cfg80211.h>
 #include "core.h"
 #include "nl80211.h"
 
@@ -42,7 +43,7 @@ static int check_information_element(str
 
 /* internal helper: get drv and dev */
 static int get_drv_dev_by_info_ifindex(struct genl_info *info,
-				       struct cfg80211_registered_driver **drv,
+				       struct cfg80211_registered_device **drv,
 				       struct net_device **dev)
 {
 	int ifindex;
@@ -55,7 +56,7 @@ static int get_drv_dev_by_info_ifindex(s
 	if (!dev)
 		return -ENODEV;
 
-	*drv = cfg80211_get_drv_from_ifindex(ifindex);
+	*drv = cfg80211_get_dev_from_ifindex(ifindex);
 	if (IS_ERR(*drv)) {
 		dev_put(*dev);
 		return PTR_ERR(*drv);
@@ -95,13 +96,13 @@ static struct nla_policy nl80211_policy[
 
 static int nl80211_get_cmdlist(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	struct sk_buff *msg;
 	void *hdr;
 	int err;
 	struct nlattr *start;
 
-	drv = cfg80211_get_drv_from_info(info);
+	drv = cfg80211_get_dev_from_info(info);
 	if (IS_ERR(drv))
 		return PTR_ERR(drv);
 
@@ -112,7 +113,7 @@ static int nl80211_get_cmdlist(struct sk
 		goto put_drv;
 	}
 
-	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, drv->wiphy);
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, drv->idx);
 
 	start = nla_nest_start(msg, NL80211_ATTR_CMDS);
 	if (!start)
@@ -151,7 +152,7 @@ static int nl80211_get_cmdlist(struct sk
  	err = -ENOBUFS;
 	nlmsg_free(msg);
  put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	return err;
 }
 #undef CHECK_CMD
@@ -161,7 +162,7 @@ static int nl80211_get_wiphys(struct sk_
 	struct sk_buff *msg;
 	void *hdr;
 	struct nlattr *start, *indexstart;
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int idx = 1;
 
 	hdr = nl80211msg_new(&msg, info->snd_pid, info->snd_seq, 0,
@@ -178,7 +179,7 @@ static int nl80211_get_wiphys(struct sk_
 		indexstart = nla_nest_start(msg, idx++);
 		if (!indexstart)
 			goto nla_put_failure;
-		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, drv->wiphy);
+		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, drv->idx);
 		nla_nest_end(msg, indexstart);
 	}
 	mutex_unlock(&cfg80211_drv_mutex);
@@ -230,14 +231,14 @@ static int addifidx(void *data, int ifid
 
 static int nl80211_get_intfs(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	struct sk_buff *msg;
 	void *hdr;
 	int err;
 	struct nlattr *start;
 	struct add_cb_data cb;
 
-	drv = cfg80211_get_drv_from_info(info);
+	drv = cfg80211_get_dev_from_info(info);
 	if (IS_ERR(drv))
 		return PTR_ERR(drv);
 
@@ -248,7 +249,7 @@ static int nl80211_get_intfs(struct sk_b
 		goto put_drv;
 	}
 
-	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, drv->wiphy);
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, drv->idx);
 
 	start = nla_nest_start(msg, NL80211_ATTR_INTERFACE_LIST);
 	if (!start) {
@@ -258,7 +259,7 @@ static int nl80211_get_intfs(struct sk_b
 
 	cb.skb = msg;
 	cb.idx = 1;
-	err = drv->ops->list_interfaces(drv->priv, &cb, addifidx);
+	err = drv->ops->list_interfaces(&drv->wiphy, &cb, addifidx);
 	if (err)
 		goto msg_free;
 
@@ -274,13 +275,13 @@ static int nl80211_get_intfs(struct sk_b
  msg_free:
 	nlmsg_free(msg);
  put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	return err;
 }
 
 static int nl80211_do_inject(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	u32 flags = 0;
 	int err, queue = -1;
 
@@ -291,7 +292,7 @@ static int nl80211_do_inject(struct sk_b
 	if (info->attrs[NL80211_ATTR_QUEUE])
 		queue = (int) nla_get_u32(info->attrs[NL80211_ATTR_QUEUE]);
 
-	drv = cfg80211_get_drv_from_info(info);
+	drv = cfg80211_get_dev_from_info(info);
 	if (IS_ERR(drv))
 		return PTR_ERR(drv);
 
@@ -300,19 +301,19 @@ static int nl80211_do_inject(struct sk_b
 		goto unlock;
 	}
 
-	err = drv->ops->inject_packet(drv->priv,
+	err = drv->ops->inject_packet(&drv->wiphy,
 		nla_data(info->attrs[NL80211_ATTR_FRAME]),
 		nla_len(info->attrs[NL80211_ATTR_FRAME]),
 		flags,
 		queue);
  unlock:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	return err;
 }
 
 static int nl80211_add_virt_intf(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	unsigned int type = NL80211_IFTYPE_UNSPECIFIED;
 
@@ -325,7 +326,7 @@ static int nl80211_add_virt_intf(struct 
 			return -EINVAL;
 	}
 
-	drv = cfg80211_get_drv_from_info(info);
+	drv = cfg80211_get_dev_from_info(info);
 	if (IS_ERR(drv))
 		return PTR_ERR(drv);
 
@@ -334,17 +335,17 @@ static int nl80211_add_virt_intf(struct 
 		goto unlock;
 	}
 
-	err = drv->ops->add_virtual_intf(drv->priv,
+	err = drv->ops->add_virtual_intf(&drv->wiphy,
 		nla_data(info->attrs[NL80211_ATTR_IFNAME]), type);
 
  unlock:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	return err;
 }
 
 static int nl80211_del_virt_intf(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int ifindex, err;
 	struct net_device *dev;
 
@@ -359,16 +360,16 @@ static int nl80211_del_virt_intf(struct 
 		goto out;
 	}
 
-	err = drv->ops->del_virtual_intf(drv->priv, ifindex);
+	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
 
  out:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	return err;
 }
 
 static int nl80211_configure(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	struct cfg80211_config config;
@@ -421,16 +422,16 @@ static int nl80211_configure(struct sk_b
 		config.channel = nla_get_u32(attr);
 	}
 
-	err = drv->ops->configure(drv->priv, dev, &config);
+	err = drv->ops->configure(&drv->wiphy, dev, &config);
  out:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_get_config(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	struct cfg80211_config config;
@@ -448,7 +449,7 @@ static int nl80211_get_config(struct sk_
 
 	memset(&config, 0, sizeof(config));
 
-	drv->ops->get_config(drv->priv, dev, &config);
+	drv->ops->get_config(&drv->wiphy, dev, &config);
 
 	hdr = nl80211msg_new(&msg, info->snd_pid, info->snd_seq, 0,
 			     NL80211_CMD_NEW_CONFIG);
@@ -486,14 +487,14 @@ static int nl80211_get_config(struct sk_
 	err = -ENOBUFS;
 	nlmsg_free(msg);
  out_put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_set_roaming(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	int roaming_control;
@@ -514,16 +515,16 @@ static int nl80211_set_roaming(struct sk
 		goto out;
 	}
 
-	err = drv->ops->set_roaming(drv->priv, dev, roaming_control);
+	err = drv->ops->set_roaming(&drv->wiphy, dev, roaming_control);
  out:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_get_roaming(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	struct sk_buff *msg;
@@ -538,7 +539,7 @@ static int nl80211_get_roaming(struct sk
 		goto out_put_drv;
 	}
 
-	err = drv->ops->get_roaming(drv->priv, dev);
+	err = drv->ops->get_roaming(&drv->wiphy, dev);
 	if (err < 0)
 		goto out_put_drv;
 
@@ -561,14 +562,14 @@ static int nl80211_get_roaming(struct sk
 	err = -ENOBUFS;
 	nlmsg_free(msg);
  out_put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_set_fixed_bssid(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	u8 *bssid;
@@ -586,16 +587,16 @@ static int nl80211_set_fixed_bssid(struc
 		goto out;
 	}
 
-	err = drv->ops->set_fixed_bssid(drv->priv, dev, bssid);
+	err = drv->ops->set_fixed_bssid(&drv->wiphy, dev, bssid);
  out:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_get_fixed_bssid(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	struct sk_buff *msg;
@@ -611,7 +612,7 @@ static int nl80211_get_fixed_bssid(struc
 		goto out_put_drv;
 	}
 
-	err = drv->ops->get_fixed_bssid(drv->priv, dev, bssid);
+	err = drv->ops->get_fixed_bssid(&drv->wiphy, dev, bssid);
 	if (err < 0)
 		goto out_put_drv;
 
@@ -634,14 +635,14 @@ static int nl80211_get_fixed_bssid(struc
 	err = -ENOBUFS;
 	nlmsg_free(msg);
  out_put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_get_association(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	struct sk_buff *msg;
@@ -657,7 +658,7 @@ static int nl80211_get_association(struc
 		goto out_put_drv;
 	}
 
-	err = drv->ops->get_association(drv->priv, dev, bssid);
+	err = drv->ops->get_association(&drv->wiphy, dev, bssid);
 	if (err < 0)
 		goto out_put_drv;
 
@@ -681,17 +682,17 @@ static int nl80211_get_association(struc
 	err = -ENOBUFS;
 	nlmsg_free(msg);
  out_put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_assoc_deauth(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
-	int (*act)(void *priv, struct net_device *dev);
+	int (*act)(struct wiphy *wiphy, struct net_device *dev);
 
 	err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
 	if (err)
@@ -716,9 +717,9 @@ static int nl80211_assoc_deauth(struct s
 		goto out;
 	}
 
-	err = act(drv->priv, dev);
+	err = act(&drv->wiphy, dev);
  out:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
@@ -744,7 +745,7 @@ static int add_bssid(void *data, u8 *bss
 
 static int nl80211_get_auth_list(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	struct net_device *dev;
 	struct sk_buff *msg;
 	void *hdr;
@@ -778,7 +779,7 @@ static int nl80211_get_auth_list(struct 
 
 	cb.skb = msg;
 	cb.idx = 1;
-	err = drv->ops->get_auth_list(drv->priv, dev, &cb, add_bssid);
+	err = drv->ops->get_auth_list(&drv->wiphy, dev, &cb, add_bssid);
 	if (err)
 		goto msg_free;
 
@@ -794,14 +795,14 @@ static int nl80211_get_auth_list(struct 
  msg_free:
 	nlmsg_free(msg);
  put_drv:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
 
 static int nl80211_initiate_scan(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 	struct net_device *dev;
 	struct scan_params params;
@@ -874,11 +875,11 @@ static int nl80211_initiate_scan(struct 
 	params.channels = channels;
 	params.n_channels = count;
 
-	err = drv->ops->initiate_scan(drv->priv, dev, &params);
+	err = drv->ops->initiate_scan(&drv->wiphy, dev, &params);
 
 	kfree(channels);
  out:
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
 	dev_put(dev);
 	return err;
 }
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/sysfs.c	2007-02-15 14:29:54.567629166 +0100
@@ -0,0 +1,85 @@
+/*
+ * This file provides /sys/class/ieee80211/<wiphy name>/
+ * and some default attributes.
+ *
+ * Copyright 2005-2006	Jiri Benc <jbenc@suse.cz>
+ * Copyright 2006	Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is GPLv2 as found in COPYING.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <net/cfg80211.h>
+#include "core.h"
+
+static inline struct cfg80211_registered_device *cdev_to_dev(
+	struct class_device *cdev)
+{
+	return container_of(cdev, struct cfg80211_registered_device, wiphy.class_dev);
+}
+
+static ssize_t _show_index(struct class_device *cdev, char *buf)
+{
+	return sprintf(buf, "%d\n", cdev_to_dev(cdev)->idx);
+}
+
+static ssize_t _show_permaddr(struct class_device *cdev, char *buf)
+{
+	char *addr = cdev_to_dev(cdev)->wiphy.perm_addr;
+
+	return sprintf(buf, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+		       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+}
+
+static struct class_device_attribute ieee80211_class_dev_attrs[] = {
+	__ATTR(index, S_IRUGO, _show_index, NULL),
+	__ATTR(macaddress, S_IRUGO, _show_permaddr, NULL),
+
+	{}
+};
+
+static void wiphy_class_dev_release(struct class_device *cdev)
+{
+	struct cfg80211_registered_device *dev = cdev_to_dev(cdev);
+
+	cfg80211_dev_free(dev);
+}
+
+static int wiphy_uevent(struct class_device *cdev, char **envp,
+			int num_envp, char *buf, int size)
+{
+	return 0;
+}
+
+static struct class ieee80211_class = {
+	.name = "ieee80211",
+	.owner = THIS_MODULE,
+	.release = wiphy_class_dev_release,
+	.class_dev_attrs = ieee80211_class_dev_attrs,
+#ifdef CONFIG_HOTPLUG
+	.uevent = wiphy_uevent,
+#endif
+};
+
+int wiphy_sysfs_init(void)
+{
+	return class_register(&ieee80211_class);
+}
+
+void wiphy_sysfs_exit(void)
+{
+	class_unregister(&ieee80211_class);
+}
+
+int wiphy_sysfs_add(struct wiphy *wiphy)
+{
+	wiphy->class_dev.class = &ieee80211_class;
+	wiphy->class_dev.class_data = wiphy;
+	return class_device_add(&wiphy->class_dev);
+}
+
+void wiphy_sysfs_del(struct wiphy *wiphy)
+{
+	class_device_del(&wiphy->class_dev);
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/sysfs.h	2007-02-15 14:29:54.567629166 +0100
@@ -0,0 +1,10 @@
+#ifndef __WIRELESS_SYSFS_H
+#define __WIRELESS_SYSFS_H
+
+extern int wiphy_sysfs_init(void);
+extern void wiphy_sysfs_exit(void);
+
+extern int wiphy_sysfs_add(struct wiphy *wiphy);
+extern void wiphy_sysfs_del(struct wiphy *wiphy);
+
+#endif /* __WIRELESS_SYSFS_H */
--- wireless-dev.orig/net/wireless/Makefile	2007-02-15 14:29:54.477629166 +0100
+++ wireless-dev/net/wireless/Makefile	2007-02-15 14:29:54.577629166 +0100
@@ -1,6 +1,6 @@
 obj-$(CONFIG_CFG80211) += cfg80211.o
 
-cfg80211-y += core.o nl80211.o
+cfg80211-y += core.o sysfs.o nl80211.o
 cfg80211-$(CONFIG_CFG80211_WEXT_COMPAT) += wext-compat.o
 
 ifeq ($(CONFIG_CFG80211),m)
--- wireless-dev.orig/include/net/wireless.h	2007-02-15 14:29:54.437629166 +0100
+++ wireless-dev/include/net/wireless.h	2007-02-15 15:32:22.414331360 +0100
@@ -2,6 +2,130 @@
 #define __NET_WIRELESS_H
 
 /*
+ * 802.11 device management
+ *
+ * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include <linux/netdevice.h>
+#include <linux/debugfs.h>
+#include <net/cfg80211.h>
+
+/**
+ * struct wiphy - wireless hardware description
+ * @idx: the wiphy index assigned to this item
+ * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
+ */
+struct wiphy {
+	/* assign these fields before you register the wiphy */
+
+	/* permanent MAC address */
+	u8 perm_addr[ETH_ALEN];
+
+	/* fields below are read-only, assigned by cfg80211 */
+
+	/* dir in /sys/class/ieee80211/, you need
+	 * to assign its dev pointer */
+	struct class_device class_dev;
+
+	/* dir in debugfs: ieee80211/<wiphyname> */
+	struct dentry *debugfsdir;
+
+	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+/** struct wireless_dev - wireless per-netdev state
+ *
+ * This structure must be allocated by the driver/stack
+ * that uses the ieee80211_ptr field in struct net_device
+ * (this is intentional so it can be allocated along with
+ * the netdev.)
+ *
+ * @wiphy: pointer to hardware description
+ */
+struct wireless_dev {
+	struct wiphy *wiphy;
+};
+
+/**
+ * wiphy_priv - return priv from wiphy
+ */
+static inline void *wiphy_priv(struct wiphy *wiphy)
+{
+	BUG_ON(!wiphy);
+	return &wiphy->priv;
+}
+
+/**
+ * set_wiphy_dev - set device pointer for wiphy
+ */
+static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)
+{
+	wiphy->class_dev.dev = dev;
+}
+
+/**
+ * wiphy_dev - get wiphy dev pointer
+ */
+static inline struct device *wiphy_dev(struct wiphy *wiphy)
+{
+	return wiphy->class_dev.dev;
+}
+
+/**
+ * wiphy_name - get wiphy name
+ */
+static inline char *wiphy_name(struct wiphy *wiphy)
+{
+	return wiphy->class_dev.class_id;
+}
+
+/**
+ * wdev_priv - return wiphy priv from wireless_dev
+ */
+static inline void *wdev_priv(struct wireless_dev *wdev)
+{
+	BUG_ON(!wdev);
+	return wiphy_priv(wdev->wiphy);
+}
+
+/**
+ * wiphy_new - create a new wiphy for use with cfg80211
+ *
+ * create a new wiphy and associate the given operations with it.
+ * @sizeof_priv bytes are allocated for private use.
+ *
+ * the returned pointer must be assigned to each netdev's
+ * ieee80211_ptr for proper operation.
+ */
+struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv);
+
+/**
+ * wiphy_register - register a wiphy with cfg80211
+ *
+ * register the given wiphy
+ *
+ * Returns a non-negative wiphy index or a negative error code.
+ */
+extern int wiphy_register(struct wiphy *wiphy);
+
+/**
+ * wiphy_unregister - deregister a wiphy from cfg80211
+ *
+ * unregister a device with the given priv pointer.
+ * After this call, no more requests can be made with this priv
+ * pointer, but the call may sleep to wait for an outstanding
+ * request that is being handled.
+ */
+extern void wiphy_unregister(struct wiphy *wiphy);
+
+/**
+ * wiphy_free - free wiphy
+ */
+extern void wiphy_free(struct wiphy *wiphy);
+
+
+/*
  * internal definitions for wireless
  */
 
--- wireless-dev.orig/net/wireless/wext-compat.c	2007-02-15 14:29:54.427629166 +0100
+++ wireless-dev/net/wireless/wext-compat.c	2007-02-15 15:32:22.654331360 +0100
@@ -68,7 +68,7 @@ static void cfg80211_wx_start_commit_tim
 }
 
 static struct cfg80211_config *cfg80211_ensure_pending_cfg(
-	struct cfg80211_registered_driver *drv)
+	struct cfg80211_registered_device *drv)
 {
 	struct cfg80211_config *cfg = drv->wext_pending_config;
 	if (!cfg)
@@ -80,7 +80,7 @@ static struct cfg80211_config *cfg80211_
 	return cfg;
 }
 
-static int cfg80211_wx_set_commit(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_commit(struct cfg80211_registered_device *drv,
 				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
@@ -103,7 +103,7 @@ static int cfg80211_wx_set_commit(struct
 	return err;
 }
 
-static int cfg80211_wx_get_name(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_name(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -114,7 +114,7 @@ static int cfg80211_wx_get_name(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_nwid(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_nwid(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -125,7 +125,7 @@ static int cfg80211_wx_set_nwid(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_nwid(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_nwid(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -136,7 +136,7 @@ static int cfg80211_wx_get_nwid(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_freq(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_freq(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -147,7 +147,7 @@ static int cfg80211_wx_set_freq(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_freq(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_freq(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -158,7 +158,7 @@ static int cfg80211_wx_get_freq(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_mode(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_mode(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -169,7 +169,7 @@ static int cfg80211_wx_set_mode(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_mode(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_mode(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -180,7 +180,7 @@ static int cfg80211_wx_get_mode(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_sens(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_sens(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -191,7 +191,7 @@ static int cfg80211_wx_set_sens(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_sens(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_sens(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -202,7 +202,7 @@ static int cfg80211_wx_get_sens(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_range(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_range(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -213,7 +213,7 @@ static int cfg80211_wx_set_range(struct 
 	return err;
 }
 
-static int cfg80211_wx_get_range(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_range(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -224,7 +224,7 @@ static int cfg80211_wx_get_range(struct 
 	return err;
 }
 
-static int cfg80211_wx_set_ap(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_ap(struct cfg80211_registered_device *drv,
 			      struct net_device *net_dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *data,
@@ -242,7 +242,7 @@ static int cfg80211_wx_set_ap(struct cfg
 	return err;
 }
 
-static int cfg80211_wx_get_ap(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_ap(struct cfg80211_registered_device *drv,
 			      struct net_device *net_dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *data,
@@ -258,7 +258,7 @@ static int cfg80211_wx_get_ap(struct cfg
 	return err;
 }
 
-static int cfg80211_wx_set_mlme(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_mlme(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -269,7 +269,7 @@ static int cfg80211_wx_set_mlme(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_waplist(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_waplist(struct cfg80211_registered_device *drv,
 				   struct net_device *net_dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *data,
@@ -280,7 +280,7 @@ static int cfg80211_wx_get_waplist(struc
 	return err;
 }
 
-static int cfg80211_wx_set_scan(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_scan(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -291,7 +291,7 @@ static int cfg80211_wx_set_scan(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_scan(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_scan(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -302,7 +302,7 @@ static int cfg80211_wx_get_scan(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_essid(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_essid(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -333,7 +333,7 @@ static int cfg80211_wx_set_essid(struct 
 	return err;
 }
 
-static int cfg80211_wx_get_essid(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_essid(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -344,7 +344,7 @@ static int cfg80211_wx_get_essid(struct 
 	return err;
 }
 
-static int cfg80211_wx_set_rate(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_rate(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -355,7 +355,7 @@ static int cfg80211_wx_set_rate(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_rate(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_rate(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -366,7 +366,7 @@ static int cfg80211_wx_get_rate(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_rts(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_rts(struct cfg80211_registered_device *drv,
 			       struct net_device *net_dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *data,
@@ -377,7 +377,7 @@ static int cfg80211_wx_set_rts(struct cf
 	return err;
 }
 
-static int cfg80211_wx_get_rts(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_rts(struct cfg80211_registered_device *drv,
 			       struct net_device *net_dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *data,
@@ -388,7 +388,7 @@ static int cfg80211_wx_get_rts(struct cf
 	return err;
 }
 
-static int cfg80211_wx_set_frag(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_frag(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -399,7 +399,7 @@ static int cfg80211_wx_set_frag(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_frag(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_frag(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -410,7 +410,7 @@ static int cfg80211_wx_get_frag(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_txpow(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_txpow(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -421,7 +421,7 @@ static int cfg80211_wx_set_txpow(struct 
 	return err;
 }
 
-static int cfg80211_wx_get_txpow(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_txpow(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -432,7 +432,7 @@ static int cfg80211_wx_get_txpow(struct 
 	return err;
 }
 
-static int cfg80211_wx_set_retry(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_retry(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -443,7 +443,7 @@ static int cfg80211_wx_set_retry(struct 
 	return err;
 }
 
-static int cfg80211_wx_get_retry(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_retry(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -454,7 +454,7 @@ static int cfg80211_wx_get_retry(struct 
 	return err;
 }
 
-static int cfg80211_wx_set_encode(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_encode(struct cfg80211_registered_device *drv,
 				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
@@ -465,7 +465,7 @@ static int cfg80211_wx_set_encode(struct
 	return err;
 }
 
-static int cfg80211_wx_get_encode(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_encode(struct cfg80211_registered_device *drv,
 				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
@@ -476,7 +476,7 @@ static int cfg80211_wx_get_encode(struct
 	return err;
 }
 
-static int cfg80211_wx_set_power(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_power(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -487,7 +487,7 @@ static int cfg80211_wx_set_power(struct 
 	return err;
 }
 
-static int cfg80211_wx_get_power(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_power(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -498,7 +498,7 @@ static int cfg80211_wx_get_power(struct 
 	return err;
 }
 
-static int cfg80211_wx_set_genie(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_genie(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -509,7 +509,7 @@ static int cfg80211_wx_set_genie(struct 
 	return err;
 }
 
-static int cfg80211_wx_get_genie(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_genie(struct cfg80211_registered_device *drv,
 				 struct net_device *net_dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *data,
@@ -520,7 +520,7 @@ static int cfg80211_wx_get_genie(struct 
 	return err;
 }
 
-static int cfg80211_wx_set_auth(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_auth(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -531,7 +531,7 @@ static int cfg80211_wx_set_auth(struct c
 	return err;
 }
 
-static int cfg80211_wx_get_auth(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_auth(struct cfg80211_registered_device *drv,
 				struct net_device *net_dev,
 				struct iw_request_info *info,
 				union iwreq_data *data,
@@ -542,7 +542,7 @@ static int cfg80211_wx_get_auth(struct c
 	return err;
 }
 
-static int cfg80211_wx_set_encodeext(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_encodeext(struct cfg80211_registered_device *drv,
 				     struct net_device *net_dev,
 				     struct iw_request_info *info,
 				     union iwreq_data *data,
@@ -553,7 +553,7 @@ static int cfg80211_wx_set_encodeext(str
 	return err;
 }
 
-static int cfg80211_wx_get_encodeext(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_get_encodeext(struct cfg80211_registered_device *drv,
 				     struct net_device *net_dev,
 				     struct iw_request_info *info,
 				     union iwreq_data *data,
@@ -564,7 +564,7 @@ static int cfg80211_wx_get_encodeext(str
 	return err;
 }
 
-static int cfg80211_wx_set_wpmksa(struct cfg80211_registered_driver *drv,
+static int cfg80211_wx_set_wpmksa(struct cfg80211_registered_device *drv,
 				  struct net_device *net_dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *data,
@@ -576,7 +576,7 @@ static int cfg80211_wx_set_wpmksa(struct
 }
 
 
-typedef int (*iw_compat_handler)(struct cfg80211_registered_driver *drv,
+typedef int (*iw_compat_handler)(struct cfg80211_registered_device *drv,
 				 struct net_device *dev,
 				 struct iw_request_info *info,
 				 union iwreq_data *wrqu,
@@ -644,7 +644,7 @@ static iw_compat_handler get_handler(uns
  * this is sort of backwards and wouldn't need to call
  * get_wireless_stats, but it was easier to just copy the code...
  */
-static int iw_handler_get_iwstats(struct cfg80211_registered_driver *drv,
+static int iw_handler_get_iwstats(struct cfg80211_registered_device *drv,
 				  struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu,
@@ -674,7 +674,7 @@ static int iw_handler_get_iwstats(struct
  * We do various checks and also take care of moving data between
  * user space and kernel space.
  */
-static int ioctl_standard_call(struct cfg80211_registered_driver *drv,
+static int ioctl_standard_call(struct cfg80211_registered_device *drv,
 			       struct net_device *dev,
 			       struct ifreq *ifr,
 			       unsigned int cmd,
@@ -809,7 +809,7 @@ int cfg80211_wext_ioctl(struct ifreq *if
 {
 	struct net_device *dev;
 	iw_compat_handler handler;
-	struct cfg80211_registered_driver *drv;
+	struct cfg80211_registered_device *drv;
 	int err;
 
 	/* Permissions are already checked in dev_ioctl() before calling us.
@@ -819,7 +819,7 @@ int cfg80211_wext_ioctl(struct ifreq *if
 	if (!dev)
 		return -ENODEV;
 
-	drv = cfg80211_get_drv_from_ifindex(dev->ifindex);
+	drv = cfg80211_get_dev_from_ifindex(dev->ifindex);
 	if (IS_ERR(drv)) {
 		err = PTR_ERR(drv);
 		goto out_put_dev;
@@ -846,7 +846,7 @@ int cfg80211_wext_ioctl(struct ifreq *if
 				err = -EOPNOTSUPP;
 	}
 
-	cfg80211_put_drv(drv);
+	cfg80211_put_dev(drv);
  out_put_dev:
 	dev_put(dev);
 	return err;

--


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

* [PATCH 04/10] cfg/nl80211: make association explicit
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (2 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 03/10] introduce wiphy concept Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 14:42 ` [PATCH 05/10] wext: clean up Johannes Berg
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This patch makes association explicit.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 include/linux/nl80211.h |    3 +++
 include/net/cfg80211.h  |    7 ++++++-
 net/wireless/nl80211.c  |   10 ++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)

--- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 13:41:33.057940064 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-15 13:48:54.087940064 +0100
@@ -78,13 +78,17 @@ struct wiphy;
  *
  * @configure: configure the given interface as requested in the config struct.
  *	       must not ignore any configuration item, if something is
- *	       is requested that cannot be fulfilled return an error
+ *	       is requested that cannot be fulfilled return an error.
+ *             This call does not actually initiate any association or such.
  *
  * @get_config: fill the given config structure with the current configuration
  *
  * @get_config_valid: return a bitmask of CFG80211_CFG_VALID_* indicating
  *		      which parameters can be set.
  *
+ * @associate: associate with previously given settings (SSID, BSSID
+ *             if userspace roaming is enabled)
+ *
  * @reassociate: reassociate with current settings (SSID, BSSID if
  *		 userspace roaming is enabled)
  *
@@ -135,6 +139,7 @@ struct cfg80211_ops {
 				    struct net_device *dev);
 
 
+	int	(*associate)(struct wiphy *wiphy, struct net_device *dev);
 	int	(*reassociate)(struct wiphy *wiphy, struct net_device *dev);
 	int	(*disassociate)(struct wiphy *wiphy, struct net_device *dev);
 	int	(*deauth)(struct wiphy *wiphy, struct net_device *dev);
--- wireless-dev.orig/include/linux/nl80211.h	2007-02-15 13:41:26.287940064 +0100
+++ wireless-dev/include/linux/nl80211.h	2007-02-15 13:48:53.357940064 +0100
@@ -98,6 +98,9 @@ enum {
 	/* deauth from current AP */
 	NL80211_CMD_DEAUTH,
 
+	/* associate with current settings */
+	NL80211_CMD_ASSOCIATE,
+
 	/* re-associate with current settings
 	 * (SSID and BSSID if roaming control in userspace) */
 	NL80211_CMD_REASSOCIATE,
--- wireless-dev.orig/net/wireless/nl80211.c	2007-02-15 13:41:33.067940064 +0100
+++ wireless-dev/net/wireless/nl80211.c	2007-02-15 13:49:48.257940064 +0100
@@ -130,6 +130,7 @@ static int nl80211_get_cmdlist(struct sk
 	CHECK_CMD(del_virtual_intf, DEL_VIRTUAL_INTERFACE);
 	CHECK_CMD(configure, CONFIGURE);
 	CHECK_CMD(get_config, GET_CONFIG);
+	CHECK_CMD(associate, ASSOCIATE);
 	CHECK_CMD(reassociate, REASSOCIATE);
 	CHECK_CMD(disassociate, DISASSOCIATE);
 	CHECK_CMD(deauth, DEAUTH);
@@ -699,6 +700,9 @@ static int nl80211_assoc_deauth(struct s
 		return err;
 
 	switch (info->genlhdr->cmd) {
+	case NL80211_CMD_ASSOCIATE:
+		act = drv->ops->associate;
+		break;
 	case NL80211_CMD_DISASSOCIATE:
 		act = drv->ops->disassociate;
 		break;
@@ -964,6 +968,12 @@ static struct genl_ops nl80211_ops[] = {
 		/* can be retrieved by unprivileged users */
 	},
 	{
+		.cmd = NL80211_CMD_ASSOCIATE,
+		.doit = nl80211_assoc_deauth,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
 		.cmd = NL80211_CMD_DISASSOCIATE,
 		.doit = nl80211_assoc_deauth,
 		.policy = nl80211_policy,

--


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

* [PATCH 05/10] wext: clean up
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (3 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 04/10] cfg/nl80211: make association explicit Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 14:42 ` [PATCH 06/10] d80211: update for wiphy api Johannes Berg
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This cleans up wext.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 net/wireless/wext-old.c |  302 ++----------------------------------------------
 1 file changed, 17 insertions(+), 285 deletions(-)

--- wireless-dev.orig/net/wireless/wext-old.c	2007-02-15 12:28:35.657940064 +0100
+++ wireless-dev/net/wireless/wext-old.c	2007-02-15 12:28:38.227940064 +0100
@@ -7,79 +7,6 @@
  * (As all part of the Linux kernel, this file is GPL)
  */
 
-/************************** DOCUMENTATION **************************/
-/*
- * API definition :
- * --------------
- * See <linux/wireless.h> for details of the APIs and the rest.
- *
- * History :
- * -------
- *
- * v1 - 5.12.01 - Jean II
- *	o Created this file.
- *
- * v2 - 13.12.01 - Jean II
- *	o Move /proc/net/wireless stuff from net/core/dev.c to here
- *	o Make Wireless Extension IOCTLs go through here
- *	o Added iw_handler handling ;-)
- *	o Added standard ioctl description
- *	o Initial dumb commit strategy based on orinoco.c
- *
- * v3 - 19.12.01 - Jean II
- *	o Make sure we don't go out of standard_ioctl[] in ioctl_standard_call
- *	o Add event dispatcher function
- *	o Add event description
- *	o Propagate events as rtnetlink IFLA_WIRELESS option
- *	o Generate event on selected SET requests
- *
- * v4 - 18.04.02 - Jean II
- *	o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
- *
- * v5 - 21.06.02 - Jean II
- *	o Add IW_PRIV_TYPE_ADDR in priv_type_size (+cleanup)
- *	o Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
- *	o Add IWEVCUSTOM for driver specific event/scanning token
- *	o Turn on WE_STRICT_WRITE by default + kernel warning
- *	o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num)
- *	o Fix off-by-one in test (extra_size <= IFNAMSIZ)
- *
- * v6 - 9.01.03 - Jean II
- *	o Add common spy support : iw_handler_set_spy(), wireless_spy_update()
- *	o Add enhanced spy support : iw_handler_set_thrspy() and event.
- *	o Add WIRELESS_EXT version display in /proc/net/wireless
- *
- * v6 - 18.06.04 - Jean II
- *	o Change get_spydata() method for added safety
- *	o Remove spy #ifdef, they are always on -> cleaner code
- *	o Allow any size GET request if user specifies length > max
- *		and if request has IW_DESCR_FLAG_NOMAX flag or is SIOCGIWPRIV
- *	o Start migrating get_wireless_stats to struct iw_handler_def
- *	o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus
- * Based on patch from Pavel Roskin <proski@gnu.org> :
- *	o Fix kernel data leak to user space in private handler handling
- *
- * v7 - 18.3.05 - Jean II
- *	o Remove (struct iw_point *)->pointer from events and streams
- *	o Remove spy_offset from struct iw_handler_def
- *	o Start deprecating dev->get_wireless_stats, output a warning
- *	o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless
- *	o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats)
- *
- * v8 - 17.02.06 - Jean II
- *	o RtNetlink requests support (SET/GET)
- *
- * v8b - 03.08.06 - Herbert Xu
- *	o Fix Wireless Event locking issues.
- *
- * v9 - 14.3.06 - Jean II
- *	o Change length in ESSID and NICK to strlen() instead of strlen()+1
- *	o Make standard_ioctl_num and standard_event_num unsigned
- *	o Remove (struct net_device *)->get_wireless_stats()
- */
-
-/***************************** INCLUDES *****************************/
-
 #include <linux/module.h>
 #include <linux/types.h>		/* off_t */
 #include <linux/netdevice.h>		/* struct ifreq, dev_get_by_name() */
@@ -97,19 +24,6 @@
 
 #include "wext.h"
 
-/**************************** CONSTANTS ****************************/
-
-/* Debugging stuff */
-#undef WE_IOCTL_DEBUG		/* Debug IOCTL API */
-#undef WE_RTNETLINK_DEBUG	/* Debug RtNetlink API */
-#undef WE_EVENT_DEBUG		/* Debug Event dispatcher */
-#undef WE_SPY_DEBUG		/* Debug enhanced spy support */
-
-/* Options */
-//CONFIG_NET_WIRELESS_RTNETLINK	/* Wireless requests over RtNetlink */
-#define WE_EVENT_RTNETLINK	/* Propagate events using RtNetlink */
-#define WE_SET_EVENT		/* Generate an event on some set commands */
-
 /************************* GLOBAL VARIABLES *************************/
 
 /* Size (in bytes) of the various private data types */
@@ -312,12 +226,6 @@ static int ioctl_standard_call(struct ne
 		return -EOPNOTSUPP;
 	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
-#ifdef WE_IOCTL_DEBUG
-	printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
-	       ifr->ifr_name, cmd);
-	printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-#endif	/* WE_IOCTL_DEBUG */
-
 	/* Prepare the call */
 	info.cmd = cmd;
 	info.flags = 0;
@@ -328,12 +236,10 @@ static int ioctl_standard_call(struct ne
 		/* No extra arguments. Trivial to handle */
 		ret = handler(dev, &info, &(iwr->u), NULL);
 
-#ifdef WE_SET_EVENT
 		/* Generate an event to notify listeners of the change */
 		if((descr->flags & IW_DESCR_FLAG_EVENT) &&
 		   ((ret == 0) || (ret == -EIWCOMMIT)))
 			wireless_send_event(dev, cmd, &(iwr->u), NULL);
-#endif	/* WE_SET_EVENT */
 	} else {
 		char *	extra;
 		int	extra_size;
@@ -408,11 +314,6 @@ static int ioctl_standard_call(struct ne
 			}
 		}
 
-#ifdef WE_IOCTL_DEBUG
-		printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-		       dev->name, extra_size);
-#endif	/* WE_IOCTL_DEBUG */
-
 		/* Create the kernel buffer */
 		/*    kzalloc ensures NULL-termination for essid_compat */
 		extra = kzalloc(extra_size, GFP_KERNEL);
@@ -429,11 +330,6 @@ static int ioctl_standard_call(struct ne
 				kfree(extra);
 				return -EFAULT;
 			}
-#ifdef WE_IOCTL_DEBUG
-			printk(KERN_DEBUG "%s (WE) : Got %d bytes\n",
-			       dev->name,
-			       iwr->u.data.length * descr->token_size);
-#endif	/* WE_IOCTL_DEBUG */
 		}
 
 		/* Call the handler */
@@ -453,15 +349,9 @@ static int ioctl_standard_call(struct ne
 					   iwr->u.data.length *
 					   descr->token_size);
 			if (err)
-				ret =  -EFAULT;				   
-#ifdef WE_IOCTL_DEBUG
-			printk(KERN_DEBUG "%s (WE) : Wrote %d bytes\n",
-			       dev->name,
-			       iwr->u.data.length * descr->token_size);
-#endif	/* WE_IOCTL_DEBUG */
+				ret =  -EFAULT;
 		}
 
-#ifdef WE_SET_EVENT
 		/* Generate an event to notify listeners of the change */
 		if((descr->flags & IW_DESCR_FLAG_EVENT) &&
 		   ((ret == 0) || (ret == -EIWCOMMIT))) {
@@ -473,7 +363,6 @@ static int ioctl_standard_call(struct ne
 				wireless_send_event(dev, cmd, &(iwr->u),
 						    extra);
 		}
-#endif	/* WE_SET_EVENT */
 
 		/* Cleanup - I told you it wasn't that long ;-) */
 		kfree(extra);
@@ -523,16 +412,6 @@ static inline int ioctl_private_call(str
 			break;
 		}
 
-#ifdef WE_IOCTL_DEBUG
-	printk(KERN_DEBUG "%s (WE) : Found private handler for 0x%04X\n",
-	       ifr->ifr_name, cmd);
-	if(descr) {
-		printk(KERN_DEBUG "%s (WE) : Name %s, set %X, get %X\n",
-		       dev->name, descr->name,
-		       descr->set_args, descr->get_args);
-	}
-#endif	/* WE_IOCTL_DEBUG */
-
 	/* Compute the size of the set/get arguments */
 	if(descr != NULL) {
 		if(IW_IS_SET(cmd)) {
@@ -589,11 +468,6 @@ static inline int ioctl_private_call(str
 				return -EFAULT;
 		}
 
-#ifdef WE_IOCTL_DEBUG
-		printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-		       dev->name, extra_size);
-#endif	/* WE_IOCTL_DEBUG */
-
 		/* Always allocate for max space. Easier, and won't last
 		 * long... */
 		extra = kmalloc(extra_size, GFP_KERNEL);
@@ -609,10 +483,6 @@ static inline int ioctl_private_call(str
 				kfree(extra);
 				return -EFAULT;
 			}
-#ifdef WE_IOCTL_DEBUG
-			printk(KERN_DEBUG "%s (WE) : Got %d elem\n",
-			       dev->name, iwr->u.data.length);
-#endif	/* WE_IOCTL_DEBUG */
 		}
 
 		/* Call the handler */
@@ -631,11 +501,7 @@ static inline int ioctl_private_call(str
 			err = copy_to_user(iwr->u.data.pointer, extra,
 					   extra_size);
 			if (err)
-				ret =  -EFAULT;				   
-#ifdef WE_IOCTL_DEBUG
-			printk(KERN_DEBUG "%s (WE) : Wrote %d elem\n",
-			       dev->name, iwr->u.data.length);
-#endif	/* WE_IOCTL_DEBUG */
+				ret =  -EFAULT;
 		}
 
 		/* Cleanup - I told you it wasn't that long ;-) */
@@ -671,8 +537,7 @@ int wireless_process_ioctl(struct ifreq 
 	/* A bunch of special cases, then the generic case...
 	 * Note that 'cmd' is already filtered in dev_ioctl() with
 	 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
-	switch(cmd) 
-	{
+	switch(cmd) {
 		case SIOCGIWSTATS:
 			/* Get Wireless Stats */
 			return ioctl_standard_call(dev,
@@ -773,22 +638,10 @@ static int rtnetlink_standard_get(struct
 		return -EOPNOTSUPP;
 	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
-#ifdef WE_RTNETLINK_DEBUG
-	printk(KERN_DEBUG "%s (WE.r) : Found standard handler for 0x%04X\n",
-	       dev->name, cmd);
-	printk(KERN_DEBUG "%s (WE.r) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-#endif	/* WE_RTNETLINK_DEBUG */
-
 	/* Check if wrqu is complete */
 	hdr_len = event_type_size[descr->header_type];
-	if(request_len < hdr_len) {
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG
-		       "%s (WE.r) : Wireless request too short (%d)\n",
-		       dev->name, request_len);
-#endif	/* WE_RTNETLINK_DEBUG */
+	if(request_len < hdr_len)
 		return -EINVAL;
-	}
 
 	/* Prepare the call */
 	info.cmd = cmd;
@@ -832,10 +685,6 @@ static int rtnetlink_standard_get(struct
 			extra_size = (wrqu_point.data.length
 				      * descr->token_size);
 		buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
-		       dev->name, extra_size, buffer_size);
-#endif	/* WE_RTNETLINK_DEBUG */
 
 		/* Create the kernel buffer that we will return */
 		buffer = kmalloc(buffer_size, GFP_KERNEL);
@@ -867,10 +716,6 @@ static int rtnetlink_standard_get(struct
 		 * dummy pointer. */
 		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
 
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
-#endif	/* WE_RTNETLINK_DEBUG */
-
 		/* Check if there is enough buffer up there */
 		if(wrqu_point.data.length < wrqu->data.length)
 			ret = -E2BIG;
@@ -915,25 +760,13 @@ static inline int rtnetlink_standard_set
 		return -EOPNOTSUPP;
 	descr = &(wext_standard_ioctl[cmd - SIOCIWFIRST]);
 
-#ifdef WE_RTNETLINK_DEBUG
-	printk(KERN_DEBUG "%s (WE.r) : Found standard SET handler for 0x%04X\n",
-	       dev->name, cmd);
-	printk(KERN_DEBUG "%s (WE.r) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-#endif	/* WE_RTNETLINK_DEBUG */
-
 	/* Extract fixed header from request. This is properly aligned. */
 	wrqu = &request->u;
 
 	/* Check if wrqu is complete */
 	hdr_len = event_type_size[descr->header_type];
-	if(request_len < hdr_len) {
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG
-		       "%s (WE.r) : Wireless request too short (%d)\n",
-		       dev->name, request_len);
-#endif	/* WE_RTNETLINK_DEBUG */
+	if(request_len < hdr_len)
 		return -EINVAL;
-	}
 
 	/* Prepare the call */
 	info.cmd = cmd;
@@ -964,18 +797,8 @@ static inline int rtnetlink_standard_set
 		extra_len = wrqu_point.data.length * descr->token_size;
 
 		/* Check if request is self consistent */
-		if((request_len - hdr_len) < extra_len) {
-#ifdef WE_RTNETLINK_DEBUG
-			printk(KERN_DEBUG "%s (WE.r) : Wireless request data too short (%d)\n",
-			       dev->name, extra_size);
-#endif	/* WE_RTNETLINK_DEBUG */
+		if((request_len - hdr_len) < extra_len)
 			return -EINVAL;
-		}
-
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes\n",
-		       dev->name, extra_size);
-#endif	/* WE_RTNETLINK_DEBUG */
 
 		/* Always allocate for max space. Easier, and won't last
 		 * long... */
@@ -991,7 +814,6 @@ static inline int rtnetlink_standard_set
 		ret = handler(dev, &info, &wrqu_point, extra);
 	}
 
-#ifdef WE_SET_EVENT
 	/* Generate an event to notify listeners of the change */
 	if((descr->flags & IW_DESCR_FLAG_EVENT) &&
 	   ((ret == 0) || (ret == -EIWCOMMIT))) {
@@ -1002,7 +824,6 @@ static inline int rtnetlink_standard_set
 		else
 			wireless_send_event(dev, cmd, wrqu, extra);
 	}
-#endif	/* WE_SET_EVENT */
 
 	/* Cleanup - I told you it wasn't that long ;-) */
 	if(extra)
@@ -1058,13 +879,6 @@ static inline int rtnetlink_private_get(
 	if(descr == NULL)
 		return -EOPNOTSUPP;
 
-#ifdef WE_RTNETLINK_DEBUG
-	printk(KERN_DEBUG "%s (WE.r) : Found private handler for 0x%04X\n",
-	       dev->name, cmd);
-	printk(KERN_DEBUG "%s (WE.r) : Name %s, set %X, get %X\n",
-	       dev->name, descr->name, descr->set_args, descr->get_args);
-#endif	/* WE_RTNETLINK_DEBUG */
-
 	/* Compute the max size of the get arguments */
 	extra_size = get_priv_size(descr->get_args);
 
@@ -1078,14 +892,8 @@ static inline int rtnetlink_private_get(
 	}
 
 	/* Check if wrqu is complete */
-	if(request_len < hdr_len) {
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG
-		       "%s (WE.r) : Wireless request too short (%d)\n",
-		       dev->name, request_len);
-#endif	/* WE_RTNETLINK_DEBUG */
+	if(request_len < hdr_len)
 		return -EINVAL;
-	}
 
 	/* Prepare the call */
 	info.cmd = cmd;
@@ -1116,11 +924,6 @@ static inline int rtnetlink_private_get(
 		/* Buffer for full reply */
 		buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
 
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
-		       dev->name, extra_size, buffer_size);
-#endif	/* WE_RTNETLINK_DEBUG */
-
 		/* Create the kernel buffer that we will return */
 		buffer = kmalloc(buffer_size, GFP_KERNEL);
 		if (buffer == NULL) {
@@ -1152,10 +955,6 @@ static inline int rtnetlink_private_get(
 		/* Put the iwe header where it should, i.e. scrap the
 		 * dummy pointer. */
 		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
-
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
-#endif	/* WE_RTNETLINK_DEBUG */
 	}
 
 	/* Return the buffer to the caller */
@@ -1213,13 +1012,6 @@ static inline int rtnetlink_private_set(
 	if(descr == NULL)
 		return -EOPNOTSUPP;
 
-#ifdef WE_RTNETLINK_DEBUG
-	printk(KERN_DEBUG "%s (WE.r) : Found private handler for 0x%04X\n",
-	       ifr->ifr_name, cmd);
-	printk(KERN_DEBUG "%s (WE.r) : Name %s, set %X, get %X\n",
-	       dev->name, descr->name, descr->set_args, descr->get_args);
-#endif	/* WE_RTNETLINK_DEBUG */
-
 	/* Compute the size of the set arguments */
 	/* Check for sub-ioctl handler */
 	if(descr->name[0] == '\0')
@@ -1242,14 +1034,8 @@ static inline int rtnetlink_private_set(
 	wrqu = &request->u;
 
 	/* Check if wrqu is complete */
-	if(request_len < hdr_len) {
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG
-		       "%s (WE.r) : Wireless request too short (%d)\n",
-		       dev->name, request_len);
-#endif	/* WE_RTNETLINK_DEBUG */
+	if(request_len < hdr_len)
 		return -EINVAL;
-	}
 
 	/* Prepare the call */
 	info.cmd = cmd;
@@ -1277,18 +1063,8 @@ static inline int rtnetlink_private_set(
 		extra_len = adjust_priv_size(descr->set_args, &wrqu_point);
 
 		/* Check if request is self consistent */
-		if((request_len - hdr_len) < extra_len) {
-#ifdef WE_RTNETLINK_DEBUG
-			printk(KERN_DEBUG "%s (WE.r) : Wireless request data too short (%d)\n",
-			       dev->name, extra_size);
-#endif	/* WE_RTNETLINK_DEBUG */
+		if((request_len - hdr_len) < extra_len)
 			return -EINVAL;
-		}
-
-#ifdef WE_RTNETLINK_DEBUG
-		printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes\n",
-		       dev->name, extra_size);
-#endif	/* WE_RTNETLINK_DEBUG */
 
 		/* Always allocate for max space. Easier, and won't last
 		 * long... */
@@ -1329,18 +1105,12 @@ int wireless_rtnetlink_get(struct net_de
 	iw_handler		handler;
 
 	/* Check length */
-	if(len < IW_EV_LCP_LEN) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
-		       dev->name, len);
+	if(len < IW_EV_LCP_LEN)
 		return -EINVAL;
-	}
 
 	/* ReCheck length (len may have padding) */
-	if(request->len > len) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request len invalid (%d-%d)\n",
-		       dev->name, request->len, len);
+	if(request->len > len)
 		return -EINVAL;
-	}
 
 	/* Only accept GET requests in here */
 	if(!IW_IS_GET(request->cmd))
@@ -1413,18 +1183,12 @@ int wireless_rtnetlink_set(struct net_de
 	iw_handler		handler;
 
 	/* Check length */
-	if(len < IW_EV_LCP_LEN) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
-		       dev->name, len);
+	if(len < IW_EV_LCP_LEN)
 		return -EINVAL;
-	}
 
 	/* ReCheck length (len may have padding) */
-	if(request->len > len) {
-		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request len invalid (%d-%d)\n",
-		       dev->name, request->len, len);
+	if(request->len > len)
 		return -EINVAL;
-	}
 
 	/* Only accept SET requests in here */
 	if(!IW_IS_SET(request->cmd))
@@ -1520,19 +1284,6 @@ int iw_handler_set_spy(struct net_device
 		/* Reset stats */
 		memset(spydata->spy_stat, 0,
 		       sizeof(struct iw_quality) * IW_MAX_SPY);
-
-#ifdef WE_SPY_DEBUG
-		printk(KERN_DEBUG "iw_handler_set_spy() :  wireless_data %p, spydata %p, num %d\n", dev->wireless_data, spydata, wrqu->data.length);
-		for (i = 0; i < wrqu->data.length; i++)
-			printk(KERN_DEBUG
-			       "%02X:%02X:%02X:%02X:%02X:%02X \n",
-			       spydata->spy_address[i][0],
-			       spydata->spy_address[i][1],
-			       spydata->spy_address[i][2],
-			       spydata->spy_address[i][3],
-			       spydata->spy_address[i][4],
-			       spydata->spy_address[i][5]);
-#endif	/* WE_SPY_DEBUG */
 	}
 
 	/* Make sure above is updated before re-enabling */
@@ -1543,6 +1294,7 @@ int iw_handler_set_spy(struct net_device
 
 	return 0;
 }
+EXPORT_SYMBOL(iw_handler_set_spy);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1578,6 +1330,7 @@ int iw_handler_get_spy(struct net_device
 		spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED;
 	return 0;
 }
+EXPORT_SYMBOL(iw_handler_get_spy);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1602,12 +1355,9 @@ int iw_handler_set_thrspy(struct net_dev
 	/* Clear flag */
 	memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under));
 
-#ifdef WE_SPY_DEBUG
-	printk(KERN_DEBUG "iw_handler_set_thrspy() :  low %d ; high %d\n", spydata->spy_thr_low.level, spydata->spy_thr_high.level);
-#endif	/* WE_SPY_DEBUG */
-
 	return 0;
 }
+EXPORT_SYMBOL(iw_handler_set_thrspy);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1631,6 +1381,7 @@ int iw_handler_get_thrspy(struct net_dev
 
 	return 0;
 }
+EXPORT_SYMBOL(iw_handler_get_thrspy);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1656,16 +1407,6 @@ static void iw_send_thrspy_event(struct 
 	memcpy(&(threshold.low), &(spydata->spy_thr_low),
 	       2 * sizeof(struct iw_quality));
 
-#ifdef WE_SPY_DEBUG
-	printk(KERN_DEBUG "iw_send_thrspy_event() : address %02X:%02X:%02X:%02X:%02X:%02X, level %d, up = %d\n",
-	       threshold.addr.sa_data[0],
-	       threshold.addr.sa_data[1],
-	       threshold.addr.sa_data[2],
-	       threshold.addr.sa_data[3],
-	       threshold.addr.sa_data[4],
-	       threshold.addr.sa_data[5], threshold.qual.level);
-#endif	/* WE_SPY_DEBUG */
-
 	/* Send event to user space */
 	wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
 }
@@ -1689,10 +1430,6 @@ void wireless_spy_update(struct net_devi
 	if(!spydata)
 		return;
 
-#ifdef WE_SPY_DEBUG
-	printk(KERN_DEBUG "wireless_spy_update() :  wireless_data %p, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_data, spydata, address[0], address[1], address[2], address[3], address[4], address[5]);
-#endif	/* WE_SPY_DEBUG */
-
 	/* Update all records that match */
 	for(i = 0; i < spydata->spy_number; i++)
 		if(!compare_ether_addr(address, spydata->spy_address[i])) {
@@ -1721,9 +1458,4 @@ void wireless_spy_update(struct net_devi
 		}
 	}
 }
-
-EXPORT_SYMBOL(iw_handler_get_spy);
-EXPORT_SYMBOL(iw_handler_get_thrspy);
-EXPORT_SYMBOL(iw_handler_set_spy);
-EXPORT_SYMBOL(iw_handler_set_thrspy);
 EXPORT_SYMBOL(wireless_spy_update);

--


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

* [PATCH 06/10] d80211: update for wiphy api
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (4 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 05/10] wext: clean up Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 16:16   ` Johannes Berg
  2007-02-19 20:49   ` Jiri Benc
  2007-02-15 14:42 ` [PATCH 07/10] bcm43xx-d80211: " Johannes Berg
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This patch lets d80211 use the new wiphy stuff from cfg80211.

Patch is large because cfg80211 requires the net_dev->ieee80211_ptr
now. Net code removal due to cfg80211 handling sysfs for us.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 include/net/d80211.h             |   25 ++++--
 net/d80211/Kconfig               |    1 
 net/d80211/Makefile              |    2 
 net/d80211/ieee80211.c           |  154 +++++++++++++++++--------------------
 net/d80211/ieee80211_cfg.c       |   32 +++++++
 net/d80211/ieee80211_cfg.h       |    9 ++
 net/d80211/ieee80211_dev.c       |  117 ----------------------------
 net/d80211/ieee80211_i.h         |   25 ------
 net/d80211/ieee80211_iface.c     |   29 +++---
 net/d80211/ieee80211_ioctl.c     |  104 ++++++++++++-------------
 net/d80211/ieee80211_led.c       |    4 
 net/d80211/ieee80211_sta.c       |   62 +++++++-------
 net/d80211/ieee80211_sysfs.c     |  162 +++++++++++----------------------------
 net/d80211/ieee80211_sysfs.h     |   12 ++
 net/d80211/ieee80211_sysfs_sta.c |    4 
 net/d80211/rc80211_simple.c      |    4 
 net/d80211/wme.c                 |   26 +++---
 17 files changed, 313 insertions(+), 459 deletions(-)

--- wireless-dev.orig/include/net/d80211.h	2007-02-15 13:28:04.547940064 +0100
+++ wireless-dev/include/net/d80211.h	2007-02-15 13:28:52.417940064 +0100
@@ -16,6 +16,8 @@
 #include <linux/wireless.h>
 #include <linux/device.h>
 #include <linux/ieee80211.h>
+#include <net/wireless.h>
+#include <net/cfg80211.h>
 
 /* Note! Only ieee80211_tx_status_irqsafe() and ieee80211_rx_irqsafe() can be
  * called in hardware interrupt context. The low-level driver must not call any
@@ -457,8 +459,12 @@ typedef enum {
 
 /* This is driver-visible part of the per-hw state the stack keeps. */
 struct ieee80211_hw {
-	/* these are assigned by d80211, don't write */
-	int index;
+	/* points to the cfg80211 wiphy for this piece. Note
+	 * that you must fill in the perm_addr and dev fields
+	 * of this structure, use the macros provided below. */
+	struct wiphy *wiphy;
+
+	/* assigned by d80211, don't write */
 	struct ieee80211_conf conf;
 
 	/* Pointer to the private area that was
@@ -467,11 +473,6 @@ struct ieee80211_hw {
 
 	/* The rest is information about your hardware */
 
-	struct device *dev;
-
-	/* permanent mac address */
-	u8 perm_addr[ETH_ALEN];
-
 	/* TODO: frame_type 802.11/802.3, sw_encryption requirements */
 
 	/* Some wireless LAN chipsets generate beacons in the hardware/firmware
@@ -550,6 +551,16 @@ struct ieee80211_hw {
 	int queues;
 };
 
+static inline void SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev)
+{
+	set_wiphy_dev(hw->wiphy, dev);
+}
+
+static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
+{
+	memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN);
+}
+
 /* Configuration block used by the low-level driver to tell the 802.11 code
  * about supported hardware features and to pass function pointers to callback
  * functions. */
--- wireless-dev.orig/net/d80211/ieee80211.c	2007-02-15 13:28:04.577940064 +0100
+++ wireless-dev/net/d80211/ieee80211.c	2007-02-15 13:29:07.637940064 +0100
@@ -21,6 +21,7 @@
 #include <net/iw_handler.h>
 #include <linux/compiler.h>
 #include <linux/bitmap.h>
+#include <net/cfg80211.h>
 
 #include "ieee80211_common.h"
 #include "ieee80211_i.h"
@@ -31,6 +32,8 @@
 #include "wme.h"
 #include "aes_ccm.h"
 #include "ieee80211_led.h"
+#include "ieee80211_cfg.h"
+#include "ieee80211_sysfs.h"
 
 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
@@ -209,7 +212,7 @@ static void ieee80211_key_threshold_noti
 					   struct ieee80211_key *key,
 					   struct sta_info *sta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_msg_key_notification *msg;
 
@@ -1047,7 +1050,7 @@ __ieee80211_tx_prepare(struct ieee80211_
 		       struct net_device *dev,
 		       struct ieee80211_tx_control *control)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	int hdrlen;
 
@@ -1187,7 +1190,7 @@ static int __ieee80211_tx(struct ieee802
 static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 			struct ieee80211_tx_control *control, int mgmt)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	ieee80211_tx_handler *handler;
 	struct ieee80211_txrx_data tx;
@@ -1423,7 +1426,7 @@ static int ieee80211_master_start_xmit(s
 static int ieee80211_subif_start_xmit(struct sk_buff *skb,
 				      struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_packet_data *pkt_data;
         struct ieee80211_sub_if_data *sdata;
 	int ret = 1, head_need;
@@ -1956,7 +1959,7 @@ static int __ieee80211_if_config(struct 
 				 struct ieee80211_tx_control *control)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_if_conf conf;
 
 	if (!local->ops->config_interface || !netif_running(dev))
@@ -1990,7 +1993,7 @@ int ieee80211_if_config(struct net_devic
 
 int ieee80211_if_config_beacon(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_control control;
 	struct sk_buff *skb;
 
@@ -2069,7 +2072,7 @@ static int ieee80211_change_mtu_apdev(st
 
 static void ieee80211_tx_timeout(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	printk(KERN_WARNING "%s: resetting interface.\n", dev->name);
 
@@ -2093,7 +2096,7 @@ static int ieee80211_set_mac_address(str
 
 static void ieee80211_set_multicast_list(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	unsigned short flags;
 
@@ -2171,7 +2174,7 @@ static struct net_device_stats *ieee8021
 
 void ieee80211_if_shutdown(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	ASSERT_RTNL();
@@ -2212,7 +2215,7 @@ static inline int identical_mac_addr_all
 
 static int ieee80211_master_open(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	int res = -EOPNOTSUPP;
 
@@ -2228,7 +2231,7 @@ static int ieee80211_master_open(struct 
 
 static int ieee80211_master_stop(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 
 	tasklet_disable(&local->tx_pending_tasklet);
@@ -2241,7 +2244,7 @@ static int ieee80211_master_stop(struct 
 
 static int ieee80211_mgmt_open(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (!netif_running(local->mdev))
 		return -EOPNOTSUPP;
@@ -2288,7 +2291,7 @@ static void ieee80211_start_hard_monitor
 static int ieee80211_open(struct net_device *dev)
 {
 	struct ieee80211_sub_if_data *sdata, *nsdata;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_if_init_conf conf;
 	int res;
 
@@ -2368,7 +2371,7 @@ static int ieee80211_open(struct net_dev
 static int ieee80211_stop(struct net_device *dev)
 {
 	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -2729,7 +2732,7 @@ void
 ieee80211_rx_monitor(struct net_device *dev, struct sk_buff *skb,
 		     struct ieee80211_rx_status *status)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_frame_info *fi;
 	struct ieee80211_sub_if_data *sdata;
 	const size_t hlen = sizeof(struct ieee80211_frame_info)
@@ -2836,7 +2839,7 @@ static void ap_sta_ps_start(struct net_d
 
 static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	int sent = 0;
 	struct ieee80211_sub_if_data *sdata;
@@ -4385,7 +4388,7 @@ static ieee80211_tx_handler ieee80211_tx
 
 int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct sta_info *sta;
 
@@ -4457,7 +4460,7 @@ int ieee80211_init_rate_ctrl_alg(struct 
 		       "algorithm\n", local->mdev->name);
 		return -ENOENT;
 	}
-	res = rate_control_add_attrs(ref, &local->class_dev.kobj);
+	res = rate_control_add_attrs(ref, &local->hw.wiphy->class_dev.kobj);
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: Failed to register sysfs attributes "
 		       "for rate control\n", local->mdev->name);
@@ -4468,7 +4471,7 @@ int ieee80211_init_rate_ctrl_alg(struct 
 	old = local->rate_ctrl;
 	local->rate_ctrl = ref;
 	if (old) {
-		rate_control_remove_attrs(ref, &local->class_dev.kobj);
+		rate_control_remove_attrs(ref, &local->hw.wiphy->class_dev.kobj);
 		rate_control_put(old);
 		sta_info_flush(local, NULL);
 	}
@@ -4487,7 +4490,7 @@ static void rate_control_deinitialize(st
 
 	ref = local->rate_ctrl;
 	local->rate_ctrl = NULL;
-	rate_control_remove_attrs(ref, &local->class_dev.kobj);
+	rate_control_remove_attrs(ref, &local->hw.wiphy->class_dev.kobj);
 	rate_control_put(ref);
 }
 
@@ -4498,37 +4501,53 @@ struct ieee80211_hw *ieee80211_alloc_hw(
         struct ieee80211_local *local;
         struct ieee80211_sub_if_data *sdata;
 	int priv_size;
-
-	local = ieee80211_dev_alloc(GFP_KERNEL);
-	if (!local)
-		return NULL;
-
-	local->ops = ops;
+	struct wiphy *wiphy;
 
 	/* Ensure 32-byte alignment of our private data and hw private data.
-	 * Each net_device is followed by a sub_if_data which is used for
-	 * interface specific information.
+	 * We use the wiphy priv data for both our ieee80211_local and for
+	 * the driver's private data
+	 *
+	 * In memory it'll be like this:
 	 *
-         * Sample memory map looks something like:
-         *
-         * 0000 *****************
-         *      * net_dev       *
-	 * 0160 *****************
-         *      * sub_if        *
-	 * 0b80 *****************
-         *      * hw_priv       *
-         * 1664 *****************
-         */
-	priv_size = ((sizeof(struct ieee80211_sub_if_data) +
+	 * +-------------------------+
+	 * | struct wiphy            |
+	 * +-------------------------+
+	 * | struct ieee80211_local  |
+	 * +-------------------------+
+	 * | driver's private data   |
+	 * +-------------------------+
+	 *
+	 */
+	priv_size = ((sizeof(struct ieee80211_local) +
 		      NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
 		    priv_data_len;
-	mdev = alloc_netdev(priv_size, "wmaster%d", ether_setup);
+
+	wiphy = wiphy_new(&d80211_config_ops, priv_size);
+
+	if (!wiphy)
+		return NULL;
+
+	local = wiphy_priv(wiphy);
+	local->hw.wiphy = wiphy;
+
+	local->hw.priv = (char *)local +
+			 ((sizeof(struct ieee80211_local) +
+			   NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
+
+	local->ops = ops;
+
+	/* for now, mdev needs sub_if_data :/ */
+	mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data),
+			    "wmaster%d", ether_setup);
 	if (!mdev) {
-		ieee80211_dev_free(local);
+		wiphy_free(wiphy);
 		return NULL;
 	}
 
-	mdev->ieee80211_ptr = local;
+	sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
+	mdev->ieee80211_ptr = &sdata->wdev;
+	sdata->wdev.wiphy = wiphy;
+
 	local->hw.priv = (char *)mdev->priv +
 			 ((sizeof(struct ieee80211_sub_if_data) +
 			   NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
@@ -4579,7 +4598,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 	mdev->type = ARPHRD_IEEE80211;
         mdev->hard_header_parse = header_parse_80211;
 
-	sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
 	sdata->type = IEEE80211_IF_TYPE_AP;
         sdata->dev = mdev;
         sdata->local = local;
@@ -4608,11 +4626,9 @@ int ieee80211_register_hw(struct ieee802
 	struct net_device *sta_dev;
 	int result;
 
-	result = ieee80211_dev_alloc_index(local);
+	result = wiphy_register(local->hw.wiphy);
 	if (result < 0)
-		return -1;
-
-	local->class_dev.dev = local->hw.dev;
+		return result;
 
 	result = ieee80211_dev_sysfs_add(local);
 	if (result < 0)
@@ -4633,21 +4649,14 @@ int ieee80211_register_hw(struct ieee802
 		goto fail_dev;
 	}
 
-	memcpy(local->mdev->dev_addr, local->hw.perm_addr, ETH_ALEN);
-	SET_NETDEV_DEV(local->mdev, local->hw.dev);
+	memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
+	SET_NETDEV_DEV(local->mdev, wiphy_dev(local->hw.wiphy));
 
 	result = register_netdevice(local->mdev);
 	if (result < 0) {
 		rtnl_unlock();
 		goto fail_dev;
 	}
-	result = sysfs_create_link(&local->class_dev.kobj,
-				   &local->mdev->class_dev.kobj,
-				   "master");
-	if (result < 0) {
-		rtnl_unlock();
-		goto fail_masterlink;
-	}
 	result = ieee80211_sysfs_add_netdevice(local->mdev);
 	if (result < 0) {
 		rtnl_unlock();
@@ -4691,15 +4700,13 @@ fail_wep:
 fail_rate:
 	ieee80211_sysfs_remove_netdevice(local->mdev);
 fail_if_sysfs:
-	sysfs_remove_link(&local->class_dev.kobj, "master");
-fail_masterlink:
 	unregister_netdev(local->mdev);
 fail_dev:
 	sta_info_stop(local);
 fail_sta_info:
 	ieee80211_dev_sysfs_del(local);
 fail_sysfs:
-	ieee80211_dev_free_index(local);
+	wiphy_unregister(local->hw.wiphy);
 	return result;
 }
 EXPORT_SYMBOL(ieee80211_register_hw);
@@ -4751,8 +4758,6 @@ void ieee80211_unregister_hw(struct ieee
 	if (local->apdev)
 		ieee80211_if_del_mgmt(local);
 
-	sysfs_remove_link(&local->class_dev.kobj, "master");
-
 	list_for_each_entry_safe(sdata, tmp, &local->sub_if_list, list)
 		__ieee80211_if_del(local, sdata);
 
@@ -4788,7 +4793,7 @@ void ieee80211_unregister_hw(struct ieee
 	skb_queue_purge(&local->skb_queue);
 	skb_queue_purge(&local->skb_queue_unreliable);
 
-	ieee80211_dev_free_index(local);
+	wiphy_unregister(local->hw.wiphy);
 	ieee80211_wep_free(local);
 	ieee80211_led_exit(local);
 }
@@ -4799,15 +4804,10 @@ void ieee80211_free_hw(struct ieee80211_
 	struct ieee80211_local *local = hw_to_local(hw);
 
 	ieee80211_if_free(local->mdev);
-	ieee80211_dev_free(local);
+	wiphy_free(local->hw.wiphy);
 }
 EXPORT_SYMBOL(ieee80211_free_hw);
 
-void ieee80211_release_hw(struct ieee80211_local *local)
-{
-	kfree(local);
-}
-
 /* Perform netif operations on all configured interfaces */
 int ieee80211_netif_oper(struct ieee80211_hw *hw, Netif_Oper op)
 {
@@ -4905,22 +4905,13 @@ static int __init ieee80211_init(void)
 
 	BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
 
-	if ((ret = ieee80211_sysfs_init())) {
-		printk(KERN_WARNING "ieee80211_init: sysfs initialization "
-		       "failed\n");
+	ret = ieee80211_wme_register();
+	if (ret) {
+		printk(KERN_DEBUG "ieee80211_init: failed to "
+		       "initialize WME (err=%d)\n", ret);
 		return ret;
 	}
 
-	{
-		ret = ieee80211_wme_register();
-		if (ret) {
-			printk(KERN_DEBUG "ieee80211_init: failed to "
-			       "initialize WME (err=%d)\n", ret);
-			ieee80211_sysfs_deinit();
-			return ret;
-		}
-	}
-
 	return 0;
 }
 
@@ -4928,7 +4919,6 @@ static int __init ieee80211_init(void)
 static void __exit ieee80211_exit(void)
 {
 	ieee80211_wme_unregister();
-	ieee80211_sysfs_deinit();
 }
 
 
--- wireless-dev.orig/net/d80211/Makefile	2007-02-15 13:28:04.637940064 +0100
+++ wireless-dev/net/d80211/Makefile	2007-02-15 13:28:52.417940064 +0100
@@ -10,7 +10,6 @@ obj-$(CONFIG_D80211) += 80211.o rc80211_
 	wpa.o \
 	ieee80211_scan.o \
 	ieee80211_sta.o \
-	ieee80211_dev.o \
 	ieee80211_iface.o \
 	ieee80211_rate.o \
 	ieee80211_sysfs.o \
@@ -19,6 +18,7 @@ obj-$(CONFIG_D80211) += 80211.o rc80211_
 	tkip.o \
 	aes_ccm.o \
 	wme.o \
+	ieee80211_cfg.o \
 	$(80211-objs-y)
 
 ifeq ($(CONFIG_NET_SCHED),)
--- wireless-dev.orig/net/d80211/ieee80211_dev.c	2007-02-15 13:28:04.697940064 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/netdevice.h>
-#include <net/d80211.h>
-#include "ieee80211_i.h"
-#include "ieee80211_led.h"
-
-struct ieee80211_dev_list {
-	struct list_head list;
-	int dev_index;
-	struct ieee80211_local *local;
-};
-
-static LIST_HEAD(dev_list);
-static DEFINE_SPINLOCK(dev_list_lock);
-
-
-/* Caller must hold dev_list_lock */
-static struct ieee80211_dev_list *__ieee80211_dev_find(int index)
-{
-	struct ieee80211_dev_list *dev_item;
-
-	list_for_each_entry(dev_item, &dev_list, list) {
-		if (dev_item->dev_index == index)
-			return dev_item;
-	}
-	return NULL;
-}
-
-int ieee80211_dev_alloc_index(struct ieee80211_local *local)
-{
-	struct ieee80211_dev_list *dev_item, *new;
-	int index = 0;
-
-	new = kmalloc(sizeof(struct ieee80211_dev_list), GFP_KERNEL);
-	if (!new)
-		return -ENOMEM;
-	new->local = local;
-	spin_lock(&dev_list_lock);
-	list_for_each_entry(dev_item, &dev_list, list) {
-		if (index < dev_item->dev_index)
-			break;
-		index++;
-	}
-	new->dev_index = index;
-	list_add_tail(&new->list, &dev_item->list);
-	spin_unlock(&dev_list_lock);
-	local->hw.index = index;
-	return index;
-}
-
-void ieee80211_dev_free_index(struct ieee80211_local *local)
-{
-	struct ieee80211_dev_list *dev_item;
-
-	spin_lock(&dev_list_lock);
-	dev_item = __ieee80211_dev_find(local->hw.index);
-	if (dev_item)
-		list_del(&dev_item->list);
-	spin_unlock(&dev_list_lock);
-	if (dev_item)
-		kfree(dev_item);
-	local->hw.index = -1;
-}
-
-struct ieee80211_local *ieee80211_dev_find(int index)
-{
-	struct ieee80211_dev_list *dev_item;
-
-	spin_lock(&dev_list_lock);
-	dev_item = __ieee80211_dev_find(index);
-	spin_unlock(&dev_list_lock);
-	return dev_item ? dev_item->local : NULL;
-}
-
-int ieee80211_dev_find_index(struct ieee80211_local *local)
-{
-	struct ieee80211_dev_list *dev_item;
-	int index = -1;
-
-	spin_lock(&dev_list_lock);
-	list_for_each_entry(dev_item, &dev_list, list) {
-		if (dev_item->local == local) {
-			index = dev_item->dev_index;
-			break;
-		}
-	}
-	spin_unlock(&dev_list_lock);
-	return index;
-}
-
-struct ieee80211_local *ieee80211_dev_alloc(gfp_t flags)
-{
-	struct ieee80211_local *local;
-
-	local = kzalloc(sizeof(struct ieee80211_local), flags);
-	if (!local)
-		return NULL;
-	local->hw.index = -1;
-	ieee80211_dev_sysfs_init(local);
-	return local;
-}
-
-void ieee80211_dev_free(struct ieee80211_local *local)
-{
-	ieee80211_dev_sysfs_put(local);
-}
--- wireless-dev.orig/net/d80211/ieee80211_iface.c	2007-02-15 13:28:04.757940064 +0100
+++ wireless-dev/net/d80211/ieee80211_iface.c	2007-02-15 13:30:23.967940064 +0100
@@ -14,6 +14,7 @@
 #include <net/d80211.h>
 #include "ieee80211_i.h"
 #include "sta_info.h"
+#include "ieee80211_sysfs.h"
 
 void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
 {
@@ -40,7 +41,7 @@ int ieee80211_if_add(struct net_device *
 		     int format, struct net_device **new_dev)
 {
 	struct net_device *ndev, *tmp_dev;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = NULL;
 	int ret;
 	int i;
@@ -51,7 +52,6 @@ int ieee80211_if_add(struct net_device *
 	if (!ndev)
 		return -ENOMEM;
 
-	ndev->ieee80211_ptr = local;
 	if (strlen(name) == 0) {
 		i = 0;
 		do {
@@ -70,14 +70,16 @@ int ieee80211_if_add(struct net_device *
 		snprintf(ndev->name, IFNAMSIZ, "%s", name);
 	}
 
-	memcpy(ndev->dev_addr, local->hw.perm_addr, ETH_ALEN);
+	memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
 	ndev->base_addr = dev->base_addr;
 	ndev->irq = dev->irq;
 	ndev->mem_start = dev->mem_start;
 	ndev->mem_end = dev->mem_end;
-	SET_NETDEV_DEV(ndev, local->hw.dev);
+	SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+	ndev->ieee80211_ptr = &sdata->wdev;
+	sdata->wdev.wiphy = local->hw.wiphy;
 	sdata->type = IEEE80211_IF_TYPE_AP;
 	sdata->dev = ndev;
 	sdata->local = local;
@@ -121,11 +123,12 @@ int ieee80211_if_add_mgmt(struct ieee802
 	if (ret < 0)
 		goto fail;
 
-	ndev->ieee80211_ptr = local;
-	memcpy(ndev->dev_addr, local->hw.perm_addr, ETH_ALEN);
-	SET_NETDEV_DEV(ndev, local->hw.dev);
+	memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
+	SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
 
 	nsdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+	ndev->ieee80211_ptr = &nsdata->wdev;
+	nsdata->wdev.wiphy = local->hw.wiphy;
 	nsdata->type = IEEE80211_IF_TYPE_MGMT;
 	nsdata->dev = ndev;
 	nsdata->local = local;
@@ -163,7 +166,7 @@ void ieee80211_if_del_mgmt(struct ieee80
 void ieee80211_if_set_type(struct net_device *dev, int type)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	sdata->type = type;
 	switch (type) {
@@ -211,7 +214,7 @@ void ieee80211_if_set_type(struct net_de
 /* Must be called with rtnl lock held. */
 void ieee80211_if_reinit(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct sta_info *sta;
 	int i;
@@ -317,7 +320,7 @@ void __ieee80211_if_del(struct ieee80211
 /* Must be called with rtnl lock held. */
 int ieee80211_if_remove(struct net_device *dev, const char *name, int id)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata, *n;
 
 	ASSERT_RTNL();
@@ -336,7 +339,7 @@ int ieee80211_if_remove(struct net_devic
 
 void ieee80211_if_free(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	/* local->apdev must be NULL when freeing management interface */
@@ -348,7 +351,7 @@ void ieee80211_if_free(struct net_device
 /* Must be called with rtnl lock held. */
 void ieee80211_if_flush(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata, *n;
 
 	ASSERT_RTNL();
@@ -359,7 +362,7 @@ void ieee80211_if_flush(struct net_devic
 
 void ieee80211_if_del(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	rtnl_lock();
--- wireless-dev.orig/net/d80211/ieee80211_i.h	2007-02-15 13:28:04.817940064 +0100
+++ wireless-dev/net/d80211/ieee80211_i.h	2007-02-15 13:28:52.427940064 +0100
@@ -20,6 +20,7 @@
 #include <linux/workqueue.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
+#include <net/wireless.h>
 #include "ieee80211_key.h"
 #include "sta_info.h"
 
@@ -290,6 +291,8 @@ struct ieee80211_sub_if_data {
         struct list_head list;
         unsigned int type;
 
+        struct wireless_dev wdev;
+
         struct net_device *dev;
         struct ieee80211_local *local;
 
@@ -347,8 +350,6 @@ struct ieee80211_local {
 	int monitors;
 	struct iw_statistics wstats;
 
-	struct class_device class_dev;
-
 	enum {
 		IEEE80211_DEV_UNITIALIZED = 0,
 		IEEE80211_DEV_REGISTERED,
@@ -599,7 +600,6 @@ static inline void bss_tim_clear(struct 
 }
 
 /* ieee80211.c */
-void ieee80211_release_hw(struct ieee80211_local *local);
 int ieee80211_hw_config(struct ieee80211_local *local);
 int ieee80211_if_config(struct net_device *dev);
 int ieee80211_if_config_beacon(struct net_device *dev);
@@ -683,14 +683,6 @@ struct sta_info * ieee80211_ibss_add_sta
 int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
 int ieee80211_sta_disassociate(struct net_device *dev, u16 reason);
 
-/* ieee80211_dev.c */
-int ieee80211_dev_alloc_index(struct ieee80211_local *local);
-void ieee80211_dev_free_index(struct ieee80211_local *local);
-struct ieee80211_local *ieee80211_dev_find(int index);
-int ieee80211_dev_find_index(struct ieee80211_local *local);
-struct ieee80211_local *ieee80211_dev_alloc(gfp_t flags);
-void ieee80211_dev_free(struct ieee80211_local *local);
-
 /* ieee80211_iface.c */
 int ieee80211_if_add(struct net_device *dev, const char *name,
 		     int format, struct net_device **new_dev);
@@ -706,17 +698,6 @@ void ieee80211_if_sdata_init(struct ieee
 int ieee80211_if_add_mgmt(struct ieee80211_local *local);
 void ieee80211_if_del_mgmt(struct ieee80211_local *local);
 
-/* ieee80211_sysfs.c */
-int ieee80211_sysfs_add_netdevice(struct net_device *dev);
-void ieee80211_sysfs_remove_netdevice(struct net_device *dev);
-void ieee80211_dev_sysfs_init(struct ieee80211_local *local);
-void ieee80211_dev_sysfs_put(struct ieee80211_local *local);
-int ieee80211_dev_sysfs_add(struct ieee80211_local *local);
-void ieee80211_dev_sysfs_del(struct ieee80211_local *local);
-int ieee80211_sysfs_init(void);
-void ieee80211_sysfs_deinit(void);
-int ieee80211_sysfs_change_if_type(struct net_device *dev);
-
 /* ieee80211_sysfs_sta.c */
 int ieee80211_sta_kset_sysfs_register(struct ieee80211_local *local);
 void ieee80211_sta_kset_sysfs_unregister(struct ieee80211_local *local);
--- wireless-dev.orig/net/d80211/ieee80211_led.c	2007-02-15 13:28:04.917940064 +0100
+++ wireless-dev/net/d80211/ieee80211_led.c	2007-02-15 13:28:52.427940064 +0100
@@ -39,7 +39,7 @@ void ieee80211_led_init(struct ieee80211
 	if (!local->rx_led)
 		return;
 	snprintf(local->rx_led_name, sizeof(local->rx_led_name),
-		 "wiphy%drx", local->hw.index);
+		 "wiphy%drx", local->hw.wiphy->wiphy_index);
 	local->rx_led->name = local->rx_led_name;
 	if (led_trigger_register(local->rx_led)) {
 		kfree(local->rx_led);
@@ -50,7 +50,7 @@ void ieee80211_led_init(struct ieee80211
 	if (!local->tx_led)
 		return;
 	snprintf(local->tx_led_name, sizeof(local->tx_led_name),
-		 "wiphy%dtx", local->hw.index);
+		 "wiphy%dtx", local->hw.wiphy->wiphy_index);
 	local->tx_led->name = local->tx_led_name;
 	if (led_trigger_register(local->tx_led)) {
 		kfree(local->tx_led);
--- wireless-dev.orig/net/d80211/ieee80211_sysfs.c	2007-02-15 13:28:04.987940064 +0100
+++ wireless-dev/net/d80211/ieee80211_sysfs.c	2007-02-15 13:28:52.427940064 +0100
@@ -13,11 +13,16 @@
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <net/d80211.h>
+#include <net/cfg80211.h>
 #include "ieee80211_i.h"
 #include "ieee80211_rate.h"
 
-#define to_ieee80211_local(class) \
-	container_of(class, struct ieee80211_local, class_dev)
+static inline struct ieee80211_local *to_ieee80211_local(struct class_device *dev)
+{
+	struct wiphy *wiphy = container_of(dev, struct wiphy, class_dev);
+	return wiphy_priv(wiphy);
+}
+
 #define to_net_dev(class) \
 	container_of(class, struct net_device, class_dev)
 
@@ -65,45 +70,6 @@ static const char *ieee80211_mode_str(in
 
 /* attributes in /sys/class/ieee80211/phyX/ */
 
-static ssize_t store_add_iface(struct class_device *dev,
-			       const char *buf, size_t len)
-{
-	struct ieee80211_local *local = to_ieee80211_local(dev);
-	struct net_device *new_dev;
-	int res;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-	if (len > IFNAMSIZ)
-		return -EINVAL;
-	res = rtnl_lock_local(local);
-	if (res)
-		return res;
-	res = ieee80211_if_add(local->mdev, buf, 0, &new_dev);
-	if (res == 0)
-		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
-	rtnl_unlock();
-	return res < 0 ? res : len;
-}
-
-static ssize_t store_remove_iface(struct class_device *dev,
-				  const char *buf, size_t len)
-{
-	struct ieee80211_local *local = to_ieee80211_local(dev);
-	int res;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-	if (len > IFNAMSIZ)
-		return -EINVAL;
-	res = rtnl_lock_local(local);
-	if (res)
-		return res;
-	res = ieee80211_if_remove(local->mdev, buf, -1);
-	rtnl_unlock();
-	return res < 0 ? res : len;
-}
-
 static ssize_t store_rate_ctrl_alg(struct class_device *dev,
 				   const char *buf, size_t len)
 {
@@ -211,8 +177,6 @@ static ssize_t ieee80211_local_fmt_rate_
 __IEEE80211_LOCAL_SHOW(rate_ctrl_alg);
 
 static struct class_device_attribute ieee80211_class_dev_attrs[] = {
-	__ATTR(add_iface, S_IWUGO, NULL, store_add_iface),
-	__ATTR(remove_iface, S_IWUGO, NULL, store_remove_iface),
 	__ATTR(channel, S_IRUGO, ieee80211_local_show_channel, NULL),
 	__ATTR(frequency, S_IRUGO, ieee80211_local_show_frequency, NULL),
 	__ATTR(radar_detect, S_IRUGO, ieee80211_local_show_radar_detect, NULL),
@@ -229,7 +193,6 @@ static struct class_device_attribute iee
 	__ATTR(tx_power_reduction, S_IRUGO, ieee80211_local_show_tx_power_reduction, NULL),
 	__ATTR(modes, S_IRUGO, ieee80211_local_show_modes, NULL),
 	__ATTR(rate_ctrl_alg, S_IRUGO | S_IWUGO, ieee80211_local_show_rate_ctrl_alg, store_rate_ctrl_alg),
-	{}
 };
 
 /* attributes in /sys/class/ieee80211/phyX/statistics/ */
@@ -622,72 +585,52 @@ static struct attribute_group ieee80211_
 	.attrs = ieee80211_monitor_attrs,
 };
 
-/* /sys/class/ieee80211/phyX functions */
-
-static void ieee80211_class_dev_release(struct class_device *dev)
+int ieee80211_dev_sysfs_add(struct ieee80211_local *local)
 {
-	ieee80211_release_hw(to_ieee80211_local(dev));
-}
+	const struct class_device_attribute *attr;
+	int i, err;
 
-#ifdef CONFIG_HOTPLUG
-static int ieee80211_uevent(struct class_device *cd, char **envp,
-			    int num_envp, char *buf, int size)
-{
-	struct ieee80211_local *local = to_ieee80211_local(cd);
+	for (i = 0; i < ARRAY_SIZE(ieee80211_class_dev_attrs); i++) {
+		attr = &ieee80211_class_dev_attrs[i];
+		err = sysfs_create_file(&local->hw.wiphy->class_dev.kobj,
+					&attr->attr);
+		if (err)
+			goto unwind;
+	}
 
-	if (num_envp < 2)
-		return -ENOMEM;
-	envp[0] = buf;
-	if (snprintf(buf, size, "IEEE80211_DEV=phy%d",
-		     local->hw.index) + 1 >= size)
-		return -ENOMEM;
-	envp[1] = NULL;
-	return 0;
-}
-#endif
+	err = sysfs_create_group(&local->hw.wiphy->class_dev.kobj,
+				 &ieee80211_stats_group);
 
-static struct class ieee80211_class = {
-	.name = "ieee80211",
-	.class_dev_attrs = ieee80211_class_dev_attrs,
-	.release = ieee80211_class_dev_release,
-#ifdef CONFIG_HOTPLUG
-	.uevent = ieee80211_uevent,
-#endif
-};
+	if (err == 0)
+		return err;
 
-void ieee80211_dev_sysfs_init(struct ieee80211_local *local)
-{
-	local->class_dev.class = &ieee80211_class;
-	local->class_dev.class_data = local;
-	class_device_initialize(&local->class_dev);
+ unwind:
+ 	/* one after the failed/last one */
+ 	i--;
+	while (i >= 0) {
+		attr = &ieee80211_class_dev_attrs[i];
+		sysfs_remove_file(&local->hw.wiphy->class_dev.kobj,
+				  &attr->attr);
+		i--;
+	}
+	return err;
 }
 
-void ieee80211_dev_sysfs_put(struct ieee80211_local *local)
+void ieee80211_dev_sysfs_del(struct ieee80211_local *local)
 {
-	class_device_put(&local->class_dev);
-}
+	const struct class_device_attribute *attr;
+	int i;
 
-int ieee80211_dev_sysfs_add(struct ieee80211_local *local)
-{
-	int res;
+	sysfs_remove_group(&local->hw.wiphy->class_dev.kobj,
+			   &ieee80211_stats_group);
 
-	snprintf(local->class_dev.class_id, BUS_ID_SIZE,
-		 "phy%d", local->hw.index);
-	res = class_device_add(&local->class_dev);
-	if (res)
-		return res;
-	res = sysfs_create_group(&local->class_dev.kobj,
-				 &ieee80211_stats_group);
-	if (res)
-		class_device_del(&local->class_dev);
-	return res;
+	for (i = 0; i < ARRAY_SIZE(ieee80211_class_dev_attrs); i++) {
+		attr = &ieee80211_class_dev_attrs[i];
+		sysfs_remove_file(&local->hw.wiphy->class_dev.kobj,
+				  &attr->attr);
+	}
 }
 
-void ieee80211_dev_sysfs_del(struct ieee80211_local *local)
-{
-	sysfs_remove_group(&local->class_dev.kobj, &ieee80211_stats_group);
-	class_device_del(&local->class_dev);
-}
 
 /* /sys/class/net/X functions */
 
@@ -746,11 +689,12 @@ int ieee80211_sysfs_change_if_type(struc
 
 int ieee80211_sysfs_add_netdevice(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int res;
 
-	res = sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
-				"hw");
+	res = sysfs_create_link(&dev->class_dev.kobj,
+				&local->hw.wiphy->class_dev.kobj,
+				"wiphy");
 	if (res)
 		goto err_out;
 	res = ieee80211_add_if_group(&dev->class_dev.kobj, dev);
@@ -760,7 +704,7 @@ int ieee80211_sysfs_add_netdevice(struct
 	return res;
 
 err_link:
-	sysfs_remove_link(&dev->class_dev.kobj, "hw");
+	sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
 err_out:
 	return res;
 }
@@ -769,17 +713,5 @@ void ieee80211_sysfs_remove_netdevice(st
 {
 	ieee80211_key_kset_sysfs_unregister(IEEE80211_DEV_TO_SUB_IF(dev));
 	ieee80211_remove_if_group(&dev->class_dev.kobj, dev);
-	sysfs_remove_link(&dev->class_dev.kobj, "hw");
-}
-
-/* general module functions */
-
-int ieee80211_sysfs_init(void)
-{
-	return class_register(&ieee80211_class);
-}
-
-void ieee80211_sysfs_deinit(void)
-{
-	class_unregister(&ieee80211_class);
+	sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
 }
--- wireless-dev.orig/net/d80211/Kconfig	2007-02-15 13:28:05.007940064 +0100
+++ wireless-dev/net/d80211/Kconfig	2007-02-15 13:28:52.437940064 +0100
@@ -6,6 +6,7 @@ config D80211
 	select CRYPTO_AES
 	select CRC32
 	select WIRELESS_EXT
+	select CFG80211
 	---help---
 	This option enables the hardware independent IEEE 802.11
 	networking stack.
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/d80211/ieee80211_cfg.c	2007-02-15 13:28:52.437940064 +0100
@@ -0,0 +1,32 @@
+/*
+ * d80211 configuration hooks for cfg80211
+ *
+ * Copyright 2006	Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is GPLv2 as found in COPYING.
+ */
+
+#include <net/cfg80211.h>
+#include "ieee80211_i.h"
+#include "ieee80211_cfg.h"
+
+static int ieee80211_list_interfaces(struct wiphy *wiphy, void *data,
+				     int (*one)(void *data, int ifindex))
+{
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+	struct ieee80211_sub_if_data *subif;
+	int err;
+
+	spin_lock_bh(&local->sub_if_lock);
+	list_for_each_entry(subif, &local->sub_if_list, list) {
+		err = one(data, subif->dev->ifindex);
+		if (err)
+			break;
+	}
+	spin_unlock_bh(&local->sub_if_lock);
+	return err;
+}
+
+struct cfg80211_ops d80211_config_ops = {
+	.list_interfaces = ieee80211_list_interfaces,
+};
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/d80211/ieee80211_cfg.h	2007-02-15 13:28:52.437940064 +0100
@@ -0,0 +1,9 @@
+/*
+ * d80211 configuration hooks for cfg80211
+ */
+#ifndef __IEEE80211_CFG_H
+#define __IEEE80211_CFG_H
+
+extern struct cfg80211_ops d80211_config_ops;
+
+#endif /* __IEEE80211_CFG_H */
--- wireless-dev.orig/net/d80211/ieee80211_sysfs_sta.c	2007-02-15 13:28:05.217940064 +0100
+++ wireless-dev/net/d80211/ieee80211_sysfs_sta.c	2007-02-15 13:28:52.437940064 +0100
@@ -39,7 +39,7 @@ static ssize_t show_sta_##name(const str
 #define STA_SHOW_RATE(name, field)					\
 static ssize_t show_sta_##name(const struct sta_info *sta, char *buf)	\
 {									\
-	struct ieee80211_local *local = sta->dev->ieee80211_ptr;	\
+	struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\
 	return sprintf(buf, "%d\n",					\
 		       (sta->field >= 0 &&				\
 			sta->field < local->num_curr_rates) ?		\
@@ -370,7 +370,7 @@ int ieee80211_sta_kset_sysfs_register(st
 	res = kobject_set_name(&local->sta_kset.kobj, "sta");
 	if (res)
 		return res;
-	local->sta_kset.kobj.parent = &local->class_dev.kobj;
+	local->sta_kset.kobj.parent = &local->hw.wiphy->class_dev.kobj;
 	local->sta_kset.ktype = &sta_ktype;
 	return kset_register(&local->sta_kset);
 }
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/d80211/ieee80211_sysfs.h	2007-02-15 13:28:52.437940064 +0100
@@ -0,0 +1,12 @@
+/* routines exported for sysfs handling */
+
+#ifndef __IEEE80211_SYSFS_H
+#define __IEEE80211_SYSFS_H
+
+int ieee80211_sysfs_add_netdevice(struct net_device *dev);
+void ieee80211_sysfs_remove_netdevice(struct net_device *dev);
+int ieee80211_sysfs_change_if_type(struct net_device *dev);
+int ieee80211_dev_sysfs_add(struct ieee80211_local *local);
+void ieee80211_dev_sysfs_del(struct ieee80211_local *local);
+
+#endif /* __IEEE80211_SYSFS_H */
--- wireless-dev.orig/net/d80211/ieee80211_ioctl.c	2007-02-15 13:28:05.327940064 +0100
+++ wireless-dev/net/d80211/ieee80211_ioctl.c	2007-02-15 13:28:52.447940064 +0100
@@ -116,7 +116,7 @@ static int ieee80211_ioctl_get_hw_featur
 					   struct prism2_hostapd_param *param,
 					   int param_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	u8 *pos = param->u.hw_features.data;
 	int left = param_len - (pos - (u8 *) param);
 	int i;
@@ -169,7 +169,7 @@ static int ieee80211_ioctl_get_hw_featur
 static int ieee80211_ioctl_scan(struct net_device *dev,
                                 struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (!local->ops->passive_scan)
 		return -EOPNOTSUPP;
@@ -209,7 +209,7 @@ static int ieee80211_ioctl_scan(struct n
 static int ieee80211_ioctl_flush(struct net_device *dev,
 				 struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	sta_info_flush(local, NULL);
 	return 0;
 }
@@ -264,7 +264,7 @@ static void ieee80211_send_layer2_update
 static int ieee80211_ioctl_add_sta(struct net_device *dev,
 				   struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	u32 rates;
 	int i, j;
@@ -356,7 +356,7 @@ static int ieee80211_ioctl_add_sta(struc
 static int ieee80211_ioctl_remove_sta(struct net_device *dev,
 				      struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 
 	sta = sta_info_get(local, param->sta_addr);
@@ -372,7 +372,7 @@ static int ieee80211_ioctl_remove_sta(st
 static int ieee80211_ioctl_get_dot11counterstable(struct net_device *dev,
 					struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
         struct ieee80211_low_level_stats stats;
 
 	memset(&stats, 0, sizeof(stats));
@@ -404,7 +404,7 @@ static int ieee80211_ioctl_get_dot11coun
 static int ieee80211_ioctl_get_info_sta(struct net_device *dev,
 					struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 
 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -453,7 +453,7 @@ static int ieee80211_ioctl_get_info_sta(
 static int ieee80211_ioctl_set_flags_sta(struct net_device *dev,
 					 struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 
 	sta = sta_info_get(local, param->sta_addr);
@@ -484,7 +484,7 @@ int ieee80211_set_hw_encryption(struct n
 				struct ieee80211_key *key)
 {
 	struct ieee80211_key_conf *keyconf = NULL;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int rc = 0;
 
 	/* default to sw encryption; this will be cleared by low-level
@@ -517,7 +517,7 @@ static int ieee80211_set_encryption(stru
 				    int idx, int alg, int set_tx_key, int *err,
 				    const u8 *_key, size_t key_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int ret = 0;
 	struct sta_info *sta;
 	struct ieee80211_key *key, *old_key;
@@ -785,7 +785,7 @@ static int ieee80211_ioctl_get_encryptio
 					  struct prism2_hostapd_param *param,
 					  int param_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int ret = 0;
 	struct sta_info *sta;
 	struct ieee80211_key **key;
@@ -903,7 +903,7 @@ static int ieee80211_ioctl_get_encryptio
 static int ieee80211_ioctl_wpa_trigger(struct net_device *dev,
 				       struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 
 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -932,7 +932,7 @@ static int ieee80211_ioctl_set_rate_sets
 					 struct prism2_hostapd_param *param,
 					 int param_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	u16 *pos = (u16 *) param->u.set_rate_sets.data;
 	int left = param_len - ((u8 *) pos - (u8 *) param);
 	int i, mode, num_supp, num_basic, *supp, *basic, *prev;
@@ -1019,7 +1019,7 @@ static int ieee80211_ioctl_add_if(struct
 		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_WDS);
 		res = ieee80211_if_update_wds(new_dev, wds->remote_addr);
 		if (res)
-			__ieee80211_if_del(dev->ieee80211_ptr,
+			__ieee80211_if_del(wdev_priv(dev->ieee80211_ptr),
 					   IEEE80211_DEV_TO_SUB_IF(new_dev));
 		return res;
 	case HOSTAP_IF_VLAN:
@@ -1033,7 +1033,7 @@ static int ieee80211_ioctl_add_if(struct
 #if 0
 		res = ieee80211_if_update_vlan(new_dev, vlan->id);
 		if (res)
-			__ieee80211_if_del(dev->ieee80211_ptr,
+			__ieee80211_if_del(wdev_priv(dev->ieee80211_ptr),
 					   IEEE80211_DEV_TO_SUB_IF(new_dev));
 #endif
 		return res;
@@ -1100,7 +1100,7 @@ static int ieee80211_ioctl_update_if(str
 	if (param->u.if_info.type == HOSTAP_IF_WDS) {
 		struct hostapd_if_wds *wds =
 			(struct hostapd_if_wds *) param->u.if_info.data;
-		struct ieee80211_local *local = dev->ieee80211_ptr;
+		struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 		struct net_device *wds_dev = NULL;
 		struct ieee80211_sub_if_data *sdata;
 
@@ -1137,7 +1137,7 @@ static int ieee80211_ioctl_scan_req(stru
 				    struct prism2_hostapd_param *param,
 				    int param_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	u8 *pos = param->u.scan_req.ssid;
 	int left = param_len - ((u8 *) pos - (u8 *) param);
 	int len = param->u.scan_req.ssid_len;
@@ -1172,7 +1172,7 @@ static int ieee80211_ioctl_sta_get_state
 static int ieee80211_ioctl_mlme(struct net_device *dev,
 				struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 
 	if (local->user_space_mlme)
@@ -1195,7 +1195,7 @@ static int ieee80211_ioctl_mlme(struct n
 static int ieee80211_ioctl_get_load_stats(struct net_device *dev,
 					  struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	param->u.get_load_stats.channel_use = local->channel_use;
 /*	if (param->u.get_load_stats.flags & LOAD_STATS_CLEAR)
@@ -1208,7 +1208,7 @@ static int ieee80211_ioctl_get_load_stat
 static int ieee80211_ioctl_set_sta_vlan(struct net_device *dev,
                                         struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
         struct sta_info *sta;
 
         sta = sta_info_get(local, param->sta_addr);
@@ -1240,7 +1240,7 @@ static int ieee80211_ioctl_set_sta_vlan(
 static int ieee80211_set_gen_ie(struct net_device *dev, u8 *ie, size_t len)
 {
 	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (local->user_space_mlme)
 		return -EOPNOTSUPP;
@@ -1282,7 +1282,7 @@ ieee80211_ioctl_set_generic_info_elem(st
 static int ieee80211_ioctl_set_regulatory_domain(struct net_device *dev,
 					    struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_conf *conf = &local->hw.conf;
         conf->regulatory_domain = param->u.set_regulatory_domain.rd;
         return 0;
@@ -1292,18 +1292,18 @@ static int ieee80211_ioctl_set_regulator
 static int ieee80211_ioctl_set_radio_enabled(struct net_device *dev,
 					     int val)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_conf *conf = &local->hw.conf;
 
 	conf->radio_enabled = val;
-	return ieee80211_hw_config(dev->ieee80211_ptr);
+	return ieee80211_hw_config(wdev_priv(dev->ieee80211_ptr));
 }
 
 static int
 ieee80211_ioctl_set_tx_queue_params(struct net_device *dev,
 				    struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_queue_params qparam;
 
 	if (!local->ops->conf_tx) {
@@ -1327,7 +1327,7 @@ ieee80211_ioctl_set_tx_queue_params(stru
 static int ieee80211_ioctl_get_tx_stats(struct net_device *dev,
 					struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_queue_stats stats;
 	int ret, i;
 
@@ -1352,7 +1352,7 @@ static int ieee80211_ioctl_get_tx_stats(
 static int ieee80211_ioctl_set_channel_flag(struct net_device *dev,
 					    struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hw_mode *mode;
 	struct ieee80211_channel *chan = NULL;
 	int i;
@@ -1385,7 +1385,7 @@ found:
 static int ieee80211_ioctl_set_quiet_params(struct net_device *dev,
 					    struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_conf *conf = &local->hw.conf;
 
 	conf->quiet_duration = param->u.quiet.duration;
@@ -1398,7 +1398,7 @@ static int ieee80211_ioctl_set_quiet_par
 static int ieee80211_ioctl_set_radar_params(struct net_device *dev,
 					    struct prism2_hostapd_param *param)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_conf *conf = &local->hw.conf;
 
 	conf->radar_firpwr_threshold = param->u.radar.radar_firpwr_threshold;
@@ -1544,7 +1544,7 @@ static int ieee80211_ioctl_giwname(struc
 				   struct iw_request_info *info,
 				   char *name, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	switch (local->hw.conf.phymode) {
 	case MODE_IEEE80211A:
@@ -1698,7 +1698,7 @@ static void ieee80211_unmask_channel(str
 
 static int ieee80211_unmask_channels(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hw_mode *mode;
 	int c;
 
@@ -1799,7 +1799,7 @@ int ieee80211_ioctl_siwfreq(struct net_d
 			    struct iw_request_info *info,
 			    struct iw_freq *freq, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hw_mode *mode;
 	int c, nfreq, set = 0;
 
@@ -1852,7 +1852,7 @@ static int ieee80211_ioctl_giwfreq(struc
 				   struct iw_request_info *info,
 				   struct iw_freq *freq, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	/* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
 	 * driver for the current channel with firmware-based management */
@@ -1868,7 +1868,7 @@ static int ieee80211_ioctl_siwessid(stru
 				    struct iw_request_info *info,
 				    struct iw_point *data, char *ssid)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
         size_t len = data->length;
 
@@ -1936,7 +1936,7 @@ static int ieee80211_ioctl_siwap(struct 
 				 struct iw_request_info *info,
 				 struct sockaddr *ap_addr, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1985,7 +1985,7 @@ static int ieee80211_ioctl_siwscan(struc
 				   struct iw_request_info *info,
 				   struct iw_point *data, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	u8 *ssid = NULL;
 	size_t ssid_len = 0;
@@ -2013,7 +2013,7 @@ static int ieee80211_ioctl_giwscan(struc
 				   struct iw_point *data, char *extra)
 {
 	int res;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	if (local->sta_scanning)
 		return -EAGAIN;
 	res = ieee80211_sta_scan_results(dev, extra, data->length);
@@ -2030,7 +2030,7 @@ static int ieee80211_ioctl_siwrts(struct
 				  struct iw_request_info *info,
 				  struct iw_param *rts, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (rts->disabled)
 		local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
@@ -2053,7 +2053,7 @@ static int ieee80211_ioctl_giwrts(struct
 				  struct iw_request_info *info,
 				  struct iw_param *rts, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	rts->value = local->rts_threshold;
 	rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
@@ -2067,7 +2067,7 @@ static int ieee80211_ioctl_siwfrag(struc
 				   struct iw_request_info *info,
 				   struct iw_param *frag, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (frag->disabled)
 		local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
@@ -2094,7 +2094,7 @@ static int ieee80211_ioctl_giwfrag(struc
 				   struct iw_request_info *info,
 				   struct iw_param *frag, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	frag->value = local->fragmentation_threshold;
 	frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD);
@@ -2108,7 +2108,7 @@ static int ieee80211_ioctl_siwretry(stru
 				    struct iw_request_info *info,
 				    struct iw_param *retry, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (retry->disabled ||
 	    (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
@@ -2138,7 +2138,7 @@ static int ieee80211_ioctl_giwretry(stru
 				    struct iw_request_info *info,
 				    struct iw_param *retry, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	retry->disabled = 0;
 	if ((retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
@@ -2173,7 +2173,7 @@ static void ieee80211_ioctl_unmask_chann
 
 static int ieee80211_ioctl_test_mode(struct net_device *dev, int mode)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int ret = -EOPNOTSUPP;
 
 	if (mode == IEEE80211_TEST_UNMASK_CHANNELS) {
@@ -2190,7 +2190,7 @@ static int ieee80211_ioctl_test_mode(str
 
 static int ieee80211_ioctl_clear_keys(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_key_conf key;
 	int i;
 	u8 addr[ETH_ALEN];
@@ -2247,7 +2247,7 @@ ieee80211_ioctl_force_unicast_rate(struc
 				   struct ieee80211_sub_if_data *sdata,
 				   int rate)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int i;
 
 	if (sdata->type != IEEE80211_IF_TYPE_AP)
@@ -2273,7 +2273,7 @@ ieee80211_ioctl_max_ratectrl_rate(struct
 				  struct ieee80211_sub_if_data *sdata,
 				  int rate)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int i;
 
 	if (sdata->type != IEEE80211_IF_TYPE_AP)
@@ -2391,7 +2391,7 @@ static int ieee80211_ioctl_prism2_param(
 					struct iw_request_info *info,
 					void *wrqu, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	int *i = (int *) extra;
 	int param = *i;
@@ -2642,7 +2642,7 @@ static int ieee80211_ioctl_get_prism2_pa
 					    struct iw_request_info *info,
 					    void *wrqu, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	int *param = (int *) extra;
 	int ret = 0;
@@ -2822,7 +2822,7 @@ static int ieee80211_ioctl_test_param(st
 				      struct iw_request_info *info,
 				      void *wrqu, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int *i = (int *) extra;
 	int param = *i;
 	int value = *(i + 1);
@@ -2964,7 +2964,7 @@ static int ieee80211_ioctl_siwauth(struc
 				   struct iw_request_info *info,
 				   struct iw_param *data, char *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	int ret = 0;
 
@@ -3020,7 +3020,7 @@ static int ieee80211_ioctl_siwauth(struc
 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *net_dev)
 {
-	struct ieee80211_local *local = net_dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(net_dev->ieee80211_ptr);
 	struct iw_statistics * wstats = &local->wstats;
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(net_dev);
 	struct sta_info *sta;
--- wireless-dev.orig/net/d80211/ieee80211_sta.c	2007-02-15 13:28:05.357940064 +0100
+++ wireless-dev/net/d80211/ieee80211_sta.c	2007-02-15 13:28:52.447940064 +0100
@@ -229,7 +229,7 @@ static void ieee80211_sta_wmm_params(str
 				     struct ieee80211_if_sta *ifsta,
 				     u8 *wmm_param, size_t wmm_param_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_queue_params params;
 	size_t left;
 	int count;
@@ -415,7 +415,7 @@ static void ieee80211_send_auth(struct n
 				int transaction, u8 *extra, size_t extra_len,
 				int encrypt)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 
@@ -472,7 +472,7 @@ static void ieee80211_authenticate(struc
 static void ieee80211_send_assoc(struct net_device *dev,
 				 struct ieee80211_if_sta *ifsta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 	u8 *pos, *ies;
@@ -590,7 +590,7 @@ static void ieee80211_send_assoc(struct 
 static void ieee80211_send_deauth(struct net_device *dev,
 				  struct ieee80211_if_sta *ifsta, u16 reason)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 
@@ -619,7 +619,7 @@ static void ieee80211_send_deauth(struct
 static void ieee80211_send_disassoc(struct net_device *dev,
 				    struct ieee80211_if_sta *ifsta, u16 reason)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 
@@ -698,7 +698,7 @@ static void ieee80211_associate(struct n
 static void ieee80211_associated(struct net_device *dev,
 				 struct ieee80211_if_sta *ifsta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	int disassoc;
 
@@ -761,7 +761,7 @@ static void ieee80211_associated(struct 
 static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
 				     u8 *ssid, size_t ssid_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 	u8 *pos, *supp_rates, *esupp_rates = NULL;
@@ -1092,7 +1092,7 @@ static void ieee80211_rx_mgmt_assoc_resp
 					 struct ieee80211_rx_status *rx_status,
 					 int reassoc)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	u32 rates;
 	u16 capab_info, status_code, aid;
@@ -1223,7 +1223,7 @@ static void ieee80211_rx_mgmt_assoc_resp
 static void __ieee80211_rx_bss_hash_add(struct net_device *dev,
 					struct ieee80211_sta_bss *bss)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	bss->hnext = local->sta_bss_hash[STA_HASH(bss->bssid)];
 	local->sta_bss_hash[STA_HASH(bss->bssid)] = bss;
 }
@@ -1233,7 +1233,7 @@ static void __ieee80211_rx_bss_hash_add(
 static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
 					struct ieee80211_sta_bss *bss)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *b, *prev = NULL;
 	b = local->sta_bss_hash[STA_HASH(bss->bssid)];
 	while (b) {
@@ -1254,7 +1254,7 @@ static void __ieee80211_rx_bss_hash_del(
 static struct ieee80211_sta_bss *
 ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 
 	bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
@@ -1277,7 +1277,7 @@ ieee80211_rx_bss_add(struct net_device *
 static struct ieee80211_sta_bss *
 ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 
 	spin_lock_bh(&local->sta_bss_lock);
@@ -1306,7 +1306,7 @@ static void ieee80211_rx_bss_free(struct
 static void ieee80211_rx_bss_put(struct net_device *dev,
 				 struct ieee80211_sta_bss *bss)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	if (!atomic_dec_and_test(&bss->users))
 		return;
 
@@ -1320,7 +1320,7 @@ static void ieee80211_rx_bss_put(struct 
 
 void ieee80211_rx_bss_list_init(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	spin_lock_init(&local->sta_bss_lock);
 	INIT_LIST_HEAD(&local->sta_bss_list);
 }
@@ -1328,7 +1328,7 @@ void ieee80211_rx_bss_list_init(struct n
 
 void ieee80211_rx_bss_list_deinit(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss, *tmp;
 
 	list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
@@ -1342,7 +1342,7 @@ static void ieee80211_rx_bss_info(struct
 				  struct ieee80211_rx_status *rx_status,
 				  int beacon)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee802_11_elems elems;
 	size_t baselen;
 	int channel, invalid = 0, clen;
@@ -1591,7 +1591,7 @@ static void ieee80211_rx_mgmt_beacon(str
 				     size_t len,
 				     struct ieee80211_rx_status *rx_status)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_if_sta *ifsta;
 	int use_protection;
@@ -1649,7 +1649,7 @@ static void ieee80211_rx_mgmt_probe_req(
 					size_t len,
 					struct ieee80211_rx_status *rx_status)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	int tx_last_beacon;
 	struct sk_buff *skb;
@@ -1802,7 +1802,7 @@ void ieee80211_sta_rx_scan(struct net_de
 
 static int ieee80211_sta_active_ibss(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int active = 0;
 	struct sta_info *sta;
 
@@ -1823,7 +1823,7 @@ static int ieee80211_sta_active_ibss(str
 
 static void ieee80211_sta_expire(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta, *tmp;
 
 	spin_lock_bh(&local->sta_lock);
@@ -1909,7 +1909,7 @@ void ieee80211_sta_work(struct work_stru
 static void ieee80211_sta_new_auth(struct net_device *dev,
 				   struct ieee80211_if_sta *ifsta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	if (sdata->type != IEEE80211_IF_TYPE_STA)
@@ -1970,7 +1970,7 @@ static int ieee80211_sta_join_ibss(struc
 				   struct ieee80211_if_sta *ifsta,
 				   struct ieee80211_sta_bss *bss)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct iw_freq rq;
 	int res, rates, i, j;
 	struct sk_buff *skb;
@@ -2131,7 +2131,7 @@ static int ieee80211_sta_join_ibss(struc
 static int ieee80211_sta_create_ibss(struct net_device *dev,
 				     struct ieee80211_if_sta *ifsta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 	struct ieee80211_sub_if_data *sdata;
 	u8 bssid[ETH_ALEN], *pos;
@@ -2188,7 +2188,7 @@ static int ieee80211_sta_create_ibss(str
 static int ieee80211_sta_find_ibss(struct net_device *dev,
 				   struct ieee80211_if_sta *ifsta)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 	int found = 0;
 	u8 bssid[ETH_ALEN];
@@ -2278,7 +2278,7 @@ int ieee80211_sta_set_ssid(struct net_de
 {
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_if_sta *ifsta;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (len > IEEE80211_MAX_SSID_LEN)
 		return -EINVAL;
@@ -2375,7 +2375,7 @@ int ieee80211_sta_set_bssid(struct net_d
 
 static void ieee80211_sta_save_oper_chan(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	local->scan_oper_channel = local->hw.conf.channel;
 	local->scan_oper_channel_val = local->hw.conf.channel_val;
 	local->scan_oper_power_level = local->hw.conf.power_level;
@@ -2387,7 +2387,7 @@ static void ieee80211_sta_save_oper_chan
 
 static int ieee80211_sta_restore_oper_chan(struct net_device *dev)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	local->hw.conf.channel = local->scan_oper_channel;
 	local->hw.conf.channel_val = local->scan_oper_channel_val;
 	local->hw.conf.power_level = local->scan_oper_power_level;
@@ -2541,7 +2541,7 @@ void ieee80211_sta_scan_work(struct work
 
 int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
 	if (ssid_len > IEEE80211_MAX_SSID_LEN)
 		return -EINVAL;
@@ -2611,7 +2611,7 @@ ieee80211_sta_scan_result(struct net_dev
 			  struct ieee80211_sta_bss *bss,
 			  char *current_ev, char *end_buf)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct iw_event iwe;
 
 	if (time_after(jiffies,
@@ -2779,7 +2779,7 @@ ieee80211_sta_scan_result(struct net_dev
 
 int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	char *current_ev = buf;
 	char *end_buf = buf + len;
 	struct ieee80211_sta_bss *bss;
@@ -2826,7 +2826,7 @@ struct sta_info * ieee80211_ibss_add_sta
 					 struct sk_buff *skb, u8 *bssid,
 					 u8 *addr)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	struct ieee80211_sub_if_data *sdata = NULL;
 	struct net_device *sta_dev = NULL;
--- wireless-dev.orig/net/d80211/rc80211_simple.c	2007-02-15 13:28:05.417940064 +0100
+++ wireless-dev/net/d80211/rc80211_simple.c	2007-02-15 13:28:52.447940064 +0100
@@ -124,7 +124,7 @@ static void rate_control_simple_tx_statu
 					  struct sk_buff *skb,
 					  struct ieee80211_tx_status *status)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct sta_info *sta;
 	struct sta_rate_control *srctrl;
@@ -216,7 +216,7 @@ rate_control_simple_get_rate(void *priv,
 			     struct sk_buff *skb,
 			     struct rate_control_extra *extra)
 {
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct sta_info *sta;
--- wireless-dev.orig/net/d80211/wme.c	2007-02-15 13:28:05.507940064 +0100
+++ wireless-dev/net/d80211/wme.c	2007-02-15 13:28:52.447940064 +0100
@@ -160,7 +160,7 @@ static inline int wme_downgrade_ac(struc
  * negative return value indicates to drop the frame */
 static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
 {
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_tx_packet_data *pkt_data =
 		(struct ieee80211_tx_packet_data *) skb->cb;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -211,7 +211,7 @@ static inline int classify80211(struct s
 
 static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
 {
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
 	struct ieee80211_tx_packet_data *pkt_data =
 		(struct ieee80211_tx_packet_data *) skb->cb;
@@ -298,7 +298,7 @@ static struct sk_buff *wme_qdiscop_deque
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
 	struct net_device *dev = qd->dev;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	struct sk_buff *skb;
 	struct Qdisc *qdisc;
@@ -334,7 +334,7 @@ static struct sk_buff *wme_qdiscop_deque
 static void wme_qdiscop_reset(struct Qdisc* qd)
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	int queue;
 
@@ -351,7 +351,7 @@ static void wme_qdiscop_reset(struct Qdi
 static void wme_qdiscop_destroy(struct Qdisc* qd)
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	struct tcf_proto *tp;
 	int queue;
@@ -392,7 +392,7 @@ static int wme_qdiscop_init(struct Qdisc
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
 	struct net_device *dev = qd->dev;
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	int queues = local->hw.queues;
 	int err = 0, i;
 
@@ -448,7 +448,7 @@ static int wme_classop_graft(struct Qdis
 			     struct Qdisc *new, struct Qdisc **old)
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	unsigned long queue = arg - 1;
 
@@ -472,7 +472,7 @@ static struct Qdisc *
 wme_classop_leaf(struct Qdisc *qd, unsigned long arg)
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	unsigned long queue = arg - 1;
 
@@ -485,7 +485,7 @@ wme_classop_leaf(struct Qdisc *qd, unsig
 
 static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid)
 {
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	unsigned long queue = TC_H_MIN(classid);
 
@@ -513,7 +513,7 @@ static int wme_classop_change(struct Qdi
 			      struct rtattr **tca, unsigned long *arg)
 {
 	unsigned long cl = *arg;
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	/* printk(KERN_DEBUG "entering %s\n", __func__); */
 
@@ -531,7 +531,7 @@ static int wme_classop_change(struct Qdi
  * when we add WMM-SA support - TSPECs may be deleted here */
 static int wme_classop_delete(struct Qdisc *qd, unsigned long cl)
 {
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	/* printk(KERN_DEBUG "entering %s\n", __func__); */
 
@@ -545,7 +545,7 @@ static int wme_classop_dump_class(struct
 				  struct sk_buff *skb, struct tcmsg *tcm)
 {
 	struct ieee80211_sched_data *q = qdisc_priv(qd);
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	/* printk(KERN_DEBUG "entering %s\n", __func__); */
 
@@ -560,7 +560,7 @@ static int wme_classop_dump_class(struct
 
 static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg)
 {
-	struct ieee80211_local *local = qd->dev->ieee80211_ptr;
+	struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = &local->hw;
 	int queue;
 	/* printk(KERN_DEBUG "entering %s\n", __func__); */

--


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

* [PATCH 07/10] bcm43xx-d80211: update for wiphy api
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (5 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 06/10] d80211: update for wiphy api Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 15:09   ` Michael Buesch
  2007-02-15 14:42 ` [PATCH 08/10] zd1211rw-d80211: " Johannes Berg
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

update bcm43xx-d80211.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
Really bcm43xx should be using the new wiphy debugfs stuff as well,
but I can't figure out what the hell it is doing when multiple
devices exist in a system. Thing is the new debugfs dir is only
created for d80211 drivers when calling register_hw() and all items
must be gone from it when calling free_hw()...

---
 drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c |    2 +-
 drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c    |   15 ++++++---------
 2 files changed, 7 insertions(+), 10 deletions(-)

--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2007-02-15 13:50:28.967940064 +0100
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2007-02-15 14:01:33.486635438 +0100
@@ -3282,7 +3282,7 @@ static int bcm43xx_wireless_core_init(st
 	ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
 	bcm43xx_macfilter_clear(dev, BCM43xx_MACFILTER_ASSOC);
 	bcm43xx_macfilter_set(dev, BCM43xx_MACFILTER_SELF,
-			      (u8 *)(wl->hw->perm_addr));
+			      (u8 *)(wl->hw->wiphy->perm_addr));
 	bcm43xx_security_init(dev);
 	bcm43xx_measure_channel_change_time(dev);
 
@@ -3743,14 +3743,11 @@ static int bcm43xx_wireless_init(struct 
 		    IEEE80211_HW_WEP_INCLUDE_IV;
 	hw->maxssi = BCM43xx_RX_MAX_SSI;
 	hw->queues = 1;
-	hw->dev = &dev->dev;
-	if (is_valid_ether_addr(sprom->r1.et1mac)) {
-		memcpy(hw->perm_addr, sprom->r1.et1mac,
-		       ARRAY_SIZE(hw->perm_addr));
-	} else {
-		memcpy(hw->perm_addr, sprom->r1.il0mac,
-		       ARRAY_SIZE(hw->perm_addr));
-	}
+	SET_IEEE80211_DEV(hw, &dev->dev);
+	if (is_valid_ether_addr(sprom->r1.et1mac))
+		SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac);
+	else
+		SET_IEEE80211_PERM_ADDR(hw, sprom->r1.il0mac);
 
 	/* Get and initialize struct bcm43xx_wl */
 	wl = hw_to_bcm43xx_wl(hw);
--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c	2007-02-15 13:50:28.917940064 +0100
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c	2007-02-15 14:02:18.646635438 +0100
@@ -308,7 +308,7 @@ void bcm43xx_debugfs_add_device(struct b
 
 	dev->dfsentry = e;
 
-	snprintf(devdir, sizeof(devdir), "wiphy%d", dev->wl->hw->index);
+	snprintf(devdir, sizeof(devdir), "%s", wiphy_name(dev->wl->hw->wiphy));
 	e->subdir = debugfs_create_dir(devdir, fs.root);
 	e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
 	                                    dev, &tsf_fops);

--


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

* [PATCH 08/10] zd1211rw-d80211: update for wiphy api
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (6 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 07/10] bcm43xx-d80211: " Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-15 14:42 ` [PATCH 09/10] cfg80211: pending config Johannes Berg
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

update zd1211rw-d80211.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 drivers/net/wireless/d80211/zd1211rw/zd_mac.c |    6 +++---
 drivers/net/wireless/d80211/zd1211rw/zd_usb.c |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

--- wireless-dev.orig/drivers/net/wireless/d80211/zd1211rw/zd_mac.c	2007-02-15 13:25:17.567940064 +0100
+++ wireless-dev/drivers/net/wireless/d80211/zd1211rw/zd_mac.c	2007-02-15 13:25:36.357940064 +0100
@@ -53,7 +53,7 @@ int zd_mac_init_hw(struct ieee80211_hw *
 		goto disable_int;
 	ZD_ASSERT(!irqs_disabled());
 	spin_lock_irq(&mac->lock);
-	memcpy(dev->perm_addr, addr, ETH_ALEN);
+	SET_IEEE80211_PERM_ADDR(dev, addr);
 	spin_unlock_irq(&mac->lock);
 
 	r = zd_read_regdomain(chip, &default_regdomain);
@@ -628,7 +628,7 @@ struct ieee80211_hw *zd_mac_alloc(struct
 	mac->dev = dev;
 
 	mac->mode = IEEE80211_IF_TYPE_MGMT;
-	mac->hwaddr = dev->perm_addr;
+	mac->hwaddr = dev->wiphy->perm_addr;
 	mac->requested_channel = 1;
 
 	memcpy(mac->channels, zd_channels, sizeof(zd_channels));
@@ -664,7 +664,7 @@ struct ieee80211_hw *zd_mac_alloc(struct
 	housekeeping_init(mac);
 	INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
 
-	dev->dev = &intf->dev;
+	SET_IEEE80211_DEV(dev, &intf->dev);
 	return dev;
 }
 
--- wireless-dev.orig/drivers/net/wireless/d80211/zd1211rw/zd_usb.c	2007-02-15 13:25:17.657940064 +0100
+++ wireless-dev/drivers/net/wireless/d80211/zd1211rw/zd_usb.c	2007-02-15 13:25:53.167940064 +0100
@@ -955,7 +955,7 @@ static int probe(struct usb_interface *i
 	}
 
 	dev_dbg_f(&intf->dev, "successful\n");
-	dev_info(&intf->dev,"wiphy%d\n", dev->index);
+	dev_info(&intf->dev, "%s\n", wiphy_name(dev->wiphy));
 	return 0;
 error:
 	usb_reset_device(interface_to_usbdev(intf));

--


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

* [PATCH 09/10] cfg80211: pending config
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (7 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 08/10] zd1211rw-d80211: " Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-16 19:10   ` Dan Williams
  2007-02-15 14:42 ` [PATCH 10/10] cfg/nl80211: remove legacy network id Johannes Berg
  2007-02-15 16:02 ` [PATCH 00/10] cfg80211 updates Johannes Berg
  10 siblings, 1 reply; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This introduces the pending config (not used yet) and by doing so
fixes the memory leak in the wext compat code.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 include/net/cfg80211.h     |    4 ++-
 include/net/wireless.h     |    3 ++
 net/wireless/core.h        |    5 ----
 net/wireless/nl80211.c     |    2 -
 net/wireless/wext-compat.c |   46 +++++----------------------------------------
 5 files changed, 13 insertions(+), 47 deletions(-)

--- wireless-dev.orig/include/net/wireless.h	2007-02-15 13:23:41.937940064 +0100
+++ wireless-dev/include/net/wireless.h	2007-02-15 13:23:43.707940064 +0100
@@ -45,6 +45,9 @@ struct wiphy {
  */
 struct wireless_dev {
 	struct wiphy *wiphy;
+
+	/* private to the generic wireless code */
+	struct cfg80211_config pending_config;
 };
 
 /**
--- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 13:23:41.967940064 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-15 13:23:43.707940064 +0100
@@ -11,6 +11,8 @@
  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
  */
 
+#define SSID_MAX_LEN	32
+
 /**
  * struct cfg80211_config - description of a configuration (request)
  */
@@ -19,7 +21,7 @@ struct cfg80211_config {
 	u32 valid;
 
 	s8 ssid_len;
-	u8 *ssid;
+	u8 ssid[SSID_MAX_LEN];
 
 	u16 network_id;
 	s32 rx_sensitivity;
--- wireless-dev.orig/net/wireless/core.h	2007-02-15 13:23:42.037940064 +0100
+++ wireless-dev/net/wireless/core.h	2007-02-15 13:23:43.707940064 +0100
@@ -24,11 +24,6 @@ struct cfg80211_registered_device {
 	/* wiphy index, internal only */
 	int idx;
 
-#ifdef CONFIG_CFG80211_WEXT_COMPAT
-	/* wext compat */
-	struct cfg80211_config *wext_pending_config;
-#endif
-
 	/* must be last because of the way we do wiphy_priv(),
 	 * and it should at least be aligned to NETDEV_ALIGN */
 	struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
--- wireless-dev.orig/net/wireless/nl80211.c	2007-02-15 13:23:42.137940064 +0100
+++ wireless-dev/net/wireless/nl80211.c	2007-02-15 13:23:43.717940064 +0100
@@ -389,8 +389,8 @@ static int nl80211_configure(struct sk_b
 
 	attr = info->attrs[NL80211_ATTR_SSID];
 	if (attr) {
-		config.ssid = nla_data(attr);
 		config.ssid_len = nla_len(attr);
+		memcpy(config.ssid, nla_data(attr), config.ssid_len);
 	}
 
 	attr = info->attrs[NL80211_ATTR_NETWORK_ID];
--- wireless-dev.orig/net/wireless/wext-compat.c	2007-02-15 13:23:42.207940064 +0100
+++ wireless-dev/net/wireless/wext-compat.c	2007-02-15 13:23:43.717940064 +0100
@@ -10,26 +10,16 @@
  *
  * Theory of operation, so to speak:
  *
- * To implement compatibility, I added a new field to struct net_device
- * that contains the pending configuration structure. This is dynamically
- * allocated when needed and freed when committed.
- *
  * Commit is done some time after the last parameter was changed
  * (with each parameter change simply (re-)schedule a timer) or
  * if explicitly asked for. This is probably not what most people
  * would expect, but perfectly fine in the WE API.
  *
- * NB: we leak memory if the user
- *      - changes some settings
- *      - quickly rmmod's the module so that the net device is destroyed
- * Since only root can do it and I don't see a way to hook into
- * the net device's destruction... tough.
- *
- * NB2: Note that each of the wrappers should check if the cfg80211
+ * NB: Note that each of the wrappers should check if the cfg80211
  * user provides the command, and for configure() it must also check
  * if that parameter can be set or not via get_config_valid()
  *
- * NB3: It's really bad that we can't report an error from the timer-
+ * NB2: It's really bad that we can't report an error from the timer-
  * based commit... Hopefully get_config_valid() can catch everything?
  *
  * see set_essid for an example
@@ -67,17 +57,9 @@ static void cfg80211_wx_start_commit_tim
 	 * as well as taking the rtnl lock (due to wext)! */
 }
 
-static struct cfg80211_config *cfg80211_ensure_pending_cfg(
-	struct cfg80211_registered_device *drv)
+static struct cfg80211_config *get_pending_cfg(struct net_device *dev)
 {
-	struct cfg80211_config *cfg = drv->wext_pending_config;
-	if (!cfg)
-		cfg = kmalloc(sizeof(*cfg)+32, GFP_KERNEL);
-	if (cfg) {
-		cfg->ssid = (char*)cfg + sizeof(*cfg);
-		drv->wext_pending_config = cfg;
-	}
-	return cfg;
+	return &dev->ieee80211_ptr->pending_config;
 }
 
 static int cfg80211_wx_set_commit(struct cfg80211_registered_device *drv,
@@ -86,20 +68,8 @@ static int cfg80211_wx_set_commit(struct
 				  union iwreq_data *data,
 				  char *extra)
 {
-	int err;
-
-	if (!drv->wext_pending_config) {
-		err = 0;
-		goto out;
-	}
-
-	err = drv->ops->configure(&drv->wiphy, net_dev,
-				  drv->wext_pending_config);
-
-	kfree(drv->wext_pending_config);
-	drv->wext_pending_config = NULL;
+	int err = -EOPNOTSUPP;
 
- out:
 	return err;
 }
 
@@ -317,11 +287,7 @@ static int cfg80211_wx_set_essid(struct 
 			& CFG80211_CFG_VALID_SSID))
 		goto out;
 
-	cfg = cfg80211_ensure_pending_cfg(drv);
-	if (!cfg) {
-		err = -ENOMEM;
-		goto out;
-	}
+	cfg = get_pending_cfg(net_dev);
 
 	memcpy(cfg->ssid, extra, data->essid.length);
 	cfg->ssid_len = data->essid.length;

--


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

* [PATCH 10/10] cfg/nl80211: remove legacy network id
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (8 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 09/10] cfg80211: pending config Johannes Berg
@ 2007-02-15 14:42 ` Johannes Berg
  2007-02-16 19:12   ` Dan Williams
  2007-02-15 16:02 ` [PATCH 00/10] cfg80211 updates Johannes Berg
  10 siblings, 1 reply; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 14:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

This patch removes the legacy network ID.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
 include/linux/nl80211.h |    4 ----
 include/net/cfg80211.h  |   10 ++++------
 net/wireless/nl80211.c  |   10 ----------
 3 files changed, 4 insertions(+), 20 deletions(-)

--- wireless-dev.orig/include/linux/nl80211.h	2007-02-15 12:28:37.497940064 +0100
+++ wireless-dev/include/linux/nl80211.h	2007-02-15 12:28:42.007940064 +0100
@@ -161,10 +161,6 @@ enum {
 	/* wiphy list */
 	NL80211_ATTR_WIPHY_LIST,
 
-	/* attributes used for configuration */
-	/* network ID (pre 802.11 HW) */
-	NL80211_ATTR_NETWORK_ID,
-
 	/* channel, 1-14 are B/G */
 	NL80211_ATTR_CHANNEL,
 
--- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 12:28:41.297940064 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-15 12:28:42.007940064 +0100
@@ -23,7 +23,6 @@ struct cfg80211_config {
 	s8 ssid_len;
 	u8 ssid[SSID_MAX_LEN];
 
-	u16 network_id;
 	s32 rx_sensitivity;
 	u32 transmit_power;
 	u32 fragmentation_threshold;
@@ -31,11 +30,10 @@ struct cfg80211_config {
 };
 
 #define CFG80211_CFG_VALID_SSID			(1<<0)
-#define CFG80211_CFG_VALID_NWID			(1<<1)
-#define CFG80211_CFG_VALID_RX_SENSITIVITY	(1<<2)
-#define CFG80211_CFG_VALID_TRANSMIT_POWER	(1<<3)
-#define CFG80211_CFG_VALID_FRAG_THRESHOLD	(1<<4)
-#define CFG80211_CFG_VALID_CHANNEL		(1<<5)
+#define CFG80211_CFG_VALID_RX_SENSITIVITY	(1<<1)
+#define CFG80211_CFG_VALID_TRANSMIT_POWER	(1<<2)
+#define CFG80211_CFG_VALID_FRAG_THRESHOLD	(1<<3)
+#define CFG80211_CFG_VALID_CHANNEL		(1<<4)
 
 struct scan_channel {
 	u32 channel;
--- wireless-dev.orig/net/wireless/nl80211.c	2007-02-15 12:28:41.307940064 +0100
+++ wireless-dev/net/wireless/nl80211.c	2007-02-15 12:28:42.007940064 +0100
@@ -75,7 +75,6 @@ static struct nla_policy nl80211_policy[
 				 .len = NL80211_MAX_FRAME_LEN },
 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
 	[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
-	[NL80211_ATTR_NETWORK_ID] = { .type = NLA_U16 },
 	[NL80211_ATTR_CHANNEL] = { .type = NLA_U32 },
 	[NL80211_ATTR_RX_SENSITIVITY] = { .type = NLA_U32 },
 	[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
@@ -393,12 +392,6 @@ static int nl80211_configure(struct sk_b
 		memcpy(config.ssid, nla_data(attr), config.ssid_len);
 	}
 
-	attr = info->attrs[NL80211_ATTR_NETWORK_ID];
-	if (attr) {
-		config.valid |= CFG80211_CFG_VALID_NWID;
-		config.network_id = nla_get_u16(attr);
-	}
-
 	attr = info->attrs[NL80211_ATTR_RX_SENSITIVITY];
 	if (attr) {
 		config.valid |= CFG80211_CFG_VALID_RX_SENSITIVITY;
@@ -465,9 +458,6 @@ static int nl80211_get_config(struct sk_
 	if (config.ssid)
 		NLA_PUT_STRING(msg, NL80211_ATTR_SSID, config.ssid);
 
-	if (config.valid & CFG80211_CFG_VALID_NWID)
-		NLA_PUT_U16(msg, NL80211_ATTR_NETWORK_ID, config.network_id);
-
 	if (config.valid & CFG80211_CFG_VALID_RX_SENSITIVITY)
 		NLA_PUT_U32(msg, NL80211_ATTR_RX_SENSITIVITY, (u32)config.rx_sensitivity);
 

--


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

* Re: [PATCH 07/10] bcm43xx-d80211: update for wiphy api
  2007-02-15 14:42 ` [PATCH 07/10] bcm43xx-d80211: " Johannes Berg
@ 2007-02-15 15:09   ` Michael Buesch
  2007-02-15 15:18     ` Johannes Berg
  0 siblings, 1 reply; 24+ messages in thread
From: Michael Buesch @ 2007-02-15 15:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville, Jiri Benc

On Thursday 15 February 2007 15:42, Johannes Berg wrote:
> update bcm43xx-d80211.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

ACK for this.

> ---
> Really bcm43xx should be using the new wiphy debugfs stuff as well,
> but I can't figure out what the hell it is doing when multiple
> devices exist in a system. Thing is the new debugfs dir is only

What do you mean? It registers multiple ieee80211_hw, of course.
Look at bcm43xx_wireless_init(), that's per-card (not per core).

> created for d80211 drivers when calling register_hw() and all items
> must be gone from it when calling free_hw()...
> 
> ---
>  drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c |    2 +-
>  drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c    |   15 ++++++---------
>  2 files changed, 7 insertions(+), 10 deletions(-)
> 
> --- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2007-02-15 13:50:28.967940064 +0100
> +++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2007-02-15 14:01:33.486635438 +0100
> @@ -3282,7 +3282,7 @@ static int bcm43xx_wireless_core_init(st
>  	ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
>  	bcm43xx_macfilter_clear(dev, BCM43xx_MACFILTER_ASSOC);
>  	bcm43xx_macfilter_set(dev, BCM43xx_MACFILTER_SELF,
> -			      (u8 *)(wl->hw->perm_addr));
> +			      (u8 *)(wl->hw->wiphy->perm_addr));
>  	bcm43xx_security_init(dev);
>  	bcm43xx_measure_channel_change_time(dev);
>  
> @@ -3743,14 +3743,11 @@ static int bcm43xx_wireless_init(struct 
>  		    IEEE80211_HW_WEP_INCLUDE_IV;
>  	hw->maxssi = BCM43xx_RX_MAX_SSI;
>  	hw->queues = 1;
> -	hw->dev = &dev->dev;
> -	if (is_valid_ether_addr(sprom->r1.et1mac)) {
> -		memcpy(hw->perm_addr, sprom->r1.et1mac,
> -		       ARRAY_SIZE(hw->perm_addr));
> -	} else {
> -		memcpy(hw->perm_addr, sprom->r1.il0mac,
> -		       ARRAY_SIZE(hw->perm_addr));
> -	}
> +	SET_IEEE80211_DEV(hw, &dev->dev);
> +	if (is_valid_ether_addr(sprom->r1.et1mac))
> +		SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac);
> +	else
> +		SET_IEEE80211_PERM_ADDR(hw, sprom->r1.il0mac);
>  
>  	/* Get and initialize struct bcm43xx_wl */
>  	wl = hw_to_bcm43xx_wl(hw);
> --- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c	2007-02-15 13:50:28.917940064 +0100
> +++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c	2007-02-15 14:02:18.646635438 +0100
> @@ -308,7 +308,7 @@ void bcm43xx_debugfs_add_device(struct b
>  
>  	dev->dfsentry = e;
>  
> -	snprintf(devdir, sizeof(devdir), "wiphy%d", dev->wl->hw->index);
> +	snprintf(devdir, sizeof(devdir), "%s", wiphy_name(dev->wl->hw->wiphy));
>  	e->subdir = debugfs_create_dir(devdir, fs.root);
>  	e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
>  	                                    dev, &tsf_fops);
> 
> --
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

-- 
Greetings Michael.

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

* Re: [PATCH 07/10] bcm43xx-d80211: update for wiphy api
  2007-02-15 15:09   ` Michael Buesch
@ 2007-02-15 15:18     ` Johannes Berg
  0 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 15:18 UTC (permalink / raw)
  To: Michael Buesch; +Cc: linux-wireless, John Linville, Jiri Benc

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

On Thu, 2007-02-15 at 16:09 +0100, Michael Buesch wrote:

> > ---
> > Really bcm43xx should be using the new wiphy debugfs stuff as well,
> > but I can't figure out what the hell it is doing when multiple
> > devices exist in a system. Thing is the new debugfs dir is only
> 
> What do you mean? It registers multiple ieee80211_hw, of course.
> Look at bcm43xx_wireless_init(), that's per-card (not per core).

Ok. I was confused with all the different structs and didn't find the
proper point to register stuff in debugfs after ieee80211_hw_register()

johannes

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

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

* Re: [PATCH 00/10] cfg80211 updates
  2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
                   ` (9 preceding siblings ...)
  2007-02-15 14:42 ` [PATCH 10/10] cfg/nl80211: remove legacy network id Johannes Berg
@ 2007-02-15 16:02 ` Johannes Berg
  10 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 16:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

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

On Thu, 2007-02-15 at 15:42 +0100, Johannes Berg wrote:

> it seems to for example that bcm43xx's debugfs
> stuff doesn't work afterwards

That's actually wrong, I had the note there and then found the
problem...

johannes

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

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

* Re: [PATCH 06/10] d80211: update for wiphy api
  2007-02-15 14:42 ` [PATCH 06/10] d80211: update for wiphy api Johannes Berg
@ 2007-02-15 16:16   ` Johannes Berg
  2007-02-19 20:49   ` Jiri Benc
  1 sibling, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-15 16:16 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville, Jiri Benc

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

As a follow up to this, I may post a patch that moves all the sysfs
stuff d80211 currently does into debugfs where I think most of it should
actually be. Then we can decide on a case-by-case basis which ones
should really be part of the userspace API.

johannes

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

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

* Re: [PATCH 09/10] cfg80211: pending config
  2007-02-15 14:42 ` [PATCH 09/10] cfg80211: pending config Johannes Berg
@ 2007-02-16 19:10   ` Dan Williams
  2007-02-16 20:22     ` Johannes Berg
  2007-02-16 20:49     ` Michael Wu
  0 siblings, 2 replies; 24+ messages in thread
From: Dan Williams @ 2007-02-16 19:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville, Jiri Benc

On Thu, 2007-02-15 at 15:42 +0100, Johannes Berg wrote:
> plain text document attachment (009-pending-config.patch)
> This introduces the pending config (not used yet) and by doing so
> fixes the memory leak in the wext compat code.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> 
> ---
>  include/net/cfg80211.h     |    4 ++-
>  include/net/wireless.h     |    3 ++
>  net/wireless/core.h        |    5 ----
>  net/wireless/nl80211.c     |    2 -
>  net/wireless/wext-compat.c |   46 +++++----------------------------------------
>  5 files changed, 13 insertions(+), 47 deletions(-)
> 
> --- wireless-dev.orig/include/net/wireless.h	2007-02-15 13:23:41.937940064 +0100
> +++ wireless-dev/include/net/wireless.h	2007-02-15 13:23:43.707940064 +0100
> @@ -45,6 +45,9 @@ struct wiphy {
>   */
>  struct wireless_dev {
>  	struct wiphy *wiphy;
> +
> +	/* private to the generic wireless code */
> +	struct cfg80211_config pending_config;
>  };
>  
>  /**
> --- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 13:23:41.967940064 +0100
> +++ wireless-dev/include/net/cfg80211.h	2007-02-15 13:23:43.707940064 +0100
> @@ -11,6 +11,8 @@
>   * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
>   */
>  
> +#define SSID_MAX_LEN	32
> +

This has _got_ to be defined somewhere else in the stack?  Can we use
that define, or is it being moved to here?  Seems a shame to have it
more than one place.

On a side note, many many drivers need something like this, and many
many drivers redefine it internally.  Is there some header that all
drivers (even fullmac like airo, orinoco, atmel, and libertas) can get
this from?

>  /**
>   * struct cfg80211_config - description of a configuration (request)
>   */
> @@ -19,7 +21,7 @@ struct cfg80211_config {
>  	u32 valid;
>  
>  	s8 ssid_len;
> -	u8 *ssid;
> +	u8 ssid[SSID_MAX_LEN];
>  
>  	u16 network_id;
>  	s32 rx_sensitivity;
> --- wireless-dev.orig/net/wireless/core.h	2007-02-15 13:23:42.037940064 +0100
> +++ wireless-dev/net/wireless/core.h	2007-02-15 13:23:43.707940064 +0100
> @@ -24,11 +24,6 @@ struct cfg80211_registered_device {
>  	/* wiphy index, internal only */
>  	int idx;
>  
> -#ifdef CONFIG_CFG80211_WEXT_COMPAT
> -	/* wext compat */
> -	struct cfg80211_config *wext_pending_config;
> -#endif
> -
>  	/* must be last because of the way we do wiphy_priv(),
>  	 * and it should at least be aligned to NETDEV_ALIGN */
>  	struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
> --- wireless-dev.orig/net/wireless/nl80211.c	2007-02-15 13:23:42.137940064 +0100
> +++ wireless-dev/net/wireless/nl80211.c	2007-02-15 13:23:43.717940064 +0100
> @@ -389,8 +389,8 @@ static int nl80211_configure(struct sk_b
>  
>  	attr = info->attrs[NL80211_ATTR_SSID];
>  	if (attr) {
> -		config.ssid = nla_data(attr);
>  		config.ssid_len = nla_len(attr);
> +		memcpy(config.ssid, nla_data(attr), config.ssid_len);
>  	}
>  
>  	attr = info->attrs[NL80211_ATTR_NETWORK_ID];
> --- wireless-dev.orig/net/wireless/wext-compat.c	2007-02-15 13:23:42.207940064 +0100
> +++ wireless-dev/net/wireless/wext-compat.c	2007-02-15 13:23:43.717940064 +0100
> @@ -10,26 +10,16 @@
>   *
>   * Theory of operation, so to speak:
>   *
> - * To implement compatibility, I added a new field to struct net_device
> - * that contains the pending configuration structure. This is dynamically
> - * allocated when needed and freed when committed.
> - *
>   * Commit is done some time after the last parameter was changed
>   * (with each parameter change simply (re-)schedule a timer) or
>   * if explicitly asked for. This is probably not what most people
>   * would expect, but perfectly fine in the WE API.
>   *
> - * NB: we leak memory if the user
> - *      - changes some settings
> - *      - quickly rmmod's the module so that the net device is destroyed
> - * Since only root can do it and I don't see a way to hook into
> - * the net device's destruction... tough.
> - *
> - * NB2: Note that each of the wrappers should check if the cfg80211
> + * NB: Note that each of the wrappers should check if the cfg80211
>   * user provides the command, and for configure() it must also check
>   * if that parameter can be set or not via get_config_valid()
>   *
> - * NB3: It's really bad that we can't report an error from the timer-
> + * NB2: It's really bad that we can't report an error from the timer-
>   * based commit... Hopefully get_config_valid() can catch everything?

Well, we'd have two choices; first, a netlink notification that the
config was unsuccessful, or second a WEXT SIOCSIWAP event of
00:00:00:xxx for WE compat.  Why wouldn't one of those work?

Dan

>   *
>   * see set_essid for an example
> @@ -67,17 +57,9 @@ static void cfg80211_wx_start_commit_tim
>  	 * as well as taking the rtnl lock (due to wext)! */
>  }
>  
> -static struct cfg80211_config *cfg80211_ensure_pending_cfg(
> -	struct cfg80211_registered_device *drv)
> +static struct cfg80211_config *get_pending_cfg(struct net_device *dev)
>  {
> -	struct cfg80211_config *cfg = drv->wext_pending_config;
> -	if (!cfg)
> -		cfg = kmalloc(sizeof(*cfg)+32, GFP_KERNEL);
> -	if (cfg) {
> -		cfg->ssid = (char*)cfg + sizeof(*cfg);
> -		drv->wext_pending_config = cfg;
> -	}
> -	return cfg;
> +	return &dev->ieee80211_ptr->pending_config;
>  }
>  
>  static int cfg80211_wx_set_commit(struct cfg80211_registered_device *drv,
> @@ -86,20 +68,8 @@ static int cfg80211_wx_set_commit(struct
>  				  union iwreq_data *data,
>  				  char *extra)
>  {
> -	int err;
> -
> -	if (!drv->wext_pending_config) {
> -		err = 0;
> -		goto out;
> -	}
> -
> -	err = drv->ops->configure(&drv->wiphy, net_dev,
> -				  drv->wext_pending_config);
> -
> -	kfree(drv->wext_pending_config);
> -	drv->wext_pending_config = NULL;
> +	int err = -EOPNOTSUPP;
>  
> - out:
>  	return err;
>  }
>  
> @@ -317,11 +287,7 @@ static int cfg80211_wx_set_essid(struct 
>  			& CFG80211_CFG_VALID_SSID))
>  		goto out;
>  
> -	cfg = cfg80211_ensure_pending_cfg(drv);
> -	if (!cfg) {
> -		err = -ENOMEM;
> -		goto out;
> -	}
> +	cfg = get_pending_cfg(net_dev);
>  
>  	memcpy(cfg->ssid, extra, data->essid.length);
>  	cfg->ssid_len = data->essid.length;
> 
> --
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 10/10] cfg/nl80211: remove legacy network id
  2007-02-15 14:42 ` [PATCH 10/10] cfg/nl80211: remove legacy network id Johannes Berg
@ 2007-02-16 19:12   ` Dan Williams
  2007-02-16 20:16     ` Johannes Berg
  0 siblings, 1 reply; 24+ messages in thread
From: Dan Williams @ 2007-02-16 19:12 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville, Jiri Benc

On Thu, 2007-02-15 at 15:42 +0100, Johannes Berg wrote:
> plain text document attachment (010-drop-nwid.patch)
> This patch removes the legacy network ID.

Don't we still need the WEXT compat bits for nwid?  Or are we just axing
it entirely?  What legacy drivers actually use this that are still in
the kernel?

Dan

> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> 
> ---
>  include/linux/nl80211.h |    4 ----
>  include/net/cfg80211.h  |   10 ++++------
>  net/wireless/nl80211.c  |   10 ----------
>  3 files changed, 4 insertions(+), 20 deletions(-)
> 
> --- wireless-dev.orig/include/linux/nl80211.h	2007-02-15 12:28:37.497940064 +0100
> +++ wireless-dev/include/linux/nl80211.h	2007-02-15 12:28:42.007940064 +0100
> @@ -161,10 +161,6 @@ enum {
>  	/* wiphy list */
>  	NL80211_ATTR_WIPHY_LIST,
>  
> -	/* attributes used for configuration */
> -	/* network ID (pre 802.11 HW) */
> -	NL80211_ATTR_NETWORK_ID,
> -
>  	/* channel, 1-14 are B/G */
>  	NL80211_ATTR_CHANNEL,
>  
> --- wireless-dev.orig/include/net/cfg80211.h	2007-02-15 12:28:41.297940064 +0100
> +++ wireless-dev/include/net/cfg80211.h	2007-02-15 12:28:42.007940064 +0100
> @@ -23,7 +23,6 @@ struct cfg80211_config {
>  	s8 ssid_len;
>  	u8 ssid[SSID_MAX_LEN];
>  
> -	u16 network_id;
>  	s32 rx_sensitivity;
>  	u32 transmit_power;
>  	u32 fragmentation_threshold;
> @@ -31,11 +30,10 @@ struct cfg80211_config {
>  };
>  
>  #define CFG80211_CFG_VALID_SSID			(1<<0)
> -#define CFG80211_CFG_VALID_NWID			(1<<1)
> -#define CFG80211_CFG_VALID_RX_SENSITIVITY	(1<<2)
> -#define CFG80211_CFG_VALID_TRANSMIT_POWER	(1<<3)
> -#define CFG80211_CFG_VALID_FRAG_THRESHOLD	(1<<4)
> -#define CFG80211_CFG_VALID_CHANNEL		(1<<5)
> +#define CFG80211_CFG_VALID_RX_SENSITIVITY	(1<<1)
> +#define CFG80211_CFG_VALID_TRANSMIT_POWER	(1<<2)
> +#define CFG80211_CFG_VALID_FRAG_THRESHOLD	(1<<3)
> +#define CFG80211_CFG_VALID_CHANNEL		(1<<4)
>  
>  struct scan_channel {
>  	u32 channel;
> --- wireless-dev.orig/net/wireless/nl80211.c	2007-02-15 12:28:41.307940064 +0100
> +++ wireless-dev/net/wireless/nl80211.c	2007-02-15 12:28:42.007940064 +0100
> @@ -75,7 +75,6 @@ static struct nla_policy nl80211_policy[
>  				 .len = NL80211_MAX_FRAME_LEN },
>  	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
>  	[NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
> -	[NL80211_ATTR_NETWORK_ID] = { .type = NLA_U16 },
>  	[NL80211_ATTR_CHANNEL] = { .type = NLA_U32 },
>  	[NL80211_ATTR_RX_SENSITIVITY] = { .type = NLA_U32 },
>  	[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
> @@ -393,12 +392,6 @@ static int nl80211_configure(struct sk_b
>  		memcpy(config.ssid, nla_data(attr), config.ssid_len);
>  	}
>  
> -	attr = info->attrs[NL80211_ATTR_NETWORK_ID];
> -	if (attr) {
> -		config.valid |= CFG80211_CFG_VALID_NWID;
> -		config.network_id = nla_get_u16(attr);
> -	}
> -
>  	attr = info->attrs[NL80211_ATTR_RX_SENSITIVITY];
>  	if (attr) {
>  		config.valid |= CFG80211_CFG_VALID_RX_SENSITIVITY;
> @@ -465,9 +458,6 @@ static int nl80211_get_config(struct sk_
>  	if (config.ssid)
>  		NLA_PUT_STRING(msg, NL80211_ATTR_SSID, config.ssid);
>  
> -	if (config.valid & CFG80211_CFG_VALID_NWID)
> -		NLA_PUT_U16(msg, NL80211_ATTR_NETWORK_ID, config.network_id);
> -
>  	if (config.valid & CFG80211_CFG_VALID_RX_SENSITIVITY)
>  		NLA_PUT_U32(msg, NL80211_ATTR_RX_SENSITIVITY, (u32)config.rx_sensitivity);
>  
> 
> --
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 10/10] cfg/nl80211: remove legacy network id
  2007-02-16 19:12   ` Dan Williams
@ 2007-02-16 20:16     ` Johannes Berg
  0 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-16 20:16 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-wireless, John Linville, Jiri Benc

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

On Fri, 2007-02-16 at 14:12 -0500, Dan Williams wrote:

> Don't we still need the WEXT compat bits for nwid?  Or are we just axing
> it entirely?  What legacy drivers actually use this that are still in
> the kernel?

Well, I was thinking that we'll probably never get around to converting
those legacy drivers that use nwid to cfg80211. And when/if we do we can
add it back.

johannes

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

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

* Re: [PATCH 09/10] cfg80211: pending config
  2007-02-16 19:10   ` Dan Williams
@ 2007-02-16 20:22     ` Johannes Berg
  2007-02-16 20:49     ` Michael Wu
  1 sibling, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-16 20:22 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-wireless, John Linville, Jiri Benc

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

On Fri, 2007-02-16 at 14:10 -0500, Dan Williams wrote:

> This has _got_ to be defined somewhere else in the stack?  Can we use
> that define, or is it being moved to here?  Seems a shame to have it
> more than one place.

It probably is...

> On a side note, many many drivers need something like this, and many
> many drivers redefine it internally.  Is there some header that all
> drivers (even fullmac like airo, orinoco, atmel, and libertas) can get
> this from?

Yeah, we should have some sort of stack/driver agnosting IEEE 802.11
defines header w/o functions in it. Then I'd use that here too.


> > - * NB3: It's really bad that we can't report an error from the timer-
> > + * NB2: It's really bad that we can't report an error from the timer-
> >   * based commit... Hopefully get_config_valid() can catch everything?
> 
> Well, we'd have two choices; first, a netlink notification that the
> config was unsuccessful, or second a WEXT SIOCSIWAP event of
> 00:00:00:xxx for WE compat.  Why wouldn't one of those work?

Yes, we can give a notification that it was unsuccessful. For wext, we
don't actually need all this I think because we do it with commit
anyway.

johannes

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

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

* Re: [PATCH 09/10] cfg80211: pending config
  2007-02-16 19:10   ` Dan Williams
  2007-02-16 20:22     ` Johannes Berg
@ 2007-02-16 20:49     ` Michael Wu
  1 sibling, 0 replies; 24+ messages in thread
From: Michael Wu @ 2007-02-16 20:49 UTC (permalink / raw)
  To: Dan Williams; +Cc: Johannes Berg, linux-wireless, John Linville, Jiri Benc

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

On Friday 16 February 2007 14:10, Dan Williams wrote:
> > --- wireless-dev.orig/include/net/cfg80211.h	2007-02-15
> > 13:23:41.967940064 +0100 +++
> > wireless-dev/include/net/cfg80211.h	2007-02-15 13:23:43.707940064 +0100
> > @@ -11,6 +11,8 @@
> >   * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
> >   */
> >
> > +#define SSID_MAX_LEN	32
> > +
>
> This has _got_ to be defined somewhere else in the stack?  Can we use
> that define, or is it being moved to here?  Seems a shame to have it
> more than one place.
>
> On a side note, many many drivers need something like this, and many
> many drivers redefine it internally.  Is there some header that all
> drivers (even fullmac like airo, orinoco, atmel, and libertas) can get
> this from?
>
That's what include/linux/ieee80211.h is (or will be) for.

-Michael Wu

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [PATCH 03/10] introduce wiphy concept
  2007-02-15 14:42 ` [PATCH 03/10] introduce wiphy concept Johannes Berg
@ 2007-02-19 20:37   ` Jiri Benc
  2007-02-19 20:55     ` Johannes Berg
  0 siblings, 1 reply; 24+ messages in thread
From: Jiri Benc @ 2007-02-19 20:37 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville

On Thu, 15 Feb 2007 15:42:44 +0100, Johannes Berg wrote:
> For the future:
> 
> Maybe instead of having ieee80211_ptr point to a struct wireless_dev
> (which can be allocated along with the netdev) we should mandate that
> each wireless netdev is allocated via a new function that puts the
> wireless_dev struct as the first part of the private area of the netdev,
> that way getting to it is just a simple addition instead of following
> a pointer... and we can also drop ieee80211_ptr from struct net_device.

Currently, you need to distinguish whether some random net_device is
wireless device or not at some places. At least d80211 needs that (yes,
ifindex doesn't wrap often, so those are just safety checks, but - well
- I'd like to be safe).

How can this be effectively achieved if ieee80211_ptr is dropped?

Thanks,

 Jiri

-- 
Jiri Benc
SUSE Labs

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

* Re: [PATCH 06/10] d80211: update for wiphy api
  2007-02-15 14:42 ` [PATCH 06/10] d80211: update for wiphy api Johannes Berg
  2007-02-15 16:16   ` Johannes Berg
@ 2007-02-19 20:49   ` Jiri Benc
  2007-02-19 21:03     ` Johannes Berg
  1 sibling, 1 reply; 24+ messages in thread
From: Jiri Benc @ 2007-02-19 20:49 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Linville

On Thu, 15 Feb 2007 15:42:47 +0100, Johannes Berg wrote:
> 
> --- wireless-dev.orig/include/net/d80211.h	2007-02-15 13:28:04.547940064 +0100
> +++ wireless-dev/include/net/d80211.h	2007-02-15 13:28:52.417940064 +0100
> @@ -16,6 +16,8 @@
>  #include <linux/wireless.h>
>  #include <linux/device.h>
>  #include <linux/ieee80211.h>
> +#include <net/wireless.h>
> +#include <net/cfg80211.h>
>  
>  /* Note! Only ieee80211_tx_status_irqsafe() and ieee80211_rx_irqsafe() can be
>   * called in hardware interrupt context. The low-level driver must not call any
> @@ -457,8 +459,12 @@ typedef enum {
>  
>  /* This is driver-visible part of the per-hw state the stack keeps. */
>  struct ieee80211_hw {
> -	/* these are assigned by d80211, don't write */
> -	int index;
> +	/* points to the cfg80211 wiphy for this piece. Note
> +	 * that you must fill in the perm_addr and dev fields
> +	 * of this structure, use the macros provided below. */
> +	struct wiphy *wiphy;
> +
> +	/* assigned by d80211, don't write */
>  	struct ieee80211_conf conf;
>  
>  	/* Pointer to the private area that was

Couldn't we just allow embedding of wiphy into a custom structure?
Something like:

struct ieee80211_hw {
	struct wiphy wiphy;
	...
}

This way the memory could become less fragmented and less pointer
dereferencing would be needed.

 Jiri

-- 
Jiri Benc
SUSE Labs

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

* Re: [PATCH 03/10] introduce wiphy concept
  2007-02-19 20:37   ` Jiri Benc
@ 2007-02-19 20:55     ` Johannes Berg
  0 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-19 20:55 UTC (permalink / raw)
  To: Jiri Benc; +Cc: linux-wireless, John Linville

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

On Mon, 2007-02-19 at 21:37 +0100, Jiri Benc wrote:

> Currently, you need to distinguish whether some random net_device is
> wireless device or not at some places. At least d80211 needs that (yes,
> ifindex doesn't wrap often, so those are just safety checks, but - well
> - I'd like to be safe).
> 
> How can this be effectively achieved if ieee80211_ptr is dropped?

Not easily at all. Just thoughts anyway :)

johannes

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

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

* Re: [PATCH 06/10] d80211: update for wiphy api
  2007-02-19 20:49   ` Jiri Benc
@ 2007-02-19 21:03     ` Johannes Berg
  0 siblings, 0 replies; 24+ messages in thread
From: Johannes Berg @ 2007-02-19 21:03 UTC (permalink / raw)
  To: Jiri Benc; +Cc: linux-wireless, John Linville

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

On Mon, 2007-02-19 at 21:49 +0100, Jiri Benc wrote:

> Couldn't we just allow embedding of wiphy into a custom structure?
> Something like:
> 
> struct ieee80211_hw {
> 	struct wiphy wiphy;
> 	...
> }
> 
> This way the memory could become less fragmented and less pointer
> dereferencing would be needed.

Actually, if you look at the memory layout in ieee80211.c, struct
ieee80211_hw is part of the private area allocated along with the struct
wiphy, so it really is:

[internal stuff]
struct wiphy {
...
}
struct ieee80211_hw {
...
}

What we could do is add

static inline struct wiphy *priv_to_wiphy(void *priv)
{
	return container_of(priv, struct wiphy, priv);
}

to the net/wireless.h header. Then we could drop the wiphy field
completely.

johannes

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

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

end of thread, other threads:[~2007-02-19 21:03 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-15 14:42 [PATCH 00/10] cfg80211 updates Johannes Berg
2007-02-15 14:42 ` [PATCH 01/10] remove cfg80211/wext-nl compatibility Johannes Berg
2007-02-15 14:42 ` [PATCH 02/10] update cfg80211/wext and wext code Johannes Berg
2007-02-15 14:42 ` [PATCH 03/10] introduce wiphy concept Johannes Berg
2007-02-19 20:37   ` Jiri Benc
2007-02-19 20:55     ` Johannes Berg
2007-02-15 14:42 ` [PATCH 04/10] cfg/nl80211: make association explicit Johannes Berg
2007-02-15 14:42 ` [PATCH 05/10] wext: clean up Johannes Berg
2007-02-15 14:42 ` [PATCH 06/10] d80211: update for wiphy api Johannes Berg
2007-02-15 16:16   ` Johannes Berg
2007-02-19 20:49   ` Jiri Benc
2007-02-19 21:03     ` Johannes Berg
2007-02-15 14:42 ` [PATCH 07/10] bcm43xx-d80211: " Johannes Berg
2007-02-15 15:09   ` Michael Buesch
2007-02-15 15:18     ` Johannes Berg
2007-02-15 14:42 ` [PATCH 08/10] zd1211rw-d80211: " Johannes Berg
2007-02-15 14:42 ` [PATCH 09/10] cfg80211: pending config Johannes Berg
2007-02-16 19:10   ` Dan Williams
2007-02-16 20:22     ` Johannes Berg
2007-02-16 20:49     ` Michael Wu
2007-02-15 14:42 ` [PATCH 10/10] cfg/nl80211: remove legacy network id Johannes Berg
2007-02-16 19:12   ` Dan Williams
2007-02-16 20:16     ` Johannes Berg
2007-02-15 16:02 ` [PATCH 00/10] cfg80211 updates Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.