Binary files orinoco-cvs-pure/.orinoco.c.swp and orinoco-cvs/.orinoco.c.swp differ
Common subdirectories: orinoco-cvs-pure/CVS and orinoco-cvs/CVS
diff -u orinoco-cvs-pure/orinoco.c orinoco-cvs/orinoco.c
--- orinoco-cvs-pure/orinoco.c	2004-02-26 14:04:18.000000000 -0500
+++ orinoco-cvs/orinoco.c	2004-02-26 14:34:53.000000000 -0500
@@ -430,6 +430,7 @@
  *	o Fix recognition of Intersil x.x.1 firmware (Pavel Roskin).
  *	o Don't let unprivileged users use dump_recs (Pavel Roskin).
  *	o RF monitor mode support (Pavel Roskin).
+ *	o Prism2 and Prism2AVS header support, FCS byte support (Mike Kershaw)
  *
  * TODO
  *	o Handle de-encapsulation within network layer, provide 802.11
@@ -486,6 +487,7 @@
 #include "hermes_rid.h"
 #include "orinoco.h"
 #include "ieee802_11.h"
+#include "prism2header.h"
 
 /********************************************************************/
 /* Module information                                               */
@@ -1133,7 +1135,7 @@
  *
  * Call context: interrupt
  */
-static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, int len)
+static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, struct hermes_rx_descriptor *rxdesc, int len)
 {
 	u32 hdrlen = 30;	/* return full header by default */
 	u32 datalen = 0;
@@ -1144,6 +1146,11 @@
 	struct orinoco_private *priv = dev->priv;
 	struct net_device_stats *stats = &priv->stats;
 	hermes_t *hw = &priv->hw;
+    int skballoclen;
+    uint8_t *datap;
+    p80211msg_lnxind_wlansniffrm_t  *prism2hdr;
+    prism2_avs_80211_v1_header *prism2avshdr;
+    uint8_t fcsquad[4] = {0xFF, 0xFF, 0xFF, 0xFF};
 
 	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr), rxfid, 
 			       HERMES_802_11_OFFSET);
@@ -1196,7 +1203,19 @@
 		goto drop;
 	}
 
-	skb = dev_alloc_skb(hdrlen + datalen);
+    /* Handle allocation for different custom headers */
+    if (priv->prism2header == 1 && dev->type == ARPHRD_IEEE80211_PRISM) 
+        skballoclen = hdrlen + datalen + sizeof(p80211msg_lnxind_wlansniffrm_t);
+    else if (priv->prism2header == 2 && dev->type == ARPHRD_IEEE80211_PRISM) 
+        skballoclen = hdrlen + datalen + sizeof(prism2_avs_80211_v1_header);
+    else
+        skballoclen = hdrlen + datalen;
+
+    /* Handle FCS bytes */
+    if (priv->fcsbytes)
+        skballoclen = skballoclen + 4;
+   
+	skb = dev_alloc_skb(skballoclen);
 	if (!skb) {
 		printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
 		       dev->name);
@@ -1204,13 +1223,100 @@
 		goto drop;
 	}
 
+    skb_put(skb, skballoclen); 
+
+    /* WARNING: Right now we build just prism2, not AVS! */
+    /* Do we build a custom header?  Only attach it if we're in the right linktype */
+    if (priv->prism2header == 1 && dev->type == ARPHRD_IEEE80211_PRISM) {
+        datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
+        prism2hdr = (p80211msg_lnxind_wlansniffrm_t *) skb->data;
+
+        /* Initialize the message members */
+        prism2hdr->msgcode = DIDmsg_lnxind_wlansniffrm;
+        prism2hdr->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+        strcpy(prism2hdr->devname, priv->ndev->name);
+
+        prism2hdr->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+        prism2hdr->hosttime.status = 0;
+        prism2hdr->hosttime.len = 4;
+        prism2hdr->hosttime.data = jiffies;
+
+        prism2hdr->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+        prism2hdr->mactime.status = 0;
+        prism2hdr->mactime.len = 4;
+        prism2hdr->mactime.data = rxdesc->time;
+
+        prism2hdr->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+        prism2hdr->channel.status = P80211ENUM_msgitem_status_no_value;
+        prism2hdr->channel.len = 4;
+        prism2hdr->channel.data = 0;
+
+        prism2hdr->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+        prism2hdr->rssi.status = P80211ENUM_msgitem_status_no_value;
+        prism2hdr->rssi.len = 4;
+        prism2hdr->rssi.data = 0;
+
+        prism2hdr->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+        prism2hdr->sq.status = P80211ENUM_msgitem_status_no_value;
+        prism2hdr->sq.len = 4;
+        prism2hdr->sq.data = 0;
+
+        prism2hdr->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+        prism2hdr->signal.status = 0;
+        prism2hdr->signal.len = 4;
+        prism2hdr->signal.data = rxdesc->signal;
+
+        prism2hdr->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+        prism2hdr->noise.status = 0;
+        prism2hdr->noise.len = 4;
+        prism2hdr->noise.data = rxdesc->silence;
+
+        prism2hdr->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+        prism2hdr->rate.status = 0;
+        prism2hdr->rate.len = 4;
+        prism2hdr->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+        prism2hdr->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+        prism2hdr->istx.status = 0;
+        prism2hdr->istx.len = 4;
+        prism2hdr->istx.data = P80211ENUM_truth_false;
+
+        prism2hdr->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+        prism2hdr->frmlen.status = 0;
+        prism2hdr->frmlen.len = 4;
+        prism2hdr->frmlen.data = hdrlen + datalen;
+    } else if (priv->prism2header == 2 && dev->type == ARPHRD_IEEE80211_PRISM) {
+        datap = skb->data + sizeof(prism2_avs_80211_v1_header);
+        prism2avshdr = (prism2_avs_80211_v1_header *) skb->data;
+
+        prism2avshdr->version = htonl(P80211CAPTURE_VERSION);
+        prism2avshdr->length = htonl(sizeof(prism2_avs_80211_v1_header));
+        prism2avshdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
+        prism2avshdr->hosttime = __cpu_to_be64(jiffies);
+        prism2avshdr->phytype = htonl(4); /* 802.11b */
+        prism2avshdr->channel = htonl(0);
+        prism2avshdr->datarate = htonl(rxdesc->rate);
+        prism2avshdr->antenna = htonl(0);
+        prism2avshdr->priority = htonl(0);
+        prism2avshdr->ssi_type = htonl(3); /* ssi raw */
+        prism2avshdr->ssi_signal = htonl(rxdesc->signal);
+        prism2avshdr->ssi_noise = htonl(rxdesc->silence);
+        prism2avshdr->preamble = htonl(0); /* Unknown */
+        prism2avshdr->encoding = htonl(1); /* CCK */
+    } else {
+        datap = skb->data;
+    }
+    
 	/* Copy the 802.11 header to the skb */
+    /*
 	memcpy(skb_put(skb, hdrlen), &(hdr.frame_ctl), hdrlen);
+    */
+    memcpy(datap, &(hdr.frame_ctl), hdrlen);
 	skb->mac.raw = skb->data;
 
 	/* If any, copy the data from the card to the skb */
 	if (datalen > 0) {
-		err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
+		err = hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen,
 				 (datalen + 1) & ~1, rxfid,
 				 HERMES_802_2_OFFSET);
 		if (err) {
@@ -1220,6 +1326,10 @@
 		}
 	}
 
+    /* Attach the FCS if requested */
+    if (priv->fcsbytes)
+        memcpy(skb->data + skballoclen - 4, fcsquad, 4);
+
 	skb->dev = dev;
 	skb->ip_summed = CHECKSUM_NONE;
 	skb->pkt_type = PACKET_OTHERHOST;
@@ -1298,7 +1408,7 @@
 	
 	/* Handle monitor frames */
 	if (port == 7) {
-		orinoco_rx_monitor(dev, rxfid, length);
+		orinoco_rx_monitor(dev, rxfid, &desc, length);
 		return;
 	}
 
@@ -2075,9 +2185,16 @@
 		}
 	}
 
-	if (priv->iw_mode == IW_MODE_MONITOR && dev->type != ARPHRD_IEEE80211) {
+    /* Is this the nicest way of doing this?  - dragorn */
+	if (priv->iw_mode == IW_MODE_MONITOR && dev->type == ARPHRD_ETHER) {
 		/* Enable monitor mode */
-		dev->type = ARPHRD_IEEE80211;
+
+        /* Set the link type */
+        if (priv->prism2header)
+            dev->type = ARPHRD_IEEE80211_PRISM;
+        else
+            dev->type = ARPHRD_IEEE80211;
+
 		err = hermes_docmd_wait(hw,
 					HERMES_CMD_MONITOR | HERMES_MONITOR_ENABLE,
 					0, NULL);
@@ -2085,7 +2202,8 @@
 			return err;
 	}
 
-	if (priv->iw_mode != IW_MODE_MONITOR && dev->type == ARPHRD_IEEE80211) {
+    /* Again, best way to test?  Do we ever use anything other than ARPHRD_ETHER for normal mode? */
+	if (priv->iw_mode != IW_MODE_MONITOR && dev->type != ARPHRD_ETHER) {
 		/* Disable monitor mode */
 		dev->type = ARPHRD_ETHER;
 		err = hermes_docmd_wait(hw,
@@ -2653,6 +2771,10 @@
 	priv->wep_on = 0;
 	priv->tx_key = 0;
 
+    /* Don't turn on the rfmon fancy stuff by default */
+    priv->prism2header = 0;
+    priv->fcsbytes = 0;
+
 	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
 	if (err == -EIO) {
 		/* Try workaround for old Symbol firmware bug */
@@ -4369,6 +4491,60 @@
 }
 #endif	/* WIRELESS_EXT > 13 */
 
+/* Set the prism2 headers */
+static int orinoco_ioctl_setprism2header(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+{
+	struct orinoco_private *priv = dev->priv;
+	int val = *( (int *) extra );
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+    /* Only allow legal values: 0 off, 1 prism2, 2 prism2avs */
+    if (val < 0 || val > 2)
+        return -EINVAL;
+
+    /* If we're in rfmon, update the linktype appropriately */
+    if (priv->iw_mode == IW_MODE_MONITOR && dev->type != ARPHRD_IEEE80211_PRISM && val) {
+        printk(KERN_DEBUG "setting type ieee80211_prism\n");
+        dev->type = ARPHRD_IEEE80211_PRISM;
+    } else if (priv->iw_mode == IW_MODE_MONITOR && dev->type != ARPHRD_IEEE80211 && val == 0) {
+        printk(KERN_DEBUG "setting type ieee80211\n");
+        dev->type = ARPHRD_IEEE80211;
+    }
+    
+    priv->prism2header = val;
+
+	orinoco_unlock(priv, &flags);
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+/* Set if we append trailing FCS bytes */
+static int orinoco_ioctl_setfcsbytes(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+{
+	struct orinoco_private *priv = dev->priv;
+	int val = *( (int *) extra );
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+    if (val < 0 || val > 1)
+        return -EINVAL;
+    
+    priv->fcsbytes = val;
+
+	orinoco_unlock(priv, &flags);
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
 /* Commit handler, called after set operations */
 static int orinoco_ioctl_commit(struct net_device *dev,
 				struct iw_request_info *info,
@@ -4461,6 +4637,12 @@
 	{ SIOCIWFIRSTPRIV + 0x7, 0,
 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	  "get_ibssport" },
+	{ SIOCIWFIRSTPRIV + 0x8,
+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_prismheader" },
+	{ SIOCIWFIRSTPRIV + 0x9,
+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_fcsbytes" },
 	{ SIOCIWLASTPRIV, 0, 0, "dump_recs" },
 };
 
@@ -4538,6 +4720,8 @@
 	(iw_handler) orinoco_ioctl_getpreamble,		/* SIOCIWFIRSTPRIV + 5 */
 	(iw_handler) orinoco_ioctl_setibssport,		/* SIOCIWFIRSTPRIV + 6 */
 	(iw_handler) orinoco_ioctl_getibssport,		/* SIOCIWFIRSTPRIV + 7 */
+    (iw_handler) orinoco_ioctl_setprism2header, /* SIOCIWFIRSTPRIV + 8 */
+    (iw_handler) orinoco_ioctl_setfcsbytes,     /* SIOCIWFIRSTPRIV + 9 */
 	[SIOCIWLASTPRIV - SIOCIWFIRSTPRIV] (iw_handler) orinoco_debug_dump_recs,
 };
 
diff -u orinoco-cvs-pure/orinoco.h orinoco-cvs/orinoco.h
--- orinoco-cvs-pure/orinoco.h	2004-02-26 14:04:18.000000000 -0500
+++ orinoco-cvs/orinoco.h	2004-02-26 11:25:12.000000000 -0500
@@ -123,6 +123,11 @@
 	u32	scan_mode;		/* Type of scan done */
 	char *	scan_result;		/* Result of previous scan */
 	int	scan_len;		/* Lenght of result */
+
+    /* rfmon format */
+    int prism2header; /* Attach no header, prism2, or prism2_avs to rfmon packets */
+    int fcsbytes; /* Attach a bogus 4-byte FCS to packets */
+
 };
 
 #ifdef ORINOCO_DEBUG
Only in orinoco-cvs: prism2header.h
