diff -Naur Prism2-2002-02-13/Makefile Prism2x-2002-02-13/Makefile
--- Prism2-2002-02-13/Makefile	Wed Feb 13 18:29:18 2002
+++ Prism2x-2002-02-13/Makefile	Fri Feb 22 16:11:26 2002
@@ -1,48 +1,115 @@
-# Edit this path to match with your system (it should point to the root
+#
+# generic Makefile for HostAP driver.
+# please edit "CONFIGURATION" to fit your needs
+#
+
+#### CONFIGURATION: #####################
+# (KERNEL_SOURCE should point to the root
 # directory of the Linux kernel source)
-KERNEL_PATH=/usr/src/linux
+KERNEL_SOURCE=/usr/src/linux-reyksbox
+PCMCIA_SOURCE=/usr/src/pcmcia-cs-3.1.28
+TYPE=PCMCIA
+#########################################
 
 CC=gcc
-INCLUDES=-I$(KERNEL_PATH)/include
-CFLAGS=-O2 -D__KERNEL__ -DMODULE -fomit-frame-pointer -Wall -c
+CPP=g++
+LD=ld
+RM=rm -f -r
+
+SOURCE=prism2.c
+SRC_DIR=driver/modules
+
+## PCMCIA ##
+CS_OBJ_DIR=obj_cs
+CS_OBJECTS=$(CS_OBJ_DIR)/prism2.o
+CS_MODULE=prism2.o
+CS_INCLUDES=-I$(PCMCIA_SOURCE)/include \
+	 -I$(KERNEL_SOURCE)/include \
+	 -I$(PCMCIA_SOURCE)/include \
+	 -I$(PCMCIA_SOURCE)/include/static
+
+## PCI ##
+PCI_OBJ_DIR=obj_pci
+PCI_OBJECTS=$(PCI_OBJ_DIR)/prism2.o
+PCI_MODULE=prism2hostap_pci.o
+PCI_INCLUDES=-I$(KERNEL_SOURCE)/include
+
+ifeq ($(TYPE),PCMCIA)
+OBJ_DIR=$(CS_OBJ_DIR)
+OBJECTS=$(CS_OBJECTS)
+MODULE=$(CS_MODULE)
+INCLUDES=$(CS_INCLUDES)
+INSTALL=install-pcmcia
+endif
+ifeq ($(TYPE),PCI)
+TYPE=PCI
+OBJ_DIR=$(PCI_OBJ_DIR)
+OBJECTS=$(PCI_OBJECTS)
+MODULE=$(PCI_MODULE)
+INCLUDES=$(PCI_INCLUDES)
+INSTALL=install-pci
+endif
 
-VERFILE := $(KERNEL_PATH)/include/linux/version.h
+VERFILE := $(KERNEL_SOURCE)/include/linux/version.h
 KERNELRELEASE := $(shell if [ -r $(VERFILE) ]; \
 	then grep UTS_RELEASE $(VERFILE) | cut -d" " -f3 | xargs echo; \
 	else uname -r; fi)
-MODPATH := /lib/modules/$(KERNELRELEASE)/pcmcia
+MODPATH := /lib/modules/$(KERNELRELEASE)
 
-MSRC=driver/modules
-
-include $(KERNEL_PATH)/.config
+include $(KERNEL_SOURCE)/.config
 ifdef CONFIG_MODVERSIONS
-CFLAGS += -DMODVERSIONS -include $(KERNEL_PATH)/include/linux/modversions.h
+CFLAGS += -DMODVERSIONS -include $(KERNEL_SOURCE)/include/linux/modversions.h
 endif
 
 ifdef CONFIG_SMP
 CFLAGS += -D__SMP__ -DSMP
 endif
 
-.c.o:
-	$(CC) $(INCLUDES) $(CFLAGS) -o $@ $<
+CFLAGS=-O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -pipe
+DEFINES=-D__KERNEL__ -DMODULE=1 -DPRISM2_NIC_$(TYPE)
+
+all: pre $(MODULE)
 
-all:	$(MSRC)/prism2.o install_info
+pre:
+	mkdir -p $(OBJ_DIR)
 
-$(MSRC)/prism2.o: $(MSRC)/prism2.c $(MSRC)/prism2_wlan.h \
-	$(MSRC)/prism2_ap.c $(MSRC)/prism2_ap.h
+$(MODULE): $(OBJECTS)
+	ld -r $(OBJECTS) -o $(SRC_DIR)/$(MODULE)
+	chmod -x $(SRC_DIR)/$(MODULE)
+
+$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
+	$(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@
 
 install_info:
-	@echo "Run 'make install' as a root to install prism2.o"
+	@echo "Run 'make install-pcmcia' to install Prism2 PCMCIA- module" 
+	@echo "Run 'make install-pci' to install Prism2.5 PCI- module" 
+
+install: $(INSTALL)
 
-install:
-	@echo "Installing to $(MODPATH)"
-	mkdir -p $(MODPATH)
-	cp $(MSRC)/prism2.o $(MODPATH)
+install-pcmcia:
+	@echo "Installing to $(MODPATH)/pcmcia"
+	mkdir -p $(MODPATH)/pcmcia
+	cp $(SRC_DIR)/$(MODULE) $(MODPATH)/pcmcia
 	depmod -a
 	@if [ ! -r /etc/pcmcia/prism2.conf ]; then \
 		echo "Installing prism2.conf to /etc/pcmcia"; \
 		cp driver/etc/prism2.conf /etc/pcmcia/prism2.conf; \
 	fi
 
+install-pci:
+	@echo "Installing to $(MODPATH)/net"
+	mkdir -p $(MODPATH)/net
+	cp $(SRC_DIR)/$(MODULE) $(MODPATH)/net
+	depmod -a
+
 clean:
-	rm -f $(MSRC)/prism2.o
+	$(RM) $(MODULE) *.d .depend.mk $(OBJ_DIR) *~ $(SRC_DIR)/*~ $(SRC_DIR)/*.o
+
+#end
+
+
+
+
+
+
+
diff -Naur Prism2-2002-02-13/driver/modules/prism2.c Prism2x-2002-02-13/driver/modules/prism2.c
--- Prism2-2002-02-13/driver/modules/prism2.c	Wed Feb 13 18:29:18 2002
+++ Prism2x-2002-02-13/driver/modules/prism2.c	Fri Feb 22 15:31:22 2002
@@ -52,15 +52,23 @@
  * from BAP; this is mainly for debugging problems with packet flooding */
 /* #define PRISM2_EXTRA_FROM_BAP_TESTS */
 
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#define add_rx_bytes(stats, n) do { (stats)->rx_bytes += n; } while (0)
+#define add_tx_bytes(stats, n) do { (stats)->tx_bytes += n; } while (0)
 
+#ifdef PRISM2_NIC_PCMCIA
 #ifndef __IN_PCMCIA_PACKAGE__
 
 /* Kernel tree PCMCIA compilation */
 #include <asm/uaccess.h>
 #include <linux/wireless.h>
 
-#define add_rx_bytes(stats, n) do { (stats)->rx_bytes += n; } while (0)
-#define add_tx_bytes(stats, n) do { (stats)->tx_bytes += n; } while (0)
 #define init_dev_name(dev, node) do { } while (0)
 #define copy_dev_name(node, dev) strcpy((node).dev_name, (dev)->name)
 
@@ -72,14 +80,6 @@
 
 #endif /* __IN_PCMCIA_PACKAGE__ */
 
-
-#include <asm/io.h>
-#include <asm/delay.h>
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -87,6 +87,14 @@
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
+#endif /* PRISM2_NIC_PCMCIA */
+
+#ifdef PRISM2_NIC_PCI
+#include <asm/uaccess.h>
+#include <linux/wireless.h>
+#include <linux/pci.h>
+#endif
+
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
@@ -94,6 +102,7 @@
 #include <linux/if_arp.h>
 
 #ifdef PRISM2_MONITOR
+#ifdef PRISM2_NIC_PCMCIA
 #ifdef __IN_PCMCIA_PACKAGE__
 /* net/sock.h (at least in 2.2.17) does not like min()/max() macros from
  * pcmcia-cs's kernel compat header */
@@ -104,6 +113,7 @@
 #undef max
 #endif
 #endif /* __IN_PCMCIA_PACKAGE__ */
+#endif /* PRISM2_NIC_PCMCIA */
 #include <net/sock.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
@@ -132,14 +142,21 @@
 
 static char *version =
 "prism2.c 0.0.0 2002-02-13 (SSH Communications Security Corp, Jouni Malinen)";
+#ifdef PRISM2_NIC_PCMCIA
 static dev_info_t dev_info = "prism2";
 static dev_link_t *dev_list = NULL;
+#endif
+#ifdef PRISM2_NIC_PCI
+static char *dev_info = "prism2.5";
+static pci_link_t *dev_list = NULL;    
+#endif
+
 static struct proc_dir_entry *prism2_proc = NULL;
 
 MODULE_AUTHOR("SSH Communications Security Corp, Jouni Malinen");
-MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
+MODULE_DESCRIPTION("Support for Intersil Prism2.x-based 802.11 wireless LAN "
 		   "cards.");
-MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards");
+MODULE_SUPPORTED_DEVICE("Intersil Prism2.x-based WLAN cards");
 #ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
 #endif
@@ -149,13 +166,13 @@
 MODULE_PARM(mtu, "i");
 MODULE_PARM_DESC(mtu, "Maximum transfer unit");
 
-
+#ifdef PRISM2_NIC_PCMCIA
 static unsigned int irq_mask = 0xdeb8;
 MODULE_PARM(irq_mask, "i");
 
 static int irq_list[4] = { -1 };
 MODULE_PARM(irq_list, "1-4i");
-
+#endif
 
 
 static int channel = 3;
@@ -170,9 +187,11 @@
 MODULE_PARM(iw_mode, "i");
 MODULE_PARM_DESC(iw_mode, "Initial operation mode");
 
+#if PRISM2_NIC_PCMCIA
 static int ignore_cis_vcc = 0;
 MODULE_PARM(ignore_cis_vcc, "i");
 MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
+#endif
 
 /* Ethernet-II snap header */
 static unsigned char snap_header[] =
@@ -184,6 +203,7 @@
 
 static void prism2_hw_reset(struct net_device *dev);
 
+/* **ooh** */
 #include "prism2_ap.c"
 
 /* ca. 1 usec */
@@ -202,11 +222,17 @@
 /* FIX: */
 #define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - sizeof(snap_header))
 
-
+#ifdef PRISM2_NIC_PCMCIA
 static void prism2_detach(dev_link_t *link);
 static void prism2_release(u_long arg);
-static int prism2_event(event_t event, int priority,
-			event_callback_args_t *args);
+static int prism2_event(event_t event, int priority, event_callback_args_t *args);
+#endif
+#ifdef PRISM2_NIC_PCI
+static int prism2_probe_pci(struct pci_dev *pdev, 
+			    const struct pci_device_id *id);
+static void prism2_release_pci(u_long arg);
+#endif
+static void prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 #ifndef final_version
 /* magic value written to SWSUPPORT0 reg. for detecting whether card is still
@@ -229,6 +255,7 @@
 #endif
 
 
+#ifdef PRISM2_NIC_PCMCIA
 #define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
 #define HFA384X_INB(a) inb(dev->base_addr + (a))
 #define HFA384X_OUTW(v,a) outw(__cpu_to_le16((v)), dev->base_addr + (a))
@@ -239,7 +266,58 @@
 
 #define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
 #define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
+#endif /* PRISM2_NIC_PCMCIA */
+
+#ifdef PRISM2_NIC_PCI
+/* ISL3874A 11Mb/s WLAN controller */
+#define PCIVENDOR_INTERSIL	0x1260UL
+#define PCIDEVICE_ISL3874	0x3873UL /* [MSM] yeah I know...the ID says 
+					    3873. Trust me, it's a 3874. */
+/* PCI Class & Sub-Class code, Network-'Other controller' */
+#define PCI_CLASS_NETWORK_OTHERS 0x280
+
+#define PCI_TYPE		(PCI_USES_MEM | PCI_ADDR0 | PCI_NO_ACPI_WAKE)
+#define PCI_SIZE		0x1000		/* Memory size - 4K bytes */
+
+struct pci_device_id pci_id_tbl[] = {
+	{
+		PCIVENDOR_INTERSIL, PCIDEVICE_ISL3874,	
+		PCI_ANY_ID, PCI_ANY_ID,
+		0, 0, 
+		/* Driver data, we just put the name here */
+		(unsigned long)"Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller"
+	},
+	{
+		0, 0, 0, 0, 0, 0, 0
+	}
+};
+
+struct pci_driver prism2_pci_drv_id = {
+	{},
+	"prism2.5", 	        /* Driver name */
+	pci_id_tbl, 		/* id table */
+	prism2_probe_pci,	/* probe function */
+        NULL,			/* remove function */
+        NULL,			/* save_state function */
+        NULL, 			/* suspend function */
+	NULL,			/* resume function */
+        NULL, 			/* enable_wake function */
+};
 
+#define init_dev_name(dev, node) 
+#define copy_dev_name(node, dev) strcpy((char*)&(node), (dev)->name)
+
+#define HFA384X_OUTB(v,a) writeb((v), dev->mem_start + (a));
+#define HFA384X_INB(a) (UINT8)readb(dev->mem_start + (a))
+#define HFA384X_OUTW(v,a) writew(__cpu_to_le16((v)), dev->mem_start + (a))
+#define HFA384X_INW(a) (u16)__le16_to_cpu(readw(dev->mem_start + (a)))
+
+#define HFA384X_OUTW_DATA(v,a) writew(__cpu_to_le16((v)), dev->mem_start + (a))
+#define HFA384X_INW_DATA(a) readw(dev->mem_start + (a))
+
+#define HFA384X_INSW(a) (u16)readw(dev->mem_start + (a))
+#define HFA384X_OUTSW(v,a) writew((v), dev->mem_start + (a))
+#endif /* PRISM2_NIC_PCI */
 
 
 static u16 hfa384x_read_reg(struct net_device *dev, u16 reg)
@@ -406,8 +484,17 @@
 
 int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf, int len)
 {
-	u16 d_off;
+        u16 d_off;
 	u16 *pos;
+#ifdef PRISM2_NIC_PCMCIA
+	int word_count;
+#endif
+
+#ifdef PRISM2_NIC_PCI
+	u8 *d = (u8*)buf;
+	unsigned int i, len2 = len;
+	u16 reg = 0;
+#endif
 
 #ifdef PRISM2_EXTRA_FROM_BAP_TESTS
 
@@ -446,18 +533,32 @@
 
 #else /* PRISM2_EXTRA_FROM_BAP_TESTS */
 
-	int word_count;
-
 	d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
 
 	pos = (u16 *) buf;
 
+#ifdef PRISM2_NIC_PCMCIA
 	word_count = len / 2;
+
 	if (word_count)
 		HFA384X_INSW(d_off, buf, word_count);
 
 	if (len & 1)
 		*((u8 *)(pos + word_count)) = HFA384X_INB(d_off);
+#endif
+
+#ifdef PRISM2_NIC_PCI
+	/* Read even(len2) buf contents from data reg */
+	for ( i = 0; i < (len2 & 0xfffe); i+=2 ) {
+	  *(u16*)(&(d[i])) = 
+	    HFA384X_INSW(d_off);
+	}
+	/* If len odd, handle last byte */
+	if ( len2 % 2 ){
+	  reg = HFA384X_INSW(d_off);
+	  d[len-1] = ((u8*)(&reg))[0];
+	}
+#endif 
 
 #endif /* PRISM2_EXTRA_FROM_BAP_TESTS */
 
@@ -467,18 +568,55 @@
 
 int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
 {
-	u16 d_off;
+        u16 d_off;
+#ifdef PRISM2_NIC_PCMCIA
 	u16 *pos;
 	int word_count;
+#endif
+#ifdef PRISM2_NIC_PCI
+	u16 reg;
+	u16 savereg;
+	int i, res;
+	u8 *d = (u8*)buf;
+	u16 o_off = (bap == 1) ? HFA384X_OFFSET1_OFF : HFA384X_OFFSET0_OFF;
+#endif
 
 	d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
 
+#ifdef PRISM2_NIC_PCMCIA
 	pos = (u16 *) buf;
 	word_count = len / 2;
 	if (word_count)
 		HFA384X_OUTSW(d_off, buf, word_count);
 	if (len & 1)
 		HFA384X_OUTB(*((char *) (pos + word_count)), d_off);
+#endif
+
+#ifdef PRISM2_NIC_PCI
+        // Write even(len) buf contents to data reg 
+	for ( i = 0; i < (len & 0xfffe); i+=2 ) {
+	  HFA384X_OUTSW(*(u16*)(&(d[i])), d_off);
+	}
+	// If len odd, handle last byte 
+	if ( len % 2 ){
+	  savereg = HFA384X_INSW(d_off);
+	  HFA384X_OUTW((len&0xfffe), o_off);
+	  // Wait for offset[busy] to clear (see BAP_TIMEOUT)
+	  i = 0; 
+	  do {
+	    reg = HFA384X_INW(o_off);
+	    if ( i > 0 ) udelay(2);
+	    i++;
+	  } while ( i < HFA384X_BAP_BUSY_TIMEOUT && HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY);
+	  if (HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY) {
+	    // If timeout, return -ETIMEDOUT 
+	    res = reg;
+	  } else {
+	    ((u8*)(&savereg))[0] = d[len-1];
+	    HFA384X_OUTSW(savereg, d_off);
+	  } 
+	} 
+#endif	
 
 	return 0;
 }
@@ -909,6 +1047,8 @@
 	local_info_t *local = (local_info_t *) dev->priv;
 
 	local->hw_ready = 0;
+
+#ifdef PRISM2_NIC_PCMCIA
 	if (local->link != NULL &&
 	    (local->link->state & DEV_PRESENT) != DEV_PRESENT) {
 		printk("%s: card already removed\n", dev_info);
@@ -918,6 +1058,7 @@
 		printk("%s: card not configured\n", dev_info);
 		return;
 	}
+#endif
 
 	hfa384x_disable_interrupts(dev);
 
@@ -925,8 +1066,10 @@
 		printk(KERN_WARNING "%s: Shutdown failed\n", dev_info);
 }
 
+
 static void prism2_cor_sreset(local_info_t *local)
 {
+#ifdef PRISM2_NIC_PCMCIA
 	int res;
 	conf_reg_t reg;
 
@@ -961,6 +1104,41 @@
 		return;
 	}
 
+#endif
+#ifdef PRISM2_NIC_PCI
+	struct net_device *dev = (struct net_device *)local->dev;
+	int	timeout;
+	u16	reg;
+
+	/* Assert reset and wait awhile 
+	 * (note: these delays are _really_ long, but they appear to be
+	 *        necessary.)
+	 */
+	HFA384X_OUTW(0x0080, HFA384X_PCICOR_OFF);
+	timeout = jiffies + HZ/4;
+	while(time_before(jiffies, timeout)) udelay(5);
+
+	/* Clear the reset and wait some more 
+	 */
+	HFA384X_OUTW(0x0, HFA384X_PCICOR_OFF);
+	timeout = jiffies + HZ/2;
+	while(time_before(jiffies, timeout)) udelay(5);
+
+	/* Wait for f/w to complete initialization (CMD:BUSY == 0) 
+	 */
+	timeout = jiffies + 2*HZ;
+	reg = HFA384X_INW(HFA384X_CMD_OFF);
+	while ((HFA384X_INW(HFA384X_OFFSET0_OFF) & HFA384X_OFFSET_BUSY) 
+	       && time_before( jiffies, timeout) ) {
+		reg = HFA384X_INW(HFA384X_CMD_OFF);
+		udelay(10);
+	}
+
+	if ((HFA384X_INW(HFA384X_OFFSET0_OFF) & HFA384X_OFFSET_BUSY)) {
+	        PDEBUG(DEBUG_PS, "corereset: Timed out waiting for cmd register.\n");
+		return;
+	}
+#endif
 	mdelay(1);
 }
 
@@ -1001,11 +1179,13 @@
 }
 
 
+#ifdef PRISM2_NIC_PCMCIA
 static void cs_error(client_handle_t handle, int func, int ret)
 {
 	error_info_t err = { func, ret };
 	CardServices(ReportError, handle, &err);
 }
+#endif
 
 
 static struct net_device_stats *prism2_get_stats(struct net_device *dev)
@@ -1034,13 +1214,16 @@
 
 static int prism2_open(struct net_device *dev)
 {
+#ifdef PRISM2_NIC_PCMCIA
 	local_info_t *local = (local_info_t *) dev->priv;
+#endif
 
 	PDEBUG(DEBUG_FLOW, "prism2_open\n");
 	netif_device_attach(dev);
 	netif_start_queue(dev);
+#ifdef PRISM2_NIC_PCMCIA
 	local->link->open++;
-
+#endif
 
 	MOD_INC_USE_COUNT;
 
@@ -1050,24 +1233,32 @@
 
 static int prism2_close(struct net_device *dev)
 {
+#ifdef PRISM2_NIC_PCMCIA
 	local_info_t *local = (local_info_t *) dev->priv;
+#endif
 
 	PDEBUG(DEBUG_FLOW, "prism2_close\n");
+
+#ifdef PRISM2_NIC_PCMCIA
 	if (!local->link->open) {
 		printk("link not open?!\n");
 		return 0;
 	}
 
 	local->link->open--;
+#endif
 	MOD_DEC_USE_COUNT;
 
 
 	if (netif_running(dev)) {
 		netif_stop_queue(dev);
 		netif_device_detach(dev);
-	} else
-		if (local->link->state & DEV_STALE_CONFIG)
-		mod_timer(&local->link->release, jiffies + HZ / 20);
+	} 
+#ifdef PRISM2_NIC_PCMCIA
+	else
+	  if (local->link->state & DEV_STALE_CONFIG)
+	    mod_timer(&local->link->release, jiffies + HZ / 20);
+#endif
 
 	return 0;
 }
@@ -1225,11 +1416,13 @@
 	unsigned long flags;
 	u16 val;
 
+#ifdef PRISM2_NIC_PCMCIA
 	if ((local->link->state & (DEV_PRESENT | DEV_CONFIG)) !=
 	    (DEV_PRESENT | DEV_CONFIG)) {
 		printk("%s: TX, but dev not OK\n", dev->name);
 		return 0;
 	}
+#endif
 
 	if (!local->hw_ready) {
 		printk(KERN_DEBUG "%s: prism2_tx: hw not ready - skipping\n",
@@ -3674,7 +3867,9 @@
 	RID(CHANNELLIST, RID_HEXDUMP),
 	RID(REGULATORYDOMAINS, RID_STRING),
 	RID(TEMPTYPE, RID_WORD),
+#ifdef PRISM2_NIC_PCMCIA
 	RID(CIS, RID_HEXDUMP),
+#endif
 	RID(STAID, RID_COMPID),
 	RID(STASUPRANGE, RID_SUPRANGE),
 	RID(MFIACTRANGES, RID_SUPRANGE),
@@ -3878,6 +4073,7 @@
 }
 
 
+#ifdef PRISM2_NIC_PCMCIA
 /* allocate local data and register with CardServices
  * initialize dev_link structure, but do not configure the card yet */
 static dev_link_t *prism2_attach(void)
@@ -4072,7 +4268,198 @@
 	}
 	kfree(link);
 }
+#endif /* prism2_attach/detach */
+
+#ifdef PRISM2_NIC_PCI
+int prism2_probe_pci(struct pci_dev *pdev, 
+		const struct pci_device_id *id)
+{
+	unsigned char	*phymem;
+	unsigned char	*mem;
+	unsigned int	irq;
+	pci_link_t	*link;
+	local_info_t *local;
+	struct net_device *dev;
+	int result;
 
+	/** STEP 1 **/
+	if (pci_enable_device(pdev))
+		return -EIO;
+
+	phymem = (unsigned char*)pci_resource_start(pdev, 0);
+	mem = ioremap((unsigned int)phymem, PCI_SIZE);
+	irq = pdev->irq;
+
+        printk(KERN_INFO "Prism2.5 PCI found ["
+		"phymem:0x%lx, irq:%d, mem:0x%lx]\n", 
+		(long)phymem, irq, (long)mem);
+
+	/** STEP 2 **/
+	link = kmalloc(sizeof(pci_link_t), GFP_KERNEL);
+	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (local) {
+		memset(local, 0, sizeof(local_info_t));
+		local->ap = kmalloc(sizeof(struct ap_data), GFP_KERNEL);
+		if (local->ap)
+			memset(local->ap, 0, sizeof(struct ap_data));
+	}
+	dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+	if (link == NULL || local == NULL || local->ap == NULL || dev == NULL)
+	{
+		printk(KERN_WARNING "prism2_probe_pci - could not kmalloc memory"
+		       "\n");
+		if (link) kfree(link);
+		if (local) {
+			if (local->ap) kfree(local->ap);
+			kfree(local);
+		}
+		if (dev) kfree(dev);
+		return 0;
+	}
+	memset(link, 0, sizeof(pci_link_t));
+	memset(dev, 0, sizeof(struct net_device));
+
+	link->priv = dev;
+	dev->priv = local;
+	local->link = link;
+	local->dev = dev;
+
+       	spin_lock_init(&local->txfidlock);
+	spin_lock_init(&local->cmdlock);
+	spin_lock_init(&local->baplock);
+
+	memcpy(local->essid, essid, sizeof(local->essid));
+#ifdef WIRELESS_EXT
+	if (iw_mode >= 1 && iw_mode <= 3) {
+		local->iw_mode = iw_mode;
+	} else {
+		printk(KERN_WARNING "prism2: Unknown iw_mode %d; using "
+		       "IW_MODE_MASTER\n", iw_mode);
+		local->iw_mode = IW_MODE_MASTER;
+	}
+#endif
+	
+	skb_queue_head_init(&local->bridge_list);
+
+	/* Initialize task queue structure for bridged packet handling */
+	INIT_LIST_HEAD(&local->bridge_queue.list);
+
+	local->bridge_queue.sync = 0;
+	local->bridge_queue.routine = (void (*)(void *))handle_bridged_queue;
+	local->bridge_queue.data = local;
+
+	ether_setup(dev);
+
+	/* kernel callbacks */
+	dev->get_stats = prism2_get_stats;
+#ifdef WIRELESS_EXT
+	dev->get_wireless_stats = prism2_get_wireless_stats;
+#endif
+	dev->open = prism2_open;
+	dev->stop = prism2_close;
+	dev->hard_start_xmit = prism2_tx;
+#ifdef HAVE_MULTICAST
+	/* FIX: to be implemented as soon as Prism2 supports GroupAddresses
+	 * and correct documentation is available */
+
+	/* dev->set_multicast_list = prism2_set_multicast_list; */
+#endif
+#ifdef HAVE_PRIVATE_IOCTL
+	dev->do_ioctl = prism2_ioctl;
+#endif
+#ifdef HAVE_CHANGE_MTU
+	dev->change_mtu = prism2_change_mtu;
+#endif
+#ifdef HAVE_TX_TIMEOUT
+	dev->tx_timeout = prism2_tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+#endif
+
+	//	init_dev_name(dev, local->node);
+	dev->mtu = mtu;
+	netif_stop_queue(dev);
+
+        dev->irq = irq;
+        dev->mem_start = (unsigned long)mem;
+        dev->mem_end = (unsigned long)mem + PCI_SIZE;
+
+	/* Link in to the list of devices managed by this driver. */
+	link->priv = local;
+	link->next = dev_list;
+	dev_list = link;
+
+	memcpy(dev->name, "wlan%d", 7);
+
+	if (register_netdev(dev)) {
+		printk(KERN_WARNING "%s: register_netdev() failed!\n",
+		       dev_info);
+
+		prism2_release_pci((u_long)link);
+
+		return 1;
+	}
+
+	printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name);
+
+	prism2_init_proc(local);
+	ap_init_data(local);
+
+	copy_dev_name(local->name, dev);
+	//	link->dev = &local->node;
+
+	request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name, dev);
+
+	prism2_cor_sreset(local);
+
+	result = prism2_hw_config(dev, 1);
+
+	printk(KERN_INFO "%s: Prism2.5 PCI init finished (return code: %d)\n", 
+	       dev_info, result);
+
+	return (result);
+}
+
+static void prism2_release_pci(u_long arg) 
+{
+  pci_link_t *link = (pci_link_t *)arg;
+  local_info_t *local = NULL;
+  struct net_device *dev;
+
+  if(link->priv) {
+    dev = (struct net_device *)link->priv;
+    if(dev->priv) 
+      local = (local_info_t *)dev->priv;
+
+    /* release local_info_t struct */
+    if (local) {
+      if (local->ap != NULL)
+	ap_free_data(local->ap);
+      prism2_remove_proc(local);
+      if (dev) {
+	unregister_netdev(dev);
+	printk("%s: Netdevice unregistered\n", dev_info);
+      } else
+	printk("%s: link->dev == NULL: do not unregister "
+	       "netdevice\n", dev_info);
+#ifdef PRISM2_MONITOR
+      if (local->nl_monitor != NULL) {
+	if (local->nl_monitor->socket == NULL)
+	  printk("nl_monitor->socket == NULL\n");
+	/* this seems to crash the kernel.. */
+	/* sock_release(local->nl_monitor->socket); */
+      }
+#endif
+      if(dev)
+	kfree(dev);
+      if(local)
+	kfree(local);
+    }
+  }
+
+  if(link)
+    kfree(link);
+}  
+#endif /* probe pci */
 
 /* Called only from hardware IRQ */
 static void prism2_alloc_ev(struct net_device *dev)
@@ -4423,11 +4810,13 @@
 	static long int last_magic_err = 0;
 #endif
 
+#ifdef PRISM2_NIC_PCMCIA
 	if ((local->link->state & (DEV_PRESENT | DEV_CONFIG)) !=
 	    (DEV_PRESENT | DEV_CONFIG)) {
 		printk("%s: Interrupt, but dev not OK\n", dev->name);
 		return;
 	}
+#endif
 
 #ifndef final_version
 	if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
@@ -4511,7 +4900,7 @@
 		PDEBUG(DEBUG_EXTRA, "prism2_interrupt: >20 events\n");
 }
 
-
+#ifdef PRISM2_NIC_PCMCIA
 #define CS_CHECK(fn, args...) \
 while ((last_ret = CardServices(last_fn = (fn), args)) != 0) goto cs_failed
 
@@ -4858,7 +5247,6 @@
 }
 
 
-
 static int prism2_event(event_t event, int priority,
 			event_callback_args_t *args)
 {
@@ -4925,10 +5313,12 @@
 	}
 	return 0;
 }
+#endif /* PRISM2_NIC_PCMCIA */
 
 
 static int __init init_prism2(void)
 {
+#ifdef PRISM2_NIC_PCMCIA
 	servinfo_t serv;
 
 	printk(KERN_INFO "%s: %s\n"
@@ -4941,6 +5331,20 @@
 		return -1;
 	}
 	register_pccard_driver(&dev_info, &prism2_attach, &prism2_detach);
+#endif
+
+#ifdef PRISM2_NIC_PCI
+	printk(KERN_INFO "%s: %s\n"
+	       "%s: (c) SSH Communications Security Corp <jkm@ssh.com>\n"
+	       "%s: PCI support by Reyk Floeter <reyk@synack.de>, https://www.wavehan.de/\n",
+	       dev_info, version, dev_info, dev_info);
+
+	if (pci_register_driver(&prism2_pci_drv_id) <= 0) {
+		printk(KERN_NOTICE "prism2: No devices found, driver not installed.\n");
+		pci_unregister_driver(&prism2_pci_drv_id);
+		return -ENODEV;
+	}
+#endif
 
 	return 0;
 }
@@ -4948,6 +5352,7 @@
 
 static void __exit exit_prism2(void)
 {
+#ifdef PRISM2_NIC_PCMCIA
 	unregister_pccard_driver(&dev_info);
 	while (dev_list) {
 		PDEBUG(DEBUG_FLOW, "exit_prism2 - detaching device\n");
@@ -4961,6 +5366,37 @@
 		remove_proc_entry("prism2", proc_net);
 
 	printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
+#endif
+#ifdef PRISM2_NIC_PCI
+  /** FIXME **/
+  pci_link_t *link = dev_list;
+  
+  PDEBUG(DEBUG_FLOW, "exit_prism2 - unregistering proc device\n");
+  if (prism2_proc != NULL)
+    remove_proc_entry("prism2", proc_net);
+
+  if (link != NULL) {
+    for (link=dev_list; link != NULL; link = link->next) {
+      PDEBUG(DEBUG_FLOW, "exit_prism2 - detaching device\n");
+      if(link->priv) {
+	local_info_t *local = (local_info_t *)link->priv;
+	//prism2_hw_reset(local->dev);
+	prism2_hw_shutdown(local->dev);
+	//prism2_reset_pci((u_long)local->dev);
+	//if(local->dev != NULL)
+	//  prism2_hw_shutdown(local->dev);
+	//iounmap((void*)local->dev->mem_start);
+	//free_irq(local->dev->irq, local->dev);
+      }
+      //      prism2_release_pci((u_long)link);
+      		/* Free the resources */
+    }
+  }
+  
+  PDEBUG(DEBUG_FLOW, "exit_prism2 - unregistering pci device\n");
+  pci_unregister_driver(&prism2_pci_drv_id);
+#endif
+
 }
 
 
diff -Naur Prism2-2002-02-13/driver/modules/prism2_ap.c Prism2x-2002-02-13/driver/modules/prism2_ap.c
--- Prism2-2002-02-13/driver/modules/prism2_ap.c	Wed Feb 13 18:29:18 2002
+++ Prism2x-2002-02-13/driver/modules/prism2_ap.c	Fri Feb 22 15:30:08 2002
@@ -226,11 +226,16 @@
 	}
 
 	/* Initialize task queue structure for AP management */
+#ifdef PRISM2_NIC_PCMCIA
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
 	local->ap->ap_queue.next = NULL;
 #else
 	INIT_LIST_HEAD(&local->ap->ap_queue.list);
 #endif
+#else
+	INIT_LIST_HEAD(&local->ap->ap_queue.list);
+#endif
+
 	local->ap->ap_queue.sync = 0;
 	local->ap->ap_queue.routine = (void (*)(void *))handle_ap_queue;
 	local->ap->ap_queue.data = local;
@@ -1154,6 +1159,7 @@
 	struct hfa384x_rx_frame *rxdesc;
 	int i;
 
+#ifdef PRISM2_NIC_PCMCIA
 	if ((local->link->state & (DEV_PRESENT | DEV_CONFIG)) !=
 	    (DEV_PRESENT | DEV_CONFIG)) {
 		printk("prism2: handle_ap_queue, but dev not OK\n");
@@ -1162,6 +1168,7 @@
 #endif
 		return;
 	}
+#endif
 
 	for (;;) {
 		int type = 0;
@@ -1187,9 +1194,13 @@
 			printk("handle_ap_queue: unknown type %d\n", type);
 	}
 
+#ifdef PRISM2_NIC_PCMCIA
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
 	MOD_DEC_USE_COUNT;
 #endif
+#else
+	MOD_DEC_USE_COUNT;
+#endif
 }
 
 
@@ -1261,6 +1272,7 @@
 	}
 
 /* tq_scheduler was removed in 2.4.0-test12 */
+#ifdef PRISM2_NIC_PCMCIA
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
 	queue_task(&local->ap->ap_queue, &tq_scheduler);
 #else
@@ -1268,6 +1280,11 @@
 	if (schedule_task(&local->ap->ap_queue) == 0)
 		MOD_DEC_USE_COUNT;
 #endif
+#else
+	MOD_INC_USE_COUNT;
+	if (schedule_task(&local->ap->ap_queue) == 0)
+		MOD_DEC_USE_COUNT;
+#endif
 }
 
 
@@ -1308,8 +1325,14 @@
 	PDEBUG(DEBUG_PS, "Scheduling buffered packet delivery for STA\n");
 
 /* tq_scheduler was removed in 2.4.0-test12 */
+#ifdef PRISM2_NIC_PCMCIA
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
 	queue_task(&local->ap->ap_queue, &tq_scheduler);
+#else
+	MOD_INC_USE_COUNT;
+	if (schedule_task(&local->ap->ap_queue) == 0)
+		MOD_DEC_USE_COUNT;
+#endif
 #else
 	MOD_INC_USE_COUNT;
 	if (schedule_task(&local->ap->ap_queue) == 0)
diff -Naur Prism2-2002-02-13/driver/modules/prism2_wlan.h Prism2x-2002-02-13/driver/modules/prism2_wlan.h
--- Prism2-2002-02-13/driver/modules/prism2_wlan.h	Wed Feb 13 18:29:18 2002
+++ Prism2x-2002-02-13/driver/modules/prism2_wlan.h	Fri Feb 22 15:30:08 2002
@@ -1,6 +1,22 @@
 #ifndef PRISM2_WLAN_H
 #define PRISM2_WLAN_H
 
+#ifndef DEV_NAME_LEN
+#define DEV_NAME_LEN	32
+#endif
+
+#ifdef PRISM2_NIC_PCI
+typedef struct dev_node_t {
+  char dev_name[DEV_NAME_LEN];
+  u_short major, minor;
+  struct dev_node_t *next;
+} dev_node_t;
+
+typedef struct pci_link {
+  void *priv;
+  struct pci_link *next;
+} pci_link_t;
+#endif
 
 #define BIT(x) (1 << (x))
 
@@ -174,6 +190,7 @@
 	unsigned int rx_message_in_bad_msg_fragments;
 };
 
+#ifdef PRISM2_NIC_PCMCIA
 /* I/O ports for HFA384X Controller access */
 #define HFA384X_CMD_OFF 0x00
 #define HFA384X_PARAM0_OFF 0x02
@@ -203,6 +220,51 @@
 #define HFA384X_AUXPAGE_OFF 0x3A
 #define HFA384X_AUXOFFSET_OFF 0x3C
 #define HFA384X_AUXDATA_OFF 0x3E
+#endif
+
+#ifdef PRISM2_NIC_PCI
+/* Memory addresses for ISL3874 controller access */
+#define HFA384X_CMD_OFF 0x00
+#define HFA384X_PARAM0_OFF 0x04
+#define HFA384X_PARAM1_OFF 0x08
+#define HFA384X_PARAM2_OFF 0x0c
+#define HFA384X_STATUS_OFF 0x10
+#define HFA384X_RESP0_OFF 0x14
+#define HFA384X_RESP1_OFF 0x18
+#define HFA384X_RESP2_OFF 0x1c
+#define HFA384X_INFOFID_OFF 0x20
+#define HFA384X_CONTROL_OFF 0x28
+#define HFA384X_SELECT0_OFF 0x30
+#define HFA384X_SELECT1_OFF 0x34
+#define HFA384X_OFFSET0_OFF 0x38
+#define HFA384X_OFFSET1_OFF 0x3c
+#define HFA384X_RXFID_OFF 0x40
+#define HFA384X_ALLOCFID_OFF 0x44
+#define HFA384X_TXCOMPLFID_OFF 0x48
+#define HFA384X_SWSUPPORT0_OFF 0x50
+#define HFA384X_SWSUPPORT1_OFF 0x54
+#define HFA384X_SWSUPPORT2_OFF 0x58
+#define HFA384X_EVSTAT_OFF 0x60
+#define HFA384X_INTEN_OFF 0x64
+#define HFA384X_EVACK_OFF 0x68
+#define HFA384X_DATA0_OFF 0x6c
+#define HFA384X_DATA1_OFF 0x70
+#define HFA384X_AUXPAGE_OFF 0x74
+#define HFA384X_AUXOFFSET_OFF 0x78
+#define HFA384X_AUXDATA_OFF 0x7c
+
+#define	HFA384X_PCICOR_OFF 0x4c
+#define	HFA384X_PCIHCR_OFF 0x5c
+#define	HFA384X_PCI_M0_ADDRH_OFF 0x80
+#define	HFA384X_PCI_M0_ADDRL_OFF 0x84
+#define	HFA384X_PCI_M0_LEN_OFF 0x88
+#define	HFA384X_PCI_M0_CTL_OFF 0x8c
+#define	HFA384X_PCI_STATUS_OFF 0x98
+#define	HFA384X_PCI_M1_ADDRH_OFF 0xa0
+#define	HFA384X_PCI_M1_ADDRL_OFF 0xa4
+#define	HFA384X_PCI_M1_LEN_OFF 0xa8
+#define	HFA384X_PCI_M1_CTL_OFF 0xac
+#endif
 
 /* Command codes for CMD reg. */
 #define HFA384X_CMDCODE_INIT 0x00
@@ -334,7 +396,9 @@
 #define HFA384X_RID_CHANNELLIST 0xFD10
 #define HFA384X_RID_REGULATORYDOMAINS 0xFD11
 #define HFA384X_RID_TEMPTYPE 0xFD12
+#ifdef PRISM2_NIC_PCMCIA
 #define HFA384X_RID_CIS 0xFD13
+#endif
 #define HFA384X_RID_STAID 0xFD20
 #define HFA384X_RID_STASUPRANGE 0xFD21
 #define HFA384X_RID_MFIACTRANGES 0xFD22
@@ -536,9 +600,15 @@
 #define PRISM2_DUMP_TX_HDR 2
 
 typedef struct local_info {
-	dev_node_t node;
 	struct net_device *dev;
+#ifdef PRISM2_NIC_PCMCIA
+    	dev_node_t node;
 	dev_link_t *link;
+#endif
+#ifdef PRISM2_NIC_PCI
+	char name[DEV_NAME_LEN];
+	pci_link_t *link;
+#endif
 	spinlock_t cmdlock, baplock;
 	u16 infofid; /* MAC buffer id for info frame */
 	/* txfid, intransmitfid, next_txtid, and next_alloc are protected by
diff -Naur Prism2-2002-02-13/driver/prism2.mk Prism2x-2002-02-13/driver/prism2.mk
--- Prism2-2002-02-13/driver/prism2.mk	Wed Feb 13 18:29:18 2002
+++ Prism2x-2002-02-13/driver/prism2.mk	Fri Feb 22 15:30:08 2002
@@ -4,7 +4,7 @@
 	etc/prism2.conf
 
 all:
-	$(MAKE) -C modules MODULES=prism2.o
+	$(MAKE) -DPRISM2_NIC_PCMCIA -C modules MODULES=prism2.o
 
 install:
 	$(MAKE) -C modules install-modules MODULES=prism2.o

