File: kernel/pcmcia-cs/files/gar-base.diff
base-0 patch-1
Line 1Line 1
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/cardmgr/Makefile work/pcmcia-cs-3.2.3/cardmgr/Makefile
--- tmp/pcmcia-cs-3.2.3/cardmgr/Makefile        2002-10-09 21:20:58.000000000 -0700
+++ work/pcmcia-cs-3.2.3/cardmgr/Makefile        2003-01-20 12:59:15.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/cardmgr/Makefile work/main.d/pcmcia-cs-3.2.3/cardmgr/Makefile
--- tmp/pcmcia-cs-3.2.3/cardmgr/Makefile        2002-10-09 23:20:58.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/cardmgr/Makefile        2003-05-13 07:28:08.000000000 -0500
Line Line
        chmod u+s $(PREFIX)/usr/X11R6/bin/xcardinfo

        chmod u+s $(PREFIX)/usr/X11R6/bin/xcardinfo

Line 12Line 12

install-probe: pcic_probe
        @mkdir -p $(PREFIX)/sbin

install-probe: pcic_probe
        @mkdir -p $(PREFIX)/sbin
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/debug-tools/Makefile work/pcmcia-cs-3.2.3/debug-tools/Makefile
--- tmp/pcmcia-cs-3.2.3/debug-tools/Makefile        2001-02-06 16:41:40.000000000 -0800
+++ work/pcmcia-cs-3.2.3/debug-tools/Makefile        2003-01-20 12:59:15.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/debug-tools/Makefile work/main.d/pcmcia-cs-3.2.3/debug-tools/Makefile
--- tmp/pcmcia-cs-3.2.3/debug-tools/Makefile        2001-02-06 18:41:40.000000000 -0600
+++ work/main.d/pcmcia-cs-3.2.3/debug-tools/Makefile        2003-05-13 07:28:08.000000000 -0500
Line Line
        cp -f dump_cis pack_cis $(PREFIX)/sbin
ifdef CONFIG_PNP_BIOS
        cp -f dump_cis pack_cis $(PREFIX)/sbin
ifdef CONFIG_PNP_BIOS
Line 26Line 26
endif

include ../rules.mk
endif

include ../rules.mk
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/ide.opts work/pcmcia-cs-3.2.3/etc/ide.opts
--- tmp/pcmcia-cs-3.2.3/etc/ide.opts        2000-06-06 14:01:50.000000000 -0700
+++ work/pcmcia-cs-3.2.3/etc/ide.opts        2003-01-20 12:59:51.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/ide.opts work/main.d/pcmcia-cs-3.2.3/etc/ide.opts
--- tmp/pcmcia-cs-3.2.3/etc/ide.opts        2000-06-06 16:01:50.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/etc/ide.opts        2003-05-13 07:28:08.000000000 -0500
Line Line
*,*,*)
#PARTS="1"
*,*,*)
#PARTS="1"
Line 38Line 38
NO_FUSER=n
;;
esac
NO_FUSER=n
;;
esac
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/memory.opts work/pcmcia-cs-3.2.3/etc/memory.opts
--- tmp/pcmcia-cs-3.2.3/etc/memory.opts        2000-06-06 14:01:50.000000000 -0700
+++ work/pcmcia-cs-3.2.3/etc/memory.opts        2003-01-20 13:00:00.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/memory.opts work/main.d/pcmcia-cs-3.2.3/etc/memory.opts
--- tmp/pcmcia-cs-3.2.3/etc/memory.opts        2000-06-06 16:01:50.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/etc/memory.opts        2003-05-13 07:28:08.000000000 -0500
Line Line
#OPTS=""
#MOUNTPT="/mnt/mem"
#OPTS=""
#MOUNTPT="/mnt/mem"
Line 50Line 50
NO_FUSER=n
;;
esac
NO_FUSER=n
;;
esac
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/network.opts work/pcmcia-cs-3.2.3/etc/network.opts
--- tmp/pcmcia-cs-3.2.3/etc/network.opts        2000-06-06 14:01:50.000000000 -0700
+++ work/pcmcia-cs-3.2.3/etc/network.opts        2003-01-20 13:00:09.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/network.opts work/main.d/pcmcia-cs-3.2.3/etc/network.opts
--- tmp/pcmcia-cs-3.2.3/etc/network.opts        2000-06-06 16:01:50.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/etc/network.opts        2003-05-13 07:28:08.000000000 -0500
Line Line
# Extra stuff to do before shutting down the interface
stop_fn () { return; }
# Extra stuff to do before shutting down the interface
stop_fn () { return; }
Line 62Line 62
NO_FUSER=n
;;
esac
NO_FUSER=n
;;
esac
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/parport.opts work/pcmcia-cs-3.2.3/etc/parport.opts
--- tmp/pcmcia-cs-3.2.3/etc/parport.opts        2000-06-06 14:01:50.000000000 -0700
+++ work/pcmcia-cs-3.2.3/etc/parport.opts        2003-01-20 13:00:15.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/parport.opts work/main.d/pcmcia-cs-3.2.3/etc/parport.opts
--- tmp/pcmcia-cs-3.2.3/etc/parport.opts        2000-06-06 16:01:50.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/etc/parport.opts        2003-05-13 07:28:08.000000000 -0500
Line Line
# Options for 'tunelp'
#LP_OPTS=""
# Options for 'tunelp'
#LP_OPTS=""
Line 74Line 74
NO_FUSER=n
;;
esac
NO_FUSER=n
;;
esac
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/scsi.opts work/pcmcia-cs-3.2.3/etc/scsi.opts
--- tmp/pcmcia-cs-3.2.3/etc/scsi.opts        2000-06-06 14:01:50.000000000 -0700
+++ work/pcmcia-cs-3.2.3/etc/scsi.opts        2003-01-20 13:00:19.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/scsi.opts work/main.d/pcmcia-cs-3.2.3/etc/scsi.opts
--- tmp/pcmcia-cs-3.2.3/etc/scsi.opts        2000-06-06 16:01:50.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/etc/scsi.opts        2003-05-13 07:28:08.000000000 -0500
Line Line
OPTS="ro,noauto"
OPTS="ro,noauto"
MOUNTPT="/mnt/media"
MOUNTPT="/mnt/cdrom"
# Card eject policy options
- NO_CHECK=n
+ NO_CHECK=y
NO_FUSER=n
;;
esac
# Card eject policy options
- NO_CHECK=n
+ NO_CHECK=y
NO_FUSER=n
;;
esac
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/serial.opts work/pcmcia-cs-3.2.3/etc/serial.opts
--- tmp/pcmcia-cs-3.2.3/etc/serial.opts        2001-02-27 16:30:50.000000000 -0800
+++ work/pcmcia-cs-3.2.3/etc/serial.opts        2003-01-20 13:00:24.000000000 -0800
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/scsi.opts.orig work/main.d/pcmcia-cs-3.2.3/etc/scsi.opts.orig
--- tmp/pcmcia-cs-3.2.3/etc/scsi.opts.orig        1969-12-31 18:00:00.000000000 -0600
+++ work/main.d/pcmcia-cs-3.2.3/etc/scsi.opts.orig        2000-06-06 16:01:50.000000000 -0500
@@ -0,0 +1,23 @@
+# SCSI adapter configuration
+#
+# The address format is "scheme,type,socket,channel,id,lun[,part]".
+#
+# For multi-partition devices, first return list of partitions in
+# $PARTS. Then, we'll get called for each partition.
+#
+# This example will mount any CD-ROM on /cdrom, if possible.
+#
+case "$ADDRESS" in
+*,sr,*,*,*,*)
+ INFO="Default CD-ROM setup"
+ LINK="/dev/cdrom"
+ PARTS=""
+ DO_FSTAB="y" ; DO_FSCK="n" ; DO_MOUNT="n"
+ FSTYPE="iso9660"
+ OPTS="ro,noauto"
+ MOUNTPT="/mnt/cdrom"
+ # Card eject policy options
+ NO_CHECK=n
+ NO_FUSER=n
+ ;;
+esac
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/etc/serial.opts work/main.d/pcmcia-cs-3.2.3/etc/serial.opts
--- tmp/pcmcia-cs-3.2.3/etc/serial.opts        2001-02-27 18:30:50.000000000 -0600
+++ work/main.d/pcmcia-cs-3.2.3/etc/serial.opts        2003-05-13 07:28:08.000000000 -0500
Line Line
# Extra stuff to do before shutting down the device
stop_fn () { return; }
# Extra stuff to do before shutting down the device
stop_fn () { return; }
Line 98Line 125
NO_FUSER=n
;;
esac
NO_FUSER=n
;;
esac

diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/wireless/hermes.c work/main.d/pcmcia-cs-3.2.3/wireless/hermes.c
--- tmp/pcmcia-cs-3.2.3/wireless/hermes.c        2002-05-01 22:37:30.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/wireless/hermes.c        2003-05-13 07:29:06.000000000 -0500
@@ -187,6 +187,10 @@
        if (err)
                return err;

+ for ( k = 0; k < HERMES_NUMPORTS_MAX; k++) {
+                hw->port_enabled[k] = 0;
+        }
+
        reg = hermes_read_regn(hw, EVSTAT);
        k = CMD_INIT_TIMEOUT;
        while ( (! (reg & HERMES_EV_CMD)) && k) {
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/wireless/hermes.h work/main.d/pcmcia-cs-3.2.3/wireless/hermes.h
--- tmp/pcmcia-cs-3.2.3/wireless/hermes.h        2002-05-01 22:32:39.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/wireless/hermes.h        2003-05-13 07:29:06.000000000 -0500
@@ -33,6 +33,10 @@
#include <linux/if_ether.h>
#include <asm/byteorder.h>

+#define                HFA384x_PORTTYPE_IBSS                        ((uint16_t)3)
+#define                HFA384x_WEPFLAGS_DISABLE_TXCRYPT        (0x10)
+#define                HFA384x_WEPFLAGS_DISABLE_RXCRYPT        (0x80)
+
/*
* Limits and constants
*/
@@ -149,6 +153,38 @@
#define                HERMES_MONITOR_DISABLE                (0x000f)

/*
+ * Configuration RIDs
+ */
+
+#define                HERMES_RID_CNF_PORTTYPE                (0xfc00)
+#define                HERMES_RID_CNF_CHANNEL                (0xfc03)
+#define                HERMES_RID_CNF_PRISM2_WEP_ON        (0xfc28)
+
+/*-- Status Fields --*/
+#define                HERMES_RXSTATUS_MSGTYPE                (0xE000)
+#define                HERMES_RXSTATUS_MACPORT                (0x0700)
+#define                HERMES_RXSTATUS_UNDECR                (0x0002)
+#define                HERMES_RXSTATUS_FCSERR                (0x0001)
+
+/*--------------------------------------------------------------------
+Communication Frames: Test/Get/Set Field Values for Receive Frames
+--------------------------------------------------------------------*/
+#define                HERMES_RXSTATUS_MSGTYPE_GET(value)        (((value) & HERMES_RXSTATUS_MSGTYPE) >> 13)
+#define                HERMES_RXSTATUS_MSGTYPE_SET(value)        ((value) << 13)
+#define                HERMES_RXSTATUS_MACPORT_GET(value)        (((value) & HERMES_RXSTATUS_MACPORT) >> 8)
+#define                HERMES_RXSTATUS_MACPORT_SET(value)        ((value) << 8)
+#define                HERMES_RXSTATUS_ISUNDECR(value)        ((value) & HERMES_RXSTATUS_UNDECR)
+#define                HERMES_RXSTATUS_ISFCSERR(value)        ((value) & HERMES_RXSTATUS_FCSERR)
+
+/*--------------------------------------------------------------------
+Communication Frames: Field Masks for Receive Frames
+--------------------------------------------------------------------*/
+/*-- Offsets --------*/
+#define                HERMES_RX_DATA_LEN_OFF                (44)
+#define                HERMES_RX_80211HDR_OFF                (14)
+#define                HERMES_RX_DATA_OFF                        (60)
+
+/*
* Frame structures and constants
*/

@@ -274,6 +310,7 @@
#define HERMES_32BIT_REGSPACING        1

        u16 inten; /* Which interrupts should be enabled? */
+         uint8_t                port_enabled[HERMES_NUMPORTS_MAX];

#ifdef HERMES_DEBUG_BUFFER
        struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
@@ -333,12 +370,14 @@

static inline int hermes_enable_port(hermes_t *hw, int port)
{
+ hw->port_enabled[port] = 1;
        return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
                                0, NULL);
}

static inline int hermes_disable_port(hermes_t *hw, int port)
{
+ hw->port_enabled[port] = 0;
        return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
                                0, NULL);
}
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/wireless/orinoco.c work/main.d/pcmcia-cs-3.2.3/wireless/orinoco.c
--- tmp/pcmcia-cs-3.2.3/wireless/orinoco.c        2002-08-08 01:43:30.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/wireless/orinoco.c        2003-05-13 07:30:15.000000000 -0500
@@ -638,6 +638,12 @@
        if (err)
                goto out;

+        /* Set the MAC address */
+        err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+                        HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+        if (err)
+                goto out;
+
        err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
        if (err == -EIO) {
                /* Try workaround for old Symbol firmware bug */
@@ -1317,6 +1323,7 @@
        struct header_struct hdr;
        struct ethhdr *eh;
        int err;
+ struct ieee802_11_hdr hdr80211;

        rxfid = hermes_read_regn(hw, RXFID);
        DEBUG(3, "__orinoco_ev_rx(): RXFID=0x%04x\n", rxfid);
@@ -1334,6 +1341,7 @@
       
        if (status & HERMES_RXSTAT_ERR) {
                if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+ if (dev->type != ARPHRD_ETHER) goto sniffing;
                        wstats->discard.code++;
                        DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
                        dev->name);
@@ -1344,7 +1352,7 @@
                stats->rx_errors++;
                goto drop;
        }
-
+sniffing:
        /* For now we ignore the 802.11 header completely, assuming
that the card's firmware has handled anything vital */

@@ -1374,6 +1382,10 @@
                stats->rx_errors++;
                goto drop;
        }
+        /* Now handle frame based on port# */
+        switch( HERMES_RXSTATUS_MACPORT_GET(status) )
+        {
+        case 0:

        /* We need space for the packet data itself, plus an ethernet
        header, plus 2 bytes so we can align the IP header on a
@@ -1452,6 +1464,26 @@

        return;

+        case 7:
+         if ( ! HERMES_RXSTATUS_ISFCSERR(status) ) {
+ if (hermes_bap_pread(hw, IRQ_BAP, &hdr80211, sizeof(hdr80211),
+ rxfid, HERMES_RX_80211HDR_OFF)) {
+ stats->rx_errors++;
+ }
+ else {
+ /* Copy to wlansnif skb */
+ orinoco_int_rxmonitor( priv, rxfid, length, &desc, &hdr80211);
+ }
+ } else {
+ printk("Received monitor frame: FCSerr set\n");
+ }
+ break;
+
+        default:
+                printk("Received frame on unsupported port=%d\n",
+                        HERMES_RXSTATUS_MACPORT_GET(status) );
+                break;
+        }
drop:       
        if (skb)
                dev_kfree_skb_irq(skb);
@@ -2036,6 +2068,24 @@
        return err;
}

+#define SET_MAC_ADDRESS
+#ifdef SET_MAC_ADDRESS
+static int
+orinoco_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct orinoco_private *priv = dev->priv;
+ struct sockaddr *mac = addr;
+
+ /* Copy the address */
+ memcpy(dev->dev_addr, mac->sa_data, WLAN_ADDR_LEN);
+
+ /* Reconfig the beast */
+ orinoco_reset(priv);
+
+ return 0;
+}
+#endif        /* SET_MAC_ADDRESS */
+
static void
orinoco_tx_timeout(struct net_device *dev)
{
@@ -3129,6 +3179,157 @@
        return 0;
}

+/*----------------------------------------------------------------
+* orinoco_wlansniff
+*
+* Start or stop sniffing.
+*
+* Arguments:
+*        wlandev                wlan device structure
+*        msgp                ptr to msg buffer
+*
+* Returns:
+*        0        success and done
+*        <0        success, but we're waiting for something to finish.
+*        >0        an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*        process thread (usually)
+*        interrupt
+----------------------------------------------------------------*/
+static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq)
+{
+        struct orinoco_private *priv = dev->priv;
+
+        hermes_t                *hw = &(priv->hw);
+ hermes_response_t resp;
+        int                         result = 0;
+        uint16_t                        word;
+
+        int *parms = (int *) wrq->u.name;
+        int enable = parms[0] > 0;
+
+        orinoco_lock(priv);
+
+        switch (enable)
+        {
+        case P80211ENUM_truth_false:
+                /* Confirm that we're in monitor mode */
+                if ( dev->type == ARPHRD_ETHER ) {
+                        result = -EFAULT;
+                }
+                /* Disable monitor mode */
+        word =        HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8);
+        result = hermes_docmd_wait(hw, word, 0, &resp);
+
+                if ( result ) break;
+
+                /* Disable port 0 */
+                result = hermes_disable_port(hw, 0);
+                if ( result ) break;
+
+                /* Clear the driver state */
+                dev->type = ARPHRD_ETHER;
+
+                /* Restore the wepflags */ //Orinoco doesn't like this
+/*
+                result = hermes_write_wordrec(hw, USER_BAP,
+                                HERMES_RID_CNF_PRISM2_WEP_ON,
+                                priv->presniff_wepflags);
+                if ( result ) break;
+
+*/
+                /* Set the port to its prior type and enable (if necessary) */
+                if (priv->presniff_port_type != 0 ) {
+                        word = priv->presniff_port_type;
+                        result = hermes_write_wordrec(hw, USER_BAP,
+                                HERMES_RID_CNF_PORTTYPE, word);
+                if ( result ) break;
+
+                        /* Enable the port */
+                        result = hermes_enable_port(hw, 0);
+                if ( result ) break;
+
+                }
+
+                break;
+        case P80211ENUM_truth_true:
+                /* Disable the port (if enabled), only check Port 0 */
+                if ( hw->port_enabled[0] ) {
+                        /* Save macport 0 state */
+                        result = hermes_read_wordrec(hw, USER_BAP,
+                                        HERMES_RID_CNF_PORTTYPE,
+                                        &(priv->presniff_port_type));
+                if ( result ) break;
+
+                        /* Save the wepflags state */
+                        result = hermes_read_wordrec(hw, USER_BAP,
+                                        HERMES_RID_CNF_PRISM2_WEP_ON,
+                                        &(priv->presniff_wepflags));
+                if ( result ) break;
+                        result = hermes_disable_port(hw, 0);
+                if ( result ) break;
+
+                }
+                else {
+                        priv->presniff_port_type = 0;
+                }
+
+                /* Set the channel we wish to sniff */
+                if (parms[1] > 0 && parms[1] < 15) {
+                 word = parms[1];
+                result = hermes_write_wordrec(hw, USER_BAP,
+                                HERMES_RID_CNF_CHANNEL, word);
+                } else {
+                 result = -EFAULT;
+                }
+
+                if ( result ) break;
+
+                /* Set the port type to pIbss */
+                word = HFA384x_PORTTYPE_IBSS;
+                result = hermes_write_wordrec(hw, USER_BAP,
+                                HERMES_RID_CNF_PORTTYPE, word);
+                if ( result ) break;
+
+/*
+         if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) &&
+ (msg->keepwepflags.data != P80211ENUM_truth_true)) {
+                // Set the wepflags for no decryption //Orinoco doesn't like this
+        word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
+                        HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+                result = hermes_write_wordrec(hw, USER_BAP,
+                                HERMES_RID_CNF_PRISM2_WEP_ON, word); //won't work with the bits above
+ }
+                if ( result ) break;
+
+*/
+                /* Enable the port */
+                result = hermes_enable_port(hw, 0);
+                if ( result ) break;
+
+                /* Enable monitor mode */
+        word =        HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
+        result = hermes_docmd_wait(hw, word, 0, &resp);
+                if ( result ) break;
+
+                /* Set the driver state */
+                /* Do we want the prism2 header? */
+                if (parms[0] == 1)
+                dev->type = ARPHRD_IEEE80211_PRISM;
+                else
+                dev->type = ARPHRD_IEEE80211;
+                break;
+        default:
+                result = -EFAULT;
+                break;
+        }
+        orinoco_unlock(priv);
+        return result;
+
+}
+
static int
orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
@@ -3380,7 +3581,10 @@
                                0, "set_ibssport" },
                                { SIOCIWFIRSTPRIV + 0x7, 0,
                                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-                                "get_ibssport" }
+                                "get_ibssport" },
+                                { SIOCIWFIRSTPRIV + 0x8,
+                                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+                                0, "monitor" }
                        };

                        err = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab));
@@ -3488,6 +3692,15 @@
                err = orinoco_ioctl_getibssport(dev, wrq);
                break;

+ case SIOCIWFIRSTPRIV + 0x8: /* set sniff (monitor) mode */
+                DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x8 (monitor)\n",
+                dev->name);
+                if (! capable(CAP_NET_ADMIN)) {
+                        err = -EPERM;
+                        break;
+                }
+ err = orinoco_wlansniff(dev, wrq);
+                break;

        default:
                err = -EOPNOTSUPP;
@@ -3884,7 +4097,9 @@
                printk(KERN_ERR "Unable to initialize /proc/hermes/%s/recs\n", dev->name);
                goto fail;
        }
-
+#ifdef SET_MAC_ADDRESS
+ dev->set_mac_address = orinoco_set_mac_address;
+#endif /* SET_MAC_ADDRESS */
#ifdef HERMES_DEBUG_BUFFER
        e = create_proc_read_entry("buf", S_IFREG | S_IRUGO,
                                        priv->dir_dev, orinoco_proc_get_hermes_buf, priv);
@@ -3955,6 +4170,7 @@
        /* Setup / override net_device fields */
        dev->init = orinoco_init;
        dev->hard_start_xmit = orinoco_xmit;
+
#ifdef HAVE_TX_TIMEOUT
        dev->tx_timeout = orinoco_tx_timeout;
        dev->watchdog_timeo = HZ; /* 1 second timeout */
@@ -3978,6 +4194,202 @@

}

+/*----------------------------------------------------------------
+* orinoco_int_rxmonitor
+*
+* Helper function for int_rx. Handles monitor frames.
+* Note that this function allocates space for the FCS and sets it
+* to 0xffffffff. The hfa384x doesn't give us the FCS value but the
+* higher layers expect it. 0xffffffff is used as a flag to indicate
+* the FCS is bogus.
+*
+* Arguments:
+*        dev                wlan device structure
+*        rxfid                received FID
+*        rxdesc                rx descriptor read from card in int_rx
+*
+* Returns:
+*        nothing
+*
+* Side effects:
+*        Allocates an skb and passes it up via the PF_PACKET interface.
+* Call context:
+*        interrupt
+----------------------------------------------------------------*/
+void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int len,
+ struct hermes_rx_descriptor *rxdesc, struct ieee802_11_hdr *hdr)
+{
+        hermes_t                        *hw = &(dev->hw);
+        uint32_t                                hdrlen = 0;
+        uint32_t                                datalen = 0;
+        uint32_t                                skblen = 0;
+        p80211msg_lnxind_wlansniffrm_t        *msg;
+        struct net_device_stats *stats = &dev->stats;
+
+
+        uint8_t                                *datap;
+        uint16_t                                fc;
+        struct sk_buff                        *skb;
+
+        /* Don't forget the status, time, and data_len fields are in host order */
+        /* Figure out how big the frame is */
+        fc = le16_to_cpu(hdr->frame_ctl);
+        switch ( WLAN_GET_FC_FTYPE(fc) )
+        {
+        case WLAN_FTYPE_DATA:
+                if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
+                        hdrlen = WLAN_HDR_A4_LEN;
+                } else {
+                        hdrlen = WLAN_HDR_A3_LEN;
+                }
+                datalen = len;
+                break;
+        case WLAN_FTYPE_MGMT:
+                hdrlen = WLAN_HDR_A3_LEN;
+                datalen = len;
+                break;
+        case WLAN_FTYPE_CTL:
+                switch ( WLAN_GET_FC_FSTYPE(fc) )
+                {
+                case WLAN_FSTYPE_PSPOLL:
+                case WLAN_FSTYPE_RTS:
+                case WLAN_FSTYPE_CFEND:
+                case WLAN_FSTYPE_CFENDCFACK:
+                        hdrlen = 16;
+                        break;
+                case WLAN_FSTYPE_CTS:
+                case WLAN_FSTYPE_ACK:
+                        hdrlen = 10;
+                        break;
+                }
+                datalen = 0;
+                break;
+        default:
+                printk("unknown frm: fc=0x%04x\n", fc);
+                return;
+        }
+
+        /* Allocate an ind message+framesize skb */
+        skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
+        hdrlen + datalen + WLAN_CRC_LEN;
+       
+        /* sanity check the length */
+        if ( skblen >
+                (sizeof(p80211msg_lnxind_wlansniffrm_t) +
+                WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
+                printk("overlen frm: len=%d\n",
+                        skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+        }
+                       
+        if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
+                printk("alloc_skb failed trying to allocate %d bytes\n", skblen);
+                return;
+        }
+
+        /* only prepend the prism header if in the right mode */
+        if (dev->ndev->type != ARPHRD_IEEE80211_PRISM) {
+        skb_put(skb, skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+        datap = skb->data;
+        } else {
+        skb_put(skb, skblen);
+        datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
+        msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
+       
+        /* Initialize the message members */
+        msg->msgcode = DIDmsg_lnxind_wlansniffrm;
+        msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+        strcpy(msg->devname, dev->ndev->name);
+       
+        msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+        msg->hosttime.status = 0;
+        msg->hosttime.len = 4;
+        msg->hosttime.data = jiffies;
+       
+        msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+        msg->mactime.status = 0;
+        msg->mactime.len = 4;
+        msg->mactime.data = rxdesc->time;
+       
+        msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+        msg->channel.status = P80211ENUM_msgitem_status_no_value;
+        msg->channel.len = 4;
+        msg->channel.data = 0;
+
+        msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+        msg->rssi.status = P80211ENUM_msgitem_status_no_value;
+        msg->rssi.len = 4;
+        msg->rssi.data = 0;
+       
+        msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+        msg->sq.status = P80211ENUM_msgitem_status_no_value;
+        msg->sq.len = 4;
+        msg->sq.data = 0;
+       
+        msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+        msg->signal.status = 0;
+        msg->signal.len = 4;
+        msg->signal.data = rxdesc->signal;
+       
+        msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+        msg->noise.status = 0;
+        msg->noise.len = 4;
+        msg->noise.data = rxdesc->silence;
+
+        msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+        msg->rate.status = 0;
+        msg->rate.len = 4;
+        msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+        msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+        msg->istx.status = 0;
+        msg->istx.len = 4;
+        msg->istx.data = P80211ENUM_truth_false;
+       
+        msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+        msg->frmlen.status = 0;
+        msg->frmlen.len = 4;
+        msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
+        }       
+
+        /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
+        memcpy( datap, &(hdr->frame_ctl), hdrlen);
+
+        /* If any, copy the data from the card to the skb */
+        if ( datalen > 0 )
+        {
+                hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen, (datalen+1)&~1,
+                                rxfid, HERMES_RX_DATA_OFF);
+
+                /* check for unencrypted stuff if WEP bit set. */
+                if (*(datap+1) & 0x40) // wep set
+                if ((*(datap+hdrlen) == 0xaa) && (*(datap+hdrlen+1) == 0xaa))
+                *(datap+1) &= 0xbf; // clear wep; it's the 802.2 header!
+        }
+
+        /* Set the CRC */
+
+        /* Pass it up */
+        memset( ((uint8_t *)(skb->tail)) - WLAN_CRC_LEN, 0xff, WLAN_CRC_LEN);
+
+ /* pass it up via the PF_PACKET interface */
+ {
+        skb->dev = dev->ndev;
+        skb->dev->last_rx = jiffies;
+
+        skb->mac.raw = skb->data ;
+        skb->ip_summed = CHECKSUM_NONE;
+        skb->pkt_type = PACKET_OTHERHOST;
+        skb->protocol = htons(ETH_P_80211_RAW); /* XXX ETH_P_802_2? */
+
+        stats->rx_packets++;
+        stats->rx_bytes += skb->len;
+
+        netif_rx(skb);
+ }
+
+        return;
+}
+
/********************************************************************/
/* module bookkeeping */
/********************************************************************/
diff --speed-large-files --minimal -Nru tmp/pcmcia-cs-3.2.3/wireless/orinoco.h work/main.d/pcmcia-cs-3.2.3/wireless/orinoco.h
--- tmp/pcmcia-cs-3.2.3/wireless/orinoco.h        2002-05-01 22:33:21.000000000 -0500
+++ work/main.d/pcmcia-cs-3.2.3/wireless/orinoco.h        2003-05-13 07:29:06.000000000 -0500
@@ -7,9 +7,25 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H

+#include "hermes.h"
+
/* To enable debug messages */
//#define ORINOCO_DEBUG                3

+#ifndef ETH_P_ECONET
+#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
+#endif
+
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+
+#ifndef ARPHRD_IEEE80211
+#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
+#endif
+
+#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
+#define ARPHRD_IEEE80211_PRISM 802
+#endif
+
#if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
#error "orinoco driver requires Wireless extensions v10 or later."
#endif /* (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10) */
@@ -27,6 +43,159 @@

/*====================================================================*/

+#define WLAN_DEVNAMELEN_MAX 16
+
+/* message data item for INT, BOUNDEDINT, ENUMINT */
+typedef struct p80211item_uint32
+{
+        uint32_t                did                __attribute__ ((packed));
+        uint16_t                status        __attribute__ ((packed));
+        uint16_t                len                __attribute__ ((packed));
+        uint32_t                data        __attribute__ ((packed));
+} __attribute__ ((packed)) p80211item_uint32_t;
+
+typedef struct p80211msg
+{
+        uint32_t        msgcode                __attribute__ ((packed));
+        uint32_t        msglen                __attribute__ ((packed));
+        uint8_t        devname[WLAN_DEVNAMELEN_MAX]        __attribute__ ((packed));
+} __attribute__ ((packed)) p80211msg_t;
+
+#define DIDmsg_lnxind_wlansniffrm 0x0041
+#define DIDmsg_lnxind_wlansniffrm_hosttime 0x1041
+#define DIDmsg_lnxind_wlansniffrm_mactime 0x2041
+#define DIDmsg_lnxind_wlansniffrm_channel 0x3041
+#define DIDmsg_lnxind_wlansniffrm_rssi 0x4041
+#define DIDmsg_lnxind_wlansniffrm_sq 0x5041
+#define DIDmsg_lnxind_wlansniffrm_signal 0x6041
+#define DIDmsg_lnxind_wlansniffrm_noise 0x7041
+#define DIDmsg_lnxind_wlansniffrm_rate 0x8041
+#define DIDmsg_lnxind_wlansniffrm_istx 0x9041
+#define DIDmsg_lnxind_wlansniffrm_frmlen 0xA041
+
+typedef struct p80211msg_lnxind_wlansniffrm
+{
+        uint32_t                msgcode;
+        uint32_t                msglen;
+        uint8_t                devname[WLAN_DEVNAMELEN_MAX];
+        p80211item_uint32_t        hosttime;
+        p80211item_uint32_t        mactime;
+        p80211item_uint32_t        channel;
+        p80211item_uint32_t        rssi;
+        p80211item_uint32_t        sq;
+        p80211item_uint32_t        signal;
+        p80211item_uint32_t        noise;
+        p80211item_uint32_t        rate;
+        p80211item_uint32_t        istx;
+        p80211item_uint32_t        frmlen;
+} __attribute__ ((packed)) p80211msg_lnxind_wlansniffrm_t;
+
+#define P80211ENUM_truth_false                        0
+#define P80211ENUM_truth_true                        1
+#define P80211ENUM_resultcode_success                1
+#define P80211ENUM_resultcode_invalid_parameters        2
+#define P80211ENUM_resultcode_not_supported        3
+#define P80211ENUM_resultcode_timeout                4
+#define P80211ENUM_resultcode_too_many_req        5
+#define P80211ENUM_resultcode_refused                6
+#define P80211ENUM_resultcode_bss_already        7
+#define P80211ENUM_resultcode_invalid_access        8
+#define P80211ENUM_resultcode_invalid_mibattribute        9
+#define P80211ENUM_resultcode_cant_set_readonly_mib        10
+#define P80211ENUM_resultcode_implementation_failure        11
+#define P80211ENUM_resultcode_cant_get_writeonly_mib        12
+#define P80211ENUM_msgitem_status_data_ok                0
+#define P80211ENUM_msgitem_status_no_value                1
+#define P80211ENUM_msgitem_status_invalid_itemname        2
+#define P80211ENUM_msgitem_status_invalid_itemdata        3
+#define P80211ENUM_msgitem_status_missing_itemdata        4
+#define P80211ENUM_msgitem_status_incomplete_itemdata        5
+#define P80211ENUM_msgitem_status_invalid_msg_did        6
+#define P80211ENUM_msgitem_status_invalid_mib_did        7
+#define P80211ENUM_msgitem_status_missing_conv_func        8
+#define P80211ENUM_msgitem_status_string_too_long        9
+#define P80211ENUM_msgitem_status_data_out_of_range        10
+#define P80211ENUM_msgitem_status_string_too_short        11
+#define P80211ENUM_msgitem_status_missing_valid_func        12
+#define P80211ENUM_msgitem_status_unknown                13
+#define P80211ENUM_msgitem_status_invalid_did                14
+#define P80211ENUM_msgitem_status_missing_print_func        15
+
+#define WLAN_GET_FC_FTYPE(n)        (((n) & 0x0C) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)        (((n) & 0xF0) >> 4)
+#define WLAN_GET_FC_TODS(n)         (((n) & 0x0100) >> 8)
+#define WLAN_GET_FC_FROMDS(n)        (((n) & 0x0200) >> 9)
+
+/*--- Sizes -----------------------------------------------*/
+#define WLAN_ADDR_LEN                        6
+#define WLAN_CRC_LEN                        4
+#define WLAN_BSSID_LEN                        6
+#define WLAN_BSS_TS_LEN                        8
+#define WLAN_HDR_A3_LEN                        24
+#define WLAN_HDR_A4_LEN                        30
+#define WLAN_SSID_MAXLEN                32
+#define WLAN_DATA_MAXLEN                2312
+
+/*--- Frame Control Field -------------------------------------*/
+/* Frame Types */
+#define WLAN_FTYPE_MGMT                        0x00
+#define WLAN_FTYPE_CTL                        0x01
+#define WLAN_FTYPE_DATA                        0x02
+
+/* Frame subtypes */
+/* Management */
+#define WLAN_FSTYPE_ASSOCREQ                0x00
+#define WLAN_FSTYPE_ASSOCRESP                0x01
+#define WLAN_FSTYPE_REASSOCREQ                0x02
+#define WLAN_FSTYPE_REASSOCRESP                0x03
+#define WLAN_FSTYPE_PROBEREQ                0x04
+#define WLAN_FSTYPE_PROBERESP                0x05
+#define WLAN_FSTYPE_BEACON                0x08
+#define WLAN_FSTYPE_ATIM                0x09
+#define WLAN_FSTYPE_DISASSOC                0x0a
+#define WLAN_FSTYPE_AUTHEN                0x0b
+#define WLAN_FSTYPE_DEAUTHEN                0x0c
+
+/* Control */
+#define WLAN_FSTYPE_PSPOLL                0x0a
+#define WLAN_FSTYPE_RTS                        0x0b
+#define WLAN_FSTYPE_CTS                        0x0c
+#define WLAN_FSTYPE_ACK                        0x0d
+#define WLAN_FSTYPE_CFEND                0x0e
+#define WLAN_FSTYPE_CFENDCFACK                0x0f
+
+/* Data */
+#define WLAN_FSTYPE_DATAONLY                0x00
+#define WLAN_FSTYPE_DATA_CFACK                0x01
+#define WLAN_FSTYPE_DATA_CFPOLL                0x02
+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL        0x03
+#define WLAN_FSTYPE_NULL                0x04
+#define WLAN_FSTYPE_CFACK                0x05
+#define WLAN_FSTYPE_CFPOLL                0x06
+#define WLAN_FSTYPE_CFACK_CFPOLL        0x07
+
+/*----------------------------------------------------------------*/
+/* Magic number, a quick test to see we're getting the desired struct */
+
+#define P80211_IOCTL_MAGIC        (0x4a2d464dUL)
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* A ptr to the following structure type is passed as the third */
+/* argument to the ioctl system call when issuing a request to */
+/* the p80211 module. */
+
+typedef struct p80211ioctl_req
+{
+        char         name[WLAN_DEVNAMELEN_MAX] __attribute__ ((packed));
+        void        *data                 __attribute__ ((packed));
+        uint32_t        magic         __attribute__ ((packed));
+        uint16_t        len         __attribute__ ((packed));
+        uint32_t        result         __attribute__ ((packed));
+} __attribute__ ((packed)) p80211ioctl_req_t;
+
struct orinoco_private {
        void *card;        /* Pointer to card dependant structure */
        /* card dependant extra reset code (i.e. bus/interface specific */
@@ -84,6 +253,8 @@
        int port_type, allow_ibss;
        int promiscuous, mc_count;

+        uint16_t                presniff_port_type;
+        uint16_t                presniff_wepflags;

        /* /proc based debugging stuff */
        struct proc_dir_entry *dir_dev;
@@ -115,4 +286,12 @@
extern void orinoco_proc_dev_cleanup(struct orinoco_private *priv);
extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);

+/*================================================================*/
+/* Function Declarations */
+
+struct ieee802_11_hdr;
+
+void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int len,
+ struct hermes_rx_descriptor *rxdesc, struct ieee802_11_hdr *hdr);
+
#endif /* _ORINOCO_H */