--- 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; }