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-13 09:55:23.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-13 09:55:23.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-13 09:55:23.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-13 09:55:23.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-13 09:55:27.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-13 09:55:23.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-13 09:55:23.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-13 09:55:24.000000000 +0200
@@ -392,9 +392,16 @@
 	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);
 	
@@ -514,7 +521,11 @@
 		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);
@@ -994,8 +1005,14 @@
 	}	
 }
 
+# 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) && 
 		(ieee->modulation & IEEE80211_OFDM_MODULATION)){
@@ -1025,8 +1042,14 @@
 	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);
 	
@@ -1660,7 +1683,6 @@
 	
 	unsigned long flags;
 	int  i;
-	
 	spin_lock_irqsave(&ieee->lock,flags);
 	#if 0
 	if(ieee->queue_stop){
@@ -1691,7 +1713,6 @@
 	}
 	/* 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){
@@ -1874,8 +1895,15 @@
 		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
@@ -2020,8 +2048,16 @@
 	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);
@@ -2225,13 +2261,22 @@
 #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,(void(*)(void*)) ieee80211_start_ibss_wq);
+	INIT_DELAYED_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq);
+	INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq);
+	INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq);
+	INIT_DELAYED_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq);
+	INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) 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
 	
 
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-13 09:55:24.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-13 09:55:24.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-13 09:55:56.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_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-13 09:55:56.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-13 09:55:52.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-13 09:55:52.000000000 +0200
@@ -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)},
@@ -271,9 +275,14 @@
 //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);
 void rtl8180_rq_tx_ack(struct net_device *dev);
 
+# 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-------------------------
 *****************************************************************************/
@@ -436,13 +445,14 @@
 	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)
 {	
@@ -727,7 +737,7 @@
 	
 	usb_fill_bulk_urb(rx_urb,priv->udev,
 		usb_rcvbulkpipe(priv->udev,0x81), rx_urb->transfer_buffer,
-			RX_URB_SIZE,rtl8187_rx_isr,dev);
+			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);
@@ -880,9 +890,12 @@
 	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;
@@ -1228,8 +1241,9 @@
 	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
@@ -1240,21 +1254,28 @@
 	*/
 	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);
+	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR)
+	{
+		rtl8180_tx(dev, skb->data, skb->len, NORM_PRIORITY, morefrag,
+			ieeerate2rtlrate(rate));
 	}
+	else
+	{
+		//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));
 	
-	
-	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);
+		priv->stats.txdatapkt++;
 		
+		if (!check_nic_enought_desc(dev, LOW_PRIORITY))
+			ieee80211_stop_queue(priv->ieee80211);
+	}
+	
 	spin_unlock_irqrestore(&priv->tx_lock,flags);	
 			
 }
@@ -2050,11 +2071,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);
@@ -2259,6 +2288,15 @@
 	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) {
@@ -2701,10 +2739,16 @@
 	_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);
@@ -2885,6 +2929,11 @@
 		//	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;
+			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){ 
@@ -2953,7 +3002,12 @@
 	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){
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-13 09:55:56.000000000 +0200
@@ -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"
@@ -165,14 +170,17 @@
 	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
 	
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-13 09:55:52.000000000 +0200
@@ -103,22 +103,34 @@
 				&(priv->Gpio0Led), 
 				LED_PIN_GPIO0, 
 				Gpio0LedBlinkTimerCallback);
+#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, 
 				SwLed0BlinkTimerCallback);
+#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, 
 				SwLed1BlinkTimerCallback);
+#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
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.
