From 637e07a3128e0b2896478ec87694e6d0dd8e3390 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 31 Jul 2005 13:07:26 -0400 Subject: [PATCH] --- yaml --- r: 6758 b: refs/heads/master c: bf79451ec5862510b402c112c039698e68d0c250 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 7 - trunk/drivers/net/wireless/Kconfig | 2 - trunk/drivers/net/wireless/Makefile | 2 - trunk/drivers/net/wireless/airo.c | 65 +- trunk/drivers/net/wireless/hostap/Kconfig | 71 - trunk/drivers/net/wireless/hostap/Makefile | 5 - trunk/drivers/net/wireless/hostap/hostap.c | 1199 ----- trunk/drivers/net/wireless/hostap/hostap.h | 57 - .../net/wireless/hostap/hostap_80211.h | 107 - .../net/wireless/hostap/hostap_80211_rx.c | 1084 ----- .../net/wireless/hostap/hostap_80211_tx.c | 522 --- trunk/drivers/net/wireless/hostap/hostap_ap.c | 3287 ------------- trunk/drivers/net/wireless/hostap/hostap_ap.h | 273 -- .../net/wireless/hostap/hostap_common.h | 499 -- .../net/wireless/hostap/hostap_config.h | 86 - trunk/drivers/net/wireless/hostap/hostap_cs.c | 985 ---- .../net/wireless/hostap/hostap_download.c | 766 --- trunk/drivers/net/wireless/hostap/hostap_hw.c | 3635 --------------- .../drivers/net/wireless/hostap/hostap_info.c | 499 -- .../net/wireless/hostap/hostap_ioctl.c | 4126 ----------------- .../drivers/net/wireless/hostap/hostap_pci.c | 455 -- .../drivers/net/wireless/hostap/hostap_plx.c | 622 --- .../drivers/net/wireless/hostap/hostap_proc.c | 448 -- .../drivers/net/wireless/hostap/hostap_wlan.h | 1066 ----- trunk/drivers/net/wireless/ipw2200.c | 1600 +++---- trunk/drivers/net/wireless/ipw2200.h | 234 +- trunk/drivers/net/wireless/strip.c | 2 +- trunk/drivers/net/wireless/wavelan_cs.c | 26 +- trunk/drivers/net/wireless/wavelan_cs.h | 6 +- trunk/drivers/net/wireless/wavelan_cs.p.h | 17 + trunk/drivers/net/wireless/wl3501_cs.c | 11 +- 32 files changed, 986 insertions(+), 20780 deletions(-) delete mode 100644 trunk/drivers/net/wireless/hostap/Kconfig delete mode 100644 trunk/drivers/net/wireless/hostap/Makefile delete mode 100644 trunk/drivers/net/wireless/hostap/hostap.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap.h delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_80211.h delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_80211_rx.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_80211_tx.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_ap.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_ap.h delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_common.h delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_config.h delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_cs.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_download.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_hw.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_info.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_ioctl.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_pci.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_plx.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_proc.c delete mode 100644 trunk/drivers/net/wireless/hostap/hostap_wlan.h diff --git a/[refs] b/[refs] index e78ba7a0b362..c2c007216979 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 24735354f3074fa90b185b8cd7cb13fd53c39e6b +refs/heads/master: bf79451ec5862510b402c112c039698e68d0c250 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 4b390695888b..ec8433c39dee 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -991,13 +991,6 @@ M: mike.miller@hp.com L: iss_storagedev@hp.com S: Supported -HOST AP DRIVER -P: Jouni Malinen -M: jkmaline@cc.hut.fi -L: hostap@shmoo.com -W: http://hostap.epitest.fi/ -S: Maintained - HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series P: Jaroslav Kysela M: perex@suse.cz diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index ff5b1b1de2fa..d20e0da05a26 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -459,8 +459,6 @@ config PRISM54 say M here and read . The module will be called prism54.ko. -source "drivers/net/wireless/hostap/Kconfig" - # yes, this works even when no drivers are selected config NET_WIRELESS bool diff --git a/trunk/drivers/net/wireless/Makefile b/trunk/drivers/net/wireless/Makefile index 0953cc0cdee6..0859787581bb 100644 --- a/trunk/drivers/net/wireless/Makefile +++ b/trunk/drivers/net/wireless/Makefile @@ -32,8 +32,6 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o obj-$(CONFIG_PRISM54) += prism54/ -obj-$(CONFIG_HOSTAP) += hostap/ - # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index 6db1fb6461de..df20adcd0730 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -1040,7 +1040,7 @@ typedef struct { u16 status; } WifiCtlHdr; -static WifiCtlHdr wifictlhdr8023 = { +WifiCtlHdr wifictlhdr8023 = { .ctlhdr = { .ctl = HOST_DONT_RLSE, } @@ -1111,13 +1111,13 @@ static int airo_thread(void *data); static void timer_func( struct net_device *dev ); static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef WIRELESS_EXT -static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); +struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); static void airo_read_wireless_stats (struct airo_info *local); #endif /* WIRELESS_EXT */ #ifdef CISCO_EXT static int readrids(struct net_device *dev, aironet_ioctl *comp); static int writerids(struct net_device *dev, aironet_ioctl *comp); -static int flashcard(struct net_device *dev, aironet_ioctl *comp); +int flashcard(struct net_device *dev, aironet_ioctl *comp); #endif /* CISCO_EXT */ #ifdef MICSUPPORT static void micinit(struct airo_info *ai); @@ -1226,12 +1226,6 @@ static int setup_proc_entry( struct net_device *dev, static int takedown_proc_entry( struct net_device *dev, struct airo_info *apriv ); -static int cmdreset(struct airo_info *ai); -static int setflashmode (struct airo_info *ai); -static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime); -static int flashputbuf(struct airo_info *ai); -static int flashrestart(struct airo_info *ai,struct net_device *dev); - #ifdef MICSUPPORT /*********************************************************************** * MIC ROUTINES * @@ -1240,11 +1234,10 @@ static int flashrestart(struct airo_info *ai,struct net_device *dev); static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq); static void MoveWindow(miccntx *context, u32 micSeq); -static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); -static void emmh32_init(emmh32_context *context); -static void emmh32_update(emmh32_context *context, u8 *pOctets, int len); -static void emmh32_final(emmh32_context *context, u8 digest[4]); -static int flashpchar(struct airo_info *ai,int byte,int dwelltime); +void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); +void emmh32_init(emmh32_context *context); +void emmh32_update(emmh32_context *context, u8 *pOctets, int len); +void emmh32_final(emmh32_context *context, u8 digest[4]); /* micinit - Initialize mic seed */ @@ -1322,7 +1315,7 @@ static int micsetup(struct airo_info *ai) { return SUCCESS; } -static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; +char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; /*=========================================================================== * Description: Mic a packet @@ -1577,7 +1570,7 @@ static void MoveWindow(miccntx *context, u32 micSeq) static unsigned char aes_counter[16]; /* expand the key to fill the MMH coefficient array */ -static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) +void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) { /* take the keying material, expand if necessary, truncate at 16-bytes */ /* run through AES counter mode to generate context->coeff[] */ @@ -1609,7 +1602,7 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct } /* prepare for calculation of a new mic */ -static void emmh32_init(emmh32_context *context) +void emmh32_init(emmh32_context *context) { /* prepare for new mic calculation */ context->accum = 0; @@ -1617,7 +1610,7 @@ static void emmh32_init(emmh32_context *context) } /* add some bytes to the mic calculation */ -static void emmh32_update(emmh32_context *context, u8 *pOctets, int len) +void emmh32_update(emmh32_context *context, u8 *pOctets, int len) { int coeff_position, byte_position; @@ -1659,7 +1652,7 @@ static void emmh32_update(emmh32_context *context, u8 *pOctets, int len) static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L }; /* calculate the mic */ -static void emmh32_final(emmh32_context *context, u8 digest[4]) +void emmh32_final(emmh32_context *context, u8 digest[4]) { int coeff_position, byte_position; u32 val; @@ -2262,7 +2255,7 @@ static void airo_read_stats(struct airo_info *ai) { ai->stats.rx_fifo_errors = vals[0]; } -static struct net_device_stats *airo_get_stats(struct net_device *dev) +struct net_device_stats *airo_get_stats(struct net_device *dev) { struct airo_info *local = dev->priv; @@ -2421,7 +2414,7 @@ EXPORT_SYMBOL(stop_airo_card); static int add_airo_dev( struct net_device *dev ); -static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) +int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) { memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); return ETH_ALEN; @@ -2688,7 +2681,7 @@ static struct net_device *init_wifidev(struct airo_info *ai, return dev; } -static int reset_card( struct net_device *dev , int lock) { +int reset_card( struct net_device *dev , int lock) { struct airo_info *ai = dev->priv; if (lock && down_interruptible(&ai->sem)) @@ -2703,9 +2696,9 @@ static int reset_card( struct net_device *dev , int lock) { return 0; } -static struct net_device *_init_airo_card( unsigned short irq, int port, - int is_pcmcia, struct pci_dev *pci, - struct device *dmdev ) +struct net_device *_init_airo_card( unsigned short irq, int port, + int is_pcmcia, struct pci_dev *pci, + struct device *dmdev ) { struct net_device *dev; struct airo_info *ai; @@ -7242,7 +7235,7 @@ static void airo_read_wireless_stats(struct airo_info *local) local->wstats.miss.beacon = vals[34]; } -static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) +struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) { struct airo_info *local = dev->priv; @@ -7457,8 +7450,14 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) { * Flash command switch table */ -static int flashcard(struct net_device *dev, aironet_ioctl *comp) { +int flashcard(struct net_device *dev, aironet_ioctl *comp) { int z; + int cmdreset(struct airo_info *); + int setflashmode(struct airo_info *); + int flashgchar(struct airo_info *,int,int); + int flashpchar(struct airo_info *,int,int); + int flashputbuf(struct airo_info *); + int flashrestart(struct airo_info *,struct net_device *); /* Only super-user can modify flash */ if (!capable(CAP_NET_ADMIN)) @@ -7516,7 +7515,7 @@ static int flashcard(struct net_device *dev, aironet_ioctl *comp) { * card. */ -static int cmdreset(struct airo_info *ai) { +int cmdreset(struct airo_info *ai) { disable_MAC(ai, 1); if(!waitbusy (ai)){ @@ -7540,7 +7539,7 @@ static int cmdreset(struct airo_info *ai) { * mode */ -static int setflashmode (struct airo_info *ai) { +int setflashmode (struct airo_info *ai) { set_bit (FLAG_FLASHING, &ai->flags); OUT4500(ai, SWS0, FLASH_COMMAND); @@ -7567,7 +7566,7 @@ static int setflashmode (struct airo_info *ai) { * x 50us for echo . */ -static int flashpchar(struct airo_info *ai,int byte,int dwelltime) { +int flashpchar(struct airo_info *ai,int byte,int dwelltime) { int echo; int waittime; @@ -7607,7 +7606,7 @@ static int flashpchar(struct airo_info *ai,int byte,int dwelltime) { * Get a character from the card matching matchbyte * Step 3) */ -static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){ +int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){ int rchar; unsigned char rbyte=0; @@ -7638,7 +7637,7 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){ * send to the card */ -static int flashputbuf(struct airo_info *ai){ +int flashputbuf(struct airo_info *ai){ int nwords; /* Write stuff */ @@ -7660,7 +7659,7 @@ static int flashputbuf(struct airo_info *ai){ /* * */ -static int flashrestart(struct airo_info *ai,struct net_device *dev){ +int flashrestart(struct airo_info *ai,struct net_device *dev){ int i,status; ssleep(1); /* Added 12/7/00 */ diff --git a/trunk/drivers/net/wireless/hostap/Kconfig b/trunk/drivers/net/wireless/hostap/Kconfig deleted file mode 100644 index 1445f3f2600f..000000000000 --- a/trunk/drivers/net/wireless/hostap/Kconfig +++ /dev/null @@ -1,71 +0,0 @@ -config HOSTAP - tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)" - depends on NET_RADIO - ---help--- - Shared driver code for IEEE 802.11b wireless cards based on - Intersil Prism2/2.5/3 chipset. This driver supports so called - Host AP mode that allows the card to act as an IEEE 802.11 - access point. - - See for more information about the - Host AP driver configuration and tools. This site includes - information and tools (hostapd and wpa_supplicant) for WPA/WPA2 - support. - - This option includes the base Host AP driver code that is shared by - different hardware models. You will also need to enable support for - PLX/PCI/CS version of the driver to actually use the driver. - - The driver can be compiled as a module and it will be called - "hostap.ko". - -config HOSTAP_FIRMWARE - bool "Support downloading firmware images with Host AP driver" - depends on HOSTAP - ---help--- - Configure Host AP driver to include support for firmware image - download. Current version supports only downloading to volatile, i.e., - RAM memory. Flash upgrade is not yet supported. - - Firmware image downloading needs user space tool, prism2_srec. It is - available from http://hostap.epitest.fi/. - -config HOSTAP_PLX - tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors" - depends on PCI && HOSTAP - ---help--- - Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based - PCI adaptors. - - "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this - driver and its help text includes more information about the Host AP - driver. - - The driver can be compiled as a module and will be named - "hostap_plx.ko". - -config HOSTAP_PCI - tristate "Host AP driver for Prism2.5 PCI adaptors" - depends on PCI && HOSTAP - ---help--- - Host AP driver's version for Prism2.5 PCI adaptors. - - "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this - driver and its help text includes more information about the Host AP - driver. - - The driver can be compiled as a module and will be named - "hostap_pci.ko". - -config HOSTAP_CS - tristate "Host AP driver for Prism2/2.5/3 PC Cards" - depends on PCMCIA!=n && HOSTAP - ---help--- - Host AP driver's version for Prism2/2.5/3 PC Cards. - - "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this - driver and its help text includes more information about the Host AP - driver. - - The driver can be compiled as a module and will be named - "hostap_cs.ko". diff --git a/trunk/drivers/net/wireless/hostap/Makefile b/trunk/drivers/net/wireless/hostap/Makefile deleted file mode 100644 index fc62235bfc24..000000000000 --- a/trunk/drivers/net/wireless/hostap/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_HOSTAP) += hostap.o - -obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o -obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o -obj-$(CONFIG_HOSTAP_PCI) += hostap_pci.o diff --git a/trunk/drivers/net/wireless/hostap/hostap.c b/trunk/drivers/net/wireless/hostap/hostap.c deleted file mode 100644 index 0858eba4575f..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap.c +++ /dev/null @@ -1,1199 +0,0 @@ -/* - * Host AP (software wireless LAN access point) driver for - * Intersil Prism2/2.5/3 - hostap.o module, common routines - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2005, Jouni Malinen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hostap_wlan.h" -#include "hostap_80211.h" -#include "hostap_ap.h" -#include "hostap.h" - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP common routines"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - -#define TX_TIMEOUT (2 * HZ) - -#define PRISM2_MAX_FRAME_SIZE 2304 -#define PRISM2_MIN_MTU 256 -/* FIX: */ -#define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */)) - - -/* hostap.c */ -static int prism2_wds_add(local_info_t *local, u8 *remote_addr, - int rtnl_locked); -static int prism2_wds_del(local_info_t *local, u8 *remote_addr, - int rtnl_locked, int do_not_remove); - -/* hostap_ap.c */ -static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], - struct iw_quality qual[], int buf_size, - int aplist); -static int prism2_ap_translate_scan(struct net_device *dev, char *buffer); -static int prism2_hostapd(struct ap_data *ap, - struct prism2_hostapd_param *param); -static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct ieee80211_crypt_data ***crypt); -static void ap_control_kickall(struct ap_data *ap); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, - u8 *mac); -static int ap_control_del_mac(struct mac_restrictions *mac_restrictions, - u8 *mac); -static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions); -static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, - u8 *mac); -#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; -#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0])) - - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ - - -/* FIX: these could be compiled separately and linked together to hostap.o */ -#include "hostap_ap.c" -#include "hostap_info.c" -#include "hostap_ioctl.c" -#include "hostap_proc.c" -#include "hostap_80211_rx.c" -#include "hostap_80211_tx.c" - - -struct net_device * hostap_add_interface(struct local_info *local, - int type, int rtnl_locked, - const char *prefix, - const char *name) -{ - struct net_device *dev, *mdev; - struct hostap_interface *iface; - int ret; - - dev = alloc_etherdev(sizeof(struct hostap_interface)); - if (dev == NULL) - return NULL; - - iface = netdev_priv(dev); - iface->dev = dev; - iface->local = local; - iface->type = type; - list_add(&iface->list, &local->hostap_interfaces); - - mdev = local->dev; - memcpy(dev->dev_addr, mdev->dev_addr, ETH_ALEN); - dev->base_addr = mdev->base_addr; - dev->irq = mdev->irq; - dev->mem_start = mdev->mem_start; - dev->mem_end = mdev->mem_end; - - hostap_setup_dev(dev, local, 0); - dev->destructor = free_netdev; - - sprintf(dev->name, "%s%s", prefix, name); - if (!rtnl_locked) - rtnl_lock(); - - ret = 0; - if (strchr(dev->name, '%')) - ret = dev_alloc_name(dev, dev->name); - - SET_NETDEV_DEV(dev, mdev->class_dev.dev); - if (ret >= 0) - ret = register_netdevice(dev); - - if (!rtnl_locked) - rtnl_unlock(); - - if (ret < 0) { - printk(KERN_WARNING "%s: failed to add new netdevice!\n", - dev->name); - free_netdev(dev); - return NULL; - } - - printk(KERN_DEBUG "%s: registered netdevice %s\n", - mdev->name, dev->name); - - return dev; -} - - -void hostap_remove_interface(struct net_device *dev, int rtnl_locked, - int remove_from_list) -{ - struct hostap_interface *iface; - - if (!dev) - return; - - iface = netdev_priv(dev); - - if (remove_from_list) { - list_del(&iface->list); - } - - if (dev == iface->local->ddev) - iface->local->ddev = NULL; - else if (dev == iface->local->apdev) - iface->local->apdev = NULL; - else if (dev == iface->local->stadev) - iface->local->stadev = NULL; - - if (rtnl_locked) - unregister_netdevice(dev); - else - unregister_netdev(dev); - - /* dev->destructor = free_netdev() will free the device data, including - * private data, when removing the device */ -} - - -static inline int prism2_wds_special_addr(u8 *addr) -{ - if (addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5]) - return 0; - - return 1; -} - - -static int prism2_wds_add(local_info_t *local, u8 *remote_addr, - int rtnl_locked) -{ - struct net_device *dev; - struct list_head *ptr; - struct hostap_interface *iface, *empty, *match; - - empty = match = NULL; - read_lock_bh(&local->iface_lock); - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - if (iface->type != HOSTAP_INTERFACE_WDS) - continue; - - if (prism2_wds_special_addr(iface->u.wds.remote_addr)) - empty = iface; - else if (memcmp(iface->u.wds.remote_addr, remote_addr, - ETH_ALEN) == 0) { - match = iface; - break; - } - } - if (!match && empty && !prism2_wds_special_addr(remote_addr)) { - /* take pre-allocated entry into use */ - memcpy(empty->u.wds.remote_addr, remote_addr, ETH_ALEN); - read_unlock_bh(&local->iface_lock); - printk(KERN_DEBUG "%s: using pre-allocated WDS netdevice %s\n", - local->dev->name, empty->dev->name); - return 0; - } - read_unlock_bh(&local->iface_lock); - - if (!prism2_wds_special_addr(remote_addr)) { - if (match) - return -EEXIST; - hostap_add_sta(local->ap, remote_addr); - } - - if (local->wds_connections >= local->wds_max_connections) - return -ENOBUFS; - - /* verify that there is room for wds# postfix in the interface name */ - if (strlen(local->dev->name) > IFNAMSIZ - 5) { - printk(KERN_DEBUG "'%s' too long base device name\n", - local->dev->name); - return -EINVAL; - } - - dev = hostap_add_interface(local, HOSTAP_INTERFACE_WDS, rtnl_locked, - local->ddev->name, "wds%d"); - if (dev == NULL) - return -ENOMEM; - - iface = netdev_priv(dev); - memcpy(iface->u.wds.remote_addr, remote_addr, ETH_ALEN); - - local->wds_connections++; - - return 0; -} - - -static int prism2_wds_del(local_info_t *local, u8 *remote_addr, - int rtnl_locked, int do_not_remove) -{ - unsigned long flags; - struct list_head *ptr; - struct hostap_interface *iface, *selected = NULL; - - write_lock_irqsave(&local->iface_lock, flags); - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - if (iface->type != HOSTAP_INTERFACE_WDS) - continue; - - if (memcmp(iface->u.wds.remote_addr, remote_addr, - ETH_ALEN) == 0) { - selected = iface; - break; - } - } - if (selected && !do_not_remove) - list_del(&selected->list); - write_unlock_irqrestore(&local->iface_lock, flags); - - if (selected) { - if (do_not_remove) - memset(selected->u.wds.remote_addr, 0, ETH_ALEN); - else { - hostap_remove_interface(selected->dev, rtnl_locked, 0); - local->wds_connections--; - } - } - - return selected ? 0 : -ENODEV; -} - - -u16 hostap_tx_callback_register(local_info_t *local, - void (*func)(struct sk_buff *, int ok, void *), - void *data) -{ - unsigned long flags; - struct hostap_tx_callback_info *entry; - - entry = (struct hostap_tx_callback_info *) kmalloc(sizeof(*entry), - GFP_ATOMIC); - if (entry == NULL) - return 0; - - entry->func = func; - entry->data = data; - - spin_lock_irqsave(&local->lock, flags); - entry->idx = local->tx_callback ? local->tx_callback->idx + 1 : 1; - entry->next = local->tx_callback; - local->tx_callback = entry; - spin_unlock_irqrestore(&local->lock, flags); - - return entry->idx; -} - - -int hostap_tx_callback_unregister(local_info_t *local, u16 idx) -{ - unsigned long flags; - struct hostap_tx_callback_info *cb, *prev = NULL; - - spin_lock_irqsave(&local->lock, flags); - cb = local->tx_callback; - while (cb != NULL && cb->idx != idx) { - prev = cb; - cb = cb->next; - } - if (cb) { - if (prev == NULL) - local->tx_callback = cb->next; - else - prev->next = cb->next; - kfree(cb); - } - spin_unlock_irqrestore(&local->lock, flags); - - return cb ? 0 : -1; -} - - -/* val is in host byte order */ -int hostap_set_word(struct net_device *dev, int rid, u16 val) -{ - struct hostap_interface *iface; - u16 tmp = cpu_to_le16(val); - iface = netdev_priv(dev); - return iface->local->func->set_rid(dev, rid, &tmp, 2); -} - - -int hostap_set_string(struct net_device *dev, int rid, const char *val) -{ - struct hostap_interface *iface; - char buf[MAX_SSID_LEN + 2]; - int len; - - iface = netdev_priv(dev); - len = strlen(val); - if (len > MAX_SSID_LEN) - return -1; - memset(buf, 0, sizeof(buf)); - buf[0] = len; /* little endian 16 bit word */ - memcpy(buf + 2, val, len); - - return iface->local->func->set_rid(dev, rid, &buf, MAX_SSID_LEN + 2); -} - - -u16 hostap_get_porttype(local_info_t *local) -{ - if (local->iw_mode == IW_MODE_ADHOC && local->pseudo_adhoc) - return HFA384X_PORTTYPE_PSEUDO_IBSS; - if (local->iw_mode == IW_MODE_ADHOC) - return HFA384X_PORTTYPE_IBSS; - if (local->iw_mode == IW_MODE_INFRA) - return HFA384X_PORTTYPE_BSS; - if (local->iw_mode == IW_MODE_REPEAT) - return HFA384X_PORTTYPE_WDS; - if (local->iw_mode == IW_MODE_MONITOR) - return HFA384X_PORTTYPE_PSEUDO_IBSS; - return HFA384X_PORTTYPE_HOSTAP; -} - - -int hostap_set_encryption(local_info_t *local) -{ - u16 val, old_val; - int i, keylen, len, idx; - char keybuf[WEP_KEY_LEN + 1]; - enum { NONE, WEP, OTHER } encrypt_type; - - idx = local->tx_keyidx; - if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL) - encrypt_type = NONE; - else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0) - encrypt_type = WEP; - else - encrypt_type = OTHER; - - if (local->func->get_rid(local->dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, - 1) < 0) { - printk(KERN_DEBUG "Could not read current WEP flags.\n"); - goto fail; - } - le16_to_cpus(&val); - old_val = val; - - if (encrypt_type != NONE || local->privacy_invoked) - val |= HFA384X_WEPFLAGS_PRIVACYINVOKED; - else - val &= ~HFA384X_WEPFLAGS_PRIVACYINVOKED; - - if (local->open_wep || encrypt_type == NONE || - ((local->ieee_802_1x || local->wpa) && local->host_decrypt)) - val &= ~HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED; - else - val |= HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED; - - if ((encrypt_type != NONE || local->privacy_invoked) && - (encrypt_type == OTHER || local->host_encrypt)) - val |= HFA384X_WEPFLAGS_HOSTENCRYPT; - else - val &= ~HFA384X_WEPFLAGS_HOSTENCRYPT; - if ((encrypt_type != NONE || local->privacy_invoked) && - (encrypt_type == OTHER || local->host_decrypt)) - val |= HFA384X_WEPFLAGS_HOSTDECRYPT; - else - val &= ~HFA384X_WEPFLAGS_HOSTDECRYPT; - - if (val != old_val && - hostap_set_word(local->dev, HFA384X_RID_CNFWEPFLAGS, val)) { - printk(KERN_DEBUG "Could not write new WEP flags (0x%x)\n", - val); - goto fail; - } - - if (encrypt_type != WEP) - return 0; - - /* 104-bit support seems to require that all the keys are set to the - * same keylen */ - keylen = 6; /* first 5 octets */ - len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), - NULL, local->crypt[idx]->priv); - if (idx >= 0 && idx < WEP_KEYS && len > 5) - keylen = WEP_KEY_LEN + 1; /* first 13 octets */ - - for (i = 0; i < WEP_KEYS; i++) { - memset(keybuf, 0, sizeof(keybuf)); - if (local->crypt[i]) { - (void) local->crypt[i]->ops->get_key( - keybuf, sizeof(keybuf), - NULL, local->crypt[i]->priv); - } - if (local->func->set_rid(local->dev, - HFA384X_RID_CNFDEFAULTKEY0 + i, - keybuf, keylen)) { - printk(KERN_DEBUG "Could not set key %d (len=%d)\n", - i, keylen); - goto fail; - } - } - if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPDEFAULTKEYID, idx)) { - printk(KERN_DEBUG "Could not set default keyid %d\n", idx); - goto fail; - } - - return 0; - - fail: - printk(KERN_DEBUG "%s: encryption setup failed\n", local->dev->name); - return -1; -} - - -int hostap_set_antsel(local_info_t *local) -{ - u16 val; - int ret = 0; - - if (local->antsel_tx != HOSTAP_ANTSEL_DO_NOT_TOUCH && - local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF, - HFA386X_CR_TX_CONFIGURE, - NULL, &val) == 0) { - val &= ~(BIT(2) | BIT(1)); - switch (local->antsel_tx) { - case HOSTAP_ANTSEL_DIVERSITY: - val |= BIT(1); - break; - case HOSTAP_ANTSEL_LOW: - break; - case HOSTAP_ANTSEL_HIGH: - val |= BIT(2); - break; - } - - if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF, - HFA386X_CR_TX_CONFIGURE, &val, NULL)) { - printk(KERN_INFO "%s: setting TX AntSel failed\n", - local->dev->name); - ret = -1; - } - } - - if (local->antsel_rx != HOSTAP_ANTSEL_DO_NOT_TOUCH && - local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF, - HFA386X_CR_RX_CONFIGURE, - NULL, &val) == 0) { - val &= ~(BIT(1) | BIT(0)); - switch (local->antsel_rx) { - case HOSTAP_ANTSEL_DIVERSITY: - break; - case HOSTAP_ANTSEL_LOW: - val |= BIT(0); - break; - case HOSTAP_ANTSEL_HIGH: - val |= BIT(0) | BIT(1); - break; - } - - if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF, - HFA386X_CR_RX_CONFIGURE, &val, NULL)) { - printk(KERN_INFO "%s: setting RX AntSel failed\n", - local->dev->name); - ret = -1; - } - } - - return ret; -} - - -int hostap_set_roaming(local_info_t *local) -{ - u16 val; - - switch (local->host_roaming) { - case 1: - val = HFA384X_ROAMING_HOST; - break; - case 2: - val = HFA384X_ROAMING_DISABLED; - break; - case 0: - default: - val = HFA384X_ROAMING_FIRMWARE; - break; - } - - return hostap_set_word(local->dev, HFA384X_RID_CNFROAMINGMODE, val); -} - - -int hostap_set_auth_algs(local_info_t *local) -{ - int val = local->auth_algs; - /* At least STA f/w v0.6.2 seems to have issues with cnfAuthentication - * set to include both Open and Shared Key flags. It tries to use - * Shared Key authentication in that case even if WEP keys are not - * configured.. STA f/w v0.7.6 is able to handle such configuration, - * but it is unknown when this was fixed between 0.6.2 .. 0.7.6. */ - if (local->sta_fw_ver < PRISM2_FW_VER(0,7,0) && - val != PRISM2_AUTH_OPEN && val != PRISM2_AUTH_SHARED_KEY) - val = PRISM2_AUTH_OPEN; - - if (hostap_set_word(local->dev, HFA384X_RID_CNFAUTHENTICATION, val)) { - printk(KERN_INFO "%s: cnfAuthentication setting to 0x%x " - "failed\n", local->dev->name, local->auth_algs); - return -EINVAL; - } - - return 0; -} - - -void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx) -{ - u16 status, fc; - - status = __le16_to_cpu(rx->status); - - printk(KERN_DEBUG "%s: RX status=0x%04x (port=%d, type=%d, " - "fcserr=%d) silence=%d signal=%d rate=%d rxflow=%d; " - "jiffies=%ld\n", - name, status, (status >> 8) & 0x07, status >> 13, status & 1, - rx->silence, rx->signal, rx->rate, rx->rxflow, jiffies); - - fc = __le16_to_cpu(rx->frame_control); - printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x " - "data_len=%d%s%s\n", - fc, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc), - __le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl), - __le16_to_cpu(rx->data_len), - fc & WLAN_FC_TODS ? " [ToDS]" : "", - fc & WLAN_FC_FROMDS ? " [FromDS]" : ""); - - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4=" - MACSTR "\n", - MAC2STR(rx->addr1), MAC2STR(rx->addr2), MAC2STR(rx->addr3), - MAC2STR(rx->addr4)); - - printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n", - MAC2STR(rx->dst_addr), MAC2STR(rx->src_addr), - __be16_to_cpu(rx->len)); -} - - -void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) -{ - u16 fc; - - printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d " - "tx_control=0x%04x; jiffies=%ld\n", - name, __le16_to_cpu(tx->status), tx->retry_count, tx->tx_rate, - __le16_to_cpu(tx->tx_control), jiffies); - - fc = __le16_to_cpu(tx->frame_control); - printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x " - "data_len=%d%s%s\n", - fc, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc), - __le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl), - __le16_to_cpu(tx->data_len), - fc & WLAN_FC_TODS ? " [ToDS]" : "", - fc & WLAN_FC_FROMDS ? " [FromDS]" : ""); - - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4=" - MACSTR "\n", - MAC2STR(tx->addr1), MAC2STR(tx->addr2), MAC2STR(tx->addr3), - MAC2STR(tx->addr4)); - - printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n", - MAC2STR(tx->dst_addr), MAC2STR(tx->src_addr), - __be16_to_cpu(tx->len)); -} - - -int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr) -{ - memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); /* addr2 */ - return ETH_ALEN; -} - - -int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr) -{ - if (*(u32 *)skb->mac.raw == LWNG_CAP_DID_BASE) { - memcpy(haddr, skb->mac.raw + - sizeof(struct linux_wlan_ng_prism_hdr) + 10, - ETH_ALEN); /* addr2 */ - } else { /* (*(u32 *)skb->mac.raw == htonl(LWNG_CAPHDR_VERSION)) */ - memcpy(haddr, skb->mac.raw + - sizeof(struct linux_wlan_ng_cap_hdr) + 10, - ETH_ALEN); /* addr2 */ - } - return ETH_ALEN; -} - - -int hostap_80211_get_hdrlen(u16 fc) -{ - int hdrlen = 24; - - switch (HOSTAP_FC_GET_TYPE(fc)) { - case WLAN_FC_TYPE_DATA: - if ((fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS)) - hdrlen = 30; /* Addr4 */ - break; - case WLAN_FC_TYPE_CTRL: - switch (HOSTAP_FC_GET_STYPE(fc)) { - case WLAN_FC_STYPE_CTS: - case WLAN_FC_STYPE_ACK: - hdrlen = 10; - break; - default: - hdrlen = 16; - break; - } - break; - } - - return hdrlen; -} - - -struct net_device_stats *hostap_get_stats(struct net_device *dev) -{ - struct hostap_interface *iface; - iface = netdev_priv(dev); - return &iface->stats; -} - - -static int prism2_close(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - - PDEBUG(DEBUG_FLOW, "%s: prism2_close\n", dev->name); - - iface = netdev_priv(dev); - local = iface->local; - - if (dev == local->ddev) { - prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING); - } -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (!local->hostapd && dev == local->dev && - (!local->func->card_present || local->func->card_present(local)) && - local->hw_ready && local->ap && local->iw_mode == IW_MODE_MASTER) - hostap_deauth_all_stas(dev, local->ap, 1); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - if (local->func->dev_close && local->func->dev_close(local)) - return 0; - - if (dev == local->dev) { - local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL); - } - - if (netif_running(dev)) { - netif_stop_queue(dev); - netif_device_detach(dev); - } - - flush_scheduled_work(); - - module_put(local->hw_module); - - local->num_dev_open--; - - if (dev != local->dev && local->dev->flags & IFF_UP && - local->master_dev_auto_open && local->num_dev_open == 1) { - /* Close master radio interface automatically if it was also - * opened automatically and we are now closing the last - * remaining non-master device. */ - dev_close(local->dev); - } - - return 0; -} - - -static int prism2_open(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - - PDEBUG(DEBUG_FLOW, "%s: prism2_open\n", dev->name); - - iface = netdev_priv(dev); - local = iface->local; - - if (local->no_pri) { - printk(KERN_DEBUG "%s: could not set interface UP - no PRI " - "f/w\n", dev->name); - return 1; - } - - if ((local->func->card_present && !local->func->card_present(local)) || - local->hw_downloading) - return -ENODEV; - - if (local->func->dev_open && local->func->dev_open(local)) - return 1; - - if (!try_module_get(local->hw_module)) - return -ENODEV; - local->num_dev_open++; - - if (!local->dev_enabled && local->func->hw_enable(dev, 1)) { - printk(KERN_WARNING "%s: could not enable MAC port\n", - dev->name); - prism2_close(dev); - return 1; - } - if (!local->dev_enabled) - prism2_callback(local, PRISM2_CALLBACK_ENABLE); - local->dev_enabled = 1; - - if (dev != local->dev && !(local->dev->flags & IFF_UP)) { - /* Master radio interface is needed for all operation, so open - * it automatically when any virtual net_device is opened. */ - local->master_dev_auto_open = 1; - dev_open(local->dev); - } - - netif_device_attach(dev); - netif_start_queue(dev); - - return 0; -} - - -static int prism2_set_mac_address(struct net_device *dev, void *p) -{ - struct hostap_interface *iface; - local_info_t *local; - struct list_head *ptr; - struct sockaddr *addr = p; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->set_rid(dev, HFA384X_RID_CNFOWNMACADDR, addr->sa_data, - ETH_ALEN) < 0 || local->func->reset_port(dev)) - return -EINVAL; - - read_lock_bh(&local->iface_lock); - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - memcpy(iface->dev->dev_addr, addr->sa_data, ETH_ALEN); - } - memcpy(local->dev->dev_addr, addr->sa_data, ETH_ALEN); - read_unlock_bh(&local->iface_lock); - - return 0; -} - - -/* TODO: to be further implemented as soon as Prism2 fully supports - * GroupAddresses and correct documentation is available */ -void hostap_set_multicast_list_queue(void *data) -{ - struct net_device *dev = (struct net_device *) data; - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, - local->is_promisc)) { - printk(KERN_INFO "%s: %sabling promiscuous mode failed\n", - dev->name, local->is_promisc ? "en" : "dis"); - } -} - - -static void hostap_set_multicast_list(struct net_device *dev) -{ -#if 0 - /* FIX: promiscuous mode seems to be causing a lot of problems with - * some station firmware versions (FCSErr frames, invalid MACPort, etc. - * corrupted incoming frames). This code is now commented out while the - * problems are investigated. */ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - if ((dev->flags & IFF_ALLMULTI) || (dev->flags & IFF_PROMISC)) { - local->is_promisc = 1; - } else { - local->is_promisc = 0; - } - - schedule_work(&local->set_multicast_list_queue); -#endif -} - - -static int prism2_change_mtu(struct net_device *dev, int new_mtu) -{ - if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU) - return -EINVAL; - - dev->mtu = new_mtu; - return 0; -} - - -static void prism2_tx_timeout(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hfa384x_regs regs; - - iface = netdev_priv(dev); - local = iface->local; - - printk(KERN_WARNING "%s Tx timed out! Resetting card\n", dev->name); - netif_stop_queue(local->dev); - - local->func->read_regs(dev, ®s); - printk(KERN_DEBUG "%s: CMD=%04x EVSTAT=%04x " - "OFFSET0=%04x OFFSET1=%04x SWSUPPORT0=%04x\n", - dev->name, regs.cmd, regs.evstat, regs.offset0, regs.offset1, - regs.swsupport0); - - local->func->schedule_reset(local); -} - - -void hostap_setup_dev(struct net_device *dev, local_info_t *local, - int main_dev) -{ - struct hostap_interface *iface; - - iface = netdev_priv(dev); - ether_setup(dev); - - /* kernel callbacks */ - dev->get_stats = hostap_get_stats; - if (iface) { - /* Currently, we point to the proper spy_data only on - * the main_dev. This could be fixed. Jean II */ - iface->wireless_data.spy_data = &iface->spy_data; - dev->wireless_data = &iface->wireless_data; - } - dev->wireless_handlers = - (struct iw_handler_def *) &hostap_iw_handler_def; - dev->do_ioctl = hostap_ioctl; - dev->open = prism2_open; - dev->stop = prism2_close; - dev->hard_start_xmit = hostap_data_start_xmit; - dev->set_mac_address = prism2_set_mac_address; - dev->set_multicast_list = hostap_set_multicast_list; - dev->change_mtu = prism2_change_mtu; - dev->tx_timeout = prism2_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; - - dev->mtu = local->mtu; - if (!main_dev) { - /* use main radio device queue */ - dev->tx_queue_len = 0; - } - - SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops); - - netif_stop_queue(dev); -} - - -static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked) -{ - struct net_device *dev = local->dev; - - if (local->apdev) - return -EEXIST; - - printk(KERN_DEBUG "%s: enabling hostapd mode\n", dev->name); - - local->apdev = hostap_add_interface(local, HOSTAP_INTERFACE_AP, - rtnl_locked, local->ddev->name, - "ap"); - if (local->apdev == NULL) - return -ENOMEM; - - local->apdev->hard_start_xmit = hostap_mgmt_start_xmit; - local->apdev->type = ARPHRD_IEEE80211; - local->apdev->hard_header_parse = hostap_80211_header_parse; - - return 0; -} - - -static int hostap_disable_hostapd(local_info_t *local, int rtnl_locked) -{ - struct net_device *dev = local->dev; - - printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name); - - hostap_remove_interface(local->apdev, rtnl_locked, 1); - local->apdev = NULL; - - return 0; -} - - -static int hostap_enable_hostapd_sta(local_info_t *local, int rtnl_locked) -{ - struct net_device *dev = local->dev; - - if (local->stadev) - return -EEXIST; - - printk(KERN_DEBUG "%s: enabling hostapd STA mode\n", dev->name); - - local->stadev = hostap_add_interface(local, HOSTAP_INTERFACE_STA, - rtnl_locked, local->ddev->name, - "sta"); - if (local->stadev == NULL) - return -ENOMEM; - - return 0; -} - - -static int hostap_disable_hostapd_sta(local_info_t *local, int rtnl_locked) -{ - struct net_device *dev = local->dev; - - printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name); - - hostap_remove_interface(local->stadev, rtnl_locked, 1); - local->stadev = NULL; - - return 0; -} - - -int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked) -{ - int ret; - - if (val < 0 || val > 1) - return -EINVAL; - - if (local->hostapd == val) - return 0; - - if (val) { - ret = hostap_enable_hostapd(local, rtnl_locked); - if (ret == 0) - local->hostapd = 1; - } else { - local->hostapd = 0; - ret = hostap_disable_hostapd(local, rtnl_locked); - if (ret != 0) - local->hostapd = 1; - } - - return ret; -} - - -int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked) -{ - int ret; - - if (val < 0 || val > 1) - return -EINVAL; - - if (local->hostapd_sta == val) - return 0; - - if (val) { - ret = hostap_enable_hostapd_sta(local, rtnl_locked); - if (ret == 0) - local->hostapd_sta = 1; - } else { - local->hostapd_sta = 0; - ret = hostap_disable_hostapd_sta(local, rtnl_locked); - if (ret != 0) - local->hostapd_sta = 1; - } - - - return ret; -} - - -int prism2_update_comms_qual(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - int ret = 0; - struct hfa384x_comms_quality sq; - - iface = netdev_priv(dev); - local = iface->local; - if (!local->sta_fw_ver) - ret = -1; - else if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) { - if (local->func->get_rid(local->dev, - HFA384X_RID_DBMCOMMSQUALITY, - &sq, sizeof(sq), 1) >= 0) { - local->comms_qual = (s16) le16_to_cpu(sq.comm_qual); - local->avg_signal = (s16) le16_to_cpu(sq.signal_level); - local->avg_noise = (s16) le16_to_cpu(sq.noise_level); - local->last_comms_qual_update = jiffies; - } else - ret = -1; - } else { - if (local->func->get_rid(local->dev, HFA384X_RID_COMMSQUALITY, - &sq, sizeof(sq), 1) >= 0) { - local->comms_qual = le16_to_cpu(sq.comm_qual); - local->avg_signal = HFA384X_LEVEL_TO_dBm( - le16_to_cpu(sq.signal_level)); - local->avg_noise = HFA384X_LEVEL_TO_dBm( - le16_to_cpu(sq.noise_level)); - local->last_comms_qual_update = jiffies; - } else - ret = -1; - } - - return ret; -} - - -int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u8 stype, - u8 *body, size_t bodylen) -{ - struct sk_buff *skb; - struct hostap_ieee80211_mgmt *mgmt; - struct hostap_skb_tx_data *meta; - struct net_device *dev = local->dev; - - skb = dev_alloc_skb(IEEE80211_MGMT_HDR_LEN + bodylen); - if (skb == NULL) - return -ENOMEM; - - mgmt = (struct hostap_ieee80211_mgmt *) - skb_put(skb, IEEE80211_MGMT_HDR_LEN); - memset(mgmt, 0, IEEE80211_MGMT_HDR_LEN); - mgmt->frame_control = - cpu_to_le16((WLAN_FC_TYPE_MGMT << 2) | (stype << 4)); - memcpy(mgmt->da, dst, ETH_ALEN); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - memcpy(mgmt->bssid, dst, ETH_ALEN); - if (body) - memcpy(skb_put(skb, bodylen), body, bodylen); - - meta = (struct hostap_skb_tx_data *) skb->cb; - memset(meta, 0, sizeof(*meta)); - meta->magic = HOSTAP_SKB_TX_DATA_MAGIC; - meta->iface = netdev_priv(dev); - - skb->dev = dev; - skb->mac.raw = skb->nh.raw = skb->data; - dev_queue_xmit(skb); - - return 0; -} - - -int prism2_sta_deauth(local_info_t *local, u16 reason) -{ - union iwreq_data wrqu; - int ret; - - if (local->iw_mode != IW_MODE_INFRA || - memcmp(local->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 || - memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0) - return 0; - - reason = cpu_to_le16(reason); - ret = prism2_sta_send_mgmt(local, local->bssid, WLAN_FC_STYPE_DEAUTH, - (u8 *) &reason, 2); - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); - return ret; -} - - -struct proc_dir_entry *hostap_proc; - -static int __init hostap_init(void) -{ - if (proc_net != NULL) { - hostap_proc = proc_mkdir("hostap", proc_net); - if (!hostap_proc) - printk(KERN_WARNING "Failed to mkdir " - "/proc/net/hostap\n"); - } else - hostap_proc = NULL; - - return 0; -} - - -static void __exit hostap_exit(void) -{ - if (hostap_proc != NULL) { - hostap_proc = NULL; - remove_proc_entry("hostap", proc_net); - } -} - - -EXPORT_SYMBOL(hostap_set_word); -EXPORT_SYMBOL(hostap_set_string); -EXPORT_SYMBOL(hostap_get_porttype); -EXPORT_SYMBOL(hostap_set_encryption); -EXPORT_SYMBOL(hostap_set_antsel); -EXPORT_SYMBOL(hostap_set_roaming); -EXPORT_SYMBOL(hostap_set_auth_algs); -EXPORT_SYMBOL(hostap_dump_rx_header); -EXPORT_SYMBOL(hostap_dump_tx_header); -EXPORT_SYMBOL(hostap_80211_header_parse); -EXPORT_SYMBOL(hostap_80211_prism_header_parse); -EXPORT_SYMBOL(hostap_80211_get_hdrlen); -EXPORT_SYMBOL(hostap_get_stats); -EXPORT_SYMBOL(hostap_setup_dev); -EXPORT_SYMBOL(hostap_proc); -EXPORT_SYMBOL(hostap_set_multicast_list_queue); -EXPORT_SYMBOL(hostap_set_hostapd); -EXPORT_SYMBOL(hostap_set_hostapd_sta); -EXPORT_SYMBOL(hostap_add_interface); -EXPORT_SYMBOL(hostap_remove_interface); -EXPORT_SYMBOL(prism2_update_comms_qual); - -module_init(hostap_init); -module_exit(hostap_exit); diff --git a/trunk/drivers/net/wireless/hostap/hostap.h b/trunk/drivers/net/wireless/hostap/hostap.h deleted file mode 100644 index 2ddcf5fc59c3..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef HOSTAP_H -#define HOSTAP_H - -/* hostap.c */ - -extern struct proc_dir_entry *hostap_proc; - -u16 hostap_tx_callback_register(local_info_t *local, - void (*func)(struct sk_buff *, int ok, void *), - void *data); -int hostap_tx_callback_unregister(local_info_t *local, u16 idx); -int hostap_set_word(struct net_device *dev, int rid, u16 val); -int hostap_set_string(struct net_device *dev, int rid, const char *val); -u16 hostap_get_porttype(local_info_t *local); -int hostap_set_encryption(local_info_t *local); -int hostap_set_antsel(local_info_t *local); -int hostap_set_roaming(local_info_t *local); -int hostap_set_auth_algs(local_info_t *local); -void hostap_dump_rx_header(const char *name, - const struct hfa384x_rx_frame *rx); -void hostap_dump_tx_header(const char *name, - const struct hfa384x_tx_frame *tx); -int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr); -int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr); -int hostap_80211_get_hdrlen(u16 fc); -struct net_device_stats *hostap_get_stats(struct net_device *dev); -void hostap_setup_dev(struct net_device *dev, local_info_t *local, - int main_dev); -void hostap_set_multicast_list_queue(void *data); -int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked); -int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked); -void hostap_cleanup(local_info_t *local); -void hostap_cleanup_handler(void *data); -struct net_device * hostap_add_interface(struct local_info *local, - int type, int rtnl_locked, - const char *prefix, const char *name); -void hostap_remove_interface(struct net_device *dev, int rtnl_locked, - int remove_from_list); -int prism2_update_comms_qual(struct net_device *dev); -int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u8 stype, - u8 *body, size_t bodylen); -int prism2_sta_deauth(local_info_t *local, u16 reason); - - -/* hostap_proc.c */ - -void hostap_init_proc(local_info_t *local); -void hostap_remove_proc(local_info_t *local); - - -/* hostap_info.c */ - -void hostap_info_init(local_info_t *local); -void hostap_info_process(local_info_t *local, struct sk_buff *skb); - - -#endif /* HOSTAP_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211.h b/trunk/drivers/net/wireless/hostap/hostap_80211.h deleted file mode 100644 index f3ad3445c72e..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_80211.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef HOSTAP_80211_H -#define HOSTAP_80211_H - -struct hostap_ieee80211_hdr { - u16 frame_control; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; - u8 addr4[6]; -} __attribute__ ((packed)); - - -struct hostap_ieee80211_mgmt { - u16 frame_control; - u16 duration; - u8 da[6]; - u8 sa[6]; - u8 bssid[6]; - u16 seq_ctrl; - union { - struct { - u16 auth_alg; - u16 auth_transaction; - u16 status_code; - /* possibly followed by Challenge text */ - u8 variable[0]; - } __attribute__ ((packed)) auth; - struct { - u16 reason_code; - } __attribute__ ((packed)) deauth; - struct { - u16 capab_info; - u16 listen_interval; - /* followed by SSID and Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) assoc_req; - struct { - u16 capab_info; - u16 status_code; - u16 aid; - /* followed by Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) assoc_resp, reassoc_resp; - struct { - u16 capab_info; - u16 listen_interval; - u8 current_ap[6]; - /* followed by SSID and Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) reassoc_req; - struct { - u16 reason_code; - } __attribute__ ((packed)) disassoc; - struct { - } __attribute__ ((packed)) probe_req; - struct { - u8 timestamp[8]; - u16 beacon_int; - u16 capab_info; - /* followed by some of SSID, Supported rates, - * FH Params, DS Params, CF Params, IBSS Params, TIM */ - u8 variable[0]; - } __attribute__ ((packed)) beacon, probe_resp; - } u; -} __attribute__ ((packed)); - - -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - - -struct hostap_80211_rx_status { - u32 mac_time; - u8 signal; - u8 noise; - u16 rate; /* in 100 kbps */ -}; - - -void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats); - - -/* prism2_rx_80211 'type' argument */ -enum { - PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC, - PRISM2_RX_NULLFUNC_ACK -}; - -int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats, int type); -void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats); -void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats); - -void hostap_dump_tx_80211(const char *name, struct sk_buff *skb); -int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); -int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); -struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct ieee80211_crypt_data *crypt); -int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); - -#endif /* HOSTAP_80211_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c deleted file mode 100644 index f4ca1e88f314..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c +++ /dev/null @@ -1,1084 +0,0 @@ -#include - -#include "hostap_80211.h" -#include "hostap.h" - -void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct hostap_ieee80211_hdr *hdr; - u16 fc; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - - printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d " - "jiffies=%ld\n", - name, rx_stats->signal, rx_stats->noise, rx_stats->rate, - skb->len, jiffies); - - if (skb->len < 2) - return; - - fc = le16_to_cpu(hdr->frame_control); - printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s", - fc, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc), - fc & WLAN_FC_TODS ? " [ToDS]" : "", - fc & WLAN_FC_FROMDS ? " [FromDS]" : ""); - - if (skb->len < IEEE80211_DATA_HDR3_LEN) { - printk("\n"); - return; - } - - printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id), - le16_to_cpu(hdr->seq_ctrl)); - - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR, - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); - if (skb->len >= 30) - printk(" A4=" MACSTR, MAC2STR(hdr->addr4)); - printk("\n"); -} - - -/* Send RX frame to netif with 802.11 (and possible prism) header. - * Called from hardware or software IRQ context. */ -int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats, int type) -{ - struct hostap_interface *iface; - local_info_t *local; - int hdrlen, phdrlen, head_need, tail_need; - u16 fc; - int prism_header, ret; - struct hostap_ieee80211_hdr *hdr; - - iface = netdev_priv(dev); - local = iface->local; - dev->last_rx = jiffies; - - if (dev->type == ARPHRD_IEEE80211_PRISM) { - if (local->monitor_type == PRISM2_MONITOR_PRISM) { - prism_header = 1; - phdrlen = sizeof(struct linux_wlan_ng_prism_hdr); - } else { /* local->monitor_type == PRISM2_MONITOR_CAPHDR */ - prism_header = 2; - phdrlen = sizeof(struct linux_wlan_ng_cap_hdr); - } - } else { - prism_header = 0; - phdrlen = 0; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - if (type == PRISM2_RX_MGMT && (fc & WLAN_FC_PVER)) { - printk(KERN_DEBUG "%s: dropped management frame with header " - "version %d\n", dev->name, fc & WLAN_FC_PVER); - dev_kfree_skb_any(skb); - return 0; - } - - hdrlen = hostap_80211_get_hdrlen(fc); - - /* check if there is enough room for extra data; if not, expand skb - * buffer to be large enough for the changes */ - head_need = phdrlen; - tail_need = 0; -#ifdef PRISM2_ADD_BOGUS_CRC - tail_need += 4; -#endif /* PRISM2_ADD_BOGUS_CRC */ - - head_need -= skb_headroom(skb); - tail_need -= skb_tailroom(skb); - - if (head_need > 0 || tail_need > 0) { - if (pskb_expand_head(skb, head_need > 0 ? head_need : 0, - tail_need > 0 ? tail_need : 0, - GFP_ATOMIC)) { - printk(KERN_DEBUG "%s: prism2_rx_80211 failed to " - "reallocate skb buffer\n", dev->name); - dev_kfree_skb_any(skb); - return 0; - } - } - - /* We now have an skb with enough head and tail room, so just insert - * the extra data */ - -#ifdef PRISM2_ADD_BOGUS_CRC - memset(skb_put(skb, 4), 0xff, 4); /* Prism2 strips CRC */ -#endif /* PRISM2_ADD_BOGUS_CRC */ - - if (prism_header == 1) { - struct linux_wlan_ng_prism_hdr *hdr; - hdr = (struct linux_wlan_ng_prism_hdr *) - skb_push(skb, phdrlen); - memset(hdr, 0, phdrlen); - hdr->msgcode = LWNG_CAP_DID_BASE; - hdr->msglen = sizeof(*hdr); - memcpy(hdr->devname, dev->name, sizeof(hdr->devname)); -#define LWNG_SETVAL(f,i,s,l,d) \ -hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \ -hdr->f.status = s; hdr->f.len = l; hdr->f.data = d - LWNG_SETVAL(hosttime, 1, 0, 4, jiffies); - LWNG_SETVAL(mactime, 2, 0, 4, rx_stats->mac_time); - LWNG_SETVAL(channel, 3, 1 /* no value */, 4, 0); - LWNG_SETVAL(rssi, 4, 1 /* no value */, 4, 0); - LWNG_SETVAL(sq, 5, 1 /* no value */, 4, 0); - LWNG_SETVAL(signal, 6, 0, 4, rx_stats->signal); - LWNG_SETVAL(noise, 7, 0, 4, rx_stats->noise); - LWNG_SETVAL(rate, 8, 0, 4, rx_stats->rate / 5); - LWNG_SETVAL(istx, 9, 0, 4, 0); - LWNG_SETVAL(frmlen, 10, 0, 4, skb->len - phdrlen); -#undef LWNG_SETVAL - } else if (prism_header == 2) { - struct linux_wlan_ng_cap_hdr *hdr; - hdr = (struct linux_wlan_ng_cap_hdr *) - skb_push(skb, phdrlen); - memset(hdr, 0, phdrlen); - hdr->version = htonl(LWNG_CAPHDR_VERSION); - hdr->length = htonl(phdrlen); - hdr->mactime = __cpu_to_be64(rx_stats->mac_time); - hdr->hosttime = __cpu_to_be64(jiffies); - hdr->phytype = htonl(4); /* dss_dot11_b */ - hdr->channel = htonl(local->channel); - hdr->datarate = htonl(rx_stats->rate); - hdr->antenna = htonl(0); /* unknown */ - hdr->priority = htonl(0); /* unknown */ - hdr->ssi_type = htonl(3); /* raw */ - hdr->ssi_signal = htonl(rx_stats->signal); - hdr->ssi_noise = htonl(rx_stats->noise); - hdr->preamble = htonl(0); /* unknown */ - hdr->encoding = htonl(1); /* cck */ - } - - ret = skb->len - phdrlen; - skb->dev = dev; - skb->mac.raw = skb->data; - skb_pull(skb, hdrlen); - if (prism_header) - skb_pull(skb, phdrlen); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = __constant_htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - - return ret; -} - - -/* Called only as a tasklet (software IRQ) */ -static void monitor_rx(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct net_device_stats *stats; - int len; - - len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR); - stats = hostap_get_stats(dev); - stats->rx_packets++; - stats->rx_bytes += len; -} - - -/* Called only as a tasklet (software IRQ) */ -static struct prism2_frag_entry * -prism2_frag_cache_find(local_info_t *local, unsigned int seq, - unsigned int frag, u8 *src, u8 *dst) -{ - struct prism2_frag_entry *entry; - int i; - - for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) { - entry = &local->frag_cache[i]; - if (entry->skb != NULL && - time_after(jiffies, entry->first_frag_time + 2 * HZ)) { - printk(KERN_DEBUG "%s: expiring fragment cache entry " - "seq=%u last_frag=%u\n", - local->dev->name, entry->seq, entry->last_frag); - dev_kfree_skb(entry->skb); - entry->skb = NULL; - } - - if (entry->skb != NULL && entry->seq == seq && - (entry->last_frag + 1 == frag || frag == -1) && - memcmp(entry->src_addr, src, ETH_ALEN) == 0 && - memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) - return entry; - } - - return NULL; -} - - -/* Called only as a tasklet (software IRQ) */ -static struct sk_buff * -prism2_frag_cache_get(local_info_t *local, struct hostap_ieee80211_hdr *hdr) -{ - struct sk_buff *skb = NULL; - u16 sc; - unsigned int frag, seq; - struct prism2_frag_entry *entry; - - sc = le16_to_cpu(hdr->seq_ctrl); - frag = WLAN_GET_SEQ_FRAG(sc); - seq = WLAN_GET_SEQ_SEQ(sc) >> 4; - - if (frag == 0) { - /* Reserve enough space to fit maximum frame length */ - skb = dev_alloc_skb(local->dev->mtu + - sizeof(struct hostap_ieee80211_hdr) + - 8 /* LLC */ + - 2 /* alignment */ + - 8 /* WEP */ + ETH_ALEN /* WDS */); - if (skb == NULL) - return NULL; - - entry = &local->frag_cache[local->frag_next_idx]; - local->frag_next_idx++; - if (local->frag_next_idx >= PRISM2_FRAG_CACHE_LEN) - local->frag_next_idx = 0; - - if (entry->skb != NULL) - dev_kfree_skb(entry->skb); - - entry->first_frag_time = jiffies; - entry->seq = seq; - entry->last_frag = frag; - entry->skb = skb; - memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); - memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); - } else { - /* received a fragment of a frame for which the head fragment - * should have already been received */ - entry = prism2_frag_cache_find(local, seq, frag, hdr->addr2, - hdr->addr1); - if (entry != NULL) { - entry->last_frag = frag; - skb = entry->skb; - } - } - - return skb; -} - - -/* Called only as a tasklet (software IRQ) */ -static int prism2_frag_cache_invalidate(local_info_t *local, - struct hostap_ieee80211_hdr *hdr) -{ - u16 sc; - unsigned int seq; - struct prism2_frag_entry *entry; - - sc = le16_to_cpu(hdr->seq_ctrl); - seq = WLAN_GET_SEQ_SEQ(sc) >> 4; - - entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1); - - if (entry == NULL) { - printk(KERN_DEBUG "%s: could not invalidate fragment cache " - "entry (seq=%u)\n", - local->dev->name, seq); - return -1; - } - - entry->skb = NULL; - return 0; -} - - -static struct hostap_bss_info *__hostap_get_bss(local_info_t *local, u8 *bssid, - u8 *ssid, size_t ssid_len) -{ - struct list_head *ptr; - struct hostap_bss_info *bss; - - list_for_each(ptr, &local->bss_list) { - bss = list_entry(ptr, struct hostap_bss_info, list); - if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 && - (ssid == NULL || - (ssid_len == bss->ssid_len && - memcmp(ssid, bss->ssid, ssid_len) == 0))) { - list_move(&bss->list, &local->bss_list); - return bss; - } - } - - return NULL; -} - - -static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid, - u8 *ssid, size_t ssid_len) -{ - struct hostap_bss_info *bss; - - if (local->num_bss_info >= HOSTAP_MAX_BSS_COUNT) { - bss = list_entry(local->bss_list.prev, - struct hostap_bss_info, list); - list_del(&bss->list); - local->num_bss_info--; - } else { - bss = (struct hostap_bss_info *) - kmalloc(sizeof(*bss), GFP_ATOMIC); - if (bss == NULL) - return NULL; - } - - memset(bss, 0, sizeof(*bss)); - memcpy(bss->bssid, bssid, ETH_ALEN); - memcpy(bss->ssid, ssid, ssid_len); - bss->ssid_len = ssid_len; - local->num_bss_info++; - list_add(&bss->list, &local->bss_list); - return bss; -} - - -static void __hostap_expire_bss(local_info_t *local) -{ - struct hostap_bss_info *bss; - - while (local->num_bss_info > 0) { - bss = list_entry(local->bss_list.prev, - struct hostap_bss_info, list); - if (!time_after(jiffies, bss->last_update + 60 * HZ)) - break; - - list_del(&bss->list); - local->num_bss_info--; - kfree(bss); - } -} - - -/* Both IEEE 802.11 Beacon and Probe Response frames have similar structure, so - * the same routine can be used to parse both of them. */ -static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb, - int stype) -{ - struct hostap_ieee80211_mgmt *mgmt; - int left, chan = 0; - u8 *pos; - u8 *ssid = NULL, *wpa = NULL, *rsn = NULL; - size_t ssid_len = 0, wpa_len = 0, rsn_len = 0; - struct hostap_bss_info *bss; - - if (skb->len < IEEE80211_MGMT_HDR_LEN + sizeof(mgmt->u.beacon)) - return; - - mgmt = (struct hostap_ieee80211_mgmt *) skb->data; - pos = mgmt->u.beacon.variable; - left = skb->len - (pos - skb->data); - - while (left >= 2) { - if (2 + pos[1] > left) - return; /* parse failed */ - switch (*pos) { - case WLAN_EID_SSID: - ssid = pos + 2; - ssid_len = pos[1]; - break; - case WLAN_EID_GENERIC: - if (pos[1] >= 4 && - pos[2] == 0x00 && pos[3] == 0x50 && - pos[4] == 0xf2 && pos[5] == 1) { - wpa = pos; - wpa_len = pos[1] + 2; - } - break; - case WLAN_EID_RSN: - rsn = pos; - rsn_len = pos[1] + 2; - break; - case WLAN_EID_DS_PARAMS: - if (pos[1] >= 1) - chan = pos[2]; - break; - } - left -= 2 + pos[1]; - pos += 2 + pos[1]; - } - - if (wpa_len > MAX_WPA_IE_LEN) - wpa_len = MAX_WPA_IE_LEN; - if (rsn_len > MAX_WPA_IE_LEN) - rsn_len = MAX_WPA_IE_LEN; - if (ssid_len > sizeof(bss->ssid)) - ssid_len = sizeof(bss->ssid); - - spin_lock(&local->lock); - bss = __hostap_get_bss(local, mgmt->bssid, ssid, ssid_len); - if (bss == NULL) - bss = __hostap_add_bss(local, mgmt->bssid, ssid, ssid_len); - if (bss) { - bss->last_update = jiffies; - bss->count++; - bss->capab_info = le16_to_cpu(mgmt->u.beacon.capab_info); - if (wpa) { - memcpy(bss->wpa_ie, wpa, wpa_len); - bss->wpa_ie_len = wpa_len; - } else - bss->wpa_ie_len = 0; - if (rsn) { - memcpy(bss->rsn_ie, rsn, rsn_len); - bss->rsn_ie_len = rsn_len; - } else - bss->rsn_ie_len = 0; - bss->chan = chan; - } - __hostap_expire_bss(local); - spin_unlock(&local->lock); -} - - -static inline int -hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats, u16 type, - u16 stype) -{ - if (local->iw_mode == IW_MODE_MASTER) { - hostap_update_sta_ps(local, (struct hostap_ieee80211_hdr *) - skb->data); - } - - if (local->hostapd && type == WLAN_FC_TYPE_MGMT) { - if (stype == WLAN_FC_STYPE_BEACON && - local->iw_mode == IW_MODE_MASTER) { - struct sk_buff *skb2; - /* Process beacon frames also in kernel driver to - * update STA(AP) table statistics */ - skb2 = skb_clone(skb, GFP_ATOMIC); - if (skb2) - hostap_rx(skb2->dev, skb2, rx_stats); - } - - /* send management frames to the user space daemon for - * processing */ - local->apdevstats.rx_packets++; - local->apdevstats.rx_bytes += skb->len; - if (local->apdev == NULL) - return -1; - prism2_rx_80211(local->apdev, skb, rx_stats, PRISM2_RX_MGMT); - return 0; - } - - if (local->iw_mode == IW_MODE_MASTER) { - if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) { - printk(KERN_DEBUG "%s: unknown management frame " - "(type=0x%02x, stype=0x%02x) dropped\n", - skb->dev->name, type, stype); - return -1; - } - - hostap_rx(skb->dev, skb, rx_stats); - return 0; - } else if (type == WLAN_FC_TYPE_MGMT && - (stype == WLAN_FC_STYPE_BEACON || - stype == WLAN_FC_STYPE_PROBE_RESP)) { - hostap_rx_sta_beacon(local, skb, stype); - return -1; - } else if (type == WLAN_FC_TYPE_MGMT && - (stype == WLAN_FC_STYPE_ASSOC_RESP || - stype == WLAN_FC_STYPE_REASSOC_RESP)) { - /* Ignore (Re)AssocResp silently since these are not currently - * needed but are still received when WPA/RSN mode is enabled. - */ - return -1; - } else { - printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: dropped unhandled" - " management frame in non-Host AP mode (type=%d:%d)\n", - skb->dev->name, type, stype); - return -1; - } -} - - -/* Called only as a tasklet (software IRQ) */ -static inline struct net_device *prism2_rx_get_wds(local_info_t *local, - u8 *addr) -{ - struct hostap_interface *iface = NULL; - struct list_head *ptr; - - read_lock_bh(&local->iface_lock); - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - if (iface->type == HOSTAP_INTERFACE_WDS && - memcmp(iface->u.wds.remote_addr, addr, ETH_ALEN) == 0) - break; - iface = NULL; - } - read_unlock_bh(&local->iface_lock); - - return iface ? iface->dev : NULL; -} - - -static inline int -hostap_rx_frame_wds(local_info_t *local, struct hostap_ieee80211_hdr *hdr, - u16 fc, struct net_device **wds) -{ - /* FIX: is this really supposed to accept WDS frames only in Master - * mode? What about Repeater or Managed with WDS frames? */ - if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) != - (WLAN_FC_TODS | WLAN_FC_FROMDS) && - (local->iw_mode != IW_MODE_MASTER || !(fc & WLAN_FC_TODS))) - return 0; /* not a WDS frame */ - - /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS) - * or own non-standard frame with 4th address after payload */ - if (memcmp(hdr->addr1, local->dev->dev_addr, ETH_ALEN) != 0 && - (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff || - hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || - hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { - /* RA (or BSSID) is not ours - drop */ - PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with " - "not own or broadcast %s=" MACSTR "\n", - local->dev->name, fc & WLAN_FC_FROMDS ? "RA" : "BSSID", - MAC2STR(hdr->addr1)); - return -1; - } - - /* check if the frame came from a registered WDS connection */ - *wds = prism2_rx_get_wds(local, hdr->addr2); - if (*wds == NULL && fc & WLAN_FC_FROMDS && - (local->iw_mode != IW_MODE_INFRA || - !(local->wds_type & HOSTAP_WDS_AP_CLIENT) || - memcmp(hdr->addr2, local->bssid, ETH_ALEN) != 0)) { - /* require that WDS link has been registered with TA or the - * frame is from current AP when using 'AP client mode' */ - PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame " - "from unknown TA=" MACSTR "\n", - local->dev->name, MAC2STR(hdr->addr2)); - if (local->ap && local->ap->autom_ap_wds) - hostap_wds_link_oper(local, hdr->addr2, WDS_ADD); - return -1; - } - - if (*wds && !(fc & WLAN_FC_FROMDS) && local->ap && - hostap_is_sta_assoc(local->ap, hdr->addr2)) { - /* STA is actually associated with us even though it has a - * registered WDS link. Assume it is in 'AP client' mode. - * Since this is a 3-addr frame, assume it is not (bogus) WDS - * frame and process it like any normal ToDS frame from - * associated STA. */ - *wds = NULL; - } - - return 0; -} - - -static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb) -{ - struct net_device *dev = local->dev; - u16 fc, ethertype; - struct hostap_ieee80211_hdr *hdr; - u8 *pos; - - if (skb->len < 24) - return 0; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - /* check that the frame is unicast frame to us */ - if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_TODS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && - memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { - /* ToDS frame with own addr BSSID and DA */ - } else if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_FROMDS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - /* FromDS frame with own addr as DA */ - } else - return 0; - - if (skb->len < 24 + 8) - return 0; - - /* check for port access entity Ethernet type */ - pos = skb->data + 24; - ethertype = (pos[6] << 8) | pos[7]; - if (ethertype == ETH_P_PAE) - return 1; - - return 0; -} - - -/* Called only as a tasklet (software IRQ) */ -static inline int -hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) -{ - struct hostap_ieee80211_hdr *hdr; - int res, hdrlen; - - if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) - return 0; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); - - if (local->tkip_countermeasures && - strcmp(crypt->ops->name, "TKIP") == 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from " MACSTR "\n", - local->dev->name, MAC2STR(hdr->addr2)); - } - return -1; - } - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR - ") res=%d\n", - local->dev->name, MAC2STR(hdr->addr2), res); - local->comm_tallies.rx_discards_wep_undecryptable++; - return -1; - } - - return res; -} - - -/* Called only as a tasklet (software IRQ) */ -static inline int -hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, - int keyidx, struct ieee80211_crypt_data *crypt) -{ - struct hostap_ieee80211_hdr *hdr; - int res, hdrlen; - - if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) - return 0; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MACSTR " keyidx=%d)\n", - local->dev->name, MAC2STR(hdr->addr2), keyidx); - return -1; - } - - return 0; -} - - -/* All received frames are sent to this function. @skb contains the frame in - * IEEE 802.11 format, i.e., in the format it was sent over air. - * This function is called only as a tasklet (software IRQ). */ -void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hostap_ieee80211_hdr *hdr; - size_t hdrlen; - u16 fc, type, stype, sc; - struct net_device *wds = NULL; - struct net_device_stats *stats; - unsigned int frag; - u8 *payload; - struct sk_buff *skb2 = NULL; - u16 ethertype; - int frame_authorized = 0; - int from_assoc_ap = 0; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - struct ieee80211_crypt_data *crypt = NULL; - void *sta = NULL; - int keyidx = 0; - - iface = netdev_priv(dev); - local = iface->local; - iface->stats.rx_packets++; - iface->stats.rx_bytes += skb->len; - - /* dev is the master radio device; change this to be the default - * virtual interface (this may be changed to WDS device below) */ - dev = local->ddev; - iface = netdev_priv(dev); - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - stats = hostap_get_stats(dev); - - if (skb->len < 10) - goto rx_dropped; - - fc = le16_to_cpu(hdr->frame_control); - type = HOSTAP_FC_GET_TYPE(fc); - stype = HOSTAP_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctrl); - frag = WLAN_GET_SEQ_FRAG(sc); - hdrlen = hostap_80211_get_hdrlen(fc); - - /* Put this code here so that we avoid duplicating it in all - * Rx paths. - Jean II */ -#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ - /* If spy monitoring on */ - if (iface->spy_data.spy_number > 0) { - struct iw_quality wstats; - wstats.level = rx_stats->signal; - wstats.noise = rx_stats->noise; - wstats.updated = 6; /* No qual value */ - /* Update spy records */ - wireless_spy_update(dev, hdr->addr2, &wstats); - } -#endif /* IW_WIRELESS_SPY */ - hostap_update_rx_stats(local->ap, hdr, rx_stats); - - if (local->iw_mode == IW_MODE_MONITOR) { - monitor_rx(dev, skb, rx_stats); - return; - } - - if (local->host_decrypt) { - int idx = 0; - if (skb->len >= hdrlen + 3) - idx = skb->data[hdrlen + 3] >> 6; - crypt = local->crypt[idx]; - sta = NULL; - - /* Use station specific key to override default keys if the - * receiver address is a unicast address ("individual RA"). If - * bcrx_sta_key parameter is set, station specific key is used - * even with broad/multicast targets (this is against IEEE - * 802.11, but makes it easier to use different keys with - * stations that do not support WEP key mapping). */ - - if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) - (void) hostap_handle_sta_crypto(local, hdr, &crypt, - &sta); - - /* allow NULL decrypt to indicate an station specific override - * for default encryption */ - if (crypt && (crypt->ops == NULL || - crypt->ops->decrypt_mpdu == NULL)) - crypt = NULL; - - if (!crypt && (fc & WLAN_FC_ISWEP)) { -#if 0 - /* This seems to be triggered by some (multicast?) - * frames from other than current BSS, so just drop the - * frames silently instead of filling system log with - * these reports. */ - printk(KERN_DEBUG "%s: WEP decryption failed (not set)" - " (SA=" MACSTR ")\n", - local->dev->name, MAC2STR(hdr->addr2)); -#endif - local->comm_tallies.rx_discards_wep_undecryptable++; - goto rx_dropped; - } - } - - if (type != WLAN_FC_TYPE_DATA) { - if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH && - fc & WLAN_FC_ISWEP && local->host_decrypt && - (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0) - { - printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " - "from " MACSTR "\n", dev->name, - MAC2STR(hdr->addr2)); - /* TODO: could inform hostapd about this so that it - * could send auth failure report */ - goto rx_dropped; - } - - if (hostap_rx_frame_mgmt(local, skb, rx_stats, type, stype)) - goto rx_dropped; - else - goto rx_exit; - } - - /* Data frame - extract src/dst addresses */ - if (skb->len < IEEE80211_DATA_HDR3_LEN) - goto rx_dropped; - - switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { - case WLAN_FC_FROMDS: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr3, ETH_ALEN); - break; - case WLAN_FC_TODS: - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - break; - case WLAN_FC_FROMDS | WLAN_FC_TODS: - if (skb->len < IEEE80211_DATA_HDR4_LEN) - goto rx_dropped; - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr4, ETH_ALEN); - break; - case 0: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - break; - } - - if (hostap_rx_frame_wds(local, hdr, fc, &wds)) - goto rx_dropped; - if (wds) { - skb->dev = dev = wds; - stats = hostap_get_stats(dev); - } - - if (local->iw_mode == IW_MODE_MASTER && !wds && - (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_FROMDS && - local->stadev && - memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) { - /* Frame from BSSID of the AP for which we are a client */ - skb->dev = dev = local->stadev; - stats = hostap_get_stats(dev); - from_assoc_ap = 1; - } - - dev->last_rx = jiffies; - - if ((local->iw_mode == IW_MODE_MASTER || - local->iw_mode == IW_MODE_REPEAT) && - !from_assoc_ap) { - switch (hostap_handle_sta_rx(local, dev, skb, rx_stats, - wds != NULL)) { - case AP_RX_CONTINUE_NOT_AUTHORIZED: - frame_authorized = 0; - break; - case AP_RX_CONTINUE: - frame_authorized = 1; - break; - case AP_RX_DROP: - goto rx_dropped; - case AP_RX_EXIT: - goto rx_exit; - } - } - - /* Nullfunc frames may have PS-bit set, so they must be passed to - * hostap_handle_sta_rx() before being dropped here. */ - if (stype != WLAN_FC_STYPE_DATA && - stype != WLAN_FC_STYPE_DATA_CFACK && - stype != WLAN_FC_STYPE_DATA_CFPOLL && - stype != WLAN_FC_STYPE_DATA_CFACKPOLL) { - if (stype != WLAN_FC_STYPE_NULLFUNC) - printk(KERN_DEBUG "%s: RX: dropped data frame " - "with no data (type=0x%02x, subtype=0x%02x)\n", - dev->name, type, stype); - goto rx_dropped; - } - - /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ - - if (local->host_decrypt && (fc & WLAN_FC_ISWEP) && - (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0) - goto rx_dropped; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - - /* skb: hdr + (possibly fragmented) plaintext payload */ - - if (local->host_decrypt && (fc & WLAN_FC_ISWEP) && - (frag != 0 || (fc & WLAN_FC_MOREFRAG))) { - int flen; - struct sk_buff *frag_skb = - prism2_frag_cache_get(local, hdr); - if (!frag_skb) { - printk(KERN_DEBUG "%s: Rx cannot get skb from " - "fragment cache (morefrag=%d seq=%u frag=%u)\n", - dev->name, (fc & WLAN_FC_MOREFRAG) != 0, - WLAN_GET_SEQ_SEQ(sc) >> 4, frag); - goto rx_dropped; - } - - flen = skb->len; - if (frag != 0) - flen -= hdrlen; - - if (frag_skb->tail + flen > frag_skb->end) { - printk(KERN_WARNING "%s: host decrypted and " - "reassembled frame did not fit skb\n", - dev->name); - prism2_frag_cache_invalidate(local, hdr); - goto rx_dropped; - } - - if (frag == 0) { - /* copy first fragment (including full headers) into - * beginning of the fragment cache skb */ - memcpy(skb_put(frag_skb, flen), skb->data, flen); - } else { - /* append frame payload to the end of the fragment - * cache skb */ - memcpy(skb_put(frag_skb, flen), skb->data + hdrlen, - flen); - } - dev_kfree_skb(skb); - skb = NULL; - - if (fc & WLAN_FC_MOREFRAG) { - /* more fragments expected - leave the skb in fragment - * cache for now; it will be delivered to upper layers - * after all fragments have been received */ - goto rx_exit; - } - - /* this was the last fragment and the frame will be - * delivered, so remove skb from fragment cache */ - skb = frag_skb; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - prism2_frag_cache_invalidate(local, hdr); - } - - /* skb: hdr + (possible reassembled) full MSDU payload; possibly still - * encrypted/authenticated */ - - if (local->host_decrypt && (fc & WLAN_FC_ISWEP) && - hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt)) - goto rx_dropped; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - if (crypt && !(fc & WLAN_FC_ISWEP) && !local->open_wep) { - if (local->ieee_802_1x && - hostap_is_eapol_frame(local, skb)) { - /* pass unencrypted EAPOL frames even if encryption is - * configured */ - PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X - passing " - "unencrypted EAPOL frame\n", local->dev->name); - } else { - printk(KERN_DEBUG "%s: encryption configured, but RX " - "frame not encrypted (SA=" MACSTR ")\n", - local->dev->name, MAC2STR(hdr->addr2)); - goto rx_dropped; - } - } - - if (local->drop_unencrypted && !(fc & WLAN_FC_ISWEP) && - !hostap_is_eapol_frame(local, skb)) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: dropped unencrypted RX data " - "frame from " MACSTR " (drop_unencrypted=1)\n", - dev->name, MAC2STR(hdr->addr2)); - } - goto rx_dropped; - } - - /* skb: hdr + (possible reassembled) full plaintext payload */ - - payload = skb->data + hdrlen; - ethertype = (payload[6] << 8) | payload[7]; - - /* If IEEE 802.1X is used, check whether the port is authorized to send - * the received frame. */ - if (local->ieee_802_1x && local->iw_mode == IW_MODE_MASTER) { - if (ethertype == ETH_P_PAE) { - PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X frame\n", - dev->name); - if (local->hostapd && local->apdev) { - /* Send IEEE 802.1X frames to the user - * space daemon for processing */ - prism2_rx_80211(local->apdev, skb, rx_stats, - PRISM2_RX_MGMT); - local->apdevstats.rx_packets++; - local->apdevstats.rx_bytes += skb->len; - goto rx_exit; - } - } else if (!frame_authorized) { - printk(KERN_DEBUG "%s: dropped frame from " - "unauthorized port (IEEE 802.1X): " - "ethertype=0x%04x\n", - dev->name, ethertype); - goto rx_dropped; - } - } - - /* convert hdr + possible LLC headers into Ethernet header */ - if (skb->len - hdrlen >= 8 && - ((memcmp(payload, rfc1042_header, 6) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(payload, bridge_tunnel_header, 6) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType */ - skb_pull(skb, hdrlen + 6); - memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); - } else { - u16 len; - /* Leave Ethernet header part of hdr and full payload */ - skb_pull(skb, hdrlen); - len = htons(skb->len); - memcpy(skb_push(skb, 2), &len, 2); - memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); - } - - if (wds && ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_TODS) && - skb->len >= ETH_HLEN + ETH_ALEN) { - /* Non-standard frame: get addr4 from its bogus location after - * the payload */ - memcpy(skb->data + ETH_ALEN, - skb->data + skb->len - ETH_ALEN, ETH_ALEN); - skb_trim(skb, skb->len - ETH_ALEN); - } - - stats->rx_packets++; - stats->rx_bytes += skb->len; - - if (local->iw_mode == IW_MODE_MASTER && !wds && - local->ap->bridge_packets) { - if (dst[0] & 0x01) { - /* copy multicast frame both to the higher layers and - * to the wireless media */ - local->ap->bridged_multicast++; - skb2 = skb_clone(skb, GFP_ATOMIC); - if (skb2 == NULL) - printk(KERN_DEBUG "%s: skb_clone failed for " - "multicast frame\n", dev->name); - } else if (hostap_is_sta_authorized(local->ap, dst)) { - /* send frame directly to the associated STA using - * wireless media and not passing to higher layers */ - local->ap->bridged_unicast++; - skb2 = skb; - skb = NULL; - } - } - - if (skb2 != NULL) { - /* send to wireless media */ - skb2->protocol = __constant_htons(ETH_P_802_3); - skb2->mac.raw = skb2->nh.raw = skb2->data; - /* skb2->nh.raw = skb2->data + ETH_HLEN; */ - skb2->dev = dev; - dev_queue_xmit(skb2); - } - - if (skb) { - skb->protocol = eth_type_trans(skb, dev); - memset(skb->cb, 0, sizeof(skb->cb)); - skb->dev = dev; - netif_rx(skb); - } - - rx_exit: - if (sta) - hostap_handle_sta_release(sta); - return; - - rx_dropped: - dev_kfree_skb(skb); - - stats->rx_dropped++; - goto rx_exit; -} - - -EXPORT_SYMBOL(hostap_80211_rx); diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c deleted file mode 100644 index 8f39871d6908..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c +++ /dev/null @@ -1,522 +0,0 @@ -void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) -{ - struct hostap_ieee80211_hdr *hdr; - u16 fc; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - - printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n", - name, skb->len, jiffies); - - if (skb->len < 2) - return; - - fc = le16_to_cpu(hdr->frame_control); - printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s", - fc, HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc), - fc & WLAN_FC_TODS ? " [ToDS]" : "", - fc & WLAN_FC_FROMDS ? " [FromDS]" : ""); - - if (skb->len < IEEE80211_DATA_HDR3_LEN) { - printk("\n"); - return; - } - - printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id), - le16_to_cpu(hdr->seq_ctrl)); - - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR, - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); - if (skb->len >= 30) - printk(" A4=" MACSTR, MAC2STR(hdr->addr4)); - printk("\n"); -} - - -/* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta) - * Convert Ethernet header into a suitable IEEE 802.11 header depending on - * device configuration. */ -int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - int need_headroom, need_tailroom = 0; - struct hostap_ieee80211_hdr hdr; - u16 fc, ethertype = 0; - enum { - WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME - } use_wds = WDS_NO; - u8 *encaps_data; - int hdr_len, encaps_len, skip_header_bytes; - int to_assoc_ap = 0; - struct hostap_skb_tx_data *meta; - - iface = netdev_priv(dev); - local = iface->local; - - if (skb->len < ETH_HLEN) { - printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb " - "(len=%d)\n", dev->name, skb->len); - kfree_skb(skb); - return 0; - } - - if (local->ddev != dev) { - use_wds = (local->iw_mode == IW_MODE_MASTER && - !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ? - WDS_OWN_FRAME : WDS_COMPLIANT_FRAME; - if (dev == local->stadev) { - to_assoc_ap = 1; - use_wds = WDS_NO; - } else if (dev == local->apdev) { - printk(KERN_DEBUG "%s: prism2_tx: trying to use " - "AP device with Ethernet net dev\n", dev->name); - kfree_skb(skb); - return 0; - } - } else { - if (local->iw_mode == IW_MODE_REPEAT) { - printk(KERN_DEBUG "%s: prism2_tx: trying to use " - "non-WDS link in Repeater mode\n", dev->name); - kfree_skb(skb); - return 0; - } else if (local->iw_mode == IW_MODE_INFRA && - (local->wds_type & HOSTAP_WDS_AP_CLIENT) && - memcmp(skb->data + ETH_ALEN, dev->dev_addr, - ETH_ALEN) != 0) { - /* AP client mode: send frames with foreign src addr - * using 4-addr WDS frames */ - use_wds = WDS_COMPLIANT_FRAME; - } - } - - /* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload - * ==> - * Prism2 TX frame with 802.11 header: - * txdesc (address order depending on used mode; includes dst_addr and - * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel; - * proto[2], payload {, possible addr4[6]} */ - - ethertype = (skb->data[12] << 8) | skb->data[13]; - - memset(&hdr, 0, sizeof(hdr)); - - /* Length of data after IEEE 802.11 header */ - encaps_data = NULL; - encaps_len = 0; - skip_header_bytes = ETH_HLEN; - if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) { - encaps_data = bridge_tunnel_header; - encaps_len = sizeof(bridge_tunnel_header); - skip_header_bytes -= 2; - } else if (ethertype >= 0x600) { - encaps_data = rfc1042_header; - encaps_len = sizeof(rfc1042_header); - skip_header_bytes -= 2; - } - - fc = (WLAN_FC_TYPE_DATA << 2) | (WLAN_FC_STYPE_DATA << 4); - hdr_len = IEEE80211_DATA_HDR3_LEN; - - if (use_wds != WDS_NO) { - /* Note! Prism2 station firmware has problems with sending real - * 802.11 frames with four addresses; until these problems can - * be fixed or worked around, 4-addr frames needed for WDS are - * using incompatible format: FromDS flag is not set and the - * fourth address is added after the frame payload; it is - * assumed, that the receiving station knows how to handle this - * frame format */ - - if (use_wds == WDS_COMPLIANT_FRAME) { - fc |= WLAN_FC_FROMDS | WLAN_FC_TODS; - /* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA, - * Addr4 = SA */ - memcpy(&hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); - hdr_len += ETH_ALEN; - } else { - /* bogus 4-addr format to workaround Prism2 station - * f/w bug */ - fc |= WLAN_FC_TODS; - /* From DS: Addr1 = DA (used as RA), - * Addr2 = BSSID (used as TA), Addr3 = SA (used as DA), - */ - - /* SA from skb->data + ETH_ALEN will be added after - * frame payload; use hdr.addr4 as a temporary buffer - */ - memcpy(&hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); - need_tailroom += ETH_ALEN; - } - - /* send broadcast and multicast frames to broadcast RA, if - * configured; otherwise, use unicast RA of the WDS link */ - if ((local->wds_type & HOSTAP_WDS_BROADCAST_RA) && - skb->data[0] & 0x01) - memset(&hdr.addr1, 0xff, ETH_ALEN); - else if (iface->type == HOSTAP_INTERFACE_WDS) - memcpy(&hdr.addr1, iface->u.wds.remote_addr, - ETH_ALEN); - else - memcpy(&hdr.addr1, local->bssid, ETH_ALEN); - memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN); - memcpy(&hdr.addr3, skb->data, ETH_ALEN); - } else if (local->iw_mode == IW_MODE_MASTER && !to_assoc_ap) { - fc |= WLAN_FC_FROMDS; - /* From DS: Addr1 = DA, Addr2 = BSSID, Addr3 = SA */ - memcpy(&hdr.addr1, skb->data, ETH_ALEN); - memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN); - memcpy(&hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); - } else if (local->iw_mode == IW_MODE_INFRA || to_assoc_ap) { - fc |= WLAN_FC_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */ - memcpy(&hdr.addr1, to_assoc_ap ? - local->assoc_ap_addr : local->bssid, ETH_ALEN); - memcpy(&hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); - memcpy(&hdr.addr3, skb->data, ETH_ALEN); - } else if (local->iw_mode == IW_MODE_ADHOC) { - /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */ - memcpy(&hdr.addr1, skb->data, ETH_ALEN); - memcpy(&hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); - memcpy(&hdr.addr3, local->bssid, ETH_ALEN); - } - - hdr.frame_control = cpu_to_le16(fc); - - skb_pull(skb, skip_header_bytes); - need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len; - if (skb_tailroom(skb) < need_tailroom) { - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) { - iface->stats.tx_dropped++; - return 0; - } - if (pskb_expand_head(skb, need_headroom, need_tailroom, - GFP_ATOMIC)) { - kfree_skb(skb); - iface->stats.tx_dropped++; - return 0; - } - } else if (skb_headroom(skb) < need_headroom) { - struct sk_buff *tmp = skb; - skb = skb_realloc_headroom(skb, need_headroom); - kfree_skb(tmp); - if (skb == NULL) { - iface->stats.tx_dropped++; - return 0; - } - } else { - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) { - iface->stats.tx_dropped++; - return 0; - } - } - - if (encaps_data) - memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len); - memcpy(skb_push(skb, hdr_len), &hdr, hdr_len); - if (use_wds == WDS_OWN_FRAME) { - memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN); - } - - iface->stats.tx_packets++; - iface->stats.tx_bytes += skb->len; - - skb->mac.raw = skb->data; - meta = (struct hostap_skb_tx_data *) skb->cb; - memset(meta, 0, sizeof(*meta)); - meta->magic = HOSTAP_SKB_TX_DATA_MAGIC; - meta->wds = use_wds; - meta->ethertype = ethertype; - meta->iface = iface; - - /* Send IEEE 802.11 encapsulated frame using the master radio device */ - skb->dev = local->dev; - dev_queue_xmit(skb); - return 0; -} - - -/* hard_start_xmit function for hostapd wlan#ap interfaces */ -int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hostap_skb_tx_data *meta; - struct hostap_ieee80211_hdr *hdr; - u16 fc; - - iface = netdev_priv(dev); - local = iface->local; - - if (skb->len < 10) { - printk(KERN_DEBUG "%s: hostap_mgmt_start_xmit: short skb " - "(len=%d)\n", dev->name, skb->len); - kfree_skb(skb); - return 0; - } - - iface->stats.tx_packets++; - iface->stats.tx_bytes += skb->len; - - meta = (struct hostap_skb_tx_data *) skb->cb; - memset(meta, 0, sizeof(*meta)); - meta->magic = HOSTAP_SKB_TX_DATA_MAGIC; - meta->iface = iface; - - if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) { - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - if (HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - HOSTAP_FC_GET_STYPE(fc) == WLAN_FC_STYPE_DATA) { - u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN + - sizeof(rfc1042_header)]; - meta->ethertype = (pos[0] << 8) | pos[1]; - } - } - - /* Send IEEE 802.11 encapsulated frame using the master radio device */ - skb->dev = local->dev; - dev_queue_xmit(skb); - return 0; -} - - -/* Called only from software IRQ */ -struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hostap_ieee80211_hdr *hdr; - u16 fc; - int hdr_len, res; - - iface = netdev_priv(skb->dev); - local = iface->local; - - if (skb->len < IEEE80211_DATA_HDR3_LEN) { - kfree_skb(skb); - return NULL; - } - - if (local->tkip_countermeasures && - crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { - hdr = (struct hostap_ieee80211_hdr *) skb->data; - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to " MACSTR "\n", - local->dev->name, MAC2STR(hdr->addr1)); - } - kfree_skb(skb); - return NULL; - } - - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) - return NULL; - - if ((skb_headroom(skb) < crypt->ops->extra_prefix_len || - skb_tailroom(skb) < crypt->ops->extra_postfix_len) && - pskb_expand_head(skb, crypt->ops->extra_prefix_len, - crypt->ops->extra_postfix_len, GFP_ATOMIC)) { - kfree_skb(skb); - return NULL; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - hdr_len = hostap_80211_get_hdrlen(fc); - - /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. */ - atomic_inc(&crypt->refcnt); - res = 0; - if (crypt->ops->encrypt_msdu) - res = crypt->ops->encrypt_msdu(skb, hdr_len, crypt->priv); - if (res == 0 && crypt->ops->encrypt_mpdu) - res = crypt->ops->encrypt_mpdu(skb, hdr_len, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - kfree_skb(skb); - return NULL; - } - - return skb; -} - - -/* hard_start_xmit function for master radio interface wifi#. - * AP processing (TX rate control, power save buffering, etc.). - * Use hardware TX function to send the frame. */ -int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - int ret = 1; - u16 fc; - struct hostap_tx_data tx; - ap_tx_ret tx_ret; - struct hostap_skb_tx_data *meta; - int no_encrypt = 0; - struct hostap_ieee80211_hdr *hdr; - - iface = netdev_priv(dev); - local = iface->local; - - tx.skb = skb; - tx.sta_ptr = NULL; - - meta = (struct hostap_skb_tx_data *) skb->cb; - if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) { - printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, " - "expected 0x%08x)\n", - dev->name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC); - ret = 0; - iface->stats.tx_dropped++; - goto fail; - } - - if (local->host_encrypt) { - /* Set crypt to default algorithm and key; will be replaced in - * AP code if STA has own alg/key */ - tx.crypt = local->crypt[local->tx_keyidx]; - tx.host_encrypt = 1; - } else { - tx.crypt = NULL; - tx.host_encrypt = 0; - } - - if (skb->len < 24) { - printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb " - "(len=%d)\n", dev->name, skb->len); - ret = 0; - iface->stats.tx_dropped++; - goto fail; - } - - /* FIX (?): - * Wi-Fi 802.11b test plan suggests that AP should ignore power save - * bit in authentication and (re)association frames and assume tha - * STA remains awake for the response. */ - tx_ret = hostap_handle_sta_tx(local, &tx); - skb = tx.skb; - meta = (struct hostap_skb_tx_data *) skb->cb; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - switch (tx_ret) { - case AP_TX_CONTINUE: - break; - case AP_TX_CONTINUE_NOT_AUTHORIZED: - if (local->ieee_802_1x && - HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - meta->ethertype != ETH_P_PAE && !meta->wds) { - printk(KERN_DEBUG "%s: dropped frame to unauthorized " - "port (IEEE 802.1X): ethertype=0x%04x\n", - dev->name, meta->ethertype); - hostap_dump_tx_80211(dev->name, skb); - - ret = 0; /* drop packet */ - iface->stats.tx_dropped++; - goto fail; - } - break; - case AP_TX_DROP: - ret = 0; /* drop packet */ - iface->stats.tx_dropped++; - goto fail; - case AP_TX_RETRY: - goto fail; - case AP_TX_BUFFERED: - /* do not free skb here, it will be freed when the - * buffered frame is sent/timed out */ - ret = 0; - goto tx_exit; - } - - /* Request TX callback if protocol version is 2 in 802.11 header; - * this version 2 is a special case used between hostapd and kernel - * driver */ - if (((fc & WLAN_FC_PVER) == BIT(1)) && - local->ap && local->ap->tx_callback_idx && meta->tx_cb_idx == 0) { - meta->tx_cb_idx = local->ap->tx_callback_idx; - - /* remove special version from the frame header */ - fc &= ~WLAN_FC_PVER; - hdr->frame_control = cpu_to_le16(fc); - } - - if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA) { - no_encrypt = 1; - tx.crypt = NULL; - } - - if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt && - !(fc & WLAN_FC_ISWEP)) { - no_encrypt = 1; - PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing " - "unencrypted EAPOL frame\n", dev->name); - tx.crypt = NULL; /* no encryption for IEEE 802.1X frames */ - } - - if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu)) - tx.crypt = NULL; - else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) { - /* Add ISWEP flag both for firmware and host based encryption - */ - fc |= WLAN_FC_ISWEP; - hdr->frame_control = cpu_to_le16(fc); - } else if (local->drop_unencrypted && - HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - meta->ethertype != ETH_P_PAE) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: dropped unencrypted TX data " - "frame (drop_unencrypted=1)\n", dev->name); - } - iface->stats.tx_dropped++; - ret = 0; - goto fail; - } - - if (tx.crypt) { - skb = hostap_tx_encrypt(skb, tx.crypt); - if (skb == NULL) { - printk(KERN_DEBUG "%s: TX - encryption failed\n", - dev->name); - ret = 0; - goto fail; - } - meta = (struct hostap_skb_tx_data *) skb->cb; - if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) { - printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, " - "expected 0x%08x) after hostap_tx_encrypt\n", - dev->name, meta->magic, - HOSTAP_SKB_TX_DATA_MAGIC); - ret = 0; - iface->stats.tx_dropped++; - goto fail; - } - } - - if (local->func->tx == NULL || local->func->tx(skb, dev)) { - ret = 0; - iface->stats.tx_dropped++; - } else { - ret = 0; - iface->stats.tx_packets++; - iface->stats.tx_bytes += skb->len; - } - - fail: - if (!ret && skb) - dev_kfree_skb(skb); - tx_exit: - if (tx.sta_ptr) - hostap_handle_sta_release(tx.sta_ptr); - return ret; -} - - -EXPORT_SYMBOL(hostap_dump_tx_80211); -EXPORT_SYMBOL(hostap_tx_encrypt); -EXPORT_SYMBOL(hostap_master_start_xmit); diff --git a/trunk/drivers/net/wireless/hostap/hostap_ap.c b/trunk/drivers/net/wireless/hostap/hostap_ap.c deleted file mode 100644 index 6e109dfb43e7..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_ap.c +++ /dev/null @@ -1,3287 +0,0 @@ -/* - * Intersil Prism2 driver with Host AP (software access point) support - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2005, Jouni Malinen - * - * This file is to be included into hostap.c when S/W AP functionality is - * compiled. - * - * AP: FIX: - * - if unicast Class 2 (assoc,reassoc,disassoc) frame received from - * unauthenticated STA, send deauth. frame (8802.11: 5.5) - * - if unicast Class 3 (data with to/from DS,deauth,pspoll) frame received - * from authenticated, but unassoc STA, send disassoc frame (8802.11: 5.5) - * - if unicast Class 3 received from unauthenticated STA, send deauth. frame - * (8802.11: 5.5) - */ - -static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL, - DEF_INTS }; -module_param_array(other_ap_policy, int, NULL, 0444); -MODULE_PARM_DESC(other_ap_policy, "Other AP beacon monitoring policy (0-3)"); - -static int ap_max_inactivity[MAX_PARM_DEVICES] = { AP_MAX_INACTIVITY_SEC, - DEF_INTS }; -module_param_array(ap_max_inactivity, int, NULL, 0444); -MODULE_PARM_DESC(ap_max_inactivity, "AP timeout (in seconds) for station " - "inactivity"); - -static int ap_bridge_packets[MAX_PARM_DEVICES] = { 1, DEF_INTS }; -module_param_array(ap_bridge_packets, int, NULL, 0444); -MODULE_PARM_DESC(ap_bridge_packets, "Bridge packets directly between " - "stations"); - -static int autom_ap_wds[MAX_PARM_DEVICES] = { 0, DEF_INTS }; -module_param_array(autom_ap_wds, int, NULL, 0444); -MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs " - "automatically"); - - -static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta); -static void hostap_event_expired_sta(struct net_device *dev, - struct sta_info *sta); -static void handle_add_proc_queue(void *data); - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -static void handle_wds_oper_queue(void *data); -static void prism2_send_mgmt(struct net_device *dev, - int type, int subtype, char *body, - int body_len, u8 *addr, u16 tx_cb_idx); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -#ifndef PRISM2_NO_PROCFS_DEBUG -static int ap_debug_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ap_data *ap = (struct ap_data *) data; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast); - p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast); - p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ); - p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets); - p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack); - p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds); - p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs); - p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc); - - return (p - page); -} -#endif /* PRISM2_NO_PROCFS_DEBUG */ - - -static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta) -{ - sta->hnext = ap->sta_hash[STA_HASH(sta->addr)]; - ap->sta_hash[STA_HASH(sta->addr)] = sta; -} - -static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta) -{ - struct sta_info *s; - - s = ap->sta_hash[STA_HASH(sta->addr)]; - if (s == NULL) return; - if (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) { - ap->sta_hash[STA_HASH(sta->addr)] = s->hnext; - return; - } - - while (s->hnext != NULL && memcmp(s->hnext->addr, sta->addr, ETH_ALEN) - != 0) - s = s->hnext; - if (s->hnext != NULL) - s->hnext = s->hnext->hnext; - else - printk("AP: could not remove STA " MACSTR " from hash table\n", - MAC2STR(sta->addr)); -} - -static void ap_free_sta(struct ap_data *ap, struct sta_info *sta) -{ - if (sta->ap && sta->local) - hostap_event_expired_sta(sta->local->dev, sta); - - if (ap->proc != NULL) { - char name[20]; - sprintf(name, MACSTR, MAC2STR(sta->addr)); - remove_proc_entry(name, ap->proc); - } - - if (sta->crypt) { - sta->crypt->ops->deinit(sta->crypt->priv); - kfree(sta->crypt); - sta->crypt = NULL; - } - - skb_queue_purge(&sta->tx_buf); - - ap->num_sta--; -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (sta->aid > 0) - ap->sta_aid[sta->aid - 1] = NULL; - - if (!sta->ap && sta->u.sta.challenge) - kfree(sta->u.sta.challenge); - del_timer(&sta->timer); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - kfree(sta); -} - - -static void hostap_set_tim(local_info_t *local, int aid, int set) -{ - if (local->func->set_tim) - local->func->set_tim(local->dev, aid, set); -} - - -static void hostap_event_new_sta(struct net_device *dev, struct sta_info *sta) -{ - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, IWEVREGISTERED, &wrqu, NULL); -} - - -static void hostap_event_expired_sta(struct net_device *dev, - struct sta_info *sta) -{ - union iwreq_data wrqu; - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, IWEVEXPIRED, &wrqu, NULL); -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - -static void ap_handle_timer(unsigned long data) -{ - struct sta_info *sta = (struct sta_info *) data; - local_info_t *local; - struct ap_data *ap; - unsigned long next_time = 0; - int was_assoc; - - if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) { - PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n"); - return; - } - - local = sta->local; - ap = local->ap; - was_assoc = sta->flags & WLAN_STA_ASSOC; - - if (atomic_read(&sta->users) != 0) - next_time = jiffies + HZ; - else if ((sta->flags & WLAN_STA_PERM) && !(sta->flags & WLAN_STA_AUTH)) - next_time = jiffies + ap->max_inactivity; - - if (time_before(jiffies, sta->last_rx + ap->max_inactivity)) { - /* station activity detected; reset timeout state */ - sta->timeout_next = STA_NULLFUNC; - next_time = sta->last_rx + ap->max_inactivity; - } else if (sta->timeout_next == STA_DISASSOC && - !(sta->flags & WLAN_STA_PENDING_POLL)) { - /* STA ACKed data nullfunc frame poll */ - sta->timeout_next = STA_NULLFUNC; - next_time = jiffies + ap->max_inactivity; - } - - if (next_time) { - sta->timer.expires = next_time; - add_timer(&sta->timer); - return; - } - - if (sta->ap) - sta->timeout_next = STA_DEAUTH; - - if (sta->timeout_next == STA_DEAUTH && !(sta->flags & WLAN_STA_PERM)) { - spin_lock(&ap->sta_table_lock); - ap_sta_hash_del(ap, sta); - list_del(&sta->list); - spin_unlock(&ap->sta_table_lock); - sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); - } else if (sta->timeout_next == STA_DISASSOC) - sta->flags &= ~WLAN_STA_ASSOC; - - if (was_assoc && !(sta->flags & WLAN_STA_ASSOC) && !sta->ap) - hostap_event_expired_sta(local->dev, sta); - - if (sta->timeout_next == STA_DEAUTH && sta->aid > 0 && - !skb_queue_empty(&sta->tx_buf)) { - hostap_set_tim(local, sta->aid, 0); - sta->flags &= ~WLAN_STA_TIM; - } - - if (sta->ap) { - if (ap->autom_ap_wds) { - PDEBUG(DEBUG_AP, "%s: removing automatic WDS " - "connection to AP " MACSTR "\n", - local->dev->name, MAC2STR(sta->addr)); - hostap_wds_link_oper(local, sta->addr, WDS_DEL); - } - } else if (sta->timeout_next == STA_NULLFUNC) { - /* send data frame to poll STA and check whether this frame - * is ACKed */ - /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but - * it is apparently not retried so TX Exc events are not - * received for it */ - sta->flags |= WLAN_STA_PENDING_POLL; - prism2_send_mgmt(local->dev, WLAN_FC_TYPE_DATA, - WLAN_FC_STYPE_DATA, NULL, 0, - sta->addr, ap->tx_callback_poll); - } else { - int deauth = sta->timeout_next == STA_DEAUTH; - u16 resp; - PDEBUG(DEBUG_AP, "%s: sending %s info to STA " MACSTR - "(last=%lu, jiffies=%lu)\n", - local->dev->name, - deauth ? "deauthentication" : "disassociation", - MAC2STR(sta->addr), sta->last_rx, jiffies); - - resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID : - WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); - prism2_send_mgmt(local->dev, WLAN_FC_TYPE_MGMT, - (deauth ? WLAN_FC_STYPE_DEAUTH : - WLAN_FC_STYPE_DISASSOC), - (char *) &resp, 2, sta->addr, 0); - } - - if (sta->timeout_next == STA_DEAUTH) { - if (sta->flags & WLAN_STA_PERM) { - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " would have been " - "removed, but it has 'perm' flag\n", - local->dev->name, MAC2STR(sta->addr)); - } else - ap_free_sta(ap, sta); - return; - } - - if (sta->timeout_next == STA_NULLFUNC) { - sta->timeout_next = STA_DISASSOC; - sta->timer.expires = jiffies + AP_DISASSOC_DELAY; - } else { - sta->timeout_next = STA_DEAUTH; - sta->timer.expires = jiffies + AP_DEAUTH_DELAY; - } - - add_timer(&sta->timer); -} - - -void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap, - int resend) -{ - u8 addr[ETH_ALEN]; - u16 resp; - int i; - - PDEBUG(DEBUG_AP, "%s: Deauthenticate all stations\n", dev->name); - memset(addr, 0xff, ETH_ALEN); - - resp = __constant_cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); - - /* deauth message sent; try to resend it few times; the message is - * broadcast, so it may be delayed until next DTIM; there is not much - * else we can do at this point since the driver is going to be shut - * down */ - for (i = 0; i < 5; i++) { - prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH, - (char *) &resp, 2, addr, 0); - - if (!resend || ap->num_sta <= 0) - return; - - mdelay(50); - } -} - - -static int ap_control_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ap_data *ap = (struct ap_data *) data; - char *policy_txt; - struct list_head *ptr; - struct mac_entry *entry; - - if (off != 0) { - *eof = 1; - return 0; - } - - switch (ap->mac_restrictions.policy) { - case MAC_POLICY_OPEN: - policy_txt = "open"; - break; - case MAC_POLICY_ALLOW: - policy_txt = "allow"; - break; - case MAC_POLICY_DENY: - policy_txt = "deny"; - break; - default: - policy_txt = "unknown"; - break; - }; - p += sprintf(p, "MAC policy: %s\n", policy_txt); - p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries); - p += sprintf(p, "MAC list:\n"); - spin_lock_bh(&ap->mac_restrictions.lock); - for (ptr = ap->mac_restrictions.mac_list.next; - ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) { - if (p - page > PAGE_SIZE - 80) { - p += sprintf(p, "All entries did not fit one page.\n"); - break; - } - - entry = list_entry(ptr, struct mac_entry, list); - p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr)); - } - spin_unlock_bh(&ap->mac_restrictions.lock); - - return (p - page); -} - - -static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, - u8 *mac) -{ - struct mac_entry *entry; - - entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL); - if (entry == NULL) - return -1; - - memcpy(entry->addr, mac, ETH_ALEN); - - spin_lock_bh(&mac_restrictions->lock); - list_add_tail(&entry->list, &mac_restrictions->mac_list); - mac_restrictions->entries++; - spin_unlock_bh(&mac_restrictions->lock); - - return 0; -} - - -static int ap_control_del_mac(struct mac_restrictions *mac_restrictions, - u8 *mac) -{ - struct list_head *ptr; - struct mac_entry *entry; - - spin_lock_bh(&mac_restrictions->lock); - for (ptr = mac_restrictions->mac_list.next; - ptr != &mac_restrictions->mac_list; ptr = ptr->next) { - entry = list_entry(ptr, struct mac_entry, list); - - if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { - list_del(ptr); - kfree(entry); - mac_restrictions->entries--; - spin_unlock_bh(&mac_restrictions->lock); - return 0; - } - } - spin_unlock_bh(&mac_restrictions->lock); - return -1; -} - - -static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions, - u8 *mac) -{ - struct list_head *ptr; - struct mac_entry *entry; - int found = 0; - - if (mac_restrictions->policy == MAC_POLICY_OPEN) - return 0; - - spin_lock_bh(&mac_restrictions->lock); - for (ptr = mac_restrictions->mac_list.next; - ptr != &mac_restrictions->mac_list; ptr = ptr->next) { - entry = list_entry(ptr, struct mac_entry, list); - - if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { - found = 1; - break; - } - } - spin_unlock_bh(&mac_restrictions->lock); - - if (mac_restrictions->policy == MAC_POLICY_ALLOW) - return !found; - else - return found; -} - - -static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions) -{ - struct list_head *ptr, *n; - struct mac_entry *entry; - - if (mac_restrictions->entries == 0) - return; - - spin_lock_bh(&mac_restrictions->lock); - for (ptr = mac_restrictions->mac_list.next, n = ptr->next; - ptr != &mac_restrictions->mac_list; - ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct mac_entry, list); - list_del(ptr); - kfree(entry); - } - mac_restrictions->entries = 0; - spin_unlock_bh(&mac_restrictions->lock); -} - - -static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, - u8 *mac) -{ - struct sta_info *sta; - u16 resp; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, mac); - if (sta) { - ap_sta_hash_del(ap, sta); - list_del(&sta->list); - } - spin_unlock_bh(&ap->sta_table_lock); - - if (!sta) - return -EINVAL; - - resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID); - prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH, - (char *) &resp, 2, sta->addr, 0); - - if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap) - hostap_event_expired_sta(dev, sta); - - ap_free_sta(ap, sta); - - return 0; -} - -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -static void ap_control_kickall(struct ap_data *ap) -{ - struct list_head *ptr, *n; - struct sta_info *sta; - - spin_lock_bh(&ap->sta_table_lock); - for (ptr = ap->sta_list.next, n = ptr->next; ptr != &ap->sta_list; - ptr = n, n = ptr->next) { - sta = list_entry(ptr, struct sta_info, list); - ap_sta_hash_del(ap, sta); - list_del(&sta->list); - if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local) - hostap_event_expired_sta(sta->local->dev, sta); - ap_free_sta(ap, sta); - } - spin_unlock_bh(&ap->sta_table_lock); -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - -#define PROC_LIMIT (PAGE_SIZE - 80) - -static int prism2_ap_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ap_data *ap = (struct ap_data *) data; - struct list_head *ptr; - int i; - - if (off > PROC_LIMIT) { - *eof = 1; - return 0; - } - - p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n"); - spin_lock_bh(&ap->sta_table_lock); - for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) { - struct sta_info *sta = (struct sta_info *) ptr; - - if (!sta->ap) - continue; - - p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(sta->addr), - sta->u.ap.channel, sta->last_rx_signal, - sta->last_rx_silence, sta->last_rx_rate); - for (i = 0; i < sta->u.ap.ssid_len; i++) - p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 && - sta->u.ap.ssid[i] < 127) ? - "%c" : "<%02x>"), - sta->u.ap.ssid[i]); - p += sprintf(p, "'"); - if (sta->capability & WLAN_CAPABILITY_ESS) - p += sprintf(p, " [ESS]"); - if (sta->capability & WLAN_CAPABILITY_IBSS) - p += sprintf(p, " [IBSS]"); - if (sta->capability & WLAN_CAPABILITY_PRIVACY) - p += sprintf(p, " [WEP]"); - p += sprintf(p, "\n"); - - if ((p - page) > PROC_LIMIT) { - printk(KERN_DEBUG "hostap: ap proc did not fit\n"); - break; - } - } - spin_unlock_bh(&ap->sta_table_lock); - - if ((p - page) <= off) { - *eof = 1; - return 0; - } - - *start = page + off; - - return (p - page - off); -} -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver) -{ - if (!ap) - return; - - if (sta_fw_ver == PRISM2_FW_VER(0,8,0)) { - PDEBUG(DEBUG_AP, "Using data::nullfunc ACK workaround - " - "firmware upgrade recommended\n"); - ap->nullfunc_ack = 1; - } else - ap->nullfunc_ack = 0; - - if (sta_fw_ver == PRISM2_FW_VER(1,4,2)) { - printk(KERN_WARNING "%s: Warning: secondary station firmware " - "version 1.4.2 does not seem to work in Host AP mode\n", - ap->local->dev->name); - } -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data) -{ - struct ap_data *ap = data; - u16 fc; - struct hostap_ieee80211_hdr *hdr; - - if (!ap->local->hostapd || !ap->local->apdev) { - dev_kfree_skb(skb); - return; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - /* Pass the TX callback frame to the hostapd; use 802.11 header version - * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */ - - fc &= ~WLAN_FC_PVER; - fc |= ok ? BIT(1) : BIT(0); - hdr->frame_control = cpu_to_le16(fc); - - skb->dev = ap->local->apdev; - skb_pull(skb, hostap_80211_get_hdrlen(fc)); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = __constant_htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -/* Called only as a tasklet (software IRQ) */ -static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data) -{ - struct ap_data *ap = data; - struct net_device *dev = ap->local->dev; - struct hostap_ieee80211_hdr *hdr; - u16 fc, *pos, auth_alg, auth_transaction, status; - struct sta_info *sta = NULL; - char *txt = NULL; - - if (ap->local->hostapd) { - dev_kfree_skb(skb); - return; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || - HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_AUTH || - skb->len < IEEE80211_MGMT_HDR_LEN + 6) { - printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid " - "frame\n", dev->name); - dev_kfree_skb(skb); - return; - } - - pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN); - auth_alg = le16_to_cpu(*pos++); - auth_transaction = le16_to_cpu(*pos++); - status = le16_to_cpu(*pos++); - - if (!ok) { - txt = "frame was not ACKed"; - goto done; - } - - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, hdr->addr1); - if (sta) - atomic_inc(&sta->users); - spin_unlock(&ap->sta_table_lock); - - if (!sta) { - txt = "STA not found"; - goto done; - } - - if (status == WLAN_STATUS_SUCCESS && - ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) || - (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) { - txt = "STA authenticated"; - sta->flags |= WLAN_STA_AUTH; - sta->last_auth = jiffies; - } else if (status != WLAN_STATUS_SUCCESS) - txt = "authentication failed"; - - done: - if (sta) - atomic_dec(&sta->users); - if (txt) { - PDEBUG(DEBUG_AP, "%s: " MACSTR " auth_cb - alg=%d trans#=%d " - "status=%d - %s\n", - dev->name, MAC2STR(hdr->addr1), auth_alg, - auth_transaction, status, txt); - } - dev_kfree_skb(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) -{ - struct ap_data *ap = data; - struct net_device *dev = ap->local->dev; - struct hostap_ieee80211_hdr *hdr; - u16 fc, *pos, status; - struct sta_info *sta = NULL; - char *txt = NULL; - - if (ap->local->hostapd) { - dev_kfree_skb(skb); - return; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || - (HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ASSOC_RESP && - HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_REASSOC_RESP) || - skb->len < IEEE80211_MGMT_HDR_LEN + 4) { - printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid " - "frame\n", dev->name); - dev_kfree_skb(skb); - return; - } - - if (!ok) { - txt = "frame was not ACKed"; - goto done; - } - - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, hdr->addr1); - if (sta) - atomic_inc(&sta->users); - spin_unlock(&ap->sta_table_lock); - - if (!sta) { - txt = "STA not found"; - goto done; - } - - pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN); - pos++; - status = le16_to_cpu(*pos++); - if (status == WLAN_STATUS_SUCCESS) { - if (!(sta->flags & WLAN_STA_ASSOC)) - hostap_event_new_sta(dev, sta); - txt = "STA associated"; - sta->flags |= WLAN_STA_ASSOC; - sta->last_assoc = jiffies; - } else - txt = "association failed"; - - done: - if (sta) - atomic_dec(&sta->users); - if (txt) { - PDEBUG(DEBUG_AP, "%s: " MACSTR " assoc_cb - %s\n", - dev->name, MAC2STR(hdr->addr1), txt); - } - dev_kfree_skb(skb); -} - -/* Called only as a tasklet (software IRQ); TX callback for poll frames used - * in verifying whether the STA is still present. */ -static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data) -{ - struct ap_data *ap = data; - struct hostap_ieee80211_hdr *hdr; - struct sta_info *sta; - - if (skb->len < 24) - goto fail; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - if (ok) { - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, hdr->addr1); - if (sta) - sta->flags &= ~WLAN_STA_PENDING_POLL; - spin_unlock(&ap->sta_table_lock); - } else { - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " did not ACK activity " - "poll frame\n", ap->local->dev->name, - MAC2STR(hdr->addr1)); - } - - fail: - dev_kfree_skb(skb); -} -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -void hostap_init_data(local_info_t *local) -{ - struct ap_data *ap = local->ap; - - if (ap == NULL) { - printk(KERN_WARNING "hostap_init_data: ap == NULL\n"); - return; - } - memset(ap, 0, sizeof(struct ap_data)); - ap->local = local; - - ap->ap_policy = GET_INT_PARM(other_ap_policy, local->card_idx); - ap->bridge_packets = GET_INT_PARM(ap_bridge_packets, local->card_idx); - ap->max_inactivity = - GET_INT_PARM(ap_max_inactivity, local->card_idx) * HZ; - ap->autom_ap_wds = GET_INT_PARM(autom_ap_wds, local->card_idx); - - spin_lock_init(&ap->sta_table_lock); - INIT_LIST_HEAD(&ap->sta_list); - - /* Initialize task queue structure for AP management */ - INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap); - - ap->tx_callback_idx = - hostap_tx_callback_register(local, hostap_ap_tx_cb, ap); - if (ap->tx_callback_idx == 0) - printk(KERN_WARNING "%s: failed to register TX callback for " - "AP\n", local->dev->name); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local); - - ap->tx_callback_auth = - hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap); - ap->tx_callback_assoc = - hostap_tx_callback_register(local, hostap_ap_tx_cb_assoc, ap); - ap->tx_callback_poll = - hostap_tx_callback_register(local, hostap_ap_tx_cb_poll, ap); - if (ap->tx_callback_auth == 0 || ap->tx_callback_assoc == 0 || - ap->tx_callback_poll == 0) - printk(KERN_WARNING "%s: failed to register TX callback for " - "AP\n", local->dev->name); - - spin_lock_init(&ap->mac_restrictions.lock); - INIT_LIST_HEAD(&ap->mac_restrictions.mac_list); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - ap->initialized = 1; -} - - -void hostap_init_ap_proc(local_info_t *local) -{ - struct ap_data *ap = local->ap; - - ap->proc = local->proc; - if (ap->proc == NULL) - return; - -#ifndef PRISM2_NO_PROCFS_DEBUG - create_proc_read_entry("ap_debug", 0, ap->proc, - ap_debug_proc_read, ap); -#endif /* PRISM2_NO_PROCFS_DEBUG */ - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - create_proc_read_entry("ap_control", 0, ap->proc, - ap_control_proc_read, ap); - create_proc_read_entry("ap", 0, ap->proc, - prism2_ap_proc_read, ap); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - -} - - -void hostap_free_data(struct ap_data *ap) -{ - struct list_head *n, *ptr; - - if (ap == NULL || !ap->initialized) { - printk(KERN_DEBUG "hostap_free_data: ap has not yet been " - "initialized - skip resource freeing\n"); - return; - } - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (ap->crypt) - ap->crypt->deinit(ap->crypt_priv); - ap->crypt = ap->crypt_priv = NULL; -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - list_for_each_safe(ptr, n, &ap->sta_list) { - struct sta_info *sta = list_entry(ptr, struct sta_info, list); - ap_sta_hash_del(ap, sta); - list_del(&sta->list); - if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local) - hostap_event_expired_sta(sta->local->dev, sta); - ap_free_sta(ap, sta); - } - -#ifndef PRISM2_NO_PROCFS_DEBUG - if (ap->proc != NULL) { - remove_proc_entry("ap_debug", ap->proc); - } -#endif /* PRISM2_NO_PROCFS_DEBUG */ - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (ap->proc != NULL) { - remove_proc_entry("ap", ap->proc); - remove_proc_entry("ap_control", ap->proc); - } - ap_control_flush_macs(&ap->mac_restrictions); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - ap->initialized = 0; -} - - -/* caller should have mutex for AP STA list handling */ -static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta) -{ - struct sta_info *s; - - s = ap->sta_hash[STA_HASH(sta)]; - while (s != NULL && memcmp(s->addr, sta, ETH_ALEN) != 0) - s = s->hnext; - return s; -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - -/* Called from timer handler and from scheduled AP queue handlers */ -static void prism2_send_mgmt(struct net_device *dev, - int type, int subtype, char *body, - int body_len, u8 *addr, u16 tx_cb_idx) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hostap_ieee80211_hdr *hdr; - u16 fc; - struct sk_buff *skb; - struct hostap_skb_tx_data *meta; - int hdrlen; - - iface = netdev_priv(dev); - local = iface->local; - dev = local->dev; /* always use master radio device */ - iface = netdev_priv(dev); - - if (!(dev->flags & IFF_UP)) { - PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt - device is not UP - " - "cannot send frame\n", dev->name); - return; - } - - skb = dev_alloc_skb(sizeof(*hdr) + body_len); - if (skb == NULL) { - PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt failed to allocate " - "skb\n", dev->name); - return; - } - - fc = (type << 2) | (subtype << 4); - hdrlen = hostap_80211_get_hdrlen(fc); - hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, hdrlen); - if (body) - memcpy(skb_put(skb, body_len), body, body_len); - - memset(hdr, 0, hdrlen); - - /* FIX: ctrl::ack sending used special HFA384X_TX_CTRL_802_11 - * tx_control instead of using local->tx_control */ - - - memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */ - if (type == WLAN_FC_TYPE_DATA) { - fc |= WLAN_FC_FROMDS; - memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */ - memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */ - } else if (type == WLAN_FC_TYPE_CTRL) { - /* control:ACK does not have addr2 or addr3 */ - memset(hdr->addr2, 0, ETH_ALEN); - memset(hdr->addr3, 0, ETH_ALEN); - } else { - memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* SA */ - memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */ - } - - hdr->frame_control = cpu_to_le16(fc); - - meta = (struct hostap_skb_tx_data *) skb->cb; - memset(meta, 0, sizeof(*meta)); - meta->magic = HOSTAP_SKB_TX_DATA_MAGIC; - meta->iface = iface; - meta->tx_cb_idx = tx_cb_idx; - - skb->dev = dev; - skb->mac.raw = skb->nh.raw = skb->data; - dev_queue_xmit(skb); -} -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -static int prism2_sta_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct sta_info *sta = (struct sta_info *) data; - int i; - - /* FIX: possible race condition.. the STA data could have just expired, - * but proc entry was still here so that the read could have started; - * some locking should be done here.. */ - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "%s=" MACSTR "\nusers=%d\naid=%d\n" - "flags=0x%04x%s%s%s%s%s%s%s\n" - "capability=0x%02x\nlisten_interval=%d\nsupported_rates=", - sta->ap ? "AP" : "STA", - MAC2STR(sta->addr), atomic_read(&sta->users), sta->aid, - sta->flags, - sta->flags & WLAN_STA_AUTH ? " AUTH" : "", - sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "", - sta->flags & WLAN_STA_PS ? " PS" : "", - sta->flags & WLAN_STA_TIM ? " TIM" : "", - sta->flags & WLAN_STA_PERM ? " PERM" : "", - sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "", - sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "", - sta->capability, sta->listen_interval); - /* supported_rates: 500 kbit/s units with msb ignored */ - for (i = 0; i < sizeof(sta->supported_rates); i++) - if (sta->supported_rates[i] != 0) - p += sprintf(p, "%d%sMbps ", - (sta->supported_rates[i] & 0x7f) / 2, - sta->supported_rates[i] & 1 ? ".5" : ""); - p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n" - "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n" - "tx_packets=%lu\n" - "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n" - "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n" - "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n" - "tx[11M]=%d\n" - "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n", - jiffies, sta->last_auth, sta->last_assoc, sta->last_rx, - sta->last_tx, - sta->rx_packets, sta->tx_packets, sta->rx_bytes, - sta->tx_bytes, skb_queue_len(&sta->tx_buf), - sta->last_rx_silence, - sta->last_rx_signal, sta->last_rx_rate / 10, - sta->last_rx_rate % 10 ? ".5" : "", - sta->tx_rate, sta->tx_count[0], sta->tx_count[1], - sta->tx_count[2], sta->tx_count[3], sta->rx_count[0], - sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]); - if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats) - p = sta->crypt->ops->print_stats(p, sta->crypt->priv); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (sta->ap) { - if (sta->u.ap.channel >= 0) - p += sprintf(p, "channel=%d\n", sta->u.ap.channel); - p += sprintf(p, "ssid="); - for (i = 0; i < sta->u.ap.ssid_len; i++) - p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 && - sta->u.ap.ssid[i] < 127) ? - "%c" : "<%02x>"), - sta->u.ap.ssid[i]); - p += sprintf(p, "\n"); - } -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - return (p - page); -} - - -static void handle_add_proc_queue(void *data) -{ - struct ap_data *ap = (struct ap_data *) data; - struct sta_info *sta; - char name[20]; - struct add_sta_proc_data *entry, *prev; - - entry = ap->add_sta_proc_entries; - ap->add_sta_proc_entries = NULL; - - while (entry) { - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, entry->addr); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&ap->sta_table_lock); - - if (sta) { - sprintf(name, MACSTR, MAC2STR(sta->addr)); - sta->proc = create_proc_read_entry( - name, 0, ap->proc, - prism2_sta_proc_read, sta); - - atomic_dec(&sta->users); - } - - prev = entry; - entry = entry->next; - kfree(prev); - } -} - - -static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr) -{ - struct sta_info *sta; - - sta = (struct sta_info *) - kmalloc(sizeof(struct sta_info), GFP_ATOMIC); - if (sta == NULL) { - PDEBUG(DEBUG_AP, "AP: kmalloc failed\n"); - return NULL; - } - - /* initialize STA info data */ - memset(sta, 0, sizeof(struct sta_info)); - sta->local = ap->local; - skb_queue_head_init(&sta->tx_buf); - memcpy(sta->addr, addr, ETH_ALEN); - - atomic_inc(&sta->users); - spin_lock_bh(&ap->sta_table_lock); - list_add(&sta->list, &ap->sta_list); - ap->num_sta++; - ap_sta_hash_add(ap, sta); - spin_unlock_bh(&ap->sta_table_lock); - - if (ap->proc) { - struct add_sta_proc_data *entry; - /* schedule a non-interrupt context process to add a procfs - * entry for the STA since procfs code use GFP_KERNEL */ - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); - if (entry) { - memcpy(entry->addr, sta->addr, ETH_ALEN); - entry->next = ap->add_sta_proc_entries; - ap->add_sta_proc_entries = entry; - schedule_work(&ap->add_sta_proc_queue); - } else - printk(KERN_DEBUG "Failed to add STA proc data\n"); - } - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - init_timer(&sta->timer); - sta->timer.expires = jiffies + ap->max_inactivity; - sta->timer.data = (unsigned long) sta; - sta->timer.function = ap_handle_timer; - if (!ap->local->hostapd) - add_timer(&sta->timer); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - return sta; -} - - -static int ap_tx_rate_ok(int rateidx, struct sta_info *sta, - local_info_t *local) -{ - if (rateidx > sta->tx_max_rate || - !(sta->tx_supp_rates & (1 << rateidx))) - return 0; - - if (local->tx_rate_control != 0 && - !(local->tx_rate_control & (1 << rateidx))) - return 0; - - return 1; -} - - -static void prism2_check_tx_rates(struct sta_info *sta) -{ - int i; - - sta->tx_supp_rates = 0; - for (i = 0; i < sizeof(sta->supported_rates); i++) { - if ((sta->supported_rates[i] & 0x7f) == 2) - sta->tx_supp_rates |= WLAN_RATE_1M; - if ((sta->supported_rates[i] & 0x7f) == 4) - sta->tx_supp_rates |= WLAN_RATE_2M; - if ((sta->supported_rates[i] & 0x7f) == 11) - sta->tx_supp_rates |= WLAN_RATE_5M5; - if ((sta->supported_rates[i] & 0x7f) == 22) - sta->tx_supp_rates |= WLAN_RATE_11M; - } - sta->tx_max_rate = sta->tx_rate = sta->tx_rate_idx = 0; - if (sta->tx_supp_rates & WLAN_RATE_1M) { - sta->tx_max_rate = 0; - if (ap_tx_rate_ok(0, sta, sta->local)) { - sta->tx_rate = 10; - sta->tx_rate_idx = 0; - } - } - if (sta->tx_supp_rates & WLAN_RATE_2M) { - sta->tx_max_rate = 1; - if (ap_tx_rate_ok(1, sta, sta->local)) { - sta->tx_rate = 20; - sta->tx_rate_idx = 1; - } - } - if (sta->tx_supp_rates & WLAN_RATE_5M5) { - sta->tx_max_rate = 2; - if (ap_tx_rate_ok(2, sta, sta->local)) { - sta->tx_rate = 55; - sta->tx_rate_idx = 2; - } - } - if (sta->tx_supp_rates & WLAN_RATE_11M) { - sta->tx_max_rate = 3; - if (ap_tx_rate_ok(3, sta, sta->local)) { - sta->tx_rate = 110; - sta->tx_rate_idx = 3; - } - } -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - -static void ap_crypt_init(struct ap_data *ap) -{ - ap->crypt = ieee80211_get_crypto_ops("WEP"); - - if (ap->crypt) { - if (ap->crypt->init) { - ap->crypt_priv = ap->crypt->init(0); - if (ap->crypt_priv == NULL) - ap->crypt = NULL; - else { - u8 key[WEP_KEY_LEN]; - get_random_bytes(key, WEP_KEY_LEN); - ap->crypt->set_key(key, WEP_KEY_LEN, NULL, - ap->crypt_priv); - } - } - } - - if (ap->crypt == NULL) { - printk(KERN_WARNING "AP could not initialize WEP: load module " - "ieee80211_crypt_wep.ko\n"); - } -} - - -/* Generate challenge data for shared key authentication. IEEE 802.11 specifies - * that WEP algorithm is used for generating challange. This should be unique, - * but otherwise there is not really need for randomness etc. Initialize WEP - * with pseudo random key and then use increasing IV to get unique challenge - * streams. - * - * Called only as a scheduled task for pending AP frames. - */ -static char * ap_auth_make_challenge(struct ap_data *ap) -{ - char *tmpbuf; - struct sk_buff *skb; - - if (ap->crypt == NULL) { - ap_crypt_init(ap); - if (ap->crypt == NULL) - return NULL; - } - - tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC); - if (tmpbuf == NULL) { - PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n"); - return NULL; - } - - skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN + - ap->crypt->extra_prefix_len + - ap->crypt->extra_postfix_len); - if (skb == NULL) { - kfree(tmpbuf); - return NULL; - } - - skb_reserve(skb, ap->crypt->extra_prefix_len); - memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0, - WLAN_AUTH_CHALLENGE_LEN); - if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) { - dev_kfree_skb(skb); - kfree(tmpbuf); - return NULL; - } - - memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len, - WLAN_AUTH_CHALLENGE_LEN); - dev_kfree_skb(skb); - - return tmpbuf; -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void handle_authen(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; - size_t hdrlen; - struct ap_data *ap = local->ap; - char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL; - int len, olen; - u16 auth_alg, auth_transaction, status_code, *pos; - u16 resp = WLAN_STATUS_SUCCESS, fc; - struct sta_info *sta = NULL; - struct ieee80211_crypt_data *crypt; - char *txt = ""; - - len = skb->len - IEEE80211_MGMT_HDR_LEN; - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = hostap_80211_get_hdrlen(fc); - - if (len < 6) { - PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload " - "(len=%d) from " MACSTR "\n", dev->name, len, - MAC2STR(hdr->addr2)); - return; - } - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&local->ap->sta_table_lock); - - if (sta && sta->crypt) - crypt = sta->crypt; - else { - int idx = 0; - if (skb->len >= hdrlen + 3) - idx = skb->data[hdrlen + 3] >> 6; - crypt = local->crypt[idx]; - } - - pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN); - auth_alg = __le16_to_cpu(*pos); - pos++; - auth_transaction = __le16_to_cpu(*pos); - pos++; - status_code = __le16_to_cpu(*pos); - pos++; - - if (memcmp(dev->dev_addr, hdr->addr2, ETH_ALEN) == 0 || - ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) { - txt = "authentication denied"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - - if (((local->auth_algs & PRISM2_AUTH_OPEN) && - auth_alg == WLAN_AUTH_OPEN) || - ((local->auth_algs & PRISM2_AUTH_SHARED_KEY) && - crypt && auth_alg == WLAN_AUTH_SHARED_KEY)) { - } else { - txt = "unsupported algorithm"; - resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; - goto fail; - } - - if (len >= 8) { - u8 *u = (u8 *) pos; - if (*u == WLAN_EID_CHALLENGE) { - if (*(u + 1) != WLAN_AUTH_CHALLENGE_LEN) { - txt = "invalid challenge len"; - resp = WLAN_STATUS_CHALLENGE_FAIL; - goto fail; - } - if (len - 8 < WLAN_AUTH_CHALLENGE_LEN) { - txt = "challenge underflow"; - resp = WLAN_STATUS_CHALLENGE_FAIL; - goto fail; - } - challenge = (char *) (u + 2); - } - } - - if (sta && sta->ap) { - if (time_after(jiffies, sta->u.ap.last_beacon + - (10 * sta->listen_interval * HZ) / 1024)) { - PDEBUG(DEBUG_AP, "%s: no beacons received for a while," - " assuming AP " MACSTR " is now STA\n", - dev->name, MAC2STR(sta->addr)); - sta->ap = 0; - sta->flags = 0; - sta->u.sta.challenge = NULL; - } else { - txt = "AP trying to authenticate?"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - } - - if ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) || - (auth_alg == WLAN_AUTH_SHARED_KEY && - (auth_transaction == 1 || - (auth_transaction == 3 && sta != NULL && - sta->u.sta.challenge != NULL)))) { - } else { - txt = "unknown authentication transaction number"; - resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; - goto fail; - } - - if (sta == NULL) { - txt = "new STA"; - - if (local->ap->num_sta >= MAX_STA_COUNT) { - /* FIX: might try to remove some old STAs first? */ - txt = "no more room for new STAs"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - - sta = ap_add_sta(local->ap, hdr->addr2); - if (sta == NULL) { - txt = "ap_add_sta failed"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - } - - switch (auth_alg) { - case WLAN_AUTH_OPEN: - txt = "authOK"; - /* IEEE 802.11 standard is not completely clear about - * whether STA is considered authenticated after - * authentication OK frame has been send or after it - * has been ACKed. In order to reduce interoperability - * issues, mark the STA authenticated before ACK. */ - sta->flags |= WLAN_STA_AUTH; - break; - - case WLAN_AUTH_SHARED_KEY: - if (auth_transaction == 1) { - if (sta->u.sta.challenge == NULL) { - sta->u.sta.challenge = - ap_auth_make_challenge(local->ap); - if (sta->u.sta.challenge == NULL) { - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - } - } else { - if (sta->u.sta.challenge == NULL || - challenge == NULL || - memcmp(sta->u.sta.challenge, challenge, - WLAN_AUTH_CHALLENGE_LEN) != 0 || - !(fc & WLAN_FC_ISWEP)) { - txt = "challenge response incorrect"; - resp = WLAN_STATUS_CHALLENGE_FAIL; - goto fail; - } - - txt = "challenge OK - authOK"; - /* IEEE 802.11 standard is not completely clear about - * whether STA is considered authenticated after - * authentication OK frame has been send or after it - * has been ACKed. In order to reduce interoperability - * issues, mark the STA authenticated before ACK. */ - sta->flags |= WLAN_STA_AUTH; - kfree(sta->u.sta.challenge); - sta->u.sta.challenge = NULL; - } - break; - } - - fail: - pos = (u16 *) body; - *pos = cpu_to_le16(auth_alg); - pos++; - *pos = cpu_to_le16(auth_transaction + 1); - pos++; - *pos = cpu_to_le16(resp); /* status_code */ - pos++; - olen = 6; - - if (resp == WLAN_STATUS_SUCCESS && sta != NULL && - sta->u.sta.challenge != NULL && - auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 1) { - u8 *tmp = (u8 *) pos; - *tmp++ = WLAN_EID_CHALLENGE; - *tmp++ = WLAN_AUTH_CHALLENGE_LEN; - pos++; - memcpy(pos, sta->u.sta.challenge, WLAN_AUTH_CHALLENGE_LEN); - olen += 2 + WLAN_AUTH_CHALLENGE_LEN; - } - - prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_AUTH, - body, olen, hdr->addr2, ap->tx_callback_auth); - - if (sta) { - sta->last_rx = jiffies; - atomic_dec(&sta->users); - } - - if (resp) { - PDEBUG(DEBUG_AP, "%s: " MACSTR " auth (alg=%d trans#=%d " - "stat=%d len=%d fc=%04x) ==> %d (%s)\n", - dev->name, MAC2STR(hdr->addr2), auth_alg, - auth_transaction, status_code, len, fc, resp, txt); - } -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void handle_assoc(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats, int reassoc) -{ - struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; - char body[12], *p, *lpos; - int len, left; - u16 *pos; - u16 resp = WLAN_STATUS_SUCCESS; - struct sta_info *sta = NULL; - int send_deauth = 0; - char *txt = ""; - u8 prev_ap[ETH_ALEN]; - - left = len = skb->len - IEEE80211_MGMT_HDR_LEN; - - if (len < (reassoc ? 10 : 4)) { - PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload " - "(len=%d, reassoc=%d) from " MACSTR "\n", - dev->name, len, reassoc, MAC2STR(hdr->addr2)); - return; - } - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { - spin_unlock_bh(&local->ap->sta_table_lock); - txt = "trying to associate before authentication"; - send_deauth = 1; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - sta = NULL; /* do not decrement sta->users */ - goto fail; - } - atomic_inc(&sta->users); - spin_unlock_bh(&local->ap->sta_table_lock); - - pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN); - sta->capability = __le16_to_cpu(*pos); - pos++; left -= 2; - sta->listen_interval = __le16_to_cpu(*pos); - pos++; left -= 2; - - if (reassoc) { - memcpy(prev_ap, pos, ETH_ALEN); - pos++; pos++; pos++; left -= 6; - } else - memset(prev_ap, 0, ETH_ALEN); - - if (left >= 2) { - unsigned int ileft; - unsigned char *u = (unsigned char *) pos; - - if (*u == WLAN_EID_SSID) { - u++; left--; - ileft = *u; - u++; left--; - - if (ileft > left || ileft > MAX_SSID_LEN) { - txt = "SSID overflow"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - - if (ileft != strlen(local->essid) || - memcmp(local->essid, u, ileft) != 0) { - txt = "not our SSID"; - resp = WLAN_STATUS_ASSOC_DENIED_UNSPEC; - goto fail; - } - - u += ileft; - left -= ileft; - } - - if (left >= 2 && *u == WLAN_EID_SUPP_RATES) { - u++; left--; - ileft = *u; - u++; left--; - - if (ileft > left || ileft == 0 || - ileft > WLAN_SUPP_RATES_MAX) { - txt = "SUPP_RATES len error"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - - memset(sta->supported_rates, 0, - sizeof(sta->supported_rates)); - memcpy(sta->supported_rates, u, ileft); - prism2_check_tx_rates(sta); - - u += ileft; - left -= ileft; - } - - if (left > 0) { - PDEBUG(DEBUG_AP, "%s: assoc from " MACSTR " with extra" - " data (%d bytes) [", - dev->name, MAC2STR(hdr->addr2), left); - while (left > 0) { - PDEBUG2(DEBUG_AP, "<%02x>", *u); - u++; left--; - } - PDEBUG2(DEBUG_AP, "]\n"); - } - } else { - txt = "frame underflow"; - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; - goto fail; - } - - /* get a unique AID */ - if (sta->aid > 0) - txt = "OK, old AID"; - else { - spin_lock_bh(&local->ap->sta_table_lock); - for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++) - if (local->ap->sta_aid[sta->aid - 1] == NULL) - break; - if (sta->aid > MAX_AID_TABLE_SIZE) { - sta->aid = 0; - spin_unlock_bh(&local->ap->sta_table_lock); - resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - txt = "no room for more AIDs"; - } else { - local->ap->sta_aid[sta->aid - 1] = sta; - spin_unlock_bh(&local->ap->sta_table_lock); - txt = "OK, new AID"; - } - } - - fail: - pos = (u16 *) body; - - if (send_deauth) { - *pos = __constant_cpu_to_le16( - WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH); - pos++; - } else { - /* FIX: CF-Pollable and CF-PollReq should be set to match the - * values in beacons/probe responses */ - /* FIX: how about privacy and WEP? */ - /* capability */ - *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS); - pos++; - - /* status_code */ - *pos = __cpu_to_le16(resp); - pos++; - - *pos = __cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) | - BIT(14) | BIT(15)); /* AID */ - pos++; - - /* Supported rates (Information element) */ - p = (char *) pos; - *p++ = WLAN_EID_SUPP_RATES; - lpos = p; - *p++ = 0; /* len */ - if (local->tx_rate_control & WLAN_RATE_1M) { - *p++ = local->basic_rates & WLAN_RATE_1M ? 0x82 : 0x02; - (*lpos)++; - } - if (local->tx_rate_control & WLAN_RATE_2M) { - *p++ = local->basic_rates & WLAN_RATE_2M ? 0x84 : 0x04; - (*lpos)++; - } - if (local->tx_rate_control & WLAN_RATE_5M5) { - *p++ = local->basic_rates & WLAN_RATE_5M5 ? - 0x8b : 0x0b; - (*lpos)++; - } - if (local->tx_rate_control & WLAN_RATE_11M) { - *p++ = local->basic_rates & WLAN_RATE_11M ? - 0x96 : 0x16; - (*lpos)++; - } - pos = (u16 *) p; - } - - prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, - (send_deauth ? WLAN_FC_STYPE_DEAUTH : - (reassoc ? WLAN_FC_STYPE_REASSOC_RESP : - WLAN_FC_STYPE_ASSOC_RESP)), - body, (u8 *) pos - (u8 *) body, - hdr->addr2, - send_deauth ? 0 : local->ap->tx_callback_assoc); - - if (sta) { - if (resp == WLAN_STATUS_SUCCESS) { - sta->last_rx = jiffies; - /* STA will be marked associated from TX callback, if - * AssocResp is ACKed */ - } - atomic_dec(&sta->users); - } - -#if 0 - PDEBUG(DEBUG_AP, "%s: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR - ") => %d(%d) (%s)\n", - dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len, - MAC2STR(prev_ap), resp, send_deauth, txt); -#endif -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void handle_deauth(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; - char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN); - int len; - u16 reason_code, *pos; - struct sta_info *sta = NULL; - - len = skb->len - IEEE80211_MGMT_HDR_LEN; - - if (len < 2) { - printk("handle_deauth - too short payload (len=%d)\n", len); - return; - } - - pos = (u16 *) body; - reason_code = __le16_to_cpu(*pos); - - PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, " - "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len, - reason_code); - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta != NULL) { - if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap) - hostap_event_expired_sta(local->dev, sta); - sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); - } - spin_unlock_bh(&local->ap->sta_table_lock); - if (sta == NULL) { - printk("%s: deauthentication from " MACSTR ", " - "reason_code=%d, but STA not authenticated\n", dev->name, - MAC2STR(hdr->addr2), reason_code); - } -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void handle_disassoc(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct net_device *dev = local->dev; - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; - char *body = skb->data + IEEE80211_MGMT_HDR_LEN; - int len; - u16 reason_code, *pos; - struct sta_info *sta = NULL; - - len = skb->len - IEEE80211_MGMT_HDR_LEN; - - if (len < 2) { - printk("handle_disassoc - too short payload (len=%d)\n", len); - return; - } - - pos = (u16 *) body; - reason_code = __le16_to_cpu(*pos); - - PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, " - "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len, - reason_code); - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta != NULL) { - if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap) - hostap_event_expired_sta(local->dev, sta); - sta->flags &= ~WLAN_STA_ASSOC; - } - spin_unlock_bh(&local->ap->sta_table_lock); - if (sta == NULL) { - printk("%s: disassociation from " MACSTR ", " - "reason_code=%d, but STA not authenticated\n", - dev->name, MAC2STR(hdr->addr2), reason_code); - } -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void ap_handle_data_nullfunc(local_info_t *local, - struct hostap_ieee80211_hdr *hdr) -{ - struct net_device *dev = local->dev; - - /* some STA f/w's seem to require control::ACK frame for - * data::nullfunc, but at least Prism2 station f/w version 0.8.0 does - * not send this.. - * send control::ACK for the data::nullfunc */ - - printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n"); - prism2_send_mgmt(dev, WLAN_FC_TYPE_CTRL, WLAN_FC_STYPE_ACK, - NULL, 0, hdr->addr2, 0); -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void ap_handle_dropped_data(local_info_t *local, - struct hostap_ieee80211_hdr *hdr) -{ - struct net_device *dev = local->dev; - struct sta_info *sta; - u16 reason; - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&local->ap->sta_table_lock); - - if (sta != NULL && (sta->flags & WLAN_STA_ASSOC)) { - PDEBUG(DEBUG_AP, "ap_handle_dropped_data: STA is now okay?\n"); - atomic_dec(&sta->users); - return; - } - - reason = __constant_cpu_to_le16( - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, - ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ? - WLAN_FC_STYPE_DEAUTH : WLAN_FC_STYPE_DISASSOC), - (char *) &reason, sizeof(reason), hdr->addr2, 0); - - if (sta) - atomic_dec(&sta->users); -} - -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -/* Called only as a scheduled task for pending AP frames. */ -static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta, - struct sk_buff *skb) -{ - if (!(sta->flags & WLAN_STA_PS)) { - /* Station has moved to non-PS mode, so send all buffered - * frames using normal device queue. */ - dev_queue_xmit(skb); - return; - } - - /* add a flag for hostap_handle_sta_tx() to know that this skb should - * be passed through even though STA is using PS */ - memcpy(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN); - skb->cb[AP_SKB_CB_MAGIC_LEN] = AP_SKB_CB_BUFFERED_FRAME; - if (!skb_queue_empty(&sta->tx_buf)) { - /* indicate to STA that more frames follow */ - skb->cb[AP_SKB_CB_MAGIC_LEN] |= AP_SKB_CB_ADD_MOREDATA; - } - dev_queue_xmit(skb); -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void handle_pspoll(local_info_t *local, - struct hostap_ieee80211_hdr *hdr, - struct hostap_80211_rx_status *rx_stats) -{ - struct net_device *dev = local->dev; - struct sta_info *sta; - u16 aid; - struct sk_buff *skb; - - PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR - " PWRMGT=%d\n", - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), - !!(le16_to_cpu(hdr->frame_control) & WLAN_FC_PWRMGT)); - - if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR - " not own MAC\n", MAC2STR(hdr->addr1)); - return; - } - - aid = __le16_to_cpu(hdr->duration_id); - if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) { - PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n"); - return; - } - aid &= ~BIT(15) & ~BIT(14); - if (aid == 0 || aid > MAX_AID_TABLE_SIZE) { - PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid); - return; - } - PDEBUG(DEBUG_PS2, " aid=%d\n", aid); - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&local->ap->sta_table_lock); - - if (sta == NULL) { - PDEBUG(DEBUG_PS, " STA not found\n"); - return; - } - if (sta->aid != aid) { - PDEBUG(DEBUG_PS, " received aid=%i does not match with " - "assoc.aid=%d\n", aid, sta->aid); - return; - } - - /* FIX: todo: - * - add timeout for buffering (clear aid in TIM vector if buffer timed - * out (expiry time must be longer than ListenInterval for - * the corresponding STA; "8802-11: 11.2.1.9 AP aging function" - * - what to do, if buffered, pspolled, and sent frame is not ACKed by - * sta; store buffer for later use and leave TIM aid bit set? use - * TX event to check whether frame was ACKed? - */ - - while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) { - /* send buffered frame .. */ - PDEBUG(DEBUG_PS2, "Sending buffered frame to STA after PS POLL" - " (buffer_count=%d)\n", skb_queue_len(&sta->tx_buf)); - - pspoll_send_buffered(local, sta, skb); - - if (sta->flags & WLAN_STA_PS) { - /* send only one buffered packet per PS Poll */ - /* FIX: should ignore further PS Polls until the - * buffered packet that was just sent is acknowledged - * (Tx or TxExc event) */ - break; - } - } - - if (skb_queue_empty(&sta->tx_buf)) { - /* try to clear aid from TIM */ - if (!(sta->flags & WLAN_STA_TIM)) - PDEBUG(DEBUG_PS2, "Re-unsetting TIM for aid %d\n", - aid); - hostap_set_tim(local, aid, 0); - sta->flags &= ~WLAN_STA_TIM; - } - - atomic_dec(&sta->users); -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - -static void handle_wds_oper_queue(void *data) -{ - local_info_t *local = data; - struct wds_oper_data *entry, *prev; - - spin_lock_bh(&local->lock); - entry = local->ap->wds_oper_entries; - local->ap->wds_oper_entries = NULL; - spin_unlock_bh(&local->lock); - - while (entry) { - PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection " - "to AP " MACSTR "\n", - local->dev->name, - entry->type == WDS_ADD ? "adding" : "removing", - MAC2STR(entry->addr)); - if (entry->type == WDS_ADD) - prism2_wds_add(local, entry->addr, 0); - else if (entry->type == WDS_DEL) - prism2_wds_del(local, entry->addr, 0, 1); - - prev = entry; - entry = entry->next; - kfree(prev); - } -} - - -/* Called only as a scheduled task for pending AP frames. */ -static void handle_beacon(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct hostap_ieee80211_hdr *hdr = - (struct hostap_ieee80211_hdr *) skb->data; - char *body = skb->data + IEEE80211_MGMT_HDR_LEN; - int len, left; - u16 *pos, beacon_int, capability; - char *ssid = NULL; - unsigned char *supp_rates = NULL; - int ssid_len = 0, supp_rates_len = 0; - struct sta_info *sta = NULL; - int new_sta = 0, channel = -1; - - len = skb->len - IEEE80211_MGMT_HDR_LEN; - - if (len < 8 + 2 + 2) { - printk(KERN_DEBUG "handle_beacon - too short payload " - "(len=%d)\n", len); - return; - } - - pos = (u16 *) body; - left = len; - - /* Timestamp (8 octets) */ - pos += 4; left -= 8; - /* Beacon interval (2 octets) */ - beacon_int = __le16_to_cpu(*pos); - pos++; left -= 2; - /* Capability information (2 octets) */ - capability = __le16_to_cpu(*pos); - pos++; left -= 2; - - if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS && - capability & WLAN_CAPABILITY_IBSS) - return; - - if (left >= 2) { - unsigned int ileft; - unsigned char *u = (unsigned char *) pos; - - if (*u == WLAN_EID_SSID) { - u++; left--; - ileft = *u; - u++; left--; - - if (ileft > left || ileft > MAX_SSID_LEN) { - PDEBUG(DEBUG_AP, "SSID: overflow\n"); - return; - } - - if (local->ap->ap_policy == AP_OTHER_AP_SAME_SSID && - (ileft != strlen(local->essid) || - memcmp(local->essid, u, ileft) != 0)) { - /* not our SSID */ - return; - } - - ssid = u; - ssid_len = ileft; - - u += ileft; - left -= ileft; - } - - if (*u == WLAN_EID_SUPP_RATES) { - u++; left--; - ileft = *u; - u++; left--; - - if (ileft > left || ileft == 0 || ileft > 8) { - PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n"); - return; - } - - supp_rates = u; - supp_rates_len = ileft; - - u += ileft; - left -= ileft; - } - - if (*u == WLAN_EID_DS_PARAMS) { - u++; left--; - ileft = *u; - u++; left--; - - if (ileft > left || ileft != 1) { - PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n"); - return; - } - - channel = *u; - - u += ileft; - left -= ileft; - } - } - - spin_lock_bh(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta != NULL) - atomic_inc(&sta->users); - spin_unlock_bh(&local->ap->sta_table_lock); - - if (sta == NULL) { - /* add new AP */ - new_sta = 1; - sta = ap_add_sta(local->ap, hdr->addr2); - if (sta == NULL) { - printk(KERN_INFO "prism2: kmalloc failed for AP " - "data structure\n"); - return; - } - hostap_event_new_sta(local->dev, sta); - - /* mark APs authentication and associated for pseudo ad-hoc - * style communication */ - sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; - - if (local->ap->autom_ap_wds) { - hostap_wds_link_oper(local, sta->addr, WDS_ADD); - } - } - - sta->ap = 1; - if (ssid) { - sta->u.ap.ssid_len = ssid_len; - memcpy(sta->u.ap.ssid, ssid, ssid_len); - sta->u.ap.ssid[ssid_len] = '\0'; - } else { - sta->u.ap.ssid_len = 0; - sta->u.ap.ssid[0] = '\0'; - } - sta->u.ap.channel = channel; - sta->rx_packets++; - sta->rx_bytes += len; - sta->u.ap.last_beacon = sta->last_rx = jiffies; - sta->capability = capability; - sta->listen_interval = beacon_int; - - atomic_dec(&sta->users); - - if (new_sta) { - memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); - memcpy(sta->supported_rates, supp_rates, supp_rates_len); - prism2_check_tx_rates(sta); - } -} - -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -/* Called only as a tasklet. */ -static void handle_ap_item(local_info_t *local, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - struct net_device *dev = local->dev; -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - u16 fc, type, stype; - struct hostap_ieee80211_hdr *hdr; - - /* FIX: should give skb->len to handler functions and check that the - * buffer is long enough */ - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - type = HOSTAP_FC_GET_TYPE(fc); - stype = HOSTAP_FC_GET_STYPE(fc); - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (!local->hostapd && type == WLAN_FC_TYPE_DATA) { - PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n"); - - if (!(fc & WLAN_FC_TODS) || (fc & WLAN_FC_FROMDS)) { - if (stype == WLAN_FC_STYPE_NULLFUNC) { - /* no ToDS nullfunc seems to be used to check - * AP association; so send reject message to - * speed up re-association */ - ap_handle_dropped_data(local, hdr); - goto done; - } - PDEBUG(DEBUG_AP, " not ToDS frame (fc=0x%04x)\n", - fc); - goto done; - } - - if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)=" - MACSTR " not own MAC\n", - MAC2STR(hdr->addr1)); - goto done; - } - - if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC) - ap_handle_data_nullfunc(local, hdr); - else - ap_handle_dropped_data(local, hdr); - goto done; - } - - if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_BEACON) { - handle_beacon(local, skb, rx_stats); - goto done; - } -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - if (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL) { - handle_pspoll(local, hdr, rx_stats); - goto done; - } - - if (local->hostapd) { - PDEBUG(DEBUG_AP, "Unknown frame in AP queue: type=0x%02x " - "subtype=0x%02x\n", type, stype); - goto done; - } - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (type != WLAN_FC_TYPE_MGMT) { - PDEBUG(DEBUG_AP, "handle_ap_item - not a management frame?\n"); - goto done; - } - - if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MACSTR - " not own MAC\n", MAC2STR(hdr->addr1)); - goto done; - } - - if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MACSTR - " not own MAC\n", MAC2STR(hdr->addr3)); - goto done; - } - - switch (stype) { - case WLAN_FC_STYPE_ASSOC_REQ: - handle_assoc(local, skb, rx_stats, 0); - break; - case WLAN_FC_STYPE_ASSOC_RESP: - PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n"); - break; - case WLAN_FC_STYPE_REASSOC_REQ: - handle_assoc(local, skb, rx_stats, 1); - break; - case WLAN_FC_STYPE_REASSOC_RESP: - PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n"); - break; - case WLAN_FC_STYPE_ATIM: - PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n"); - break; - case WLAN_FC_STYPE_DISASSOC: - handle_disassoc(local, skb, rx_stats); - break; - case WLAN_FC_STYPE_AUTH: - handle_authen(local, skb, rx_stats); - break; - case WLAN_FC_STYPE_DEAUTH: - handle_deauth(local, skb, rx_stats); - break; - default: - PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n", stype); - break; - } -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - done: - dev_kfree_skb(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -void hostap_rx(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 fc; - struct hostap_ieee80211_hdr *hdr; - - iface = netdev_priv(dev); - local = iface->local; - - if (skb->len < 16) - goto drop; - - local->stats.rx_packets++; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL && - HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && - HOSTAP_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) - goto drop; - - skb->protocol = __constant_htons(ETH_P_HOSTAP); - handle_ap_item(local, skb, rx_stats); - return; - - drop: - dev_kfree_skb(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -static void schedule_packet_send(local_info_t *local, struct sta_info *sta) -{ - struct sk_buff *skb; - struct hostap_ieee80211_hdr *hdr; - struct hostap_80211_rx_status rx_stats; - - if (skb_queue_empty(&sta->tx_buf)) - return; - - skb = dev_alloc_skb(16); - if (skb == NULL) { - printk(KERN_DEBUG "%s: schedule_packet_send: skb alloc " - "failed\n", local->dev->name); - return; - } - - hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, 16); - - /* Generate a fake pspoll frame to start packet delivery */ - hdr->frame_control = __constant_cpu_to_le16( - (WLAN_FC_TYPE_CTRL << 2) | (WLAN_FC_STYPE_PSPOLL << 4)); - memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN); - memcpy(hdr->addr2, sta->addr, ETH_ALEN); - hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14)); - - PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for " - "STA " MACSTR "\n", local->dev->name, MAC2STR(sta->addr)); - - skb->dev = local->dev; - - memset(&rx_stats, 0, sizeof(rx_stats)); - hostap_rx(local->dev, skb, &rx_stats); -} - - -static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], - struct iw_quality qual[], int buf_size, - int aplist) -{ - struct ap_data *ap = local->ap; - struct list_head *ptr; - int count = 0; - - spin_lock_bh(&ap->sta_table_lock); - - for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list; - ptr = ptr->next) { - struct sta_info *sta = (struct sta_info *) ptr; - - if (aplist && !sta->ap) - continue; - addr[count].sa_family = ARPHRD_ETHER; - memcpy(addr[count].sa_data, sta->addr, ETH_ALEN); - if (sta->last_rx_silence == 0) - qual[count].qual = sta->last_rx_signal < 27 ? - 0 : (sta->last_rx_signal - 27) * 92 / 127; - else - qual[count].qual = sta->last_rx_signal - - sta->last_rx_silence - 35; - qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); - qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); - qual[count].updated = sta->last_rx_updated; - - sta->last_rx_updated = 0; - - count++; - if (count >= buf_size) - break; - } - spin_unlock_bh(&ap->sta_table_lock); - - return count; -} - - -/* Translate our list of Access Points & Stations to a card independant - * format that the Wireless Tools will understand - Jean II */ -static int prism2_ap_translate_scan(struct net_device *dev, char *buffer) -{ - struct hostap_interface *iface; - local_info_t *local; - struct ap_data *ap; - struct list_head *ptr; - struct iw_event iwe; - char *current_ev = buffer; - char *end_buf = buffer + IW_SCAN_MAX_DATA; -#if !defined(PRISM2_NO_KERNEL_IEEE80211_MGMT) - char buf[64]; -#endif - - iface = netdev_priv(dev); - local = iface->local; - ap = local->ap; - - spin_lock_bh(&ap->sta_table_lock); - - for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list; - ptr = ptr->next) { - struct sta_info *sta = (struct sta_info *) ptr; - - /* First entry *MUST* be the AP MAC address */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN); - iwe.len = IW_EV_ADDR_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_ADDR_LEN); - - /* Use the mode to indicate if it's a station or - * an Access Point */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (sta->ap) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_INFRA; - iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_UINT_LEN); - - /* Some quality */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - if (sta->last_rx_silence == 0) - iwe.u.qual.qual = sta->last_rx_signal < 27 ? - 0 : (sta->last_rx_signal - 27) * 92 / 127; - else - iwe.u.qual.qual = sta->last_rx_signal - - sta->last_rx_silence - 35; - iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); - iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); - iwe.u.qual.updated = sta->last_rx_updated; - iwe.len = IW_EV_QUAL_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_QUAL_LEN); - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - if (sta->ap) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.length = sta->u.ap.ssid_len; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, - sta->u.ap.ssid); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - if (sta->capability & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = - IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, - sta->u.ap.ssid - /* 0 byte memcpy */); - - if (sta->u.ap.channel > 0 && - sta->u.ap.channel <= FREQ_COUNT) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = freq_list[sta->u.ap.channel - 1] - * 100000; - iwe.u.freq.e = 1; - current_ev = iwe_stream_add_event( - current_ev, end_buf, &iwe, - IW_EV_FREQ_LEN); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "beacon_interval=%d", - sta->listen_interval); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - } -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - sta->last_rx_updated = 0; - - /* To be continued, we should make good use of IWEVCUSTOM */ - } - - spin_unlock_bh(&ap->sta_table_lock); - - return current_ev - buffer; -} - - -static int prism2_hostapd_add_sta(struct ap_data *ap, - struct prism2_hostapd_param *param) -{ - struct sta_info *sta; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, param->sta_addr); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&ap->sta_table_lock); - - if (sta == NULL) { - sta = ap_add_sta(ap, param->sta_addr); - if (sta == NULL) - return -1; - } - - if (!(sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local) - hostap_event_new_sta(sta->local->dev, sta); - - sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; - sta->last_rx = jiffies; - sta->aid = param->u.add_sta.aid; - sta->capability = param->u.add_sta.capability; - sta->tx_supp_rates = param->u.add_sta.tx_supp_rates; - if (sta->tx_supp_rates & WLAN_RATE_1M) - sta->supported_rates[0] = 2; - if (sta->tx_supp_rates & WLAN_RATE_2M) - sta->supported_rates[1] = 4; - if (sta->tx_supp_rates & WLAN_RATE_5M5) - sta->supported_rates[2] = 11; - if (sta->tx_supp_rates & WLAN_RATE_11M) - sta->supported_rates[3] = 22; - prism2_check_tx_rates(sta); - atomic_dec(&sta->users); - return 0; -} - - -static int prism2_hostapd_remove_sta(struct ap_data *ap, - struct prism2_hostapd_param *param) -{ - struct sta_info *sta; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, param->sta_addr); - if (sta) { - ap_sta_hash_del(ap, sta); - list_del(&sta->list); - } - spin_unlock_bh(&ap->sta_table_lock); - - if (!sta) - return -ENOENT; - - if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local) - hostap_event_expired_sta(sta->local->dev, sta); - ap_free_sta(ap, sta); - - return 0; -} - - -static int prism2_hostapd_get_info_sta(struct ap_data *ap, - struct prism2_hostapd_param *param) -{ - struct sta_info *sta; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, param->sta_addr); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&ap->sta_table_lock); - - if (!sta) - return -ENOENT; - - param->u.get_info_sta.inactive_sec = (jiffies - sta->last_rx) / HZ; - - atomic_dec(&sta->users); - - return 1; -} - - -static int prism2_hostapd_set_flags_sta(struct ap_data *ap, - struct prism2_hostapd_param *param) -{ - struct sta_info *sta; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, param->sta_addr); - if (sta) { - sta->flags |= param->u.set_flags_sta.flags_or; - sta->flags &= param->u.set_flags_sta.flags_and; - } - spin_unlock_bh(&ap->sta_table_lock); - - if (!sta) - return -ENOENT; - - return 0; -} - - -static int prism2_hostapd_sta_clear_stats(struct ap_data *ap, - struct prism2_hostapd_param *param) -{ - struct sta_info *sta; - int rate; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, param->sta_addr); - if (sta) { - sta->rx_packets = sta->tx_packets = 0; - sta->rx_bytes = sta->tx_bytes = 0; - for (rate = 0; rate < WLAN_RATE_COUNT; rate++) { - sta->tx_count[rate] = 0; - sta->rx_count[rate] = 0; - } - } - spin_unlock_bh(&ap->sta_table_lock); - - if (!sta) - return -ENOENT; - - return 0; -} - - -static int prism2_hostapd(struct ap_data *ap, - struct prism2_hostapd_param *param) -{ - switch (param->cmd) { - case PRISM2_HOSTAPD_FLUSH: - ap_control_kickall(ap); - return 0; - case PRISM2_HOSTAPD_ADD_STA: - return prism2_hostapd_add_sta(ap, param); - case PRISM2_HOSTAPD_REMOVE_STA: - return prism2_hostapd_remove_sta(ap, param); - case PRISM2_HOSTAPD_GET_INFO_STA: - return prism2_hostapd_get_info_sta(ap, param); - case PRISM2_HOSTAPD_SET_FLAGS_STA: - return prism2_hostapd_set_flags_sta(ap, param); - case PRISM2_HOSTAPD_STA_CLEAR_STATS: - return prism2_hostapd_sta_clear_stats(ap, param); - default: - printk(KERN_WARNING "prism2_hostapd: unknown cmd=%d\n", - param->cmd); - return -EOPNOTSUPP; - } -} - - -/* Update station info for host-based TX rate control and return current - * TX rate */ -static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev) -{ - int ret = sta->tx_rate; - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - sta->tx_count[sta->tx_rate_idx]++; - sta->tx_since_last_failure++; - sta->tx_consecutive_exc = 0; - if (sta->tx_since_last_failure >= WLAN_RATE_UPDATE_COUNT && - sta->tx_rate_idx < sta->tx_max_rate) { - /* use next higher rate */ - int old_rate, new_rate; - old_rate = new_rate = sta->tx_rate_idx; - while (new_rate < sta->tx_max_rate) { - new_rate++; - if (ap_tx_rate_ok(new_rate, sta, local)) { - sta->tx_rate_idx = new_rate; - break; - } - } - if (old_rate != sta->tx_rate_idx) { - switch (sta->tx_rate_idx) { - case 0: sta->tx_rate = 10; break; - case 1: sta->tx_rate = 20; break; - case 2: sta->tx_rate = 55; break; - case 3: sta->tx_rate = 110; break; - default: sta->tx_rate = 0; break; - } - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate raised to" - " %d\n", dev->name, MAC2STR(sta->addr), - sta->tx_rate); - } - sta->tx_since_last_failure = 0; - } - - return ret; -} - - -/* Called only from software IRQ. Called for each TX frame prior possible - * encryption and transmit. */ -ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) -{ - struct sta_info *sta = NULL; - struct sk_buff *skb = tx->skb; - int set_tim, ret; - struct hostap_ieee80211_hdr *hdr; - struct hostap_skb_tx_data *meta; - - meta = (struct hostap_skb_tx_data *) skb->cb; - ret = AP_TX_CONTINUE; - if (local->ap == NULL || skb->len < 10 || - meta->iface->type == HOSTAP_INTERFACE_STA) - goto out; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - - if (hdr->addr1[0] & 0x01) { - /* broadcast/multicast frame - no AP related processing */ - goto out; - } - - /* unicast packet - check whether destination STA is associated */ - spin_lock(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr1); - if (sta) - atomic_inc(&sta->users); - spin_unlock(&local->ap->sta_table_lock); - - if (local->iw_mode == IW_MODE_MASTER && sta == NULL && !meta->wds && - meta->iface->type != HOSTAP_INTERFACE_MASTER && - meta->iface->type != HOSTAP_INTERFACE_AP) { -#if 0 - /* This can happen, e.g., when wlan0 is added to a bridge and - * bridging code does not know which port is the correct target - * for a unicast frame. In this case, the packet is send to all - * ports of the bridge. Since this is a valid scenario, do not - * print out any errors here. */ - if (net_ratelimit()) { - printk(KERN_DEBUG "AP: drop packet to non-associated " - "STA " MACSTR "\n", MAC2STR(hdr->addr1)); - } -#endif - local->ap->tx_drop_nonassoc++; - ret = AP_TX_DROP; - goto out; - } - - if (sta == NULL) - goto out; - - if (!(sta->flags & WLAN_STA_AUTHORIZED)) - ret = AP_TX_CONTINUE_NOT_AUTHORIZED; - - /* Set tx_rate if using host-based TX rate control */ - if (!local->fw_tx_rate_control) - local->ap->last_tx_rate = meta->rate = - ap_update_sta_tx_rate(sta, local->dev); - - if (local->iw_mode != IW_MODE_MASTER) - goto out; - - if (!(sta->flags & WLAN_STA_PS)) - goto out; - - if (memcmp(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN) == 0) { - if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_ADD_MOREDATA) { - /* indicate to STA that more frames follow */ - hdr->frame_control |= - __constant_cpu_to_le16(WLAN_FC_MOREDATA); - } - - if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_BUFFERED_FRAME) { - /* packet was already buffered and now send due to - * PS poll, so do not rebuffer it */ - goto out; - } - } - - if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) { - PDEBUG(DEBUG_PS, "%s: No more space in STA (" MACSTR ")'s PS " - "mode buffer\n", local->dev->name, MAC2STR(sta->addr)); - /* Make sure that TIM is set for the station (it might not be - * after AP wlan hw reset). */ - /* FIX: should fix hw reset to restore bits based on STA - * buffer state.. */ - hostap_set_tim(local, sta->aid, 1); - sta->flags |= WLAN_STA_TIM; - ret = AP_TX_DROP; - goto out; - } - - /* STA in PS mode, buffer frame for later delivery */ - set_tim = skb_queue_empty(&sta->tx_buf); - skb_queue_tail(&sta->tx_buf, skb); - /* FIX: could save RX time to skb and expire buffered frames after - * some time if STA does not poll for them */ - - if (set_tim) { - if (sta->flags & WLAN_STA_TIM) - PDEBUG(DEBUG_PS2, "Re-setting TIM for aid %d\n", - sta->aid); - hostap_set_tim(local, sta->aid, 1); - sta->flags |= WLAN_STA_TIM; - } - - ret = AP_TX_BUFFERED; - - out: - if (sta != NULL) { - if (ret == AP_TX_CONTINUE || - ret == AP_TX_CONTINUE_NOT_AUTHORIZED) { - sta->tx_packets++; - sta->tx_bytes += skb->len; - sta->last_tx = jiffies; - } - - if ((ret == AP_TX_CONTINUE || - ret == AP_TX_CONTINUE_NOT_AUTHORIZED) && - sta->crypt && tx->host_encrypt) { - tx->crypt = sta->crypt; - tx->sta_ptr = sta; /* hostap_handle_sta_release() will - * be called to release sta info - * later */ - } else - atomic_dec(&sta->users); - } - - return ret; -} - - -void hostap_handle_sta_release(void *ptr) -{ - struct sta_info *sta = ptr; - atomic_dec(&sta->users); -} - - -/* Called only as a tasklet (software IRQ) */ -void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb) -{ - struct sta_info *sta; - struct hostap_ieee80211_hdr *hdr; - struct hostap_skb_tx_data *meta; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - meta = (struct hostap_skb_tx_data *) skb->cb; - - spin_lock(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr1); - if (!sta) { - spin_unlock(&local->ap->sta_table_lock); - PDEBUG(DEBUG_AP, "%s: Could not find STA " MACSTR " for this " - "TX error (@%lu)\n", - local->dev->name, MAC2STR(hdr->addr1), jiffies); - return; - } - - sta->tx_since_last_failure = 0; - sta->tx_consecutive_exc++; - - if (sta->tx_consecutive_exc >= WLAN_RATE_DECREASE_THRESHOLD && - sta->tx_rate_idx > 0 && meta->rate <= sta->tx_rate) { - /* use next lower rate */ - int old, rate; - old = rate = sta->tx_rate_idx; - while (rate > 0) { - rate--; - if (ap_tx_rate_ok(rate, sta, local)) { - sta->tx_rate_idx = rate; - break; - } - } - if (old != sta->tx_rate_idx) { - switch (sta->tx_rate_idx) { - case 0: sta->tx_rate = 10; break; - case 1: sta->tx_rate = 20; break; - case 2: sta->tx_rate = 55; break; - case 3: sta->tx_rate = 110; break; - default: sta->tx_rate = 0; break; - } - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate lowered " - "to %d\n", local->dev->name, MAC2STR(sta->addr), - sta->tx_rate); - } - sta->tx_consecutive_exc = 0; - } - spin_unlock(&local->ap->sta_table_lock); -} - - -static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta, - int pwrmgt, int type, int stype) -{ - if (pwrmgt && !(sta->flags & WLAN_STA_PS)) { - sta->flags |= WLAN_STA_PS; - PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to use PS " - "mode (type=0x%02X, stype=0x%02X)\n", - MAC2STR(sta->addr), type, stype); - } else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) { - sta->flags &= ~WLAN_STA_PS; - PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to not use " - "PS mode (type=0x%02X, stype=0x%02X)\n", - MAC2STR(sta->addr), type, stype); - if (type != WLAN_FC_TYPE_CTRL || stype != WLAN_FC_STYPE_PSPOLL) - schedule_packet_send(local, sta); - } -} - - -/* Called only as a tasklet (software IRQ). Called for each RX frame to update - * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */ -int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr) -{ - struct sta_info *sta; - u16 fc; - - spin_lock(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta) - atomic_inc(&sta->users); - spin_unlock(&local->ap->sta_table_lock); - - if (!sta) - return -1; - - fc = le16_to_cpu(hdr->frame_control); - hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT, - HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc)); - - atomic_dec(&sta->users); - return 0; -} - - -/* Called only as a tasklet (software IRQ). Called for each RX frame after - * getting RX header and payload from hardware. */ -ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, - struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats, - int wds) -{ - int ret; - struct sta_info *sta; - u16 fc, type, stype; - struct hostap_ieee80211_hdr *hdr; - - if (local->ap == NULL) - return AP_RX_CONTINUE; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - - fc = le16_to_cpu(hdr->frame_control); - type = HOSTAP_FC_GET_TYPE(fc); - stype = HOSTAP_FC_GET_STYPE(fc); - - spin_lock(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta) - atomic_inc(&sta->users); - spin_unlock(&local->ap->sta_table_lock); - - if (sta && !(sta->flags & WLAN_STA_AUTHORIZED)) - ret = AP_RX_CONTINUE_NOT_AUTHORIZED; - else - ret = AP_RX_CONTINUE; - - - if (fc & WLAN_FC_TODS) { - if (!wds && (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) { - if (local->hostapd) { - prism2_rx_80211(local->apdev, skb, rx_stats, - PRISM2_RX_NON_ASSOC); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - } else { - printk(KERN_DEBUG "%s: dropped received packet" - " from non-associated STA " MACSTR - " (type=0x%02x, subtype=0x%02x)\n", - dev->name, MAC2STR(hdr->addr2), type, - stype); - hostap_rx(dev, skb, rx_stats); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - } - ret = AP_RX_EXIT; - goto out; - } - } else if (fc & WLAN_FC_FROMDS) { - if (!wds) { - /* FromDS frame - not for us; probably - * broadcast/multicast in another BSS - drop */ - if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - printk(KERN_DEBUG "Odd.. FromDS packet " - "received with own BSSID\n"); - hostap_dump_rx_80211(dev->name, skb, rx_stats); - } - ret = AP_RX_DROP; - goto out; - } - } else if (stype == WLAN_FC_STYPE_NULLFUNC && sta == NULL && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - - if (local->hostapd) { - prism2_rx_80211(local->apdev, skb, rx_stats, - PRISM2_RX_NON_ASSOC); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - } else { - /* At least Lucent f/w seems to send data::nullfunc - * frames with no ToDS flag when the current AP returns - * after being unavailable for some time. Speed up - * re-association by informing the station about it not - * being associated. */ - printk(KERN_DEBUG "%s: rejected received nullfunc " - "frame without ToDS from not associated STA " - MACSTR "\n", - dev->name, MAC2STR(hdr->addr2)); - hostap_rx(dev, skb, rx_stats); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - } - ret = AP_RX_EXIT; - goto out; - } else if (stype == WLAN_FC_STYPE_NULLFUNC) { - /* At least Lucent cards seem to send periodic nullfunc - * frames with ToDS. Let these through to update SQ - * stats and PS state. Nullfunc frames do not contain - * any data and they will be dropped below. */ - } else { - /* If BSSID (Addr3) is foreign, this frame is a normal - * broadcast frame from an IBSS network. Drop it silently. - * If BSSID is own, report the dropping of this frame. */ - if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { - printk(KERN_DEBUG "%s: dropped received packet from " - MACSTR " with no ToDS flag (type=0x%02x, " - "subtype=0x%02x)\n", dev->name, - MAC2STR(hdr->addr2), type, stype); - hostap_dump_rx_80211(dev->name, skb, rx_stats); - } - ret = AP_RX_DROP; - goto out; - } - - if (sta) { - hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT, - type, stype); - - sta->rx_packets++; - sta->rx_bytes += skb->len; - sta->last_rx = jiffies; - } - - if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC && - fc & WLAN_FC_TODS) { - if (local->hostapd) { - prism2_rx_80211(local->apdev, skb, rx_stats, - PRISM2_RX_NULLFUNC_ACK); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - } else { - /* some STA f/w's seem to require control::ACK frame - * for data::nullfunc, but Prism2 f/w 0.8.0 (at least - * from Compaq) does not send this.. Try to generate - * ACK for these frames from the host driver to make - * power saving work with, e.g., Lucent WaveLAN f/w */ - hostap_rx(dev, skb, rx_stats); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - } - ret = AP_RX_EXIT; - goto out; - } - - out: - if (sta) - atomic_dec(&sta->users); - - return ret; -} - - -/* Called only as a tasklet (software IRQ) */ -int hostap_handle_sta_crypto(local_info_t *local, - struct hostap_ieee80211_hdr *hdr, - struct ieee80211_crypt_data **crypt, - void **sta_ptr) -{ - struct sta_info *sta; - - spin_lock(&local->ap->sta_table_lock); - sta = ap_get_sta(local->ap, hdr->addr2); - if (sta) - atomic_inc(&sta->users); - spin_unlock(&local->ap->sta_table_lock); - - if (!sta) - return -1; - - if (sta->crypt) { - *crypt = sta->crypt; - *sta_ptr = sta; - /* hostap_handle_sta_release() will be called to release STA - * info */ - } else - atomic_dec(&sta->users); - - return 0; -} - - -/* Called only as a tasklet (software IRQ) */ -int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr) -{ - struct sta_info *sta; - int ret = 0; - - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, sta_addr); - if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap) - ret = 1; - spin_unlock(&ap->sta_table_lock); - - return ret; -} - - -/* Called only as a tasklet (software IRQ) */ -int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr) -{ - struct sta_info *sta; - int ret = 0; - - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, sta_addr); - if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap && - ((sta->flags & WLAN_STA_AUTHORIZED) || - ap->local->ieee_802_1x == 0)) - ret = 1; - spin_unlock(&ap->sta_table_lock); - - return ret; -} - - -/* Called only as a tasklet (software IRQ) */ -int hostap_add_sta(struct ap_data *ap, u8 *sta_addr) -{ - struct sta_info *sta; - int ret = 1; - - if (!ap) - return -1; - - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, sta_addr); - if (sta) - ret = 0; - spin_unlock(&ap->sta_table_lock); - - if (ret == 1) { - sta = ap_add_sta(ap, sta_addr); - if (!sta) - ret = -1; - sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; - sta->ap = 1; - memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); - /* No way of knowing which rates are supported since we did not - * get supported rates element from beacon/assoc req. Assume - * that remote end supports all 802.11b rates. */ - sta->supported_rates[0] = 0x82; - sta->supported_rates[1] = 0x84; - sta->supported_rates[2] = 0x0b; - sta->supported_rates[3] = 0x16; - sta->tx_supp_rates = WLAN_RATE_1M | WLAN_RATE_2M | - WLAN_RATE_5M5 | WLAN_RATE_11M; - sta->tx_rate = 110; - sta->tx_max_rate = sta->tx_rate_idx = 3; - } - - return ret; -} - - -/* Called only as a tasklet (software IRQ) */ -int hostap_update_rx_stats(struct ap_data *ap, - struct hostap_ieee80211_hdr *hdr, - struct hostap_80211_rx_status *rx_stats) -{ - struct sta_info *sta; - - if (!ap) - return -1; - - spin_lock(&ap->sta_table_lock); - sta = ap_get_sta(ap, hdr->addr2); - if (sta) { - sta->last_rx_silence = rx_stats->noise; - sta->last_rx_signal = rx_stats->signal; - sta->last_rx_rate = rx_stats->rate; - sta->last_rx_updated = 7; - if (rx_stats->rate == 10) - sta->rx_count[0]++; - else if (rx_stats->rate == 20) - sta->rx_count[1]++; - else if (rx_stats->rate == 55) - sta->rx_count[2]++; - else if (rx_stats->rate == 110) - sta->rx_count[3]++; - } - spin_unlock(&ap->sta_table_lock); - - return sta ? 0 : -1; -} - - -void hostap_update_rates(local_info_t *local) -{ - struct list_head *ptr; - struct ap_data *ap = local->ap; - - if (!ap) - return; - - spin_lock_bh(&ap->sta_table_lock); - for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) { - struct sta_info *sta = (struct sta_info *) ptr; - prism2_check_tx_rates(sta); - } - spin_unlock_bh(&ap->sta_table_lock); -} - - -static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct ieee80211_crypt_data ***crypt) -{ - struct sta_info *sta; - - spin_lock_bh(&ap->sta_table_lock); - sta = ap_get_sta(ap, addr); - if (sta) - atomic_inc(&sta->users); - spin_unlock_bh(&ap->sta_table_lock); - - if (!sta && permanent) - sta = ap_add_sta(ap, addr); - - if (!sta) - return NULL; - - if (permanent) - sta->flags |= WLAN_STA_PERM; - - *crypt = &sta->crypt; - - return sta; -} - - -void hostap_add_wds_links(local_info_t *local) -{ - struct ap_data *ap = local->ap; - struct list_head *ptr; - - spin_lock_bh(&ap->sta_table_lock); - list_for_each(ptr, &ap->sta_list) { - struct sta_info *sta = list_entry(ptr, struct sta_info, list); - if (sta->ap) - hostap_wds_link_oper(local, sta->addr, WDS_ADD); - } - spin_unlock_bh(&ap->sta_table_lock); - - schedule_work(&local->ap->wds_oper_queue); -} - - -void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type) -{ - struct wds_oper_data *entry; - - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); - if (!entry) - return; - memcpy(entry->addr, addr, ETH_ALEN); - entry->type = type; - spin_lock_bh(&local->lock); - entry->next = local->ap->wds_oper_entries; - local->ap->wds_oper_entries = entry; - spin_unlock_bh(&local->lock); - - schedule_work(&local->ap->wds_oper_queue); -} - - -EXPORT_SYMBOL(hostap_init_data); -EXPORT_SYMBOL(hostap_init_ap_proc); -EXPORT_SYMBOL(hostap_free_data); -EXPORT_SYMBOL(hostap_check_sta_fw_version); -EXPORT_SYMBOL(hostap_handle_sta_tx); -EXPORT_SYMBOL(hostap_handle_sta_release); -EXPORT_SYMBOL(hostap_handle_sta_tx_exc); -EXPORT_SYMBOL(hostap_update_sta_ps); -EXPORT_SYMBOL(hostap_handle_sta_rx); -EXPORT_SYMBOL(hostap_is_sta_assoc); -EXPORT_SYMBOL(hostap_is_sta_authorized); -EXPORT_SYMBOL(hostap_add_sta); -EXPORT_SYMBOL(hostap_update_rates); -EXPORT_SYMBOL(hostap_add_wds_links); -EXPORT_SYMBOL(hostap_wds_link_oper); -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -EXPORT_SYMBOL(hostap_deauth_all_stas); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_ap.h b/trunk/drivers/net/wireless/hostap/hostap_ap.h deleted file mode 100644 index 137f78e4532b..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_ap.h +++ /dev/null @@ -1,273 +0,0 @@ -#ifndef HOSTAP_AP_H -#define HOSTAP_AP_H - -/* AP data structures for STAs */ - -/* maximum number of frames to buffer per STA */ -#define STA_MAX_TX_BUFFER 32 - -/* Flags used in skb->cb[6] to control how the packet is handled in TX path. - * skb->cb[0..5] must contain magic value 'hostap' to indicate that cb[6] is - * used. */ -#define AP_SKB_CB_MAGIC "hostap" -#define AP_SKB_CB_MAGIC_LEN 6 -#define AP_SKB_CB_BUFFERED_FRAME BIT(0) -#define AP_SKB_CB_ADD_MOREDATA BIT(1) - - -/* STA flags */ -#define WLAN_STA_AUTH BIT(0) -#define WLAN_STA_ASSOC BIT(1) -#define WLAN_STA_PS BIT(2) -#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */ -#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */ -#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is - * controlling whether STA is authorized to - * send and receive non-IEEE 802.1X frames - */ -#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ - -#define WLAN_RATE_1M BIT(0) -#define WLAN_RATE_2M BIT(1) -#define WLAN_RATE_5M5 BIT(2) -#define WLAN_RATE_11M BIT(3) -#define WLAN_RATE_COUNT 4 - -/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8, - * but some pre-standard IEEE 802.11g products use longer elements. */ -#define WLAN_SUPP_RATES_MAX 32 - -/* Try to increase TX rate after # successfully sent consecutive packets */ -#define WLAN_RATE_UPDATE_COUNT 50 - -/* Decrease TX rate after # consecutive dropped packets */ -#define WLAN_RATE_DECREASE_THRESHOLD 2 - -struct sta_info { - struct list_head list; - struct sta_info *hnext; /* next entry in hash table list */ - atomic_t users; /* number of users (do not remove if > 0) */ - struct proc_dir_entry *proc; - - u8 addr[6]; - u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */ - u32 flags; - u16 capability; - u16 listen_interval; /* or beacon_int for APs */ - u8 supported_rates[WLAN_SUPP_RATES_MAX]; - - unsigned long last_auth; - unsigned long last_assoc; - unsigned long last_rx; - unsigned long last_tx; - unsigned long rx_packets, tx_packets; - unsigned long rx_bytes, tx_bytes; - struct sk_buff_head tx_buf; - /* FIX: timeout buffers with an expiry time somehow derived from - * listen_interval */ - - s8 last_rx_silence; /* Noise in dBm */ - s8 last_rx_signal; /* Signal strength in dBm */ - u8 last_rx_rate; /* TX rate in 0.1 Mbps */ - u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */ - - u8 tx_supp_rates; /* bit field of supported TX rates */ - u8 tx_rate; /* current TX rate (in 0.1 Mbps) */ - u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */ - u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */ - u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */ - u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate) - */ - u32 tx_since_last_failure; - u32 tx_consecutive_exc; - - struct ieee80211_crypt_data *crypt; - - int ap; /* whether this station is an AP */ - - local_info_t *local; - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - union { - struct { - char *challenge; /* shared key authentication - * challenge */ - } sta; - struct { - int ssid_len; - unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */ - int channel; - unsigned long last_beacon; /* last RX beacon time */ - } ap; - } u; - - struct timer_list timer; - enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next; -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ -}; - - -#define MAX_STA_COUNT 1024 - -/* Maximum number of AIDs to use for STAs; must be 2007 or lower - * (8802.11 limitation) */ -#define MAX_AID_TABLE_SIZE 128 - -#define STA_HASH_SIZE 256 -#define STA_HASH(sta) (sta[5]) - - -/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC - * has passed since last received frame from the station, a nullfunc data - * frame is sent to the station. If this frame is not acknowledged and no other - * frames have been received, the station will be disassociated after - * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after - * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with - * max inactivity timer. */ -#define AP_MAX_INACTIVITY_SEC (5 * 60) -#define AP_DISASSOC_DELAY (HZ) -#define AP_DEAUTH_DELAY (HZ) - -/* ap_policy: whether to accept frames to/from other APs/IBSS */ -typedef enum { - AP_OTHER_AP_SKIP_ALL = 0, - AP_OTHER_AP_SAME_SSID = 1, - AP_OTHER_AP_ALL = 2, - AP_OTHER_AP_EVEN_IBSS = 3 -} ap_policy_enum; - -#define PRISM2_AUTH_OPEN BIT(0) -#define PRISM2_AUTH_SHARED_KEY BIT(1) - - -/* MAC address-based restrictions */ -struct mac_entry { - struct list_head list; - u8 addr[6]; -}; - -struct mac_restrictions { - enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy; - unsigned int entries; - struct list_head mac_list; - spinlock_t lock; -}; - - -struct add_sta_proc_data { - u8 addr[ETH_ALEN]; - struct add_sta_proc_data *next; -}; - - -typedef enum { WDS_ADD, WDS_DEL } wds_oper_type; -struct wds_oper_data { - wds_oper_type type; - u8 addr[ETH_ALEN]; - struct wds_oper_data *next; -}; - - -struct ap_data { - int initialized; /* whether ap_data has been initialized */ - local_info_t *local; - int bridge_packets; /* send packet to associated STAs directly to the - * wireless media instead of higher layers in the - * kernel */ - unsigned int bridged_unicast; /* number of unicast frames bridged on - * wireless media */ - unsigned int bridged_multicast; /* number of non-unicast frames - * bridged on wireless media */ - unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped - * because they were to an address that - * was not associated */ - int nullfunc_ack; /* use workaround for nullfunc frame ACKs */ - - spinlock_t sta_table_lock; - int num_sta; /* number of entries in sta_list */ - struct list_head sta_list; /* STA info list head */ - struct sta_info *sta_hash[STA_HASH_SIZE]; - - struct proc_dir_entry *proc; - - ap_policy_enum ap_policy; - unsigned int max_inactivity; - int autom_ap_wds; - - struct mac_restrictions mac_restrictions; /* MAC-based auth */ - int last_tx_rate; - - struct work_struct add_sta_proc_queue; - struct add_sta_proc_data *add_sta_proc_entries; - - struct work_struct wds_oper_queue; - struct wds_oper_data *wds_oper_entries; - - u16 tx_callback_idx; - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - /* pointers to STA info; based on allocated AID or NULL if AID free - * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 - * and so on - */ - struct sta_info *sta_aid[MAX_AID_TABLE_SIZE]; - - u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll; - - /* WEP operations for generating challenges to be used with shared key - * authentication */ - struct ieee80211_crypto_ops *crypt; - void *crypt_priv; -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ -}; - - -void hostap_rx(struct net_device *dev, struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats); -void hostap_init_data(local_info_t *local); -void hostap_init_ap_proc(local_info_t *local); -void hostap_free_data(struct ap_data *ap); -void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver); - -typedef enum { - AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED, - AP_TX_CONTINUE_NOT_AUTHORIZED -} ap_tx_ret; -struct hostap_tx_data { - struct sk_buff *skb; - int host_encrypt; - struct ieee80211_crypt_data *crypt; - void *sta_ptr; -}; -ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); -void hostap_handle_sta_release(void *ptr); -void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb); -int hostap_update_sta_ps(local_info_t *local, - struct hostap_ieee80211_hdr *hdr); -typedef enum { - AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED -} ap_rx_ret; -ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, - struct sk_buff *skb, - struct hostap_80211_rx_status *rx_stats, - int wds); -int hostap_handle_sta_crypto(local_info_t *local, - struct hostap_ieee80211_hdr *hdr, - struct ieee80211_crypt_data **crypt, - void **sta_ptr); -int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); -int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); -int hostap_add_sta(struct ap_data *ap, u8 *sta_addr); -int hostap_update_rx_stats(struct ap_data *ap, - struct hostap_ieee80211_hdr *hdr, - struct hostap_80211_rx_status *rx_stats); -void hostap_update_rates(local_info_t *local); -void hostap_add_wds_links(local_info_t *local); -void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type); - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap, - int resend); -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - -#endif /* HOSTAP_AP_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_common.h b/trunk/drivers/net/wireless/hostap/hostap_common.h deleted file mode 100644 index 3b79d9e95e6f..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_common.h +++ /dev/null @@ -1,499 +0,0 @@ -#ifndef HOSTAP_COMMON_H -#define HOSTAP_COMMON_H - -#define BIT(x) (1 << (x)) - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ - - - -/* IEEE 802.11 defines */ - -#define WLAN_FC_PVER (BIT(1) | BIT(0)) -#define WLAN_FC_TODS BIT(8) -#define WLAN_FC_FROMDS BIT(9) -#define WLAN_FC_MOREFRAG BIT(10) -#define WLAN_FC_RETRY BIT(11) -#define WLAN_FC_PWRMGT BIT(12) -#define WLAN_FC_MOREDATA BIT(13) -#define WLAN_FC_ISWEP BIT(14) -#define WLAN_FC_ORDER BIT(15) - -/* - * To be replaced with ieee80211.h WLAN_FC_GET_* once HostAP code is updated to - * use the versions without right shift. - */ -#define HOSTAP_FC_GET_TYPE(fc) (((fc) & (BIT(3) | BIT(2))) >> 2) -#define HOSTAP_FC_GET_STYPE(fc) \ - (((fc) & (BIT(7) | BIT(6) | BIT(5) | BIT(4))) >> 4) - -#define WLAN_FC_TYPE_MGMT 0 -#define WLAN_FC_TYPE_CTRL 1 -#define WLAN_FC_TYPE_DATA 2 - -/* management */ -#define WLAN_FC_STYPE_ASSOC_REQ 0 -#define WLAN_FC_STYPE_ASSOC_RESP 1 -#define WLAN_FC_STYPE_REASSOC_REQ 2 -#define WLAN_FC_STYPE_REASSOC_RESP 3 -#define WLAN_FC_STYPE_PROBE_REQ 4 -#define WLAN_FC_STYPE_PROBE_RESP 5 -#define WLAN_FC_STYPE_BEACON 8 -#define WLAN_FC_STYPE_ATIM 9 -#define WLAN_FC_STYPE_DISASSOC 10 -#define WLAN_FC_STYPE_AUTH 11 -#define WLAN_FC_STYPE_DEAUTH 12 - -/* control */ -#define WLAN_FC_STYPE_PSPOLL 10 -#define WLAN_FC_STYPE_RTS 11 -#define WLAN_FC_STYPE_CTS 12 -#define WLAN_FC_STYPE_ACK 13 -#define WLAN_FC_STYPE_CFEND 14 -#define WLAN_FC_STYPE_CFENDACK 15 - -/* data */ -#define WLAN_FC_STYPE_DATA 0 -#define WLAN_FC_STYPE_DATA_CFACK 1 -#define WLAN_FC_STYPE_DATA_CFPOLL 2 -#define WLAN_FC_STYPE_DATA_CFACKPOLL 3 -#define WLAN_FC_STYPE_NULLFUNC 4 -#define WLAN_FC_STYPE_CFACK 5 -#define WLAN_FC_STYPE_CFPOLL 6 -#define WLAN_FC_STYPE_CFACKPOLL 7 - -#define WLAN_CAPABILITY_ESS WLAN_CAPABILITY_BSS - - -/* Information Element IDs */ -#define WLAN_EID_SSID 0 -#define WLAN_EID_SUPP_RATES 1 -#define WLAN_EID_FH_PARAMS 2 -#define WLAN_EID_DS_PARAMS 3 -#define WLAN_EID_CF_PARAMS 4 -#define WLAN_EID_TIM 5 -#define WLAN_EID_IBSS_PARAMS 6 -#define WLAN_EID_CHALLENGE 16 -#define WLAN_EID_RSN 48 -#define WLAN_EID_GENERIC 221 - - -/* HFA384X Configuration RIDs */ -#define HFA384X_RID_CNFPORTTYPE 0xFC00 -#define HFA384X_RID_CNFOWNMACADDR 0xFC01 -#define HFA384X_RID_CNFDESIREDSSID 0xFC02 -#define HFA384X_RID_CNFOWNCHANNEL 0xFC03 -#define HFA384X_RID_CNFOWNSSID 0xFC04 -#define HFA384X_RID_CNFOWNATIMWINDOW 0xFC05 -#define HFA384X_RID_CNFSYSTEMSCALE 0xFC06 -#define HFA384X_RID_CNFMAXDATALEN 0xFC07 -#define HFA384X_RID_CNFWDSADDRESS 0xFC08 -#define HFA384X_RID_CNFPMENABLED 0xFC09 -#define HFA384X_RID_CNFPMEPS 0xFC0A -#define HFA384X_RID_CNFMULTICASTRECEIVE 0xFC0B -#define HFA384X_RID_CNFMAXSLEEPDURATION 0xFC0C -#define HFA384X_RID_CNFPMHOLDOVERDURATION 0xFC0D -#define HFA384X_RID_CNFOWNNAME 0xFC0E -#define HFA384X_RID_CNFOWNDTIMPERIOD 0xFC10 -#define HFA384X_RID_CNFWDSADDRESS1 0xFC11 /* AP f/w only */ -#define HFA384X_RID_CNFWDSADDRESS2 0xFC12 /* AP f/w only */ -#define HFA384X_RID_CNFWDSADDRESS3 0xFC13 /* AP f/w only */ -#define HFA384X_RID_CNFWDSADDRESS4 0xFC14 /* AP f/w only */ -#define HFA384X_RID_CNFWDSADDRESS5 0xFC15 /* AP f/w only */ -#define HFA384X_RID_CNFWDSADDRESS6 0xFC16 /* AP f/w only */ -#define HFA384X_RID_CNFMULTICASTPMBUFFERING 0xFC17 /* AP f/w only */ -#define HFA384X_RID_UNKNOWN1 0xFC20 -#define HFA384X_RID_UNKNOWN2 0xFC21 -#define HFA384X_RID_CNFWEPDEFAULTKEYID 0xFC23 -#define HFA384X_RID_CNFDEFAULTKEY0 0xFC24 -#define HFA384X_RID_CNFDEFAULTKEY1 0xFC25 -#define HFA384X_RID_CNFDEFAULTKEY2 0xFC26 -#define HFA384X_RID_CNFDEFAULTKEY3 0xFC27 -#define HFA384X_RID_CNFWEPFLAGS 0xFC28 -#define HFA384X_RID_CNFWEPKEYMAPPINGTABLE 0xFC29 -#define HFA384X_RID_CNFAUTHENTICATION 0xFC2A -#define HFA384X_RID_CNFMAXASSOCSTA 0xFC2B /* AP f/w only */ -#define HFA384X_RID_CNFTXCONTROL 0xFC2C -#define HFA384X_RID_CNFROAMINGMODE 0xFC2D -#define HFA384X_RID_CNFHOSTAUTHENTICATION 0xFC2E /* AP f/w only */ -#define HFA384X_RID_CNFRCVCRCERROR 0xFC30 -#define HFA384X_RID_CNFMMLIFE 0xFC31 -#define HFA384X_RID_CNFALTRETRYCOUNT 0xFC32 -#define HFA384X_RID_CNFBEACONINT 0xFC33 -#define HFA384X_RID_CNFAPPCFINFO 0xFC34 /* AP f/w only */ -#define HFA384X_RID_CNFSTAPCFINFO 0xFC35 -#define HFA384X_RID_CNFPRIORITYQUSAGE 0xFC37 -#define HFA384X_RID_CNFTIMCTRL 0xFC40 -#define HFA384X_RID_UNKNOWN3 0xFC41 /* added in STA f/w 0.7.x */ -#define HFA384X_RID_CNFTHIRTY2TALLY 0xFC42 /* added in STA f/w 0.8.0 */ -#define HFA384X_RID_CNFENHSECURITY 0xFC43 /* AP f/w or STA f/w >= 1.6.3 */ -#define HFA384X_RID_CNFDBMADJUST 0xFC46 /* added in STA f/w 1.3.1 */ -#define HFA384X_RID_GENERICELEMENT 0xFC48 /* added in STA f/w 1.7.0; - * write only */ -#define HFA384X_RID_PROPAGATIONDELAY 0xFC49 /* added in STA f/w 1.7.6 */ -#define HFA384X_RID_GROUPADDRESSES 0xFC80 -#define HFA384X_RID_CREATEIBSS 0xFC81 -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD 0xFC82 -#define HFA384X_RID_RTSTHRESHOLD 0xFC83 -#define HFA384X_RID_TXRATECONTROL 0xFC84 -#define HFA384X_RID_PROMISCUOUSMODE 0xFC85 -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD0 0xFC90 /* AP f/w only */ -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD1 0xFC91 /* AP f/w only */ -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD2 0xFC92 /* AP f/w only */ -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD3 0xFC93 /* AP f/w only */ -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD4 0xFC94 /* AP f/w only */ -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD5 0xFC95 /* AP f/w only */ -#define HFA384X_RID_FRAGMENTATIONTHRESHOLD6 0xFC96 /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD0 0xFC97 /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD1 0xFC98 /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD2 0xFC99 /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD3 0xFC9A /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD4 0xFC9B /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD5 0xFC9C /* AP f/w only */ -#define HFA384X_RID_RTSTHRESHOLD6 0xFC9D /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL0 0xFC9E /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL1 0xFC9F /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL2 0xFCA0 /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL3 0xFCA1 /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL4 0xFCA2 /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL5 0xFCA3 /* AP f/w only */ -#define HFA384X_RID_TXRATECONTROL6 0xFCA4 /* AP f/w only */ -#define HFA384X_RID_CNFSHORTPREAMBLE 0xFCB0 -#define HFA384X_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1 -#define HFA384X_RID_CNFAUTHENTICATIONRSPTO 0xFCB2 -#define HFA384X_RID_CNFBASICRATES 0xFCB3 -#define HFA384X_RID_CNFSUPPORTEDRATES 0xFCB4 -#define HFA384X_RID_CNFFALLBACKCTRL 0xFCB5 /* added in STA f/w 1.3.1 */ -#define HFA384X_RID_WEPKEYDISABLE 0xFCB6 /* added in STA f/w 1.3.1 */ -#define HFA384X_RID_WEPKEYMAPINDEX 0xFCB7 /* ? */ -#define HFA384X_RID_BROADCASTKEYID 0xFCB8 /* ? */ -#define HFA384X_RID_ENTSECFLAGEYID 0xFCB9 /* ? */ -#define HFA384X_RID_CNFPASSIVESCANCTRL 0xFCBA /* added in STA f/w 1.5.0 */ -#define HFA384X_RID_SSNHANDLINGMODE 0xFCBB /* added in STA f/w 1.7.0 */ -#define HFA384X_RID_MDCCONTROL 0xFCBC /* added in STA f/w 1.7.0 */ -#define HFA384X_RID_MDCCOUNTRY 0xFCBD /* added in STA f/w 1.7.0 */ -#define HFA384X_RID_TXPOWERMAX 0xFCBE /* added in STA f/w 1.7.0 */ -#define HFA384X_RID_CNFLFOENABLED 0xFCBF /* added in STA f/w 1.6.3 */ -#define HFA384X_RID_CAPINFO 0xFCC0 /* added in STA f/w 1.7.0 */ -#define HFA384X_RID_LISTENINTERVAL 0xFCC1 /* added in STA f/w 1.7.0 */ -#define HFA384X_RID_SW_ANT_DIV 0xFCC2 /* added in STA f/w 1.7.0; Prism3 */ -#define HFA384X_RID_LED_CTRL 0xFCC4 /* added in STA f/w 1.7.6 */ -#define HFA384X_RID_HFODELAY 0xFCC5 /* added in STA f/w 1.7.6 */ -#define HFA384X_RID_DISALLOWEDBSSID 0xFCC6 /* added in STA f/w 1.8.0 */ -#define HFA384X_RID_TICKTIME 0xFCE0 -#define HFA384X_RID_SCANREQUEST 0xFCE1 -#define HFA384X_RID_JOINREQUEST 0xFCE2 -#define HFA384X_RID_AUTHENTICATESTATION 0xFCE3 /* AP f/w only */ -#define HFA384X_RID_CHANNELINFOREQUEST 0xFCE4 /* AP f/w only */ -#define HFA384X_RID_HOSTSCAN 0xFCE5 /* added in STA f/w 1.3.1 */ - -/* HFA384X Information RIDs */ -#define HFA384X_RID_MAXLOADTIME 0xFD00 -#define HFA384X_RID_DOWNLOADBUFFER 0xFD01 -#define HFA384X_RID_PRIID 0xFD02 -#define HFA384X_RID_PRISUPRANGE 0xFD03 -#define HFA384X_RID_CFIACTRANGES 0xFD04 -#define HFA384X_RID_NICSERNUM 0xFD0A -#define HFA384X_RID_NICID 0xFD0B -#define HFA384X_RID_MFISUPRANGE 0xFD0C -#define HFA384X_RID_CFISUPRANGE 0xFD0D -#define HFA384X_RID_CHANNELLIST 0xFD10 -#define HFA384X_RID_REGULATORYDOMAINS 0xFD11 -#define HFA384X_RID_TEMPTYPE 0xFD12 -#define HFA384X_RID_CIS 0xFD13 -#define HFA384X_RID_STAID 0xFD20 -#define HFA384X_RID_STASUPRANGE 0xFD21 -#define HFA384X_RID_MFIACTRANGES 0xFD22 -#define HFA384X_RID_CFIACTRANGES2 0xFD23 -#define HFA384X_RID_PRODUCTNAME 0xFD24 /* added in STA f/w 1.3.1; - * only Prism2.5(?) */ -#define HFA384X_RID_PORTSTATUS 0xFD40 -#define HFA384X_RID_CURRENTSSID 0xFD41 -#define HFA384X_RID_CURRENTBSSID 0xFD42 -#define HFA384X_RID_COMMSQUALITY 0xFD43 -#define HFA384X_RID_CURRENTTXRATE 0xFD44 -#define HFA384X_RID_CURRENTBEACONINTERVAL 0xFD45 -#define HFA384X_RID_CURRENTSCALETHRESHOLDS 0xFD46 -#define HFA384X_RID_PROTOCOLRSPTIME 0xFD47 -#define HFA384X_RID_SHORTRETRYLIMIT 0xFD48 -#define HFA384X_RID_LONGRETRYLIMIT 0xFD49 -#define HFA384X_RID_MAXTRANSMITLIFETIME 0xFD4A -#define HFA384X_RID_MAXRECEIVELIFETIME 0xFD4B -#define HFA384X_RID_CFPOLLABLE 0xFD4C -#define HFA384X_RID_AUTHENTICATIONALGORITHMS 0xFD4D -#define HFA384X_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F -#define HFA384X_RID_DBMCOMMSQUALITY 0xFD51 /* added in STA f/w 1.3.1 */ -#define HFA384X_RID_CURRENTTXRATE1 0xFD80 /* AP f/w only */ -#define HFA384X_RID_CURRENTTXRATE2 0xFD81 /* AP f/w only */ -#define HFA384X_RID_CURRENTTXRATE3 0xFD82 /* AP f/w only */ -#define HFA384X_RID_CURRENTTXRATE4 0xFD83 /* AP f/w only */ -#define HFA384X_RID_CURRENTTXRATE5 0xFD84 /* AP f/w only */ -#define HFA384X_RID_CURRENTTXRATE6 0xFD85 /* AP f/w only */ -#define HFA384X_RID_OWNMACADDR 0xFD86 /* AP f/w only */ -#define HFA384X_RID_SCANRESULTSTABLE 0xFD88 /* added in STA f/w 0.8.3 */ -#define HFA384X_RID_HOSTSCANRESULTS 0xFD89 /* added in STA f/w 1.3.1 */ -#define HFA384X_RID_AUTHENTICATIONUSED 0xFD8A /* added in STA f/w 1.3.4 */ -#define HFA384X_RID_CNFFAASWITCHCTRL 0xFD8B /* added in STA f/w 1.6.3 */ -#define HFA384X_RID_ASSOCIATIONFAILURE 0xFD8D /* added in STA f/w 1.8.0 */ -#define HFA384X_RID_PHYTYPE 0xFDC0 -#define HFA384X_RID_CURRENTCHANNEL 0xFDC1 -#define HFA384X_RID_CURRENTPOWERSTATE 0xFDC2 -#define HFA384X_RID_CCAMODE 0xFDC3 -#define HFA384X_RID_SUPPORTEDDATARATES 0xFDC6 -#define HFA384X_RID_LFO_VOLT_REG_TEST_RES 0xFDC7 /* added in STA f/w 1.7.1 */ -#define HFA384X_RID_BUILDSEQ 0xFFFE -#define HFA384X_RID_FWID 0xFFFF - - -struct hfa384x_comp_ident -{ - u16 id; - u16 variant; - u16 major; - u16 minor; -} __attribute__ ((packed)); - -#define HFA384X_COMP_ID_PRI 0x15 -#define HFA384X_COMP_ID_STA 0x1f -#define HFA384X_COMP_ID_FW_AP 0x14b - -struct hfa384x_sup_range -{ - u16 role; - u16 id; - u16 variant; - u16 bottom; - u16 top; -} __attribute__ ((packed)); - - -struct hfa384x_build_id -{ - u16 pri_seq; - u16 sec_seq; -} __attribute__ ((packed)); - -/* FD01 - Download Buffer */ -struct hfa384x_rid_download_buffer -{ - u16 page; - u16 offset; - u16 length; -} __attribute__ ((packed)); - -/* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */ -struct hfa384x_comms_quality { - u16 comm_qual; /* 0 .. 92 */ - u16 signal_level; /* 27 .. 154 */ - u16 noise_level; /* 27 .. 154 */ -} __attribute__ ((packed)); - - -/* netdevice private ioctls (used, e.g., with iwpriv from user space) */ - -/* New wireless extensions API - SET/GET convention (even ioctl numbers are - * root only) - */ -#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0) -#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1) -#define PRISM2_IOCTL_WRITEMIF (SIOCIWFIRSTPRIV + 2) -#define PRISM2_IOCTL_READMIF (SIOCIWFIRSTPRIV + 3) -#define PRISM2_IOCTL_MONITOR (SIOCIWFIRSTPRIV + 4) -#define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6) -#define PRISM2_IOCTL_INQUIRE (SIOCIWFIRSTPRIV + 8) -#define PRISM2_IOCTL_WDS_ADD (SIOCIWFIRSTPRIV + 10) -#define PRISM2_IOCTL_WDS_DEL (SIOCIWFIRSTPRIV + 12) -#define PRISM2_IOCTL_SET_RID_WORD (SIOCIWFIRSTPRIV + 14) -#define PRISM2_IOCTL_MACCMD (SIOCIWFIRSTPRIV + 16) -#define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18) -#define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20) -#define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22) - -/* following are not in SIOCGIWPRIV list; check permission in the driver code - */ -#define PRISM2_IOCTL_DOWNLOAD (SIOCDEVPRIVATE + 13) -#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14) - - -/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */ -enum { - /* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */ - PRISM2_PARAM_TXRATECTRL = 2, - PRISM2_PARAM_BEACON_INT = 3, - PRISM2_PARAM_PSEUDO_IBSS = 4, - PRISM2_PARAM_ALC = 5, - /* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */ - PRISM2_PARAM_DUMP = 7, - PRISM2_PARAM_OTHER_AP_POLICY = 8, - PRISM2_PARAM_AP_MAX_INACTIVITY = 9, - PRISM2_PARAM_AP_BRIDGE_PACKETS = 10, - PRISM2_PARAM_DTIM_PERIOD = 11, - PRISM2_PARAM_AP_NULLFUNC_ACK = 12, - PRISM2_PARAM_MAX_WDS = 13, - PRISM2_PARAM_AP_AUTOM_AP_WDS = 14, - PRISM2_PARAM_AP_AUTH_ALGS = 15, - PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16, - PRISM2_PARAM_HOST_ENCRYPT = 17, - PRISM2_PARAM_HOST_DECRYPT = 18, - PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19, - PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20, - PRISM2_PARAM_HOST_ROAMING = 21, - PRISM2_PARAM_BCRX_STA_KEY = 22, - PRISM2_PARAM_IEEE_802_1X = 23, - PRISM2_PARAM_ANTSEL_TX = 24, - PRISM2_PARAM_ANTSEL_RX = 25, - PRISM2_PARAM_MONITOR_TYPE = 26, - PRISM2_PARAM_WDS_TYPE = 27, - PRISM2_PARAM_HOSTSCAN = 28, - PRISM2_PARAM_AP_SCAN = 29, - PRISM2_PARAM_ENH_SEC = 30, - PRISM2_PARAM_IO_DEBUG = 31, - PRISM2_PARAM_BASIC_RATES = 32, - PRISM2_PARAM_OPER_RATES = 33, - PRISM2_PARAM_HOSTAPD = 34, - PRISM2_PARAM_HOSTAPD_STA = 35, - PRISM2_PARAM_WPA = 36, - PRISM2_PARAM_PRIVACY_INVOKED = 37, - PRISM2_PARAM_TKIP_COUNTERMEASURES = 38, - PRISM2_PARAM_DROP_UNENCRYPTED = 39, - PRISM2_PARAM_SCAN_CHANNEL_MASK = 40, -}; - -enum { HOSTAP_ANTSEL_DO_NOT_TOUCH = 0, HOSTAP_ANTSEL_DIVERSITY = 1, - HOSTAP_ANTSEL_LOW = 2, HOSTAP_ANTSEL_HIGH = 3 }; - - -/* PRISM2_IOCTL_MACCMD ioctl() subcommands: */ -enum { AP_MAC_CMD_POLICY_OPEN = 0, AP_MAC_CMD_POLICY_ALLOW = 1, - AP_MAC_CMD_POLICY_DENY = 2, AP_MAC_CMD_FLUSH = 3, - AP_MAC_CMD_KICKALL = 4 }; - - -/* PRISM2_IOCTL_DOWNLOAD ioctl() dl_cmd: */ -enum { - PRISM2_DOWNLOAD_VOLATILE = 1 /* RAM */, - /* Note! Old versions of prism2_srec have a fatal error in CRC-16 - * calculation, which will corrupt all non-volatile downloads. - * PRISM2_DOWNLOAD_NON_VOLATILE used to be 2, but it is now 3 to - * prevent use of old versions of prism2_srec for non-volatile - * download. */ - PRISM2_DOWNLOAD_NON_VOLATILE = 3 /* FLASH */, - PRISM2_DOWNLOAD_VOLATILE_GENESIS = 4 /* RAM in Genesis mode */, - /* Persistent versions of volatile download commands (keep firmware - * data in memory and automatically re-download after hw_reset */ - PRISM2_DOWNLOAD_VOLATILE_PERSISTENT = 5, - PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT = 6, -}; - -struct prism2_download_param { - u32 dl_cmd; - u32 start_addr; - u32 num_areas; - struct prism2_download_area { - u32 addr; /* wlan card address */ - u32 len; - void __user *ptr; /* pointer to data in user space */ - } data[0]; -}; - -#define PRISM2_MAX_DOWNLOAD_AREA_LEN 131072 -#define PRISM2_MAX_DOWNLOAD_LEN 262144 - - -/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */ -enum { - PRISM2_HOSTAPD_FLUSH = 1, - PRISM2_HOSTAPD_ADD_STA = 2, - PRISM2_HOSTAPD_REMOVE_STA = 3, - PRISM2_HOSTAPD_GET_INFO_STA = 4, - /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ - PRISM2_SET_ENCRYPTION = 6, - PRISM2_GET_ENCRYPTION = 7, - PRISM2_HOSTAPD_SET_FLAGS_STA = 8, - PRISM2_HOSTAPD_GET_RID = 9, - PRISM2_HOSTAPD_SET_RID = 10, - PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11, - PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12, - PRISM2_HOSTAPD_MLME = 13, - PRISM2_HOSTAPD_SCAN_REQ = 14, - PRISM2_HOSTAPD_STA_CLEAR_STATS = 15, -}; - -#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024 -#define PRISM2_HOSTAPD_RID_HDR_LEN \ -((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data)) -#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ -((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data)) - -/* Maximum length for algorithm names (-1 for nul termination) used in ioctl() - */ -#define HOSTAP_CRYPT_ALG_NAME_LEN 16 - - -struct prism2_hostapd_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u16 aid; - u16 capability; - u8 tx_supp_rates; - } add_sta; - struct { - u32 inactive_sec; - } get_info_sta; - struct { - u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN]; - u32 flags; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[0]; - } crypt; - struct { - u32 flags_and; - u32 flags_or; - } set_flags_sta; - struct { - u16 rid; - u16 len; - u8 data[0]; - } rid; - struct { - u8 len; - u8 data[0]; - } generic_elem; - struct { -#define MLME_STA_DEAUTH 0 -#define MLME_STA_DISASSOC 1 - u16 cmd; - u16 reason_code; - } mlme; - struct { - u8 ssid_len; - u8 ssid[32]; - } scan_req; - } u; -}; - -#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0) -#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1) - -#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2 -#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 -#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 -#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7 - - -#endif /* HOSTAP_COMMON_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_config.h b/trunk/drivers/net/wireless/hostap/hostap_config.h deleted file mode 100644 index 0b526febd1a8..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_config.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef HOSTAP_CONFIG_H -#define HOSTAP_CONFIG_H - -#define PRISM2_VERSION "0.4.1-kernel" - -/* In the previous versions of Host AP driver, support for user space version - * of IEEE 802.11 management (hostapd) used to be disabled in the default - * configuration. From now on, support for hostapd is always included and it is - * possible to disable kernel driver version of IEEE 802.11 management with a - * separate define, PRISM2_NO_KERNEL_IEEE80211_MGMT. */ -/* #define PRISM2_NO_KERNEL_IEEE80211_MGMT */ - -/* Maximum number of events handler per one interrupt */ -#define PRISM2_MAX_INTERRUPT_EVENTS 20 - -/* Use PCI bus master to copy data to/from BAP (only available for - * hostap_pci.o). - * - * Note! This is extremely experimental. PCI bus master is not supported by - * Intersil and it seems to have some problems at least on TX path (see below). - * The driver code for implementing bus master support is based on guessing - * and experimenting suitable control bits and these might not be correct. - * This code is included because using bus master makes a huge difference in - * host CPU load (something like 40% host CPU usage to 5-10% when sending or - * receiving at maximum throughput). - * - * Note2! Station firmware version 1.3.5 and primary firmware version 1.0.7 - * have some fixes for PCI corruption and these (or newer) versions are - * recommended especially when using bus mastering. - * - * NOTE: PCI bus mastering code has not been updated for long time and it is - * not likely to compile and it will _not_ work as is. Only enable this if you - * are prepared to first fix the implementation.. - */ -/* #define PRISM2_BUS_MASTER */ - -#ifdef PRISM2_BUS_MASTER - -/* PCI bus master implementation seems to be broken in current - * hardware/firmware versions. Enable this to use enable command to fix - * something before starting bus master operation on TX path. This will add - * some latency and an extra interrupt to each TX packet. */ -#define PRISM2_ENABLE_BEFORE_TX_BUS_MASTER - -#endif /* PRISM2_BUS_MASTER */ - -/* Include code for downloading firmware images into volatile RAM. */ -#define PRISM2_DOWNLOAD_SUPPORT - -/* Allow kernel configuration to enable download support. */ -#if !defined(PRISM2_DOWNLOAD_SUPPORT) && defined(CONFIG_HOSTAP_FIRMWARE) -#define PRISM2_DOWNLOAD_SUPPORT -#endif - -#ifdef PRISM2_DOWNLOAD_SUPPORT -/* Allow writing firmware images into flash, i.e., to non-volatile storage. - * Before you enable this option, you should make absolutely sure that you are - * using prism2_srec utility that comes with THIS version of the driver! - * In addition, please note that it is possible to kill your card with - * non-volatile download if you are using incorrect image. This feature has not - * been fully tested, so please be careful with it. */ -/* #define PRISM2_NON_VOLATILE_DOWNLOAD */ -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - -/* Save low-level I/O for debugging. This should not be enabled in normal use. - */ -/* #define PRISM2_IO_DEBUG */ - -/* Following defines can be used to remove unneeded parts of the driver, e.g., - * to limit the size of the kernel module. Definitions can be added here in - * hostap_config.h or they can be added to make command with EXTRA_CFLAGS, - * e.g., - * 'make pccard EXTRA_CFLAGS="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"' - */ - -/* Do not include debug messages into the driver */ -/* #define PRISM2_NO_DEBUG */ - -/* Do not include /proc/net/prism2/wlan#/{registers,debug} */ -/* #define PRISM2_NO_PROCFS_DEBUG */ - -/* Do not include station functionality (i.e., allow only Master (Host AP) mode - */ -/* #define PRISM2_NO_STATION_MODES */ - -#endif /* HOSTAP_CONFIG_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c deleted file mode 100644 index a5a6d6a966ee..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ /dev/null @@ -1,985 +0,0 @@ -#define PRISM2_PCCARD - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "hostap_wlan.h" - - -static char *version = PRISM2_VERSION " (Jouni Malinen )"; -static dev_info_t dev_info = "hostap_cs"; -static dev_link_t *dev_list = NULL; - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " - "cards (PC Card)."); -MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -static int ignore_cis_vcc; -module_param(ignore_cis_vcc, int, 0444); -MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry"); - - -#ifdef PRISM2_IO_DEBUG - -static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v); - outb(v, dev->base_addr + a); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline u8 hfa384x_inb_debug(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - u8 v; - - iface = netdev_priv(dev); - local = iface->local; - spin_lock_irqsave(&local->lock, flags); - v = inb(dev->base_addr + a); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v); - spin_unlock_irqrestore(&local->lock, flags); - return v; -} - -static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v); - outw(v, dev->base_addr + a); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline u16 hfa384x_inw_debug(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - u16 v; - - iface = netdev_priv(dev); - local = iface->local; - spin_lock_irqsave(&local->lock, flags); - v = inw(dev->base_addr + a); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v); - spin_unlock_irqrestore(&local->lock, flags); - return v; -} - -static inline void hfa384x_outsw_debug(struct net_device *dev, int a, - u8 *buf, int wc) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc); - outsw(dev->base_addr + a, buf, wc); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline void hfa384x_insw_debug(struct net_device *dev, int a, - u8 *buf, int wc) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc); - insw(dev->base_addr + a, buf, wc); - spin_unlock_irqrestore(&local->lock, flags); -} - -#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v)) -#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a)) -#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v)) -#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a)) -#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc)) -#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc)) - -#else /* PRISM2_IO_DEBUG */ - -#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((v), dev->base_addr + (a)) -#define HFA384X_INW(a) inw(dev->base_addr + (a)) -#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_IO_DEBUG */ - - -static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf, - int len) -{ - u16 d_off; - u16 *pos; - - d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; - pos = (u16 *) buf; - - if (len / 2) - HFA384X_INSW(d_off, buf, len / 2); - pos += len / 2; - - if (len & 1) - *((char *) pos) = HFA384X_INB(d_off); - - return 0; -} - - -static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) -{ - u16 d_off; - u16 *pos; - - d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; - pos = (u16 *) buf; - - if (len / 2) - HFA384X_OUTSW(d_off, buf, len / 2); - pos += len / 2; - - if (len & 1) - HFA384X_OUTB(*((char *) pos), d_off); - - return 0; -} - - -/* FIX: This might change at some point.. */ -#include "hostap_hw.c" - - - -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_pccard_card_present(local_info_t *local) -{ - if (local->link != NULL && - ((local->link->state & (DEV_PRESENT | DEV_CONFIG)) == - (DEV_PRESENT | DEV_CONFIG))) - return 1; - return 0; -} - - -/* - * SanDisk CompactFlash WLAN Flashcard - Product Manual v1.0 - * Document No. 20-10-00058, January 2004 - * http://www.sandisk.com/pdf/industrial/ProdManualCFWLANv1.0.pdf - */ -#define SANDISK_WLAN_ACTIVATION_OFF 0x40 -#define SANDISK_HCR_OFF 0x42 - - -static void sandisk_set_iobase(local_info_t *local) -{ - int res; - conf_reg_t reg; - - reg.Function = 0; - reg.Action = CS_WRITE; - reg.Offset = 0x10; /* 0x3f0 IO base 1 */ - reg.Value = local->link->io.BasePort1 & 0x00ff; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" - " res=%d\n", res); - } - udelay(10); - - reg.Function = 0; - reg.Action = CS_WRITE; - reg.Offset = 0x12; /* 0x3f2 IO base 2 */ - reg.Value = (local->link->io.BasePort1 & 0xff00) >> 8; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" - " res=%d\n", res); - } -} - - -static void sandisk_write_hcr(local_info_t *local, int hcr) -{ - struct net_device *dev = local->dev; - int i; - - HFA384X_OUTB(0x80, SANDISK_WLAN_ACTIVATION_OFF); - udelay(50); - for (i = 0; i < 10; i++) { - HFA384X_OUTB(hcr, SANDISK_HCR_OFF); - } - udelay(55); - HFA384X_OUTB(0x45, SANDISK_WLAN_ACTIVATION_OFF); -} - - -static int sandisk_enable_wireless(struct net_device *dev) -{ - int res, ret = 0; - conf_reg_t reg; - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - tuple_t tuple; - cisparse_t *parse = NULL; - u_char buf[64]; - - if (local->link->io.NumPorts1 < 0x42) { - /* Not enough ports to be SanDisk multi-function card */ - ret = -ENODEV; - goto done; - } - - parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); - if (parse == NULL) { - ret = -ENOMEM; - goto done; - } - - tuple.DesiredTuple = CISTPL_MANFID; - tuple.Attributes = TUPLE_RETURN_COMMON; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(local->link->handle, &tuple) || - pcmcia_get_tuple_data(local->link->handle, &tuple) || - pcmcia_parse_tuple(local->link->handle, &tuple, parse) || - parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { - /* No SanDisk manfid found */ - ret = -ENODEV; - goto done; - } - - tuple.DesiredTuple = CISTPL_LONGLINK_MFC; - if (pcmcia_get_first_tuple(local->link->handle, &tuple) || - pcmcia_get_tuple_data(local->link->handle, &tuple) || - pcmcia_parse_tuple(local->link->handle, &tuple, parse) || - parse->longlink_mfc.nfn < 2) { - /* No multi-function links found */ - ret = -ENODEV; - goto done; - } - - printk(KERN_DEBUG "%s: Multi-function SanDisk ConnectPlus detected" - " - using vendor-specific initialization\n", dev->name); - local->sandisk_connectplus = 1; - - reg.Function = 0; - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - reg.Value = COR_SOFT_RESET; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", - dev->name, res); - goto done; - } - mdelay(5); - - reg.Function = 0; - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - /* - * Do not enable interrupts here to avoid some bogus events. Interrupts - * will be enabled during the first cor_sreset call. - */ - reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", - dev->name, res); - goto done; - } - mdelay(5); - - sandisk_set_iobase(local); - - HFA384X_OUTB(0xc5, SANDISK_WLAN_ACTIVATION_OFF); - udelay(10); - HFA384X_OUTB(0x4b, SANDISK_WLAN_ACTIVATION_OFF); - udelay(10); - -done: - kfree(parse); - return ret; -} - - -static void prism2_pccard_cor_sreset(local_info_t *local) -{ - int res; - conf_reg_t reg; - - if (!prism2_pccard_card_present(local)) - return; - - reg.Function = 0; - reg.Action = CS_READ; - reg.Offset = CISREG_COR; - reg.Value = 0; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", - res); - return; - } - printk(KERN_DEBUG "prism2_pccard_cor_sreset: original COR %02x\n", - reg.Value); - - reg.Action = CS_WRITE; - reg.Value |= COR_SOFT_RESET; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", - res); - return; - } - - mdelay(local->sandisk_connectplus ? 5 : 2); - - reg.Value &= ~COR_SOFT_RESET; - if (local->sandisk_connectplus) - reg.Value |= COR_IREQ_ENA; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", - res); - return; - } - - mdelay(local->sandisk_connectplus ? 5 : 2); - - if (local->sandisk_connectplus) - sandisk_set_iobase(local); -} - - -static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) -{ - int res; - conf_reg_t reg; - int old_cor; - - if (!prism2_pccard_card_present(local)) - return; - - if (local->sandisk_connectplus) { - sandisk_write_hcr(local, hcr); - return; - } - - reg.Function = 0; - reg.Action = CS_READ; - reg.Offset = CISREG_COR; - reg.Value = 0; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " - "(%d)\n", res); - return; - } - printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n", - reg.Value); - old_cor = reg.Value; - - reg.Action = CS_WRITE; - reg.Value |= COR_SOFT_RESET; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " - "(%d)\n", res); - return; - } - - mdelay(10); - - /* Setup Genesis mode */ - reg.Action = CS_WRITE; - reg.Value = hcr; - reg.Offset = CISREG_CCSR; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " - "(%d)\n", res); - return; - } - mdelay(10); - - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - reg.Value = old_cor & ~COR_SOFT_RESET; - res = pcmcia_access_configuration_register(local->link->handle, ®); - if (res != CS_SUCCESS) { - printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " - "(%d)\n", res); - return; - } - - mdelay(10); -} - - -static int prism2_pccard_dev_open(local_info_t *local) -{ - local->link->open++; - return 0; -} - - -static int prism2_pccard_dev_close(local_info_t *local) -{ - if (local == NULL || local->link == NULL) - return 1; - - if (!local->link->open) { - printk(KERN_WARNING "%s: prism2_pccard_dev_close(): " - "link not open?!\n", local->dev->name); - return 1; - } - - local->link->open--; - - return 0; -} - - -static struct prism2_helper_functions prism2_pccard_funcs = -{ - .card_present = prism2_pccard_card_present, - .cor_sreset = prism2_pccard_cor_sreset, - .dev_open = prism2_pccard_dev_open, - .dev_close = prism2_pccard_dev_close, - .genesis_reset = prism2_pccard_genesis_reset, - .hw_type = HOSTAP_HW_PCCARD, -}; - - -/* 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) -{ - dev_link_t *link; - client_reg_t client_reg; - int ret; - - link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); - if (link == NULL) - return NULL; - - memset(link, 0, sizeof(dev_link_t)); - - PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info); - link->conf.Vcc = 33; - link->conf.IntType = INT_MEMORY_AND_IO; - - /* register with CardServices */ - link->next = dev_list; - dev_list = link; - client_reg.dev_info = &dev_info; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - ret = pcmcia_register_client(&link->handle, &client_reg); - if (ret != CS_SUCCESS) { - cs_error(link->handle, RegisterClient, ret); - prism2_detach(link); - return NULL; - } - return link; -} - - -static void prism2_detach(dev_link_t *link) -{ - dev_link_t **linkp; - - PDEBUG(DEBUG_FLOW, "prism2_detach\n"); - - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) - break; - if (*linkp == NULL) { - printk(KERN_WARNING "%s: Attempt to detach non-existing " - "PCMCIA client\n", dev_info); - return; - } - - if (link->state & DEV_CONFIG) { - prism2_release((u_long)link); - } - - if (link->handle) { - int res = pcmcia_deregister_client(link->handle); - if (res) { - printk("CardService(DeregisterClient) => %d\n", res); - cs_error(link->handle, DeregisterClient, res); - } - } - - *linkp = link->next; - /* release net devices */ - if (link->priv) { - prism2_free_local_data((struct net_device *) link->priv); - - } - kfree(link); -} - - -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - -#define CFG_CHECK2(fn, retf) \ -do { int ret = (retf); \ -if (ret != 0) { \ - PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ - cs_error(link->handle, fn, ret); \ - goto next_entry; \ -} \ -} while (0) - - -/* run after a CARD_INSERTION event is received to configure the PCMCIA - * socket and make the device available to the system */ -static int prism2_config(dev_link_t *link) -{ - struct net_device *dev; - struct hostap_interface *iface; - local_info_t *local; - int ret = 1; - tuple_t tuple; - cisparse_t *parse; - int last_fn, last_ret; - u_char buf[64]; - config_info_t conf; - cistpl_cftable_entry_t dflt = { 0 }; - - PDEBUG(DEBUG_FLOW, "prism2_config()\n"); - - parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); - if (parse == NULL) { - ret = -ENOMEM; - goto failed; - } - - tuple.DesiredTuple = CISTPL_CONFIG; - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse)); - link->conf.ConfigBase = parse->config.base; - link->conf.Present = parse->config.rmask[0]; - - CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link->handle, &conf)); - PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info, - ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc); - link->conf.Vcc = conf.Vcc; - - /* Look for an appropriate configuration table entry in the CIS */ - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); - for (;;) { - cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); - CFG_CHECK2(GetTupleData, - pcmcia_get_tuple_data(link->handle, &tuple)); - CFG_CHECK2(ParseTuple, - pcmcia_parse_tuple(link->handle, &tuple, parse)); - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - dflt = *cfg; - if (cfg->index == 0) - goto next_entry; - link->conf.ConfigIndex = cfg->index; - PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X " - "(default 0x%02X)\n", cfg->index, dflt.index); - - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - link->conf.Attributes |= CONF_ENABLE_SPKR; - link->conf.Status = CCSR_AUDIO_ENA; - } - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / - 10000 && !ignore_cis_vcc) { - PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping" - " this entry\n"); - goto next_entry; - } - } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / - 10000 && !ignore_cis_vcc) { - PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch " - "- skipping this entry\n"); - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp1 = link->conf.Vpp2 = - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) - link->conf.Attributes |= CONF_ENABLE_IRQ; - else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) { - /* At least Compaq WL200 does not have IRQInfo1 set, - * but it does not work without interrupts.. */ - printk("Config has no IRQ info, but trying to enable " - "IRQ anyway..\n"); - link->conf.Attributes |= CONF_ENABLE_IRQ; - } - - /* IO window settings */ - PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " - "dflt.io.nwin=%d\n", - cfg->io.nwin, dflt.io.nwin); - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, " - "io.base=0x%04x, len=%d\n", io->flags, - io->win[0].base, io->win[0].len); - if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & - CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - link->io.Attributes2 = link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; - } - } - - /* This reserves IO space but doesn't actually enable it */ - CFG_CHECK2(RequestIO, - pcmcia_request_io(link->handle, &link->io)); - - /* This configuration table entry is OK */ - break; - - next_entry: - CS_CHECK(GetNextTuple, - pcmcia_get_next_tuple(link->handle, &tuple)); - } - - /* Need to allocate net_device before requesting IRQ handler */ - dev = prism2_init_local_data(&prism2_pccard_funcs, 0, - &handle_to_dev(link->handle)); - if (dev == NULL) - goto failed; - link->priv = dev; - - /* - * Allocate an interrupt line. Note that this does not assign a - * handler to the interrupt, unless the 'Handler' member of the - * irq structure is initialized. - */ - if (link->conf.Attributes & CONF_ENABLE_IRQ) { - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = prism2_interrupt; - link->irq.Instance = dev; - CS_CHECK(RequestIRQ, - pcmcia_request_irq(link->handle, &link->irq)); - } - - /* - * This actually configures the PCMCIA socket -- setting up - * the I/O windows and the interrupt mapping, and putting the - * card and host interface into "Memory and IO" mode. - */ - CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link->handle, &link->conf)); - - dev->irq = link->irq.AssignedIRQ; - dev->base_addr = link->io.BasePort1; - - /* Finally, report what we've done */ - printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", - dev_info, link->conf.ConfigIndex, - link->conf.Vcc / 10, link->conf.Vcc % 10); - if (link->conf.Vpp1) - printk(", Vpp %d.%d", link->conf.Vpp1 / 10, - link->conf.Vpp1 % 10); - if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %d", link->irq.AssignedIRQ); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1+link->io.NumPorts1-1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2+link->io.NumPorts2-1); - printk("\n"); - - link->state |= DEV_CONFIG; - link->state &= ~DEV_CONFIG_PENDING; - - iface = netdev_priv(dev); - local = iface->local; - local->link = link; - strcpy(local->node.dev_name, dev->name); - link->dev = &local->node; - - local->shutdown = 0; - - sandisk_enable_wireless(dev); - - ret = prism2_hw_config(dev, 1); - if (!ret) { - ret = hostap_hw_ready(dev); - if (ret == 0 && local->ddev) - strcpy(local->node.dev_name, local->ddev->name); - } - kfree(parse); - return ret; - - cs_failed: - cs_error(link->handle, last_fn, last_ret); - - failed: - kfree(parse); - prism2_release((u_long)link); - return ret; -} - - -static void prism2_release(u_long arg) -{ - dev_link_t *link = (dev_link_t *)arg; - - PDEBUG(DEBUG_FLOW, "prism2_release\n"); - - if (link->priv) { - struct net_device *dev = link->priv; - struct hostap_interface *iface; - - iface = netdev_priv(dev); - if (link->state & DEV_CONFIG) - prism2_hw_shutdown(dev, 0); - iface->local->shutdown = 1; - } - - if (link->win) - pcmcia_release_window(link->win); - pcmcia_release_configuration(link->handle); - if (link->io.NumPorts1) - pcmcia_release_io(link->handle, &link->io); - if (link->irq.AssignedIRQ) - pcmcia_release_irq(link->handle, &link->irq); - - link->state &= ~DEV_CONFIG; - - PDEBUG(DEBUG_FLOW, "release - done\n"); -} - - -static int prism2_event(event_t event, int priority, - event_callback_args_t *args) -{ - dev_link_t *link = args->client_data; - struct net_device *dev = (struct net_device *) link->priv; - - switch (event) { - case CS_EVENT_CARD_INSERTION: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - if (prism2_config(link)) { - PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); - } - break; - - case CS_EVENT_CARD_REMOVAL: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info); - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - netif_stop_queue(dev); - netif_device_detach(dev); - prism2_release((u_long) link); - } - break; - - case CS_EVENT_PM_SUSPEND: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); - link->state |= DEV_SUSPEND; - /* fall through */ - - case CS_EVENT_RESET_PHYSICAL: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info); - if (link->state & DEV_CONFIG) { - if (link->open) { - netif_stop_queue(dev); - netif_device_detach(dev); - } - prism2_suspend(dev); - pcmcia_release_configuration(link->handle); - } - break; - - case CS_EVENT_PM_RESUME: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); - link->state &= ~DEV_SUSPEND; - /* fall through */ - - case CS_EVENT_CARD_RESET: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info); - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, - &link->conf); - prism2_hw_shutdown(dev, 1); - prism2_hw_config(dev, link->open ? 0 : 1); - if (link->open) { - netif_device_attach(dev); - netif_start_queue(dev); - } - } - break; - - default: - PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", - dev_info, event); - break; - } - return 0; -} - - -static struct pcmcia_device_id hostap_cs_ids[] = { - PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), - PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), - PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), - PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), - PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), - PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), - PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), - PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), - PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), - PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus", - 0x7a954bd9, 0x74be00c6), - PCMCIA_DEVICE_PROD_ID1234( - "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P", - "Eval-RevA", - 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e), - PCMCIA_DEVICE_PROD_ID123( - "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", - 0xe6ec52ce, 0x08649af2, 0x4b74baa0), - PCMCIA_DEVICE_PROD_ID123( - "D", "Link DWL-650 11Mbps WLAN Card", "Version 01.02", - 0x71b18589, 0xb6f1b0ab, 0x4b74baa0), - PCMCIA_DEVICE_PROD_ID123( - "Instant Wireless ", " Network PC CARD", "Version 01.02", - 0x11d901af, 0x6e9bd926, 0x4b74baa0), - PCMCIA_DEVICE_PROD_ID123( - "SMC", "SMC2632W", "Version 01.02", - 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0), - PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", - 0x54f7c49c, 0x15a75e5b), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", - 0x74c5e40d, 0xdb472a18), - PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", - 0x0733cc81, 0x0c52f395), - PCMCIA_DEVICE_PROD_ID12( - "ZoomAir 11Mbps High", "Rate wireless Networking", - 0x273fe3db, 0x32a1eaee), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); - - -static struct pcmcia_driver hostap_driver = { - .drv = { - .name = "hostap_cs", - }, - .attach = prism2_attach, - .detach = prism2_detach, - .owner = THIS_MODULE, - .event = prism2_event, - .id_table = hostap_cs_ids, -}; - -static int __init init_prism2_pccard(void) -{ - printk(KERN_INFO "%s: %s\n", dev_info, version); - return pcmcia_register_driver(&hostap_driver); -} - -static void __exit exit_prism2_pccard(void) -{ - pcmcia_unregister_driver(&hostap_driver); - printk(KERN_INFO "%s: Driver unloaded\n", dev_info); -} - - -module_init(init_prism2_pccard); -module_exit(exit_prism2_pccard); diff --git a/trunk/drivers/net/wireless/hostap/hostap_download.c b/trunk/drivers/net/wireless/hostap/hostap_download.c deleted file mode 100644 index ab26b52b3e76..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_download.c +++ /dev/null @@ -1,766 +0,0 @@ -static int prism2_enable_aux_port(struct net_device *dev, int enable) -{ - u16 val, reg; - int i, tries; - unsigned long flags; - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->no_pri) { - if (enable) { - PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux " - "port is already enabled\n", dev->name); - } - return 0; - } - - spin_lock_irqsave(&local->cmdlock, flags); - - /* wait until busy bit is clear */ - tries = HFA384X_CMD_BUSY_TIMEOUT; - while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) { - tries--; - udelay(1); - } - if (tries == 0) { - reg = HFA384X_INW(HFA384X_CMD_OFF); - spin_unlock_irqrestore(&local->cmdlock, flags); - printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n", - dev->name, reg); - return -ETIMEDOUT; - } - - val = HFA384X_INW(HFA384X_CONTROL_OFF); - - if (enable) { - HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF); - HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF); - HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF); - - if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED) - printk("prism2_enable_aux_port: was not disabled!?\n"); - val &= ~HFA384X_AUX_PORT_MASK; - val |= HFA384X_AUX_PORT_ENABLE; - } else { - HFA384X_OUTW(0, HFA384X_PARAM0_OFF); - HFA384X_OUTW(0, HFA384X_PARAM1_OFF); - HFA384X_OUTW(0, HFA384X_PARAM2_OFF); - - if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED) - printk("prism2_enable_aux_port: was not enabled!?\n"); - val &= ~HFA384X_AUX_PORT_MASK; - val |= HFA384X_AUX_PORT_DISABLE; - } - HFA384X_OUTW(val, HFA384X_CONTROL_OFF); - - udelay(5); - - i = 10000; - while (i > 0) { - val = HFA384X_INW(HFA384X_CONTROL_OFF); - val &= HFA384X_AUX_PORT_MASK; - - if ((enable && val == HFA384X_AUX_PORT_ENABLED) || - (!enable && val == HFA384X_AUX_PORT_DISABLED)) - break; - - udelay(10); - i--; - } - - spin_unlock_irqrestore(&local->cmdlock, flags); - - if (i == 0) { - printk("prism2_enable_aux_port(%d) timed out\n", - enable); - return -ETIMEDOUT; - } - - return 0; -} - - -static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len, - void *buf) -{ - u16 page, offset; - if (addr & 1 || len & 1) - return -1; - - page = addr >> 7; - offset = addr & 0x7f; - - HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF); - HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF); - - udelay(5); - -#ifdef PRISM2_PCI - { - u16 *pos = (u16 *) buf; - while (len > 0) { - *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF); - len -= 2; - } - } -#else /* PRISM2_PCI */ - HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2); -#endif /* PRISM2_PCI */ - - return 0; -} - - -static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len, - void *buf) -{ - u16 page, offset; - if (addr & 1 || len & 1) - return -1; - - page = addr >> 7; - offset = addr & 0x7f; - - HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF); - HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF); - - udelay(5); - -#ifdef PRISM2_PCI - { - u16 *pos = (u16 *) buf; - while (len > 0) { - HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF); - len -= 2; - } - } -#else /* PRISM2_PCI */ - HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2); -#endif /* PRISM2_PCI */ - - return 0; -} - - -static int prism2_pda_ok(u8 *buf) -{ - u16 *pda = (u16 *) buf; - int pos; - u16 len, pdr; - - if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff && - buf[3] == 0x00) - return 0; - - pos = 0; - while (pos + 1 < PRISM2_PDA_SIZE / 2) { - len = le16_to_cpu(pda[pos]); - pdr = le16_to_cpu(pda[pos + 1]); - if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2) - return 0; - - if (pdr == 0x0000 && len == 2) { - /* PDA end found */ - return 1; - } - - pos += len + 1; - } - - return 0; -} - - -static int prism2_download_aux_dump(struct net_device *dev, - unsigned int addr, int len, u8 *buf) -{ - int res; - - prism2_enable_aux_port(dev, 1); - res = hfa384x_from_aux(dev, addr, len, buf); - prism2_enable_aux_port(dev, 0); - if (res) - return -1; - - return 0; -} - - -static u8 * prism2_read_pda(struct net_device *dev) -{ - u8 *buf; - int res, i, found = 0; -#define NUM_PDA_ADDRS 4 - unsigned int pda_addr[NUM_PDA_ADDRS] = { - 0x7f0000 /* others than HFA3841 */, - 0x3f0000 /* HFA3841 */, - 0x390000 /* apparently used in older cards */, - 0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */, - }; - - buf = (u8 *) kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL); - if (buf == NULL) - return NULL; - - /* Note: wlan card should be in initial state (just after init cmd) - * and no other operations should be performed concurrently. */ - - prism2_enable_aux_port(dev, 1); - - for (i = 0; i < NUM_PDA_ADDRS; i++) { - PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x", - dev->name, pda_addr[i]); - res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf); - if (res) - continue; - if (res == 0 && prism2_pda_ok(buf)) { - PDEBUG2(DEBUG_EXTRA2, ": OK\n"); - found = 1; - break; - } else { - PDEBUG2(DEBUG_EXTRA2, ": failed\n"); - } - } - - prism2_enable_aux_port(dev, 0); - - if (!found) { - printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name); - kfree(buf); - buf = NULL; - } - - return buf; -} - - -static int prism2_download_volatile(local_info_t *local, - struct prism2_download_data *param) -{ - struct net_device *dev = local->dev; - int ret = 0, i; - u16 param0, param1; - - if (local->hw_downloading) { - printk(KERN_WARNING "%s: Already downloading - aborting new " - "request\n", dev->name); - return -1; - } - - local->hw_downloading = 1; - if (local->pri_only) { - hfa384x_disable_interrupts(dev); - } else { - prism2_hw_shutdown(dev, 0); - - if (prism2_hw_init(dev, 0)) { - printk(KERN_WARNING "%s: Could not initialize card for" - " download\n", dev->name); - ret = -1; - goto out; - } - } - - if (prism2_enable_aux_port(dev, 1)) { - printk(KERN_WARNING "%s: Could not enable AUX port\n", - dev->name); - ret = -1; - goto out; - } - - param0 = param->start_addr & 0xffff; - param1 = param->start_addr >> 16; - - HFA384X_OUTW(0, HFA384X_PARAM2_OFF); - HFA384X_OUTW(param1, HFA384X_PARAM1_OFF); - if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | - (HFA384X_PROGMODE_ENABLE_VOLATILE << 8), - param0)) { - printk(KERN_WARNING "%s: Download command execution failed\n", - dev->name); - ret = -1; - goto out; - } - - for (i = 0; i < param->num_areas; i++) { - PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n", - dev->name, param->data[i].len, param->data[i].addr); - if (hfa384x_to_aux(dev, param->data[i].addr, - param->data[i].len, param->data[i].data)) { - printk(KERN_WARNING "%s: RAM download at 0x%08x " - "(len=%d) failed\n", dev->name, - param->data[i].addr, param->data[i].len); - ret = -1; - goto out; - } - } - - HFA384X_OUTW(param1, HFA384X_PARAM1_OFF); - HFA384X_OUTW(0, HFA384X_PARAM2_OFF); - if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD | - (HFA384X_PROGMODE_DISABLE << 8), param0)) { - printk(KERN_WARNING "%s: Download command execution failed\n", - dev->name); - ret = -1; - goto out; - } - /* ProgMode disable causes the hardware to restart itself from the - * given starting address. Give hw some time and ACK command just in - * case restart did not happen. */ - mdelay(5); - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); - - if (prism2_enable_aux_port(dev, 0)) { - printk(KERN_DEBUG "%s: Disabling AUX port failed\n", - dev->name); - /* continue anyway.. restart should have taken care of this */ - } - - mdelay(5); - local->hw_downloading = 0; - if (prism2_hw_config(dev, 2)) { - printk(KERN_WARNING "%s: Card configuration after RAM " - "download failed\n", dev->name); - ret = -1; - goto out; - } - - out: - local->hw_downloading = 0; - return ret; -} - - -static int prism2_enable_genesis(local_info_t *local, int hcr) -{ - struct net_device *dev = local->dev; - u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff }; - u8 readbuf[4]; - - printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n", - dev->name, hcr); - local->func->cor_sreset(local); - hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq); - local->func->genesis_reset(local, hcr); - - /* Readback test */ - hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf); - hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq); - hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf); - - if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) { - printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n", - hcr); - return 0; - } else { - printk(KERN_DEBUG "Readback test failed, HCR 0x%02x " - "write %02x %02x %02x %02x read %02x %02x %02x %02x\n", - hcr, initseq[0], initseq[1], initseq[2], initseq[3], - readbuf[0], readbuf[1], readbuf[2], readbuf[3]); - return 1; - } -} - - -static int prism2_get_ram_size(local_info_t *local) -{ - int ret; - - /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */ - if (prism2_enable_genesis(local, 0x1f) == 0) - ret = 8; - else if (prism2_enable_genesis(local, 0x0f) == 0) - ret = 16; - else - ret = -1; - - /* Disable genesis mode */ - local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17); - - return ret; -} - - -static int prism2_download_genesis(local_info_t *local, - struct prism2_download_data *param) -{ - struct net_device *dev = local->dev; - int ram16 = 0, i; - int ret = 0; - - if (local->hw_downloading) { - printk(KERN_WARNING "%s: Already downloading - aborting new " - "request\n", dev->name); - return -EBUSY; - } - - if (!local->func->genesis_reset || !local->func->cor_sreset) { - printk(KERN_INFO "%s: Genesis mode downloading not supported " - "with this hwmodel\n", dev->name); - return -EOPNOTSUPP; - } - - local->hw_downloading = 1; - - if (prism2_enable_aux_port(dev, 1)) { - printk(KERN_DEBUG "%s: failed to enable AUX port\n", - dev->name); - ret = -EIO; - goto out; - } - - if (local->sram_type == -1) { - /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */ - if (prism2_enable_genesis(local, 0x1f) == 0) { - ram16 = 0; - PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 " - "SRAM\n", dev->name); - } else if (prism2_enable_genesis(local, 0x0f) == 0) { - ram16 = 1; - PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 " - "SRAM\n", dev->name); - } else { - printk(KERN_DEBUG "%s: Could not initiate genesis " - "mode\n", dev->name); - ret = -EIO; - goto out; - } - } else { - if (prism2_enable_genesis(local, local->sram_type == 8 ? - 0x1f : 0x0f)) { - printk(KERN_DEBUG "%s: Failed to set Genesis " - "mode (sram_type=%d)\n", dev->name, - local->sram_type); - ret = -EIO; - goto out; - } - ram16 = local->sram_type != 8; - } - - for (i = 0; i < param->num_areas; i++) { - PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n", - dev->name, param->data[i].len, param->data[i].addr); - if (hfa384x_to_aux(dev, param->data[i].addr, - param->data[i].len, param->data[i].data)) { - printk(KERN_WARNING "%s: RAM download at 0x%08x " - "(len=%d) failed\n", dev->name, - param->data[i].addr, param->data[i].len); - ret = -EIO; - goto out; - } - } - - PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n"); - local->func->genesis_reset(local, ram16 ? 0x07 : 0x17); - if (prism2_enable_aux_port(dev, 0)) { - printk(KERN_DEBUG "%s: Failed to disable AUX port\n", - dev->name); - } - - mdelay(5); - local->hw_downloading = 0; - - PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n"); - /* - * Make sure the INIT command does not generate a command completion - * event by disabling interrupts. - */ - hfa384x_disable_interrupts(dev); - if (prism2_hw_init(dev, 1)) { - printk(KERN_DEBUG "%s: Initialization after genesis mode " - "download failed\n", dev->name); - ret = -EIO; - goto out; - } - - PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n"); - if (prism2_hw_init2(dev, 1)) { - printk(KERN_DEBUG "%s: Initialization(2) after genesis mode " - "download failed\n", dev->name); - ret = -EIO; - goto out; - } - - out: - local->hw_downloading = 0; - return ret; -} - - -#ifdef PRISM2_NON_VOLATILE_DOWNLOAD -/* Note! Non-volatile downloading functionality has not yet been tested - * thoroughly and it may corrupt flash image and effectively kill the card that - * is being updated. You have been warned. */ - -static inline int prism2_download_block(struct net_device *dev, - u32 addr, u8 *data, - u32 bufaddr, int rest_len) -{ - u16 param0, param1; - int block_len; - - block_len = rest_len < 4096 ? rest_len : 4096; - - param0 = addr & 0xffff; - param1 = addr >> 16; - - HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF); - HFA384X_OUTW(param1, HFA384X_PARAM1_OFF); - - if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | - (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8), - param0)) { - printk(KERN_WARNING "%s: Flash download command execution " - "failed\n", dev->name); - return -1; - } - - if (hfa384x_to_aux(dev, bufaddr, block_len, data)) { - printk(KERN_WARNING "%s: flash download at 0x%08x " - "(len=%d) failed\n", dev->name, addr, block_len); - return -1; - } - - HFA384X_OUTW(0, HFA384X_PARAM2_OFF); - HFA384X_OUTW(0, HFA384X_PARAM1_OFF); - if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | - (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8), - 0)) { - printk(KERN_WARNING "%s: Flash write command execution " - "failed\n", dev->name); - return -1; - } - - return block_len; -} - - -static int prism2_download_nonvolatile(local_info_t *local, - struct prism2_download_data *dl) -{ - struct net_device *dev = local->dev; - int ret = 0, i; - struct { - u16 page; - u16 offset; - u16 len; - } dlbuffer; - u32 bufaddr; - - if (local->hw_downloading) { - printk(KERN_WARNING "%s: Already downloading - aborting new " - "request\n", dev->name); - return -1; - } - - ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER, - &dlbuffer, 6, 0); - - if (ret < 0) { - printk(KERN_WARNING "%s: Could not read download buffer " - "parameters\n", dev->name); - goto out; - } - - dlbuffer.page = le16_to_cpu(dlbuffer.page); - dlbuffer.offset = le16_to_cpu(dlbuffer.offset); - dlbuffer.len = le16_to_cpu(dlbuffer.len); - - printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n", - dlbuffer.len, dlbuffer.page, dlbuffer.offset); - - bufaddr = (dlbuffer.page << 7) + dlbuffer.offset; - - local->hw_downloading = 1; - - if (!local->pri_only) { - prism2_hw_shutdown(dev, 0); - - if (prism2_hw_init(dev, 0)) { - printk(KERN_WARNING "%s: Could not initialize card for" - " download\n", dev->name); - ret = -1; - goto out; - } - } - - hfa384x_disable_interrupts(dev); - - if (prism2_enable_aux_port(dev, 1)) { - printk(KERN_WARNING "%s: Could not enable AUX port\n", - dev->name); - ret = -1; - goto out; - } - - printk(KERN_DEBUG "%s: starting flash download\n", dev->name); - for (i = 0; i < dl->num_areas; i++) { - int rest_len = dl->data[i].len; - int data_off = 0; - - while (rest_len > 0) { - int block_len; - - block_len = prism2_download_block( - dev, dl->data[i].addr + data_off, - dl->data[i].data + data_off, bufaddr, - rest_len); - - if (block_len < 0) { - ret = -1; - goto out; - } - - rest_len -= block_len; - data_off += block_len; - } - } - - HFA384X_OUTW(0, HFA384X_PARAM1_OFF); - HFA384X_OUTW(0, HFA384X_PARAM2_OFF); - if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | - (HFA384X_PROGMODE_DISABLE << 8), 0)) { - printk(KERN_WARNING "%s: Download command execution failed\n", - dev->name); - ret = -1; - goto out; - } - - if (prism2_enable_aux_port(dev, 0)) { - printk(KERN_DEBUG "%s: Disabling AUX port failed\n", - dev->name); - /* continue anyway.. restart should have taken care of this */ - } - - mdelay(5); - - local->func->hw_reset(dev); - local->hw_downloading = 0; - if (prism2_hw_config(dev, 2)) { - printk(KERN_WARNING "%s: Card configuration after flash " - "download failed\n", dev->name); - ret = -1; - } else { - printk(KERN_INFO "%s: Card initialized successfully after " - "flash download\n", dev->name); - } - - out: - local->hw_downloading = 0; - return ret; -} -#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */ - - -static void prism2_download_free_data(struct prism2_download_data *dl) -{ - int i; - - if (dl == NULL) - return; - - for (i = 0; i < dl->num_areas; i++) - kfree(dl->data[i].data); - kfree(dl); -} - - -static int prism2_download(local_info_t *local, - struct prism2_download_param *param) -{ - int ret = 0; - int i; - u32 total_len = 0; - struct prism2_download_data *dl = NULL; - - printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x " - "num_areas=%d\n", - param->dl_cmd, param->start_addr, param->num_areas); - - if (param->num_areas > 100) { - ret = -EINVAL; - goto out; - } - - dl = kmalloc(sizeof(*dl) + param->num_areas * - sizeof(struct prism2_download_data_area), GFP_KERNEL); - if (dl == NULL) { - ret = -ENOMEM; - goto out; - } - memset(dl, 0, sizeof(*dl) + param->num_areas * - sizeof(struct prism2_download_data_area)); - dl->dl_cmd = param->dl_cmd; - dl->start_addr = param->start_addr; - dl->num_areas = param->num_areas; - for (i = 0; i < param->num_areas; i++) { - PDEBUG(DEBUG_EXTRA2, - " area %d: addr=0x%08x len=%d ptr=0x%p\n", - i, param->data[i].addr, param->data[i].len, - param->data[i].ptr); - - dl->data[i].addr = param->data[i].addr; - dl->data[i].len = param->data[i].len; - - total_len += param->data[i].len; - if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN || - total_len > PRISM2_MAX_DOWNLOAD_LEN) { - ret = -E2BIG; - goto out; - } - - dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL); - if (dl->data[i].data == NULL) { - ret = -ENOMEM; - goto out; - } - - if (copy_from_user(dl->data[i].data, param->data[i].ptr, - param->data[i].len)) { - ret = -EFAULT; - goto out; - } - } - - switch (param->dl_cmd) { - case PRISM2_DOWNLOAD_VOLATILE: - case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT: - ret = prism2_download_volatile(local, dl); - break; - case PRISM2_DOWNLOAD_VOLATILE_GENESIS: - case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT: - ret = prism2_download_genesis(local, dl); - break; - case PRISM2_DOWNLOAD_NON_VOLATILE: -#ifdef PRISM2_NON_VOLATILE_DOWNLOAD - ret = prism2_download_nonvolatile(local, dl); -#else /* PRISM2_NON_VOLATILE_DOWNLOAD */ - printk(KERN_INFO "%s: non-volatile downloading not enabled\n", - local->dev->name); - ret = -EOPNOTSUPP; -#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */ - break; - default: - printk(KERN_DEBUG "%s: unsupported download command %d\n", - local->dev->name, param->dl_cmd); - ret = -EINVAL; - break; - }; - - out: - if (ret == 0 && dl && - param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) { - prism2_download_free_data(local->dl_pri); - local->dl_pri = dl; - } else if (ret == 0 && dl && - param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) { - prism2_download_free_data(local->dl_sec); - local->dl_sec = dl; - } else - prism2_download_free_data(dl); - - return ret; -} diff --git a/trunk/drivers/net/wireless/hostap/hostap_hw.c b/trunk/drivers/net/wireless/hostap/hostap_hw.c deleted file mode 100644 index dc31f5351b36..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_hw.c +++ /dev/null @@ -1,3635 +0,0 @@ -/* - * Host AP (software wireless LAN access point) driver for - * Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2005, Jouni Malinen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - * - * FIX: - * - there is currently no way of associating TX packets to correct wds device - * when TX Exc/OK event occurs, so all tx_packets and some - * tx_errors/tx_dropped are added to the main netdevice; using sw_support - * field in txdesc might be used to fix this (using Alloc event to increment - * tx_packets would need some further info in txfid table) - * - * Buffer Access Path (BAP) usage: - * Prism2 cards have two separate BAPs for accessing the card memory. These - * should allow concurrent access to two different frames and the driver - * previously used BAP0 for sending data and BAP1 for receiving data. - * However, there seems to be number of issues with concurrent access and at - * least one know hardware bug in using BAP0 and BAP1 concurrently with PCI - * Prism2.5. Therefore, the driver now only uses BAP0 for moving data between - * host and card memories. BAP0 accesses are protected with local->baplock - * (spin_lock_bh) to prevent concurrent use. - */ - - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hostap_80211.h" -#include "hostap.h" -#include "hostap_ap.h" - - -/* #define final_version */ - -static int mtu = 1500; -module_param(mtu, int, 0444); -MODULE_PARM_DESC(mtu, "Maximum transfer unit"); - -static int channel[MAX_PARM_DEVICES] = { 3, DEF_INTS }; -module_param_array(channel, int, NULL, 0444); -MODULE_PARM_DESC(channel, "Initial channel"); - -static char essid[33] = "test"; -module_param_string(essid, essid, sizeof(essid), 0444); -MODULE_PARM_DESC(essid, "Host AP's ESSID"); - -static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS }; -module_param_array(iw_mode, int, NULL, 0444); -MODULE_PARM_DESC(iw_mode, "Initial operation mode"); - -static int beacon_int[MAX_PARM_DEVICES] = { 100, DEF_INTS }; -module_param_array(beacon_int, int, NULL, 0444); -MODULE_PARM_DESC(beacon_int, "Beacon interval (1 = 1024 usec)"); - -static int dtim_period[MAX_PARM_DEVICES] = { 1, DEF_INTS }; -module_param_array(dtim_period, int, NULL, 0444); -MODULE_PARM_DESC(dtim_period, "DTIM period"); - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) -static int bus_master_threshold_rx[MAX_PARM_DEVICES] = { 100, DEF_INTS }; -module_param_array(bus_master_threshold_rx, int, NULL, 0444); -MODULE_PARM_DESC(bus_master_threshold_rx, "Packet length threshold for using " - "PCI bus master on RX"); - -static int bus_master_threshold_tx[MAX_PARM_DEVICES] = { 100, DEF_INTS }; -module_param_array(bus_master_threshold_tx, int, NULL, 0444); -MODULE_PARM_DESC(bus_master_threshold_tx, "Packet length threshold for using " - "PCI bus master on TX"); -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - -static char dev_template[16] = "wlan%d"; -module_param_string(dev_template, dev_template, sizeof(dev_template), 0444); -MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: " - "wlan%d)"); - -#ifdef final_version -#define EXTRA_EVENTS_WTERR 0 -#else -/* check WTERR events (Wait Time-out) in development versions */ -#define EXTRA_EVENTS_WTERR HFA384X_EV_WTERR -#endif - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) -#define EXTRA_EVENTS_BUS_MASTER (HFA384X_EV_PCI_M0 | HFA384X_EV_PCI_M1) -#else -#define EXTRA_EVENTS_BUS_MASTER 0 -#endif - -/* Events that will be using BAP0 */ -#define HFA384X_BAP0_EVENTS \ - (HFA384X_EV_TXEXC | HFA384X_EV_RX | HFA384X_EV_INFO | HFA384X_EV_TX) - -/* event mask, i.e., events that will result in an interrupt */ -#define HFA384X_EVENT_MASK \ - (HFA384X_BAP0_EVENTS | HFA384X_EV_ALLOC | HFA384X_EV_INFDROP | \ - HFA384X_EV_CMD | HFA384X_EV_TICK | \ - EXTRA_EVENTS_WTERR | EXTRA_EVENTS_BUS_MASTER) - -/* Default TX control flags: use 802.11 headers and request interrupt for - * failed transmits. Frames that request ACK callback, will add - * _TX_OK flag and _ALT_RTRY flag may be used to select different retry policy. - */ -#define HFA384X_TX_CTRL_FLAGS \ - (HFA384X_TX_CTRL_802_11 | HFA384X_TX_CTRL_TX_EX) - - -/* ca. 1 usec */ -#define HFA384X_CMD_BUSY_TIMEOUT 5000 -#define HFA384X_BAP_BUSY_TIMEOUT 50000 - -/* ca. 10 usec */ -#define HFA384X_CMD_COMPL_TIMEOUT 20000 -#define HFA384X_DL_COMPL_TIMEOUT 1000000 - -/* Wait times for initialization; yield to other processes to avoid busy - * waiting for long time. */ -#define HFA384X_INIT_TIMEOUT (HZ / 2) /* 500 ms */ -#define HFA384X_ALLOC_COMPL_TIMEOUT (HZ / 20) /* 50 ms */ - - -static void prism2_hw_reset(struct net_device *dev); -static void prism2_check_sta_fw_version(local_info_t *local); - -#ifdef PRISM2_DOWNLOAD_SUPPORT -/* hostap_download.c */ -static int prism2_download_aux_dump(struct net_device *dev, - unsigned int addr, int len, u8 *buf); -static u8 * prism2_read_pda(struct net_device *dev); -static int prism2_download(local_info_t *local, - struct prism2_download_param *param); -static void prism2_download_free_data(struct prism2_download_data *dl); -static int prism2_download_volatile(local_info_t *local, - struct prism2_download_data *param); -static int prism2_download_genesis(local_info_t *local, - struct prism2_download_data *param); -static int prism2_get_ram_size(local_info_t *local); -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - - - - -#ifndef final_version -/* magic value written to SWSUPPORT0 reg. for detecting whether card is still - * present */ -#define HFA384X_MAGIC 0x8A32 -#endif - - -static u16 hfa384x_read_reg(struct net_device *dev, u16 reg) -{ - return HFA384X_INW(reg); -} - - -static void hfa384x_read_regs(struct net_device *dev, - struct hfa384x_regs *regs) -{ - regs->cmd = HFA384X_INW(HFA384X_CMD_OFF); - regs->evstat = HFA384X_INW(HFA384X_EVSTAT_OFF); - regs->offset0 = HFA384X_INW(HFA384X_OFFSET0_OFF); - regs->offset1 = HFA384X_INW(HFA384X_OFFSET1_OFF); - regs->swsupport0 = HFA384X_INW(HFA384X_SWSUPPORT0_OFF); -} - - -/** - * __hostap_cmd_queue_free - Free Prism2 command queue entry (private) - * @local: pointer to private Host AP driver data - * @entry: Prism2 command queue entry to be freed - * @del_req: request the entry to be removed - * - * Internal helper function for freeing Prism2 command queue entries. - * Caller must have acquired local->cmdlock before calling this function. - */ -static inline void __hostap_cmd_queue_free(local_info_t *local, - struct hostap_cmd_queue *entry, - int del_req) -{ - if (del_req) { - entry->del_req = 1; - if (!list_empty(&entry->list)) { - list_del_init(&entry->list); - local->cmd_queue_len--; - } - } - - if (atomic_dec_and_test(&entry->usecnt) && entry->del_req) - kfree(entry); -} - - -/** - * hostap_cmd_queue_free - Free Prism2 command queue entry - * @local: pointer to private Host AP driver data - * @entry: Prism2 command queue entry to be freed - * @del_req: request the entry to be removed - * - * Free a Prism2 command queue entry. - */ -static inline void hostap_cmd_queue_free(local_info_t *local, - struct hostap_cmd_queue *entry, - int del_req) -{ - unsigned long flags; - - spin_lock_irqsave(&local->cmdlock, flags); - __hostap_cmd_queue_free(local, entry, del_req); - spin_unlock_irqrestore(&local->cmdlock, flags); -} - - -/** - * prism2_clear_cmd_queue - Free all pending Prism2 command queue entries - * @local: pointer to private Host AP driver data - */ -static void prism2_clear_cmd_queue(local_info_t *local) -{ - struct list_head *ptr, *n; - unsigned long flags; - struct hostap_cmd_queue *entry; - - spin_lock_irqsave(&local->cmdlock, flags); - list_for_each_safe(ptr, n, &local->cmd_queue) { - entry = list_entry(ptr, struct hostap_cmd_queue, list); - atomic_inc(&entry->usecnt); - printk(KERN_DEBUG "%s: removed pending cmd_queue entry " - "(type=%d, cmd=0x%04x, param0=0x%04x)\n", - local->dev->name, entry->type, entry->cmd, - entry->param0); - __hostap_cmd_queue_free(local, entry, 1); - } - if (local->cmd_queue_len) { - /* This should not happen; print debug message and clear - * queue length. */ - printk(KERN_DEBUG "%s: cmd_queue_len (%d) not zero after " - "flush\n", local->dev->name, local->cmd_queue_len); - local->cmd_queue_len = 0; - } - spin_unlock_irqrestore(&local->cmdlock, flags); -} - - -/** - * hfa384x_cmd_issue - Issue a Prism2 command to the hardware - * @dev: pointer to net_device - * @entry: Prism2 command queue entry to be issued - */ -static inline int hfa384x_cmd_issue(struct net_device *dev, - struct hostap_cmd_queue *entry) -{ - struct hostap_interface *iface; - local_info_t *local; - int tries; - u16 reg; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->card_present && !local->func->card_present(local)) - return -ENODEV; - - if (entry->issued) { - printk(KERN_DEBUG "%s: driver bug - re-issuing command @%p\n", - dev->name, entry); - } - - /* wait until busy bit is clear; this should always be clear since the - * commands are serialized */ - tries = HFA384X_CMD_BUSY_TIMEOUT; - while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) { - tries--; - udelay(1); - } -#ifndef final_version - if (tries != HFA384X_CMD_BUSY_TIMEOUT) { - prism2_io_debug_error(dev, 1); - printk(KERN_DEBUG "%s: hfa384x_cmd_issue: cmd reg was busy " - "for %d usec\n", dev->name, - HFA384X_CMD_BUSY_TIMEOUT - tries); - } -#endif - if (tries == 0) { - reg = HFA384X_INW(HFA384X_CMD_OFF); - prism2_io_debug_error(dev, 2); - printk(KERN_DEBUG "%s: hfa384x_cmd_issue - timeout - " - "reg=0x%04x\n", dev->name, reg); - return -ETIMEDOUT; - } - - /* write command */ - spin_lock_irqsave(&local->cmdlock, flags); - HFA384X_OUTW(entry->param0, HFA384X_PARAM0_OFF); - HFA384X_OUTW(entry->param1, HFA384X_PARAM1_OFF); - HFA384X_OUTW(entry->cmd, HFA384X_CMD_OFF); - entry->issued = 1; - spin_unlock_irqrestore(&local->cmdlock, flags); - - return 0; -} - - -/** - * hfa384x_cmd - Issue a Prism2 command and wait (sleep) for completion - * @dev: pointer to net_device - * @cmd: Prism2 command code (HFA384X_CMD_CODE_*) - * @param0: value for Param0 register - * @param1: value for Param1 register (pointer; %NULL if not used) - * @resp0: pointer for Resp0 data or %NULL if Resp0 is not needed - * - * Issue given command (possibly after waiting in command queue) and sleep - * until the command is completed (or timed out or interrupted). This can be - * called only from user process context. - */ -static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0, - u16 *param1, u16 *resp0) -{ - struct hostap_interface *iface; - local_info_t *local; - int err, res, issue, issued = 0; - unsigned long flags; - struct hostap_cmd_queue *entry; - DECLARE_WAITQUEUE(wait, current); - - iface = netdev_priv(dev); - local = iface->local; - - if (in_interrupt()) { - printk(KERN_DEBUG "%s: hfa384x_cmd called from interrupt " - "context\n", dev->name); - return -1; - } - - if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN) { - printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n", - dev->name); - return -1; - } - - if (signal_pending(current)) - return -EINTR; - - entry = (struct hostap_cmd_queue *) - kmalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n", - dev->name); - return -ENOMEM; - } - memset(entry, 0, sizeof(*entry)); - atomic_set(&entry->usecnt, 1); - entry->type = CMD_SLEEP; - entry->cmd = cmd; - entry->param0 = param0; - if (param1) - entry->param1 = *param1; - init_waitqueue_head(&entry->compl); - - /* prepare to wait for command completion event, but do not sleep yet - */ - add_wait_queue(&entry->compl, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irqsave(&local->cmdlock, flags); - issue = list_empty(&local->cmd_queue); - if (issue) - entry->issuing = 1; - list_add_tail(&entry->list, &local->cmd_queue); - local->cmd_queue_len++; - spin_unlock_irqrestore(&local->cmdlock, flags); - - err = 0; - if (!issue) - goto wait_completion; - - if (signal_pending(current)) - err = -EINTR; - - if (!err) { - if (hfa384x_cmd_issue(dev, entry)) - err = -ETIMEDOUT; - else - issued = 1; - } - - wait_completion: - if (!err && entry->type != CMD_COMPLETED) { - /* sleep until command is completed or timed out */ - res = schedule_timeout(2 * HZ); - } else - res = -1; - - if (!err && signal_pending(current)) - err = -EINTR; - - if (err && issued) { - /* the command was issued, so a CmdCompl event should occur - * soon; however, there's a pending signal and - * schedule_timeout() would be interrupted; wait a short period - * of time to avoid removing entry from the list before - * CmdCompl event */ - udelay(300); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&entry->compl, &wait); - - /* If entry->list is still in the list, it must be removed - * first and in this case prism2_cmd_ev() does not yet have - * local reference to it, and the data can be kfree()'d - * here. If the command completion event is still generated, - * it will be assigned to next (possibly) pending command, but - * the driver will reset the card anyway due to timeout - * - * If the entry is not in the list prism2_cmd_ev() has a local - * reference to it, but keeps cmdlock as long as the data is - * needed, so the data can be kfree()'d here. */ - - /* FIX: if the entry->list is in the list, it has not been completed - * yet, so removing it here is somewhat wrong.. this could cause - * references to freed memory and next list_del() causing NULL pointer - * dereference.. it would probably be better to leave the entry in the - * list and the list should be emptied during hw reset */ - - spin_lock_irqsave(&local->cmdlock, flags); - if (!list_empty(&entry->list)) { - printk(KERN_DEBUG "%s: hfa384x_cmd: entry still in list? " - "(entry=%p, type=%d, res=%d)\n", dev->name, entry, - entry->type, res); - list_del_init(&entry->list); - local->cmd_queue_len--; - } - spin_unlock_irqrestore(&local->cmdlock, flags); - - if (err) { - printk(KERN_DEBUG "%s: hfa384x_cmd: interrupted; err=%d\n", - dev->name, err); - res = err; - goto done; - } - - if (entry->type != CMD_COMPLETED) { - u16 reg = HFA384X_INW(HFA384X_EVSTAT_OFF); - printk(KERN_DEBUG "%s: hfa384x_cmd: command was not " - "completed (res=%d, entry=%p, type=%d, cmd=0x%04x, " - "param0=0x%04x, EVSTAT=%04x INTEN=%04x)\n", dev->name, - res, entry, entry->type, entry->cmd, entry->param0, reg, - HFA384X_INW(HFA384X_INTEN_OFF)); - if (reg & HFA384X_EV_CMD) { - /* Command completion event is pending, but the - * interrupt was not delivered - probably an issue - * with pcmcia-cs configuration. */ - printk(KERN_WARNING "%s: interrupt delivery does not " - "seem to work\n", dev->name); - } - prism2_io_debug_error(dev, 3); - res = -ETIMEDOUT; - goto done; - } - - if (resp0 != NULL) - *resp0 = entry->resp0; -#ifndef final_version - if (entry->res) { - printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x, " - "resp0=0x%04x\n", - dev->name, cmd, entry->res, entry->resp0); - } -#endif /* final_version */ - - res = entry->res; - done: - hostap_cmd_queue_free(local, entry, 1); - return res; -} - - -/** - * hfa384x_cmd_callback - Issue a Prism2 command; callback when completed - * @dev: pointer to net_device - * @cmd: Prism2 command code (HFA384X_CMD_CODE_*) - * @param0: value for Param0 register - * @callback: command completion callback function (%NULL = no callback) - * @context: context data to be given to the callback function - * - * Issue given command (possibly after waiting in command queue) and use - * callback function to indicate command completion. This can be called both - * from user and interrupt context. The callback function will be called in - * hardware IRQ context. It can be %NULL, when no function is called when - * command is completed. - */ -static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0, - void (*callback)(struct net_device *dev, - long context, u16 resp0, - u16 status), - long context) -{ - struct hostap_interface *iface; - local_info_t *local; - int issue, ret; - unsigned long flags; - struct hostap_cmd_queue *entry; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN + 2) { - printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n", - dev->name); - return -1; - } - - entry = (struct hostap_cmd_queue *) - kmalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc " - "failed\n", dev->name); - return -ENOMEM; - } - memset(entry, 0, sizeof(*entry)); - atomic_set(&entry->usecnt, 1); - entry->type = CMD_CALLBACK; - entry->cmd = cmd; - entry->param0 = param0; - entry->callback = callback; - entry->context = context; - - spin_lock_irqsave(&local->cmdlock, flags); - issue = list_empty(&local->cmd_queue); - if (issue) - entry->issuing = 1; - list_add_tail(&entry->list, &local->cmd_queue); - local->cmd_queue_len++; - spin_unlock_irqrestore(&local->cmdlock, flags); - - if (issue && hfa384x_cmd_issue(dev, entry)) - ret = -ETIMEDOUT; - else - ret = 0; - - hostap_cmd_queue_free(local, entry, ret); - - return ret; -} - - -/** - * __hfa384x_cmd_no_wait - Issue a Prism2 command (private) - * @dev: pointer to net_device - * @cmd: Prism2 command code (HFA384X_CMD_CODE_*) - * @param0: value for Param0 register - * @io_debug_num: I/O debug error number - * - * Shared helper function for hfa384x_cmd_wait() and hfa384x_cmd_no_wait(). - */ -static int __hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd, u16 param0, - int io_debug_num) -{ - int tries; - u16 reg; - - /* wait until busy bit is clear; this should always be clear since the - * commands are serialized */ - tries = HFA384X_CMD_BUSY_TIMEOUT; - while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) { - tries--; - udelay(1); - } - if (tries == 0) { - reg = HFA384X_INW(HFA384X_CMD_OFF); - prism2_io_debug_error(dev, io_debug_num); - printk(KERN_DEBUG "%s: __hfa384x_cmd_no_wait(%d) - timeout - " - "reg=0x%04x\n", dev->name, io_debug_num, reg); - return -ETIMEDOUT; - } - - /* write command */ - HFA384X_OUTW(param0, HFA384X_PARAM0_OFF); - HFA384X_OUTW(cmd, HFA384X_CMD_OFF); - - return 0; -} - - -/** - * hfa384x_cmd_wait - Issue a Prism2 command and busy wait for completion - * @dev: pointer to net_device - * @cmd: Prism2 command code (HFA384X_CMD_CODE_*) - * @param0: value for Param0 register - */ -static int hfa384x_cmd_wait(struct net_device *dev, u16 cmd, u16 param0) -{ - int res, tries; - u16 reg; - - res = __hfa384x_cmd_no_wait(dev, cmd, param0, 4); - if (res) - return res; - - /* wait for command completion */ - if ((cmd & HFA384X_CMDCODE_MASK) == HFA384X_CMDCODE_DOWNLOAD) - tries = HFA384X_DL_COMPL_TIMEOUT; - else - tries = HFA384X_CMD_COMPL_TIMEOUT; - - while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) && - tries > 0) { - tries--; - udelay(10); - } - if (tries == 0) { - reg = HFA384X_INW(HFA384X_EVSTAT_OFF); - prism2_io_debug_error(dev, 5); - printk(KERN_DEBUG "%s: hfa384x_cmd_wait - timeout2 - " - "reg=0x%04x\n", dev->name, reg); - return -ETIMEDOUT; - } - - res = (HFA384X_INW(HFA384X_STATUS_OFF) & - (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | - BIT(8))) >> 8; -#ifndef final_version - if (res) { - printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x\n", - dev->name, cmd, res); - } -#endif - - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); - - return res; -} - - -/** - * hfa384x_cmd_no_wait - Issue a Prism2 command; do not wait for completion - * @dev: pointer to net_device - * @cmd: Prism2 command code (HFA384X_CMD_CODE_*) - * @param0: value for Param0 register - */ -static inline int hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd, - u16 param0) -{ - return __hfa384x_cmd_no_wait(dev, cmd, param0, 6); -} - - -/** - * prism2_cmd_ev - Prism2 command completion event handler - * @dev: pointer to net_device - * - * Interrupt handler for command completion events. Called by the main - * interrupt handler in hardware IRQ context. Read Resp0 and status registers - * from the hardware and ACK the event. Depending on the issued command type - * either wake up the sleeping process that is waiting for command completion - * or call the callback function. Issue the next command, if one is pending. - */ -static void prism2_cmd_ev(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hostap_cmd_queue *entry = NULL; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock(&local->cmdlock); - if (!list_empty(&local->cmd_queue)) { - entry = list_entry(local->cmd_queue.next, - struct hostap_cmd_queue, list); - atomic_inc(&entry->usecnt); - list_del_init(&entry->list); - local->cmd_queue_len--; - - if (!entry->issued) { - printk(KERN_DEBUG "%s: Command completion event, but " - "cmd not issued\n", dev->name); - __hostap_cmd_queue_free(local, entry, 1); - entry = NULL; - } - } - spin_unlock(&local->cmdlock); - - if (!entry) { - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); - printk(KERN_DEBUG "%s: Command completion event, but no " - "pending commands\n", dev->name); - return; - } - - entry->resp0 = HFA384X_INW(HFA384X_RESP0_OFF); - entry->res = (HFA384X_INW(HFA384X_STATUS_OFF) & - (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | - BIT(9) | BIT(8))) >> 8; - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); - - /* TODO: rest of the CmdEv handling could be moved to tasklet */ - if (entry->type == CMD_SLEEP) { - entry->type = CMD_COMPLETED; - wake_up_interruptible(&entry->compl); - } else if (entry->type == CMD_CALLBACK) { - if (entry->callback) - entry->callback(dev, entry->context, entry->resp0, - entry->res); - } else { - printk(KERN_DEBUG "%s: Invalid command completion type %d\n", - dev->name, entry->type); - } - hostap_cmd_queue_free(local, entry, 1); - - /* issue next command, if pending */ - entry = NULL; - spin_lock(&local->cmdlock); - if (!list_empty(&local->cmd_queue)) { - entry = list_entry(local->cmd_queue.next, - struct hostap_cmd_queue, list); - if (entry->issuing) { - /* hfa384x_cmd() has already started issuing this - * command, so do not start here */ - entry = NULL; - } - if (entry) - atomic_inc(&entry->usecnt); - } - spin_unlock(&local->cmdlock); - - if (entry) { - /* issue next command; if command issuing fails, remove the - * entry from cmd_queue */ - int res = hfa384x_cmd_issue(dev, entry); - spin_lock(&local->cmdlock); - __hostap_cmd_queue_free(local, entry, res); - spin_unlock(&local->cmdlock); - } -} - - -static inline int hfa384x_wait_offset(struct net_device *dev, u16 o_off) -{ - int tries = HFA384X_BAP_BUSY_TIMEOUT; - int res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY; - - while (res && tries > 0) { - tries--; - udelay(1); - res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY; - } - return res; -} - - -/* Offset must be even */ -static int hfa384x_setup_bap(struct net_device *dev, u16 bap, u16 id, - int offset) -{ - u16 o_off, s_off; - int ret = 0; - - if (offset % 2 || bap > 1) - return -EINVAL; - - if (bap == BAP1) { - o_off = HFA384X_OFFSET1_OFF; - s_off = HFA384X_SELECT1_OFF; - } else { - o_off = HFA384X_OFFSET0_OFF; - s_off = HFA384X_SELECT0_OFF; - } - - if (hfa384x_wait_offset(dev, o_off)) { - prism2_io_debug_error(dev, 7); - printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout before\n", - dev->name); - ret = -ETIMEDOUT; - goto out; - } - - HFA384X_OUTW(id, s_off); - HFA384X_OUTW(offset, o_off); - - if (hfa384x_wait_offset(dev, o_off)) { - prism2_io_debug_error(dev, 8); - printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout after\n", - dev->name); - ret = -ETIMEDOUT; - goto out; - } -#ifndef final_version - if (HFA384X_INW(o_off) & HFA384X_OFFSET_ERR) { - prism2_io_debug_error(dev, 9); - printk(KERN_DEBUG "%s: hfa384x_setup_bap - offset error " - "(%d,0x04%x,%d); reg=0x%04x\n", - dev->name, bap, id, offset, HFA384X_INW(o_off)); - ret = -EINVAL; - } -#endif - - out: - return ret; -} - - -static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len, - int exact_len) -{ - struct hostap_interface *iface; - local_info_t *local; - int res, rlen = 0; - struct hfa384x_rid_hdr rec; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->no_pri) { - printk(KERN_DEBUG "%s: cannot get RID %04x (len=%d) - no PRI " - "f/w\n", dev->name, rid, len); - return -ENOTTY; /* Well.. not really correct, but return - * something unique enough.. */ - } - - if ((local->func->card_present && !local->func->card_present(local)) || - local->hw_downloading) - return -ENODEV; - - res = down_interruptible(&local->rid_bap_sem); - if (res) - return res; - - res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS, rid, NULL, NULL); - if (res) { - printk(KERN_DEBUG "%s: hfa384x_get_rid: CMDCODE_ACCESS failed " - "(res=%d, rid=%04x, len=%d)\n", - dev->name, res, rid, len); - up(&local->rid_bap_sem); - return res; - } - - spin_lock_bh(&local->baplock); - - res = hfa384x_setup_bap(dev, BAP0, rid, 0); - if (!res) - res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec)); - - if (le16_to_cpu(rec.len) == 0) { - /* RID not available */ - res = -ENODATA; - } - - rlen = (le16_to_cpu(rec.len) - 1) * 2; - if (!res && exact_len && rlen != len) { - printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: " - "rid=0x%04x, len=%d (expected %d)\n", - dev->name, rid, rlen, len); - res = -ENODATA; - } - - if (!res) - res = hfa384x_from_bap(dev, BAP0, buf, len); - - spin_unlock_bh(&local->baplock); - up(&local->rid_bap_sem); - - if (res) { - if (res != -ENODATA) - printk(KERN_DEBUG "%s: hfa384x_get_rid (rid=%04x, " - "len=%d) - failed - res=%d\n", dev->name, rid, - len, res); - if (res == -ETIMEDOUT) - prism2_hw_reset(dev); - return res; - } - - return rlen; -} - - -static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hfa384x_rid_hdr rec; - int res; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->no_pri) { - printk(KERN_DEBUG "%s: cannot set RID %04x (len=%d) - no PRI " - "f/w\n", dev->name, rid, len); - return -ENOTTY; /* Well.. not really correct, but return - * something unique enough.. */ - } - - if ((local->func->card_present && !local->func->card_present(local)) || - local->hw_downloading) - return -ENODEV; - - rec.rid = cpu_to_le16(rid); - /* RID len in words and +1 for rec.rid */ - rec.len = cpu_to_le16(len / 2 + len % 2 + 1); - - res = down_interruptible(&local->rid_bap_sem); - if (res) - return res; - - spin_lock_bh(&local->baplock); - res = hfa384x_setup_bap(dev, BAP0, rid, 0); - if (!res) - res = hfa384x_to_bap(dev, BAP0, &rec, sizeof(rec)); - if (!res) - res = hfa384x_to_bap(dev, BAP0, buf, len); - spin_unlock_bh(&local->baplock); - - if (res) { - printk(KERN_DEBUG "%s: hfa384x_set_rid (rid=%04x, len=%d) - " - "failed - res=%d\n", dev->name, rid, len, res); - up(&local->rid_bap_sem); - return res; - } - - res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL); - up(&local->rid_bap_sem); - if (res) { - printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE " - "failed (res=%d, rid=%04x, len=%d)\n", - dev->name, res, rid, len); - return res; - } - - if (res == -ETIMEDOUT) - prism2_hw_reset(dev); - - return res; -} - - -static void hfa384x_disable_interrupts(struct net_device *dev) -{ - /* disable interrupts and clear event status */ - HFA384X_OUTW(0, HFA384X_INTEN_OFF); - HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF); -} - - -static void hfa384x_enable_interrupts(struct net_device *dev) -{ - /* ack pending events and enable interrupts from selected events */ - HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF); - HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF); -} - - -static void hfa384x_events_no_bap0(struct net_device *dev) -{ - HFA384X_OUTW(HFA384X_EVENT_MASK & ~HFA384X_BAP0_EVENTS, - HFA384X_INTEN_OFF); -} - - -static void hfa384x_events_all(struct net_device *dev) -{ - HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF); -} - - -static void hfa384x_events_only_cmd(struct net_device *dev) -{ - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_INTEN_OFF); -} - - -static u16 hfa384x_allocate_fid(struct net_device *dev, int len) -{ - u16 fid; - unsigned long delay; - - /* FIX: this could be replace with hfa384x_cmd() if the Alloc event - * below would be handled like CmdCompl event (sleep here, wake up from - * interrupt handler */ - if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_ALLOC, len)) { - printk(KERN_DEBUG "%s: cannot allocate fid, len=%d\n", - dev->name, len); - return 0xffff; - } - - delay = jiffies + HFA384X_ALLOC_COMPL_TIMEOUT; - while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC) && - time_before(jiffies, delay)) - yield(); - if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC)) { - printk("%s: fid allocate, len=%d - timeout\n", dev->name, len); - return 0xffff; - } - - fid = HFA384X_INW(HFA384X_ALLOCFID_OFF); - HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF); - - return fid; -} - - -static int prism2_reset_port(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - int res; - - iface = netdev_priv(dev); - local = iface->local; - - if (!local->dev_enabled) - return 0; - - res = hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0, - NULL, NULL); - if (res) - printk(KERN_DEBUG "%s: reset port failed to disable port\n", - dev->name); - else { - res = hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0, - NULL, NULL); - if (res) - printk(KERN_DEBUG "%s: reset port failed to enable " - "port\n", dev->name); - } - - /* It looks like at least some STA firmware versions reset - * fragmentation threshold back to 2346 after enable command. Restore - * the configured value, if it differs from this default. */ - if (local->fragm_threshold != 2346 && - hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, - local->fragm_threshold)) { - printk(KERN_DEBUG "%s: failed to restore fragmentation " - "threshold (%d) after Port0 enable\n", - dev->name, local->fragm_threshold); - } - - return res; -} - - -static int prism2_get_version_info(struct net_device *dev, u16 rid, - const char *txt) -{ - struct hfa384x_comp_ident comp; - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->no_pri) { - /* PRI f/w not yet available - cannot read RIDs */ - return -1; - } - if (hfa384x_get_rid(dev, rid, &comp, sizeof(comp), 1) < 0) { - printk(KERN_DEBUG "Could not get RID for component %s\n", txt); - return -1; - } - - printk(KERN_INFO "%s: %s: id=0x%02x v%d.%d.%d\n", dev->name, txt, - __le16_to_cpu(comp.id), __le16_to_cpu(comp.major), - __le16_to_cpu(comp.minor), __le16_to_cpu(comp.variant)); - return 0; -} - - -static int prism2_setup_rids(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 tmp; - int ret = 0; - - iface = netdev_priv(dev); - local = iface->local; - - hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000); - - if (!local->fw_ap) { - tmp = hostap_get_porttype(local); - ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp); - if (ret) { - printk("%s: Port type setting to %d failed\n", - dev->name, tmp); - goto fail; - } - } - - /* Setting SSID to empty string seems to kill the card in Host AP mode - */ - if (local->iw_mode != IW_MODE_MASTER || local->essid[0] != '\0') { - ret = hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, - local->essid); - if (ret) { - printk("%s: AP own SSID setting failed\n", dev->name); - goto fail; - } - } - - ret = hostap_set_word(dev, HFA384X_RID_CNFMAXDATALEN, - PRISM2_DATA_MAXLEN); - if (ret) { - printk("%s: MAC data length setting to %d failed\n", - dev->name, PRISM2_DATA_MAXLEN); - goto fail; - } - - if (hfa384x_get_rid(dev, HFA384X_RID_CHANNELLIST, &tmp, 2, 1) < 0) { - printk("%s: Channel list read failed\n", dev->name); - ret = -EINVAL; - goto fail; - } - local->channel_mask = __le16_to_cpu(tmp); - - if (local->channel < 1 || local->channel > 14 || - !(local->channel_mask & (1 << (local->channel - 1)))) { - printk(KERN_WARNING "%s: Channel setting out of range " - "(%d)!\n", dev->name, local->channel); - ret = -EBUSY; - goto fail; - } - - ret = hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel); - if (ret) { - printk("%s: Channel setting to %d failed\n", - dev->name, local->channel); - goto fail; - } - - ret = hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, - local->beacon_int); - if (ret) { - printk("%s: Beacon interval setting to %d failed\n", - dev->name, local->beacon_int); - /* this may fail with Symbol/Lucent firmware */ - if (ret == -ETIMEDOUT) - goto fail; - } - - ret = hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, - local->dtim_period); - if (ret) { - printk("%s: DTIM period setting to %d failed\n", - dev->name, local->dtim_period); - /* this may fail with Symbol/Lucent firmware */ - if (ret == -ETIMEDOUT) - goto fail; - } - - ret = hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, - local->is_promisc); - if (ret) - printk(KERN_INFO "%s: Setting promiscuous mode (%d) failed\n", - dev->name, local->is_promisc); - - if (!local->fw_ap) { - ret = hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, - local->essid); - if (ret) { - printk("%s: Desired SSID setting failed\n", dev->name); - goto fail; - } - } - - /* Setup TXRateControl, defaults to allow use of 1, 2, 5.5, and - * 11 Mbps in automatic TX rate fallback and 1 and 2 Mbps as basic - * rates */ - if (local->tx_rate_control == 0) { - local->tx_rate_control = - HFA384X_RATES_1MBPS | - HFA384X_RATES_2MBPS | - HFA384X_RATES_5MBPS | - HFA384X_RATES_11MBPS; - } - if (local->basic_rates == 0) - local->basic_rates = HFA384X_RATES_1MBPS | HFA384X_RATES_2MBPS; - - if (!local->fw_ap) { - ret = hostap_set_word(dev, HFA384X_RID_TXRATECONTROL, - local->tx_rate_control); - if (ret) { - printk("%s: TXRateControl setting to %d failed\n", - dev->name, local->tx_rate_control); - goto fail; - } - - ret = hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES, - local->tx_rate_control); - if (ret) { - printk("%s: cnfSupportedRates setting to %d failed\n", - dev->name, local->tx_rate_control); - } - - ret = hostap_set_word(dev, HFA384X_RID_CNFBASICRATES, - local->basic_rates); - if (ret) { - printk("%s: cnfBasicRates setting to %d failed\n", - dev->name, local->basic_rates); - } - - ret = hostap_set_word(dev, HFA384X_RID_CREATEIBSS, 1); - if (ret) { - printk("%s: Create IBSS setting to 1 failed\n", - dev->name); - } - } - - if (local->name_set) - (void) hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, - local->name); - - if (hostap_set_encryption(local)) { - printk(KERN_INFO "%s: could not configure encryption\n", - dev->name); - } - - (void) hostap_set_antsel(local); - - if (hostap_set_roaming(local)) { - printk(KERN_INFO "%s: could not set host roaming\n", - dev->name); - } - - if (local->sta_fw_ver >= PRISM2_FW_VER(1,6,3) && - hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY, local->enh_sec)) - printk(KERN_INFO "%s: cnfEnhSecurity setting to 0x%x failed\n", - dev->name, local->enh_sec); - - /* 32-bit tallies were added in STA f/w 0.8.0, but they were apparently - * not working correctly (last seven counters report bogus values). - * This has been fixed in 0.8.2, so enable 32-bit tallies only - * beginning with that firmware version. Another bug fix for 32-bit - * tallies in 1.4.0; should 16-bit tallies be used for some other - * versions, too? */ - if (local->sta_fw_ver >= PRISM2_FW_VER(0,8,2)) { - if (hostap_set_word(dev, HFA384X_RID_CNFTHIRTY2TALLY, 1)) { - printk(KERN_INFO "%s: cnfThirty2Tally setting " - "failed\n", dev->name); - local->tallies32 = 0; - } else - local->tallies32 = 1; - } else - local->tallies32 = 0; - - hostap_set_auth_algs(local); - - if (hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, - local->fragm_threshold)) { - printk(KERN_INFO "%s: setting FragmentationThreshold to %d " - "failed\n", dev->name, local->fragm_threshold); - } - - if (hostap_set_word(dev, HFA384X_RID_RTSTHRESHOLD, - local->rts_threshold)) { - printk(KERN_INFO "%s: setting RTSThreshold to %d failed\n", - dev->name, local->rts_threshold); - } - - if (local->manual_retry_count >= 0 && - hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT, - local->manual_retry_count)) { - printk(KERN_INFO "%s: setting cnfAltRetryCount to %d failed\n", - dev->name, local->manual_retry_count); - } - - if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1) && - hfa384x_get_rid(dev, HFA384X_RID_CNFDBMADJUST, &tmp, 2, 1) == 2) { - local->rssi_to_dBm = le16_to_cpu(tmp); - } - - if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->wpa && - hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1)) { - printk(KERN_INFO "%s: setting ssnHandlingMode to 1 failed\n", - dev->name); - } - - if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->generic_elem && - hfa384x_set_rid(dev, HFA384X_RID_GENERICELEMENT, - local->generic_elem, local->generic_elem_len)) { - printk(KERN_INFO "%s: setting genericElement failed\n", - dev->name); - } - - fail: - return ret; -} - - -static int prism2_hw_init(struct net_device *dev, int initial) -{ - struct hostap_interface *iface; - local_info_t *local; - int ret, first = 1; - unsigned long start, delay; - - PDEBUG(DEBUG_FLOW, "prism2_hw_init()\n"); - - iface = netdev_priv(dev); - local = iface->local; - - clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits); - - init: - /* initialize HFA 384x */ - ret = hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_INIT, 0); - if (ret) { - printk(KERN_INFO "%s: first command failed - assuming card " - "does not have primary firmware\n", dev_info); - } - - if (first && (HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) { - /* EvStat has Cmd bit set in some cases, so retry once if no - * wait was needed */ - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); - printk(KERN_DEBUG "%s: init command completed too quickly - " - "retrying\n", dev->name); - first = 0; - goto init; - } - - start = jiffies; - delay = jiffies + HFA384X_INIT_TIMEOUT; - while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) && - time_before(jiffies, delay)) - yield(); - if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) { - printk(KERN_DEBUG "%s: assuming no Primary image in " - "flash - card initialization not completed\n", - dev_info); - local->no_pri = 1; -#ifdef PRISM2_DOWNLOAD_SUPPORT - if (local->sram_type == -1) - local->sram_type = prism2_get_ram_size(local); -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - return 1; - } - local->no_pri = 0; - printk(KERN_DEBUG "prism2_hw_init: initialized in %lu ms\n", - (jiffies - start) * 1000 / HZ); - HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); - return 0; -} - - -static int prism2_hw_init2(struct net_device *dev, int initial) -{ - struct hostap_interface *iface; - local_info_t *local; - int i; - - iface = netdev_priv(dev); - local = iface->local; - -#ifdef PRISM2_DOWNLOAD_SUPPORT - kfree(local->pda); - if (local->no_pri) - local->pda = NULL; - else - local->pda = prism2_read_pda(dev); -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - - hfa384x_disable_interrupts(dev); - -#ifndef final_version - HFA384X_OUTW(HFA384X_MAGIC, HFA384X_SWSUPPORT0_OFF); - if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) { - printk("SWSUPPORT0 write/read failed: %04X != %04X\n", - HFA384X_INW(HFA384X_SWSUPPORT0_OFF), HFA384X_MAGIC); - goto failed; - } -#endif - - if (initial || local->pri_only) { - hfa384x_events_only_cmd(dev); - /* get card version information */ - if (prism2_get_version_info(dev, HFA384X_RID_NICID, "NIC") || - prism2_get_version_info(dev, HFA384X_RID_PRIID, "PRI")) { - hfa384x_disable_interrupts(dev); - goto failed; - } - - if (prism2_get_version_info(dev, HFA384X_RID_STAID, "STA")) { - printk(KERN_DEBUG "%s: Failed to read STA f/w version " - "- only Primary f/w present\n", dev->name); - local->pri_only = 1; - return 0; - } - local->pri_only = 0; - hfa384x_disable_interrupts(dev); - } - - /* FIX: could convert allocate_fid to use sleeping CmdCompl wait and - * enable interrupts before this. This would also require some sort of - * sleeping AllocEv waiting */ - - /* allocate TX FIDs */ - local->txfid_len = PRISM2_TXFID_LEN; - for (i = 0; i < PRISM2_TXFID_COUNT; i++) { - local->txfid[i] = hfa384x_allocate_fid(dev, local->txfid_len); - if (local->txfid[i] == 0xffff && local->txfid_len > 1600) { - local->txfid[i] = hfa384x_allocate_fid(dev, 1600); - if (local->txfid[i] != 0xffff) { - printk(KERN_DEBUG "%s: Using shorter TX FID " - "(1600 bytes)\n", dev->name); - local->txfid_len = 1600; - } - } - if (local->txfid[i] == 0xffff) - goto failed; - local->intransmitfid[i] = PRISM2_TXFID_EMPTY; - } - - hfa384x_events_only_cmd(dev); - - if (initial) { - struct list_head *ptr; - prism2_check_sta_fw_version(local); - - if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR, - &dev->dev_addr, 6, 1) < 0) { - printk("%s: could not get own MAC address\n", - dev->name); - } - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - memcpy(iface->dev->dev_addr, dev->dev_addr, ETH_ALEN); - } - } else if (local->fw_ap) - prism2_check_sta_fw_version(local); - - prism2_setup_rids(dev); - - /* MAC is now configured, but port 0 is not yet enabled */ - return 0; - - failed: - if (!local->no_pri) - printk(KERN_WARNING "%s: Initialization failed\n", dev_info); - return 1; -} - - -static int prism2_hw_enable(struct net_device *dev, int initial) -{ - struct hostap_interface *iface; - local_info_t *local; - int was_resetting; - - iface = netdev_priv(dev); - local = iface->local; - was_resetting = local->hw_resetting; - - if (hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL, NULL)) { - printk("%s: MAC port 0 enabling failed\n", dev->name); - return 1; - } - - local->hw_ready = 1; - local->hw_reset_tries = 0; - local->hw_resetting = 0; - hfa384x_enable_interrupts(dev); - - /* at least D-Link DWL-650 seems to require additional port reset - * before it starts acting as an AP, so reset port automatically - * here just in case */ - if (initial && prism2_reset_port(dev)) { - printk("%s: MAC port 0 reseting failed\n", dev->name); - return 1; - } - - if (was_resetting && netif_queue_stopped(dev)) { - /* If hw_reset() was called during pending transmit, netif - * queue was stopped. Wake it up now since the wlan card has - * been resetted. */ - netif_wake_queue(dev); - } - - return 0; -} - - -static int prism2_hw_config(struct net_device *dev, int initial) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->hw_downloading) - return 1; - - if (prism2_hw_init(dev, initial)) { - return local->no_pri ? 0 : 1; - } - - if (prism2_hw_init2(dev, initial)) - return 1; - - /* Enable firmware if secondary image is loaded and at least one of the - * netdevices is up. */ - if (!local->pri_only && - (initial == 0 || (initial == 2 && local->num_dev_open > 0))) { - if (!local->dev_enabled) - prism2_callback(local, PRISM2_CALLBACK_ENABLE); - local->dev_enabled = 1; - return prism2_hw_enable(dev, initial); - } - - return 0; -} - - -static void prism2_hw_shutdown(struct net_device *dev, int no_disable) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - /* Allow only command completion events during disable */ - hfa384x_events_only_cmd(dev); - - local->hw_ready = 0; - if (local->dev_enabled) - prism2_callback(local, PRISM2_CALLBACK_DISABLE); - local->dev_enabled = 0; - - if (local->func->card_present && !local->func->card_present(local)) { - printk(KERN_DEBUG "%s: card already removed or not configured " - "during shutdown\n", dev->name); - return; - } - - if ((no_disable & HOSTAP_HW_NO_DISABLE) == 0 && - hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL, NULL)) - printk(KERN_WARNING "%s: Shutdown failed\n", dev_info); - - hfa384x_disable_interrupts(dev); - - if (no_disable & HOSTAP_HW_ENABLE_CMDCOMPL) - hfa384x_events_only_cmd(dev); - else - prism2_clear_cmd_queue(local); -} - - -static void prism2_hw_reset(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - -#if 0 - static long last_reset = 0; - - /* do not reset card more than once per second to avoid ending up in a - * busy loop reseting the card */ - if (time_before_eq(jiffies, last_reset + HZ)) - return; - last_reset = jiffies; -#endif - - iface = netdev_priv(dev); - local = iface->local; - - if (in_interrupt()) { - printk(KERN_DEBUG "%s: driver bug - prism2_hw_reset() called " - "in interrupt context\n", dev->name); - return; - } - - if (local->hw_downloading) - return; - - if (local->hw_resetting) { - printk(KERN_WARNING "%s: %s: already resetting card - " - "ignoring reset request\n", dev_info, dev->name); - return; - } - - local->hw_reset_tries++; - if (local->hw_reset_tries > 10) { - printk(KERN_WARNING "%s: too many reset tries, skipping\n", - dev->name); - return; - } - - printk(KERN_WARNING "%s: %s: resetting card\n", dev_info, dev->name); - hfa384x_disable_interrupts(dev); - local->hw_resetting = 1; - if (local->func->cor_sreset) { - /* Host system seems to hang in some cases with high traffic - * load or shared interrupts during COR sreset. Disable shared - * interrupts during reset to avoid these crashes. COS sreset - * takes quite a long time, so it is unfortunate that this - * seems to be needed. Anyway, I do not know of any better way - * of avoiding the crash. */ - disable_irq(dev->irq); - local->func->cor_sreset(local); - enable_irq(dev->irq); - } - prism2_hw_shutdown(dev, 1); - prism2_hw_config(dev, 0); - local->hw_resetting = 0; - -#ifdef PRISM2_DOWNLOAD_SUPPORT - if (local->dl_pri) { - printk(KERN_DEBUG "%s: persistent download of primary " - "firmware\n", dev->name); - if (prism2_download_genesis(local, local->dl_pri) < 0) - printk(KERN_WARNING "%s: download (PRI) failed\n", - dev->name); - } - - if (local->dl_sec) { - printk(KERN_DEBUG "%s: persistent download of secondary " - "firmware\n", dev->name); - if (prism2_download_volatile(local, local->dl_sec) < 0) - printk(KERN_WARNING "%s: download (SEC) failed\n", - dev->name); - } -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - - /* TODO: restore beacon TIM bits for STAs that have buffered frames */ -} - - -static void prism2_schedule_reset(local_info_t *local) -{ - schedule_work(&local->reset_queue); -} - - -/* Called only as scheduled task after noticing card timeout in interrupt - * context */ -static void handle_reset_queue(void *data) -{ - local_info_t *local = (local_info_t *) data; - - printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name); - prism2_hw_reset(local->dev); - - if (netif_queue_stopped(local->dev)) { - int i; - - for (i = 0; i < PRISM2_TXFID_COUNT; i++) - if (local->intransmitfid[i] == PRISM2_TXFID_EMPTY) { - PDEBUG(DEBUG_EXTRA, "prism2_tx_timeout: " - "wake up queue\n"); - netif_wake_queue(local->dev); - break; - } - } -} - - -static int prism2_get_txfid_idx(local_info_t *local) -{ - int idx, end; - unsigned long flags; - - spin_lock_irqsave(&local->txfidlock, flags); - end = idx = local->next_txfid; - do { - if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) { - local->intransmitfid[idx] = PRISM2_TXFID_RESERVED; - spin_unlock_irqrestore(&local->txfidlock, flags); - return idx; - } - idx++; - if (idx >= PRISM2_TXFID_COUNT) - idx = 0; - } while (idx != end); - spin_unlock_irqrestore(&local->txfidlock, flags); - - PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: " - "packet dropped\n"); - local->stats.tx_dropped++; - - return -1; -} - - -/* Called only from hardware IRQ */ -static void prism2_transmit_cb(struct net_device *dev, long context, - u16 resp0, u16 res) -{ - struct hostap_interface *iface; - local_info_t *local; - int idx = (int) context; - - iface = netdev_priv(dev); - local = iface->local; - - if (res) { - printk(KERN_DEBUG "%s: prism2_transmit_cb - res=0x%02x\n", - dev->name, res); - return; - } - - if (idx < 0 || idx >= PRISM2_TXFID_COUNT) { - printk(KERN_DEBUG "%s: prism2_transmit_cb called with invalid " - "idx=%d\n", dev->name, idx); - return; - } - - if (!test_and_clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) { - printk(KERN_DEBUG "%s: driver bug: prism2_transmit_cb called " - "with no pending transmit\n", dev->name); - } - - if (netif_queue_stopped(dev)) { - /* ready for next TX, so wake up queue that was stopped in - * prism2_transmit() */ - netif_wake_queue(dev); - } - - spin_lock(&local->txfidlock); - - /* With reclaim, Resp0 contains new txfid for transmit; the old txfid - * will be automatically allocated for the next TX frame */ - local->intransmitfid[idx] = resp0; - - PDEBUG(DEBUG_FID, "%s: prism2_transmit_cb: txfid[%d]=0x%04x, " - "resp0=0x%04x, transmit_txfid=0x%04x\n", - dev->name, idx, local->txfid[idx], - resp0, local->intransmitfid[local->next_txfid]); - - idx++; - if (idx >= PRISM2_TXFID_COUNT) - idx = 0; - local->next_txfid = idx; - - /* check if all TX buffers are occupied */ - do { - if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) { - spin_unlock(&local->txfidlock); - return; - } - idx++; - if (idx >= PRISM2_TXFID_COUNT) - idx = 0; - } while (idx != local->next_txfid); - spin_unlock(&local->txfidlock); - - /* no empty TX buffers, stop queue */ - netif_stop_queue(dev); -} - - -/* Called only from software IRQ if PCI bus master is not used (with bus master - * this can be called both from software and hardware IRQ) */ -static int prism2_transmit(struct net_device *dev, int idx) -{ - struct hostap_interface *iface; - local_info_t *local; - int res; - - iface = netdev_priv(dev); - local = iface->local; - - /* The driver tries to stop netif queue so that there would not be - * more than one attempt to transmit frames going on; check that this - * is really the case */ - - if (test_and_set_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) { - printk(KERN_DEBUG "%s: driver bug - prism2_transmit() called " - "when previous TX was pending\n", dev->name); - return -1; - } - - /* stop the queue for the time that transmit is pending */ - netif_stop_queue(dev); - - /* transmit packet */ - res = hfa384x_cmd_callback( - dev, - HFA384X_CMDCODE_TRANSMIT | HFA384X_CMD_TX_RECLAIM, - local->txfid[idx], - prism2_transmit_cb, (long) idx); - - if (res) { - struct net_device_stats *stats; - printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT " - "failed (res=%d)\n", dev->name, res); - stats = hostap_get_stats(dev); - stats->tx_dropped++; - netif_wake_queue(dev); - return -1; - } - dev->trans_start = jiffies; - - /* Since we did not wait for command completion, the card continues - * to process on the background and we will finish handling when - * command completion event is handled (prism2_cmd_ev() function) */ - - return 0; -} - - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) -/* Called only from hardware IRQ */ -static void prism2_tx_cb(struct net_device *dev, void *context, - u16 resp0, u16 res) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long addr; - int buf_len = (int) context; - - iface = netdev_priv(dev); - local = iface->local; - - if (res) { - printk(KERN_DEBUG "%s: prism2_tx_cb - res=0x%02x\n", - dev->name, res); - return; - } - - addr = virt_to_phys(local->bus_m0_buf); - HFA384X_OUTW((addr & 0xffff0000) >> 16, HFA384X_PCI_M0_ADDRH_OFF); - HFA384X_OUTW(addr & 0x0000ffff, HFA384X_PCI_M0_ADDRL_OFF); - HFA384X_OUTW(buf_len / 2, HFA384X_PCI_M0_LEN_OFF); - HFA384X_OUTW(HFA384X_PCI_CTL_TO_BAP, HFA384X_PCI_M0_CTL_OFF); -} -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - - -/* Send IEEE 802.11 frame (convert the header into Prism2 TX descriptor and - * send the payload with this descriptor) */ -/* Called only from software IRQ */ -static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hfa384x_tx_frame txdesc; - struct hostap_ieee80211_hdr *hdr; - struct hostap_skb_tx_data *meta; - int hdr_len, data_len, idx, res, ret = -1; - u16 tx_control, fc; - - iface = netdev_priv(dev); - local = iface->local; - - meta = (struct hostap_skb_tx_data *) skb->cb; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - - prism2_callback(local, PRISM2_CALLBACK_TX_START); - - if ((local->func->card_present && !local->func->card_present(local)) || - !local->hw_ready || local->hw_downloading || local->pri_only) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: prism2_tx_80211: hw not ready -" - " skipping\n", dev->name); - } - goto fail; - } - - memset(&txdesc, 0, sizeof(txdesc)); - - /* skb->data starts with txdesc->frame_control */ - hdr_len = 24; - memcpy(&txdesc.frame_control, skb->data, hdr_len); - fc = le16_to_cpu(txdesc.frame_control); - if (HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - (fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS) && skb->len >= 30) { - /* Addr4 */ - memcpy(txdesc.addr4, skb->data + hdr_len, ETH_ALEN); - hdr_len += ETH_ALEN; - } - - tx_control = local->tx_control; - if (meta->tx_cb_idx) { - tx_control |= HFA384X_TX_CTRL_TX_OK; - txdesc.sw_support = cpu_to_le16(meta->tx_cb_idx); - } - txdesc.tx_control = cpu_to_le16(tx_control); - txdesc.tx_rate = meta->rate; - - data_len = skb->len - hdr_len; - txdesc.data_len = cpu_to_le16(data_len); - txdesc.len = cpu_to_be16(data_len); - - idx = prism2_get_txfid_idx(local); - if (idx < 0) - goto fail; - - if (local->frame_dump & PRISM2_DUMP_TX_HDR) - hostap_dump_tx_header(dev->name, &txdesc); - - spin_lock(&local->baplock); - res = hfa384x_setup_bap(dev, BAP0, local->txfid[idx], 0); - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - if (!res && skb->len >= local->bus_master_threshold_tx) { - u8 *pos; - int buf_len; - - local->bus_m0_tx_idx = idx; - - /* FIX: BAP0 should be locked during bus master transfer, but - * baplock with BH's disabled is not OK for this; netif queue - * stopping is not enough since BAP0 is used also for RID - * read/write */ - - /* stop the queue for the time that bus mastering on BAP0 is - * in use */ - netif_stop_queue(dev); - - spin_unlock(&local->baplock); - - /* Copy frame data to bus_m0_buf */ - pos = local->bus_m0_buf; - memcpy(pos, &txdesc, sizeof(txdesc)); - pos += sizeof(txdesc); - memcpy(pos, skb->data + hdr_len, skb->len - hdr_len); - pos += skb->len - hdr_len; - buf_len = pos - local->bus_m0_buf; - if (buf_len & 1) - buf_len++; - -#ifdef PRISM2_ENABLE_BEFORE_TX_BUS_MASTER - /* Any RX packet seems to break something with TX bus - * mastering; enable command is enough to fix this.. */ - if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_ENABLE, 0, - prism2_tx_cb, (long) buf_len)) { - printk(KERN_DEBUG "%s: TX: enable port0 failed\n", - dev->name); - } -#else /* PRISM2_ENABLE_BEFORE_TX_BUS_MASTER */ - prism2_tx_cb(dev, (void *) buf_len, 0, 0); -#endif /* PRISM2_ENABLE_BEFORE_TX_BUS_MASTER */ - - /* Bus master transfer will be started from command completion - * event handler and TX handling will be finished by calling - * prism2_transmit() from bus master event handler */ - goto tx_stats; - } -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - - if (!res) - res = hfa384x_to_bap(dev, BAP0, &txdesc, sizeof(txdesc)); - if (!res) - res = hfa384x_to_bap(dev, BAP0, skb->data + hdr_len, - skb->len - hdr_len); - spin_unlock(&local->baplock); - - if (!res) - res = prism2_transmit(dev, idx); - if (res) { - printk(KERN_DEBUG "%s: prism2_tx_80211 - to BAP0 failed\n", - dev->name); - local->intransmitfid[idx] = PRISM2_TXFID_EMPTY; - schedule_work(&local->reset_queue); - goto fail; - } - - ret = 0; - -fail: - prism2_callback(local, PRISM2_CALLBACK_TX_END); - return ret; -} - - -/* Some SMP systems have reported number of odd errors with hostap_pci. fid - * register has changed values between consecutive reads for an unknown reason. - * This should really not happen, so more debugging is needed. This test - * version is a big slower, but it will detect most of such register changes - * and will try to get the correct fid eventually. */ -#define EXTRA_FID_READ_TESTS - -static inline u16 prism2_read_fid_reg(struct net_device *dev, u16 reg) -{ -#ifdef EXTRA_FID_READ_TESTS - u16 val, val2, val3; - int i; - - for (i = 0; i < 10; i++) { - val = HFA384X_INW(reg); - val2 = HFA384X_INW(reg); - val3 = HFA384X_INW(reg); - - if (val == val2 && val == val3) - return val; - - printk(KERN_DEBUG "%s: detected fid change (try=%d, reg=%04x):" - " %04x %04x %04x\n", - dev->name, i, reg, val, val2, val3); - if ((val == val2 || val == val3) && val != 0) - return val; - if (val2 == val3 && val2 != 0) - return val2; - } - printk(KERN_WARNING "%s: Uhhuh.. could not read good fid from reg " - "%04x (%04x %04x %04x)\n", dev->name, reg, val, val2, val3); - return val; -#else /* EXTRA_FID_READ_TESTS */ - return HFA384X_INW(reg); -#endif /* EXTRA_FID_READ_TESTS */ -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_rx(local_info_t *local) -{ - struct net_device *dev = local->dev; - int res, rx_pending = 0; - u16 len, hdr_len, rxfid, status, macport; - struct net_device_stats *stats; - struct hfa384x_rx_frame rxdesc; - struct sk_buff *skb = NULL; - - prism2_callback(local, PRISM2_CALLBACK_RX_START); - stats = hostap_get_stats(dev); - - rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF); -#ifndef final_version - if (rxfid == 0) { - rxfid = HFA384X_INW(HFA384X_RXFID_OFF); - printk(KERN_DEBUG "prism2_rx: rxfid=0 (next 0x%04x)\n", - rxfid); - if (rxfid == 0) { - schedule_work(&local->reset_queue); - goto rx_dropped; - } - /* try to continue with the new rxfid value */ - } -#endif - - spin_lock(&local->baplock); - res = hfa384x_setup_bap(dev, BAP0, rxfid, 0); - if (!res) - res = hfa384x_from_bap(dev, BAP0, &rxdesc, sizeof(rxdesc)); - - if (res) { - spin_unlock(&local->baplock); - printk(KERN_DEBUG "%s: copy from BAP0 failed %d\n", dev->name, - res); - if (res == -ETIMEDOUT) { - schedule_work(&local->reset_queue); - } - goto rx_dropped; - } - - len = le16_to_cpu(rxdesc.data_len); - hdr_len = sizeof(rxdesc); - status = le16_to_cpu(rxdesc.status); - macport = (status >> 8) & 0x07; - - /* Drop frames with too large reported payload length. Monitor mode - * seems to sometimes pass frames (e.g., ctrl::ack) with signed and - * negative value, so allow also values 65522 .. 65534 (-14 .. -2) for - * macport 7 */ - if (len > PRISM2_DATA_MAXLEN + 8 /* WEP */) { - if (macport == 7 && local->iw_mode == IW_MODE_MONITOR) { - if (len >= (u16) -14) { - hdr_len -= 65535 - len; - hdr_len--; - } - len = 0; - } else { - spin_unlock(&local->baplock); - printk(KERN_DEBUG "%s: Received frame with invalid " - "length 0x%04x\n", dev->name, len); - hostap_dump_rx_header(dev->name, &rxdesc); - goto rx_dropped; - } - } - - skb = dev_alloc_skb(len + hdr_len); - if (!skb) { - spin_unlock(&local->baplock); - printk(KERN_DEBUG "%s: RX failed to allocate skb\n", - dev->name); - goto rx_dropped; - } - skb->dev = dev; - memcpy(skb_put(skb, hdr_len), &rxdesc, hdr_len); - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - if (len >= local->bus_master_threshold_rx) { - unsigned long addr; - - hfa384x_events_no_bap1(dev); - - local->rx_skb = skb; - /* Internal BAP0 offset points to the byte following rxdesc; - * copy rest of the data using bus master */ - addr = virt_to_phys(skb_put(skb, len)); - HFA384X_OUTW((addr & 0xffff0000) >> 16, - HFA384X_PCI_M0_ADDRH_OFF); - HFA384X_OUTW(addr & 0x0000ffff, HFA384X_PCI_M0_ADDRL_OFF); - if (len & 1) - len++; - HFA384X_OUTW(len / 2, HFA384X_PCI_M0_LEN_OFF); - HFA384X_OUTW(HFA384X_PCI_CTL_FROM_BAP, HFA384X_PCI_M0_CTL_OFF); - - /* pci_bus_m1 event will be generated when data transfer is - * complete and the frame will then be added to rx_list and - * rx_tasklet is scheduled */ - rx_pending = 1; - - /* Have to release baplock before returning, although BAP0 - * should really not be used before DMA transfer has been - * completed. */ - spin_unlock(&local->baplock); - } else -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - { - if (len > 0) - res = hfa384x_from_bap(dev, BAP0, skb_put(skb, len), - len); - spin_unlock(&local->baplock); - if (res) { - printk(KERN_DEBUG "%s: RX failed to read " - "frame data\n", dev->name); - goto rx_dropped; - } - - skb_queue_tail(&local->rx_list, skb); - tasklet_schedule(&local->rx_tasklet); - } - - rx_exit: - prism2_callback(local, PRISM2_CALLBACK_RX_END); - if (!rx_pending) { - HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF); - } - - return; - - rx_dropped: - stats->rx_dropped++; - if (skb) - dev_kfree_skb(skb); - goto rx_exit; -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_rx_skb(local_info_t *local, struct sk_buff *skb) -{ - struct hfa384x_rx_frame *rxdesc; - struct net_device *dev = skb->dev; - struct hostap_80211_rx_status stats; - int hdrlen, rx_hdrlen; - - rx_hdrlen = sizeof(*rxdesc); - if (skb->len < sizeof(*rxdesc)) { - /* Allow monitor mode to receive shorter frames */ - if (local->iw_mode == IW_MODE_MONITOR && - skb->len >= sizeof(*rxdesc) - 30) { - rx_hdrlen = skb->len; - } else { - dev_kfree_skb(skb); - return; - } - } - - rxdesc = (struct hfa384x_rx_frame *) skb->data; - - if (local->frame_dump & PRISM2_DUMP_RX_HDR && - skb->len >= sizeof(*rxdesc)) - hostap_dump_rx_header(dev->name, rxdesc); - - if (le16_to_cpu(rxdesc->status) & HFA384X_RX_STATUS_FCSERR && - (!local->monitor_allow_fcserr || - local->iw_mode != IW_MODE_MONITOR)) - goto drop; - - if (skb->len > PRISM2_DATA_MAXLEN) { - printk(KERN_DEBUG "%s: RX: len(%d) > MAX(%d)\n", - dev->name, skb->len, PRISM2_DATA_MAXLEN); - goto drop; - } - - stats.mac_time = le32_to_cpu(rxdesc->time); - stats.signal = rxdesc->signal - local->rssi_to_dBm; - stats.noise = rxdesc->silence - local->rssi_to_dBm; - stats.rate = rxdesc->rate; - - /* Convert Prism2 RX structure into IEEE 802.11 header */ - hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control)); - if (hdrlen > rx_hdrlen) - hdrlen = rx_hdrlen; - - memmove(skb_pull(skb, rx_hdrlen - hdrlen), - &rxdesc->frame_control, hdrlen); - - hostap_80211_rx(dev, skb, &stats); - return; - - drop: - dev_kfree_skb(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_rx_tasklet(unsigned long data) -{ - local_info_t *local = (local_info_t *) data; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&local->rx_list)) != NULL) - hostap_rx_skb(local, skb); -} - - -/* Called only from hardware IRQ */ -static void prism2_alloc_ev(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - int idx; - u16 fid; - - iface = netdev_priv(dev); - local = iface->local; - - fid = prism2_read_fid_reg(dev, HFA384X_ALLOCFID_OFF); - - PDEBUG(DEBUG_FID, "FID: interrupt: ALLOC - fid=0x%04x\n", fid); - - spin_lock(&local->txfidlock); - idx = local->next_alloc; - - do { - if (local->txfid[idx] == fid) { - PDEBUG(DEBUG_FID, "FID: found matching txfid[%d]\n", - idx); - -#ifndef final_version - if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) - printk("Already released txfid found at idx " - "%d\n", idx); - if (local->intransmitfid[idx] == PRISM2_TXFID_RESERVED) - printk("Already reserved txfid found at idx " - "%d\n", idx); -#endif - local->intransmitfid[idx] = PRISM2_TXFID_EMPTY; - idx++; - local->next_alloc = idx >= PRISM2_TXFID_COUNT ? 0 : - idx; - - if (!test_bit(HOSTAP_BITS_TRANSMIT, &local->bits) && - netif_queue_stopped(dev)) - netif_wake_queue(dev); - - spin_unlock(&local->txfidlock); - return; - } - - idx++; - if (idx >= PRISM2_TXFID_COUNT) - idx = 0; - } while (idx != local->next_alloc); - - printk(KERN_WARNING "%s: could not find matching txfid (0x%04x, new " - "read 0x%04x) for alloc event\n", dev->name, fid, - HFA384X_INW(HFA384X_ALLOCFID_OFF)); - printk(KERN_DEBUG "TXFIDs:"); - for (idx = 0; idx < PRISM2_TXFID_COUNT; idx++) - printk(" %04x[%04x]", local->txfid[idx], - local->intransmitfid[idx]); - printk("\n"); - spin_unlock(&local->txfidlock); - - /* FIX: should probably schedule reset; reference to one txfid was lost - * completely.. Bad things will happen if we run out of txfids - * Actually, this will cause netdev watchdog to notice TX timeout and - * then card reset after all txfids have been leaked. */ -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_tx_callback(local_info_t *local, - struct hfa384x_tx_frame *txdesc, int ok, - char *payload) -{ - u16 sw_support, hdrlen, len; - struct sk_buff *skb; - struct hostap_tx_callback_info *cb; - - /* Make sure that frame was from us. */ - if (memcmp(txdesc->addr2, local->dev->dev_addr, ETH_ALEN)) { - printk(KERN_DEBUG "%s: TX callback - foreign frame\n", - local->dev->name); - return; - } - - sw_support = le16_to_cpu(txdesc->sw_support); - - spin_lock(&local->lock); - cb = local->tx_callback; - while (cb != NULL && cb->idx != sw_support) - cb = cb->next; - spin_unlock(&local->lock); - - if (cb == NULL) { - printk(KERN_DEBUG "%s: could not find TX callback (idx %d)\n", - local->dev->name, sw_support); - return; - } - - hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control)); - len = le16_to_cpu(txdesc->data_len); - skb = dev_alloc_skb(hdrlen + len); - if (skb == NULL) { - printk(KERN_DEBUG "%s: hostap_tx_callback failed to allocate " - "skb\n", local->dev->name); - return; - } - - memcpy(skb_put(skb, hdrlen), (void *) &txdesc->frame_control, hdrlen); - if (payload) - memcpy(skb_put(skb, len), payload, len); - - skb->dev = local->dev; - skb->mac.raw = skb->data; - - cb->func(skb, ok, cb->data); -} - - -/* Called only as a tasklet (software IRQ) */ -static int hostap_tx_compl_read(local_info_t *local, int error, - struct hfa384x_tx_frame *txdesc, - char **payload) -{ - u16 fid, len; - int res, ret = 0; - struct net_device *dev = local->dev; - - fid = prism2_read_fid_reg(dev, HFA384X_TXCOMPLFID_OFF); - - PDEBUG(DEBUG_FID, "interrupt: TX (err=%d) - fid=0x%04x\n", fid, error); - - spin_lock(&local->baplock); - res = hfa384x_setup_bap(dev, BAP0, fid, 0); - if (!res) - res = hfa384x_from_bap(dev, BAP0, txdesc, sizeof(*txdesc)); - if (res) { - PDEBUG(DEBUG_EXTRA, "%s: TX (err=%d) - fid=0x%04x - could not " - "read txdesc\n", dev->name, error, fid); - if (res == -ETIMEDOUT) { - schedule_work(&local->reset_queue); - } - ret = -1; - goto fail; - } - if (txdesc->sw_support) { - len = le16_to_cpu(txdesc->data_len); - if (len < PRISM2_DATA_MAXLEN) { - *payload = (char *) kmalloc(len, GFP_ATOMIC); - if (*payload == NULL || - hfa384x_from_bap(dev, BAP0, *payload, len)) { - PDEBUG(DEBUG_EXTRA, "%s: could not read TX " - "frame payload\n", dev->name); - kfree(*payload); - *payload = NULL; - ret = -1; - goto fail; - } - } - } - - fail: - spin_unlock(&local->baplock); - - return ret; -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_tx_ev(local_info_t *local) -{ - struct net_device *dev = local->dev; - char *payload = NULL; - struct hfa384x_tx_frame txdesc; - - if (hostap_tx_compl_read(local, 0, &txdesc, &payload)) - goto fail; - - if (local->frame_dump & PRISM2_DUMP_TX_HDR) { - PDEBUG(DEBUG_EXTRA, "%s: TX - status=0x%04x " - "retry_count=%d tx_rate=%d seq_ctrl=%d " - "duration_id=%d\n", - dev->name, le16_to_cpu(txdesc.status), - txdesc.retry_count, txdesc.tx_rate, - le16_to_cpu(txdesc.seq_ctrl), - le16_to_cpu(txdesc.duration_id)); - } - - if (txdesc.sw_support) - hostap_tx_callback(local, &txdesc, 1, payload); - kfree(payload); - - fail: - HFA384X_OUTW(HFA384X_EV_TX, HFA384X_EVACK_OFF); -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_sta_tx_exc_tasklet(unsigned long data) -{ - local_info_t *local = (local_info_t *) data; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&local->sta_tx_exc_list)) != NULL) { - struct hfa384x_tx_frame *txdesc = - (struct hfa384x_tx_frame *) skb->data; - - if (skb->len >= sizeof(*txdesc)) { - /* Convert Prism2 RX structure into IEEE 802.11 header - */ - u16 fc = le16_to_cpu(txdesc->frame_control); - int hdrlen = hostap_80211_get_hdrlen(fc); - memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen), - &txdesc->frame_control, hdrlen); - - hostap_handle_sta_tx_exc(local, skb); - } - dev_kfree_skb(skb); - } -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_txexc(local_info_t *local) -{ - struct net_device *dev = local->dev; - u16 status, fc; - int show_dump, res; - char *payload = NULL; - struct hfa384x_tx_frame txdesc; - - show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR; - local->stats.tx_errors++; - - res = hostap_tx_compl_read(local, 1, &txdesc, &payload); - HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF); - if (res) - return; - - status = le16_to_cpu(txdesc.status); - - /* We produce a TXDROP event only for retry or lifetime - * exceeded, because that's the only status that really mean - * that this particular node went away. - * Other errors means that *we* screwed up. - Jean II */ - if (status & (HFA384X_TX_STATUS_RETRYERR | HFA384X_TX_STATUS_AGEDERR)) - { - union iwreq_data wrqu; - - /* Copy 802.11 dest address. */ - memcpy(wrqu.addr.sa_data, txdesc.addr1, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL); - } else - show_dump = 1; - - if (local->iw_mode == IW_MODE_MASTER || - local->iw_mode == IW_MODE_REPEAT || - local->wds_type & HOSTAP_WDS_AP_CLIENT) { - struct sk_buff *skb; - skb = dev_alloc_skb(sizeof(txdesc)); - if (skb) { - memcpy(skb_put(skb, sizeof(txdesc)), &txdesc, - sizeof(txdesc)); - skb_queue_tail(&local->sta_tx_exc_list, skb); - tasklet_schedule(&local->sta_tx_exc_tasklet); - } - } - - if (txdesc.sw_support) - hostap_tx_callback(local, &txdesc, 0, payload); - kfree(payload); - - if (!show_dump) - return; - - PDEBUG(DEBUG_EXTRA, "%s: TXEXC - status=0x%04x (%s%s%s%s)" - " tx_control=%04x\n", - dev->name, status, - status & HFA384X_TX_STATUS_RETRYERR ? "[RetryErr]" : "", - status & HFA384X_TX_STATUS_AGEDERR ? "[AgedErr]" : "", - status & HFA384X_TX_STATUS_DISCON ? "[Discon]" : "", - status & HFA384X_TX_STATUS_FORMERR ? "[FormErr]" : "", - le16_to_cpu(txdesc.tx_control)); - - fc = le16_to_cpu(txdesc.frame_control); - PDEBUG(DEBUG_EXTRA, " retry_count=%d tx_rate=%d fc=0x%04x " - "(%s%s%s::%d%s%s)\n", - txdesc.retry_count, txdesc.tx_rate, fc, - HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT ? "Mgmt" : "", - HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_CTRL ? "Ctrl" : "", - HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA ? "Data" : "", - HOSTAP_FC_GET_STYPE(fc), - fc & WLAN_FC_TODS ? " ToDS" : "", - fc & WLAN_FC_FROMDS ? " FromDS" : ""); - PDEBUG(DEBUG_EXTRA, " A1=" MACSTR " A2=" MACSTR " A3=" - MACSTR " A4=" MACSTR "\n", - MAC2STR(txdesc.addr1), MAC2STR(txdesc.addr2), - MAC2STR(txdesc.addr3), MAC2STR(txdesc.addr4)); -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_info_tasklet(unsigned long data) -{ - local_info_t *local = (local_info_t *) data; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&local->info_list)) != NULL) { - hostap_info_process(local, skb); - dev_kfree_skb(skb); - } -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info(local_info_t *local) -{ - struct net_device *dev = local->dev; - u16 fid; - int res, left; - struct hfa384x_info_frame info; - struct sk_buff *skb; - - fid = HFA384X_INW(HFA384X_INFOFID_OFF); - - spin_lock(&local->baplock); - res = hfa384x_setup_bap(dev, BAP0, fid, 0); - if (!res) - res = hfa384x_from_bap(dev, BAP0, &info, sizeof(info)); - if (res) { - spin_unlock(&local->baplock); - printk(KERN_DEBUG "Could not get info frame (fid=0x%04x)\n", - fid); - if (res == -ETIMEDOUT) { - schedule_work(&local->reset_queue); - } - goto out; - } - - le16_to_cpus(&info.len); - le16_to_cpus(&info.type); - left = (info.len - 1) * 2; - - if (info.len & 0x8000 || info.len == 0 || left > 2060) { - /* data register seems to give 0x8000 in some error cases even - * though busy bit is not set in offset register; - * in addition, length must be at least 1 due to type field */ - spin_unlock(&local->baplock); - printk(KERN_DEBUG "%s: Received info frame with invalid " - "length 0x%04x (type 0x%04x)\n", dev->name, info.len, - info.type); - goto out; - } - - skb = dev_alloc_skb(sizeof(info) + left); - if (skb == NULL) { - spin_unlock(&local->baplock); - printk(KERN_DEBUG "%s: Could not allocate skb for info " - "frame\n", dev->name); - goto out; - } - - memcpy(skb_put(skb, sizeof(info)), &info, sizeof(info)); - if (left > 0 && hfa384x_from_bap(dev, BAP0, skb_put(skb, left), left)) - { - spin_unlock(&local->baplock); - printk(KERN_WARNING "%s: Info frame read failed (fid=0x%04x, " - "len=0x%04x, type=0x%04x\n", - dev->name, fid, info.len, info.type); - dev_kfree_skb(skb); - goto out; - } - spin_unlock(&local->baplock); - - skb_queue_tail(&local->info_list, skb); - tasklet_schedule(&local->info_tasklet); - - out: - HFA384X_OUTW(HFA384X_EV_INFO, HFA384X_EVACK_OFF); -} - - -/* Called only as a tasklet (software IRQ) */ -static void hostap_bap_tasklet(unsigned long data) -{ - local_info_t *local = (local_info_t *) data; - struct net_device *dev = local->dev; - u16 ev; - int frames = 30; - - if (local->func->card_present && !local->func->card_present(local)) - return; - - set_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits); - - /* Process all pending BAP events without generating new interrupts - * for them */ - while (frames-- > 0) { - ev = HFA384X_INW(HFA384X_EVSTAT_OFF); - if (ev == 0xffff || !(ev & HFA384X_BAP0_EVENTS)) - break; - if (ev & HFA384X_EV_RX) - prism2_rx(local); - if (ev & HFA384X_EV_INFO) - prism2_info(local); - if (ev & HFA384X_EV_TX) - prism2_tx_ev(local); - if (ev & HFA384X_EV_TXEXC) - prism2_txexc(local); - } - - set_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits); - clear_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits); - - /* Enable interrupts for new BAP events */ - hfa384x_events_all(dev); - clear_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits); -} - - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) -/* Called only from hardware IRQ */ -static void prism2_bus_master_ev(struct net_device *dev, int bap) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (bap == BAP1) { - /* FIX: frame payload was DMA'd to skb->data; might need to - * invalidate data cache for that memory area */ - skb_queue_tail(&local->rx_list, local->rx_skb); - tasklet_schedule(&local->rx_tasklet); - HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF); - } else { - if (prism2_transmit(dev, local->bus_m0_tx_idx)) { - printk(KERN_DEBUG "%s: prism2_transmit() failed " - "when called from bus master event\n", - dev->name); - local->intransmitfid[local->bus_m0_tx_idx] = - PRISM2_TXFID_EMPTY; - schedule_work(&local->reset_queue); - } - } -} -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - - -/* Called only from hardware IRQ */ -static void prism2_infdrop(struct net_device *dev) -{ - static unsigned long last_inquire = 0; - - PDEBUG(DEBUG_EXTRA, "%s: INFDROP event\n", dev->name); - - /* some firmware versions seem to get stuck with - * full CommTallies in high traffic load cases; every - * packet will then cause INFDROP event and CommTallies - * info frame will not be sent automatically. Try to - * get out of this state by inquiring CommTallies. */ - if (!last_inquire || time_after(jiffies, last_inquire + HZ)) { - hfa384x_cmd_callback(dev, HFA384X_CMDCODE_INQUIRE, - HFA384X_INFO_COMMTALLIES, NULL, 0); - last_inquire = jiffies; - } -} - - -/* Called only from hardware IRQ */ -static void prism2_ev_tick(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 evstat, inten; - static int prev_stuck = 0; - - iface = netdev_priv(dev); - local = iface->local; - - if (time_after(jiffies, local->last_tick_timer + 5 * HZ) && - local->last_tick_timer) { - evstat = HFA384X_INW(HFA384X_EVSTAT_OFF); - inten = HFA384X_INW(HFA384X_INTEN_OFF); - if (!prev_stuck) { - printk(KERN_INFO "%s: SW TICK stuck? " - "bits=0x%lx EvStat=%04x IntEn=%04x\n", - dev->name, local->bits, evstat, inten); - } - local->sw_tick_stuck++; - if ((evstat & HFA384X_BAP0_EVENTS) && - (inten & HFA384X_BAP0_EVENTS)) { - printk(KERN_INFO "%s: trying to recover from IRQ " - "hang\n", dev->name); - hfa384x_events_no_bap0(dev); - } - prev_stuck = 1; - } else - prev_stuck = 0; -} - - -/* Called only from hardware IRQ */ -static inline void prism2_check_magic(local_info_t *local) -{ - /* at least PCI Prism2.5 with bus mastering seems to sometimes - * return 0x0000 in SWSUPPORT0 for unknown reason, but re-reading the - * register once or twice seems to get the correct value.. PCI cards - * cannot anyway be removed during normal operation, so there is not - * really any need for this verification with them. */ - -#ifndef PRISM2_PCI -#ifndef final_version - static unsigned long last_magic_err = 0; - struct net_device *dev = local->dev; - - if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) { - if (!local->hw_ready) - return; - HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF); - if (time_after(jiffies, last_magic_err + 10 * HZ)) { - printk("%s: Interrupt, but SWSUPPORT0 does not match: " - "%04X != %04X - card removed?\n", dev->name, - HFA384X_INW(HFA384X_SWSUPPORT0_OFF), - HFA384X_MAGIC); - last_magic_err = jiffies; - } else if (net_ratelimit()) { - printk(KERN_DEBUG "%s: interrupt - SWSUPPORT0=%04x " - "MAGIC=%04x\n", dev->name, - HFA384X_INW(HFA384X_SWSUPPORT0_OFF), - HFA384X_MAGIC); - } - if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != 0xffff) - schedule_work(&local->reset_queue); - return; - } -#endif /* final_version */ -#endif /* !PRISM2_PCI */ -} - - -/* Called only from hardware IRQ */ -static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct hostap_interface *iface; - local_info_t *local; - int events = 0; - u16 ev; - - iface = netdev_priv(dev); - local = iface->local; - - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0); - - if (local->func->card_present && !local->func->card_present(local)) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: Interrupt, but dev not OK\n", - dev->name); - } - return IRQ_HANDLED; - } - - prism2_check_magic(local); - - for (;;) { - ev = HFA384X_INW(HFA384X_EVSTAT_OFF); - if (ev == 0xffff) { - if (local->shutdown) - return IRQ_HANDLED; - HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF); - printk(KERN_DEBUG "%s: prism2_interrupt: ev=0xffff\n", - dev->name); - return IRQ_HANDLED; - } - - ev &= HFA384X_INW(HFA384X_INTEN_OFF); - if (ev == 0) - break; - - if (ev & HFA384X_EV_CMD) { - prism2_cmd_ev(dev); - } - - /* Above events are needed even before hw is ready, but other - * events should be skipped during initialization. This may - * change for AllocEv if allocate_fid is implemented without - * busy waiting. */ - if (!local->hw_ready || local->hw_resetting || - !local->dev_enabled) { - ev = HFA384X_INW(HFA384X_EVSTAT_OFF); - if (ev & HFA384X_EV_CMD) - goto next_event; - if ((ev & HFA384X_EVENT_MASK) == 0) - return IRQ_HANDLED; - if (local->dev_enabled && (ev & ~HFA384X_EV_TICK) && - net_ratelimit()) { - printk(KERN_DEBUG "%s: prism2_interrupt: hw " - "not ready; skipping events 0x%04x " - "(IntEn=0x%04x)%s%s%s\n", - dev->name, ev, - HFA384X_INW(HFA384X_INTEN_OFF), - !local->hw_ready ? " (!hw_ready)" : "", - local->hw_resetting ? - " (hw_resetting)" : "", - !local->dev_enabled ? - " (!dev_enabled)" : ""); - } - HFA384X_OUTW(ev, HFA384X_EVACK_OFF); - return IRQ_HANDLED; - } - - if (ev & HFA384X_EV_TICK) { - prism2_ev_tick(dev); - HFA384X_OUTW(HFA384X_EV_TICK, HFA384X_EVACK_OFF); - } - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - if (ev & HFA384X_EV_PCI_M0) { - prism2_bus_master_ev(dev, BAP0); - HFA384X_OUTW(HFA384X_EV_PCI_M0, HFA384X_EVACK_OFF); - } - - if (ev & HFA384X_EV_PCI_M1) { - /* previous RX has been copied can be ACKed now */ - HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF); - - prism2_bus_master_ev(dev, BAP1); - HFA384X_OUTW(HFA384X_EV_PCI_M1, HFA384X_EVACK_OFF); - } -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - - if (ev & HFA384X_EV_ALLOC) { - prism2_alloc_ev(dev); - HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF); - } - - /* Reading data from the card is quite time consuming, so do it - * in tasklets. TX, TXEXC, RX, and INFO events will be ACKed - * and unmasked after needed data has been read completely. */ - if (ev & HFA384X_BAP0_EVENTS) { - hfa384x_events_no_bap0(dev); - tasklet_schedule(&local->bap_tasklet); - } - -#ifndef final_version - if (ev & HFA384X_EV_WTERR) { - PDEBUG(DEBUG_EXTRA, "%s: WTERR event\n", dev->name); - HFA384X_OUTW(HFA384X_EV_WTERR, HFA384X_EVACK_OFF); - } -#endif /* final_version */ - - if (ev & HFA384X_EV_INFDROP) { - prism2_infdrop(dev); - HFA384X_OUTW(HFA384X_EV_INFDROP, HFA384X_EVACK_OFF); - } - - next_event: - events++; - if (events >= PRISM2_MAX_INTERRUPT_EVENTS) { - PDEBUG(DEBUG_EXTRA, "prism2_interrupt: >%d events " - "(EvStat=0x%04x)\n", - PRISM2_MAX_INTERRUPT_EVENTS, - HFA384X_INW(HFA384X_EVSTAT_OFF)); - break; - } - } - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 1); - return IRQ_RETVAL(events); -} - - -static void prism2_check_sta_fw_version(local_info_t *local) -{ - struct hfa384x_comp_ident comp; - int id, variant, major, minor; - - if (hfa384x_get_rid(local->dev, HFA384X_RID_STAID, - &comp, sizeof(comp), 1) < 0) - return; - - local->fw_ap = 0; - id = le16_to_cpu(comp.id); - if (id != HFA384X_COMP_ID_STA) { - if (id == HFA384X_COMP_ID_FW_AP) - local->fw_ap = 1; - return; - } - - major = __le16_to_cpu(comp.major); - minor = __le16_to_cpu(comp.minor); - variant = __le16_to_cpu(comp.variant); - local->sta_fw_ver = PRISM2_FW_VER(major, minor, variant); - - /* Station firmware versions before 1.4.x seem to have a bug in - * firmware-based WEP encryption when using Host AP mode, so use - * host_encrypt as a default for them. Firmware version 1.4.9 is the - * first one that has been seen to produce correct encryption, but the - * bug might be fixed before that (although, at least 1.4.2 is broken). - */ - local->fw_encrypt_ok = local->sta_fw_ver >= PRISM2_FW_VER(1,4,9); - - if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt && - !local->fw_encrypt_ok) { - printk(KERN_DEBUG "%s: defaulting to host-based encryption as " - "a workaround for firmware bug in Host AP mode WEP\n", - local->dev->name); - local->host_encrypt = 1; - } - - /* IEEE 802.11 standard compliant WDS frames (4 addresses) were broken - * in station firmware versions before 1.5.x. With these versions, the - * driver uses a workaround with bogus frame format (4th address after - * the payload). This is not compatible with other AP devices. Since - * the firmware bug is fixed in the latest station firmware versions, - * automatically enable standard compliant mode for cards using station - * firmware version 1.5.0 or newer. */ - if (local->sta_fw_ver >= PRISM2_FW_VER(1,5,0)) - local->wds_type |= HOSTAP_WDS_STANDARD_FRAME; - else { - printk(KERN_DEBUG "%s: defaulting to bogus WDS frame as a " - "workaround for firmware bug in Host AP mode WDS\n", - local->dev->name); - } - - hostap_check_sta_fw_version(local->ap, local->sta_fw_ver); -} - - -static void prism2_crypt_deinit_entries(local_info_t *local, int force) -{ - struct list_head *ptr, *n; - struct ieee80211_crypt_data *entry; - - for (ptr = local->crypt_deinit_list.next, n = ptr->next; - ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct ieee80211_crypt_data, list); - - if (atomic_read(&entry->refcnt) != 0 && !force) - continue; - - list_del(ptr); - - if (entry->ops) - entry->ops->deinit(entry->priv); - kfree(entry); - } -} - - -static void prism2_crypt_deinit_handler(unsigned long data) -{ - local_info_t *local = (local_info_t *) data; - unsigned long flags; - - spin_lock_irqsave(&local->lock, flags); - prism2_crypt_deinit_entries(local, 0); - if (!list_empty(&local->crypt_deinit_list)) { - printk(KERN_DEBUG "%s: entries remaining in delayed crypt " - "deletion list\n", local->dev->name); - local->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&local->crypt_deinit_timer); - } - spin_unlock_irqrestore(&local->lock, flags); - -} - - -static void hostap_passive_scan(unsigned long data) -{ - local_info_t *local = (local_info_t *) data; - struct net_device *dev = local->dev; - u16 channel; - - if (local->passive_scan_interval <= 0) - return; - - if (local->passive_scan_state == PASSIVE_SCAN_LISTEN) { - int max_tries = 16; - - /* Even though host system does not really know when the WLAN - * MAC is sending frames, try to avoid changing channels for - * passive scanning when a host-generated frame is being - * transmitted */ - if (test_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) { - printk(KERN_DEBUG "%s: passive scan detected pending " - "TX - delaying\n", dev->name); - local->passive_scan_timer.expires = jiffies + HZ / 10; - add_timer(&local->passive_scan_timer); - return; - } - - do { - local->passive_scan_channel++; - if (local->passive_scan_channel > 14) - local->passive_scan_channel = 1; - max_tries--; - } while (!(local->channel_mask & - (1 << (local->passive_scan_channel - 1))) && - max_tries > 0); - - if (max_tries == 0) { - printk(KERN_INFO "%s: no allowed passive scan channels" - " found\n", dev->name); - return; - } - - printk(KERN_DEBUG "%s: passive scan channel %d\n", - dev->name, local->passive_scan_channel); - channel = local->passive_scan_channel; - local->passive_scan_state = PASSIVE_SCAN_WAIT; - local->passive_scan_timer.expires = jiffies + HZ / 10; - } else { - channel = local->channel; - local->passive_scan_state = PASSIVE_SCAN_LISTEN; - local->passive_scan_timer.expires = jiffies + - local->passive_scan_interval * HZ; - } - - if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST | - (HFA384X_TEST_CHANGE_CHANNEL << 8), - channel, NULL, 0)) - printk(KERN_ERR "%s: passive scan channel set %d " - "failed\n", dev->name, channel); - - add_timer(&local->passive_scan_timer); -} - - -/* Called only as a scheduled task when communications quality values should - * be updated. */ -static void handle_comms_qual_update(void *data) -{ - local_info_t *local = data; - prism2_update_comms_qual(local->dev); -} - - -/* Software watchdog - called as a timer. Hardware interrupt (Tick event) is - * used to monitor that local->last_tick_timer is being updated. If not, - * interrupt busy-loop is assumed and driver tries to recover by masking out - * some events. */ -static void hostap_tick_timer(unsigned long data) -{ - static unsigned long last_inquire = 0; - local_info_t *local = (local_info_t *) data; - local->last_tick_timer = jiffies; - - /* Inquire CommTallies every 10 seconds to keep the statistics updated - * more often during low load and when using 32-bit tallies. */ - if ((!last_inquire || time_after(jiffies, last_inquire + 10 * HZ)) && - !local->hw_downloading && local->hw_ready && - !local->hw_resetting && local->dev_enabled) { - hfa384x_cmd_callback(local->dev, HFA384X_CMDCODE_INQUIRE, - HFA384X_INFO_COMMTALLIES, NULL, 0); - last_inquire = jiffies; - } - - if ((local->last_comms_qual_update == 0 || - time_after(jiffies, local->last_comms_qual_update + 10 * HZ)) && - (local->iw_mode == IW_MODE_INFRA || - local->iw_mode == IW_MODE_ADHOC)) { - schedule_work(&local->comms_qual_update); - } - - local->tick_timer.expires = jiffies + 2 * HZ; - add_timer(&local->tick_timer); -} - - -#ifndef PRISM2_NO_PROCFS_DEBUG -static int prism2_registers_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - - if (off != 0) { - *eof = 1; - return 0; - } - -#define SHOW_REG(n) \ -p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF)) - - SHOW_REG(CMD); - SHOW_REG(PARAM0); - SHOW_REG(PARAM1); - SHOW_REG(PARAM2); - SHOW_REG(STATUS); - SHOW_REG(RESP0); - SHOW_REG(RESP1); - SHOW_REG(RESP2); - SHOW_REG(INFOFID); - SHOW_REG(CONTROL); - SHOW_REG(SELECT0); - SHOW_REG(SELECT1); - SHOW_REG(OFFSET0); - SHOW_REG(OFFSET1); - SHOW_REG(RXFID); - SHOW_REG(ALLOCFID); - SHOW_REG(TXCOMPLFID); - SHOW_REG(SWSUPPORT0); - SHOW_REG(SWSUPPORT1); - SHOW_REG(SWSUPPORT2); - SHOW_REG(EVSTAT); - SHOW_REG(INTEN); - SHOW_REG(EVACK); - /* Do not read data registers, because they change the state of the - * MAC (offset += 2) */ - /* SHOW_REG(DATA0); */ - /* SHOW_REG(DATA1); */ - SHOW_REG(AUXPAGE); - SHOW_REG(AUXOFFSET); - /* SHOW_REG(AUXDATA); */ -#ifdef PRISM2_PCI - SHOW_REG(PCICOR); - SHOW_REG(PCIHCR); - SHOW_REG(PCI_M0_ADDRH); - SHOW_REG(PCI_M0_ADDRL); - SHOW_REG(PCI_M0_LEN); - SHOW_REG(PCI_M0_CTL); - SHOW_REG(PCI_STATUS); - SHOW_REG(PCI_M1_ADDRH); - SHOW_REG(PCI_M1_ADDRL); - SHOW_REG(PCI_M1_LEN); - SHOW_REG(PCI_M1_CTL); -#endif /* PRISM2_PCI */ - - return (p - page); -} -#endif /* PRISM2_NO_PROCFS_DEBUG */ - - -struct set_tim_data { - struct list_head list; - int aid; - int set; -}; - -static int prism2_set_tim(struct net_device *dev, int aid, int set) -{ - struct list_head *ptr; - struct set_tim_data *new_entry; - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - new_entry = (struct set_tim_data *) - kmalloc(sizeof(*new_entry), GFP_ATOMIC); - if (new_entry == NULL) { - printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n", - local->dev->name); - return -ENOMEM; - } - memset(new_entry, 0, sizeof(*new_entry)); - new_entry->aid = aid; - new_entry->set = set; - - spin_lock_bh(&local->set_tim_lock); - list_for_each(ptr, &local->set_tim_list) { - struct set_tim_data *entry = - list_entry(ptr, struct set_tim_data, list); - if (entry->aid == aid) { - PDEBUG(DEBUG_PS2, "%s: prism2_set_tim: aid=%d " - "set=%d ==> %d\n", - local->dev->name, aid, entry->set, set); - entry->set = set; - kfree(new_entry); - new_entry = NULL; - break; - } - } - if (new_entry) - list_add_tail(&new_entry->list, &local->set_tim_list); - spin_unlock_bh(&local->set_tim_lock); - - schedule_work(&local->set_tim_queue); - - return 0; -} - - -static void handle_set_tim_queue(void *data) -{ - local_info_t *local = (local_info_t *) data; - struct set_tim_data *entry; - u16 val; - - for (;;) { - entry = NULL; - spin_lock_bh(&local->set_tim_lock); - if (!list_empty(&local->set_tim_list)) { - entry = list_entry(local->set_tim_list.next, - struct set_tim_data, list); - list_del(&entry->list); - } - spin_unlock_bh(&local->set_tim_lock); - if (!entry) - break; - - PDEBUG(DEBUG_PS2, "%s: handle_set_tim_queue: aid=%d set=%d\n", - local->dev->name, entry->aid, entry->set); - - val = entry->aid; - if (entry->set) - val |= 0x8000; - if (hostap_set_word(local->dev, HFA384X_RID_CNFTIMCTRL, val)) { - printk(KERN_DEBUG "%s: set_tim failed (aid=%d " - "set=%d)\n", - local->dev->name, entry->aid, entry->set); - } - - kfree(entry); - } -} - - -static void prism2_clear_set_tim_queue(local_info_t *local) -{ - struct list_head *ptr, *n; - - list_for_each_safe(ptr, n, &local->set_tim_list) { - struct set_tim_data *entry; - entry = list_entry(ptr, struct set_tim_data, list); - list_del(&entry->list); - kfree(entry); - } -} - - -static struct net_device * -prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, - struct device *sdev) -{ - struct net_device *dev; - struct hostap_interface *iface; - struct local_info *local; - int len, i, ret; - - if (funcs == NULL) - return NULL; - - len = strlen(dev_template); - if (len >= IFNAMSIZ || strstr(dev_template, "%d") == NULL) { - printk(KERN_WARNING "hostap: Invalid dev_template='%s'\n", - dev_template); - return NULL; - } - - len = sizeof(struct hostap_interface) + - 3 + sizeof(struct local_info) + - 3 + sizeof(struct ap_data); - - dev = alloc_etherdev(len); - if (dev == NULL) - return NULL; - - iface = netdev_priv(dev); - local = (struct local_info *) ((((long) (iface + 1)) + 3) & ~3); - local->ap = (struct ap_data *) ((((long) (local + 1)) + 3) & ~3); - local->dev = iface->dev = dev; - iface->local = local; - iface->type = HOSTAP_INTERFACE_MASTER; - INIT_LIST_HEAD(&local->hostap_interfaces); - - local->hw_module = THIS_MODULE; - -#ifdef PRISM2_IO_DEBUG - local->io_debug_enabled = 1; -#endif /* PRISM2_IO_DEBUG */ - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - local->bus_m0_buf = (u8 *) kmalloc(sizeof(struct hfa384x_tx_frame) + - PRISM2_DATA_MAXLEN, GFP_DMA); - if (local->bus_m0_buf == NULL) - goto fail; -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - - local->func = funcs; - local->func->cmd = hfa384x_cmd; - local->func->read_regs = hfa384x_read_regs; - local->func->get_rid = hfa384x_get_rid; - local->func->set_rid = hfa384x_set_rid; - local->func->hw_enable = prism2_hw_enable; - local->func->hw_config = prism2_hw_config; - local->func->hw_reset = prism2_hw_reset; - local->func->hw_shutdown = prism2_hw_shutdown; - local->func->reset_port = prism2_reset_port; - local->func->schedule_reset = prism2_schedule_reset; -#ifdef PRISM2_DOWNLOAD_SUPPORT - local->func->read_aux = prism2_download_aux_dump; - local->func->download = prism2_download; -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - local->func->tx = prism2_tx_80211; - local->func->set_tim = prism2_set_tim; - local->func->need_tx_headroom = 0; /* no need to add txdesc in - * skb->data (FIX: maybe for DMA bus - * mastering? */ - - local->mtu = mtu; - - rwlock_init(&local->iface_lock); - spin_lock_init(&local->txfidlock); - spin_lock_init(&local->cmdlock); - spin_lock_init(&local->baplock); - spin_lock_init(&local->lock); - init_MUTEX(&local->rid_bap_sem); - - if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES) - card_idx = 0; - local->card_idx = card_idx; - - len = strlen(essid); - memcpy(local->essid, essid, - len > MAX_SSID_LEN ? MAX_SSID_LEN : len); - local->essid[MAX_SSID_LEN] = '\0'; - i = GET_INT_PARM(iw_mode, card_idx); - if ((i >= IW_MODE_ADHOC && i <= IW_MODE_REPEAT) || - i == IW_MODE_MONITOR) { - local->iw_mode = i; - } else { - printk(KERN_WARNING "prism2: Unknown iw_mode %d; using " - "IW_MODE_MASTER\n", i); - local->iw_mode = IW_MODE_MASTER; - } - local->channel = GET_INT_PARM(channel, card_idx); - local->beacon_int = GET_INT_PARM(beacon_int, card_idx); - local->dtim_period = GET_INT_PARM(dtim_period, card_idx); - local->wds_max_connections = 16; - local->tx_control = HFA384X_TX_CTRL_FLAGS; - local->manual_retry_count = -1; - local->rts_threshold = 2347; - local->fragm_threshold = 2346; - local->rssi_to_dBm = 100; /* default; to be overriden by - * cnfDbmAdjust, if available */ - local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY; - local->sram_type = -1; - local->scan_channel_mask = 0xffff; -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - local->bus_master_threshold_rx = GET_INT_PARM(bus_master_threshold_rx, - card_idx); - local->bus_master_threshold_tx = GET_INT_PARM(bus_master_threshold_tx, - card_idx); -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - - /* Initialize task queue structures */ - INIT_WORK(&local->reset_queue, handle_reset_queue, local); - INIT_WORK(&local->set_multicast_list_queue, - hostap_set_multicast_list_queue, local->dev); - - INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local); - INIT_LIST_HEAD(&local->set_tim_list); - spin_lock_init(&local->set_tim_lock); - - INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local); - - /* Initialize tasklets for handling hardware IRQ related operations - * outside hw IRQ handler */ -#define HOSTAP_TASKLET_INIT(q, f, d) \ -do { memset((q), 0, sizeof(*(q))); (q)->func = (f); (q)->data = (d); } \ -while (0) - HOSTAP_TASKLET_INIT(&local->bap_tasklet, hostap_bap_tasklet, - (unsigned long) local); - - HOSTAP_TASKLET_INIT(&local->info_tasklet, hostap_info_tasklet, - (unsigned long) local); - hostap_info_init(local); - - HOSTAP_TASKLET_INIT(&local->rx_tasklet, - hostap_rx_tasklet, (unsigned long) local); - skb_queue_head_init(&local->rx_list); - - HOSTAP_TASKLET_INIT(&local->sta_tx_exc_tasklet, - hostap_sta_tx_exc_tasklet, (unsigned long) local); - skb_queue_head_init(&local->sta_tx_exc_list); - - INIT_LIST_HEAD(&local->cmd_queue); - init_waitqueue_head(&local->hostscan_wq); - INIT_LIST_HEAD(&local->crypt_deinit_list); - init_timer(&local->crypt_deinit_timer); - local->crypt_deinit_timer.data = (unsigned long) local; - local->crypt_deinit_timer.function = prism2_crypt_deinit_handler; - - init_timer(&local->passive_scan_timer); - local->passive_scan_timer.data = (unsigned long) local; - local->passive_scan_timer.function = hostap_passive_scan; - - init_timer(&local->tick_timer); - local->tick_timer.data = (unsigned long) local; - local->tick_timer.function = hostap_tick_timer; - local->tick_timer.expires = jiffies + 2 * HZ; - add_timer(&local->tick_timer); - - INIT_LIST_HEAD(&local->bss_list); - - hostap_setup_dev(dev, local, 1); - local->saved_eth_header_parse = dev->hard_header_parse; - - dev->hard_start_xmit = hostap_master_start_xmit; - dev->type = ARPHRD_IEEE80211; - dev->hard_header_parse = hostap_80211_header_parse; - - rtnl_lock(); - ret = dev_alloc_name(dev, "wifi%d"); - SET_NETDEV_DEV(dev, sdev); - if (ret >= 0) - ret = register_netdevice(dev); - rtnl_unlock(); - if (ret < 0) { - printk(KERN_WARNING "%s: register netdevice failed!\n", - dev_info); - goto fail; - } - printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name); - -#ifndef PRISM2_NO_PROCFS_DEBUG - create_proc_read_entry("registers", 0, local->proc, - prism2_registers_proc_read, local); -#endif /* PRISM2_NO_PROCFS_DEBUG */ - - hostap_init_data(local); - return dev; - - fail: -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - kfree(local->bus_m0_buf); -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - free_netdev(dev); - return NULL; -} - - -static int hostap_hw_ready(struct net_device *dev) -{ - struct hostap_interface *iface; - struct local_info *local; - - iface = netdev_priv(dev); - local = iface->local; - local->ddev = hostap_add_interface(local, HOSTAP_INTERFACE_MAIN, 0, - "", dev_template); - - if (local->ddev) { - if (local->iw_mode == IW_MODE_INFRA || - local->iw_mode == IW_MODE_ADHOC) { - netif_carrier_off(local->dev); - netif_carrier_off(local->ddev); - } - hostap_init_proc(local); - hostap_init_ap_proc(local); - return 0; - } - - return -1; -} - - -static void prism2_free_local_data(struct net_device *dev) -{ - struct hostap_tx_callback_info *tx_cb, *tx_cb_prev; - int i; - struct hostap_interface *iface; - struct local_info *local; - struct list_head *ptr, *n; - - if (dev == NULL) - return; - - iface = netdev_priv(dev); - local = iface->local; - - flush_scheduled_work(); - - if (timer_pending(&local->crypt_deinit_timer)) - del_timer(&local->crypt_deinit_timer); - prism2_crypt_deinit_entries(local, 1); - - if (timer_pending(&local->passive_scan_timer)) - del_timer(&local->passive_scan_timer); - - if (timer_pending(&local->tick_timer)) - del_timer(&local->tick_timer); - - prism2_clear_cmd_queue(local); - - skb_queue_purge(&local->info_list); - skb_queue_purge(&local->rx_list); - skb_queue_purge(&local->sta_tx_exc_list); - - if (local->dev_enabled) - prism2_callback(local, PRISM2_CALLBACK_DISABLE); - - for (i = 0; i < WEP_KEYS; i++) { - struct ieee80211_crypt_data *crypt = local->crypt[i]; - if (crypt) { - if (crypt->ops) - crypt->ops->deinit(crypt->priv); - kfree(crypt); - local->crypt[i] = NULL; - } - } - - if (local->ap != NULL) - hostap_free_data(local->ap); - -#ifndef PRISM2_NO_PROCFS_DEBUG - if (local->proc != NULL) - remove_proc_entry("registers", local->proc); -#endif /* PRISM2_NO_PROCFS_DEBUG */ - hostap_remove_proc(local); - - tx_cb = local->tx_callback; - while (tx_cb != NULL) { - tx_cb_prev = tx_cb; - tx_cb = tx_cb->next; - kfree(tx_cb_prev); - } - - hostap_set_hostapd(local, 0, 0); - hostap_set_hostapd_sta(local, 0, 0); - - for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) { - if (local->frag_cache[i].skb != NULL) - dev_kfree_skb(local->frag_cache[i].skb); - } - -#ifdef PRISM2_DOWNLOAD_SUPPORT - prism2_download_free_data(local->dl_pri); - prism2_download_free_data(local->dl_sec); -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - - list_for_each_safe(ptr, n, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - if (iface->type == HOSTAP_INTERFACE_MASTER) { - /* special handling for this interface below */ - continue; - } - hostap_remove_interface(iface->dev, 0, 1); - } - - prism2_clear_set_tim_queue(local); - - list_for_each_safe(ptr, n, &local->bss_list) { - struct hostap_bss_info *bss = - list_entry(ptr, struct hostap_bss_info, list); - kfree(bss); - } - -#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER) - kfree(local->bus_m0_buf); -#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */ - kfree(local->pda); - kfree(local->last_scan_results); - kfree(local->generic_elem); - - unregister_netdev(local->dev); - free_netdev(local->dev); -} - - -#ifndef PRISM2_PLX -static void prism2_suspend(struct net_device *dev) -{ - struct hostap_interface *iface; - struct local_info *local; - union iwreq_data wrqu; - - iface = dev->priv; - local = iface->local; - - /* Send disconnect event, e.g., to trigger reassociation after resume - * if wpa_supplicant is used. */ - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); - - /* Disable hardware and firmware */ - prism2_hw_shutdown(dev, 0); -} -#endif /* PRISM2_PLX */ - - -/* These might at some point be compiled separately and used as separate - * kernel modules or linked into one */ -#ifdef PRISM2_DOWNLOAD_SUPPORT -#include "hostap_download.c" -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - -#ifdef PRISM2_CALLBACK -/* External hostap_callback.c file can be used to, e.g., blink activity led. - * This can use platform specific code and must define prism2_callback() - * function (if PRISM2_CALLBACK is not defined, these function calls are not - * used. */ -#include "hostap_callback.c" -#endif /* PRISM2_CALLBACK */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_info.c b/trunk/drivers/net/wireless/hostap/hostap_info.c deleted file mode 100644 index 5aa998fdf1c4..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_info.c +++ /dev/null @@ -1,499 +0,0 @@ -/* Host AP driver Info Frame processing (part of hostap.o module) */ - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf, - int left) -{ - struct hfa384x_comm_tallies *tallies; - - if (left < sizeof(struct hfa384x_comm_tallies)) { - printk(KERN_DEBUG "%s: too short (len=%d) commtallies " - "info frame\n", local->dev->name, left); - return; - } - - tallies = (struct hfa384x_comm_tallies *) buf; -#define ADD_COMM_TALLIES(name) \ -local->comm_tallies.name += le16_to_cpu(tallies->name) - ADD_COMM_TALLIES(tx_unicast_frames); - ADD_COMM_TALLIES(tx_multicast_frames); - ADD_COMM_TALLIES(tx_fragments); - ADD_COMM_TALLIES(tx_unicast_octets); - ADD_COMM_TALLIES(tx_multicast_octets); - ADD_COMM_TALLIES(tx_deferred_transmissions); - ADD_COMM_TALLIES(tx_single_retry_frames); - ADD_COMM_TALLIES(tx_multiple_retry_frames); - ADD_COMM_TALLIES(tx_retry_limit_exceeded); - ADD_COMM_TALLIES(tx_discards); - ADD_COMM_TALLIES(rx_unicast_frames); - ADD_COMM_TALLIES(rx_multicast_frames); - ADD_COMM_TALLIES(rx_fragments); - ADD_COMM_TALLIES(rx_unicast_octets); - ADD_COMM_TALLIES(rx_multicast_octets); - ADD_COMM_TALLIES(rx_fcs_errors); - ADD_COMM_TALLIES(rx_discards_no_buffer); - ADD_COMM_TALLIES(tx_discards_wrong_sa); - ADD_COMM_TALLIES(rx_discards_wep_undecryptable); - ADD_COMM_TALLIES(rx_message_in_msg_fragments); - ADD_COMM_TALLIES(rx_message_in_bad_msg_fragments); -#undef ADD_COMM_TALLIES -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info_commtallies32(local_info_t *local, unsigned char *buf, - int left) -{ - struct hfa384x_comm_tallies32 *tallies; - - if (left < sizeof(struct hfa384x_comm_tallies32)) { - printk(KERN_DEBUG "%s: too short (len=%d) commtallies32 " - "info frame\n", local->dev->name, left); - return; - } - - tallies = (struct hfa384x_comm_tallies32 *) buf; -#define ADD_COMM_TALLIES(name) \ -local->comm_tallies.name += le32_to_cpu(tallies->name) - ADD_COMM_TALLIES(tx_unicast_frames); - ADD_COMM_TALLIES(tx_multicast_frames); - ADD_COMM_TALLIES(tx_fragments); - ADD_COMM_TALLIES(tx_unicast_octets); - ADD_COMM_TALLIES(tx_multicast_octets); - ADD_COMM_TALLIES(tx_deferred_transmissions); - ADD_COMM_TALLIES(tx_single_retry_frames); - ADD_COMM_TALLIES(tx_multiple_retry_frames); - ADD_COMM_TALLIES(tx_retry_limit_exceeded); - ADD_COMM_TALLIES(tx_discards); - ADD_COMM_TALLIES(rx_unicast_frames); - ADD_COMM_TALLIES(rx_multicast_frames); - ADD_COMM_TALLIES(rx_fragments); - ADD_COMM_TALLIES(rx_unicast_octets); - ADD_COMM_TALLIES(rx_multicast_octets); - ADD_COMM_TALLIES(rx_fcs_errors); - ADD_COMM_TALLIES(rx_discards_no_buffer); - ADD_COMM_TALLIES(tx_discards_wrong_sa); - ADD_COMM_TALLIES(rx_discards_wep_undecryptable); - ADD_COMM_TALLIES(rx_message_in_msg_fragments); - ADD_COMM_TALLIES(rx_message_in_bad_msg_fragments); -#undef ADD_COMM_TALLIES -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info_commtallies(local_info_t *local, unsigned char *buf, - int left) -{ - if (local->tallies32) - prism2_info_commtallies32(local, buf, left); - else - prism2_info_commtallies16(local, buf, left); -} - - -#ifndef PRISM2_NO_STATION_MODES -#ifndef PRISM2_NO_DEBUG -static const char* hfa384x_linkstatus_str(u16 linkstatus) -{ - switch (linkstatus) { - case HFA384X_LINKSTATUS_CONNECTED: - return "Connected"; - case HFA384X_LINKSTATUS_DISCONNECTED: - return "Disconnected"; - case HFA384X_LINKSTATUS_AP_CHANGE: - return "Access point change"; - case HFA384X_LINKSTATUS_AP_OUT_OF_RANGE: - return "Access point out of range"; - case HFA384X_LINKSTATUS_AP_IN_RANGE: - return "Access point in range"; - case HFA384X_LINKSTATUS_ASSOC_FAILED: - return "Association failed"; - default: - return "Unknown"; - } -} -#endif /* PRISM2_NO_DEBUG */ - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info_linkstatus(local_info_t *local, unsigned char *buf, - int left) -{ - u16 val; - int non_sta_mode; - - /* Alloc new JoinRequests to occur since LinkStatus for the previous - * has been received */ - local->last_join_time = 0; - - if (left != 2) { - printk(KERN_DEBUG "%s: invalid linkstatus info frame " - "length %d\n", local->dev->name, left); - return; - } - - non_sta_mode = local->iw_mode == IW_MODE_MASTER || - local->iw_mode == IW_MODE_REPEAT || - local->iw_mode == IW_MODE_MONITOR; - - val = buf[0] | (buf[1] << 8); - if (!non_sta_mode || val != HFA384X_LINKSTATUS_DISCONNECTED) { - PDEBUG(DEBUG_EXTRA, "%s: LinkStatus=%d (%s)\n", - local->dev->name, val, hfa384x_linkstatus_str(val)); - } - - if (non_sta_mode) { - netif_carrier_on(local->dev); - netif_carrier_on(local->ddev); - return; - } - - /* Get current BSSID later in scheduled task */ - set_bit(PRISM2_INFO_PENDING_LINKSTATUS, &local->pending_info); - local->prev_link_status = val; - schedule_work(&local->info_queue); -} - - -static void prism2_host_roaming(local_info_t *local) -{ - struct hfa384x_join_request req; - struct net_device *dev = local->dev; - struct hfa384x_hostscan_result *selected, *entry; - int i; - unsigned long flags; - - if (local->last_join_time && - time_before(jiffies, local->last_join_time + 10 * HZ)) { - PDEBUG(DEBUG_EXTRA, "%s: last join request has not yet been " - "completed - waiting for it before issuing new one\n", - dev->name); - return; - } - - /* ScanResults are sorted: first ESS results in decreasing signal - * quality then IBSS results in similar order. - * Trivial roaming policy: just select the first entry. - * This could probably be improved by adding hysteresis to limit - * number of handoffs, etc. - * - * Could do periodic RID_SCANREQUEST or Inquire F101 to get new - * ScanResults */ - spin_lock_irqsave(&local->lock, flags); - if (local->last_scan_results == NULL || - local->last_scan_results_count == 0) { - spin_unlock_irqrestore(&local->lock, flags); - PDEBUG(DEBUG_EXTRA, "%s: no scan results for host roaming\n", - dev->name); - return; - } - - selected = &local->last_scan_results[0]; - - if (local->preferred_ap[0] || local->preferred_ap[1] || - local->preferred_ap[2] || local->preferred_ap[3] || - local->preferred_ap[4] || local->preferred_ap[5]) { - /* Try to find preferred AP */ - PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID " MACSTR "\n", - dev->name, MAC2STR(local->preferred_ap)); - for (i = 0; i < local->last_scan_results_count; i++) { - entry = &local->last_scan_results[i]; - if (memcmp(local->preferred_ap, entry->bssid, 6) == 0) - { - PDEBUG(DEBUG_EXTRA, "%s: using preferred AP " - "selection\n", dev->name); - selected = entry; - break; - } - } - } - - memcpy(req.bssid, selected->bssid, 6); - req.channel = selected->chid; - spin_unlock_irqrestore(&local->lock, flags); - - PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=" MACSTR " channel=%d\n", - dev->name, MAC2STR(req.bssid), le16_to_cpu(req.channel)); - if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req, - sizeof(req))) { - printk(KERN_DEBUG "%s: JoinRequest failed\n", dev->name); - } - local->last_join_time = jiffies; -} - - -static void hostap_report_scan_complete(local_info_t *local) -{ - union iwreq_data wrqu; - - /* Inform user space about new scan results (just empty event, - * SIOCGIWSCAN can be used to fetch data */ - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(local->dev, SIOCGIWSCAN, &wrqu, NULL); - - /* Allow SIOCGIWSCAN handling to occur since we have received - * scanning result */ - local->scan_timestamp = 0; -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info_scanresults(local_info_t *local, unsigned char *buf, - int left) -{ - u16 *pos; - int new_count, i; - unsigned long flags; - struct hfa384x_scan_result *res; - struct hfa384x_hostscan_result *results, *prev; - - if (left < 4) { - printk(KERN_DEBUG "%s: invalid scanresult info frame " - "length %d\n", local->dev->name, left); - return; - } - - pos = (u16 *) buf; - pos++; - pos++; - left -= 4; - - new_count = left / sizeof(struct hfa384x_scan_result); - results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result), - GFP_ATOMIC); - if (results == NULL) - return; - - /* Convert to hostscan result format. */ - res = (struct hfa384x_scan_result *) pos; - for (i = 0; i < new_count; i++) { - memcpy(&results[i], &res[i], - sizeof(struct hfa384x_scan_result)); - results[i].atim = 0; - } - - spin_lock_irqsave(&local->lock, flags); - local->last_scan_type = PRISM2_SCAN; - prev = local->last_scan_results; - local->last_scan_results = results; - local->last_scan_results_count = new_count; - spin_unlock_irqrestore(&local->lock, flags); - kfree(prev); - - hostap_report_scan_complete(local); - - /* Perform rest of ScanResults handling later in scheduled task */ - set_bit(PRISM2_INFO_PENDING_SCANRESULTS, &local->pending_info); - schedule_work(&local->info_queue); -} - - -/* Called only as a tasklet (software IRQ) */ -static void prism2_info_hostscanresults(local_info_t *local, - unsigned char *buf, int left) -{ - int i, result_size, copy_len, new_count; - struct hfa384x_hostscan_result *results, *prev; - unsigned long flags; - u16 *pos; - u8 *ptr; - - wake_up_interruptible(&local->hostscan_wq); - - if (left < 4) { - printk(KERN_DEBUG "%s: invalid hostscanresult info frame " - "length %d\n", local->dev->name, left); - return; - } - - pos = (u16 *) buf; - copy_len = result_size = le16_to_cpu(*pos); - if (result_size == 0) { - printk(KERN_DEBUG "%s: invalid result_size (0) in " - "hostscanresults\n", local->dev->name); - return; - } - if (copy_len > sizeof(struct hfa384x_hostscan_result)) - copy_len = sizeof(struct hfa384x_hostscan_result); - - pos++; - pos++; - left -= 4; - ptr = (u8 *) pos; - - new_count = left / result_size; - results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result), - GFP_ATOMIC); - if (results == NULL) - return; - memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result)); - - for (i = 0; i < new_count; i++) { - memcpy(&results[i], ptr, copy_len); - ptr += result_size; - left -= result_size; - } - - if (left) { - printk(KERN_DEBUG "%s: short HostScan result entry (%d/%d)\n", - local->dev->name, left, result_size); - } - - spin_lock_irqsave(&local->lock, flags); - local->last_scan_type = PRISM2_HOSTSCAN; - prev = local->last_scan_results; - local->last_scan_results = results; - local->last_scan_results_count = new_count; - spin_unlock_irqrestore(&local->lock, flags); - kfree(prev); - - hostap_report_scan_complete(local); -} -#endif /* PRISM2_NO_STATION_MODES */ - - -/* Called only as a tasklet (software IRQ) */ -void hostap_info_process(local_info_t *local, struct sk_buff *skb) -{ - struct hfa384x_info_frame *info; - unsigned char *buf; - int left; -#ifndef PRISM2_NO_DEBUG - int i; -#endif /* PRISM2_NO_DEBUG */ - - info = (struct hfa384x_info_frame *) skb->data; - buf = skb->data + sizeof(*info); - left = skb->len - sizeof(*info); - - switch (info->type) { - case HFA384X_INFO_COMMTALLIES: - prism2_info_commtallies(local, buf, left); - break; - -#ifndef PRISM2_NO_STATION_MODES - case HFA384X_INFO_LINKSTATUS: - prism2_info_linkstatus(local, buf, left); - break; - - case HFA384X_INFO_SCANRESULTS: - prism2_info_scanresults(local, buf, left); - break; - - case HFA384X_INFO_HOSTSCANRESULTS: - prism2_info_hostscanresults(local, buf, left); - break; -#endif /* PRISM2_NO_STATION_MODES */ - -#ifndef PRISM2_NO_DEBUG - default: - PDEBUG(DEBUG_EXTRA, "%s: INFO - len=%d type=0x%04x\n", - local->dev->name, info->len, info->type); - PDEBUG(DEBUG_EXTRA, "Unknown info frame:"); - for (i = 0; i < (left < 100 ? left : 100); i++) - PDEBUG2(DEBUG_EXTRA, " %02x", buf[i]); - PDEBUG2(DEBUG_EXTRA, "\n"); - break; -#endif /* PRISM2_NO_DEBUG */ - } -} - - -#ifndef PRISM2_NO_STATION_MODES -static void handle_info_queue_linkstatus(local_info_t *local) -{ - int val = local->prev_link_status; - int connected; - union iwreq_data wrqu; - - connected = - val == HFA384X_LINKSTATUS_CONNECTED || - val == HFA384X_LINKSTATUS_AP_CHANGE || - val == HFA384X_LINKSTATUS_AP_IN_RANGE; - - if (local->func->get_rid(local->dev, HFA384X_RID_CURRENTBSSID, - local->bssid, ETH_ALEN, 1) < 0) { - printk(KERN_DEBUG "%s: could not read CURRENTBSSID after " - "LinkStatus event\n", local->dev->name); - } else { - PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" MACSTR "\n", - local->dev->name, - MAC2STR((unsigned char *) local->bssid)); - if (local->wds_type & HOSTAP_WDS_AP_CLIENT) - hostap_add_sta(local->ap, local->bssid); - } - - /* Get BSSID if we have a valid AP address */ - if (connected) { - netif_carrier_on(local->dev); - netif_carrier_on(local->ddev); - memcpy(wrqu.ap_addr.sa_data, local->bssid, ETH_ALEN); - } else { - netif_carrier_off(local->dev); - netif_carrier_off(local->ddev); - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - } - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - - /* - * Filter out sequential disconnect events in order not to cause a - * flood of SIOCGIWAP events that have a race condition with EAPOL - * frames and can confuse wpa_supplicant about the current association - * status. - */ - if (connected || local->prev_linkstatus_connected) - wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); - local->prev_linkstatus_connected = connected; -} - - -static void handle_info_queue_scanresults(local_info_t *local) -{ - if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) - prism2_host_roaming(local); - - if (local->host_roaming == 2 && local->iw_mode == IW_MODE_INFRA && - memcmp(local->preferred_ap, "\x00\x00\x00\x00\x00\x00", - ETH_ALEN) != 0) { - /* - * Firmware seems to be getting into odd state in host_roaming - * mode 2 when hostscan is used without join command, so try - * to fix this by re-joining the current AP. This does not - * actually trigger a new association if the current AP is - * still in the scan results. - */ - prism2_host_roaming(local); - } -} - - -/* Called only as scheduled task after receiving info frames (used to avoid - * pending too much time in HW IRQ handler). */ -static void handle_info_queue(void *data) -{ - local_info_t *local = (local_info_t *) data; - - if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS, - &local->pending_info)) - handle_info_queue_linkstatus(local); - - if (test_and_clear_bit(PRISM2_INFO_PENDING_SCANRESULTS, - &local->pending_info)) - handle_info_queue_scanresults(local); -} -#endif /* PRISM2_NO_STATION_MODES */ - - -void hostap_info_init(local_info_t *local) -{ - skb_queue_head_init(&local->info_list); -#ifndef PRISM2_NO_STATION_MODES - INIT_WORK(&local->info_queue, handle_info_queue, local); -#endif /* PRISM2_NO_STATION_MODES */ -} - - -EXPORT_SYMBOL(hostap_info_init); -EXPORT_SYMBOL(hostap_info_process); diff --git a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c deleted file mode 100644 index f892aa87b13e..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c +++ /dev/null @@ -1,4126 +0,0 @@ -/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ - -#ifdef in_atomic -/* Get kernel_locked() for in_atomic() */ -#include -#endif -#include - - -static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct iw_statistics *wstats; - - iface = netdev_priv(dev); - local = iface->local; - - /* Why are we doing that ? Jean II */ - if (iface->type != HOSTAP_INTERFACE_MAIN) - return NULL; - - wstats = &local->wstats; - - wstats->status = 0; - wstats->discard.code = - local->comm_tallies.rx_discards_wep_undecryptable; - wstats->discard.misc = - local->comm_tallies.rx_fcs_errors + - local->comm_tallies.rx_discards_no_buffer + - local->comm_tallies.tx_discards_wrong_sa; - - wstats->discard.retries = - local->comm_tallies.tx_retry_limit_exceeded; - wstats->discard.fragment = - local->comm_tallies.rx_message_in_bad_msg_fragments; - - if (local->iw_mode != IW_MODE_MASTER && - local->iw_mode != IW_MODE_REPEAT) { - int update = 1; -#ifdef in_atomic - /* RID reading might sleep and it must not be called in - * interrupt context or while atomic. However, this - * function seems to be called while atomic (at least in Linux - * 2.5.59). Update signal quality values only if in suitable - * context. Otherwise, previous values read from tick timer - * will be used. */ - if (in_atomic()) - update = 0; -#endif /* in_atomic */ - - if (update && prism2_update_comms_qual(dev) == 0) - wstats->qual.updated = 7; - - wstats->qual.qual = local->comms_qual; - wstats->qual.level = local->avg_signal; - wstats->qual.noise = local->avg_noise; - } else { - wstats->qual.qual = 0; - wstats->qual.level = 0; - wstats->qual.noise = 0; - wstats->qual.updated = 0; - } - - return wstats; -} - - -static int prism2_get_datarates(struct net_device *dev, u8 *rates) -{ - struct hostap_interface *iface; - local_info_t *local; - u8 buf[12]; - int len; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - len = local->func->get_rid(dev, HFA384X_RID_SUPPORTEDDATARATES, buf, - sizeof(buf), 0); - if (len < 2) - return 0; - - val = le16_to_cpu(*(u16 *) buf); /* string length */ - - if (len - 2 < val || val > 10) - return 0; - - memcpy(rates, buf + 2, val); - return val; -} - - -static int prism2_get_name(struct net_device *dev, - struct iw_request_info *info, - char *name, char *extra) -{ - u8 rates[10]; - int len, i, over2 = 0; - - len = prism2_get_datarates(dev, rates); - - for (i = 0; i < len; i++) { - if (rates[i] == 0x0b || rates[i] == 0x16) { - over2 = 1; - break; - } - } - - strcpy(name, over2 ? "IEEE 802.11b" : "IEEE 802.11-DS"); - - return 0; -} - - -static void prism2_crypt_delayed_deinit(local_info_t *local, - struct ieee80211_crypt_data **crypt) -{ - struct ieee80211_crypt_data *tmp; - unsigned long flags; - - tmp = *crypt; - *crypt = NULL; - - if (tmp == NULL) - return; - - /* must not run ops->deinit() while there may be pending encrypt or - * decrypt operations. Use a list of delayed deinits to avoid needing - * locking. */ - - spin_lock_irqsave(&local->lock, flags); - list_add(&tmp->list, &local->crypt_deinit_list); - if (!timer_pending(&local->crypt_deinit_timer)) { - local->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&local->crypt_deinit_timer); - } - spin_unlock_irqrestore(&local->lock, flags); -} - - -static int prism2_ioctl_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *keybuf) -{ - struct hostap_interface *iface; - local_info_t *local; - int i; - struct ieee80211_crypt_data **crypt; - - iface = netdev_priv(dev); - local = iface->local; - - i = erq->flags & IW_ENCODE_INDEX; - if (i < 1 || i > 4) - i = local->tx_keyidx; - else - i--; - if (i < 0 || i >= WEP_KEYS) - return -EINVAL; - - crypt = &local->crypt[i]; - - if (erq->flags & IW_ENCODE_DISABLED) { - if (*crypt) - prism2_crypt_delayed_deinit(local, crypt); - goto done; - } - - if (*crypt != NULL && (*crypt)->ops != NULL && - strcmp((*crypt)->ops->name, "WEP") != 0) { - /* changing to use WEP; deinit previously used algorithm */ - prism2_crypt_delayed_deinit(local, crypt); - } - - if (*crypt == NULL) { - struct ieee80211_crypt_data *new_crypt; - - /* take WEP into use */ - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(struct ieee80211_crypt_data), - GFP_KERNEL); - if (new_crypt == NULL) - return -ENOMEM; - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (!new_crypt->ops) { - request_module("ieee80211_crypt_wep"); - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - } - if (new_crypt->ops) - new_crypt->priv = new_crypt->ops->init(i); - if (!new_crypt->ops || !new_crypt->priv) { - kfree(new_crypt); - new_crypt = NULL; - - printk(KERN_WARNING "%s: could not initialize WEP: " - "load module hostap_crypt_wep.o\n", - dev->name); - return -EOPNOTSUPP; - } - *crypt = new_crypt; - } - - if (erq->length > 0) { - int len = erq->length <= 5 ? 5 : 13; - int first = 1, j; - if (len > erq->length) - memset(keybuf + erq->length, 0, len - erq->length); - (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv); - for (j = 0; j < WEP_KEYS; j++) { - if (j != i && local->crypt[j]) { - first = 0; - break; - } - } - if (first) - local->tx_keyidx = i; - } else { - /* No key data - just set the default TX key index */ - local->tx_keyidx = i; - } - - done: - local->open_wep = erq->flags & IW_ENCODE_OPEN; - - if (hostap_set_encryption(local)) { - printk(KERN_DEBUG "%s: set_encryption failed\n", dev->name); - return -EINVAL; - } - - /* Do not reset port0 if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. Prism2 documentation seem to require port reset - * after WEP configuration. However, keys are apparently changed at - * least in Managed mode. */ - if (local->iw_mode != IW_MODE_INFRA && local->func->reset_port(dev)) { - printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); - return -EINVAL; - } - - return 0; -} - - -static int prism2_ioctl_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *key) -{ - struct hostap_interface *iface; - local_info_t *local; - int i, len; - u16 val; - struct ieee80211_crypt_data *crypt; - - iface = netdev_priv(dev); - local = iface->local; - - i = erq->flags & IW_ENCODE_INDEX; - if (i < 1 || i > 4) - i = local->tx_keyidx; - else - i--; - if (i < 0 || i >= WEP_KEYS) - return -EINVAL; - - crypt = local->crypt[i]; - erq->flags = i + 1; - - if (crypt == NULL || crypt->ops == NULL) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - - if (strcmp(crypt->ops->name, "WEP") != 0) { - /* only WEP is supported with wireless extensions, so just - * report that encryption is used */ - erq->length = 0; - erq->flags |= IW_ENCODE_ENABLED; - return 0; - } - - /* Reads from HFA384X_RID_CNFDEFAULTKEY* return bogus values, so show - * the keys from driver buffer */ - len = crypt->ops->get_key(key, WEP_KEY_LEN, NULL, crypt->priv); - erq->length = (len >= 0 ? len : 0); - - if (local->func->get_rid(dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0) - { - printk("CNFWEPFLAGS reading failed\n"); - return -EOPNOTSUPP; - } - le16_to_cpus(&val); - if (val & HFA384X_WEPFLAGS_PRIVACYINVOKED) - erq->flags |= IW_ENCODE_ENABLED; - else - erq->flags |= IW_ENCODE_DISABLED; - if (val & HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED) - erq->flags |= IW_ENCODE_RESTRICTED; - else - erq->flags |= IW_ENCODE_OPEN; - - return 0; -} - - -static int hostap_set_rate(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - int ret, basic_rates; - - iface = netdev_priv(dev); - local = iface->local; - - basic_rates = local->basic_rates & local->tx_rate_control; - if (!basic_rates || basic_rates != local->basic_rates) { - printk(KERN_INFO "%s: updating basic rate set automatically " - "to match with the new supported rate set\n", - dev->name); - if (!basic_rates) - basic_rates = local->tx_rate_control; - - local->basic_rates = basic_rates; - if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES, - basic_rates)) - printk(KERN_WARNING "%s: failed to set " - "cnfBasicRates\n", dev->name); - } - - ret = (hostap_set_word(dev, HFA384X_RID_TXRATECONTROL, - local->tx_rate_control) || - hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES, - local->tx_rate_control) || - local->func->reset_port(dev)); - - if (ret) { - printk(KERN_WARNING "%s: TXRateControl/cnfSupportedRates " - "setting to 0x%x failed\n", - dev->name, local->tx_rate_control); - } - - /* Update TX rate configuration for all STAs based on new operational - * rate set. */ - hostap_update_rates(local); - - return ret; -} - - -static int prism2_ioctl_siwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (rrq->fixed) { - switch (rrq->value) { - case 11000000: - local->tx_rate_control = HFA384X_RATES_11MBPS; - break; - case 5500000: - local->tx_rate_control = HFA384X_RATES_5MBPS; - break; - case 2000000: - local->tx_rate_control = HFA384X_RATES_2MBPS; - break; - case 1000000: - local->tx_rate_control = HFA384X_RATES_1MBPS; - break; - default: - local->tx_rate_control = HFA384X_RATES_1MBPS | - HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS | - HFA384X_RATES_11MBPS; - break; - } - } else { - switch (rrq->value) { - case 11000000: - local->tx_rate_control = HFA384X_RATES_1MBPS | - HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS | - HFA384X_RATES_11MBPS; - break; - case 5500000: - local->tx_rate_control = HFA384X_RATES_1MBPS | - HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS; - break; - case 2000000: - local->tx_rate_control = HFA384X_RATES_1MBPS | - HFA384X_RATES_2MBPS; - break; - case 1000000: - local->tx_rate_control = HFA384X_RATES_1MBPS; - break; - default: - local->tx_rate_control = HFA384X_RATES_1MBPS | - HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS | - HFA384X_RATES_11MBPS; - break; - } - } - - return hostap_set_rate(dev); -} - - -static int prism2_ioctl_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - u16 val; - struct hostap_interface *iface; - local_info_t *local; - int ret = 0; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->get_rid(dev, HFA384X_RID_TXRATECONTROL, &val, 2, 1) < - 0) - return -EINVAL; - - if ((val & 0x1) && (val > 1)) - rrq->fixed = 0; - else - rrq->fixed = 1; - - if (local->iw_mode == IW_MODE_MASTER && local->ap != NULL && - !local->fw_tx_rate_control) { - /* HFA384X_RID_CURRENTTXRATE seems to always be 2 Mbps in - * Host AP mode, so use the recorded TX rate of the last sent - * frame */ - rrq->value = local->ap->last_tx_rate > 0 ? - local->ap->last_tx_rate * 100000 : 11000000; - return 0; - } - - if (local->func->get_rid(dev, HFA384X_RID_CURRENTTXRATE, &val, 2, 1) < - 0) - return -EINVAL; - - switch (val) { - case HFA384X_RATES_1MBPS: - rrq->value = 1000000; - break; - case HFA384X_RATES_2MBPS: - rrq->value = 2000000; - break; - case HFA384X_RATES_5MBPS: - rrq->value = 5500000; - break; - case HFA384X_RATES_11MBPS: - rrq->value = 11000000; - break; - default: - /* should not happen */ - rrq->value = 11000000; - ret = -EINVAL; - break; - } - - return ret; -} - - -static int prism2_ioctl_siwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *sens, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - /* Set the desired AP density */ - if (sens->value < 1 || sens->value > 3) - return -EINVAL; - - if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) || - local->func->reset_port(dev)) - return -EINVAL; - - return 0; -} - -static int prism2_ioctl_giwsens(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *sens, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - /* Get the current AP density */ - if (local->func->get_rid(dev, HFA384X_RID_CNFSYSTEMSCALE, &val, 2, 1) < - 0) - return -EINVAL; - - sens->value = __le16_to_cpu(val); - sens->fixed = 1; - - return 0; -} - - -/* Deprecated in new wireless extension API */ -static int prism2_ioctl_giwaplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - struct sockaddr *addr; - struct iw_quality *qual; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->iw_mode != IW_MODE_MASTER) { - printk(KERN_DEBUG "SIOCGIWAPLIST is currently only supported " - "in Host AP mode\n"); - data->length = 0; - return -EOPNOTSUPP; - } - - addr = kmalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL); - qual = kmalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL); - if (addr == NULL || qual == NULL) { - kfree(addr); - kfree(qual); - data->length = 0; - return -ENOMEM; - } - - data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); - - memcpy(extra, &addr, sizeof(struct sockaddr) * data->length); - data->flags = 1; /* has quality information */ - memcpy(extra + sizeof(struct sockaddr) * data->length, &qual, - sizeof(struct iw_quality) * data->length); - - kfree(addr); - kfree(qual); - - return 0; -} - - -static int prism2_ioctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - if (rts->disabled) - val = __constant_cpu_to_le16(2347); - else if (rts->value < 0 || rts->value > 2347) - return -EINVAL; - else - val = __cpu_to_le16(rts->value); - - if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) || - local->func->reset_port(dev)) - return -EINVAL; - - local->rts_threshold = rts->value; - - return 0; -} - -static int prism2_ioctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->get_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2, 1) < - 0) - return -EINVAL; - - rts->value = __le16_to_cpu(val); - rts->disabled = (rts->value == 2347); - rts->fixed = 1; - - return 0; -} - - -static int prism2_ioctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - if (rts->disabled) - val = __constant_cpu_to_le16(2346); - else if (rts->value < 256 || rts->value > 2346) - return -EINVAL; - else - val = __cpu_to_le16(rts->value & ~0x1); /* even numbers only */ - - local->fragm_threshold = rts->value & ~0x1; - if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val, - 2) - || local->func->reset_port(dev)) - return -EINVAL; - - return 0; -} - -static int prism2_ioctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->get_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, - &val, 2, 1) < 0) - return -EINVAL; - - rts->value = __le16_to_cpu(val); - rts->disabled = (rts->value == 2346); - rts->fixed = 1; - - return 0; -} - - -#ifndef PRISM2_NO_STATION_MODES -static int hostap_join_ap(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hfa384x_join_request req; - unsigned long flags; - int i; - struct hfa384x_hostscan_result *entry; - - iface = netdev_priv(dev); - local = iface->local; - - memcpy(req.bssid, local->preferred_ap, ETH_ALEN); - req.channel = 0; - - spin_lock_irqsave(&local->lock, flags); - for (i = 0; i < local->last_scan_results_count; i++) { - if (!local->last_scan_results) - break; - entry = &local->last_scan_results[i]; - if (memcmp(local->preferred_ap, entry->bssid, ETH_ALEN) == 0) { - req.channel = entry->chid; - break; - } - } - spin_unlock_irqrestore(&local->lock, flags); - - if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req, - sizeof(req))) { - printk(KERN_DEBUG "%s: JoinRequest " MACSTR - " failed\n", - dev->name, MAC2STR(local->preferred_ap)); - return -1; - } - - printk(KERN_DEBUG "%s: Trying to join BSSID " MACSTR "\n", - dev->name, MAC2STR(local->preferred_ap)); - - return 0; -} -#endif /* PRISM2_NO_STATION_MODES */ - - -static int prism2_ioctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ -#ifdef PRISM2_NO_STATION_MODES - return -EOPNOTSUPP; -#else /* PRISM2_NO_STATION_MODES */ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - memcpy(local->preferred_ap, &ap_addr->sa_data, ETH_ALEN); - - if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) { - struct hfa384x_scan_request scan_req; - memset(&scan_req, 0, sizeof(scan_req)); - scan_req.channel_list = __constant_cpu_to_le16(0x3fff); - scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS); - if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, - &scan_req, sizeof(scan_req))) { - printk(KERN_DEBUG "%s: ScanResults request failed - " - "preferred AP delayed to next unsolicited " - "scan\n", dev->name); - } - } else if (local->host_roaming == 2 && - local->iw_mode == IW_MODE_INFRA) { - if (hostap_join_ap(dev)) - return -EINVAL; - } else { - printk(KERN_DEBUG "%s: Preferred AP (SIOCSIWAP) is used only " - "in Managed mode when host_roaming is enabled\n", - dev->name); - } - - return 0; -#endif /* PRISM2_NO_STATION_MODES */ -} - -static int prism2_ioctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - ap_addr->sa_family = ARPHRD_ETHER; - switch (iface->type) { - case HOSTAP_INTERFACE_AP: - memcpy(&ap_addr->sa_data, dev->dev_addr, ETH_ALEN); - break; - case HOSTAP_INTERFACE_STA: - memcpy(&ap_addr->sa_data, local->assoc_ap_addr, ETH_ALEN); - break; - case HOSTAP_INTERFACE_WDS: - memcpy(&ap_addr->sa_data, iface->u.wds.remote_addr, ETH_ALEN); - break; - default: - if (local->func->get_rid(dev, HFA384X_RID_CURRENTBSSID, - &ap_addr->sa_data, ETH_ALEN, 1) < 0) - return -EOPNOTSUPP; - - /* local->bssid is also updated in LinkStatus handler when in - * station mode */ - memcpy(local->bssid, &ap_addr->sa_data, ETH_ALEN); - break; - } - - return 0; -} - - -static int prism2_ioctl_siwnickn(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *nickname) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - memset(local->name, 0, sizeof(local->name)); - memcpy(local->name, nickname, data->length); - local->name_set = 1; - - if (hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name) || - local->func->reset_port(dev)) - return -EINVAL; - - return 0; -} - -static int prism2_ioctl_giwnickn(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *nickname) -{ - struct hostap_interface *iface; - local_info_t *local; - int len; - char name[MAX_NAME_LEN + 3]; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME, - &name, MAX_NAME_LEN + 2, 0); - val = __le16_to_cpu(*(u16 *) name); - if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN) - return -EOPNOTSUPP; - - name[val + 2] = '\0'; - data->length = val + 1; - memcpy(nickname, name + 2, val + 1); - - return 0; -} - - -static int prism2_ioctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - /* freq => chan. */ - if (freq->e == 1 && - freq->m / 100000 >= freq_list[0] && - freq->m / 100000 <= freq_list[FREQ_COUNT - 1]) { - int ch; - int fr = freq->m / 100000; - for (ch = 0; ch < FREQ_COUNT; ch++) { - if (fr == freq_list[ch]) { - freq->e = 0; - freq->m = ch + 1; - break; - } - } - } - - if (freq->e != 0 || freq->m < 1 || freq->m > FREQ_COUNT || - !(local->channel_mask & (1 << (freq->m - 1)))) - return -EINVAL; - - local->channel = freq->m; /* channel is used in prism2_setup_rids() */ - if (hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel) || - local->func->reset_port(dev)) - return -EINVAL; - - return 0; -} - -static int prism2_ioctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) < - 0) - return -EINVAL; - - le16_to_cpus(&val); - if (val < 1 || val > FREQ_COUNT) - return -EINVAL; - - freq->m = freq_list[val - 1] * 100000; - freq->e = 1; - - return 0; -} - - -static void hostap_monitor_set_type(local_info_t *local) -{ - struct net_device *dev = local->ddev; - - if (dev == NULL) - return; - - if (local->monitor_type == PRISM2_MONITOR_PRISM || - local->monitor_type == PRISM2_MONITOR_CAPHDR) { - dev->type = ARPHRD_IEEE80211_PRISM; - dev->hard_header_parse = - hostap_80211_prism_header_parse; - } else { - dev->type = ARPHRD_IEEE80211; - dev->hard_header_parse = hostap_80211_header_parse; - } -} - - -static int prism2_ioctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (iface->type == HOSTAP_INTERFACE_WDS) - return -EOPNOTSUPP; - - if (data->flags == 0) - ssid[0] = '\0'; /* ANY */ - - if (local->iw_mode == IW_MODE_MASTER && ssid[0] == '\0') { - /* Setting SSID to empty string seems to kill the card in - * Host AP mode */ - printk(KERN_DEBUG "%s: Host AP mode does not support " - "'Any' essid\n", dev->name); - return -EINVAL; - } - - memcpy(local->essid, ssid, data->length); - local->essid[data->length] = '\0'; - - if ((!local->fw_ap && - hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid)) - || hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid) || - local->func->reset_port(dev)) - return -EINVAL; - - return 0; -} - -static int prism2_ioctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *essid) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - if (iface->type == HOSTAP_INTERFACE_WDS) - return -EOPNOTSUPP; - - data->flags = 1; /* active */ - if (local->iw_mode == IW_MODE_MASTER) { - data->length = strlen(local->essid); - memcpy(essid, local->essid, IW_ESSID_MAX_SIZE); - } else { - int len; - char ssid[MAX_SSID_LEN + 2]; - memset(ssid, 0, sizeof(ssid)); - len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID, - &ssid, MAX_SSID_LEN + 2, 0); - val = __le16_to_cpu(*(u16 *) ssid); - if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) { - return -EOPNOTSUPP; - } - data->length = val; - memcpy(essid, ssid + 2, IW_ESSID_MAX_SIZE); - } - - return 0; -} - - -static int prism2_ioctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - struct iw_range *range = (struct iw_range *) extra; - u8 rates[10]; - u16 val; - int i, len, over2; - - iface = netdev_priv(dev); - local = iface->local; - - data->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - /* TODO: could fill num_txpower and txpower array with - * something; however, there are 128 different values.. */ - - range->txpower_capa = IW_TXPOW_DBM; - - if (local->iw_mode == IW_MODE_INFRA || local->iw_mode == IW_MODE_ADHOC) - { - range->min_pmp = 1 * 1024; - range->max_pmp = 65535 * 1024; - range->min_pmt = 1 * 1024; - range->max_pmt = 1000 * 1024; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | - IW_POWER_UNICAST_R | IW_POWER_ALL_R; - } - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 18; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->min_retry = 0; - range->max_retry = 255; - - range->num_channels = FREQ_COUNT; - - val = 0; - for (i = 0; i < FREQ_COUNT; i++) { - if (local->channel_mask & (1 << i)) { - range->freq[val].i = i + 1; - range->freq[val].m = freq_list[i] * 100000; - range->freq[val].e = 1; - val++; - } - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - - if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) { - range->max_qual.qual = 70; /* what is correct max? This was not - * documented exactly. At least - * 69 has been observed. */ - range->max_qual.level = 0; /* dB */ - range->max_qual.noise = 0; /* dB */ - - /* What would be suitable values for "average/typical" qual? */ - range->avg_qual.qual = 20; - range->avg_qual.level = -60; - range->avg_qual.noise = -95; - } else { - range->max_qual.qual = 92; /* 0 .. 92 */ - range->max_qual.level = 154; /* 27 .. 154 */ - range->max_qual.noise = 154; /* 27 .. 154 */ - } - range->sensitivity = 3; - - range->max_encoding_tokens = WEP_KEYS; - range->num_encoding_sizes = 2; - range->encoding_size[0] = 5; - range->encoding_size[1] = 13; - - over2 = 0; - len = prism2_get_datarates(dev, rates); - range->num_bitrates = 0; - for (i = 0; i < len; i++) { - if (range->num_bitrates < IW_MAX_BITRATES) { - range->bitrate[range->num_bitrates] = - rates[i] * 500000; - range->num_bitrates++; - } - if (rates[i] == 0x0b || rates[i] == 0x16) - over2 = 1; - } - /* estimated maximum TCP throughput values (bps) */ - range->throughput = over2 ? 5500000 : 1500000; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - /* Event capability (kernel + driver) */ - range->event_capa[0] = (IW_EVENT_CAPA_K_0 | - IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) | - IW_EVENT_CAPA_MASK(SIOCGIWAP) | - IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); - range->event_capa[1] = IW_EVENT_CAPA_K_1; - range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) | - IW_EVENT_CAPA_MASK(IWEVCUSTOM) | - IW_EVENT_CAPA_MASK(IWEVREGISTERED) | - IW_EVENT_CAPA_MASK(IWEVEXPIRED)); - - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - - return 0; -} - - -static int hostap_monitor_mode_enable(local_info_t *local) -{ - struct net_device *dev = local->dev; - - printk(KERN_DEBUG "Enabling monitor mode\n"); - hostap_monitor_set_type(local); - - if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, - HFA384X_PORTTYPE_PSEUDO_IBSS)) { - printk(KERN_DEBUG "Port type setting for monitor mode " - "failed\n"); - return -EOPNOTSUPP; - } - - /* Host decrypt is needed to get the IV and ICV fields; - * however, monitor mode seems to remove WEP flag from frame - * control field */ - if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS, - HFA384X_WEPFLAGS_HOSTENCRYPT | - HFA384X_WEPFLAGS_HOSTDECRYPT)) { - printk(KERN_DEBUG "WEP flags setting failed\n"); - return -EOPNOTSUPP; - } - - if (local->func->reset_port(dev) || - local->func->cmd(dev, HFA384X_CMDCODE_TEST | - (HFA384X_TEST_MONITOR << 8), - 0, NULL, NULL)) { - printk(KERN_DEBUG "Setting monitor mode failed\n"); - return -EOPNOTSUPP; - } - - return 0; -} - - -static int hostap_monitor_mode_disable(local_info_t *local) -{ - struct net_device *dev = local->ddev; - - if (dev == NULL) - return -1; - - printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name); - dev->type = ARPHRD_ETHER; - dev->hard_header_parse = local->saved_eth_header_parse; - if (local->func->cmd(dev, HFA384X_CMDCODE_TEST | - (HFA384X_TEST_STOP << 8), - 0, NULL, NULL)) - return -1; - return hostap_set_encryption(local); -} - - -static int prism2_ioctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - int double_reset = 0; - - iface = netdev_priv(dev); - local = iface->local; - - if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA && - *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT && - *mode != IW_MODE_MONITOR) - return -EOPNOTSUPP; - -#ifdef PRISM2_NO_STATION_MODES - if (*mode == IW_MODE_ADHOC || *mode == IW_MODE_INFRA) - return -EOPNOTSUPP; -#endif /* PRISM2_NO_STATION_MODES */ - - if (*mode == local->iw_mode) - return 0; - - if (*mode == IW_MODE_MASTER && local->essid[0] == '\0') { - printk(KERN_WARNING "%s: empty SSID not allowed in Master " - "mode\n", dev->name); - return -EINVAL; - } - - if (local->iw_mode == IW_MODE_MONITOR) - hostap_monitor_mode_disable(local); - - if ((local->iw_mode == IW_MODE_ADHOC || - local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) { - /* There seems to be a firmware bug in at least STA f/w v1.5.6 - * that leaves beacon frames to use IBSS type when moving from - * IBSS to Host AP mode. Doing double Port0 reset seems to be - * enough to workaround this. */ - double_reset = 1; - } - - printk(KERN_DEBUG "prism2: %s: operating mode changed " - "%d -> %d\n", dev->name, local->iw_mode, *mode); - local->iw_mode = *mode; - - if (local->iw_mode == IW_MODE_MONITOR) - hostap_monitor_mode_enable(local); - else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt && - !local->fw_encrypt_ok) { - printk(KERN_DEBUG "%s: defaulting to host-based encryption as " - "a workaround for firmware bug in Host AP mode WEP\n", - dev->name); - local->host_encrypt = 1; - } - - if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, - hostap_get_porttype(local))) - return -EOPNOTSUPP; - - if (local->func->reset_port(dev)) - return -EINVAL; - if (double_reset && local->func->reset_port(dev)) - return -EINVAL; - - if (local->iw_mode != IW_MODE_INFRA && local->iw_mode != IW_MODE_ADHOC) - { - /* netif_carrier is used only in client modes for now, so make - * sure carrier is on when moving to non-client modes. */ - netif_carrier_on(local->dev); - netif_carrier_on(local->ddev); - } - return 0; -} - - -static int prism2_ioctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - switch (iface->type) { - case HOSTAP_INTERFACE_STA: - *mode = IW_MODE_INFRA; - break; - case HOSTAP_INTERFACE_WDS: - *mode = IW_MODE_REPEAT; - break; - default: - *mode = local->iw_mode; - break; - } - return 0; -} - - -static int prism2_ioctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, char *extra) -{ -#ifdef PRISM2_NO_STATION_MODES - return -EOPNOTSUPP; -#else /* PRISM2_NO_STATION_MODES */ - int ret = 0; - - if (wrq->disabled) - return hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 0); - - switch (wrq->flags & IW_POWER_MODE) { - case IW_POWER_UNICAST_R: - ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 0); - if (ret) - return ret; - ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1); - if (ret) - return ret; - break; - case IW_POWER_ALL_R: - ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 1); - if (ret) - return ret; - ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1); - if (ret) - return ret; - break; - case IW_POWER_ON: - break; - default: - return -EINVAL; - } - - if (wrq->flags & IW_POWER_TIMEOUT) { - ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1); - if (ret) - return ret; - ret = hostap_set_word(dev, HFA384X_RID_CNFPMHOLDOVERDURATION, - wrq->value / 1024); - if (ret) - return ret; - } - if (wrq->flags & IW_POWER_PERIOD) { - ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1); - if (ret) - return ret; - ret = hostap_set_word(dev, HFA384X_RID_CNFMAXSLEEPDURATION, - wrq->value / 1024); - if (ret) - return ret; - } - - return ret; -#endif /* PRISM2_NO_STATION_MODES */ -} - - -static int prism2_ioctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ -#ifdef PRISM2_NO_STATION_MODES - return -EOPNOTSUPP; -#else /* PRISM2_NO_STATION_MODES */ - struct hostap_interface *iface; - local_info_t *local; - u16 enable, mcast; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->get_rid(dev, HFA384X_RID_CNFPMENABLED, &enable, 2, 1) - < 0) - return -EINVAL; - - if (!__le16_to_cpu(enable)) { - rrq->disabled = 1; - return 0; - } - - rrq->disabled = 0; - - if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - u16 timeout; - if (local->func->get_rid(dev, - HFA384X_RID_CNFPMHOLDOVERDURATION, - &timeout, 2, 1) < 0) - return -EINVAL; - - rrq->flags = IW_POWER_TIMEOUT; - rrq->value = __le16_to_cpu(timeout) * 1024; - } else { - u16 period; - if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION, - &period, 2, 1) < 0) - return -EINVAL; - - rrq->flags = IW_POWER_PERIOD; - rrq->value = __le16_to_cpu(period) * 1024; - } - - if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast, - 2, 1) < 0) - return -EINVAL; - - if (__le16_to_cpu(mcast)) - rrq->flags |= IW_POWER_ALL_R; - else - rrq->flags |= IW_POWER_UNICAST_R; - - return 0; -#endif /* PRISM2_NO_STATION_MODES */ -} - - -static int prism2_ioctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (rrq->disabled) - return -EINVAL; - - /* setting retry limits is not supported with the current station - * firmware code; simulate this with alternative retry count for now */ - if (rrq->flags == IW_RETRY_LIMIT) { - if (rrq->value < 0) { - /* disable manual retry count setting and use firmware - * defaults */ - local->manual_retry_count = -1; - local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY; - } else { - if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT, - rrq->value)) { - printk(KERN_DEBUG "%s: Alternate retry count " - "setting to %d failed\n", - dev->name, rrq->value); - return -EOPNOTSUPP; - } - - local->manual_retry_count = rrq->value; - local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY; - } - return 0; - } - - return -EOPNOTSUPP; - -#if 0 - /* what could be done, if firmware would support this.. */ - - if (rrq->flags & IW_RETRY_LIMIT) { - if (rrq->flags & IW_RETRY_MAX) - HFA384X_RID_LONGRETRYLIMIT = rrq->value; - else if (rrq->flags & IW_RETRY_MIN) - HFA384X_RID_SHORTRETRYLIMIT = rrq->value; - else { - HFA384X_RID_LONGRETRYLIMIT = rrq->value; - HFA384X_RID_SHORTRETRYLIMIT = rrq->value; - } - - } - - if (rrq->flags & IW_RETRY_LIFETIME) { - HFA384X_RID_MAXTRANSMITLIFETIME = rrq->value / 1024; - } - - return 0; -#endif /* 0 */ -} - -static int prism2_ioctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 shortretry, longretry, lifetime, altretry; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->get_rid(dev, HFA384X_RID_SHORTRETRYLIMIT, &shortretry, - 2, 1) < 0 || - local->func->get_rid(dev, HFA384X_RID_LONGRETRYLIMIT, &longretry, - 2, 1) < 0 || - local->func->get_rid(dev, HFA384X_RID_MAXTRANSMITLIFETIME, - &lifetime, 2, 1) < 0) - return -EINVAL; - - le16_to_cpus(&shortretry); - le16_to_cpus(&longretry); - le16_to_cpus(&lifetime); - - rrq->disabled = 0; - - if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { - rrq->flags = IW_RETRY_LIFETIME; - rrq->value = lifetime * 1024; - } else { - if (local->manual_retry_count >= 0) { - rrq->flags = IW_RETRY_LIMIT; - if (local->func->get_rid(dev, - HFA384X_RID_CNFALTRETRYCOUNT, - &altretry, 2, 1) >= 0) - rrq->value = le16_to_cpu(altretry); - else - rrq->value = local->manual_retry_count; - } else if ((rrq->flags & IW_RETRY_MAX)) { - rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - rrq->value = longretry; - } else { - rrq->flags = IW_RETRY_LIMIT; - rrq->value = shortretry; - if (shortretry != longretry) - rrq->flags |= IW_RETRY_MIN; - } - } - return 0; -} - - -/* Note! This TX power controlling is experimental and should not be used in - * production use. It just sets raw power register and does not use any kind of - * feedback information from the measured TX power (CR58). This is now - * commented out to make sure that it is not used by accident. TX power - * configuration will be enabled again after proper algorithm using feedback - * has been implemented. */ - -#ifdef RAW_TXPOWER_SETTING -/* Map HFA386x's CR31 to and from dBm with some sort of ad hoc mapping.. - * This version assumes following mapping: - * CR31 is 7-bit value with -64 to +63 range. - * -64 is mapped into +20dBm and +63 into -43dBm. - * This is certainly not an exact mapping for every card, but at least - * increasing dBm value should correspond to increasing TX power. - */ - -static int prism2_txpower_hfa386x_to_dBm(u16 val) -{ - signed char tmp; - - if (val > 255) - val = 255; - - tmp = val; - tmp >>= 2; - - return -12 - tmp; -} - -static u16 prism2_txpower_dBm_to_hfa386x(int val) -{ - signed char tmp; - - if (val > 20) - return 128; - else if (val < -43) - return 127; - - tmp = val; - tmp = -12 - tmp; - tmp <<= 2; - - return (unsigned char) tmp; -} -#endif /* RAW_TXPOWER_SETTING */ - - -static int prism2_ioctl_siwtxpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; -#ifdef RAW_TXPOWER_SETTING - char *tmp; -#endif - u16 val; - int ret = 0; - - iface = netdev_priv(dev); - local = iface->local; - - if (rrq->disabled) { - if (local->txpower_type != PRISM2_TXPOWER_OFF) { - val = 0xff; /* use all standby and sleep modes */ - ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, - HFA386X_CR_A_D_TEST_MODES2, - &val, NULL); - printk(KERN_DEBUG "%s: Turning radio off: %s\n", - dev->name, ret ? "failed" : "OK"); - local->txpower_type = PRISM2_TXPOWER_OFF; - } - return (ret ? -EOPNOTSUPP : 0); - } - - if (local->txpower_type == PRISM2_TXPOWER_OFF) { - val = 0; /* disable all standby and sleep modes */ - ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, - HFA386X_CR_A_D_TEST_MODES2, &val, NULL); - printk(KERN_DEBUG "%s: Turning radio on: %s\n", - dev->name, ret ? "failed" : "OK"); - local->txpower_type = PRISM2_TXPOWER_UNKNOWN; - } - -#ifdef RAW_TXPOWER_SETTING - if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) { - printk(KERN_DEBUG "Setting ALC on\n"); - val = HFA384X_TEST_CFG_BIT_ALC; - local->func->cmd(dev, HFA384X_CMDCODE_TEST | - (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL); - local->txpower_type = PRISM2_TXPOWER_AUTO; - return 0; - } - - if (local->txpower_type != PRISM2_TXPOWER_FIXED) { - printk(KERN_DEBUG "Setting ALC off\n"); - val = HFA384X_TEST_CFG_BIT_ALC; - local->func->cmd(dev, HFA384X_CMDCODE_TEST | - (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL); - local->txpower_type = PRISM2_TXPOWER_FIXED; - } - - if (rrq->flags == IW_TXPOW_DBM) - tmp = "dBm"; - else if (rrq->flags == IW_TXPOW_MWATT) - tmp = "mW"; - else - tmp = "UNKNOWN"; - printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp); - - if (rrq->flags != IW_TXPOW_DBM) { - printk("SIOCSIWTXPOW with mW is not supported; use dBm\n"); - return -EOPNOTSUPP; - } - - local->txpower = rrq->value; - val = prism2_txpower_dBm_to_hfa386x(local->txpower); - if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, - HFA386X_CR_MANUAL_TX_POWER, &val, NULL)) - ret = -EOPNOTSUPP; -#else /* RAW_TXPOWER_SETTING */ - if (rrq->fixed) - ret = -EOPNOTSUPP; -#endif /* RAW_TXPOWER_SETTING */ - - return ret; -} - -static int prism2_ioctl_giwtxpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rrq, char *extra) -{ -#ifdef RAW_TXPOWER_SETTING - struct hostap_interface *iface; - local_info_t *local; - u16 resp0; - - iface = netdev_priv(dev); - local = iface->local; - - rrq->flags = IW_TXPOW_DBM; - rrq->disabled = 0; - rrq->fixed = 0; - - if (local->txpower_type == PRISM2_TXPOWER_AUTO) { - if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF, - HFA386X_CR_MANUAL_TX_POWER, - NULL, &resp0) == 0) { - rrq->value = prism2_txpower_hfa386x_to_dBm(resp0); - } else { - /* Could not get real txpower; guess 15 dBm */ - rrq->value = 15; - } - } else if (local->txpower_type == PRISM2_TXPOWER_OFF) { - rrq->value = 0; - rrq->disabled = 1; - } else if (local->txpower_type == PRISM2_TXPOWER_FIXED) { - rrq->value = local->txpower; - rrq->fixed = 1; - } else { - printk("SIOCGIWTXPOW - unknown txpower_type=%d\n", - local->txpower_type); - } - return 0; -#else /* RAW_TXPOWER_SETTING */ - return -EOPNOTSUPP; -#endif /* RAW_TXPOWER_SETTING */ -} - - -#ifndef PRISM2_NO_STATION_MODES - -/* HostScan request works with and without host_roaming mode. In addition, it - * does not break current association. However, it requires newer station - * firmware version (>= 1.3.1) than scan request. */ -static int prism2_request_hostscan(struct net_device *dev, - u8 *ssid, u8 ssid_len) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hfa384x_hostscan_request scan_req; - - iface = netdev_priv(dev); - local = iface->local; - - memset(&scan_req, 0, sizeof(scan_req)); - scan_req.channel_list = cpu_to_le16(local->channel_mask & - local->scan_channel_mask); - scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS); - if (ssid) { - if (ssid_len > 32) - return -EINVAL; - scan_req.target_ssid_len = cpu_to_le16(ssid_len); - memcpy(scan_req.target_ssid, ssid, ssid_len); - } - - if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req, - sizeof(scan_req))) { - printk(KERN_DEBUG "%s: HOSTSCAN failed\n", dev->name); - return -EINVAL; - } - return 0; -} - - -static int prism2_request_scan(struct net_device *dev) -{ - struct hostap_interface *iface; - local_info_t *local; - struct hfa384x_scan_request scan_req; - int ret = 0; - - iface = netdev_priv(dev); - local = iface->local; - - memset(&scan_req, 0, sizeof(scan_req)); - scan_req.channel_list = cpu_to_le16(local->channel_mask & - local->scan_channel_mask); - scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS); - - /* FIX: - * It seems to be enough to set roaming mode for a short moment to - * host-based and then setup scanrequest data and return the mode to - * firmware-based. - * - * Master mode would need to drop to Managed mode for a short while - * to make scanning work.. Or sweep through the different channels and - * use passive scan based on beacons. */ - - if (!local->host_roaming) - hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE, - HFA384X_ROAMING_HOST); - - if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req, - sizeof(scan_req))) { - printk(KERN_DEBUG "SCANREQUEST failed\n"); - ret = -EINVAL; - } - - if (!local->host_roaming) - hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE, - HFA384X_ROAMING_FIRMWARE); - - return 0; -} - -#else /* !PRISM2_NO_STATION_MODES */ - -static inline int prism2_request_hostscan(struct net_device *dev, - u8 *ssid, u8 ssid_len) -{ - return -EOPNOTSUPP; -} - - -static inline int prism2_request_scan(struct net_device *dev) -{ - return -EOPNOTSUPP; -} - -#endif /* !PRISM2_NO_STATION_MODES */ - - -static int prism2_ioctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - int ret; - u8 *ssid = NULL, ssid_len = 0; - struct iw_scan_req *req = (struct iw_scan_req *) extra; - - iface = netdev_priv(dev); - local = iface->local; - - if (data->length < sizeof(struct iw_scan_req)) - req = NULL; - - if (local->iw_mode == IW_MODE_MASTER) { - /* In master mode, we just return the results of our local - * tables, so we don't need to start anything... - * Jean II */ - data->length = 0; - return 0; - } - - if (!local->dev_enabled) - return -ENETDOWN; - - if (req && data->flags & IW_SCAN_THIS_ESSID) { - ssid = req->essid; - ssid_len = req->essid_len; - - if (ssid_len && - ((local->iw_mode != IW_MODE_INFRA && - local->iw_mode != IW_MODE_ADHOC) || - (local->sta_fw_ver < PRISM2_FW_VER(1,3,1)))) - return -EOPNOTSUPP; - } - - if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) - ret = prism2_request_hostscan(dev, ssid, ssid_len); - else - ret = prism2_request_scan(dev); - - if (ret == 0) - local->scan_timestamp = jiffies; - - /* Could inquire F101, F103 or wait for SIOCGIWSCAN and read RID */ - - return ret; -} - - -#ifndef PRISM2_NO_STATION_MODES -static char * __prism2_translate_scan(local_info_t *local, - struct hfa384x_hostscan_result *scan, - struct hostap_bss_info *bss, - char *current_ev, char *end_buf) -{ - int i, chan; - struct iw_event iwe; - char *current_val; - u16 capabilities; - u8 *pos; - u8 *ssid, *bssid; - size_t ssid_len; - char *buf; - - if (bss) { - ssid = bss->ssid; - ssid_len = bss->ssid_len; - bssid = bss->bssid; - } else { - ssid = scan->ssid; - ssid_len = le16_to_cpu(scan->ssid_len); - bssid = scan->bssid; - } - if (ssid_len > 32) - ssid_len = 32; - - /* First entry *MUST* be the AP MAC address */ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN); - /* FIX: - * I do not know how this is possible, but iwe_stream_add_event - * seems to re-order memcpy execution so that len is set only - * after copying.. Pre-setting len here "fixes" this, but real - * problems should be solved (after which these iwe.len - * settings could be removed from this function). */ - iwe.len = IW_EV_ADDR_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_ADDR_LEN); - - /* Other entries will be displayed in the order we give them */ - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.length = ssid_len; - iwe.u.data.flags = 1; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (bss) { - capabilities = bss->capab_info; - } else { - capabilities = le16_to_cpu(scan->capability); - } - if (capabilities & (WLAN_CAPABILITY_ESS | - WLAN_CAPABILITY_IBSS)) { - if (capabilities & WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - iwe.len = IW_EV_UINT_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_UINT_LEN); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - if (scan) { - chan = scan->chid; - } else if (bss) { - chan = bss->chan; - } else { - chan = 0; - } - - if (chan > 0) { - iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000; - iwe.u.freq.e = 1; - iwe.len = IW_EV_FREQ_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_FREQ_LEN); - } - - if (scan) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - if (local->last_scan_type == PRISM2_HOSTSCAN) { - iwe.u.qual.level = le16_to_cpu(scan->sl); - iwe.u.qual.noise = le16_to_cpu(scan->anl); - } else { - iwe.u.qual.level = - HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl)); - iwe.u.qual.noise = - HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl)); - } - iwe.len = IW_EV_QUAL_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_QUAL_LEN); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - if (capabilities & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); - - /* TODO: add SuppRates into BSS table */ - if (scan) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWRATE; - current_val = current_ev + IW_EV_LCP_LEN; - pos = scan->sup_rates; - for (i = 0; i < sizeof(scan->sup_rates); i++) { - if (pos[i] == 0) - break; - /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000); - current_val = iwe_stream_add_value( - current_ev, current_val, end_buf, &iwe, - IW_EV_PARAM_LEN); - } - /* Check if we added any event */ - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; - } - - /* TODO: add BeaconInt,resp_rate,atim into BSS table */ - buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL); - if (buf && scan) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval)); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate)); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); - - if (local->last_scan_type == PRISM2_HOSTSCAN && - (capabilities & WLAN_CAPABILITY_IBSS)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "atim=%d", le16_to_cpu(scan->atim)); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - } - } - kfree(buf); - - if (bss && bss->wpa_ie_len > 0 && bss->wpa_ie_len <= MAX_WPA_IE_LEN) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = bss->wpa_ie_len; - current_ev = iwe_stream_add_point( - current_ev, end_buf, &iwe, bss->wpa_ie); - } - - if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = bss->rsn_ie_len; - current_ev = iwe_stream_add_point( - current_ev, end_buf, &iwe, bss->rsn_ie); - } - - return current_ev; -} - - -/* Translate scan data returned from the card to a card independant - * format that the Wireless Tools will understand - Jean II */ -static inline int prism2_translate_scan(local_info_t *local, - char *buffer, int buflen) -{ - struct hfa384x_hostscan_result *scan; - int entry, hostscan; - char *current_ev = buffer; - char *end_buf = buffer + buflen; - struct list_head *ptr; - - spin_lock_bh(&local->lock); - - list_for_each(ptr, &local->bss_list) { - struct hostap_bss_info *bss; - bss = list_entry(ptr, struct hostap_bss_info, list); - bss->included = 0; - } - - hostscan = local->last_scan_type == PRISM2_HOSTSCAN; - for (entry = 0; entry < local->last_scan_results_count; entry++) { - int found = 0; - scan = &local->last_scan_results[entry]; - - /* Report every SSID if the AP is using multiple SSIDs. If no - * BSS record is found (e.g., when WPA mode is disabled), - * report the AP once. */ - list_for_each(ptr, &local->bss_list) { - struct hostap_bss_info *bss; - bss = list_entry(ptr, struct hostap_bss_info, list); - if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { - bss->included = 1; - current_ev = __prism2_translate_scan( - local, scan, bss, current_ev, end_buf); - found++; - } - } - if (!found) { - current_ev = __prism2_translate_scan( - local, scan, NULL, current_ev, end_buf); - } - /* Check if there is space for one more entry */ - if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { - /* Ask user space to try again with a bigger buffer */ - spin_unlock_bh(&local->lock); - return -E2BIG; - } - } - - /* Prism2 firmware has limits (32 at least in some versions) for number - * of BSSes in scan results. Extend this limit by using local BSS list. - */ - list_for_each(ptr, &local->bss_list) { - struct hostap_bss_info *bss; - bss = list_entry(ptr, struct hostap_bss_info, list); - if (bss->included) - continue; - current_ev = __prism2_translate_scan(local, NULL, bss, - current_ev, end_buf); - /* Check if there is space for one more entry */ - if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { - /* Ask user space to try again with a bigger buffer */ - spin_unlock_bh(&local->lock); - return -E2BIG; - } - } - - spin_unlock_bh(&local->lock); - - return current_ev - buffer; -} -#endif /* PRISM2_NO_STATION_MODES */ - - -static inline int prism2_ioctl_giwscan_sta(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ -#ifdef PRISM2_NO_STATION_MODES - return -EOPNOTSUPP; -#else /* PRISM2_NO_STATION_MODES */ - struct hostap_interface *iface; - local_info_t *local; - int res; - - iface = netdev_priv(dev); - local = iface->local; - - /* Wait until the scan is finished. We can probably do better - * than that - Jean II */ - if (local->scan_timestamp && - time_before(jiffies, local->scan_timestamp + 3 * HZ)) { - /* Important note : we don't want to block the caller - * until results are ready for various reasons. - * First, managing wait queues is complex and racy - * (there may be multiple simultaneous callers). - * Second, we grab some rtnetlink lock before comming - * here (in dev_ioctl()). - * Third, the caller can wait on the Wireless Event - * - Jean II */ - return -EAGAIN; - } - local->scan_timestamp = 0; - - res = prism2_translate_scan(local, extra, data->length); - - if (res >= 0) { - data->length = res; - return 0; - } else { - data->length = 0; - return res; - } -#endif /* PRISM2_NO_STATION_MODES */ -} - - -static int prism2_ioctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - int res; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->iw_mode == IW_MODE_MASTER) { - /* In MASTER mode, it doesn't make sense to go around - * scanning the frequencies and make the stations we serve - * wait when what the user is really interested about is the - * list of stations and access points we are talking to. - * So, just extract results from our cache... - * Jean II */ - - /* Translate to WE format */ - res = prism2_ap_translate_scan(dev, extra); - if (res >= 0) { - printk(KERN_DEBUG "Scan result translation succeeded " - "(length=%d)\n", res); - data->length = res; - return 0; - } else { - printk(KERN_DEBUG - "Scan result translation failed (res=%d)\n", - res); - data->length = 0; - return res; - } - } else { - /* Station mode */ - return prism2_ioctl_giwscan_sta(dev, info, data, extra); - } -} - - -static const struct iw_priv_args prism2_priv[] = { - { PRISM2_IOCTL_MONITOR, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" }, - { PRISM2_IOCTL_READMIF, - IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" }, - { PRISM2_IOCTL_WRITEMIF, - IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, 0, "writemif" }, - { PRISM2_IOCTL_RESET, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "reset" }, - { PRISM2_IOCTL_INQUIRE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inquire" }, - { PRISM2_IOCTL_SET_RID_WORD, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_rid_word" }, - { PRISM2_IOCTL_MACCMD, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maccmd" }, - { PRISM2_IOCTL_WDS_ADD, - IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_add" }, - { PRISM2_IOCTL_WDS_DEL, - IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_del" }, - { PRISM2_IOCTL_ADDMAC, - IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addmac" }, - { PRISM2_IOCTL_DELMAC, - IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "delmac" }, - { PRISM2_IOCTL_KICKMAC, - IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "kickmac" }, - /* --- raw access to sub-ioctls --- */ - { PRISM2_IOCTL_PRISM2_PARAM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "prism2_param" }, - { PRISM2_IOCTL_GET_PRISM2_PARAM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprism2_param" }, - /* --- sub-ioctls handlers --- */ - { PRISM2_IOCTL_PRISM2_PARAM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" }, - { PRISM2_IOCTL_GET_PRISM2_PARAM, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" }, - /* --- sub-ioctls definitions --- */ - { PRISM2_PARAM_TXRATECTRL, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txratectrl" }, - { PRISM2_PARAM_TXRATECTRL, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettxratectrl" }, - { PRISM2_PARAM_BEACON_INT, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beacon_int" }, - { PRISM2_PARAM_BEACON_INT, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbeacon_int" }, -#ifndef PRISM2_NO_STATION_MODES - { PRISM2_PARAM_PSEUDO_IBSS, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "pseudo_ibss" }, - { PRISM2_PARAM_PSEUDO_IBSS, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpseudo_ibss" }, -#endif /* PRISM2_NO_STATION_MODES */ - { PRISM2_PARAM_ALC, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "alc" }, - { PRISM2_PARAM_ALC, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getalc" }, - { PRISM2_PARAM_DUMP, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dump" }, - { PRISM2_PARAM_DUMP, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdump" }, - { PRISM2_PARAM_OTHER_AP_POLICY, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "other_ap_policy" }, - { PRISM2_PARAM_OTHER_AP_POLICY, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getother_ap_pol" }, - { PRISM2_PARAM_AP_MAX_INACTIVITY, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_inactivity" }, - { PRISM2_PARAM_AP_MAX_INACTIVITY, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_inactivi" }, - { PRISM2_PARAM_AP_BRIDGE_PACKETS, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bridge_packets" }, - { PRISM2_PARAM_AP_BRIDGE_PACKETS, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbridge_packe" }, - { PRISM2_PARAM_DTIM_PERIOD, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dtim_period" }, - { PRISM2_PARAM_DTIM_PERIOD, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdtim_period" }, - { PRISM2_PARAM_AP_NULLFUNC_ACK, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "nullfunc_ack" }, - { PRISM2_PARAM_AP_NULLFUNC_ACK, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getnullfunc_ack" }, - { PRISM2_PARAM_MAX_WDS, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_wds" }, - { PRISM2_PARAM_MAX_WDS, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_wds" }, - { PRISM2_PARAM_AP_AUTOM_AP_WDS, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "autom_ap_wds" }, - { PRISM2_PARAM_AP_AUTOM_AP_WDS, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getautom_ap_wds" }, - { PRISM2_PARAM_AP_AUTH_ALGS, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_auth_algs" }, - { PRISM2_PARAM_AP_AUTH_ALGS, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_auth_algs" }, - { PRISM2_PARAM_MONITOR_ALLOW_FCSERR, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "allow_fcserr" }, - { PRISM2_PARAM_MONITOR_ALLOW_FCSERR, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getallow_fcserr" }, - { PRISM2_PARAM_HOST_ENCRYPT, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_encrypt" }, - { PRISM2_PARAM_HOST_ENCRYPT, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_encrypt" }, - { PRISM2_PARAM_HOST_DECRYPT, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_decrypt" }, - { PRISM2_PARAM_HOST_DECRYPT, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_decrypt" }, - { PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "busmaster_rx" }, - { PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbusmaster_rx" }, - { PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "busmaster_tx" }, - { PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbusmaster_tx" }, -#ifndef PRISM2_NO_STATION_MODES - { PRISM2_PARAM_HOST_ROAMING, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_roaming" }, - { PRISM2_PARAM_HOST_ROAMING, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_roaming" }, -#endif /* PRISM2_NO_STATION_MODES */ - { PRISM2_PARAM_BCRX_STA_KEY, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bcrx_sta_key" }, - { PRISM2_PARAM_BCRX_STA_KEY, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbcrx_sta_key" }, - { PRISM2_PARAM_IEEE_802_1X, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ieee_802_1x" }, - { PRISM2_PARAM_IEEE_802_1X, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getieee_802_1x" }, - { PRISM2_PARAM_ANTSEL_TX, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_tx" }, - { PRISM2_PARAM_ANTSEL_TX, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_tx" }, - { PRISM2_PARAM_ANTSEL_RX, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_rx" }, - { PRISM2_PARAM_ANTSEL_RX, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_rx" }, - { PRISM2_PARAM_MONITOR_TYPE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor_type" }, - { PRISM2_PARAM_MONITOR_TYPE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmonitor_type" }, - { PRISM2_PARAM_WDS_TYPE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wds_type" }, - { PRISM2_PARAM_WDS_TYPE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwds_type" }, - { PRISM2_PARAM_HOSTSCAN, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostscan" }, - { PRISM2_PARAM_HOSTSCAN, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostscan" }, - { PRISM2_PARAM_AP_SCAN, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_scan" }, - { PRISM2_PARAM_AP_SCAN, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_scan" }, - { PRISM2_PARAM_ENH_SEC, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "enh_sec" }, - { PRISM2_PARAM_ENH_SEC, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getenh_sec" }, -#ifdef PRISM2_IO_DEBUG - { PRISM2_PARAM_IO_DEBUG, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "io_debug" }, - { PRISM2_PARAM_IO_DEBUG, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getio_debug" }, -#endif /* PRISM2_IO_DEBUG */ - { PRISM2_PARAM_BASIC_RATES, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "basic_rates" }, - { PRISM2_PARAM_BASIC_RATES, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbasic_rates" }, - { PRISM2_PARAM_OPER_RATES, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oper_rates" }, - { PRISM2_PARAM_OPER_RATES, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getoper_rates" }, - { PRISM2_PARAM_HOSTAPD, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd" }, - { PRISM2_PARAM_HOSTAPD, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd" }, - { PRISM2_PARAM_HOSTAPD_STA, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd_sta" }, - { PRISM2_PARAM_HOSTAPD_STA, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd_sta" }, - { PRISM2_PARAM_WPA, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wpa" }, - { PRISM2_PARAM_WPA, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwpa" }, - { PRISM2_PARAM_PRIVACY_INVOKED, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "privacy_invoked" }, - { PRISM2_PARAM_PRIVACY_INVOKED, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprivacy_invo" }, - { PRISM2_PARAM_TKIP_COUNTERMEASURES, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "tkip_countermea" }, - { PRISM2_PARAM_TKIP_COUNTERMEASURES, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettkip_counter" }, - { PRISM2_PARAM_DROP_UNENCRYPTED, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypte" }, - { PRISM2_PARAM_DROP_UNENCRYPTED, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdrop_unencry" }, - { PRISM2_PARAM_SCAN_CHANNEL_MASK, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "scan_channels" }, - { PRISM2_PARAM_SCAN_CHANNEL_MASK, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getscan_channel" }, -}; - - -static int prism2_ioctl_priv_inquire(struct net_device *dev, int *i) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->cmd(dev, HFA384X_CMDCODE_INQUIRE, *i, NULL, NULL)) - return -EOPNOTSUPP; - - return 0; -} - - -static int prism2_ioctl_priv_prism2_param(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - int *i = (int *) extra; - int param = *i; - int value = *(i + 1); - int ret = 0; - u16 val; - - iface = netdev_priv(dev); - local = iface->local; - - switch (param) { - case PRISM2_PARAM_TXRATECTRL: - local->fw_tx_rate_control = value; - break; - - case PRISM2_PARAM_BEACON_INT: - if (hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, value) || - local->func->reset_port(dev)) - ret = -EINVAL; - else - local->beacon_int = value; - break; - -#ifndef PRISM2_NO_STATION_MODES - case PRISM2_PARAM_PSEUDO_IBSS: - if (value == local->pseudo_adhoc) - break; - - if (value != 0 && value != 1) { - ret = -EINVAL; - break; - } - - printk(KERN_DEBUG "prism2: %s: pseudo IBSS change %d -> %d\n", - dev->name, local->pseudo_adhoc, value); - local->pseudo_adhoc = value; - if (local->iw_mode != IW_MODE_ADHOC) - break; - - if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, - hostap_get_porttype(local))) { - ret = -EOPNOTSUPP; - break; - } - - if (local->func->reset_port(dev)) - ret = -EINVAL; - break; -#endif /* PRISM2_NO_STATION_MODES */ - - case PRISM2_PARAM_ALC: - printk(KERN_DEBUG "%s: %s ALC\n", dev->name, - value == 0 ? "Disabling" : "Enabling"); - val = HFA384X_TEST_CFG_BIT_ALC; - local->func->cmd(dev, HFA384X_CMDCODE_TEST | - (HFA384X_TEST_CFG_BITS << 8), - value == 0 ? 0 : 1, &val, NULL); - break; - - case PRISM2_PARAM_DUMP: - local->frame_dump = value; - break; - - case PRISM2_PARAM_OTHER_AP_POLICY: - if (value < 0 || value > 3) { - ret = -EINVAL; - break; - } - if (local->ap != NULL) - local->ap->ap_policy = value; - break; - - case PRISM2_PARAM_AP_MAX_INACTIVITY: - if (value < 0 || value > 7 * 24 * 60 * 60) { - ret = -EINVAL; - break; - } - if (local->ap != NULL) - local->ap->max_inactivity = value * HZ; - break; - - case PRISM2_PARAM_AP_BRIDGE_PACKETS: - if (local->ap != NULL) - local->ap->bridge_packets = value; - break; - - case PRISM2_PARAM_DTIM_PERIOD: - if (value < 0 || value > 65535) { - ret = -EINVAL; - break; - } - if (hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, value) - || local->func->reset_port(dev)) - ret = -EINVAL; - else - local->dtim_period = value; - break; - - case PRISM2_PARAM_AP_NULLFUNC_ACK: - if (local->ap != NULL) - local->ap->nullfunc_ack = value; - break; - - case PRISM2_PARAM_MAX_WDS: - local->wds_max_connections = value; - break; - - case PRISM2_PARAM_AP_AUTOM_AP_WDS: - if (local->ap != NULL) { - if (!local->ap->autom_ap_wds && value) { - /* add WDS link to all APs in STA table */ - hostap_add_wds_links(local); - } - local->ap->autom_ap_wds = value; - } - break; - - case PRISM2_PARAM_AP_AUTH_ALGS: - local->auth_algs = value; - if (hostap_set_auth_algs(local)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_MONITOR_ALLOW_FCSERR: - local->monitor_allow_fcserr = value; - break; - - case PRISM2_PARAM_HOST_ENCRYPT: - local->host_encrypt = value; - if (hostap_set_encryption(local) || - local->func->reset_port(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_HOST_DECRYPT: - local->host_decrypt = value; - if (hostap_set_encryption(local) || - local->func->reset_port(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX: - local->bus_master_threshold_rx = value; - break; - - case PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX: - local->bus_master_threshold_tx = value; - break; - -#ifndef PRISM2_NO_STATION_MODES - case PRISM2_PARAM_HOST_ROAMING: - if (value < 0 || value > 2) { - ret = -EINVAL; - break; - } - local->host_roaming = value; - if (hostap_set_roaming(local) || local->func->reset_port(dev)) - ret = -EINVAL; - break; -#endif /* PRISM2_NO_STATION_MODES */ - - case PRISM2_PARAM_BCRX_STA_KEY: - local->bcrx_sta_key = value; - break; - - case PRISM2_PARAM_IEEE_802_1X: - local->ieee_802_1x = value; - break; - - case PRISM2_PARAM_ANTSEL_TX: - if (value < 0 || value > HOSTAP_ANTSEL_HIGH) { - ret = -EINVAL; - break; - } - local->antsel_tx = value; - hostap_set_antsel(local); - break; - - case PRISM2_PARAM_ANTSEL_RX: - if (value < 0 || value > HOSTAP_ANTSEL_HIGH) { - ret = -EINVAL; - break; - } - local->antsel_rx = value; - hostap_set_antsel(local); - break; - - case PRISM2_PARAM_MONITOR_TYPE: - if (value != PRISM2_MONITOR_80211 && - value != PRISM2_MONITOR_CAPHDR && - value != PRISM2_MONITOR_PRISM) { - ret = -EINVAL; - break; - } - local->monitor_type = value; - if (local->iw_mode == IW_MODE_MONITOR) - hostap_monitor_set_type(local); - break; - - case PRISM2_PARAM_WDS_TYPE: - local->wds_type = value; - break; - - case PRISM2_PARAM_HOSTSCAN: - { - struct hfa384x_hostscan_request scan_req; - u16 rate; - - memset(&scan_req, 0, sizeof(scan_req)); - scan_req.channel_list = __constant_cpu_to_le16(0x3fff); - switch (value) { - case 1: rate = HFA384X_RATES_1MBPS; break; - case 2: rate = HFA384X_RATES_2MBPS; break; - case 3: rate = HFA384X_RATES_5MBPS; break; - case 4: rate = HFA384X_RATES_11MBPS; break; - default: rate = HFA384X_RATES_1MBPS; break; - } - scan_req.txrate = cpu_to_le16(rate); - /* leave SSID empty to accept all SSIDs */ - - if (local->iw_mode == IW_MODE_MASTER) { - if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, - HFA384X_PORTTYPE_BSS) || - local->func->reset_port(dev)) - printk(KERN_DEBUG "Leaving Host AP mode " - "for HostScan failed\n"); - } - - if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req, - sizeof(scan_req))) { - printk(KERN_DEBUG "HOSTSCAN failed\n"); - ret = -EINVAL; - } - if (local->iw_mode == IW_MODE_MASTER) { - wait_queue_t __wait; - init_waitqueue_entry(&__wait, current); - add_wait_queue(&local->hostscan_wq, &__wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - if (signal_pending(current)) - ret = -EINTR; - set_current_state(TASK_RUNNING); - remove_wait_queue(&local->hostscan_wq, &__wait); - - if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, - HFA384X_PORTTYPE_HOSTAP) || - local->func->reset_port(dev)) - printk(KERN_DEBUG "Returning to Host AP mode " - "after HostScan failed\n"); - } - break; - } - - case PRISM2_PARAM_AP_SCAN: - local->passive_scan_interval = value; - if (timer_pending(&local->passive_scan_timer)) - del_timer(&local->passive_scan_timer); - if (value > 0) { - local->passive_scan_timer.expires = jiffies + - local->passive_scan_interval * HZ; - add_timer(&local->passive_scan_timer); - } - break; - - case PRISM2_PARAM_ENH_SEC: - if (value < 0 || value > 3) { - ret = -EINVAL; - break; - } - local->enh_sec = value; - if (hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY, - local->enh_sec) || - local->func->reset_port(dev)) { - printk(KERN_INFO "%s: cnfEnhSecurity requires STA f/w " - "1.6.3 or newer\n", dev->name); - ret = -EOPNOTSUPP; - } - break; - -#ifdef PRISM2_IO_DEBUG - case PRISM2_PARAM_IO_DEBUG: - local->io_debug_enabled = value; - break; -#endif /* PRISM2_IO_DEBUG */ - - case PRISM2_PARAM_BASIC_RATES: - if ((value & local->tx_rate_control) != value || value == 0) { - printk(KERN_INFO "%s: invalid basic rate set - basic " - "rates must be in supported rate set\n", - dev->name); - ret = -EINVAL; - break; - } - local->basic_rates = value; - if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES, - local->basic_rates) || - local->func->reset_port(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_OPER_RATES: - local->tx_rate_control = value; - if (hostap_set_rate(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_HOSTAPD: - ret = hostap_set_hostapd(local, value, 1); - break; - - case PRISM2_PARAM_HOSTAPD_STA: - ret = hostap_set_hostapd_sta(local, value, 1); - break; - - case PRISM2_PARAM_WPA: - local->wpa = value; - if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0)) - ret = -EOPNOTSUPP; - else if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, - value ? 1 : 0)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_PRIVACY_INVOKED: - local->privacy_invoked = value; - if (hostap_set_encryption(local) || - local->func->reset_port(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_TKIP_COUNTERMEASURES: - local->tkip_countermeasures = value; - break; - - case PRISM2_PARAM_DROP_UNENCRYPTED: - local->drop_unencrypted = value; - break; - - case PRISM2_PARAM_SCAN_CHANNEL_MASK: - local->scan_channel_mask = value; - break; - - default: - printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n", - dev->name, param); - ret = -EOPNOTSUPP; - break; - } - - return ret; -} - - -static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - int *param = (int *) extra; - int ret = 0; - - iface = netdev_priv(dev); - local = iface->local; - - switch (*param) { - case PRISM2_PARAM_TXRATECTRL: - *param = local->fw_tx_rate_control; - break; - - case PRISM2_PARAM_BEACON_INT: - *param = local->beacon_int; - break; - - case PRISM2_PARAM_PSEUDO_IBSS: - *param = local->pseudo_adhoc; - break; - - case PRISM2_PARAM_ALC: - ret = -EOPNOTSUPP; /* FIX */ - break; - - case PRISM2_PARAM_DUMP: - *param = local->frame_dump; - break; - - case PRISM2_PARAM_OTHER_AP_POLICY: - if (local->ap != NULL) - *param = local->ap->ap_policy; - else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_AP_MAX_INACTIVITY: - if (local->ap != NULL) - *param = local->ap->max_inactivity / HZ; - else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_AP_BRIDGE_PACKETS: - if (local->ap != NULL) - *param = local->ap->bridge_packets; - else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_DTIM_PERIOD: - *param = local->dtim_period; - break; - - case PRISM2_PARAM_AP_NULLFUNC_ACK: - if (local->ap != NULL) - *param = local->ap->nullfunc_ack; - else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_MAX_WDS: - *param = local->wds_max_connections; - break; - - case PRISM2_PARAM_AP_AUTOM_AP_WDS: - if (local->ap != NULL) - *param = local->ap->autom_ap_wds; - else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_AP_AUTH_ALGS: - *param = local->auth_algs; - break; - - case PRISM2_PARAM_MONITOR_ALLOW_FCSERR: - *param = local->monitor_allow_fcserr; - break; - - case PRISM2_PARAM_HOST_ENCRYPT: - *param = local->host_encrypt; - break; - - case PRISM2_PARAM_HOST_DECRYPT: - *param = local->host_decrypt; - break; - - case PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX: - *param = local->bus_master_threshold_rx; - break; - - case PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX: - *param = local->bus_master_threshold_tx; - break; - - case PRISM2_PARAM_HOST_ROAMING: - *param = local->host_roaming; - break; - - case PRISM2_PARAM_BCRX_STA_KEY: - *param = local->bcrx_sta_key; - break; - - case PRISM2_PARAM_IEEE_802_1X: - *param = local->ieee_802_1x; - break; - - case PRISM2_PARAM_ANTSEL_TX: - *param = local->antsel_tx; - break; - - case PRISM2_PARAM_ANTSEL_RX: - *param = local->antsel_rx; - break; - - case PRISM2_PARAM_MONITOR_TYPE: - *param = local->monitor_type; - break; - - case PRISM2_PARAM_WDS_TYPE: - *param = local->wds_type; - break; - - case PRISM2_PARAM_HOSTSCAN: - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_AP_SCAN: - *param = local->passive_scan_interval; - break; - - case PRISM2_PARAM_ENH_SEC: - *param = local->enh_sec; - break; - -#ifdef PRISM2_IO_DEBUG - case PRISM2_PARAM_IO_DEBUG: - *param = local->io_debug_enabled; - break; -#endif /* PRISM2_IO_DEBUG */ - - case PRISM2_PARAM_BASIC_RATES: - *param = local->basic_rates; - break; - - case PRISM2_PARAM_OPER_RATES: - *param = local->tx_rate_control; - break; - - case PRISM2_PARAM_HOSTAPD: - *param = local->hostapd; - break; - - case PRISM2_PARAM_HOSTAPD_STA: - *param = local->hostapd_sta; - break; - - case PRISM2_PARAM_WPA: - if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0)) - ret = -EOPNOTSUPP; - *param = local->wpa; - break; - - case PRISM2_PARAM_PRIVACY_INVOKED: - *param = local->privacy_invoked; - break; - - case PRISM2_PARAM_TKIP_COUNTERMEASURES: - *param = local->tkip_countermeasures; - break; - - case PRISM2_PARAM_DROP_UNENCRYPTED: - *param = local->drop_unencrypted; - break; - - case PRISM2_PARAM_SCAN_CHANNEL_MASK: - *param = local->scan_channel_mask; - break; - - default: - printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n", - dev->name, *param); - ret = -EOPNOTSUPP; - break; - } - - return ret; -} - - -static int prism2_ioctl_priv_readmif(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 resp0; - - iface = netdev_priv(dev); - local = iface->local; - - if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF, *extra, NULL, - &resp0)) - return -EOPNOTSUPP; - else - *extra = resp0; - - return 0; -} - - -static int prism2_ioctl_priv_writemif(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct hostap_interface *iface; - local_info_t *local; - u16 cr, val; - - iface = netdev_priv(dev); - local = iface->local; - - cr = *extra; - val = *(extra + 1); - if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, cr, &val, NULL)) - return -EOPNOTSUPP; - - return 0; -} - - -static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i) -{ - struct hostap_interface *iface; - local_info_t *local; - int ret = 0; - u32 mode; - - iface = netdev_priv(dev); - local = iface->local; - - printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor " - "- update software to use iwconfig mode monitor\n", - dev->name, current->pid, current->comm); - - /* Backward compatibility code - this can be removed at some point */ - - if (*i == 0) { - /* Disable monitor mode - old mode was not saved, so go to - * Master mode */ - mode = IW_MODE_MASTER; - ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL); - } else if (*i == 1) { - /* netlink socket mode is not supported anymore since it did - * not separate different devices from each other and was not - * best method for delivering large amount of packets to - * user space */ - ret = -EOPNOTSUPP; - } else if (*i == 2 || *i == 3) { - switch (*i) { - case 2: - local->monitor_type = PRISM2_MONITOR_80211; - break; - case 3: - local->monitor_type = PRISM2_MONITOR_PRISM; - break; - } - mode = IW_MODE_MONITOR; - ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL); - hostap_monitor_mode_enable(local); - } else - ret = -EINVAL; - - return ret; -} - - -static int prism2_ioctl_priv_reset(struct net_device *dev, int *i) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - printk(KERN_DEBUG "%s: manual reset request(%d)\n", dev->name, *i); - switch (*i) { - case 0: - /* Disable and enable card */ - local->func->hw_shutdown(dev, 1); - local->func->hw_config(dev, 0); - break; - - case 1: - /* COR sreset */ - local->func->hw_reset(dev); - break; - - case 2: - /* Disable and enable port 0 */ - local->func->reset_port(dev); - break; - - case 3: - prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING); - if (local->func->cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL, - NULL)) - return -EINVAL; - break; - - case 4: - if (local->func->cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL, - NULL)) - return -EINVAL; - break; - - default: - printk(KERN_DEBUG "Unknown reset request %d\n", *i); - return -EOPNOTSUPP; - } - - return 0; -} - - -static int prism2_ioctl_priv_set_rid_word(struct net_device *dev, int *i) -{ - int rid = *i; - int value = *(i + 1); - - printk(KERN_DEBUG "%s: Set RID[0x%X] = %d\n", dev->name, rid, value); - - if (hostap_set_word(dev, rid, value)) - return -EINVAL; - - return 0; -} - - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -static int ap_mac_cmd_ioctl(local_info_t *local, int *cmd) -{ - int ret = 0; - - switch (*cmd) { - case AP_MAC_CMD_POLICY_OPEN: - local->ap->mac_restrictions.policy = MAC_POLICY_OPEN; - break; - case AP_MAC_CMD_POLICY_ALLOW: - local->ap->mac_restrictions.policy = MAC_POLICY_ALLOW; - break; - case AP_MAC_CMD_POLICY_DENY: - local->ap->mac_restrictions.policy = MAC_POLICY_DENY; - break; - case AP_MAC_CMD_FLUSH: - ap_control_flush_macs(&local->ap->mac_restrictions); - break; - case AP_MAC_CMD_KICKALL: - ap_control_kickall(local->ap); - hostap_deauth_all_stas(local->dev, local->ap, 0); - break; - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - -#ifdef PRISM2_DOWNLOAD_SUPPORT -static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p) -{ - struct prism2_download_param *param; - int ret = 0; - - if (p->length < sizeof(struct prism2_download_param) || - p->length > 1024 || !p->pointer) - return -EINVAL; - - param = (struct prism2_download_param *) - kmalloc(p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - if (p->length < sizeof(struct prism2_download_param) + - param->num_areas * sizeof(struct prism2_download_area)) { - ret = -EINVAL; - goto out; - } - - ret = local->func->download(local, param); - - out: - if (param != NULL) - kfree(param); - - return ret; -} -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - - -static int prism2_set_genericelement(struct net_device *dev, u8 *elem, - size_t len) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - u8 *buf; - - /* - * Add 16-bit length in the beginning of the buffer because Prism2 RID - * includes it. - */ - buf = kmalloc(len + 2, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - *((u16 *) buf) = cpu_to_le16(len); - memcpy(buf + 2, elem, len); - - kfree(local->generic_elem); - local->generic_elem = buf; - local->generic_elem_len = len + 2; - - return local->func->set_rid(local->dev, HFA384X_RID_GENERICELEMENT, - buf, len + 2); -} - - -static int prism2_ioctl_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - /* - * Host AP driver does not use these parameters and allows - * wpa_supplicant to control them internally. - */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - local->tkip_countermeasures = data->value; - break; - case IW_AUTH_DROP_UNENCRYPTED: - local->drop_unencrypted = data->value; - break; - case IW_AUTH_80211_AUTH_ALG: - local->auth_algs = data->value; - break; - case IW_AUTH_WPA_ENABLED: - if (data->value == 0) { - local->wpa = 0; - if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0)) - break; - prism2_set_genericelement(dev, "", 0); - local->host_roaming = 0; - local->privacy_invoked = 0; - if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, - 0) || - hostap_set_roaming(local) || - hostap_set_encryption(local) || - local->func->reset_port(dev)) - return -EINVAL; - break; - } - if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0)) - return -EOPNOTSUPP; - local->host_roaming = 2; - local->privacy_invoked = 1; - local->wpa = 1; - if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1) || - hostap_set_roaming(local) || - hostap_set_encryption(local) || - local->func->reset_port(dev)) - return -EINVAL; - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - local->ieee_802_1x = data->value; - break; - case IW_AUTH_PRIVACY_INVOKED: - local->privacy_invoked = data->value; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - - -static int prism2_ioctl_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - /* - * Host AP driver does not use these parameters and allows - * wpa_supplicant to control them internally. - */ - return -EOPNOTSUPP; - case IW_AUTH_TKIP_COUNTERMEASURES: - data->value = local->tkip_countermeasures; - break; - case IW_AUTH_DROP_UNENCRYPTED: - data->value = local->drop_unencrypted; - break; - case IW_AUTH_80211_AUTH_ALG: - data->value = local->auth_algs; - break; - case IW_AUTH_WPA_ENABLED: - data->value = local->wpa; - break; - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - data->value = local->ieee_802_1x; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - - -static int prism2_ioctl_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; - int i, ret = 0; - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - void *sta_ptr; - u8 *addr; - const char *alg, *module; - - i = erq->flags & IW_ENCODE_INDEX; - if (i > WEP_KEYS) - return -EINVAL; - if (i < 1 || i > WEP_KEYS) - i = local->tx_keyidx; - else - i--; - if (i < 0 || i >= WEP_KEYS) - return -EINVAL; - - addr = ext->addr.sa_data; - if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && - addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) { - sta_ptr = NULL; - crypt = &local->crypt[i]; - } else { - if (i != 0) - return -EINVAL; - sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt); - if (sta_ptr == NULL) { - if (local->iw_mode == IW_MODE_INFRA) { - /* - * TODO: add STA entry for the current AP so - * that unicast key can be used. For now, this - * is emulated by using default key idx 0. - */ - i = 0; - crypt = &local->crypt[i]; - } else - return -EINVAL; - } - } - - if ((erq->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - if (*crypt) - prism2_crypt_delayed_deinit(local, crypt); - goto done; - } - - switch (ext->alg) { - case IW_ENCODE_ALG_WEP: - alg = "WEP"; - module = "ieee80211_crypt_wep"; - break; - case IW_ENCODE_ALG_TKIP: - alg = "TKIP"; - module = "ieee80211_crypt_tkip"; - break; - case IW_ENCODE_ALG_CCMP: - alg = "CCMP"; - module = "ieee80211_crypt_ccmp"; - break; - default: - printk(KERN_DEBUG "%s: unsupported algorithm %d\n", - local->dev->name, ext->alg); - ret = -EOPNOTSUPP; - goto done; - } - - ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) { - request_module(module); - ops = ieee80211_get_crypto_ops(alg); - } - if (ops == NULL) { - printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", - local->dev->name, alg); - ret = -EOPNOTSUPP; - goto done; - } - - if (sta_ptr || ext->alg != IW_ENCODE_ALG_WEP) { - /* - * Per station encryption and other than WEP algorithms - * require host-based encryption, so force them on - * automatically. - */ - local->host_decrypt = local->host_encrypt = 1; - } - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - prism2_crypt_delayed_deinit(local, crypt); - - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(struct ieee80211_crypt_data), - GFP_KERNEL); - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); - new_crypt->ops = ops; - new_crypt->priv = new_crypt->ops->init(i); - if (new_crypt->priv == NULL) { - kfree(new_crypt); - ret = -EINVAL; - goto done; - } - - *crypt = new_crypt; - } - - /* - * TODO: if ext_flags does not have IW_ENCODE_EXT_RX_SEQ_VALID, the - * existing seq# should not be changed. - * TODO: if ext_flags has IW_ENCODE_EXT_TX_SEQ_VALID, next TX seq# - * should be changed to something else than zero. - */ - if ((!(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) || ext->key_len > 0) - && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, - (*crypt)->priv) < 0) { - printk(KERN_DEBUG "%s: key setting failed\n", - local->dev->name); - ret = -EINVAL; - goto done; - } - - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - if (!sta_ptr) - local->tx_keyidx = i; - else if (i) { - ret = -EINVAL; - goto done; - } - } - - - if (sta_ptr == NULL && ext->key_len > 0) { - int first = 1, j; - for (j = 0; j < WEP_KEYS; j++) { - if (j != i && local->crypt[j]) { - first = 0; - break; - } - } - if (first) - local->tx_keyidx = i; - } - - done: - if (sta_ptr) - hostap_handle_sta_release(sta_ptr); - - local->open_wep = erq->flags & IW_ENCODE_OPEN; - - /* - * Do not reset port0 if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. Prism2 documentation seem to require port reset - * after WEP configuration. However, keys are apparently changed at - * least in Managed mode. - */ - if (ret == 0 && - (hostap_set_encryption(local) || - (local->iw_mode != IW_MODE_INFRA && - local->func->reset_port(local->dev)))) - ret = -EINVAL; - - return ret; -} - - -static int prism2_ioctl_giwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - struct ieee80211_crypt_data **crypt; - void *sta_ptr; - int max_key_len, i; - struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; - u8 *addr; - - max_key_len = erq->length - sizeof(*ext); - if (max_key_len < 0) - return -EINVAL; - - i = erq->flags & IW_ENCODE_INDEX; - if (i < 1 || i > WEP_KEYS) - i = local->tx_keyidx; - else - i--; - - addr = ext->addr.sa_data; - if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && - addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) { - sta_ptr = NULL; - crypt = &local->crypt[i]; - } else { - i = 0; - sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt); - if (sta_ptr == NULL) - return -EINVAL; - } - erq->flags = i + 1; - memset(ext, 0, sizeof(*ext)); - - if (*crypt == NULL || (*crypt)->ops == NULL) { - ext->alg = IW_ENCODE_ALG_NONE; - ext->key_len = 0; - erq->flags |= IW_ENCODE_DISABLED; - } else { - if (strcmp((*crypt)->ops->name, "WEP") == 0) - ext->alg = IW_ENCODE_ALG_WEP; - else if (strcmp((*crypt)->ops->name, "TKIP") == 0) - ext->alg = IW_ENCODE_ALG_TKIP; - else if (strcmp((*crypt)->ops->name, "CCMP") == 0) - ext->alg = IW_ENCODE_ALG_CCMP; - else - return -EINVAL; - - if ((*crypt)->ops->get_key) { - ext->key_len = - (*crypt)->ops->get_key(ext->key, - max_key_len, - ext->tx_seq, - (*crypt)->priv); - if (ext->key_len && - (ext->alg == IW_ENCODE_ALG_TKIP || - ext->alg == IW_ENCODE_ALG_CCMP)) - ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; - } - } - - if (sta_ptr) - hostap_handle_sta_release(sta_ptr); - - return 0; -} - - -static int prism2_ioctl_set_encryption(local_info_t *local, - struct prism2_hostapd_param *param, - int param_len) -{ - int ret = 0; - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - void *sta_ptr; - - param->u.crypt.err = 0; - param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0'; - - if (param_len != - (int) ((char *) param->u.crypt.key - (char *) param) + - param->u.crypt.key_len) - return -EINVAL; - - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - if (param->u.crypt.idx >= WEP_KEYS) - return -EINVAL; - sta_ptr = NULL; - crypt = &local->crypt[param->u.crypt.idx]; - } else { - if (param->u.crypt.idx) - return -EINVAL; - sta_ptr = ap_crypt_get_ptrs( - local->ap, param->sta_addr, - (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_PERMANENT), - &crypt); - - if (sta_ptr == NULL) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - return -EINVAL; - } - } - - if (strcmp(param->u.crypt.alg, "none") == 0) { - if (crypt) - prism2_crypt_delayed_deinit(local, crypt); - goto done; - } - - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { - request_module("ieee80211_crypt_wep"); - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { - request_module("ieee80211_crypt_tkip"); - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { - request_module("ieee80211_crypt_ccmp"); - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - } - if (ops == NULL) { - printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", - local->dev->name, param->u.crypt.alg); - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG; - ret = -EINVAL; - goto done; - } - - /* station based encryption and other than WEP algorithms require - * host-based encryption, so force them on automatically */ - local->host_decrypt = local->host_encrypt = 1; - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - prism2_crypt_delayed_deinit(local, crypt); - - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(struct ieee80211_crypt_data), - GFP_KERNEL); - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); - new_crypt->ops = ops; - new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); - if (new_crypt->priv == NULL) { - kfree(new_crypt); - param->u.crypt.err = - HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED; - ret = -EINVAL; - goto done; - } - - *crypt = new_crypt; - } - - if ((!(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) || - param->u.crypt.key_len > 0) && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(param->u.crypt.key, - param->u.crypt.key_len, param->u.crypt.seq, - (*crypt)->priv) < 0) { - printk(KERN_DEBUG "%s: key setting failed\n", - local->dev->name); - param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; - ret = -EINVAL; - goto done; - } - - if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { - if (!sta_ptr) - local->tx_keyidx = param->u.crypt.idx; - else if (param->u.crypt.idx) { - printk(KERN_DEBUG "%s: TX key idx setting failed\n", - local->dev->name); - param->u.crypt.err = - HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED; - ret = -EINVAL; - goto done; - } - } - - done: - if (sta_ptr) - hostap_handle_sta_release(sta_ptr); - - /* Do not reset port0 if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. Prism2 documentation seem to require port reset - * after WEP configuration. However, keys are apparently changed at - * least in Managed mode. */ - if (ret == 0 && - (hostap_set_encryption(local) || - (local->iw_mode != IW_MODE_INFRA && - local->func->reset_port(local->dev)))) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_CARD_CONF_FAILED; - return -EINVAL; - } - - return ret; -} - - -static int prism2_ioctl_get_encryption(local_info_t *local, - struct prism2_hostapd_param *param, - int param_len) -{ - struct ieee80211_crypt_data **crypt; - void *sta_ptr; - int max_key_len; - - param->u.crypt.err = 0; - - max_key_len = param_len - - (int) ((char *) param->u.crypt.key - (char *) param); - if (max_key_len < 0) - return -EINVAL; - - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - sta_ptr = NULL; - if (param->u.crypt.idx >= WEP_KEYS) - param->u.crypt.idx = local->tx_keyidx; - crypt = &local->crypt[param->u.crypt.idx]; - } else { - param->u.crypt.idx = 0; - sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0, - &crypt); - - if (sta_ptr == NULL) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - return -EINVAL; - } - } - - if (*crypt == NULL || (*crypt)->ops == NULL) { - memcpy(param->u.crypt.alg, "none", 5); - param->u.crypt.key_len = 0; - param->u.crypt.idx = 0xff; - } else { - strncpy(param->u.crypt.alg, (*crypt)->ops->name, - HOSTAP_CRYPT_ALG_NAME_LEN); - param->u.crypt.key_len = 0; - - memset(param->u.crypt.seq, 0, 8); - if ((*crypt)->ops->get_key) { - param->u.crypt.key_len = - (*crypt)->ops->get_key(param->u.crypt.key, - max_key_len, - param->u.crypt.seq, - (*crypt)->priv); - } - } - - if (sta_ptr) - hostap_handle_sta_release(sta_ptr); - - return 0; -} - - -static int prism2_ioctl_get_rid(local_info_t *local, - struct prism2_hostapd_param *param, - int param_len) -{ - int max_len, res; - - max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN; - if (max_len < 0) - return -EINVAL; - - res = local->func->get_rid(local->dev, param->u.rid.rid, - param->u.rid.data, param->u.rid.len, 0); - if (res >= 0) { - param->u.rid.len = res; - return 0; - } - - return res; -} - - -static int prism2_ioctl_set_rid(local_info_t *local, - struct prism2_hostapd_param *param, - int param_len) -{ - int max_len; - - max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN; - if (max_len < 0 || max_len < param->u.rid.len) - return -EINVAL; - - return local->func->set_rid(local->dev, param->u.rid.rid, - param->u.rid.data, param->u.rid.len); -} - - -static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local, - struct prism2_hostapd_param *param, - int param_len) -{ - printk(KERN_DEBUG "%ssta: associated as client with AP " MACSTR "\n", - local->dev->name, MAC2STR(param->sta_addr)); - memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN); - return 0; -} - - -static int prism2_ioctl_siwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - return prism2_set_genericelement(dev, extra, data->length); -} - - -static int prism2_ioctl_giwgenie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - int len = local->generic_elem_len - 2; - - if (len <= 0 || local->generic_elem == NULL) { - data->length = 0; - return 0; - } - - if (data->length < len) - return -E2BIG; - - data->length = len; - memcpy(extra, local->generic_elem + 2, len); - - return 0; -} - - -static int prism2_ioctl_set_generic_element(local_info_t *local, - struct prism2_hostapd_param *param, - int param_len) -{ - int max_len, len; - - len = param->u.generic_elem.len; - max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN; - if (max_len < 0 || max_len < len) - return -EINVAL; - - return prism2_set_genericelement(local->dev, - param->u.generic_elem.data, len); -} - - -static int prism2_ioctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct hostap_interface *iface = dev->priv; - local_info_t *local = iface->local; - struct iw_mlme *mlme = (struct iw_mlme *) extra; - u16 reason; - - reason = cpu_to_le16(mlme->reason_code); - - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - return prism2_sta_send_mgmt(local, mlme->addr.sa_data, - WLAN_FC_STYPE_DEAUTH, - (u8 *) &reason, 2); - case IW_MLME_DISASSOC: - return prism2_sta_send_mgmt(local, mlme->addr.sa_data, - WLAN_FC_STYPE_DISASSOC, - (u8 *) &reason, 2); - default: - return -EOPNOTSUPP; - } -} - - -static int prism2_ioctl_mlme(local_info_t *local, - struct prism2_hostapd_param *param) -{ - u16 reason; - - reason = cpu_to_le16(param->u.mlme.reason_code); - switch (param->u.mlme.cmd) { - case MLME_STA_DEAUTH: - return prism2_sta_send_mgmt(local, param->sta_addr, - WLAN_FC_STYPE_DEAUTH, - (u8 *) &reason, 2); - case MLME_STA_DISASSOC: - return prism2_sta_send_mgmt(local, param->sta_addr, - WLAN_FC_STYPE_DISASSOC, - (u8 *) &reason, 2); - default: - return -EOPNOTSUPP; - } -} - - -static int prism2_ioctl_scan_req(local_info_t *local, - struct prism2_hostapd_param *param) -{ -#ifndef PRISM2_NO_STATION_MODES - if ((local->iw_mode != IW_MODE_INFRA && - local->iw_mode != IW_MODE_ADHOC) || - (local->sta_fw_ver < PRISM2_FW_VER(1,3,1))) - return -EOPNOTSUPP; - - if (!local->dev_enabled) - return -ENETDOWN; - - return prism2_request_hostscan(local->dev, param->u.scan_req.ssid, - param->u.scan_req.ssid_len); -#else /* PRISM2_NO_STATION_MODES */ - return -EOPNOTSUPP; -#endif /* PRISM2_NO_STATION_MODES */ -} - - -static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p) -{ - struct prism2_hostapd_param *param; - int ret = 0; - int ap_ioctl = 0; - - if (p->length < sizeof(struct prism2_hostapd_param) || - p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) - return -EINVAL; - - param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - case PRISM2_SET_ENCRYPTION: - ret = prism2_ioctl_set_encryption(local, param, p->length); - break; - case PRISM2_GET_ENCRYPTION: - ret = prism2_ioctl_get_encryption(local, param, p->length); - break; - case PRISM2_HOSTAPD_GET_RID: - ret = prism2_ioctl_get_rid(local, param, p->length); - break; - case PRISM2_HOSTAPD_SET_RID: - ret = prism2_ioctl_set_rid(local, param, p->length); - break; - case PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR: - ret = prism2_ioctl_set_assoc_ap_addr(local, param, p->length); - break; - case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT: - ret = prism2_ioctl_set_generic_element(local, param, - p->length); - break; - case PRISM2_HOSTAPD_MLME: - ret = prism2_ioctl_mlme(local, param); - break; - case PRISM2_HOSTAPD_SCAN_REQ: - ret = prism2_ioctl_scan_req(local, param); - break; - default: - ret = prism2_hostapd(local->ap, param); - ap_ioctl = 1; - break; - } - - if (ret == 1 || !ap_ioctl) { - if (copy_to_user(p->pointer, param, p->length)) { - ret = -EFAULT; - goto out; - } else if (ap_ioctl) - ret = 0; - } - - out: - if (param != NULL) - kfree(param); - - return ret; -} - - -static void prism2_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct hostap_interface *iface; - local_info_t *local; - - iface = netdev_priv(dev); - local = iface->local; - - strncpy(info->driver, "hostap", sizeof(info->driver) - 1); - strncpy(info->version, PRISM2_VERSION, - sizeof(info->version) - 1); - snprintf(info->fw_version, sizeof(info->fw_version) - 1, - "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff, - (local->sta_fw_ver >> 8) & 0xff, - local->sta_fw_ver & 0xff); -} - -static struct ethtool_ops prism2_ethtool_ops = { - .get_drvinfo = prism2_get_drvinfo -}; - - -/* Structures to export the Wireless Handlers */ - -static const iw_handler prism2_handler[] = -{ - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) prism2_get_name, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) prism2_ioctl_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) prism2_ioctl_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) prism2_ioctl_siwmode, /* SIOCSIWMODE */ - (iw_handler) prism2_ioctl_giwmode, /* SIOCGIWMODE */ - (iw_handler) prism2_ioctl_siwsens, /* SIOCSIWSENS */ - (iw_handler) prism2_ioctl_giwsens, /* SIOCGIWSENS */ - (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ - (iw_handler) prism2_ioctl_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ - (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ - iw_handler_set_spy, /* SIOCSIWSPY */ - iw_handler_get_spy, /* SIOCGIWSPY */ - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ - (iw_handler) prism2_ioctl_siwap, /* SIOCSIWAP */ - (iw_handler) prism2_ioctl_giwap, /* SIOCGIWAP */ - (iw_handler) prism2_ioctl_siwmlme, /* SIOCSIWMLME */ - (iw_handler) prism2_ioctl_giwaplist, /* SIOCGIWAPLIST */ - (iw_handler) prism2_ioctl_siwscan, /* SIOCSIWSCAN */ - (iw_handler) prism2_ioctl_giwscan, /* SIOCGIWSCAN */ - (iw_handler) prism2_ioctl_siwessid, /* SIOCSIWESSID */ - (iw_handler) prism2_ioctl_giwessid, /* SIOCGIWESSID */ - (iw_handler) prism2_ioctl_siwnickn, /* SIOCSIWNICKN */ - (iw_handler) prism2_ioctl_giwnickn, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) prism2_ioctl_siwrate, /* SIOCSIWRATE */ - (iw_handler) prism2_ioctl_giwrate, /* SIOCGIWRATE */ - (iw_handler) prism2_ioctl_siwrts, /* SIOCSIWRTS */ - (iw_handler) prism2_ioctl_giwrts, /* SIOCGIWRTS */ - (iw_handler) prism2_ioctl_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) prism2_ioctl_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) prism2_ioctl_siwtxpow, /* SIOCSIWTXPOW */ - (iw_handler) prism2_ioctl_giwtxpow, /* SIOCGIWTXPOW */ - (iw_handler) prism2_ioctl_siwretry, /* SIOCSIWRETRY */ - (iw_handler) prism2_ioctl_giwretry, /* SIOCGIWRETRY */ - (iw_handler) prism2_ioctl_siwencode, /* SIOCSIWENCODE */ - (iw_handler) prism2_ioctl_giwencode, /* SIOCGIWENCODE */ - (iw_handler) prism2_ioctl_siwpower, /* SIOCSIWPOWER */ - (iw_handler) prism2_ioctl_giwpower, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) prism2_ioctl_siwgenie, /* SIOCSIWGENIE */ - (iw_handler) prism2_ioctl_giwgenie, /* SIOCGIWGENIE */ - (iw_handler) prism2_ioctl_siwauth, /* SIOCSIWAUTH */ - (iw_handler) prism2_ioctl_giwauth, /* SIOCGIWAUTH */ - (iw_handler) prism2_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ - (iw_handler) prism2_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ - (iw_handler) NULL, /* -- hole -- */ -}; - -static const iw_handler prism2_private_handler[] = -{ /* SIOCIWFIRSTPRIV + */ - (iw_handler) prism2_ioctl_priv_prism2_param, /* 0 */ - (iw_handler) prism2_ioctl_priv_get_prism2_param, /* 1 */ - (iw_handler) prism2_ioctl_priv_writemif, /* 2 */ - (iw_handler) prism2_ioctl_priv_readmif, /* 3 */ -}; - -static const struct iw_handler_def hostap_iw_handler_def = -{ - .num_standard = sizeof(prism2_handler) / sizeof(iw_handler), - .num_private = sizeof(prism2_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(prism2_priv) / sizeof(struct iw_priv_args), - .standard = (iw_handler *) prism2_handler, - .private = (iw_handler *) prism2_private_handler, - .private_args = (struct iw_priv_args *) prism2_priv, - .get_wireless_stats = hostap_get_wireless_stats, -}; - - -int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct iwreq *wrq = (struct iwreq *) ifr; - struct hostap_interface *iface; - local_info_t *local; - int ret = 0; - - iface = netdev_priv(dev); - local = iface->local; - - switch (cmd) { - /* Private ioctls (iwpriv) that have not yet been converted - * into new wireless extensions API */ - - case PRISM2_IOCTL_INQUIRE: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_ioctl_priv_inquire(dev, (int *) wrq->u.name); - break; - - case PRISM2_IOCTL_MONITOR: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name); - break; - - case PRISM2_IOCTL_RESET: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name); - break; - - case PRISM2_IOCTL_WDS_ADD: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_wds_add(local, wrq->u.ap_addr.sa_data, 1); - break; - - case PRISM2_IOCTL_WDS_DEL: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_wds_del(local, wrq->u.ap_addr.sa_data, 1, 0); - break; - - case PRISM2_IOCTL_SET_RID_WORD: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_ioctl_priv_set_rid_word(dev, - (int *) wrq->u.name); - break; - -#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - case PRISM2_IOCTL_MACCMD: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = ap_mac_cmd_ioctl(local, (int *) wrq->u.name); - break; - - case PRISM2_IOCTL_ADDMAC: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = ap_control_add_mac(&local->ap->mac_restrictions, - wrq->u.ap_addr.sa_data); - break; - case PRISM2_IOCTL_DELMAC: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = ap_control_del_mac(&local->ap->mac_restrictions, - wrq->u.ap_addr.sa_data); - break; - case PRISM2_IOCTL_KICKMAC: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = ap_control_kick_mac(local->ap, local->dev, - wrq->u.ap_addr.sa_data); - break; -#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ - - - /* Private ioctls that are not used with iwpriv; - * in SIOCDEVPRIVATE range */ - -#ifdef PRISM2_DOWNLOAD_SUPPORT - case PRISM2_IOCTL_DOWNLOAD: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_ioctl_priv_download(local, &wrq->u.data); - break; -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - - case PRISM2_IOCTL_HOSTAPD: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = prism2_ioctl_priv_hostapd(local, &wrq->u.data); - break; - - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} diff --git a/trunk/drivers/net/wireless/hostap/hostap_pci.c b/trunk/drivers/net/wireless/hostap/hostap_pci.c deleted file mode 100644 index 786c146f533e..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_pci.c +++ /dev/null @@ -1,455 +0,0 @@ -#define PRISM2_PCI - -/* Host AP driver's support for Intersil Prism2.5 PCI cards is based on - * driver patches from Reyk Floeter and - * Andy Warner */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "hostap_wlan.h" - - -static char *version = PRISM2_VERSION " (Jouni Malinen )"; -static char *dev_info = "hostap_pci"; - - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN " - "PCI cards."); -MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -/* FIX: do we need mb/wmb/rmb with memory operations? */ - - -static struct pci_device_id prism2_pci_id_table[] __devinitdata = { - /* Intersil Prism3 ISL3872 11Mb/s WLAN Controller */ - { 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID }, - /* Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller */ - { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID }, - /* Samsung MagicLAN SWL-2210P */ - { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID }, - { 0 } -}; - - -#ifdef PRISM2_IO_DEBUG - -static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v); - writeb(v, local->mem_start + a); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline u8 hfa384x_inb_debug(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - u8 v; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - v = readb(local->mem_start + a); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v); - spin_unlock_irqrestore(&local->lock, flags); - return v; -} - -static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v); - writew(v, local->mem_start + a); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline u16 hfa384x_inw_debug(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - u16 v; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - v = readw(local->mem_start + a); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v); - spin_unlock_irqrestore(&local->lock, flags); - return v; -} - -#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v)) -#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a)) -#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v)) -#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a)) -#define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), cpu_to_le16((v))) -#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw_debug(dev, (a))) - -#else /* PRISM2_IO_DEBUG */ - -static inline void hfa384x_outb(struct net_device *dev, int a, u8 v) -{ - struct hostap_interface *iface; - local_info_t *local; - iface = netdev_priv(dev); - local = iface->local; - writeb(v, local->mem_start + a); -} - -static inline u8 hfa384x_inb(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - iface = netdev_priv(dev); - local = iface->local; - return readb(local->mem_start + a); -} - -static inline void hfa384x_outw(struct net_device *dev, int a, u16 v) -{ - struct hostap_interface *iface; - local_info_t *local; - iface = netdev_priv(dev); - local = iface->local; - writew(v, local->mem_start + a); -} - -static inline u16 hfa384x_inw(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - iface = netdev_priv(dev); - local = iface->local; - return readw(local->mem_start + a); -} - -#define HFA384X_OUTB(v,a) hfa384x_outb(dev, (a), (v)) -#define HFA384X_INB(a) hfa384x_inb(dev, (a)) -#define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v)) -#define HFA384X_INW(a) hfa384x_inw(dev, (a)) -#define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), cpu_to_le16((v))) -#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw(dev, (a))) - -#endif /* PRISM2_IO_DEBUG */ - - -static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf, - int len) -{ - u16 d_off; - u16 *pos; - - d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; - pos = (u16 *) buf; - - for ( ; len > 1; len -= 2) - *pos++ = HFA384X_INW_DATA(d_off); - - if (len & 1) - *((char *) pos) = HFA384X_INB(d_off); - - return 0; -} - - -static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) -{ - u16 d_off; - u16 *pos; - - d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; - pos = (u16 *) buf; - - for ( ; len > 1; len -= 2) - HFA384X_OUTW_DATA(*pos++, d_off); - - if (len & 1) - HFA384X_OUTB(*((char *) pos), d_off); - - return 0; -} - - -/* FIX: This might change at some point.. */ -#include "hostap_hw.c" - -static void prism2_pci_cor_sreset(local_info_t *local) -{ - struct net_device *dev = local->dev; - u16 reg; - - reg = HFA384X_INB(HFA384X_PCICOR_OFF); - printk(KERN_DEBUG "%s: Original COR value: 0x%0x\n", dev->name, reg); - - /* linux-wlan-ng uses extremely long hold and settle times for - * COR sreset. A comment in the driver code mentions that the long - * delays appear to be necessary. However, at least IBM 22P6901 seems - * to work fine with shorter delays. - * - * Longer delays can be configured by uncommenting following line: */ -/* #define PRISM2_PCI_USE_LONG_DELAYS */ - -#ifdef PRISM2_PCI_USE_LONG_DELAYS - int i; - - HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF); - mdelay(250); - - HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF); - mdelay(500); - - /* Wait for f/w to complete initialization (CMD:BUSY == 0) */ - i = 2000000 / 10; - while ((HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) && --i) - udelay(10); - -#else /* PRISM2_PCI_USE_LONG_DELAYS */ - - HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF); - mdelay(2); - HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF); - mdelay(2); - -#endif /* PRISM2_PCI_USE_LONG_DELAYS */ - - if (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) { - printk(KERN_DEBUG "%s: COR sreset timeout\n", dev->name); - } -} - - -static void prism2_pci_genesis_reset(local_info_t *local, int hcr) -{ - struct net_device *dev = local->dev; - - HFA384X_OUTW(0x00C5, HFA384X_PCICOR_OFF); - mdelay(10); - HFA384X_OUTW(hcr, HFA384X_PCIHCR_OFF); - mdelay(10); - HFA384X_OUTW(0x0045, HFA384X_PCICOR_OFF); - mdelay(10); -} - - -static struct prism2_helper_functions prism2_pci_funcs = -{ - .card_present = NULL, - .cor_sreset = prism2_pci_cor_sreset, - .dev_open = NULL, - .dev_close = NULL, - .genesis_reset = prism2_pci_genesis_reset, - .hw_type = HOSTAP_HW_PCI, -}; - - -static int prism2_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - unsigned long phymem; - void __iomem *mem = NULL; - local_info_t *local = NULL; - struct net_device *dev = NULL; - static int cards_found /* = 0 */; - int irq_registered = 0; - struct hostap_interface *iface; - - if (pci_enable_device(pdev)) - return -EIO; - - phymem = pci_resource_start(pdev, 0); - - if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) { - printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n"); - goto err_out_disable; - } - - mem = ioremap(phymem, pci_resource_len(pdev, 0)); - if (mem == NULL) { - printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ; - goto fail; - } - -#ifdef PRISM2_BUS_MASTER - pci_set_master(pdev); -#endif /* PRISM2_BUS_MASTER */ - - dev = prism2_init_local_data(&prism2_pci_funcs, cards_found, - &pdev->dev); - if (dev == NULL) - goto fail; - iface = netdev_priv(dev); - local = iface->local; - cards_found++; - - dev->irq = pdev->irq; - local->mem_start = mem; - - prism2_pci_cor_sreset(local); - - pci_set_drvdata(pdev, dev); - - if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name, - dev)) { - printk(KERN_WARNING "%s: request_irq failed\n", dev->name); - goto fail; - } else - irq_registered = 1; - - if (!local->pri_only && prism2_hw_config(dev, 1)) { - printk(KERN_DEBUG "%s: hardware initialization failed\n", - dev_info); - goto fail; - } - - printk(KERN_INFO "%s: Intersil Prism2.5 PCI: " - "mem=0x%lx, irq=%d\n", dev->name, phymem, dev->irq); - - return hostap_hw_ready(dev); - - fail: - if (irq_registered && dev) - free_irq(dev->irq, dev); - - if (mem) - iounmap(mem); - - release_mem_region(phymem, pci_resource_len(pdev, 0)); - - err_out_disable: - pci_disable_device(pdev); - prism2_free_local_data(dev); - - return -ENODEV; -} - - -static void prism2_pci_remove(struct pci_dev *pdev) -{ - struct net_device *dev; - struct hostap_interface *iface; - void __iomem *mem_start; - - dev = pci_get_drvdata(pdev); - iface = netdev_priv(dev); - - /* Reset the hardware, and ensure interrupts are disabled. */ - prism2_pci_cor_sreset(iface->local); - hfa384x_disable_interrupts(dev); - - if (dev->irq) - free_irq(dev->irq, dev); - - mem_start = iface->local->mem_start; - prism2_free_local_data(dev); - - iounmap(mem_start); - - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - pci_disable_device(pdev); -} - - -#ifdef CONFIG_PM -static int prism2_pci_suspend(struct pci_dev *pdev, u32 state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (netif_running(dev)) { - netif_stop_queue(dev); - netif_device_detach(dev); - } - prism2_suspend(dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, 3); - - return 0; -} - -static int prism2_pci_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - pci_enable_device(pdev); - pci_restore_state(pdev); - prism2_hw_config(dev, 0); - if (netif_running(dev)) { - netif_device_attach(dev); - netif_start_queue(dev); - } - - return 0; -} -#endif /* CONFIG_PM */ - - -MODULE_DEVICE_TABLE(pci, prism2_pci_id_table); - -static struct pci_driver prism2_pci_drv_id = { - .name = "prism2_pci", - .id_table = prism2_pci_id_table, - .probe = prism2_pci_probe, - .remove = prism2_pci_remove, -#ifdef CONFIG_PM - .suspend = prism2_pci_suspend, - .resume = prism2_pci_resume, -#endif /* CONFIG_PM */ - /* Linux 2.4.6 added save_state and enable_wake that are not used here - */ -}; - - -static int __init init_prism2_pci(void) -{ - printk(KERN_INFO "%s: %s\n", dev_info, version); - - return pci_register_driver(&prism2_pci_drv_id); -} - - -static void __exit exit_prism2_pci(void) -{ - pci_unregister_driver(&prism2_pci_drv_id); - printk(KERN_INFO "%s: Driver unloaded\n", dev_info); -} - - -module_init(init_prism2_pci); -module_exit(exit_prism2_pci); diff --git a/trunk/drivers/net/wireless/hostap/hostap_plx.c b/trunk/drivers/net/wireless/hostap/hostap_plx.c deleted file mode 100644 index c2f5b1f2b857..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_plx.c +++ /dev/null @@ -1,622 +0,0 @@ -#define PRISM2_PLX - -/* Host AP driver's support for PC Cards on PCI adapters using PLX9052 is - * based on: - * - Host AP driver patch from james@madingley.org - * - linux-wlan-ng driver, Copyright (C) AbsoluteValue Systems, Inc. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "hostap_wlan.h" - - -static char *version = PRISM2_VERSION " (Jouni Malinen )"; -static char *dev_info = "hostap_plx"; - - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " - "cards (PLX)."); -MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -static int ignore_cis; -module_param(ignore_cis, int, 0444); -MODULE_PARM_DESC(ignore_cis, "Do not verify manfid information in CIS"); - - -#define PLX_MIN_ATTR_LEN 512 /* at least 2 x 256 is needed for CIS */ -#define COR_SRESET 0x80 -#define COR_LEVLREQ 0x40 -#define COR_ENABLE_FUNC 0x01 -/* PCI Configuration Registers */ -#define PLX_PCIIPR 0x3d /* PCI Interrupt Pin */ -/* Local Configuration Registers */ -#define PLX_INTCSR 0x4c /* Interrupt Control/Status Register */ -#define PLX_INTCSR_PCI_INTEN BIT(6) /* PCI Interrupt Enable */ -#define PLX_CNTRL 0x50 -#define PLX_CNTRL_SERIAL_EEPROM_PRESENT BIT(28) - - -#define PLXDEV(vendor,dev,str) { vendor, dev, PCI_ANY_ID, PCI_ANY_ID } - -static struct pci_device_id prism2_plx_id_table[] __devinitdata = { - PLXDEV(0x10b7, 0x7770, "3Com AirConnect PCI 777A"), - PLXDEV(0x111a, 0x1023, "Siemens SpeedStream SS1023"), - PLXDEV(0x126c, 0x8030, "Nortel emobility"), - PLXDEV(0x1385, 0x4100, "Netgear MA301"), - PLXDEV(0x15e8, 0x0130, "National Datacomm NCP130 (PLX9052)"), - PLXDEV(0x15e8, 0x0131, "National Datacomm NCP130 (TMD7160)"), - PLXDEV(0x1638, 0x1100, "Eumitcom WL11000"), - PLXDEV(0x16ab, 0x1101, "Global Sun Tech GL24110P (?)"), - PLXDEV(0x16ab, 0x1102, "Linksys WPC11 with WDT11"), - PLXDEV(0x16ab, 0x1103, "Longshine 8031"), - PLXDEV(0x16ec, 0x3685, "US Robotics USR2415"), - PLXDEV(0xec80, 0xec00, "Belkin F5D6000"), - { 0 } -}; - - -/* Array of known Prism2/2.5 PC Card manufactured ids. If your card's manfid - * is not listed here, you will need to add it here to get the driver - * initialized. */ -static struct prism2_plx_manfid { - u16 manfid1, manfid2; -} prism2_plx_known_manfids[] = { - { 0x000b, 0x7110 } /* D-Link DWL-650 Rev. P1 */, - { 0x000b, 0x7300 } /* Philips 802.11b WLAN PCMCIA */, - { 0x0101, 0x0777 } /* 3Com AirConnect PCI 777A */, - { 0x0126, 0x8000 } /* Proxim RangeLAN */, - { 0x0138, 0x0002 } /* Compaq WL100 */, - { 0x0156, 0x0002 } /* Intersil Prism II Ref. Design (and others) */, - { 0x026f, 0x030b } /* Buffalo WLI-CF-S11G */, - { 0x0274, 0x1612 } /* Linksys WPC11 Ver 2.5 */, - { 0x0274, 0x1613 } /* Linksys WPC11 Ver 3 */, - { 0x028a, 0x0002 } /* D-Link DRC-650 */, - { 0x0250, 0x0002 } /* Samsung SWL2000-N */, - { 0xc250, 0x0002 } /* EMTAC A2424i */, - { 0xd601, 0x0002 } /* Z-Com XI300 */, - { 0xd601, 0x0005 } /* Zcomax XI-325H 200mW */, - { 0, 0} -}; - - -#ifdef PRISM2_IO_DEBUG - -static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v); - outb(v, dev->base_addr + a); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline u8 hfa384x_inb_debug(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - u8 v; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - v = inb(dev->base_addr + a); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v); - spin_unlock_irqrestore(&local->lock, flags); - return v; -} - -static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v); - outw(v, dev->base_addr + a); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline u16 hfa384x_inw_debug(struct net_device *dev, int a) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - u16 v; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - v = inw(dev->base_addr + a); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v); - spin_unlock_irqrestore(&local->lock, flags); - return v; -} - -static inline void hfa384x_outsw_debug(struct net_device *dev, int a, - u8 *buf, int wc) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc); - outsw(dev->base_addr + a, buf, wc); - spin_unlock_irqrestore(&local->lock, flags); -} - -static inline void hfa384x_insw_debug(struct net_device *dev, int a, - u8 *buf, int wc) -{ - struct hostap_interface *iface; - local_info_t *local; - unsigned long flags; - - iface = netdev_priv(dev); - local = iface->local; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc); - insw(dev->base_addr + a, buf, wc); - spin_unlock_irqrestore(&local->lock, flags); -} - -#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v)) -#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a)) -#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v)) -#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a)) -#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc)) -#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc)) - -#else /* PRISM2_IO_DEBUG */ - -#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((v), dev->base_addr + (a)) -#define HFA384X_INW(a) inw(dev->base_addr + (a)) -#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_IO_DEBUG */ - - -static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf, - int len) -{ - u16 d_off; - u16 *pos; - - d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; - pos = (u16 *) buf; - - if (len / 2) - HFA384X_INSW(d_off, buf, len / 2); - pos += len / 2; - - if (len & 1) - *((char *) pos) = HFA384X_INB(d_off); - - return 0; -} - - -static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) -{ - u16 d_off; - u16 *pos; - - d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF; - pos = (u16 *) buf; - - if (len / 2) - HFA384X_OUTSW(d_off, buf, len / 2); - pos += len / 2; - - if (len & 1) - HFA384X_OUTB(*((char *) pos), d_off); - - return 0; -} - - -/* FIX: This might change at some point.. */ -#include "hostap_hw.c" - - -static void prism2_plx_cor_sreset(local_info_t *local) -{ - unsigned char corsave; - - printk(KERN_DEBUG "%s: Doing reset via direct COR access.\n", - dev_info); - - /* Set sreset bit of COR and clear it after hold time */ - - if (local->attr_mem == NULL) { - /* TMD7160 - COR at card's first I/O addr */ - corsave = inb(local->cor_offset); - outb(corsave | COR_SRESET, local->cor_offset); - mdelay(2); - outb(corsave & ~COR_SRESET, local->cor_offset); - mdelay(2); - } else { - /* PLX9052 */ - corsave = readb(local->attr_mem + local->cor_offset); - writeb(corsave | COR_SRESET, - local->attr_mem + local->cor_offset); - mdelay(2); - writeb(corsave & ~COR_SRESET, - local->attr_mem + local->cor_offset); - mdelay(2); - } -} - - -static void prism2_plx_genesis_reset(local_info_t *local, int hcr) -{ - unsigned char corsave; - - if (local->attr_mem == NULL) { - /* TMD7160 - COR at card's first I/O addr */ - corsave = inb(local->cor_offset); - outb(corsave | COR_SRESET, local->cor_offset); - mdelay(10); - outb(hcr, local->cor_offset + 2); - mdelay(10); - outb(corsave & ~COR_SRESET, local->cor_offset); - mdelay(10); - } else { - /* PLX9052 */ - corsave = readb(local->attr_mem + local->cor_offset); - writeb(corsave | COR_SRESET, - local->attr_mem + local->cor_offset); - mdelay(10); - writeb(hcr, local->attr_mem + local->cor_offset + 2); - mdelay(10); - writeb(corsave & ~COR_SRESET, - local->attr_mem + local->cor_offset); - mdelay(10); - } -} - - -static struct prism2_helper_functions prism2_plx_funcs = -{ - .card_present = NULL, - .cor_sreset = prism2_plx_cor_sreset, - .dev_open = NULL, - .dev_close = NULL, - .genesis_reset = prism2_plx_genesis_reset, - .hw_type = HOSTAP_HW_PLX, -}; - - -static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, - unsigned int *cor_offset, - unsigned int *cor_index) -{ -#define CISTPL_CONFIG 0x1A -#define CISTPL_MANFID 0x20 -#define CISTPL_END 0xFF -#define CIS_MAX_LEN 256 - u8 *cis; - int i, pos; - unsigned int rmsz, rasz, manfid1, manfid2; - struct prism2_plx_manfid *manfid; - - cis = kmalloc(CIS_MAX_LEN, GFP_KERNEL); - if (cis == NULL) - return -ENOMEM; - - /* read CIS; it is in even offsets in the beginning of attr_mem */ - for (i = 0; i < CIS_MAX_LEN; i++) - cis[i] = readb(attr_mem + 2 * i); - printk(KERN_DEBUG "%s: CIS: %02x %02x %02x %02x %02x %02x ...\n", - dev_info, cis[0], cis[1], cis[2], cis[3], cis[4], cis[5]); - - /* set reasonable defaults for Prism2 cards just in case CIS parsing - * fails */ - *cor_offset = 0x3e0; - *cor_index = 0x01; - manfid1 = manfid2 = 0; - - pos = 0; - while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) { - if (pos + cis[pos + 1] >= CIS_MAX_LEN) - goto cis_error; - - switch (cis[pos]) { - case CISTPL_CONFIG: - if (cis[pos + 1] < 1) - goto cis_error; - rmsz = (cis[pos + 2] & 0x3c) >> 2; - rasz = cis[pos + 2] & 0x03; - if (4 + rasz + rmsz > cis[pos + 1]) - goto cis_error; - *cor_index = cis[pos + 3] & 0x3F; - *cor_offset = 0; - for (i = 0; i <= rasz; i++) - *cor_offset += cis[pos + 4 + i] << (8 * i); - printk(KERN_DEBUG "%s: cor_index=0x%x " - "cor_offset=0x%x\n", dev_info, - *cor_index, *cor_offset); - if (*cor_offset > attr_len) { - printk(KERN_ERR "%s: COR offset not within " - "attr_mem\n", dev_info); - kfree(cis); - return -1; - } - break; - - case CISTPL_MANFID: - if (cis[pos + 1] < 4) - goto cis_error; - manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); - manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); - printk(KERN_DEBUG "%s: manfid=0x%04x, 0x%04x\n", - dev_info, manfid1, manfid2); - break; - } - - pos += cis[pos + 1] + 2; - } - - if (pos >= CIS_MAX_LEN || cis[pos] != CISTPL_END) - goto cis_error; - - for (manfid = prism2_plx_known_manfids; manfid->manfid1 != 0; manfid++) - if (manfid1 == manfid->manfid1 && manfid2 == manfid->manfid2) { - kfree(cis); - return 0; - } - - printk(KERN_INFO "%s: unknown manfid 0x%04x, 0x%04x - assuming this is" - " not supported card\n", dev_info, manfid1, manfid2); - goto fail; - - cis_error: - printk(KERN_WARNING "%s: invalid CIS data\n", dev_info); - - fail: - kfree(cis); - if (ignore_cis) { - printk(KERN_INFO "%s: ignore_cis parameter set - ignoring " - "errors during CIS verification\n", dev_info); - return 0; - } - return -1; -} - - -static int prism2_plx_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - unsigned int pccard_ioaddr, plx_ioaddr; - unsigned long pccard_attr_mem; - unsigned int pccard_attr_len; - void __iomem *attr_mem = NULL; - unsigned int cor_offset, cor_index; - u32 reg; - local_info_t *local = NULL; - struct net_device *dev = NULL; - struct hostap_interface *iface; - static int cards_found /* = 0 */; - int irq_registered = 0; - int tmd7160; - - if (pci_enable_device(pdev)) - return -EIO; - - /* National Datacomm NCP130 based on TMD7160, not PLX9052. */ - tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131); - - plx_ioaddr = pci_resource_start(pdev, 1); - pccard_ioaddr = pci_resource_start(pdev, tmd7160 ? 2 : 3); - - if (tmd7160) { - /* TMD7160 */ - attr_mem = NULL; /* no access to PC Card attribute memory */ - - printk(KERN_INFO "TMD7160 PCI/PCMCIA adapter: io=0x%x, " - "irq=%d, pccard_io=0x%x\n", - plx_ioaddr, pdev->irq, pccard_ioaddr); - - cor_offset = plx_ioaddr; - cor_index = 0x04; - - outb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, plx_ioaddr); - mdelay(1); - reg = inb(plx_ioaddr); - if (reg != (cor_index | COR_LEVLREQ | COR_ENABLE_FUNC)) { - printk(KERN_ERR "%s: Error setting COR (expected=" - "0x%02x, was=0x%02x)\n", dev_info, - cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, reg); - goto fail; - } - } else { - /* PLX9052 */ - pccard_attr_mem = pci_resource_start(pdev, 2); - pccard_attr_len = pci_resource_len(pdev, 2); - if (pccard_attr_len < PLX_MIN_ATTR_LEN) - goto fail; - - - attr_mem = ioremap(pccard_attr_mem, pccard_attr_len); - if (attr_mem == NULL) { - printk(KERN_ERR "%s: cannot remap attr_mem\n", - dev_info); - goto fail; - } - - printk(KERN_INFO "PLX9052 PCI/PCMCIA adapter: " - "mem=0x%lx, plx_io=0x%x, irq=%d, pccard_io=0x%x\n", - pccard_attr_mem, plx_ioaddr, pdev->irq, pccard_ioaddr); - - if (prism2_plx_check_cis(attr_mem, pccard_attr_len, - &cor_offset, &cor_index)) { - printk(KERN_INFO "Unknown PC Card CIS - not a " - "Prism2/2.5 card?\n"); - goto fail; - } - - printk(KERN_DEBUG "Prism2/2.5 PC Card detected in PLX9052 " - "adapter\n"); - - /* Write COR to enable PC Card */ - writeb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, - attr_mem + cor_offset); - - /* Enable PCI interrupts if they are not already enabled */ - reg = inl(plx_ioaddr + PLX_INTCSR); - printk(KERN_DEBUG "PLX_INTCSR=0x%x\n", reg); - if (!(reg & PLX_INTCSR_PCI_INTEN)) { - outl(reg | PLX_INTCSR_PCI_INTEN, - plx_ioaddr + PLX_INTCSR); - if (!(inl(plx_ioaddr + PLX_INTCSR) & - PLX_INTCSR_PCI_INTEN)) { - printk(KERN_WARNING "%s: Could not enable " - "Local Interrupts\n", dev_info); - goto fail; - } - } - - reg = inl(plx_ioaddr + PLX_CNTRL); - printk(KERN_DEBUG "PLX_CNTRL=0x%x (Serial EEPROM " - "present=%d)\n", - reg, (reg & PLX_CNTRL_SERIAL_EEPROM_PRESENT) != 0); - /* should set PLX_PCIIPR to 0x01 (INTA#) if Serial EEPROM is - * not present; but are there really such cards in use(?) */ - } - - dev = prism2_init_local_data(&prism2_plx_funcs, cards_found, - &pdev->dev); - if (dev == NULL) - goto fail; - iface = netdev_priv(dev); - local = iface->local; - cards_found++; - - dev->irq = pdev->irq; - dev->base_addr = pccard_ioaddr; - local->attr_mem = attr_mem; - local->cor_offset = cor_offset; - - pci_set_drvdata(pdev, dev); - - if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name, - dev)) { - printk(KERN_WARNING "%s: request_irq failed\n", dev->name); - goto fail; - } else - irq_registered = 1; - - if (prism2_hw_config(dev, 1)) { - printk(KERN_DEBUG "%s: hardware initialization failed\n", - dev_info); - goto fail; - } - - return hostap_hw_ready(dev); - - fail: - prism2_free_local_data(dev); - - if (irq_registered && dev) - free_irq(dev->irq, dev); - - if (attr_mem) - iounmap(attr_mem); - - pci_disable_device(pdev); - - return -ENODEV; -} - - -static void prism2_plx_remove(struct pci_dev *pdev) -{ - struct net_device *dev; - struct hostap_interface *iface; - - dev = pci_get_drvdata(pdev); - iface = netdev_priv(dev); - - /* Reset the hardware, and ensure interrupts are disabled. */ - prism2_plx_cor_sreset(iface->local); - hfa384x_disable_interrupts(dev); - - if (iface->local->attr_mem) - iounmap(iface->local->attr_mem); - if (dev->irq) - free_irq(dev->irq, dev); - - prism2_free_local_data(dev); - pci_disable_device(pdev); -} - - -MODULE_DEVICE_TABLE(pci, prism2_plx_id_table); - -static struct pci_driver prism2_plx_drv_id = { - .name = "prism2_plx", - .id_table = prism2_plx_id_table, - .probe = prism2_plx_probe, - .remove = prism2_plx_remove, - .suspend = NULL, - .resume = NULL, - .enable_wake = NULL -}; - - -static int __init init_prism2_plx(void) -{ - printk(KERN_INFO "%s: %s\n", dev_info, version); - - return pci_register_driver(&prism2_plx_drv_id); -} - - -static void __exit exit_prism2_plx(void) -{ - pci_unregister_driver(&prism2_plx_drv_id); - printk(KERN_INFO "%s: Driver unloaded\n", dev_info); -} - - -module_init(init_prism2_plx); -module_exit(exit_prism2_plx); diff --git a/trunk/drivers/net/wireless/hostap/hostap_proc.c b/trunk/drivers/net/wireless/hostap/hostap_proc.c deleted file mode 100644 index a0a4cbd4937a..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_proc.c +++ /dev/null @@ -1,448 +0,0 @@ -/* /proc routines for Host AP driver */ - -#define PROC_LIMIT (PAGE_SIZE - 80) - - -#ifndef PRISM2_NO_PROCFS_DEBUG -static int prism2_debug_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - int i; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "next_txfid=%d next_alloc=%d\n", - local->next_txfid, local->next_alloc); - for (i = 0; i < PRISM2_TXFID_COUNT; i++) - p += sprintf(p, "FID: tx=%04X intransmit=%04X\n", - local->txfid[i], local->intransmitfid[i]); - p += sprintf(p, "FW TX rate control: %d\n", local->fw_tx_rate_control); - p += sprintf(p, "beacon_int=%d\n", local->beacon_int); - p += sprintf(p, "dtim_period=%d\n", local->dtim_period); - p += sprintf(p, "wds_max_connections=%d\n", - local->wds_max_connections); - p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled); - p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck); - for (i = 0; i < WEP_KEYS; i++) { - if (local->crypt[i] && local->crypt[i]->ops) { - p += sprintf(p, "crypt[%d]=%s\n", - i, local->crypt[i]->ops->name); - } - } - p += sprintf(p, "pri_only=%d\n", local->pri_only); - p += sprintf(p, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI); - p += sprintf(p, "sram_type=%d\n", local->sram_type); - p += sprintf(p, "no_pri=%d\n", local->no_pri); - - return (p - page); -} -#endif /* PRISM2_NO_PROCFS_DEBUG */ - - -static int prism2_stats_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - struct comm_tallies_sums *sums = (struct comm_tallies_sums *) - &local->comm_tallies; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "TxUnicastFrames=%u\n", sums->tx_unicast_frames); - p += sprintf(p, "TxMulticastframes=%u\n", sums->tx_multicast_frames); - p += sprintf(p, "TxFragments=%u\n", sums->tx_fragments); - p += sprintf(p, "TxUnicastOctets=%u\n", sums->tx_unicast_octets); - p += sprintf(p, "TxMulticastOctets=%u\n", sums->tx_multicast_octets); - p += sprintf(p, "TxDeferredTransmissions=%u\n", - sums->tx_deferred_transmissions); - p += sprintf(p, "TxSingleRetryFrames=%u\n", - sums->tx_single_retry_frames); - p += sprintf(p, "TxMultipleRetryFrames=%u\n", - sums->tx_multiple_retry_frames); - p += sprintf(p, "TxRetryLimitExceeded=%u\n", - sums->tx_retry_limit_exceeded); - p += sprintf(p, "TxDiscards=%u\n", sums->tx_discards); - p += sprintf(p, "RxUnicastFrames=%u\n", sums->rx_unicast_frames); - p += sprintf(p, "RxMulticastFrames=%u\n", sums->rx_multicast_frames); - p += sprintf(p, "RxFragments=%u\n", sums->rx_fragments); - p += sprintf(p, "RxUnicastOctets=%u\n", sums->rx_unicast_octets); - p += sprintf(p, "RxMulticastOctets=%u\n", sums->rx_multicast_octets); - p += sprintf(p, "RxFCSErrors=%u\n", sums->rx_fcs_errors); - p += sprintf(p, "RxDiscardsNoBuffer=%u\n", - sums->rx_discards_no_buffer); - p += sprintf(p, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa); - p += sprintf(p, "RxDiscardsWEPUndecryptable=%u\n", - sums->rx_discards_wep_undecryptable); - p += sprintf(p, "RxMessageInMsgFragments=%u\n", - sums->rx_message_in_msg_fragments); - p += sprintf(p, "RxMessageInBadMsgFragments=%u\n", - sums->rx_message_in_bad_msg_fragments); - /* FIX: this may grow too long for one page(?) */ - - return (p - page); -} - - -static int prism2_wds_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - struct list_head *ptr; - struct hostap_interface *iface; - - if (off > PROC_LIMIT) { - *eof = 1; - return 0; - } - - read_lock_bh(&local->iface_lock); - list_for_each(ptr, &local->hostap_interfaces) { - iface = list_entry(ptr, struct hostap_interface, list); - if (iface->type != HOSTAP_INTERFACE_WDS) - continue; - p += sprintf(p, "%s\t" MACSTR "\n", - iface->dev->name, - MAC2STR(iface->u.wds.remote_addr)); - if ((p - page) > PROC_LIMIT) { - printk(KERN_DEBUG "%s: wds proc did not fit\n", - local->dev->name); - break; - } - } - read_unlock_bh(&local->iface_lock); - - if ((p - page) <= off) { - *eof = 1; - return 0; - } - - *start = page + off; - - return (p - page - off); -} - - -static int prism2_bss_list_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - struct list_head *ptr; - struct hostap_bss_info *bss; - int i; - - if (off > PROC_LIMIT) { - *eof = 1; - return 0; - } - - p += sprintf(p, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" - "SSID(hex)\tWPA IE\n"); - spin_lock_bh(&local->lock); - list_for_each(ptr, &local->bss_list) { - bss = list_entry(ptr, struct hostap_bss_info, list); - p += sprintf(p, MACSTR "\t%lu\t%u\t0x%x\t", - MAC2STR(bss->bssid), bss->last_update, - bss->count, bss->capab_info); - for (i = 0; i < bss->ssid_len; i++) { - p += sprintf(p, "%c", - bss->ssid[i] >= 32 && bss->ssid[i] < 127 ? - bss->ssid[i] : '_'); - } - p += sprintf(p, "\t"); - for (i = 0; i < bss->ssid_len; i++) { - p += sprintf(p, "%02x", bss->ssid[i]); - } - p += sprintf(p, "\t"); - for (i = 0; i < bss->wpa_ie_len; i++) { - p += sprintf(p, "%02x", bss->wpa_ie[i]); - } - p += sprintf(p, "\n"); - if ((p - page) > PROC_LIMIT) { - printk(KERN_DEBUG "%s: BSS proc did not fit\n", - local->dev->name); - break; - } - } - spin_unlock_bh(&local->lock); - - if ((p - page) <= off) { - *eof = 1; - return 0; - } - - *start = page + off; - - return (p - page - off); -} - - -static int prism2_crypt_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - int i; - - if (off > PROC_LIMIT) { - *eof = 1; - return 0; - } - - p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx); - for (i = 0; i < WEP_KEYS; i++) { - if (local->crypt[i] && local->crypt[i]->ops && - local->crypt[i]->ops->print_stats) { - p = local->crypt[i]->ops->print_stats( - p, local->crypt[i]->priv); - } - } - - if ((p - page) <= off) { - *eof = 1; - return 0; - } - - *start = page + off; - - return (p - page - off); -} - - -static int prism2_pda_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - local_info_t *local = (local_info_t *) data; - - if (local->pda == NULL || off >= PRISM2_PDA_SIZE) { - *eof = 1; - return 0; - } - - if (off + count > PRISM2_PDA_SIZE) - count = PRISM2_PDA_SIZE - off; - - memcpy(page, local->pda + off, count); - return count; -} - - -static int prism2_aux_dump_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - local_info_t *local = (local_info_t *) data; - - if (local->func->read_aux == NULL) { - *eof = 1; - return 0; - } - - if (local->func->read_aux(local->dev, off, count, page)) { - *eof = 1; - return 0; - } - *start = page; - - return count; -} - - -#ifdef PRISM2_IO_DEBUG -static int prism2_io_debug_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - local_info_t *local = (local_info_t *) data; - int head = local->io_debug_head; - int start_bytes, left, copy, copied; - - if (off + count > PRISM2_IO_DEBUG_SIZE * 4) { - *eof = 1; - if (off >= PRISM2_IO_DEBUG_SIZE * 4) - return 0; - count = PRISM2_IO_DEBUG_SIZE * 4 - off; - } - - copied = 0; - start_bytes = (PRISM2_IO_DEBUG_SIZE - head) * 4; - left = count; - - if (off < start_bytes) { - copy = start_bytes - off; - if (copy > count) - copy = count; - memcpy(page, ((u8 *) &local->io_debug[head]) + off, copy); - left -= copy; - if (left > 0) - memcpy(&page[copy], local->io_debug, left); - } else { - memcpy(page, ((u8 *) local->io_debug) + (off - start_bytes), - left); - } - - *start = page; - - return count; -} -#endif /* PRISM2_IO_DEBUG */ - - -#ifndef PRISM2_NO_STATION_MODES -static int prism2_scan_results_proc_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - local_info_t *local = (local_info_t *) data; - int entry, i, len, total = 0; - struct hfa384x_hostscan_result *scanres; - u8 *pos; - - p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates " - "SSID\n"); - - spin_lock_bh(&local->lock); - for (entry = 0; entry < local->last_scan_results_count; entry++) { - scanres = &local->last_scan_results[entry]; - - if (total + (p - page) <= off) { - total += p - page; - p = page; - } - if (total + (p - page) > off + count) - break; - if ((p - page) > (PAGE_SIZE - 200)) - break; - - p += sprintf(p, "%d %d %d %d 0x%02x %d " MACSTR " %d ", - le16_to_cpu(scanres->chid), - (s16) le16_to_cpu(scanres->anl), - (s16) le16_to_cpu(scanres->sl), - le16_to_cpu(scanres->beacon_interval), - le16_to_cpu(scanres->capability), - le16_to_cpu(scanres->rate), - MAC2STR(scanres->bssid), - le16_to_cpu(scanres->atim)); - - pos = scanres->sup_rates; - for (i = 0; i < sizeof(scanres->sup_rates); i++) { - if (pos[i] == 0) - break; - p += sprintf(p, "<%02x>", pos[i]); - } - p += sprintf(p, " "); - - pos = scanres->ssid; - len = le16_to_cpu(scanres->ssid_len); - if (len > 32) - len = 32; - for (i = 0; i < len; i++) { - unsigned char c = pos[i]; - if (c >= 32 && c < 127) - p += sprintf(p, "%c", c); - else - p += sprintf(p, "<%02x>", c); - } - p += sprintf(p, "\n"); - } - spin_unlock_bh(&local->lock); - - total += (p - page); - if (total >= off + count) - *eof = 1; - - if (total < off) { - *eof = 1; - return 0; - } - - len = total - off; - if (len > (p - page)) - len = p - page; - *start = p - len; - if (len > count) - len = count; - - return len; -} -#endif /* PRISM2_NO_STATION_MODES */ - - -void hostap_init_proc(local_info_t *local) -{ - local->proc = NULL; - - if (hostap_proc == NULL) { - printk(KERN_WARNING "%s: hostap proc directory not created\n", - local->dev->name); - return; - } - - local->proc = proc_mkdir(local->ddev->name, hostap_proc); - if (local->proc == NULL) { - printk(KERN_INFO "/proc/net/hostap/%s creation failed\n", - local->ddev->name); - return; - } - -#ifndef PRISM2_NO_PROCFS_DEBUG - create_proc_read_entry("debug", 0, local->proc, - prism2_debug_proc_read, local); -#endif /* PRISM2_NO_PROCFS_DEBUG */ - create_proc_read_entry("stats", 0, local->proc, - prism2_stats_proc_read, local); - create_proc_read_entry("wds", 0, local->proc, - prism2_wds_proc_read, local); - create_proc_read_entry("pda", 0, local->proc, - prism2_pda_proc_read, local); - create_proc_read_entry("aux_dump", 0, local->proc, - prism2_aux_dump_proc_read, local); - create_proc_read_entry("bss_list", 0, local->proc, - prism2_bss_list_proc_read, local); - create_proc_read_entry("crypt", 0, local->proc, - prism2_crypt_proc_read, local); -#ifdef PRISM2_IO_DEBUG - create_proc_read_entry("io_debug", 0, local->proc, - prism2_io_debug_proc_read, local); -#endif /* PRISM2_IO_DEBUG */ -#ifndef PRISM2_NO_STATION_MODES - create_proc_read_entry("scan_results", 0, local->proc, - prism2_scan_results_proc_read, local); -#endif /* PRISM2_NO_STATION_MODES */ -} - - -void hostap_remove_proc(local_info_t *local) -{ - if (local->proc != NULL) { -#ifndef PRISM2_NO_STATION_MODES - remove_proc_entry("scan_results", local->proc); -#endif /* PRISM2_NO_STATION_MODES */ -#ifdef PRISM2_IO_DEBUG - remove_proc_entry("io_debug", local->proc); -#endif /* PRISM2_IO_DEBUG */ - remove_proc_entry("pda", local->proc); - remove_proc_entry("aux_dump", local->proc); - remove_proc_entry("wds", local->proc); - remove_proc_entry("stats", local->proc); - remove_proc_entry("bss_list", local->proc); - remove_proc_entry("crypt", local->proc); -#ifndef PRISM2_NO_PROCFS_DEBUG - remove_proc_entry("debug", local->proc); -#endif /* PRISM2_NO_PROCFS_DEBUG */ - if (hostap_proc != NULL) - remove_proc_entry(local->proc->name, hostap_proc); - } -} - - -EXPORT_SYMBOL(hostap_init_proc); -EXPORT_SYMBOL(hostap_remove_proc); diff --git a/trunk/drivers/net/wireless/hostap/hostap_wlan.h b/trunk/drivers/net/wireless/hostap/hostap_wlan.h deleted file mode 100644 index a632d45f334d..000000000000 --- a/trunk/drivers/net/wireless/hostap/hostap_wlan.h +++ /dev/null @@ -1,1066 +0,0 @@ -#ifndef HOSTAP_WLAN_H -#define HOSTAP_WLAN_H - -#include "hostap_config.h" -#include "hostap_common.h" - -#define MAX_PARM_DEVICES 8 -#define PARM_MIN_MAX "1-" __MODULE_STRING(MAX_PARM_DEVICES) -#define DEF_INTS -1, -1, -1, -1, -1, -1, -1 -#define GET_INT_PARM(var,idx) var[var[idx] < 0 ? 0 : idx] - - -/* Specific skb->protocol value that indicates that the packet already contains - * txdesc header. - * FIX: This might need own value that would be allocated especially for Prism2 - * txdesc; ETH_P_CONTROL is commented as "Card specific control frames". - * However, these skb's should have only minimal path in the kernel side since - * prism2_send_mgmt() sends these with dev_queue_xmit() to prism2_tx(). */ -#define ETH_P_HOSTAP ETH_P_CONTROL - -#ifndef ARPHRD_IEEE80211 -#define ARPHRD_IEEE80211 801 -#endif -#ifndef ARPHRD_IEEE80211_PRISM -#define ARPHRD_IEEE80211_PRISM 802 -#endif - -/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header - * (from linux-wlan-ng) */ -struct linux_wlan_ng_val { - u32 did; - u16 status, len; - u32 data; -} __attribute__ ((packed)); - -struct linux_wlan_ng_prism_hdr { - u32 msgcode, msglen; - char devname[16]; - struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal, - noise, rate, istx, frmlen; -} __attribute__ ((packed)); - -struct linux_wlan_ng_cap_hdr { - u32 version; - u32 length; - u64 mactime; - u64 hosttime; - u32 phytype; - u32 channel; - u32 datarate; - u32 antenna; - u32 priority; - u32 ssi_type; - s32 ssi_signal; - s32 ssi_noise; - u32 preamble; - u32 encoding; -} __attribute__ ((packed)); - -#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */ -#define LWNG_CAPHDR_VERSION 0x80211001 - -struct hfa384x_rx_frame { - /* HFA384X RX frame descriptor */ - u16 status; /* HFA384X_RX_STATUS_ flags */ - u32 time; /* timestamp, 1 microsecond resolution */ - u8 silence; /* 27 .. 154; seems to be 0 */ - u8 signal; /* 27 .. 154 */ - u8 rate; /* 10, 20, 55, or 110 */ - u8 rxflow; - u32 reserved; - - /* 802.11 */ - u16 frame_control; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; - u8 addr4[6]; - u16 data_len; - - /* 802.3 */ - u8 dst_addr[6]; - u8 src_addr[6]; - u16 len; - - /* followed by frame data; max 2304 bytes */ -} __attribute__ ((packed)); - - -struct hfa384x_tx_frame { - /* HFA384X TX frame descriptor */ - u16 status; /* HFA384X_TX_STATUS_ flags */ - u16 reserved1; - u16 reserved2; - u32 sw_support; - u8 retry_count; /* not yet implemented */ - u8 tx_rate; /* Host AP only; 0 = firmware, or 10, 20, 55, 110 */ - u16 tx_control; /* HFA384X_TX_CTRL_ flags */ - - /* 802.11 */ - u16 frame_control; /* parts not used */ - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; /* filled by firmware */ - u8 addr3[6]; - u16 seq_ctrl; /* filled by firmware */ - u8 addr4[6]; - u16 data_len; - - /* 802.3 */ - u8 dst_addr[6]; - u8 src_addr[6]; - u16 len; - - /* followed by frame data; max 2304 bytes */ -} __attribute__ ((packed)); - - -struct hfa384x_rid_hdr -{ - u16 len; - u16 rid; -} __attribute__ ((packed)); - - -/* Macro for converting signal levels (range 27 .. 154) to wireless ext - * dBm value with some accuracy */ -#define HFA384X_LEVEL_TO_dBm(v) 0x100 + (v) * 100 / 255 - 100 - -#define HFA384X_LEVEL_TO_dBm_sign(v) (v) * 100 / 255 - 100 - -struct hfa384x_scan_request { - u16 channel_list; - u16 txrate; /* HFA384X_RATES_* */ -} __attribute__ ((packed)); - -struct hfa384x_hostscan_request { - u16 channel_list; - u16 txrate; - u16 target_ssid_len; - u8 target_ssid[32]; -} __attribute__ ((packed)); - -struct hfa384x_join_request { - u8 bssid[6]; - u16 channel; -} __attribute__ ((packed)); - -struct hfa384x_info_frame { - u16 len; - u16 type; -} __attribute__ ((packed)); - -struct hfa384x_comm_tallies { - u16 tx_unicast_frames; - u16 tx_multicast_frames; - u16 tx_fragments; - u16 tx_unicast_octets; - u16 tx_multicast_octets; - u16 tx_deferred_transmissions; - u16 tx_single_retry_frames; - u16 tx_multiple_retry_frames; - u16 tx_retry_limit_exceeded; - u16 tx_discards; - u16 rx_unicast_frames; - u16 rx_multicast_frames; - u16 rx_fragments; - u16 rx_unicast_octets; - u16 rx_multicast_octets; - u16 rx_fcs_errors; - u16 rx_discards_no_buffer; - u16 tx_discards_wrong_sa; - u16 rx_discards_wep_undecryptable; - u16 rx_message_in_msg_fragments; - u16 rx_message_in_bad_msg_fragments; -} __attribute__ ((packed)); - -struct hfa384x_comm_tallies32 { - u32 tx_unicast_frames; - u32 tx_multicast_frames; - u32 tx_fragments; - u32 tx_unicast_octets; - u32 tx_multicast_octets; - u32 tx_deferred_transmissions; - u32 tx_single_retry_frames; - u32 tx_multiple_retry_frames; - u32 tx_retry_limit_exceeded; - u32 tx_discards; - u32 rx_unicast_frames; - u32 rx_multicast_frames; - u32 rx_fragments; - u32 rx_unicast_octets; - u32 rx_multicast_octets; - u32 rx_fcs_errors; - u32 rx_discards_no_buffer; - u32 tx_discards_wrong_sa; - u32 rx_discards_wep_undecryptable; - u32 rx_message_in_msg_fragments; - u32 rx_message_in_bad_msg_fragments; -} __attribute__ ((packed)); - -struct hfa384x_scan_result_hdr { - u16 reserved; - u16 scan_reason; -#define HFA384X_SCAN_IN_PROGRESS 0 /* no results available yet */ -#define HFA384X_SCAN_HOST_INITIATED 1 -#define HFA384X_SCAN_FIRMWARE_INITIATED 2 -#define HFA384X_SCAN_INQUIRY_FROM_HOST 3 -} __attribute__ ((packed)); - -#define HFA384X_SCAN_MAX_RESULTS 32 - -struct hfa384x_scan_result { - u16 chid; - u16 anl; - u16 sl; - u8 bssid[6]; - u16 beacon_interval; - u16 capability; - u16 ssid_len; - u8 ssid[32]; - u8 sup_rates[10]; - u16 rate; -} __attribute__ ((packed)); - -struct hfa384x_hostscan_result { - u16 chid; - u16 anl; - u16 sl; - u8 bssid[6]; - u16 beacon_interval; - u16 capability; - u16 ssid_len; - u8 ssid[32]; - u8 sup_rates[10]; - u16 rate; - u16 atim; -} __attribute__ ((packed)); - -struct comm_tallies_sums { - unsigned int tx_unicast_frames; - unsigned int tx_multicast_frames; - unsigned int tx_fragments; - unsigned int tx_unicast_octets; - unsigned int tx_multicast_octets; - unsigned int tx_deferred_transmissions; - unsigned int tx_single_retry_frames; - unsigned int tx_multiple_retry_frames; - unsigned int tx_retry_limit_exceeded; - unsigned int tx_discards; - unsigned int rx_unicast_frames; - unsigned int rx_multicast_frames; - unsigned int rx_fragments; - unsigned int rx_unicast_octets; - unsigned int rx_multicast_octets; - unsigned int rx_fcs_errors; - unsigned int rx_discards_no_buffer; - unsigned int tx_discards_wrong_sa; - unsigned int rx_discards_wep_undecryptable; - unsigned int rx_message_in_msg_fragments; - unsigned int rx_message_in_bad_msg_fragments; -}; - - -struct hfa384x_regs { - u16 cmd; - u16 evstat; - u16 offset0; - u16 offset1; - u16 swsupport0; -}; - - -#if defined(PRISM2_PCCARD) || defined(PRISM2_PLX) -/* I/O ports for HFA384X Controller access */ -#define HFA384X_CMD_OFF 0x00 -#define HFA384X_PARAM0_OFF 0x02 -#define HFA384X_PARAM1_OFF 0x04 -#define HFA384X_PARAM2_OFF 0x06 -#define HFA384X_STATUS_OFF 0x08 -#define HFA384X_RESP0_OFF 0x0A -#define HFA384X_RESP1_OFF 0x0C -#define HFA384X_RESP2_OFF 0x0E -#define HFA384X_INFOFID_OFF 0x10 -#define HFA384X_CONTROL_OFF 0x14 -#define HFA384X_SELECT0_OFF 0x18 -#define HFA384X_SELECT1_OFF 0x1A -#define HFA384X_OFFSET0_OFF 0x1C -#define HFA384X_OFFSET1_OFF 0x1E -#define HFA384X_RXFID_OFF 0x20 -#define HFA384X_ALLOCFID_OFF 0x22 -#define HFA384X_TXCOMPLFID_OFF 0x24 -#define HFA384X_SWSUPPORT0_OFF 0x28 -#define HFA384X_SWSUPPORT1_OFF 0x2A -#define HFA384X_SWSUPPORT2_OFF 0x2C -#define HFA384X_EVSTAT_OFF 0x30 -#define HFA384X_INTEN_OFF 0x32 -#define HFA384X_EVACK_OFF 0x34 -#define HFA384X_DATA0_OFF 0x36 -#define HFA384X_DATA1_OFF 0x38 -#define HFA384X_AUXPAGE_OFF 0x3A -#define HFA384X_AUXOFFSET_OFF 0x3C -#define HFA384X_AUXDATA_OFF 0x3E -#endif /* PRISM2_PCCARD || PRISM2_PLX */ - -#ifdef PRISM2_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_PCICOR_OFF 0x4C -#define HFA384X_SWSUPPORT0_OFF 0x50 -#define HFA384X_SWSUPPORT1_OFF 0x54 -#define HFA384X_SWSUPPORT2_OFF 0x58 -#define HFA384X_PCIHCR_OFF 0x5C -#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_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 - -/* PCI bus master control bits (these are undocumented; based on guessing and - * experimenting..) */ -#define HFA384X_PCI_CTL_FROM_BAP (BIT(5) | BIT(1) | BIT(0)) -#define HFA384X_PCI_CTL_TO_BAP (BIT(5) | BIT(0)) - -#endif /* PRISM2_PCI */ - - -/* Command codes for CMD reg. */ -#define HFA384X_CMDCODE_INIT 0x00 -#define HFA384X_CMDCODE_ENABLE 0x01 -#define HFA384X_CMDCODE_DISABLE 0x02 -#define HFA384X_CMDCODE_ALLOC 0x0A -#define HFA384X_CMDCODE_TRANSMIT 0x0B -#define HFA384X_CMDCODE_INQUIRE 0x11 -#define HFA384X_CMDCODE_ACCESS 0x21 -#define HFA384X_CMDCODE_ACCESS_WRITE (0x21 | BIT(8)) -#define HFA384X_CMDCODE_DOWNLOAD 0x22 -#define HFA384X_CMDCODE_READMIF 0x30 -#define HFA384X_CMDCODE_WRITEMIF 0x31 -#define HFA384X_CMDCODE_TEST 0x38 - -#define HFA384X_CMDCODE_MASK 0x3F - -/* Test mode operations */ -#define HFA384X_TEST_CHANGE_CHANNEL 0x08 -#define HFA384X_TEST_MONITOR 0x0B -#define HFA384X_TEST_STOP 0x0F -#define HFA384X_TEST_CFG_BITS 0x15 -#define HFA384X_TEST_CFG_BIT_ALC BIT(3) - -#define HFA384X_CMD_BUSY BIT(15) - -#define HFA384X_CMD_TX_RECLAIM BIT(8) - -#define HFA384X_OFFSET_ERR BIT(14) -#define HFA384X_OFFSET_BUSY BIT(15) - - -/* ProgMode for download command */ -#define HFA384X_PROGMODE_DISABLE 0 -#define HFA384X_PROGMODE_ENABLE_VOLATILE 1 -#define HFA384X_PROGMODE_ENABLE_NON_VOLATILE 2 -#define HFA384X_PROGMODE_PROGRAM_NON_VOLATILE 3 - -#define HFA384X_AUX_MAGIC0 0xfe01 -#define HFA384X_AUX_MAGIC1 0xdc23 -#define HFA384X_AUX_MAGIC2 0xba45 - -#define HFA384X_AUX_PORT_DISABLED 0 -#define HFA384X_AUX_PORT_DISABLE BIT(14) -#define HFA384X_AUX_PORT_ENABLE BIT(15) -#define HFA384X_AUX_PORT_ENABLED (BIT(14) | BIT(15)) -#define HFA384X_AUX_PORT_MASK (BIT(14) | BIT(15)) - -#define PRISM2_PDA_SIZE 1024 - - -/* Events; EvStat, Interrupt mask (IntEn), and acknowledge bits (EvAck) */ -#define HFA384X_EV_TICK BIT(15) -#define HFA384X_EV_WTERR BIT(14) -#define HFA384X_EV_INFDROP BIT(13) -#ifdef PRISM2_PCI -#define HFA384X_EV_PCI_M1 BIT(9) -#define HFA384X_EV_PCI_M0 BIT(8) -#endif /* PRISM2_PCI */ -#define HFA384X_EV_INFO BIT(7) -#define HFA384X_EV_DTIM BIT(5) -#define HFA384X_EV_CMD BIT(4) -#define HFA384X_EV_ALLOC BIT(3) -#define HFA384X_EV_TXEXC BIT(2) -#define HFA384X_EV_TX BIT(1) -#define HFA384X_EV_RX BIT(0) - - -/* HFA384X Information frames */ -#define HFA384X_INFO_HANDOVERADDR 0xF000 /* AP f/w ? */ -#define HFA384X_INFO_HANDOVERDEAUTHADDR 0xF001 /* AP f/w 1.3.7 */ -#define HFA384X_INFO_COMMTALLIES 0xF100 -#define HFA384X_INFO_SCANRESULTS 0xF101 -#define HFA384X_INFO_CHANNELINFORESULTS 0xF102 /* AP f/w only */ -#define HFA384X_INFO_HOSTSCANRESULTS 0xF103 -#define HFA384X_INFO_LINKSTATUS 0xF200 -#define HFA384X_INFO_ASSOCSTATUS 0xF201 /* ? */ -#define HFA384X_INFO_AUTHREQ 0xF202 /* ? */ -#define HFA384X_INFO_PSUSERCNT 0xF203 /* ? */ -#define HFA384X_INFO_KEYIDCHANGED 0xF204 /* ? */ - -enum { HFA384X_LINKSTATUS_CONNECTED = 1, - HFA384X_LINKSTATUS_DISCONNECTED = 2, - HFA384X_LINKSTATUS_AP_CHANGE = 3, - HFA384X_LINKSTATUS_AP_OUT_OF_RANGE = 4, - HFA384X_LINKSTATUS_AP_IN_RANGE = 5, - HFA384X_LINKSTATUS_ASSOC_FAILED = 6 }; - -enum { HFA384X_PORTTYPE_BSS = 1, HFA384X_PORTTYPE_WDS = 2, - HFA384X_PORTTYPE_PSEUDO_IBSS = 3, HFA384X_PORTTYPE_IBSS = 0, - HFA384X_PORTTYPE_HOSTAP = 6 }; - -#define HFA384X_RATES_1MBPS BIT(0) -#define HFA384X_RATES_2MBPS BIT(1) -#define HFA384X_RATES_5MBPS BIT(2) -#define HFA384X_RATES_11MBPS BIT(3) - -#define HFA384X_ROAMING_FIRMWARE 1 -#define HFA384X_ROAMING_HOST 2 -#define HFA384X_ROAMING_DISABLED 3 - -#define HFA384X_WEPFLAGS_PRIVACYINVOKED BIT(0) -#define HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED BIT(1) -#define HFA384X_WEPFLAGS_HOSTENCRYPT BIT(4) -#define HFA384X_WEPFLAGS_HOSTDECRYPT BIT(7) - -#define HFA384X_RX_STATUS_MSGTYPE (BIT(15) | BIT(14) | BIT(13)) -#define HFA384X_RX_STATUS_PCF BIT(12) -#define HFA384X_RX_STATUS_MACPORT (BIT(10) | BIT(9) | BIT(8)) -#define HFA384X_RX_STATUS_UNDECR BIT(1) -#define HFA384X_RX_STATUS_FCSERR BIT(0) - -#define HFA384X_RX_STATUS_GET_MSGTYPE(s) \ -(((s) & HFA384X_RX_STATUS_MSGTYPE) >> 13) -#define HFA384X_RX_STATUS_GET_MACPORT(s) \ -(((s) & HFA384X_RX_STATUS_MACPORT) >> 8) - -enum { HFA384X_RX_MSGTYPE_NORMAL = 0, HFA384X_RX_MSGTYPE_RFC1042 = 1, - HFA384X_RX_MSGTYPE_BRIDGETUNNEL = 2, HFA384X_RX_MSGTYPE_MGMT = 4 }; - - -#define HFA384X_TX_CTRL_ALT_RTRY BIT(5) -#define HFA384X_TX_CTRL_802_11 BIT(3) -#define HFA384X_TX_CTRL_802_3 0 -#define HFA384X_TX_CTRL_TX_EX BIT(2) -#define HFA384X_TX_CTRL_TX_OK BIT(1) - -#define HFA384X_TX_STATUS_RETRYERR BIT(0) -#define HFA384X_TX_STATUS_AGEDERR BIT(1) -#define HFA384X_TX_STATUS_DISCON BIT(2) -#define HFA384X_TX_STATUS_FORMERR BIT(3) - -/* HFA3861/3863 (BBP) Control Registers */ -#define HFA386X_CR_TX_CONFIGURE 0x12 /* CR9 */ -#define HFA386X_CR_RX_CONFIGURE 0x14 /* CR10 */ -#define HFA386X_CR_A_D_TEST_MODES2 0x1A /* CR13 */ -#define HFA386X_CR_MANUAL_TX_POWER 0x3E /* CR31 */ -#define HFA386X_CR_MEASURED_TX_POWER 0x74 /* CR58 */ - - -#ifdef __KERNEL__ - -#define PRISM2_TXFID_COUNT 8 -#define PRISM2_DATA_MAXLEN 2304 -#define PRISM2_TXFID_LEN (PRISM2_DATA_MAXLEN + sizeof(struct hfa384x_tx_frame)) -#define PRISM2_TXFID_EMPTY 0xffff -#define PRISM2_TXFID_RESERVED 0xfffe -#define PRISM2_DUMMY_FID 0xffff -#define MAX_SSID_LEN 32 -#define MAX_NAME_LEN 32 /* this is assumed to be equal to MAX_SSID_LEN */ - -#define PRISM2_DUMP_RX_HDR BIT(0) -#define PRISM2_DUMP_TX_HDR BIT(1) -#define PRISM2_DUMP_TXEXC_HDR BIT(2) - -struct hostap_tx_callback_info { - u16 idx; - void (*func)(struct sk_buff *, int ok, void *); - void *data; - struct hostap_tx_callback_info *next; -}; - - -/* IEEE 802.11 requires that STA supports concurrent reception of at least - * three fragmented frames. This define can be increased to support more - * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ -#define PRISM2_FRAG_CACHE_LEN 4 - -struct prism2_frag_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int last_frag; - struct sk_buff *skb; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; -}; - - -struct hostap_cmd_queue { - struct list_head list; - wait_queue_head_t compl; - volatile enum { CMD_SLEEP, CMD_CALLBACK, CMD_COMPLETED } type; - void (*callback)(struct net_device *dev, long context, u16 resp0, - u16 res); - long context; - u16 cmd, param0, param1; - u16 resp0, res; - volatile int issued, issuing; - - atomic_t usecnt; - int del_req; -}; - -/* options for hw_shutdown */ -#define HOSTAP_HW_NO_DISABLE BIT(0) -#define HOSTAP_HW_ENABLE_CMDCOMPL BIT(1) - -typedef struct local_info local_info_t; - -struct prism2_helper_functions { - /* these functions are defined in hardware model specific files - * (hostap_{cs,plx,pci}.c */ - int (*card_present)(local_info_t *local); - void (*cor_sreset)(local_info_t *local); - int (*dev_open)(local_info_t *local); - int (*dev_close)(local_info_t *local); - void (*genesis_reset)(local_info_t *local, int hcr); - - /* the following functions are from hostap_hw.c, but they may have some - * hardware model specific code */ - - /* FIX: low-level commands like cmd might disappear at some point to - * make it easier to change them if needed (e.g., cmd would be replaced - * with write_mif/read_mif/testcmd/inquire); at least get_rid and - * set_rid might move to hostap_{cs,plx,pci}.c */ - int (*cmd)(struct net_device *dev, u16 cmd, u16 param0, u16 *param1, - u16 *resp0); - void (*read_regs)(struct net_device *dev, struct hfa384x_regs *regs); - int (*get_rid)(struct net_device *dev, u16 rid, void *buf, int len, - int exact_len); - int (*set_rid)(struct net_device *dev, u16 rid, void *buf, int len); - int (*hw_enable)(struct net_device *dev, int initial); - int (*hw_config)(struct net_device *dev, int initial); - void (*hw_reset)(struct net_device *dev); - void (*hw_shutdown)(struct net_device *dev, int no_disable); - int (*reset_port)(struct net_device *dev); - void (*schedule_reset)(local_info_t *local); - int (*download)(local_info_t *local, - struct prism2_download_param *param); - int (*tx)(struct sk_buff *skb, struct net_device *dev); - int (*set_tim)(struct net_device *dev, int aid, int set); - int (*read_aux)(struct net_device *dev, unsigned addr, int len, - u8 *buf); - - int need_tx_headroom; /* number of bytes of headroom needed before - * IEEE 802.11 header */ - enum { HOSTAP_HW_PCCARD, HOSTAP_HW_PLX, HOSTAP_HW_PCI } hw_type; -}; - - -struct prism2_download_data { - u32 dl_cmd; - u32 start_addr; - u32 num_areas; - struct prism2_download_data_area { - u32 addr; /* wlan card address */ - u32 len; - u8 *data; /* allocated data */ - } data[0]; -}; - - -#define HOSTAP_MAX_BSS_COUNT 64 -#define MAX_WPA_IE_LEN 64 - -struct hostap_bss_info { - struct list_head list; - unsigned long last_update; - unsigned int count; - u8 bssid[ETH_ALEN]; - u16 capab_info; - u8 ssid[32]; - size_t ssid_len; - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - int chan; - int included; -}; - - -/* Per radio private Host AP data - shared by all net devices interfaces used - * by each radio (wlan#, wlan#ap, wlan#sta, WDS). - * ((struct hostap_interface *) netdev_priv(dev))->local points to this - * structure. */ -struct local_info { - struct module *hw_module; - int card_idx; - int dev_enabled; - int master_dev_auto_open; /* was master device opened automatically */ - int num_dev_open; /* number of open devices */ - struct net_device *dev; /* master radio device */ - struct net_device *ddev; /* main data device */ - struct list_head hostap_interfaces; /* Host AP interface list (contains - * struct hostap_interface entries) - */ - rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock - * when removing entries from the list. - * TX and RX paths can use read lock. */ - spinlock_t cmdlock, baplock, lock; - struct semaphore rid_bap_sem; - u16 infofid; /* MAC buffer id for info frame */ - /* txfid, intransmitfid, next_txtid, and next_alloc are protected by - * txfidlock */ - spinlock_t txfidlock; - int txfid_len; /* length of allocated TX buffers */ - u16 txfid[PRISM2_TXFID_COUNT]; /* buffer IDs for TX frames */ - /* buffer IDs for intransmit frames or PRISM2_TXFID_EMPTY if - * corresponding txfid is free for next TX frame */ - u16 intransmitfid[PRISM2_TXFID_COUNT]; - int next_txfid; /* index to the next txfid to be checked for - * availability */ - int next_alloc; /* index to the next intransmitfid to be checked for - * allocation events */ - - /* bitfield for atomic bitops */ -#define HOSTAP_BITS_TRANSMIT 0 -#define HOSTAP_BITS_BAP_TASKLET 1 -#define HOSTAP_BITS_BAP_TASKLET2 2 - long bits; - - struct ap_data *ap; - - char essid[MAX_SSID_LEN + 1]; - char name[MAX_NAME_LEN + 1]; - int name_set; - u16 channel_mask; /* mask of allowed channels */ - u16 scan_channel_mask; /* mask of channels to be scanned */ - struct comm_tallies_sums comm_tallies; - struct net_device_stats stats; - struct proc_dir_entry *proc; - int iw_mode; /* operating mode (IW_MODE_*) */ - int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS - * 1: IW_MODE_ADHOC is "pseudo IBSS" */ - char bssid[ETH_ALEN]; - int channel; - int beacon_int; - int dtim_period; - int mtu; - int frame_dump; /* dump RX/TX frame headers, PRISM2_DUMP_ flags */ - int fw_tx_rate_control; - u16 tx_rate_control; - u16 basic_rates; - int hw_resetting; - int hw_ready; - int hw_reset_tries; /* how many times reset has been tried */ - int hw_downloading; - int shutdown; - int pri_only; - int no_pri; /* no PRI f/w present */ - int sram_type; /* 8 = x8 SRAM, 16 = x16 SRAM, -1 = unknown */ - - enum { - PRISM2_TXPOWER_AUTO = 0, PRISM2_TXPOWER_OFF, - PRISM2_TXPOWER_FIXED, PRISM2_TXPOWER_UNKNOWN - } txpower_type; - int txpower; /* if txpower_type == PRISM2_TXPOWER_FIXED */ - - /* command queue for hfa384x_cmd(); protected with cmdlock */ - struct list_head cmd_queue; - /* max_len for cmd_queue; in addition, cmd_callback can use two - * additional entries to prevent sleeping commands from stopping - * transmits */ -#define HOSTAP_CMD_QUEUE_MAX_LEN 16 - int cmd_queue_len; /* number of entries in cmd_queue */ - - /* if card timeout is detected in interrupt context, reset_queue is - * used to schedule card reseting to be done in user context */ - struct work_struct reset_queue; - - /* For scheduling a change of the promiscuous mode RID */ - int is_promisc; - struct work_struct set_multicast_list_queue; - - struct work_struct set_tim_queue; - struct list_head set_tim_list; - spinlock_t set_tim_lock; - - int wds_max_connections; - int wds_connections; -#define HOSTAP_WDS_BROADCAST_RA BIT(0) -#define HOSTAP_WDS_AP_CLIENT BIT(1) -#define HOSTAP_WDS_STANDARD_FRAME BIT(2) - u32 wds_type; - u16 tx_control; /* flags to be used in TX description */ - int manual_retry_count; /* -1 = use f/w default; otherwise retry count - * to be used with all frames */ - - struct iw_statistics wstats; - unsigned long scan_timestamp; /* Time started to scan */ - enum { - PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1, - PRISM2_MONITOR_CAPHDR = 2 - } monitor_type; - int (*saved_eth_header_parse)(struct sk_buff *skb, - unsigned char *haddr); - int monitor_allow_fcserr; - - int hostapd; /* whether user space daemon, hostapd, is used for AP - * management */ - int hostapd_sta; /* whether hostapd is used with an extra STA interface - */ - struct net_device *apdev; - struct net_device_stats apdevstats; - - char assoc_ap_addr[ETH_ALEN]; - struct net_device *stadev; - struct net_device_stats stadevstats; - -#define WEP_KEYS 4 -#define WEP_KEY_LEN 13 - struct ieee80211_crypt_data *crypt[WEP_KEYS]; - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ - struct timer_list crypt_deinit_timer; - struct list_head crypt_deinit_list; - - int open_wep; /* allow unencrypted frames */ - int host_encrypt; - int host_decrypt; - int privacy_invoked; /* force privacy invoked flag even if no keys are - * configured */ - int fw_encrypt_ok; /* whether firmware-based WEP encrypt is working - * in Host AP mode (STA f/w 1.4.9 or newer) */ - int bcrx_sta_key; /* use individual keys to override default keys even - * with RX of broad/multicast frames */ - - struct prism2_frag_entry frag_cache[PRISM2_FRAG_CACHE_LEN]; - unsigned int frag_next_idx; - - int ieee_802_1x; /* is IEEE 802.1X used */ - - int antsel_tx, antsel_rx; - int rts_threshold; /* dot11RTSThreshold */ - int fragm_threshold; /* dot11FragmentationThreshold */ - int auth_algs; /* PRISM2_AUTH_ flags */ - - int enh_sec; /* cnfEnhSecurity options (broadcast SSID hide/ignore) */ - int tallies32; /* 32-bit tallies in use */ - - struct prism2_helper_functions *func; - - int bus_master_threshold_tx; - int bus_master_threshold_rx; - u8 *bus_m1_buf; - - u8 *pda; - int fw_ap; -#define PRISM2_FW_VER(major, minor, variant) \ -(((major) << 16) | ((minor) << 8) | variant) - u32 sta_fw_ver; - - /* Tasklets for handling hardware IRQ related operations outside hw IRQ - * handler */ - struct tasklet_struct bap_tasklet; - - struct tasklet_struct info_tasklet; - struct sk_buff_head info_list; /* info frames as skb's for - * info_tasklet */ - - struct hostap_tx_callback_info *tx_callback; /* registered TX callbacks - */ - - struct tasklet_struct rx_tasklet; - struct sk_buff_head rx_list; - - struct tasklet_struct sta_tx_exc_tasklet; - struct sk_buff_head sta_tx_exc_list; - - int host_roaming; - unsigned long last_join_time; /* time of last JoinRequest */ - struct hfa384x_hostscan_result *last_scan_results; - int last_scan_results_count; - enum { PRISM2_SCAN, PRISM2_HOSTSCAN } last_scan_type; - struct work_struct info_queue; - long pending_info; /* bit field of pending info_queue items */ -#define PRISM2_INFO_PENDING_LINKSTATUS 0 -#define PRISM2_INFO_PENDING_SCANRESULTS 1 - int prev_link_status; /* previous received LinkStatus info */ - int prev_linkstatus_connected; - u8 preferred_ap[6]; /* use this AP if possible */ - -#ifdef PRISM2_CALLBACK - void *callback_data; /* Can be used in callbacks; e.g., allocate - * on enable event and free on disable event. - * Host AP driver code does not touch this. */ -#endif /* PRISM2_CALLBACK */ - - wait_queue_head_t hostscan_wq; - - /* Passive scan in Host AP mode */ - struct timer_list passive_scan_timer; - int passive_scan_interval; /* in seconds, 0 = disabled */ - int passive_scan_channel; - enum { PASSIVE_SCAN_WAIT, PASSIVE_SCAN_LISTEN } passive_scan_state; - - struct timer_list tick_timer; - unsigned long last_tick_timer; - unsigned int sw_tick_stuck; - - /* commsQuality / dBmCommsQuality data from periodic polling; only - * valid for Managed and Ad-hoc modes */ - unsigned long last_comms_qual_update; - int comms_qual; /* in some odd unit.. */ - int avg_signal; /* in dB (note: negative) */ - int avg_noise; /* in dB (note: negative) */ - struct work_struct comms_qual_update; - - /* RSSI to dBm adjustment (for RX descriptor fields) */ - int rssi_to_dBm; /* substract from RSSI to get approximate dBm value */ - - /* BSS list / protected by local->lock */ - struct list_head bss_list; - int num_bss_info; - int wpa; /* WPA support enabled */ - int tkip_countermeasures; - int drop_unencrypted; - /* Generic IEEE 802.11 info element to be added to - * ProbeResp/Beacon/(Re)AssocReq */ - u8 *generic_elem; - size_t generic_elem_len; - -#ifdef PRISM2_DOWNLOAD_SUPPORT - /* Persistent volatile download data */ - struct prism2_download_data *dl_pri; - struct prism2_download_data *dl_sec; -#endif /* PRISM2_DOWNLOAD_SUPPORT */ - -#ifdef PRISM2_IO_DEBUG -#define PRISM2_IO_DEBUG_SIZE 10000 - u32 io_debug[PRISM2_IO_DEBUG_SIZE]; - int io_debug_head; - int io_debug_enabled; -#endif /* PRISM2_IO_DEBUG */ - - /* struct local_info is used also in hostap.o that does not define - * any PRISM2_{PCCARD,PLX,PCI}. Make sure that the hardware version - * specific fields are in the end of the struct (these could also be - * moved to void *priv or something like that). */ -#ifdef PRISM2_PCCARD - dev_node_t node; - dev_link_t *link; - int sandisk_connectplus; -#endif /* PRISM2_PCCARD */ - -#ifdef PRISM2_PLX - void __iomem *attr_mem; - unsigned int cor_offset; -#endif /* PRISM2_PLX */ - -#ifdef PRISM2_PCI - void __iomem *mem_start; -#ifdef PRISM2_BUS_MASTER - /* bus master for BAP0 (TX) */ - int bus_m0_tx_idx; - u8 *bus_m0_buf; - - /* bus master for BAP1 (RX) */ - struct sk_buff *rx_skb; -#endif /* PRISM2_BUS_MASTER */ -#endif /* PRISM2_PCI */ - - /* NOTE! Do not add common entries here after hardware version - * specific blocks. */ -}; - - -/* Per interface private Host AP data - * Allocated for each net device that Host AP uses (wlan#, wlan#ap, wlan#sta, - * WDS) and netdev_priv(dev) points to this structure. */ -struct hostap_interface { - struct list_head list; /* list entry in Host AP interface list */ - struct net_device *dev; /* pointer to this device */ - struct local_info *local; /* pointer to shared private data */ - struct net_device_stats stats; - struct iw_spy_data spy_data; /* iwspy support */ - struct iw_public_data wireless_data; - - enum { - HOSTAP_INTERFACE_MASTER, - HOSTAP_INTERFACE_MAIN, - HOSTAP_INTERFACE_AP, - HOSTAP_INTERFACE_STA, - HOSTAP_INTERFACE_WDS, - } type; - - union { - struct hostap_interface_wds { - u8 remote_addr[ETH_ALEN]; - } wds; - } u; -}; - - -#define HOSTAP_SKB_TX_DATA_MAGIC 0xf08a36a2 - -/* TX meta data - stored in skb->cb buffer, so this must be not increase over - * 48-byte limit */ -struct hostap_skb_tx_data { - unsigned int magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ - int rate; /* transmit rate */ - struct hostap_interface *iface; - unsigned long jiffies; /* queueing timestamp */ - int wds; - unsigned short ethertype; - int tx_cb_idx; -}; - - -#ifndef PRISM2_NO_DEBUG - -#define DEBUG_FID BIT(0) -#define DEBUG_PS BIT(1) -#define DEBUG_FLOW BIT(2) -#define DEBUG_AP BIT(3) -#define DEBUG_HW BIT(4) -#define DEBUG_EXTRA BIT(5) -#define DEBUG_EXTRA2 BIT(6) -#define DEBUG_PS2 BIT(7) -#define DEBUG_MASK (DEBUG_PS | DEBUG_AP | DEBUG_HW | DEBUG_EXTRA) -#define PDEBUG(n, args...) \ -do { if ((n) & DEBUG_MASK) printk(KERN_DEBUG args); } while (0) -#define PDEBUG2(n, args...) \ -do { if ((n) & DEBUG_MASK) printk(args); } while (0) - -#else /* PRISM2_NO_DEBUG */ - -#define PDEBUG(n, args...) -#define PDEBUG2(n, args...) - -#endif /* PRISM2_NO_DEBUG */ - -enum { BAP0 = 0, BAP1 = 1 }; - -#define PRISM2_IO_DEBUG_CMD_INB 0 -#define PRISM2_IO_DEBUG_CMD_INW 1 -#define PRISM2_IO_DEBUG_CMD_INSW 2 -#define PRISM2_IO_DEBUG_CMD_OUTB 3 -#define PRISM2_IO_DEBUG_CMD_OUTW 4 -#define PRISM2_IO_DEBUG_CMD_OUTSW 5 -#define PRISM2_IO_DEBUG_CMD_ERROR 6 -#define PRISM2_IO_DEBUG_CMD_INTERRUPT 7 - -#ifdef PRISM2_IO_DEBUG - -#define PRISM2_IO_DEBUG_ENTRY(cmd, reg, value) \ -(((cmd) << 24) | ((reg) << 16) | value) - -static inline void prism2_io_debug_add(struct net_device *dev, int cmd, - int reg, int value) -{ - struct hostap_interface *iface = netdev_priv(dev); - local_info_t *local = iface->local; - - if (!local->io_debug_enabled) - return; - - local->io_debug[local->io_debug_head] = jiffies & 0xffffffff; - if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE) - local->io_debug_head = 0; - local->io_debug[local->io_debug_head] = - PRISM2_IO_DEBUG_ENTRY(cmd, reg, value); - if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE) - local->io_debug_head = 0; -} - - -static inline void prism2_io_debug_error(struct net_device *dev, int err) -{ - struct hostap_interface *iface = netdev_priv(dev); - local_info_t *local = iface->local; - unsigned long flags; - - if (!local->io_debug_enabled) - return; - - spin_lock_irqsave(&local->lock, flags); - prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_ERROR, 0, err); - if (local->io_debug_enabled == 1) { - local->io_debug_enabled = 0; - printk(KERN_DEBUG "%s: I/O debug stopped\n", dev->name); - } - spin_unlock_irqrestore(&local->lock, flags); -} - -#else /* PRISM2_IO_DEBUG */ - -static inline void prism2_io_debug_add(struct net_device *dev, int cmd, - int reg, int value) -{ -} - -static inline void prism2_io_debug_error(struct net_device *dev, int err) -{ -} - -#endif /* PRISM2_IO_DEBUG */ - - -#ifdef PRISM2_CALLBACK -enum { - /* Called when card is enabled */ - PRISM2_CALLBACK_ENABLE, - - /* Called when card is disabled */ - PRISM2_CALLBACK_DISABLE, - - /* Called when RX/TX starts/ends */ - PRISM2_CALLBACK_RX_START, PRISM2_CALLBACK_RX_END, - PRISM2_CALLBACK_TX_START, PRISM2_CALLBACK_TX_END -}; -void prism2_callback(local_info_t *local, int event); -#else /* PRISM2_CALLBACK */ -#define prism2_callback(d, e) do { } while (0) -#endif /* PRISM2_CALLBACK */ - -#endif /* __KERNEL__ */ - -#endif /* HOSTAP_WLAN_H */ diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index 133666d43d7e..5df203155aa3 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -1,5 +1,5 @@ /****************************************************************************** - + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 802.11 status code portion of this file from ethereal-0.10.6: @@ -8,22 +8,22 @@ By Gerald Combs Copyright 1998 Gerald Combs - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 + this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + The full GNU General Public License is included in this distribution in the file called LICENSE. - + Contact Information: James P. Ketrenos Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -56,7 +56,7 @@ static const char ipw_modes[] = { }; static void ipw_rx(struct ipw_priv *priv); -static int ipw_queue_tx_reclaim(struct ipw_priv *priv, +static int ipw_queue_tx_reclaim(struct ipw_priv *priv, struct clx2_tx_queue *txq, int qindex); static int ipw_queue_reset(struct ipw_priv *priv); @@ -101,23 +101,23 @@ static int is_valid_channel(int mode_mask, int channel) return 0; } -static char *snprint_line(char *buf, size_t count, +static char *snprint_line(char *buf, size_t count, const u8 *data, u32 len, u32 ofs) { int out, i, j, l; char c; - + out = snprintf(buf, count, "%08X", ofs); for (l = 0, i = 0; i < 2; i++) { out += snprintf(buf + out, count - out, " "); - for (j = 0; j < 8 && l < len; j++, l++) - out += snprintf(buf + out, count - out, "%02X ", + for (j = 0; j < 8 && l < len; j++, l++) + out += snprintf(buf + out, count - out, "%02X ", data[(i * 8 + j)]); for (; j < 8; j++) out += snprintf(buf + out, count - out, " "); } - + out += snprintf(buf + out, count - out, " "); for (l = 0, i = 0; i < 2; i++) { out += snprintf(buf + out, count - out, " "); @@ -125,14 +125,14 @@ static char *snprint_line(char *buf, size_t count, c = data[(i * 8 + j)]; if (!isascii(c) || !isprint(c)) c = '.'; - + out += snprintf(buf + out, count - out, "%c", c); } for (; j < 8; j++) out += snprintf(buf + out, count - out, " "); } - + return buf; } @@ -145,7 +145,7 @@ static void printk_buf(int level, const u8 *data, u32 len) while (len) { printk(KERN_DEBUG "%s\n", - snprint_line(line, sizeof(line), &data[ofs], + snprint_line(line, sizeof(line), &data[ofs], min(len, 16U), ofs)); ofs += 16; len -= min(len, 16U); @@ -161,21 +161,21 @@ static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg); static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value); static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c) { - IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); + IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); _ipw_write_reg8(a, b, c); } static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value); static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c) { - IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); + IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); _ipw_write_reg16(a, b, c); } static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value); static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c) { - IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); + IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(b), (u32)(c)); _ipw_write_reg32(a, b, c); } @@ -229,7 +229,7 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *data, int n static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) { - IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", + IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); _ipw_write32(priv, CX2_INDIRECT_DATA, value); @@ -241,7 +241,7 @@ static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); _ipw_write8(priv, CX2_INDIRECT_DATA, value); - IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n", + IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n", (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value); } @@ -285,7 +285,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, u32 dif_len = addr - aligned_addr; u32 aligned_len; u32 i; - + IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); /* Read the first nibble byte by byte */ @@ -303,7 +303,7 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, aligned_len = num & CX2_INDIRECT_ADDR_MASK; for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) *(u32*)buf = ipw_read32(priv, CX2_AUTOINC_DATA); - + /* Copy the last nibble */ dif_len = num - aligned_len; _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); @@ -311,16 +311,16 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); } -static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf, +static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf, int num) { u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; u32 dif_len = addr - aligned_addr; u32 aligned_len; u32 i; - + IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); - + /* Write the first nibble byte by byte */ if (unlikely(dif_len)) { /* Start writing at aligned_addr + dif_len */ @@ -330,13 +330,13 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf, num -= dif_len; aligned_addr += 4; } - + /* Write DWs through autoinc register */ _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); aligned_len = num & CX2_INDIRECT_ADDR_MASK; for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32*)buf); - + /* Copy the last nibble */ dif_len = num - aligned_len; _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); @@ -344,7 +344,7 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 *buf, _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); } -static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, +static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, int num) { memcpy_toio((priv->hw_base + addr), buf, num); @@ -379,37 +379,37 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv) static char *ipw_error_desc(u32 val) { switch (val) { - case IPW_FW_ERROR_OK: + case IPW_FW_ERROR_OK: return "ERROR_OK"; - case IPW_FW_ERROR_FAIL: + case IPW_FW_ERROR_FAIL: return "ERROR_FAIL"; - case IPW_FW_ERROR_MEMORY_UNDERFLOW: + case IPW_FW_ERROR_MEMORY_UNDERFLOW: return "MEMORY_UNDERFLOW"; - case IPW_FW_ERROR_MEMORY_OVERFLOW: + case IPW_FW_ERROR_MEMORY_OVERFLOW: return "MEMORY_OVERFLOW"; - case IPW_FW_ERROR_BAD_PARAM: + case IPW_FW_ERROR_BAD_PARAM: return "ERROR_BAD_PARAM"; - case IPW_FW_ERROR_BAD_CHECKSUM: + case IPW_FW_ERROR_BAD_CHECKSUM: return "ERROR_BAD_CHECKSUM"; - case IPW_FW_ERROR_NMI_INTERRUPT: + case IPW_FW_ERROR_NMI_INTERRUPT: return "ERROR_NMI_INTERRUPT"; - case IPW_FW_ERROR_BAD_DATABASE: + case IPW_FW_ERROR_BAD_DATABASE: return "ERROR_BAD_DATABASE"; - case IPW_FW_ERROR_ALLOC_FAIL: + case IPW_FW_ERROR_ALLOC_FAIL: return "ERROR_ALLOC_FAIL"; - case IPW_FW_ERROR_DMA_UNDERRUN: + case IPW_FW_ERROR_DMA_UNDERRUN: return "ERROR_DMA_UNDERRUN"; - case IPW_FW_ERROR_DMA_STATUS: + case IPW_FW_ERROR_DMA_STATUS: return "ERROR_DMA_STATUS"; - case IPW_FW_ERROR_DINOSTATUS_ERROR: + case IPW_FW_ERROR_DINOSTATUS_ERROR: return "ERROR_DINOSTATUS_ERROR"; - case IPW_FW_ERROR_EEPROMSTATUS_ERROR: + case IPW_FW_ERROR_EEPROMSTATUS_ERROR: return "ERROR_EEPROMSTATUS_ERROR"; - case IPW_FW_ERROR_SYSASSERT: + case IPW_FW_ERROR_SYSASSERT: return "ERROR_SYSASSERT"; - case IPW_FW_ERROR_FATAL_ERROR: + case IPW_FW_ERROR_FATAL_ERROR: return "ERROR_FATALSTATUS_ERROR"; - default: + default: return "UNKNOWNSTATUS_ERROR"; } } @@ -420,15 +420,15 @@ static void ipw_dump_nic_error_log(struct ipw_priv *priv) base = ipw_read32(priv, IPWSTATUS_ERROR_LOG); count = ipw_read_reg32(priv, base); - + if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { IPW_ERROR("Start IPW Error Log Dump:\n"); IPW_ERROR("Status: 0x%08X, Config: %08X\n", priv->status, priv->config); } - for (i = ERROR_START_OFFSET; - i <= count * ERROR_ELEM_SIZE; + for (i = ERROR_START_OFFSET; + i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) { desc = ipw_read_reg32(priv, base + i); time = ipw_read_reg32(priv, base + i + 1*sizeof(u32)); @@ -439,8 +439,8 @@ static void ipw_dump_nic_error_log(struct ipw_priv *priv) idata = ipw_read_reg32(priv, base + i + 6*sizeof(u32)); IPW_ERROR( - "%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", - ipw_error_desc(desc), time, blink1, blink2, + "%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + ipw_error_desc(desc), time, blink1, blink2, ilink1, ilink2, idata); } } @@ -451,12 +451,12 @@ static void ipw_dump_nic_event_log(struct ipw_priv *priv) base = ipw_read32(priv, IPW_EVENT_LOG); count = ipw_read_reg32(priv, base); - + if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE) IPW_ERROR("Start IPW Event Log Dump:\n"); - for (i = EVENT_START_OFFSET; - i <= count * EVENT_ELEM_SIZE; + for (i = EVENT_START_OFFSET; + i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) { ev = ipw_read_reg32(priv, base + i); time = ipw_read_reg32(priv, base + i + 1*sizeof(u32)); @@ -479,7 +479,7 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, IPW_DEBUG_ORD("Invalid argument\n"); return -EINVAL; } - + /* verify device ordinal tables have been initialized */ if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) { IPW_DEBUG_ORD("Access ordinals before initialization\n"); @@ -491,7 +491,7 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, /* * TABLE 0: Direct access to a table of 32 bit values * - * This is a very simple table with the data directly + * This is a very simple table with the data directly * read from the table */ @@ -523,15 +523,15 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, case IPW_ORD_TABLE_1_MASK: /* * TABLE 1: Indirect access to a table of 32 bit values - * - * This is a fairly large table of u32 values each + * + * This is a fairly large table of u32 values each * representing starting addr for the data (which is * also a u32) */ /* remove the table id from the ordinal */ ord &= IPW_ORD_TABLE_VALUE_MASK; - + /* boundary check */ if (ord > priv->table1_len) { IPW_DEBUG_ORD("ordinal value too long\n"); @@ -570,30 +570,30 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, /* get the address of statistic */ addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3)); - - /* get the second DW of statistics ; + + /* get the second DW of statistics ; * two 16-bit words - first is length, second is count */ field_info = ipw_read_reg32(priv, priv->table2_addr + (ord << 3) + sizeof(u32)); - + /* get each entry length */ field_len = *((u16 *)&field_info); - + /* get number of entries */ field_count = *(((u16 *)&field_info) + 1); - + /* abort if not enought memory */ total_len = field_len * field_count; if (total_len > *len) { *len = total_len; return -EINVAL; } - + *len = total_len; if (!total_len) return 0; IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, " - "field_info = 0x%08x\n", + "field_info = 0x%08x\n", addr, total_len, field_info); ipw_read_indirect(priv, addr, val, total_len); break; @@ -604,14 +604,14 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, } - + return 0; } static void ipw_init_ordinals(struct ipw_priv *priv) { priv->table0_addr = IPW_ORDINALS_TABLE_LOWER; - priv->table0_len = ipw_read32(priv, priv->table0_addr); + priv->table0_len = ipw_read32(priv, priv->table0_addr); IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n", priv->table0_addr, priv->table0_len); @@ -635,7 +635,7 @@ static void ipw_init_ordinals(struct ipw_priv *priv) * The following adds a new attribute to the sysfs representation * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) * used for controling the debug level. - * + * * See the level definitions in ipw for details. */ static ssize_t show_debug_level(struct device_driver *d, char *buf) @@ -655,8 +655,8 @@ static ssize_t store_debug_level(struct device_driver *d, val = simple_strtoul(p, &p, 16); } else val = simple_strtoul(p, &p, 10); - if (p == buf) - printk(KERN_INFO DRV_NAME + if (p == buf) + printk(KERN_INFO DRV_NAME ": %s is not in hex or decimal form.\n", buf); else ipw_debug_level = val; @@ -664,7 +664,7 @@ static ssize_t store_debug_level(struct device_driver *d, return strnlen(buf, count); } -static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, +static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, store_debug_level); static ssize_t show_status(struct device *d, @@ -701,7 +701,7 @@ static ssize_t show_nic_type(struct device *d, case EEPROM_NIC_TYPE_HP: return sprintf(buf, "HP\n"); } - + return sprintf(buf, "UNKNOWN\n"); } static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); @@ -711,7 +711,7 @@ static ssize_t dump_error_log(struct device *d, { char *p = (char *)buf; - if (p[0] == '1') + if (p[0] == '1') ipw_dump_nic_error_log((struct ipw_priv*)d->driver_data); return strnlen(buf, count); @@ -723,7 +723,7 @@ static ssize_t dump_event_log(struct device *d, { char *p = (char *)buf; - if (p[0] == '1') + if (p[0] == '1') ipw_dump_nic_event_log((struct ipw_priv*)d->driver_data); return strnlen(buf, count); @@ -774,7 +774,7 @@ static ssize_t store_eeprom_delay(struct device *d, sscanf(buf, "%i", &p->eeprom_delay); return strnlen(buf, count); } -static DEVICE_ATTR(eeprom_delay, S_IWUSR|S_IRUGO, +static DEVICE_ATTR(eeprom_delay, S_IWUSR|S_IRUGO, show_eeprom_delay,store_eeprom_delay); static ssize_t show_command_event_reg(struct device *d, @@ -797,7 +797,7 @@ static ssize_t store_command_event_reg(struct device *d, ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); return strnlen(buf, count); } -static DEVICE_ATTR(command_event_reg, S_IWUSR|S_IRUGO, +static DEVICE_ATTR(command_event_reg, S_IWUSR|S_IRUGO, show_command_event_reg,store_command_event_reg); static ssize_t show_mem_gpio_reg(struct device *d, @@ -828,11 +828,11 @@ static ssize_t show_indirect_dword(struct device *d, { u32 reg = 0; struct ipw_priv *priv = d->driver_data; - if (priv->status & STATUS_INDIRECT_DWORD) + if (priv->status & STATUS_INDIRECT_DWORD) reg = ipw_read_reg32(priv, priv->indirect_dword); - else + else reg = 0; - + return sprintf(buf, "0x%08x\n", reg); } static ssize_t store_indirect_dword(struct device *d, @@ -845,7 +845,7 @@ static ssize_t store_indirect_dword(struct device *d, priv->status |= STATUS_INDIRECT_DWORD; return strnlen(buf, count); } -static DEVICE_ATTR(indirect_dword, S_IWUSR|S_IRUGO, +static DEVICE_ATTR(indirect_dword, S_IWUSR|S_IRUGO, show_indirect_dword,store_indirect_dword); static ssize_t show_indirect_byte(struct device *d, @@ -853,9 +853,9 @@ static ssize_t show_indirect_byte(struct device *d, { u8 reg = 0; struct ipw_priv *priv = d->driver_data; - if (priv->status & STATUS_INDIRECT_BYTE) + if (priv->status & STATUS_INDIRECT_BYTE) reg = ipw_read_reg8(priv, priv->indirect_byte); - else + else reg = 0; return sprintf(buf, "0x%02x\n", reg); @@ -870,7 +870,7 @@ static ssize_t store_indirect_byte(struct device *d, priv->status |= STATUS_INDIRECT_BYTE; return strnlen(buf, count); } -static DEVICE_ATTR(indirect_byte, S_IWUSR|S_IRUGO, +static DEVICE_ATTR(indirect_byte, S_IWUSR|S_IRUGO, show_indirect_byte, store_indirect_byte); static ssize_t show_direct_dword(struct device *d, @@ -879,9 +879,9 @@ static ssize_t show_direct_dword(struct device *d, u32 reg = 0; struct ipw_priv *priv = d->driver_data; - if (priv->status & STATUS_DIRECT_DWORD) + if (priv->status & STATUS_DIRECT_DWORD) reg = ipw_read32(priv, priv->direct_dword); - else + else reg = 0; return sprintf(buf, "0x%08x\n", reg); @@ -896,7 +896,7 @@ static ssize_t store_direct_dword(struct device *d, priv->status |= STATUS_DIRECT_DWORD; return strnlen(buf, count); } -static DEVICE_ATTR(direct_dword, S_IWUSR|S_IRUGO, +static DEVICE_ATTR(direct_dword, S_IWUSR|S_IRUGO, show_direct_dword,store_direct_dword); @@ -914,7 +914,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, char *buf) { /* 0 - RF kill not enabled - 1 - SW based RF kill active (sysfs) + 1 - SW based RF kill active (sysfs) 2 - HW based RF kill active 3 - Both HW and SW baed RF kill active */ struct ipw_priv *priv = d->driver_data; @@ -925,7 +925,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) { - if ((disable_radio ? 1 : 0) == + if ((disable_radio ? 1 : 0) == (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) return 0 ; @@ -935,7 +935,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) if (disable_radio) { priv->status |= STATUS_RF_KILL_SW; - if (priv->workqueue) { + if (priv->workqueue) { cancel_delayed_work(&priv->request_scan); } wake_up_interruptible(&priv->wait_command_queue); @@ -947,9 +947,9 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) "disabled by HW switch\n"); /* Make sure the RF_KILL check timer is running */ cancel_delayed_work(&priv->rf_kill); - queue_delayed_work(priv->workqueue, &priv->rf_kill, + queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); - } else + } else queue_work(priv->workqueue, &priv->up); } @@ -960,7 +960,7 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = d->driver_data; - + ipw_radio_kill_sw(priv, buf[0] == '1'); return count; @@ -1055,7 +1055,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); handled |= CX2_INTA_BIT_RF_KILL_DONE; } - + if (inta & CX2_INTA_BIT_FATAL_ERROR) { IPW_ERROR("Firmware error detected. Restarting.\n"); #ifdef CONFIG_IPW_DEBUG @@ -1074,7 +1074,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) } if (handled != inta) { - IPW_ERROR("Unhandled INTA bits 0x%08x\n", + IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); } @@ -1083,63 +1083,63 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } - + #ifdef CONFIG_IPW_DEBUG #define IPW_CMD(x) case IPW_CMD_ ## x : return #x static char *get_cmd_string(u8 cmd) { switch (cmd) { IPW_CMD(HOST_COMPLETE); - IPW_CMD(POWER_DOWN); - IPW_CMD(SYSTEM_CONFIG); - IPW_CMD(MULTICAST_ADDRESS); - IPW_CMD(SSID); - IPW_CMD(ADAPTER_ADDRESS); - IPW_CMD(PORT_TYPE); - IPW_CMD(RTS_THRESHOLD); - IPW_CMD(FRAG_THRESHOLD); - IPW_CMD(POWER_MODE); - IPW_CMD(WEP_KEY); - IPW_CMD(TGI_TX_KEY); - IPW_CMD(SCAN_REQUEST); - IPW_CMD(SCAN_REQUEST_EXT); - IPW_CMD(ASSOCIATE); - IPW_CMD(SUPPORTED_RATES); - IPW_CMD(SCAN_ABORT); - IPW_CMD(TX_FLUSH); - IPW_CMD(QOS_PARAMETERS); - IPW_CMD(DINO_CONFIG); - IPW_CMD(RSN_CAPABILITIES); - IPW_CMD(RX_KEY); - IPW_CMD(CARD_DISABLE); - IPW_CMD(SEED_NUMBER); - IPW_CMD(TX_POWER); - IPW_CMD(COUNTRY_INFO); - IPW_CMD(AIRONET_INFO); - IPW_CMD(AP_TX_POWER); - IPW_CMD(CCKM_INFO); - IPW_CMD(CCX_VER_INFO); - IPW_CMD(SET_CALIBRATION); - IPW_CMD(SENSITIVITY_CALIB); - IPW_CMD(RETRY_LIMIT); - IPW_CMD(IPW_PRE_POWER_DOWN); - IPW_CMD(VAP_BEACON_TEMPLATE); - IPW_CMD(VAP_DTIM_PERIOD); - IPW_CMD(EXT_SUPPORTED_RATES); - IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT); - IPW_CMD(VAP_QUIET_INTERVALS); - IPW_CMD(VAP_CHANNEL_SWITCH); - IPW_CMD(VAP_MANDATORY_CHANNELS); - IPW_CMD(VAP_CELL_PWR_LIMIT); - IPW_CMD(VAP_CF_PARAM_SET); - IPW_CMD(VAP_SET_BEACONING_STATE); - IPW_CMD(MEASUREMENT); - IPW_CMD(POWER_CAPABILITY); - IPW_CMD(SUPPORTED_CHANNELS); - IPW_CMD(TPC_REPORT); - IPW_CMD(WME_INFO); - IPW_CMD(PRODUCTION_COMMAND); - default: + IPW_CMD(POWER_DOWN); + IPW_CMD(SYSTEM_CONFIG); + IPW_CMD(MULTICAST_ADDRESS); + IPW_CMD(SSID); + IPW_CMD(ADAPTER_ADDRESS); + IPW_CMD(PORT_TYPE); + IPW_CMD(RTS_THRESHOLD); + IPW_CMD(FRAG_THRESHOLD); + IPW_CMD(POWER_MODE); + IPW_CMD(WEP_KEY); + IPW_CMD(TGI_TX_KEY); + IPW_CMD(SCAN_REQUEST); + IPW_CMD(SCAN_REQUEST_EXT); + IPW_CMD(ASSOCIATE); + IPW_CMD(SUPPORTED_RATES); + IPW_CMD(SCAN_ABORT); + IPW_CMD(TX_FLUSH); + IPW_CMD(QOS_PARAMETERS); + IPW_CMD(DINO_CONFIG); + IPW_CMD(RSN_CAPABILITIES); + IPW_CMD(RX_KEY); + IPW_CMD(CARD_DISABLE); + IPW_CMD(SEED_NUMBER); + IPW_CMD(TX_POWER); + IPW_CMD(COUNTRY_INFO); + IPW_CMD(AIRONET_INFO); + IPW_CMD(AP_TX_POWER); + IPW_CMD(CCKM_INFO); + IPW_CMD(CCX_VER_INFO); + IPW_CMD(SET_CALIBRATION); + IPW_CMD(SENSITIVITY_CALIB); + IPW_CMD(RETRY_LIMIT); + IPW_CMD(IPW_PRE_POWER_DOWN); + IPW_CMD(VAP_BEACON_TEMPLATE); + IPW_CMD(VAP_DTIM_PERIOD); + IPW_CMD(EXT_SUPPORTED_RATES); + IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT); + IPW_CMD(VAP_QUIET_INTERVALS); + IPW_CMD(VAP_CHANNEL_SWITCH); + IPW_CMD(VAP_MANDATORY_CHANNELS); + IPW_CMD(VAP_CELL_PWR_LIMIT); + IPW_CMD(VAP_CF_PARAM_SET); + IPW_CMD(VAP_SET_BEACONING_STATE); + IPW_CMD(MEASUREMENT); + IPW_CMD(POWER_CAPABILITY); + IPW_CMD(SUPPORTED_CHANNELS); + IPW_CMD(TPC_REPORT); + IPW_CMD(WME_INFO); + IPW_CMD(PRODUCTION_COMMAND); + default: return "UNKNOWN"; } } @@ -1156,8 +1156,8 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) } priv->status |= STATUS_HCMD_ACTIVE; - - IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", + + IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); printk_buf(IPW_DL_HOST_COMMAND, (u8*)cmd->param, cmd->len); @@ -1198,11 +1198,11 @@ static int ipw_send_host_complete(struct ipw_priv *priv) IPW_ERROR("failed to send HOST_COMPLETE command\n"); return -1; } - + return 0; } -static int ipw_send_system_config(struct ipw_priv *priv, +static int ipw_send_system_config(struct ipw_priv *priv, struct ipw_sys_config *config) { struct host_cmd cmd = { @@ -1241,7 +1241,7 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 *ssid, int len) IPW_ERROR("failed to send SSID command\n"); return -1; } - + return 0; } @@ -1266,7 +1266,7 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 *mac) IPW_ERROR("failed to send ADAPTER_ADDRESS command\n"); return -1; } - + return 0; } @@ -1294,7 +1294,7 @@ static void ipw_scan_check(void *data) struct ipw_priv *priv = data; if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { IPW_DEBUG_SCAN("Scan completion watchdog resetting " - "adapter (%dms).\n", + "adapter (%dms).\n", IPW_SCAN_CHECK_WATCHDOG / 100); ipw_adapter_restart(priv); } @@ -1318,8 +1318,8 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv, IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n"); return -1; } - - queue_delayed_work(priv->workqueue, &priv->scan_check, + + queue_delayed_work(priv->workqueue, &priv->scan_check, IPW_SCAN_CHECK_WATCHDOG); return 0; } @@ -1340,7 +1340,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv) IPW_ERROR("failed to send SCAN_ABORT command\n"); return -1; } - + return 0; } @@ -1379,7 +1379,7 @@ static int ipw_send_associate(struct ipw_priv *priv, IPW_ERROR("failed to send ASSOCIATE command\n"); return -1; } - + return 0; } @@ -1401,7 +1401,7 @@ static int ipw_send_supported_rates(struct ipw_priv *priv, IPW_ERROR("failed to send SUPPORTED_RATES command\n"); return -1; } - + return 0; } @@ -1423,7 +1423,7 @@ static int ipw_set_random_seed(struct ipw_priv *priv) IPW_ERROR("failed to send SEED_NUMBER command\n"); return -1; } - + return 0; } @@ -1446,7 +1446,7 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) IPW_ERROR("failed to send CARD_DISABLE command\n"); return -1; } - + return 0; } #endif @@ -1469,7 +1469,7 @@ static int ipw_send_tx_power(struct ipw_priv *priv, IPW_ERROR("failed to send TX_POWER command\n"); return -1; } - + return 0; } @@ -1533,7 +1533,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) IPW_ERROR("Invalid args\n"); return -1; } - + /* If on battery, set to 3, if AC set to CAM, else user * level */ switch (mode) { @@ -1577,7 +1577,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) static inline void eeprom_write_reg(struct ipw_priv *p, u32 data) { ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data); - + /* the eeprom requires some time to complete the operation */ udelay(p->eeprom_delay); @@ -1628,7 +1628,7 @@ static u16 eeprom_read_u16(struct ipw_priv* priv, u8 addr) { int i; u16 r=0; - + /* Send READ Opcode */ eeprom_op(priv,EEPROM_CMD_READ,addr); @@ -1643,11 +1643,11 @@ static u16 eeprom_read_u16(struct ipw_priv* priv, u8 addr) data = ipw_read_reg32(priv,FW_MEM_REG_EEPROM_ACCESS); r = (r<<1) | ((data & EEPROM_BIT_DO)?1:0); } - + /* Send another dummy bit */ eeprom_write_reg(priv,0); eeprom_disable_cs(priv); - + return r; } @@ -1671,15 +1671,15 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv) { int i; u16 *eeprom = (u16 *)priv->eeprom; - + IPW_DEBUG_TRACE(">>\n"); /* read entire contents of eeprom into private buffer */ for ( i=0; i<128; i++ ) eeprom[i] = eeprom_read_u16(priv,(u8)i); - /* - If the data looks correct, then copy it to our private + /* + If the data looks correct, then copy it to our private copy. Otherwise let the firmware know to perform the operation on it's own */ @@ -1688,7 +1688,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv) /* write the eeprom data to sram */ for( i=0; ieeprom[i]); /* Do not load eeprom data on fatal error or suspend */ @@ -1709,14 +1709,14 @@ static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count) count >>= 2; if (!count) return; _ipw_write32(priv, CX2_AUTOINC_ADDR, start); - while (count--) + while (count--) _ipw_write32(priv, CX2_AUTOINC_DATA, 0); } static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv) { ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL, - CB_NUMBER_OF_ELEMENTS_SMALL * + CB_NUMBER_OF_ELEMENTS_SMALL * sizeof(struct command_block)); } @@ -1724,10 +1724,10 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv) { /* start dma engine but no transfers yet*/ IPW_DEBUG_FW(">> : \n"); - + /* Start the dma */ ipw_fw_dma_reset_command_blocks(priv); - + /* Write CB base address */ ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL); @@ -1740,18 +1740,18 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv) u32 control = 0; IPW_DEBUG_FW(">> :\n"); - - //set the Stop and Abort bit + + //set the Stop and Abort bit control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); priv->sram_desc.last_cb_index = 0; - + IPW_DEBUG_FW("<< \n"); } static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index, struct command_block *cb) { - u32 address = CX2_SHARED_SRAM_DMA_CONTROL + (sizeof(struct command_block) * index); + u32 address = CX2_SHARED_SRAM_DMA_CONTROL + (sizeof(struct command_block) * index); IPW_DEBUG_FW(">> :\n"); ipw_write_indirect(priv, address, (u8*)cb, (int)sizeof(struct command_block)); @@ -1767,13 +1767,13 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv) u32 index=0; IPW_DEBUG_FW(">> :\n"); - + for (index = 0; index < priv->sram_desc.last_cb_index; index++) ipw_fw_dma_write_command_block(priv, index, &priv->sram_desc.cb_list[index]); /* Enable the DMA in the CSR register */ ipw_clear_bit(priv, CX2_RESET_REG,CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); - + /* Set the Start bit. */ control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); @@ -1824,10 +1824,10 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv) IPW_DEBUG_FW("<< :\n"); current_cb_address= ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); - + current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL )/ sizeof (struct command_block); - + IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", current_cb_index, current_cb_address ); @@ -1844,8 +1844,8 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv, int is_last) { - u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC | - CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG | + u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC | + CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG | CB_DEST_SIZE_LONG; struct command_block *cb; u32 last_cb_element=0; @@ -1866,7 +1866,7 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv, if (is_last) control |= CB_LAST_VALID; - + control |= length; /* Calculate the CB Element's checksum value */ @@ -1902,7 +1902,7 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, if (status) { IPW_DEBUG_FW_INFO(": Failed\n"); return -1; - } else + } else IPW_DEBUG_FW_INFO(": Added new cb\n"); src_offset += CB_MAX_LENGTH; @@ -1919,11 +1919,11 @@ static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, if (status) { IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n"); return -1; - } else + } else IPW_DEBUG_FW_INFO(": Adding new cb - the buffer tail\n"); } - - + + IPW_DEBUG_FW("<< \n"); return 0; } @@ -1936,7 +1936,7 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv) IPW_DEBUG_FW(">> : \n"); current_index = ipw_fw_dma_command_block_index(priv); - IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", + IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n", (int) priv->sram_desc.last_cb_index); while (current_index < priv->sram_desc.last_cb_index) { @@ -1956,33 +1956,33 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv) ipw_fw_dma_abort(priv); /*Disable the DMA in the CSR register*/ - ipw_set_bit(priv, CX2_RESET_REG, + ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); IPW_DEBUG_FW("<< dmaWaitSync \n"); return 0; } -static void ipw_remove_current_network(struct ipw_priv *priv) +static void ipw_remove_current_network(struct ipw_priv *priv) { struct list_head *element, *safe; - struct ieee80211_network *network = NULL; + struct ieee80211_network *network = NULL; list_for_each_safe(element, safe, &priv->ieee->network_list) { network = list_entry(element, struct ieee80211_network, list); if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { list_del(element); - list_add_tail(&network->list, + list_add_tail(&network->list, &priv->ieee->network_free_list); } } } /** - * Check that card is still alive. + * Check that card is still alive. * Reads debug register from domain0. * If card is present, pre-defined value should * be found there. - * + * * @param priv * @return 1 if card is present, 0 otherwise */ @@ -1997,16 +1997,16 @@ static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, int i = 0; do { - if ((ipw_read32(priv, addr) & mask) == mask) + if ((ipw_read32(priv, addr) & mask) == mask) return i; mdelay(10); i += 10; } while (i < timeout); - + return -ETIME; } -/* These functions load the firmware and micro code for the operation of +/* These functions load the firmware and micro code for the operation of * the ipw hardware. It assumes the buffer has all the bits for the * image and the caller is handling the memory allocation and clean up. */ @@ -2015,7 +2015,7 @@ static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, static int ipw_stop_master(struct ipw_priv * priv) { int rc; - + IPW_DEBUG_TRACE(">> \n"); /* stop master. typical delay - 0 */ ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); @@ -2079,16 +2079,16 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, u16 *image; image = (u16 *)data; - + IPW_DEBUG_TRACE(">> \n"); rc = ipw_stop_master(priv); if (rc < 0) return rc; - + // spin_lock_irqsave(&priv->lock, flags); - + for (addr = CX2_SHARED_LOWER_BOUND; addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { ipw_write32(priv, addr, 0); @@ -2107,10 +2107,10 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, /* reset PHY */ ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN); mdelay(1); - + ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0); mdelay(1); - + /* enable ucode store */ ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0); ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS); @@ -2128,7 +2128,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, for (i = 0; i < len / 2; i++) ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); - + /* enable DINO */ ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, @@ -2148,10 +2148,10 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, if (cr & DINO_RXFIFO_DATA) { /* alive_command_responce size is NOT multiple of 4 */ u32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4]; - - for (i = 0; i < ARRAY_SIZE(response_buffer); i++) + + for (i = 0; i < ARRAY_SIZE(response_buffer); i++) response_buffer[i] = - ipw_read_reg32(priv, + ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); memcpy(&priv->dino_alive, response_buffer, sizeof(priv->dino_alive)); @@ -2218,7 +2218,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, chunk = (struct fw_chunk *)(data + offset); offset += sizeof(struct fw_chunk); /* build DMA packet and queue up for sending */ - /* dma to chunk->address, the chunk->length bytes from data + + /* dma to chunk->address, the chunk->length bytes from data + * offeset*/ /* Dma loading */ rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, @@ -2227,7 +2227,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); goto out; } - + offset += chunk->length; } while (offset < len); @@ -2255,16 +2255,16 @@ static int ipw_stop_nic(struct ipw_priv *priv) /* stop*/ ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); - - rc = ipw_poll_bit(priv, CX2_RESET_REG, - CX2_RESET_REG_MASTER_DISABLED, 500); + + rc = ipw_poll_bit(priv, CX2_RESET_REG, + CX2_RESET_REG_MASTER_DISABLED, 500); if (rc < 0) { IPW_ERROR("wait for reg master disabled failed\n"); return rc; - } + } ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); - + return rc; } @@ -2274,22 +2274,22 @@ static void ipw_start_nic(struct ipw_priv *priv) /* prvHwStartNic release ARC*/ ipw_clear_bit(priv, CX2_RESET_REG, - CX2_RESET_REG_MASTER_DISABLED | - CX2_RESET_REG_STOP_MASTER | + CX2_RESET_REG_MASTER_DISABLED | + CX2_RESET_REG_STOP_MASTER | CBD_RESET_REG_PRINCETON_RESET); - + /* enable power management */ ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); IPW_DEBUG_TRACE("<<\n"); } - + static int ipw_init_nic(struct ipw_priv *priv) { int rc; IPW_DEBUG_TRACE(">>\n"); - /* reset */ + /* reset */ /*prvHwInitNic */ /* set "initialization complete" bit to move adapter to D0 state */ ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); @@ -2298,8 +2298,8 @@ static int ipw_init_nic(struct ipw_priv *priv) ipw_write32(priv, CX2_READ_INT_REGISTER, CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); /* wait for clock stabilization */ - rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, - CX2_GP_CNTRL_BIT_CLOCK_READY, 250); + rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, + CX2_GP_CNTRL_BIT_CLOCK_READY, 250); if (rc < 0 ) IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); @@ -2316,7 +2316,7 @@ static int ipw_init_nic(struct ipw_priv *priv) } -/* Call this function from process context, it will sleep in request_firmware. +/* Call this function from process context, it will sleep in request_firmware. * Probe is an ok place to call this from. */ static int ipw_reset_nic(struct ipw_priv *priv) @@ -2324,18 +2324,18 @@ static int ipw_reset_nic(struct ipw_priv *priv) int rc = 0; IPW_DEBUG_TRACE(">>\n"); - + rc = ipw_init_nic(priv); - + /* Clear the 'host command active' bit... */ priv->status &= ~STATUS_HCMD_ACTIVE; wake_up_interruptible(&priv->wait_command_queue); IPW_DEBUG_TRACE("<<\n"); return rc; -} +} -static int ipw_get_fw(struct ipw_priv *priv, +static int ipw_get_fw(struct ipw_priv *priv, const struct firmware **fw, const char *name) { struct fw_header *header; @@ -2346,7 +2346,7 @@ static int ipw_get_fw(struct ipw_priv *priv, if (rc < 0) { IPW_ERROR("%s load failed: Reason %d\n", name, rc); return rc; - } + } header = (struct fw_header *)(*fw)->data; if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) { @@ -2389,7 +2389,7 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv, } list_add_tail(&rxq->pool[i].list, &rxq->rx_used); } - + /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; @@ -2418,43 +2418,43 @@ static int ipw_load(struct ipw_priv *priv) if (!fw_loaded) { #endif rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); - if (rc) + if (rc) goto error; - + switch (priv->ieee->iw_mode) { case IW_MODE_ADHOC: - rc = ipw_get_fw(priv, &ucode, + rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("ibss_ucode")); - if (rc) + if (rc) goto error; - + rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); break; - + #ifdef CONFIG_IPW_PROMISC case IW_MODE_MONITOR: - rc = ipw_get_fw(priv, &ucode, + rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("ibss_ucode")); - if (rc) + if (rc) goto error; - + rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("sniffer")); break; #endif case IW_MODE_INFRA: - rc = ipw_get_fw(priv, &ucode, + rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode")); - if (rc) + if (rc) goto error; - + rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss")); break; - + default: rc = -EINVAL; } - if (rc) + if (rc) goto error; #ifdef CONFIG_PM @@ -2478,7 +2478,7 @@ static int ipw_load(struct ipw_priv *priv) /* ack pending interrupts */ ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); - + ipw_stop_nic(priv); rc = ipw_reset_nic(priv); @@ -2487,11 +2487,11 @@ static int ipw_load(struct ipw_priv *priv) goto error; } - ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND, + ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND, CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND); /* DMA the initial boot firmware into the device */ - rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), + rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), bootfw->size - sizeof(struct fw_header)); if (rc < 0) { IPW_ERROR("Unable to load boot firmware\n"); @@ -2502,31 +2502,31 @@ static int ipw_load(struct ipw_priv *priv) ipw_start_nic(priv); /* wait for the device to finish it's initial startup sequence */ - rc = ipw_poll_bit(priv, CX2_INTA_RW, - CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); + rc = ipw_poll_bit(priv, CX2_INTA_RW, + CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); if (rc < 0) { IPW_ERROR("device failed to boot initial fw image\n"); goto error; } IPW_DEBUG_INFO("initial device response after %dms\n", rc); - /* ack fw init done interrupt */ + /* ack fw init done interrupt */ ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); /* DMA the ucode into the device */ - rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), + rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), ucode->size - sizeof(struct fw_header)); if (rc < 0) { IPW_ERROR("Unable to load ucode\n"); goto error; } - + /* stop nic */ ipw_stop_nic(priv); /* DMA bss firmware into the device */ - rc = ipw_load_firmware(priv, firmware->data + - sizeof(struct fw_header), + rc = ipw_load_firmware(priv, firmware->data + + sizeof(struct fw_header), firmware->size - sizeof(struct fw_header)); if (rc < 0 ) { IPW_ERROR("Unable to load firmware\n"); @@ -2543,7 +2543,7 @@ static int ipw_load(struct ipw_priv *priv) /* Ensure interrupts are disabled */ ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); - + /* kick start the device */ ipw_start_nic(priv); @@ -2560,8 +2560,8 @@ static int ipw_load(struct ipw_priv *priv) } /* wait for the device */ - rc = ipw_poll_bit(priv, CX2_INTA_RW, - CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); + rc = ipw_poll_bit(priv, CX2_INTA_RW, + CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); if (rc < 0) { IPW_ERROR("device failed to start after 500ms\n"); goto error; @@ -2573,7 +2573,7 @@ static int ipw_load(struct ipw_priv *priv) /* read eeprom data and initialize the eeprom region of sram */ priv->eeprom_delay = 1; - ipw_eeprom_init_sram(priv); + ipw_eeprom_init_sram(priv); /* enable interrupts */ ipw_enable_interrupts(priv); @@ -2613,7 +2613,7 @@ static int ipw_load(struct ipw_priv *priv) return rc; } -/** +/** * DMA services * * Theory of operation @@ -2622,17 +2622,17 @@ static int ipw_load(struct ipw_priv *priv) * 2 empty entries always kept in the buffer to protect from overflow. * * For Tx queue, there are low mark and high mark limits. If, after queuing - * the packet for Tx, free space become < low mark, Tx queue stopped. When - * reclaiming packets (on 'tx done IRQ), if free space become > high mark, + * the packet for Tx, free space become < low mark, Tx queue stopped. When + * reclaiming packets (on 'tx done IRQ), if free space become > high mark, * Tx queue resumed. * * The IPW operates with six queues, one receive queue in the device's * sram, one transmit queue for sending commands to the device firmware, - * and four transmit queues for data. + * and four transmit queues for data. * - * The four transmit queues allow for performing quality of service (qos) + * The four transmit queues allow for performing quality of service (qos) * transmissions as per the 802.11 protocol. Currently Linux does not - * provide a mechanism to the user for utilizing prioritized queues, so + * provide a mechanism to the user for utilizing prioritized queues, so * we only utilize the first data transmit queue (queue1). */ @@ -2658,7 +2658,7 @@ static inline int ipw_queue_inc_wrap(int index, int n_bd) /** * Initialize common DMA queue structure - * + * * @param q queue to init * @param count Number of BD's to allocate. Should be power of 2 * @param read_register Address for 'read' register @@ -2670,7 +2670,7 @@ static inline int ipw_queue_inc_wrap(int index, int n_bd) * @param size Address for 'size' register * (not offset within BAR, full address) */ -static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q, +static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q, int count, u32 read, u32 write, u32 base, u32 size) { @@ -2696,7 +2696,7 @@ static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q, _ipw_read32(priv, 0x90); } -static int ipw_queue_tx_init(struct ipw_priv *priv, +static int ipw_queue_tx_init(struct ipw_priv *priv, struct clx2_tx_queue *q, int count, u32 read, u32 write, u32 base, u32 size) @@ -2725,7 +2725,7 @@ static int ipw_queue_tx_init(struct ipw_priv *priv, /** * Free one TFD, those at index [txq->q.last_used]. * Do NOT advance any indexes - * + * * @param dev * @param txq */ @@ -2735,7 +2735,7 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv, struct tfd_frame *bd = &txq->bd[txq->q.last_used]; struct pci_dev *dev = priv->pci_dev; int i; - + /* classify bd */ if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE) /* nothing to cleanup after for host commands */ @@ -2761,10 +2761,10 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv, /** * Deallocate DMA queue. - * + * * Empty queue by removing and destroying all BD's. * Free all buffers. - * + * * @param dev * @param q */ @@ -2774,17 +2774,17 @@ static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_queue *q = &txq->q; struct pci_dev *dev = priv->pci_dev; - if (q->n_bd == 0) - return; + if (q->n_bd == 0) + return; /* first, empty all BD's */ for (; q->first_empty != q->last_used; q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) { ipw_queue_tx_free_tfd(priv, txq); } - + /* free buffers belonging to queue itself */ - pci_free_consistent(dev, sizeof(txq->bd[0])*q->n_bd, txq->bd, + pci_free_consistent(dev, sizeof(txq->bd[0])*q->n_bd, txq->bd, q->dma_addr); kfree(txq->txb); @@ -2795,7 +2795,7 @@ static void ipw_queue_tx_free(struct ipw_priv *priv, /** * Destroy all DMA queues and structures - * + * * @param priv */ static void ipw_tx_queue_free(struct ipw_priv *priv) @@ -2877,8 +2877,8 @@ static inline u8 ipw_find_station(struct ipw_priv *priv, u8 *bssid) { int i; - for (i = 0; i < priv->num_stations; i++) - if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) + for (i = 0; i < priv->num_stations; i++) + if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) return i; return IPW_INVALID_STATION; @@ -2895,7 +2895,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet) IPW_DEBUG_ASSOC("Disassocation attempt from " MAC_FMT " " "on channel %d.\n", - MAC_ARG(priv->assoc_request.bssid), + MAC_ARG(priv->assoc_request.bssid), priv->assoc_request.channel); priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED); @@ -2975,10 +2975,10 @@ static const struct ipw_status_code ipw_status_codes[] = { }; #ifdef CONFIG_IPW_DEBUG -static const char *ipw_get_status_code(u16 status) +static const char *ipw_get_status_code(u16 status) { int i; - for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) + for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) if (ipw_status_codes[i].status == status) return ipw_status_codes[i].reason; return "Unknown status value."; @@ -3027,12 +3027,12 @@ static void ipw_reset_stats(struct ipw_priv *priv) priv->last_rx_packets = 0; priv->last_tx_packets = 0; priv->last_tx_failures = 0; - + /* Firmware managed, reset only when NIC is restarted, so we have to * normalize on the current value */ - ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, + ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &priv->last_rx_err, &len); - ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, + ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &priv->last_tx_failures, &len); /* Driver managed, reset with each association */ @@ -3072,7 +3072,7 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv) case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; } - if (priv->ieee->mode == IEEE_B) + if (priv->ieee->mode == IEEE_B) return 11000000; else return 54000000; @@ -3083,32 +3083,32 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv) u32 rate, len = sizeof(rate); int err; - if (!(priv->status & STATUS_ASSOCIATED)) + if (!(priv->status & STATUS_ASSOCIATED)) return 0; if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) { - err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate, + err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate, &len); if (err) { IPW_DEBUG_INFO("failed querying ordinals.\n"); return 0; } - } else + } else return ipw_get_max_rate(priv); switch (rate) { - case IPW_TX_RATE_1MB: return 1000000; - case IPW_TX_RATE_2MB: return 2000000; - case IPW_TX_RATE_5MB: return 5500000; - case IPW_TX_RATE_6MB: return 6000000; - case IPW_TX_RATE_9MB: return 9000000; - case IPW_TX_RATE_11MB: return 11000000; - case IPW_TX_RATE_12MB: return 12000000; - case IPW_TX_RATE_18MB: return 18000000; - case IPW_TX_RATE_24MB: return 24000000; - case IPW_TX_RATE_36MB: return 36000000; - case IPW_TX_RATE_48MB: return 48000000; - case IPW_TX_RATE_54MB: return 54000000; + case IPW_TX_RATE_1MB: return 1000000; + case IPW_TX_RATE_2MB: return 2000000; + case IPW_TX_RATE_5MB: return 5500000; + case IPW_TX_RATE_6MB: return 6000000; + case IPW_TX_RATE_9MB: return 9000000; + case IPW_TX_RATE_11MB: return 11000000; + case IPW_TX_RATE_12MB: return 12000000; + case IPW_TX_RATE_18MB: return 18000000; + case IPW_TX_RATE_24MB: return 24000000; + case IPW_TX_RATE_36MB: return 36000000; + case IPW_TX_RATE_48MB: return 48000000; + case IPW_TX_RATE_54MB: return 54000000; } return 0; @@ -3125,7 +3125,7 @@ static void ipw_gather_stats(struct ipw_priv *priv) u32 quality = 0; u32 len = sizeof(u32); s16 rssi; - u32 beacon_quality, signal_quality, tx_quality, rx_quality, + u32 beacon_quality, signal_quality, tx_quality, rx_quality, rate_quality; if (!(priv->status & STATUS_ASSOCIATED)) { @@ -3134,9 +3134,9 @@ static void ipw_gather_stats(struct ipw_priv *priv) } /* Update the statistics */ - ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS, + ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS, &priv->missed_beacons, &len); - missed_beacons_delta = priv->missed_beacons - + missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons; priv->last_missed_beacons = priv->missed_beacons; if (priv->assoc_request.beacon_interval) { @@ -3163,13 +3163,13 @@ static void ipw_gather_stats(struct ipw_priv *priv) priv->last_tx_packets = priv->tx_packets; /* Calculate quality based on the following: - * + * * Missed beacon: 100% = 0, 0% = 70% missed * Rate: 60% = 1Mbs, 100% = Max * Rx and Tx errors represent a straight % of total Rx/Tx * RSSI: 100% = > -50, 0% = < -80 * Rx errors: 100% = 0, 0% = 50% missed - * + * * The lowest computed quality is used. * */ @@ -3178,72 +3178,72 @@ static void ipw_gather_stats(struct ipw_priv *priv) if (beacon_quality < BEACON_THRESHOLD) beacon_quality = 0; else - beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 / + beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 / (100 - BEACON_THRESHOLD); - IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n", + IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n", beacon_quality, missed_beacons_percent); - + priv->last_rate = ipw_get_current_rate(priv); rate_quality = priv->last_rate * 40 / priv->last_rate + 60; IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", rate_quality, priv->last_rate / 1000000); - - if (rx_packets_delta > 100 && - rx_packets_delta + rx_err_delta) - rx_quality = 100 - (rx_err_delta * 100) / + + if (rx_packets_delta > 100 && + rx_packets_delta + rx_err_delta) + rx_quality = 100 - (rx_err_delta * 100) / (rx_packets_delta + rx_err_delta); else rx_quality = 100; IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n", rx_quality, rx_err_delta, rx_packets_delta); - - if (tx_packets_delta > 100 && - tx_packets_delta + tx_failures_delta) - tx_quality = 100 - (tx_failures_delta * 100) / + + if (tx_packets_delta > 100 && + tx_packets_delta + tx_failures_delta) + tx_quality = 100 - (tx_failures_delta * 100) / (tx_packets_delta + tx_failures_delta); else tx_quality = 100; IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n", tx_quality, tx_failures_delta, tx_packets_delta); - + rssi = average_value(&priv->average_rssi); if (rssi > PERFECT_RSSI) signal_quality = 100; else if (rssi < WORST_RSSI) signal_quality = 0; else - signal_quality = (rssi - WORST_RSSI) * 100 / + signal_quality = (rssi - WORST_RSSI) * 100 / (PERFECT_RSSI - WORST_RSSI); IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", signal_quality, rssi); - - quality = min(beacon_quality, + + quality = min(beacon_quality, min(rate_quality, min(tx_quality, min(rx_quality, signal_quality)))); if (quality == beacon_quality) IPW_DEBUG_STATS( - "Quality (%d%%): Clamped to missed beacons.\n", + "Quality (%d%%): Clamped to missed beacons.\n", quality); if (quality == rate_quality) IPW_DEBUG_STATS( - "Quality (%d%%): Clamped to rate quality.\n", + "Quality (%d%%): Clamped to rate quality.\n", quality); if (quality == tx_quality) IPW_DEBUG_STATS( - "Quality (%d%%): Clamped to Tx quality.\n", + "Quality (%d%%): Clamped to Tx quality.\n", quality); if (quality == rx_quality) IPW_DEBUG_STATS( - "Quality (%d%%): Clamped to Rx quality.\n", + "Quality (%d%%): Clamped to Rx quality.\n", quality); if (quality == signal_quality) IPW_DEBUG_STATS( - "Quality (%d%%): Clamped to signal quality.\n", + "Quality (%d%%): Clamped to signal quality.\n", quality); priv->quality = quality; - - queue_delayed_work(priv->workqueue, &priv->gather_stats, + + queue_delayed_work(priv->workqueue, &priv->gather_stats, IPW_STATS_INTERVAL); } @@ -3254,35 +3254,35 @@ static void ipw_gather_stats(struct ipw_priv *priv) static inline void ipw_rx_notification(struct ipw_priv* priv, struct ipw_rx_notification *notif) { - IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", + IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); - + switch (notif->subtype) { case HOST_NOTIFICATION_STATUS_ASSOCIATED: { struct notif_association *assoc = ¬if->u.assoc; - + switch (assoc->state) { case CMAS_ASSOCIATED: { IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "associated: '%s' " MAC_FMT " \n", + "associated: '%s' " MAC_FMT " \n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid)); - + switch (priv->ieee->iw_mode) { case IW_MODE_INFRA: - memcpy(priv->ieee->bssid, priv->bssid, + memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN); break; case IW_MODE_ADHOC: - memcpy(priv->ieee->bssid, priv->bssid, + memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN); - + /* clear out the station table */ priv->num_stations = 0; IPW_DEBUG_ASSOC("queueing adhoc check\n"); - queue_delayed_work(priv->workqueue, + queue_delayed_work(priv->workqueue, &priv->adhoc_check, priv->assoc_request.beacon_interval); break; @@ -3306,19 +3306,19 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, schedule_work(&priv->gather_stats); notify_wx_assoc_event(priv); -/* queue_delayed_work(priv->workqueue, +/* queue_delayed_work(priv->workqueue, &priv->request_scan, SCAN_ASSOCIATED_INTERVAL); */ break; } - + case CMAS_AUTHENTICATED: { if (priv->status & (STATUS_ASSOCIATED | STATUS_AUTH)) { #ifdef CONFIG_IPW_DEBUG struct notif_authenticate *auth = ¬if->u.auth; IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "deauthenticated: '%s' " MAC_FMT ": (0x%04X) - %s \n", + "deauthenticated: '%s' " MAC_FMT ": (0x%04X) - %s \n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid), ntohs(auth->status), @@ -3332,29 +3332,29 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, netif_carrier_off(priv->net_dev); netif_stop_queue(priv->net_dev); queue_work(priv->workqueue, &priv->request_scan); - notify_wx_assoc_event(priv); + notify_wx_assoc_event(priv); break; - } + } IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "authenticated: '%s' " MAC_FMT "\n", + "authenticated: '%s' " MAC_FMT "\n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + MAC_ARG(priv->bssid)); break; } - + case CMAS_INIT: { IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "disassociated: '%s' " MAC_FMT " \n", + "disassociated: '%s' " MAC_FMT " \n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid)); priv->status &= ~( STATUS_DISASSOCIATING | - STATUS_ASSOCIATING | + STATUS_ASSOCIATING | STATUS_ASSOCIATED | STATUS_AUTH); - + netif_stop_queue(priv->net_dev); if (!(priv->status & STATUS_ROAMING)) { netif_carrier_off(priv->net_dev); @@ -3365,21 +3365,21 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, cancel_delayed_work(&priv->adhoc_check); /* Queue up another scan... */ - queue_work(priv->workqueue, + queue_work(priv->workqueue, &priv->request_scan); cancel_delayed_work(&priv->gather_stats); } else { priv->status |= STATUS_ROAMING; - queue_work(priv->workqueue, + queue_work(priv->workqueue, &priv->request_scan); } - + ipw_reset_stats(priv); break; } - - default: + + default: IPW_ERROR("assoc: unknown (%d)\n", assoc->state); break; @@ -3393,7 +3393,7 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, switch (auth->state) { case CMAS_AUTHENTICATED: IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, - "authenticated: '%s' " MAC_FMT " \n", + "authenticated: '%s' " MAC_FMT " \n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid)); priv->status |= STATUS_AUTH; @@ -3405,9 +3405,9 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, "authentication failed (0x%04X): %s\n", ntohs(auth->status), ipw_get_status_code(ntohs(auth->status))); - } + } IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "deauthenticated: '%s' " MAC_FMT "\n", + "deauthenticated: '%s' " MAC_FMT "\n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid)); @@ -3420,7 +3420,7 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, queue_work(priv->workqueue, &priv->request_scan); notify_wx_assoc_event(priv); break; - + case CMAS_TX_AUTH_SEQ_1: IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, "AUTH_SEQ_1\n"); @@ -3474,9 +3474,9 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT: { struct notif_channel_result *x = ¬if->u.channel_result; - + if (notif->size == sizeof(*x)) { - IPW_DEBUG_SCAN("Scan result for channel %d\n", + IPW_DEBUG_SCAN("Scan result for channel %d\n", x->channel_num); } else { IPW_DEBUG_SCAN("Scan result of wrong size %d " @@ -3491,20 +3491,20 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, if (notif->size == sizeof(*x)) { IPW_DEBUG_SCAN("Scan completed: type %d, %d channels, " "%d status\n", - x->scan_type, - x->num_channels, + x->scan_type, + x->num_channels, x->status); } else { IPW_ERROR("Scan completed of wrong size %d " "(should be %zd)\n", notif->size, sizeof(*x)); } - + priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); cancel_delayed_work(&priv->scan_check); - - if (!(priv->status & (STATUS_ASSOCIATED | + + if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING | STATUS_ROAMING | STATUS_DISASSOCIATING))) @@ -3512,7 +3512,7 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, else if (priv->status & STATUS_ROAMING) { /* If a scan completed and we are in roam mode, then * the scan that completed was the one requested as a - * result of entering roam... so, schedule the + * result of entering roam... so, schedule the * roam work */ queue_work(priv->workqueue, &priv->roam); } else if (priv->status & STATUS_SCAN_PENDING) @@ -3536,11 +3536,11 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, } case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION: { - struct notif_link_deterioration *x = + struct notif_link_deterioration *x = ¬if->u.link_deterioration; if (notif->size==sizeof(*x)) { IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, - "link deterioration: '%s' " MAC_FMT " \n", + "link deterioration: '%s' " MAC_FMT " \n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid)); memcpy(&priv->last_link_deterioration, x, sizeof(*x)); @@ -3580,14 +3580,14 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, if (x->number > priv->missed_beacon_threshold && priv->status & STATUS_ASSOCIATED) { - IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | + IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE, "Missed beacon: %d - disassociate\n", x->number); - queue_work(priv->workqueue, + queue_work(priv->workqueue, &priv->disassociate); } else if (x->number > priv->roaming_threshold) { - IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, + IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, "Missed beacon: %d - initiate " "roaming\n", x->number); @@ -3614,7 +3614,7 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, x->key_state,x->security_type, x->station_index); break; - } + } IPW_ERROR("TGi Tx Key of wrong size %d (should be %zd)\n", notif->size, sizeof(*x)); @@ -3628,8 +3628,8 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, memcpy(&priv->calib, x, sizeof(*x)); IPW_DEBUG_INFO("TODO: Calibration\n"); break; - } - + } + IPW_ERROR("Calibration of wrong size %d (should be %zd)\n", notif->size, sizeof(*x)); break; @@ -3656,7 +3656,7 @@ static inline void ipw_rx_notification(struct ipw_priv* priv, /** * Destroys all DMA structures and initialise them again - * + * * @param priv * @return error code */ @@ -3725,18 +3725,18 @@ static int ipw_queue_reset(struct ipw_priv *priv) /** * Reclaim Tx queue entries no more used by NIC. - * + * * When FW adwances 'R' index, all entries between old and * new 'R' index need to be reclaimed. As result, some free space * forms. If there is enough free space (> low mark), wake Tx queue. - * + * * @note Need to protect against garbage in 'R' index * @param priv * @param txq * @param qindex * @return Number of used entries remains in the queue */ -static int ipw_queue_tx_reclaim(struct ipw_priv *priv, +static int ipw_queue_tx_reclaim(struct ipw_priv *priv, struct clx2_tx_queue *txq, int qindex) { u32 hw_tail; @@ -3797,7 +3797,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, -/* +/* * Rx theory of operation * * The host allocates 32 DMA target addresses and passes the host address @@ -3807,43 +3807,43 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, * Rx Queue Indexes * The host/firmware share two index registers for managing the Rx buffers. * - * The READ index maps to the first position that the firmware may be writing - * to -- the driver can read up to (but not including) this position and get - * good data. + * The READ index maps to the first position that the firmware may be writing + * to -- the driver can read up to (but not including) this position and get + * good data. * The READ index is managed by the firmware once the card is enabled. * * The WRITE index maps to the last position the driver has read from -- the * position preceding WRITE is the last slot the firmware can place a packet. * * The queue is empty (no good data) if WRITE = READ - 1, and is full if - * WRITE = READ. + * WRITE = READ. * - * During initialization the host sets up the READ queue position to the first + * During initialization the host sets up the READ queue position to the first * INDEX position, and WRITE to the last (READ - 1 wrapped) * * When the firmware places a packet in a buffer it will advance the READ index * and fire the RX interrupt. The driver can then query the READ index and * process as many packets as possible, moving the WRITE index forward as it * resets the Rx queue buffers with new memory. - * + * * The management in the driver is as follows: - * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When + * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled - * to replensish the ipw->rxq->rx_free. + * to replensish the ipw->rxq->rx_free. * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the * ipw->rxq is replenished and the READ INDEX is updated (updating the * 'processed' and 'read' driver indexes as well) * + A received packet is processed and handed to the kernel network stack, * detached from the ipw->rxq. The driver 'processed' index is updated. * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free - * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ - * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there + * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ + * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there * were enough free buffers and RX_STALLED is set it is cleared. * * * Driver sequence: * - * ipw_rx_queue_alloc() Allocates rx_free + * ipw_rx_queue_alloc() Allocates rx_free * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls * ipw_rx_queue_restock * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx @@ -3853,7 +3853,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, * * -- enable interrupts -- * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the - * READ INDEX, detaching the SKB from the pool. + * READ INDEX, detaching the SKB from the pool. * Moves the packet buffer from queue to rx_used. * Calls ipw_rx_queue_restock to refill any empty * slots. @@ -3861,7 +3861,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf, * */ -/* +/* * If there are slots in the RX queue that need to be restocked, * and we have free pre-allocated buffers, fill the ranks as much * as we can pulling from rx_free. @@ -3893,20 +3893,20 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv) } spin_unlock_irqrestore(&rxq->lock, flags); - /* If the pre-allocated buffer pool is dropping low, schedule to + /* If the pre-allocated buffer pool is dropping low, schedule to * refill it */ if (rxq->free_count <= RX_LOW_WATERMARK) queue_work(priv->workqueue, &priv->rx_replenish); /* If we've added more space for the firmware to place data, tell it */ - if (write != rxq->write) + if (write != rxq->write) ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write); } /* * Move all used packet from rx_used to rx_free, allocating a new SKB for each. - * Also restock the Rx queue via ipw_rx_queue_restock. - * + * Also restock the Rx queue via ipw_rx_queue_restock. + * * This is called as a scheduled work item (except for during intialization) */ static void ipw_rx_queue_replenish(void *data) @@ -3931,12 +3931,12 @@ static void ipw_rx_queue_replenish(void *data) break; } list_del(element); - + rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; rxb->dma_addr = pci_map_single( priv->pci_dev, rxb->skb->data, CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - + list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; } @@ -3947,17 +3947,17 @@ static void ipw_rx_queue_replenish(void *data) /* Assumes that the skb field of the buffers in 'pool' is kept accurate. * If an SKB has been detached, the POOL needs to have it's SKB set to NULL - * This free routine walks the list of POOL entries and if SKB is set to + * This free routine walks the list of POOL entries and if SKB is set to * non NULL it is unmapped and freed */ -static void ipw_rx_queue_free(struct ipw_priv *priv, +static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq) { int i; if (!rxq) return; - + for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { if (rxq->pool[i].skb != NULL) { pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, @@ -3982,7 +3982,7 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv) INIT_LIST_HEAD(&rxq->rx_used); /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) list_add_tail(&rxq->pool[i].list, &rxq->rx_used); /* Set us so that we have processed and used all buffers, but have @@ -3999,44 +3999,44 @@ static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate) rate &= ~IEEE80211_BASIC_RATE_MASK; if (ieee_mode == IEEE_A) { switch (rate) { - case IEEE80211_OFDM_RATE_6MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? + case IEEE80211_OFDM_RATE_6MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_9MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? + case IEEE80211_OFDM_RATE_9MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_12MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? + case IEEE80211_OFDM_RATE_12MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_18MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? + case IEEE80211_OFDM_RATE_18MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_24MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? + case IEEE80211_OFDM_RATE_24MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_36MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? + case IEEE80211_OFDM_RATE_36MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_48MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? + case IEEE80211_OFDM_RATE_48MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_54MB: - return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? + case IEEE80211_OFDM_RATE_54MB: + return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0; default: return 0; } } - + /* B and G mixed */ switch (rate) { - case IEEE80211_CCK_RATE_1MB: + case IEEE80211_CCK_RATE_1MB: return priv->rates_mask & IEEE80211_CCK_RATE_1MB_MASK ? 1 : 0; - case IEEE80211_CCK_RATE_2MB: + case IEEE80211_CCK_RATE_2MB: return priv->rates_mask & IEEE80211_CCK_RATE_2MB_MASK ? 1 : 0; - case IEEE80211_CCK_RATE_5MB: + case IEEE80211_CCK_RATE_5MB: return priv->rates_mask & IEEE80211_CCK_RATE_5MB_MASK ? 1 : 0; - case IEEE80211_CCK_RATE_11MB: + case IEEE80211_CCK_RATE_11MB: return priv->rates_mask & IEEE80211_CCK_RATE_11MB_MASK ? 1 : 0; } @@ -4046,28 +4046,28 @@ static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate) /* G */ switch (rate) { - case IEEE80211_OFDM_RATE_6MB: + case IEEE80211_OFDM_RATE_6MB: return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_9MB: + case IEEE80211_OFDM_RATE_9MB: return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_12MB: + case IEEE80211_OFDM_RATE_12MB: return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_18MB: + case IEEE80211_OFDM_RATE_18MB: return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_24MB: + case IEEE80211_OFDM_RATE_24MB: return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_36MB: + case IEEE80211_OFDM_RATE_36MB: return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_48MB: + case IEEE80211_OFDM_RATE_48MB: return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0; - case IEEE80211_OFDM_RATE_54MB: + case IEEE80211_OFDM_RATE_54MB: return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0; } return 0; } -static int ipw_compatible_rates(struct ipw_priv *priv, +static int ipw_compatible_rates(struct ipw_priv *priv, const struct ieee80211_network *network, struct ipw_supported_rates *rates) { @@ -4082,7 +4082,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv, network->rates[i], priv->rates_mask); continue; } - + rates->supported_rates[rates->num_rates++] = network->rates[i]; } @@ -4093,7 +4093,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv, network->rates_ex[i], priv->rates_mask); continue; } - + rates->supported_rates[rates->num_rates++] = network->rates_ex[i]; } @@ -4115,62 +4115,62 @@ static inline void ipw_copy_rates(struct ipw_supported_rates *dest, static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates, u8 modulation, u32 rate_mask) { - u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? + u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? IEEE80211_BASIC_RATE_MASK : 0; - + if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK) - rates->supported_rates[rates->num_rates++] = basic_mask | + rates->supported_rates[rates->num_rates++] = basic_mask | IEEE80211_CCK_RATE_5MB; if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK) - rates->supported_rates[rates->num_rates++] = basic_mask | + rates->supported_rates[rates->num_rates++] = basic_mask | IEEE80211_CCK_RATE_11MB; } static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates, u8 modulation, u32 rate_mask) { - u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? + u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ? IEEE80211_BASIC_RATE_MASK : 0; if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK) - rates->supported_rates[rates->num_rates++] = basic_mask | + rates->supported_rates[rates->num_rates++] = basic_mask | IEEE80211_OFDM_RATE_6MB; if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_OFDM_RATE_9MB; if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK) - rates->supported_rates[rates->num_rates++] = basic_mask | + rates->supported_rates[rates->num_rates++] = basic_mask | IEEE80211_OFDM_RATE_12MB; if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_OFDM_RATE_18MB; if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK) - rates->supported_rates[rates->num_rates++] = basic_mask | + rates->supported_rates[rates->num_rates++] = basic_mask | IEEE80211_OFDM_RATE_24MB; if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_OFDM_RATE_36MB; if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_OFDM_RATE_48MB; if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK) - rates->supported_rates[rates->num_rates++] = + rates->supported_rates[rates->num_rates++] = IEEE80211_OFDM_RATE_54MB; } @@ -4190,11 +4190,11 @@ static int ipw_best_network( /* Verify that this network's capability is compatible with the * current mode (AdHoc or Infrastructure) */ if ((priv->ieee->iw_mode == IW_MODE_INFRA && - !(network->capability & WLAN_CAPABILITY_BSS)) || + !(network->capability & WLAN_CAPABILITY_BSS)) || (priv->ieee->iw_mode == IW_MODE_ADHOC && !(network->capability & WLAN_CAPABILITY_IBSS))) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded due to " - "capability mismatch.\n", + "capability mismatch.\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid)); return 0; @@ -4209,33 +4209,33 @@ static int ipw_best_network( MAC_ARG(network->bssid)); return 0; } - + if (unlikely(roaming)) { /* If we are roaming, then ensure check if this is a valid * network to try and roam to */ if ((network->ssid_len != match->network->ssid_len) || - memcmp(network->ssid, match->network->ssid, + memcmp(network->ssid, match->network->ssid, network->ssid_len)) { IPW_DEBUG_ASSOC("Netowrk '%s (" MAC_FMT ")' excluded " "because of non-network ESSID.\n", - escape_essid(network->ssid, + escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid)); return 0; } } else { - /* If an ESSID has been configured then compare the broadcast - * ESSID to ours */ - if ((priv->config & CFG_STATIC_ESSID) && + /* If an ESSID has been configured then compare the broadcast + * ESSID to ours */ + if ((priv->config & CFG_STATIC_ESSID) && ((network->ssid_len != priv->essid_len) || - memcmp(network->ssid, priv->essid, + memcmp(network->ssid, priv->essid, min(network->ssid_len, priv->essid_len)))) { char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; strncpy(escaped, escape_essid( network->ssid, network->ssid_len), sizeof(escaped)); IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " - "because of ESSID mismatch: '%s'.\n", + "because of ESSID mismatch: '%s'.\n", escaped, MAC_ARG(network->bssid), escape_essid(priv->essid, priv->essid_len)); return 0; @@ -4244,11 +4244,11 @@ static int ipw_best_network( /* If the old network rate is better than this one, don't bother * testing everything else. */ - if (match->network && match->network->stats.rssi > + if (match->network && match->network->stats.rssi > network->stats.rssi) { char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - strncpy(escaped, - escape_essid(network->ssid, network->ssid_len), + strncpy(escaped, + escape_essid(network->ssid, network->ssid_len), sizeof(escaped)); IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded because " "'%s (" MAC_FMT ")' has a stronger signal.\n", @@ -4258,7 +4258,7 @@ static int ipw_best_network( MAC_ARG(match->network->bssid)); return 0; } - + /* If this network has already had an association attempt within the * last 3 seconds, do not try and associate again... */ if (network->last_associate && @@ -4273,7 +4273,7 @@ static int ipw_best_network( } /* Now go through and see if the requested network is valid... */ - if (priv->ieee->scan_age != 0 && + if (priv->ieee->scan_age != 0 && jiffies - network->last_scanned > priv->ieee->scan_age) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " "because of age: %lums.\n", @@ -4281,9 +4281,9 @@ static int ipw_best_network( MAC_ARG(network->bssid), (jiffies - network->last_scanned) / (HZ / 100)); return 0; - } + } - if ((priv->config & CFG_STATIC_CHANNEL) && + if ((priv->config & CFG_STATIC_CHANNEL) && (network->channel != priv->channel)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " "because of channel mismatch: %d != %d.\n", @@ -4292,22 +4292,22 @@ static int ipw_best_network( network->channel, priv->channel); return 0; } - + /* Verify privacy compatability */ - if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != + if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " "because of privacy mismatch: %s != %s.\n", escape_essid(network->ssid, network->ssid_len), MAC_ARG(network->bssid), - priv->capability & CAP_PRIVACY_ON ? "on" : + priv->capability & CAP_PRIVACY_ON ? "on" : "off", - network->capability & + network->capability & WLAN_CAPABILITY_PRIVACY ?"on" : "off"); return 0; } - - if ((priv->config & CFG_STATIC_BSSID) && + + if ((priv->config & CFG_STATIC_BSSID) && memcmp(network->bssid, priv->bssid, ETH_ALEN)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " "because of BSSID mismatch: " MAC_FMT ".\n", @@ -4316,7 +4316,7 @@ static int ipw_best_network( MAC_ARG(priv->bssid)); return 0; } - + /* Filter out any incompatible freq / mode combinations */ if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " @@ -4326,7 +4326,7 @@ static int ipw_best_network( MAC_ARG(network->bssid)); return 0; } - + ipw_compatible_rates(priv, network, &rates); if (rates.num_rates == 0) { IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " @@ -4335,7 +4335,7 @@ static int ipw_best_network( MAC_ARG(network->bssid)); return 0; } - + /* TODO: Perform any further minimal comparititive tests. We do not * want to put too much policy logic here; intelligent scan selection * should occur within a generic IEEE 802.11 user space tool. */ @@ -4352,7 +4352,7 @@ static int ipw_best_network( } -static void ipw_adhoc_create(struct ipw_priv *priv, +static void ipw_adhoc_create(struct ipw_priv *priv, struct ieee80211_network *network) { /* @@ -4361,7 +4361,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv, * comes to creating a new ad-hoc network, we have tell the FW * exactly which band to use. * - * We also have the possibility of an invalid channel for the + * We also have the possibility of an invalid channel for the * chossen band. Attempting to create a new ad-hoc network * with an invalid channel for wireless mode will trigger a * FW fatal error. @@ -4393,10 +4393,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv, if (priv->capability & CAP_PRIVACY_ON) network->capability |= WLAN_CAPABILITY_PRIVACY; network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); - memcpy(network->rates, priv->rates.supported_rates, + memcpy(network->rates, priv->rates.supported_rates, network->rates_len); network->rates_ex_len = priv->rates.num_rates - network->rates_len; - memcpy(network->rates_ex, + memcpy(network->rates_ex, &priv->rates.supported_rates[network->rates_len], network->rates_ex_len); network->last_scanned = 0; @@ -4407,10 +4407,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv, network->beacon_interval = 100; /* Default */ network->listen_interval = 10; /* Default */ network->atim_window = 0; /* Default */ -#ifdef CONFIG_IEEE80211_WPA +#ifdef CONFIG_IEEE80211_WPA network->wpa_ie_len = 0; network->rsn_ie_len = 0; -#endif /* CONFIG_IEEE80211_WPA */ +#endif /* CONFIG_IEEE80211_WPA */ } static void ipw_send_wep_keys(struct ipw_priv *priv) @@ -4426,7 +4426,7 @@ static void ipw_send_wep_keys(struct ipw_priv *priv) key->cmd_id = DINO_CMD_WEP_KEY; key->seq_num = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { key->key_index = i; if (!(priv->sec.flags & (1 << i))) { key->key_size = 0; @@ -4439,13 +4439,13 @@ static void ipw_send_wep_keys(struct ipw_priv *priv) IPW_ERROR("failed to send WEP_KEY command\n"); return; } - } + } } static void ipw_adhoc_check(void *data) { struct ipw_priv *priv = data; - + if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold && !(priv->config & CFG_ADHOC_PERSIST)) { IPW_DEBUG_SCAN("Disassociating due to missed beacons\n"); @@ -4454,7 +4454,7 @@ static void ipw_adhoc_check(void *data) return; } - queue_delayed_work(priv->workqueue, &priv->adhoc_check, + queue_delayed_work(priv->workqueue, &priv->adhoc_check, priv->assoc_request.beacon_interval); } @@ -4464,13 +4464,13 @@ static void ipw_debug_config(struct ipw_priv *priv) IPW_DEBUG_INFO("Scan completed, no valid APs matched " "[CFG 0x%08X]\n", priv->config); if (priv->config & CFG_STATIC_CHANNEL) - IPW_DEBUG_INFO("Channel locked to %d\n", + IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel); else IPW_DEBUG_INFO("Channel unlocked.\n"); if (priv->config & CFG_STATIC_ESSID) - IPW_DEBUG_INFO("ESSID locked to '%s'\n", - escape_essid(priv->essid, + IPW_DEBUG_INFO("ESSID locked to '%s'\n", + escape_essid(priv->essid, priv->essid_len)); else IPW_DEBUG_INFO("ESSID unlocked.\n"); @@ -4498,9 +4498,9 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, u32 reg; u16 mask = 0; - /* Identify 'current FW band' and match it with the fixed + /* Identify 'current FW band' and match it with the fixed * Tx rates */ - + switch (priv->ieee->freq_band) { case IEEE80211_52GHZ_BAND: /* A only */ /* IEEE_A */ @@ -4509,7 +4509,7 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, fr.tx_rates = 0; break; } - + fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A; break; @@ -4521,7 +4521,7 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, fr.tx_rates = 0; } break; - } + } /* IEEE_G */ if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | @@ -4535,17 +4535,17 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv, mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1); fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK; } - + if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) { mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1); fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK; } - + if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) { mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1); fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK; } - + fr.tx_rates |= mask; break; } @@ -4565,7 +4565,7 @@ static int ipw_associate_network(struct ipw_priv *priv, ipw_set_fixed_rate(priv, network); if (!(priv->config & CFG_STATIC_ESSID)) { - priv->essid_len = min(network->ssid_len, + priv->essid_len = min(network->ssid_len, (u8)IW_ESSID_MAX_SIZE); memcpy(priv->essid, network->ssid, priv->essid_len); } @@ -4583,12 +4583,12 @@ static int ipw_associate_network(struct ipw_priv *priv, priv->assoc_request.auth_key = 0; } - if (priv->capability & CAP_PRIVACY_ON) + if (priv->capability & CAP_PRIVACY_ON) ipw_send_wep_keys(priv); - /* - * It is valid for our ieee device to support multiple modes, but - * when it comes to associating to a given network we have to choose + /* + * It is valid for our ieee device to support multiple modes, but + * when it comes to associating to a given network we have to choose * just one mode. */ if (network->mode & priv->ieee->mode & IEEE_A) @@ -4601,18 +4601,18 @@ static int ipw_associate_network(struct ipw_priv *priv, IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " "802.11%c [%d], enc=%s%s%s%c%c\n", roaming ? "Rea" : "A", - escape_essid(priv->essid, priv->essid_len), - network->channel, - ipw_modes[priv->assoc_request.ieee_mode], - rates->num_rates, + escape_essid(priv->essid, priv->essid_len), + network->channel, + ipw_modes[priv->assoc_request.ieee_mode], + rates->num_rates, priv->capability & CAP_PRIVACY_ON ? "on " : "off", - priv->capability & CAP_PRIVACY_ON ? - (priv->capability & CAP_SHARED_KEY ? "(shared)" : + priv->capability & CAP_PRIVACY_ON ? + (priv->capability & CAP_SHARED_KEY ? "(shared)" : "(open)") : "", priv->capability & CAP_PRIVACY_ON ? " key=" : "", - priv->capability & CAP_PRIVACY_ON ? + priv->capability & CAP_PRIVACY_ON ? '1' + priv->sec.active_key : '.', - priv->capability & CAP_PRIVACY_ON ? + priv->capability & CAP_PRIVACY_ON ? '.' : ' '); priv->assoc_request.beacon_interval = network->beacon_interval; @@ -4637,14 +4637,14 @@ static int ipw_associate_network(struct ipw_priv *priv, memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); priv->assoc_request.atim_window = network->atim_window; } else { - memcpy(&priv->assoc_request.dest, network->bssid, + memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN); priv->assoc_request.atim_window = 0; } priv->assoc_request.capability = network->capability; priv->assoc_request.listen_interval = network->listen_interval; - + err = ipw_send_ssid(priv, priv->essid, priv->essid_len); if (err) { IPW_DEBUG_HC("Attempt to send SSID command failed.\n"); @@ -4654,7 +4654,7 @@ static int ipw_associate_network(struct ipw_priv *priv, rates->ieee_mode = priv->assoc_request.ieee_mode; rates->purpose = IPW_RATE_CONNECT; ipw_send_supported_rates(priv, rates); - + if (priv->assoc_request.ieee_mode == IPW_G_MODE) priv->sys_config.dot11g_auto_detection = 1; else @@ -4664,7 +4664,7 @@ static int ipw_associate_network(struct ipw_priv *priv, IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); return err; } - + IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi); err = ipw_set_sensitivity(priv, network->stats.rssi); if (err) { @@ -4679,7 +4679,7 @@ static int ipw_associate_network(struct ipw_priv *priv, */ priv->channel = network->channel; memcpy(priv->bssid, network->bssid, ETH_ALEN); - priv->status |= STATUS_ASSOCIATING; + priv->status |= STATUS_ASSOCIATING; priv->status &= ~STATUS_SECURITY_UPDATED; priv->assoc_network = network; @@ -4689,8 +4689,8 @@ static int ipw_associate_network(struct ipw_priv *priv, IPW_DEBUG_HC("Attempt to send associate command failed.\n"); return err; } - - IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n", + + IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n", escape_essid(priv->essid, priv->essid_len), MAC_ARG(priv->bssid)); @@ -4706,8 +4706,8 @@ static void ipw_roam(void *data) }; /* The roaming process is as follows: - * - * 1. Missed beacon threshold triggers the roaming process by + * + * 1. Missed beacon threshold triggers the roaming process by * setting the status ROAM bit and requesting a scan. * 2. When the scan completes, it schedules the ROAM work * 3. The ROAM work looks at all of the known networks for one that @@ -4718,7 +4718,7 @@ static void ipw_roam(void *data) * 5. When the disassociation completes, the roam work is again * scheduled. The second time through, the driver is no longer * associated, and the newly selected network is sent an - * association request. + * association request. * 6. At this point ,the roaming process is complete and the ROAM * status bit is cleared. */ @@ -4727,9 +4727,9 @@ static void ipw_roam(void *data) * set, then we are not actively roaming, so just return */ if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING))) return; - + if (priv->status & STATUS_ASSOCIATED) { - /* First pass through ROAM process -- look for a better + /* First pass through ROAM process -- look for a better * network */ u8 rssi = priv->assoc_network->stats.rssi; priv->assoc_network->stats.rssi = -128; @@ -4738,7 +4738,7 @@ static void ipw_roam(void *data) ipw_best_network(priv, &match, network, 1); } priv->assoc_network->stats.rssi = rssi; - + if (match.network == priv->assoc_network) { IPW_DEBUG_ASSOC("No better APs in this network to " "roam to.\n"); @@ -4746,12 +4746,12 @@ static void ipw_roam(void *data) ipw_debug_config(priv); return; } - + ipw_send_disassociate(priv, 1); priv->assoc_network = match.network; return; - } + } /* Second pass through ROAM process -- request association */ ipw_compatible_rates(priv, priv->assoc_network, &match.rates); @@ -4778,7 +4778,7 @@ static void ipw_associate(void *data) return; } - list_for_each_entry(network, &priv->ieee->network_list, list) + list_for_each_entry(network, &priv->ieee->network_list, list) ipw_best_network(priv, &match, network, 0); network = match.network; @@ -4790,29 +4790,29 @@ static void ipw_associate(void *data) priv->config & CFG_STATIC_ESSID && !list_empty(&priv->ieee->network_free_list)) { element = priv->ieee->network_free_list.next; - network = list_entry(element, struct ieee80211_network, + network = list_entry(element, struct ieee80211_network, list); ipw_adhoc_create(priv, network); rates = &priv->rates; list_del(element); list_add_tail(&network->list, &priv->ieee->network_list); } - + /* If we reached the end of the list, then we don't have any valid * matching APs */ if (!network) { ipw_debug_config(priv); - queue_delayed_work(priv->workqueue, &priv->request_scan, + queue_delayed_work(priv->workqueue, &priv->request_scan, SCAN_INTERVAL); - + return; } ipw_associate_network(priv, network, rates, 0); } - -static inline void ipw_handle_data_packet(struct ipw_priv *priv, + +static inline void ipw_handle_data_packet(struct ipw_priv *priv, struct ipw_rx_mem_buffer *rxb, struct ieee80211_rx_stats *stats) { @@ -4821,9 +4821,9 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv, /* We received data from the HW, so stop the watchdog */ priv->net_dev->trans_start = jiffies; - /* We only process data packets if the + /* We only process data packets if the * interface is open */ - if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > + if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) { priv->ieee->stats.rx_errors++; priv->wstats.discard.misc++; @@ -4844,7 +4844,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv, IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); - if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) + if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) priv->ieee->stats.rx_errors++; else /* ieee80211_rx succeeded, so it now owns the SKB */ rxb->skb = NULL; @@ -4879,7 +4879,7 @@ static void ipw_rx(struct ipw_priv *priv) priv->rxq->queue[i] = NULL; pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, - CX2_RX_BUF_SIZE, + CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); pkt = (struct ipw_rx_packet *)rxb->skb->data; @@ -4891,14 +4891,14 @@ static void ipw_rx(struct ipw_priv *priv) switch (pkt->header.message_type) { case RX_FRAME_TYPE: /* 802.11 frame */ { struct ieee80211_rx_stats stats = { - .rssi = pkt->u.frame.rssi_dbm - + .rssi = pkt->u.frame.rssi_dbm - IPW_RSSI_TO_DBM, .signal = pkt->u.frame.signal, .rate = pkt->u.frame.rate, .mac_time = jiffies, - .received_channel = + .received_channel = pkt->u.frame.received_channel, - .freq = (pkt->u.frame.control & (1<<0)) ? + .freq = (pkt->u.frame.control & (1<<0)) ? IEEE80211_24GHZ_BAND : IEEE80211_52GHZ_BAND, .len = pkt->u.frame.length, }; @@ -4918,21 +4918,21 @@ static void ipw_rx(struct ipw_priv *priv) break; } #endif - - header = (struct ieee80211_hdr *)(rxb->skb->data + + + header = (struct ieee80211_hdr *)(rxb->skb->data + IPW_RX_FRAME_SIZE); /* TODO: Check Ad-Hoc dest/source and make sure * that we are actually parsing these packets - * correctly -- we should probably use the + * correctly -- we should probably use the * frame control of the packet and disregard * the current iw_mode */ switch (priv->ieee->iw_mode) { case IW_MODE_ADHOC: - network_packet = - !memcmp(header->addr1, - priv->net_dev->dev_addr, + network_packet = + !memcmp(header->addr1, + priv->net_dev->dev_addr, ETH_ALEN) || - !memcmp(header->addr3, + !memcmp(header->addr3, priv->bssid, ETH_ALEN) || is_broadcast_ether_addr(header->addr1) || is_multicast_ether_addr(header->addr1); @@ -4940,20 +4940,20 @@ static void ipw_rx(struct ipw_priv *priv) case IW_MODE_INFRA: default: - network_packet = - !memcmp(header->addr3, + network_packet = + !memcmp(header->addr3, priv->bssid, ETH_ALEN) || - !memcmp(header->addr1, - priv->net_dev->dev_addr, + !memcmp(header->addr1, + priv->net_dev->dev_addr, ETH_ALEN) || is_broadcast_ether_addr(header->addr1) || is_multicast_ether_addr(header->addr1); break; } - + if (network_packet && priv->assoc_network) { priv->assoc_network->stats.rssi = stats.rssi; - average_add(&priv->average_rssi, + average_add(&priv->average_rssi, stats.rssi); priv->last_rx_rssi = stats.rssi; } @@ -4967,7 +4967,7 @@ static void ipw_rx(struct ipw_priv *priv) priv->wstats.discard.misc++; break; } - + switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { case IEEE80211_FTYPE_MGMT: ieee80211_rx_mgt(priv->ieee, header, &stats); @@ -4979,17 +4979,17 @@ static void ipw_rx(struct ipw_priv *priv) !memcmp(header->addr3, priv->bssid, ETH_ALEN)) ipw_add_station(priv, header->addr2); break; - + case IEEE80211_FTYPE_CTL: break; - + case IEEE80211_FTYPE_DATA: if (network_packet) ipw_handle_data_packet(priv, rxb, &stats); else - IPW_DEBUG_DROP("Dropping: " MAC_FMT + IPW_DEBUG_DROP("Dropping: " MAC_FMT ", " MAC_FMT ", " MAC_FMT "\n", - MAC_ARG(header->addr1), MAC_ARG(header->addr2), + MAC_ARG(header->addr1), MAC_ARG(header->addr2), MAC_ARG(header->addr3)); break; } @@ -5010,19 +5010,19 @@ static void ipw_rx(struct ipw_priv *priv) pkt->header.message_type); break; } - - /* For now we just don't re-use anything. We can tweak this - * later to try and re-use notification packets and SKBs that + + /* For now we just don't re-use anything. We can tweak this + * later to try and re-use notification packets and SKBs that * fail to Rx correctly */ if (rxb->skb != NULL) { dev_kfree_skb_any(rxb->skb); rxb->skb = NULL; } - + pci_unmap_single(priv->pci_dev, rxb->dma_addr, CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); list_add_tail(&rxb->list, &priv->rxq->rx_used); - + i = (i + 1) % RX_QUEUE_SIZE; } @@ -5043,7 +5043,7 @@ static void ipw_abort_scan(struct ipw_priv *priv) priv->status |= STATUS_SCAN_ABORTING; err = ipw_send_scan_abort(priv); - if (err) + if (err) IPW_DEBUG_HC("Request to abort scan failed.\n"); } @@ -5052,7 +5052,7 @@ static int ipw_request_scan(struct ipw_priv *priv) struct ipw_scan_request_ext scan; int channel_index = 0; int i, err, scan_type; - + if (priv->status & STATUS_EXIT_PENDING) { IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n"); priv->status |= STATUS_SCAN_PENDING; @@ -5065,7 +5065,7 @@ static int ipw_request_scan(struct ipw_priv *priv) ipw_abort_scan(priv); return 0; } - + if (priv->status & STATUS_SCAN_ABORTING) { IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); priv->status |= STATUS_SCAN_PENDING; @@ -5086,23 +5086,23 @@ static int ipw_request_scan(struct ipw_priv *priv) scan.full_scan_index = ieee80211_get_scans(priv->ieee); /* If we are roaming, then make this a directed scan for the current - * network. Otherwise, ensure that every other scan is a fast + * network. Otherwise, ensure that every other scan is a fast * channel hop scan */ if ((priv->status & STATUS_ROAMING) || ( - !(priv->status & STATUS_ASSOCIATED) && - (priv->config & CFG_STATIC_ESSID) && + !(priv->status & STATUS_ASSOCIATED) && + (priv->config & CFG_STATIC_ESSID) && (scan.full_scan_index % 2))) { err = ipw_send_ssid(priv, priv->essid, priv->essid_len); if (err) { IPW_DEBUG_HC("Attempt to send SSID command failed.\n"); return err; } - + scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; } else { scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; } - + if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { int start = channel_index; for (i = 0; i < MAX_A_CHANNELS; i++) { @@ -5112,13 +5112,13 @@ static int ipw_request_scan(struct ipw_priv *priv) band_a_active_channel[i] == priv->channel) continue; channel_index++; - scan.channels_list[channel_index] = + scan.channels_list[channel_index] = band_a_active_channel[i]; ipw_set_scan_type(&scan, channel_index, scan_type); } - + if (start != channel_index) { - scan.channels_list[start] = (u8)(IPW_A_MODE << 6) | + scan.channels_list[start] = (u8)(IPW_A_MODE << 6) | (channel_index - start); channel_index++; } @@ -5133,17 +5133,17 @@ static int ipw_request_scan(struct ipw_priv *priv) band_b_active_channel[i] == priv->channel) continue; channel_index++; - scan.channels_list[channel_index] = + scan.channels_list[channel_index] = band_b_active_channel[i]; ipw_set_scan_type(&scan, channel_index, scan_type); } if (start != channel_index) { - scan.channels_list[start] = (u8)(IPW_B_MODE << 6) | + scan.channels_list[start] = (u8)(IPW_B_MODE << 6) | (channel_index - start); } } - + err = ipw_send_scan_request_ext(priv, &scan); if (err) { IPW_DEBUG_HC("Sending scan command failed: %08X\n", @@ -5161,20 +5161,20 @@ static int ipw_request_scan(struct ipw_priv *priv) * This file defines the Wireless Extension handlers. It does not * define any methods of hardware manipulation and relies on the * functions defined in ipw_main to provide the HW interaction. - * - * The exception to this is the use of the ipw_get_ordinal() + * + * The exception to this is the use of the ipw_get_ordinal() * function used to poll the hardware vs. making unecessary calls. * */ -static int ipw_wx_get_name(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_name(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); if (!(priv->status & STATUS_ASSOCIATED)) strcpy(wrqu->name, "unassociated"); - else + else snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", ipw_modes[priv->assoc_request.ieee_mode]); IPW_DEBUG_WX("Name: %s\n", wrqu->name); @@ -5220,42 +5220,42 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel) return 0; } -static int ipw_wx_set_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) +static int ipw_wx_set_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); struct iw_freq *fwrq = &wrqu->freq; - + /* if setting by freq convert to channel */ if (fwrq->e == 1) { if ((fwrq->m >= (int) 2.412e8 && fwrq->m <= (int) 2.487e8)) { int f = fwrq->m / 100000; int c = 0; - + while ((c < REG_MAX_CHANNEL) && (f != ipw_frequencies[c])) c++; - + /* hack to fall through */ fwrq->e = 0; fwrq->m = c + 1; } } - - if (fwrq->e > 0 || fwrq->m > 1000) + + if (fwrq->e > 0 || fwrq->m > 1000) return -EOPNOTSUPP; IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); return ipw_set_channel(priv, (u8)fwrq->m); - + return 0; } -static int ipw_wx_get_freq(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_freq(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5267,15 +5267,15 @@ static int ipw_wx_get_freq(struct net_device *dev, if (priv->config & CFG_STATIC_CHANNEL || priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) wrqu->freq.m = priv->channel; - else + else wrqu->freq.m = 0; IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); return 0; } -static int ipw_wx_set_mode(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_mode(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5301,15 +5301,15 @@ static int ipw_wx_set_mode(struct net_device *dev, } #ifdef CONFIG_IPW_PROMISC - if (priv->ieee->iw_mode == IW_MODE_MONITOR) + if (priv->ieee->iw_mode == IW_MODE_MONITOR) priv->net_dev->type = ARPHRD_ETHER; - - if (wrqu->mode == IW_MODE_MONITOR) + + if (wrqu->mode == IW_MODE_MONITOR) priv->net_dev->type = ARPHRD_IEEE80211; #endif /* CONFIG_IPW_PROMISC */ - + #ifdef CONFIG_PM - /* Free the existing firmware and reset the fw_loaded + /* Free the existing firmware and reset the fw_loaded * flag so ipw_load() will bring in the new firmawre */ if (fw_loaded) { fw_loaded = 0; @@ -5323,12 +5323,12 @@ static int ipw_wx_set_mode(struct net_device *dev, priv->ieee->iw_mode = wrqu->mode; ipw_adapter_restart(priv); - + return err; } -static int ipw_wx_get_mode(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_mode(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5364,8 +5364,8 @@ static const s32 period_duration[] = { 1000000 }; -static int ipw_wx_get_range(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_range(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5377,7 +5377,7 @@ static int ipw_wx_get_range(struct net_device *dev, memset(range, 0, sizeof(*range)); /* 54Mbs == ~27 Mb/s real (802.11g) */ - range->throughput = 27 * 1000 * 1000; + range->throughput = 27 * 1000 * 1000; range->max_qual.qual = 100; /* TODO: Find real max RSSI and stick here */ @@ -5393,16 +5393,16 @@ static int ipw_wx_get_range(struct net_device *dev, range->num_bitrates = min(priv->rates.num_rates, (u8)IW_MAX_BITRATES); - for (i = 0; i < range->num_bitrates; i++) - range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) * + for (i = 0; i < range->num_bitrates; i++) + range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) * 500000; - + range->max_rts = DEFAULT_RTS_THRESHOLD; range->min_frag = MIN_FRAG_THRESHOLD; range->max_frag = MAX_FRAG_THRESHOLD; range->encoding_size[0] = 5; - range->encoding_size[1] = 13; + range->encoding_size[1] = 13; range->num_encoding_sizes = 2; range->max_encoding_tokens = WEP_KEYS; @@ -5428,8 +5428,8 @@ static int ipw_wx_get_range(struct net_device *dev, return 0; } -static int ipw_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_wap(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5441,7 +5441,7 @@ static int ipw_wx_set_wap(struct net_device *dev, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) + if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) return -EINVAL; if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || @@ -5482,14 +5482,14 @@ static int ipw_wx_set_wap(struct net_device *dev, return 0; } -static int ipw_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_wap(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); /* If we are associated, trying to associate, or have a statically * configured BSSID then return that; otherwise return ANY */ - if (priv->config & CFG_STATIC_BSSID || + if (priv->config & CFG_STATIC_BSSID || priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { wrqu->ap_addr.sa_family = ARPHRD_ETHER; memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); @@ -5501,14 +5501,14 @@ static int ipw_wx_get_wap(struct net_device *dev, return 0; } -static int ipw_wx_set_essid(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_essid(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); char *essid = ""; /* ANY */ int length = 0; - + if (wrqu->essid.flags && wrqu->essid.length) { length = wrqu->essid.length - 1; essid = extra; @@ -5540,7 +5540,7 @@ static int ipw_wx_set_essid(struct net_device *dev, priv->essid_len = length; memcpy(priv->essid, essid, priv->essid_len); - + /* If we are currently associated, or trying to associate * then see if this is a new ESSID (causing us to disassociate) */ if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { @@ -5553,8 +5553,8 @@ static int ipw_wx_set_essid(struct net_device *dev, return 0; } -static int ipw_wx_get_essid(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_essid(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5562,10 +5562,10 @@ static int ipw_wx_get_essid(struct net_device *dev, /* If we are associated, trying to associate, or have a statically * configured ESSID then return that; otherwise return ANY */ if (priv->config & CFG_STATIC_ESSID || - priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { - IPW_DEBUG_WX("Getting essid: '%s'\n", + priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { + IPW_DEBUG_WX("Getting essid: '%s'\n", escape_essid(priv->essid, priv->essid_len)); - memcpy(extra, priv->essid, priv->essid_len); + memcpy(extra, priv->essid, priv->essid_len); wrqu->essid.length = priv->essid_len; wrqu->essid.flags = 1; /* active */ } else { @@ -5577,10 +5577,10 @@ static int ipw_wx_get_essid(struct net_device *dev, return 0; } -static int ipw_wx_set_nick(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_nick(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_WX("Setting nick to '%s'\n", extra); @@ -5596,10 +5596,10 @@ static int ipw_wx_set_nick(struct net_device *dev, } -static int ipw_wx_get_nick(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_nick(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_WX("Getting nick\n"); wrqu->data.length = strlen(priv->nick) + 1; @@ -5612,15 +5612,15 @@ static int ipw_wx_get_nick(struct net_device *dev, static int ipw_wx_set_rate(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); - return -EOPNOTSUPP; + return -EOPNOTSUPP; } -static int ipw_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_rate(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv * priv = ieee80211_priv(dev); wrqu->bitrate.value = priv->last_rate; @@ -5629,10 +5629,10 @@ static int ipw_wx_get_rate(struct net_device *dev, } -static int ipw_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_rts(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); if (wrqu->rts.disabled) @@ -5641,7 +5641,7 @@ static int ipw_wx_set_rts(struct net_device *dev, if (wrqu->rts.value < MIN_RTS_THRESHOLD || wrqu->rts.value > MAX_RTS_THRESHOLD) return -EINVAL; - + priv->rts_threshold = wrqu->rts.value; } @@ -5650,14 +5650,14 @@ static int ipw_wx_set_rts(struct net_device *dev, return 0; } -static int ipw_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_rts(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); wrqu->rts.value = priv->rts_threshold; wrqu->rts.fixed = 0; /* no auto select */ - wrqu->rts.disabled = + wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); @@ -5665,10 +5665,10 @@ static int ipw_wx_get_rts(struct net_device *dev, } -static int ipw_wx_set_txpow(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_txpow(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); struct ipw_tx_power tx_power; int i; @@ -5679,7 +5679,7 @@ static int ipw_wx_set_txpow(struct net_device *dev, if (wrqu->power.flags != IW_TXPOW_DBM) return -EINVAL; - if ((wrqu->power.value > 20) || + if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) return -EINVAL; @@ -5709,10 +5709,10 @@ static int ipw_wx_set_txpow(struct net_device *dev, } -static int ipw_wx_get_txpow(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_txpow(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); wrqu->power.value = priv->tx_power; @@ -5720,15 +5720,15 @@ static int ipw_wx_get_txpow(struct net_device *dev, wrqu->power.flags = IW_TXPOW_DBM; wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; - IPW_DEBUG_WX("GET TX Power -> %s %d \n", + IPW_DEBUG_WX("GET TX Power -> %s %d \n", wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value); return 0; } -static int ipw_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_frag(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5739,7 +5739,7 @@ static int ipw_wx_set_frag(struct net_device *dev, if (wrqu->frag.value < MIN_FRAG_THRESHOLD || wrqu->frag.value > MAX_FRAG_THRESHOLD) return -EINVAL; - + priv->ieee->fts = wrqu->frag.value & ~0x1; } @@ -5748,14 +5748,14 @@ static int ipw_wx_set_frag(struct net_device *dev, return 0; } -static int ipw_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_frag(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); wrqu->frag.value = priv->ieee->fts; wrqu->frag.fixed = 0; /* no auto select */ - wrqu->frag.disabled = + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); @@ -5763,26 +5763,26 @@ static int ipw_wx_get_frag(struct net_device *dev, return 0; } -static int ipw_wx_set_retry(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_retry(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); - return -EOPNOTSUPP; + return -EOPNOTSUPP; } -static int ipw_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_retry(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); - return -EOPNOTSUPP; + return -EOPNOTSUPP; } -static int ipw_wx_set_scan(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_scan(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5792,32 +5792,32 @@ static int ipw_wx_set_scan(struct net_device *dev, return 0; } -static int ipw_wx_get_scan(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_scan(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra); } -static int ipw_wx_set_encode(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_encode(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *key) { struct ipw_priv *priv = ieee80211_priv(dev); return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); } -static int ipw_wx_get_encode(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_encode(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *key) { struct ipw_priv *priv = ieee80211_priv(dev); return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key); } -static int ipw_wx_set_power(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_power(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5834,7 +5834,7 @@ static int ipw_wx_set_power(struct net_device *dev, IPW_DEBUG_WX("SET Power Management Mode -> off\n"); return 0; - } + } switch (wrqu->power.flags & IW_POWER_MODE) { case IW_POWER_ON: /* If not specified */ @@ -5844,14 +5844,14 @@ static int ipw_wx_set_power(struct net_device *dev, default: /* Otherwise we don't support it */ IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", wrqu->power.flags); - return -EOPNOTSUPP; + return -EOPNOTSUPP; } - + /* If the user hasn't specified a power management mode yet, default * to BATTERY */ if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC) priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY; - else + else priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); if (err) { @@ -5861,12 +5861,12 @@ static int ipw_wx_set_power(struct net_device *dev, IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); - + return 0; } -static int ipw_wx_get_power(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_power(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5878,40 +5878,40 @@ static int ipw_wx_get_power(struct net_device *dev, } IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); - + return 0; } -static int ipw_wx_set_powermode(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_powermode(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); int mode = *(int *)extra; int err; - + if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { mode = IPW_POWER_AC; priv->power_mode = mode; } else { priv->power_mode = IPW_POWER_ENABLED | mode; } - + if (priv->power_mode != mode) { err = ipw_send_power_mode(priv, mode); - + if (err) { IPW_DEBUG_WX("failed setting power mode.\n"); return err; } } - + return 0; } #define MAX_WX_STRING 80 -static int ipw_wx_get_powermode(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_get_powermode(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); @@ -5929,7 +5929,7 @@ static int ipw_wx_get_powermode(struct net_device *dev, break; default: p += snprintf(p, MAX_WX_STRING - (p - extra), - "(Timeout %dms, Period %dms)", + "(Timeout %dms, Period %dms)", timeout_duration[level - 1] / 1000, period_duration[level - 1] / 1000); } @@ -5955,7 +5955,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, mode); return -EINVAL; } - + if (priv->adapter == IPW_2915ABG) { priv->ieee->abg_ture = 1; if (mode & IEEE_A) { @@ -5978,7 +5978,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, modulation |= IEEE80211_CCK_MODULATION; } else priv->ieee->abg_ture = 0; - + if (mode & IEEE_G) { band |= IEEE80211_24GHZ_BAND; modulation |= IEEE80211_OFDM_MODULATION; @@ -5991,17 +5991,17 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev, init_supported_rates(priv, &priv->rates); /* If we are currently associated, or trying to associate - * then see if this is a new configuration (causing us to + * then see if this is a new configuration (causing us to * disassociate) */ if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { - /* The resulting association will trigger + /* The resulting association will trigger * the new rates to be sent to the device */ IPW_DEBUG_ASSOC("Disassociating due to mode change.\n"); ipw_disassociate(priv); } else ipw_send_supported_rates(priv, &priv->rates); - IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", + IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", mode & IEEE_A ? 'a' : '.', mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); @@ -6020,7 +6020,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, case IEEE80211_CCK_MODULATION: strncpy(extra, "802.11b (2)", MAX_WX_STRING); break; - case IEEE80211_OFDM_MODULATION: + case IEEE80211_OFDM_MODULATION: strncpy(extra, "802.11g (4)", MAX_WX_STRING); break; default: @@ -6029,7 +6029,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, } break; - case IEEE80211_52GHZ_BAND: + case IEEE80211_52GHZ_BAND: strncpy(extra, "802.11a (1)", MAX_WX_STRING); break; @@ -6038,7 +6038,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, case IEEE80211_CCK_MODULATION: strncpy(extra, "802.11ab (3)", MAX_WX_STRING); break; - case IEEE80211_OFDM_MODULATION: + case IEEE80211_OFDM_MODULATION: strncpy(extra, "802.11ag (5)", MAX_WX_STRING); break; default: @@ -6046,8 +6046,8 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, break; } break; - } - + } + IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); wrqu->data.length = strlen(extra) + 1; @@ -6056,10 +6056,10 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev, } #ifdef CONFIG_IPW_PROMISC -static int ipw_wx_set_promisc(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_set_promisc(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); int *parms = (int *)extra; int enable = (parms[0] > 0); @@ -6070,7 +6070,7 @@ static int ipw_wx_set_promisc(struct net_device *dev, priv->net_dev->type = ARPHRD_IEEE80211; ipw_adapter_restart(priv); } - + ipw_set_channel(priv, parms[1]); } else { if (priv->ieee->iw_mode != IW_MODE_MONITOR) @@ -6082,10 +6082,10 @@ static int ipw_wx_set_promisc(struct net_device *dev, } -static int ipw_wx_reset(struct net_device *dev, - struct iw_request_info *info, +static int ipw_wx_reset(struct net_device *dev, + struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ +{ struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_WX("RESET\n"); ipw_adapter_restart(priv); @@ -6135,35 +6135,35 @@ static iw_handler ipw_wx_handlers[] = #define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 -static struct iw_priv_args ipw_priv_args[] = { +static struct iw_priv_args ipw_priv_args[] = { { .cmd = IPW_PRIV_SET_POWER, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, .name = "set_power" - }, + }, { .cmd = IPW_PRIV_GET_POWER, .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_power" + .name = "get_power" }, { .cmd = IPW_PRIV_SET_MODE, .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_mode" + .name = "set_mode" }, { .cmd = IPW_PRIV_GET_MODE, .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_mode" + .name = "get_mode" }, #ifdef CONFIG_IPW_PROMISC { - IPW_PRIV_SET_PROMISC, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" - }, + IPW_PRIV_SET_PROMISC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" + }, { - IPW_PRIV_RESET, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" + IPW_PRIV_RESET, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" }, #endif /* CONFIG_IPW_PROMISC */ }; @@ -6175,18 +6175,18 @@ static iw_handler ipw_priv_handler[] = { ipw_wx_get_wireless_mode, #ifdef CONFIG_IPW_PROMISC ipw_wx_set_promisc, - ipw_wx_reset, + ipw_wx_reset, #endif }; -static struct iw_handler_def ipw_wx_handler_def = +static struct iw_handler_def ipw_wx_handler_def = { .standard = ipw_wx_handlers, .num_standard = ARRAY_SIZE(ipw_wx_handlers), .num_private = ARRAY_SIZE(ipw_priv_handler), .num_private_args = ARRAY_SIZE(ipw_priv_args), - .private = ipw_priv_handler, - .private_args = ipw_priv_args, + .private = ipw_priv_handler, + .private_args = ipw_priv_args, }; @@ -6201,11 +6201,11 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) { struct ipw_priv *priv = ieee80211_priv(dev); struct iw_statistics *wstats; - + wstats = &priv->wstats; /* if hw is disabled, then ipw2100_get_ordinal() can't be called. - * ipw2100_wx_wireless_stats seems to be called before fw is + * ipw2100_wx_wireless_stats seems to be called before fw is * initialized. STATUS_ASSOCIATED will only be set if the hw is up * and associated; if not associcated, the values are all meaningless * anyway, so set them all to NULL and INVALID */ @@ -6219,7 +6219,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) wstats->qual.updated |= IW_QUAL_NOISE_INVALID | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; return wstats; - } + } wstats->qual.qual = priv->quality; wstats->qual.level = average_value(&priv->average_rssi); @@ -6230,11 +6230,11 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device * dev) wstats->miss.beacon = average_value(&priv->average_missed_beacons); wstats->discard.retries = priv->last_tx_failures; wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable; - + /* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len)) goto fail_get_ordinal; wstats->discard.retries += tx_retry; */ - + return wstats; } @@ -6255,7 +6255,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config) sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ sys_config->dot11g_auto_detection = 0; - sys_config->enable_cts_to_self = 0; + sys_config->enable_cts_to_self = 0; sys_config->bt_coexist_collision_thr = 0; sys_config->pass_noise_stats_to_host = 1; } @@ -6265,8 +6265,8 @@ static int ipw_net_open(struct net_device *dev) struct ipw_priv *priv = ieee80211_priv(dev); IPW_DEBUG_INFO("dev->open\n"); /* we should be verifying the device is ready to be opened */ - if (!(priv->status & STATUS_RF_KILL_MASK) && - (priv->status & STATUS_ASSOCIATED)) + if (!(priv->status & STATUS_RF_KILL_MASK) && + (priv->status & STATUS_ASSOCIATED)) netif_start_queue(dev); return 0; } @@ -6306,7 +6306,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) id = ipw_add_station(priv, hdr->addr1); if (id == IPW_INVALID_STATION) { IPW_WARNING("Attempt to send data to " - "invalid cell: " MAC_FMT "\n", + "invalid cell: " MAC_FMT "\n", MAC_ARG(hdr->addr1)); goto drop; } @@ -6337,7 +6337,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) tfd->u.data.tx_flags = DCT_FLAG_NO_WEP; else tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD; - + if (priv->assoc_request.ieee_mode == IPW_B_MODE) tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK; else @@ -6351,10 +6351,10 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) /* payload */ tfd->u.data.num_chunks = min((u8)(NUM_TFD_CHUNKS - 2), txb->nr_frags); for (i = 0; i < tfd->u.data.num_chunks; i++) { - IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", + IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", i, tfd->u.data.num_chunks, txb->fragments[i]->len - hdr_len); - printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len, + printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len, txb->fragments[i]->len - hdr_len); tfd->u.data.chunk_ptr[i] = pci_map_single( @@ -6390,14 +6390,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) priv->pci_dev, skb->data, tfd->u.data.chunk_len[i], PCI_DMA_TODEVICE); tfd->u.data.num_chunks++; - } + } } /* kick DMA */ q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); ipw_write32(priv, q->reg_w, q->first_empty); - if (ipw_queue_space(q) < q->high_mark) + if (ipw_queue_space(q) < q->high_mark) netif_stop_queue(priv->net_dev); return; @@ -6437,7 +6437,7 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, static struct net_device_stats *ipw_net_get_stats(struct net_device *dev) { struct ipw_priv *priv = ieee80211_priv(dev); - + priv->ieee->stats.tx_packets = priv->tx_packets; priv->ieee->stats.rx_packets = priv->rx_packets; return &priv->ieee->stats; @@ -6462,7 +6462,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p) return 0; } -static void ipw_ethtool_get_drvinfo(struct net_device *dev, +static void ipw_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct ipw_priv *p = ieee80211_priv(dev); @@ -6478,7 +6478,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev, len = sizeof(date); ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len); - snprintf(info->fw_version, sizeof(info->fw_version),"%s (%s)", + snprintf(info->fw_version, sizeof(info->fw_version),"%s (%s)", vers, date); strcpy(info->bus_info, pci_name(p->pci_dev)); info->eedump_len = CX2_EEPROM_IMAGE_SIZE; @@ -6502,7 +6502,7 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev, if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) return -EINVAL; - + memcpy(bytes, &((u8 *)p->eeprom)[eeprom->offset], eeprom->len); return 0; } @@ -6517,8 +6517,8 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev, return -EINVAL; memcpy(&((u8 *)p->eeprom)[eeprom->offset], bytes, eeprom->len); - for (i = IPW_EEPROM_DATA; - i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; + for (i = IPW_EEPROM_DATA; + i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++) ipw_write8(p, i, p->eeprom[i]); @@ -6537,7 +6537,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) { struct ipw_priv *priv = data; u32 inta, inta_mask; - + if (!priv) return IRQ_NONE; @@ -6550,7 +6550,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) inta = ipw_read32(priv, CX2_INTA_RW); inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); - + if (inta == 0xFFFFFFFF) { /* Hardware disappeared */ IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n"); @@ -6564,11 +6564,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) /* tell the device to stop sending interrupts */ ipw_disable_interrupts(priv); - + /* ack current interrupts */ inta &= (CX2_INTA_MASK_ALL & inta_mask); ipw_write32(priv, CX2_INTA_RW, inta); - + /* Cache INTA value for our tasklet */ priv->isr_inta = inta; @@ -6586,7 +6586,7 @@ static void ipw_rf_kill(void *adapter) { struct ipw_priv *priv = adapter; unsigned long flags; - + spin_lock_irqsave(&priv->lock, flags); if (rf_kill_active(priv)) { @@ -6605,7 +6605,7 @@ static void ipw_rf_kill(void *adapter) /* we can not do an adapter restart while inside an irq lock */ queue_work(priv->workqueue, &priv->adapter_restart); - } else + } else IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " "enabled\n"); @@ -6621,7 +6621,7 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) priv->workqueue = create_workqueue(DRV_NAME, 0); #else priv->workqueue = create_workqueue(DRV_NAME); -#endif +#endif init_waitqueue_head(&priv->wait_command_queue); INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv); @@ -6632,9 +6632,9 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv); INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv); INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv); - INIT_WORK(&priv->request_scan, + INIT_WORK(&priv->request_scan, (void (*)(void *))ipw_request_scan, priv); - INIT_WORK(&priv->gather_stats, + INIT_WORK(&priv->gather_stats, (void (*)(void *))ipw_gather_stats, priv); INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv); INIT_WORK(&priv->roam, ipw_roam, priv); @@ -6653,17 +6653,17 @@ static void shim__set_security(struct net_device *dev, struct ipw_priv *priv = ieee80211_priv(dev); int i; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { if (sec->flags & (1 << i)) { priv->sec.key_sizes[i] = sec->key_sizes[i]; if (sec->key_sizes[i] == 0) priv->sec.flags &= ~(1 << i); else - memcpy(priv->sec.keys[i], sec->keys[i], + memcpy(priv->sec.keys[i], sec->keys[i], sec->key_sizes[i]); priv->sec.flags |= (1 << i); priv->status |= STATUS_SECURITY_UPDATED; - } + } } if ((sec->flags & SEC_ACTIVE_KEY) && @@ -6671,7 +6671,7 @@ static void shim__set_security(struct net_device *dev, if (sec->active_key <= 3) { priv->sec.active_key = sec->active_key; priv->sec.flags |= SEC_ACTIVE_KEY; - } else + } else priv->sec.flags &= ~SEC_ACTIVE_KEY; priv->status |= STATUS_SECURITY_UPDATED; } @@ -6686,18 +6686,18 @@ static void shim__set_security(struct net_device *dev, priv->capability &= ~CAP_SHARED_KEY; priv->status |= STATUS_SECURITY_UPDATED; } - + if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) { priv->sec.flags |= SEC_ENABLED; priv->sec.enabled = sec->enabled; priv->status |= STATUS_SECURITY_UPDATED; - if (sec->enabled) + if (sec->enabled) priv->capability |= CAP_PRIVACY_ON; else priv->capability &= ~CAP_PRIVACY_ON; } - + if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) { priv->sec.level = sec->level; @@ -6705,14 +6705,14 @@ static void shim__set_security(struct net_device *dev, priv->status |= STATUS_SECURITY_UPDATED; } - /* To match current functionality of ipw2100 (which works well w/ - * various supplicants, we don't force a disassociate if the + /* To match current functionality of ipw2100 (which works well w/ + * various supplicants, we don't force a disassociate if the * privacy capability changes ... */ #if 0 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) && - (((priv->assoc_request.capability & + (((priv->assoc_request.capability & WLAN_CAPABILITY_PRIVACY) && !sec->enabled) || - (!(priv->assoc_request.capability & + (!(priv->assoc_request.capability & WLAN_CAPABILITY_PRIVACY) && sec->enabled))) { IPW_DEBUG_ASSOC("Disassociating due to capability " "change.\n"); @@ -6721,7 +6721,7 @@ static void shim__set_security(struct net_device *dev, #endif } -static int init_supported_rates(struct ipw_priv *priv, +static int init_supported_rates(struct ipw_priv *priv, struct ipw_supported_rates *rates) { /* TODO: Mask out rates based on priv->rates_mask */ @@ -6751,7 +6751,7 @@ static int init_supported_rates(struct ipw_priv *priv, return 0; } -static int ipw_config(struct ipw_priv *priv) +static int ipw_config(struct ipw_priv *priv) { int i; struct ipw_tx_power tx_power; @@ -6799,7 +6799,7 @@ static int ipw_config(struct ipw_priv *priv) if (ipw_set_random_seed(priv)) goto error; - + /* final state transition to the RUN state */ if (ipw_send_host_complete(priv)) goto error; @@ -6809,7 +6809,7 @@ static int ipw_config(struct ipw_priv *priv) goto error; return 0; - + error: return -EIO; } @@ -6823,7 +6823,7 @@ static int ipw_up(struct ipw_priv *priv) return -EIO; for (i = 0; i < MAX_HW_RESTARTS; i++ ) { - /* Load the microcode, firmware, and eeprom. + /* Load the microcode, firmware, and eeprom. * Also start the clocks. */ rc = ipw_load(priv); if (rc) { @@ -6850,7 +6850,7 @@ static int ipw_up(struct ipw_priv *priv) IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc); } - + IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n", i, MAX_HW_RESTARTS); @@ -6859,7 +6859,7 @@ static int ipw_up(struct ipw_priv *priv) ipw_down(priv); } - /* tried to restart and config the device for as long as our + /* tried to restart and config the device for as long as our * patience could withstand */ IPW_ERROR("Unable to initialize device after %d attempts.\n", i); @@ -6931,7 +6931,7 @@ static struct pci_device_id card_ids[] = { {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ - + /* required last entry */ {0,} }; @@ -6994,7 +6994,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, pci_set_master(pdev); err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (!err) + if (!err) err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); if (err) { printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n"); @@ -7004,18 +7004,18 @@ static int ipw_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, priv); err = pci_request_regions(pdev, DRV_NAME); - if (err) + if (err) goto out_pci_disable_device; - /* We disable the RETRY_TIMEOUT register (0x41) to keep + /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - + length = pci_resource_len(pdev, 0); priv->hw_len = length; - + base = ioremap_nocache(pci_resource_start(pdev, 0), length); if (!base) { err = -ENODEV; @@ -7036,16 +7036,16 @@ static int ipw_pci_probe(struct pci_dev *pdev, if (ifname) strncpy(net_dev->name, ifname, IFNAMSIZ); - if (associate) + if (associate) priv->config |= CFG_ASSOCIATE; else IPW_DEBUG_INFO("Auto associate disabled.\n"); - - if (auto_create) + + if (auto_create) priv->config |= CFG_ADHOC_CREATE; else IPW_DEBUG_INFO("Auto adhoc creation disabled.\n"); - + if (disable) { priv->status |= STATUS_RF_KILL_SW; IPW_DEBUG_INFO("Radio disabled.\n"); @@ -7063,7 +7063,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, case 1: priv->ieee->iw_mode = IW_MODE_ADHOC; break; -#ifdef CONFIG_IPW_PROMISC +#ifdef CONFIG_IPW_PROMISC case 2: priv->ieee->iw_mode = IW_MODE_MONITOR; break; @@ -7076,7 +7076,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, if ((priv->pci_dev->device == 0x4223) || (priv->pci_dev->device == 0x4224)) { - printk(KERN_INFO DRV_NAME + printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2915ABG Network " "Connection\n"); priv->ieee->abg_ture = 1; @@ -7086,15 +7086,15 @@ static int ipw_pci_probe(struct pci_dev *pdev, priv->adapter = IPW_2915ABG; priv->ieee->mode = IEEE_A|IEEE_G|IEEE_B; } else { - if (priv->pci_dev->device == 0x4221) - printk(KERN_INFO DRV_NAME + if (priv->pci_dev->device == 0x4221) + printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2225BG Network " "Connection\n"); else - printk(KERN_INFO DRV_NAME + printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2200BG Network " "Connection\n"); - + priv->ieee->abg_ture = 0; band = IEEE80211_24GHZ_BAND; modulation = IEEE80211_OFDM_MODULATION | @@ -7117,7 +7117,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, priv->power_mode = IPW_POWER_AC; priv->tx_power = IPW_DEFAULT_TX_POWER; - err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, + err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); if (err) { IPW_ERROR("Error allocating IRQ %d\n", pdev->irq); @@ -7200,7 +7200,7 @@ static void ipw_pci_remove(struct pci_dev *pdev) /* ipw_down will ensure that there is no more pending work * in the workqueue's, so we can safely remove them now. */ - if (priv->workqueue) { + if (priv->workqueue) { cancel_delayed_work(&priv->adhoc_check); cancel_delayed_work(&priv->gather_stats); cancel_delayed_work(&priv->request_scan); @@ -7249,7 +7249,7 @@ static int ipw_pci_suspend(struct pci_dev *pdev, u32 state) #endif pci_disable_device(pdev); pci_set_power_state(pdev, state); - + return 0; } @@ -7258,7 +7258,7 @@ static int ipw_pci_resume(struct pci_dev *pdev) struct ipw_priv *priv = pci_get_drvdata(pdev); struct net_device *dev = priv->net_dev; u32 val; - + printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); pci_set_power_state(pdev, 0); @@ -7274,8 +7274,8 @@ static int ipw_pci_resume(struct pci_dev *pdev) * from interfering with C3 CPU state. pci_restore_state won't help * here since it only restores the first 64 bytes pci config header. */ - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); /* Set the device back into the PRESENT state; this will also wake @@ -7284,7 +7284,7 @@ static int ipw_pci_resume(struct pci_dev *pdev) /* Bring the device back up */ queue_work(priv->workqueue, &priv->up); - + return 0; } #endif @@ -7314,7 +7314,7 @@ static int __init ipw_init(void) return ret; } - ret = driver_create_file(&ipw_driver.driver, + ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level); if (ret) { IPW_ERROR("Unable to create driver sysfs file\n"); @@ -7344,12 +7344,12 @@ module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); module_param(channel, int, 0444); -MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); +MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); module_param(ifname, charp, 0444); MODULE_PARM_DESC(ifname, "network device name (default eth%d)"); -#ifdef CONFIG_IPW_PROMISC +#ifdef CONFIG_IPW_PROMISC module_param(mode, int, 0444); MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); #else diff --git a/trunk/drivers/net/wireless/ipw2200.h b/trunk/drivers/net/wireless/ipw2200.h index 4e8b75e7962a..78b5f444271d 100644 --- a/trunk/drivers/net/wireless/ipw2200.h +++ b/trunk/drivers/net/wireless/ipw2200.h @@ -1,23 +1,23 @@ /****************************************************************************** - + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 + this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + The full GNU General Public License is included in this distribution in the file called LICENSE. - + Contact Information: James P. Ketrenos Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -55,8 +55,8 @@ #ifndef IRQ_NONE typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED +#define IRQ_NONE +#define IRQ_HANDLED #define IRQ_RETVAL(x) #endif @@ -179,18 +179,18 @@ enum connection_manager_assoc_states #define IPW_B_MODE 1 #define IPW_G_MODE 2 -/* - * TX Queue Flag Definitions +/* + * TX Queue Flag Definitions */ /* abort attempt if mgmt frame is rx'd */ -#define DCT_FLAG_ABORT_MGMT 0x01 - +#define DCT_FLAG_ABORT_MGMT 0x01 + /* require CTS */ #define DCT_FLAG_CTS_REQUIRED 0x02 /* use short preamble */ -#define DCT_FLAG_SHORT_PREMBL 0x04 +#define DCT_FLAG_SHORT_PREMBL 0x04 /* RTS/CTS first */ #define DCT_FLAG_RTS_REQD 0x08 @@ -205,7 +205,7 @@ enum connection_manager_assoc_states #define DCT_FLAG_TSF_REQD 0x40 /* ACK rx is expected to follow */ -#define DCT_FLAG_ACK_REQD 0x80 +#define DCT_FLAG_ACK_REQD 0x80 #define DCT_FLAG_EXT_MODE_CCK 0x01 #define DCT_FLAG_EXT_MODE_OFDM 0x00 @@ -238,13 +238,13 @@ enum connection_manager_assoc_states #define HOST_NOTIFICATION_CHANNEL_SWITCHED 23 #define HOST_NOTIFICATION_RX_DURING_QUIET_PERIOD 24 #define HOST_NOTIFICATION_NOISE_STATS 25 -#define HOST_NOTIFICATION_S36_MEASUREMENT_ACCEPTED 30 +#define HOST_NOTIFICATION_S36_MEASUREMENT_ACCEPTED 30 #define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31 #define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1 #define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT 24 #define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8 -#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300 +#define IPW_REAL_RATE_RX_PACKET_THRESHOLD 300 #define MACADRR_BYTE_LEN 6 @@ -258,7 +258,7 @@ enum connection_manager_assoc_states /** * Generic queue structure - * + * * Contains common data for Rx and Tx queues */ struct clx2_queue { @@ -318,7 +318,7 @@ struct machdr24 // TX TFD with 32 byte MAC Header struct tx_tfd_32 -{ +{ struct machdr32 mchdr; // 32 u32 uivplaceholder[2]; // 8 } __attribute__ ((packed)) ; @@ -368,8 +368,8 @@ struct tfd_data { /* Tx Parameters */ u8 cmd_id; - u8 seq_num; - u16 len; + u8 seq_num; + u16 len; u8 priority; u8 tx_flags; u8 tx_flags_ext; @@ -378,10 +378,10 @@ struct tfd_data { u8 rate; u8 antenna; u16 next_packet_duration; - u16 next_frag_len; + u16 next_frag_len; u16 back_off_counter; //////txop; u8 retrylimit; - u16 cwcurrent; + u16 cwcurrent; u8 reserved3; /* 802.11 MAC Header */ @@ -457,29 +457,29 @@ struct rate_histogram } failed; } __attribute__ ((packed)); -/* statistics command response */ +/* statistics command response */ struct ipw_cmd_stats { u8 cmd_id; u8 seq_num; - u16 good_sfd; - u16 bad_plcp; - u16 wrong_bssid; - u16 valid_mpdu; - u16 bad_mac_header; - u16 reserved_frame_types; - u16 rx_ina; - u16 bad_crc32; - u16 invalid_cts; - u16 invalid_acks; - u16 long_distance_ina_fina; + u16 good_sfd; + u16 bad_plcp; + u16 wrong_bssid; + u16 valid_mpdu; + u16 bad_mac_header; + u16 reserved_frame_types; + u16 rx_ina; + u16 bad_crc32; + u16 invalid_cts; + u16 invalid_acks; + u16 long_distance_ina_fina; u16 dsp_silence_unreachable; - u16 accumulated_rssi; - u16 rx_ovfl_frame_tossed; + u16 accumulated_rssi; + u16 rx_ovfl_frame_tossed; u16 rssi_silence_threshold; u16 rx_ovfl_frame_supplied; - u16 last_rx_frame_signal; - u16 last_rx_frame_noise; - u16 rx_autodetec_no_ofdm; + u16 last_rx_frame_signal; + u16 last_rx_frame_noise; + u16 rx_autodetec_no_ofdm; u16 rx_autodetec_no_barker; u16 reserved; } __attribute__ ((packed)); @@ -568,11 +568,11 @@ struct ipw_rx_notification { } __attribute__ ((packed)); struct ipw_rx_frame { - u32 reserved1; + u32 reserved1; u8 parent_tsf[4]; // fw_use[0] is boolean for OUR_TSF_IS_GREATER u8 received_channel; // The channel that this frame was received on. - // Note that for .11b this does not have to be - // the same as the channel that it was sent. + // Note that for .11b this does not have to be + // the same as the channel that it was sent. // Filled by LMAC u8 frameStatus; u8 rate; @@ -583,13 +583,13 @@ struct ipw_rx_frame { u16 noise; u8 antennaAndPhy; u8 control; // control bit should be on in bg - u8 rtscts_rate; // rate of rts or cts (in rts cts sequence rate + u8 rtscts_rate; // rate of rts or cts (in rts cts sequence rate // is identical) u8 rtscts_seen; // 0x1 RTS seen ; 0x2 CTS seen u16 length; u8 data[0]; } __attribute__ ((packed)); - + struct ipw_rx_header { u8 message_type; u8 rx_seq_num; @@ -716,8 +716,8 @@ struct ipw_wep_key } __attribute__ ((packed)); struct ipw_tgi_tx_key -{ - u8 key_id; +{ + u8 key_id; u8 security_type; u8 station_index; u8 flags; @@ -727,7 +727,7 @@ struct ipw_tgi_tx_key #define IPW_SCAN_CHANNELS 54 -struct ipw_scan_request +struct ipw_scan_request { u8 scan_type; u16 dwell_time; @@ -753,7 +753,7 @@ struct ipw_scan_request_ext u16 dwell_time[IPW_SCAN_TYPES]; } __attribute__ ((packed)); -extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) +extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) { if (index % 2) return scan->scan_type[index / 2] & 0x0F; @@ -761,16 +761,16 @@ extern inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) return (scan->scan_type[index / 2] & 0xF0) >> 4; } -extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, +extern inline void ipw_set_scan_type(struct ipw_scan_request_ext *scan, u8 index, u8 scan_type) { - if (index % 2) - scan->scan_type[index / 2] = - (scan->scan_type[index / 2] & 0xF0) | + if (index % 2) + scan->scan_type[index / 2] = + (scan->scan_type[index / 2] & 0xF0) | (scan_type & 0x0F); else - scan->scan_type[index / 2] = - (scan->scan_type[index / 2] & 0x0F) | + scan->scan_type[index / 2] = + (scan->scan_type[index / 2] & 0x0F) | ((scan_type & 0x0F) << 4); } @@ -909,14 +909,14 @@ struct ipw_sensitivity_calib /** * Host command structure. - * + * * On input, the following fields should be filled: * - cmd * - len * - status_len * - param (if needed) - * - * On output, + * + * On output, * - \a status contains status; * - \a param filled with status parameters. */ @@ -926,8 +926,8 @@ struct ipw_cmd { u32 status_len; /**< How many 32 bit parameters in the status */ u32 len; /**< incoming parameters length, bytes */ /** - * command parameters. - * There should be enough space for incoming and + * command parameters. + * There should be enough space for incoming and * outcoming parameters. * Incoming parameters listed 1-st, followed by outcoming params. * nParams=(len+3)/4+status_len @@ -955,8 +955,8 @@ struct ipw_cmd { #define STATUS_STATE_PENDING (1<<13) #define STATUS_SCAN_PENDING (1<<20) -#define STATUS_SCANNING (1<<21) -#define STATUS_SCAN_ABORTING (1<<22) +#define STATUS_SCANNING (1<<21) +#define STATUS_SCAN_ABORTING (1<<22) #define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ #define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ @@ -1009,7 +1009,7 @@ struct ipw_priv { /* pci hardware address support */ void __iomem *hw_base; unsigned long hw_len; - + struct fw_image_desc sram_desc; /* result of ucode download */ @@ -1036,7 +1036,7 @@ struct ipw_priv { int rx_pend_max; /**< maximum pending buffers for one IRQ */ u32 hcmd_seq; /**< sequence number for hcmd */ u32 missed_beacon_threshold; - u32 roaming_threshold; + u32 roaming_threshold; struct ipw_associate assoc_request; struct ieee80211_network *assoc_network; @@ -1071,11 +1071,11 @@ struct ipw_priv { u8 channel; struct ipw_sys_config sys_config; u32 power_mode; - u8 bssid[ETH_ALEN]; + u8 bssid[ETH_ALEN]; u16 rts_threshold; u8 mac_addr[ETH_ALEN]; u8 num_stations; - u8 stations[MAX_STATIONS][ETH_ALEN]; + u8 stations[MAX_STATIONS][ETH_ALEN]; u32 notif_missed_beacons; @@ -1094,13 +1094,13 @@ struct ipw_priv { u32 quality; /* eeprom */ - u8 eeprom[0x100]; /* 256 bytes of eeprom */ + u8 eeprom[0x100]; /* 256 bytes of eeprom */ int eeprom_delay; - struct iw_statistics wstats; + struct iw_statistics wstats; struct workqueue_struct *workqueue; - + struct work_struct adhoc_check; struct work_struct associate; struct work_struct disassociate; @@ -1125,7 +1125,7 @@ struct ipw_priv { #define IPW_DEFAULT_TX_POWER 0x14 u8 tx_power; -#ifdef CONFIG_PM +#ifdef CONFIG_PM u32 pm_state[16]; #endif @@ -1159,7 +1159,7 @@ do { if (ipw_debug_level & (level)) \ * list here in the form of: * * #define IPW_DL_xxxx VALUE - * + * * shifting value to the left one bit from the previous entry. xxxx should be * the name of the classification (for example, WEP) * @@ -1173,7 +1173,7 @@ do { if (ipw_debug_level & (level)) \ * * you simply need to add your entry to the ipw_debug_levels array. * - * If you do not see debug_level in /proc/net/ipw then you do not have + * If you do not see debug_level in /proc/net/ipw then you do not have * CONFIG_IPW_DEBUG defined in your kernel configuration * */ @@ -1247,7 +1247,7 @@ do { if (ipw_debug_level & (level)) \ #define DINO_ENABLE_SYSTEM 0x80 #define DINO_ENABLE_CS 0x40 -#define DINO_RXFIFO_DATA 0x01 +#define DINO_RXFIFO_DATA 0x01 #define DINO_CONTROL_REG 0x00200000 #define CX2_INTA_RW 0x00000008 @@ -1320,7 +1320,7 @@ do { if (ipw_debug_level & (level)) \ #define DMA_CONTROL_SMALL_CB_CONST_VALUE 0x00540000 #define DMA_CB_STOP_AND_ABORT 0x00000C00 -#define DMA_CB_START 0x00000100 +#define DMA_CB_START 0x00000100 #define CX2_SHARED_SRAM_SIZE 0x00030000 @@ -1410,7 +1410,7 @@ do { if (ipw_debug_level & (level)) \ #define EEPROM_NIC_TYPE_HP 4 #define FW_MEM_REG_LOWER_BOUND 0x00300000 -#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) +#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) #define EEPROM_BIT_SK (1<<0) #define EEPROM_BIT_CS (1<<1) @@ -1506,15 +1506,15 @@ enum { #define IPW_RATE_CONNECT 0 -/* - * Rate values and masks +/* + * Rate values and masks */ #define IPW_TX_RATE_1MB 0x0A #define IPW_TX_RATE_2MB 0x14 #define IPW_TX_RATE_5MB 0x37 #define IPW_TX_RATE_6MB 0x0D #define IPW_TX_RATE_9MB 0x0F -#define IPW_TX_RATE_11MB 0x6E +#define IPW_TX_RATE_11MB 0x6E #define IPW_TX_RATE_12MB 0x05 #define IPW_TX_RATE_18MB 0x07 #define IPW_TX_RATE_24MB 0x09 @@ -1525,25 +1525,25 @@ enum { #define IPW_ORD_TABLE_ID_MASK 0x0000FF00 #define IPW_ORD_TABLE_VALUE_MASK 0x000000FF -#define IPW_ORD_TABLE_0_MASK 0x0000F000 -#define IPW_ORD_TABLE_1_MASK 0x0000F100 -#define IPW_ORD_TABLE_2_MASK 0x0000F200 -#define IPW_ORD_TABLE_3_MASK 0x0000F300 -#define IPW_ORD_TABLE_4_MASK 0x0000F400 -#define IPW_ORD_TABLE_5_MASK 0x0000F500 -#define IPW_ORD_TABLE_6_MASK 0x0000F600 -#define IPW_ORD_TABLE_7_MASK 0x0000F700 +#define IPW_ORD_TABLE_0_MASK 0x0000F000 +#define IPW_ORD_TABLE_1_MASK 0x0000F100 +#define IPW_ORD_TABLE_2_MASK 0x0000F200 +#define IPW_ORD_TABLE_3_MASK 0x0000F300 +#define IPW_ORD_TABLE_4_MASK 0x0000F400 +#define IPW_ORD_TABLE_5_MASK 0x0000F500 +#define IPW_ORD_TABLE_6_MASK 0x0000F600 +#define IPW_ORD_TABLE_7_MASK 0x0000F700 /* * Table 0 Entries (all entries are 32 bits) */ -enum { +enum { IPW_ORD_STAT_TX_CURR_RATE = IPW_ORD_TABLE_0_MASK + 1, IPW_ORD_STAT_FRAG_TRESHOLD, IPW_ORD_STAT_RTS_THRESHOLD, - IPW_ORD_STAT_TX_HOST_REQUESTS, - IPW_ORD_STAT_TX_HOST_COMPLETE, - IPW_ORD_STAT_TX_DIR_DATA, + IPW_ORD_STAT_TX_HOST_REQUESTS, + IPW_ORD_STAT_TX_HOST_COMPLETE, + IPW_ORD_STAT_TX_DIR_DATA, IPW_ORD_STAT_TX_DIR_DATA_B_1, IPW_ORD_STAT_TX_DIR_DATA_B_2, IPW_ORD_STAT_TX_DIR_DATA_B_5_5, @@ -1561,18 +1561,18 @@ enum { IPW_ORD_STAT_TX_DIR_DATA_G_5_5, IPW_ORD_STAT_TX_DIR_DATA_G_6, IPW_ORD_STAT_TX_DIR_DATA_G_9, - IPW_ORD_STAT_TX_DIR_DATA_G_11, + IPW_ORD_STAT_TX_DIR_DATA_G_11, IPW_ORD_STAT_TX_DIR_DATA_G_12, IPW_ORD_STAT_TX_DIR_DATA_G_18, IPW_ORD_STAT_TX_DIR_DATA_G_24, IPW_ORD_STAT_TX_DIR_DATA_G_36, IPW_ORD_STAT_TX_DIR_DATA_G_48, IPW_ORD_STAT_TX_DIR_DATA_G_54, - IPW_ORD_STAT_TX_NON_DIR_DATA, + IPW_ORD_STAT_TX_NON_DIR_DATA, IPW_ORD_STAT_TX_NON_DIR_DATA_B_1, IPW_ORD_STAT_TX_NON_DIR_DATA_B_2, IPW_ORD_STAT_TX_NON_DIR_DATA_B_5_5, - IPW_ORD_STAT_TX_NON_DIR_DATA_B_11, + IPW_ORD_STAT_TX_NON_DIR_DATA_B_11, /* Hole */ @@ -1586,7 +1586,7 @@ enum { IPW_ORD_STAT_TX_NON_DIR_DATA_G_5_5, IPW_ORD_STAT_TX_NON_DIR_DATA_G_6, IPW_ORD_STAT_TX_NON_DIR_DATA_G_9, - IPW_ORD_STAT_TX_NON_DIR_DATA_G_11, + IPW_ORD_STAT_TX_NON_DIR_DATA_G_11, IPW_ORD_STAT_TX_NON_DIR_DATA_G_12, IPW_ORD_STAT_TX_NON_DIR_DATA_G_18, IPW_ORD_STAT_TX_NON_DIR_DATA_G_24, @@ -1601,12 +1601,12 @@ enum { IPW_ORD_STAT_FULL_SCANS, IPW_ORD_STAT_PARTIAL_SCANS, IPW_ORD_STAT_TGH_ABORTED_SCANS, - IPW_ORD_STAT_TX_TOTAL_BYTES, + IPW_ORD_STAT_TX_TOTAL_BYTES, IPW_ORD_STAT_CURR_RSSI_RAW, IPW_ORD_STAT_RX_BEACON, IPW_ORD_STAT_MISSED_BEACONS, - IPW_ORD_TABLE_0_LAST -}; + IPW_ORD_TABLE_0_LAST +}; #define IPW_RSSI_TO_DBM 112 @@ -1626,15 +1626,15 @@ enum { * ADDAPTER_MAC: 6 byte MAC address * RTC: 4 byte clock */ -enum { +enum { IPW_ORD_STAT_FW_VERSION = IPW_ORD_TABLE_2_MASK | 1, - IPW_ORD_STAT_FW_DATE, + IPW_ORD_STAT_FW_DATE, IPW_ORD_STAT_UCODE_VERSION, - IPW_ORD_STAT_UCODE_DATE, - IPW_ORD_STAT_ADAPTER_MAC, - IPW_ORD_STAT_RTC, - IPW_ORD_TABLE_2_LAST -}; + IPW_ORD_STAT_UCODE_DATE, + IPW_ORD_STAT_ADAPTER_MAC, + IPW_ORD_STAT_RTC, + IPW_ORD_TABLE_2_LAST +}; /* Table 3 */ enum { @@ -1711,7 +1711,7 @@ struct host_cmd { #define CFG_BT_COEXISTENCE_WME_OVER_BT 0x08 #define CFG_BT_COEXISTENCE_OOB 0x10 #define CFG_BT_COEXISTENCE_MAX 0xFF -#define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM*/ +#define CFG_BT_COEXISTENCE_DEF 0x80 /* read Bt from EEPROM*/ #define CFG_CTS_TO_ITSELF_ENABLED_MIN 0x0 #define CFG_CTS_TO_ITSELF_ENABLED_MAX 0x1 @@ -1722,9 +1722,9 @@ struct host_cmd { #define CFG_SYS_ANTENNA_B 0x003 /* - * The definitions below were lifted off the ipw2100 driver, which only + * The definitions below were lifted off the ipw2100 driver, which only * supports 'b' mode, so I'm sure these are not exactly correct. - * + * * Somebody fix these!! */ #define REG_MIN_CHANNEL 0 @@ -1733,11 +1733,11 @@ struct host_cmd { #define REG_CHANNEL_MASK 0x00003FFF #define IPW_IBSS_11B_DEFAULT_MASK 0x87ff -static const long ipw_frequencies[] = { - 2412, 2417, 2422, 2427, - 2432, 2437, 2442, 2447, - 2452, 2457, 2462, 2467, - 2472, 2484 +static const long ipw_frequencies[] = { + 2412, 2417, 2422, 2427, + 2432, 2437, 2442, 2447, + 2452, 2457, 2462, 2467, + 2472, 2484 }; #define FREQ_COUNT ARRAY_SIZE(ipw_frequencies) diff --git a/trunk/drivers/net/wireless/strip.c b/trunk/drivers/net/wireless/strip.c index 4b0acae22b0d..6c42b573a95a 100644 --- a/trunk/drivers/net/wireless/strip.c +++ b/trunk/drivers/net/wireless/strip.c @@ -209,7 +209,7 @@ enum { NoStructure = 0, /* Really old firmware */ StructuredMessages = 1, /* Parsable AT response msgs */ ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */ -}; +} FirmwareLevel; struct strip { int magic; diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index 183c4732ef65..f6130a53b796 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -59,12 +59,6 @@ /* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */ #include "wavelan_cs.p.h" /* Private header */ -#ifdef WAVELAN_ROAMING -static void wl_cell_expiry(unsigned long data); -static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp); -static void wv_nwid_filter(unsigned char mode, net_local *lp); -#endif /* WAVELAN_ROAMING */ - /************************* MISC SUBROUTINES **************************/ /* * Subroutines which won't fit in one of the following category @@ -506,9 +500,9 @@ fee_write(u_long base, /* i/o port of the card */ #ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */ -static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00}; +unsigned char WAVELAN_BEACON_ADDRESS[]= {0x09,0x00,0x0e,0x20,0x03,0x00}; -static void wv_roam_init(struct net_device *dev) +void wv_roam_init(struct net_device *dev) { net_local *lp= netdev_priv(dev); @@ -537,7 +531,7 @@ static void wv_roam_init(struct net_device *dev) printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name); } -static void wv_roam_cleanup(struct net_device *dev) +void wv_roam_cleanup(struct net_device *dev) { wavepoint_history *ptr,*old_ptr; net_local *lp= netdev_priv(dev); @@ -556,7 +550,7 @@ static void wv_roam_cleanup(struct net_device *dev) } /* Enable/Disable NWID promiscuous mode on a given device */ -static void wv_nwid_filter(unsigned char mode, net_local *lp) +void wv_nwid_filter(unsigned char mode, net_local *lp) { mm_t m; unsigned long flags; @@ -581,7 +575,7 @@ static void wv_nwid_filter(unsigned char mode, net_local *lp) } /* Find a record in the WavePoint table matching a given NWID */ -static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp) +wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp) { wavepoint_history *ptr=lp->wavepoint_table.head; @@ -594,7 +588,7 @@ static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp) } /* Create a new wavepoint table entry */ -static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp) +wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp) { wavepoint_history *new_wavepoint; @@ -630,7 +624,7 @@ static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char se } /* Remove a wavepoint entry from WavePoint table */ -static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp) +void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp) { if(wavepoint==NULL) return; @@ -652,7 +646,7 @@ static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp) } /* Timer callback function - checks WavePoint table for stale entries */ -static void wl_cell_expiry(unsigned long data) +void wl_cell_expiry(unsigned long data) { net_local *lp=(net_local *)data; wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point; @@ -692,7 +686,7 @@ static void wl_cell_expiry(unsigned long data) } /* Update SNR history of a wavepoint */ -static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq) +void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq) { int i=0,num_missed=0,ptr=0; int average_fast=0,average_slow=0; @@ -729,7 +723,7 @@ static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqua } /* Perform a handover to a new WavePoint */ -static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp) +void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp) { kio_addr_t base = lp->dev->base_addr; mm_t m; diff --git a/trunk/drivers/net/wireless/wavelan_cs.h b/trunk/drivers/net/wireless/wavelan_cs.h index fabc63ee153c..29cff6daf860 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.h +++ b/trunk/drivers/net/wireless/wavelan_cs.h @@ -62,7 +62,7 @@ * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this * part to accommodate your hardware... */ -static const unsigned char MAC_ADDRESSES[][3] = +const unsigned char MAC_ADDRESSES[][3] = { { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */ { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */ @@ -79,14 +79,14 @@ static const unsigned char MAC_ADDRESSES[][3] = * (as read in the offset register of the dac area). * Used to map channel numbers used by `wfreqsel' to frequencies */ -static const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, +const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, 0xD0, 0xF0, 0xF8, 0x150 }; /* Frequencies of the 1.0 modem (fixed frequencies). * Use to map the PSA `subband' to a frequency * Note : all frequencies apart from the first one need to be multiplied by 10 */ -static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; +const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; /*************************** PC INTERFACE ****************************/ diff --git a/trunk/drivers/net/wireless/wavelan_cs.p.h b/trunk/drivers/net/wireless/wavelan_cs.p.h index 01d882be8790..677ff71883cb 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.p.h +++ b/trunk/drivers/net/wireless/wavelan_cs.p.h @@ -647,6 +647,23 @@ struct net_local void __iomem *mem; }; +/**************************** PROTOTYPES ****************************/ + +#ifdef WAVELAN_ROAMING +/* ---------------------- ROAMING SUBROUTINES -----------------------*/ + +wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp); +wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local *lp); +void wl_del_wavepoint(wavepoint_history *wavepoint, net_local *lp); +void wl_cell_expiry(unsigned long data); +wavepoint_history *wl_best_sigqual(int fast_search, net_local *lp); +void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq); +void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp); +void wv_nwid_filter(unsigned char mode, net_local *lp); +void wv_roam_init(struct net_device *dev); +void wv_roam_cleanup(struct net_device *dev); +#endif /* WAVELAN_ROAMING */ + /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ static inline u_char /* data */ hasr_read(u_long); /* Read the host interface : base address */ diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c index 7cc5edbf6ede..dd902126d018 100644 --- a/trunk/drivers/net/wireless/wl3501_cs.c +++ b/trunk/drivers/net/wireless/wl3501_cs.c @@ -296,8 +296,7 @@ static int wl3501_get_flash_mac_addr(struct wl3501_card *this) * * Move 'size' bytes from PC to card. (Shouldn't be interrupted) */ -static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, - int size) +void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size) { /* switch to SRAM Page 0 */ wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 : @@ -318,8 +317,8 @@ static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, * * Move 'size' bytes from card to PC. (Shouldn't be interrupted) */ -static void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest, - int size) +void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest, + int size) { /* switch to SRAM Page 0 */ wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 : @@ -1439,14 +1438,14 @@ static int wl3501_open(struct net_device *dev) goto out; } -static struct net_device_stats *wl3501_get_stats(struct net_device *dev) +struct net_device_stats *wl3501_get_stats(struct net_device *dev) { struct wl3501_card *this = dev->priv; return &this->stats; } -static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) +struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) { struct wl3501_card *this = dev->priv; struct iw_statistics *wstats = &this->wstats;