diff -Naur a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
--- a/Documentation/networking/README.ipw2200	2007-07-10 20:56:30.000000000 +0200
+++ b/Documentation/networking/README.ipw2200	2007-07-12 17:22:20.000000000 +0200
@@ -1,21 +1,33 @@
 
-Intel(R) PRO/Wireless 2915ABG Driver for Linux in support of:
+Intel(R) PRO/Wireless 2915ABG Network Connection driver for Linux
+in support of:
 
 Intel(R) PRO/Wireless 2200BG Network Connection
 Intel(R) PRO/Wireless 2915ABG Network Connection
 
-Note: The Intel(R) PRO/Wireless 2915ABG Driver for Linux and Intel(R)
-PRO/Wireless 2200BG Driver for Linux is a unified driver that works on
+Note: The Intel(R) PRO/Wireless 2915ABG driver for Linux and Intel(R)
+PRO/Wireless 2200BG driver for Linux is a unified driver that works on
 both hardware adapters listed above. In this document the Intel(R)
-PRO/Wireless 2915ABG Driver for Linux will be used to reference the
+PRO/Wireless 2915ABG driver for Linux will be used to refer to the
 unified driver.
 
 Copyright (C) 2004-2006, Intel Corporation
 
+INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS.
+EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH
+PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER, AND INTEL DISCLAIMS
+ANY EXPRESS OR IMPLIED WARRANTY RELATING TO SALE AND/OR USE OF INTEL
+PRODUCTS, INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A
+PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT,
+COPYRIGHT, OR OTHER INTELLECTUAL PROPERTY RIGHT.
+This document is subject to change without notice.
+* Other names and brands may be claimed as the property of others.
+
+
 README.ipw2200
 
-Version: 1.1.2
-Date   : March 30, 2006
+Version: 1.2.2
+Date   : July 12, 2007
 
 
 Index
@@ -26,11 +38,9 @@
 1.2. Module parameters
 1.3. Wireless Extension Private Methods
 1.4. Sysfs Helper Files
-1.5. Supported channels
 2.   Ad-Hoc Networking
 3.   Interacting with Wireless Tools
 3.1. iwconfig mode
-3.2. iwconfig sens
 4.   About the Version Numbers
 5.   Firmware installation
 6.   Support
@@ -90,20 +100,20 @@
 
 1.   Introduction
 -----------------------------------------------
-The following sections attempt to provide a brief introduction to using 
+The following sections attempt to provide a brief introduction to use
 the Intel(R) PRO/Wireless 2915ABG Driver for Linux.
 
 This document is not meant to be a comprehensive manual on 
 understanding or using wireless technologies, but should be sufficient 
 to get you moving without wires on Linux.
 
-For information on building and installing the driver, see the INSTALL
-file.
+For information on building and installing the Intel PRO/Wireless
+2915ABG Network Connection driver, see the INSTALL file.
 
 
 1.1. Overview of Features
 -----------------------------------------------
-The current release (1.1.2) supports the following features:
+The current release (1.2.2) supports the following features:
 
 + BSS mode (Infrastructure, Managed)
 + IBSS mode (Ad-Hoc)
@@ -123,7 +133,7 @@
 + Monitor mode (aka RFMon)
 
 The distinction between officially supported and enabled is a reflection 
-on the amount of validation and interoperability testing that has been
+of the amount of validation and interoperability testing that has been
 performed on a given feature. 
 
 
@@ -134,40 +144,41 @@
 Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
 2915ABG Driver for Linux allows configuration options to be provided 
 as module parameters.  The most common way to specify a module parameter 
-is via the command line.  
+is command line.  
 
 The general form is:
 
-% modprobe ipw2200 parameter=value
+% modprobe ipw2200 [parameter]=[value]
 
 Where the supported parameter are:
 
   associate
-	Set to 0 to disable the auto scan-and-associate functionality of the
+	Setting to 0 to disable the auto scan-and-associate functionality of the
 	driver.  If disabled, the driver will not attempt to scan 
 	for and associate to a network until it has been configured with 
-	one or more properties for the target network, for example configuring 
+	one or more properties to the target network, such as configuring 
 	the network SSID.  Default is 1 (auto-associate)
 	
 	Example: % modprobe ipw2200 associate=0
 
   auto_create
-	Set to 0 to disable the auto creation of an Ad-Hoc network 
+	Setting to 0 to disable the auto creation of an Ad-Hoc network 
 	matching the channel and network name parameters provided.  
 	Default is 1.
 
   channel
-	channel number for association.  The normal method for setting
-        the channel would be to use the standard wireless tools
+	channel number for association.  The general method for setting
+        the channel is to use the standard wireless tools
         (i.e. `iwconfig eth1 channel 10`), but it is useful sometimes
 	to set this while debugging.  Channel 0 means 'ANY'
 
   debug
 	If using a debug build, this is used to control the amount of debug
-	info is logged.  See the 'dvals' and 'load' script for more info on
+	info to be logged.  See the 'dvals' and 'load' script for more info on
 	how to use this (the dvals and load scripts are provided as part 
-	of the ipw2200 development snapshot releases available from the 
-	SourceForge project at http://ipw2200.sf.net)
+	of the Intel PRO/Wireless 2915ABG Network Connection driver
+        development snapshot releases available from the SourceForge project
+        at http://ipw2200.sf.net)
   
   led
 	Can be used to turn on experimental LED code.
@@ -177,11 +188,26 @@
 	Can be used to set the default mode of the adapter.  
 	0 = Managed, 1 = Ad-Hoc, 2 = Monitor
 
+  ifname
+	Rename the wireless network interface. It is not supported now.
+	This parameter was a hack pre-dating the ifrename utility and
+	has now been superseded by it. The ifrename utility can be found
+	in the wireless-tool package. Following is an example to change
+	the default name of wireless interface eth%d to wlan%d.
+
+	create (or edit) file /etc/iftab and append a line to it, such as:
+	wlan*	driver	ipw2200
+
+	then modified /etc/modprobe.conf and added this line:
+	install ipw2200 /sbin/modprobe --ignore-install ipw2200; /usr/sbin/ifrename
+
+	Please refer to the manpage of ifrename for details.
+
 
 1.3. Wireless Extension Private Methods
 -----------------------------------------------
 
-As an interface designed to handle generic hardware, there are certain 
+Since an interface is designed to handle generic hardware, there are certain 
 capabilities not exposed through the normal Wireless Tool interface.  As 
 such, a provision is provided for a driver to declare custom, or 
 private, methods.  The Intel(R) PRO/Wireless 2915ABG Driver for Linux 
@@ -261,14 +287,15 @@
 
 The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries 
 at two levels -- driver level, which apply to all instances of the driver 
-(in the event that there are more than one device installed) and device 
+(in the event that there is more than one device installed) and device 
 level, which applies only to the single specific instance.
 
 
 1.4.1 Driver Level Sysfs Helper Files
 -----------------------------------------------
 
-For the driver level files, look in /sys/bus/pci/drivers/ipw2200/
+For the Intel PRO/Wireless 2915ABG Network Connection driver
+level files, look in /sys/bus/pci/drivers/ipw2200/
 
   debug_level  
 	
@@ -316,45 +343,16 @@
 	running ifconfig and is therefore disabled by default.
 
 
-1.5. Supported channels
------------------------------------------------
-
-Upon loading the Intel(R) PRO/Wireless 2915ABG Driver for Linux, a
-message stating the detected geography code and the number of 802.11
-channels supported by the card will be displayed in the log.
-
-The geography code corresponds to a regulatory domain as shown in the
-table below.
-
-					  Supported channels
-Code	Geography			802.11bg	802.11a
-
----	Restricted			11 	 	 0
-ZZF	Custom US/Canada		11	 	 8
-ZZD	Rest of World			13	 	 0
-ZZA	Custom USA & Europe & High	11		13
-ZZB	Custom NA & Europe    		11		13
-ZZC	Custom Japan			11	 	 4
-ZZM	Custom 				11	 	 0
-ZZE	Europe				13		19
-ZZJ	Custom Japan			14	 	 4
-ZZR	Rest of World			14	 	 0
-ZZH	High Band			13	 	 4
-ZZG	Custom Europe			13	 	 4
-ZZK	Europe 				13		24
-ZZL	Europe				11		13
-
-
 2.   Ad-Hoc Networking
 -----------------------------------------------
 
 When using a device in an Ad-Hoc network, it is useful to understand the 
-sequence and requirements for the driver to be able to create, join, or 
-merge networks.
+sequence and requirements for the Intel PRO/Wireless 2915ABG
+Network Connection driver to be able to create, join, or merge networks.
 
 The following attempts to provide enough information so that you can 
-have a consistent experience while using the driver as a member of an 
-Ad-Hoc network.
+have a consistent experience while using the Intel PRO/Wireless 2915ABG 
+Network Connection driver as a member of an ad-hoc network.
 
 2.1. Joining an Ad-Hoc Network
 -----------------------------------------------
@@ -384,15 +382,6 @@
 are reset to the value used when the module was loaded.  This includes
 channels, rates, ESSID, etc.
 
-3.2 iwconfig sens
------------------------------------------------
-
-The 'iwconfig ethX sens XX' command will not set the signal sensitivity
-threshold, as described in iwconfig documentation, but rather the number
-of consecutive missed beacons that will trigger handover, i.e. roaming
-to another access point. At the same time, it will set the disassociation
-threshold to 3 times the given value.
-
 
 4.   About the Version Numbers
 -----------------------------------------------
@@ -407,7 +396,7 @@
 	major.minor.development
 
 Any version where the 'development' portion is 0 (for example
-1.0.0, 1.1.0, etc.) indicates a stable version that will be made 
+1.0.0, 1.2.2, etc.) indicates a stable version that will be made 
 available for kernel inclusion.
 
 Any version where the 'development' portion is not a 0 (for
@@ -419,14 +408,16 @@
 available as quickly as possible, unknown anomalies should be expected.
 
 The major version number will be incremented when significant changes
-are made to the driver.  Currently, there are no major changes planned.
+are made to the Intel PRO/Wireless 2915ABG Network Connection
+driver.  Currently, there are no major changes planned.
 
 5.  Firmware installation
 ----------------------------------------------
 
-The driver requires a firmware image, download it and extract the
-files under /lib/firmware (or wherever your hotplug's firmware.agent
-will look for firmware files)
+The Intel PRO/Wireless 2915ABG Network Connection driver
+requires a firmware image, download it and extract the files under
+/lib/firmware (or wherever your hotplug's firmware.agent will look
+for firmware files)
 
 The firmware can be downloaded from the following URL:
 
@@ -448,7 +439,7 @@
 7.  License
 -----------------------------------------------
 
-  Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.
+  Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
 
   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 
diff -Naur a/drivers/net/wireless/compat.c b/drivers/net/wireless/compat.c
--- a/drivers/net/wireless/compat.c	1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/wireless/compat.c	2007-07-12 17:22:20.000000000 +0200
@@ -0,0 +1,598 @@
+/*
+ * Header file to maintain compatibility among different kernel versions.
+ *
+ * Copyright (c) 2004-2006  Zhu Yi <yi.zhu@intel.com>, Intel Corporation
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+
+#if WIRELESS_EXT < 18
+/* Support for wpa_supplicant before WE-18, deprecated. */
+
+/* following definitions must match definitions in driver_ipw.c */
+
+#define IPW_IOCTL_WPA_SUPPLICANT		SIOCIWFIRSTPRIV+30
+
+#define IPW_CMD_SET_WPA_PARAM			1
+#define	IPW_CMD_SET_WPA_IE			2
+#define IPW_CMD_SET_ENCRYPTION			3
+#define IPW_CMD_MLME				4
+
+#define IPW_PARAM_WPA_ENABLED			1
+#define IPW_PARAM_TKIP_COUNTERMEASURES		2
+#define IPW_PARAM_DROP_UNENCRYPTED		3
+#define IPW_PARAM_PRIVACY_INVOKED		4
+#define IPW_PARAM_AUTH_ALGS			5
+#define IPW_PARAM_IEEE_802_1X			6
+
+#define IPW_MLME_STA_DEAUTH			1
+#define IPW_MLME_STA_DISASSOC			2
+
+#define IPW_CRYPT_ERR_UNKNOWN_ALG		2
+#define IPW_CRYPT_ERR_UNKNOWN_ADDR		3
+#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED		4
+#define IPW_CRYPT_ERR_KEY_SET_FAILED		5
+#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED		6
+#define IPW_CRYPT_ERR_CARD_CONF_FAILED		7
+
+#define	IPW_CRYPT_ALG_NAME_LEN			16
+
+struct ipw_param {
+	u32 cmd;
+	u8 sta_addr[ETH_ALEN];
+	union {
+		struct {
+			u8 name;
+			u32 value;
+		} wpa_param;
+		struct {
+			u32 len;
+			u8 reserved[32];
+			u8 data[0];
+		} wpa_ie;
+		struct {
+			u32 command;
+			u32 reason_code;
+		} mlme;
+		struct {
+			u8 alg[IPW_CRYPT_ALG_NAME_LEN];
+			u8 set_tx;
+			u32 err;
+			u8 idx;
+			u8 seq[8];	/* sequence counter (set: RX, get: TX) */
+			u16 key_len;
+			u8 key[0];
+		} crypt;
+
+	} u;
+};
+
+/* end of driver_ipw.c code */
+
+struct ipw_priv;
+static int ipw_wpa_enable(struct ipw_priv *priv, int value);
+static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value);
+static int ipw_disassociate(void *data);
+static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level);
+static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level);
+static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,
+                                int wpa_ie_len);
+
+static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_crypt_data *crypt;
+	unsigned long flags;
+	int ret = 0;
+
+	switch (name) {
+	case IPW_PARAM_WPA_ENABLED:
+		ret = ipw_wpa_enable(priv, value);
+		break;
+
+	case IPW_PARAM_TKIP_COUNTERMEASURES:
+		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
+			IPW_WARNING("Can't set TKIP countermeasures: "
+				    "crypt not set!\n");
+			break;
+		}
+
+		flags = crypt->ops->get_flags(crypt->priv);
+
+		if (value)
+			flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+		else
+			flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+
+		crypt->ops->set_flags(flags, crypt->priv);
+
+		break;
+
+	case IPW_PARAM_DROP_UNENCRYPTED:{
+			/* HACK:
+			 *
+			 * wpa_supplicant calls set_wpa_enabled when the driver
+			 * is loaded and unloaded, regardless of if WPA is being
+			 * used.  No other calls are made which can be used to
+			 * determine if encryption will be used or not prior to
+			 * association being expected.  If encryption is not being
+			 * used, drop_unencrypted is set to false, else true -- we
+			 * can use this to determine if the CAP_PRIVACY_ON bit should
+			 * be set.
+			 */
+			struct ieee80211_security sec = {
+				.flags = SEC_ENABLED,
+				.enabled = value,
+			};
+			priv->ieee->drop_unencrypted = value;
+			/* We only change SEC_LEVEL for open mode. Others
+			 * are set by ipw_wpa_set_encryption.
+			 */
+			if (!value) {
+				sec.flags |= SEC_LEVEL;
+				sec.level = SEC_LEVEL_0;
+			} else {
+				sec.flags |= SEC_LEVEL;
+				sec.level = SEC_LEVEL_1;
+			}
+			if (priv->ieee->set_security)
+				priv->ieee->set_security(priv->ieee->dev, &sec);
+			break;
+		}
+
+	case IPW_PARAM_PRIVACY_INVOKED:
+		priv->ieee->privacy_invoked = value;
+		break;
+
+	case IPW_PARAM_AUTH_ALGS:
+		ret = ipw_wpa_set_auth_algs(priv, value);
+		break;
+
+	case IPW_PARAM_IEEE_802_1X:
+		priv->ieee->ieee802_1x = value;
+		break;
+
+	default:
+		IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name);
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+static int ipw_wpa_mlme(struct net_device *dev, int command, int reason)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	int ret = 0;
+
+	switch (command) {
+	case IPW_MLME_STA_DEAUTH:
+		// silently ignore
+		break;
+
+	case IPW_MLME_STA_DISASSOC:
+		ipw_disassociate(priv);
+		break;
+
+	default:
+		IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command);
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+static int ipw_wpa_ie_cipher2level(u8 cipher)
+{
+	switch (cipher) {
+	case 4:		/* CCMP */
+		return SEC_LEVEL_3;
+	case 2:		/* TKIP */
+		return SEC_LEVEL_2;
+	case 5:		/* WEP104 */
+	case 1:		/* WEP40 */
+		return SEC_LEVEL_1;
+	case 0:		/* NONE */
+		return SEC_LEVEL_0;
+	default:
+		return -1;
+	}
+}
+
+static int ipw_wpa_set_wpa_ie(struct net_device *dev,
+			      struct ipw_param *param, int plen)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee;
+	u8 *buf;
+	u8 *ptk, *gtk;
+	int level;
+
+	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
+	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
+		return -EINVAL;
+
+	if (param->u.wpa_ie.len) {
+		buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+
+		memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = buf;
+		ieee->wpa_ie_len = param->u.wpa_ie.len;
+	} else {
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = NULL;
+		ieee->wpa_ie_len = 0;
+		goto done;
+	}
+
+	if (priv->ieee->host_encrypt)
+		goto done;
+
+	/* HACK: Parse wpa_ie here to get pairwise suite, otherwise
+	 * we need to change driver_ipw.c from wpa_supplicant. This
+	 * is OK since -Dipw is deprecated. The -Dwext driver has a
+	 * clean way to handle this. */
+	gtk = ptk = (u8 *) ieee->wpa_ie;
+	if (ieee->wpa_ie[0] == 0x30) {	/* RSN IE */
+		gtk += 4 + 3;
+		ptk += 4 + 4 + 2 + 3;
+	} else {		/* WPA IE */
+		gtk += 8 + 3;
+		ptk += 8 + 4 + 2 + 3;
+	}
+
+	if (ptk - (u8 *) ieee->wpa_ie > ieee->wpa_ie_len)
+		return -EINVAL;
+
+	level = ipw_wpa_ie_cipher2level(*gtk);
+	ipw_set_hw_decrypt_multicast(priv, level);
+
+	level = ipw_wpa_ie_cipher2level(*ptk);
+	ipw_set_hw_decrypt_unicast(priv, level);
+
+      done:
+	ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
+	return 0;
+}
+
+/* implementation borrowed from hostap driver */
+
+static int ipw_wpa_set_encryption(struct net_device *dev,
+				  struct ipw_param *param, int param_len)
+{
+	int ret = 0;
+	int group_key = 0;
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_crypto_ops *ops;
+	struct ieee80211_crypt_data **crypt;
+
+	struct ieee80211_security sec = {
+		.flags = 0,
+	};
+
+	param->u.crypt.err = 0;
+	param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0';
+
+	if (param_len !=
+	    (int)((char *)param->u.crypt.key - (char *)param) +
+	    param->u.crypt.key_len) {
+		IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
+			       param->u.crypt.key_len);
+		return -EINVAL;
+	}
+	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+		if (param->u.crypt.idx >= WEP_KEYS)
+			return -EINVAL;
+		crypt = &ieee->crypt[param->u.crypt.idx];
+	} else {
+		return -EINVAL;
+	}
+
+	if (param->u.crypt.idx != 0)
+		group_key = 1;
+
+	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
+	if (strcmp(param->u.crypt.alg, "none") == 0) {
+		if (crypt) {
+			sec.enabled = 0;
+			sec.encrypt = 0;
+			sec.level = SEC_LEVEL_0;
+			sec.flags |= SEC_LEVEL;
+			ieee80211_crypt_delayed_deinit(ieee, crypt);
+		}
+		goto done;
+	}
+	sec.enabled = 1;
+	sec.encrypt = 1;
+
+	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
+	if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		if (group_key)
+			ieee->host_mc_decrypt = 1;
+		else
+			ieee->host_encrypt_msdu = 1;
+	}
+
+	/*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu ||
+	   ieee->host_decrypt))
+	   goto skip_host_crypt; */
+	if (group_key ? !ieee->host_mc_decrypt :
+	    !(ieee->host_encrypt || ieee->host_decrypt ||
+	      ieee->host_encrypt_msdu))
+		goto skip_host_crypt;
+
+	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
+		request_module("ieee80211_crypt_wep");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		request_module("ieee80211_crypt_tkip");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
+		request_module("ieee80211_crypt_ccmp");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	}
+	if (ops == NULL) {
+		IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
+			       dev->name, param->u.crypt.alg);
+		param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG;
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (*crypt == NULL || (*crypt)->ops != ops) {
+		struct ieee80211_crypt_data *new_crypt;
+
+		ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+		new_crypt = (struct ieee80211_crypt_data *)
+		    kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+		if (new_crypt == NULL) {
+			ret = -ENOMEM;
+			goto done;
+		}
+		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+		new_crypt->ops = ops;
+		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+			new_crypt->priv =
+			    new_crypt->ops->init(param->u.crypt.idx);
+
+		if (new_crypt->priv == NULL) {
+			kfree(new_crypt);
+			param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED;
+			ret = -EINVAL;
+			goto done;
+		}
+
+		*crypt = new_crypt;
+	}
+
+	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
+	    (*crypt)->ops->set_key(param->u.crypt.key,
+				   param->u.crypt.key_len, param->u.crypt.seq,
+				   (*crypt)->priv) < 0) {
+		IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
+		param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED;
+		ret = -EINVAL;
+		goto done;
+	}
+
+      skip_host_crypt:
+	if (param->u.crypt.set_tx) {
+		ieee->tx_keyidx = param->u.crypt.idx;
+		sec.active_key = param->u.crypt.idx;
+		sec.flags |= SEC_ACTIVE_KEY;
+	} else
+		sec.flags &= ~SEC_ACTIVE_KEY;
+
+	if (param->u.crypt.alg != NULL) {
+		memcpy(sec.keys[param->u.crypt.idx],
+		       param->u.crypt.key, param->u.crypt.key_len);
+		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
+		sec.flags |= (1 << param->u.crypt.idx);
+
+		if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_1;
+		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_2;
+		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_3;
+		}
+		/* Don't set sec level for group keys. */
+		if (group_key)
+			sec.flags &= ~SEC_LEVEL;
+	}
+      done:
+	if (ieee->set_security)
+		ieee->set_security(ieee->dev, &sec);
+
+	/* Do not reset port if card is in Managed mode since resetting will
+	 * generate new IEEE 802.11 authentication which may end up in looping
+	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
+	 * configuration (for example... Prism2), implement the reset_port in
+	 * the callbacks structures used to initialize the 802.11 stack. */
+	if (ieee->reset_on_keychange &&
+	    ieee->iw_mode != IW_MODE_INFRA &&
+	    ieee->reset_port && ieee->reset_port(dev)) {
+		IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
+		param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p)
+{
+	struct ipw_param *param;
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	int ret = 0;
+
+	IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
+
+	if (p->length < sizeof(struct ipw_param) || !p->pointer)
+		return -EINVAL;
+
+	param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL);
+	if (param == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(param, p->pointer, p->length)) {
+		kfree(param);
+		return -EFAULT;
+	}
+
+	mutex_lock(&priv->mutex);
+	switch (param->cmd) {
+
+	case IPW_CMD_SET_WPA_PARAM:
+		ret = ipw_wpa_set_param(dev, param->u.wpa_param.name,
+					param->u.wpa_param.value);
+		break;
+
+	case IPW_CMD_SET_WPA_IE:
+		ret = ipw_wpa_set_wpa_ie(dev, param, p->length);
+		break;
+
+	case IPW_CMD_SET_ENCRYPTION:
+		ret = ipw_wpa_set_encryption(dev, param, p->length);
+		break;
+
+	case IPW_CMD_MLME:
+		ret = ipw_wpa_mlme(dev, param->u.mlme.command,
+				   param->u.mlme.reason_code);
+		break;
+
+	default:
+		IPW_ERROR("%s: Unknown WPA supplicant request: %d\n",
+			  dev->name, param->cmd);
+		ret = -EOPNOTSUPP;
+	}
+
+	mutex_unlock(&priv->mutex);
+	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
+		ret = -EFAULT;
+
+	kfree(param);
+	return ret;
+}
+
+static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct iwreq *wrq = (struct iwreq *)rq;
+	int ret = -1;
+	switch (cmd) {
+	case IPW_IOCTL_WPA_SUPPLICANT:
+		ret = ipw_wpa_supplicant(dev, &wrq->u.data);
+		return ret;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return -EOPNOTSUPP;
+}
+#endif
+
+/* GEO code borrowed from ieee80211_geo.c */
+static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+{
+	int i;
+
+	/* Driver needs to initialize the geography map before using
+	 * these helper functions */
+	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+		for (i = 0; i < ieee->geo.bg_channels; i++)
+			/* NOTE: If G mode is currently supported but
+			 * this is a B only channel, we don't see it
+			 * as valid. */
+			if ((ieee->geo.bg[i].channel == channel) &&
+			    (!(ieee->mode & IEEE_G) ||
+			     !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
+				return IEEE80211_24GHZ_BAND;
+
+	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+		for (i = 0; i < ieee->geo.a_channels; i++)
+			if (ieee->geo.a[i].channel == channel)
+				return IEEE80211_52GHZ_BAND;
+
+	return 0;
+}
+
+static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+{
+	int i;
+
+	/* Driver needs to initialize the geography map before using
+	 * these helper functions */
+	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+		for (i = 0; i < ieee->geo.bg_channels; i++)
+			if (ieee->geo.bg[i].channel == channel)
+				return i;
+
+	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+		for (i = 0; i < ieee->geo.a_channels; i++)
+			if (ieee->geo.a[i].channel == channel)
+				return i;
+
+	return -1;
+}
+
+static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
+{
+	int i;
+
+	/* Driver needs to initialize the geography map before using
+	 * these helper functions */
+	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+	freq /= 100000;
+
+	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+		for (i = 0; i < ieee->geo.bg_channels; i++)
+			if (ieee->geo.bg[i].freq == freq)
+				return ieee->geo.bg[i].channel;
+
+	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+		for (i = 0; i < ieee->geo.a_channels; i++)
+			if (ieee->geo.a[i].freq == freq)
+				return ieee->geo.a[i].channel;
+
+	return 0;
+}
+
+static int ipw_set_geo(struct ieee80211_device *ieee,
+		       const struct ieee80211_geo *geo)
+{
+	memcpy(ieee->geo.name, geo->name, 3);
+	ieee->geo.name[3] = '\0';
+	ieee->geo.bg_channels = geo->bg_channels;
+	ieee->geo.a_channels = geo->a_channels;
+	memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
+	       sizeof(struct ieee80211_channel));
+	memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
+	       sizeof(struct ieee80211_channel));
+	return 0;
+}
+
+static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
+{
+	return &ieee->geo;
+}
diff -Naur a/drivers/net/wireless/compat.h b/drivers/net/wireless/compat.h
--- a/drivers/net/wireless/compat.h	1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/wireless/compat.h	2007-07-12 17:22:20.000000000 +0200
@@ -0,0 +1,87 @@
+/*
+ * Header file to maintain compatibility among different kernel versions.
+ *
+ * Copyright (c) 2004-2006  Zhu Yi <yi.zhu@intel.com>, Intel Corporation
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+# include <linux/mutex.h>
+#else
+# define mutex semaphore
+# define mutex_init init_MUTEX
+# define mutex_lock down
+# define mutex_unlock up
+#endif
+
+#ifndef IW_QUAL_DBM
+# define IW_QUAL_DBM 0
+#endif
+
+#ifndef ARPHRD_IEEE80211_RADIOTAP
+#define ARPHRD_IEEE80211_RADIOTAP 803  /* IEEE 802.11 + radiotap header */
+#endif
+
+#ifndef __bitwise		/* if __leXX is not defined */
+typedef __u16 __le16;
+typedef __u64 __le64;
+#endif
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_UPDATED    0x01	/* Value was updated since last read */
+#define IW_QUAL_LEVEL_UPDATED   0x02
+#define IW_QUAL_NOISE_UPDATED   0x04
+#define IW_QUAL_ALL_UPDATED     0x07
+#define IW_QUAL_QUAL_INVALID    0x10	/* Driver doesn't provide value */
+#define IW_QUAL_LEVEL_INVALID   0x20
+#define IW_QUAL_NOISE_INVALID   0x40
+#define IW_QUAL_ALL_INVALID     0x70
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8)
+#define	__iomem
+#define	__le32		u32
+#endif
+
+#ifndef	NETDEV_TX_OK
+#define	NETDEV_TX_OK		0
+#endif
+
+#ifndef IRQF_SHARED
+#define IRQF_SHARED	SA_SHIRQ
+#endif
+
+#ifndef IW_SCAN_TYPE_ACTIVE
+#define IW_SCAN_TYPE_ACTIVE 0
+#define IW_SCAN_TYPE_PASSIVE 1
+#endif
+
+#if WIRELESS_EXT < 18
+#define IW_AUTH_ALG_OPEN_SYSTEM			0x1
+#define IW_AUTH_ALG_SHARED_KEY			0x2
+#define IW_AUTH_ALG_LEAP			0x4
+#endif
+
+#if WIRELESS_EXT > 20
+#define IW_ESSID_FIX	0
+#else
+#define IW_ESSID_FIX	1
+#define IW_RETRY_LONG IW_RETRY_MAX
+#define IW_RETRY_SHORT IW_RETRY_MIN
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+static inline void *kzalloc(size_t size, unsigned flags)
+{
+	void *ret = kmalloc(size, flags);
+	if (ret)
+		memset(ret, 0, size);
+	return ret;
+}
+#endif
diff -Naur a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
--- a/drivers/net/wireless/ipw2200.c	2007-07-10 20:56:30.000000000 +0200
+++ b/drivers/net/wireless/ipw2200.c	2007-07-12 17:24:06.000000000 +0200
@@ -70,7 +70,7 @@
 #define VQ
 #endif
 
-#define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ
+#define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2006 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
@@ -187,15 +187,25 @@
 static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
 static void ipw_rx_queue_replenish(void *);
 static int ipw_up(struct ipw_priv *);
-static void ipw_bg_up(struct work_struct *work);
 static void ipw_down(struct ipw_priv *);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_up(void *work);
+static void ipw_bg_down(void *work);
+#else
+static void ipw_bg_up(struct work_struct *work);
 static void ipw_bg_down(struct work_struct *work);
+#endif
 static int ipw_config(struct ipw_priv *);
 static int init_supported_rates(struct ipw_priv *priv,
 				struct ipw_supported_rates *prates);
 static void ipw_set_hwcrypto_keys(struct ipw_priv *);
 static void ipw_send_wep_keys(struct ipw_priv *, int);
 
+static inline int ipw_is_multicast_ether_addr(const u8 * addr)
+{
+	return (0x01 & addr[0]);
+}
+
 static int snprint_line(char *buf, size_t count,
 			const u8 * data, u32 len, u32 ofs)
 {
@@ -637,6 +647,8 @@
 	return (priv->status & STATUS_INIT) ? 1 : 0;
 }
 
+#include "compat.c"
+
 static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
 {
 	u32 addr, field_info, field_len, field_count, total_len;
@@ -862,10 +874,16 @@
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_led_link_on(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_led_link_on(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, led_link_on.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_led_link_on(priv);
 	mutex_unlock(&priv->mutex);
@@ -907,10 +925,16 @@
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_led_link_off(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_led_link_off(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, led_link_off.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_led_link_off(priv);
 	mutex_unlock(&priv->mutex);
@@ -987,10 +1011,16 @@
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_led_activity_off(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_led_activity_off(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, led_act_off.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_led_activity_off(priv);
 	mutex_unlock(&priv->mutex);
@@ -1229,7 +1259,10 @@
 }
 
 static ssize_t show_event_log(struct device *d,
-			      struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			      struct device_attribute *attr,
+#endif
+			      char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	u32 log_len = ipw_get_event_log_len(priv);
@@ -1250,7 +1283,10 @@
 static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
 
 static ssize_t show_error(struct device *d,
-			  struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			  struct device_attribute *attr,
+#endif
+			  char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	u32 len = 0, i;
@@ -1285,7 +1321,9 @@
 }
 
 static ssize_t clear_error(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 			   struct device_attribute *attr,
+#endif
 			   const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
@@ -1298,7 +1336,10 @@
 static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
 
 static ssize_t show_cmd_log(struct device *d,
-			    struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			    struct device_attribute *attr,
+#endif
+			    char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	u32 len = 0, i;
@@ -1328,8 +1369,10 @@
 static void ipw_prom_free(struct ipw_priv *priv);
 static int ipw_prom_alloc(struct ipw_priv *priv);
 static ssize_t store_rtap_iface(struct device *d,
-			 struct device_attribute *attr,
-			 const char *buf, size_t count)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				struct device_attribute *attr,
+#endif
+				const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	int rc = 0;
@@ -1373,8 +1416,10 @@
 }
 
 static ssize_t show_rtap_iface(struct device *d,
-			struct device_attribute *attr,
-			char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			       struct device_attribute *attr,
+#endif
+			       char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	if (rtap_iface)
@@ -1391,8 +1436,10 @@
 		   store_rtap_iface);
 
 static ssize_t store_rtap_filter(struct device *d,
-			 struct device_attribute *attr,
-			 const char *buf, size_t count)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				 struct device_attribute *attr,
+#endif
+				 const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 
@@ -1411,8 +1458,10 @@
 }
 
 static ssize_t show_rtap_filter(struct device *d,
-			struct device_attribute *attr,
-			char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				struct device_attribute *attr,
+#endif
+				char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	return sprintf(buf, "0x%04X",
@@ -1423,14 +1472,20 @@
 		   store_rtap_filter);
 #endif
 
-static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
+static ssize_t show_scan_age(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			     struct device_attribute *attr,
+#endif
 			     char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	return sprintf(buf, "%d\n", priv->ieee->scan_age);
 }
 
-static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
+static ssize_t store_scan_age(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			      struct device_attribute *attr,
+#endif
 			      const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
@@ -1466,14 +1521,20 @@
 
 static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
 
-static ssize_t show_led(struct device *d, struct device_attribute *attr,
+static ssize_t show_led(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			struct device_attribute *attr,
+#endif
 			char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
 	return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
 }
 
-static ssize_t store_led(struct device *d, struct device_attribute *attr,
+static ssize_t store_led(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			 struct device_attribute *attr,
+#endif
 			 const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
@@ -1500,7 +1561,10 @@
 static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
 
 static ssize_t show_status(struct device *d,
-			   struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			   struct device_attribute *attr,
+#endif
+			   char *buf)
 {
 	struct ipw_priv *p = d->driver_data;
 	return sprintf(buf, "0x%08x\n", (int)p->status);
@@ -1508,7 +1572,10 @@
 
 static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 
-static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
+static ssize_t show_cfg(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			struct device_attribute *attr,
+#endif
 			char *buf)
 {
 	struct ipw_priv *p = d->driver_data;
@@ -1518,7 +1585,10 @@
 static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
 
 static ssize_t show_nic_type(struct device *d,
-			     struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			     struct device_attribute *attr,
+#endif
+			     char *buf)
 {
 	struct ipw_priv *priv = d->driver_data;
 	return sprintf(buf, "TYPE: %d\n", priv->nic_type);
@@ -1527,7 +1597,10 @@
 static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
 
 static ssize_t show_ucode_version(struct device *d,
-				  struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				  struct device_attribute *attr,
+#endif
+				  char *buf)
 {
 	u32 len = sizeof(u32), tmp = 0;
 	struct ipw_priv *p = d->driver_data;
@@ -1540,7 +1613,10 @@
 
 static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);
 
-static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
+static ssize_t show_rtc(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			struct device_attribute *attr,
+#endif
 			char *buf)
 {
 	u32 len = sizeof(u32), tmp = 0;
@@ -1559,13 +1635,18 @@
  * operations.
  */
 static ssize_t show_eeprom_delay(struct device *d,
-				 struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				 struct device_attribute *attr,
+#endif
+				 char *buf)
 {
 	int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
 	return sprintf(buf, "%i\n", n);
 }
 static ssize_t store_eeprom_delay(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 				  struct device_attribute *attr,
+#endif
 				  const char *buf, size_t count)
 {
 	struct ipw_priv *p = d->driver_data;
@@ -1577,7 +1658,10 @@
 		   show_eeprom_delay, store_eeprom_delay);
 
 static ssize_t show_command_event_reg(struct device *d,
-				      struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				      struct device_attribute *attr,
+#endif
+				      char *buf)
 {
 	u32 reg = 0;
 	struct ipw_priv *p = d->driver_data;
@@ -1586,7 +1670,9 @@
 	return sprintf(buf, "0x%08x\n", reg);
 }
 static ssize_t store_command_event_reg(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 				       struct device_attribute *attr,
+#endif
 				       const char *buf, size_t count)
 {
 	u32 reg;
@@ -1601,7 +1687,10 @@
 		   show_command_event_reg, store_command_event_reg);
 
 static ssize_t show_mem_gpio_reg(struct device *d,
-				 struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				 struct device_attribute *attr,
+#endif
+				 char *buf)
 {
 	u32 reg = 0;
 	struct ipw_priv *p = d->driver_data;
@@ -1610,7 +1699,9 @@
 	return sprintf(buf, "0x%08x\n", reg);
 }
 static ssize_t store_mem_gpio_reg(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 				  struct device_attribute *attr,
+#endif
 				  const char *buf, size_t count)
 {
 	u32 reg;
@@ -1625,7 +1716,10 @@
 		   show_mem_gpio_reg, store_mem_gpio_reg);
 
 static ssize_t show_indirect_dword(struct device *d,
-				   struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				   struct device_attribute *attr,
+#endif
+				   char *buf)
 {
 	u32 reg = 0;
 	struct ipw_priv *priv = d->driver_data;
@@ -1638,7 +1732,9 @@
 	return sprintf(buf, "0x%08x\n", reg);
 }
 static ssize_t store_indirect_dword(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 				    struct device_attribute *attr,
+#endif
 				    const char *buf, size_t count)
 {
 	struct ipw_priv *priv = d->driver_data;
@@ -1652,7 +1748,10 @@
 		   show_indirect_dword, store_indirect_dword);
 
 static ssize_t show_indirect_byte(struct device *d,
-				  struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				  struct device_attribute *attr,
+#endif
+				  char *buf)
 {
 	u8 reg = 0;
 	struct ipw_priv *priv = d->driver_data;
@@ -1665,7 +1764,9 @@
 	return sprintf(buf, "0x%02x\n", reg);
 }
 static ssize_t store_indirect_byte(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 				   struct device_attribute *attr,
+#endif
 				   const char *buf, size_t count)
 {
 	struct ipw_priv *priv = d->driver_data;
@@ -1679,7 +1780,10 @@
 		   show_indirect_byte, store_indirect_byte);
 
 static ssize_t show_direct_dword(struct device *d,
-				 struct device_attribute *attr, char *buf)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				 struct device_attribute *attr,
+#endif
+				 char *buf)
 {
 	u32 reg = 0;
 	struct ipw_priv *priv = d->driver_data;
@@ -1692,7 +1796,9 @@
 	return sprintf(buf, "0x%08x\n", reg);
 }
 static ssize_t store_direct_dword(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
 				  struct device_attribute *attr,
+#endif
 				  const char *buf, size_t count)
 {
 	struct ipw_priv *priv = d->driver_data;
@@ -1715,7 +1821,10 @@
 	return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
 }
 
-static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
+static ssize_t show_rf_kill(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			    struct device_attribute *attr,
+#endif
 			    char *buf)
 {
 	/* 0 - RF kill not enabled
@@ -1759,7 +1868,10 @@
 	return 1;
 }
 
-static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
+static ssize_t store_rf_kill(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			     struct device_attribute *attr,
+#endif
 			     const char *buf, size_t count)
 {
 	struct ipw_priv *priv = d->driver_data;
@@ -1771,7 +1883,10 @@
 
 static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
 
-static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
+static ssize_t show_speed_scan(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			       struct device_attribute *attr,
+#endif
 			       char *buf)
 {
 	struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
@@ -1786,7 +1901,10 @@
 	return sprintf(buf, "0\n");
 }
 
-static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
+static ssize_t store_speed_scan(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+				struct device_attribute *attr,
+#endif
 				const char *buf, size_t count)
 {
 	struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
@@ -1800,7 +1918,7 @@
 			break;
 		}
 
-		if (ieee80211_is_valid_channel(priv->ieee, channel))
+		if (ipw_is_valid_channel(priv->ieee, channel))
 			priv->speed_scan[pos++] = channel;
 		else
 			IPW_WARNING("Skipping invalid channel request: %d\n",
@@ -1825,14 +1943,20 @@
 static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
 		   store_speed_scan);
 
-static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
+static ssize_t show_net_stats(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			      struct device_attribute *attr,
+#endif
 			      char *buf)
 {
 	struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
 	return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
 }
 
-static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
+static ssize_t store_net_stats(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+			       struct device_attribute *attr,
+#endif
 			       const char *buf, size_t count)
 {
 	struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
@@ -1852,7 +1976,7 @@
 			     char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	int len = 0, i;
 
 	len = sprintf(&buf[len],
@@ -1893,6 +2017,66 @@
 
 static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
 
+static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, int pri);
+
+/* SYSFS INJECT */
+static ssize_t store_inject(struct device *d,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+	struct device_attribute *attr,
+#endif
+	const char *buf, size_t count) 
+{
+	struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_txb * txb;
+	struct sk_buff *skb_frag;
+	unsigned char * newbuf;
+	unsigned long flags;
+
+	// should test (ieee->is_queue_full) 
+	
+	// Fw only accepts data, so avoid accidental fw errors.
+	if ( (buf[0]&0x0c) != '\x08') {
+		//printk("ipw2200: inject: discarding non-data frame (type=%02X)\n",(int)(unsigned char)buf[0]);
+		return count;
+	}
+
+	if (count>1500) {
+		count=1500;
+		printk("ipw2200: inject: cutting down frame to 1500 bytes\n");
+	}
+	
+	spin_lock_irqsave(&priv->lock, flags);
+
+	// Create a txb with one skb
+	txb = kmalloc(sizeof(struct ieee80211_txb) + sizeof(u8 *), GFP_ATOMIC);
+	if (!txb)
+		goto nosepuede;
+	txb->nr_frags=1;
+	txb->frag_size = ieee->tx_headroom;
+	txb->fragments[0]=__dev_alloc_skb(count + ieee->tx_headroom, GFP_ATOMIC);
+	if (!txb->fragments[0]) {
+		kfree(txb);
+		goto nosepuede;
+	}
+	skb_reserve(txb->fragments[0], ieee->tx_headroom);
+	txb->encrypted=0;
+	txb->payload_size=count;
+	skb_frag = txb->fragments[0];
+	newbuf=skb_put(skb_frag, count);
+
+	// copy data into txb->skb and send it
+	memcpy(newbuf, buf, count);
+	
+	ipw_tx_skb(priv, txb, 0);
+
+nosepuede:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return count;
+}
+
+static DEVICE_ATTR(inject, S_IWUSR, NULL, store_inject);
+
 static void notify_wx_assoc_event(struct ipw_priv *priv)
 {
 	union iwreq_data wrqu;
@@ -2277,10 +2461,16 @@
 	}
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_adapter_restart(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_adapter_restart(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, adapter_restart);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_adapter_restart(priv);
 	mutex_unlock(&priv->mutex);
@@ -2299,10 +2489,16 @@
 	}
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_scan_check(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_scan_check(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, scan_check.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_scan_check(priv);
 	mutex_unlock(&priv->mutex);
@@ -2411,7 +2607,7 @@
 
 static int ipw_set_tx_power(struct ipw_priv *priv)
 {
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	struct ipw_tx_power tx_power;
 	s8 max_power;
 	int i;
@@ -2506,7 +2702,7 @@
 		break;
 	}
 
-	param = cpu_to_le32(mode);
+	param = cpu_to_le32(param);
 	return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
 				&param);
 }
@@ -3882,19 +4078,31 @@
 	return 1;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_disassociate(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_disassociate(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, disassociate);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_disassociate(priv);
 	mutex_unlock(&priv->mutex);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_system_config(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_system_config(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, system_config);
+#endif
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS
 	if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
@@ -4261,10 +4469,16 @@
 			   IPW_STATS_INTERVAL);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_gather_stats(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_gather_stats(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, gather_stats.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_gather_stats(priv);
 	mutex_unlock(&priv->mutex);
@@ -5109,10 +5323,16 @@
 	ipw_rx_queue_restock(priv);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_rx_queue_replenish(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_rx_queue_replenish(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, rx_replenish);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_rx_queue_replenish(priv);
 	mutex_unlock(&priv->mutex);
@@ -5544,10 +5764,16 @@
 	return 1;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_merge_adhoc_network(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_merge_adhoc_network(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, merge_networks);
+#endif
 	struct ieee80211_network *network = NULL;
 	struct ipw_network_match match = {
 		.network = priv->assoc_network
@@ -5736,7 +5962,7 @@
 	}
 
 	/* Filter out invalid channel in current GEO */
-	if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) {
+	if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
 		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
 				"because of invalid channel in current GEO\n",
 				escape_essid(network->ssid, network->ssid_len),
@@ -5781,7 +6007,7 @@
 static void ipw_adhoc_create(struct ipw_priv *priv,
 			     struct ieee80211_network *network)
 {
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	int i;
 
 	/*
@@ -5796,10 +6022,10 @@
 	 * FW fatal error.
 	 *
 	 */
-	switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
+	switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
 	case IEEE80211_52GHZ_BAND:
 		network->mode = IEEE_A;
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = ipw_channel_to_index(priv->ieee, priv->channel);
 		BUG_ON(i == -1);
 		if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
 			IPW_WARNING("Overriding invalid channel\n");
@@ -5812,7 +6038,7 @@
 			network->mode = IEEE_G;
 		else
 			network->mode = IEEE_B;
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = ipw_channel_to_index(priv->ieee, priv->channel);
 		BUG_ON(i == -1);
 		if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
 			IPW_WARNING("Overriding invalid channel\n");
@@ -6004,10 +6230,16 @@
 			   priv->assoc_request.beacon_interval);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_adhoc_check(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_adhoc_check(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, adhoc_check.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_adhoc_check(priv);
 	mutex_unlock(&priv->mutex);
@@ -6132,7 +6364,7 @@
 	const struct ieee80211_geo *geo;
 	int i;
 
-	geo = ieee80211_get_geo(priv->ieee);
+	geo = ipw_get_geo(priv->ieee);
 
 	if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
 		int start = channel_index;
@@ -6192,7 +6424,7 @@
 				channel_index++;
 				scan->channels_list[channel_index] = channel;
 				index =
-				    ieee80211_channel_to_index(priv->ieee, channel);
+				    ipw_channel_to_index(priv->ieee, channel);
 				ipw_set_scan_type(scan, channel_index,
 						  geo->bg[index].
 						  flags &
@@ -6284,7 +6516,7 @@
 		u8 channel;
 		u8 band = 0;
 
-		switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
+		switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
 		case IEEE80211_52GHZ_BAND:
 			band = (u8) (IPW_A_MODE << 6) | 1;
 			channel = priv->channel;
@@ -6356,24 +6588,42 @@
 	return err;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_request_passive_scan(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_request_passive_scan(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, request_passive_scan);
+#endif
   	ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_request_scan(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_request_scan(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, request_scan.work);
+#endif
 	ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_abort_scan(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_abort_scan(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, abort_scan);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_abort_scan(priv);
 	mutex_unlock(&priv->mutex);
@@ -6431,6 +6681,7 @@
 				capabilities);
 }
 
+#if WIRELESS_EXT > 17
 /*
  * WE-18 support
  */
@@ -6737,6 +6988,7 @@
 	}
 	return 0;
 }
+#endif
 
 #ifdef CONFIG_IPW2200_QOS
 
@@ -7101,7 +7353,7 @@
 	struct ieee80211_qos_data *qos_data = NULL;
 	int active, supported;
 	u8 *daddr = skb->data + ETH_ALEN;
-	int unicast = !is_multicast_ether_addr(daddr);
+	int unicast = !ipw_is_multicast_ether_addr(daddr);
 
 	if (!(priv->status & STATUS_ASSOCIATED))
 		return 0;
@@ -7148,10 +7400,16 @@
 /*
 * background support to run QoS activate functionality
 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_qos_activate(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_qos_activate(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, qos_activate);
+#endif
 
 	if (priv == NULL)
 		return;
@@ -7459,10 +7717,16 @@
 	priv->status &= ~STATUS_ROAMING;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_roam(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_roam(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, roam);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_roam(priv);
 	mutex_unlock(&priv->mutex);
@@ -7557,10 +7821,16 @@
 	return 1;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_associate(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_associate(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, associate);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_associate(priv);
 	mutex_unlock(&priv->mutex);
@@ -7641,7 +7911,7 @@
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
 	hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
 	if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
-	    (is_multicast_ether_addr(hdr->addr1) ?
+	    (ipw_is_multicast_ether_addr(hdr->addr1) ?
 	     !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
@@ -8043,7 +8313,7 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our BSSID go through */
-		if (is_multicast_ether_addr(header->addr1))
+		if (ipw_is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -8056,7 +8326,7 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our BSS go through */
-		if (is_multicast_ether_addr(header->addr1))
+		if (ipw_is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -8179,7 +8449,11 @@
 		skb->dev = priv->ieee->dev;
 
 		/* Point raw at the ieee80211_stats */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+		skb->mac.raw = skb->data;
+#else
 		skb_reset_mac_header(skb);
+#endif
 
 		skb->pkt_type = PACKET_OTHERHOST;
 		skb->protocol = __constant_htons(ETH_P_80211_STATS);
@@ -8605,7 +8879,7 @@
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	struct iw_freq *fwrq = &wrqu->freq;
 	int ret = 0, i;
 	u8 channel, flags;
@@ -8620,17 +8894,17 @@
 	}
 	/* if setting by freq convert to channel */
 	if (fwrq->e == 1) {
-		channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
+		channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
 		if (channel == 0)
 			return -EINVAL;
 	} else
 		channel = fwrq->m;
 
-	if (!(band = ieee80211_is_valid_channel(priv->ieee, channel)))
+	if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
 		return -EINVAL;
 
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
-		i = ieee80211_channel_to_index(priv->ieee, channel);
+		i = ipw_channel_to_index(priv->ieee, channel);
 		if (i == -1)
 			return -EINVAL;
 
@@ -8664,11 +8938,11 @@
 	    priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) {
 		int i;
 
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = ipw_channel_to_index(priv->ieee, priv->channel);
 		BUG_ON(i == -1);
 		wrqu->freq.e = 1;
 
-		switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
+		switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
 		case IEEE80211_52GHZ_BAND:
 			wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000;
 			break;
@@ -8775,7 +9049,7 @@
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct iw_range *range = (struct iw_range *)extra;
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	int i = 0, j;
 
 	wrqu->data.length = sizeof(*range);
@@ -8847,6 +9121,7 @@
 
 	mutex_unlock(&priv->mutex);
 
+#if WIRELESS_EXT >= 17
 	/* Event capability (kernel + driver) */
 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
 				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
@@ -8854,8 +9129,11 @@
 				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 
+#if WIRELESS_EXT >= 18
 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+	    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+#endif
 
 	IPW_DEBUG_WX("GET Range\n");
 	return 0;
@@ -8950,7 +9228,8 @@
                 return 0;
         }
 
-	length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
+	length = min((int) (wrqu->essid.length - IW_ESSID_FIX),
+		     IW_ESSID_MAX_SIZE);
 
 	priv->config |= CFG_STATIC_ESSID;
 
@@ -9027,7 +9306,7 @@
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_WX("Getting nick\n");
 	mutex_lock(&priv->mutex);
-	wrqu->data.length = strlen(priv->nick);
+	wrqu->data.length = strlen(priv->nick) + IW_ESSID_FIX;
 	memcpy(extra, priv->nick, wrqu->data.length);
 	wrqu->data.flags = 1;	/* active */
 	mutex_unlock(&priv->mutex);
@@ -9398,6 +9677,7 @@
 	return 0;
 }
 
+#if WIRELESS_EXT > 17
 static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
 				   int essid_len)
 {
@@ -9463,12 +9743,14 @@
 	mutex_unlock(&priv->mutex);
 	return err;
 }
+#endif				/* WIRELESS_EXT > 17 */
 
 static int ipw_wx_set_scan(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+#if WIRELESS_EXT > 17
 	struct iw_scan_req *req = (struct iw_scan_req *)extra;
 
 	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
@@ -9483,7 +9765,7 @@
 			return 0;
 		}
 	}
-
+#endif
 	IPW_DEBUG_WX("Start scan\n");
 
 	queue_delayed_work(priv->workqueue, &priv->request_scan, 0);
@@ -9567,6 +9849,7 @@
 		priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
 	else
 		priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
+
 	err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
 	if (err) {
 		IPW_DEBUG_WX("failed setting power mode.\n");
@@ -9603,22 +9886,19 @@
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int mode = *(int *)extra;
 	int err;
+
 	mutex_lock(&priv->mutex);
-	if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
+	if ((mode < 1) || (mode > IPW_POWER_LIMIT))
 		mode = IPW_POWER_AC;
-		priv->power_mode = mode;
-	} else {
-		priv->power_mode = IPW_POWER_ENABLED | mode;
-	}
 
-	if (priv->power_mode != mode) {
+	if (IPW_POWER_LEVEL(priv->power_mode) != mode) {
 		err = ipw_send_power_mode(priv, mode);
-
 		if (err) {
 			IPW_DEBUG_WX("failed setting power mode.\n");
 			mutex_unlock(&priv->mutex);
 			return err;
 		}
+		priv->power_mode = IPW_POWER_ENABLED | mode;
 	}
 	mutex_unlock(&priv->mutex);
 	return 0;
@@ -9935,6 +10215,7 @@
 	IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
 	IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
 	IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
+#if WIRELESS_EXT > 17
 	IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
 	IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
 	IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
@@ -9942,6 +10223,7 @@
 	IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
 	IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
 	IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
+#endif
 };
 
 enum {
@@ -10017,7 +10299,9 @@
 	.num_private_args = ARRAY_SIZE(ipw_priv_args),
 	.private = ipw_priv_handler,
 	.private_args = ipw_priv_args,
+#if WIRELESS_EXT >= 17
 	.get_wireless_stats = ipw_get_wireless_stats,
+#endif
 };
 
 /*
@@ -10138,7 +10422,7 @@
 	hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
-		unicast = !is_multicast_ether_addr(hdr->addr1);
+		unicast = !ipw_is_multicast_ether_addr(hdr->addr1);
 		id = ipw_find_station(priv, hdr->addr1);
 		if (id == IPW_INVALID_STATION) {
 			id = ipw_add_station(priv, hdr->addr1);
@@ -10153,7 +10437,7 @@
 
 	case IW_MODE_INFRA:
 	default:
-		unicast = !is_multicast_ether_addr(hdr->addr3);
+		unicast = !ipw_is_multicast_ether_addr(hdr->addr3);
 		id = 0;
 		break;
 	}
@@ -10401,7 +10685,11 @@
 
 		rt_hdr->it_len = dst->len;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+		memcpy(skb_put(dst, len), src->data, len);
+#else
 		skb_copy_from_linear_data(src, skb_put(dst, len), len);
+#endif
 
 		if (!ieee80211_rx(priv->prom_priv->ieee, dst, &dummystats))
 			dev_kfree_skb_any(dst);
@@ -10535,7 +10823,11 @@
 	return 0;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static struct ethtool_ops ipw_ethtool_ops = {
+#else
 static const struct ethtool_ops ipw_ethtool_ops = {
+#endif
 	.get_link = ipw_ethtool_get_link,
 	.get_drvinfo = ipw_ethtool_get_drvinfo,
 	.get_eeprom_len = ipw_ethtool_get_eeprom_len,
@@ -10543,7 +10835,11 @@
 	.set_eeprom = ipw_ethtool_set_eeprom,
 };
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
+#else
 static irqreturn_t ipw_isr(int irq, void *data)
+#endif
 {
 	struct ipw_priv *priv = data;
 	u32 inta, inta_mask;
@@ -10554,7 +10850,7 @@
 	spin_lock(&priv->irq_lock);
 
 	if (!(priv->status & STATUS_INT_ENABLED)) {
-		/* Shared IRQ */
+		/* IRQ is disabled */
 		goto none;
 	}
 
@@ -10623,10 +10919,16 @@
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_rf_kill(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_rf_kill(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, rf_kill.work);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_rf_kill(priv);
 	mutex_unlock(&priv->mutex);
@@ -10659,10 +10961,16 @@
 		queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_link_up(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_link_up(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, link_up);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_link_up(priv);
 	mutex_unlock(&priv->mutex);
@@ -10688,10 +10996,16 @@
 	}
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_link_down(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_link_down(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, link_down);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_link_down(priv);
 	mutex_unlock(&priv->mutex);
@@ -10701,10 +11015,50 @@
 {
 	int ret = 0;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) && defined (PF_SYNCTHREAD)
+	priv->workqueue = create_workqueue(DRV_NAME, 0);
+#else
 	priv->workqueue = create_workqueue(DRV_NAME);
+#endif
 	init_waitqueue_head(&priv->wait_command_queue);
 	init_waitqueue_head(&priv->wait_state);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
+	INIT_WORK(&priv->associate, ipw_bg_associate, priv);
+	INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
+	INIT_WORK(&priv->system_config, ipw_system_config, priv);
+	INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
+	INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
+	INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
+	INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
+	INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
+	INIT_WORK(&priv->request_scan,
+		  (void (*)(void *))ipw_request_scan, priv);
+	INIT_WORK(&priv->request_passive_scan,
+		  (void (*)(void *))ipw_request_passive_scan, priv);
+	INIT_WORK(&priv->gather_stats,
+		  (void (*)(void *))ipw_bg_gather_stats, priv);
+	INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
+	INIT_WORK(&priv->roam, ipw_bg_roam, priv);
+	INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
+	INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
+	INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
+	INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
+		  priv);
+	INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
+		  priv);
+	INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
+		  priv);
+	INIT_WORK(&priv->merge_networks,
+		  (void (*)(void *))ipw_merge_adhoc_network, priv);
+
+# ifdef CONFIG_IPW2200_QOS
+	INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
+		  priv);
+# endif				/* CONFIG_IPW2200_QOS */
+
+#else
 	INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check);
 	INIT_WORK(&priv->associate, ipw_bg_associate);
 	INIT_WORK(&priv->disassociate, ipw_bg_disassociate);
@@ -10727,9 +11081,11 @@
 	INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off);
 	INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network);
 
-#ifdef CONFIG_IPW2200_QOS
+# ifdef CONFIG_IPW2200_QOS
 	INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);
-#endif				/* CONFIG_IPW2200_QOS */
+# endif				/* CONFIG_IPW2200_QOS */
+
+#endif		/* LINUX_VERSION_CODE < 2.6.20 */
 
 	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
 		     ipw_irq_tasklet, (unsigned long)priv);
@@ -11237,7 +11593,7 @@
 				    priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
 			j = 0;
 		}
-		if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
+		if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
 			IPW_WARNING("Could not set geography.");
 			return 0;
 		}
@@ -11282,10 +11638,16 @@
 	return -EIO;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_up(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_up(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, up);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_up(priv);
 	mutex_unlock(&priv->mutex);
@@ -11354,10 +11716,16 @@
 	ipw_led_radio_off(priv);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void ipw_bg_down(void *work)
+{
+	struct ipw_priv *priv = work;
+#else
 static void ipw_bg_down(struct work_struct *work)
 {
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, down);
+#endif
 	mutex_lock(&priv->mutex);
 	ipw_down(priv);
 	mutex_unlock(&priv->mutex);
@@ -11433,6 +11801,7 @@
 #ifdef CONFIG_IPW2200_PROMISCUOUS
 	&dev_attr_rtap_iface.attr,
 	&dev_attr_rtap_filter.attr,
+	&dev_attr_inject.attr,
 #endif
 	NULL
 };
@@ -11648,11 +12017,22 @@
 	net_dev->open = ipw_net_open;
 	net_dev->stop = ipw_net_stop;
 	net_dev->init = ipw_net_init;
+#if WIRELESS_EXT < 18
+	net_dev->do_ioctl = ipw_ioctl;
+#endif
 	net_dev->get_stats = ipw_net_get_stats;
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
+#if IW_HANDLER_VERSION >= 6
 	priv->wireless_data.spy_data = &priv->ieee->spy_data;
 	net_dev->wireless_data = &priv->wireless_data;
+#else
+	net_dev->get_wireless_stats = ipw_get_wireless_stats;
+#if WIRELESS_EXT == 16
+	ipw_wx_handler_def.spy_offset = offsetof(struct ieee80211_device,
+						 spy_data);
+#endif
+#endif
 	net_dev->wireless_handlers = &ipw_wx_handler_def;
 	net_dev->ethtool_ops = &ipw_ethtool_ops;
 	net_dev->irq = pdev->irq;
@@ -11777,7 +12157,11 @@
 }
 
 #ifdef CONFIG_PM
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+static int ipw_pci_suspend(struct pci_dev *pdev, u32 state)
+#else
 static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+#endif
 {
 	struct ipw_priv *priv = pci_get_drvdata(pdev);
 	struct net_device *dev = priv->net_dev;
@@ -11790,9 +12174,18 @@
 	/* Remove the PRESENT state of the device */
 	netif_device_detach(dev);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+	pci_save_state(pdev, priv->pm_state);
+#else
 	pci_save_state(pdev);
+#endif
 	pci_disable_device(pdev);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+	pci_set_power_state(pdev, state);
+#else
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#endif
 
 	return 0;
 }
@@ -11806,14 +12199,22 @@
 
 	printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+	pci_set_power_state(pdev, 0);
+#else
 	pci_set_power_state(pdev, PCI_D0);
+#endif
 	err = pci_enable_device(pdev);
 	if (err) {
 		printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
 		       dev->name);
 		return err;
 	}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+	pci_restore_state(pdev, priv->pm_state);
+#else
 	pci_restore_state(pdev);
+#endif
 
 	/*
 	 * Suspend/Resume resets the PCI configuration space, so we have to
@@ -11836,6 +12237,7 @@
 }
 #endif
 
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11)
 static void ipw_pci_shutdown(struct pci_dev *pdev)
 {
 	struct ipw_priv *priv = pci_get_drvdata(pdev);
@@ -11845,6 +12247,7 @@
 
 	pci_disable_device(pdev);
 }
+#endif
 
 /* driver initialization stuff */
 static struct pci_driver ipw_driver = {
@@ -11856,7 +12259,9 @@
 	.suspend = ipw_pci_suspend,
 	.resume = ipw_pci_resume,
 #endif
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11)
 	.shutdown = ipw_pci_shutdown,
+#endif
 };
 
 static int __init ipw_init(void)
diff -Naur a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
--- a/drivers/net/wireless/ipw2200.h	2007-07-10 20:56:30.000000000 +0200
+++ b/drivers/net/wireless/ipw2200.h	2007-07-12 17:22:20.000000000 +0200
@@ -32,7 +32,10 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
 #include <linux/mutex.h>
+#endif
 
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -49,6 +52,7 @@
 #include <linux/jiffies.h>
 #include <asm/io.h>
 
+#include "compat.h"
 #include <net/ieee80211.h>
 #include <net/ieee80211_radiotap.h>
 
@@ -1286,25 +1290,41 @@
 
 	struct iw_statistics wstats;
 
+#if IW_HANDLER_VERSION >= 6
 	struct iw_public_data wireless_data;
+#endif
 
 	struct workqueue_struct *workqueue;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	struct work_struct adhoc_check;
+	struct work_struct request_scan;
+	struct work_struct rf_kill;
+	struct work_struct gather_stats;
+	struct work_struct scan_check;
+	struct work_struct led_link_on;
+	struct work_struct led_link_off;
+	struct work_struct led_act_off;
+#else
 	struct delayed_work adhoc_check;
+	struct delayed_work request_scan;
+	struct delayed_work rf_kill;
+	struct delayed_work gather_stats;
+	struct delayed_work scan_check;
+	struct delayed_work led_link_on;
+	struct delayed_work led_link_off;
+	struct delayed_work led_act_off;
+#endif
 	struct work_struct associate;
 	struct work_struct disassociate;
 	struct work_struct system_config;
 	struct work_struct rx_replenish;
-	struct delayed_work request_scan;
   	struct work_struct request_passive_scan;
 	struct work_struct adapter_restart;
-	struct delayed_work rf_kill;
 	struct work_struct up;
 	struct work_struct down;
-	struct delayed_work gather_stats;
 	struct work_struct abort_scan;
 	struct work_struct roam;
-	struct delayed_work scan_check;
 	struct work_struct link_up;
 	struct work_struct link_down;
 
@@ -1319,9 +1339,6 @@
 	u32 led_ofdm_on;
 	u32 led_ofdm_off;
 
-	struct delayed_work led_link_on;
-	struct delayed_work led_link_off;
-	struct delayed_work led_act_off;
 	struct work_struct merge_networks;
 
 	struct ipw_cmd_log *cmdlog;
