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 +#include + +#include +#include +#include + +#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 #include -#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 -#include - -#include -#include -#include - #include #include #include @@ -87,6 +87,14 @@ #include #include +#endif /* PRISM2_NIC_PCMCIA */ + +#ifdef PRISM2_NIC_PCI +#include +#include +#include +#endif + #include #include #include @@ -94,6 +102,7 @@ #include #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 #include #include @@ -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*)(®))[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 \n" + "%s: PCI support by Reyk Floeter , 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