diff -Naur r8187_orig/ieee80211/ieee80211_crypt.c r8187_rawtx/ieee80211/ieee80211_crypt.c
--- r8187_orig/ieee80211/ieee80211_crypt.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_crypt.c	2007-05-16 22:00:07.000000000 +0200
@@ -11,7 +11,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -19,6 +18,12 @@
 #include <asm/string.h>
 #include <asm/errno.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
 MODULE_AUTHOR("Jouni Malinen");
diff -Naur r8187_orig/ieee80211/ieee80211_crypt_ccmp.c r8187_rawtx/ieee80211/ieee80211_crypt_ccmp.c
--- r8187_orig/ieee80211/ieee80211_crypt_ccmp.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_crypt_ccmp.c	2007-05-16 22:00:07.000000000 +0200
@@ -9,7 +9,6 @@
  * more details.
  */
 
-#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -22,11 +21,22 @@
 #include <asm/string.h>
 #include <linux/wireless.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 
+    #include <asm/scatterlist.h>
+#else
+    #include <linux/scatterlist.h>
+#endif
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: CCMP");
diff -Naur r8187_orig/ieee80211/ieee80211_crypt_tkip.c r8187_rawtx/ieee80211/ieee80211_crypt_tkip.c
--- r8187_orig/ieee80211/ieee80211_crypt_tkip.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_crypt_tkip.c	2007-05-16 22:00:07.000000000 +0200
@@ -9,7 +9,6 @@
  * more details.
  */
 
-#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -21,11 +20,21 @@
 #include <linux/if_arp.h>
 #include <asm/string.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 
+    #include <asm/scatterlist.h>
+#else
+    #include <linux/scatterlist.h>
+#endif
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
@@ -431,7 +440,11 @@
 static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
 		       u8 *data, size_t data_len, u8 *mic)
 {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+	struct hash_desc desc;
+#endif
 	struct scatterlist sg[2];
+	int ret = 0;
 
 	if (tkey->tfm_michael == NULL) {
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
@@ -445,12 +458,20 @@
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 
 	crypto_digest_init(tkey->tfm_michael);
 	crypto_digest_setkey(tkey->tfm_michael, key, 8);
 	crypto_digest_update(tkey->tfm_michael, sg, 2);
 	crypto_digest_final(tkey->tfm_michael, mic);
+#else
+	if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
+		return -1;
+	desc.tfm = tkey->tfm_michael;
+	desc.flags = 0;
+	ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
+#endif
 
-	return 0;
+	return ret;
 }
 
 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
diff -Naur r8187_orig/ieee80211/ieee80211_crypt_wep.c r8187_rawtx/ieee80211/ieee80211_crypt_wep.c
--- r8187_orig/ieee80211/ieee80211_crypt_wep.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_crypt_wep.c	2007-05-16 22:00:07.000000000 +0200
@@ -9,7 +9,6 @@
  * more details.
  */
 
-#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -18,11 +17,21 @@
 #include <linux/skbuff.h>
 #include <asm/string.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 
+    #include <asm/scatterlist.h>
+#else
+    #include <linux/scatterlist.h>
+#endif
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
diff -Naur r8187_orig/ieee80211/ieee80211.h r8187_rawtx/ieee80211/ieee80211.h
--- r8187_orig/ieee80211/ieee80211.h	2007-12-05 09:27:45.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211.h	2007-05-16 22:00:11.000000000 +0200
@@ -108,6 +108,8 @@
 #define	ieee80211_start_protocol	ieee80211_start_protocol_rtl
 #define	ieee80211_stop_protocol		ieee80211_stop_protocol_rtl
 #define	ieee80211_rx_mgt		ieee80211_rx_mgt_rtl
+#define	ieee80211_stop_queue		ieee80211_stop_queue_rtl
+#define	ieee80211_wake_queue		ieee80211_wake_queue_rtl
 
 
 typedef struct ieee_param {
@@ -193,6 +195,22 @@
 	struct list_head list;
 };
 
+#define LWNG_CAP_DID_BASE   (4 | (1 << 6)) /* section 4, group 1 */
+/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
+ * (from linux-wlan-ng) */
+struct linux_wlan_ng_val {
+	u32 did;
+	u16 status, len;
+	u32 data;
+} __attribute__ ((packed));
+
+struct linux_wlan_ng_prism_hdr {
+	u32 msgcode, msglen;
+	char devname[16];
+	struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
+		noise, rate, istx, frmlen;
+} __attribute__ ((packed));
+
 struct ieee80211_hdr {
 	u16 frame_ctl;
 	u16 duration_id;
@@ -1064,10 +1082,15 @@
 	struct timer_list beacon_timer;
 	
 	struct work_struct associate_complete_wq;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+	struct delayed_work associate_retry_wq;
+	struct delayed_work softmac_scan_wq;
+#else
 	struct work_struct associate_retry_wq;
+	struct work_struct softmac_scan_wq;
+#endif
 	struct work_struct start_ibss_wq;
 	struct work_struct associate_procedure_wq;
-	struct work_struct softmac_scan_wq;
 	struct work_struct wx_sync_scan_wq;
 	struct work_struct ps_request_tx_ack_wq;//for ps
 	struct work_struct hw_wakeup_wq;
@@ -1390,7 +1413,11 @@
 extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b);
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
+#else
 extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
+#endif
 
 extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, 
 			       struct iw_request_info *info, 
diff -Naur r8187_orig/ieee80211/ieee80211_module.c r8187_rawtx/ieee80211/ieee80211_module.c
--- r8187_orig/ieee80211/ieee80211_module.c	2007-12-03 10:07:33.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_module.c	2007-05-16 22:00:07.000000000 +0200
@@ -31,7 +31,6 @@
 *******************************************************************************/
 
 #include <linux/compiler.h>
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -52,6 +51,12 @@
 #include <asm/uaccess.h>
 #include <net/arp.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
 MODULE_DESCRIPTION("802.11 data/management/control stack");
diff -Naur r8187_orig/ieee80211/ieee80211_rx.c r8187_rawtx/ieee80211/ieee80211_rx.c
--- r8187_orig/ieee80211/ieee80211_rx.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_rx.c	2007-05-16 22:00:07.000000000 +0200
@@ -22,7 +22,6 @@
  
 
 #include <linux/compiler.h>
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -43,18 +42,85 @@
 #include <asm/uaccess.h>
 #include <linux/ctype.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
 static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
 					struct sk_buff *skb,
 					struct ieee80211_rx_stats *rx_stats)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
+	struct ieee80211_hdr *hdr1 = (struct ieee80211_hdr *)skb->data;
+	u16 fc = le16_to_cpu(hdr1->frame_ctl);
+//begin prism header code
+	int prism_header;
+	int hdrlen, phdrlen, head_need, tail_need;
+
+	if (ieee->dev->type == ARPHRD_IEEE80211_PRISM) {
+		prism_header = 1;
+		phdrlen = sizeof(struct linux_wlan_ng_prism_hdr);
+	} else {
+		prism_header = 0;
+		phdrlen = 0;
+	}
 
+	hdrlen = ieee80211_get_hdrlen(fc);
+
+	/* check if there is enough room for extra data; if not, expand skb
+	 * buffer to be large enough for the changes */
+	head_need = phdrlen;
+	tail_need = 0;
+#ifdef PRISM2_ADD_BOGUS_CRC
+	tail_need += 4;
+#endif /* PRISM2_ADD_BOGUS_CRC */
+
+	head_need -= skb_headroom(skb);
+	tail_need -= skb_tailroom(skb);
+
+	if (head_need > 0 || tail_need > 0) {
+		if (pskb_expand_head(skb, head_need > 0 ? head_need : 0,
+				     tail_need > 0 ? tail_need : 0,
+				     GFP_ATOMIC)) {
+			printk(KERN_DEBUG "%s: ieee80211_rx failed to "
+			       "reallocate skb buffer\n", ieee->dev->name);
+			dev_kfree_skb_any(skb);
+			return;
+		}
+	}
+
+	if (prism_header == 1) {
+		struct linux_wlan_ng_prism_hdr *hdr;
+		hdr = (struct linux_wlan_ng_prism_hdr *)
+			skb_push(skb, phdrlen);
+		memset(hdr, 0, phdrlen);
+		hdr->msgcode = LWNG_CAP_DID_BASE;
+		hdr->msglen = sizeof(*hdr);
+		memcpy(hdr->devname, ieee->dev->name, sizeof(hdr->devname));
+#define LWNG_SETVAL(f,i,s,l,d) \
+hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
+hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
+		LWNG_SETVAL(hosttime, 1, 0, 4, jiffies);
+		LWNG_SETVAL(mactime, 2, 0, 4, ((u32)rx_stats->mac_time));
+		LWNG_SETVAL(channel, 3, 1 /* no value */, 4, 0);
+		LWNG_SETVAL(rssi, 4, 1 /* no value */, 4, 0);
+		LWNG_SETVAL(sq, 5, 1 /* no value */, 4, 0);
+		LWNG_SETVAL(signal, 6, 0, 4, rx_stats->signal);
+		LWNG_SETVAL(noise, 7, 0, 4, rx_stats->noise);
+		LWNG_SETVAL(rate, 8, 0, 4, rx_stats->rate / 5);
+		LWNG_SETVAL(istx, 9, 0, 4, 0);
+		LWNG_SETVAL(frmlen, 10, 0, 4, skb->len - phdrlen);
+#undef LWNG_SETVAL
+	}
+//end prism header code
 	skb->dev = ieee->dev;
 	skb->mac.raw = skb->data;
-	skb_pull(skb, ieee80211_get_hdrlen(fc));
+	skb_pull(skb, hdrlen);
+	if (prism_header)
+		skb_pull(skb, phdrlen);
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = __constant_htons(ETH_P_80211_RAW);
 	memset(skb->cb, 0, sizeof(skb->cb));
diff -Naur r8187_orig/ieee80211/ieee80211_softmac.c r8187_rawtx/ieee80211/ieee80211_softmac.c
--- r8187_orig/ieee80211/ieee80211_softmac.c	2007-12-05 09:26:56.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_softmac.c	2007-05-16 22:00:07.000000000 +0200
@@ -1,14 +1,14 @@
 /* IEEE 802.11 SoftMAC layer
  * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
  *
- * Mostly extracted from the rtl8180-sa2400 driver for the 
+ * Mostly extracted from the rtl8180-sa2400 driver for the
  * in-kernel generic ieee802.11 stack.
  *
  * Few lines might be stolen from other part of the ieee80211
  * stack. Copyright who own it's copyright
  *
  * WPA code stolen from the ipw2200 driver.
- * Copyright who own it's copyright. 
+ * Copyright who own it's copyright.
  *
  * released under the GPL
  */
@@ -37,25 +37,25 @@
 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
 {
 	unsigned int rate_len = 0;
-	
+
 	if (ieee->modulation & IEEE80211_CCK_MODULATION)
 		rate_len = IEEE80211_CCK_RATE_LEN + 2;
-		
+
 	if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-		
+
 		rate_len += IEEE80211_OFDM_RATE_LEN + 2;
-	
+
 	return rate_len;
 }
 
-/* pleace the MFIE rate, tag to the memory (double) poined. 
+/* pleace the MFIE rate, tag to the memory (double) poined.
  * Then it updates the pointer so that
  * it points after the new MFIE tag added.
- */  
+ */
 void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
 {
-	u8 *tag = *tag_p; 
-	
+	u8 *tag = *tag_p;
+
 	if (ieee->modulation & IEEE80211_CCK_MODULATION){
 		*tag++ = MFIE_TYPE_RATES;
 		*tag++ = 4;
@@ -64,17 +64,17 @@
 		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
 		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
 	}
-	
+
 	/* We may add an option for custom rates that specific HW might support */
 	*tag_p = tag;
 }
 
 void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
-{	
-	u8 *tag = *tag_p; 
-	
+{
+	u8 *tag = *tag_p;
+
 		if (ieee->modulation & IEEE80211_OFDM_MODULATION){
-		
+
 		*tag++ = MFIE_TYPE_RATES_EX;
 		*tag++ = 8;
 		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
@@ -85,9 +85,9 @@
 		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
 		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
 		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-		
+
 	}
-	
+
 	/* We may add an option for custom rates that specific HW might support */
 	*tag_p = tag;
 }
@@ -96,11 +96,11 @@
 {
 	int nh;
 	nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
-			
+
 /*
  * if the queue is full but we have newer frames then
  * just overwrites the oldest.
- *	
+ *
  * if (nh == ieee->mgmt_queue_tail)
  *		return -1;
  */	//david, 2007.1.23
@@ -110,22 +110,22 @@
 		ieee->mgmt_queue_head = nh;
 		ieee->mgmt_queue_ring[nh] = skb;
 	}
-	
+
 	//return 0;
 }
 
 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
 {
 	struct sk_buff *ret;
-	
+
 	if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
 		return NULL;
-		
+
 	ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
-	
-	ieee->mgmt_queue_tail = 
+
+	ieee->mgmt_queue_tail =
 		(ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
-	
+
 	return ret;
 }
 
@@ -143,19 +143,19 @@
 	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
 	struct ieee80211_hdr_3addr  *header=
 		(struct ieee80211_hdr_3addr  *) skb->data;
-	
-	
+
+
 	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	/* called with 2nd param 0, no mgmt lock required */
 	ieee80211_sta_wakeup(ieee,0);
-		
+
 	if(single){
-		
+
 		if(ieee->queue_stop){
-			
+
 			enqueue_mgmt(ieee,skb);
-		
+
 		}else{
 			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl << 4);
 
@@ -163,28 +163,28 @@
 				ieee->seq_ctrl = 0;
 			else
 				ieee->seq_ctrl++;
-			
+
 			/* avoid watchdog triggers */
 			ieee->dev->trans_start = jiffies;
 			ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
 			//added by david, 2007.1.23
 			dev_kfree_skb_any(skb);
 		}
-		
+
 		spin_unlock_irqrestore(&ieee->lock, flags);
 	}else{
 		spin_unlock_irqrestore(&ieee->lock, flags);
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
-	
+
 		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl << 4);
-	
+
 		if (ieee->seq_ctrl == 0xFFF)
 			ieee->seq_ctrl = 0;
 		else
 			ieee->seq_ctrl++;
-		
+
 		ieee->softmac_hard_start_xmit(skb,ieee->dev);
-		
+
 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
 	}
 }
@@ -192,36 +192,36 @@
 
 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
 {
-	
+
 	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
 	struct ieee80211_hdr_3addr  *header =
 		(struct ieee80211_hdr_3addr  *) skb->data;
-	
-	
+
+
 	if(single){
-		
+
 		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl << 4);
 
 		if (ieee->seq_ctrl == 0xFFF)
 			ieee->seq_ctrl = 0;
 		else
 			ieee->seq_ctrl++;
-			
+
 		/* avoid watchdog triggers */
 		ieee->dev->trans_start = jiffies;
 		ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
-	
+
 	}else{
-		
+
 		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl << 4);
-	
+
 		if (ieee->seq_ctrl == 0xFFF)
 			ieee->seq_ctrl = 0;
 		else
 			ieee->seq_ctrl++;
 
 		ieee->softmac_hard_start_xmit(skb,ieee->dev);
-		
+
 	}
 }
 
@@ -231,35 +231,35 @@
 	u8 *tag;
 	struct sk_buff *skb;
 	struct ieee80211_probe_request *req;
-	
+
 	len = ieee->current_network.ssid_len;
-	
+
 	rate_len = ieee80211_MFIE_rate_len(ieee);
-	
+
 	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
 			    2 + len + rate_len);
-	
-	if (!skb) 
+
+	if (!skb)
 		return NULL;
-	
+
 	req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
-	if (ieee->ps == IEEE80211_PS_DISABLED) 
+	if (ieee->ps == IEEE80211_PS_DISABLED)
 		req->header.frame_ctl = IEEE80211_STYPE_PROBE_REQ;//changed!!
-	else 
+	else
 		req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ|IEEE80211_FCTL_PM);//tony ,for ps ctl bit
-	req->header.duration_id = 0; //FIXME: is this OK ? 
-	
+	req->header.duration_id = 0; //FIXME: is this OK ?
+
 	memset(req->header.addr1, 0xff, ETH_ALEN);
 	memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memset(req->header.addr3, 0xff, ETH_ALEN);
-	
+
 	tag = (u8 *) skb_put(skb,len+2+rate_len);
-	
+
 	*tag++ = MFIE_TYPE_SSID;
 	*tag++ = len;
 	memcpy(tag, ieee->current_network.ssid, len);
 	tag += len;
-	
+
 	ieee80211_MFIE_Brate(ieee,&tag);
 	ieee80211_MFIE_Grate(ieee,&tag);
 	return skb;
@@ -269,18 +269,18 @@
 void ieee80211_send_beacon(struct ieee80211_device *ieee)
 {
 	struct sk_buff *skb;
-	
-	unsigned long flags;	
-	
+
+	unsigned long flags;
+
 	skb = ieee80211_get_beacon_(ieee);
 	if (skb){
 		softmac_mgmt_xmit(skb, ieee);
 		ieee->softmac_stats.tx_beacons++;
 	}
 
-	ieee->beacon_timer.expires = jiffies + 
+	ieee->beacon_timer.expires = jiffies +
 		(MSECS( ieee->current_network.beacon_interval -5));
-	
+
 	spin_lock_irqsave(&ieee->beacon_lock,flags);
 	if(ieee->beacon_txing)
 		add_timer(&ieee->beacon_timer);
@@ -299,7 +299,7 @@
 void ieee80211_send_probe(struct ieee80211_device *ieee)
 {
 	struct sk_buff *skb;
-	
+
 	skb = ieee80211_probe_req(ieee);
 	if (skb){
 		softmac_mgmt_xmit(skb, ieee);
@@ -316,29 +316,29 @@
 }
 
 /* this performs syncro scan blocking the caller until all channels
- * in the allowed channel map has been checked. 
+ * in the allowed channel map has been checked.
  */
 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 {
 	short ch = 0;
-        
+
 	down(&ieee->scan_sem);
-	
+
 	while(1)
 	{
-		
+
 		do{
 			ch++;
-			if (ch > MAX_CHANNEL_NUMBER) 
+			if (ch > MAX_CHANNEL_NUMBER)
 				goto out; /* scan completed */
-				
+
 		}while(!ieee->channel_map[ch]);
-	
+
 		/* this fuction can be called in two situations
 		 * 1- We have switched to ad-hoc mode and we are
 		 *    performing a complete syncro scan before conclude
-		 *    there are no interesting cell and to create a 
-		 *    new one. In this case the link state is 
+		 *    there are no interesting cell and to create a
+		 *    new one. In this case the link state is
 		 *    IEEE80211_NOLINK until we found an interesting cell.
 		 *    If so the ieee8021_new_net, called by the RX path
 		 *    will set the state to IEEE80211_LINKED, so we stop
@@ -351,24 +351,24 @@
 		 *    not filter RX frames and the channel is changing.
 		 * So the only situation in witch are interested is to check
 		 * if the state become LINKED because of the #1 situation
-		 */    
-		    
+		 */
+
 		if (ieee->state == IEEE80211_LINKED)
 			goto out;
-		
+
 		ieee->set_chan(ieee->dev, ch);
 	//	printk(KERN_INFO "current probe channel is %d!\n",ch);
 		ieee80211_send_probe_requests(ieee);
-		
+
 		/* this prevent excessive time wait when we
 		 * need to wait for a syncro scan to end..
-		 */  		
+		 */
 		if (ieee->sync_scan_hurryup)
 			goto out;
 
 
 		msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
-		
+
 	}
 out:
 	ieee->sync_scan_hurryup = 0;
@@ -379,43 +379,50 @@
 void ieee80211_softmac_scan(struct ieee80211_device *ieee)
 {
 	short watchdog = 0;
-	
+
 	do{
-		ieee->current_network.channel = 
+		ieee->current_network.channel =
 			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-		if (watchdog++ > MAX_CHANNEL_NUMBER) 
+		if (watchdog++ > MAX_CHANNEL_NUMBER)
 				return; /* no good chans */
-				
+
 	}while(!ieee->channel_map[ieee->current_network.channel]);
-		
+
 
 	schedule_work(&ieee->softmac_scan_wq);
 }
 #endif
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_softmac_scan_wq(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
+#else
 void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
-{	
+{
+#endif
 	short watchdog = 0;
 	down(&ieee->scan_sem);
-	
-	
+
+
 	do{
-		ieee->current_network.channel = 
+		ieee->current_network.channel =
 			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-		if (watchdog++ > MAX_CHANNEL_NUMBER) 
+		if (watchdog++ > MAX_CHANNEL_NUMBER)
 				goto out; /* no good chans */
-				
+
 	}while(!ieee->channel_map[ieee->current_network.channel]);
-	
+
 	if (ieee->scanning == 0 )
 		goto out;
-	
+
 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
 	ieee80211_send_probe_requests(ieee);
 
-#if 0	
+#if 0
 	ieee->.expires = jiffies + (IEEE80211_SOFTMAC_SCAN_TIME);
-	if (ieee->scanning == 1) 
+	if (ieee->scanning == 1)
 		add_timer(&ieee->scan_timer);
 #endif
 	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
@@ -428,7 +435,7 @@
 {
 	unsigned long flags;
 	struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
-	
+
 	spin_lock_irqsave(&ieee->lock, flags);
 	ieee80211_softmac_scan(ieee);
 	spin_unlock_irqrestore(&ieee->lock, flags);
@@ -438,13 +445,13 @@
 
 void ieee80211_beacons_start(struct ieee80211_device *ieee)
 {
-	unsigned long flags;	
+	unsigned long flags;
 
 	spin_lock_irqsave(&ieee->beacon_lock,flags);
 
 	ieee->beacon_txing = 1;
 	ieee80211_send_beacon(ieee);
-	
+
 	spin_unlock_irqrestore(&ieee->beacon_lock,flags);
 }
 
@@ -476,25 +483,25 @@
 	if(ieee->start_send_beacons)
 		ieee->start_send_beacons(ieee->dev);
 	if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
-		ieee80211_beacons_start(ieee); 
+		ieee80211_beacons_start(ieee);
 }
 
 
 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
 {
-//	unsigned long flags;	
-	
+//	unsigned long flags;
+
 	//ieee->sync_scan_hurryup = 1;
-	
+
 	down(&ieee->scan_sem);
 //	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	if (ieee->scanning == 1){
 		ieee->scanning = 0;
 		//del_timer_sync(&ieee->scan_timer);
 		cancel_delayed_work(&ieee->softmac_scan_wq);
 	}
-	
+
 //	spin_unlock_irqrestore(&ieee->lock, flags);
 	up(&ieee->scan_sem);
 }
@@ -510,62 +517,66 @@
 /* called with ieee->lock held */
 void ieee80211_start_scan(struct ieee80211_device *ieee)
 {
-	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){	
+	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
 		if (ieee->scanning == 0){
 			ieee->scanning = 1;
 			//ieee80211_softmac_scan(ieee);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
 			queue_work(ieee->wq, &ieee->softmac_scan_wq);
+#else
+			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
+#endif
 		}
 	}else
 		ieee->start_scan(ieee->dev);
-	
+
 }
 
 /* called with wx_sem held */
 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
 {
 	ieee->sync_scan_hurryup = 0;
-	
+
 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
 		ieee80211_softmac_scan_syncro(ieee);
 	else
 		ieee->scan_syncro(ieee->dev);
-		
+
 }
 
-inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon, 
+inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
 	struct ieee80211_device *ieee, int challengelen)
 {
-	struct sk_buff *skb;	
+	struct sk_buff *skb;
 	struct ieee80211_authentication *auth;
-	
-	skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen); 
-	
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
+
 	if (!skb) return NULL;
-	
+
 	auth = (struct ieee80211_authentication *)
 		skb_put(skb, sizeof(struct ieee80211_authentication));
-	
+
 	auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
 	if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
 	if (ieee->ps != IEEE80211_PS_DISABLED) auth->header.frame_ctl |= IEEE80211_FCTL_PM;//tony 060624
 
-	
+
 	auth->header.duration_id = 0x013a; //FIXME
-	
+
 	memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
 	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
-	
+
 	auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
-	
+
 	auth->transaction = cpu_to_le16(ieee->associate_seq);
 	ieee->associate_seq++;
-	
+
 	auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
-	
+
 	return skb;
-	
+
 }
 
 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
@@ -577,23 +588,23 @@
 	int encrypt;
 	int atim_len,erp_len;
 	struct ieee80211_crypt_data* crypt;
-	
+
 	char *ssid = ieee->current_network.ssid;
 	int ssid_len = ieee->current_network.ssid_len;
 	int rate_len = ieee->current_network.rates_len+2;
 	int rate_ex_len = ieee->current_network.rates_ex_len;
 	if(rate_ex_len > 0) rate_ex_len+=2;
-	
+
 	if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
 		atim_len = 4;
 	else
 		atim_len = 0;
-	
-	if(ieee80211_is_54g(ieee->current_network)) 
+
+	if(ieee80211_is_54g(ieee->current_network))
 		erp_len = 3;
 	else
 		erp_len = 0;
-	
+
 	beacon_size = sizeof(struct ieee80211_probe_response)+
 		ssid_len
 		+3 //channel
@@ -601,72 +612,72 @@
 		+rate_ex_len
 		+atim_len
 		+erp_len;
-	
+
 	skb = dev_alloc_skb(beacon_size);
-	
-	if (!skb) 
+
+	if (!skb)
 		return NULL;
-	
+
 	beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
-	
+
 	memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
 	memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
 
 	beacon_buf->header.duration_id = 0; //FIXME
-	beacon_buf->beacon_interval = 
+	beacon_buf->beacon_interval =
 		cpu_to_le16(ieee->current_network.beacon_interval);
-	beacon_buf->capability = 
+	beacon_buf->capability =
 		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
-	
+
 	if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
-		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));		
-	
+		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
+
 	crypt = ieee->crypt[ieee->tx_keyidx];
 
-	encrypt = ieee->host_encrypt && crypt && crypt->ops && 
+	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
 		(0 == strcmp(crypt->ops->name, "WEP"));
 
-	if (encrypt)	
+	if (encrypt)
 		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-	
-		
+
+
 	beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
-	
-	beacon_buf->info_element.id = MFIE_TYPE_SSID;	
+
+	beacon_buf->info_element.id = MFIE_TYPE_SSID;
 	beacon_buf->info_element.len = ssid_len;
-	
+
 	tag = (u8*) beacon_buf->info_element.data;
-	
+
 	memcpy(tag, ssid, ssid_len);
-	
+
 	tag += ssid_len;
-	
+
 	*(tag++) = MFIE_TYPE_RATES;
-	*(tag++) = rate_len-2; 
+	*(tag++) = rate_len-2;
 	memcpy(tag,ieee->current_network.rates,rate_len-2);
 	tag+=rate_len-2;
-	
+
 	*(tag++) = MFIE_TYPE_DS_SET;
 	*(tag++) = 1;
 	*(tag++) = ieee->current_network.channel;
-	
+
 	if(atim_len){
 		*(tag++) = MFIE_TYPE_IBSS_SET;
 		*(tag++) = 2;
 		*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
 		tag+=2;
 	}
-	
+
 	if(erp_len){
 		*(tag++) = MFIE_TYPE_ERP;
 		*(tag++) = 1;
-		*(tag++) = 0; 
+		*(tag++) = 0;
 	}
-	
+
 	if(rate_ex_len){
 		*(tag++) = MFIE_TYPE_RATES_EX;
-		*(tag++) = rate_ex_len-2; 
+		*(tag++) = rate_ex_len-2;
 		memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
 		tag+=rate_ex_len-2;
 	}
@@ -679,52 +690,52 @@
 {
 	struct sk_buff *skb;
 	u8* tag;
-	
+
 	struct ieee80211_crypt_data* crypt;
 	struct ieee80211_assoc_response_frame *assoc;
 	short encrypt;
-	
+
 	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
 	int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
-	
-	skb = dev_alloc_skb(len); 
-	
-	if (!skb) 
+
+	skb = dev_alloc_skb(len);
+
+	if (!skb)
 		return NULL;
-	
+
 	assoc = (struct ieee80211_assoc_response_frame *)
 		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
-	
+
 	assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
 	memcpy(assoc->header.addr1, dest,ETH_ALEN);
 	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? 
+	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
 		WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
-	
-		
+
+
 	if(ieee->short_slot)
 		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-		
+
 	if (ieee->host_encrypt)
 		crypt = ieee->crypt[ieee->tx_keyidx];
 	else crypt = NULL;
-	
+
 	encrypt = ( crypt && crypt->ops);
-	   
+
 	if (encrypt)
 		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-	
+
 	assoc->status = 0;
 	assoc->aid = cpu_to_le16(ieee->assoc_id);
 	if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
 	else ieee->assoc_id++;
-	
+
 	tag = (u8*) skb_put(skb, rate_len);
-	
+
 	ieee80211_MFIE_Brate(ieee, &tag);
 	ieee80211_MFIE_Grate(ieee, &tag);
-	
+
 	return skb;
 }
 
@@ -732,59 +743,59 @@
 {
 	struct sk_buff *skb;
 	struct ieee80211_authentication *auth;
-	
-	skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1); 
-	
-	if (!skb) 
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
+
+	if (!skb)
 		return NULL;
-	
+
 	skb->len = sizeof(struct ieee80211_authentication);
-	
+
 	auth = (struct ieee80211_authentication *)skb->data;
-	
+
 	auth->status = cpu_to_le16(status);
 	auth->transaction = cpu_to_le16(2);
 	auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
-	
+
 	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(auth->header.addr1, dest, ETH_ALEN);
-	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); 
+	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
 	return skb;
-	
-	
+
+
 }
 
 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
 {
 	struct sk_buff *skb;
 	struct ieee80211_hdr_3addr* hdr;
-	
-	skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr)); 
-	
-	if (!skb) 
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
+
+	if (!skb)
 		return NULL;
-	
+
 	hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
-	
+
 	memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
 	memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
-	
-	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 
-		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | 
-		(pwr ? IEEE80211_FCTL_PM:0)); 
-	
+
+	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
+		(pwr ? IEEE80211_FCTL_PM:0));
+
 	return skb;
-	
-	
+
+
 }
 
 
 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
 {
 	struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
-	
+
 	if (buf)
 		softmac_mgmt_xmit(buf, ieee);
 }
@@ -793,7 +804,7 @@
 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
 {
 	struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
-	
+
 	if (buf)
 		softmac_mgmt_xmit(buf, ieee);
 }
@@ -801,10 +812,10 @@
 
 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
 {
-	
+
 	struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
-	
-	if (buf) 
+
+	if (buf)
 		softmac_mgmt_xmit(buf, ieee);
 }
 
@@ -812,72 +823,72 @@
 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
 {
 	struct sk_buff *skb;
-	
+
 	struct ieee80211_assoc_request_frame *hdr;
 	u8 *tag;
-	
+
 	unsigned int wpa_len = beacon->wpa_ie_len;
 	unsigned int rsn_len = beacon->rsn_ie_len;
-	
+
 	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
-	
-	
-	
+
+
+
 	int len=sizeof(struct ieee80211_assoc_request_frame)+
 				+ beacon->ssid_len//essid tagged val
 				+ rate_len//rates tagged val
 				+ rsn_len
 				+ wpa_len;
-				
+
 	skb = dev_alloc_skb(len);
-	
-	if (!skb) 
+
+	if (!skb)
 		return NULL;
-	
+
 	hdr = (struct ieee80211_assoc_request_frame *)
 		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
-	
-	
+
+
 	hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
 	if (ieee->ps != IEEE80211_PS_DISABLED) hdr->header.frame_ctl |= IEEE80211_FCTL_PM; //tony
 	hdr->header.duration_id= 37; //FIXME
 	memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
 	memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
-	
+
 	hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
-	if (beacon->capability & WLAN_CAPABILITY_PRIVACY ) 
+	if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
 	if(beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //tony 20060606
-	
+
 	if(ieee->short_slot)
 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-	
+
 	hdr->listen_interval = 0xa; //FIXME
-	
+
 	hdr->info_element.id = MFIE_TYPE_SSID;
 
 	hdr->info_element.len = beacon->ssid_len;
 	tag = skb_put(skb, beacon->ssid_len);
 	memcpy(tag, beacon->ssid, beacon->ssid_len);
-	
-	tag = skb_put(skb, rate_len); 
-	
+
+	tag = skb_put(skb, rate_len);
+
 	ieee80211_MFIE_Brate(ieee, &tag);
 	ieee80211_MFIE_Grate(ieee, &tag);
-	
+
 	tag = skb_put(skb,wpa_len);
-	
+
 	if(wpa_len) {
 		if(wpa_len > (22 + 2) )
 		{
 			beacon->wpa_ie[wpa_len - 2] = 0;
 		}
-	
+
 	}
 	memcpy(tag,beacon->wpa_ie,wpa_len);
-	
+
 	tag = skb_put(skb,rsn_len);
 
 	if(rsn_len) {
@@ -890,12 +901,12 @@
 
 void ieee80211_associate_abort(struct ieee80211_device *ieee)
 {
-	
+
 	unsigned long flags;
 	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	ieee->associate_seq++;
-	
+
 	/* don't scan, and avoid to have the RX path possibily
 	 * try again to associate. Even do not react to AUTH or
 	 * ASSOC response. Just wait for the retry wq to be scheduled.
@@ -903,17 +914,17 @@
 	 * with, so we retry or just get back to NO_LINK and scanning
 	 */
 	if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
-		IEEE80211_DEBUG_MGMT("Authentication failed\n"); 
+		IEEE80211_DEBUG_MGMT("Authentication failed\n");
 		ieee->softmac_stats.no_auth_rs++;
 	}else{
-		IEEE80211_DEBUG_MGMT("Association failed\n"); 
+		IEEE80211_DEBUG_MGMT("Association failed\n");
 		ieee->softmac_stats.no_ass_rs++;
 	}
-		
+
 	ieee->state = IEEE80211_ASSOCIATING_RETRY;
-		
+
 	queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-	
+
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
@@ -927,50 +938,50 @@
 {
 	struct ieee80211_network *beacon = &ieee->current_network;
 	struct sk_buff *skb;
-	
+
 	IEEE80211_DEBUG_MGMT("Stopping scan\n");
-	
+
 	ieee->softmac_stats.tx_auth_rq++;
 	skb=ieee80211_authentication_req(beacon, ieee, 0);
-	
-	if (!skb) 
+
+	if (!skb)
 		ieee80211_associate_abort(ieee);
-	else{ 
+	else{
 		ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
 		IEEE80211_DEBUG_MGMT("Sending authentication request\n");
 		softmac_mgmt_xmit(skb, ieee);
 		ieee->associate_timer.expires = jiffies + (HZ / 2);
 		add_timer(&ieee->associate_timer);
-	}	
+	}
 }
 
 void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
 {
-	u8 *c;	
+	u8 *c;
 	struct sk_buff *skb;
 	struct ieee80211_network *beacon = &ieee->current_network;
 //	int hlen = sizeof(struct ieee80211_authentication);
-	
+
 	ieee->associate_seq++;
 	ieee->softmac_stats.tx_auth_rq++;
-	
+
 	skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
-	if (!skb) 
+	if (!skb)
 		ieee80211_associate_abort(ieee);
 	else{
 		c = skb_put(skb, chlen+2);
 		*(c++) = MFIE_TYPE_CHALLENGE;
 		*(c++) = chlen;
 		memcpy(c, challenge, chlen);
-		
+
 		IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
-		
+
 		ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr  ));
-			
+
 		softmac_mgmt_xmit(skb, ieee);
 		ieee->associate_timer.expires = jiffies + (HZ / 2);
 		add_timer(&ieee->associate_timer);
-	}	
+	}
 	kfree(challenge);
 }
 
@@ -978,28 +989,34 @@
 {
 	struct sk_buff* skb;
 	struct ieee80211_network *beacon = &ieee->current_network;
-	
+
 	del_timer_sync(&ieee->associate_timer);
-	
+
 	IEEE80211_DEBUG_MGMT("Sending association request\n");
-	
+
 	ieee->softmac_stats.tx_ass_rq++;
 	skb=ieee80211_association_req(beacon, ieee);
-	if (!skb) 
+	if (!skb)
 		ieee80211_associate_abort(ieee);
 	else{
 		softmac_mgmt_xmit(skb, ieee);
 		ieee->associate_timer.expires = jiffies + (HZ / 2);
 		add_timer(&ieee->associate_timer);
-	}	
+	}
 }
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_associate_complete_wq(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
+#else
 void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
 {
+#endif
 	printk(KERN_INFO "Associated successfully\n");
-	if(ieee80211_is_54g(ieee->current_network) && 
+	if(ieee80211_is_54g(ieee->current_network) &&
 		(ieee->modulation & IEEE80211_OFDM_MODULATION)){
-		
+
 		ieee->rate = 540;
 		printk(KERN_INFO"Using G rates\n");
 	}else{
@@ -1007,7 +1024,7 @@
 		printk(KERN_INFO"Using B rates\n");
 	}
 	ieee->link_change(ieee->dev);
-	notify_wx_assoc_event(ieee); 
+	notify_wx_assoc_event(ieee);
 	if (ieee->data_hard_resume)
 		ieee->data_hard_resume(ieee->dev);
 	netif_carrier_on(ieee->dev);
@@ -1017,52 +1034,58 @@
 {
 
 	del_timer_sync(&ieee->associate_timer);
-	
+
 	ieee->seq_ctrl = 0;
 	ieee->state = IEEE80211_LINKED;
 	IEEE80211_DEBUG_MGMT("Successfully associated\n");
-	
+
 	queue_work(ieee->wq, &ieee->associate_complete_wq);
 }
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_associate_procedure_wq(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
+#else
 void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
 {
+#endif
 	ieee->sync_scan_hurryup = 1;
 	down(&ieee->wx_sem);
-	
+
 	if (ieee->data_hard_stop)
 		ieee->data_hard_stop(ieee->dev);
-	
+
 	ieee80211_stop_scan(ieee);
 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-	
+
 	ieee->associate_seq = 1;
 	ieee80211_associate_step1(ieee);
-	
+
 	up(&ieee->wx_sem);
 }
 
 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
 {
-	
+
 	u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
 	int tmp_ssid_len = 0;
-	
+
 	short apset,ssidset,ssidbroad,apmatch,ssidmatch;
-	
-	/* we are interested in new new only if we are not associated 
+
+	/* we are interested in new new only if we are not associated
 	 * and we are not associating / authenticating
 	 */
 	if (ieee->state != IEEE80211_NOLINK)
-		return; 
-		
+		return;
+
 	if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
 		return;
-	
+
 	if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
 		return;
 
-	
+
 	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
 		/* if the user specified the AP MAC, we need also the essid
 		 * This could be obtained by beacons or, if the network does not
@@ -1073,23 +1096,23 @@
 		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0]== '\0');
 		apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
 		ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
-		
-		
-		
+
+
+
 		if (	/* if the user set the AP check if match.
 		         * if the network does not broadcast essid we check the user supplyed ANY essid
 			 * if the network does broadcast and the user does not set essid it is OK
 			 * if the network does broadcast and the user did set essid chech if essid match
 			 */
-			( apset && apmatch && 
-				((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||  
+			( apset && apmatch &&
+				((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
 			/* if the ap is not set, check that the user set the bssid
 			 * and the network does bradcast and that those two bssid matches
-			 */ 
-			(!apset && ssidset && ssidbroad && ssidmatch) 
+			 */
+			(!apset && ssidset && ssidbroad && ssidmatch)
 			){
-			
-			
+
+
 				/* if the essid is hidden replace it with the
 				* essid provided by the user.
 				*/
@@ -1098,18 +1121,18 @@
 					tmp_ssid_len = ieee->current_network.ssid_len;
 				}
 				memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
-				
+
 				if (!ssidbroad){
 					strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
 					ieee->current_network.ssid_len = tmp_ssid_len;
 				}
 				printk(KERN_INFO"Linking with %s\n",ieee->current_network.ssid);
-				
+
 				if (ieee->iw_mode == IW_MODE_INFRA){
 					ieee->state = IEEE80211_ASSOCIATING;
 					queue_work(ieee->wq, &ieee->associate_procedure_wq);
 				}else{
-					if(ieee80211_is_54g(ieee->current_network) && 
+					if(ieee80211_is_54g(ieee->current_network) &&
 						(ieee->modulation & IEEE80211_OFDM_MODULATION)){
 						ieee->rate = 540;
 						printk(KERN_INFO"Using G rates\n");
@@ -1119,7 +1142,7 @@
 					}
 					ieee->state = IEEE80211_LINKED;
 				}
-			
+
 		}
 	}
 
@@ -1127,26 +1150,26 @@
 
 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
 {
-	
+
 	unsigned long flags;
 	struct ieee80211_network *target;
-	
+
 	spin_lock_irqsave(&ieee->lock, flags);
-			
+
 	list_for_each_entry(target, &ieee->network_list, list) {
-		
+
 		/* if the state become different that NOLINK means
 		 * we had found what we are searching for
 		 */
-		if (ieee->state != IEEE80211_NOLINK) 
+		if (ieee->state != IEEE80211_NOLINK)
 			break;
-			
+
 		//if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
 			ieee80211_softmac_new_net(ieee, target);
 	}
-	
+
 	spin_unlock_irqrestore(&ieee->lock, flags);
-	
+
 }
 
 
@@ -1154,7 +1177,7 @@
 {
 	struct ieee80211_authentication *a;
 	u8 *t;
-	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ 
+	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
 		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
 		return 0xcafe;
 	}
@@ -1162,34 +1185,34 @@
 	a = (struct ieee80211_authentication*) skb->data;
 	if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
 		t = skb->data + sizeof(struct ieee80211_authentication);
-		
+
 		if(*(t++) == MFIE_TYPE_CHALLENGE){
 			*chlen = *(t++);
 			*challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
 			memcpy(*challenge, t, *chlen);
 		}
 	}
-	
+
 	return cpu_to_le16(a->status);
-	
+
 }
 
 
 int auth_rq_parse(struct sk_buff *skb,u8* dest)
 {
 	struct ieee80211_authentication *a;
-	
-	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ 
-		IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);	
+
+	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
+		IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
 		return -1;
 	}
 	a = (struct ieee80211_authentication*) skb->data;
-	
+
 	memcpy(dest,a->header.addr2, ETH_ALEN);
-	
-	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) 
+
+	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
 		return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
-	
+
 	return WLAN_STATUS_SUCCESS;
 }
 
@@ -1199,21 +1222,21 @@
 	u8 *skbend;
 	u8 *ssid=NULL;
 	u8 ssidlen = 0;
-	
+
 	struct ieee80211_hdr_3addr   *header =
 		(struct ieee80211_hdr_3addr   *) skb->data;
-	
-	if (skb->len < sizeof (struct ieee80211_hdr_3addr  )) 
+
+	if (skb->len < sizeof (struct ieee80211_hdr_3addr  ))
 		return -1; /* corrupted */
-	
+
 	memcpy(src,header->addr2, ETH_ALEN);
-	
+
 	skbend = (u8*)skb->data + skb->len;
-	
+
 	tag = skb->data + sizeof (struct ieee80211_hdr_3addr  );
-	
+
 	while (tag+1 < skbend){
-		if (*tag == 0){ 
+		if (*tag == 0){
 			ssid = tag+2;
 			ssidlen = *(tag+1);
 			break;
@@ -1222,41 +1245,41 @@
 		tag = tag + *(tag); /* point to the last data byte of the tag */
 		tag++; /* point to the next tag */
 	}
-	
+
 	//IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
 	if (ssidlen == 0) return 1;
-	
+
 	if (!ssid) return 1; /* ssid not found in tagged param */
 	return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
-		
+
 }
 
 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
 {
 	struct ieee80211_assoc_request_frame *a;
-	
-	if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - 
-		sizeof(struct ieee80211_info_element))) { 
-		
+
+	if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
+		sizeof(struct ieee80211_info_element))) {
+
 		IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
 		return -1;
 	}
-	
+
 	a = (struct ieee80211_assoc_request_frame*) skb->data;
-		
+
 	memcpy(dest,a->header.addr2,ETH_ALEN);
-	
+
 	return 0;
 }
 
 static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
 {
 	struct ieee80211_assoc_response_frame *a;
-	if (skb->len <  sizeof(struct ieee80211_assoc_response_frame)){ 
+	if (skb->len <  sizeof(struct ieee80211_assoc_response_frame)){
 		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
 		return 0xcafe;
 	}
-	
+
 	a = (struct ieee80211_assoc_response_frame*) skb->data;
 	*aid = le16_to_cpu(a->aid) & 0x3fff;
 	return le16_to_cpu(a->status);
@@ -1266,7 +1289,7 @@
 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
 	u8 dest[ETH_ALEN];
-	
+
 	//IEEE80211DMESG("Rx probe");
 	ieee->softmac_stats.rx_probe_rq++;
 	//DMESG("Dest is "MACSTR, MAC2STR(dest));
@@ -1284,26 +1307,26 @@
 	int status;
 	//IEEE80211DMESG("Rx probe");
 	ieee->softmac_stats.rx_auth_rq++;
-	
+
 	if ((status = auth_rq_parse(skb, dest))!= -1){
 		ieee80211_resp_to_auth(ieee, status, dest);
 	}
 	//DMESG("Dest is "MACSTR, MAC2STR(dest));
-	
+
 }
 
 static inline void
 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
-	
+
 	u8 dest[ETH_ALEN];
 	//unsigned long flags;
-	
+
 	ieee->softmac_stats.rx_ass_rq++;
 	if (assoc_rq_parse(skb,dest) != -1){
 		ieee80211_resp_to_assoc_rq(ieee, dest);
 	}
-	
+
 	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
 	//FIXME
 	#if 0
@@ -1317,24 +1340,24 @@
 
 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
 {
-	
+
 	struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
-	
+
 	if (buf)
 		softmac_ps_mgmt_xmit(buf, ieee);
 //	printk(KERN_INFO "ieee80211_sta_ps_send_null_frame!\n");
 
-} 
+}
 
 
 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
-{	
+{
 	int timeout = ieee->ps_timeout;
 	u8 dtim;
 	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
-		ieee->iw_mode != IW_MODE_INFRA || 
+		ieee->iw_mode != IW_MODE_INFRA ||
 		ieee->state != IEEE80211_LINKED)
-		
+
 		return 0;
 	*/
 	dtim = ieee->current_network.dtim_data;
@@ -1343,7 +1366,7 @@
 		return 0;
 	printk(KERN_INFO "VALID\n");
 	ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-		
+
 	if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
 		return 2;
 	printk(KERN_INFO "no UCAST\n");
@@ -1358,11 +1381,11 @@
 		return 0;
 	printk(KERN_INFO "cc\n");
 	if(time_l){
-		*time_l = ieee->current_network.last_dtim_sta_time[0] 
-			+ (ieee->current_network.beacon_interval 
+		*time_l = ieee->current_network.last_dtim_sta_time[0]
+			+ (ieee->current_network.beacon_interval
 			* ieee->current_network.dtim_period) * 1000;
 	}
-	
+
 	if(time_h){
 		*time_h = ieee->current_network.last_dtim_sta_time[1];
 		if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
@@ -1372,8 +1395,8 @@
 	ieee->ps_tl=*time_l;
 //	printk(KERN_INFO "ieee->ps_tl %lu!\n",ieee->ps_tl);
 	return 1;
-	
-	
+
+
 }
 
 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
@@ -1381,72 +1404,72 @@
 
 	u32 th,tl;
 	short sleep;
-	
+
 	unsigned long flags,flags2;
 ////	printk(KERN_INFO "enter ieee80211_sta_ps!\n");
 	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	if((ieee->ps == IEEE80211_PS_DISABLED ||
-		ieee->iw_mode != IW_MODE_INFRA || 
+		ieee->iw_mode != IW_MODE_INFRA ||
 		ieee->state != IEEE80211_LINKED)){
-		
+
 //		#warning CHECK_LOCK_HERE
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-		
-		ieee80211_sta_wakeup(ieee, 1);	
+
+		ieee80211_sta_wakeup(ieee, 1);
 		printk(KERN_WARNING "wakeup 1!\n" );
 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
 	}
-	
+
 	sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
 	/* 2 wake, 1 sleep, 0 do nothing */
 	//printk(KERN_INFO "sleep %d,th %lu, tl %lu,sta_sleep %d\n",sleep,th,tl,ieee->sta_sleep);
 	if(sleep == 0)
 		goto out;
-	
+
 	if(sleep == 1){
-	
+
 		if(ieee->sta_sleep == 1)
 			//ieee->enter_sleep_state(ieee->dev,th,tl);
 			queue_work(ieee->wq,&ieee->hw_sleep_wq);
-		
+
 		else if(ieee->sta_sleep == 0){
 		//	printk("send null 1\n");
 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-			
+
 			if(ieee->ps_is_queue_empty(ieee->dev)){
-				
-			
+
+
 				ieee->sta_sleep = 2;
-				
+
 			//	ieee->ps_request_tx_ack(ieee->dev);
 			//	printk(KERN_INFO "ps request address %lu!\n",ieee->ps_request_tx_ack);
-			//	queue_work(ieee->wq,&ieee->ps_request_tx_ack_wq);	
+			//	queue_work(ieee->wq,&ieee->ps_request_tx_ack_wq);
 				ieee80211_sta_ps_send_null_frame(ieee,1);
 				ieee80211_sta_ps_send_null_frame(ieee,1);
-				
+
 				ieee->ps_th = th;
 				ieee->ps_tl = tl;
 			//	udelay(100);
 				ieee80211_ps_tx_ack(ieee,1);//add without interrupt like 8185
-			}	
+			}
 			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
-			
+
 		}
-		
-		
+
+
 	}else if(sleep == 2){
 //	#warning CHECK_LOCK_HERE
 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-			
+
 		ieee80211_sta_wakeup(ieee,1);
 		printk(KERN_WARNING "wakeup 2!\n" );
 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
 	}
 
-out:	
+out:
 	spin_unlock_irqrestore(&ieee->lock, flags);
-	
+
 }
 
 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
@@ -1460,14 +1483,14 @@
 			ieee80211_sta_ps_send_null_frame(ieee, 0);
 		}
 		return;
-		
+
 	}
-	if(ieee->sta_sleep == 1) 
+	if(ieee->sta_sleep == 1)
 		//ieee->sta_wake_up(ieee->dev);
 		queue_work(ieee->wq,&ieee->hw_wakeup_wq);
-		
+
 	ieee->sta_sleep = 0;
-	
+
 	if(nl){
 		//ieee->ps_request_tx_ack(ieee->dev);
 		//queue_work(ieee->wq,&ieee->ps_request_tx_ack_wq);
@@ -1480,7 +1503,7 @@
 	unsigned long flags,flags2;
 //	printk(KERN_INFO "ieee80211_ps_tx_ack,success %d,sta_sleep %d!\n",success,ieee->sta_sleep);
 	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	if(ieee->sta_sleep == 2){
 		/* Null frame with PS bit set */
 		if(success){
@@ -1495,7 +1518,7 @@
 	}
 	/* 21112005 - tx again null without PS bit if lost */
 	else {
-	
+
 		if((ieee->sta_sleep == 0) && !success){
 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
 			ieee80211_sta_ps_send_null_frame(ieee, 0);
@@ -1519,66 +1542,66 @@
 	header = (struct ieee80211_hdr_3addr *) skb->data;
 	if(!ieee->proto_started)
 		return 0;
-	
+
 	if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
-		ieee->iw_mode == IW_MODE_INFRA && 
+		ieee->iw_mode == IW_MODE_INFRA &&
 		ieee->state == IEEE80211_LINKED)) {
 ////		printk(KERN_INFO "schedule ps task!\n");
 		tasklet_schedule(&ieee->ps_task);}
-				
+
 	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
 		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
 		ieee->last_rx_ps_time = jiffies;
-		
+
 	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
-	
+
 		case IEEE80211_STYPE_ASSOC_RESP:
 		case IEEE80211_STYPE_REASSOC_RESP:
-		
+
 			IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
 					WLAN_FC_GET_STYPE(header->frame_ctl));
 			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
-				ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && 
+				ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
 				ieee->iw_mode == IW_MODE_INFRA){
 				if (0 == (errcode=assoc_parse(skb, &aid))){
-					
+
 					ieee->state=IEEE80211_LINKED;
 					ieee->assoc_id = aid;
 					ieee->softmac_stats.rx_ass_ok++;
-					
+
 					ieee80211_associate_complete(ieee);
 				}else{
 					ieee->softmac_stats.rx_ass_err++;
 					IEEE80211_DEBUG_MGMT(
 						"Association response status code 0x%x\n",
 						errcode);
-					ieee80211_associate_abort(ieee); 
+					ieee80211_associate_abort(ieee);
 				}
 			}
 			break;
-		
+
 		case IEEE80211_STYPE_ASSOC_REQ:
 		case IEEE80211_STYPE_REASSOC_REQ:
-		
+
 			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
 				ieee->iw_mode == IW_MODE_MASTER)
-					
+
 				ieee80211_rx_assoc_rq(ieee, skb);
 			break;
-			
+
 		case IEEE80211_STYPE_AUTH:
-		
+
 			if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
-				if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING && 
+				if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
 				ieee->iw_mode == IW_MODE_INFRA){
-			
+
 						IEEE80211_DEBUG_MGMT("Received authentication response");
-						
+
 						if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
 							if(ieee->open_wep || !challenge){
 								ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
 								ieee->softmac_stats.rx_auth_rs_ok++;
-								
+
 								ieee80211_associate_step2(ieee);
 							}else{
 								ieee80211_auth_challenge(ieee, challenge, chlen);
@@ -1588,47 +1611,47 @@
 							IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
 							ieee80211_associate_abort(ieee);
 						}
-						
+
 					}else if (ieee->iw_mode == IW_MODE_MASTER){
 						ieee80211_rx_auth_rq(ieee, skb);
 					}
 				}
 			break;
-				
+
 		case IEEE80211_STYPE_PROBE_REQ:
-		
-			if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && 
-				((ieee->iw_mode == IW_MODE_ADHOC || 
+
+			if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
+				((ieee->iw_mode == IW_MODE_ADHOC ||
 				ieee->iw_mode == IW_MODE_MASTER) &&
 				ieee->state == IEEE80211_LINKED))
-				
+
 				ieee80211_rx_probe_rq(ieee, skb);
 			break;
-			
+
 		case IEEE80211_STYPE_DISASSOC:
 		case IEEE80211_STYPE_DEAUTH:
-			/* FIXME for now repeat all the association procedure 
+			/* FIXME for now repeat all the association procedure
 			* both for disassociation and deauthentication
 			*/
 			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
-				ieee->state == IEEE80211_LINKED && 
+				ieee->state == IEEE80211_LINKED &&
 				ieee->iw_mode == IW_MODE_INFRA){
-				
+
 				ieee->state = IEEE80211_ASSOCIATING;
 				ieee->softmac_stats.reassoc++;
-				
+
 				notify_wx_assoc_event(ieee);
-								
+
 				queue_work(ieee->wq, &ieee->associate_procedure_wq);
 			}
-			
+
 			break;
-		
-		default: 
+
+		default:
 			return -1;
 			break;
 	}
-	
+
 	//dev_kfree_skb_any(skb);
 	return 0;
 }
@@ -1646,21 +1669,20 @@
  * This might be useful if each fragment need it's own
  * descriptor, thus just keep a total free memory > than
  * the max fragmentation treshold is not enought.. If the
- * ieee802.11 stack passed a TXB struct then you needed  
- * to keep N free descriptors where 
+ * ieee802.11 stack passed a TXB struct then you needed
+ * to keep N free descriptors where
  * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
  * In this way you need just one and the 802.11 stack
- * will take care of buffering fragments and pass them to 
+ * will take care of buffering fragments and pass them to
  * to the driver later, when it wakes the queue.
- */ 
- 
+ */
+
 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
 {
-	
-	
+
+
 	unsigned long flags;
 	int  i;
-	
 	spin_lock_irqsave(&ieee->lock,flags);
 	#if 0
 	if(ieee->queue_stop){
@@ -1671,13 +1693,13 @@
 		err = 1;
 		goto exit;
 	}
-	
+
 	ieee->stats.tx_bytes+=skb->len;
-	
-	
+
+
 	txb=ieee80211_skb_to_txb(ieee,skb);
-	
-	
+
+
 	if(txb==NULL){
 		IEEE80211DMESG("WW: IEEE stack failed to provide txb");
 		//dev_kfree_skb_any(skb);
@@ -1691,9 +1713,8 @@
 	}
 	/* called with 2nd parm 0, no tx mgmt lock required */
 	ieee80211_sta_wakeup(ieee,0);
-	
 	for(i = 0; i < txb->nr_frags; i++) {
-	
+
 		if (ieee->queue_stop){
 			//added by david. 2007.1.23
 			if(ieee->tx_pending.txb != NULL) {
@@ -1709,16 +1730,16 @@
 				//(i+1)<txb->nr_frags);
 			ieee->stats.tx_packets++;
 			ieee->stats.tx_bytes += txb->fragments[i]->len;
-			ieee->dev->trans_start = jiffies; 
+			ieee->dev->trans_start = jiffies;
 		}
-	}	
+	}
 	lost:
 	//ieee80211_txb_free(txb);
-	
+
 	exit:
 	atomic_dec(&ieee->tx_pending_txb);
 	spin_unlock_irqrestore(&ieee->lock,flags);
-	
+
 }
 
 /* called with ieee->lock acquired */
@@ -1726,13 +1747,13 @@
 {
 	int i;
 	for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
-		
+
 		if (ieee->queue_stop){
 			ieee->tx_pending.frag = i;
 			return;
 		}else{
-		
-			ieee->softmac_data_hard_start_xmit( 
+
+			ieee->softmac_data_hard_start_xmit(
 				ieee->tx_pending.txb->fragments[i],
 				ieee->dev,ieee->rate);
 				//(i+1)<ieee->tx_pending.txb->nr_frags);
@@ -1740,8 +1761,8 @@
 			ieee->dev->trans_start = jiffies;
 		}
 	}
-	
-	
+
+
 	//ieee80211_txb_free(ieee->tx_pending.txb);
 	ieee->tx_pending.txb = NULL;
 }
@@ -1751,7 +1772,7 @@
 {
 	unsigned long flags;
 	struct sk_buff *ret;
-	
+
 	spin_lock_irqsave(&ieee->lock,flags);
 	// added by david, 2007.1.23
 	while((ret = dequeue_mgmt(ieee)) != NULL) {
@@ -1773,17 +1794,17 @@
 	unsigned long flags;
 	struct sk_buff *skb;
 	struct ieee80211_hdr_3addr  *header;
-	
+
 	spin_lock_irqsave(&ieee->lock,flags);
 	if (! ieee->queue_stop) goto exit;
-	
+
 	ieee->queue_stop = 0;
-	
+
 	if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
 		while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
-			
+
 			header = (struct ieee80211_hdr_3addr  *) skb->data;
-			
+
 			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl << 4);
 
 			if (ieee->seq_ctrl == 0xFFF)
@@ -1799,12 +1820,12 @@
 	}
 	if (!ieee->queue_stop && ieee->tx_pending.txb)
 		ieee80211_resume_tx(ieee);
-	
+
 	if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
 		ieee->softmac_stats.swtxawake++;
 		netif_wake_queue(ieee->dev);
 	}
-	
+
 exit :
 	spin_unlock_irqrestore(&ieee->lock,flags);
 }
@@ -1821,17 +1842,17 @@
 	}
 	ieee->queue_stop = 1;
 	//spin_unlock_irqrestore(&ieee->lock,flags);
-	
+
 }
 
 
 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
 {
-	
+
 	get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
-	
+
 	/* an IBSS cell address must have the two less significant
-	 * bits of the first byte = 2 
+	 * bits of the first byte = 2
 	 */
 	ieee->current_network.bssid[0] &= ~0x01;
 	ieee->current_network.bssid[0] |= 0x02;
@@ -1841,61 +1862,68 @@
 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
 {
 	ieee->assoc_id = 1;
-	
+
 	if (ieee->current_network.ssid_len == 0){
-		strncpy(ieee->current_network.ssid, 
+		strncpy(ieee->current_network.ssid,
 			IEEE80211_DEFAULT_TX_ESSID,
 			IW_ESSID_MAX_SIZE);
-			
+
 		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
 		ieee->ssid_set = 1;
 	}
-	
+
 	memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
-	 
+
 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
 	ieee->state = IEEE80211_LINKED;
 	ieee->link_change(ieee->dev);
 	notify_wx_assoc_event(ieee);
-	
+
 	if (ieee->data_hard_resume)
 		ieee->data_hard_resume(ieee->dev);
-	
+
 	netif_carrier_on(ieee->dev);
 }
 
 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
 {
 	if(ieee->raw_tx){
-		
+
 		if (ieee->data_hard_resume)
 			ieee->data_hard_resume(ieee->dev);
-	
+
 		netif_carrier_on(ieee->dev);
 	}
 }
+
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_start_ibss_wq(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, start_ibss_wq);
+#else
 void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
 {
-	
+#endif
+
 	/* iwconfig mode ad-hoc will schedule this and return
 	 * on the other hand this will block further iwconfig SET
 	 * operations because of the wx_sem hold.
 	 * Anyway some most set operations set a flag to speed-up
-	 * (abort) this wq (when syncro scanning) before sleeping 
+	 * (abort) this wq (when syncro scanning) before sleeping
 	 * on the semaphore
 	 */
-	
+
 	down(&ieee->wx_sem);
-	
+
 	if (ieee->current_network.ssid_len == 0){
 		strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
 		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
 		ieee->ssid_set = 1;
-	} 
-	
+	}
+
 	/* check if we have this cell in our network list */
 	ieee80211_softmac_check_all_nets(ieee);
-	
+
 	/* if not then the state is not linked. Maybe the user swithced to
 	 * ad-hoc mode just after being in monitor mode, or just after
 	 * being very few time in managed mode (so the card have had no
@@ -1915,25 +1943,25 @@
 
 	/* the network definitively is not here.. create a new cell */
 	if (ieee->state == IEEE80211_NOLINK){
-		printk("creating new IBSS cell\n"); 
+		printk("creating new IBSS cell\n");
 		if(!ieee->wap_set)
 			ieee80211_randomize_cell(ieee);
-		
+
 		if(ieee->modulation & IEEE80211_CCK_MODULATION){
-		
+
 			ieee->current_network.rates_len = 4;
-			
+
 			ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
 			ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
 			ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
 			ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-				
+
 		}else
 			ieee->current_network.rates_len = 0;
-		
+
 		if(ieee->modulation & IEEE80211_OFDM_MODULATION){
 			ieee->current_network.rates_ex_len = 8;
-			
+
 			ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
 			ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
 			ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
@@ -1942,34 +1970,34 @@
 			ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
 			ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
 			ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-			
+
 			ieee->rate = 540;
 		}else{
 			ieee->current_network.rates_ex_len = 0;
 			ieee->rate = 110;
 		}
-	
+
 		ieee->current_network.atim_window = 0;
 		ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
 		if(ieee->short_slot)
 			ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
-				 
+
 	}
-	
+
 	ieee->state = IEEE80211_LINKED;
-		
+
 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
 	ieee->link_change(ieee->dev);
-	
+
 	notify_wx_assoc_event(ieee);
-	
+
 	ieee80211_start_send_beacons(ieee);
-	
+
 	if (ieee->data_hard_resume)
 		ieee->data_hard_resume(ieee->dev);
-	
+
 	netif_carrier_on(ieee->dev);
-	
+
 	up(&ieee->wx_sem);
 }
 
@@ -1988,7 +2016,7 @@
 	 * in associating / authenticating phase) start the background scanning.
 	 */
 	ieee80211_softmac_check_all_nets(ieee);
-	
+
 	/* ensure no-one start an associating process (thus setting
 	 * the ieee->state to ieee80211_ASSOCIATING) while we
 	 * have just cheked it and we are going to enable scan.
@@ -1997,10 +2025,10 @@
 	 * the rx path), so we cannot be in the middle of such function
 	 */
 	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	if (ieee->state == IEEE80211_NOLINK)
 		ieee80211_start_scan(ieee);
-	
+
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
@@ -2008,30 +2036,38 @@
 void ieee80211_disassociate(struct ieee80211_device *ieee)
 {
 	netif_carrier_off(ieee->dev);
-	
+
 	if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
 			ieee80211_reset_queue(ieee);
-	
+
 	if (ieee->data_hard_stop)
 			ieee->data_hard_stop(ieee->dev);
-	
+
 	ieee->state = IEEE80211_NOLINK;
 	ieee->link_change(ieee->dev);
 	notify_wx_assoc_event(ieee);
-	
+
 }
+
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_associate_retry_wq(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
+#else
 void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
 {
+#endif
 	unsigned long flags;
-	
+
 	down(&ieee->wx_sem);
 	if(!ieee->proto_started)
 		goto exit;
-		
+
 	if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
 		goto exit;
-		
-	/* until we do not set the state to IEEE80211_NOLINK 
+
+	/* until we do not set the state to IEEE80211_NOLINK
 	* there are no possibility to have someone else trying
 	* to start an association procdure (we get here with
 	* ieee->state = IEEE80211_ASSOCIATING).
@@ -2041,18 +2077,18 @@
 	* RX path works with ieee->lock held so there are no
 	* problems. If we are still disassociated then start a scan.
 	* the lock here is necessary to ensure no one try to start
-	* an association procedure when we have just checked the 
+	* an association procedure when we have just checked the
 	* state and we are going to start the scan.
 	*/
 	ieee->state = IEEE80211_NOLINK;
 
 	ieee80211_softmac_check_all_nets(ieee);
-	
+
 	spin_lock_irqsave(&ieee->lock, flags);
-	
+
 	if(ieee->state == IEEE80211_NOLINK)
 		ieee80211_start_scan(ieee);
-	
+
 	spin_unlock_irqrestore(&ieee->lock, flags);
 
 exit:
@@ -2062,39 +2098,39 @@
 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
 {
 	u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
-	
+
 	struct sk_buff *skb;
 	struct ieee80211_probe_response *b;
-	
+
 	skb = ieee80211_probe_resp(ieee, broadcast_addr);
-	
-	if (!skb) 
+
+	if (!skb)
 		return NULL;
-	
+
 	b = (struct ieee80211_probe_response *) skb->data;
 	b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
-		
+
 	return skb;
-	
+
 }
 
 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
 {
 	struct sk_buff *skb;
 	struct ieee80211_probe_response *b;
-	
+
 	skb = ieee80211_get_beacon_(ieee);
-	if(!skb) 
+	if(!skb)
 		return NULL;
-		
-	b = (struct ieee80211_probe_response *) skb->data;	
+
+	b = (struct ieee80211_probe_response *) skb->data;
 	b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl << 4);
-	
+
 	if (ieee->seq_ctrl == 0xFFF)
 		ieee->seq_ctrl = 0;
 	else
 		ieee->seq_ctrl++;
-	
+
 	return skb;
 }
 
@@ -2111,14 +2147,14 @@
 {
 	if (!ieee->proto_started)
 		return;
-	
+
 	ieee->proto_started = 0;
-	
+
 	ieee80211_stop_send_beacons(ieee);
-	
+
 	del_timer_sync(&ieee->associate_timer);
-	cancel_delayed_work(&ieee->associate_retry_wq);	
-	
+	cancel_delayed_work(&ieee->associate_retry_wq);
+
 	ieee80211_stop_scan(ieee);
 
 	ieee80211_disassociate(ieee);
@@ -2135,28 +2171,28 @@
 void ieee80211_start_protocol(struct ieee80211_device *ieee)
 {
 	short ch = 0;
-	
+
 	if (ieee->proto_started)
 		return;
-		
+
 	ieee->proto_started = 1;
-	
+
 	if (ieee->current_network.channel == 0){
 		do{
 			ch++;
-			if (ch > MAX_CHANNEL_NUMBER) 
+			if (ch > MAX_CHANNEL_NUMBER)
 				return; /* no channel found */
-				
+
 		}while(!ieee->channel_map[ch]);
-		
+
 		ieee->current_network.channel = ch;
 	}
-	
+
 	if (ieee->current_network.beacon_interval == 0)
 		ieee->current_network.beacon_interval = 100;
-	
+
 	ieee->set_chan(ieee->dev,ieee->current_network.channel);
-	
+
 	ieee->last_seq_num = -1;
 	ieee->last_frag_num = -1;
 	ieee->last_packet_time = 0;
@@ -2167,18 +2203,18 @@
 	 * attempts does not fail just because the user provide the essid
 	 * and the nic is still checking for the AP MAC ??
 	 */
-	
+
 	if (ieee->iw_mode == IW_MODE_INFRA)
 		ieee80211_start_bss(ieee);
-		
+
 	else if (ieee->iw_mode == IW_MODE_ADHOC)
 		ieee80211_start_ibss(ieee);
-		
+
 	else if (ieee->iw_mode == IW_MODE_MASTER)
 		ieee80211_start_master_bss(ieee);
-		
+
 	else if(ieee->iw_mode == IW_MODE_MONITOR)
-		ieee80211_start_monitor_mode(ieee);	
+		ieee80211_start_monitor_mode(ieee);
 }
 
 
@@ -2186,11 +2222,11 @@
 void ieee80211_softmac_init(struct ieee80211_device *ieee)
 {
 	memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
-	
+
 	ieee->state = IEEE80211_NOLINK;
 	ieee->sync_scan_hurryup = 0;
 	ieee->seq_ctrl = 0;
-	
+
 	ieee->assoc_id = 0;
 	ieee->queue_stop = 0;
 	ieee->scanning = 0;
@@ -2203,7 +2239,7 @@
 	ieee->ps = IEEE80211_PS_DISABLED;
 	ieee->sta_sleep = 0;
 
-	
+
 	init_mgmt_queue(ieee);
 #if 0
 	init_timer(&ieee->scan_timer);
@@ -2211,7 +2247,7 @@
 	ieee->scan_timer.function = ieee80211_softmac_scan_cb;
 #endif
 	ieee->tx_pending.txb = NULL;
-	
+
 	init_timer(&ieee->associate_timer);
 	ieee->associate_timer.data = (unsigned long)ieee;
 	ieee->associate_timer.function = ieee80211_associate_abort_cb;
@@ -2219,28 +2255,37 @@
 	init_timer(&ieee->beacon_timer);
 	ieee->beacon_timer.data = (unsigned long) ieee;
 	ieee->beacon_timer.function = ieee80211_send_beacon_cb;
-	
+
 #ifdef PF_SYNCTHREAD
 	ieee->wq = create_workqueue(DRV_NAME,0);
-#else	
+#else
 	ieee->wq = create_workqueue(DRV_NAME);
 #endif
-	
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
 	INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
 	INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
 	INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
 	INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
 	INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
 	INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
+#else
+	INIT_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
+	INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
+	INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
+	INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
+	INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
+	INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
+#endif
 ///	INIT_WORK(&ieee->ps_request_tx_ack_wq,(void(*)(void*))ieee->ps_request_tx_ack,ieee->dev);//for ps 07.26
-	
+
 
 	sema_init(&ieee->wx_sem, 1);
 	sema_init(&ieee->scan_sem, 1);
-	
+
 	spin_lock_init(&ieee->mgmt_tx_lock);
 	spin_lock_init(&ieee->beacon_lock);
-	
+
 	tasklet_init(&ieee->ps_task,
 	     (void(*)(unsigned long)) ieee80211_sta_ps,
 	     (unsigned long)ieee);
@@ -2250,20 +2295,20 @@
 void ieee80211_softmac_free(struct ieee80211_device *ieee)
 {
 	down(&ieee->wx_sem);
-	
+
 	del_timer_sync(&ieee->associate_timer);
 	cancel_delayed_work(&ieee->associate_retry_wq);
 	destroy_workqueue(ieee->wq);
-	
+
 	up(&ieee->wx_sem);
 }
 
-/******************************************************** 
+/********************************************************
  * Start of WPA code.                                   *
  * this is stolen from the ipw2200 driver               *
  ********************************************************/
 
- 
+
 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
 {
 	/* This is called when wpa_supplicant loads and closes the driver
@@ -2273,7 +2318,7 @@
 	return 0;
 }
 
- 
+
 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
 {
 	/* make sure WPA is enabled */
@@ -2285,7 +2330,7 @@
 
 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
 {
-	
+
 	int ret = 0;
 
 	switch (command) {
@@ -2339,7 +2384,7 @@
 
 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
 {
-	
+
 	struct ieee80211_security sec = {
 		.flags = SEC_AUTH_MODE,
 	};
@@ -2435,7 +2480,7 @@
 				  struct ieee_param *param, int param_len)
 {
 	int ret = 0;
-	
+
 	struct ieee80211_crypto_ops *ops;
 	struct ieee80211_crypt_data **crypt;
 
@@ -2600,7 +2645,7 @@
 		ret = -EINVAL;
 		goto out;
 	}
-	
+
 	param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
 	if (param == NULL){
 		ret = -ENOMEM;
@@ -2644,7 +2689,7 @@
 	kfree(param);
 out:
 	up(&ieee->wx_sem);
-	
+
 	return ret;
 }
 
diff -Naur r8187_orig/ieee80211/ieee80211_softmac_wx.c r8187_rawtx/ieee80211/ieee80211_softmac_wx.c
--- r8187_orig/ieee80211/ieee80211_softmac_wx.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_softmac_wx.c	2007-05-16 22:00:07.000000000 +0200
@@ -236,7 +236,7 @@
 int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b)
 {
-	
+	short prev = ieee->raw_tx;
 	ieee->sync_scan_hurryup = 1;
 	
 	down(&ieee->wx_sem);
@@ -246,7 +246,7 @@
 	
 	if (wrqu->mode == IW_MODE_MONITOR){
 	
-		ieee->dev->type = ARPHRD_IEEE80211;
+		ieee->dev->type = ARPHRD_IEEE80211_PRISM;
 	}else{
 		ieee->dev->type = ARPHRD_ETHER;
 	}
@@ -259,13 +259,37 @@
 		ieee80211_start_protocol(ieee);
 	}
 
+	if(ieee->iw_mode == IW_MODE_MONITOR)
+	{
+		ieee->raw_tx = 1;
+		if(prev == 0 && ieee->raw_tx){
+			if (ieee->data_hard_resume)
+				ieee->data_hard_resume(ieee->dev);
+
+			netif_carrier_on(ieee->dev);
+		}
+
+		netif_carrier_on(ieee->dev);
+	}
+	else
+	{
+		ieee->raw_tx = 0;
+	}
+
+
 out:
 	up(&ieee->wx_sem);
 	return 0;
 }
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_wx_sync_scan_wq(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
+#else
 void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
 {
+#endif
 	short chan;
 
 	chan = ieee->current_network.channel;
@@ -356,7 +380,11 @@
 	spin_lock_irqsave(&ieee->lock, flags);
 	
 	if (wrqu->essid.flags && wrqu->essid.length) {
+#if WIRELESS_EXT > 20
+		len = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
+#else
 		len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
+#endif
 		
 		strncpy(ieee->current_network.ssid, extra, len);
 		ieee->current_network.ssid_len = len;
diff -Naur r8187_orig/ieee80211/ieee80211_tx.c r8187_rawtx/ieee80211/ieee80211_tx.c
--- r8187_orig/ieee80211/ieee80211_tx.c	2007-12-05 09:53:21.000000000 +0100
+++ r8187_rawtx/ieee80211/ieee80211_tx.c	2007-05-16 22:00:07.000000000 +0200
@@ -32,7 +32,6 @@
 ******************************************************************************/
 
 #include <linux/compiler.h>
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in6.h>
@@ -52,6 +51,12 @@
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 
 
@@ -481,19 +486,19 @@
 			ieee->seq_ctrl++;
 		//---
 	}else{
-		if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
+		if (unlikely(skb->len < 14)) {
 			printk(KERN_WARNING "%s: skb too small (%d).\n",
 			ieee->dev->name, skb->len);
 			goto success;
 		}
-	
+
 		txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
 		if(!txb){
 			printk(KERN_WARNING "%s: Could not allocate TXB\n",
 			ieee->dev->name);
 			goto failed;
 		}
-		
+		txb->nr_frags = 1;
 		txb->encrypted = 0;
 		txb->payload_size = skb->len;
 		memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
diff -Naur r8187_orig/Makefile r8187_rawtx/Makefile
--- r8187_orig/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ r8187_rawtx/Makefile	2007-05-13 09:54:38.000000000 +0200
@@ -0,0 +1,36 @@
+prefix        = /lib/modules/$(shell uname -r)/kernel/drivers/net/wireless
+r8187dir      = $(prefix)/rtl8187
+ieeedir       = $(prefix)/rtl_ieee80211
+
+default: all
+
+all:
+	$(MAKE) -C ieee80211 $(@)
+	-chmod +x symvers
+	-./symvers
+	$(MAKE) -C rtl8187 $(@)
+
+install:
+	install -d $(ieeedir)
+	install -d $(r8187dir)
+	install -m 644 ./ieee80211/*.ko $(ieeedir)
+	install -m 644 ./rtl8187/*.ko $(r8187dir)
+	-depmod -ae
+
+uninstall:
+	-rm -f $(ieeedir)/ieee80211-rtl.ko
+	-rm -f $(ieeedir)/ieee80211_crypt-rtl.ko
+	-rm -f $(ieeedir)/ieee80211_crypt_ccmp-rtl.ko
+	-rm -f $(ieeedir)/ieee80211_crypt_tkip-rtl.ko
+	-rm -f $(ieeedir)/ieee80211_crypt_wep-rtl.ko
+	-rm -f $(r8187dir)/r8187.ko
+	-rm -fr $(ieeedir)
+	-rm -fr $(r8187dir)
+	-depmod -ae
+
+clean:
+	$(MAKE) -C ieee80211 $(@)
+	$(MAKE) -C rtl8187 $(@)
+
+distclean: clean
+
diff -Naur r8187_orig/rtl8187/ieee80211.h r8187_rawtx/rtl8187/ieee80211.h
--- r8187_orig/rtl8187/ieee80211.h	2007-12-05 09:50:41.000000000 +0100
+++ r8187_rawtx/rtl8187/ieee80211.h	2007-05-16 21:51:38.000000000 +0200
@@ -108,6 +108,8 @@
 #define	ieee80211_start_protocol	ieee80211_start_protocol_rtl
 #define	ieee80211_stop_protocol		ieee80211_stop_protocol_rtl
 #define	ieee80211_rx_mgt		ieee80211_rx_mgt_rtl
+#define	ieee80211_stop_queue		ieee80211_stop_queue_rtl
+#define	ieee80211_wake_queue		ieee80211_wake_queue_rtl
 
 
 typedef struct ieee_param {
@@ -193,6 +195,22 @@
 	struct list_head list;
 };
 
+#define LWNG_CAP_DID_BASE   (4 | (1 << 6)) /* section 4, group 1 */
+/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
+ * (from linux-wlan-ng) */
+struct linux_wlan_ng_val {
+	u32 did;
+	u16 status, len;
+	u32 data;
+} __attribute__ ((packed));
+
+struct linux_wlan_ng_prism_hdr {
+	u32 msgcode, msglen;
+	char devname[16];
+	struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
+		noise, rate, istx, frmlen;
+} __attribute__ ((packed));
+
 struct ieee80211_hdr {
 	u16 frame_ctl;
 	u16 duration_id;
@@ -1064,10 +1082,15 @@
 	struct timer_list beacon_timer;
 	
 	struct work_struct associate_complete_wq;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+	struct delayed_work associate_retry_wq;
+	struct delayed_work softmac_scan_wq;
+#else
 	struct work_struct associate_retry_wq;
+	struct work_struct softmac_scan_wq;
+#endif
 	struct work_struct start_ibss_wq;
 	struct work_struct associate_procedure_wq;
-	struct work_struct softmac_scan_wq;
 	struct work_struct wx_sync_scan_wq;
 	struct work_struct ps_request_tx_ack_wq;//for ps
 	struct work_struct hw_wakeup_wq;
@@ -1390,7 +1413,11 @@
 extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b);
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
+#else
 extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
+#endif
 
 extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, 
 			       struct iw_request_info *info, 
diff -Naur r8187_orig/rtl8187/r8180_hw.h r8187_rawtx/rtl8187/r8180_hw.h
--- r8187_orig/rtl8187/r8180_hw.h	2007-12-03 12:30:10.000000000 +0100
+++ r8187_rawtx/rtl8187/r8180_hw.h	2007-05-16 21:51:38.000000000 +0200
@@ -1,16 +1,16 @@
-/* 
+/*
 	This is part of rtl8187 OpenSource driver.
-	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it> 
+	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
 	Released under the terms of GPL (General Public Licence)
-	
-	Parts of this driver are based on the GPL part of the 
+
+	Parts of this driver are based on the GPL part of the
 	official Realtek driver.
-	Parts of this driver are based on the rtl8180 driver skeleton 
+	Parts of this driver are based on the rtl8180 driver skeleton
 	from Patric Schenke & Andres Salomon.
-	Parts of this driver are based on the Intel Pro Wireless 
+	Parts of this driver are based on the Intel Pro Wireless
 	2100 GPL driver.
-	
-	We want to tanks the Authors of those projects 
+
+	We want to tanks the Authors of those projects
 	and the Ndiswrapper project Authors.
 */
 
@@ -20,7 +20,7 @@
 #ifndef R8180_HW
 #define R8180_HW
 
-#define MAX_SLEEP_TIME (10000000) 
+#define MAX_SLEEP_TIME (10000000)
 #define MIN_SLEEP_TIME (50000)
 
 #define	RTL8187_RF_INDEX	0x8225
@@ -80,7 +80,7 @@
 #define EPROM_CMD_OPERATING_MODE_SHIFT 6
 #define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
 #define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0 
+#define EPROM_CMD_NORMAL 0
 #define EPROM_CMD_LOAD 1
 #define EPROM_CMD_PROGRAM 2
 #define EPROM_CS_SHIFT 3
@@ -193,8 +193,8 @@
 
 
 
-/* 
- * Operational registers offsets in PCI (I/O) space. 
+/*
+ * Operational registers offsets in PCI (I/O) space.
  * RealTek names are used.
  */
 
@@ -310,7 +310,7 @@
 /* following are for rtl8185 */
 #define RFPinsOutput 0x80
 #define RFPinsEnable 0x82
-#define RF_TIMING 0x8c 
+#define RF_TIMING 0x8c
 #define RFPinsSelect 0x84
 #define ANAPARAM2 0x60
 #define RF_PARA 0x88
@@ -339,7 +339,7 @@
 #define MIN_RESP_RATE_SHIFT 0
 #define RATE_FALLBACK 0xbe
 /*
- *  0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR) 
+ *  0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
  *  is set to 1
  */
 
@@ -380,7 +380,7 @@
 
 
 /*
- *  0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR) 
+ *  0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
  *  is set to 0
  */
 
@@ -437,7 +437,7 @@
 
 
 /*
- * Bitmasks for specific register functions. 
+ * Bitmasks for specific register functions.
  * Names are derived from the register name and function name.
  *
  * <REGISTER>_<FUNCTION>[<bit>]
@@ -501,7 +501,7 @@
 #define TCR_HWVERID_SHIFT 25
 #define TCR_SWPLCPLEN     ((1<<24))
 #define TCR_PLCP_LEN TCR_SAT // rtl8180
-#define TCR_MXDMA_MASK   ((1<<23)|(1<<22)|(1<<21)) 
+#define TCR_MXDMA_MASK   ((1<<23)|(1<<22)|(1<<21))
 #define TCR_MXDMA_1024 6
 #define TCR_MXDMA_2048 7
 #define TCR_MXDMA_SHIFT  21
diff -Naur r8187_orig/rtl8187/r8180_rtl8225.h r8187_rawtx/rtl8187/r8180_rtl8225.h
--- r8187_orig/rtl8187/r8180_rtl8225.h	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/rtl8187/r8180_rtl8225.h	2007-05-16 21:51:38.000000000 +0200
@@ -48,4 +48,5 @@
 
 extern u32 rtl8225_chan[];
 
+void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
 #endif
diff -Naur r8187_orig/rtl8187/r8180_wx.c r8187_rawtx/rtl8187/r8180_wx.c
--- r8187_orig/rtl8187/r8180_wx.c	2007-03-02 04:22:29.000000000 +0100
+++ r8187_rawtx/rtl8187/r8180_wx.c	2007-05-16 21:51:33.000000000 +0200
@@ -21,7 +21,7 @@
 
 #include "r8187.h"
 #include "r8180_hw.h"
-
+#include "r8180_rtl8225.h"
 
 //#define RATE_COUNT 4
 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
@@ -121,22 +121,72 @@
 	return ret;
 }
 
-static int r8180_wx_set_rawtx(struct net_device *dev, 
-			       struct iw_request_info *info, 
-			       union iwreq_data *wrqu, char *extra)
+static int r8180_wx_get_txpow(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-	
+	int i=0;
 	down(&priv->wx_sem);
-	
-	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
-	
+	wrqu->power.value = 0;
+	for(i=0; i<15; i++)
+	{
+		if(priv->chtxpwr[i] > wrqu->power.value) wrqu->power.value = priv->chtxpwr[i];
+		if(priv->chtxpwr_ofdm[i] > wrqu->power.value) wrqu->power.value = priv->chtxpwr_ofdm[i];
+	}
+	wrqu->power.fixed = 1;
+	wrqu->power.flags = IW_TXPOW_DBM;
+	wrqu->power.disabled = 0;
 	up(&priv->wx_sem);
-	
+
+	return 0;
+}
+
+#if 1
+static int r8180_wx_set_txpow(struct net_device *dev,
+			      struct iw_request_info *info,
+			      union iwreq_data *wrqu, char *extra)
+{
+	int ret = 0, i=0;
+	struct r8180_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	if (wrqu->power.flags != IW_TXPOW_DBM)
+	{
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if(wrqu->power.value > priv->txpwr_max)
+	{
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if(wrqu->power.value < 0)
+	{
+		ret = -EINVAL;
+		goto out;
+	}
+
+	for(i=1;i<15;i++)
+	{
+		priv->chtxpwr[i] = priv->chtxpwr_orig[i] - (priv->txpwr_max - wrqu->power.value);
+		if(priv->chtxpwr[i] > priv->chtxpwr_orig[i]) priv->chtxpwr[i] = 0;
+
+		priv->chtxpwr_ofdm[i] = priv->chtxpwr_ofdm_orig[i] - (priv->txpwr_max - wrqu->power.value);
+		if(priv->chtxpwr_ofdm[i] > priv->chtxpwr_ofdm_orig[i]) priv->chtxpwr_ofdm[i] = 0;
+	}
+	rtl8225z2_SetTXPowerLevel(dev, 1);
+
+	out:
+	up(&priv->wx_sem);
+
 	return ret;
 	 
 }
+#endif
 
 static int r8180_wx_set_rts(struct net_device *dev, 
 			     struct iw_request_info *info, 
@@ -836,6 +886,7 @@
 
 }
 
+#if 0
 static int r8180_wx_radio_on(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
@@ -871,6 +922,7 @@
 	return 0;
 
 }
+#endif
 
 static int r8180_wx_set_channelplan(struct net_device *dev, 
 			     struct iw_request_info *info, 
@@ -965,8 +1017,8 @@
         r8180_wx_get_rts,                    /* SIOCGIWRTS */
         r8180_wx_set_frag,        /* SIOCSIWFRAG */
         r8180_wx_get_frag,        /* SIOCGIWFRAG */
-        dummy,                    /* SIOCSIWTXPOW */
-        dummy,                    /* SIOCGIWTXPOW */
+        r8180_wx_set_txpow,       /* SIOCSIWTXPOW */
+        r8180_wx_get_txpow,       /* SIOCGIWTXPOW */
         r8180_wx_set_retry,       /* SIOCSIWRETRY */
         r8180_wx_get_retry,       /* SIOCGIWRETRY */
         r8180_wx_set_enc,         /* SIOCSIWENCODE */
@@ -1007,7 +1059,7 @@
 	},
 	{
 		SIOCIWFIRSTPRIV + 0x6, 
-		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" 
+		0, 0, "dummy" 
 	},
 	{	SIOCIWFIRSTPRIV + 0x7, 
 		0, 0, "dummy" 
@@ -1053,11 +1105,11 @@
  	},
 	{
 		SIOCIWFIRSTPRIV + 0x12, 
-		0, 0, "radioon"
+		0, 0, "dummy"
  	},
 	{
 		SIOCIWFIRSTPRIV + 0x13, 
-		0, 0, "radiooff"
+		0, 0, "dummy"
  	},
 	{
 		SIOCIWFIRSTPRIV + 0x14, 
@@ -1089,7 +1141,7 @@
 	dummy,
 	r8180_wx_set_scan_type,
 	dummy,
-	r8180_wx_set_rawtx,
+	dummy,
 	dummy,
 	r8180_wx_set_iwmode,
 	r8180_wx_get_iwmode,
@@ -1101,8 +1153,8 @@
 	r8180_wx_get_sigqual,
 	r8180_wx_reset_stats,
 	dummy,
-	r8180_wx_radio_on,
-	r8180_wx_radio_off,
+	dummy,
+	dummy,
 	r8180_wx_set_channelplan,
 	r8180_wx_get_channelplan,
 	dummy,
diff -Naur r8187_orig/rtl8187/r8187_core.c r8187_rawtx/rtl8187/r8187_core.c
--- r8187_orig/rtl8187/r8187_core.c	2007-03-28 08:39:13.000000000 +0200
+++ r8187_rawtx/rtl8187/r8187_core.c	2007-05-16 21:51:33.000000000 +0200
@@ -1,27 +1,27 @@
 /*
    This is part of rtl8187 OpenSource driver - v 0.1
-   Copyright (C) Andrea Merello 2005  <andreamrl@tiscali.it> 
+   Copyright (C) Andrea Merello 2005  <andreamrl@tiscali.it>
    Released under the terms of GPL (General Public License)
-   
-   
-   Parts of this driver are based on the rtl8180 driver skeleton 
+
+
+   Parts of this driver are based on the rtl8180 driver skeleton
    from Patric Schenke & Andres Salomon.
 
    Parts of this driver are based on the Intel Pro Wireless 2*00 GPL drivers.
-   
+
    some ideas might be derived from David Young rtl8180 netbsd driver.
-   
+
    Parts of the usb code are from the r8150.c driver in linux kernel
-   
+
    Some ideas borrowed from the 8139too.c driver included in linux kernel.
-   
-   We (I?) want to thanks the Authors of those projecs and also the 
+
+   We (I?) want to thanks the Authors of those projecs and also the
    Ndiswrapper's project Authors.
-   
-   A special big thanks goes also to Realtek corp. for their help in my 
-   attempt to add RTL8187 and RTL8225 support, and to David Young also. 
 
-	- Please note that this file is a modified version from rtl8180-sa2400 
+   A special big thanks goes also to Realtek corp. for their help in my
+   attempt to add RTL8187 and RTL8225 support, and to David Young also.
+
+	- Please note that this file is a modified version from rtl8180-sa2400
 	drv. So some other people have contributed to this project, and they are
 	thanked in the rtl8180-sa2400 CHANGELOG.
 */
@@ -83,6 +83,10 @@
 #define USB_VENDOR_ID_NETGEAR		0x0846
 #endif
 
+#if !(defined(CONFIG_USB_EHCI_HCD) || defined (CONFIG_USB_EHCI_HCD_MODULE))
+	#error	Build your kernel with ehci_hcd support!
+#endif
+
 static struct usb_device_id rtl8187_usb_id_tbl[] = {
 	{USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8187)},
 	{USB_DEVICE(USB_VENDOR_ID_NETGEAR, 0x6100)},
@@ -137,7 +141,7 @@
 
 static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id);
-			 
+
 static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf);
 
 static struct usb_driver rtl8187_usb_driver = {
@@ -161,10 +165,10 @@
 
 void write_nic_byte_E(struct net_device *dev, int indx, u8 data)
 {
-	
+
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
 			       indx|0xfe00, 0, &data, 1, HZ / 2);
@@ -173,10 +177,10 @@
 
 void write_nic_byte(struct net_device *dev, int indx, u8 data)
 {
-	
+
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
 			       indx|0xff00, 0, &data, 1, HZ / 2);
@@ -185,10 +189,10 @@
 
 void write_nic_word(struct net_device *dev, int indx, u16 data)
 {
-	
+
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
 			       indx|0xff00, 0, &data, 2, HZ / 2);
@@ -197,23 +201,23 @@
 
 void write_nic_dword(struct net_device *dev, int indx, u32 data)
 {
-	
+
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
 			       indx|0xff00, 0, &data, 4, HZ / 2);
 }
- 
- 
- 
+
+
+
 u8 read_nic_byte(struct net_device *dev, int indx)
 {
 	u8 data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
 			       indx|0xff00, 0, &data, 1, HZ / 2);
@@ -225,20 +229,20 @@
 	u8 data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
 			       indx|0xfe00, 0, &data, 1, HZ / 2);
 	return data;
 }
 
- 
+
 u16 read_nic_word(struct net_device *dev, int indx)
 {
 	u16 data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
 			       indx|0xff00, 0, &data, 2, HZ / 2);
@@ -251,14 +255,14 @@
 	u32 data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
-	
+
 	usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
 			       indx|0xff00, 0, &data, 4, HZ / 2);
 	return data;
 }
 
-/* this might still called in what was the PHY rtl8185/rtl8187 common code 
+/* this might still called in what was the PHY rtl8185/rtl8187 common code
  * plans are to possibilty turn it again in one common code...
  */
 inline void force_pci_posting(struct net_device *dev)
@@ -271,8 +275,17 @@
 //void set_nic_txring(struct net_device *dev);
 static struct net_device_stats *rtl8180_stats(struct net_device *dev);
 void rtl8180_commit(struct net_device *dev);
-void rtl8180_restart(struct net_device *dev);
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_rq_tx_ack(struct work_struct *work);
+#else
 void rtl8180_rq_tx_ack(struct net_device *dev);
+#endif
+
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_restart(struct work_struct *work);
+#else
+void rtl8180_restart(struct net_device *dev);
+#endif
 
 /****************************************************************************
    -----------------------------PROCFS STUFF-------------------------
@@ -286,12 +299,12 @@
 {
 	struct net_device *dev = data;
 //	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	int len = 0;
 	int i,n;
-			
+
 	int max=0xff;
-	
+
 	/* This dump the current register page */
 	for(n=0;n<=max;)
 	{
@@ -308,7 +321,7 @@
 	len += snprintf(page + len, count - len,"\n");
 
 
-		
+
 	*eof = 1;
 	return len;
 
@@ -321,15 +334,15 @@
 {
 	struct net_device *dev = data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	int len = 0;
-	
+
 	len += snprintf(page + len, count - len,
 		"NIC int: %lu\n"
 		"Total int: %lu\n",
 		priv->stats.ints,
 		priv->stats.shints);
-			
+
 	*eof = 1;
 	return len;
 }
@@ -341,12 +354,12 @@
 {
 	struct net_device *dev = data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	int len = 0;
 	unsigned long totalOK;
 	totalOK=priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint;
 
-	
+
 	len += snprintf(page + len, count - len,
 	/*	"TX normal priority ok int: %lu\n"
 		"TX normal priority error int: %lu\n"
@@ -363,7 +376,7 @@
 		"TX HW queue: %d\n"
 		"TX lp dropped: %lu\n"
 		"TX np dropped: %lu\n"
-		"TX total data packets %lu\n",		
+		"TX total data packets %lu\n",
 //		"TX beacon aborted: %lu\n",
 		priv->stats.txnpokint,
 		priv->stats.txnperr,
@@ -391,13 +404,13 @@
 		priv->stats.txerr,
 		priv->stats.txretry,
 		priv->stats.txbeaconok,
-		priv->stats.txbeaconerr		
+		priv->stats.txbeaconerr
 
 		);
-			
+
 	*eof = 1;
 	return len;
-}		
+}
 
 
 
@@ -407,9 +420,9 @@
 {
 	struct net_device *dev = data;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	int len = 0;
-	
+
 	len += snprintf(page + len, count - len,
 		/*"RX packets: %lu\n"
 		"RX urb status error: %lu\n"
@@ -431,21 +444,22 @@
 		priv->stats.rxicverr
 
 	);
-			
+
 	*eof = 1;
 	return len;
-}		
-
+}
 
+#if WIRELESS_EXT < 17
 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
        return &priv->wstats;
 }
+#endif
 
 void rtl8180_proc_module_init(void)
-{	
+{
 	DMESG("Initializing proc filesystem");
 	rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, proc_net);
 }
@@ -477,8 +491,8 @@
 {
 	struct proc_dir_entry *e;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	priv->dir_dev = create_proc_entry(dev->name, 
-					  S_IFDIR | S_IRUGO | S_IXUGO, 
+	priv->dir_dev = create_proc_entry(dev->name,
+					  S_IFDIR | S_IRUGO | S_IXUGO,
 					  rtl8180_proc);
 	if (!priv->dir_dev) {
 		DMESGE("Unable to initialize /proc/net/rtl8187/%s\n",
@@ -488,7 +502,7 @@
 	#if 0
 	e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_hw, dev);
-				   
+
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/rtl8187/%s/stats-hw\n",
@@ -497,17 +511,17 @@
 	#endif
 	e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_rx, dev);
-				   
+
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/rtl8187/%s/stats-rx\n",
 		      dev->name);
 	}
-	
-	
+
+
 	e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_tx, dev);
-				   
+
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/rtl8187/%s/stats-tx\n",
@@ -516,27 +530,27 @@
 	#if 0
 	e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_ieee, dev);
-				   
+
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/rtl8187/%s/stats-ieee\n",
 		      dev->name);
 	}
-	
-	
+
+
 	e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_ap, dev);
-				   
+
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/rtl8187/%s/stats-ap\n",
 		      dev->name);
 	}
 	#endif
-	
+
 	e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_registers, dev);
-	
+
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/rtl8187/%s/registers\n",
@@ -552,14 +566,14 @@
 {
 	int i;
 	u8 *buf =(u8*)buffer;
-	
+
 	printk("ASCII BUFFER DUMP (len: %x):\n",len);
-	
+
 	for(i=0;i<len;i++)
 		printk("%c",buf[i]);
-		
+
 	printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
-	
+
 	for(i=0;i<len;i++)
 		printk("%x",buf[i]);
 
@@ -569,10 +583,10 @@
 short check_nic_enought_desc(struct net_device *dev, priority_t priority)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	
-	int used = atomic_read((priority == NORM_PRIORITY) ? 
+
+	int used = atomic_read((priority == NORM_PRIORITY) ?
 		&priv->tx_np_pending : &priv->tx_lp_pending);
-	
+
 	return (used < MAX_TX_URB);
 }
 
@@ -600,9 +614,9 @@
 	int i;
 	int n;
 	int max=0xff;
-	
-	DMESG("Dumping NIC register map");	
-	
+
+	DMESG("Dumping NIC register map");
+
 	for(n=0;n<=max;)
 	{
 		printk( "\nD: %2x> ", n);
@@ -619,11 +633,11 @@
 
 void rtl8180_irq_enable(struct net_device *dev)
 {
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);	
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	//priv->irq_enabled = 1;
 /*
-	write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\ 
-	INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\ 
+	write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
+	INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
 	INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
 	INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
 */
@@ -633,7 +647,7 @@
 
 void rtl8180_irq_disable(struct net_device *dev)
 {
-//	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);	
+//	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	write_nic_word(dev,INTA_MASK,0);
 	force_pci_posting(dev);
@@ -657,27 +671,27 @@
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	u8 msr;
-	
+
 	msr  = read_nic_byte(dev, MSR);
 	msr &= ~ MSR_LINK_MASK;
-	
+
 	/* do not change in link_state != WLAN_LINK_ASSOCIATED.
-	 * msr must be updated if the state is ASSOCIATING. 
+	 * msr must be updated if the state is ASSOCIATING.
 	 * this is intentional and make sense for ad-hoc and
 	 * master (see the create BSS/IBSS func)
 	 */
-	if (priv->ieee80211->state == IEEE80211_LINKED){ 
-			
+	if (priv->ieee80211->state == IEEE80211_LINKED){
+
 		if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
 			msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
 		else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
 			msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
 		else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
 			msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
-		
+
 	}else
 		msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
-		
+
 	write_nic_byte(dev, MSR, msr);
 }
 
@@ -687,20 +701,20 @@
 	u32 tx;
 	priv->chan=ch;
 	#if 0
-	if(priv->ieee80211->iw_mode == IW_MODE_ADHOC || 
+	if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
 		priv->ieee80211->iw_mode == IW_MODE_MASTER){
-	
-			priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;	
+
+			priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
 			priv->ieee80211->master_chan = ch;
-			rtl8180_update_beacon_ch(dev); 
+			rtl8180_update_beacon_ch(dev);
 		}
 	#endif
-	
+
 	/* this hack should avoid frame TX during channel setting*/
 	tx = read_nic_dword(dev,TX_CONF);
 	tx &= ~TX_LOOPBACK_MASK;
 
-#ifndef LOOP_TEST	
+#ifndef LOOP_TEST
 	write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
 
 	priv->rf_set_chan(dev,priv->chan);
@@ -715,25 +729,25 @@
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	int err;
-	
+
 //	u8 *rx;
-	
+
 	//DMESG("starting RX");
 	/*rx = kmalloc(RX_URB_SIZE*sizeof(u8),GFP_ATOMIC);
-	if(!rx){ 
+	if(!rx){
 		DMESGE("unable to allocate RX buffer");
 		return;
 	}*/
-	
+
 	usb_fill_bulk_urb(rx_urb,priv->udev,
 		usb_rcvbulkpipe(priv->udev,0x81), rx_urb->transfer_buffer,
-			RX_URB_SIZE,rtl8187_rx_isr,dev);
-	err = usb_submit_urb(rx_urb, GFP_ATOMIC);	
+			RX_URB_SIZE,rtl8187_rx_isr, dev);
+	err = usb_submit_urb(rx_urb, GFP_ATOMIC);
 	if(err && err != -EPERM){
 		DMESGE("cannot submit RX command. URB_STATUS %x",rx_urb->status);
-		
+
 	}
-	
+
 }
 
 
@@ -741,30 +755,30 @@
 {
 	int i;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	if(!priv->rx_urb)
 		DMESGE("Cannot intiate RX urb mechanism");
-	for(i=0;i<MAX_RX_URB;i++) // RX_MAX_URB is 1 
+	for(i=0;i<MAX_RX_URB;i++) // RX_MAX_URB is 1
 		rtl8187_rx_urbsubmit(dev,priv->rx_urb[i]);
 	priv->tx_urb_index = 0;
-		
+
 }
 
 void rtl8187_set_rxconf(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u32 rxconf;
-	
+
 	rxconf=read_nic_dword(dev,RX_CONF);
 	rxconf = rxconf &~ MAC_FILTER_MASK;
 	rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
 	rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
 	rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
 	rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
-	rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);	
+	rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
 
 	if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
-	
+
 	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
 	   dev->flags & IFF_PROMISC){
 		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
@@ -772,40 +786,40 @@
 		rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
 		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
 	}
-	
+
 	/*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
 		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
 		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
 	}*/
-	
+
 	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
 		rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
 		rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
 	}
-	
+
 	if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
 		rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
-	
-	
+
+
 	rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
 	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
-	
-	
+
+
 	rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
-	
+
 	rxconf = rxconf &~ MAX_RX_DMA_MASK;
 	rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
-	
+
 	rxconf = rxconf | RCR_ONLYERLPKT;
-	
+
 //	rxconf = rxconf &~ RCR_CS_MASK;
 //	rxconf = rxconf | (1<<RCR_CS_SHIFT);
 
-	write_nic_dword(dev, RX_CONF, rxconf);	
-	
+	write_nic_dword(dev, RX_CONF, rxconf);
+
 	// V rtl suggested V //
 //	write_nic_dword(dev, RX_CONF, 0x901ce70e);
-	
+
 	//fix_rx_fifo(dev);
 // 	//set_nic_rxring(dev);
 	#ifdef DEBUG_RX
@@ -816,23 +830,23 @@
 void rtl8180_rx_enable(struct net_device *dev)
 {
 	u8 cmd;
-	
-	
+
+
 	rtl8187_rx_initiate(dev);
 
-	rtl8187_set_rxconf(dev);	
+	rtl8187_set_rxconf(dev);
 
 	cmd=read_nic_byte(dev,CMD);
 	write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
 #if 0
-	/* In rtl8139 driver seems that DMA threshold has to be written 
-	 *  after enabling RX, so we rewrite RX_CONFIG register 
+	/* In rtl8139 driver seems that DMA threshold has to be written
+	 *  after enabling RX, so we rewrite RX_CONFIG register
 	 */
 	//mdelay(100);
-	write_nic_dword(dev, RX_CONF, rxconf); 
-	
+	write_nic_dword(dev, RX_CONF, rxconf);
+
 #endif
-	
+
 }
 
 
@@ -842,36 +856,36 @@
 	u8 byte;
 	u32 txconf;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	byte = read_nic_byte(dev,CW_CONF);
 	byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
 	byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
 	write_nic_byte(dev, CW_CONF, byte);
-	
+
 	byte = read_nic_byte(dev, TX_AGC_CTL);
 	byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
 	byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
 	byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
 	write_nic_byte(dev, TX_AGC_CTL, byte);
-	
+
 	txconf= read_nic_dword(dev,TX_CONF);
-	
+
 	#if 0
 	if(priv->card_8185){
-		
+
 		txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
-	
+
 	}else{
-	
-		if(priv->ieee80211->hw_seq) 
+
+		if(priv->ieee80211->hw_seq)
 			txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
-		else 
+		else
 			txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
 	}
 	#endif
 
 	txconf = txconf &~ TX_LOOPBACK_MASK;
-	
+
 #ifndef LOOP_TEST
 	txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
 #else
@@ -879,23 +893,26 @@
 #endif
 	txconf = txconf &~ TCR_DPRETRY_MASK;
 	txconf = txconf &~ TCR_RTSRETRY_MASK;
-	
-	txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT); // long
-	txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT); // short
-	
+
+	if(priv->ieee80211->iw_mode != IW_MODE_MONITOR)
+	{
+		txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT); // long
+		txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT); // short
+	}
+
 	txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
-	
+
 	txconf = txconf &~ TCR_MXDMA_MASK;
 	txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
-	
+
 	txconf = txconf | TCR_CWMIN;
 	txconf = txconf | TCR_DISCW;
 	txconf = txconf &~ TCR_SWPLCPLEN;
-	
+
 	txconf=txconf | (1<<TX_NOICV_SHIFT);
-	
+
 	write_nic_dword(dev,TX_CONF,txconf);
-	
+
 	// V RTL suggested V //
 //	write_nic_dword(dev,TX_CONF,0x00e00707);
 
@@ -903,9 +920,9 @@
 #ifdef DEBUG_TX
 	DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
 #endif
-	
+
 	cmd=read_nic_byte(dev,CMD);
-	write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));		
+	write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
 
 //	mdelay(100);
 	//write_nic_dword(dev,TX_CONF,txconf);
@@ -923,13 +940,13 @@
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);	
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 }
 
 
 void rtl8180_
-_disable(struct net_device *dev) 
+_disable(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
@@ -946,7 +963,7 @@
 	u8 cmd;
 	int i;
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	
+
 	cmd=read_nic_byte(dev,CMD);
 	write_nic_byte(dev, CMD, cmd &~ \
 		       ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
@@ -957,9 +974,9 @@
 		usb_kill_urb(priv->rx_urb[i]);
 	}
 	/*while (read_nic_byte(dev,CMD) & (1<<CMD_RX_ENABLE_SHIFT))
-	  udelay(10); 
+	  udelay(10);
 	*/
-	
+
 //	if(!priv->rx_skb_complete)
 //		dev_kfree_skb_any(priv->rx_skb);
 }
@@ -971,13 +988,13 @@
 	int i;
 	u32 *tmp;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
-					  sizeof(u32)*8*count, 
+					  sizeof(u32)*8*count,
 					  &priv->txbeaconringdma);
 	if (!priv->txbeaconring) return -1;
 	for (tmp=priv->txbeaconring,i=0;i<count;i++){
-		*tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv 
+		*tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
 		/*
 		*(tmp+2) = (u32)dma_tmp;
 		*(tmp+3) = bufsize;
@@ -986,7 +1003,7 @@
 			*(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
 		else
 			*(tmp+4) = (u32)priv->txbeaconringdma;
-		
+
 		tmp=tmp+8;
 	}
 	#endif
@@ -996,15 +1013,15 @@
 
 void rtl8180_reset(struct net_device *dev)
 {
-	
+
 	u8 cr;
-	
+
 	/* make sure the analog power is on before
 	 * reset, otherwise reset may fail
 	 */
 	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
 	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-	
+
 	rtl8180_irq_disable(dev);
 
 	mdelay(200);
@@ -1012,19 +1029,19 @@
 	write_nic_byte_E(dev,0x18,0x11);
 	write_nic_byte_E(dev,0x18,0x00);
 	mdelay(200);
-	
+
 	cr=read_nic_byte(dev,CMD);
 	cr = cr & 2;
 	cr = cr | (1<<CMD_RST_SHIFT);
 	write_nic_byte(dev,CMD,cr);
-	
+
 	force_pci_posting(dev);
-	
+
 	mdelay(200);
-	
-	if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT)) 
+
+	if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
 		DMESGW("Card reset timeout!");
-	else 
+	else
 		DMESG("Card successfully reset");
 
 	rtl8180_set_mode(dev,EPROM_CMD_LOAD);
@@ -1036,13 +1053,13 @@
 	 */
 	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
 	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-	
+
 }
 
 inline u16 ieeerate2rtlrate(int rate)
 {
 	switch(rate){
-	case 10:	
+	case 10:
 	return 0;
 	case 20:
 	return 1;
@@ -1068,14 +1085,14 @@
 	return 11;
 	default:
 	return 3;
-	
+
 	}
 }
 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
 inline u16 rtl8180_rate2rate(short rate)
 {
 	if (rate >11) return 0;
-	return rtl_rate[rate]; 
+	return rtl_rate[rate];
 }
 
 
@@ -1089,49 +1106,49 @@
 u16 N_DBPSOfRate(u16 DataRate)
 {
 	 u16 N_DBPS = 24;
-	 
+
 	 switch(DataRate)
 	 {
 	 case 60:
 	  N_DBPS = 24;
 	  break;
-	 
+
 	 case 90:
 	  N_DBPS = 36;
 	  break;
-	 
+
 	 case 120:
 	  N_DBPS = 48;
 	  break;
-	 
+
 	 case 180:
 	  N_DBPS = 72;
 	  break;
-	 
+
 	 case 240:
 	  N_DBPS = 96;
 	  break;
-	 
+
 	 case 360:
 	  N_DBPS = 144;
 	  break;
-	 
+
 	 case 480:
 	  N_DBPS = 192;
 	  break;
-	 
+
 	 case 540:
 	  N_DBPS = 216;
 	  break;
-	 
+
 	 default:
 	  break;
 	 }
-	 
+
 	 return N_DBPS;
 }
 
-u16 ComputeTxTime( 
+u16 ComputeTxTime(
 	u16		FrameLength,
 	u16		DataRate,
 	u8		bManagementFrame,
@@ -1146,7 +1163,7 @@
 	{
 		if( bManagementFrame || !bShortPreamble || DataRate == 10 )
 		{	// long preamble
-			FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));		
+			FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
 		}
 		else
 		{	// Short preamble
@@ -1156,14 +1173,14 @@
 				FrameTime ++;
 	} else {	//802.11g DSSS-OFDM PLCP length field calculation.
 		N_DBPS = N_DBPSOfRate(DataRate);
-		Ceiling = (16 + 8*FrameLength + 6) / N_DBPS 
+		Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
 				+ (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
 		FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
 	}
 	return FrameTime;
 }
 
-		
+
 #if 0
 void rtl8187_rx_isr(struct urb *rx_urb, struct pt_regs *regs)
 {
@@ -1172,7 +1189,7 @@
 
 	priv->rxurb_task = rx_urb;
 //	DMESGW("David: Rx tasklet start!");
-	tasklet_schedule(&priv->irq_rx_tasklet);	
+	tasklet_schedule(&priv->irq_rx_tasklet);
 //	DMESGW("=David: Rx tasklet finish!");
 }
 #endif
@@ -1223,13 +1240,14 @@
 void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
-	short morefrag = 0;	
+
+	short morefrag = 0;
 	unsigned long flags;
 	struct ieee80211_hdr *h = (struct ieee80211_hdr  *) skb->data;
 
-	if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS)
-		morefrag = 1;
+	if(priv->ieee80211->iw_mode != IW_MODE_MONITOR)
+		if (le16_to_cpu(h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS)
+			morefrag = 1;
 //	DMESG("%x %x", h->frame_ctl, h->seq_ctl);
 	/*
 	* This function doesn't require lock because we make
@@ -1238,25 +1256,24 @@
 	* the ieee stack, or from the try_wake_queue (again trought
 	* the ieee stack.
 	*/
-	spin_lock_irqsave(&priv->tx_lock,flags);	
-			
+	spin_lock_irqsave(&priv->tx_lock,flags);
+
 	//DMESG("TX");
 	if (!check_nic_enought_desc(dev, LOW_PRIORITY)){
 		DMESG("Error: no TX slot ");
 		ieee80211_stop_queue(priv->ieee80211);
 	}
-	
-	
+
 	rtl8180_tx(dev, skb->data, skb->len, LOW_PRIORITY, morefrag,
 		ieeerate2rtlrate(rate));
 
 	priv->stats.txdatapkt++;
-	
+
 	if (!check_nic_enought_desc(dev, LOW_PRIORITY))
 		ieee80211_stop_queue(priv->ieee80211);
-		
-	spin_unlock_irqrestore(&priv->tx_lock,flags);	
-			
+
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+
 }
 #if 0
 /* This is a rough attempt to TX a frame
@@ -1269,9 +1286,9 @@
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	int ret;
 	unsigned long flags;
-	
+
 	spin_lock_irqsave(&priv->tx_lock,flags);
-	
+
 	ret = rtl8180_tx(dev, (u32*)skb->data, skb->len, NORM_PRIORITY, 0,DEFAULT_BASICRATE);
 /*
 	int i;
@@ -1281,9 +1298,9 @@
 */
 	priv->ieee80211->stats.tx_bytes+=skb->len;
 	priv->ieee80211->stats.tx_packets++;
-	
-	spin_unlock_irqrestore(&priv->tx_lock,flags);	
-	
+
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+
 	dev_kfree_skb_any(skb);
 	return ret;
 }
@@ -1296,7 +1313,7 @@
 	u16 duration;
 	u16 drift;
 	*ext=0;
-	
+
 	switch(rate){
 	case 0://1mbps
 		*ext=0;
@@ -1305,7 +1322,7 @@
 		if(drift ==0 ) break;
 		duration++;
 		break;
-		
+
 	case 1://2mbps
 		*ext=0;
 		duration = ((len+4)<<4) /0x4;
@@ -1313,30 +1330,30 @@
 		if(drift ==0 ) break;
 		duration++;
 		break;
-		
+
 	case 2: //5.5mbps
 		*ext=0;
 		duration = ((len+4)<<4) /0xb;
 		drift = ((len+4)<<4) % 0xb;
-		if(drift ==0 ) 
+		if(drift ==0 )
 			break;
 		duration++;
 		break;
-		
+
 	default:
-	case 3://11mbps				
+	case 3://11mbps
 		*ext=0;
 		duration = ((len+4)<<4) /0x16;
 		drift = ((len+4)<<4) % 0x16;
-		if(drift ==0 ) 
+		if(drift ==0 )
 			break;
 		duration++;
-		if(drift > 6) 
+		if(drift > 6)
 			break;
 		*ext=1;
 		break;
 	}
-	
+
 	return duration;
 }
 #endif
@@ -1369,10 +1386,10 @@
 	if ((msrm == (MSR_LINK_ADHOC<<MSR_LINK_SHIFT) ||
 		(msrm == (MSR_LINK_MASTER<<MSR_LINK_SHIFT)))){
 		write_nic_byte(dev, MSR, msr2 | MSR_LINK_NONE);
-		write_nic_byte(dev, MSR, msr);	
+		write_nic_byte(dev, MSR, msr);
 	}
-	
-	 
+
+
 }
 
 
@@ -1382,21 +1399,21 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_network *net;
 	net = & priv->ieee80211->current_network;
-	
-	
+
+
 	write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
 	write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
 	//for(i=0;i<ETH_ALEN;i++)
 	//	write_nic_byte(dev,BSSID+i,net->bssid[i]);
 
 	rtl8180_update_msr(dev);
-		
+
 //	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
 	write_nic_word(dev, AtimWnd, 2);
-	write_nic_word(dev, AtimtrItv, 100);	
+	write_nic_word(dev, AtimtrItv, 100);
 	write_nic_word(dev, BEACON_INTERVAL, net->beacon_interval);
 	write_nic_word(dev, BcnIntTime, 100);
-	
+
 
 }
 
@@ -1406,18 +1423,18 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	struct sk_buff *skb;
 	int i = 0;
-	
+
 	rtl8187_net_update(dev);
-	
+
 	skb = ieee80211_get_beacon(priv->ieee80211);
-	
-	
-	if(!skb){ 
+
+
+	if(!skb){
 		DMESG("not enought memory for allocating beacon");
 		return;
 	}
-	
-#if 0	
+
+#if 0
 	while(MAX_TX_URB!=atomic_read(&priv->tx_np_pending)){
 		msleep_interruptible_rtl(HZ/2);
 		if(i++ > 20){
@@ -1427,7 +1444,7 @@
 	}
 #endif
 	write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
-	
+
 	i=0;
 	//while(!read_nic_byte(dev,BQREQ & (1<<7)))
 	while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
@@ -1438,7 +1455,7 @@
 			return ;
 		}
 	}
-		
+
 	rtl8180_tx(dev, skb->data, skb->len, NORM_PRIORITY,
 		0, priv->ieee80211->basic_rate);
 
@@ -1461,15 +1478,15 @@
 }
 
 
-/* This function do the real dirty work: it sends a TX command 
- * descriptor plus data URB 
+/* This function do the real dirty work: it sends a TX command
+ * descriptor plus data URB
  */
- 
+
 short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, priority_t priority,
 		 short morefrag, short rate)
 {
 	//u32 *tx;
-	u8 *tx; 
+	u8 *tx;
 	u8 *pdata;
 	u8 seg = ((u32)txbuf % 4);
 	u32 *pdata32;
@@ -1480,7 +1497,7 @@
 	int pend;
 	int status;
 	struct urb *tx_urb;
-	int urb_len;	
+	int urb_len;
 	u16	AckCtsTime;
 	u16	FrameTime;
 	u16 duration;
@@ -1498,20 +1515,20 @@
 			priv->stats.txlpdrop++;
 		return -1;
 	}
-		
-#if 0	
+
+#if 0
 	//tx = kmalloc((len + 4*3), GFP_ATOMIC);
 	urb_len = len + 4*3;
 	if((0 == urb_len%64)||(0 == urb_len%512)) {
-	  urb_len += 1;	  
+	  urb_len += 1;
 	}
 	tx = kmalloc(urb_len, GFP_ATOMIC);
 	if(!tx) return -ENOMEM;
-	//printk(KERN_WARNING "urb_len = %d\n", urb_len);	
+	//printk(KERN_WARNING "urb_len = %d\n", urb_len);
 	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
-	
+
 	if(!tx_urb){
-		
+
 		kfree(tx);
 		return -ENOMEM;
 	}
@@ -1519,7 +1536,7 @@
 	//urb_len = TX_URB_SIZE;
 	urb_len = len + 4*3;
 	if((0 == urb_len%64)||(0 == urb_len%512)) {
-	  urb_len += 1;	  
+	  urb_len += 1;
 	}
 
 	tx_urb = priv->tx_context[priv->tx_urb_index].tx_urb;
@@ -1527,7 +1544,7 @@
 	pdata = tx + 12;
 	priv->tx_urb_index = (priv->tx_urb_index + 1) % MAX_TX_URB;
 #endif
-#if 0	
+#if 0
 	memcpy(tx+3,txbuf,len);
 	tx[0] = 0;
 	tx[0] |= len & 0xfff;
@@ -1535,7 +1552,7 @@
 //	printk(KERN_INFO "preamble mode %d,rate %d!\n",priv->plcp_preamble_mode,rate);
 	if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE)
 		if (priv->plcp_preamble_mode==1 && rate!=0) {	//  short mode now, not long!
-			tx[0] |= (1<<16);	
+			tx[0] |= (1<<16);
 //			printk(KERN_INFO "use short preamble!\n");
 		}			// enable short preamble mode.
 
@@ -1548,11 +1565,11 @@
 			AckCtsTime = ComputeTxTime(14, 10,0, 0);	// AckCTSLng = 14 use 1M bps send
 			FrameTime = ComputeTxTime(len + 4, rtl8180_rate2rate(rate), 0, tx[0]&(1<<16));
 			// RTS/CTS time is calculate as follow
-			duration = FrameTime + 3*10 + 2*AckCtsTime;	//10us is the SifsTime;	
+			duration = FrameTime + 3*10 + 2*AckCtsTime;	//10us is the SifsTime;
 			tx[1] |= duration; 	//Need to edit here!  ----hikaru
 			printk(KERN_INFO "duration %d!\n",duration);
 	}
-	else 
+	else
 		tx[1]=0;
 	//if(len > priv->rts_threshold){
 //		tx[0] |= (1<<23); //ENABLE RTS
@@ -1562,18 +1579,18 @@
 	tx[0] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 19); /* RTS RATE - should be basic rate */
 	tx[0] |= (rate << 24);
 //	tx[1] = 0;
-	
+
 //	duration = rtl8180_len2duration(len,
-//		rate,&ext);	
+//		rate,&ext);
 //	tx[1] |= (duration & 0x7fff) <<16;
 //	if(ext) tx[1] |= (1<<31);
 
-	
+
 //	tx[2] = 0x303020;
 	tx[2] = 3;  // CW min
 	tx[2] |= (7<<4); //CW max
 	tx[2] |= (11<<8);//(priv->retry_data<<8); //retry lim
-	
+
 //	printk("%x\n%x\n",tx[0],tx[1]);
 
 	#ifdef DUMP_TX
@@ -1601,12 +1618,12 @@
 	}
 #endif
 	//memcpy(pdata, txbuf, len);
-	
+
 	//tx[0] = 0;
 	//tx[1] = 0;
 	tx[2] = 0;
 	tx[3] = 0;
-	
+
 	//tx[0] |= len & 0xfff;
 	tx[0] = len & 0xff;
 	tx[1] = (len & 0x0f00) >> 8;
@@ -1614,25 +1631,25 @@
 
 	if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE)
 		if (priv->plcp_preamble_mode==1 && rate!=0) {	//  short mode now, not long!
-			tx[2] |= 1;	
+			tx[2] |= 1;
 
-		}			
+		}
 
 	if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
 			tx[2] |= (1<<7);	//enalbe RTS function
 			AckCtsTime = ComputeTxTime(14, 10,0, 0);	// AckCTSLng = 14 use 1M bps send
 			FrameTime = ComputeTxTime(len + 4, rtl8180_rate2rate(rate), 0, tx[2]&1);
 			// RTS/CTS time is calculate as follow
-			duration = FrameTime + 3*10 + 2*AckCtsTime;	//10us is the SifsTime;	
+			duration = FrameTime + 3*10 + 2*AckCtsTime;	//10us is the SifsTime;
 			tx[4] |= duration & 0xff; 	//Need to edit here!  ----hikaru
-			tx[5] |= (duration & 0xff00) >> 8; 
+			tx[5] |= (duration & 0xff00) >> 8;
 			printk(KERN_INFO "duration %d!\n",duration);
 	}
 	else {
 		tx[4] = 0;
 		tx[5] = 0;
 	}
-	
+
 	if(morefrag) tx[2] |= (1<<1);
 	tx[2] |= (ieeerate2rtlrate(priv->ieee80211->basic_rate) << 3); /* RTS RATE - should be basic rate */
 	tx[3] |= rate;
@@ -1640,7 +1657,7 @@
 	tx[8] = 3;  // CW min
 	tx[8] |= (7<<4); //CW max
 	tx[9] |= 11;//(priv->retry_data<<8); //retry lim
-	
+
 
 	/* FIXME check what EP is for low/norm PRI */
 	usb_fill_bulk_urb(tx_urb,priv->udev,
@@ -1662,7 +1679,7 @@
 	}
 }
 
- 
+
 
 //void rtl8180_irq_rx_tasklet(struct r8180_priv * priv);
 
@@ -1671,70 +1688,70 @@
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	int i,j;
-	
+
 	priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * MAX_RX_URB, GFP_KERNEL);
-	
+
 	for(i=0;i<MAX_RX_URB;i++){
 		priv->rx_urb[i] = usb_alloc_urb(0,GFP_KERNEL);
-		if(!priv->rx_urb[i]) 
+		if(!priv->rx_urb[i])
 			goto destroy;
-		
+
 		priv->rx_urb[i]->transfer_buffer = kmalloc(RX_URB_SIZE, GFP_KERNEL);
-		if(!priv->rx_urb[i]->transfer_buffer) 
+		if(!priv->rx_urb[i]->transfer_buffer)
 			goto destroy1;
-			
+
 		priv->rx_urb[i]->transfer_buffer_length = RX_URB_SIZE;
 	}
 
 	for(j=0; j < MAX_TX_URB; j++){
 		struct tx_urb_context *ptrcontext = &priv->tx_context[j];
 		u8 seg_size;
-		
+
 		ptrcontext->tx_urb = usb_alloc_urb(0,GFP_KERNEL);
-		if(!ptrcontext->tx_urb) 
+		if(!ptrcontext->tx_urb)
 			goto destroy_tx;
-		
+
 		ptrcontext->transfer_buffer = kmalloc(TX_URB_SIZE, GFP_KERNEL);
-		if(!ptrcontext->transfer_buffer) 
+		if(!ptrcontext->transfer_buffer)
 			goto destroy1_tx;
 		// set tx_urb 4 byte align
 		seg_size = (u32)ptrcontext->transfer_buffer % 4;
 		ptrcontext->ptalign_buf = ptrcontext->transfer_buffer + ((seg_size > 0)? (4 - seg_size):0);
 	}
-	
+
 	return 0;
 
 destroy1_tx:
 	usb_free_urb(priv->tx_context[j].tx_urb);
-	
+
 destroy_tx:
 	while (--j >= 0){
 		kfree(priv->tx_context[j].transfer_buffer);
 		usb_free_urb(priv->tx_context[j].tx_urb);
 	}
-	
+
 destroy1:
 	usb_free_urb(priv->rx_urb[i]);
-	
+
 destroy:
 	while (--i >= 0){
 		kfree(priv->rx_urb[i]->transfer_buffer);
 		usb_free_urb(priv->rx_urb[i]);
 	}
-	
+
 	kfree(priv->rx_urb);
-	
+
 	priv->rx_urb = NULL;
 	DMESGE("Endpoint Alloc Failure");
 	return -ENOMEM;
-		
+
 }
 
 void rtl8187_usb_deleteendpoints(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	int i,j;
-	
+
 	if(priv->rx_urb){
 		for(i=0;i<MAX_RX_URB;i++){
 			usb_kill_urb(priv->rx_urb[i]);
@@ -1743,12 +1760,12 @@
 		}
 		kfree(priv->rx_urb);
 		priv->rx_urb = NULL;
-		
+
 	}
 	//added by david. 2007.1.30
 	for(j=0; j < MAX_TX_URB; j++){
 		struct tx_urb_context *ptrcontext = &priv->tx_context[j];
-		
+
 		usb_kill_urb(ptrcontext->tx_urb);
 		kfree(ptrcontext->transfer_buffer);
 		ptrcontext->transfer_buffer = NULL;
@@ -1763,16 +1780,16 @@
 	int i;
 	u16 word;
 	int basic_rate,min_rr_rate,max_rr_rate;
-	
+
 //	struct r8180_priv *priv = ieee80211_priv(dev);
-	
-	//if (ieee80211_is_54g(priv->ieee80211->current_network) && 
+
+	//if (ieee80211_is_54g(priv->ieee80211->current_network) &&
 //		priv->ieee80211->state == IEEE80211_LINKED){
 	basic_rate = ieeerate2rtlrate(240);
 	min_rr_rate = ieeerate2rtlrate(60);
 	max_rr_rate = ieeerate2rtlrate(240);
-	
-//	
+
+//
 //	}else{
 //		basic_rate = ieeerate2rtlrate(20);
 //		min_rr_rate = ieeerate2rtlrate(10);
@@ -1784,7 +1801,7 @@
 
 	word  = read_nic_word(dev, BRSR);
 	word &= ~BRSR_MBR_8185;
-		
+
 
 	for(i=0;i<=basic_rate;i++)
 		word |= (1<<i);
@@ -1797,7 +1814,7 @@
 void rtl8187_link_change(struct net_device *dev)
 {
 //	int i;
-	
+
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	//write_nic_word(dev, BintrItv, net->beacon_interval);
 	rtl8187_net_update(dev);
@@ -1813,10 +1830,15 @@
 
 #define HW_WAKE_DELAY 5
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_wakeup(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, hw_wakeup_wq);
+	struct net_device *dev = ieee->dev;
+#else
 void rtl8180_hw_wakeup(struct net_device *dev)
 {
-	//unsigned long flags;
-	
+#endif
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	printk(KERN_INFO "enter rtl8180_hw_wakeup!\n");
 	if (!priv->ps_sleep_finish) {
@@ -1829,7 +1851,7 @@
 //	spin_lock_irqsave(&priv->ps_lock,flags);
 	//DMESG("Waken up!");
 //	write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)&~CONFIG4_PWRMGT);
-	
+
 		if(priv->rf_wakeup)
 			priv->rf_wakeup(dev);
 		priv->ps_sleep_finish=0;
@@ -1853,19 +1875,32 @@
 	schedule_work(&priv->rtl8180_hw_wakeup_wq);
 	printk(KERN_INFO "timer wakup schedule!\n");
 }
-void rtl8180_rq_tx_ack(struct net_device *dev){
-		
+
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_rq_tx_ack(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ps_request_tx_ack_wq);
+	struct net_device *dev = ieee->dev;
+#else
+void rtl8180_rq_tx_ack(struct net_device *dev)
+{
+#endif
 	struct r8180_priv *priv = ieee80211_priv(dev);
 //	write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)|CONFIG4_PWRMGT);
 	priv->ack_tx_to_ieee = 1;
 //	printk(KERN_INFO "rtl8180_rq_tx_ack!\n");
 }
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_sleep(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, hw_sleep_wq);
+	struct net_device *dev = ieee->dev;
+#else
 void rtl8180_hw_sleep(struct net_device *dev)
 {
-
+#endif
 	struct r8180_priv *priv = ieee80211_priv(dev);
-
 	u32 rb,tl;
 	//unsigned long flags;
 	u32  timeout;
@@ -1886,27 +1921,27 @@
 	rb = read_nic_dword(dev, TSFTR);
 ////	printk(KERN_INFO "enter rtl8180_hw_sleep!\n");
 //	spin_lock_irqsave(&priv->ps_lock,flags);
-	
+
 	/* Writing HW register with 0 equals to disable
 	 * the timer, that is not really what we want
 	 */
 	tl = priv->ieee80211->ps_tl;
 //	printk(KERN_INFO "tl is %lu!\n",tl);
 	tl -= HW_WAKE_DELAY*1000;
-	 
+
 	if(tl == 0) tl = 1;
-	
+
 	/* FIXME HACK FIXME HACK */
 //	force_pci_posting(dev);
 //	mdelay(1);
-	
+
 //	rb = read_nic_dword(dev, TSFTR);
 #ifdef TONY_PS
 	printk(KERN_INFO "tl %lu, rb %lu!\n",tl,rb);
 #endif
-	
+
 	//DMESG("sleep until %x, hw @:%x",tl,rb);
-	
+
 	/* If the interval in witch we are requested to sleep is too
 	 * short then give up and remain awake
 	 */
@@ -1914,12 +1949,12 @@
 	if(((rb<tl)&& (tl-rb) < MIN_SLEEP_TIME)
 		||((rb>tl)&& (rb-tl) < MIN_SLEEP_TIME))
 		return;
-		
+
 //	write_nic_dword(dev, TimerInt, tl);
 	//DMESG("sleep..");
 //	rb = read_nic_dword(dev, TSFTR);
-	
-	/* if we suspect the TimerInt is gone beyond tl 
+
+	/* if we suspect the TimerInt is gone beyond tl
 	 * while setting it, then give up
 	 */
 	if(((tl > rb) && ((tl-rb) > MAX_SLEEP_TIME))||
@@ -1927,29 +1962,29 @@
 		return;
 
 	if (rb>tl)
-		timeout = (rb-tl)>>10;//divide by 1024 
+		timeout = (rb-tl)>>10;//divide by 1024
 	else
-		timeout = (tl-rb)>>10; 
+		timeout = (tl-rb)>>10;
 
 //	if(priv->rf_sleep)
 //		priv->rf_sleep(dev);
 	priv->ps_timer.expires = jiffies+timeout;
 ////	printk(KERN_INFO "jiffies %lu, timeout %lu!\n",jiffies,timeout);
 	add_timer(&priv->ps_timer);
-	
+
 	if(priv->rf_sleep)
 		priv->rf_sleep(dev);
 	priv->ps_sleep_finish=1;
 //	}
 //	up(&priv->power_sem);
-//	spin_unlock_irqrestore(&priv->ps_lock,flags);	
+//	spin_unlock_irqrestore(&priv->ps_lock,flags);
 	printk(KERN_INFO "leave sleep!\n");
 }
 
 short rtl8180_is_tx_queue_empty(struct net_device *dev){
-		
+
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	
+
 	int used;
 #ifdef TONY_TRACK
 	DMESG("enter rtl8180_is_tx_queue_empty!\n");
@@ -1957,11 +1992,11 @@
 
 	used = atomic_read(&priv->tx_np_pending);
 ////	printk(KERN_INFO "np used %d!\n",used);
-	if (used) return 0; 
+	if (used) return 0;
 	used = atomic_read(&priv->tx_lp_pending);
 ////	printk(KERN_INFO "lp used %d!\n",used);
 	if (used) return 0;
-	
+
 	return 1;
 }
 
@@ -1969,7 +2004,7 @@
 
 short rtl8180_init(struct net_device *dev)
 {
-		
+
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	int i, j;
 	u16 word;
@@ -1977,16 +2012,16 @@
 	//u16 version;
 	//u8 hw_version;
 	//u8 config3;
-	
+
 	//FIXME: these constants are placed in a bad pleace.
 
 //	priv->txbuffsize = 1024;
 //	priv->txringcount = 32;
 //	priv->rxbuffersize = 1024;
-//	priv->rxringcount = 32; 
+//	priv->rxringcount = 32;
 //	priv->txbeaconcount = 3;
 //	priv->rx_skb_complete = 1;
-	//priv->txnp_pending.ispending=0; 
+	//priv->txnp_pending.ispending=0;
 	/* ^^ the SKB does not containt a partial RXed
 	 * packet (is empty)
 	 */
@@ -2004,9 +2039,9 @@
 		ch >>= 1;
 	}
 	//memcpy(priv->stats,0,sizeof(struct Stats));
-	
+
 	//priv->irq_enabled=0;
-	
+
 //	priv->stats.rxdmafail=0;
 	priv->stats.txrdu=0;
 //	priv->stats.rxrdu=0;
@@ -2042,7 +2077,7 @@
 
 	priv->ps_sleep_finish=0;
 	priv->ieee80211->iw_mode = IW_MODE_INFRA;
-	
+
 	priv->retry_rts = DEFAULT_RETRY_RTS;
 	priv->retry_data = DEFAULT_RETRY_DATA;
 	priv->ieee80211->rate = 110; //11 mbps
@@ -2050,11 +2085,19 @@
 	priv->ieee80211->mode = IEEE_G|IEEE_B; //2007.1.25
 	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
 	spin_lock_init(&priv->tx_lock);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
 	INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8180_restart,dev);
 	INIT_WORK(&priv->rtl8180_hw_wakeup_wq,(void(*)(void*))rtl8180_hw_wakeup,dev);
 	INIT_WORK(&priv->ieee80211->ps_request_tx_ack_wq,(void(*)(void*))rtl8180_rq_tx_ack,dev);
 	INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void(*)(void*))rtl8180_hw_wakeup,dev);
 	INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void(*)(void*))rtl8180_hw_sleep,dev);
+#else
+	INIT_WORK(&priv->reset_wq, rtl8180_restart);
+	INIT_WORK(&priv->rtl8180_hw_wakeup_wq, rtl8180_hw_wakeup);
+	INIT_WORK(&priv->ieee80211->ps_request_tx_ack_wq, rtl8180_rq_tx_ack);
+	INIT_WORK(&priv->ieee80211->hw_wakeup_wq, rtl8180_hw_wakeup);
+	INIT_WORK(&priv->ieee80211->hw_sleep_wq, rtl8180_hw_sleep);
+#endif
 //	INIT_WORK(&priv->ps_request_tx_ack_wq,(void(*)(void*))rtl8180_rq_tx_ack,dev);
 	sema_init(&priv->wx_sem,1);
 	sema_init(&priv->power_sem,1);
@@ -2068,17 +2111,17 @@
 	priv->ps_timer.data = (unsigned long)dev;
 	priv->ps_timer.function = timer_hw_wakeup_wq;
 
-	//priv->ieee80211->func = 
+	//priv->ieee80211->func =
 	//	kmalloc(sizeof(struct ieee80211_helper_functions),GFP_KERNEL);
 	//memset(priv->ieee80211->func, 0,
 	  //     sizeof(struct ieee80211_helper_functions));
-	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;	
+	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
 	priv->ieee80211->iw_mode = IW_MODE_INFRA;
-	priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN | 
-		IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | 
+	priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
+		IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
 		IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
 		/*IEEE_SOFTMAC_BEACONS | */IEEE_SOFTMAC_SINGLE_QUEUE;
-	
+
 	priv->ieee80211->active_scan = 1;
 	priv->ieee80211->rate = 110; //11 mbps
 	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
@@ -2100,51 +2143,51 @@
 	priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
 	//priv->ieee80211->start_send_beacons = NULL;
 	//priv->ieee80211->stop_send_beacons = NULL;
-	
+
 	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
-	
+
 	priv->card_8185 = 2;
 	priv->phy_ver = 2;
 	priv->card_type = USB;
-	
+
 	#if 0
 	hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
-	
+
 	switch (hw_version){
 		case HW_VERID_R8185_ABC:
-			DMESG("MAC controller is a RTL8185 b/g");	
+			DMESG("MAC controller is a RTL8185 b/g");
 			priv->card_8185 = 1;
 			/* you should not find a card with 8225 PHY ver < C*/
 			priv->phy_ver = 2;
 			break;
-			 
+
 		case HW_VERID_R8185_D:
-			DMESG("MAC controller is a RTL8185 b/g (V. D)");	
+			DMESG("MAC controller is a RTL8185 b/g (V. D)");
 			priv->card_8185 = 2;
 			/* you should not find a card with 8225 PHY ver < C*/
 			priv->phy_ver = 2;
 			break;
-			
+
 		case HW_VERID_R8180_ABCD:
 			DMESG("MAC controller is a RTL8180");
 			priv->card_8185 = 0;
 			break;
-		
+
 		case HW_VERID_R8180_F:
 			DMESG("MAC controller is a RTL8180 (v. F)");
 			priv->card_8185 = 0;
 			break;
-		
+
 		default:
 			DMESGW("MAC chip not recognized: version %x. Assuming RTL8180",hw_version);
 			priv->card_8185 = 0;
 			break;
 	}
-	
-	
+
+
 	/* you should not found any 8185 Ver B Card */
 	priv->card_8185_Bversion = 0;
-	
+
 	config3 = read_nic_byte(dev, CONFIG3);
 	if(config3 & 0x8){
 		priv->card_type = CARDBUS;
@@ -2162,13 +2205,13 @@
 	priv->plcp_preamble_mode = 2;
 
 
-	
+
 	/* commented out just because we already do
 	   this when resetting the card
 	   andrea 20050924
 	 */
 	#if 0
-		
+
 	u8 txcr, txreg50;
 	u32 txreg54, txreg60;
 
@@ -2204,8 +2247,8 @@
        // DMESG("<<txcr:%x>>", txcr);
 
 #endif
-	
-	/*the eeprom type is stored in RCR register bit #6 */ 
+
+	/*the eeprom type is stored in RCR register bit #6 */
 	if (RCR_9356SEL & read_nic_dword(dev, RCR)){
 		priv->epromtype=EPROM_93c56;
 		DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
@@ -2213,58 +2256,67 @@
 		priv->epromtype=EPROM_93c46;
 		DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
 	}
-	
+
 	dev->get_stats = rtl8180_stats;
-	
+
 	dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
 	dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
 	dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
 	dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
 	dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
 	dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
-	
+
 	DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
-		
+
 	for(i=1,j=0; i<6; i+=2,j++){
-		
+
 		word = eprom_read(dev,EPROM_TXPW0 + j);
 		priv->chtxpwr[i]=word & 0xf;
 		priv->chtxpwr_ofdm[i]=(word & 0xf0)>>4;
 		priv->chtxpwr[i+1]=(word & 0xf00)>>8;
 		priv->chtxpwr_ofdm[i+1]=(word & 0xf000)>>12;
 	}
-	
+
 	for(i=1,j=0; i<4; i+=2,j++){
-			
+
 		word = eprom_read(dev,EPROM_TXPW1 + j);
 		priv->chtxpwr[i+6]=word & 0xf;
 		priv->chtxpwr_ofdm[i+6]=(word & 0xf0)>>4;
 		priv->chtxpwr[i+6+1]=(word & 0xf00)>>8;
 		priv->chtxpwr_ofdm[i+6+1]=(word & 0xf000)>>12;
 	}
-	
+
 	for(i=1,j=0; i<4; i+=2,j++){
-			
+
 		word = eprom_read(dev,EPROM_TXPW2 + j);
 		priv->chtxpwr[i+6+4]=word & 0xf;
 		priv->chtxpwr_ofdm[i+6+4]=(word & 0xf0)>>4;
 		priv->chtxpwr[i+6+4+1]=(word & 0xf00)>>8;
 		priv->chtxpwr_ofdm[i+6+4+1]=(word & 0xf000)>>12;
 	}
-	
-		
+
+
 	priv->rf_chip = 0xff & eprom_read(dev,EPROM_RFCHIPID);
-	
+
 	word = eprom_read(dev,EPROM_TXPW_BASE);
 	priv->cck_txpwr_base = word & 0xf;
 	priv->ofdm_txpwr_base = (word>>4) & 0xf;
-	
+
+	priv->txpwr_max = 0;
+	for(i=1; i<15; i++)
+	{
+		if(priv->chtxpwr[i] > priv->txpwr_max) priv->txpwr_max = priv->chtxpwr[i];
+		if(priv->chtxpwr_ofdm[i] > priv->txpwr_max) priv->txpwr_max = priv->chtxpwr_ofdm[i];
+		priv->chtxpwr_orig[i] = priv->chtxpwr[i];
+		priv->chtxpwr_ofdm_orig[i] = priv->chtxpwr_ofdm[i];
+	}
+
 	/* check RF frontend chipset */
-	
+
 	switch (priv->rf_chip) {
-		
+
 		case EPROM_RFCHIPID_RTL8225U:
-		
+
 		DMESG("Card reports RF frontend Realtek 8225");
 		DMESGW("This driver has EXPERIMENTAL support for this chipset.");
 		DMESGW("use it with care and at your own risk and");
@@ -2283,30 +2335,30 @@
 			DMESG("This seems a legacy 1st version radio");
 		}
 		priv->rf_close = rtl8225_rf_close;
-		
+
 		priv->max_sens = RTL8225_RF_MAX_SENS;
 		priv->sens = RTL8225_RF_DEF_SENS;
 		break;
-				
+
 		default:
 		DMESGW("Unknown RF module %x",priv->rf_chip);
 		DMESGW("Exiting...");
 		return -1;
-		
+
 	}
 
 	InitSwLeds(dev);
-	
+
 //	DMESG("Energy threshold: %x",priv->cs_treshold);
 	DMESG("PAPE from CONFIG2: %x",read_nic_byte(dev,CONFIG2)&0x7);
 	//DMESG("CONFIG2: %x ECONFIG2: %x",read_nic_byte(dev,CONFIG2),eprom_read(dev,EPROM_CONFIG2));
-	
-	if(rtl8187_usb_initendpoints(dev)!=0){ 
+
+	if(rtl8187_usb_initendpoints(dev)!=0){
 		DMESG("Endopoints initialization failed");
 		return -ENOMEM;
 	}
-#if 0		
-	if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount)) 
+#if 0
+	if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
 		return -ENOMEM;
 
 	if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
@@ -2320,16 +2372,16 @@
 	if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
 				  TX_LOWPRIORITY_RING_ADDR))
 		return -ENOMEM;
-	
-	
+
+
 	if (0!=alloc_tx_beacon_desc_ring(dev, priv->txbeaconcount))
 		return -ENOMEM;
 #endif
-	
+
 
 #ifdef DEBUG_EPROM
 	dump_eprom(dev);
-#endif 
+#endif
 	return 0;
 
 }
@@ -2349,7 +2401,7 @@
 	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
 
 	conf3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));	
+	write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
 
 	write_nic_dword(dev, ANAPARAM2, a);
 
@@ -2369,23 +2421,23 @@
 
 	conf3 = read_nic_byte(dev, CONFIG3);
 	write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
-	
+
 	write_nic_dword(dev, ANAPARAM, a);
 
 	conf3 = read_nic_byte(dev, CONFIG3);
 	write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
 
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-	
+
 }
 
 
 void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
 {
-	write_nic_byte(dev, TX_ANTENNA, ant); 
+	write_nic_byte(dev, TX_ANTENNA, ant);
 	force_pci_posting(dev);
 	mdelay(1);
-}	
+}
 
 
 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data)
@@ -2393,26 +2445,26 @@
 	//u8 phyr;
 	u32 phyw;
 //	int i;
-	
+
 	adr |= 0x80;
-	 
+
 	phyw= ((data<<8) | adr);
-	
-	
-	
-	// Note that, we must write 0xff7c after 0x7d-0x7f to write BB register. 
+
+
+
+	// Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
 	write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
 	write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
 	write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
 	write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
 
 	//read_nic_dword(dev, PHY_ADR);
-#if 0	
+#if 0
 	for(i=0;i<10;i++){
 		write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
 		phyr = read_nic_byte(dev, PHY_READ);
 		if(phyr == (data&0xff)) break;
-			
+
 	}
 #endif
 	/* this is ok to fail when we write AGC table. check for AGC table might be
@@ -2442,26 +2494,26 @@
         struct r8180_priv *priv = ieee80211_priv(dev);
 	//u32 anaparam;
 	//u8 config3;
-	
+
 	//rtl8180_rtx_disable(dev);
 	rtl8180_reset(dev);
 
 	write_nic_byte(dev,0x85,0);
 	write_nic_byte(dev,0x91,0);
-	
+
 	/* light blink! */
 	write_nic_byte(dev,0x85,4);
 	LedControl8187(dev, LED_CTL_POWER_ON);
 	//write_nic_byte(dev,0x91,1);
 	//write_nic_byte(dev,0x90,0);
-	
+
 	priv->irq_mask = 0xffff;
 /*
 	priv->dma_poll_mask = 0;
 	priv->dma_poll_mask|= (1<<TX_DMA_STOP_BEACON_SHIFT);
-*/	
+*/
 //	rtl8180_beacon_tx_disable(dev);
-	
+
 	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
 	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
 	write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
@@ -2469,32 +2521,32 @@
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 	rtl8180_update_msr(dev);
 
-/*	
+/*
 	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	
+
 	write_nic_word(dev,0xf4,0xffff);
 	write_nic_byte(dev,
-		       CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80);	
+		       CONFIG1, (read_nic_byte(dev,CONFIG1) & 0x3f) | 0x80);
 
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 */
-	write_nic_dword(dev,INT_TIMEOUT,0);	
+	write_nic_dword(dev,INT_TIMEOUT,0);
 
 #ifdef DEBUG_REGISTERS
-	rtl8180_dump_reg(dev);	
+	rtl8180_dump_reg(dev);
 #endif
-	
-	
-	write_nic_byte(dev, WPA_CONFIG, 0);	
+
+
+	write_nic_byte(dev, WPA_CONFIG, 0);
 
 	write_nic_byte(dev, RATE_FALLBACK, 0x81);
 	rtl8187_set_rate(dev);
-		
-	priv->rf_init(dev);	
+
+	priv->rf_init(dev);
 
 	if(priv->rf_set_sens != NULL)
-		priv->rf_set_sens(dev,priv->sens);	
-	
+		priv->rf_set_sens(dev,priv->sens);
+
 	write_nic_word(dev,0x5e,1);
 
 	#if 1
@@ -2510,13 +2562,13 @@
 
 	//add for Led controll
 	write_nic_byte(dev,0x85,4);
-	
-		
+
+
 	rtl8180_irq_enable(dev);
 	/*DMESG ("lfree %d",get_curr_tx_free_desc(dev,LOW_PRIORITY));
-	
+
 	DMESG ("nfree %d",get_curr_tx_free_desc(dev,NORM_PRIORITY));
-	
+
 	DMESG ("hfree %d",get_curr_tx_free_desc(dev,HI_PRIORITY));
 	if(check_nic_enought_desc(dev,NORM_PRIORITY)) DMESG("NORM OK");
 	if(check_nic_enought_desc(dev,HI_PRIORITY)) DMESG("HI OK");
@@ -2534,7 +2586,7 @@
 {
 	int i;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u16 word;	
+	u16 word;
 	DMESG("Enabling beacon TX");
 	//write_nic_byte(dev, 0x42,0xe6);// TCR
 	//rtl8180_init_beacon(dev);
@@ -2547,41 +2599,41 @@
 	//write_nic_word(dev,0x7a,0);
 	//write_nic_word(dev,0x7a,0x8000);
 
-	
+
 	word  = read_nic_word(dev, BcnItv);
 	word &= ~BcnItv_BcnItv; // clear Bcn_Itv
 	write_nic_word(dev, BcnItv, word);
 
-	write_nic_word(dev, AtimWnd, 
+	write_nic_word(dev, AtimWnd,
 		       read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
-	
+
 	word  = read_nic_word(dev, BintrItv);
 	word &= ~BintrItv_BintrItv;
-	
-	//word |= priv->ieee80211->beacon_interval * 
+
+	//word |= priv->ieee80211->beacon_interval *
 	//	((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
 	// FIXME:FIXME check if correct ^^ worked with 0x3e8;
-	
+
 	write_nic_word(dev, BintrItv, word);
-	
+
 	//write_nic_word(dev,0x2e,0xe002);
 	//write_nic_dword(dev,0x30,0xb8c7832e);
 	for(i=0; i<ETH_ALEN; i++)
 		write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
-	
+
 //	rtl8180_update_msr(dev);
 
-	
+
 	//write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
-	
+
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-	
+
 	rtl8180_irq_enable(dev);
-	
+
 	/* VV !!!!!!!!!! VV*/
 	/*
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,0x9d,0x00); 	
+	write_nic_byte(dev,0x9d,0x00);
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 */
 }
@@ -2592,7 +2644,7 @@
 static struct net_device_stats *rtl8180_stats(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	
+
 	return &priv->ieee80211->stats;
 }
 
@@ -2602,20 +2654,20 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
 	priv->up=1;
-	
+
 	//DMESG("Bringing up iface");
 
 	rtl8180_adapter_start(dev);
 
-	
+
 	rtl8180_rx_enable(dev);
 
 	rtl8180_tx_enable(dev);
-	
+
 	ieee80211_softmac_start_protocol(priv->ieee80211);
 
 	//LedControl8187(dev, LED_CTL_SITE_SURVEY);
-	
+
 	ieee80211_reset_queue(priv->ieee80211);
 	if(!netif_queue_stopped(dev))
 		netif_start_queue(dev);
@@ -2630,12 +2682,12 @@
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	int ret;
-	
+
 	down(&priv->wx_sem);
 	ret = rtl8180_up(dev);
 	up(&priv->wx_sem);
 	return ret;
-	
+
 }
 
 
@@ -2644,7 +2696,7 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
 	if (priv->up == 1) return -1;
-	
+
 	return _rtl8180_up(dev);
 }
 
@@ -2653,15 +2705,15 @@
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	int ret;
-	
+
 	down(&priv->wx_sem);
-	
+
 	ret = rtl8180_down(dev);
-	
+
 	LedControl8187(dev, LED_CTL_NO_LINK);
-	
+
 	up(&priv->wx_sem);
-	
+
 	return ret;
 
 }
@@ -2671,18 +2723,18 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
 	if (priv->up == 0) return -1;
-	
+
 	priv->up=0;
 
 /* FIXME */
 	if (!netif_queue_stopped(dev))
 		netif_stop_queue(dev);
-	
+
 	rtl8180_rtx_disable(dev);
 	rtl8180_irq_disable(dev);
 
 	ieee80211_softmac_stop_protocol(priv->ieee80211);
-		
+
 	return 0;
 }
 
@@ -2692,7 +2744,7 @@
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
 	if (priv->up == 0) return ;
-	
+
 	ieee80211_softmac_stop_protocol(priv->ieee80211);
 	sema_init(&priv->power_sem,1);
 	//printk(KERN_WARNING "priv->power_semb %d!\n",priv->power_sem);
@@ -2701,14 +2753,20 @@
 	_rtl8180_up(dev);
 }
 
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_restart(struct work_struct *work)
+{
+	struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
+	struct net_device *dev = priv->dev;
+#else
 void rtl8180_restart(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-
+#endif
 	down(&priv->wx_sem);
-	
+
 	rtl8180_commit(dev);
-	
+
 	up(&priv->wx_sem);
 }
 
@@ -2718,16 +2776,16 @@
 	short promisc;
 
 	//down(&priv->wx_sem);
-	
+
 	/* FIXME FIXME */
-	
+
 	promisc = (dev->flags & IFF_PROMISC) ? 1:0;
-	
+
 	if (promisc != priv->promisc)
 	//	rtl8180_commit(dev);
-	
+
 	priv->promisc = promisc;
-	
+
 	//schedule_work(&priv->reset_wq);
 	//up(&priv->wx_sem);
 }
@@ -2737,15 +2795,15 @@
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	struct sockaddr *addr = mac;
-	
+
 	down(&priv->wx_sem);
-	
+
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-		
+
 	schedule_work(&priv->reset_wq);
-	
+
 	up(&priv->wx_sem);
-	
+
 	return 0;
 }
 
@@ -2758,8 +2816,8 @@
 	int ret=-1;
 
 	down(&priv->wx_sem);
-	
-        
+
+
 	switch (cmd) {
 	    case RTL_IOCTL_WPA_SUPPLICANT:
 		ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
@@ -2771,7 +2829,7 @@
 	}
 
 	up(&priv->wx_sem);
-	
+
 	return ret;
 }
 
@@ -2792,9 +2850,9 @@
 	//u32 *desc;
 	u8 *desc;
 	u8 signal,quality,rate;
-	
+
 	//DMESG("rtl8187_rx_isr");
-	
+
 	struct ieee80211_rx_stats stats = {
 		.signal = 0,
 		.noise = -98,
@@ -2803,31 +2861,31 @@
 		.freq = IEEE80211_24GHZ_BAND,
 	};
 
-	
+
 	//DMESG("RX %d ",rx_urb->status);
 	status = rx_urb->status;
 	if(status == 0){
-		
+
 		len = rx_urb->actual_length;
-	//	len = len - 4 - 15 - 1; /* CRC, DESC, SEPARATOR*/ 
+	//	len = len - 4 - 15 - 1; /* CRC, DESC, SEPARATOR*/
 		len -= 4*4;/* 4 dword and 4 byte CRC */
-#if 0	
+#if 0
 		desc = (u32*)(rx_urb->transfer_buffer + len);
-		
+
 		flen = desc[0] & 0xfff;
-		
+
 		if( flen <= rx_urb->actual_length){
-		
+
 			//stats.signal = (desc[1] & 0x7f00)>>8;
 			//stats.noise = desc[1] &0xff;
 			signal=(desc[1]& (0xff0000))>>16;
 			signal=(signal&0xfe)>>1;	// Modify by hikaru 6.6
-				
+
 			quality=(desc[1] & (0xff));
-			
+
 			rate=(desc[0] &((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
-		//	printk(KERN_INFO "rate is %d!\n",rate);	
-			stats.rate = rtl8180_rate2rate(rate);	
+		//	printk(KERN_INFO "rate is %d!\n",rate);
+			stats.rate = rtl8180_rate2rate(rate);
 		//	printk(KERN_INFO "stats.rate is %d!\n",stats.rate);
 			//stats.rate = desc[0] >> 20 & 0xf;
 			stats.mac_time[0] = desc[2];
@@ -2835,35 +2893,35 @@
 #endif
 
 		desc = rx_urb->transfer_buffer + len;
-		
+
 		flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
-		
+
 		if( flen <= rx_urb->actual_length){
-		
+
 			//stats.signal = (desc[1] & 0x7f00)>>8;
 			//stats.noise = desc[1] &0xff;
 			signal=(desc[6]& 0xfe)>>1;
 			//signal=(signal&0xfe)>>1;	// Modify by hikaru 6.6
-				
+
 			quality=desc[4] & 0xff;
-			
+
 			//rate=(desc[2] &((1<<7)|(1<<6)|(1<<5)|(1<<4)))>>4;
 			rate=(desc[2] & 0xf0)>>4;
-		//	printk(KERN_INFO "rate is %d!\n",rate);	
-			stats.rate = rtl8180_rate2rate(rate);	
+		//	printk(KERN_INFO "rate is %d!\n",rate);
+			stats.rate = rtl8180_rate2rate(rate);
 		//	printk(KERN_INFO "stats.rate is %d!\n",stats.rate);
 			//stats.rate = desc[0] >> 20 & 0xf;
-			stats.mac_time[0] = desc[8] + (desc[9]<<8) + (desc[10]<<16) + (desc[11]<<24);   
-			stats.mac_time[1] = desc[12] + (desc[13]<<8) + (desc[14]<<16) + (desc[15]<<24);   
+			stats.mac_time[0] = desc[8] + (desc[9]<<8) + (desc[10]<<16) + (desc[11]<<24);
+			stats.mac_time[1] = desc[12] + (desc[13]<<8) + (desc[14]<<16) + (desc[15]<<24);
+
 
-			
 			//calculate link quality begin
-			if(!rtl8180_IsWirelessBMode(stats.rate) ) 
+			if(!rtl8180_IsWirelessBMode(stats.rate) )
 			{ // OFDM rate.
 				if(signal>90)
 					signal=90;
 				else if(signal<25)
-					signal=25;  
+					signal=25;
 				signal = (90-signal)*100/65;
 			}
 			else
@@ -2871,7 +2929,7 @@
 				if(signal>95)
 					signal = 95;
 				else if(signal<30)
-					signal = 30;  
+					signal = 30;
 				signal =(95-signal )*100/65;
 			}
 			priv->wstats.qual.level = signal;
@@ -2879,30 +2937,35 @@
 			if(quality > 64)
 				priv ->wstats.qual.qual = 0;
 			else
-				priv ->wstats.qual.qual = ((64-quality) * 100) / 64;  // SQ value is the SIGNAL_QUALITY returned to IORequest, 
-						//and this value only appear when STA is associated to AP or 
+				priv ->wstats.qual.qual = ((64-quality) * 100) / 64;  // SQ value is the SIGNAL_QUALITY returned to IORequest,
+						//and this value only appear when STA is associated to AP or
 						// STA is in IBSS mode
 		//	printk(KERN_INFO "quality is %d!\n",priv->wstats.qual.qual);
 			priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
 			priv->wstats.qual.updated = 7;
-			//calculate link quality end 
+			if(priv->ieee80211->iw_mode == IW_MODE_MONITOR)
+			{
+				stats.signal = priv->wstats.qual.level;
+				stats.noise = priv->wstats.qual.noise;
+			}
+			//calculate link quality end
 			skb = dev_alloc_skb(flen-4);
-			if(skb){ 
+			if(skb){
 			memcpy(skb_put(skb,flen-4),
 				rx_urb->transfer_buffer,flen -4);
-			
+
 			#ifdef DUMP_RX
 			int i;
 			for(i=0;i<flen-4;i++)
 				printk("%2x ",((u8*)(rx_urb->transfer_buffer))[i]);
 			printk("------RATE %x:w---------------\n",stats.rate);
-			
+
 			#endif
 			priv->stats.rxok++;
 		//	priv->rxskb = skb;
 		//	priv->tempstats = &stats;
 
-			if(!ieee80211_rx(priv->ieee80211, 
+			if(!ieee80211_rx(priv->ieee80211,
 				skb, &stats))
 			dev_kfree_skb_any(skb);
 			}
@@ -2913,7 +2976,7 @@
 	}
 
 	//LedControl8187(dev, LED_CTL_RX);
-	
+
 	if(status != -ENOENT)rtl8187_rx_urbsubmit(dev,rx_urb);
 	else DMESG("RX process aborted due to explicit shutdown");
 }
@@ -2931,20 +2994,20 @@
 	struct r8180_priv *priv= NULL;
 	struct usb_device *udev = interface_to_usbdev(intf);
 
-printk(KERN_WARNING "===> rtl8187_usb_probe()\n");	
-	
+printk(KERN_WARNING "===> rtl8187_usb_probe()\n");
+
 	dev = alloc_ieee80211(sizeof(struct r8180_priv));
-	
+
 	SET_MODULE_OWNER(dev);
-	usb_set_intfdata(intf, dev);	
-	
+	usb_set_intfdata(intf, dev);
+
 	SET_NETDEV_DEV(dev, &intf->dev);
 
 	priv = ieee80211_priv(dev);
 	priv->ieee80211 = netdev_priv(dev);
-	
+
 	priv->udev=udev;
-	
+
 	dev->open = rtl8180_open;
 	dev->stop = rtl8180_close;
 	//dev->hard_start_xmit = rtl8180_8023_hard_start_xmit;
@@ -2953,41 +3016,46 @@
 	dev->do_ioctl = rtl8180_ioctl;
 	dev->set_multicast_list = r8180_set_multicast;
 	dev->set_mac_address = r8180_set_mac_adr;
+#if WIRELESS_EXT >= 12
+#if WIRELESS_EXT < 17
 	dev->get_wireless_stats = r8180_get_wireless_stats;
+#endif
+	dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
+#endif
 	dev->type=ARPHRD_ETHER;
-	
+
 	if (dev_alloc_name(dev, ifname) < 0){
                 DMESG("Oops: devname already taken! Trying wlan%%d...\n");
 		ifname = "wlan%d";
 		dev_alloc_name(dev, ifname);
         }
-	
+
 //	dev->open=rtl8180_init;
-	
-	if(rtl8180_init(dev)!=0){ 
+
+	if(rtl8180_init(dev)!=0){
 		DMESG("Initialization failed");
 		goto fail;
 	}
-	
+
 	netif_carrier_off(dev);
 	netif_stop_queue(dev);
-	
+
 	register_netdev(dev);
-	
+
 	rtl8180_proc_init_one(dev);
 
-		
+
 	DMESG("Driver probe completed\n");
-	return 0;	
+	return 0;
+
 
-	
 fail:
 	free_ieee80211(dev);
-		
+
 	DMESG("wlan driver load failed\n");
-	
+
 	return -ENODEV;
-	
+
 }
 
 
@@ -2996,13 +3064,13 @@
 	struct r8180_priv *priv;
 	struct net_device *dev = usb_get_intfdata(intf);
  	if(dev){
-		
+
 		unregister_netdev(dev);
-		
+
 		priv=ieee80211_priv(dev);
-		
+
 		rtl8180_proc_remove_one(dev);
-		
+
 		rtl8180_down(dev);
 		priv->rf_close(dev);
 		//rtl8180_rtx_disable(dev);
@@ -3046,11 +3114,11 @@
 	unsigned long flags;
 	short enough_desc;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	
+
 	spin_lock_irqsave(&priv->tx_lock,flags);
 	enough_desc = check_nic_enought_desc(dev,pri);
-        spin_unlock_irqrestore(&priv->tx_lock,flags);	
-	
+        spin_unlock_irqrestore(&priv->tx_lock,flags);
+
 	if(enough_desc)
 		ieee80211_wake_queue(priv->ieee80211);
 }
diff -Naur r8187_orig/rtl8187/r8187.h r8187_rawtx/rtl8187/r8187.h
--- r8187_orig/rtl8187/r8187.h	2007-12-05 04:22:20.000000000 +0100
+++ r8187_rawtx/rtl8187/r8187.h	2007-05-16 21:51:38.000000000 +0200
@@ -1,17 +1,17 @@
-/* 
+/*
    This is part of rtl8187 OpenSource driver.
-   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it> 
+   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
    Released under the terms of GPL (General Public Licence)
-   
-   Parts of this driver are based on the GPL part of the 
+
+   Parts of this driver are based on the GPL part of the
    official realtek driver
-   
-   Parts of this driver are based on the rtl8180 driver skeleton 
+
+   Parts of this driver are based on the rtl8180 driver skeleton
    from Patric Schenke & Andres Salomon
-   
+
    Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-   
-   We want to tanks the Authors of those projects and the Ndiswrapper 
+
+   We want to tanks the Authors of those projects and the Ndiswrapper
    project Authors.
 */
 
@@ -26,7 +26,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
@@ -47,6 +46,12 @@
 #include <asm/io.h>
 #include <asm/semaphore.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+
 #include "ieee80211.h"
 #include "r8187_led.h"
 #include "r8180_hw.h"
@@ -74,7 +79,7 @@
 {
 	struct buffer *next;
 	u32 *buf;
-	
+
 } buffer;
 
 #if 0
@@ -123,7 +128,7 @@
 	unsigned long txdatapkt;
 	unsigned long rxok;
 	unsigned long rxretry;//retry number  tony 20060601
-	unsigned long rxcrcerrmin;//crc error (0-500) 
+	unsigned long rxcrcerrmin;//crc error (0-500)
 	unsigned long rxcrcerrmid;//crc error (500-1000)
 	unsigned long rxcrcerrmax;//crc error (>1000)
 	unsigned long rxicverr;//ICV error
@@ -142,7 +147,7 @@
 	short epromtype;
 	int irq;
 	struct ieee80211_device *ieee80211;
-	
+
 	short card_8185; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D */
 	short card_8185_Bversion; /* if TCR reports card V B/C this discriminates */
 	short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
@@ -151,12 +156,12 @@
 	short hw_plcp_len;
 	short plcp_preamble_mode; // 0:auto 1:short 2:long
 
-		
+
 //	spinlock_t irq_lock;
 //	spinlock_t irq_th_lock;
 	spinlock_t tx_lock;
 	spinlock_t ps_lock;
-	
+
 	u16 irq_mask;
 //	short irq_enabled;
 	struct net_device *dev;
@@ -165,17 +170,20 @@
 	short max_sens;
 	u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
 	u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
+	u8 chtxpwr_orig[15]; //channels from 1 to 14, 0 not used
+	u8 chtxpwr_ofdm_orig[15]; //channels from 1 to 14, 0 not used
 	u8 cck_txpwr_base;
 	u8 ofdm_txpwr_base;
+	u8 txpwr_max;
 	u8 challow[15]; //channels from 1 to 14, 0 not used
 	u8 channel_plan;  // it's the channel plan index
 
 	short up;
 	short crcmon; //if 1 allow bad crc frame reception in monitor mode
-//	short prism_hdr;
+	short prism_hdr;
 	struct timer_list ps_timer;
 	short PS_timeout;//when ps set on ,if tx timeout ,this will be set 1
-	
+
 //	struct timer_list scan_timer;
 	/*short scanpending;
 	short stopscan;*/
@@ -185,7 +193,7 @@
 	struct semaphore wx_sem;
 	struct semaphore power_sem;
 //	short hw_wep;
-		
+
 //	short digphy;
 //	short antb;
 //	short diversity;
@@ -200,12 +208,12 @@
 	void (*rf_wakeup)(struct net_device *dev);
 	void (*rf_sleep)(struct net_device *dev);
 	//short rate;
-	short promisc;	
+	short promisc;
 	/*stats*/
 	struct Stats stats;
 	struct iw_statistics wstats;
 	struct proc_dir_entry *dir_dev;
-	
+
 	/*RX stuff*/
 //	u32 *rxring;
 //	u32 *rxringtail;
@@ -213,20 +221,20 @@
 	struct urb **rx_urb;
 	struct tx_urb_context tx_context[MAX_TX_URB];
 	short  tx_urb_index;
-	
+
 	//struct buffer *rxbuffer;
 	//struct buffer *rxbufferhead;
 	//int rxringcount;
 	//u16 rxbuffersize;
-	
-	//struct sk_buff *rx_skb; 
+
+	//struct sk_buff *rx_skb;
 
 	//short rx_skb_complete;
 
 	//u32 rx_prevlen;
 	atomic_t tx_lp_pending;
 	atomic_t tx_np_pending;
-#if 0	
+#if 0
 	/*TX stuff*/
 	u32 *txlpring;
 	u32 *txhpring;
@@ -256,7 +264,7 @@
 	struct urb *rxurb_task;
 //	u8 dma_poll_mask;
 	//short tx_suspend;
-	
+
 	/* adhoc/master mode stuff */
 #if 0
 	u32 *txbeacontail;
@@ -270,15 +278,20 @@
 	//u16 master_beaconinterval;
 //	u32 master_beaconsize;
 	//u16 beacon_interval;
-	
+
 	u8 retry_data;
 	u8 retry_rts;
 	u16 rts;
 	u8 ps_sleep_finish;//1, finish hw sleep ,0 finish hw wakeup
 
-	
+
 	struct work_struct reset_wq;
 	struct work_struct rtl8180_hw_wakeup_wq;
+//        struct work_struct rtl8180_rq_tx_ack_wq;
+//         struct work_struct rtl8180_hw_sleep_wq;
+
+        struct work_struct SwLed0WorkItemCallback_wq;
+
 	short ack_tx_to_ieee;
 
 
@@ -292,15 +305,15 @@
 	LED_STRATEGY_8187	LedStrategy;
 	u8			PsrValue;
 	struct work_struct		Gpio0LedWorkItem;
-	struct work_struct		SwLed0WorkItem; 
-	struct work_struct		SwLed1WorkItem;	
-	
+	struct work_struct		SwLed0WorkItem;
+	struct work_struct		SwLed1WorkItem;
+
 }r8180_priv;
 
 
-typedef enum{ 
+typedef enum{
 	LOW_PRIORITY ,
-	NORM_PRIORITY 
+	NORM_PRIORITY
 	} priority_t;
 
 
diff -Naur r8187_orig/rtl8187/r8187_led.c r8187_rawtx/rtl8187/r8187_led.c
--- r8187_orig/rtl8187/r8187_led.c	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/rtl8187/r8187_led.c	2007-05-16 21:51:33.000000000 +0200
@@ -3,35 +3,35 @@
 
 Module Name:
  	r8187_led.c
-	
+
 Abstract:
  	RTL8187 LED control functions
- 	    
+
 Major Change History:
 	When        Who      What
 	----------    ---------------   -------------------------------
 	2006-09-07    Xiong		Created
-    
-Notes:	
- 	
+
+Notes:
+
 --*/
 
 /*--------------------------Include File------------------------------------*/
 #include "r8180_hw.h"
 #include "r8187.h"
-#include "r8180_93cx6.h" 
+#include "r8180_93cx6.h"
 #include "r8187_led.h"
 
 
 /**
 *
-* Initialization function for Sw Leds controll. 
-* 
+* Initialization function for Sw Leds controll.
+*
 * \param dev      The net device for this driver.
 * \return void.
 *
-* Note: 
-* 
+* Note:
+*
 */
 void
 InitSwLeds(
@@ -49,7 +49,7 @@
 	DMESG("EEPROM Customer ID: %02X\n", priv->EEPROMCustomerID);
 
 	if(priv->CustomerID == RT_CID_DEFAULT)
-	{ // If we have not yet change priv->CustomerID in register, 
+	{ // If we have not yet change priv->CustomerID in register,
 	  // we initialzie it from that of EEPROM with proper translation, 2006.07.03, by rcnjko.
 		switch(priv->EEPROMCustomerID)
 		{
@@ -57,19 +57,19 @@
 		case EEPROM_CID_RSVD1:
 			priv->CustomerID = RT_CID_DEFAULT;
 			break;
-	
+
 		case EEPROM_CID_ALPHA0:
 			priv->CustomerID = RT_CID_8187_ALPHA0;
 			break;
-	
+
 		case EEPROM_CID_SERCOMM_PS:
 			priv->CustomerID = RT_CID_8187_SERCOMM_PS;
 			break;
-	
+
 		case EEPROM_CID_HW_LED:
 			priv->CustomerID = RT_CID_8187_HW_LED;
 			break;
-	
+
 		default:
 			// Invalid value, so, we use default value instead.
 			priv->CustomerID = RT_CID_DEFAULT;
@@ -78,13 +78,13 @@
 	}
 	switch(priv->CustomerID)
 	{
-	case RT_CID_DEFAULT: 
+	case RT_CID_DEFAULT:
 		priv->LedStrategy = SW_LED_MODE0;
 		break;
-	
+
 	case RT_CID_8187_ALPHA0:
 		priv->LedStrategy = SW_LED_MODE1;
-		break;	
+		break;
 
 	case RT_CID_8187_SERCOMM_PS:
 		priv->LedStrategy = SW_LED_MODE3;
@@ -98,27 +98,39 @@
 		priv->LedStrategy = SW_LED_MODE0;
 		break;
 	}
-	
-	InitLed8187(dev, 
-				&(priv->Gpio0Led), 
-				LED_PIN_GPIO0, 
+
+	InitLed8187(dev,
+				&(priv->Gpio0Led),
+				LED_PIN_GPIO0,
 				Gpio0LedBlinkTimerCallback);
-	INIT_WORK(&priv->Gpio0LedWorkItem, 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	INIT_WORK(&priv->Gpio0LedWorkItem,
 				(void(*)(void*))Gpio0LedWorkItemCallback, dev);
+#else
+	INIT_WORK(&priv->Gpio0LedWorkItem, Gpio0LedWorkItemCallback);
+#endif
 
 	InitLed8187(dev,
-				&(priv->SwLed0), 
-				LED_PIN_LED0, 
+				&(priv->SwLed0),
+				LED_PIN_LED0,
 				SwLed0BlinkTimerCallback);
-	INIT_WORK(&priv->SwLed0WorkItem, 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	INIT_WORK(&priv->SwLed0WorkItem,
 				(void(*)(void*))SwLed0WorkItemCallback, dev);
+#else
+	INIT_WORK(&priv->SwLed0WorkItem, SwLed0WorkItemCallback);
+#endif
 
 	InitLed8187(dev,
-				&(priv->SwLed1), 
-				LED_PIN_LED1, 
+				&(priv->SwLed1),
+				LED_PIN_LED1,
 				SwLed1BlinkTimerCallback);
-	INIT_WORK(&priv->SwLed1WorkItem, 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	INIT_WORK(&priv->SwLed1WorkItem,
 				(void(*)(void*))SwLed1WorkItemCallback, dev);
+#else
+	INIT_WORK(&priv->SwLed1WorkItem, SwLed1WorkItemCallback);
+#endif
 }
 
 void
@@ -135,7 +147,7 @@
 
 void
 InitLed8187(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187		pLed,
 	LED_PIN_8187		LedPin,
 	void	* 		BlinkCallBackFunc)
@@ -157,7 +169,7 @@
 
 void
 DeInitLed8187(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed)
 {
 	//PlatformCancelTimer(dev, &(pLed->BlinkTimer));
@@ -178,10 +190,10 @@
 		return;
 
 /*
-	if(	priv->eRFPowerState != eRfOn && 
-		(LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || 
-		 LedAction == LED_CTL_SITE_SURVEY || 
-		 LedAction == LED_CTL_LINK || 
+	if(	priv->eRFPowerState != eRfOn &&
+		(LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
+		 LedAction == LED_CTL_SITE_SURVEY ||
+		 LedAction == LED_CTL_LINK ||
 		 LedAction == LED_CTL_NO_LINK) )
 	{
 		return;
@@ -213,7 +225,7 @@
 
 
 //
-//	Description:	
+//	Description:
 //		Implement each led action for SW_LED_MODE0.
 //		This is default strategy.
 //
@@ -261,7 +273,7 @@
 	case LED_CTL_NO_LINK:
 		pLed->CurrLedState = LED_OFF;
 		break;
-	
+
 	case LED_CTL_POWER_ON:
 		pLed->CurrLedState = LED_POWER_ON_BLINK;
 		break;
@@ -297,10 +309,10 @@
 		{
 			pLed->bLedBlinkInProgress = 1;
 			if( pLed->bLedOn )
-				pLed->BlinkingLedState = LED_OFF; 
+				pLed->BlinkingLedState = LED_OFF;
 			else
-				pLed->BlinkingLedState = LED_ON; 
-			
+				pLed->BlinkingLedState = LED_ON;
+
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
 			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
@@ -312,10 +324,10 @@
 		{
 			pLed->bLedBlinkInProgress = 1;
 			if( pLed->bLedOn )
-				pLed->BlinkingLedState = LED_OFF; 
+				pLed->BlinkingLedState = LED_OFF;
 			else
 				pLed->BlinkingLedState = LED_ON;
-			
+
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
 			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
@@ -334,7 +346,7 @@
 }
 
 //
-//	Description:	
+//	Description:
 //		Implement each led action for SW_LED_MODE1.
 //		For example, this is applied by ALPHA.
 //
@@ -357,9 +369,9 @@
 			pLed0->BlinkTimes = 2;
 			pLed0->bLedBlinkInProgress = 1;
 			if( pLed0->bLedOn )
-				pLed0->BlinkingLedState = LED_OFF; 
+				pLed0->BlinkingLedState = LED_OFF;
 			else
-				pLed0->BlinkingLedState = LED_ON; 
+				pLed0->BlinkingLedState = LED_ON;
 
 			pLed0->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
 			add_timer(&(pLed0->BlinkTimer));
@@ -382,7 +394,7 @@
 			SwLedOff(dev, pLed0);
 		}
 		break;
-	
+
 	case LED_CTL_POWER_ON:
 		pLed0->CurrLedState = LED_OFF;
 		SwLedOff(dev, pLed0);
@@ -407,7 +419,7 @@
 			pLed0->BlinkTimes = 10;
 			pLed0->bLedBlinkInProgress = 1;
 			if( pLed0->bLedOn )
-				pLed0->BlinkingLedState = LED_OFF; 
+				pLed0->BlinkingLedState = LED_OFF;
 			else
 				pLed0->BlinkingLedState = LED_ON;
 
@@ -423,9 +435,9 @@
 }
 
 //
-//	Description:	
-//		Implement each led action for SW_LED_MODE2, 
-//		which is customized for AzWave 8187 minicard.  
+//	Description:
+//		Implement each led action for SW_LED_MODE2,
+//		which is customized for AzWave 8187 minicard.
 //		2006.04.03, by rcnjko.
 //
 void
@@ -450,9 +462,9 @@
 			pLed->BlinkTimes = 2;
 
 			if( pLed->bLedOn )
-				pLed->BlinkingLedState = LED_OFF; 
+				pLed->BlinkingLedState = LED_OFF;
 			else
-				pLed->BlinkingLedState = LED_ON; 
+				pLed->BlinkingLedState = LED_ON;
 
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
 			add_timer(&(pLed->BlinkTimer));
@@ -465,7 +477,7 @@
 		{
 			pLed->bLedBlinkInProgress = 1;
 
-			//if(	dev->MgntInfo.mAssoc || 
+			//if(	dev->MgntInfo.mAssoc ||
 			//	dev->MgntInfo.mIbss )
 			//{
 				pLed->CurrLedState = LED_SCAN_BLINK;
@@ -486,7 +498,7 @@
 			}
 			else
 			{
-				pLed->BlinkingLedState = LED_ON; 
+				pLed->BlinkingLedState = LED_ON;
 				pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
 				add_timer(&(pLed->BlinkTimer));
 				//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
@@ -498,7 +510,7 @@
 			{
 				pLed->CurrLedState = LED_SCAN_BLINK;
 				/*
-				if(	dev->MgntInfo.mAssoc || 
+				if(	dev->MgntInfo.mAssoc ||
 					dev->MgntInfo.mIbss )
 				{
 					pLed->CurrLedState = LED_SCAN_BLINK;
@@ -522,14 +534,14 @@
 
 			if( pLed->bLedOn )
 			{
-				pLed->BlinkingLedState = LED_OFF; 
+				pLed->BlinkingLedState = LED_OFF;
 				pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
 				add_timer(&(pLed->BlinkTimer));
 				//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
 			}
 			else
 			{
-				pLed->BlinkingLedState = LED_ON; 
+				pLed->BlinkingLedState = LED_ON;
 				pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
 				add_timer(&(pLed->BlinkTimer));
 				//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
@@ -564,9 +576,9 @@
 
 
 //
-//	Description:	
-//		Implement each led action for SW_LED_MODE3, 
-//		which is customized for Sercomm Printer Server case. 
+//	Description:
+//		Implement each led action for SW_LED_MODE3,
+//		which is customized for Sercomm Printer Server case.
 //		2006.04.21, by rcnjko.
 //
 void
@@ -591,9 +603,9 @@
 			pLed->BlinkTimes = 2;
 
 			if( pLed->bLedOn )
-				pLed->BlinkingLedState = LED_OFF; 
+				pLed->BlinkingLedState = LED_OFF;
 			else
-				pLed->BlinkingLedState = LED_ON; 
+				pLed->BlinkingLedState = LED_ON;
 
 			pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
 			add_timer(&(pLed->BlinkTimer));
@@ -610,9 +622,9 @@
 			pLed->BlinkTimes = 10;
 
 			if( pLed->bLedOn )
-				pLed->BlinkingLedState = LED_OFF; 
+				pLed->BlinkingLedState = LED_OFF;
 			else
-				pLed->BlinkingLedState = LED_ON; 
+				pLed->BlinkingLedState = LED_ON;
 
 			pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
 			add_timer(&(pLed->BlinkTimer));
@@ -729,18 +741,21 @@
 	}
 }
 
-// 
+//
 // Callback fucntion of the workitem for SW LEDs.
 // 2006.03.01, by rcnjko.
 //
-void
-Gpio0LedWorkItemCallback(
-	void *			Context
-	)
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void Gpio0LedWorkItemCallback(struct work_struct *work)
+{
+	struct r8180_priv *priv = container_of(work, struct r8180_priv, Gpio0LedWorkItem);
+	struct net_device *dev = priv->dev;
+#else
+void Gpio0LedWorkItemCallback(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)Context;
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	PLED_8187	pLed = &(priv->Gpio0Led); 
+#endif
+	PLED_8187	pLed = &(priv->Gpio0Led);
 
 	if(priv->LedStrategy == SW_LED_MODE2)
 		SwLedCm2Blink(dev, pLed);
@@ -750,27 +765,31 @@
 	//LeaveCallbackOfRtWorkItem( &(usbdevice->Gpio0LedWorkItem) );
 }
 
-void
-SwLed0WorkItemCallback(
-	void *			Context
-	)
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void SwLed0WorkItemCallback(struct work_struct *work)
+{
+	struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed0WorkItem);
+	struct net_device *dev = priv->dev;
+#else
+void SwLed0WorkItemCallback(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)Context;
 	struct r8180_priv *priv = ieee80211_priv(dev);
-
+#endif
 	SwLedBlink(dev, &(priv->SwLed0));
 
 	//LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed0WorkItem) );
 }
 
-void
-SwLed1WorkItemCallback(
-	void *			Context
-	)
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void SwLed1WorkItemCallback(struct work_struct *work)
+{
+	struct r8180_priv *priv = container_of(work, struct r8180_priv, SwLed1WorkItem);
+	struct net_device *dev = priv->dev;
+#else
+void SwLed1WorkItemCallback(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)Context;
 	struct r8180_priv *priv = ieee80211_priv(dev);
-
+#endif
 	SwLedBlink(dev, &(priv->SwLed1));
 
 	//LeaveCallbackOfRtWorkItem( &(usbdevice->SwLed1WorkItem) );
@@ -782,19 +801,19 @@
 //
 void
 SwLedBlink(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 	)
 {
 	u8 bStopBlinking = 0;
 
 	// Change LED according to BlinkingLedState specified.
-	if( pLed->BlinkingLedState == LED_ON ) 
+	if( pLed->BlinkingLedState == LED_ON )
 	{
 		SwLedOn(dev, pLed);
 		//DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
-	}	
-	else 
+	}
+	else
 	{
 		SwLedOff(dev, pLed);
 		//DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
@@ -828,40 +847,40 @@
 		}
 
 		pLed->BlinkTimes = 0;
-		pLed->bLedBlinkInProgress = 0;	
+		pLed->bLedBlinkInProgress = 0;
 	}
 	else
 	{
 		// Assign LED state to toggle.
-		if( pLed->BlinkingLedState == LED_ON ) 
+		if( pLed->BlinkingLedState == LED_ON )
 			pLed->BlinkingLedState = LED_OFF;
-		else 
+		else
 			pLed->BlinkingLedState = LED_ON;
 
-		// Schedule a timer to toggle LED state. 
+		// Schedule a timer to toggle LED state.
 		switch( pLed->CurrLedState )
 		{
 		case LED_BLINK_NORMAL:
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
-			add_timer(&(pLed->BlinkTimer));		
+			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
 			break;
 
 		case LED_BLINK_SLOWLY:
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
-			add_timer(&(pLed->BlinkTimer));			
+			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
 			break;
 
 		case LED_BLINK_CM3:
 			pLed->BlinkTimer.expires = jiffies + LED_CM3_BLINK_INTERVAL;
-			add_timer(&(pLed->BlinkTimer));			
+			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM3_BLINK_INTERVAL);
 			break;
 
 		default:
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
-			add_timer(&(pLed->BlinkTimer));			
+			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
 			break;
 		}
@@ -871,11 +890,11 @@
 
 
 //
-//	Implementation of LED blinking behavior for SwLedControlMode2. 
+//	Implementation of LED blinking behavior for SwLedControlMode2.
 //
 void
 SwLedCm2Blink(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 	)
 {
@@ -884,12 +903,12 @@
 	u8 bStopBlinking = 0;
 
 	// Change LED according to BlinkingLedState specified.
-	if( pLed->BlinkingLedState == LED_ON ) 
+	if( pLed->BlinkingLedState == LED_ON )
 	{
 		SwLedOn(dev, pLed);
 		//DMESG("Blinktimes (%d): turn on\n", pLed->BlinkTimes);
-	}	
-	else 
+	}
+	else
 	{
 		SwLedOff(dev, pLed);
 		//DMESG("Blinktimes (%d): turn off\n", pLed->BlinkTimes);
@@ -899,13 +918,13 @@
 	pLed->BlinkTimes--;
 	switch(pLed->CurrLedState)
 	{
-	case LED_BLINK_NORMAL: 
+	case LED_BLINK_NORMAL:
 		if(pLed->BlinkTimes == 0)
 		{
 			bStopBlinking = 1;
 		}
 		break;
-/* CM2 scan blink and no link blind now not be supported 
+/* CM2 scan blink and no link blind now not be supported
 	case LED_SCAN_BLINK:
 		if( (priv->mAssoc || priv->mIbss) &&  // Linked.
 			(!priv->bScanInProgress) && // Not in scan stage.
@@ -916,9 +935,9 @@
 		break;
 
 	case LED_NO_LINK_BLINK:
-		//Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03	
+		//Revised miniCard Ad-hoc mode "Slow Blink" by Isaiah 2006-08-03
 		//if( (priv->mAssoc || priv->mIbss) ) // Linked.
-		if( priv->mAssoc) 
+		if( priv->mAssoc)
 		{
 			bStopBlinking = 1;
 		}
@@ -950,28 +969,28 @@
 		}
 */
 		pLed->BlinkTimes = 0;
-		pLed->bLedBlinkInProgress = 0;	
+		pLed->bLedBlinkInProgress = 0;
 	}
 	else
 	{
 		// Assign LED state to toggle.
-		if( pLed->BlinkingLedState == LED_ON ) 
+		if( pLed->BlinkingLedState == LED_ON )
 			pLed->BlinkingLedState = LED_OFF;
-		else 
+		else
 			pLed->BlinkingLedState = LED_ON;
 
-		// Schedule a timer to toggle LED state. 
+		// Schedule a timer to toggle LED state.
 		switch( pLed->CurrLedState )
 		{
 		case LED_BLINK_NORMAL:
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_NORMAL_INTERVAL;
-			add_timer(&(pLed->BlinkTimer));			
+			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
 			break;
 
 		case LED_BLINK_SLOWLY:
 			pLed->BlinkTimer.expires = jiffies + LED_BLINK_SLOWLY_INTERVAL;
-			add_timer(&(pLed->BlinkTimer));			
+			add_timer(&(pLed->BlinkTimer));
 			//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
 			break;
 
@@ -979,11 +998,11 @@
 		case LED_NO_LINK_BLINK:
 			if( pLed->bLedOn ) {
 				pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_ON_INTERVAL;
-				add_timer(&(pLed->BlinkTimer));				
+				add_timer(&(pLed->BlinkTimer));
 				//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_ON_INTERVAL);
 			} else {
 				pLed->BlinkTimer.expires = jiffies + LED_CM2_BLINK_OFF_INTERVAL;
-				add_timer(&(pLed->BlinkTimer));		
+				add_timer(&(pLed->BlinkTimer));
 				//PlatformSetTimer(dev, &(pLed->BlinkTimer), LED_CM2_BLINK_OFF_INTERVAL);
 			}
 			break;
@@ -1000,7 +1019,7 @@
 
 void
 SwLedOn(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 )
 {
@@ -1032,7 +1051,7 @@
 
 void
 SwLedOff(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 )
 {
@@ -1060,5 +1079,5 @@
 	}
 
 	pLed->bLedOn = 0;
-}	
+}
 
diff -Naur r8187_orig/rtl8187/r8187_led.h r8187_rawtx/rtl8187/r8187_led.h
--- r8187_orig/rtl8187/r8187_led.h	2007-01-15 03:00:37.000000000 +0100
+++ r8187_rawtx/rtl8187/r8187_led.h	2007-05-16 21:51:38.000000000 +0200
@@ -7,7 +7,7 @@
 
 Abstract:
     definitions and stuctures for rtl8187 led control.
-    
+
 Major Change History:
       When        Who	What
     ----------	------	----------------------------------------------
@@ -127,14 +127,14 @@
 
 void
 InitLed8187(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187		pLed,
 	LED_PIN_8187		LedPin,
 	void	* 		BlinkCallBackFunc);
 
 void
 DeInitLed8187(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed);
 
 void
@@ -188,42 +188,37 @@
 	PLED_8187		pLed
 	);
 
-void
-Gpio0LedWorkItemCallback(
-	void *			Context
-	);
-
-void
-SwLed0WorkItemCallback(
-	void *			Context
-	);
-
-void
-SwLed1WorkItemCallback(
-	void *			Context
-	);
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void SwLed0WorkItemCallback(struct work_struct *work);
+void SwLed1WorkItemCallback(struct work_struct *work);
+void Gpio0LedWorkItemCallback(struct work_struct *work);
+#else
+void SwLed0WorkItemCallback(struct net_device *dev);
+void SwLed1WorkItemCallback(struct net_device *dev);
+void Gpio0LedWorkItemCallback(struct net_device *dev);
+#endif
 
 void
 SwLedBlink(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 	);
 
 void
 SwLedCm2Blink(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 	);
 
 void
 SwLedOn(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 );
 
 void
 SwLedOff(
-	struct net_device *dev, 
+	struct net_device *dev,
 	PLED_8187			pLed
 );
 
diff -Naur r8187_orig/symvers r8187_rawtx/symvers
--- r8187_orig/symvers	1970-01-01 01:00:00.000000000 +0100
+++ r8187_rawtx/symvers	2007-05-13 09:54:44.000000000 +0200
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+cd rtl8187
+
+if [ -e Module.symvers ]
+then
+	rm Module.symvers
+fi
+
+if [ -e Modules.symvers ]
+then
+	rm Modules.symvers
+fi
+
+if [ -e ../ieee80211/Module.symvers ]
+then
+	ln -sf ../ieee80211/Module.symvers ./
+fi
+
+if [ -e ../ieee80211/Modules.symvers ]
+then
+	ln -sf ../ieee80211/Modules.symvers ./
+fi
+
+cd ..
\ Kein Zeilenumbruch am Dateiende.
