linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] cfg80211 changes for wireless-dev
@ 2007-02-09 16:24 johannes
  2007-02-09 16:24 ` [PATCH 1/5] cfg80211: update to code submitted to mainline johannes
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: johannes @ 2007-02-09 16:24 UTC (permalink / raw)
  To: linux-wireless

This makes the version of cfg80211 in wireless-dev mostly identical
(except for nl80211) with the version I'm submitting for mainline.

johannes


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

* [PATCH 1/5] cfg80211: update to code submitted to mainline
  2007-02-09 16:24 [PATCH 0/5] cfg80211 changes for wireless-dev johannes
@ 2007-02-09 16:24 ` johannes
  2007-02-11 13:13   ` Johannes Berg
  2007-02-09 16:24 ` [PATCH 2/5] wext: clean up johannes
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: johannes @ 2007-02-09 16:24 UTC (permalink / raw)
  To: linux-wireless

This updates cfg80211 to be really similar to the code
I submitted for mainline.

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

---
 include/linux/netdevice.h  |    8 
 include/linux/nl80211.h    |    5 
 include/net/cfg80211.h     |  134 +++-
 include/net/iw_handler.h   |    3 
 include/net/wireless.h     |   23 
 net/Kconfig                |   14 
 net/core/dev.c             |   67 --
 net/wireless/Makefile      |   24 
 net/wireless/core.c        |  166 +++---
 net/wireless/core.h        |   43 -
 net/wireless/nl80211.c     |   78 --
 net/wireless/sysfs.c       |   65 ++
 net/wireless/sysfs.h       |   10 
 net/wireless/wext-common.c |   65 ++
 net/wireless/wext-compat.c | 1231 ++++++++-------------------------------------
 net/wireless/wext-export.c |   29 +
 net/wireless/wext-mod.c    |   20 
 net/wireless/wext-old.c    |   14 
 net/wireless/wext.h        |   42 +
 19 files changed, 701 insertions(+), 1340 deletions(-)

--- wireless-dev.orig/include/linux/netdevice.h	2007-02-09 17:08:25.543840519 +0100
+++ wireless-dev/include/linux/netdevice.h	2007-02-09 17:08:44.023840519 +0100
@@ -42,6 +42,8 @@
 struct vlan_group;
 struct ethtool_ops;
 struct netpoll_info;
+/* 802.11 specific */
+struct wiphy;
 					/* source back-compat hooks */
 #define SET_ETHTOOL_OPS(netdev,ops) \
 	( (netdev)->ethtool_ops = (ops) )
@@ -355,10 +357,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;
 
 	/*
@@ -403,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 wiphy		*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-09 17:08:25.833840519 +0100
+++ wireless-dev/include/net/cfg80211.h	2007-02-09 17:08:44.033840519 +0100
@@ -2,19 +2,45 @@
 #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>
+#include <linux/device.h>
 
 /*
- * 802.11 configuration in-kernel interface
+ * 802.11 configuration and wiphy management in-kernel interface
  *
  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
  */
 
 /**
+ * struct wiphy
+ *
+ * @wiphy_index: the wiphy index assigned to this item
+ * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
+ * @name: name of this wiphy
+ */
+struct wiphy {
+	/* assign these fields before you register the wiphy */
+
+	/* permanent MAC address */
+	u8 perm_addr[ETH_ALEN];
+
+	/* the actual hardware */
+	struct device *dev;
+
+	/* fields below are read-only, assigned by cfg80211 */
+
+	/* index assigned to this wiphy */
+	int wiphy_index;
+	/* dir in /sys/class/ieee80211/ */
+	struct class_device class_dev;
+
+	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+/**
  * struct cfg80211_config - description of a configuration (request)
  */
 struct cfg80211_config {
@@ -63,18 +89,12 @@ struct scan_params {
  * 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.
- *
- * @inject_packet: inject the given frame with the NL80211_FLAG_*
- *		   flags onto the given queue.
+ * @list_interfaces: Call the one() function with the given data and the
+ *                   ifindex for each interface belonging to the wiphy.
+ *		     This callback is required.
  *
  * @add_virtual_intf: create a new virtual interface with the given name
  *
@@ -82,13 +102,17 @@ struct scan_params {
  *
  * @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)
  *
@@ -118,74 +142,93 @@ 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,
-				 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	(*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);
 
 
-	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
+ * wiphy_priv - return priv from wiphy
+ */
+static inline void *wiphy_priv(struct wiphy *wiphy)
+{
+	return &wiphy->priv;
+}
+
+/**
+ * wiphy_new - create a new wiphy for use with cfg80211
  *
- * register a given method structure with the cfg80211 system
- * and associate the 'priv' pointer with it.
+ * create a new wiphy and associate the given operations with it.
+ * @sizeof_priv bytes are allocated for private use.
  *
- * Returns a non-negative wiphy index or a negative error code.
+ * 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
  *
- * NOTE: for proper operation, this priv pointer MUST also be
- * assigned to each &struct net_device's @ieee80211_ptr member!
+ * register the given wiphy
+ *
+ * Returns a non-negative wiphy index or a negative error code.
  */
-extern int cfg80211_register(struct cfg80211_ops *ops, void *priv);
+extern int wiphy_register(struct wiphy *wiphy);
 
 /**
- * cfg80211_unregister - deregister a wiphy from cfg80211
+ * 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 cfg80211_unregister(void *priv);
+extern void wiphy_unregister(struct wiphy *wiphy);
+
+/**
+ * wiphy_free - free wiphy
+ */
+extern void wiphy_free(struct wiphy *wiphy);
+
 
 /* helper functions specific to nl80211 */
 extern void *nl80211hdr_put(struct sk_buff *skb, u32 pid,
@@ -193,13 +236,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);
-#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/wireless/Makefile	2007-02-09 17:08:26.033840519 +0100
+++ wireless-dev/net/wireless/Makefile	2007-02-09 17:08:44.033840519 +0100
@@ -1,16 +1,16 @@
 obj-$(CONFIG_CFG80211) += cfg80211.o
 
-cfg80211-objs := \
-	core.o nl80211.o
+cfg80211-y += core.o sysfs.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
--- wireless-dev.orig/net/wireless/core.c	2007-02-09 17:08:26.093840519 +0100
+++ wireless-dev/net/wireless/core.c	2007-02-09 17:08:44.033840519 +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 "core.h"
+#include "sysfs.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
@@ -24,31 +27,13 @@ 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;
-}
-
 /* requires cfg80211_drv_mutex to be held! */
 static struct cfg80211_registered_driver *cfg80211_drv_by_wiphy(int wiphy)
 {
 	struct cfg80211_registered_driver *result = NULL, *drv;
 
 	list_for_each_entry(drv, &cfg80211_drv_list, list) {
-		if (drv->wiphy == wiphy) {
+		if (drv->wiphy.wiphy_index == wiphy) {
 			result = drv;
 			break;
 		}
@@ -76,7 +61,8 @@ __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_drv(dev->ieee80211_ptr);
 			dev_put(dev);
 		}
 		err = -ENODEV;
@@ -116,7 +102,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)
 {
@@ -127,11 +112,11 @@ cfg80211_get_drv_from_ifindex(int ifinde
 	dev = dev_get_by_index(ifindex);
 	if (!dev)
 		goto out;
-	drv = cfg80211_drv_by_priv(dev->ieee80211_ptr);
+	drv = wiphy_to_drv(dev->ieee80211_ptr);
 	if (drv)
 		mutex_lock(&drv->mtx);
 	else
-		drv = ERR_PTR(-ENOSYS);
+		drv = ERR_PTR(-ENODEV);
 	dev_put(dev);
  out:
 	mutex_unlock(&cfg80211_drv_mutex);
@@ -146,63 +131,72 @@ 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_driver *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;
+	mutex_init(&result->mtx);
+	/* special index -1: newly created */
+	result->wiphy.wiphy_index = -1;
 
-	drv->ops = ops;
-	drv->priv = priv;
+	return &result->wiphy;
+}
+EXPORT_SYMBOL(wiphy_new);
+
+int wiphy_register(struct wiphy *wiphy)
+{
+	struct cfg80211_registered_driver *drv = wiphy_to_drv(wiphy);
+	int res;
+
+	if (wiphy->wiphy_index != -1)
+		return -EINVAL;
+
+	mutex_lock(&cfg80211_drv_mutex);
 
 	if (unlikely(wiphy_counter<0)) {
 		/* ugh, wrapped! */
-		kfree(drv);
 		res = -ENOSPC;
 		goto out_unlock;
 	}
-	mutex_init(&drv->mtx);
-	drv->wiphy = wiphy_counter;
+	drv->wiphy.wiphy_index = wiphy_counter;
 	list_add(&drv->list, &cfg80211_drv_list);
-	/* return wiphy number */
-	res = drv->wiphy;
+
+	/* give it a proper name */
+	snprintf(drv->wiphy.class_dev.class_id, BUS_ID_SIZE,
+		 "wiphy%d", drv->wiphy.wiphy_index);
+
+	res = wiphy_sysfs_add(&drv->wiphy);
+	if (res)
+		goto out_unlock;
 
 	/* now increase counter for the next time */
 	wiphy_counter++;
 
+	/* return wiphy number */
+	res = drv->wiphy.wiphy_index;
+
  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_driver *drv = wiphy_to_drv(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 */
@@ -211,35 +205,49 @@ void cfg80211_unregister(void *priv)
 	mutex_unlock(&drv->mtx);
 
 	mutex_unlock(&cfg80211_drv_mutex);
+}
+EXPORT_SYMBOL(wiphy_unregister);
 
+void cfg80211_drv_free(struct cfg80211_registered_driver *drv)
+{
 	mutex_destroy(&drv->mtx);
 	kfree(drv);
 }
-EXPORT_SYMBOL_GPL(cfg80211_unregister);
 
-/* module initialisation/exit functions */
+void wiphy_free(struct wiphy *wiphy)
+{
+	if (wiphy->wiphy_index != -1)
+		wiphy_sysfs_del(wiphy);
+	else
+		cfg80211_drv_free(wiphy_to_drv(wiphy));
+}
+EXPORT_SYMBOL(wiphy_free);
+
 
 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();
+	int err = wiphy_sysfs_init();
+
+	if (err)
+		return err;
+
+	err = cfg80211_wext_init();
+
+	if (err)
+		goto out_exit_sysfs;
+
+	return 0;
+
+ out_exit_sysfs:
+ 	wiphy_sysfs_exit();
+
+	return err;
 }
+module_init(cfg80211_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();
+	cfg80211_wext_exit();
+	wiphy_sysfs_exit();
 }
-
-module_init(cfg80211_init);
 module_exit(cfg80211_exit);
--- wireless-dev.orig/net/wireless/core.h	2007-02-09 17:08:26.133840519 +0100
+++ wireless-dev/net/wireless/core.h	2007-02-09 17:08:44.033840519 +0100
@@ -5,47 +5,39 @@
  */
 #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/cfg80211.h>
 
 struct cfg80211_registered_driver {
 	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
 	 * 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
+
+	/* 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_driver *wiphy_to_drv(struct wiphy *wiphy)
+{
+	return container_of(wiphy, struct cfg80211_registered_driver, wiphy);
+}
+
 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.
@@ -75,4 +67,7 @@ cfg80211_get_drv_from_ifindex(int ifinde
 
 extern void cfg80211_put_drv(struct cfg80211_registered_driver *drv);
 
+/* free object */
+extern void cfg80211_drv_free(struct cfg80211_registered_driver *drv);
+
 #endif /* __NET_WIRELESS_CORE_H */
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/sysfs.c	2007-02-09 17:08:44.033840519 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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_driver *cdev_to_drv(
+	struct class_device *cdev)
+{
+	return container_of(cdev, struct cfg80211_registered_driver, wiphy.class_dev);
+}
+
+static void wiphy_class_dev_release(struct class_device *cdev)
+{
+	struct cfg80211_registered_driver *drv = cdev_to_drv(cdev);
+
+	cfg80211_drv_free(drv);
+}
+
+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,
+#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;
+	class_device_initialize(&wiphy->class_dev);
+	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-09 17:08:44.033840519 +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/include/net/iw_handler.h	2007-02-09 17:08:25.863840519 +0100
+++ wireless-dev/include/net/iw_handler.h	2007-02-09 17:08:44.043840519 +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-09 17:08:44.043840519 +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/Kconfig	2007-02-09 17:08:26.843840519 +0100
+++ wireless-dev/net/Kconfig	2007-02-09 17:08:44.043840519 +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/core/dev.c	2007-02-09 17:08:26.873840519 +0100
+++ wireless-dev/net/core/dev.c	2007-02-09 17:08:44.043840519 +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/wext-common.c	2007-02-09 17:08:26.233840519 +0100
+++ wireless-dev/net/wireless/wext-common.c	2007-02-09 17:08:44.043840519 +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
@@ -297,6 +304,7 @@ const struct iw_ioctl_description standa
 unsigned standard_event_num = (sizeof(standard_event) /
 					sizeof(struct iw_ioctl_description));
 
+
 /* Size (in bytes) of various events */
 const int event_type_size[] = {
 	IW_EV_LCP_LEN,			/* IW_HEADER_TYPE_NULL */
@@ -545,8 +553,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 +616,48 @@ 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;
+
+	dev_load(ifr->ifr_name);
+
+#ifdef CONFIG_WIRELESS_EXT
+	rtnl_lock();
+	/* Follow me in 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;
+	/* 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
+	rtnl_lock();
+	ret = call_cfg80211_wext_ioctl(ifr, cmd);
+	rtnl_unlock();
+
+	if (ret == 0 && IW_IS_GET(cmd) &&
+	    copy_to_user(arg, ifr, sizeof(struct ifreq)))
+		ret = -EFAULT;
+#endif
+
+	return ret;
+}
--- wireless-dev.orig/net/wireless/wext-compat.c	2007-02-09 17:08:26.273840519 +0100
+++ wireless-dev/net/wireless/wext-compat.c	2007-02-09 17:08:44.053840519 +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;
-
-	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_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;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- 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;
+	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_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;
+	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_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;
-
-	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_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;
-
-	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_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;
-
-	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_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;
-
-	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_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;
-
-	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_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;
-
-	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_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;
-
-	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_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;
+	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_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;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- 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;
-
-	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_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;
-	}
+	int err = -EOPNOTSUPP;
 
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
-
- 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;
+	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_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;
-
-	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_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;
-
-	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_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;
+	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_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;
-
-	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_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;
-
-	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_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;
-	}
-
-	/* TODO: DO SOMETHING */
-	err = -ENOSYS;
+	int err = -EOPNOTSUPP;
 
- 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;
@@ -1126,348 +669,16 @@ 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
  * 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;
@@ -1475,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;
@@ -1487,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) &&
@@ -1557,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)) {
@@ -1597,7 +808,8 @@ 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;
 
 	/* Permissions are already checked in dev_ioctl() before calling us.
 	 * The copy_to/from_user() of ifr is also dealt with in there */
@@ -1606,26 +818,25 @@ int cfg80211_wext_ioctl(struct ifreq *if
 	if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
 		return -ENODEV;
 
+	drv = cfg80211_get_drv_from_ifindex(dev->ifindex);
+	if (!IS_ERR(drv))
+		return PTR_ERR(drv);
+
 	/* 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,
+			return ioctl_standard_call(drv, dev, ifr, cmd,
 						   &iw_handler_get_iwstats);
 
 		case SIOCGIWPRIV:
 			return -EOPNOTSUPP;
 		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,
+				return ioctl_standard_call(drv, dev, ifr, cmd,
 							   handler);
 			return -EOPNOTSUPP;
 	}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/wext-export.c	2007-02-09 17:08:44.053840519 +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;
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/net/wireless/wext-mod.c	2007-02-09 17:08:44.053840519 +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-09 17:08:26.583840519 +0100
+++ wireless-dev/net/wireless/wext-old.c	2007-02-09 17:08:44.063840519 +0100
@@ -124,6 +124,7 @@ static const char iw_priv_type_size[] = 
 	0,				/* Not defined */
 };
 
+
 /************************ COMMON SUBROUTINES ************************/
 /*
  * Stuff that may be used in various place or doesn't fit in one
@@ -308,9 +309,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 +770,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 +912,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 +1727,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/wext.h	2007-02-09 17:08:26.623840519 +0100
+++ wireless-dev/net/wireless/wext.h	2007-02-09 17:08:44.063840519 +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 */
--- wireless-dev.orig/net/wireless/nl80211.c	2007-02-09 17:08:26.663840519 +0100
+++ wireless-dev/net/wireless/nl80211.c	2007-02-09 17:08:44.063840519 +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"
 
@@ -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->wiphy.wiphy_index);
 
 	start = nla_nest_start(msg, NL80211_ATTR_CMDS);
 	if (!start)
@@ -124,7 +125,6 @@ static int nl80211_get_cmdlist(struct sk
 	NLA_PUT_FLAG(msg, NL80211_CMD_GET_WIPHYS);
 	NLA_PUT_FLAG(msg, NL80211_CMD_GET_INTERFACES);
 
-	CHECK_CMD(inject_packet, INJECT);
 	CHECK_CMD(add_virtual_intf, ADD_VIRTUAL_INTERFACE);
 	CHECK_CMD(del_virtual_intf, DEL_VIRTUAL_INTERFACE);
 	CHECK_CMD(configure, CONFIGURE);
@@ -178,7 +178,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->wiphy.wiphy_index);
 		nla_nest_end(msg, indexstart);
 	}
 	mutex_unlock(&cfg80211_drv_mutex);
@@ -248,7 +248,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->wiphy.wiphy_index);
 
 	start = nla_nest_start(msg, NL80211_ATTR_INTERFACE_LIST);
 	if (!start) {
@@ -258,7 +258,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;
 
@@ -278,38 +278,6 @@ static int nl80211_get_intfs(struct sk_b
 	return err;
 }
 
-static int nl80211_do_inject(struct sk_buff *skb, struct genl_info *info)
-{
-	struct cfg80211_registered_driver *drv;
-	u32 flags = 0;
-	int err, queue = -1;
-
-	if (!info->attrs[NL80211_ATTR_FRAME])
-		return -EINVAL;
-	if (info->attrs[NL80211_ATTR_FLAGS])
-		flags = nla_get_u32(info->attrs[NL80211_ATTR_FLAGS]);
-	if (info->attrs[NL80211_ATTR_QUEUE])
-		queue = (int) nla_get_u32(info->attrs[NL80211_ATTR_QUEUE]);
-
-	drv = cfg80211_get_drv_from_info(info);
-	if (IS_ERR(drv))
-		return PTR_ERR(drv);
-
-	if (!drv->ops->inject_packet) {
-		err = -ENOSYS;
-		goto unlock;
-	}
-
-	err = drv->ops->inject_packet(drv->priv,
-		nla_data(info->attrs[NL80211_ATTR_FRAME]),
-		nla_len(info->attrs[NL80211_ATTR_FRAME]),
-		flags,
-		queue);
- unlock:
-	cfg80211_put_drv(drv);
-	return err;
-}
-
 static int nl80211_add_virt_intf(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_driver *drv;
@@ -334,7 +302,7 @@ 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:
@@ -359,7 +327,7 @@ 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);
@@ -421,7 +389,7 @@ 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);
 	dev_put(dev);
@@ -448,7 +416,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);
@@ -514,7 +482,7 @@ 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);
 	dev_put(dev);
@@ -538,7 +506,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;
 
@@ -586,7 +554,7 @@ 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);
 	dev_put(dev);
@@ -611,7 +579,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;
 
@@ -657,7 +625,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;
 
@@ -691,7 +659,7 @@ static int nl80211_assoc_deauth(struct s
 	struct cfg80211_registered_driver *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,7 +684,7 @@ static int nl80211_assoc_deauth(struct s
 		goto out;
 	}
 
-	err = act(drv->priv, dev);
+	err = act(&drv->wiphy, dev);
  out:
 	cfg80211_put_drv(drv);
 	dev_put(dev);
@@ -778,7 +746,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;
 
@@ -874,7 +842,7 @@ 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:
@@ -903,12 +871,6 @@ static struct genl_ops nl80211_ops[] = {
 		/* can be retrieved by unprivileged users */
 	},
 	{
-		.cmd = NL80211_CMD_INJECT,
-		.doit = nl80211_do_inject,
-		.policy = nl80211_policy,
-		.flags = GENL_ADMIN_PERM,
-	},
-	{
 		.cmd = NL80211_CMD_ADD_VIRTUAL_INTERFACE,
 		.doit = nl80211_add_virt_intf,
 		.policy = nl80211_policy,
--- wireless-dev.orig/include/linux/nl80211.h	2007-02-09 17:08:25.813840519 +0100
+++ wireless-dev/include/linux/nl80211.h	2007-02-09 17:08:44.063840519 +0100
@@ -20,11 +20,6 @@ enum {
 	/* Supported commands returned */
 	NL80211_CMD_NEW_CMDLIST,
 
-	/* Inject a frame using NL80211_ATTR_FLAGS and NL80211_ATTR_FRAME.
-	 * If kernel sends this, it's a status notification for the injected
-	 * frame. */
-	NL80211_CMD_INJECT,
-
 	/* add a virtual interface to a group that is identified by any
 	 * other ifindex in the group of a wiphy index, needs the
 	 * NL80211_IF_NAME attribute */

--


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

* [PATCH 2/5] wext: clean up
  2007-02-09 16:24 [PATCH 0/5] cfg80211 changes for wireless-dev johannes
  2007-02-09 16:24 ` [PATCH 1/5] cfg80211: update to code submitted to mainline johannes
@ 2007-02-09 16:24 ` johannes
  2007-02-09 16:24 ` [PATCH 3/5] d80211: update for wiphy api johannes
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: johannes @ 2007-02-09 16:24 UTC (permalink / raw)
  To: linux-wireless

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-09 17:08:44.063840519 +0100
+++ wireless-dev/net/wireless/wext-old.c	2007-02-09 17:08:47.093840519 +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 */
@@ -313,12 +227,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;
@@ -329,12 +237,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;
@@ -409,11 +315,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);
@@ -430,11 +331,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 */
@@ -454,15 +350,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))) {
@@ -474,7 +364,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);
@@ -524,16 +413,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)) {
@@ -590,11 +469,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);
@@ -610,10 +484,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 */
@@ -632,11 +502,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 ;-) */
@@ -672,8 +538,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,
@@ -774,22 +639,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;
@@ -833,10 +686,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);
@@ -868,10 +717,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;
@@ -916,25 +761,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;
@@ -965,18 +798,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... */
@@ -992,7 +815,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))) {
@@ -1003,7 +825,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)
@@ -1059,13 +880,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);
 
@@ -1079,14 +893,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;
@@ -1117,11 +925,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) {
@@ -1153,10 +956,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 */
@@ -1214,13 +1013,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')
@@ -1243,14 +1035,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;
@@ -1278,18 +1064,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... */
@@ -1330,18 +1106,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))
@@ -1414,18 +1184,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))
@@ -1521,19 +1285,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 */
@@ -1544,6 +1295,7 @@ int iw_handler_set_spy(struct net_device
 
 	return 0;
 }
+EXPORT_SYMBOL(iw_handler_set_spy);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1579,6 +1331,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);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1603,12 +1356,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);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1632,6 +1382,7 @@ int iw_handler_get_thrspy(struct net_dev
 
 	return 0;
 }
+EXPORT_SYMBOL(iw_handler_get_thrspy);
 
 /*------------------------------------------------------------------*/
 /*
@@ -1657,16 +1408,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);
 }
@@ -1690,10 +1431,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])) {
@@ -1722,9 +1459,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] 7+ messages in thread

* [PATCH 3/5] d80211: update for wiphy api
  2007-02-09 16:24 [PATCH 0/5] cfg80211 changes for wireless-dev johannes
  2007-02-09 16:24 ` [PATCH 1/5] cfg80211: update to code submitted to mainline johannes
  2007-02-09 16:24 ` [PATCH 2/5] wext: clean up johannes
@ 2007-02-09 16:24 ` johannes
  2007-02-09 16:24 ` [PATCH 4/5] zd1211rw-d80211: " johannes
  2007-02-09 16:24 ` [PATCH 5/5] bcm43xx-d80211: " johannes
  4 siblings, 0 replies; 7+ messages in thread
From: johannes @ 2007-02-09 16:24 UTC (permalink / raw)
  To: linux-wireless

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

Patch is large because cfg80211 requires the net_dev->ieee80211_ptr now.

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

---
 include/net/d80211.h             |   24 ++++-
 net/d80211/Kconfig               |    1 
 net/d80211/Makefile              |    2 
 net/d80211/ieee80211.c           |  150 ++++++++++++++++--------------------
 net/d80211/ieee80211_cfg.c       |   32 +++++++
 net/d80211/ieee80211_cfg.h       |    9 ++
 net/d80211/ieee80211_dev.c       |  117 ----------------------------
 net/d80211/ieee80211_i.h         |   22 -----
 net/d80211/ieee80211_iface.c     |   27 +++---
 net/d80211/ieee80211_ioctl.c     |  104 ++++++++++++-------------
 net/d80211/ieee80211_led.c       |    4 
 net/d80211/ieee80211_sta.c       |   56 ++++++-------
 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, 301 insertions(+), 455 deletions(-)

--- wireless-dev.orig/include/net/d80211.h	2007-02-09 17:08:23.083840519 +0100
+++ wireless-dev/include/net/d80211.h	2007-02-09 17:08:49.973840519 +0100
@@ -16,6 +16,7 @@
 #include <linux/wireless.h>
 #include <linux/device.h>
 #include <linux/ieee80211.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
@@ -454,8 +455,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
@@ -464,11 +469,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
@@ -547,6 +547,16 @@ struct ieee80211_hw {
 	int queues;
 };
 
+static inline void SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev)
+{
+	hw->wiphy->dev = 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-09 17:08:23.103840519 +0100
+++ wireless-dev/net/d80211/ieee80211.c	2007-02-09 17:08:49.973840519 +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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_msg_key_notification *msg;
 
@@ -1056,7 +1059,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	int hdrlen;
 
@@ -1196,7 +1199,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	ieee80211_tx_handler *handler;
 	struct ieee80211_txrx_data tx;
@@ -1422,7 +1425,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_packet_data *pkt_data;
         struct ieee80211_sub_if_data *sdata;
 	int ret = 1, head_need;
@@ -1860,7 +1863,7 @@ static int __ieee80211_if_config(struct 
 				 struct sk_buff *beacon)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = dev->ieee80211_ptr;
+	struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_if_conf conf;
 
 	if (!local->ops->config_interface || !netif_running(dev))
@@ -1893,7 +1896,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 
 	if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
@@ -1971,7 +1974,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 = wiphy_priv(dev->ieee80211_ptr);
 
 	printk(KERN_WARNING "%s: resetting interface.\n", dev->name);
 
@@ -1995,7 +1998,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 = wiphy_priv(dev->ieee80211_ptr);
         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	unsigned short flags;
 
@@ -2073,7 +2076,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	ASSERT_RTNL();
@@ -2114,7 +2117,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	int res = -EOPNOTSUPP;
 
@@ -2130,7 +2133,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 
 	tasklet_disable(&local->tx_pending_tasklet);
@@ -2143,7 +2146,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 = wiphy_priv(dev->ieee80211_ptr);
 
 	if (!netif_running(local->mdev))
 		return -EOPNOTSUPP;
@@ -2190,7 +2193,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_if_init_conf conf;
 	int res;
 
@@ -2270,7 +2273,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 = wiphy_priv(dev->ieee80211_ptr);
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -2631,7 +2634,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_frame_info *fi;
 	struct ieee80211_sub_if_data *sdata;
 	const size_t hlen = sizeof(struct ieee80211_frame_info)
@@ -2738,7 +2741,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	int sent = 0;
 	struct ieee80211_sub_if_data *sdata;
@@ -4287,7 +4290,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct sta_info *sta;
 
@@ -4360,7 +4363,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);
@@ -4371,7 +4374,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);
 	}
@@ -4390,7 +4393,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);
 }
 
@@ -4401,37 +4404,50 @@ 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
 	 *
-         * Sample memory map looks something like:
-         *
-         * 0000 *****************
-         *      * net_dev       *
-	 * 0160 *****************
-         *      * sub_if        *
-	 * 0b80 *****************
-         *      * hw_priv       *
-         * 1664 *****************
-         */
-	priv_size = ((sizeof(struct ieee80211_sub_if_data) +
+	 * In memory it'll be like this:
+	 *
+	 * +-------------------------+
+	 * | 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;
+	mdev->ieee80211_ptr = wiphy;
 	local->hw.priv = (char *)mdev->priv +
 			 ((sizeof(struct ieee80211_sub_if_data) +
 			   NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
@@ -4512,11 +4528,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)
@@ -4537,21 +4551,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, local->hw.wiphy->dev);
 
 	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();
@@ -4595,15 +4602,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);
@@ -4655,8 +4660,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);
 
@@ -4692,7 +4695,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);
 }
@@ -4703,15 +4706,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)
 {
@@ -4809,22 +4807,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;
 }
 
@@ -4832,7 +4821,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-09 17:08:23.143840519 +0100
+++ wireless-dev/net/d80211/Makefile	2007-02-09 17:08:49.973840519 +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-09 17:08:23.183840519 +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-09 17:08:23.223840519 +0100
+++ wireless-dev/net/d80211/ieee80211_iface.c	2007-02-09 17:08:49.983840519 +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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = NULL;
 	int ret;
 	int i;
@@ -51,7 +52,7 @@ int ieee80211_if_add(struct net_device *
 	if (!ndev)
 		return -ENOMEM;
 
-	ndev->ieee80211_ptr = local;
+	ndev->ieee80211_ptr = local->hw.wiphy;
 	if (strlen(name) == 0) {
 		i = 0;
 		do {
@@ -70,13 +71,13 @@ 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;
 	ndev->flags = dev->flags & IFF_MULTICAST;
-	SET_NETDEV_DEV(ndev, local->hw.dev);
+	SET_NETDEV_DEV(ndev, local->hw.wiphy->dev);
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
 	sdata->type = IEEE80211_IF_TYPE_AP;
@@ -122,9 +123,9 @@ 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);
+	ndev->ieee80211_ptr = local->hw.wiphy;
+	memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
+	SET_NETDEV_DEV(ndev, local->hw.wiphy->dev);
 
 	nsdata = IEEE80211_DEV_TO_SUB_IF(ndev);
 	nsdata->type = IEEE80211_IF_TYPE_MGMT;
@@ -164,7 +165,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 = wiphy_priv(dev->ieee80211_ptr);
 
 	sdata->type = type;
 	switch (type) {
@@ -212,7 +213,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct sta_info *sta;
 	int i;
@@ -318,7 +319,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata, *n;
 
 	ASSERT_RTNL();
@@ -337,7 +338,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 = wiphy_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 */
@@ -349,7 +350,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata, *n;
 
 	ASSERT_RTNL();
@@ -360,7 +361,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 = wiphy_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-09 17:08:23.283840519 +0100
+++ wireless-dev/net/d80211/ieee80211_i.h	2007-02-09 17:08:49.983840519 +0100
@@ -344,8 +344,6 @@ struct ieee80211_local {
 	int monitors;
 	struct iw_statistics wstats;
 
-	struct class_device class_dev;
-
 	enum {
 		IEEE80211_DEV_UNITIALIZED = 0,
 		IEEE80211_DEV_REGISTERED,
@@ -596,7 +594,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);
@@ -680,14 +677,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);
@@ -703,17 +692,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-09 17:08:23.323840519 +0100
+++ wireless-dev/net/d80211/ieee80211_led.c	2007-02-09 17:08:49.983840519 +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-09 17:08:23.373840519 +0100
+++ wireless-dev/net/d80211/ieee80211_sysfs.c	2007-02-09 17:08:49.993840519 +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 = wiphy_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-09 17:08:23.413840519 +0100
+++ wireless-dev/net/d80211/Kconfig	2007-02-09 17:08:49.993840519 +0100
@@ -5,6 +5,7 @@ config D80211
 	select CRYPTO_ARC4
 	select CRYPTO_AES
 	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-09 17:08:50.003840519 +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-09 17:08:50.003840519 +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-09 17:08:23.593840519 +0100
+++ wireless-dev/net/d80211/ieee80211_sysfs_sta.c	2007-02-09 17:08:50.003840519 +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 = wiphy_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-09 17:08:50.003840519 +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-09 17:08:23.793840519 +0100
+++ wireless-dev/net/d80211/ieee80211_ioctl.c	2007-02-09 17:08:50.013840519 +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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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(wiphy_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(wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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(wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_priv(dev->ieee80211_ptr);
 	int *i = (int *) extra;
 	int param = *i;
 	int value = *(i + 1);
@@ -2965,7 +2965,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	int ret = 0;
 
@@ -3021,7 +3021,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 = wiphy_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-09 17:08:23.913840519 +0100
+++ wireless-dev/net/d80211/ieee80211_sta.c	2007-02-09 17:08:50.113840519 +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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_tx_queue_params params;
 	size_t left;
 	int count;
@@ -469,7 +469,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 	u8 *pos, *ies;
@@ -689,7 +689,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	int disassoc;
 
@@ -752,7 +752,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
 	u8 *pos, *supp_rates, *esupp_rates = NULL;
@@ -1082,7 +1082,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sta_info *sta;
 	u32 rates;
 	u16 capab_info, status_code, aid;
@@ -1213,7 +1213,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 = wiphy_priv(dev->ieee80211_ptr);
 	bss->hnext = local->sta_bss_hash[STA_HASH(bss->bssid)];
 	local->sta_bss_hash[STA_HASH(bss->bssid)] = bss;
 }
@@ -1223,7 +1223,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *b, *prev = NULL;
 	b = local->sta_bss_hash[STA_HASH(bss->bssid)];
 	while (b) {
@@ -1244,7 +1244,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 
 	bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
@@ -1267,7 +1267,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 
 	spin_lock_bh(&local->sta_bss_lock);
@@ -1296,7 +1296,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 = wiphy_priv(dev->ieee80211_ptr);
 	if (!atomic_dec_and_test(&bss->users))
 		return;
 
@@ -1310,7 +1310,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 = wiphy_priv(dev->ieee80211_ptr);
 	spin_lock_init(&local->sta_bss_lock);
 	INIT_LIST_HEAD(&local->sta_bss_list);
 }
@@ -1318,7 +1318,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss, *tmp;
 
 	list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
@@ -1332,7 +1332,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee802_11_elems elems;
 	size_t baselen;
 	int channel, invalid = 0, clen;
@@ -1581,7 +1581,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_if_sta *ifsta;
 	int use_protection;
@@ -1639,7 +1639,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	int tx_last_beacon;
 	struct sk_buff *skb;
@@ -1792,7 +1792,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 = wiphy_priv(dev->ieee80211_ptr);
 	int active = 0;
 	struct sta_info *sta;
 
@@ -1813,7 +1813,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct sta_info *sta, *tmp;
 
 	spin_lock_bh(&local->sta_lock);
@@ -1899,7 +1899,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	if (sdata->type != IEEE80211_IF_TYPE_STA)
@@ -1960,7 +1960,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct iw_freq rq;
 	int res, rates, i, j;
 	struct sk_buff *skb;
@@ -2120,7 +2120,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 	struct ieee80211_sub_if_data *sdata;
 	u8 bssid[ETH_ALEN], *pos;
@@ -2177,7 +2177,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 	int found = 0;
 	u8 bssid[ETH_ALEN];
@@ -2267,7 +2267,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 = wiphy_priv(dev->ieee80211_ptr);
 
 	if (len > IEEE80211_MAX_SSID_LEN)
 		return -EINVAL;
@@ -2364,7 +2364,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 = wiphy_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;
@@ -2376,7 +2376,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 = wiphy_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;
@@ -2530,7 +2530,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 = wiphy_priv(dev->ieee80211_ptr);
 
 	if (ssid_len > IEEE80211_MAX_SSID_LEN)
 		return -EINVAL;
@@ -2600,7 +2600,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 = wiphy_priv(dev->ieee80211_ptr);
 	struct iw_event iwe;
 
 	if (time_after(jiffies,
@@ -2768,7 +2768,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 = wiphy_priv(dev->ieee80211_ptr);
 	char *current_ev = buf;
 	char *end_buf = buf + len;
 	struct ieee80211_sta_bss *bss;
@@ -2815,7 +2815,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 = wiphy_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-09 17:08:23.953840519 +0100
+++ wireless-dev/net/d80211/rc80211_simple.c	2007-02-09 17:08:50.113840519 +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 = wiphy_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 = wiphy_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-09 17:08:24.003840519 +0100
+++ wireless-dev/net/d80211/wme.c	2007-02-09 17:08:50.113840519 +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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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 = wiphy_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] 7+ messages in thread

* [PATCH 4/5] zd1211rw-d80211: update for wiphy api
  2007-02-09 16:24 [PATCH 0/5] cfg80211 changes for wireless-dev johannes
                   ` (2 preceding siblings ...)
  2007-02-09 16:24 ` [PATCH 3/5] d80211: update for wiphy api johannes
@ 2007-02-09 16:24 ` johannes
  2007-02-09 16:24 ` [PATCH 5/5] bcm43xx-d80211: " johannes
  4 siblings, 0 replies; 7+ messages in thread
From: johannes @ 2007-02-09 16:24 UTC (permalink / raw)
  To: linux-wireless

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-09 17:08:20.773840519 +0100
+++ wireless-dev/drivers/net/wireless/d80211/zd1211rw/zd_mac.c	2007-02-09 17:08:56.243840519 +0100
@@ -54,7 +54,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);
@@ -589,7 +589,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));
@@ -625,7 +625,7 @@ struct ieee80211_hw *zd_mac_alloc(struct
 	housekeeping_init(mac);
 
 	SET_MODULE_OWNER(dev);
-	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-09 17:08:21.003840519 +0100
+++ wireless-dev/drivers/net/wireless/d80211/zd1211rw/zd_usb.c	2007-02-09 17:08:56.253840519 +0100
@@ -1062,7 +1062,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,"wiphy%d\n", dev->wiphy->wiphy_index);
 	return 0;
 error:
 	usb_reset_device(interface_to_usbdev(intf));

--


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

* [PATCH 5/5] bcm43xx-d80211: update for wiphy api
  2007-02-09 16:24 [PATCH 0/5] cfg80211 changes for wireless-dev johannes
                   ` (3 preceding siblings ...)
  2007-02-09 16:24 ` [PATCH 4/5] zd1211rw-d80211: " johannes
@ 2007-02-09 16:24 ` johannes
  4 siblings, 0 replies; 7+ messages in thread
From: johannes @ 2007-02-09 16:24 UTC (permalink / raw)
  To: linux-wireless

update bcm43xx-d80211.

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

---
 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_debugfs.c	2007-02-09 17:08:20.133840519 +0100
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c	2007-02-09 17:09:00.763840519 +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), "wiphy%d", dev->wl->hw->wiphy->wiphy_index);
 	e->subdir = debugfs_create_dir(devdir, fs.root);
 	e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
 	                                    dev, &tsf_fops);
--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2007-02-09 17:08:20.213840519 +0100
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2007-02-09 17:09:00.773840519 +0100
@@ -3166,7 +3166,7 @@ static int bcm43xx_wireless_core_init(st
 	ssb_chipco_set_clockmode(chipco, SSB_CLKMODE_DYNAMIC);
 	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);
 
@@ -3562,14 +3562,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);

--


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

* Re: [PATCH 1/5] cfg80211: update to code submitted to mainline
  2007-02-09 16:24 ` [PATCH 1/5] cfg80211: update to code submitted to mainline johannes
@ 2007-02-11 13:13   ` Johannes Berg
  0 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2007-02-11 13:13 UTC (permalink / raw)
  To: linux-wireless

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

On Fri, 2007-02-09 at 17:24 +0100, johannes@sipsolutions.net wrote:


> 
> +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;
> +
> +       dev_load(ifr->ifr_name);
> +
> +#ifdef CONFIG_WIRELESS_EXT
> +       rtnl_lock();
> +       /* Follow me in wext-old.c */
> +       ret = wireless_process_ioctl(ifr, cmd);
> +       rtnl_unlock();
> +
> +       if (ret == 0 && IW_IS_GET(cmd) &&
              ^^^^^^^^^^^^

That's the bug. That test must be removed.

johannes

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

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

end of thread, other threads:[~2007-02-11 13:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-09 16:24 [PATCH 0/5] cfg80211 changes for wireless-dev johannes
2007-02-09 16:24 ` [PATCH 1/5] cfg80211: update to code submitted to mainline johannes
2007-02-11 13:13   ` Johannes Berg
2007-02-09 16:24 ` [PATCH 2/5] wext: clean up johannes
2007-02-09 16:24 ` [PATCH 3/5] d80211: update for wiphy api johannes
2007-02-09 16:24 ` [PATCH 4/5] zd1211rw-d80211: " johannes
2007-02-09 16:24 ` [PATCH 5/5] bcm43xx-d80211: " johannes

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