diff -u -urN orinoco-0.13b/Makefile orinoco-0.13b+nortel+airsnort/Makefile
--- orinoco-0.13b/Makefile	Mon Feb 10 04:38:09 2003
+++ orinoco-0.13b+nortel+airsnort/Makefile	Fri Apr  4 13:06:54 2003
@@ -5,14 +5,14 @@
 KERNEL_SRC = /lib/modules/$(KERNEL_VERSION)/build
 KERNEL_HEADERS = $(KERNEL_SRC)/include
 
-MODULES = hermes.o orinoco.o orinoco_cs.o orinoco_plx.o orinoco_pci.o
+MODULES = hermes.o orinoco.o orinoco_cs.o orinoco_plx.o orinoco_pci.o nortel_pci.o
 ifeq ($(shell uname -m),ppc)
 MODULES += airport.o
 endif
 
 SRCS = hermes.c \
 	orinoco.c \
-	airport.c orinoco_cs.c orinoco_plx.c orinoco_pci.c \
+	airport.c orinoco_cs.c orinoco_plx.c orinoco_pci.c nortel_pci.c \
 	userhermes.c
 HDRS = hermes.h hermes_rid.h ieee802_11.h orinoco.h
 CONF = hermes.conf
diff -u -urN orinoco-0.13b/hermes.c orinoco-0.13b+nortel+airsnort/hermes.c
--- orinoco-0.13b/hermes.c	Mon Feb 10 04:38:09 2003
+++ orinoco-0.13b+nortel+airsnort/hermes.c	Fri Apr  4 13:06:54 2003
@@ -129,7 +129,9 @@
 			int io_space, int reg_spacing)
 {
 	hw->iobase = address;
-	hw->io_space = io_space;
+	hw->iobase1 = 0;
+	hw->iobase2 = 0;
+       	hw->io_space = io_space;
 	hw->reg_spacing = reg_spacing;
 	hw->inten = 0x0;
 
@@ -183,6 +185,10 @@
 	err = hermes_issue_cmd(hw, HERMES_CMD_INIT, 0);
 	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;
diff -u -urN orinoco-0.13b/hermes.h orinoco-0.13b+nortel+airsnort/hermes.h
--- orinoco-0.13b/hermes.h	Mon Feb 10 04:38:09 2003
+++ orinoco-0.13b+nortel+airsnort/hermes.h	Fri Apr  4 13:06:54 2003
@@ -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
  */
 
@@ -278,7 +314,7 @@
 
 /* Basic control structure */
 typedef struct hermes {
-	ulong iobase;
+	ulong iobase, iobase1, iobase2;
 	int io_space; /* 1 if we IO-mapped IO, 0 for memory-mapped IO? */
 #define HERMES_IO	1
 #define HERMES_MEM	0
@@ -287,6 +323,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];
@@ -340,12 +377,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 -u -urN orinoco-0.13b/nortel_pci.c orinoco-0.13b+nortel+airsnort/nortel_pci.c
--- orinoco-0.13b/nortel_pci.c	Thu Jan  1 01:00:00 1970
+++ orinoco-0.13b+nortel+airsnort/nortel_pci.c	Fri Apr  4 13:23:02 2003
@@ -0,0 +1,357 @@
+/* nortel_pci.c (based on orinoco_plx.c and orinoco_pci.c)
+ * 
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter. 
+ *
+ * Copyright (C) 2001 Daniel Barlow <dan@telent.net>
+ *           (C) 2002 Tobias Hoffmann
+ *           (C) 2003 Christoph Jungegger <disdos@traum404.de>
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/wireless.h>
+#include <linux/fcntl.h>
+
+#include <pcmcia/cisreg.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+static char dev_info[] = "nortel_pci";
+
+#define COR_OFFSET    (0xe0)	/* COR attribute offset of Prism2 PC card */
+#define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+
+
+/*
+ * Do a soft reset of the PCI card using the Configuration Option Register
+ * We need this to get going...
+ * This is the part of the code that is strongly inspired from wlan-ng
+ *
+ * Note : This code is done with irq enabled. This mean that many
+ * interrupts will occur while we are there. This is why we use the
+ * jiffies to regulate time instead of a straight mdelay(). Usually we
+ * need only around 245 iteration of the loop to do 250 ms delay.
+ *
+ * Note bis : Don't try to access HERMES_CMD during the reset phase.
+ * It just won't work !
+ */
+static int
+nortel_pci_cor_reset(struct orinoco_private *priv)
+{
+	unsigned long brg1_ioaddr=priv->hw.iobase1;
+	unsigned long brg2_ioaddr=priv->hw.iobase2;
+
+        /* Assert the reset until the card notice */
+	outw_p(8, brg1_ioaddr+2);
+	inw(brg2_ioaddr+COR_OFFSET);
+	outw_p(0x80, brg2_ioaddr+COR_OFFSET);
+        mdelay(1);
+        printk(KERN_NOTICE "Reset done;\n");
+
+        /* Give time for the card to recover from this hard effort */
+	outw_p(0, brg2_ioaddr+COR_OFFSET);
+	outw_p(0, brg2_ioaddr+COR_OFFSET);
+	mdelay(1);
+        printk(KERN_NOTICE "Clear Reset\n");
+
+	/* set COR as usual*/
+	outw_p(COR_VALUE, brg2_ioaddr+COR_OFFSET);
+	outw_p(COR_VALUE, brg2_ioaddr+COR_OFFSET);
+	mdelay(1);
+
+	outw_p(0x228, brg1_ioaddr+2);
+	
+        return 0;
+}
+
+static int nortel_pci_init_one(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	int err = 0;
+	u16 *attr_mem = NULL;
+	u32 reg;
+	struct orinoco_private *priv = NULL;
+	unsigned long brg1_ioaddr = 0, brg2_ioaddr = 0, pccard_ioaddr = 0;
+	unsigned long brg1_iolen = 0, brg2_iolen = 0, pccard_iolen = 0;
+	struct net_device *dev = NULL;
+	int netdev_registered = 0;
+	int i;
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return -EIO;
+
+	brg1_ioaddr = pci_resource_start(pdev, 0);
+	brg1_iolen = pci_resource_len(pdev, 0);
+	if (! request_region(brg1_ioaddr, brg1_iolen, dev_info)) {
+		printk(KERN_ERR "nortel_pci: Bridge I/O resource 1 0x%lx @ 0x%lx busy\n",
+		       brg1_iolen, brg1_ioaddr);
+		brg1_ioaddr = 0;
+		err = -EBUSY;
+		goto fail;
+	}
+
+	brg2_ioaddr = pci_resource_start(pdev, 1);
+	brg2_iolen = pci_resource_len(pdev, 1);
+	if (! request_region(brg2_ioaddr, brg2_iolen, dev_info)) {
+		printk(KERN_ERR "nortel_pci: Bridge I/O resource 2 0x%lx @ 0x%lx busy\n",
+		       brg2_iolen, brg2_ioaddr);
+		brg2_ioaddr = 0;
+		err = -EBUSY;
+		goto fail;
+	}
+
+	pccard_ioaddr = pci_resource_start(pdev, 2);
+	pccard_iolen = pci_resource_len(pdev, 2);
+	if (! request_region(pccard_ioaddr, pccard_iolen, dev_info)) {
+		printk(KERN_ERR "nortel_pci: I/O resource 0x%lx @ 0x%lx busy\n",
+		       pccard_iolen, pccard_ioaddr);
+		pccard_ioaddr = 0;
+		err = -EBUSY;
+		goto fail;
+	}
+
+	/* setup bridge */
+	if (inw(brg1_ioaddr)&1) {
+		printk(KERN_ERR "nortel_pci: brg1 answer1 wrong\n");
+		goto fail;
+	}
+	outw_p(0x118,brg1_ioaddr+2);
+	outw_p(0x108,brg1_ioaddr+2);
+	mdelay(30);
+	outw_p(0x8,brg1_ioaddr+2);
+	for (i=0; i<30; i++) {
+		mdelay(30);
+		if (inw(brg1_ioaddr)&0x10) {
+			break;
+		}
+        }
+	if (i==30) {
+		printk(KERN_ERR "nortel_pci: brg1 timed out\n");
+		goto fail;
+	}
+	if (inw(brg2_ioaddr+0xe0)&1) {
+		printk(KERN_ERR "nortel_pci: brg2 answer1 wrong\n");
+		goto fail;
+	}
+	if (inw(brg2_ioaddr+0xe2)&1) {
+		printk(KERN_ERR "nortel_pci: brg2 answer2 wrong\n");
+		goto fail;
+	}
+	if (inw(brg2_ioaddr+0xe4)&1) {
+		printk(KERN_ERR "nortel_pci: brg2 answer3 wrong\n");
+		goto fail;
+	}
+
+	/* set the PCMCIA COR-Register */
+	outw_p(COR_VALUE, brg2_ioaddr+COR_OFFSET);
+	mdelay(1);
+	reg = inw(brg2_ioaddr+COR_OFFSET);
+	if (reg != COR_VALUE) {
+		printk(KERN_ERR "nortel_pci: Error setting COR value (reg=%x)\n", reg);
+		goto fail;
+	}
+
+	/* set leds */
+	outw_p(1,brg1_ioaddr+10);
+
+
+	dev = alloc_orinocodev(0, NULL);
+	if (! dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	priv = dev->priv;
+	dev->base_addr = pccard_ioaddr;
+	priv->hard_reset = nortel_pci_cor_reset;
+	SET_MODULE_OWNER(dev);
+
+	printk(KERN_DEBUG
+	       "Detected Nortel PCI device at %s irq:%d, io addr:0x%lx\n",
+	       pdev->slot_name, pdev->irq, pccard_ioaddr);
+
+	hermes_struct_init(&(priv->hw), dev->base_addr,
+			HERMES_IO, HERMES_16BIT_REGSPACING);
+	pci_set_drvdata(pdev, dev);
+	priv->hw.iobase1=brg1_ioaddr;
+	priv->hw.iobase2=brg2_ioaddr;
+
+	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, priv);
+	if (err) {
+		printk(KERN_ERR "nortel_pci: Error allocating IRQ %d.\n", pdev->irq);
+		err = -EBUSY;
+		goto fail;
+	}
+	dev->irq = pdev->irq;
+	nortel_pci_cor_reset(priv);
+
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR "%s: Failed to register net device\n", dev->name);
+		goto fail;
+	}
+	netdev_registered = 1;
+
+//	err = orinoco_proc_dev_init(dev);
+//	if (err) {
+//		printk(KERN_ERR "%s: Failed to create /proc node\n", dev->name);
+//		err = -EIO;
+//		goto fail;
+//	}
+	
+
+	return 0;		/* succeeded */
+
+fail:	
+	if (!err) {
+		err=-1;
+	}
+	printk(KERN_DEBUG "nortel_pci: init_one(), FAIL!\n");
+
+	if (priv) {
+//		orinoco_proc_dev_cleanup(dev);
+
+		if (netdev_registered)
+			unregister_netdev(dev);
+		
+		if (dev->irq)
+			free_irq(dev->irq, priv);
+		
+		pci_set_drvdata(pdev, NULL);
+		kfree(dev);
+	}
+
+	if (brg1_ioaddr)
+		release_region(brg1_ioaddr, brg1_iolen);
+	if (brg2_ioaddr)
+		release_region(brg2_ioaddr, brg2_iolen);
+	if (pccard_ioaddr)
+		release_region(pccard_ioaddr, pccard_iolen);
+
+	if (attr_mem)
+		iounmap(attr_mem);
+
+	pci_disable_device(pdev);
+
+	return err;
+}
+
+static void __devexit nortel_pci_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = dev->priv;
+
+	/* clear leds */
+	outw_p(0,priv->hw.iobase1+10);
+
+	if (! dev)
+		BUG();
+
+//	orinoco_proc_dev_cleanup(dev);
+
+	unregister_netdev(dev);
+		
+	if (dev->irq)
+		free_irq(dev->irq, priv);
+	
+	pci_set_drvdata(pdev, NULL);
+	kfree(dev);
+
+	release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+	release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
+	release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
+
+	pci_disable_device(pdev);
+
+}
+
+
+static struct pci_device_id nortel_pci_id_table[] __devinitdata = {
+	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},	/* Nortel emobility PCI */
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);
+
+static struct pci_driver nortel_pci_driver = {
+	.name     = "nortel_pci",
+	.id_table = nortel_pci_id_table,
+	.probe    = nortel_pci_init_one,
+	.remove   = __devexit_p(nortel_pci_remove_one),
+	.suspend  = 0,
+	.resume   = 0
+};
+
+static char version[] __initdata = "nortel_pci.c 0.13a (Daniel Barlow <dan@telent.net>, Tobias Hoffmann, Christoph Jungegger)";
+MODULE_AUTHOR("Daniel Barlow <dan@telent.net>, Tobias Hoffmann, Christoph Jungegger");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the Nortel PCI bridge");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("Dual MPL/GPL");
+#endif
+
+static int __init nortel_pci_init(void)
+{
+	printk(KERN_DEBUG "%s\n", version);
+	return pci_module_init(&nortel_pci_driver);
+}
+
+extern void __exit nortel_pci_exit(void)
+{
+	pci_unregister_driver(&nortel_pci_driver);
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ);
+}
+
+module_init(nortel_pci_init);
+module_exit(nortel_pci_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -u -urN orinoco-0.13b/orinoco.c orinoco-0.13b+nortel+airsnort/orinoco.c
--- orinoco-0.13b/orinoco.c	Mon Feb 10 04:38:09 2003
+++ orinoco-0.13b+nortel+airsnort/orinoco.c	Fri Apr  4 13:00:27 2003
@@ -1586,6 +1586,7 @@
 	struct header_struct hdr;
 	struct ethhdr *eh;
 	int err;
+        struct ieee802_11_hdr hdr80211;
 
 	rxfid = hermes_read_regn(hw, RXFID);
 
@@ -1602,6 +1603,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);
@@ -1612,7 +1614,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 */
 
@@ -1642,6 +1644,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
@@ -1718,6 +1724,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:	
 	stats->rx_dropped++;
 
@@ -2348,6 +2374,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)
 {
@@ -2935,7 +2979,7 @@
 	if (!priv->has_sensitivity)
 		return -EOPNOTSUPP;
 
-	if ((val < 1) || (val > 3))
+	if ((val < 0) || (val > 3))
 		return -EINVAL;
 	
 	err = orinoco_lock(priv, &flags);
@@ -3500,6 +3544,175 @@
 	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;
+	unsigned long flags;
+
+	orinoco_lock(priv, &flags);
+
+	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:
+             /* Re-initialize the card before changing channel as advised at
+              * http://lists.samba.org/pipermail/wireless/2002-June/004491.html
+              * by Ian Goldberg.  Implementation by Pat Swieskowski.
+              */
+//		__orinoco_down(dev);
+                hermes_set_irqmask(hw, 0);
+		hermes_init(hw);
+//		__orinoco_up(dev);
+                hermes_set_irqmask(hw, ORINOCO_INTEN);
+/*
+		__orinoco_stop_irqs(priv);
+		hermes_reset(hw);
+		__orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |
+				   HERMES_EV_TX | HERMES_EV_TXEXC |
+				   HERMES_EV_WTERR | HERMES_EV_INFO |
+				   HERMES_EV_INFDROP);
+*/
+		/* 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, &flags);
+	return result;
+
+}
+
 static int
 orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
@@ -3732,6 +3945,9 @@
 				{ SIOCIWFIRSTPRIV + 0x7, 0,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  "get_ibssport" },
+				{ SIOCIWFIRSTPRIV + 0x8,
+				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+				  0, "monitor" },
 				{ SIOCIWLASTPRIV, 0, 0, "dump_recs" },
 			};
 
@@ -3826,6 +4042,16 @@
 		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;
+
 	case SIOCIWLASTPRIV:
 		err = orinoco_debug_dump_recs(priv);
 		if (err)
@@ -4047,6 +4273,9 @@
 	dev->tx_timeout = orinoco_tx_timeout;
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
 	dev->get_stats = orinoco_get_stats;
+#ifdef SET_MAC_ADDRESS
+        dev->set_mac_address = orinoco_set_mac_address;
+#endif	/* SET_MAC_ADDRESS */
 	dev->get_wireless_stats = orinoco_get_wireless_stats;
 	dev->do_ioctl = orinoco_ioctl;
 	dev->change_mtu = orinoco_change_mtu;
@@ -4069,6 +4298,197 @@
 
 	return dev;
 
+}
+
+/*----------------------------------------------------------------
+* 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;
+	
+	/* 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;
+	}	  
+
+	/* 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!
+	}
+
+       /* 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;
 }
 
 /********************************************************************/
diff -u -urN orinoco-0.13b/orinoco.h orinoco-0.13b+nortel+airsnort/orinoco.h
--- orinoco-0.13b/orinoco.h	Mon Feb 10 04:38:09 2003
+++ orinoco-0.13b+nortel+airsnort/orinoco.h	Fri Apr  4 13:00:27 2003
@@ -17,6 +17,20 @@
 /* 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) */
@@ -34,6 +48,158 @@
 				HERMES_EV_TXEXC | HERMES_EV_WTERR | HERMES_EV_INFO | \
 				HERMES_EV_INFDROP )
 
+#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 */
@@ -95,6 +261,9 @@
 	/* Configuration dependent variables */
 	int port_type, createibss;
 	int promiscuous, mc_count;
+
+	uint16_t		presniff_port_type;
+	uint16_t		presniff_wepflags;
 };
 
 #ifdef ORINOCO_DEBUG
@@ -141,5 +310,14 @@
 {
 	spin_unlock_irqrestore(&priv->lock, *flags);
 }
+
+/*================================================================*/
+/* 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 */
diff -u -urN orinoco-0.13b/orinoco_cs.c orinoco-0.13b+nortel+airsnort/orinoco_cs.c
--- orinoco-0.13b/orinoco_cs.c	Mon Feb 10 04:38:09 2003
+++ orinoco-0.13b+nortel+airsnort/orinoco_cs.c	Fri Apr  4 12:56:23 2003
@@ -64,9 +64,13 @@
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
 
+/* Control device name allocation. 0 -> dldwdX ; 1 -> ethX */
+static int eth = 1;
+
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
 MODULE_PARM(ignore_cis_vcc, "i");
+MODULE_PARM(eth, "i");
 
 /********************************************************************/
 /* Magic constants						    */
@@ -88,6 +92,7 @@
 struct orinoco_pccard {
 	dev_link_t link;
 	dev_node_t node;
+	int instance;
 
 	/* Used to handle hard reset */
 	/* yuck, we need this hack to work around the insanity of the
@@ -101,6 +106,7 @@
  * dev_link_t structure (defined in ds.h).
  */
 static dev_link_t *dev_list; /* = NULL */
+static int num_instances = 0;
 
 /********************************************************************/
 /* Function prototypes						    */
@@ -198,6 +204,7 @@
 	card = priv->card;
 
 	/* Link both structures together */
+	card->instance = num_instances++; /* FIXME: Racy? */
 	link = &card->link;
 	link->priv = dev;
 
@@ -297,6 +304,9 @@
 		unregister_netdev(dev);
 	}
 	kfree(dev);
+
+	num_instances--; /* FIXME: Racy? */
+
 }				/* orinoco_cs_detach */
 
 /*
@@ -496,8 +506,12 @@
 	SET_MODULE_OWNER(dev);
 	card->node.major = card->node.minor = 0;
 
-	/* register_netdev will give us an ethX name */
-	dev->name[0] = '\0';
+	/* Instance name : by default, use hermesX, on demand use the
+	* regular ethX (less risky) - Jean II */
+	if(!eth)
+		sprintf(dev->name, "wvlan%d", card->instance);
+	else
+		dev->name[0] = '\0';
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR "orinoco_cs: register_netdev() failed\n");
@@ -703,11 +717,11 @@
 	printk(KERN_DEBUG "%s\n", version);
 
 	CardServices(GetCardServicesInfo, &serv);
-	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_NOTICE "orinoco_cs: Card Services release "
-		       "does not match!\n");
-		return -1;
-	}
+//	if (serv.Revision != CS_RELEASE_CODE) {
+//		printk(KERN_NOTICE "orinoco_cs: Card Services release "
+//		       "does not match!\n");
+//		return -1;
+//	}
 
 	register_pccard_driver(&dev_info, &orinoco_cs_attach, &orinoco_cs_detach);
 
