nexmon – Rev 1

Subversion Repositories:
Rev:
--- rtl8187_linux_26.1010.0622.2006/beta-8187/ieee80211.h       2006-06-06 04:58:02.000000000 +0200
+++ rtl8187_prismhdr/beta-8187/ieee80211.h      2006-11-29 20:28:16.152853116 +0100
@@ -156,6 +156,23 @@
        struct list_head list;
 };
 
+#define LWNG_CAP_DID_BASE   (4 | (1 << 6)) /* section 4, group 1 */
+#define IW_MODE_MONITOR_PRISM  15
+/* 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;
--- rtl8187_linux_26.1010.0622.2006/beta-8187/r8187_core.c      2006-06-22 07:43:30.000000000 +0200
+++ rtl8187_prismhdr/beta-8187/r8187_core.c     2006-12-16 16:44:12.244211046 +0100
@@ -1112,7 +1112,10 @@
        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 || priv->ieee80211->raw_tx != 1)
+                       morefrag = 1;
+       }
 //     DMESG("%x %x", h->frame_ctl, h->seq_ctl);
        /*
        * This function doesn't require lock because we make
@@ -2346,7 +2349,8 @@
                
                if( flen <= rx_urb->actual_length){
                
-                       stats.signal = (desc[1] & 0x7f00)>>8;
+//                     stats.signal = (desc[1] & 0x7f00)>>8;
+                       stats.signal = (desc[1] & 0xff00)>>8;
                        stats.noise = desc[1] &0xff;
                        stats.rate = desc[0] >> 20 & 0xf;
                        stats.mac_time[0] = desc[2];
@@ -2368,6 +2372,8 @@
                //      priv->rxskb = skb;
                //      priv->tempstats = &stats;
 
+
+                       stats.signal -= stats.noise;
                        if(!ieee80211_rx(priv->ieee80211, 
                                skb, &stats))
                        dev_kfree_skb_any(skb);
--- rtl8187_linux_26.1010.0622.2006/beta-8187/r8187.h   2006-06-06 08:48:10.000000000 +0200
+++ rtl8187_prismhdr/beta-8187/r8187.h  2006-12-16 16:44:31.418296142 +0100
@@ -148,7 +148,7 @@
        u8 challow[15]; //channels from 1 to 14, 0 not used
        short up;
        short crcmon; //if 1 allow bad crc frame reception in monitor mode
-//     short prism_hdr;
+       short prism_hdr;
        
 //     struct timer_list scan_timer;
        /*short scanpending;
--- rtl8187_linux_26.1010.0622.2006/ieee80211/ieee80211.h       2006-06-06 04:57:56.000000000 +0200
+++ rtl8187_prismhdr/ieee80211/ieee80211.h      2006-11-29 20:45:25.190415628 +0100
@@ -156,6 +156,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;
--- rtl8187_linux_26.1010.0622.2006/ieee80211/ieee80211_rx.c    2006-06-06 04:58:00.000000000 +0200
+++ rtl8187_prismhdr/ieee80211/ieee80211_rx.c   2006-12-14 11:40:23.461865287 +0100
@@ -49,12 +49,72 @@
                                        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);
+       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, 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
+       }
 
        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));
--- rtl8187_linux_26.1010.0622.2006/ieee80211/ieee80211_tx.c    2006-06-06 04:57:54.000000000 +0200
+++ rtl8187_prismhdr/ieee80211/ieee80211_tx.c   2006-12-16 11:57:57.695139366 +0100
@@ -458,7 +458,8 @@
                        ieee->seq_ctrl++;
                //---
        }else{
-               if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
+//             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;
--- rtl8187_linux_26.1010.0622.2006/ieee80211/ieee80211_softmac_wx.c    2006-06-06 04:57:54.000000000 +0200
+++ rtl8187_prismhdr/ieee80211/ieee80211_softmac_wx.c   2006-11-29 20:43:49.275996836 +0100
@@ -245,8 +245,7 @@
                goto out;
        
        if (wrqu->mode == IW_MODE_MONITOR){
-       
-               ieee->dev->type = ARPHRD_IEEE80211;
+               ieee->dev->type = ARPHRD_IEEE80211_PRISM;
        }else{
                ieee->dev->type = ARPHRD_ETHER;
        }