Browse Source

Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6

Jeff Garzik 20 years ago
parent
commit
0b310f36d7

+ 5 - 2
drivers/net/wireless/Kconfig

@@ -6,7 +6,8 @@ menu "Wireless LAN (non-hamradio)"
 	depends on NETDEVICES
 	depends on NETDEVICES
 
 
 config NET_RADIO
 config NET_RADIO
-	bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
+	bool "Wireless LAN drivers (non-hamradio)"
+	select WIRELESS_EXT
 	---help---
 	---help---
 	  Support for wireless LANs and everything having to do with radio,
 	  Support for wireless LANs and everything having to do with radio,
 	  but not with amateur radio or FM broadcasting.
 	  but not with amateur radio or FM broadcasting.
@@ -239,7 +240,8 @@ config IPW2200_DEBUG
 
 
 config AIRO
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
-	depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN)
+ 	depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
+	select CRYPTO
 	---help---
 	---help---
 	  This is the standard Linux driver to support Cisco/Aironet ISA and
 	  This is the standard Linux driver to support Cisco/Aironet ISA and
 	  PCI 802.11 wireless cards.
 	  PCI 802.11 wireless cards.
@@ -387,6 +389,7 @@ config PCMCIA_SPECTRUM
 config AIRO_CS
 config AIRO_CS
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
 	depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
 	depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
+	select CRYPTO
 	---help---
 	---help---
 	  This is the standard Linux driver to support Cisco/Aironet PCMCIA
 	  This is the standard Linux driver to support Cisco/Aironet PCMCIA
 	  802.11 wireless cards.  This driver is the same as the Aironet
 	  802.11 wireless cards.  This driver is the same as the Aironet

+ 276 - 55
drivers/net/wireless/airo.c

@@ -36,6 +36,7 @@
 #include <linux/in.h>
 #include <linux/in.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/scatterlist.h>
 #include <linux/scatterlist.h>
+#include <linux/crypto.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/system.h>
 
 
@@ -87,14 +88,6 @@ static struct pci_driver airo_driver = {
 #include <linux/delay.h>
 #include <linux/delay.h>
 #endif
 #endif
 
 
-/* Support Cisco MIC feature */
-#define MICSUPPORT
-
-#if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO)
-#warning MIC support requires Crypto API
-#undef MICSUPPORT
-#endif
-
 /* Hack to do some power saving */
 /* Hack to do some power saving */
 #define POWER_ON_DOWN
 #define POWER_ON_DOWN
 
 
@@ -1118,7 +1111,6 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp);
 static int writerids(struct net_device *dev, aironet_ioctl *comp);
 static int writerids(struct net_device *dev, aironet_ioctl *comp);
 static int flashcard(struct net_device *dev, aironet_ioctl *comp);
 static int flashcard(struct net_device *dev, aironet_ioctl *comp);
 #endif /* CISCO_EXT */
 #endif /* CISCO_EXT */
-#ifdef MICSUPPORT
 static void micinit(struct airo_info *ai);
 static void micinit(struct airo_info *ai);
 static int micsetup(struct airo_info *ai);
 static int micsetup(struct airo_info *ai);
 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
@@ -1127,9 +1119,6 @@ static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket,
 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
 
 
-#include <linux/crypto.h>
-#endif
-
 struct airo_info {
 struct airo_info {
 	struct net_device_stats	stats;
 	struct net_device_stats	stats;
 	struct net_device             *dev;
 	struct net_device             *dev;
@@ -1190,12 +1179,10 @@ struct airo_info {
 	unsigned long		scan_timestamp;	/* Time started to scan */
 	unsigned long		scan_timestamp;	/* Time started to scan */
 	struct iw_spy_data	spy_data;
 	struct iw_spy_data	spy_data;
 	struct iw_public_data	wireless_data;
 	struct iw_public_data	wireless_data;
-#ifdef MICSUPPORT
 	/* MIC stuff */
 	/* MIC stuff */
 	struct crypto_tfm	*tfm;
 	struct crypto_tfm	*tfm;
 	mic_module		mod[2];
 	mic_module		mod[2];
 	mic_statistics		micstats;
 	mic_statistics		micstats;
-#endif
 	HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
 	HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
 	HostTxDesc txfids[MPI_MAX_FIDS];
 	HostTxDesc txfids[MPI_MAX_FIDS];
 	HostRidDesc config_desc;
 	HostRidDesc config_desc;
@@ -1229,7 +1216,6 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
 static int flashputbuf(struct airo_info *ai);
 static int flashputbuf(struct airo_info *ai);
 static int flashrestart(struct airo_info *ai,struct net_device *dev);
 static int flashrestart(struct airo_info *ai,struct net_device *dev);
 
 
-#ifdef MICSUPPORT
 /***********************************************************************
 /***********************************************************************
  *                              MIC ROUTINES                           *
  *                              MIC ROUTINES                           *
  ***********************************************************************
  ***********************************************************************
@@ -1686,7 +1672,6 @@ static void emmh32_final(emmh32_context *context, u8 digest[4])
 	digest[2] = (val>>8) & 0xFF;
 	digest[2] = (val>>8) & 0xFF;
 	digest[3] = val & 0xFF;
 	digest[3] = val & 0xFF;
 }
 }
-#endif
 
 
 static int readBSSListRid(struct airo_info *ai, int first,
 static int readBSSListRid(struct airo_info *ai, int first,
 		      BSSListRid *list) {
 		      BSSListRid *list) {
@@ -2005,7 +1990,6 @@ static int mpi_send_packet (struct net_device *dev)
 	 * Firmware automaticly puts 802 header on so
 	 * Firmware automaticly puts 802 header on so
 	 * we don't need to account for it in the length
 	 * we don't need to account for it in the length
 	 */
 	 */
-#ifdef MICSUPPORT
 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
 		(ntohs(((u16 *)buffer)[6]) != 0x888E)) {
 		(ntohs(((u16 *)buffer)[6]) != 0x888E)) {
 		MICBuffer pMic;
 		MICBuffer pMic;
@@ -2022,9 +2006,7 @@ static int mpi_send_packet (struct net_device *dev)
 		memcpy (sendbuf, &pMic, sizeof(pMic));
 		memcpy (sendbuf, &pMic, sizeof(pMic));
 		sendbuf += sizeof(pMic);
 		sendbuf += sizeof(pMic);
 		memcpy (sendbuf, buffer, len - sizeof(etherHead));
 		memcpy (sendbuf, buffer, len - sizeof(etherHead));
-	} else
-#endif
-	{
+	} else {
 		*payloadLen = cpu_to_le16(len - sizeof(etherHead));
 		*payloadLen = cpu_to_le16(len - sizeof(etherHead));
 
 
 		dev->trans_start = jiffies;
 		dev->trans_start = jiffies;
@@ -2400,9 +2382,7 @@ void stop_airo_card( struct net_device *dev, int freeres )
 				ai->shared, ai->shared_dma);
 				ai->shared, ai->shared_dma);
 		}
 		}
         }
         }
-#ifdef MICSUPPORT
 	crypto_free_tfm(ai->tfm);
 	crypto_free_tfm(ai->tfm);
-#endif
 	del_airo_dev( dev );
 	del_airo_dev( dev );
 	free_netdev( dev );
 	free_netdev( dev );
 }
 }
@@ -2726,9 +2706,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
 	ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
 	ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
 	if (ai->thr_pid < 0)
 	if (ai->thr_pid < 0)
 		goto err_out_free;
 		goto err_out_free;
-#ifdef MICSUPPORT
 	ai->tfm = NULL;
 	ai->tfm = NULL;
-#endif
 	rc = add_airo_dev( dev );
 	rc = add_airo_dev( dev );
 	if (rc)
 	if (rc)
 		goto err_out_thr;
 		goto err_out_thr;
@@ -2969,10 +2947,8 @@ static int airo_thread(void *data) {
 			airo_read_wireless_stats(ai);
 			airo_read_wireless_stats(ai);
 		else if (test_bit(JOB_PROMISC, &ai->flags))
 		else if (test_bit(JOB_PROMISC, &ai->flags))
 			airo_set_promisc(ai);
 			airo_set_promisc(ai);
-#ifdef MICSUPPORT
 		else if (test_bit(JOB_MIC, &ai->flags))
 		else if (test_bit(JOB_MIC, &ai->flags))
 			micinit(ai);
 			micinit(ai);
-#endif
 		else if (test_bit(JOB_EVENT, &ai->flags))
 		else if (test_bit(JOB_EVENT, &ai->flags))
 			airo_send_event(dev);
 			airo_send_event(dev);
 		else if (test_bit(JOB_AUTOWEP, &ai->flags))
 		else if (test_bit(JOB_AUTOWEP, &ai->flags))
@@ -3010,12 +2986,10 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
 
 
 		if ( status & EV_MIC ) {
 		if ( status & EV_MIC ) {
 			OUT4500( apriv, EVACK, EV_MIC );
 			OUT4500( apriv, EVACK, EV_MIC );
-#ifdef MICSUPPORT
 			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
 			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
 				set_bit(JOB_MIC, &apriv->flags);
 				set_bit(JOB_MIC, &apriv->flags);
 				wake_up_interruptible(&apriv->thr_wait);
 				wake_up_interruptible(&apriv->thr_wait);
 			}
 			}
-#endif
 		}
 		}
 		if ( status & EV_LINK ) {
 		if ( status & EV_LINK ) {
 			union iwreq_data	wrqu;
 			union iwreq_data	wrqu;
@@ -3194,11 +3168,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
 				}
 				}
 				bap_read (apriv, buffer + hdrlen/2, len, BAP0);
 				bap_read (apriv, buffer + hdrlen/2, len, BAP0);
 			} else {
 			} else {
-#ifdef MICSUPPORT
 				MICBuffer micbuf;
 				MICBuffer micbuf;
-#endif
 				bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
 				bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
-#ifdef MICSUPPORT
 				if (apriv->micstats.enabled) {
 				if (apriv->micstats.enabled) {
 					bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
 					bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
 					if (ntohs(micbuf.typelen) > 0x05DC)
 					if (ntohs(micbuf.typelen) > 0x05DC)
@@ -3211,15 +3182,10 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
 						skb_trim (skb, len + hdrlen);
 						skb_trim (skb, len + hdrlen);
 					}
 					}
 				}
 				}
-#endif
 				bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
 				bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
-#ifdef MICSUPPORT
 				if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
 				if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
 badmic:
 badmic:
 					dev_kfree_skb_irq (skb);
 					dev_kfree_skb_irq (skb);
-#else
-				if (0) {
-#endif
 badrx:
 badrx:
 					OUT4500( apriv, EVACK, EV_RX);
 					OUT4500( apriv, EVACK, EV_RX);
 					goto exitrx;
 					goto exitrx;
@@ -3430,10 +3396,8 @@ static void mpi_receive_802_3(struct airo_info *ai)
 	int len = 0;
 	int len = 0;
 	struct sk_buff *skb;
 	struct sk_buff *skb;
 	char *buffer;
 	char *buffer;
-#ifdef MICSUPPORT
 	int off = 0;
 	int off = 0;
 	MICBuffer micbuf;
 	MICBuffer micbuf;
-#endif
 
 
 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
 	/* Make sure we got something */
 	/* Make sure we got something */
@@ -3448,7 +3412,6 @@ static void mpi_receive_802_3(struct airo_info *ai)
 			goto badrx;
 			goto badrx;
 		}
 		}
 		buffer = skb_put(skb,len);
 		buffer = skb_put(skb,len);
-#ifdef MICSUPPORT
 		memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
 		memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
 		if (ai->micstats.enabled) {
 		if (ai->micstats.enabled) {
 			memcpy(&micbuf,
 			memcpy(&micbuf,
@@ -3470,9 +3433,6 @@ badmic:
 			dev_kfree_skb_irq (skb);
 			dev_kfree_skb_irq (skb);
 			goto badrx;
 			goto badrx;
 		}
 		}
-#else
-		memcpy(buffer, ai->rxfids[0].virtual_host_addr, len);
-#endif
 #ifdef WIRELESS_SPY
 #ifdef WIRELESS_SPY
 		if (ai->spy_data.spy_number > 0) {
 		if (ai->spy_data.spy_number > 0) {
 			char *sa;
 			char *sa;
@@ -3689,13 +3649,11 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 		ai->config.authType = AUTH_OPEN;
 		ai->config.authType = AUTH_OPEN;
 		ai->config.modulation = MOD_CCK;
 		ai->config.modulation = MOD_CCK;
 
 
-#ifdef MICSUPPORT
 		if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
 		if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
 		    (micsetup(ai) == SUCCESS)) {
 		    (micsetup(ai) == SUCCESS)) {
 			ai->config.opmode |= MODE_MIC;
 			ai->config.opmode |= MODE_MIC;
 			set_bit(FLAG_MIC_CAPABLE, &ai->flags);
 			set_bit(FLAG_MIC_CAPABLE, &ai->flags);
 		}
 		}
-#endif
 
 
 		/* Save off the MAC */
 		/* Save off the MAC */
 		for( i = 0; i < ETH_ALEN; i++ ) {
 		for( i = 0; i < ETH_ALEN; i++ ) {
@@ -4170,15 +4128,12 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
 	}
 	}
 	len -= ETH_ALEN * 2;
 	len -= ETH_ALEN * 2;
 
 
-#ifdef MICSUPPORT
 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
 	    (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
 	    (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
 		if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
 		if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
 			return ERROR;
 			return ERROR;
 		miclen = sizeof(pMic);
 		miclen = sizeof(pMic);
 	}
 	}
-#endif
-
 	// packet is destination[6], source[6], payload[len-12]
 	// packet is destination[6], source[6], payload[len-12]
 	// write the payload length and dst/src/payload
 	// write the payload length and dst/src/payload
 	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
 	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
@@ -5801,11 +5756,13 @@ static int airo_set_wap(struct net_device *dev,
 	Cmd cmd;
 	Cmd cmd;
 	Resp rsp;
 	Resp rsp;
 	APListRid APList_rid;
 	APListRid APList_rid;
-	static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
+	static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+	static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
 
 	if (awrq->sa_family != ARPHRD_ETHER)
 	if (awrq->sa_family != ARPHRD_ETHER)
 		return -EINVAL;
 		return -EINVAL;
-	else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
+	else if (!memcmp(any, awrq->sa_data, ETH_ALEN) ||
+	         !memcmp(off, awrq->sa_data, ETH_ALEN)) {
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&cmd, 0, sizeof(cmd));
 		cmd.cmd=CMD_LOSE_SYNC;
 		cmd.cmd=CMD_LOSE_SYNC;
 		if (down_interruptible(&local->sem))
 		if (down_interruptible(&local->sem))
@@ -6294,6 +6251,267 @@ static int airo_get_encode(struct net_device *dev,
 	return 0;
 	return 0;
 }
 }
 
 
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set extended Encryption parameters
+ */
+static int airo_set_encodeext(struct net_device *dev,
+			   struct iw_request_info *info,
+			    union iwreq_data *wrqu,
+			    char *extra)
+{
+	struct airo_info *local = dev->priv;
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	CapabilityRid cap_rid;		/* Card capability info */
+	int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
+	u16 currentAuthType = local->config.authType;
+	int idx, key_len, alg = ext->alg;	/* Check encryption mode */
+	wep_key_t key;
+
+	/* Is WEP supported ? */
+	readCapabilityRid(local, &cap_rid, 1);
+	/* Older firmware doesn't support this...
+	if(!(cap_rid.softCap & 2)) {
+		return -EOPNOTSUPP;
+	} */
+	readConfigRid(local, 1);
+
+	/* Determine and validate the key index */
+	idx = encoding->flags & IW_ENCODE_INDEX;
+	if (idx) {
+		if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1))
+			return -EINVAL;
+		idx--;
+	} else
+		idx = get_wep_key(local, 0xffff);
+
+	if (encoding->flags & IW_ENCODE_DISABLED)
+		alg = IW_ENCODE_ALG_NONE;
+
+	/* Just setting the transmit key? */
+	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+		set_wep_key(local, idx, NULL, 0, perm, 1);
+	} else {
+		/* Set the requested key first */
+		memset(key.key, 0, MAX_KEY_SIZE);
+		switch (alg) {
+		case IW_ENCODE_ALG_NONE:
+			key.len = 0;
+			break;
+		case IW_ENCODE_ALG_WEP:
+			if (ext->key_len > MIN_KEY_SIZE) {
+				key.len = MAX_KEY_SIZE;
+			} else if (ext->key_len > 0) {
+				key.len = MIN_KEY_SIZE;
+			} else {
+				return -EINVAL;
+			}
+			key_len = min (ext->key_len, key.len);
+			memcpy(key.key, ext->key, key_len);
+			break;
+		default:
+			return -EINVAL;
+		}
+		/* Send the key to the card */
+		set_wep_key(local, idx, key.key, key.len, perm, 1);
+	}
+
+	/* Read the flags */
+	if(encoding->flags & IW_ENCODE_DISABLED)
+		local->config.authType = AUTH_OPEN;	// disable encryption
+	if(encoding->flags & IW_ENCODE_RESTRICTED)
+		local->config.authType = AUTH_SHAREDKEY;	// Only Both
+	if(encoding->flags & IW_ENCODE_OPEN)
+		local->config.authType = AUTH_ENCRYPT;	// Only Wep
+	/* Commit the changes to flags if needed */
+	if (local->config.authType != currentAuthType)
+		set_bit (FLAG_COMMIT, &local->flags);
+
+	return -EINPROGRESS;
+}
+
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get extended Encryption parameters
+ */
+static int airo_get_encodeext(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu,
+			    char *extra)
+{
+	struct airo_info *local = dev->priv;
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	CapabilityRid cap_rid;		/* Card capability info */
+	int idx, max_key_len;
+
+	/* Is it supported ? */
+	readCapabilityRid(local, &cap_rid, 1);
+	if(!(cap_rid.softCap & 2)) {
+		return -EOPNOTSUPP;
+	}
+	readConfigRid(local, 1);
+
+	max_key_len = encoding->length - sizeof(*ext);
+	if (max_key_len < 0)
+		return -EINVAL;
+
+	idx = encoding->flags & IW_ENCODE_INDEX;
+	if (idx) {
+		if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1))
+			return -EINVAL;
+		idx--;
+	} else
+		idx = get_wep_key(local, 0xffff);
+
+	encoding->flags = idx + 1;
+	memset(ext, 0, sizeof(*ext));
+
+	/* Check encryption mode */
+	switch(local->config.authType) {
+		case AUTH_ENCRYPT:
+			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
+			break;
+		case AUTH_SHAREDKEY:
+			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
+			break;
+		default:
+		case AUTH_OPEN:
+			encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
+			break;
+	}
+	/* We can't return the key, so set the proper flag and return zero */
+	encoding->flags |= IW_ENCODE_NOKEY;
+	memset(extra, 0, 16);
+	
+	/* Copy the key to the user buffer */
+	ext->key_len = get_wep_key(local, idx);
+	if (ext->key_len > 16) {
+		ext->key_len=0;
+	}
+
+	return 0;
+}
+
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : set extended authentication parameters
+ */
+static int airo_set_auth(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct airo_info *local = dev->priv;
+	struct iw_param *param = &wrqu->param;
+	u16 currentAuthType = local->config.authType;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_KEY_MGMT:
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+	case IW_AUTH_PRIVACY_INVOKED:
+		/*
+		 * airo does not use these parameters
+		 */
+		break;
+
+	case IW_AUTH_DROP_UNENCRYPTED:
+		if (param->value) {
+			/* Only change auth type if unencrypted */
+			if (currentAuthType == AUTH_OPEN)
+				local->config.authType = AUTH_ENCRYPT;
+		} else {
+			local->config.authType = AUTH_OPEN;
+		}
+
+		/* Commit the changes to flags if needed */
+		if (local->config.authType != currentAuthType)
+			set_bit (FLAG_COMMIT, &local->flags);
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG: {
+			/* FIXME: What about AUTH_OPEN?  This API seems to
+			 * disallow setting our auth to AUTH_OPEN.
+			 */
+			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+				local->config.authType = AUTH_SHAREDKEY;
+			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+				local->config.authType = AUTH_ENCRYPT;
+			} else
+				return -EINVAL;
+			break;
+
+			/* Commit the changes to flags if needed */
+			if (local->config.authType != currentAuthType)
+				set_bit (FLAG_COMMIT, &local->flags);
+		}
+
+	case IW_AUTH_WPA_ENABLED:
+		/* Silently accept disable of WPA */
+		if (param->value > 0)
+			return -EOPNOTSUPP;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	return -EINPROGRESS;
+}
+
+
+/*------------------------------------------------------------------*/
+/*
+ * Wireless Handler : get extended authentication parameters
+ */
+static int airo_get_auth(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct airo_info *local = dev->priv;
+	struct iw_param *param = &wrqu->param;
+	u16 currentAuthType = local->config.authType;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_DROP_UNENCRYPTED:
+		switch (currentAuthType) {
+		case AUTH_SHAREDKEY:
+		case AUTH_ENCRYPT:
+			param->value = 1;
+			break;
+		default:
+			param->value = 0;
+			break;
+		}
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		switch (currentAuthType) {
+		case AUTH_SHAREDKEY:
+			param->value = IW_AUTH_ALG_SHARED_KEY;
+			break;
+		case AUTH_ENCRYPT:
+		default:
+			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+			break;
+		}
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		param->value = 0;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+
 /*------------------------------------------------------------------*/
 /*------------------------------------------------------------------*/
 /*
 /*
  * Wireless Handler : set Tx-Power
  * Wireless Handler : set Tx-Power
@@ -7050,6 +7268,15 @@ static const iw_handler		airo_handler[] =
 	(iw_handler) airo_get_encode,		/* SIOCGIWENCODE */
 	(iw_handler) airo_get_encode,		/* SIOCGIWENCODE */
 	(iw_handler) airo_set_power,		/* SIOCSIWPOWER */
 	(iw_handler) airo_set_power,		/* SIOCSIWPOWER */
 	(iw_handler) airo_get_power,		/* SIOCGIWPOWER */
 	(iw_handler) airo_get_power,		/* SIOCGIWPOWER */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,			/* SIOCSIWGENIE */
+	(iw_handler) NULL,			/* SIOCGIWGENIE */
+	(iw_handler) airo_set_auth,		/* SIOCSIWAUTH */
+	(iw_handler) airo_get_auth,		/* SIOCGIWAUTH */
+	(iw_handler) airo_set_encodeext,	/* SIOCSIWENCODEEXT */
+	(iw_handler) airo_get_encodeext,	/* SIOCGIWENCODEEXT */
+	(iw_handler) NULL,			/* SIOCSIWPMKSA */
 };
 };
 
 
 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
@@ -7270,13 +7497,11 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 	case AIROGSTAT:     ridcode = RID_STATUS;       break;
 	case AIROGSTAT:     ridcode = RID_STATUS;       break;
 	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
 	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
 	case AIROGSTATSC32: ridcode = RID_STATS;        break;
 	case AIROGSTATSC32: ridcode = RID_STATS;        break;
-#ifdef MICSUPPORT
 	case AIROGMICSTATS:
 	case AIROGMICSTATS:
 		if (copy_to_user(comp->data, &ai->micstats,
 		if (copy_to_user(comp->data, &ai->micstats,
 				 min((int)comp->len,(int)sizeof(ai->micstats))))
 				 min((int)comp->len,(int)sizeof(ai->micstats))))
 			return -EFAULT;
 			return -EFAULT;
 		return 0;
 		return 0;
-#endif
 	case AIRORRID:      ridcode = comp->ridnum;     break;
 	case AIRORRID:      ridcode = comp->ridnum;     break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -7308,9 +7533,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 	struct airo_info *ai = dev->priv;
 	struct airo_info *ai = dev->priv;
 	int  ridcode;
 	int  ridcode;
-#ifdef MICSUPPORT
         int  enabled;
         int  enabled;
-#endif
 	Resp      rsp;
 	Resp      rsp;
 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
 	unsigned char *iobuf;
 	unsigned char *iobuf;
@@ -7367,11 +7590,9 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 
 
 		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
 		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
 
 
-#ifdef MICSUPPORT
 		enabled = ai->micstats.enabled;
 		enabled = ai->micstats.enabled;
 		memset(&ai->micstats,0,sizeof(ai->micstats));
 		memset(&ai->micstats,0,sizeof(ai->micstats));
 		ai->micstats.enabled = enabled;
 		ai->micstats.enabled = enabled;
-#endif
 
 
 		if (copy_to_user(comp->data, iobuf,
 		if (copy_to_user(comp->data, iobuf,
 				 min((int)comp->len, (int)RIDSIZE))) {
 				 min((int)comp->len, (int)RIDSIZE))) {

+ 37 - 11
drivers/net/wireless/ipw2100.c

@@ -167,7 +167,7 @@ that only one external action is invoked at a time.
 
 
 #include "ipw2100.h"
 #include "ipw2100.h"
 
 
-#define IPW2100_VERSION "1.1.3"
+#define IPW2100_VERSION "git-1.1.4"
 
 
 #define DRV_NAME	"ipw2100"
 #define DRV_NAME	"ipw2100"
 #define DRV_VERSION	IPW2100_VERSION
 #define DRV_VERSION	IPW2100_VERSION
@@ -1672,6 +1672,18 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv)
 	return err;
 	return err;
 }
 }
 
 
+static const struct ieee80211_geo ipw_geos[] = {
+	{			/* Restricted */
+	 "---",
+	 .bg_channels = 14,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}, {2467, 12},
+		{2472, 13}, {2484, 14}},
+	 },
+};
+
 static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
@@ -1727,6 +1739,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 		goto exit;
 		goto exit;
 	}
 	}
 
 
+	/* Initialize the geo */
+	if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) {
+		printk(KERN_WARNING DRV_NAME "Could not set geo\n");
+		return 0;
+	}
+	priv->ieee->freq_band = IEEE80211_24GHZ_BAND;
+
 	lock = LOCK_NONE;
 	lock = LOCK_NONE;
 	if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
 	if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
 		printk(KERN_ERR DRV_NAME
 		printk(KERN_ERR DRV_NAME
@@ -3750,7 +3769,7 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr,
 	struct net_device *dev = priv->net_dev;
 	struct net_device *dev = priv->net_dev;
 	const char *p = buf;
 	const char *p = buf;
 
 
-	(void) dev; /* kill unused-var warning for debug-only code */
+	(void)dev;		/* kill unused-var warning for debug-only code */
 
 
 	if (count < 1)
 	if (count < 1)
 		return count;
 		return count;
@@ -4070,7 +4089,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
 	unsigned long val;
 	unsigned long val;
 	char *p = buffer;
 	char *p = buffer;
 
 
-	(void) dev; /* kill unused-var warning for debug-only code */
+	(void)dev;		/* kill unused-var warning for debug-only code */
 
 
 	IPW_DEBUG_INFO("enter\n");
 	IPW_DEBUG_INFO("enter\n");
 
 
@@ -5107,12 +5126,13 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
 		.host_command_length = 4
 		.host_command_length = 4
 	};
 	};
 	int err = 0;
 	int err = 0;
+	u32 tmp = tx_power;
 
 
 	if (tx_power != IPW_TX_POWER_DEFAULT)
 	if (tx_power != IPW_TX_POWER_DEFAULT)
-		tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
-		    (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
+		tmp = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
+		      (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
 
 
-	cmd.host_command_parameters[0] = tx_power;
+	cmd.host_command_parameters[0] = tmp;
 
 
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
 		err = ipw2100_hw_send_command(priv, &cmd);
 		err = ipw2100_hw_send_command(priv, &cmd);
@@ -5365,9 +5385,12 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
 						     SEC_LEVEL_0, 0, 1);
 						     SEC_LEVEL_0, 0, 1);
 	} else {
 	} else {
 		auth_mode = IPW_AUTH_OPEN;
 		auth_mode = IPW_AUTH_OPEN;
-		if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
-		    (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
-			auth_mode = IPW_AUTH_SHARED;
+		if (priv->ieee->sec.flags & SEC_AUTH_MODE) {
+			if (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)
+				auth_mode = IPW_AUTH_SHARED;
+			else if (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP)
+				auth_mode = IPW_AUTH_LEAP_CISCO_ID;
+		}
 
 
 		sec_level = SEC_LEVEL_0;
 		sec_level = SEC_LEVEL_0;
 		if (priv->ieee->sec.flags & SEC_LEVEL)
 		if (priv->ieee->sec.flags & SEC_LEVEL)
@@ -5760,6 +5783,9 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 	} else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
 	} else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
 		sec.auth_mode = WLAN_AUTH_OPEN;
 		sec.auth_mode = WLAN_AUTH_OPEN;
 		ieee->open_wep = 1;
 		ieee->open_wep = 1;
+	} else if (value & IW_AUTH_ALG_LEAP) {
+		sec.auth_mode = WLAN_AUTH_LEAP;
+		ieee->open_wep = 1;
 	} else
 	} else
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -5771,8 +5797,8 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 	return ret;
 	return ret;
 }
 }
 
 
-void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
-			     char *wpa_ie, int wpa_ie_len)
+static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
+				    char *wpa_ie, int wpa_ie_len)
 {
 {
 
 
 	struct ipw2100_wpa_assoc_frame frame;
 	struct ipw2100_wpa_assoc_frame frame;

+ 4 - 2
drivers/net/wireless/ipw2100.h

@@ -392,8 +392,10 @@ struct ipw2100_notification {
 #define IPW_WEP104_CIPHER (1<<5)
 #define IPW_WEP104_CIPHER (1<<5)
 #define IPW_CKIP_CIPHER   (1<<6)
 #define IPW_CKIP_CIPHER   (1<<6)
 
 
-#define	IPW_AUTH_OPEN     0
-#define	IPW_AUTH_SHARED   1
+#define	IPW_AUTH_OPEN     	0
+#define	IPW_AUTH_SHARED   	1
+#define IPW_AUTH_LEAP	  	2
+#define IPW_AUTH_LEAP_CISCO_ID	0x80
 
 
 struct statistic {
 struct statistic {
 	int value;
 	int value;

+ 452 - 424
drivers/net/wireless/ipw2200.c

@@ -33,7 +33,7 @@
 #include "ipw2200.h"
 #include "ipw2200.h"
 #include <linux/version.h>
 #include <linux/version.h>
 
 
-#define IPW2200_VERSION "git-1.0.8"
+#define IPW2200_VERSION "git-1.0.10"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
 #define DRV_VERSION     IPW2200_VERSION
@@ -55,7 +55,9 @@ static int associate = 1;
 static int auto_create = 1;
 static int auto_create = 1;
 static int led = 0;
 static int led = 0;
 static int disable = 0;
 static int disable = 0;
-static int hwcrypto = 1;
+static int bt_coexist = 0;
+static int hwcrypto = 0;
+static int roaming = 1;
 static const char ipw_modes[] = {
 static const char ipw_modes[] = {
 	'a', 'b', 'g', '?'
 	'a', 'b', 'g', '?'
 };
 };
@@ -227,12 +229,15 @@ static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
 	return total;
 	return total;
 }
 }
 
 
+/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
 static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
 static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
 #define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
 #define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
 
 
+/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */
 static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
 static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
 #define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
 #define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
 
 
+/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
 static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
 static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
 static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
 static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
 {
 {
@@ -241,6 +246,7 @@ static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
 	_ipw_write_reg8(a, b, c);
 	_ipw_write_reg8(a, b, c);
 }
 }
 
 
+/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
 static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
 static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
 static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
 static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
 {
 {
@@ -249,6 +255,7 @@ static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
 	_ipw_write_reg16(a, b, c);
 	_ipw_write_reg16(a, b, c);
 }
 }
 
 
+/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
 static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
 static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
 {
 {
@@ -257,48 +264,70 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
 	_ipw_write_reg32(a, b, c);
 	_ipw_write_reg32(a, b, c);
 }
 }
 
 
+/* 8-bit direct write (low 4K) */
 #define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
 #define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
+
+/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
 #define ipw_write8(ipw, ofs, val) \
 #define ipw_write8(ipw, ofs, val) \
  IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
  IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
  _ipw_write8(ipw, ofs, val)
  _ipw_write8(ipw, ofs, val)
 
 
+/* 16-bit direct write (low 4K) */
 #define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
 #define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
+
+/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
 #define ipw_write16(ipw, ofs, val) \
 #define ipw_write16(ipw, ofs, val) \
  IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
  IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
  _ipw_write16(ipw, ofs, val)
  _ipw_write16(ipw, ofs, val)
 
 
+/* 32-bit direct write (low 4K) */
 #define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
 #define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
+
+/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
 #define ipw_write32(ipw, ofs, val) \
 #define ipw_write32(ipw, ofs, val) \
  IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
  IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
  _ipw_write32(ipw, ofs, val)
  _ipw_write32(ipw, ofs, val)
 
 
+/* 8-bit direct read (low 4K) */
 #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
 #define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
+
+/* 8-bit direct read (low 4K), with debug wrapper */
 static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
 static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
 {
 {
 	IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
 	IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
 	return _ipw_read8(ipw, ofs);
 	return _ipw_read8(ipw, ofs);
 }
 }
 
 
+/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
 #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
 #define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
 
 
+/* 16-bit direct read (low 4K) */
 #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
 #define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
+
+/* 16-bit direct read (low 4K), with debug wrapper */
 static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
 static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
 {
 {
 	IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
 	IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
 	return _ipw_read16(ipw, ofs);
 	return _ipw_read16(ipw, ofs);
 }
 }
 
 
+/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
 #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
 #define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
 
 
+/* 32-bit direct read (low 4K) */
 #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
 #define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
+
+/* 32-bit direct read (low 4K), with debug wrapper */
 static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
 static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
 {
 {
 	IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
 	IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
 	return _ipw_read32(ipw, ofs);
 	return _ipw_read32(ipw, ofs);
 }
 }
 
 
+/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
 #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
 #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
 
 
+/* multi-byte read (above 4K), with debug wrapper */
 static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
 static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
 static inline void __ipw_read_indirect(const char *f, int l,
 static inline void __ipw_read_indirect(const char *f, int l,
 				       struct ipw_priv *a, u32 b, u8 * c, int d)
 				       struct ipw_priv *a, u32 b, u8 * c, int d)
@@ -308,15 +337,17 @@ static inline void __ipw_read_indirect(const char *f, int l,
 	_ipw_read_indirect(a, b, c, d);
 	_ipw_read_indirect(a, b, c, d);
 }
 }
 
 
+/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
 #define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
 #define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
 
 
+/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
 				int num);
 				int num);
 #define ipw_write_indirect(a, b, c, d) \
 #define ipw_write_indirect(a, b, c, d) \
 	IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
 	IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
 	_ipw_write_indirect(a, b, c, d)
 	_ipw_write_indirect(a, b, c, d)
 
 
-/* indirect write s */
+/* 32-bit indirect write (above 4K) */
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
 {
 {
 	IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
 	IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
@@ -324,22 +355,29 @@ static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
 	_ipw_write32(priv, IPW_INDIRECT_DATA, value);
 	_ipw_write32(priv, IPW_INDIRECT_DATA, value);
 }
 }
 
 
+/* 8-bit indirect write (above 4K) */
 static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
 static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
 {
 {
+	u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK;	/* dword align */
+	u32 dif_len = reg - aligned_addr;
+
 	IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
 	IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
-	_ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
-	_ipw_write8(priv, IPW_INDIRECT_DATA, value);
+	_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
+	_ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value);
 }
 }
 
 
+/* 16-bit indirect write (above 4K) */
 static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
 static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
 {
 {
+	u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK;	/* dword align */
+	u32 dif_len = (reg - aligned_addr) & (~0x1ul);
+
 	IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
 	IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
-	_ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
-	_ipw_write16(priv, IPW_INDIRECT_DATA, value);
+	_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
+	_ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value);
 }
 }
 
 
-/* indirect read s */
-
+/* 8-bit indirect read (above 4K) */
 static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
 static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
 {
 {
 	u32 word;
 	u32 word;
@@ -349,6 +387,7 @@ static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
 	return (word >> ((reg & 0x3) * 8)) & 0xff;
 	return (word >> ((reg & 0x3) * 8)) & 0xff;
 }
 }
 
 
+/* 32-bit indirect read (above 4K) */
 static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
 static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
 {
 {
 	u32 value;
 	u32 value;
@@ -361,11 +400,12 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
 	return value;
 	return value;
 }
 }
 
 
-/* iterative/auto-increment 32 bit reads and writes */
+/* General purpose, no alignment requirement, iterative (multi-byte) read, */
+/*    for area above 1st 4K of SRAM/reg space */
 static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 			       int num)
 			       int num)
 {
 {
-	u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
+	u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;	/* dword align */
 	u32 dif_len = addr - aligned_addr;
 	u32 dif_len = addr - aligned_addr;
 	u32 i;
 	u32 i;
 
 
@@ -375,7 +415,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 		return;
 		return;
 	}
 	}
 
 
-	/* Read the first nibble byte by byte */
+	/* Read the first dword (or portion) byte by byte */
 	if (unlikely(dif_len)) {
 	if (unlikely(dif_len)) {
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		/* Start reading at aligned_addr + dif_len */
 		/* Start reading at aligned_addr + dif_len */
@@ -384,11 +424,12 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 		aligned_addr += 4;
 		aligned_addr += 4;
 	}
 	}
 
 
+	/* Read all of the middle dwords as dwords, with auto-increment */
 	_ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
 	_ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
 	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
 	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
 		*(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
 		*(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
 
 
-	/* Copy the last nibble */
+	/* Read the last dword (or portion) byte by byte */
 	if (unlikely(num)) {
 	if (unlikely(num)) {
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		for (i = 0; num > 0; i++, num--)
 		for (i = 0; num > 0; i++, num--)
@@ -396,10 +437,12 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 	}
 	}
 }
 }
 
 
+/* General purpose, no alignment requirement, iterative (multi-byte) write, */
+/*    for area above 1st 4K of SRAM/reg space */
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 				int num)
 				int num)
 {
 {
-	u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
+	u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;	/* dword align */
 	u32 dif_len = addr - aligned_addr;
 	u32 dif_len = addr - aligned_addr;
 	u32 i;
 	u32 i;
 
 
@@ -409,20 +452,21 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 		return;
 		return;
 	}
 	}
 
 
-	/* Write the first nibble byte by byte */
+	/* Write the first dword (or portion) byte by byte */
 	if (unlikely(dif_len)) {
 	if (unlikely(dif_len)) {
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
-		/* Start reading at aligned_addr + dif_len */
+		/* Start writing at aligned_addr + dif_len */
 		for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
 		for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
 			_ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
 			_ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
 		aligned_addr += 4;
 		aligned_addr += 4;
 	}
 	}
 
 
+	/* Write all of the middle dwords as dwords, with auto-increment */
 	_ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
 	_ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
 	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
 	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
 		_ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
 		_ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
 
 
-	/* Copy the last nibble */
+	/* Write the last dword (or portion) byte by byte */
 	if (unlikely(num)) {
 	if (unlikely(num)) {
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		_ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
 		for (i = 0; num > 0; i++, num--, buf++)
 		for (i = 0; num > 0; i++, num--, buf++)
@@ -430,17 +474,21 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
 	}
 	}
 }
 }
 
 
+/* General purpose, no alignment requirement, iterative (multi-byte) write, */
+/*    for 1st 4K of SRAM/regs space */
 static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
 static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
 			     int num)
 			     int num)
 {
 {
 	memcpy_toio((priv->hw_base + addr), buf, num);
 	memcpy_toio((priv->hw_base + addr), buf, num);
 }
 }
 
 
+/* Set bit(s) in low 4K of SRAM/regs */
 static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
 static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
 {
 {
 	ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
 	ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
 }
 }
 
 
+/* Clear bit(s) in low 4K of SRAM/regs */
 static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
 static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
 {
 {
 	ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
 	ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
@@ -701,7 +749,7 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
 
 
 }
 }
 
 
-u32 ipw_register_toggle(u32 reg)
+static u32 ipw_register_toggle(u32 reg)
 {
 {
 	reg &= ~IPW_START_STANDBY;
 	reg &= ~IPW_START_STANDBY;
 	if (reg & IPW_GATE_ODMA)
 	if (reg & IPW_GATE_ODMA)
@@ -722,11 +770,11 @@ u32 ipw_register_toggle(u32 reg)
  * - On radio OFF, turn off any LEDs started during radio on
  * - On radio OFF, turn off any LEDs started during radio on
  *
  *
  */
  */
-#define LD_TIME_LINK_ON 300
-#define LD_TIME_LINK_OFF 2700
-#define LD_TIME_ACT_ON 250
+#define LD_TIME_LINK_ON msecs_to_jiffies(300)
+#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)
+#define LD_TIME_ACT_ON msecs_to_jiffies(250)
 
 
-void ipw_led_link_on(struct ipw_priv *priv)
+static void ipw_led_link_on(struct ipw_priv *priv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	u32 led;
 	u32 led;
@@ -764,12 +812,12 @@ void ipw_led_link_on(struct ipw_priv *priv)
 static void ipw_bg_led_link_on(void *data)
 static void ipw_bg_led_link_on(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_led_link_on(data);
 	ipw_led_link_on(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
-void ipw_led_link_off(struct ipw_priv *priv)
+static void ipw_led_link_off(struct ipw_priv *priv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	u32 led;
 	u32 led;
@@ -808,9 +856,9 @@ void ipw_led_link_off(struct ipw_priv *priv)
 static void ipw_bg_led_link_off(void *data)
 static void ipw_bg_led_link_off(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_led_link_off(data);
 	ipw_led_link_off(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static void __ipw_led_activity_on(struct ipw_priv *priv)
 static void __ipw_led_activity_on(struct ipw_priv *priv)
@@ -847,6 +895,7 @@ static void __ipw_led_activity_on(struct ipw_priv *priv)
 	}
 	}
 }
 }
 
 
+#if 0
 void ipw_led_activity_on(struct ipw_priv *priv)
 void ipw_led_activity_on(struct ipw_priv *priv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
@@ -854,8 +903,9 @@ void ipw_led_activity_on(struct ipw_priv *priv)
 	__ipw_led_activity_on(priv);
 	__ipw_led_activity_on(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 }
+#endif  /*  0  */
 
 
-void ipw_led_activity_off(struct ipw_priv *priv)
+static void ipw_led_activity_off(struct ipw_priv *priv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	u32 led;
 	u32 led;
@@ -885,12 +935,12 @@ void ipw_led_activity_off(struct ipw_priv *priv)
 static void ipw_bg_led_activity_off(void *data)
 static void ipw_bg_led_activity_off(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_led_activity_off(data);
 	ipw_led_activity_off(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
-void ipw_led_band_on(struct ipw_priv *priv)
+static void ipw_led_band_on(struct ipw_priv *priv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	u32 led;
 	u32 led;
@@ -925,7 +975,7 @@ void ipw_led_band_on(struct ipw_priv *priv)
 	spin_unlock_irqrestore(&priv->lock, flags);
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 }
 
 
-void ipw_led_band_off(struct ipw_priv *priv)
+static void ipw_led_band_off(struct ipw_priv *priv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	u32 led;
 	u32 led;
@@ -948,24 +998,24 @@ void ipw_led_band_off(struct ipw_priv *priv)
 	spin_unlock_irqrestore(&priv->lock, flags);
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 }
 
 
-void ipw_led_radio_on(struct ipw_priv *priv)
+static void ipw_led_radio_on(struct ipw_priv *priv)
 {
 {
 	ipw_led_link_on(priv);
 	ipw_led_link_on(priv);
 }
 }
 
 
-void ipw_led_radio_off(struct ipw_priv *priv)
+static void ipw_led_radio_off(struct ipw_priv *priv)
 {
 {
 	ipw_led_activity_off(priv);
 	ipw_led_activity_off(priv);
 	ipw_led_link_off(priv);
 	ipw_led_link_off(priv);
 }
 }
 
 
-void ipw_led_link_up(struct ipw_priv *priv)
+static void ipw_led_link_up(struct ipw_priv *priv)
 {
 {
 	/* Set the Link Led on for all nic types */
 	/* Set the Link Led on for all nic types */
 	ipw_led_link_on(priv);
 	ipw_led_link_on(priv);
 }
 }
 
 
-void ipw_led_link_down(struct ipw_priv *priv)
+static void ipw_led_link_down(struct ipw_priv *priv)
 {
 {
 	ipw_led_activity_off(priv);
 	ipw_led_activity_off(priv);
 	ipw_led_link_off(priv);
 	ipw_led_link_off(priv);
@@ -974,7 +1024,7 @@ void ipw_led_link_down(struct ipw_priv *priv)
 		ipw_led_radio_off(priv);
 		ipw_led_radio_off(priv);
 }
 }
 
 
-void ipw_led_init(struct ipw_priv *priv)
+static void ipw_led_init(struct ipw_priv *priv)
 {
 {
 	priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
 	priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
 
 
@@ -1025,7 +1075,7 @@ void ipw_led_init(struct ipw_priv *priv)
 	}
 	}
 }
 }
 
 
-void ipw_led_shutdown(struct ipw_priv *priv)
+static void ipw_led_shutdown(struct ipw_priv *priv)
 {
 {
 	ipw_led_activity_off(priv);
 	ipw_led_activity_off(priv);
 	ipw_led_link_off(priv);
 	ipw_led_link_off(priv);
@@ -1074,6 +1124,7 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
 
 
 static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
 static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
 {
 {
+	/* length = 1st dword in log */
 	return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
 	return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
 }
 }
 
 
@@ -1870,7 +1921,8 @@ static char *get_cmd_string(u8 cmd)
 }
 }
 
 
 #define HOST_COMPLETE_TIMEOUT HZ
 #define HOST_COMPLETE_TIMEOUT HZ
-static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
+
+static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
 {
 {
 	int rc = 0;
 	int rc = 0;
 	unsigned long flags;
 	unsigned long flags;
@@ -1897,9 +1949,15 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
 	IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
 	IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
 		     get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
 		     get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
 		     priv->status);
 		     priv->status);
-	printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
 
 
-	rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
+#ifndef DEBUG_CMD_WEP_KEY
+	if (cmd->cmd == IPW_CMD_WEP_KEY)
+		IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");
+	else
+#endif
+		printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
+
+	rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);
 	if (rc) {
 	if (rc) {
 		priv->status &= ~STATUS_HCMD_ACTIVE;
 		priv->status &= ~STATUS_HCMD_ACTIVE;
 		IPW_ERROR("Failed to send %s: Reason %d\n",
 		IPW_ERROR("Failed to send %s: Reason %d\n",
@@ -1942,61 +2000,62 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
 	return rc;
 	return rc;
 }
 }
 
 
-static int ipw_send_host_complete(struct ipw_priv *priv)
+static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command)
 {
 {
 	struct host_cmd cmd = {
 	struct host_cmd cmd = {
-		.cmd = IPW_CMD_HOST_COMPLETE,
-		.len = 0
+		.cmd = command,
 	};
 	};
 
 
+	return __ipw_send_cmd(priv, &cmd);
+}
+
+static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,
+			    void *data)
+{
+	struct host_cmd cmd = {
+		.cmd = command,
+		.len = len,
+		.param = data,
+	};
+
+	return __ipw_send_cmd(priv, &cmd);
+}
+
+static int ipw_send_host_complete(struct ipw_priv *priv)
+{
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
 }
 }
 
 
 static int ipw_send_system_config(struct ipw_priv *priv,
 static int ipw_send_system_config(struct ipw_priv *priv,
 				  struct ipw_sys_config *config)
 				  struct ipw_sys_config *config)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SYSTEM_CONFIG,
-		.len = sizeof(*config)
-	};
-
 	if (!priv || !config) {
 	if (!priv || !config) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, config, sizeof(*config));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config),
+				config);
 }
 }
 
 
 static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
 static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SSID,
-		.len = min(len, IW_ESSID_MAX_SIZE)
-	};
-
 	if (!priv || !ssid) {
 	if (!priv || !ssid) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, ssid, cmd.len);
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),
+				ssid);
 }
 }
 
 
 static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
 static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_ADAPTER_ADDRESS,
-		.len = ETH_ALEN
-	};
-
 	if (!priv || !mac) {
 	if (!priv || !mac) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
@@ -2005,8 +2064,7 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
 	IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
 	IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
 		       priv->net_dev->name, MAC_ARG(mac));
 		       priv->net_dev->name, MAC_ARG(mac));
 
 
-	memcpy(cmd.param, mac, ETH_ALEN);
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
 }
 }
 
 
 /*
 /*
@@ -2036,9 +2094,9 @@ static void ipw_adapter_restart(void *adapter)
 static void ipw_bg_adapter_restart(void *data)
 static void ipw_bg_adapter_restart(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_adapter_restart(data);
 	ipw_adapter_restart(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
 #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
@@ -2048,8 +2106,8 @@ static void ipw_scan_check(void *data)
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
 	if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
 	if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
 		IPW_DEBUG_SCAN("Scan completion watchdog resetting "
 		IPW_DEBUG_SCAN("Scan completion watchdog resetting "
-			       "adapter (%dms).\n",
-			       IPW_SCAN_CHECK_WATCHDOG / 100);
+			       "adapter after (%dms).\n",
+			       jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
 		queue_work(priv->workqueue, &priv->adapter_restart);
 		queue_work(priv->workqueue, &priv->adapter_restart);
 	}
 	}
 }
 }
@@ -2057,59 +2115,48 @@ static void ipw_scan_check(void *data)
 static void ipw_bg_scan_check(void *data)
 static void ipw_bg_scan_check(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_scan_check(data);
 	ipw_scan_check(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static int ipw_send_scan_request_ext(struct ipw_priv *priv,
 static int ipw_send_scan_request_ext(struct ipw_priv *priv,
 				     struct ipw_scan_request_ext *request)
 				     struct ipw_scan_request_ext *request)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SCAN_REQUEST_EXT,
-		.len = sizeof(*request)
-	};
-
-	memcpy(cmd.param, request, sizeof(*request));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,
+				sizeof(*request), request);
 }
 }
 
 
 static int ipw_send_scan_abort(struct ipw_priv *priv)
 static int ipw_send_scan_abort(struct ipw_priv *priv)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SCAN_ABORT,
-		.len = 0
-	};
-
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);
 }
 }
 
 
 static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
 static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SENSITIVITY_CALIB,
-		.len = sizeof(struct ipw_sensitivity_calib)
+	struct ipw_sensitivity_calib calib = {
+		.beacon_rssi_raw = sens,
 	};
 	};
-	struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
-	    &cmd.param;
-	calib->beacon_rssi_raw = sens;
-	return ipw_send_cmd(priv, &cmd);
+
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),
+				&calib);
 }
 }
 
 
 static int ipw_send_associate(struct ipw_priv *priv,
 static int ipw_send_associate(struct ipw_priv *priv,
 			      struct ipw_associate *associate)
 			      struct ipw_associate *associate)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_ASSOCIATE,
-		.len = sizeof(*associate)
-	};
-
 	struct ipw_associate tmp_associate;
 	struct ipw_associate tmp_associate;
+
+	if (!priv || !associate) {
+		IPW_ERROR("Invalid args\n");
+		return -1;
+	}
+
 	memcpy(&tmp_associate, associate, sizeof(*associate));
 	memcpy(&tmp_associate, associate, sizeof(*associate));
 	tmp_associate.policy_support =
 	tmp_associate.policy_support =
 	    cpu_to_le16(tmp_associate.policy_support);
 	    cpu_to_le16(tmp_associate.policy_support);
@@ -2122,80 +2169,55 @@ static int ipw_send_associate(struct ipw_priv *priv,
 	    cpu_to_le16(tmp_associate.beacon_interval);
 	    cpu_to_le16(tmp_associate.beacon_interval);
 	tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
 	tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
 
 
-	if (!priv || !associate) {
-		IPW_ERROR("Invalid args\n");
-		return -1;
-	}
-
-	memcpy(cmd.param, &tmp_associate, sizeof(*associate));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate),
+				&tmp_associate);
 }
 }
 
 
 static int ipw_send_supported_rates(struct ipw_priv *priv,
 static int ipw_send_supported_rates(struct ipw_priv *priv,
 				    struct ipw_supported_rates *rates)
 				    struct ipw_supported_rates *rates)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SUPPORTED_RATES,
-		.len = sizeof(*rates)
-	};
-
 	if (!priv || !rates) {
 	if (!priv || !rates) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, rates, sizeof(*rates));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),
+				rates);
 }
 }
 
 
 static int ipw_set_random_seed(struct ipw_priv *priv)
 static int ipw_set_random_seed(struct ipw_priv *priv)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_SEED_NUMBER,
-		.len = sizeof(u32)
-	};
+	u32 val;
 
 
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	get_random_bytes(&cmd.param, sizeof(u32));
+	get_random_bytes(&val, sizeof(val));
 
 
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val);
 }
 }
 
 
 static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
 static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_CARD_DISABLE,
-		.len = sizeof(u32)
-	};
-
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	*((u32 *) & cmd.param) = phy_off;
-
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off),
+				&phy_off);
 }
 }
 
 
 static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
 static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_TX_POWER,
-		.len = sizeof(*power)
-	};
-
 	if (!priv || !power) {
 	if (!priv || !power) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, power, sizeof(*power));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power);
 }
 }
 
 
 static int ipw_set_tx_power(struct ipw_priv *priv)
 static int ipw_set_tx_power(struct ipw_priv *priv)
@@ -2247,18 +2269,14 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
 	struct ipw_rts_threshold rts_threshold = {
 	struct ipw_rts_threshold rts_threshold = {
 		.rts_threshold = rts,
 		.rts_threshold = rts,
 	};
 	};
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_RTS_THRESHOLD,
-		.len = sizeof(rts_threshold)
-	};
 
 
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD,
+				sizeof(rts_threshold), &rts_threshold);
 }
 }
 
 
 static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
 static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -2266,27 +2284,19 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
 	struct ipw_frag_threshold frag_threshold = {
 	struct ipw_frag_threshold frag_threshold = {
 		.frag_threshold = frag,
 		.frag_threshold = frag,
 	};
 	};
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_FRAG_THRESHOLD,
-		.len = sizeof(frag_threshold)
-	};
 
 
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD,
+				sizeof(frag_threshold), &frag_threshold);
 }
 }
 
 
 static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
 static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_POWER_MODE,
-		.len = sizeof(u32)
-	};
-	u32 *param = (u32 *) (&cmd.param);
+	u32 param;
 
 
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
@@ -2297,17 +2307,18 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
 	 * level */
 	 * level */
 	switch (mode) {
 	switch (mode) {
 	case IPW_POWER_BATTERY:
 	case IPW_POWER_BATTERY:
-		*param = IPW_POWER_INDEX_3;
+		param = IPW_POWER_INDEX_3;
 		break;
 		break;
 	case IPW_POWER_AC:
 	case IPW_POWER_AC:
-		*param = IPW_POWER_MODE_CAM;
+		param = IPW_POWER_MODE_CAM;
 		break;
 		break;
 	default:
 	default:
-		*param = mode;
+		param = mode;
 		break;
 		break;
 	}
 	}
 
 
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
+				&param);
 }
 }
 
 
 static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
 static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
@@ -2316,18 +2327,14 @@ static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
 		.short_retry_limit = slimit,
 		.short_retry_limit = slimit,
 		.long_retry_limit = llimit
 		.long_retry_limit = llimit
 	};
 	};
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_RETRY_LIMIT,
-		.len = sizeof(retry_limit)
-	};
 
 
 	if (!priv) {
 	if (!priv) {
 		IPW_ERROR("Invalid args\n");
 		IPW_ERROR("Invalid args\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
-	memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit),
+				&retry_limit);
 }
 }
 
 
 /*
 /*
@@ -2454,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
 	/*
 	/*
 	   If the data looks correct, then copy it to our private
 	   If the data looks correct, then copy it to our private
 	   copy.  Otherwise let the firmware know to perform the operation
 	   copy.  Otherwise let the firmware know to perform the operation
-	   on it's own
+	   on its own.
 	 */
 	 */
 	if ((priv->eeprom + EEPROM_VERSION) != 0) {
 	if ((priv->eeprom + EEPROM_VERSION) != 0) {
 		IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
 		IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
@@ -2707,22 +2714,25 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
 
 
 static int ipw_fw_dma_wait(struct ipw_priv *priv)
 static int ipw_fw_dma_wait(struct ipw_priv *priv)
 {
 {
-	u32 current_index = 0;
+	u32 current_index = 0, previous_index;
 	u32 watchdog = 0;
 	u32 watchdog = 0;
 
 
 	IPW_DEBUG_FW(">> : \n");
 	IPW_DEBUG_FW(">> : \n");
 
 
 	current_index = ipw_fw_dma_command_block_index(priv);
 	current_index = ipw_fw_dma_command_block_index(priv);
-	IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n",
+	IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
 			  (int)priv->sram_desc.last_cb_index);
 			  (int)priv->sram_desc.last_cb_index);
 
 
 	while (current_index < priv->sram_desc.last_cb_index) {
 	while (current_index < priv->sram_desc.last_cb_index) {
 		udelay(50);
 		udelay(50);
+		previous_index = current_index;
 		current_index = ipw_fw_dma_command_block_index(priv);
 		current_index = ipw_fw_dma_command_block_index(priv);
 
 
-		watchdog++;
-
-		if (watchdog > 400) {
+		if (previous_index < current_index) {
+			watchdog = 0;
+			continue;
+		}
+		if (++watchdog > 400) {
 			IPW_DEBUG_FW_INFO("Timeout\n");
 			IPW_DEBUG_FW_INFO("Timeout\n");
 			ipw_fw_dma_dump_command_block(priv);
 			ipw_fw_dma_dump_command_block(priv);
 			ipw_fw_dma_abort(priv);
 			ipw_fw_dma_abort(priv);
@@ -2772,6 +2782,7 @@ static inline int ipw_alive(struct ipw_priv *priv)
 	return ipw_read32(priv, 0x90) == 0xd55555d5;
 	return ipw_read32(priv, 0x90) == 0xd55555d5;
 }
 }
 
 
+/* timeout in msec, attempted in 10-msec quanta */
 static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
 static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
 			       int timeout)
 			       int timeout)
 {
 {
@@ -2800,10 +2811,11 @@ static int ipw_stop_master(struct ipw_priv *priv)
 	/* stop master. typical delay - 0 */
 	/* stop master. typical delay - 0 */
 	ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
 	ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
 
 
+	/* timeout is in msec, polled in 10-msec quanta */
 	rc = ipw_poll_bit(priv, IPW_RESET_REG,
 	rc = ipw_poll_bit(priv, IPW_RESET_REG,
 			  IPW_RESET_REG_MASTER_DISABLED, 100);
 			  IPW_RESET_REG_MASTER_DISABLED, 100);
 	if (rc < 0) {
 	if (rc < 0) {
-		IPW_ERROR("stop master failed in 10ms\n");
+		IPW_ERROR("wait for stop master failed after 100ms\n");
 		return -1;
 		return -1;
 	}
 	}
 
 
@@ -2890,8 +2902,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
 	mdelay(1);
 	mdelay(1);
 
 
 	/* enable ucode store */
 	/* enable ucode store */
-	ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0);
-	ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS);
+	ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0);
+	ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS);
 	mdelay(1);
 	mdelay(1);
 
 
 	/* write ucode */
 	/* write ucode */
@@ -3036,7 +3048,7 @@ static int ipw_stop_nic(struct ipw_priv *priv)
 	rc = ipw_poll_bit(priv, IPW_RESET_REG,
 	rc = ipw_poll_bit(priv, IPW_RESET_REG,
 			  IPW_RESET_REG_MASTER_DISABLED, 500);
 			  IPW_RESET_REG_MASTER_DISABLED, 500);
 	if (rc < 0) {
 	if (rc < 0) {
-		IPW_ERROR("wait for reg master disabled failed\n");
+		IPW_ERROR("wait for reg master disabled failed after 500ms\n");
 		return rc;
 		return rc;
 	}
 	}
 
 
@@ -3209,55 +3221,31 @@ static int ipw_load(struct ipw_priv *priv)
 	const struct firmware *firmware = NULL;
 	const struct firmware *firmware = NULL;
 	const struct firmware *ucode = NULL;
 	const struct firmware *ucode = NULL;
 #endif
 #endif
+	char *ucode_name;
+	char *fw_name;
 	int rc = 0, retries = 3;
 	int rc = 0, retries = 3;
 
 
-#ifdef CONFIG_PM
-	if (!fw_loaded) {
-#endif
-		rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
-		if (rc)
-			goto error;
-
-		switch (priv->ieee->iw_mode) {
-		case IW_MODE_ADHOC:
-			rc = ipw_get_fw(priv, &ucode,
-					IPW_FW_NAME("ibss_ucode"));
-			if (rc)
-				goto error;
-
-			rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
-			break;
-
+	switch (priv->ieee->iw_mode) {
+	case IW_MODE_ADHOC:
+		ucode_name = IPW_FW_NAME("ibss_ucode");
+		fw_name = IPW_FW_NAME("ibss");
+		break;
 #ifdef CONFIG_IPW2200_MONITOR
 #ifdef CONFIG_IPW2200_MONITOR
-		case IW_MODE_MONITOR:
-			rc = ipw_get_fw(priv, &ucode,
-					IPW_FW_NAME("sniffer_ucode"));
-			if (rc)
-				goto error;
-
-			rc = ipw_get_fw(priv, &firmware,
-					IPW_FW_NAME("sniffer"));
-			break;
+	case IW_MODE_MONITOR:
+		ucode_name = IPW_FW_NAME("sniffer_ucode");
+		fw_name = IPW_FW_NAME("sniffer");
+		break;
 #endif
 #endif
-		case IW_MODE_INFRA:
-			rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode"));
-			if (rc)
-				goto error;
-
-			rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
-			break;
-
-		default:
-			rc = -EINVAL;
-		}
-
-		if (rc)
-			goto error;
-
-#ifdef CONFIG_PM
-		fw_loaded = 1;
+	case IW_MODE_INFRA:
+		ucode_name = IPW_FW_NAME("bss_ucode");
+		fw_name = IPW_FW_NAME("bss");
+		break;
+	default:
+		rc = -EINVAL;
 	}
 	}
-#endif
+
+	if (rc < 0)
+		goto error;
 
 
 	if (!priv->rxq)
 	if (!priv->rxq)
 		priv->rxq = ipw_rx_queue_alloc(priv);
 		priv->rxq = ipw_rx_queue_alloc(priv);
@@ -3279,7 +3267,7 @@ static int ipw_load(struct ipw_priv *priv)
 	ipw_stop_nic(priv);
 	ipw_stop_nic(priv);
 
 
 	rc = ipw_reset_nic(priv);
 	rc = ipw_reset_nic(priv);
-	if (rc) {
+	if (rc < 0) {
 		IPW_ERROR("Unable to reset NIC\n");
 		IPW_ERROR("Unable to reset NIC\n");
 		goto error;
 		goto error;
 	}
 	}
@@ -3287,6 +3275,15 @@ static int ipw_load(struct ipw_priv *priv)
 	ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
 	ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
 			IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
 			IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
 
 
+#ifdef CONFIG_PM
+	if (!fw_loaded) {
+#endif
+		rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
+		if (rc < 0)
+			goto error;
+#ifdef CONFIG_PM
+	}
+#endif
 	/* DMA the initial boot firmware into the device */
 	/* DMA the initial boot firmware into the device */
 	rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
 	rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
 			       bootfw->size - sizeof(struct fw_header));
 			       bootfw->size - sizeof(struct fw_header));
@@ -3298,7 +3295,7 @@ static int ipw_load(struct ipw_priv *priv)
 	/* kick start the device */
 	/* kick start the device */
 	ipw_start_nic(priv);
 	ipw_start_nic(priv);
 
 
-	/* wait for the device to finish it's initial startup sequence */
+	/* wait for the device to finish its initial startup sequence */
 	rc = ipw_poll_bit(priv, IPW_INTA_RW,
 	rc = ipw_poll_bit(priv, IPW_INTA_RW,
 			  IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
 			  IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
 	if (rc < 0) {
 	if (rc < 0) {
@@ -3310,6 +3307,16 @@ static int ipw_load(struct ipw_priv *priv)
 	/* ack fw init done interrupt */
 	/* ack fw init done interrupt */
 	ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
 	ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
 
 
+#ifdef CONFIG_PM
+	if (!fw_loaded) {
+#endif
+		rc = ipw_get_fw(priv, &ucode, ucode_name);
+		if (rc < 0)
+			goto error;
+#ifdef CONFIG_PM
+	}
+#endif
+
 	/* DMA the ucode into the device */
 	/* DMA the ucode into the device */
 	rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
 	rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
 			    ucode->size - sizeof(struct fw_header));
 			    ucode->size - sizeof(struct fw_header));
@@ -3321,6 +3328,16 @@ static int ipw_load(struct ipw_priv *priv)
 	/* stop nic */
 	/* stop nic */
 	ipw_stop_nic(priv);
 	ipw_stop_nic(priv);
 
 
+#ifdef CONFIG_PM
+	if (!fw_loaded) {
+#endif
+		rc = ipw_get_fw(priv, &firmware, fw_name);
+		if (rc < 0)
+			goto error;
+#ifdef CONFIG_PM
+	}
+#endif
+
 	/* DMA bss firmware into the device */
 	/* DMA bss firmware into the device */
 	rc = ipw_load_firmware(priv, firmware->data +
 	rc = ipw_load_firmware(priv, firmware->data +
 			       sizeof(struct fw_header),
 			       sizeof(struct fw_header),
@@ -3329,11 +3346,14 @@ static int ipw_load(struct ipw_priv *priv)
 		IPW_ERROR("Unable to load firmware: %d\n", rc);
 		IPW_ERROR("Unable to load firmware: %d\n", rc);
 		goto error;
 		goto error;
 	}
 	}
+#ifdef CONFIG_PM
+	fw_loaded = 1;
+#endif
 
 
 	ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
 	ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
 
 
 	rc = ipw_queue_reset(priv);
 	rc = ipw_queue_reset(priv);
-	if (rc) {
+	if (rc < 0) {
 		IPW_ERROR("Unable to initialize queues\n");
 		IPW_ERROR("Unable to initialize queues\n");
 		goto error;
 		goto error;
 	}
 	}
@@ -3362,7 +3382,7 @@ static int ipw_load(struct ipw_priv *priv)
 	rc = ipw_poll_bit(priv, IPW_INTA_RW,
 	rc = ipw_poll_bit(priv, IPW_INTA_RW,
 			  IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
 			  IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
 	if (rc < 0) {
 	if (rc < 0) {
-		IPW_ERROR("device failed to start after 500ms\n");
+		IPW_ERROR("device failed to start within 500ms\n");
 		goto error;
 		goto error;
 	}
 	}
 	IPW_DEBUG_INFO("device response after %dms\n", rc);
 	IPW_DEBUG_INFO("device response after %dms\n", rc);
@@ -3715,9 +3735,9 @@ static int ipw_disassociate(void *data)
 static void ipw_bg_disassociate(void *data)
 static void ipw_bg_disassociate(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_disassociate(data);
 	ipw_disassociate(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static void ipw_system_config(void *data)
 static void ipw_system_config(void *data)
@@ -4077,9 +4097,9 @@ static void ipw_gather_stats(struct ipw_priv *priv)
 static void ipw_bg_gather_stats(void *data)
 static void ipw_bg_gather_stats(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_gather_stats(data);
 	ipw_gather_stats(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 /* Missed beacon behavior:
 /* Missed beacon behavior:
@@ -4121,8 +4141,9 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
 		return;
 		return;
 	}
 	}
 
 
-	if (missed_count > priv->roaming_threshold &&
-	    missed_count <= priv->disassociate_threshold) {
+	if (roaming &&
+	    (missed_count > priv->roaming_threshold &&
+	     missed_count <= priv->disassociate_threshold)) {
 		/* If we are not already roaming, set the ROAM
 		/* If we are not already roaming, set the ROAM
 		 * bit in the status and kick off a scan.
 		 * bit in the status and kick off a scan.
 		 * This can happen several times before we reach
 		 * This can happen several times before we reach
@@ -4150,7 +4171,6 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
 	}
 	}
 
 
 	IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
 	IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
-
 }
 }
 
 
 /**
 /**
@@ -4911,13 +4931,13 @@ static void ipw_rx_queue_replenish(void *data)
 static void ipw_bg_rx_queue_replenish(void *data)
 static void ipw_bg_rx_queue_replenish(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_rx_queue_replenish(data);
 	ipw_rx_queue_replenish(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
+ * If an SKB has been detached, the POOL needs to have its SKB set to NULL
  * This free routine walks the list of POOL entries and if SKB is set to
  * This free routine walks the list of POOL entries and if SKB is set to
  * non NULL it is unmapped and freed
  * non NULL it is unmapped and freed
  */
  */
@@ -5257,10 +5277,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
 	if (priv->ieee->scan_age != 0 &&
 	if (priv->ieee->scan_age != 0 &&
 	    time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
 	    time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
 		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
 		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
-				"because of age: %lums.\n",
+				"because of age: %ums.\n",
 				escape_essid(network->ssid, network->ssid_len),
 				escape_essid(network->ssid, network->ssid_len),
 				MAC_ARG(network->bssid),
 				MAC_ARG(network->bssid),
-				1000 * (jiffies - network->last_scanned) / HZ);
+				jiffies_to_msecs(jiffies -
+						 network->last_scanned));
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -5369,7 +5390,7 @@ static void ipw_merge_adhoc_network(void *data)
 			return;
 			return;
 		}
 		}
 
 
-		down(&priv->sem);
+		mutex_lock(&priv->mutex);
 		if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
 		if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
 			IPW_DEBUG_MERGE("remove network %s\n",
 			IPW_DEBUG_MERGE("remove network %s\n",
 					escape_essid(priv->essid,
 					escape_essid(priv->essid,
@@ -5379,7 +5400,7 @@ static void ipw_merge_adhoc_network(void *data)
 
 
 		ipw_disassociate(priv);
 		ipw_disassociate(priv);
 		priv->assoc_network = match.network;
 		priv->assoc_network = match.network;
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return;
 		return;
 	}
 	}
 }
 }
@@ -5467,11 +5488,12 @@ static int ipw_best_network(struct ipw_priv *priv,
 	if (network->last_associate &&
 	if (network->last_associate &&
 	    time_after(network->last_associate + (HZ * 3UL), jiffies)) {
 	    time_after(network->last_associate + (HZ * 3UL), jiffies)) {
 		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
 		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
-				"because of storming (%lus since last "
+				"because of storming (%ums since last "
 				"assoc attempt).\n",
 				"assoc attempt).\n",
 				escape_essid(network->ssid, network->ssid_len),
 				escape_essid(network->ssid, network->ssid_len),
 				MAC_ARG(network->bssid),
 				MAC_ARG(network->bssid),
-				(jiffies - network->last_associate) / HZ);
+				jiffies_to_msecs(jiffies -
+						 network->last_associate));
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -5479,10 +5501,11 @@ static int ipw_best_network(struct ipw_priv *priv,
 	if (priv->ieee->scan_age != 0 &&
 	if (priv->ieee->scan_age != 0 &&
 	    time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
 	    time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
 		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
 		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
-				"because of age: %lums.\n",
+				"because of age: %ums.\n",
 				escape_essid(network->ssid, network->ssid_len),
 				escape_essid(network->ssid, network->ssid_len),
 				MAC_ARG(network->bssid),
 				MAC_ARG(network->bssid),
-				1000 * (jiffies - network->last_scanned) / HZ);
+				jiffies_to_msecs(jiffies -
+						 network->last_scanned));
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -5671,54 +5694,44 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
 
 
 static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
 static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
 {
 {
-	struct ipw_tgi_tx_key *key;
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_TGI_TX_KEY,
-		.len = sizeof(*key)
-	};
+	struct ipw_tgi_tx_key key;
 
 
 	if (!(priv->ieee->sec.flags & (1 << index)))
 	if (!(priv->ieee->sec.flags & (1 << index)))
 		return;
 		return;
 
 
-	key = (struct ipw_tgi_tx_key *)&cmd.param;
-	key->key_id = index;
-	memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
-	key->security_type = type;
-	key->station_index = 0;	/* always 0 for BSS */
-	key->flags = 0;
+	key.key_id = index;
+	memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
+	key.security_type = type;
+	key.station_index = 0;	/* always 0 for BSS */
+	key.flags = 0;
 	/* 0 for new key; previous value of counter (after fatal error) */
 	/* 0 for new key; previous value of counter (after fatal error) */
-	key->tx_counter[0] = 0;
-	key->tx_counter[1] = 0;
+	key.tx_counter[0] = 0;
+	key.tx_counter[1] = 0;
 
 
-	ipw_send_cmd(priv, &cmd);
+	ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);
 }
 }
 
 
 static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
 static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
 {
 {
-	struct ipw_wep_key *key;
+	struct ipw_wep_key key;
 	int i;
 	int i;
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_WEP_KEY,
-		.len = sizeof(*key)
-	};
 
 
-	key = (struct ipw_wep_key *)&cmd.param;
-	key->cmd_id = DINO_CMD_WEP_KEY;
-	key->seq_num = 0;
+	key.cmd_id = DINO_CMD_WEP_KEY;
+	key.seq_num = 0;
 
 
 	/* Note: AES keys cannot be set for multiple times.
 	/* Note: AES keys cannot be set for multiple times.
 	 * Only set it at the first time. */
 	 * Only set it at the first time. */
 	for (i = 0; i < 4; i++) {
 	for (i = 0; i < 4; i++) {
-		key->key_index = i | type;
+		key.key_index = i | type;
 		if (!(priv->ieee->sec.flags & (1 << i))) {
 		if (!(priv->ieee->sec.flags & (1 << i))) {
-			key->key_size = 0;
+			key.key_size = 0;
 			continue;
 			continue;
 		}
 		}
 
 
-		key->key_size = priv->ieee->sec.key_sizes[i];
-		memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
+		key.key_size = priv->ieee->sec.key_sizes[i];
+		memcpy(key.key, priv->ieee->sec.keys[i], key.key_size);
 
 
-		ipw_send_cmd(priv, &cmd);
+		ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key);
 	}
 	}
 }
 }
 
 
@@ -5822,9 +5835,9 @@ static void ipw_adhoc_check(void *data)
 static void ipw_bg_adhoc_check(void *data)
 static void ipw_bg_adhoc_check(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_adhoc_check(data);
 	ipw_adhoc_check(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 #ifdef CONFIG_IPW2200_DEBUG
 #ifdef CONFIG_IPW2200_DEBUG
@@ -6051,7 +6064,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
 	    (priv->status & STATUS_EXIT_PENDING))
 	    (priv->status & STATUS_EXIT_PENDING))
 		return 0;
 		return 0;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	if (priv->status & STATUS_SCANNING) {
 	if (priv->status & STATUS_SCANNING) {
 		IPW_DEBUG_HC("Concurrent scan requested.  Ignoring.\n");
 		IPW_DEBUG_HC("Concurrent scan requested.  Ignoring.\n");
@@ -6159,16 +6172,16 @@ static int ipw_request_scan(struct ipw_priv *priv)
 	queue_delayed_work(priv->workqueue, &priv->scan_check,
 	queue_delayed_work(priv->workqueue, &priv->scan_check,
 			   IPW_SCAN_CHECK_WATCHDOG);
 			   IPW_SCAN_CHECK_WATCHDOG);
       done:
       done:
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return err;
 	return err;
 }
 }
 
 
 static void ipw_bg_abort_scan(void *data)
 static void ipw_bg_abort_scan(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_abort_scan(data);
 	ipw_abort_scan(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static int ipw_wpa_enable(struct ipw_priv *priv, int value)
 static int ipw_wpa_enable(struct ipw_priv *priv, int value)
@@ -6193,6 +6206,9 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
 	} else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
 	} else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
 		sec.auth_mode = WLAN_AUTH_OPEN;
 		sec.auth_mode = WLAN_AUTH_OPEN;
 		ieee->open_wep = 1;
 		ieee->open_wep = 1;
+	} else if (value & IW_AUTH_ALG_LEAP) {
+		sec.auth_mode = WLAN_AUTH_LEAP;
+		ieee->open_wep = 1;
 	} else
 	} else
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -6204,7 +6220,8 @@ static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
 	return ret;
 	return ret;
 }
 }
 
 
-void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
+static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,
+				int wpa_ie_len)
 {
 {
 	/* make sure WPA is enabled */
 	/* make sure WPA is enabled */
 	ipw_wpa_enable(priv, 1);
 	ipw_wpa_enable(priv, 1);
@@ -6215,15 +6232,10 @@ void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
 static int ipw_set_rsn_capa(struct ipw_priv *priv,
 static int ipw_set_rsn_capa(struct ipw_priv *priv,
 			    char *capabilities, int length)
 			    char *capabilities, int length)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_RSN_CAPABILITIES,
-		.len = length,
-	};
-
 	IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
 	IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
 
 
-	memcpy(cmd.param, capabilities, length);
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length,
+				capabilities);
 }
 }
 
 
 /*
 /*
@@ -6244,7 +6256,7 @@ static int ipw_wx_set_genie(struct net_device *dev,
 	    (wrqu->data.length && extra == NULL))
 	    (wrqu->data.length && extra == NULL))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	//down(&priv->sem);
+	//mutex_lock(&priv->mutex);
 
 
 	//if (!ieee->wpa_enabled) {
 	//if (!ieee->wpa_enabled) {
 	//      err = -EOPNOTSUPP;
 	//      err = -EOPNOTSUPP;
@@ -6270,7 +6282,7 @@ static int ipw_wx_set_genie(struct net_device *dev,
 
 
 	ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
 	ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
       out:
       out:
-	//up(&priv->sem);
+	//mutex_unlock(&priv->mutex);
 	return err;
 	return err;
 }
 }
 
 
@@ -6283,7 +6295,7 @@ static int ipw_wx_get_genie(struct net_device *dev,
 	struct ieee80211_device *ieee = priv->ieee;
 	struct ieee80211_device *ieee = priv->ieee;
 	int err = 0;
 	int err = 0;
 
 
-	//down(&priv->sem);
+	//mutex_lock(&priv->mutex);
 
 
 	//if (!ieee->wpa_enabled) {
 	//if (!ieee->wpa_enabled) {
 	//      err = -EOPNOTSUPP;
 	//      err = -EOPNOTSUPP;
@@ -6304,7 +6316,7 @@ static int ipw_wx_get_genie(struct net_device *dev,
 	memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
 	memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
 
 
       out:
       out:
-	//up(&priv->sem);
+	//mutex_unlock(&priv->mutex);
 	return err;
 	return err;
 }
 }
 
 
@@ -6964,12 +6976,12 @@ static void ipw_bg_qos_activate(void *data)
 	if (priv == NULL)
 	if (priv == NULL)
 		return;
 		return;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	if (priv->status & STATUS_ASSOCIATED)
 	if (priv->status & STATUS_ASSOCIATED)
 		ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
 		ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static int ipw_handle_probe_response(struct net_device *dev,
 static int ipw_handle_probe_response(struct net_device *dev,
@@ -7010,25 +7022,15 @@ static int ipw_handle_assoc_response(struct net_device *dev,
 static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
 static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
 				       *qos_param)
 				       *qos_param)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_QOS_PARAMETERS,
-		.len = (sizeof(struct ieee80211_qos_parameters) * 3)
-	};
-
-	memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,
+				sizeof(*qos_param) * 3, qos_param);
 }
 }
 
 
 static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
 static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
 				     *qos_param)
 				     *qos_param)
 {
 {
-	struct host_cmd cmd = {
-		.cmd = IPW_CMD_WME_INFO,
-		.len = sizeof(*qos_param)
-	};
-
-	memcpy(cmd.param, qos_param, sizeof(*qos_param));
-	return ipw_send_cmd(priv, &cmd);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),
+				qos_param);
 }
 }
 
 
 #endif				/* CONFIG_IPW_QOS */
 #endif				/* CONFIG_IPW_QOS */
@@ -7052,19 +7054,22 @@ static int ipw_associate_network(struct ipw_priv *priv,
 
 
 	memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
 	memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
 	priv->assoc_request.channel = network->channel;
 	priv->assoc_request.channel = network->channel;
+	priv->assoc_request.auth_key = 0;
+
 	if ((priv->capability & CAP_PRIVACY_ON) &&
 	if ((priv->capability & CAP_PRIVACY_ON) &&
-	    (priv->capability & CAP_SHARED_KEY)) {
+	    (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) {
 		priv->assoc_request.auth_type = AUTH_SHARED_KEY;
 		priv->assoc_request.auth_type = AUTH_SHARED_KEY;
 		priv->assoc_request.auth_key = priv->ieee->sec.active_key;
 		priv->assoc_request.auth_key = priv->ieee->sec.active_key;
 
 
-		if ((priv->capability & CAP_PRIVACY_ON) &&
-		    (priv->ieee->sec.level == SEC_LEVEL_1) &&
+		if ((priv->ieee->sec.level == SEC_LEVEL_1) &&
 		    !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
 		    !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
 			ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
 			ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
-	} else {
+
+	} else if ((priv->capability & CAP_PRIVACY_ON) &&
+		   (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP))
+		priv->assoc_request.auth_type = AUTH_LEAP;
+	else
 		priv->assoc_request.auth_type = AUTH_OPEN;
 		priv->assoc_request.auth_type = AUTH_OPEN;
-		priv->assoc_request.auth_key = 0;
-	}
 
 
 	if (priv->ieee->wpa_ie_len) {
 	if (priv->ieee->wpa_ie_len) {
 		priv->assoc_request.policy_support = 0x02;	/* RSN active */
 		priv->assoc_request.policy_support = 0x02;	/* RSN active */
@@ -7278,9 +7283,9 @@ static void ipw_roam(void *data)
 static void ipw_bg_roam(void *data)
 static void ipw_bg_roam(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_roam(data);
 	ipw_roam(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static int ipw_associate(void *data)
 static int ipw_associate(void *data)
@@ -7375,9 +7380,9 @@ static int ipw_associate(void *data)
 static void ipw_bg_associate(void *data)
 static void ipw_bg_associate(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_associate(data);
 	ipw_associate(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
 static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
@@ -8126,7 +8131,7 @@ static int ipw_wx_get_name(struct net_device *dev,
 			   union iwreq_data *wrqu, char *extra)
 			   union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (priv->status & STATUS_RF_KILL_MASK)
 	if (priv->status & STATUS_RF_KILL_MASK)
 		strcpy(wrqu->name, "radio off");
 		strcpy(wrqu->name, "radio off");
 	else if (!(priv->status & STATUS_ASSOCIATED))
 	else if (!(priv->status & STATUS_ASSOCIATED))
@@ -8135,7 +8140,7 @@ static int ipw_wx_get_name(struct net_device *dev,
 		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
 		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
 			 ipw_modes[priv->assoc_request.ieee_mode]);
 			 ipw_modes[priv->assoc_request.ieee_mode]);
 	IPW_DEBUG_WX("Name: %s\n", wrqu->name);
 	IPW_DEBUG_WX("Name: %s\n", wrqu->name);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8204,9 +8209,9 @@ static int ipw_wx_set_freq(struct net_device *dev,
 
 
 	if (fwrq->m == 0) {
 	if (fwrq->m == 0) {
 		IPW_DEBUG_WX("SET Freq/Channel -> any\n");
 		IPW_DEBUG_WX("SET Freq/Channel -> any\n");
-		down(&priv->sem);
+		mutex_lock(&priv->mutex);
 		ret = ipw_set_channel(priv, 0);
 		ret = ipw_set_channel(priv, 0);
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return ret;
 		return ret;
 	}
 	}
 	/* if setting by freq convert to channel */
 	/* if setting by freq convert to channel */
@@ -8234,9 +8239,9 @@ static int ipw_wx_set_freq(struct net_device *dev,
 	}
 	}
 
 
 	IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
 	IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ret = ipw_set_channel(priv, channel);
 	ret = ipw_set_channel(priv, channel);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -8250,14 +8255,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
 
 
 	/* If we are associated, trying to associate, or have a statically
 	/* If we are associated, trying to associate, or have a statically
 	 * configured CHANNEL then return that; otherwise return ANY */
 	 * configured CHANNEL then return that; otherwise return ANY */
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (priv->config & CFG_STATIC_CHANNEL ||
 	if (priv->config & CFG_STATIC_CHANNEL ||
 	    priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
 	    priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
 		wrqu->freq.m = priv->channel;
 		wrqu->freq.m = priv->channel;
 	else
 	else
 		wrqu->freq.m = 0;
 		wrqu->freq.m = 0;
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
 	IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
 	return 0;
 	return 0;
 }
 }
@@ -8287,7 +8292,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
 	if (wrqu->mode == priv->ieee->iw_mode)
 	if (wrqu->mode == priv->ieee->iw_mode)
 		return 0;
 		return 0;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	ipw_sw_reset(priv, 0);
 	ipw_sw_reset(priv, 0);
 
 
@@ -8310,7 +8315,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
 	priv->ieee->iw_mode = wrqu->mode;
 	priv->ieee->iw_mode = wrqu->mode;
 
 
 	queue_work(priv->workqueue, &priv->adapter_restart);
 	queue_work(priv->workqueue, &priv->adapter_restart);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return err;
 	return err;
 }
 }
 
 
@@ -8319,10 +8324,10 @@ static int ipw_wx_get_mode(struct net_device *dev,
 			   union iwreq_data *wrqu, char *extra)
 			   union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->mode = priv->ieee->iw_mode;
 	wrqu->mode = priv->ieee->iw_mode;
 	IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
 	IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8369,7 +8374,7 @@ static int ipw_wx_get_range(struct net_device *dev,
 	range->avg_qual.level = 0;	/* FIXME to real average level */
 	range->avg_qual.level = 0;	/* FIXME to real average level */
 	range->avg_qual.noise = 0;
 	range->avg_qual.noise = 0;
 	range->avg_qual.updated = 7;	/* Updated all three */
 	range->avg_qual.updated = 7;	/* Updated all three */
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
 	range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
 
 
 	for (i = 0; i < range->num_bitrates; i++)
 	for (i = 0; i < range->num_bitrates; i++)
@@ -8387,7 +8392,7 @@ static int ipw_wx_get_range(struct net_device *dev,
 
 
 	/* Set the Wireless Extension versions */
 	/* Set the Wireless Extension versions */
 	range->we_version_compiled = WIRELESS_EXT;
 	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 16;
+	range->we_version_source = 18;
 
 
 	i = 0;
 	i = 0;
 	if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
 	if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
@@ -8411,7 +8416,7 @@ static int ipw_wx_get_range(struct net_device *dev,
 	range->num_channels = i;
 	range->num_channels = i;
 	range->num_frequency = i;
 	range->num_frequency = i;
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 
 
 	/* Event capability (kernel + driver) */
 	/* Event capability (kernel + driver) */
 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
@@ -8419,6 +8424,9 @@ static int ipw_wx_get_range(struct net_device *dev,
 				IW_EVENT_CAPA_MASK(SIOCGIWAP));
 				IW_EVENT_CAPA_MASK(SIOCGIWAP));
 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 
 
+	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
 	IPW_DEBUG_WX("GET Range\n");
 	IPW_DEBUG_WX("GET Range\n");
 	return 0;
 	return 0;
 }
 }
@@ -8438,7 +8446,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
 
 
 	if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
 	if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
 		return -EINVAL;
 		return -EINVAL;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
 	if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
 	    !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
 	    !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
 		/* we disable mandatory BSSID association */
 		/* we disable mandatory BSSID association */
@@ -8447,14 +8455,14 @@ static int ipw_wx_set_wap(struct net_device *dev,
 		IPW_DEBUG_ASSOC("Attempting to associate with new "
 		IPW_DEBUG_ASSOC("Attempting to associate with new "
 				"parameters.\n");
 				"parameters.\n");
 		ipw_associate(priv);
 		ipw_associate(priv);
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return 0;
 		return 0;
 	}
 	}
 
 
 	priv->config |= CFG_STATIC_BSSID;
 	priv->config |= CFG_STATIC_BSSID;
 	if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
 	if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
 		IPW_DEBUG_WX("BSSID set to current BSSID.\n");
 		IPW_DEBUG_WX("BSSID set to current BSSID.\n");
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -8468,7 +8476,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
 	if (!ipw_disassociate(priv))
 	if (!ipw_disassociate(priv))
 		ipw_associate(priv);
 		ipw_associate(priv);
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8479,7 +8487,7 @@ static int ipw_wx_get_wap(struct net_device *dev,
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	/* If we are associated, trying to associate, or have a statically
 	/* If we are associated, trying to associate, or have a statically
 	 * configured BSSID then return that; otherwise return ANY */
 	 * configured BSSID then return that; otherwise return ANY */
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (priv->config & CFG_STATIC_BSSID ||
 	if (priv->config & CFG_STATIC_BSSID ||
 	    priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 	    priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		wrqu->ap_addr.sa_family = ARPHRD_ETHER;
 		wrqu->ap_addr.sa_family = ARPHRD_ETHER;
@@ -8489,7 +8497,7 @@ static int ipw_wx_get_wap(struct net_device *dev,
 
 
 	IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
 	IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
 		     MAC_ARG(wrqu->ap_addr.sa_data));
 		     MAC_ARG(wrqu->ap_addr.sa_data));
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8500,7 +8508,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	char *essid = "";	/* ANY */
 	char *essid = "";	/* ANY */
 	int length = 0;
 	int length = 0;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (wrqu->essid.flags && wrqu->essid.length) {
 	if (wrqu->essid.flags && wrqu->essid.length) {
 		length = wrqu->essid.length - 1;
 		length = wrqu->essid.length - 1;
 		essid = extra;
 		essid = extra;
@@ -8515,7 +8523,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
 			priv->config &= ~CFG_STATIC_ESSID;
 			priv->config &= ~CFG_STATIC_ESSID;
 			ipw_associate(priv);
 			ipw_associate(priv);
 		}
 		}
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -8525,7 +8533,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
 
 
 	if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
 	if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
 		IPW_DEBUG_WX("ESSID set to current ESSID.\n");
 		IPW_DEBUG_WX("ESSID set to current ESSID.\n");
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -8540,7 +8548,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
 	if (!ipw_disassociate(priv))
 	if (!ipw_disassociate(priv))
 		ipw_associate(priv);
 		ipw_associate(priv);
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8552,7 +8560,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
 
 
 	/* If we are associated, trying to associate, or have a statically
 	/* If we are associated, trying to associate, or have a statically
 	 * configured ESSID then return that; otherwise return ANY */
 	 * configured ESSID then return that; otherwise return ANY */
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (priv->config & CFG_STATIC_ESSID ||
 	if (priv->config & CFG_STATIC_ESSID ||
 	    priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 	    priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		IPW_DEBUG_WX("Getting essid: '%s'\n",
 		IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -8565,7 +8573,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
 		wrqu->essid.length = 0;
 		wrqu->essid.length = 0;
 		wrqu->essid.flags = 0;	/* active */
 		wrqu->essid.flags = 0;	/* active */
 	}
 	}
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8578,12 +8586,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
 	IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
 	IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
 		return -E2BIG;
 		return -E2BIG;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
 	wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
 	memset(priv->nick, 0, sizeof(priv->nick));
 	memset(priv->nick, 0, sizeof(priv->nick));
 	memcpy(priv->nick, extra, wrqu->data.length);
 	memcpy(priv->nick, extra, wrqu->data.length);
 	IPW_DEBUG_TRACE("<<\n");
 	IPW_DEBUG_TRACE("<<\n");
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 
 
 }
 }
@@ -8594,11 +8602,11 @@ static int ipw_wx_get_nick(struct net_device *dev,
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_WX("Getting nick\n");
 	IPW_DEBUG_WX("Getting nick\n");
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->data.length = strlen(priv->nick) + 1;
 	wrqu->data.length = strlen(priv->nick) + 1;
 	memcpy(extra, priv->nick, wrqu->data.length);
 	memcpy(extra, priv->nick, wrqu->data.length);
 	wrqu->data.flags = 1;	/* active */
 	wrqu->data.flags = 1;	/* active */
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8691,7 +8699,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
       apply:
       apply:
 	IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
 	IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
 		     mask, fixed ? "fixed" : "sub-rates");
 		     mask, fixed ? "fixed" : "sub-rates");
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (mask == IEEE80211_DEFAULT_RATES_MASK) {
 	if (mask == IEEE80211_DEFAULT_RATES_MASK) {
 		priv->config &= ~CFG_FIXED_RATE;
 		priv->config &= ~CFG_FIXED_RATE;
 		ipw_set_fixed_rate(priv, priv->ieee->mode);
 		ipw_set_fixed_rate(priv, priv->ieee->mode);
@@ -8700,7 +8708,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
 
 
 	if (priv->rates_mask == mask) {
 	if (priv->rates_mask == mask) {
 		IPW_DEBUG_WX("Mask set to current mask.\n");
 		IPW_DEBUG_WX("Mask set to current mask.\n");
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -8711,7 +8719,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
 	if (!ipw_disassociate(priv))
 	if (!ipw_disassociate(priv))
 		ipw_associate(priv);
 		ipw_associate(priv);
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -8720,9 +8728,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
 			   union iwreq_data *wrqu, char *extra)
 			   union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->bitrate.value = priv->last_rate;
 	wrqu->bitrate.value = priv->last_rate;
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
 	IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
 	return 0;
 	return 0;
 }
 }
@@ -8732,20 +8740,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
 			  union iwreq_data *wrqu, char *extra)
 			  union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (wrqu->rts.disabled)
 	if (wrqu->rts.disabled)
 		priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
 		priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
 	else {
 	else {
 		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
 		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
 		    wrqu->rts.value > MAX_RTS_THRESHOLD) {
 		    wrqu->rts.value > MAX_RTS_THRESHOLD) {
-			up(&priv->sem);
+			mutex_unlock(&priv->mutex);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		priv->rts_threshold = wrqu->rts.value;
 		priv->rts_threshold = wrqu->rts.value;
 	}
 	}
 
 
 	ipw_send_rts_threshold(priv, priv->rts_threshold);
 	ipw_send_rts_threshold(priv, priv->rts_threshold);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
 	IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
 	return 0;
 	return 0;
 }
 }
@@ -8755,11 +8763,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
 			  union iwreq_data *wrqu, char *extra)
 			  union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->rts.value = priv->rts_threshold;
 	wrqu->rts.value = priv->rts_threshold;
 	wrqu->rts.fixed = 0;	/* no auto select */
 	wrqu->rts.fixed = 0;	/* no auto select */
 	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
 	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
 	IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
 	return 0;
 	return 0;
 }
 }
@@ -8771,7 +8779,7 @@ static int ipw_wx_set_txpow(struct net_device *dev,
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int err = 0;
 	int err = 0;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
 	if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
 		err = -EINPROGRESS;
 		err = -EINPROGRESS;
 		goto out;
 		goto out;
@@ -8794,7 +8802,7 @@ static int ipw_wx_set_txpow(struct net_device *dev,
 	priv->tx_power = wrqu->power.value;
 	priv->tx_power = wrqu->power.value;
 	err = ipw_set_tx_power(priv);
 	err = ipw_set_tx_power(priv);
       out:
       out:
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return err;
 	return err;
 }
 }
 
 
@@ -8803,12 +8811,12 @@ static int ipw_wx_get_txpow(struct net_device *dev,
 			    union iwreq_data *wrqu, char *extra)
 			    union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->power.value = priv->tx_power;
 	wrqu->power.value = priv->tx_power;
 	wrqu->power.fixed = 1;
 	wrqu->power.fixed = 1;
 	wrqu->power.flags = IW_TXPOW_DBM;
 	wrqu->power.flags = IW_TXPOW_DBM;
 	wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
 	wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 
 
 	IPW_DEBUG_WX("GET TX Power -> %s %d \n",
 	IPW_DEBUG_WX("GET TX Power -> %s %d \n",
 		     wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
 		     wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
@@ -8821,13 +8829,13 @@ static int ipw_wx_set_frag(struct net_device *dev,
 			   union iwreq_data *wrqu, char *extra)
 			   union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (wrqu->frag.disabled)
 	if (wrqu->frag.disabled)
 		priv->ieee->fts = DEFAULT_FTS;
 		priv->ieee->fts = DEFAULT_FTS;
 	else {
 	else {
 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
 		    wrqu->frag.value > MAX_FRAG_THRESHOLD) {
 		    wrqu->frag.value > MAX_FRAG_THRESHOLD) {
-			up(&priv->sem);
+			mutex_unlock(&priv->mutex);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 
@@ -8835,7 +8843,7 @@ static int ipw_wx_set_frag(struct net_device *dev,
 	}
 	}
 
 
 	ipw_send_frag_threshold(priv, wrqu->frag.value);
 	ipw_send_frag_threshold(priv, wrqu->frag.value);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
 	IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
 	return 0;
 	return 0;
 }
 }
@@ -8845,11 +8853,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
 			   union iwreq_data *wrqu, char *extra)
 			   union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->frag.value = priv->ieee->fts;
 	wrqu->frag.value = priv->ieee->fts;
 	wrqu->frag.fixed = 0;	/* no auto select */
 	wrqu->frag.fixed = 0;	/* no auto select */
 	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
 	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
 	IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
 
 
 	return 0;
 	return 0;
@@ -8870,7 +8878,7 @@ static int ipw_wx_set_retry(struct net_device *dev,
 	if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
 	if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (wrqu->retry.flags & IW_RETRY_MIN)
 	if (wrqu->retry.flags & IW_RETRY_MIN)
 		priv->short_retry_limit = (u8) wrqu->retry.value;
 		priv->short_retry_limit = (u8) wrqu->retry.value;
 	else if (wrqu->retry.flags & IW_RETRY_MAX)
 	else if (wrqu->retry.flags & IW_RETRY_MAX)
@@ -8882,7 +8890,7 @@ static int ipw_wx_set_retry(struct net_device *dev,
 
 
 	ipw_send_retry_limit(priv, priv->short_retry_limit,
 	ipw_send_retry_limit(priv, priv->short_retry_limit,
 			     priv->long_retry_limit);
 			     priv->long_retry_limit);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
 	IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
 		     priv->short_retry_limit, priv->long_retry_limit);
 		     priv->short_retry_limit, priv->long_retry_limit);
 	return 0;
 	return 0;
@@ -8894,11 +8902,11 @@ static int ipw_wx_get_retry(struct net_device *dev,
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	wrqu->retry.disabled = 0;
 	wrqu->retry.disabled = 0;
 
 
 	if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
 	if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -8912,7 +8920,7 @@ static int ipw_wx_get_retry(struct net_device *dev,
 		wrqu->retry.flags = IW_RETRY_LIMIT;
 		wrqu->retry.flags = IW_RETRY_LIMIT;
 		wrqu->retry.value = priv->short_retry_limit;
 		wrqu->retry.value = priv->short_retry_limit;
 	}
 	}
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 
 
 	IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
 	IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
 
 
@@ -8929,7 +8937,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
 	    (priv->status & STATUS_EXIT_PENDING))
 	    (priv->status & STATUS_EXIT_PENDING))
 		return 0;
 		return 0;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	if (priv->status & STATUS_RF_KILL_MASK) {
 	if (priv->status & STATUS_RF_KILL_MASK) {
 		IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
 		IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
@@ -8981,7 +8989,7 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
 	priv->status |= STATUS_SCANNING;
 	priv->status |= STATUS_SCANNING;
 
 
       done:
       done:
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return err;
 	return err;
 }
 }
 
 
@@ -9024,7 +9032,7 @@ static int ipw_wx_set_encode(struct net_device *dev,
 	int ret;
 	int ret;
 	u32 cap = priv->capability;
 	u32 cap = priv->capability;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
 	ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
 
 
 	/* In IBSS mode, we need to notify the firmware to update
 	/* In IBSS mode, we need to notify the firmware to update
@@ -9034,7 +9042,7 @@ static int ipw_wx_set_encode(struct net_device *dev,
 	    priv->status & STATUS_ASSOCIATED)
 	    priv->status & STATUS_ASSOCIATED)
 		ipw_disassociate(priv);
 		ipw_disassociate(priv);
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -9052,17 +9060,17 @@ static int ipw_wx_set_power(struct net_device *dev,
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int err;
 	int err;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (wrqu->power.disabled) {
 	if (wrqu->power.disabled) {
 		priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
 		priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
 		err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
 		err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
 		if (err) {
 		if (err) {
 			IPW_DEBUG_WX("failed setting power mode.\n");
 			IPW_DEBUG_WX("failed setting power mode.\n");
-			up(&priv->sem);
+			mutex_unlock(&priv->mutex);
 			return err;
 			return err;
 		}
 		}
 		IPW_DEBUG_WX("SET Power Management Mode -> off\n");
 		IPW_DEBUG_WX("SET Power Management Mode -> off\n");
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -9074,7 +9082,7 @@ static int ipw_wx_set_power(struct net_device *dev,
 	default:		/* Otherwise we don't support it */
 	default:		/* Otherwise we don't support it */
 		IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
 		IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
 			     wrqu->power.flags);
 			     wrqu->power.flags);
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 	}
 	}
 
 
@@ -9087,12 +9095,12 @@ static int ipw_wx_set_power(struct net_device *dev,
 	err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
 	err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
 	if (err) {
 	if (err) {
 		IPW_DEBUG_WX("failed setting power mode.\n");
 		IPW_DEBUG_WX("failed setting power mode.\n");
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return err;
 		return err;
 	}
 	}
 
 
 	IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
 	IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9101,13 +9109,13 @@ static int ipw_wx_get_power(struct net_device *dev,
 			    union iwreq_data *wrqu, char *extra)
 			    union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
 		wrqu->power.disabled = 1;
 	else
 	else
 		wrqu->power.disabled = 0;
 		wrqu->power.disabled = 0;
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
 	IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
 
 
 	return 0;
 	return 0;
@@ -9120,7 +9128,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int mode = *(int *)extra;
 	int mode = *(int *)extra;
 	int err;
 	int err;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
 	if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
 		mode = IPW_POWER_AC;
 		mode = IPW_POWER_AC;
 		priv->power_mode = mode;
 		priv->power_mode = mode;
@@ -9133,11 +9141,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
 
 
 		if (err) {
 		if (err) {
 			IPW_DEBUG_WX("failed setting power mode.\n");
 			IPW_DEBUG_WX("failed setting power mode.\n");
-			up(&priv->sem);
+			mutex_unlock(&priv->mutex);
 			return err;
 			return err;
 		}
 		}
 	}
 	}
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9186,7 +9194,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
 		IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
 		IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (priv->adapter == IPW_2915ABG) {
 	if (priv->adapter == IPW_2915ABG) {
 		priv->ieee->abg_true = 1;
 		priv->ieee->abg_true = 1;
 		if (mode & IEEE_A) {
 		if (mode & IEEE_A) {
@@ -9198,7 +9206,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
 		if (mode & IEEE_A) {
 		if (mode & IEEE_A) {
 			IPW_WARNING("Attempt to set 2200BG into "
 			IPW_WARNING("Attempt to set 2200BG into "
 				    "802.11a mode\n");
 				    "802.11a mode\n");
-			up(&priv->sem);
+			mutex_unlock(&priv->mutex);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 
@@ -9235,7 +9243,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
 	IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
 	IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
 		     mode & IEEE_A ? 'a' : '.',
 		     mode & IEEE_A ? 'a' : '.',
 		     mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
 		     mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9244,7 +9252,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
 				    union iwreq_data *wrqu, char *extra)
 				    union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	switch (priv->ieee->mode) {
 	switch (priv->ieee->mode) {
 	case IEEE_A:
 	case IEEE_A:
 		strncpy(extra, "802.11a (1)", MAX_WX_STRING);
 		strncpy(extra, "802.11a (1)", MAX_WX_STRING);
@@ -9275,7 +9283,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
 	IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
 	IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
 
 
 	wrqu->data.length = strlen(extra) + 1;
 	wrqu->data.length = strlen(extra) + 1;
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -9286,7 +9294,7 @@ static int ipw_wx_set_preamble(struct net_device *dev,
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int mode = *(int *)extra;
 	int mode = *(int *)extra;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	/* Switching from SHORT -> LONG requires a disassociation */
 	/* Switching from SHORT -> LONG requires a disassociation */
 	if (mode == 1) {
 	if (mode == 1) {
 		if (!(priv->config & CFG_PREAMBLE_LONG)) {
 		if (!(priv->config & CFG_PREAMBLE_LONG)) {
@@ -9305,11 +9313,11 @@ static int ipw_wx_set_preamble(struct net_device *dev,
 		priv->config &= ~CFG_PREAMBLE_LONG;
 		priv->config &= ~CFG_PREAMBLE_LONG;
 		goto done;
 		goto done;
 	}
 	}
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return -EINVAL;
 	return -EINVAL;
 
 
       done:
       done:
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9318,12 +9326,12 @@ static int ipw_wx_get_preamble(struct net_device *dev,
 			       union iwreq_data *wrqu, char *extra)
 			       union iwreq_data *wrqu, char *extra)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (priv->config & CFG_PREAMBLE_LONG)
 	if (priv->config & CFG_PREAMBLE_LONG)
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
 	else
 	else
 		snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
 		snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9335,7 +9343,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int *parms = (int *)extra;
 	int *parms = (int *)extra;
 	int enable = (parms[0] > 0);
 	int enable = (parms[0] > 0);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
 	IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
 	if (enable) {
 	if (enable) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
@@ -9350,13 +9358,13 @@ static int ipw_wx_set_monitor(struct net_device *dev,
 		ipw_set_channel(priv, parms[1]);
 		ipw_set_channel(priv, parms[1]);
 	} else {
 	} else {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
-			up(&priv->sem);
+			mutex_unlock(&priv->mutex);
 			return 0;
 			return 0;
 		}
 		}
 		priv->net_dev->type = ARPHRD_ETHER;
 		priv->net_dev->type = ARPHRD_ETHER;
 		queue_work(priv->workqueue, &priv->adapter_restart);
 		queue_work(priv->workqueue, &priv->adapter_restart);
 	}
 	}
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9386,7 +9394,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 
 
 	IPW_DEBUG_WX("SW_RESET\n");
 	IPW_DEBUG_WX("SW_RESET\n");
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	ret = ipw_sw_reset(priv, 0);
 	ret = ipw_sw_reset(priv, 0);
 	if (!ret) {
 	if (!ret) {
@@ -9398,9 +9406,9 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 	 * module parameter, so take appropriate action */
 	 * module parameter, so take appropriate action */
 	ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
 	ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
 	ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	if (!(priv->status & STATUS_RF_KILL_MASK)) {
 	if (!(priv->status & STATUS_RF_KILL_MASK)) {
 		/* Configuration likely changed -- force [re]association */
 		/* Configuration likely changed -- force [re]association */
@@ -9410,7 +9418,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 			ipw_associate(priv);
 			ipw_associate(priv);
 	}
 	}
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -9586,7 +9594,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
 static  void init_sys_config(struct ipw_sys_config *sys_config)
 static  void init_sys_config(struct ipw_sys_config *sys_config)
 {
 {
 	memset(sys_config, 0, sizeof(struct ipw_sys_config));
 	memset(sys_config, 0, sizeof(struct ipw_sys_config));
-	sys_config->bt_coexistence = 1;	/* We may need to look into prvStaBtConfig */
+	sys_config->bt_coexistence = 0;
 	sys_config->answer_broadcast_ssid_probe = 0;
 	sys_config->answer_broadcast_ssid_probe = 0;
 	sys_config->accept_all_data_frames = 0;
 	sys_config->accept_all_data_frames = 0;
 	sys_config->accept_non_directed_frames = 1;
 	sys_config->accept_non_directed_frames = 1;
@@ -9607,11 +9615,11 @@ static int ipw_net_open(struct net_device *dev)
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_INFO("dev->open\n");
 	IPW_DEBUG_INFO("dev->open\n");
 	/* we should be verifying the device is ready to be opened */
 	/* we should be verifying the device is ready to be opened */
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	if (!(priv->status & STATUS_RF_KILL_MASK) &&
 	if (!(priv->status & STATUS_RF_KILL_MASK) &&
 	    (priv->status & STATUS_ASSOCIATED))
 	    (priv->status & STATUS_ASSOCIATED))
 		netif_start_queue(dev);
 		netif_start_queue(dev);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9890,13 +9898,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
 	struct sockaddr *addr = p;
 	struct sockaddr *addr = p;
 	if (!is_valid_ether_addr(addr->sa_data))
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 		return -EADDRNOTAVAIL;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	priv->config |= CFG_CUSTOM_MAC;
 	priv->config |= CFG_CUSTOM_MAC;
 	memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
 	memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
 	printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
 	printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
 	       priv->net_dev->name, MAC_ARG(priv->mac_addr));
 	       priv->net_dev->name, MAC_ARG(priv->mac_addr));
 	queue_work(priv->workqueue, &priv->adapter_restart);
 	queue_work(priv->workqueue, &priv->adapter_restart);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9940,9 +9948,9 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
 
 
 	if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
 	if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
 		return -EINVAL;
 		return -EINVAL;
-	down(&p->sem);
+	mutex_lock(&p->mutex);
 	memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
 	memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
-	up(&p->sem);
+	mutex_unlock(&p->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -9954,12 +9962,12 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
 
 
 	if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
 	if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
 		return -EINVAL;
 		return -EINVAL;
-	down(&p->sem);
+	mutex_lock(&p->mutex);
 	memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
 	memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
 	for (i = IPW_EEPROM_DATA;
 	for (i = IPW_EEPROM_DATA;
 	     i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
 	     i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
 		ipw_write8(p, i, p->eeprom[i]);
 		ipw_write8(p, i, p->eeprom[i]);
-	up(&p->sem);
+	mutex_unlock(&p->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -10054,12 +10062,12 @@ static void ipw_rf_kill(void *adapter)
 static void ipw_bg_rf_kill(void *data)
 static void ipw_bg_rf_kill(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_rf_kill(data);
 	ipw_rf_kill(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
-void ipw_link_up(struct ipw_priv *priv)
+static void ipw_link_up(struct ipw_priv *priv)
 {
 {
 	priv->last_seq_num = -1;
 	priv->last_seq_num = -1;
 	priv->last_frag_num = -1;
 	priv->last_frag_num = -1;
@@ -10089,12 +10097,12 @@ void ipw_link_up(struct ipw_priv *priv)
 static void ipw_bg_link_up(void *data)
 static void ipw_bg_link_up(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_link_up(data);
 	ipw_link_up(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
-void ipw_link_down(struct ipw_priv *priv)
+static void ipw_link_down(struct ipw_priv *priv)
 {
 {
 	ipw_led_link_down(priv);
 	ipw_led_link_down(priv);
 	netif_carrier_off(priv->net_dev);
 	netif_carrier_off(priv->net_dev);
@@ -10117,9 +10125,9 @@ void ipw_link_down(struct ipw_priv *priv)
 static void ipw_bg_link_down(void *data)
 static void ipw_bg_link_down(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_link_down(data);
 	ipw_link_down(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static int ipw_setup_deferred_work(struct ipw_priv *priv)
 static int ipw_setup_deferred_work(struct ipw_priv *priv)
@@ -10292,6 +10300,20 @@ static int ipw_config(struct ipw_priv *priv)
 
 
 	/* set basic system config settings */
 	/* set basic system config settings */
 	init_sys_config(&priv->sys_config);
 	init_sys_config(&priv->sys_config);
+
+	/* Support Bluetooth if we have BT h/w on board, and user wants to.
+	 * Does not support BT priority yet (don't abort or defer our Tx) */
+	if (bt_coexist) {
+		unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY];
+
+		if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG)
+			priv->sys_config.bt_coexistence
+			    |= CFG_BT_COEXISTENCE_SIGNAL_CHNL;
+		if (bt_caps & EEPROM_SKU_CAP_BT_OOB)
+			priv->sys_config.bt_coexistence
+			    |= CFG_BT_COEXISTENCE_OOB;
+	}
+
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
 		priv->sys_config.answer_broadcast_ssid_probe = 1;
 		priv->sys_config.answer_broadcast_ssid_probe = 1;
 	else
 	else
@@ -10782,9 +10804,9 @@ static int ipw_up(struct ipw_priv *priv)
 static void ipw_bg_up(void *data)
 static void ipw_bg_up(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_up(data);
 	ipw_up(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 static void ipw_deinit(struct ipw_priv *priv)
 static void ipw_deinit(struct ipw_priv *priv)
@@ -10853,23 +10875,23 @@ static void ipw_down(struct ipw_priv *priv)
 static void ipw_bg_down(void *data)
 static void ipw_bg_down(void *data)
 {
 {
 	struct ipw_priv *priv = data;
 	struct ipw_priv *priv = data;
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 	ipw_down(data);
 	ipw_down(data);
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 }
 }
 
 
 /* Called by register_netdev() */
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 static int ipw_net_init(struct net_device *dev)
 {
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	if (ipw_up(priv)) {
 	if (ipw_up(priv)) {
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -10959,7 +10981,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
 	for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
 		INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
 		INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
 
 
-	init_MUTEX(&priv->sem);
+	mutex_init(&priv->mutex);
 	if (pci_enable_device(pdev)) {
 	if (pci_enable_device(pdev)) {
 		err = -ENODEV;
 		err = -ENODEV;
 		goto out_free_ieee80211;
 		goto out_free_ieee80211;
@@ -11017,7 +11039,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	SET_MODULE_OWNER(net_dev);
 	SET_MODULE_OWNER(net_dev);
 	SET_NETDEV_DEV(net_dev, &pdev->dev);
 	SET_NETDEV_DEV(net_dev, &pdev->dev);
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
 	priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
 	priv->ieee->set_security = shim__set_security;
 	priv->ieee->set_security = shim__set_security;
@@ -11050,11 +11072,11 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
 	err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
 	if (err) {
 	if (err) {
 		IPW_ERROR("failed to create sysfs device attributes\n");
 		IPW_ERROR("failed to create sysfs device attributes\n");
-		up(&priv->sem);
+		mutex_unlock(&priv->mutex);
 		goto out_release_irq;
 		goto out_release_irq;
 	}
 	}
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 	err = register_netdev(net_dev);
 	err = register_netdev(net_dev);
 	if (err) {
 	if (err) {
 		IPW_ERROR("failed to register network device\n");
 		IPW_ERROR("failed to register network device\n");
@@ -11091,13 +11113,13 @@ static void ipw_pci_remove(struct pci_dev *pdev)
 	if (!priv)
 	if (!priv)
 		return;
 		return;
 
 
-	down(&priv->sem);
+	mutex_lock(&priv->mutex);
 
 
 	priv->status |= STATUS_EXIT_PENDING;
 	priv->status |= STATUS_EXIT_PENDING;
 	ipw_down(priv);
 	ipw_down(priv);
 	sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
 	sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
 
 
-	up(&priv->sem);
+	mutex_unlock(&priv->mutex);
 
 
 	unregister_netdev(priv->net_dev);
 	unregister_netdev(priv->net_dev);
 
 
@@ -11281,12 +11303,18 @@ module_param(mode, int, 0444);
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
 #endif
 #endif
 
 
+module_param(bt_coexist, int, 0444);
+MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)");
+
 module_param(hwcrypto, int, 0444);
 module_param(hwcrypto, int, 0444);
-MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
+MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)");
 
 
 module_param(cmdlog, int, 0444);
 module_param(cmdlog, int, 0444);
 MODULE_PARM_DESC(cmdlog,
 MODULE_PARM_DESC(cmdlog,
 		 "allocate a ring buffer for logging firmware commands");
 		 "allocate a ring buffer for logging firmware commands");
 
 
+module_param(roaming, int, 0444);
+MODULE_PARM_DESC(roaming, "enable roaming support (default on)");
+
 module_exit(ipw_exit);
 module_exit(ipw_exit);
 module_init(ipw_init);
 module_init(ipw_init);

+ 36 - 28
drivers/net/wireless/ipw2200.h

@@ -33,6 +33,7 @@
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
 #include <linux/config.h>
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/mutex.h>
 
 
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>
@@ -46,6 +47,7 @@
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <linux/wireless.h>
 #include <linux/wireless.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
+#include <linux/jiffies.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
 #include <net/ieee80211.h>
 #include <net/ieee80211.h>
@@ -852,7 +854,7 @@ struct ipw_scan_request_ext {
 	u16 dwell_time[IPW_SCAN_TYPES];
 	u16 dwell_time[IPW_SCAN_TYPES];
 } __attribute__ ((packed));
 } __attribute__ ((packed));
 
 
-extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index)
+static inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index)
 {
 {
 	if (index % 2)
 	if (index % 2)
 		return scan->scan_type[index / 2] & 0x0F;
 		return scan->scan_type[index / 2] & 0x0F;
@@ -860,7 +862,7 @@ extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index)
 		return (scan->scan_type[index / 2] & 0xF0) >> 4;
 		return (scan->scan_type[index / 2] & 0xF0) >> 4;
 }
 }
 
 
-extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan,
+static inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan,
 				     u8 index, u8 scan_type)
 				     u8 index, u8 scan_type)
 {
 {
 	if (index % 2)
 	if (index % 2)
@@ -1120,7 +1122,7 @@ struct ipw_priv {
 	struct ieee80211_device *ieee;
 	struct ieee80211_device *ieee;
 
 
 	spinlock_t lock;
 	spinlock_t lock;
-	struct semaphore sem;
+	struct mutex mutex;
 
 
 	/* basic pci-network driver stuff */
 	/* basic pci-network driver stuff */
 	struct pci_dev *pci_dev;
 	struct pci_dev *pci_dev;
@@ -1406,13 +1408,6 @@ do { if (ipw_debug_level & (level)) \
 * Register bit definitions
 * Register bit definitions
 */
 */
 
 
-/* Dino control registers bits */
-
-#define DINO_ENABLE_SYSTEM 0x80
-#define DINO_ENABLE_CS     0x40
-#define DINO_RXFIFO_DATA   0x01
-#define DINO_CONTROL_REG   0x00200000
-
 #define IPW_INTA_RW       0x00000008
 #define IPW_INTA_RW       0x00000008
 #define IPW_INTA_MASK_R   0x0000000C
 #define IPW_INTA_MASK_R   0x0000000C
 #define IPW_INDIRECT_ADDR 0x00000010
 #define IPW_INDIRECT_ADDR 0x00000010
@@ -1459,6 +1454,11 @@ do { if (ipw_debug_level & (level)) \
 #define IPW_DOMAIN_0_END 0x1000
 #define IPW_DOMAIN_0_END 0x1000
 #define CLX_MEM_BAR_SIZE 0x1000
 #define CLX_MEM_BAR_SIZE 0x1000
 
 
+/* Dino/baseband control registers bits */
+
+#define DINO_ENABLE_SYSTEM 0x80	/* 1 = baseband processor on, 0 = reset */
+#define DINO_ENABLE_CS     0x40	/* 1 = enable ucode load */
+#define DINO_RXFIFO_DATA   0x01	/* 1 = data available */
 #define IPW_BASEBAND_CONTROL_STATUS	0X00200000
 #define IPW_BASEBAND_CONTROL_STATUS	0X00200000
 #define IPW_BASEBAND_TX_FIFO_WRITE	0X00200004
 #define IPW_BASEBAND_TX_FIFO_WRITE	0X00200004
 #define IPW_BASEBAND_RX_FIFO_READ	0X00200004
 #define IPW_BASEBAND_RX_FIFO_READ	0X00200004
@@ -1567,13 +1567,18 @@ do { if (ipw_debug_level & (level)) \
 #define EEPROM_BSS_CHANNELS_BG  (GET_EEPROM_ADDR(0x2c,LSB))	/* 2 bytes  */
 #define EEPROM_BSS_CHANNELS_BG  (GET_EEPROM_ADDR(0x2c,LSB))	/* 2 bytes  */
 #define EEPROM_HW_VERSION       (GET_EEPROM_ADDR(0x72,LSB))	/* 2 bytes  */
 #define EEPROM_HW_VERSION       (GET_EEPROM_ADDR(0x72,LSB))	/* 2 bytes  */
 
 
-/* NIC type as found in the one byte EEPROM_NIC_TYPE  offset*/
+/* NIC type as found in the one byte EEPROM_NIC_TYPE offset */
 #define EEPROM_NIC_TYPE_0 0
 #define EEPROM_NIC_TYPE_0 0
 #define EEPROM_NIC_TYPE_1 1
 #define EEPROM_NIC_TYPE_1 1
 #define EEPROM_NIC_TYPE_2 2
 #define EEPROM_NIC_TYPE_2 2
 #define EEPROM_NIC_TYPE_3 3
 #define EEPROM_NIC_TYPE_3 3
 #define EEPROM_NIC_TYPE_4 4
 #define EEPROM_NIC_TYPE_4 4
 
 
+/* Bluetooth Coexistence capabilities as found in EEPROM_SKU_CAPABILITY */
+#define EEPROM_SKU_CAP_BT_CHANNEL_SIG  0x01	/* we can tell BT our channel # */
+#define EEPROM_SKU_CAP_BT_PRIORITY     0x02	/* BT can take priority over us */
+#define EEPROM_SKU_CAP_BT_OOB          0x04	/* we can signal BT out-of-band */
+
 #define FW_MEM_REG_LOWER_BOUND          0x00300000
 #define FW_MEM_REG_LOWER_BOUND          0x00300000
 #define FW_MEM_REG_EEPROM_ACCESS        (FW_MEM_REG_LOWER_BOUND + 0x40)
 #define FW_MEM_REG_EEPROM_ACCESS        (FW_MEM_REG_LOWER_BOUND + 0x40)
 #define IPW_EVENT_REG                   (FW_MEM_REG_LOWER_BOUND + 0x04)
 #define IPW_EVENT_REG                   (FW_MEM_REG_LOWER_BOUND + 0x04)
@@ -1658,9 +1663,10 @@ enum {
 	IPW_FW_ERROR_FATAL_ERROR
 	IPW_FW_ERROR_FATAL_ERROR
 };
 };
 
 
-#define AUTH_OPEN       0
-#define AUTH_SHARED_KEY 1
-#define AUTH_IGNORE     3
+#define AUTH_OPEN	0
+#define AUTH_SHARED_KEY	1
+#define AUTH_LEAP	2
+#define AUTH_IGNORE	3
 
 
 #define HC_ASSOCIATE      0
 #define HC_ASSOCIATE      0
 #define HC_REASSOCIATE    1
 #define HC_REASSOCIATE    1
@@ -1860,7 +1866,7 @@ struct host_cmd {
 	u8 cmd;
 	u8 cmd;
 	u8 len;
 	u8 len;
 	u16 reserved;
 	u16 reserved;
-	u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
+	u32 *param;
 } __attribute__ ((packed));
 } __attribute__ ((packed));
 
 
 struct ipw_cmd_log {
 struct ipw_cmd_log {
@@ -1869,21 +1875,23 @@ struct ipw_cmd_log {
 	struct host_cmd cmd;
 	struct host_cmd cmd;
 };
 };
 
 
-#define CFG_BT_COEXISTENCE_MIN                  0x00
-#define CFG_BT_COEXISTENCE_DEFER                0x02
-#define CFG_BT_COEXISTENCE_KILL                 0x04
-#define CFG_BT_COEXISTENCE_WME_OVER_BT          0x08
-#define CFG_BT_COEXISTENCE_OOB                  0x10
-#define CFG_BT_COEXISTENCE_MAX                  0xFF
-#define CFG_BT_COEXISTENCE_DEF                  0x80	/* read Bt from EEPROM */
-
-#define CFG_CTS_TO_ITSELF_ENABLED_MIN	0x0
-#define CFG_CTS_TO_ITSELF_ENABLED_MAX	0x1
+/* SysConfig command parameters ... */
+/* bt_coexistence param */
+#define CFG_BT_COEXISTENCE_SIGNAL_CHNL  0x01	/* tell BT our chnl # */
+#define CFG_BT_COEXISTENCE_DEFER        0x02	/* defer our Tx if BT traffic */
+#define CFG_BT_COEXISTENCE_KILL         0x04	/* kill our Tx if BT traffic */
+#define CFG_BT_COEXISTENCE_WME_OVER_BT  0x08	/* multimedia extensions */
+#define CFG_BT_COEXISTENCE_OOB          0x10	/* signal BT via out-of-band */
+
+/* clear-to-send to self param */
+#define CFG_CTS_TO_ITSELF_ENABLED_MIN	0x00
+#define CFG_CTS_TO_ITSELF_ENABLED_MAX	0x01
 #define CFG_CTS_TO_ITSELF_ENABLED_DEF	CFG_CTS_TO_ITSELF_ENABLED_MIN
 #define CFG_CTS_TO_ITSELF_ENABLED_DEF	CFG_CTS_TO_ITSELF_ENABLED_MIN
 
 
-#define CFG_SYS_ANTENNA_BOTH                      0x000
-#define CFG_SYS_ANTENNA_A                         0x001
-#define CFG_SYS_ANTENNA_B                         0x003
+/* Antenna diversity param (h/w can select best antenna, based on signal) */
+#define CFG_SYS_ANTENNA_BOTH            0x00	/* NIC selects best antenna */
+#define CFG_SYS_ANTENNA_A               0x01	/* force antenna A */
+#define CFG_SYS_ANTENNA_B               0x03	/* force antenna B */
 
 
 /*
 /*
  * The definitions below were lifted off the ipw2100 driver, which only
  * The definitions below were lifted off the ipw2100 driver, which only

+ 0 - 2
drivers/net/wireless/netwave_cs.c

@@ -55,10 +55,8 @@
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
-#ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <net/iw_handler.h>
-#endif
 
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cs.h>

+ 1 - 5
drivers/net/wireless/wavelan.p.h

@@ -98,11 +98,7 @@
  * characteristics of the hardware.  Applications such as mobile IP may
  * characteristics of the hardware.  Applications such as mobile IP may
  * take advantage of it.
  * take advantage of it.
  *
  *
- * You will need to enable the CONFIG_NET_RADIO define in the kernel
- * configuration to enable the wireless extensions (this is the one
- * giving access to the radio network device choice).
- *
- * It might also be a good idea as well to fetch the wireless tools to
+ * It might be a good idea as well to fetch the wireless tools to
  * configure the device and play a bit.
  * configure the device and play a bit.
  */
  */
 
 

+ 1 - 8
drivers/net/wireless/wavelan_cs.p.h

@@ -99,11 +99,7 @@
  * caracteristics of the hardware in a standard way and support for
  * caracteristics of the hardware in a standard way and support for
  * applications for taking advantage of it (like Mobile IP).
  * applications for taking advantage of it (like Mobile IP).
  *
  *
- * You will need to enable the CONFIG_NET_RADIO define in the kernel
- * configuration to enable the wireless extensions (this is the one
- * giving access to the radio network device choice).
- *
- * It might also be a good idea as well to fetch the wireless tools to
+ * It might be a good idea as well to fetch the wireless tools to
  * configure the device and play a bit.
  * configure the device and play a bit.
  */
  */
 
 
@@ -440,11 +436,8 @@
 #include <linux/ioport.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/fcntl.h>
 #include <linux/ethtool.h>
 #include <linux/ethtool.h>
-
-#ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Wireless extensions */
 #include <linux/wireless.h>		/* Wireless extensions */
 #include <net/iw_handler.h>		/* New driver API */
 #include <net/iw_handler.h>		/* New driver API */
-#endif
 
 
 /* Pcmcia headers that we need */
 /* Pcmcia headers that we need */
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs_types.h>

+ 8 - 0
include/net/ieee80211.h

@@ -1285,6 +1285,14 @@ extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
 extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
 				      struct iw_request_info *info,
 				      struct iw_request_info *info,
 				      union iwreq_data *wrqu, char *extra);
 				      union iwreq_data *wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu,
+				 char *extra);
+extern int ieee80211_wx_get_auth(struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu,
+				 char *extra);
 
 
 static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
 static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
 {
 {

+ 3 - 0
net/Kconfig

@@ -217,6 +217,9 @@ source "net/irda/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/ieee80211/Kconfig"
 source "net/ieee80211/Kconfig"
 
 
+config WIRELESS_EXT
+	bool
+
 endif   # if NET
 endif   # if NET
 endmenu # Networking
 endmenu # Networking
 
 

+ 1 - 1
net/core/Makefile

@@ -14,5 +14,5 @@ obj-$(CONFIG_XFRM) += flow.o
 obj-$(CONFIG_SYSFS) += net-sysfs.o
 obj-$(CONFIG_SYSFS) += net-sysfs.o
 obj-$(CONFIG_NET_DIVERT) += dv.o
 obj-$(CONFIG_NET_DIVERT) += dv.o
 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
-obj-$(CONFIG_NET_RADIO) += wireless.o
+obj-$(CONFIG_WIRELESS_EXT) += wireless.o
 obj-$(CONFIG_NETPOLL) += netpoll.o
 obj-$(CONFIG_NETPOLL) += netpoll.o

+ 4 - 6
net/core/dev.c

@@ -110,10 +110,8 @@
 #include <linux/netpoll.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
 #include <linux/rcupdate.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
-#ifdef CONFIG_NET_RADIO
-#include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
+#include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <net/iw_handler.h>
-#endif	/* CONFIG_NET_RADIO */
 #include <asm/current.h>
 #include <asm/current.h>
 
 
 /*
 /*
@@ -2028,7 +2026,7 @@ static struct file_operations softnet_seq_fops = {
 	.release = seq_release,
 	.release = seq_release,
 };
 };
 
 
-#ifdef WIRELESS_EXT
+#ifdef CONFIG_WIRELESS_EXT
 extern int wireless_proc_init(void);
 extern int wireless_proc_init(void);
 #else
 #else
 #define wireless_proc_init() 0
 #define wireless_proc_init() 0
@@ -2581,7 +2579,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
 					ret = -EFAULT;
 					ret = -EFAULT;
 				return ret;
 				return ret;
 			}
 			}
-#ifdef WIRELESS_EXT
+#ifdef CONFIG_WIRELESS_EXT
 			/* Take care of Wireless Extensions */
 			/* Take care of Wireless Extensions */
 			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
 			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
 				/* If command is `set a parameter', or
 				/* If command is `set a parameter', or
@@ -2602,7 +2600,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
 					ret = -EFAULT;
 					ret = -EFAULT;
 				return ret;
 				return ret;
 			}
 			}
-#endif	/* WIRELESS_EXT */
+#endif	/* CONFIG_WIRELESS_EXT */
 			return -EINVAL;
 			return -EINVAL;
 	}
 	}
 }
 }

+ 27 - 3
net/ieee80211/ieee80211_rx.c

@@ -369,8 +369,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 
 	/* Put this code here so that we avoid duplicating it in all
 	/* Put this code here so that we avoid duplicating it in all
 	 * Rx paths. - Jean II */
 	 * Rx paths. - Jean II */
+#ifdef CONFIG_WIRELESS_EXT
 #ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
 #ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
-#ifdef CONFIG_NET_RADIO
 	/* If spy monitoring on */
 	/* If spy monitoring on */
 	if (ieee->spy_data.spy_number > 0) {
 	if (ieee->spy_data.spy_number > 0) {
 		struct iw_quality wstats;
 		struct iw_quality wstats;
@@ -397,8 +397,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		/* Update spy records */
 		/* Update spy records */
 		wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
 		wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
 	}
 	}
-#endif				/* CONFIG_NET_RADIO */
 #endif				/* IW_WIRELESS_SPY */
 #endif				/* IW_WIRELESS_SPY */
+#endif				/* CONFIG_WIRELESS_EXT */
 
 
 #ifdef NOT_YET
 #ifdef NOT_YET
 	hostap_update_rx_stats(local->ap, hdr, rx_stats);
 	hostap_update_rx_stats(local->ap, hdr, rx_stats);
@@ -574,7 +574,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	/* skb: hdr + (possibly fragmented) plaintext payload */
 	/* skb: hdr + (possibly fragmented) plaintext payload */
 	// PR: FIXME: hostap has additional conditions in the "if" below:
 	// PR: FIXME: hostap has additional conditions in the "if" below:
 	// ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
 	// ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
-	if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
+	if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
 		int flen;
 		int flen;
 		struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
 		struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
 		IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
 		IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
@@ -1607,6 +1607,30 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
 					    header, stats);
 					    header, stats);
 		break;
 		break;
 
 
+	case IEEE80211_STYPE_REASSOC_REQ:
+		IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",
+				     WLAN_FC_GET_STYPE(le16_to_cpu
+						       (header->frame_ctl)));
+
+		IEEE80211_WARNING("%s: IEEE80211_REASSOC_REQ received\n",
+				  ieee->dev->name);
+		if (ieee->handle_reassoc_request != NULL)
+			ieee->handle_reassoc_request(ieee->dev,
+						    (struct ieee80211_reassoc_request *)
+						     header);
+		break;
+
+	case IEEE80211_STYPE_ASSOC_REQ:
+		IEEE80211_DEBUG_MGMT("received assoc (%d)\n",
+				     WLAN_FC_GET_STYPE(le16_to_cpu
+						       (header->frame_ctl)));
+
+		IEEE80211_WARNING("%s: IEEE80211_ASSOC_REQ received\n",
+				  ieee->dev->name);
+		if (ieee->handle_assoc_request != NULL)
+			ieee->handle_assoc_request(ieee->dev);
+		break;
+
 	case IEEE80211_STYPE_DEAUTH:
 	case IEEE80211_STYPE_DEAUTH:
 		IEEE80211_DEBUG_MGMT("DEAUTH\n");
 		IEEE80211_DEBUG_MGMT("DEAUTH\n");
 		if (ieee->handle_deauth != NULL)
 		if (ieee->handle_deauth != NULL)

+ 89 - 0
net/ieee80211/ieee80211_wx.c

@@ -761,9 +761,98 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
 	return 0;
 	return 0;
 }
 }
 
 
+int ieee80211_wx_set_auth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu,
+			  char *extra)
+{
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+	
+	switch (wrqu->param.flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_KEY_MGMT:
+		/*
+		 * Host AP driver does not use these parameters and allows
+		 * wpa_supplicant to control them internally.
+		 */
+		break;
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		break;		/* FIXME */
+	case IW_AUTH_DROP_UNENCRYPTED:
+		ieee->drop_unencrypted = !!wrqu->param.value;
+		break;
+	case IW_AUTH_80211_AUTH_ALG:
+		break;		/* FIXME */
+	case IW_AUTH_WPA_ENABLED:
+		ieee->privacy_invoked = ieee->wpa_enabled = !!wrqu->param.value;
+		break;
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		ieee->ieee802_1x = !!wrqu->param.value;
+		break;
+	case IW_AUTH_PRIVACY_INVOKED:
+		ieee->privacy_invoked = !!wrqu->param.value;
+		break;
+	default:
+		err = -EOPNOTSUPP;
+		break;
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	return err;
+}
+
+int ieee80211_wx_get_auth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu,
+			  char *extra)
+{
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	unsigned long flags;
+	int err = 0;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+	
+	switch (wrqu->param.flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_KEY_MGMT:
+	case IW_AUTH_TKIP_COUNTERMEASURES:		/* FIXME */
+	case IW_AUTH_80211_AUTH_ALG:			/* FIXME */
+		/*
+		 * Host AP driver does not use these parameters and allows
+		 * wpa_supplicant to control them internally.
+		 */
+		err = -EOPNOTSUPP;
+		break;
+	case IW_AUTH_DROP_UNENCRYPTED:
+		wrqu->param.value = ieee->drop_unencrypted;
+		break;
+	case IW_AUTH_WPA_ENABLED:
+		wrqu->param.value = ieee->wpa_enabled;
+		break;
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		wrqu->param.value = ieee->ieee802_1x;
+		break;
+	default:
+		err = -EOPNOTSUPP;
+		break;
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	return err;
+}
+
 EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
 EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
 EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
 EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
 
 
 EXPORT_SYMBOL(ieee80211_wx_get_scan);
 EXPORT_SYMBOL(ieee80211_wx_get_scan);
 EXPORT_SYMBOL(ieee80211_wx_set_encode);
 EXPORT_SYMBOL(ieee80211_wx_set_encode);
 EXPORT_SYMBOL(ieee80211_wx_get_encode);
 EXPORT_SYMBOL(ieee80211_wx_get_encode);
+
+EXPORT_SYMBOL_GPL(ieee80211_wx_set_auth);
+EXPORT_SYMBOL_GPL(ieee80211_wx_get_auth);

+ 3 - 6
net/socket.c

@@ -84,10 +84,7 @@
 #include <linux/compat.h>
 #include <linux/compat.h>
 #include <linux/kmod.h>
 #include <linux/kmod.h>
 #include <linux/audit.h>
 #include <linux/audit.h>
-
-#ifdef CONFIG_NET_RADIO
-#include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
-#endif	/* CONFIG_NET_RADIO */
+#include <linux/wireless.h>
 
 
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/unistd.h>
@@ -840,11 +837,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
 	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
 		err = dev_ioctl(cmd, argp);
 		err = dev_ioctl(cmd, argp);
 	} else
 	} else
-#ifdef WIRELESS_EXT
+#ifdef CONFIG_WIRELESS_EXT
 	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
 	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
 		err = dev_ioctl(cmd, argp);
 		err = dev_ioctl(cmd, argp);
 	} else
 	} else
-#endif	/* WIRELESS_EXT */
+#endif	/* CONFIG_WIRELESS_EXT */
 	switch (cmd) {
 	switch (cmd) {
 		case FIOSETOWN:
 		case FIOSETOWN:
 		case SIOCSPGRP:
 		case SIOCSPGRP: