aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/airo.c65
-rw-r--r--drivers/net/wireless/hostap/Kconfig104
-rw-r--r--drivers/net/wireless/hostap/Makefile8
-rw-r--r--drivers/net/wireless/hostap/hostap.c1207
-rw-r--r--drivers/net/wireless/hostap/hostap.h57
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h107
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c1084
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c522
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c3286
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h272
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h557
-rw-r--r--drivers/net/wireless/hostap/hostap_config.h86
-rw-r--r--drivers/net/wireless/hostap/hostap_crypt.c167
-rw-r--r--drivers/net/wireless/hostap/hostap_crypt.h50
-rw-r--r--drivers/net/wireless/hostap/hostap_crypt_ccmp.c486
-rw-r--r--drivers/net/wireless/hostap/hostap_crypt_tkip.c696
-rw-r--r--drivers/net/wireless/hostap/hostap_crypt_wep.c281
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c950
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c766
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c3631
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c478
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c4123
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c453
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c620
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c466
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h1075
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/net/wireless/wavelan_cs.c26
-rw-r--r--drivers/net/wireless/wavelan_cs.h6
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h17
-rw-r--r--drivers/net/wireless/wl3501_cs.c11
33 files changed, 21595 insertions, 68 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 0aaa12c0c098..a60866d62ec7 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -355,6 +355,8 @@ config PRISM54
355 say M here and read <file:Documentation/modules.txt>. The module 355 say M here and read <file:Documentation/modules.txt>. The module
356 will be called prism54.ko. 356 will be called prism54.ko.
357 357
358source "drivers/net/wireless/hostap/Kconfig"
359
358# yes, this works even when no drivers are selected 360# yes, this works even when no drivers are selected
359config NET_WIRELESS 361config NET_WIRELESS
360 bool 362 bool
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 2b87841322cc..6c9cb0eb8581 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -28,6 +28,8 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
28 28
29obj-$(CONFIG_PRISM54) += prism54/ 29obj-$(CONFIG_PRISM54) += prism54/
30 30
31obj-$(CONFIG_HOSTAP) += hostap/
32
31# 16-bit wireless PCMCIA client drivers 33# 16-bit wireless PCMCIA client drivers
32obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o 34obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
33obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o 35obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 463c789cdc77..e3168a13b786 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1040,7 +1040,7 @@ typedef struct {
1040 u16 status; 1040 u16 status;
1041} WifiCtlHdr; 1041} WifiCtlHdr;
1042 1042
1043WifiCtlHdr wifictlhdr8023 = { 1043static WifiCtlHdr wifictlhdr8023 = {
1044 .ctlhdr = { 1044 .ctlhdr = {
1045 .ctl = HOST_DONT_RLSE, 1045 .ctl = HOST_DONT_RLSE,
1046 } 1046 }
@@ -1111,13 +1111,13 @@ static int airo_thread(void *data);
1111static void timer_func( struct net_device *dev ); 1111static void timer_func( struct net_device *dev );
1112static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 1112static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
1113#ifdef WIRELESS_EXT 1113#ifdef WIRELESS_EXT
1114struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); 1114static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
1115static void airo_read_wireless_stats (struct airo_info *local); 1115static void airo_read_wireless_stats (struct airo_info *local);
1116#endif /* WIRELESS_EXT */ 1116#endif /* WIRELESS_EXT */
1117#ifdef CISCO_EXT 1117#ifdef CISCO_EXT
1118static int readrids(struct net_device *dev, aironet_ioctl *comp); 1118static int readrids(struct net_device *dev, aironet_ioctl *comp);
1119static int writerids(struct net_device *dev, aironet_ioctl *comp); 1119static int writerids(struct net_device *dev, aironet_ioctl *comp);
1120int flashcard(struct net_device *dev, aironet_ioctl *comp); 1120static int flashcard(struct net_device *dev, aironet_ioctl *comp);
1121#endif /* CISCO_EXT */ 1121#endif /* CISCO_EXT */
1122#ifdef MICSUPPORT 1122#ifdef MICSUPPORT
1123static void micinit(struct airo_info *ai); 1123static void micinit(struct airo_info *ai);
@@ -1223,6 +1223,12 @@ static int setup_proc_entry( struct net_device *dev,
1223static int takedown_proc_entry( struct net_device *dev, 1223static int takedown_proc_entry( struct net_device *dev,
1224 struct airo_info *apriv ); 1224 struct airo_info *apriv );
1225 1225
1226static int cmdreset(struct airo_info *ai);
1227static int setflashmode (struct airo_info *ai);
1228static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
1229static int flashputbuf(struct airo_info *ai);
1230static int flashrestart(struct airo_info *ai,struct net_device *dev);
1231
1226#ifdef MICSUPPORT 1232#ifdef MICSUPPORT
1227/*********************************************************************** 1233/***********************************************************************
1228 * MIC ROUTINES * 1234 * MIC ROUTINES *
@@ -1231,10 +1237,11 @@ static int takedown_proc_entry( struct net_device *dev,
1231 1237
1232static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq); 1238static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
1233static void MoveWindow(miccntx *context, u32 micSeq); 1239static void MoveWindow(miccntx *context, u32 micSeq);
1234void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *); 1240static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *);
1235void emmh32_init(emmh32_context *context); 1241static void emmh32_init(emmh32_context *context);
1236void emmh32_update(emmh32_context *context, u8 *pOctets, int len); 1242static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1237void emmh32_final(emmh32_context *context, u8 digest[4]); 1243static void emmh32_final(emmh32_context *context, u8 digest[4]);
1244static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
1238 1245
1239/* micinit - Initialize mic seed */ 1246/* micinit - Initialize mic seed */
1240 1247
@@ -1312,7 +1319,7 @@ static int micsetup(struct airo_info *ai) {
1312 return SUCCESS; 1319 return SUCCESS;
1313} 1320}
1314 1321
1315char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; 1322static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
1316 1323
1317/*=========================================================================== 1324/*===========================================================================
1318 * Description: Mic a packet 1325 * Description: Mic a packet
@@ -1567,7 +1574,7 @@ static void MoveWindow(miccntx *context, u32 micSeq)
1567static unsigned char aes_counter[16]; 1574static unsigned char aes_counter[16];
1568 1575
1569/* expand the key to fill the MMH coefficient array */ 1576/* expand the key to fill the MMH coefficient array */
1570void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm) 1577static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm)
1571{ 1578{
1572 /* take the keying material, expand if necessary, truncate at 16-bytes */ 1579 /* take the keying material, expand if necessary, truncate at 16-bytes */
1573 /* run through AES counter mode to generate context->coeff[] */ 1580 /* run through AES counter mode to generate context->coeff[] */
@@ -1599,7 +1606,7 @@ void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto
1599} 1606}
1600 1607
1601/* prepare for calculation of a new mic */ 1608/* prepare for calculation of a new mic */
1602void emmh32_init(emmh32_context *context) 1609static void emmh32_init(emmh32_context *context)
1603{ 1610{
1604 /* prepare for new mic calculation */ 1611 /* prepare for new mic calculation */
1605 context->accum = 0; 1612 context->accum = 0;
@@ -1607,7 +1614,7 @@ void emmh32_init(emmh32_context *context)
1607} 1614}
1608 1615
1609/* add some bytes to the mic calculation */ 1616/* add some bytes to the mic calculation */
1610void emmh32_update(emmh32_context *context, u8 *pOctets, int len) 1617static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1611{ 1618{
1612 int coeff_position, byte_position; 1619 int coeff_position, byte_position;
1613 1620
@@ -1649,7 +1656,7 @@ void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1649static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L }; 1656static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1650 1657
1651/* calculate the mic */ 1658/* calculate the mic */
1652void emmh32_final(emmh32_context *context, u8 digest[4]) 1659static void emmh32_final(emmh32_context *context, u8 digest[4])
1653{ 1660{
1654 int coeff_position, byte_position; 1661 int coeff_position, byte_position;
1655 u32 val; 1662 u32 val;
@@ -2251,7 +2258,7 @@ static void airo_read_stats(struct airo_info *ai) {
2251 ai->stats.rx_fifo_errors = vals[0]; 2258 ai->stats.rx_fifo_errors = vals[0];
2252} 2259}
2253 2260
2254struct net_device_stats *airo_get_stats(struct net_device *dev) 2261static struct net_device_stats *airo_get_stats(struct net_device *dev)
2255{ 2262{
2256 struct airo_info *local = dev->priv; 2263 struct airo_info *local = dev->priv;
2257 2264
@@ -2410,7 +2417,7 @@ EXPORT_SYMBOL(stop_airo_card);
2410 2417
2411static int add_airo_dev( struct net_device *dev ); 2418static int add_airo_dev( struct net_device *dev );
2412 2419
2413int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) 2420static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
2414{ 2421{
2415 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); 2422 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
2416 return ETH_ALEN; 2423 return ETH_ALEN;
@@ -2677,7 +2684,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
2677 return dev; 2684 return dev;
2678} 2685}
2679 2686
2680int reset_card( struct net_device *dev , int lock) { 2687static int reset_card( struct net_device *dev , int lock) {
2681 struct airo_info *ai = dev->priv; 2688 struct airo_info *ai = dev->priv;
2682 2689
2683 if (lock && down_interruptible(&ai->sem)) 2690 if (lock && down_interruptible(&ai->sem))
@@ -2692,9 +2699,9 @@ int reset_card( struct net_device *dev , int lock) {
2692 return 0; 2699 return 0;
2693} 2700}
2694 2701
2695struct net_device *_init_airo_card( unsigned short irq, int port, 2702static struct net_device *_init_airo_card( unsigned short irq, int port,
2696 int is_pcmcia, struct pci_dev *pci, 2703 int is_pcmcia, struct pci_dev *pci,
2697 struct device *dmdev ) 2704 struct device *dmdev )
2698{ 2705{
2699 struct net_device *dev; 2706 struct net_device *dev;
2700 struct airo_info *ai; 2707 struct airo_info *ai;
@@ -7177,7 +7184,7 @@ static void airo_read_wireless_stats(struct airo_info *local)
7177 local->wstats.miss.beacon = vals[34]; 7184 local->wstats.miss.beacon = vals[34];
7178} 7185}
7179 7186
7180struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) 7187static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7181{ 7188{
7182 struct airo_info *local = dev->priv; 7189 struct airo_info *local = dev->priv;
7183 7190
@@ -7392,14 +7399,8 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7392 * Flash command switch table 7399 * Flash command switch table
7393 */ 7400 */
7394 7401
7395int flashcard(struct net_device *dev, aironet_ioctl *comp) { 7402static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7396 int z; 7403 int z;
7397 int cmdreset(struct airo_info *);
7398 int setflashmode(struct airo_info *);
7399 int flashgchar(struct airo_info *,int,int);
7400 int flashpchar(struct airo_info *,int,int);
7401 int flashputbuf(struct airo_info *);
7402 int flashrestart(struct airo_info *,struct net_device *);
7403 7404
7404 /* Only super-user can modify flash */ 7405 /* Only super-user can modify flash */
7405 if (!capable(CAP_NET_ADMIN)) 7406 if (!capable(CAP_NET_ADMIN))
@@ -7457,7 +7458,7 @@ int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7457 * card. 7458 * card.
7458 */ 7459 */
7459 7460
7460int cmdreset(struct airo_info *ai) { 7461static int cmdreset(struct airo_info *ai) {
7461 disable_MAC(ai, 1); 7462 disable_MAC(ai, 1);
7462 7463
7463 if(!waitbusy (ai)){ 7464 if(!waitbusy (ai)){
@@ -7481,7 +7482,7 @@ int cmdreset(struct airo_info *ai) {
7481 * mode 7482 * mode
7482 */ 7483 */
7483 7484
7484int setflashmode (struct airo_info *ai) { 7485static int setflashmode (struct airo_info *ai) {
7485 set_bit (FLAG_FLASHING, &ai->flags); 7486 set_bit (FLAG_FLASHING, &ai->flags);
7486 7487
7487 OUT4500(ai, SWS0, FLASH_COMMAND); 7488 OUT4500(ai, SWS0, FLASH_COMMAND);
@@ -7508,7 +7509,7 @@ int setflashmode (struct airo_info *ai) {
7508 * x 50us for echo . 7509 * x 50us for echo .
7509 */ 7510 */
7510 7511
7511int flashpchar(struct airo_info *ai,int byte,int dwelltime) { 7512static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7512 int echo; 7513 int echo;
7513 int waittime; 7514 int waittime;
7514 7515
@@ -7548,7 +7549,7 @@ int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7548 * Get a character from the card matching matchbyte 7549 * Get a character from the card matching matchbyte
7549 * Step 3) 7550 * Step 3)
7550 */ 7551 */
7551int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){ 7552static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
7552 int rchar; 7553 int rchar;
7553 unsigned char rbyte=0; 7554 unsigned char rbyte=0;
7554 7555
@@ -7579,7 +7580,7 @@ int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
7579 * send to the card 7580 * send to the card
7580 */ 7581 */
7581 7582
7582int flashputbuf(struct airo_info *ai){ 7583static int flashputbuf(struct airo_info *ai){
7583 int nwords; 7584 int nwords;
7584 7585
7585 /* Write stuff */ 7586 /* Write stuff */
@@ -7601,7 +7602,7 @@ int flashputbuf(struct airo_info *ai){
7601/* 7602/*
7602 * 7603 *
7603 */ 7604 */
7604int flashrestart(struct airo_info *ai,struct net_device *dev){ 7605static int flashrestart(struct airo_info *ai,struct net_device *dev){
7605 int i,status; 7606 int i,status;
7606 7607
7607 ssleep(1); /* Added 12/7/00 */ 7608 ssleep(1); /* Added 12/7/00 */
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig
new file mode 100644
index 000000000000..2871e879b518
--- /dev/null
+++ b/drivers/net/wireless/hostap/Kconfig
@@ -0,0 +1,104 @@
1config HOSTAP
2 tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
3 depends on NET_RADIO
4 ---help---
5 Shared driver code for IEEE 802.11b wireless cards based on
6 Intersil Prism2/2.5/3 chipset. This driver supports so called
7 Host AP mode that allows the card to act as an IEEE 802.11
8 access point.
9
10 In addition, this includes generic IEEE 802.11 code, e.g., for
11 WEP/TKIP/CCMP encryption that can be shared with other drivers.
12
13 See <http://hostap.epitest.fi/> for more information about the
14 Host AP driver configuration and tools. This site includes
15 information and tools (hostapd and wpa_supplicant) for WPA/WPA2
16 support.
17
18 This option includes the base Host AP driver code that is shared by
19 different hardware models. You will also need to enable support for
20 PLX/PCI/CS version of the driver to actually use the driver.
21
22 The driver can be compiled as a module and it will be called
23 "hostap.ko".
24
25config HOSTAP_WEP
26 tristate "IEEE 802.11 WEP encryption"
27 depends on HOSTAP
28 select CRYPTO
29 ---help---
30 Software implementation of IEEE 802.11 WEP encryption.
31
32 This can be compiled as a modules and it will be called
33 "hostap_crypt_wep.ko".
34
35config HOSTAP_TKIP
36 tristate "IEEE 802.11 TKIP encryption"
37 depends on HOSTAP
38 select CRYPTO
39 ---help---
40 Software implementation of IEEE 802.11 TKIP encryption.
41
42 This can be compiled as a modules and it will be called
43 "hostap_crypt_tkip.ko".
44
45config HOSTAP_CCMP
46 tristate "IEEE 802.11 CCMP encryption"
47 depends on HOSTAP
48 select CRYPTO
49 ---help---
50 Software implementation of IEEE 802.11 CCMP encryption.
51
52 This can be compiled as a modules and it will be called
53 "hostap_crypt_ccmp.ko".
54
55config HOSTAP_FIRMWARE
56 bool "Support downloading firmware images with Host AP driver"
57 depends on HOSTAP
58 ---help---
59 Configure Host AP driver to include support for firmware image
60 download. Current version supports only downloading to volatile, i.e.,
61 RAM memory. Flash upgrade is not yet supported.
62
63 Firmware image downloading needs user space tool, prism2_srec. It is
64 available from http://hostap.epitest.fi/.
65
66config HOSTAP_PLX
67 tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
68 depends on PCI && HOSTAP
69 ---help---
70 Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based
71 PCI adaptors.
72
73 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
74 driver and its help text includes more information about the Host AP
75 driver.
76
77 The driver can be compiled as a module and will be named
78 "hostap_plx.ko".
79
80config HOSTAP_PCI
81 tristate "Host AP driver for Prism2.5 PCI adaptors"
82 depends on PCI && HOSTAP
83 ---help---
84 Host AP driver's version for Prism2.5 PCI adaptors.
85
86 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
87 driver and its help text includes more information about the Host AP
88 driver.
89
90 The driver can be compiled as a module and will be named
91 "hostap_pci.ko".
92
93config HOSTAP_CS
94 tristate "Host AP driver for Prism2/2.5/3 PC Cards"
95 depends on PCMCIA!=n && HOSTAP
96 ---help---
97 Host AP driver's version for Prism2/2.5/3 PC Cards.
98
99 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
100 driver and its help text includes more information about the Host AP
101 driver.
102
103 The driver can be compiled as a module and will be named
104 "hostap_cs.ko".
diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile
new file mode 100644
index 000000000000..087554075038
--- /dev/null
+++ b/drivers/net/wireless/hostap/Makefile
@@ -0,0 +1,8 @@
1obj-$(CONFIG_HOSTAP) += hostap.o
2obj-$(CONFIG_HOSTAP_WEP) += hostap_crypt_wep.o
3obj-$(CONFIG_HOSTAP_TKIP) += hostap_crypt_tkip.o
4obj-$(CONFIG_HOSTAP_CCMP) += hostap_crypt_ccmp.o
5
6obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
7obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o
8obj-$(CONFIG_HOSTAP_PCI) += hostap_pci.o
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
new file mode 100644
index 000000000000..4fe8017b877c
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -0,0 +1,1207 @@
1/*
2 * Host AP (software wireless LAN access point) driver for
3 * Intersil Prism2/2.5/3 - hostap.o module, common routines
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. See README and COPYING for
12 * more details.
13 */
14
15#ifndef EXPORT_SYMTAB
16#define EXPORT_SYMTAB
17#endif
18
19#include <linux/config.h>
20#include <linux/version.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/proc_fs.h>
25#include <linux/if_arp.h>
26#include <linux/delay.h>
27#include <linux/random.h>
28#include <linux/workqueue.h>
29#include <linux/kmod.h>
30#include <linux/rtnetlink.h>
31#include <linux/wireless.h>
32#include <net/iw_handler.h>
33#include <asm/uaccess.h>
34
35#include "hostap_wlan.h"
36#include "hostap_80211.h"
37#include "hostap_ap.h"
38#include "hostap.h"
39#include "hostap_crypt.h"
40
41MODULE_AUTHOR("Jouni Malinen");
42MODULE_DESCRIPTION("Host AP common routines");
43MODULE_LICENSE("GPL");
44
45/* Old hostap_crypt module is now part of hostap module. */
46#include "hostap_crypt.c"
47
48#define TX_TIMEOUT (2 * HZ)
49
50#define PRISM2_MAX_FRAME_SIZE 2304
51#define PRISM2_MIN_MTU 256
52/* FIX: */
53#define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */))
54
55
56/* hostap.c */
57static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
58 int rtnl_locked);
59static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
60 int rtnl_locked, int do_not_remove);
61
62/* hostap_ap.c */
63static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
64 struct iw_quality qual[], int buf_size,
65 int aplist);
66static int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
67static int prism2_hostapd(struct ap_data *ap,
68 struct prism2_hostapd_param *param);
69static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
70 struct prism2_crypt_data ***crypt);
71static void ap_control_kickall(struct ap_data *ap);
72#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
73static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
74 u8 *mac);
75static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
76 u8 *mac);
77static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
78static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
79 u8 *mac);
80#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */
81
82
83static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
84 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
85#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
86
87
88/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
89/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
90static unsigned char rfc1042_header[] =
91{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
92/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
93static unsigned char bridge_tunnel_header[] =
94{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
95/* No encapsulation header if EtherType < 0x600 (=length) */
96
97
98/* FIX: these could be compiled separately and linked together to hostap.o */
99#include "hostap_ap.c"
100#include "hostap_info.c"
101#include "hostap_ioctl.c"
102#include "hostap_proc.c"
103#include "hostap_80211_rx.c"
104#include "hostap_80211_tx.c"
105
106
107struct net_device * hostap_add_interface(struct local_info *local,
108 int type, int rtnl_locked,
109 const char *prefix,
110 const char *name)
111{
112 struct net_device *dev, *mdev;
113 struct hostap_interface *iface;
114 int ret;
115
116 dev = alloc_etherdev(sizeof(struct hostap_interface));
117 if (dev == NULL)
118 return NULL;
119
120 iface = netdev_priv(dev);
121 iface->dev = dev;
122 iface->local = local;
123 iface->type = type;
124 list_add(&iface->list, &local->hostap_interfaces);
125
126 mdev = local->dev;
127 memcpy(dev->dev_addr, mdev->dev_addr, ETH_ALEN);
128 dev->base_addr = mdev->base_addr;
129 dev->irq = mdev->irq;
130 dev->mem_start = mdev->mem_start;
131 dev->mem_end = mdev->mem_end;
132
133 hostap_setup_dev(dev, local, 0);
134 dev->destructor = free_netdev;
135
136 sprintf(dev->name, "%s%s", prefix, name);
137 if (!rtnl_locked)
138 rtnl_lock();
139
140 ret = 0;
141 if (strchr(dev->name, '%'))
142 ret = dev_alloc_name(dev, dev->name);
143
144 if (ret >= 0)
145 ret = register_netdevice(dev);
146
147 if (!rtnl_locked)
148 rtnl_unlock();
149
150 if (ret < 0) {
151 printk(KERN_WARNING "%s: failed to add new netdevice!\n",
152 dev->name);
153 free_netdev(dev);
154 return NULL;
155 }
156
157 printk(KERN_DEBUG "%s: registered netdevice %s\n",
158 mdev->name, dev->name);
159
160 return dev;
161}
162
163
164void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
165 int remove_from_list)
166{
167 struct hostap_interface *iface;
168
169 if (!dev)
170 return;
171
172 iface = netdev_priv(dev);
173
174 if (remove_from_list) {
175 list_del(&iface->list);
176 }
177
178 if (dev == iface->local->ddev)
179 iface->local->ddev = NULL;
180 else if (dev == iface->local->apdev)
181 iface->local->apdev = NULL;
182 else if (dev == iface->local->stadev)
183 iface->local->stadev = NULL;
184
185 if (rtnl_locked)
186 unregister_netdevice(dev);
187 else
188 unregister_netdev(dev);
189
190 /* dev->destructor = free_netdev() will free the device data, including
191 * private data, when removing the device */
192}
193
194
195static inline int prism2_wds_special_addr(u8 *addr)
196{
197 if (addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5])
198 return 0;
199
200 return 1;
201}
202
203
204static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
205 int rtnl_locked)
206{
207 struct net_device *dev;
208 struct list_head *ptr;
209 struct hostap_interface *iface, *empty, *match;
210
211 empty = match = NULL;
212 read_lock_bh(&local->iface_lock);
213 list_for_each(ptr, &local->hostap_interfaces) {
214 iface = list_entry(ptr, struct hostap_interface, list);
215 if (iface->type != HOSTAP_INTERFACE_WDS)
216 continue;
217
218 if (prism2_wds_special_addr(iface->u.wds.remote_addr))
219 empty = iface;
220 else if (memcmp(iface->u.wds.remote_addr, remote_addr,
221 ETH_ALEN) == 0) {
222 match = iface;
223 break;
224 }
225 }
226 if (!match && empty && !prism2_wds_special_addr(remote_addr)) {
227 /* take pre-allocated entry into use */
228 memcpy(empty->u.wds.remote_addr, remote_addr, ETH_ALEN);
229 read_unlock_bh(&local->iface_lock);
230 printk(KERN_DEBUG "%s: using pre-allocated WDS netdevice %s\n",
231 local->dev->name, empty->dev->name);
232 return 0;
233 }
234 read_unlock_bh(&local->iface_lock);
235
236 if (!prism2_wds_special_addr(remote_addr)) {
237 if (match)
238 return -EEXIST;
239 hostap_add_sta(local->ap, remote_addr);
240 }
241
242 if (local->wds_connections >= local->wds_max_connections)
243 return -ENOBUFS;
244
245 /* verify that there is room for wds# postfix in the interface name */
246 if (strlen(local->dev->name) > IFNAMSIZ - 5) {
247 printk(KERN_DEBUG "'%s' too long base device name\n",
248 local->dev->name);
249 return -EINVAL;
250 }
251
252 dev = hostap_add_interface(local, HOSTAP_INTERFACE_WDS, rtnl_locked,
253 local->ddev->name, "wds%d");
254 if (dev == NULL)
255 return -ENOMEM;
256
257 iface = netdev_priv(dev);
258 memcpy(iface->u.wds.remote_addr, remote_addr, ETH_ALEN);
259
260 local->wds_connections++;
261
262 return 0;
263}
264
265
266static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
267 int rtnl_locked, int do_not_remove)
268{
269 unsigned long flags;
270 struct list_head *ptr;
271 struct hostap_interface *iface, *selected = NULL;
272
273 write_lock_irqsave(&local->iface_lock, flags);
274 list_for_each(ptr, &local->hostap_interfaces) {
275 iface = list_entry(ptr, struct hostap_interface, list);
276 if (iface->type != HOSTAP_INTERFACE_WDS)
277 continue;
278
279 if (memcmp(iface->u.wds.remote_addr, remote_addr,
280 ETH_ALEN) == 0) {
281 selected = iface;
282 break;
283 }
284 }
285 if (selected && !do_not_remove)
286 list_del(&selected->list);
287 write_unlock_irqrestore(&local->iface_lock, flags);
288
289 if (selected) {
290 if (do_not_remove)
291 memset(selected->u.wds.remote_addr, 0, ETH_ALEN);
292 else {
293 hostap_remove_interface(selected->dev, rtnl_locked, 0);
294 local->wds_connections--;
295 }
296 }
297
298 return selected ? 0 : -ENODEV;
299}
300
301
302u16 hostap_tx_callback_register(local_info_t *local,
303 void (*func)(struct sk_buff *, int ok, void *),
304 void *data)
305{
306 unsigned long flags;
307 struct hostap_tx_callback_info *entry;
308
309 entry = (struct hostap_tx_callback_info *) kmalloc(sizeof(*entry),
310 GFP_ATOMIC);
311 if (entry == NULL)
312 return 0;
313
314 entry->func = func;
315 entry->data = data;
316
317 spin_lock_irqsave(&local->lock, flags);
318 entry->idx = local->tx_callback ? local->tx_callback->idx + 1 : 1;
319 entry->next = local->tx_callback;
320 local->tx_callback = entry;
321 spin_unlock_irqrestore(&local->lock, flags);
322
323 return entry->idx;
324}
325
326
327int hostap_tx_callback_unregister(local_info_t *local, u16 idx)
328{
329 unsigned long flags;
330 struct hostap_tx_callback_info *cb, *prev = NULL;
331
332 spin_lock_irqsave(&local->lock, flags);
333 cb = local->tx_callback;
334 while (cb != NULL && cb->idx != idx) {
335 prev = cb;
336 cb = cb->next;
337 }
338 if (cb) {
339 if (prev == NULL)
340 local->tx_callback = cb->next;
341 else
342 prev->next = cb->next;
343 kfree(cb);
344 }
345 spin_unlock_irqrestore(&local->lock, flags);
346
347 return cb ? 0 : -1;
348}
349
350
351/* val is in host byte order */
352int hostap_set_word(struct net_device *dev, int rid, u16 val)
353{
354 struct hostap_interface *iface;
355 u16 tmp = cpu_to_le16(val);
356 iface = netdev_priv(dev);
357 return iface->local->func->set_rid(dev, rid, &tmp, 2);
358}
359
360
361int hostap_set_string(struct net_device *dev, int rid, const char *val)
362{
363 struct hostap_interface *iface;
364 char buf[MAX_SSID_LEN + 2];
365 int len;
366
367 iface = netdev_priv(dev);
368 len = strlen(val);
369 if (len > MAX_SSID_LEN)
370 return -1;
371 memset(buf, 0, sizeof(buf));
372 buf[0] = len; /* little endian 16 bit word */
373 memcpy(buf + 2, val, len);
374
375 return iface->local->func->set_rid(dev, rid, &buf, MAX_SSID_LEN + 2);
376}
377
378
379u16 hostap_get_porttype(local_info_t *local)
380{
381 if (local->iw_mode == IW_MODE_ADHOC && local->pseudo_adhoc)
382 return HFA384X_PORTTYPE_PSEUDO_IBSS;
383 if (local->iw_mode == IW_MODE_ADHOC)
384 return HFA384X_PORTTYPE_IBSS;
385 if (local->iw_mode == IW_MODE_INFRA)
386 return HFA384X_PORTTYPE_BSS;
387 if (local->iw_mode == IW_MODE_REPEAT)
388 return HFA384X_PORTTYPE_WDS;
389 if (local->iw_mode == IW_MODE_MONITOR)
390 return HFA384X_PORTTYPE_PSEUDO_IBSS;
391 return HFA384X_PORTTYPE_HOSTAP;
392}
393
394
395int hostap_set_encryption(local_info_t *local)
396{
397 u16 val, old_val;
398 int i, keylen, len, idx;
399 char keybuf[WEP_KEY_LEN + 1];
400 enum { NONE, WEP, OTHER } encrypt_type;
401
402 idx = local->tx_keyidx;
403 if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL)
404 encrypt_type = NONE;
405 else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0)
406 encrypt_type = WEP;
407 else
408 encrypt_type = OTHER;
409
410 if (local->func->get_rid(local->dev, HFA384X_RID_CNFWEPFLAGS, &val, 2,
411 1) < 0) {
412 printk(KERN_DEBUG "Could not read current WEP flags.\n");
413 goto fail;
414 }
415 le16_to_cpus(&val);
416 old_val = val;
417
418 if (encrypt_type != NONE || local->privacy_invoked)
419 val |= HFA384X_WEPFLAGS_PRIVACYINVOKED;
420 else
421 val &= ~HFA384X_WEPFLAGS_PRIVACYINVOKED;
422
423 if (local->open_wep || encrypt_type == NONE ||
424 ((local->ieee_802_1x || local->wpa) && local->host_decrypt))
425 val &= ~HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED;
426 else
427 val |= HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED;
428
429 if ((encrypt_type != NONE || local->privacy_invoked) &&
430 (encrypt_type == OTHER || local->host_encrypt))
431 val |= HFA384X_WEPFLAGS_HOSTENCRYPT;
432 else
433 val &= ~HFA384X_WEPFLAGS_HOSTENCRYPT;
434 if ((encrypt_type != NONE || local->privacy_invoked) &&
435 (encrypt_type == OTHER || local->host_decrypt))
436 val |= HFA384X_WEPFLAGS_HOSTDECRYPT;
437 else
438 val &= ~HFA384X_WEPFLAGS_HOSTDECRYPT;
439
440 if (val != old_val &&
441 hostap_set_word(local->dev, HFA384X_RID_CNFWEPFLAGS, val)) {
442 printk(KERN_DEBUG "Could not write new WEP flags (0x%x)\n",
443 val);
444 goto fail;
445 }
446
447 if (encrypt_type != WEP)
448 return 0;
449
450 /* 104-bit support seems to require that all the keys are set to the
451 * same keylen */
452 keylen = 6; /* first 5 octets */
453 len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf),
454 NULL, local->crypt[idx]->priv);
455 if (idx >= 0 && idx < WEP_KEYS && len > 5)
456 keylen = WEP_KEY_LEN + 1; /* first 13 octets */
457
458 for (i = 0; i < WEP_KEYS; i++) {
459 memset(keybuf, 0, sizeof(keybuf));
460 if (local->crypt[i]) {
461 (void) local->crypt[i]->ops->get_key(
462 keybuf, sizeof(keybuf),
463 NULL, local->crypt[i]->priv);
464 }
465 if (local->func->set_rid(local->dev,
466 HFA384X_RID_CNFDEFAULTKEY0 + i,
467 keybuf, keylen)) {
468 printk(KERN_DEBUG "Could not set key %d (len=%d)\n",
469 i, keylen);
470 goto fail;
471 }
472 }
473 if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPDEFAULTKEYID, idx)) {
474 printk(KERN_DEBUG "Could not set default keyid %d\n", idx);
475 goto fail;
476 }
477
478 return 0;
479
480 fail:
481 printk(KERN_DEBUG "%s: encryption setup failed\n", local->dev->name);
482 return -1;
483}
484
485
486int hostap_set_antsel(local_info_t *local)
487{
488 u16 val;
489 int ret = 0;
490
491 if (local->antsel_tx != HOSTAP_ANTSEL_DO_NOT_TOUCH &&
492 local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF,
493 HFA386X_CR_TX_CONFIGURE,
494 NULL, &val) == 0) {
495 val &= ~(BIT(2) | BIT(1));
496 switch (local->antsel_tx) {
497 case HOSTAP_ANTSEL_DIVERSITY:
498 val |= BIT(1);
499 break;
500 case HOSTAP_ANTSEL_LOW:
501 break;
502 case HOSTAP_ANTSEL_HIGH:
503 val |= BIT(2);
504 break;
505 }
506
507 if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF,
508 HFA386X_CR_TX_CONFIGURE, &val, NULL)) {
509 printk(KERN_INFO "%s: setting TX AntSel failed\n",
510 local->dev->name);
511 ret = -1;
512 }
513 }
514
515 if (local->antsel_rx != HOSTAP_ANTSEL_DO_NOT_TOUCH &&
516 local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF,
517 HFA386X_CR_RX_CONFIGURE,
518 NULL, &val) == 0) {
519 val &= ~(BIT(1) | BIT(0));
520 switch (local->antsel_rx) {
521 case HOSTAP_ANTSEL_DIVERSITY:
522 break;
523 case HOSTAP_ANTSEL_LOW:
524 val |= BIT(0);
525 break;
526 case HOSTAP_ANTSEL_HIGH:
527 val |= BIT(0) | BIT(1);
528 break;
529 }
530
531 if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF,
532 HFA386X_CR_RX_CONFIGURE, &val, NULL)) {
533 printk(KERN_INFO "%s: setting RX AntSel failed\n",
534 local->dev->name);
535 ret = -1;
536 }
537 }
538
539 return ret;
540}
541
542
543int hostap_set_roaming(local_info_t *local)
544{
545 u16 val;
546
547 switch (local->host_roaming) {
548 case 1:
549 val = HFA384X_ROAMING_HOST;
550 break;
551 case 2:
552 val = HFA384X_ROAMING_DISABLED;
553 break;
554 case 0:
555 default:
556 val = HFA384X_ROAMING_FIRMWARE;
557 break;
558 }
559
560 return hostap_set_word(local->dev, HFA384X_RID_CNFROAMINGMODE, val);
561}
562
563
564int hostap_set_auth_algs(local_info_t *local)
565{
566 int val = local->auth_algs;
567 /* At least STA f/w v0.6.2 seems to have issues with cnfAuthentication
568 * set to include both Open and Shared Key flags. It tries to use
569 * Shared Key authentication in that case even if WEP keys are not
570 * configured.. STA f/w v0.7.6 is able to handle such configuration,
571 * but it is unknown when this was fixed between 0.6.2 .. 0.7.6. */
572 if (local->sta_fw_ver < PRISM2_FW_VER(0,7,0) &&
573 val != PRISM2_AUTH_OPEN && val != PRISM2_AUTH_SHARED_KEY)
574 val = PRISM2_AUTH_OPEN;
575
576 if (hostap_set_word(local->dev, HFA384X_RID_CNFAUTHENTICATION, val)) {
577 printk(KERN_INFO "%s: cnfAuthentication setting to 0x%x "
578 "failed\n", local->dev->name, local->auth_algs);
579 return -EINVAL;
580 }
581
582 return 0;
583}
584
585
586void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
587{
588 u16 status, fc;
589
590 status = __le16_to_cpu(rx->status);
591
592 printk(KERN_DEBUG "%s: RX status=0x%04x (port=%d, type=%d, "
593 "fcserr=%d) silence=%d signal=%d rate=%d rxflow=%d; "
594 "jiffies=%ld\n",
595 name, status, (status >> 8) & 0x07, status >> 13, status & 1,
596 rx->silence, rx->signal, rx->rate, rx->rxflow, jiffies);
597
598 fc = __le16_to_cpu(rx->frame_control);
599 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
600 "data_len=%d%s%s\n",
601 fc, WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc),
602 __le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl),
603 __le16_to_cpu(rx->data_len),
604 fc & WLAN_FC_TODS ? " [ToDS]" : "",
605 fc & WLAN_FC_FROMDS ? " [FromDS]" : "");
606
607 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4="
608 MACSTR "\n",
609 MAC2STR(rx->addr1), MAC2STR(rx->addr2), MAC2STR(rx->addr3),
610 MAC2STR(rx->addr4));
611
612 printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n",
613 MAC2STR(rx->dst_addr), MAC2STR(rx->src_addr),
614 __be16_to_cpu(rx->len));
615}
616
617
618void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
619{
620 u16 fc;
621
622 printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d "
623 "tx_control=0x%04x; jiffies=%ld\n",
624 name, __le16_to_cpu(tx->status), tx->retry_count, tx->tx_rate,
625 __le16_to_cpu(tx->tx_control), jiffies);
626
627 fc = __le16_to_cpu(tx->frame_control);
628 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
629 "data_len=%d%s%s\n",
630 fc, WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc),
631 __le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl),
632 __le16_to_cpu(tx->data_len),
633 fc & WLAN_FC_TODS ? " [ToDS]" : "",
634 fc & WLAN_FC_FROMDS ? " [FromDS]" : "");
635
636 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4="
637 MACSTR "\n",
638 MAC2STR(tx->addr1), MAC2STR(tx->addr2), MAC2STR(tx->addr3),
639 MAC2STR(tx->addr4));
640
641 printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n",
642 MAC2STR(tx->dst_addr), MAC2STR(tx->src_addr),
643 __be16_to_cpu(tx->len));
644}
645
646
647int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr)
648{
649 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); /* addr2 */
650 return ETH_ALEN;
651}
652
653
654int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr)
655{
656 if (*(u32 *)skb->mac.raw == LWNG_CAP_DID_BASE) {
657 memcpy(haddr, skb->mac.raw +
658 sizeof(struct linux_wlan_ng_prism_hdr) + 10,
659 ETH_ALEN); /* addr2 */
660 } else { /* (*(u32 *)skb->mac.raw == htonl(LWNG_CAPHDR_VERSION)) */
661 memcpy(haddr, skb->mac.raw +
662 sizeof(struct linux_wlan_ng_cap_hdr) + 10,
663 ETH_ALEN); /* addr2 */
664 }
665 return ETH_ALEN;
666}
667
668
669int hostap_80211_get_hdrlen(u16 fc)
670{
671 int hdrlen = 24;
672
673 switch (WLAN_FC_GET_TYPE(fc)) {
674 case WLAN_FC_TYPE_DATA:
675 if ((fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS))
676 hdrlen = 30; /* Addr4 */
677 break;
678 case WLAN_FC_TYPE_CTRL:
679 switch (WLAN_FC_GET_STYPE(fc)) {
680 case WLAN_FC_STYPE_CTS:
681 case WLAN_FC_STYPE_ACK:
682 hdrlen = 10;
683 break;
684 default:
685 hdrlen = 16;
686 break;
687 }
688 break;
689 }
690
691 return hdrlen;
692}
693
694
695struct net_device_stats *hostap_get_stats(struct net_device *dev)
696{
697 struct hostap_interface *iface;
698 iface = netdev_priv(dev);
699 return &iface->stats;
700}
701
702
703static int prism2_close(struct net_device *dev)
704{
705 struct hostap_interface *iface;
706 local_info_t *local;
707
708 PDEBUG(DEBUG_FLOW, "%s: prism2_close\n", dev->name);
709
710 iface = netdev_priv(dev);
711 local = iface->local;
712
713 if (dev == local->ddev) {
714 prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
715 }
716#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
717 if (!local->hostapd && dev == local->dev &&
718 (!local->func->card_present || local->func->card_present(local)) &&
719 local->hw_ready && local->ap && local->iw_mode == IW_MODE_MASTER)
720 hostap_deauth_all_stas(dev, local->ap, 1);
721#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
722
723 if (local->func->dev_close && local->func->dev_close(local))
724 return 0;
725
726 if (dev == local->dev) {
727 local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
728 }
729
730 if (netif_running(dev)) {
731 netif_stop_queue(dev);
732 netif_device_detach(dev);
733 }
734
735 flush_scheduled_work();
736
737 module_put(local->hw_module);
738
739 local->num_dev_open--;
740
741 if (dev != local->dev && local->dev->flags & IFF_UP &&
742 local->master_dev_auto_open && local->num_dev_open == 1) {
743 /* Close master radio interface automatically if it was also
744 * opened automatically and we are now closing the last
745 * remaining non-master device. */
746 dev_close(local->dev);
747 }
748
749 return 0;
750}
751
752
753static int prism2_open(struct net_device *dev)
754{
755 struct hostap_interface *iface;
756 local_info_t *local;
757
758 PDEBUG(DEBUG_FLOW, "%s: prism2_open\n", dev->name);
759
760 iface = netdev_priv(dev);
761 local = iface->local;
762
763 if (local->no_pri) {
764 printk(KERN_DEBUG "%s: could not set interface UP - no PRI "
765 "f/w\n", dev->name);
766 return 1;
767 }
768
769 if ((local->func->card_present && !local->func->card_present(local)) ||
770 local->hw_downloading)
771 return -ENODEV;
772
773 if (local->func->dev_open && local->func->dev_open(local))
774 return 1;
775
776 if (!try_module_get(local->hw_module))
777 return -ENODEV;
778 local->num_dev_open++;
779
780 if (!local->dev_enabled && local->func->hw_enable(dev, 1)) {
781 printk(KERN_WARNING "%s: could not enable MAC port\n",
782 dev->name);
783 prism2_close(dev);
784 return 1;
785 }
786 if (!local->dev_enabled)
787 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
788 local->dev_enabled = 1;
789
790 if (dev != local->dev && !(local->dev->flags & IFF_UP)) {
791 /* Master radio interface is needed for all operation, so open
792 * it automatically when any virtual net_device is opened. */
793 local->master_dev_auto_open = 1;
794 dev_open(local->dev);
795 }
796
797 netif_device_attach(dev);
798 netif_start_queue(dev);
799
800 return 0;
801}
802
803
804static int prism2_set_mac_address(struct net_device *dev, void *p)
805{
806 struct hostap_interface *iface;
807 local_info_t *local;
808 struct list_head *ptr;
809 struct sockaddr *addr = p;
810
811 iface = netdev_priv(dev);
812 local = iface->local;
813
814 if (local->func->set_rid(dev, HFA384X_RID_CNFOWNMACADDR, addr->sa_data,
815 ETH_ALEN) < 0 || local->func->reset_port(dev))
816 return -EINVAL;
817
818 read_lock_bh(&local->iface_lock);
819 list_for_each(ptr, &local->hostap_interfaces) {
820 iface = list_entry(ptr, struct hostap_interface, list);
821 memcpy(iface->dev->dev_addr, addr->sa_data, ETH_ALEN);
822 }
823 memcpy(local->dev->dev_addr, addr->sa_data, ETH_ALEN);
824 read_unlock_bh(&local->iface_lock);
825
826 return 0;
827}
828
829
830/* TODO: to be further implemented as soon as Prism2 fully supports
831 * GroupAddresses and correct documentation is available */
832void hostap_set_multicast_list_queue(void *data)
833{
834 struct net_device *dev = (struct net_device *) data;
835 struct hostap_interface *iface;
836 local_info_t *local;
837
838 iface = netdev_priv(dev);
839 local = iface->local;
840 if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
841 local->is_promisc)) {
842 printk(KERN_INFO "%s: %sabling promiscuous mode failed\n",
843 dev->name, local->is_promisc ? "en" : "dis");
844 }
845}
846
847
848static void hostap_set_multicast_list(struct net_device *dev)
849{
850#if 0
851 /* FIX: promiscuous mode seems to be causing a lot of problems with
852 * some station firmware versions (FCSErr frames, invalid MACPort, etc.
853 * corrupted incoming frames). This code is now commented out while the
854 * problems are investigated. */
855 struct hostap_interface *iface;
856 local_info_t *local;
857
858 iface = netdev_priv(dev);
859 local = iface->local;
860 if ((dev->flags & IFF_ALLMULTI) || (dev->flags & IFF_PROMISC)) {
861 local->is_promisc = 1;
862 } else {
863 local->is_promisc = 0;
864 }
865
866 schedule_work(&local->set_multicast_list_queue);
867#endif
868}
869
870
871static int prism2_change_mtu(struct net_device *dev, int new_mtu)
872{
873 if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU)
874 return -EINVAL;
875
876 dev->mtu = new_mtu;
877 return 0;
878}
879
880
881static void prism2_tx_timeout(struct net_device *dev)
882{
883 struct hostap_interface *iface;
884 local_info_t *local;
885 struct hfa384x_regs regs;
886
887 iface = netdev_priv(dev);
888 local = iface->local;
889
890 printk(KERN_WARNING "%s Tx timed out! Resetting card\n", dev->name);
891 netif_stop_queue(local->dev);
892
893 local->func->read_regs(dev, &regs);
894 printk(KERN_DEBUG "%s: CMD=%04x EVSTAT=%04x "
895 "OFFSET0=%04x OFFSET1=%04x SWSUPPORT0=%04x\n",
896 dev->name, regs.cmd, regs.evstat, regs.offset0, regs.offset1,
897 regs.swsupport0);
898
899 local->func->schedule_reset(local);
900}
901
902
903void hostap_setup_dev(struct net_device *dev, local_info_t *local,
904 int main_dev)
905{
906 struct hostap_interface *iface;
907
908 iface = netdev_priv(dev);
909 ether_setup(dev);
910
911 /* kernel callbacks */
912 dev->get_stats = hostap_get_stats;
913 if (iface) {
914 /* Currently, we point to the proper spy_data only on
915 * the main_dev. This could be fixed. Jean II */
916 iface->wireless_data.spy_data = &iface->spy_data;
917 dev->wireless_data = &iface->wireless_data;
918 }
919 dev->wireless_handlers =
920 (struct iw_handler_def *) &hostap_iw_handler_def;
921 dev->do_ioctl = hostap_ioctl;
922 dev->open = prism2_open;
923 dev->stop = prism2_close;
924 dev->hard_start_xmit = hostap_data_start_xmit;
925 dev->set_mac_address = prism2_set_mac_address;
926 dev->set_multicast_list = hostap_set_multicast_list;
927 dev->change_mtu = prism2_change_mtu;
928 dev->tx_timeout = prism2_tx_timeout;
929 dev->watchdog_timeo = TX_TIMEOUT;
930
931 dev->mtu = local->mtu;
932 if (!main_dev) {
933 /* use main radio device queue */
934 dev->tx_queue_len = 0;
935 }
936
937 SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
938
939 netif_stop_queue(dev);
940}
941
942
943static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
944{
945 struct net_device *dev = local->dev;
946
947 if (local->apdev)
948 return -EEXIST;
949
950 printk(KERN_DEBUG "%s: enabling hostapd mode\n", dev->name);
951
952 local->apdev = hostap_add_interface(local, HOSTAP_INTERFACE_AP,
953 rtnl_locked, local->ddev->name,
954 "ap");
955 if (local->apdev == NULL)
956 return -ENOMEM;
957
958 local->apdev->hard_start_xmit = hostap_mgmt_start_xmit;
959 local->apdev->type = ARPHRD_IEEE80211;
960 local->apdev->hard_header_parse = hostap_80211_header_parse;
961
962 return 0;
963}
964
965
966static int hostap_disable_hostapd(local_info_t *local, int rtnl_locked)
967{
968 struct net_device *dev = local->dev;
969
970 printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name);
971
972 hostap_remove_interface(local->apdev, rtnl_locked, 1);
973 local->apdev = NULL;
974
975 return 0;
976}
977
978
979static int hostap_enable_hostapd_sta(local_info_t *local, int rtnl_locked)
980{
981 struct net_device *dev = local->dev;
982
983 if (local->stadev)
984 return -EEXIST;
985
986 printk(KERN_DEBUG "%s: enabling hostapd STA mode\n", dev->name);
987
988 local->stadev = hostap_add_interface(local, HOSTAP_INTERFACE_STA,
989 rtnl_locked, local->ddev->name,
990 "sta");
991 if (local->stadev == NULL)
992 return -ENOMEM;
993
994 return 0;
995}
996
997
998static int hostap_disable_hostapd_sta(local_info_t *local, int rtnl_locked)
999{
1000 struct net_device *dev = local->dev;
1001
1002 printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name);
1003
1004 hostap_remove_interface(local->stadev, rtnl_locked, 1);
1005 local->stadev = NULL;
1006
1007 return 0;
1008}
1009
1010
1011int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked)
1012{
1013 int ret;
1014
1015 if (val < 0 || val > 1)
1016 return -EINVAL;
1017
1018 if (local->hostapd == val)
1019 return 0;
1020
1021 if (val) {
1022 ret = hostap_enable_hostapd(local, rtnl_locked);
1023 if (ret == 0)
1024 local->hostapd = 1;
1025 } else {
1026 local->hostapd = 0;
1027 ret = hostap_disable_hostapd(local, rtnl_locked);
1028 if (ret != 0)
1029 local->hostapd = 1;
1030 }
1031
1032 return ret;
1033}
1034
1035
1036int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked)
1037{
1038 int ret;
1039
1040 if (val < 0 || val > 1)
1041 return -EINVAL;
1042
1043 if (local->hostapd_sta == val)
1044 return 0;
1045
1046 if (val) {
1047 ret = hostap_enable_hostapd_sta(local, rtnl_locked);
1048 if (ret == 0)
1049 local->hostapd_sta = 1;
1050 } else {
1051 local->hostapd_sta = 0;
1052 ret = hostap_disable_hostapd_sta(local, rtnl_locked);
1053 if (ret != 0)
1054 local->hostapd_sta = 1;
1055 }
1056
1057
1058 return ret;
1059}
1060
1061
1062int prism2_update_comms_qual(struct net_device *dev)
1063{
1064 struct hostap_interface *iface;
1065 local_info_t *local;
1066 int ret = 0;
1067 struct hfa384x_comms_quality sq;
1068
1069 iface = netdev_priv(dev);
1070 local = iface->local;
1071 if (!local->sta_fw_ver)
1072 ret = -1;
1073 else if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1074 if (local->func->get_rid(local->dev,
1075 HFA384X_RID_DBMCOMMSQUALITY,
1076 &sq, sizeof(sq), 1) >= 0) {
1077 local->comms_qual = (s16) le16_to_cpu(sq.comm_qual);
1078 local->avg_signal = (s16) le16_to_cpu(sq.signal_level);
1079 local->avg_noise = (s16) le16_to_cpu(sq.noise_level);
1080 local->last_comms_qual_update = jiffies;
1081 } else
1082 ret = -1;
1083 } else {
1084 if (local->func->get_rid(local->dev, HFA384X_RID_COMMSQUALITY,
1085 &sq, sizeof(sq), 1) >= 0) {
1086 local->comms_qual = le16_to_cpu(sq.comm_qual);
1087 local->avg_signal = HFA384X_LEVEL_TO_dBm(
1088 le16_to_cpu(sq.signal_level));
1089 local->avg_noise = HFA384X_LEVEL_TO_dBm(
1090 le16_to_cpu(sq.noise_level));
1091 local->last_comms_qual_update = jiffies;
1092 } else
1093 ret = -1;
1094 }
1095
1096 return ret;
1097}
1098
1099
1100int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u8 stype,
1101 u8 *body, size_t bodylen)
1102{
1103 struct sk_buff *skb;
1104 struct hostap_ieee80211_mgmt *mgmt;
1105 struct hostap_skb_tx_data *meta;
1106 struct net_device *dev = local->dev;
1107
1108 skb = dev_alloc_skb(IEEE80211_MGMT_HDR_LEN + bodylen);
1109 if (skb == NULL)
1110 return -ENOMEM;
1111
1112 mgmt = (struct hostap_ieee80211_mgmt *)
1113 skb_put(skb, IEEE80211_MGMT_HDR_LEN);
1114 memset(mgmt, 0, IEEE80211_MGMT_HDR_LEN);
1115 mgmt->frame_control =
1116 cpu_to_le16((WLAN_FC_TYPE_MGMT << 2) | (stype << 4));
1117 memcpy(mgmt->da, dst, ETH_ALEN);
1118 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1119 memcpy(mgmt->bssid, dst, ETH_ALEN);
1120 if (body)
1121 memcpy(skb_put(skb, bodylen), body, bodylen);
1122
1123 meta = (struct hostap_skb_tx_data *) skb->cb;
1124 memset(meta, 0, sizeof(*meta));
1125 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
1126 meta->iface = netdev_priv(dev);
1127
1128 skb->dev = dev;
1129 skb->mac.raw = skb->nh.raw = skb->data;
1130 dev_queue_xmit(skb);
1131
1132 return 0;
1133}
1134
1135
1136int prism2_sta_deauth(local_info_t *local, u16 reason)
1137{
1138 union iwreq_data wrqu;
1139 int ret;
1140
1141 if (local->iw_mode != IW_MODE_INFRA ||
1142 memcmp(local->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 ||
1143 memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0)
1144 return 0;
1145
1146 reason = cpu_to_le16(reason);
1147 ret = prism2_sta_send_mgmt(local, local->bssid, WLAN_FC_STYPE_DEAUTH,
1148 (u8 *) &reason, 2);
1149 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1150 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
1151 return ret;
1152}
1153
1154
1155struct proc_dir_entry *hostap_proc;
1156
1157static int __init hostap_init(void)
1158{
1159 hostap_crypto_init();
1160
1161 if (proc_net != NULL) {
1162 hostap_proc = proc_mkdir("hostap", proc_net);
1163 if (!hostap_proc)
1164 printk(KERN_WARNING "Failed to mkdir "
1165 "/proc/net/hostap\n");
1166 } else
1167 hostap_proc = NULL;
1168
1169 return 0;
1170}
1171
1172
1173static void __exit hostap_exit(void)
1174{
1175 if (hostap_proc != NULL) {
1176 hostap_proc = NULL;
1177 remove_proc_entry("hostap", proc_net);
1178 }
1179
1180 hostap_crypto_deinit();
1181}
1182
1183
1184EXPORT_SYMBOL(hostap_set_word);
1185EXPORT_SYMBOL(hostap_set_string);
1186EXPORT_SYMBOL(hostap_get_porttype);
1187EXPORT_SYMBOL(hostap_set_encryption);
1188EXPORT_SYMBOL(hostap_set_antsel);
1189EXPORT_SYMBOL(hostap_set_roaming);
1190EXPORT_SYMBOL(hostap_set_auth_algs);
1191EXPORT_SYMBOL(hostap_dump_rx_header);
1192EXPORT_SYMBOL(hostap_dump_tx_header);
1193EXPORT_SYMBOL(hostap_80211_header_parse);
1194EXPORT_SYMBOL(hostap_80211_prism_header_parse);
1195EXPORT_SYMBOL(hostap_80211_get_hdrlen);
1196EXPORT_SYMBOL(hostap_get_stats);
1197EXPORT_SYMBOL(hostap_setup_dev);
1198EXPORT_SYMBOL(hostap_proc);
1199EXPORT_SYMBOL(hostap_set_multicast_list_queue);
1200EXPORT_SYMBOL(hostap_set_hostapd);
1201EXPORT_SYMBOL(hostap_set_hostapd_sta);
1202EXPORT_SYMBOL(hostap_add_interface);
1203EXPORT_SYMBOL(hostap_remove_interface);
1204EXPORT_SYMBOL(prism2_update_comms_qual);
1205
1206module_init(hostap_init);
1207module_exit(hostap_exit);
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
new file mode 100644
index 000000000000..2ddcf5fc59c3
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -0,0 +1,57 @@
1#ifndef HOSTAP_H
2#define HOSTAP_H
3
4/* hostap.c */
5
6extern struct proc_dir_entry *hostap_proc;
7
8u16 hostap_tx_callback_register(local_info_t *local,
9 void (*func)(struct sk_buff *, int ok, void *),
10 void *data);
11int hostap_tx_callback_unregister(local_info_t *local, u16 idx);
12int hostap_set_word(struct net_device *dev, int rid, u16 val);
13int hostap_set_string(struct net_device *dev, int rid, const char *val);
14u16 hostap_get_porttype(local_info_t *local);
15int hostap_set_encryption(local_info_t *local);
16int hostap_set_antsel(local_info_t *local);
17int hostap_set_roaming(local_info_t *local);
18int hostap_set_auth_algs(local_info_t *local);
19void hostap_dump_rx_header(const char *name,
20 const struct hfa384x_rx_frame *rx);
21void hostap_dump_tx_header(const char *name,
22 const struct hfa384x_tx_frame *tx);
23int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr);
24int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr);
25int hostap_80211_get_hdrlen(u16 fc);
26struct net_device_stats *hostap_get_stats(struct net_device *dev);
27void hostap_setup_dev(struct net_device *dev, local_info_t *local,
28 int main_dev);
29void hostap_set_multicast_list_queue(void *data);
30int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked);
31int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked);
32void hostap_cleanup(local_info_t *local);
33void hostap_cleanup_handler(void *data);
34struct net_device * hostap_add_interface(struct local_info *local,
35 int type, int rtnl_locked,
36 const char *prefix, const char *name);
37void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
38 int remove_from_list);
39int prism2_update_comms_qual(struct net_device *dev);
40int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u8 stype,
41 u8 *body, size_t bodylen);
42int prism2_sta_deauth(local_info_t *local, u16 reason);
43
44
45/* hostap_proc.c */
46
47void hostap_init_proc(local_info_t *local);
48void hostap_remove_proc(local_info_t *local);
49
50
51/* hostap_info.c */
52
53void hostap_info_init(local_info_t *local);
54void hostap_info_process(local_info_t *local, struct sk_buff *skb);
55
56
57#endif /* HOSTAP_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
new file mode 100644
index 000000000000..878151f40657
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -0,0 +1,107 @@
1#ifndef HOSTAP_80211_H
2#define HOSTAP_80211_H
3
4struct hostap_ieee80211_hdr {
5 u16 frame_control;
6 u16 duration_id;
7 u8 addr1[6];
8 u8 addr2[6];
9 u8 addr3[6];
10 u16 seq_ctrl;
11 u8 addr4[6];
12} __attribute__ ((packed));
13
14
15struct hostap_ieee80211_mgmt {
16 u16 frame_control;
17 u16 duration;
18 u8 da[6];
19 u8 sa[6];
20 u8 bssid[6];
21 u16 seq_ctrl;
22 union {
23 struct {
24 u16 auth_alg;
25 u16 auth_transaction;
26 u16 status_code;
27 /* possibly followed by Challenge text */
28 u8 variable[0];
29 } __attribute__ ((packed)) auth;
30 struct {
31 u16 reason_code;
32 } __attribute__ ((packed)) deauth;
33 struct {
34 u16 capab_info;
35 u16 listen_interval;
36 /* followed by SSID and Supported rates */
37 u8 variable[0];
38 } __attribute__ ((packed)) assoc_req;
39 struct {
40 u16 capab_info;
41 u16 status_code;
42 u16 aid;
43 /* followed by Supported rates */
44 u8 variable[0];
45 } __attribute__ ((packed)) assoc_resp, reassoc_resp;
46 struct {
47 u16 capab_info;
48 u16 listen_interval;
49 u8 current_ap[6];
50 /* followed by SSID and Supported rates */
51 u8 variable[0];
52 } __attribute__ ((packed)) reassoc_req;
53 struct {
54 u16 reason_code;
55 } __attribute__ ((packed)) disassoc;
56 struct {
57 } __attribute__ ((packed)) probe_req;
58 struct {
59 u8 timestamp[8];
60 u16 beacon_int;
61 u16 capab_info;
62 /* followed by some of SSID, Supported rates,
63 * FH Params, DS Params, CF Params, IBSS Params, TIM */
64 u8 variable[0];
65 } __attribute__ ((packed)) beacon, probe_resp;
66 } u;
67} __attribute__ ((packed));
68
69
70#define IEEE80211_MGMT_HDR_LEN 24
71#define IEEE80211_DATA_HDR3_LEN 24
72#define IEEE80211_DATA_HDR4_LEN 30
73
74
75struct hostap_80211_rx_status {
76 u32 mac_time;
77 u8 signal;
78 u8 noise;
79 u16 rate; /* in 100 kbps */
80};
81
82
83void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
84 struct hostap_80211_rx_status *rx_stats);
85
86
87/* prism2_rx_80211 'type' argument */
88enum {
89 PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
90 PRISM2_RX_NULLFUNC_ACK
91};
92
93int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
94 struct hostap_80211_rx_status *rx_stats, int type);
95void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
96 struct hostap_80211_rx_status *rx_stats);
97void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
98 struct hostap_80211_rx_status *rx_stats);
99
100void hostap_dump_tx_80211(const char *name, struct sk_buff *skb);
101int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev);
102int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
103struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
104 struct prism2_crypt_data *crypt);
105int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
106
107#endif /* HOSTAP_80211_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
new file mode 100644
index 000000000000..917296c4fcbd
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -0,0 +1,1084 @@
1#include <linux/etherdevice.h>
2
3#include "hostap_80211.h"
4#include "hostap.h"
5
6void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
7 struct hostap_80211_rx_status *rx_stats)
8{
9 struct hostap_ieee80211_hdr *hdr;
10 u16 fc;
11
12 hdr = (struct hostap_ieee80211_hdr *) skb->data;
13
14 printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
15 "jiffies=%ld\n",
16 name, rx_stats->signal, rx_stats->noise, rx_stats->rate,
17 skb->len, jiffies);
18
19 if (skb->len < 2)
20 return;
21
22 fc = le16_to_cpu(hdr->frame_control);
23 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
24 fc, WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc),
25 fc & WLAN_FC_TODS ? " [ToDS]" : "",
26 fc & WLAN_FC_FROMDS ? " [FromDS]" : "");
27
28 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
29 printk("\n");
30 return;
31 }
32
33 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
34 le16_to_cpu(hdr->seq_ctrl));
35
36 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR,
37 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3));
38 if (skb->len >= 30)
39 printk(" A4=" MACSTR, MAC2STR(hdr->addr4));
40 printk("\n");
41}
42
43
44/* Send RX frame to netif with 802.11 (and possible prism) header.
45 * Called from hardware or software IRQ context. */
46int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
47 struct hostap_80211_rx_status *rx_stats, int type)
48{
49 struct hostap_interface *iface;
50 local_info_t *local;
51 int hdrlen, phdrlen, head_need, tail_need;
52 u16 fc;
53 int prism_header, ret;
54 struct hostap_ieee80211_hdr *hdr;
55
56 iface = netdev_priv(dev);
57 local = iface->local;
58 dev->last_rx = jiffies;
59
60 if (dev->type == ARPHRD_IEEE80211_PRISM) {
61 if (local->monitor_type == PRISM2_MONITOR_PRISM) {
62 prism_header = 1;
63 phdrlen = sizeof(struct linux_wlan_ng_prism_hdr);
64 } else { /* local->monitor_type == PRISM2_MONITOR_CAPHDR */
65 prism_header = 2;
66 phdrlen = sizeof(struct linux_wlan_ng_cap_hdr);
67 }
68 } else {
69 prism_header = 0;
70 phdrlen = 0;
71 }
72
73 hdr = (struct hostap_ieee80211_hdr *) skb->data;
74 fc = le16_to_cpu(hdr->frame_control);
75
76 if (type == PRISM2_RX_MGMT && (fc & WLAN_FC_PVER)) {
77 printk(KERN_DEBUG "%s: dropped management frame with header "
78 "version %d\n", dev->name, fc & WLAN_FC_PVER);
79 dev_kfree_skb_any(skb);
80 return 0;
81 }
82
83 hdrlen = hostap_80211_get_hdrlen(fc);
84
85 /* check if there is enough room for extra data; if not, expand skb
86 * buffer to be large enough for the changes */
87 head_need = phdrlen;
88 tail_need = 0;
89#ifdef PRISM2_ADD_BOGUS_CRC
90 tail_need += 4;
91#endif /* PRISM2_ADD_BOGUS_CRC */
92
93 head_need -= skb_headroom(skb);
94 tail_need -= skb_tailroom(skb);
95
96 if (head_need > 0 || tail_need > 0) {
97 if (pskb_expand_head(skb, head_need > 0 ? head_need : 0,
98 tail_need > 0 ? tail_need : 0,
99 GFP_ATOMIC)) {
100 printk(KERN_DEBUG "%s: prism2_rx_80211 failed to "
101 "reallocate skb buffer\n", dev->name);
102 dev_kfree_skb_any(skb);
103 return 0;
104 }
105 }
106
107 /* We now have an skb with enough head and tail room, so just insert
108 * the extra data */
109
110#ifdef PRISM2_ADD_BOGUS_CRC
111 memset(skb_put(skb, 4), 0xff, 4); /* Prism2 strips CRC */
112#endif /* PRISM2_ADD_BOGUS_CRC */
113
114 if (prism_header == 1) {
115 struct linux_wlan_ng_prism_hdr *hdr;
116 hdr = (struct linux_wlan_ng_prism_hdr *)
117 skb_push(skb, phdrlen);
118 memset(hdr, 0, phdrlen);
119 hdr->msgcode = LWNG_CAP_DID_BASE;
120 hdr->msglen = sizeof(*hdr);
121 memcpy(hdr->devname, dev->name, sizeof(hdr->devname));
122#define LWNG_SETVAL(f,i,s,l,d) \
123hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
124hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
125 LWNG_SETVAL(hosttime, 1, 0, 4, jiffies);
126 LWNG_SETVAL(mactime, 2, 0, 0, rx_stats->mac_time);
127 LWNG_SETVAL(channel, 3, 1 /* no value */, 4, 0);
128 LWNG_SETVAL(rssi, 4, 1 /* no value */, 4, 0);
129 LWNG_SETVAL(sq, 5, 1 /* no value */, 4, 0);
130 LWNG_SETVAL(signal, 6, 0, 4, rx_stats->signal);
131 LWNG_SETVAL(noise, 7, 0, 4, rx_stats->noise);
132 LWNG_SETVAL(rate, 8, 0, 4, rx_stats->rate / 5);
133 LWNG_SETVAL(istx, 9, 0, 4, 0);
134 LWNG_SETVAL(frmlen, 10, 0, 4, skb->len - phdrlen);
135#undef LWNG_SETVAL
136 } else if (prism_header == 2) {
137 struct linux_wlan_ng_cap_hdr *hdr;
138 hdr = (struct linux_wlan_ng_cap_hdr *)
139 skb_push(skb, phdrlen);
140 memset(hdr, 0, phdrlen);
141 hdr->version = htonl(LWNG_CAPHDR_VERSION);
142 hdr->length = htonl(phdrlen);
143 hdr->mactime = __cpu_to_be64(rx_stats->mac_time);
144 hdr->hosttime = __cpu_to_be64(jiffies);
145 hdr->phytype = htonl(4); /* dss_dot11_b */
146 hdr->channel = htonl(local->channel);
147 hdr->datarate = htonl(rx_stats->rate);
148 hdr->antenna = htonl(0); /* unknown */
149 hdr->priority = htonl(0); /* unknown */
150 hdr->ssi_type = htonl(3); /* raw */
151 hdr->ssi_signal = htonl(rx_stats->signal);
152 hdr->ssi_noise = htonl(rx_stats->noise);
153 hdr->preamble = htonl(0); /* unknown */
154 hdr->encoding = htonl(1); /* cck */
155 }
156
157 ret = skb->len - phdrlen;
158 skb->dev = dev;
159 skb->mac.raw = skb->data;
160 skb_pull(skb, hdrlen);
161 if (prism_header)
162 skb_pull(skb, phdrlen);
163 skb->pkt_type = PACKET_OTHERHOST;
164 skb->protocol = __constant_htons(ETH_P_802_2);
165 memset(skb->cb, 0, sizeof(skb->cb));
166 netif_rx(skb);
167
168 return ret;
169}
170
171
172/* Called only as a tasklet (software IRQ) */
173static void monitor_rx(struct net_device *dev, struct sk_buff *skb,
174 struct hostap_80211_rx_status *rx_stats)
175{
176 struct net_device_stats *stats;
177 int len;
178
179 len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR);
180 stats = hostap_get_stats(dev);
181 stats->rx_packets++;
182 stats->rx_bytes += len;
183}
184
185
186/* Called only as a tasklet (software IRQ) */
187static struct prism2_frag_entry *
188prism2_frag_cache_find(local_info_t *local, unsigned int seq,
189 unsigned int frag, u8 *src, u8 *dst)
190{
191 struct prism2_frag_entry *entry;
192 int i;
193
194 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
195 entry = &local->frag_cache[i];
196 if (entry->skb != NULL &&
197 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
198 printk(KERN_DEBUG "%s: expiring fragment cache entry "
199 "seq=%u last_frag=%u\n",
200 local->dev->name, entry->seq, entry->last_frag);
201 dev_kfree_skb(entry->skb);
202 entry->skb = NULL;
203 }
204
205 if (entry->skb != NULL && entry->seq == seq &&
206 (entry->last_frag + 1 == frag || frag == -1) &&
207 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
208 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
209 return entry;
210 }
211
212 return NULL;
213}
214
215
216/* Called only as a tasklet (software IRQ) */
217static struct sk_buff *
218prism2_frag_cache_get(local_info_t *local, struct hostap_ieee80211_hdr *hdr)
219{
220 struct sk_buff *skb = NULL;
221 u16 sc;
222 unsigned int frag, seq;
223 struct prism2_frag_entry *entry;
224
225 sc = le16_to_cpu(hdr->seq_ctrl);
226 frag = WLAN_GET_SEQ_FRAG(sc);
227 seq = WLAN_GET_SEQ_SEQ(sc);
228
229 if (frag == 0) {
230 /* Reserve enough space to fit maximum frame length */
231 skb = dev_alloc_skb(local->dev->mtu +
232 sizeof(struct hostap_ieee80211_hdr) +
233 8 /* LLC */ +
234 2 /* alignment */ +
235 8 /* WEP */ + ETH_ALEN /* WDS */);
236 if (skb == NULL)
237 return NULL;
238
239 entry = &local->frag_cache[local->frag_next_idx];
240 local->frag_next_idx++;
241 if (local->frag_next_idx >= PRISM2_FRAG_CACHE_LEN)
242 local->frag_next_idx = 0;
243
244 if (entry->skb != NULL)
245 dev_kfree_skb(entry->skb);
246
247 entry->first_frag_time = jiffies;
248 entry->seq = seq;
249 entry->last_frag = frag;
250 entry->skb = skb;
251 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
252 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
253 } else {
254 /* received a fragment of a frame for which the head fragment
255 * should have already been received */
256 entry = prism2_frag_cache_find(local, seq, frag, hdr->addr2,
257 hdr->addr1);
258 if (entry != NULL) {
259 entry->last_frag = frag;
260 skb = entry->skb;
261 }
262 }
263
264 return skb;
265}
266
267
268/* Called only as a tasklet (software IRQ) */
269static int prism2_frag_cache_invalidate(local_info_t *local,
270 struct hostap_ieee80211_hdr *hdr)
271{
272 u16 sc;
273 unsigned int seq;
274 struct prism2_frag_entry *entry;
275
276 sc = le16_to_cpu(hdr->seq_ctrl);
277 seq = WLAN_GET_SEQ_SEQ(sc);
278
279 entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1);
280
281 if (entry == NULL) {
282 printk(KERN_DEBUG "%s: could not invalidate fragment cache "
283 "entry (seq=%u)\n",
284 local->dev->name, seq);
285 return -1;
286 }
287
288 entry->skb = NULL;
289 return 0;
290}
291
292
293static struct hostap_bss_info *__hostap_get_bss(local_info_t *local, u8 *bssid,
294 u8 *ssid, size_t ssid_len)
295{
296 struct list_head *ptr;
297 struct hostap_bss_info *bss;
298
299 list_for_each(ptr, &local->bss_list) {
300 bss = list_entry(ptr, struct hostap_bss_info, list);
301 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
302 (ssid == NULL ||
303 (ssid_len == bss->ssid_len &&
304 memcmp(ssid, bss->ssid, ssid_len) == 0))) {
305 list_move(&bss->list, &local->bss_list);
306 return bss;
307 }
308 }
309
310 return NULL;
311}
312
313
314static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid,
315 u8 *ssid, size_t ssid_len)
316{
317 struct hostap_bss_info *bss;
318
319 if (local->num_bss_info >= HOSTAP_MAX_BSS_COUNT) {
320 bss = list_entry(local->bss_list.prev,
321 struct hostap_bss_info, list);
322 list_del(&bss->list);
323 local->num_bss_info--;
324 } else {
325 bss = (struct hostap_bss_info *)
326 kmalloc(sizeof(*bss), GFP_ATOMIC);
327 if (bss == NULL)
328 return NULL;
329 }
330
331 memset(bss, 0, sizeof(*bss));
332 memcpy(bss->bssid, bssid, ETH_ALEN);
333 memcpy(bss->ssid, ssid, ssid_len);
334 bss->ssid_len = ssid_len;
335 local->num_bss_info++;
336 list_add(&bss->list, &local->bss_list);
337 return bss;
338}
339
340
341static void __hostap_expire_bss(local_info_t *local)
342{
343 struct hostap_bss_info *bss;
344
345 while (local->num_bss_info > 0) {
346 bss = list_entry(local->bss_list.prev,
347 struct hostap_bss_info, list);
348 if (!time_after(jiffies, bss->last_update + 60 * HZ))
349 break;
350
351 list_del(&bss->list);
352 local->num_bss_info--;
353 kfree(bss);
354 }
355}
356
357
358/* Both IEEE 802.11 Beacon and Probe Response frames have similar structure, so
359 * the same routine can be used to parse both of them. */
360static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb,
361 int stype)
362{
363 struct hostap_ieee80211_mgmt *mgmt;
364 int left, chan = 0;
365 u8 *pos;
366 u8 *ssid = NULL, *wpa = NULL, *rsn = NULL;
367 size_t ssid_len = 0, wpa_len = 0, rsn_len = 0;
368 struct hostap_bss_info *bss;
369
370 if (skb->len < IEEE80211_MGMT_HDR_LEN + sizeof(mgmt->u.beacon))
371 return;
372
373 mgmt = (struct hostap_ieee80211_mgmt *) skb->data;
374 pos = mgmt->u.beacon.variable;
375 left = skb->len - (pos - skb->data);
376
377 while (left >= 2) {
378 if (2 + pos[1] > left)
379 return; /* parse failed */
380 switch (*pos) {
381 case WLAN_EID_SSID:
382 ssid = pos + 2;
383 ssid_len = pos[1];
384 break;
385 case WLAN_EID_GENERIC:
386 if (pos[1] >= 4 &&
387 pos[2] == 0x00 && pos[3] == 0x50 &&
388 pos[4] == 0xf2 && pos[5] == 1) {
389 wpa = pos;
390 wpa_len = pos[1] + 2;
391 }
392 break;
393 case WLAN_EID_RSN:
394 rsn = pos;
395 rsn_len = pos[1] + 2;
396 break;
397 case WLAN_EID_DS_PARAMS:
398 if (pos[1] >= 1)
399 chan = pos[2];
400 break;
401 }
402 left -= 2 + pos[1];
403 pos += 2 + pos[1];
404 }
405
406 if (wpa_len > MAX_WPA_IE_LEN)
407 wpa_len = MAX_WPA_IE_LEN;
408 if (rsn_len > MAX_WPA_IE_LEN)
409 rsn_len = MAX_WPA_IE_LEN;
410 if (ssid_len > sizeof(bss->ssid))
411 ssid_len = sizeof(bss->ssid);
412
413 spin_lock(&local->lock);
414 bss = __hostap_get_bss(local, mgmt->bssid, ssid, ssid_len);
415 if (bss == NULL)
416 bss = __hostap_add_bss(local, mgmt->bssid, ssid, ssid_len);
417 if (bss) {
418 bss->last_update = jiffies;
419 bss->count++;
420 bss->capab_info = le16_to_cpu(mgmt->u.beacon.capab_info);
421 if (wpa) {
422 memcpy(bss->wpa_ie, wpa, wpa_len);
423 bss->wpa_ie_len = wpa_len;
424 } else
425 bss->wpa_ie_len = 0;
426 if (rsn) {
427 memcpy(bss->rsn_ie, rsn, rsn_len);
428 bss->rsn_ie_len = rsn_len;
429 } else
430 bss->rsn_ie_len = 0;
431 bss->chan = chan;
432 }
433 __hostap_expire_bss(local);
434 spin_unlock(&local->lock);
435}
436
437
438static inline int
439hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
440 struct hostap_80211_rx_status *rx_stats, u16 type,
441 u16 stype)
442{
443 if (local->iw_mode == IW_MODE_MASTER) {
444 hostap_update_sta_ps(local, (struct hostap_ieee80211_hdr *)
445 skb->data);
446 }
447
448 if (local->hostapd && type == WLAN_FC_TYPE_MGMT) {
449 if (stype == WLAN_FC_STYPE_BEACON &&
450 local->iw_mode == IW_MODE_MASTER) {
451 struct sk_buff *skb2;
452 /* Process beacon frames also in kernel driver to
453 * update STA(AP) table statistics */
454 skb2 = skb_clone(skb, GFP_ATOMIC);
455 if (skb2)
456 hostap_rx(skb2->dev, skb2, rx_stats);
457 }
458
459 /* send management frames to the user space daemon for
460 * processing */
461 local->apdevstats.rx_packets++;
462 local->apdevstats.rx_bytes += skb->len;
463 if (local->apdev == NULL)
464 return -1;
465 prism2_rx_80211(local->apdev, skb, rx_stats, PRISM2_RX_MGMT);
466 return 0;
467 }
468
469 if (local->iw_mode == IW_MODE_MASTER) {
470 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
471 printk(KERN_DEBUG "%s: unknown management frame "
472 "(type=0x%02x, stype=0x%02x) dropped\n",
473 skb->dev->name, type, stype);
474 return -1;
475 }
476
477 hostap_rx(skb->dev, skb, rx_stats);
478 return 0;
479 } else if (type == WLAN_FC_TYPE_MGMT &&
480 (stype == WLAN_FC_STYPE_BEACON ||
481 stype == WLAN_FC_STYPE_PROBE_RESP)) {
482 hostap_rx_sta_beacon(local, skb, stype);
483 return -1;
484 } else if (type == WLAN_FC_TYPE_MGMT &&
485 (stype == WLAN_FC_STYPE_ASSOC_RESP ||
486 stype == WLAN_FC_STYPE_REASSOC_RESP)) {
487 /* Ignore (Re)AssocResp silently since these are not currently
488 * needed but are still received when WPA/RSN mode is enabled.
489 */
490 return -1;
491 } else {
492 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: dropped unhandled"
493 " management frame in non-Host AP mode (type=%d:%d)\n",
494 skb->dev->name, type, stype);
495 return -1;
496 }
497}
498
499
500/* Called only as a tasklet (software IRQ) */
501static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
502 u8 *addr)
503{
504 struct hostap_interface *iface = NULL;
505 struct list_head *ptr;
506
507 read_lock_bh(&local->iface_lock);
508 list_for_each(ptr, &local->hostap_interfaces) {
509 iface = list_entry(ptr, struct hostap_interface, list);
510 if (iface->type == HOSTAP_INTERFACE_WDS &&
511 memcmp(iface->u.wds.remote_addr, addr, ETH_ALEN) == 0)
512 break;
513 iface = NULL;
514 }
515 read_unlock_bh(&local->iface_lock);
516
517 return iface ? iface->dev : NULL;
518}
519
520
521static inline int
522hostap_rx_frame_wds(local_info_t *local, struct hostap_ieee80211_hdr *hdr,
523 u16 fc, struct net_device **wds)
524{
525 /* FIX: is this really supposed to accept WDS frames only in Master
526 * mode? What about Repeater or Managed with WDS frames? */
527 if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) !=
528 (WLAN_FC_TODS | WLAN_FC_FROMDS) &&
529 (local->iw_mode != IW_MODE_MASTER || !(fc & WLAN_FC_TODS)))
530 return 0; /* not a WDS frame */
531
532 /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS)
533 * or own non-standard frame with 4th address after payload */
534 if (memcmp(hdr->addr1, local->dev->dev_addr, ETH_ALEN) != 0 &&
535 (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff ||
536 hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
537 hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
538 /* RA (or BSSID) is not ours - drop */
539 PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with "
540 "not own or broadcast %s=" MACSTR "\n",
541 local->dev->name, fc & WLAN_FC_FROMDS ? "RA" : "BSSID",
542 MAC2STR(hdr->addr1));
543 return -1;
544 }
545
546 /* check if the frame came from a registered WDS connection */
547 *wds = prism2_rx_get_wds(local, hdr->addr2);
548 if (*wds == NULL && fc & WLAN_FC_FROMDS &&
549 (local->iw_mode != IW_MODE_INFRA ||
550 !(local->wds_type & HOSTAP_WDS_AP_CLIENT) ||
551 memcmp(hdr->addr2, local->bssid, ETH_ALEN) != 0)) {
552 /* require that WDS link has been registered with TA or the
553 * frame is from current AP when using 'AP client mode' */
554 PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame "
555 "from unknown TA=" MACSTR "\n",
556 local->dev->name, MAC2STR(hdr->addr2));
557 if (local->ap && local->ap->autom_ap_wds)
558 hostap_wds_link_oper(local, hdr->addr2, WDS_ADD);
559 return -1;
560 }
561
562 if (*wds && !(fc & WLAN_FC_FROMDS) && local->ap &&
563 hostap_is_sta_assoc(local->ap, hdr->addr2)) {
564 /* STA is actually associated with us even though it has a
565 * registered WDS link. Assume it is in 'AP client' mode.
566 * Since this is a 3-addr frame, assume it is not (bogus) WDS
567 * frame and process it like any normal ToDS frame from
568 * associated STA. */
569 *wds = NULL;
570 }
571
572 return 0;
573}
574
575
576static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
577{
578 struct net_device *dev = local->dev;
579 u16 fc, ethertype;
580 struct hostap_ieee80211_hdr *hdr;
581 u8 *pos;
582
583 if (skb->len < 24)
584 return 0;
585
586 hdr = (struct hostap_ieee80211_hdr *) skb->data;
587 fc = le16_to_cpu(hdr->frame_control);
588
589 /* check that the frame is unicast frame to us */
590 if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_TODS &&
591 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
592 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
593 /* ToDS frame with own addr BSSID and DA */
594 } else if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_FROMDS &&
595 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
596 /* FromDS frame with own addr as DA */
597 } else
598 return 0;
599
600 if (skb->len < 24 + 8)
601 return 0;
602
603 /* check for port access entity Ethernet type */
604 pos = skb->data + 24;
605 ethertype = (pos[6] << 8) | pos[7];
606 if (ethertype == ETH_P_PAE)
607 return 1;
608
609 return 0;
610}
611
612
613/* Called only as a tasklet (software IRQ) */
614static inline int
615hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
616 struct prism2_crypt_data *crypt)
617{
618 struct hostap_ieee80211_hdr *hdr;
619 int res, hdrlen;
620
621 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
622 return 0;
623
624 hdr = (struct hostap_ieee80211_hdr *) skb->data;
625 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
626
627 if (local->tkip_countermeasures &&
628 strcmp(crypt->ops->name, "TKIP") == 0) {
629 if (net_ratelimit()) {
630 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
631 "received packet from " MACSTR "\n",
632 local->dev->name, MAC2STR(hdr->addr2));
633 }
634 return -1;
635 }
636
637 atomic_inc(&crypt->refcnt);
638 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
639 atomic_dec(&crypt->refcnt);
640 if (res < 0) {
641 printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR
642 ") res=%d\n",
643 local->dev->name, MAC2STR(hdr->addr2), res);
644 local->comm_tallies.rx_discards_wep_undecryptable++;
645 return -1;
646 }
647
648 return res;
649}
650
651
652/* Called only as a tasklet (software IRQ) */
653static inline int
654hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
655 int keyidx, struct prism2_crypt_data *crypt)
656{
657 struct hostap_ieee80211_hdr *hdr;
658 int res, hdrlen;
659
660 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
661 return 0;
662
663 hdr = (struct hostap_ieee80211_hdr *) skb->data;
664 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
665
666 atomic_inc(&crypt->refcnt);
667 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
668 atomic_dec(&crypt->refcnt);
669 if (res < 0) {
670 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
671 " (SA=" MACSTR " keyidx=%d)\n",
672 local->dev->name, MAC2STR(hdr->addr2), keyidx);
673 return -1;
674 }
675
676 return 0;
677}
678
679
680/* All received frames are sent to this function. @skb contains the frame in
681 * IEEE 802.11 format, i.e., in the format it was sent over air.
682 * This function is called only as a tasklet (software IRQ). */
683void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
684 struct hostap_80211_rx_status *rx_stats)
685{
686 struct hostap_interface *iface;
687 local_info_t *local;
688 struct hostap_ieee80211_hdr *hdr;
689 size_t hdrlen;
690 u16 fc, type, stype, sc;
691 struct net_device *wds = NULL;
692 struct net_device_stats *stats;
693 unsigned int frag;
694 u8 *payload;
695 struct sk_buff *skb2 = NULL;
696 u16 ethertype;
697 int frame_authorized = 0;
698 int from_assoc_ap = 0;
699 u8 dst[ETH_ALEN];
700 u8 src[ETH_ALEN];
701 struct prism2_crypt_data *crypt = NULL;
702 void *sta = NULL;
703 int keyidx = 0;
704
705 iface = netdev_priv(dev);
706 local = iface->local;
707 iface->stats.rx_packets++;
708 iface->stats.rx_bytes += skb->len;
709
710 /* dev is the master radio device; change this to be the default
711 * virtual interface (this may be changed to WDS device below) */
712 dev = local->ddev;
713 iface = netdev_priv(dev);
714
715 hdr = (struct hostap_ieee80211_hdr *) skb->data;
716 stats = hostap_get_stats(dev);
717
718 if (skb->len < 10)
719 goto rx_dropped;
720
721 fc = le16_to_cpu(hdr->frame_control);
722 type = WLAN_FC_GET_TYPE(fc);
723 stype = WLAN_FC_GET_STYPE(fc);
724 sc = le16_to_cpu(hdr->seq_ctrl);
725 frag = WLAN_GET_SEQ_FRAG(sc);
726 hdrlen = hostap_80211_get_hdrlen(fc);
727
728 /* Put this code here so that we avoid duplicating it in all
729 * Rx paths. - Jean II */
730#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
731 /* If spy monitoring on */
732 if (iface->spy_data.spy_number > 0) {
733 struct iw_quality wstats;
734 wstats.level = rx_stats->signal;
735 wstats.noise = rx_stats->noise;
736 wstats.updated = 6; /* No qual value */
737 /* Update spy records */
738 wireless_spy_update(dev, hdr->addr2, &wstats);
739 }
740#endif /* IW_WIRELESS_SPY */
741 hostap_update_rx_stats(local->ap, hdr, rx_stats);
742
743 if (local->iw_mode == IW_MODE_MONITOR) {
744 monitor_rx(dev, skb, rx_stats);
745 return;
746 }
747
748 if (local->host_decrypt) {
749 int idx = 0;
750 if (skb->len >= hdrlen + 3)
751 idx = skb->data[hdrlen + 3] >> 6;
752 crypt = local->crypt[idx];
753 sta = NULL;
754
755 /* Use station specific key to override default keys if the
756 * receiver address is a unicast address ("individual RA"). If
757 * bcrx_sta_key parameter is set, station specific key is used
758 * even with broad/multicast targets (this is against IEEE
759 * 802.11, but makes it easier to use different keys with
760 * stations that do not support WEP key mapping). */
761
762 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
763 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
764 &sta);
765
766 /* allow NULL decrypt to indicate an station specific override
767 * for default encryption */
768 if (crypt && (crypt->ops == NULL ||
769 crypt->ops->decrypt_mpdu == NULL))
770 crypt = NULL;
771
772 if (!crypt && (fc & WLAN_FC_ISWEP)) {
773#if 0
774 /* This seems to be triggered by some (multicast?)
775 * frames from other than current BSS, so just drop the
776 * frames silently instead of filling system log with
777 * these reports. */
778 printk(KERN_DEBUG "%s: WEP decryption failed (not set)"
779 " (SA=" MACSTR ")\n",
780 local->dev->name, MAC2STR(hdr->addr2));
781#endif
782 local->comm_tallies.rx_discards_wep_undecryptable++;
783 goto rx_dropped;
784 }
785 }
786
787 if (type != WLAN_FC_TYPE_DATA) {
788 if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
789 fc & WLAN_FC_ISWEP && local->host_decrypt &&
790 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
791 {
792 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
793 "from " MACSTR "\n", dev->name,
794 MAC2STR(hdr->addr2));
795 /* TODO: could inform hostapd about this so that it
796 * could send auth failure report */
797 goto rx_dropped;
798 }
799
800 if (hostap_rx_frame_mgmt(local, skb, rx_stats, type, stype))
801 goto rx_dropped;
802 else
803 goto rx_exit;
804 }
805
806 /* Data frame - extract src/dst addresses */
807 if (skb->len < IEEE80211_DATA_HDR3_LEN)
808 goto rx_dropped;
809
810 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
811 case WLAN_FC_FROMDS:
812 memcpy(dst, hdr->addr1, ETH_ALEN);
813 memcpy(src, hdr->addr3, ETH_ALEN);
814 break;
815 case WLAN_FC_TODS:
816 memcpy(dst, hdr->addr3, ETH_ALEN);
817 memcpy(src, hdr->addr2, ETH_ALEN);
818 break;
819 case WLAN_FC_FROMDS | WLAN_FC_TODS:
820 if (skb->len < IEEE80211_DATA_HDR4_LEN)
821 goto rx_dropped;
822 memcpy(dst, hdr->addr3, ETH_ALEN);
823 memcpy(src, hdr->addr4, ETH_ALEN);
824 break;
825 case 0:
826 memcpy(dst, hdr->addr1, ETH_ALEN);
827 memcpy(src, hdr->addr2, ETH_ALEN);
828 break;
829 }
830
831 if (hostap_rx_frame_wds(local, hdr, fc, &wds))
832 goto rx_dropped;
833 if (wds) {
834 skb->dev = dev = wds;
835 stats = hostap_get_stats(dev);
836 }
837
838 if (local->iw_mode == IW_MODE_MASTER && !wds &&
839 (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_FROMDS &&
840 local->stadev &&
841 memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
842 /* Frame from BSSID of the AP for which we are a client */
843 skb->dev = dev = local->stadev;
844 stats = hostap_get_stats(dev);
845 from_assoc_ap = 1;
846 }
847
848 dev->last_rx = jiffies;
849
850 if ((local->iw_mode == IW_MODE_MASTER ||
851 local->iw_mode == IW_MODE_REPEAT) &&
852 !from_assoc_ap) {
853 switch (hostap_handle_sta_rx(local, dev, skb, rx_stats,
854 wds != NULL)) {
855 case AP_RX_CONTINUE_NOT_AUTHORIZED:
856 frame_authorized = 0;
857 break;
858 case AP_RX_CONTINUE:
859 frame_authorized = 1;
860 break;
861 case AP_RX_DROP:
862 goto rx_dropped;
863 case AP_RX_EXIT:
864 goto rx_exit;
865 }
866 }
867
868 /* Nullfunc frames may have PS-bit set, so they must be passed to
869 * hostap_handle_sta_rx() before being dropped here. */
870 if (stype != WLAN_FC_STYPE_DATA &&
871 stype != WLAN_FC_STYPE_DATA_CFACK &&
872 stype != WLAN_FC_STYPE_DATA_CFPOLL &&
873 stype != WLAN_FC_STYPE_DATA_CFACKPOLL) {
874 if (stype != WLAN_FC_STYPE_NULLFUNC)
875 printk(KERN_DEBUG "%s: RX: dropped data frame "
876 "with no data (type=0x%02x, subtype=0x%02x)\n",
877 dev->name, type, stype);
878 goto rx_dropped;
879 }
880
881 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
882
883 if (local->host_decrypt && (fc & WLAN_FC_ISWEP) &&
884 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
885 goto rx_dropped;
886 hdr = (struct hostap_ieee80211_hdr *) skb->data;
887
888 /* skb: hdr + (possibly fragmented) plaintext payload */
889
890 if (local->host_decrypt && (fc & WLAN_FC_ISWEP) &&
891 (frag != 0 || (fc & WLAN_FC_MOREFRAG))) {
892 int flen;
893 struct sk_buff *frag_skb =
894 prism2_frag_cache_get(local, hdr);
895 if (!frag_skb) {
896 printk(KERN_DEBUG "%s: Rx cannot get skb from "
897 "fragment cache (morefrag=%d seq=%u frag=%u)\n",
898 dev->name, (fc & WLAN_FC_MOREFRAG) != 0,
899 WLAN_GET_SEQ_SEQ(sc), frag);
900 goto rx_dropped;
901 }
902
903 flen = skb->len;
904 if (frag != 0)
905 flen -= hdrlen;
906
907 if (frag_skb->tail + flen > frag_skb->end) {
908 printk(KERN_WARNING "%s: host decrypted and "
909 "reassembled frame did not fit skb\n",
910 dev->name);
911 prism2_frag_cache_invalidate(local, hdr);
912 goto rx_dropped;
913 }
914
915 if (frag == 0) {
916 /* copy first fragment (including full headers) into
917 * beginning of the fragment cache skb */
918 memcpy(skb_put(frag_skb, flen), skb->data, flen);
919 } else {
920 /* append frame payload to the end of the fragment
921 * cache skb */
922 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
923 flen);
924 }
925 dev_kfree_skb(skb);
926 skb = NULL;
927
928 if (fc & WLAN_FC_MOREFRAG) {
929 /* more fragments expected - leave the skb in fragment
930 * cache for now; it will be delivered to upper layers
931 * after all fragments have been received */
932 goto rx_exit;
933 }
934
935 /* this was the last fragment and the frame will be
936 * delivered, so remove skb from fragment cache */
937 skb = frag_skb;
938 hdr = (struct hostap_ieee80211_hdr *) skb->data;
939 prism2_frag_cache_invalidate(local, hdr);
940 }
941
942 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
943 * encrypted/authenticated */
944
945 if (local->host_decrypt && (fc & WLAN_FC_ISWEP) &&
946 hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
947 goto rx_dropped;
948
949 hdr = (struct hostap_ieee80211_hdr *) skb->data;
950 if (crypt && !(fc & WLAN_FC_ISWEP) && !local->open_wep) {
951 if (local->ieee_802_1x &&
952 hostap_is_eapol_frame(local, skb)) {
953 /* pass unencrypted EAPOL frames even if encryption is
954 * configured */
955 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X - passing "
956 "unencrypted EAPOL frame\n", local->dev->name);
957 } else {
958 printk(KERN_DEBUG "%s: encryption configured, but RX "
959 "frame not encrypted (SA=" MACSTR ")\n",
960 local->dev->name, MAC2STR(hdr->addr2));
961 goto rx_dropped;
962 }
963 }
964
965 if (local->drop_unencrypted && !(fc & WLAN_FC_ISWEP) &&
966 !hostap_is_eapol_frame(local, skb)) {
967 if (net_ratelimit()) {
968 printk(KERN_DEBUG "%s: dropped unencrypted RX data "
969 "frame from " MACSTR " (drop_unencrypted=1)\n",
970 dev->name, MAC2STR(hdr->addr2));
971 }
972 goto rx_dropped;
973 }
974
975 /* skb: hdr + (possible reassembled) full plaintext payload */
976
977 payload = skb->data + hdrlen;
978 ethertype = (payload[6] << 8) | payload[7];
979
980 /* If IEEE 802.1X is used, check whether the port is authorized to send
981 * the received frame. */
982 if (local->ieee_802_1x && local->iw_mode == IW_MODE_MASTER) {
983 if (ethertype == ETH_P_PAE) {
984 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X frame\n",
985 dev->name);
986 if (local->hostapd && local->apdev) {
987 /* Send IEEE 802.1X frames to the user
988 * space daemon for processing */
989 prism2_rx_80211(local->apdev, skb, rx_stats,
990 PRISM2_RX_MGMT);
991 local->apdevstats.rx_packets++;
992 local->apdevstats.rx_bytes += skb->len;
993 goto rx_exit;
994 }
995 } else if (!frame_authorized) {
996 printk(KERN_DEBUG "%s: dropped frame from "
997 "unauthorized port (IEEE 802.1X): "
998 "ethertype=0x%04x\n",
999 dev->name, ethertype);
1000 goto rx_dropped;
1001 }
1002 }
1003
1004 /* convert hdr + possible LLC headers into Ethernet header */
1005 if (skb->len - hdrlen >= 8 &&
1006 ((memcmp(payload, rfc1042_header, 6) == 0 &&
1007 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1008 memcmp(payload, bridge_tunnel_header, 6) == 0)) {
1009 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1010 * replace EtherType */
1011 skb_pull(skb, hdrlen + 6);
1012 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1013 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1014 } else {
1015 u16 len;
1016 /* Leave Ethernet header part of hdr and full payload */
1017 skb_pull(skb, hdrlen);
1018 len = htons(skb->len);
1019 memcpy(skb_push(skb, 2), &len, 2);
1020 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1021 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1022 }
1023
1024 if (wds && ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == WLAN_FC_TODS) &&
1025 skb->len >= ETH_HLEN + ETH_ALEN) {
1026 /* Non-standard frame: get addr4 from its bogus location after
1027 * the payload */
1028 memcpy(skb->data + ETH_ALEN,
1029 skb->data + skb->len - ETH_ALEN, ETH_ALEN);
1030 skb_trim(skb, skb->len - ETH_ALEN);
1031 }
1032
1033 stats->rx_packets++;
1034 stats->rx_bytes += skb->len;
1035
1036 if (local->iw_mode == IW_MODE_MASTER && !wds &&
1037 local->ap->bridge_packets) {
1038 if (dst[0] & 0x01) {
1039 /* copy multicast frame both to the higher layers and
1040 * to the wireless media */
1041 local->ap->bridged_multicast++;
1042 skb2 = skb_clone(skb, GFP_ATOMIC);
1043 if (skb2 == NULL)
1044 printk(KERN_DEBUG "%s: skb_clone failed for "
1045 "multicast frame\n", dev->name);
1046 } else if (hostap_is_sta_authorized(local->ap, dst)) {
1047 /* send frame directly to the associated STA using
1048 * wireless media and not passing to higher layers */
1049 local->ap->bridged_unicast++;
1050 skb2 = skb;
1051 skb = NULL;
1052 }
1053 }
1054
1055 if (skb2 != NULL) {
1056 /* send to wireless media */
1057 skb2->protocol = __constant_htons(ETH_P_802_3);
1058 skb2->mac.raw = skb2->nh.raw = skb2->data;
1059 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
1060 skb2->dev = dev;
1061 dev_queue_xmit(skb2);
1062 }
1063
1064 if (skb) {
1065 skb->protocol = eth_type_trans(skb, dev);
1066 memset(skb->cb, 0, sizeof(skb->cb));
1067 skb->dev = dev;
1068 netif_rx(skb);
1069 }
1070
1071 rx_exit:
1072 if (sta)
1073 hostap_handle_sta_release(sta);
1074 return;
1075
1076 rx_dropped:
1077 dev_kfree_skb(skb);
1078
1079 stats->rx_dropped++;
1080 goto rx_exit;
1081}
1082
1083
1084EXPORT_SYMBOL(hostap_80211_rx);
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
new file mode 100644
index 000000000000..8a94a80ec55f
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -0,0 +1,522 @@
1void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
2{
3 struct hostap_ieee80211_hdr *hdr;
4 u16 fc;
5
6 hdr = (struct hostap_ieee80211_hdr *) skb->data;
7
8 printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
9 name, skb->len, jiffies);
10
11 if (skb->len < 2)
12 return;
13
14 fc = le16_to_cpu(hdr->frame_control);
15 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
16 fc, WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc),
17 fc & WLAN_FC_TODS ? " [ToDS]" : "",
18 fc & WLAN_FC_FROMDS ? " [FromDS]" : "");
19
20 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
21 printk("\n");
22 return;
23 }
24
25 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
26 le16_to_cpu(hdr->seq_ctrl));
27
28 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR,
29 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3));
30 if (skb->len >= 30)
31 printk(" A4=" MACSTR, MAC2STR(hdr->addr4));
32 printk("\n");
33}
34
35
36/* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta)
37 * Convert Ethernet header into a suitable IEEE 802.11 header depending on
38 * device configuration. */
39int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
40{
41 struct hostap_interface *iface;
42 local_info_t *local;
43 int need_headroom, need_tailroom = 0;
44 struct hostap_ieee80211_hdr hdr;
45 u16 fc, ethertype = 0;
46 enum {
47 WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
48 } use_wds = WDS_NO;
49 u8 *encaps_data;
50 int hdr_len, encaps_len, skip_header_bytes;
51 int to_assoc_ap = 0;
52 struct hostap_skb_tx_data *meta;
53
54 iface = netdev_priv(dev);
55 local = iface->local;
56
57 if (skb->len < ETH_HLEN) {
58 printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
59 "(len=%d)\n", dev->name, skb->len);
60 kfree_skb(skb);
61 return 0;
62 }
63
64 if (local->ddev != dev) {
65 use_wds = (local->iw_mode == IW_MODE_MASTER &&
66 !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ?
67 WDS_OWN_FRAME : WDS_COMPLIANT_FRAME;
68 if (dev == local->stadev) {
69 to_assoc_ap = 1;
70 use_wds = WDS_NO;
71 } else if (dev == local->apdev) {
72 printk(KERN_DEBUG "%s: prism2_tx: trying to use "
73 "AP device with Ethernet net dev\n", dev->name);
74 kfree_skb(skb);
75 return 0;
76 }
77 } else {
78 if (local->iw_mode == IW_MODE_REPEAT) {
79 printk(KERN_DEBUG "%s: prism2_tx: trying to use "
80 "non-WDS link in Repeater mode\n", dev->name);
81 kfree_skb(skb);
82 return 0;
83 } else if (local->iw_mode == IW_MODE_INFRA &&
84 (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
85 memcmp(skb->data + ETH_ALEN, dev->dev_addr,
86 ETH_ALEN) != 0) {
87 /* AP client mode: send frames with foreign src addr
88 * using 4-addr WDS frames */
89 use_wds = WDS_COMPLIANT_FRAME;
90 }
91 }
92
93 /* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload
94 * ==>
95 * Prism2 TX frame with 802.11 header:
96 * txdesc (address order depending on used mode; includes dst_addr and
97 * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel;
98 * proto[2], payload {, possible addr4[6]} */
99
100 ethertype = (skb->data[12] << 8) | skb->data[13];
101
102 memset(&hdr, 0, sizeof(hdr));
103
104 /* Length of data after IEEE 802.11 header */
105 encaps_data = NULL;
106 encaps_len = 0;
107 skip_header_bytes = ETH_HLEN;
108 if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
109 encaps_data = bridge_tunnel_header;
110 encaps_len = sizeof(bridge_tunnel_header);
111 skip_header_bytes -= 2;
112 } else if (ethertype >= 0x600) {
113 encaps_data = rfc1042_header;
114 encaps_len = sizeof(rfc1042_header);
115 skip_header_bytes -= 2;
116 }
117
118 fc = (WLAN_FC_TYPE_DATA << 2) | (WLAN_FC_STYPE_DATA << 4);
119 hdr_len = IEEE80211_DATA_HDR3_LEN;
120
121 if (use_wds != WDS_NO) {
122 /* Note! Prism2 station firmware has problems with sending real
123 * 802.11 frames with four addresses; until these problems can
124 * be fixed or worked around, 4-addr frames needed for WDS are
125 * using incompatible format: FromDS flag is not set and the
126 * fourth address is added after the frame payload; it is
127 * assumed, that the receiving station knows how to handle this
128 * frame format */
129
130 if (use_wds == WDS_COMPLIANT_FRAME) {
131 fc |= WLAN_FC_FROMDS | WLAN_FC_TODS;
132 /* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA,
133 * Addr4 = SA */
134 memcpy(&hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
135 hdr_len += ETH_ALEN;
136 } else {
137 /* bogus 4-addr format to workaround Prism2 station
138 * f/w bug */
139 fc |= WLAN_FC_TODS;
140 /* From DS: Addr1 = DA (used as RA),
141 * Addr2 = BSSID (used as TA), Addr3 = SA (used as DA),
142 */
143
144 /* SA from skb->data + ETH_ALEN will be added after
145 * frame payload; use hdr.addr4 as a temporary buffer
146 */
147 memcpy(&hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
148 need_tailroom += ETH_ALEN;
149 }
150
151 /* send broadcast and multicast frames to broadcast RA, if
152 * configured; otherwise, use unicast RA of the WDS link */
153 if ((local->wds_type & HOSTAP_WDS_BROADCAST_RA) &&
154 skb->data[0] & 0x01)
155 memset(&hdr.addr1, 0xff, ETH_ALEN);
156 else if (iface->type == HOSTAP_INTERFACE_WDS)
157 memcpy(&hdr.addr1, iface->u.wds.remote_addr,
158 ETH_ALEN);
159 else
160 memcpy(&hdr.addr1, local->bssid, ETH_ALEN);
161 memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN);
162 memcpy(&hdr.addr3, skb->data, ETH_ALEN);
163 } else if (local->iw_mode == IW_MODE_MASTER && !to_assoc_ap) {
164 fc |= WLAN_FC_FROMDS;
165 /* From DS: Addr1 = DA, Addr2 = BSSID, Addr3 = SA */
166 memcpy(&hdr.addr1, skb->data, ETH_ALEN);
167 memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN);
168 memcpy(&hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
169 } else if (local->iw_mode == IW_MODE_INFRA || to_assoc_ap) {
170 fc |= WLAN_FC_TODS;
171 /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
172 memcpy(&hdr.addr1, to_assoc_ap ?
173 local->assoc_ap_addr : local->bssid, ETH_ALEN);
174 memcpy(&hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
175 memcpy(&hdr.addr3, skb->data, ETH_ALEN);
176 } else if (local->iw_mode == IW_MODE_ADHOC) {
177 /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
178 memcpy(&hdr.addr1, skb->data, ETH_ALEN);
179 memcpy(&hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
180 memcpy(&hdr.addr3, local->bssid, ETH_ALEN);
181 }
182
183 hdr.frame_control = cpu_to_le16(fc);
184
185 skb_pull(skb, skip_header_bytes);
186 need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
187 if (skb_tailroom(skb) < need_tailroom) {
188 skb = skb_unshare(skb, GFP_ATOMIC);
189 if (skb == NULL) {
190 iface->stats.tx_dropped++;
191 return 0;
192 }
193 if (pskb_expand_head(skb, need_headroom, need_tailroom,
194 GFP_ATOMIC)) {
195 kfree_skb(skb);
196 iface->stats.tx_dropped++;
197 return 0;
198 }
199 } else if (skb_headroom(skb) < need_headroom) {
200 struct sk_buff *tmp = skb;
201 skb = skb_realloc_headroom(skb, need_headroom);
202 kfree_skb(tmp);
203 if (skb == NULL) {
204 iface->stats.tx_dropped++;
205 return 0;
206 }
207 } else {
208 skb = skb_unshare(skb, GFP_ATOMIC);
209 if (skb == NULL) {
210 iface->stats.tx_dropped++;
211 return 0;
212 }
213 }
214
215 if (encaps_data)
216 memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
217 memcpy(skb_push(skb, hdr_len), &hdr, hdr_len);
218 if (use_wds == WDS_OWN_FRAME) {
219 memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN);
220 }
221
222 iface->stats.tx_packets++;
223 iface->stats.tx_bytes += skb->len;
224
225 skb->mac.raw = skb->data;
226 meta = (struct hostap_skb_tx_data *) skb->cb;
227 memset(meta, 0, sizeof(*meta));
228 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
229 meta->wds = use_wds;
230 meta->ethertype = ethertype;
231 meta->iface = iface;
232
233 /* Send IEEE 802.11 encapsulated frame using the master radio device */
234 skb->dev = local->dev;
235 dev_queue_xmit(skb);
236 return 0;
237}
238
239
240/* hard_start_xmit function for hostapd wlan#ap interfaces */
241int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
242{
243 struct hostap_interface *iface;
244 local_info_t *local;
245 struct hostap_skb_tx_data *meta;
246 struct hostap_ieee80211_hdr *hdr;
247 u16 fc;
248
249 iface = netdev_priv(dev);
250 local = iface->local;
251
252 if (skb->len < 10) {
253 printk(KERN_DEBUG "%s: hostap_mgmt_start_xmit: short skb "
254 "(len=%d)\n", dev->name, skb->len);
255 kfree_skb(skb);
256 return 0;
257 }
258
259 iface->stats.tx_packets++;
260 iface->stats.tx_bytes += skb->len;
261
262 meta = (struct hostap_skb_tx_data *) skb->cb;
263 memset(meta, 0, sizeof(*meta));
264 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
265 meta->iface = iface;
266
267 if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
268 hdr = (struct hostap_ieee80211_hdr *) skb->data;
269 fc = le16_to_cpu(hdr->frame_control);
270 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
271 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_DATA) {
272 u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
273 sizeof(rfc1042_header)];
274 meta->ethertype = (pos[0] << 8) | pos[1];
275 }
276 }
277
278 /* Send IEEE 802.11 encapsulated frame using the master radio device */
279 skb->dev = local->dev;
280 dev_queue_xmit(skb);
281 return 0;
282}
283
284
285/* Called only from software IRQ */
286struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
287 struct prism2_crypt_data *crypt)
288{
289 struct hostap_interface *iface;
290 local_info_t *local;
291 struct hostap_ieee80211_hdr *hdr;
292 u16 fc;
293 int hdr_len, res;
294
295 iface = netdev_priv(skb->dev);
296 local = iface->local;
297
298 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
299 kfree_skb(skb);
300 return NULL;
301 }
302
303 if (local->tkip_countermeasures &&
304 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
305 hdr = (struct hostap_ieee80211_hdr *) skb->data;
306 if (net_ratelimit()) {
307 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
308 "TX packet to " MACSTR "\n",
309 local->dev->name, MAC2STR(hdr->addr1));
310 }
311 kfree_skb(skb);
312 return NULL;
313 }
314
315 skb = skb_unshare(skb, GFP_ATOMIC);
316 if (skb == NULL)
317 return NULL;
318
319 if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
320 skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
321 pskb_expand_head(skb, crypt->ops->extra_prefix_len,
322 crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
323 kfree_skb(skb);
324 return NULL;
325 }
326
327 hdr = (struct hostap_ieee80211_hdr *) skb->data;
328 fc = le16_to_cpu(hdr->frame_control);
329 hdr_len = hostap_80211_get_hdrlen(fc);
330
331 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
332 * call both MSDU and MPDU encryption functions from here. */
333 atomic_inc(&crypt->refcnt);
334 res = 0;
335 if (crypt->ops->encrypt_msdu)
336 res = crypt->ops->encrypt_msdu(skb, hdr_len, crypt->priv);
337 if (res == 0 && crypt->ops->encrypt_mpdu)
338 res = crypt->ops->encrypt_mpdu(skb, hdr_len, crypt->priv);
339 atomic_dec(&crypt->refcnt);
340 if (res < 0) {
341 kfree_skb(skb);
342 return NULL;
343 }
344
345 return skb;
346}
347
348
349/* hard_start_xmit function for master radio interface wifi#.
350 * AP processing (TX rate control, power save buffering, etc.).
351 * Use hardware TX function to send the frame. */
352int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
353{
354 struct hostap_interface *iface;
355 local_info_t *local;
356 int ret = 1;
357 u16 fc;
358 struct hostap_tx_data tx;
359 ap_tx_ret tx_ret;
360 struct hostap_skb_tx_data *meta;
361 int no_encrypt = 0;
362 struct hostap_ieee80211_hdr *hdr;
363
364 iface = netdev_priv(dev);
365 local = iface->local;
366
367 tx.skb = skb;
368 tx.sta_ptr = NULL;
369
370 meta = (struct hostap_skb_tx_data *) skb->cb;
371 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
372 printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
373 "expected 0x%08x)\n",
374 dev->name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC);
375 ret = 0;
376 iface->stats.tx_dropped++;
377 goto fail;
378 }
379
380 if (local->host_encrypt) {
381 /* Set crypt to default algorithm and key; will be replaced in
382 * AP code if STA has own alg/key */
383 tx.crypt = local->crypt[local->tx_keyidx];
384 tx.host_encrypt = 1;
385 } else {
386 tx.crypt = NULL;
387 tx.host_encrypt = 0;
388 }
389
390 if (skb->len < 24) {
391 printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
392 "(len=%d)\n", dev->name, skb->len);
393 ret = 0;
394 iface->stats.tx_dropped++;
395 goto fail;
396 }
397
398 /* FIX (?):
399 * Wi-Fi 802.11b test plan suggests that AP should ignore power save
400 * bit in authentication and (re)association frames and assume tha
401 * STA remains awake for the response. */
402 tx_ret = hostap_handle_sta_tx(local, &tx);
403 skb = tx.skb;
404 meta = (struct hostap_skb_tx_data *) skb->cb;
405 hdr = (struct hostap_ieee80211_hdr *) skb->data;
406 fc = le16_to_cpu(hdr->frame_control);
407 switch (tx_ret) {
408 case AP_TX_CONTINUE:
409 break;
410 case AP_TX_CONTINUE_NOT_AUTHORIZED:
411 if (local->ieee_802_1x &&
412 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
413 meta->ethertype != ETH_P_PAE && !meta->wds) {
414 printk(KERN_DEBUG "%s: dropped frame to unauthorized "
415 "port (IEEE 802.1X): ethertype=0x%04x\n",
416 dev->name, meta->ethertype);
417 hostap_dump_tx_80211(dev->name, skb);
418
419 ret = 0; /* drop packet */
420 iface->stats.tx_dropped++;
421 goto fail;
422 }
423 break;
424 case AP_TX_DROP:
425 ret = 0; /* drop packet */
426 iface->stats.tx_dropped++;
427 goto fail;
428 case AP_TX_RETRY:
429 goto fail;
430 case AP_TX_BUFFERED:
431 /* do not free skb here, it will be freed when the
432 * buffered frame is sent/timed out */
433 ret = 0;
434 goto tx_exit;
435 }
436
437 /* Request TX callback if protocol version is 2 in 802.11 header;
438 * this version 2 is a special case used between hostapd and kernel
439 * driver */
440 if (((fc & WLAN_FC_PVER) == BIT(1)) &&
441 local->ap && local->ap->tx_callback_idx && meta->tx_cb_idx == 0) {
442 meta->tx_cb_idx = local->ap->tx_callback_idx;
443
444 /* remove special version from the frame header */
445 fc &= ~WLAN_FC_PVER;
446 hdr->frame_control = cpu_to_le16(fc);
447 }
448
449 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA) {
450 no_encrypt = 1;
451 tx.crypt = NULL;
452 }
453
454 if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt &&
455 !(fc & WLAN_FC_ISWEP)) {
456 no_encrypt = 1;
457 PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing "
458 "unencrypted EAPOL frame\n", dev->name);
459 tx.crypt = NULL; /* no encryption for IEEE 802.1X frames */
460 }
461
462 if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
463 tx.crypt = NULL;
464 else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) {
465 /* Add ISWEP flag both for firmware and host based encryption
466 */
467 fc |= WLAN_FC_ISWEP;
468 hdr->frame_control = cpu_to_le16(fc);
469 } else if (local->drop_unencrypted &&
470 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
471 meta->ethertype != ETH_P_PAE) {
472 if (net_ratelimit()) {
473 printk(KERN_DEBUG "%s: dropped unencrypted TX data "
474 "frame (drop_unencrypted=1)\n", dev->name);
475 }
476 iface->stats.tx_dropped++;
477 ret = 0;
478 goto fail;
479 }
480
481 if (tx.crypt) {
482 skb = hostap_tx_encrypt(skb, tx.crypt);
483 if (skb == NULL) {
484 printk(KERN_DEBUG "%s: TX - encryption failed\n",
485 dev->name);
486 ret = 0;
487 goto fail;
488 }
489 meta = (struct hostap_skb_tx_data *) skb->cb;
490 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
491 printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
492 "expected 0x%08x) after hostap_tx_encrypt\n",
493 dev->name, meta->magic,
494 HOSTAP_SKB_TX_DATA_MAGIC);
495 ret = 0;
496 iface->stats.tx_dropped++;
497 goto fail;
498 }
499 }
500
501 if (local->func->tx == NULL || local->func->tx(skb, dev)) {
502 ret = 0;
503 iface->stats.tx_dropped++;
504 } else {
505 ret = 0;
506 iface->stats.tx_packets++;
507 iface->stats.tx_bytes += skb->len;
508 }
509
510 fail:
511 if (!ret && skb)
512 dev_kfree_skb(skb);
513 tx_exit:
514 if (tx.sta_ptr)
515 hostap_handle_sta_release(tx.sta_ptr);
516 return ret;
517}
518
519
520EXPORT_SYMBOL(hostap_dump_tx_80211);
521EXPORT_SYMBOL(hostap_tx_encrypt);
522EXPORT_SYMBOL(hostap_master_start_xmit);
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
new file mode 100644
index 000000000000..b9684e3a568b
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -0,0 +1,3286 @@
1/*
2 * Intersil Prism2 driver with Host AP (software access point) support
3 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
4 * <jkmaline@cc.hut.fi>
5 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
6 *
7 * This file is to be included into hostap.c when S/W AP functionality is
8 * compiled.
9 *
10 * AP: FIX:
11 * - if unicast Class 2 (assoc,reassoc,disassoc) frame received from
12 * unauthenticated STA, send deauth. frame (8802.11: 5.5)
13 * - if unicast Class 3 (data with to/from DS,deauth,pspoll) frame received
14 * from authenticated, but unassoc STA, send disassoc frame (8802.11: 5.5)
15 * - if unicast Class 3 received from unauthenticated STA, send deauth. frame
16 * (8802.11: 5.5)
17 */
18
19static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL,
20 DEF_INTS };
21module_param_array(other_ap_policy, int, NULL, 0444);
22MODULE_PARM_DESC(other_ap_policy, "Other AP beacon monitoring policy (0-3)");
23
24static int ap_max_inactivity[MAX_PARM_DEVICES] = { AP_MAX_INACTIVITY_SEC,
25 DEF_INTS };
26module_param_array(ap_max_inactivity, int, NULL, 0444);
27MODULE_PARM_DESC(ap_max_inactivity, "AP timeout (in seconds) for station "
28 "inactivity");
29
30static int ap_bridge_packets[MAX_PARM_DEVICES] = { 1, DEF_INTS };
31module_param_array(ap_bridge_packets, int, NULL, 0444);
32MODULE_PARM_DESC(ap_bridge_packets, "Bridge packets directly between "
33 "stations");
34
35static int autom_ap_wds[MAX_PARM_DEVICES] = { 0, DEF_INTS };
36module_param_array(autom_ap_wds, int, NULL, 0444);
37MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs "
38 "automatically");
39
40
41static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta);
42static void hostap_event_expired_sta(struct net_device *dev,
43 struct sta_info *sta);
44static void handle_add_proc_queue(void *data);
45
46#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
47static void handle_wds_oper_queue(void *data);
48static void prism2_send_mgmt(struct net_device *dev,
49 int type, int subtype, char *body,
50 int body_len, u8 *addr, u16 tx_cb_idx);
51#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
52
53
54#ifndef PRISM2_NO_PROCFS_DEBUG
55static int ap_debug_proc_read(char *page, char **start, off_t off,
56 int count, int *eof, void *data)
57{
58 char *p = page;
59 struct ap_data *ap = (struct ap_data *) data;
60
61 if (off != 0) {
62 *eof = 1;
63 return 0;
64 }
65
66 p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
67 p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
68 p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ);
69 p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets);
70 p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack);
71 p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds);
72 p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs);
73 p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
74
75 return (p - page);
76}
77#endif /* PRISM2_NO_PROCFS_DEBUG */
78
79
80static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta)
81{
82 sta->hnext = ap->sta_hash[STA_HASH(sta->addr)];
83 ap->sta_hash[STA_HASH(sta->addr)] = sta;
84}
85
86static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
87{
88 struct sta_info *s;
89
90 s = ap->sta_hash[STA_HASH(sta->addr)];
91 if (s == NULL) return;
92 if (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) {
93 ap->sta_hash[STA_HASH(sta->addr)] = s->hnext;
94 return;
95 }
96
97 while (s->hnext != NULL && memcmp(s->hnext->addr, sta->addr, ETH_ALEN)
98 != 0)
99 s = s->hnext;
100 if (s->hnext != NULL)
101 s->hnext = s->hnext->hnext;
102 else
103 printk("AP: could not remove STA " MACSTR " from hash table\n",
104 MAC2STR(sta->addr));
105}
106
107static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
108{
109 if (sta->ap && sta->local)
110 hostap_event_expired_sta(sta->local->dev, sta);
111
112 if (ap->proc != NULL) {
113 char name[20];
114 sprintf(name, MACSTR, MAC2STR(sta->addr));
115 remove_proc_entry(name, ap->proc);
116 }
117
118 if (sta->crypt) {
119 sta->crypt->ops->deinit(sta->crypt->priv);
120 kfree(sta->crypt);
121 sta->crypt = NULL;
122 }
123
124 skb_queue_purge(&sta->tx_buf);
125
126 ap->num_sta--;
127#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
128 if (sta->aid > 0)
129 ap->sta_aid[sta->aid - 1] = NULL;
130
131 if (!sta->ap && sta->u.sta.challenge)
132 kfree(sta->u.sta.challenge);
133 del_timer(&sta->timer);
134#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
135
136 kfree(sta);
137}
138
139
140static void hostap_set_tim(local_info_t *local, int aid, int set)
141{
142 if (local->func->set_tim)
143 local->func->set_tim(local->dev, aid, set);
144}
145
146
147static void hostap_event_new_sta(struct net_device *dev, struct sta_info *sta)
148{
149 union iwreq_data wrqu;
150 memset(&wrqu, 0, sizeof(wrqu));
151 memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
152 wrqu.addr.sa_family = ARPHRD_ETHER;
153 wireless_send_event(dev, IWEVREGISTERED, &wrqu, NULL);
154}
155
156
157static void hostap_event_expired_sta(struct net_device *dev,
158 struct sta_info *sta)
159{
160 union iwreq_data wrqu;
161 memset(&wrqu, 0, sizeof(wrqu));
162 memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
163 wrqu.addr.sa_family = ARPHRD_ETHER;
164 wireless_send_event(dev, IWEVEXPIRED, &wrqu, NULL);
165}
166
167
168#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
169
170static void ap_handle_timer(unsigned long data)
171{
172 struct sta_info *sta = (struct sta_info *) data;
173 local_info_t *local;
174 struct ap_data *ap;
175 unsigned long next_time = 0;
176 int was_assoc;
177
178 if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) {
179 PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n");
180 return;
181 }
182
183 local = sta->local;
184 ap = local->ap;
185 was_assoc = sta->flags & WLAN_STA_ASSOC;
186
187 if (atomic_read(&sta->users) != 0)
188 next_time = jiffies + HZ;
189 else if ((sta->flags & WLAN_STA_PERM) && !(sta->flags & WLAN_STA_AUTH))
190 next_time = jiffies + ap->max_inactivity;
191
192 if (time_before(jiffies, sta->last_rx + ap->max_inactivity)) {
193 /* station activity detected; reset timeout state */
194 sta->timeout_next = STA_NULLFUNC;
195 next_time = sta->last_rx + ap->max_inactivity;
196 } else if (sta->timeout_next == STA_DISASSOC &&
197 !(sta->flags & WLAN_STA_PENDING_POLL)) {
198 /* STA ACKed data nullfunc frame poll */
199 sta->timeout_next = STA_NULLFUNC;
200 next_time = jiffies + ap->max_inactivity;
201 }
202
203 if (next_time) {
204 sta->timer.expires = next_time;
205 add_timer(&sta->timer);
206 return;
207 }
208
209 if (sta->ap)
210 sta->timeout_next = STA_DEAUTH;
211
212 if (sta->timeout_next == STA_DEAUTH && !(sta->flags & WLAN_STA_PERM)) {
213 spin_lock(&ap->sta_table_lock);
214 ap_sta_hash_del(ap, sta);
215 list_del(&sta->list);
216 spin_unlock(&ap->sta_table_lock);
217 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
218 } else if (sta->timeout_next == STA_DISASSOC)
219 sta->flags &= ~WLAN_STA_ASSOC;
220
221 if (was_assoc && !(sta->flags & WLAN_STA_ASSOC) && !sta->ap)
222 hostap_event_expired_sta(local->dev, sta);
223
224 if (sta->timeout_next == STA_DEAUTH && sta->aid > 0 &&
225 !skb_queue_empty(&sta->tx_buf)) {
226 hostap_set_tim(local, sta->aid, 0);
227 sta->flags &= ~WLAN_STA_TIM;
228 }
229
230 if (sta->ap) {
231 if (ap->autom_ap_wds) {
232 PDEBUG(DEBUG_AP, "%s: removing automatic WDS "
233 "connection to AP " MACSTR "\n",
234 local->dev->name, MAC2STR(sta->addr));
235 hostap_wds_link_oper(local, sta->addr, WDS_DEL);
236 }
237 } else if (sta->timeout_next == STA_NULLFUNC) {
238 /* send data frame to poll STA and check whether this frame
239 * is ACKed */
240 /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but
241 * it is apparently not retried so TX Exc events are not
242 * received for it */
243 sta->flags |= WLAN_STA_PENDING_POLL;
244 prism2_send_mgmt(local->dev, WLAN_FC_TYPE_DATA,
245 WLAN_FC_STYPE_DATA, NULL, 0,
246 sta->addr, ap->tx_callback_poll);
247 } else {
248 int deauth = sta->timeout_next == STA_DEAUTH;
249 u16 resp;
250 PDEBUG(DEBUG_AP, "%s: sending %s info to STA " MACSTR
251 "(last=%lu, jiffies=%lu)\n",
252 local->dev->name,
253 deauth ? "deauthentication" : "disassociation",
254 MAC2STR(sta->addr), sta->last_rx, jiffies);
255
256 resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID :
257 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
258 prism2_send_mgmt(local->dev, WLAN_FC_TYPE_MGMT,
259 (deauth ? WLAN_FC_STYPE_DEAUTH :
260 WLAN_FC_STYPE_DISASSOC),
261 (char *) &resp, 2, sta->addr, 0);
262 }
263
264 if (sta->timeout_next == STA_DEAUTH) {
265 if (sta->flags & WLAN_STA_PERM) {
266 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " would have been "
267 "removed, but it has 'perm' flag\n",
268 local->dev->name, MAC2STR(sta->addr));
269 } else
270 ap_free_sta(ap, sta);
271 return;
272 }
273
274 if (sta->timeout_next == STA_NULLFUNC) {
275 sta->timeout_next = STA_DISASSOC;
276 sta->timer.expires = jiffies + AP_DISASSOC_DELAY;
277 } else {
278 sta->timeout_next = STA_DEAUTH;
279 sta->timer.expires = jiffies + AP_DEAUTH_DELAY;
280 }
281
282 add_timer(&sta->timer);
283}
284
285
286void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
287 int resend)
288{
289 u8 addr[ETH_ALEN];
290 u16 resp;
291 int i;
292
293 PDEBUG(DEBUG_AP, "%s: Deauthenticate all stations\n", dev->name);
294 memset(addr, 0xff, ETH_ALEN);
295
296 resp = __constant_cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
297
298 /* deauth message sent; try to resend it few times; the message is
299 * broadcast, so it may be delayed until next DTIM; there is not much
300 * else we can do at this point since the driver is going to be shut
301 * down */
302 for (i = 0; i < 5; i++) {
303 prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH,
304 (char *) &resp, 2, addr, 0);
305
306 if (!resend || ap->num_sta <= 0)
307 return;
308
309 mdelay(50);
310 }
311}
312
313
314static int ap_control_proc_read(char *page, char **start, off_t off,
315 int count, int *eof, void *data)
316{
317 char *p = page;
318 struct ap_data *ap = (struct ap_data *) data;
319 char *policy_txt;
320 struct list_head *ptr;
321 struct mac_entry *entry;
322
323 if (off != 0) {
324 *eof = 1;
325 return 0;
326 }
327
328 switch (ap->mac_restrictions.policy) {
329 case MAC_POLICY_OPEN:
330 policy_txt = "open";
331 break;
332 case MAC_POLICY_ALLOW:
333 policy_txt = "allow";
334 break;
335 case MAC_POLICY_DENY:
336 policy_txt = "deny";
337 break;
338 default:
339 policy_txt = "unknown";
340 break;
341 };
342 p += sprintf(p, "MAC policy: %s\n", policy_txt);
343 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
344 p += sprintf(p, "MAC list:\n");
345 spin_lock_bh(&ap->mac_restrictions.lock);
346 for (ptr = ap->mac_restrictions.mac_list.next;
347 ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) {
348 if (p - page > PAGE_SIZE - 80) {
349 p += sprintf(p, "All entries did not fit one page.\n");
350 break;
351 }
352
353 entry = list_entry(ptr, struct mac_entry, list);
354 p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
355 }
356 spin_unlock_bh(&ap->mac_restrictions.lock);
357
358 return (p - page);
359}
360
361
362static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
363 u8 *mac)
364{
365 struct mac_entry *entry;
366
367 entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
368 if (entry == NULL)
369 return -1;
370
371 memcpy(entry->addr, mac, ETH_ALEN);
372
373 spin_lock_bh(&mac_restrictions->lock);
374 list_add_tail(&entry->list, &mac_restrictions->mac_list);
375 mac_restrictions->entries++;
376 spin_unlock_bh(&mac_restrictions->lock);
377
378 return 0;
379}
380
381
382static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
383 u8 *mac)
384{
385 struct list_head *ptr;
386 struct mac_entry *entry;
387
388 spin_lock_bh(&mac_restrictions->lock);
389 for (ptr = mac_restrictions->mac_list.next;
390 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
391 entry = list_entry(ptr, struct mac_entry, list);
392
393 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
394 list_del(ptr);
395 kfree(entry);
396 mac_restrictions->entries--;
397 spin_unlock_bh(&mac_restrictions->lock);
398 return 0;
399 }
400 }
401 spin_unlock_bh(&mac_restrictions->lock);
402 return -1;
403}
404
405
406static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
407 u8 *mac)
408{
409 struct list_head *ptr;
410 struct mac_entry *entry;
411 int found = 0;
412
413 if (mac_restrictions->policy == MAC_POLICY_OPEN)
414 return 0;
415
416 spin_lock_bh(&mac_restrictions->lock);
417 for (ptr = mac_restrictions->mac_list.next;
418 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
419 entry = list_entry(ptr, struct mac_entry, list);
420
421 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
422 found = 1;
423 break;
424 }
425 }
426 spin_unlock_bh(&mac_restrictions->lock);
427
428 if (mac_restrictions->policy == MAC_POLICY_ALLOW)
429 return !found;
430 else
431 return found;
432}
433
434
435static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
436{
437 struct list_head *ptr, *n;
438 struct mac_entry *entry;
439
440 if (mac_restrictions->entries == 0)
441 return;
442
443 spin_lock_bh(&mac_restrictions->lock);
444 for (ptr = mac_restrictions->mac_list.next, n = ptr->next;
445 ptr != &mac_restrictions->mac_list;
446 ptr = n, n = ptr->next) {
447 entry = list_entry(ptr, struct mac_entry, list);
448 list_del(ptr);
449 kfree(entry);
450 }
451 mac_restrictions->entries = 0;
452 spin_unlock_bh(&mac_restrictions->lock);
453}
454
455
456static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
457 u8 *mac)
458{
459 struct sta_info *sta;
460 u16 resp;
461
462 spin_lock_bh(&ap->sta_table_lock);
463 sta = ap_get_sta(ap, mac);
464 if (sta) {
465 ap_sta_hash_del(ap, sta);
466 list_del(&sta->list);
467 }
468 spin_unlock_bh(&ap->sta_table_lock);
469
470 if (!sta)
471 return -EINVAL;
472
473 resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
474 prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH,
475 (char *) &resp, 2, sta->addr, 0);
476
477 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
478 hostap_event_expired_sta(dev, sta);
479
480 ap_free_sta(ap, sta);
481
482 return 0;
483}
484
485#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
486
487
488static void ap_control_kickall(struct ap_data *ap)
489{
490 struct list_head *ptr, *n;
491 struct sta_info *sta;
492
493 spin_lock_bh(&ap->sta_table_lock);
494 for (ptr = ap->sta_list.next, n = ptr->next; ptr != &ap->sta_list;
495 ptr = n, n = ptr->next) {
496 sta = list_entry(ptr, struct sta_info, list);
497 ap_sta_hash_del(ap, sta);
498 list_del(&sta->list);
499 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
500 hostap_event_expired_sta(sta->local->dev, sta);
501 ap_free_sta(ap, sta);
502 }
503 spin_unlock_bh(&ap->sta_table_lock);
504}
505
506
507#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
508
509#define PROC_LIMIT (PAGE_SIZE - 80)
510
511static int prism2_ap_proc_read(char *page, char **start, off_t off,
512 int count, int *eof, void *data)
513{
514 char *p = page;
515 struct ap_data *ap = (struct ap_data *) data;
516 struct list_head *ptr;
517 int i;
518
519 if (off > PROC_LIMIT) {
520 *eof = 1;
521 return 0;
522 }
523
524 p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
525 spin_lock_bh(&ap->sta_table_lock);
526 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
527 struct sta_info *sta = (struct sta_info *) ptr;
528
529 if (!sta->ap)
530 continue;
531
532 p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(sta->addr),
533 sta->u.ap.channel, sta->last_rx_signal,
534 sta->last_rx_silence, sta->last_rx_rate);
535 for (i = 0; i < sta->u.ap.ssid_len; i++)
536 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
537 sta->u.ap.ssid[i] < 127) ?
538 "%c" : "<%02x>"),
539 sta->u.ap.ssid[i]);
540 p += sprintf(p, "'");
541 if (sta->capability & WLAN_CAPABILITY_ESS)
542 p += sprintf(p, " [ESS]");
543 if (sta->capability & WLAN_CAPABILITY_IBSS)
544 p += sprintf(p, " [IBSS]");
545 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
546 p += sprintf(p, " [WEP]");
547 p += sprintf(p, "\n");
548
549 if ((p - page) > PROC_LIMIT) {
550 printk(KERN_DEBUG "hostap: ap proc did not fit\n");
551 break;
552 }
553 }
554 spin_unlock_bh(&ap->sta_table_lock);
555
556 if ((p - page) <= off) {
557 *eof = 1;
558 return 0;
559 }
560
561 *start = page + off;
562
563 return (p - page - off);
564}
565#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
566
567
568void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
569{
570 if (!ap)
571 return;
572
573 if (sta_fw_ver == PRISM2_FW_VER(0,8,0)) {
574 PDEBUG(DEBUG_AP, "Using data::nullfunc ACK workaround - "
575 "firmware upgrade recommended\n");
576 ap->nullfunc_ack = 1;
577 } else
578 ap->nullfunc_ack = 0;
579
580 if (sta_fw_ver == PRISM2_FW_VER(1,4,2)) {
581 printk(KERN_WARNING "%s: Warning: secondary station firmware "
582 "version 1.4.2 does not seem to work in Host AP mode\n",
583 ap->local->dev->name);
584 }
585}
586
587
588/* Called only as a tasklet (software IRQ) */
589static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
590{
591 struct ap_data *ap = data;
592 u16 fc;
593 struct hostap_ieee80211_hdr *hdr;
594
595 if (!ap->local->hostapd || !ap->local->apdev) {
596 dev_kfree_skb(skb);
597 return;
598 }
599
600 hdr = (struct hostap_ieee80211_hdr *) skb->data;
601 fc = le16_to_cpu(hdr->frame_control);
602
603 /* Pass the TX callback frame to the hostapd; use 802.11 header version
604 * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
605
606 fc &= ~WLAN_FC_PVER;
607 fc |= ok ? BIT(1) : BIT(0);
608 hdr->frame_control = cpu_to_le16(fc);
609
610 skb->dev = ap->local->apdev;
611 skb_pull(skb, hostap_80211_get_hdrlen(fc));
612 skb->pkt_type = PACKET_OTHERHOST;
613 skb->protocol = __constant_htons(ETH_P_802_2);
614 memset(skb->cb, 0, sizeof(skb->cb));
615 netif_rx(skb);
616}
617
618
619#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
620/* Called only as a tasklet (software IRQ) */
621static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
622{
623 struct ap_data *ap = data;
624 struct net_device *dev = ap->local->dev;
625 struct hostap_ieee80211_hdr *hdr;
626 u16 fc, *pos, auth_alg, auth_transaction, status;
627 struct sta_info *sta = NULL;
628 char *txt = NULL;
629
630 if (ap->local->hostapd) {
631 dev_kfree_skb(skb);
632 return;
633 }
634
635 hdr = (struct hostap_ieee80211_hdr *) skb->data;
636 fc = le16_to_cpu(hdr->frame_control);
637 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
638 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_AUTH ||
639 skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
640 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
641 "frame\n", dev->name);
642 dev_kfree_skb(skb);
643 return;
644 }
645
646 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
647 auth_alg = le16_to_cpu(*pos++);
648 auth_transaction = le16_to_cpu(*pos++);
649 status = le16_to_cpu(*pos++);
650
651 if (!ok) {
652 txt = "frame was not ACKed";
653 goto done;
654 }
655
656 spin_lock(&ap->sta_table_lock);
657 sta = ap_get_sta(ap, hdr->addr1);
658 if (sta)
659 atomic_inc(&sta->users);
660 spin_unlock(&ap->sta_table_lock);
661
662 if (!sta) {
663 txt = "STA not found";
664 goto done;
665 }
666
667 if (status == WLAN_STATUS_SUCCESS &&
668 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
669 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
670 txt = "STA authenticated";
671 sta->flags |= WLAN_STA_AUTH;
672 sta->last_auth = jiffies;
673 } else if (status != WLAN_STATUS_SUCCESS)
674 txt = "authentication failed";
675
676 done:
677 if (sta)
678 atomic_dec(&sta->users);
679 if (txt) {
680 PDEBUG(DEBUG_AP, "%s: " MACSTR " auth_cb - alg=%d trans#=%d "
681 "status=%d - %s\n",
682 dev->name, MAC2STR(hdr->addr1), auth_alg,
683 auth_transaction, status, txt);
684 }
685 dev_kfree_skb(skb);
686}
687
688
689/* Called only as a tasklet (software IRQ) */
690static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
691{
692 struct ap_data *ap = data;
693 struct net_device *dev = ap->local->dev;
694 struct hostap_ieee80211_hdr *hdr;
695 u16 fc, *pos, status;
696 struct sta_info *sta = NULL;
697 char *txt = NULL;
698
699 if (ap->local->hostapd) {
700 dev_kfree_skb(skb);
701 return;
702 }
703
704 hdr = (struct hostap_ieee80211_hdr *) skb->data;
705 fc = le16_to_cpu(hdr->frame_control);
706 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
707 (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ASSOC_RESP &&
708 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_REASSOC_RESP) ||
709 skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
710 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
711 "frame\n", dev->name);
712 dev_kfree_skb(skb);
713 return;
714 }
715
716 if (!ok) {
717 txt = "frame was not ACKed";
718 goto done;
719 }
720
721 spin_lock(&ap->sta_table_lock);
722 sta = ap_get_sta(ap, hdr->addr1);
723 if (sta)
724 atomic_inc(&sta->users);
725 spin_unlock(&ap->sta_table_lock);
726
727 if (!sta) {
728 txt = "STA not found";
729 goto done;
730 }
731
732 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
733 pos++;
734 status = le16_to_cpu(*pos++);
735 if (status == WLAN_STATUS_SUCCESS) {
736 if (!(sta->flags & WLAN_STA_ASSOC))
737 hostap_event_new_sta(dev, sta);
738 txt = "STA associated";
739 sta->flags |= WLAN_STA_ASSOC;
740 sta->last_assoc = jiffies;
741 } else
742 txt = "association failed";
743
744 done:
745 if (sta)
746 atomic_dec(&sta->users);
747 if (txt) {
748 PDEBUG(DEBUG_AP, "%s: " MACSTR " assoc_cb - %s\n",
749 dev->name, MAC2STR(hdr->addr1), txt);
750 }
751 dev_kfree_skb(skb);
752}
753
754/* Called only as a tasklet (software IRQ); TX callback for poll frames used
755 * in verifying whether the STA is still present. */
756static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
757{
758 struct ap_data *ap = data;
759 struct hostap_ieee80211_hdr *hdr;
760 struct sta_info *sta;
761
762 if (skb->len < 24)
763 goto fail;
764 hdr = (struct hostap_ieee80211_hdr *) skb->data;
765 if (ok) {
766 spin_lock(&ap->sta_table_lock);
767 sta = ap_get_sta(ap, hdr->addr1);
768 if (sta)
769 sta->flags &= ~WLAN_STA_PENDING_POLL;
770 spin_unlock(&ap->sta_table_lock);
771 } else {
772 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " did not ACK activity "
773 "poll frame\n", ap->local->dev->name,
774 MAC2STR(hdr->addr1));
775 }
776
777 fail:
778 dev_kfree_skb(skb);
779}
780#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
781
782
783void hostap_init_data(local_info_t *local)
784{
785 struct ap_data *ap = local->ap;
786
787 if (ap == NULL) {
788 printk(KERN_WARNING "hostap_init_data: ap == NULL\n");
789 return;
790 }
791 memset(ap, 0, sizeof(struct ap_data));
792 ap->local = local;
793
794 ap->ap_policy = GET_INT_PARM(other_ap_policy, local->card_idx);
795 ap->bridge_packets = GET_INT_PARM(ap_bridge_packets, local->card_idx);
796 ap->max_inactivity =
797 GET_INT_PARM(ap_max_inactivity, local->card_idx) * HZ;
798 ap->autom_ap_wds = GET_INT_PARM(autom_ap_wds, local->card_idx);
799
800 spin_lock_init(&ap->sta_table_lock);
801 INIT_LIST_HEAD(&ap->sta_list);
802
803 /* Initialize task queue structure for AP management */
804 INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap);
805
806 ap->tx_callback_idx =
807 hostap_tx_callback_register(local, hostap_ap_tx_cb, ap);
808 if (ap->tx_callback_idx == 0)
809 printk(KERN_WARNING "%s: failed to register TX callback for "
810 "AP\n", local->dev->name);
811#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
812 INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local);
813
814 ap->tx_callback_auth =
815 hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap);
816 ap->tx_callback_assoc =
817 hostap_tx_callback_register(local, hostap_ap_tx_cb_assoc, ap);
818 ap->tx_callback_poll =
819 hostap_tx_callback_register(local, hostap_ap_tx_cb_poll, ap);
820 if (ap->tx_callback_auth == 0 || ap->tx_callback_assoc == 0 ||
821 ap->tx_callback_poll == 0)
822 printk(KERN_WARNING "%s: failed to register TX callback for "
823 "AP\n", local->dev->name);
824
825 spin_lock_init(&ap->mac_restrictions.lock);
826 INIT_LIST_HEAD(&ap->mac_restrictions.mac_list);
827#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
828
829 ap->initialized = 1;
830}
831
832
833void hostap_init_ap_proc(local_info_t *local)
834{
835 struct ap_data *ap = local->ap;
836
837 ap->proc = local->proc;
838 if (ap->proc == NULL)
839 return;
840
841#ifndef PRISM2_NO_PROCFS_DEBUG
842 create_proc_read_entry("ap_debug", 0, ap->proc,
843 ap_debug_proc_read, ap);
844#endif /* PRISM2_NO_PROCFS_DEBUG */
845
846#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
847 create_proc_read_entry("ap_control", 0, ap->proc,
848 ap_control_proc_read, ap);
849 create_proc_read_entry("ap", 0, ap->proc,
850 prism2_ap_proc_read, ap);
851#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
852
853}
854
855
856void hostap_free_data(struct ap_data *ap)
857{
858 struct list_head *n, *ptr;
859
860 if (ap == NULL || !ap->initialized) {
861 printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
862 "initialized - skip resource freeing\n");
863 return;
864 }
865
866#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
867 if (ap->crypt)
868 ap->crypt->deinit(ap->crypt_priv);
869 ap->crypt = ap->crypt_priv = NULL;
870#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
871
872 list_for_each_safe(ptr, n, &ap->sta_list) {
873 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
874 ap_sta_hash_del(ap, sta);
875 list_del(&sta->list);
876 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
877 hostap_event_expired_sta(sta->local->dev, sta);
878 ap_free_sta(ap, sta);
879 }
880
881#ifndef PRISM2_NO_PROCFS_DEBUG
882 if (ap->proc != NULL) {
883 remove_proc_entry("ap_debug", ap->proc);
884 }
885#endif /* PRISM2_NO_PROCFS_DEBUG */
886
887#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
888 if (ap->proc != NULL) {
889 remove_proc_entry("ap", ap->proc);
890 remove_proc_entry("ap_control", ap->proc);
891 }
892 ap_control_flush_macs(&ap->mac_restrictions);
893#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
894
895 ap->initialized = 0;
896}
897
898
899/* caller should have mutex for AP STA list handling */
900static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
901{
902 struct sta_info *s;
903
904 s = ap->sta_hash[STA_HASH(sta)];
905 while (s != NULL && memcmp(s->addr, sta, ETH_ALEN) != 0)
906 s = s->hnext;
907 return s;
908}
909
910
911#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
912
913/* Called from timer handler and from scheduled AP queue handlers */
914static void prism2_send_mgmt(struct net_device *dev,
915 int type, int subtype, char *body,
916 int body_len, u8 *addr, u16 tx_cb_idx)
917{
918 struct hostap_interface *iface;
919 local_info_t *local;
920 struct hostap_ieee80211_hdr *hdr;
921 u16 fc;
922 struct sk_buff *skb;
923 struct hostap_skb_tx_data *meta;
924 int hdrlen;
925
926 iface = netdev_priv(dev);
927 local = iface->local;
928 dev = local->dev; /* always use master radio device */
929 iface = netdev_priv(dev);
930
931 if (!(dev->flags & IFF_UP)) {
932 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt - device is not UP - "
933 "cannot send frame\n", dev->name);
934 return;
935 }
936
937 skb = dev_alloc_skb(sizeof(*hdr) + body_len);
938 if (skb == NULL) {
939 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt failed to allocate "
940 "skb\n", dev->name);
941 return;
942 }
943
944 fc = (type << 2) | (subtype << 4);
945 hdrlen = hostap_80211_get_hdrlen(fc);
946 hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, hdrlen);
947 if (body)
948 memcpy(skb_put(skb, body_len), body, body_len);
949
950 memset(hdr, 0, hdrlen);
951
952 /* FIX: ctrl::ack sending used special HFA384X_TX_CTRL_802_11
953 * tx_control instead of using local->tx_control */
954
955
956 memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
957 if (type == WLAN_FC_TYPE_DATA) {
958 fc |= WLAN_FC_FROMDS;
959 memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
960 memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
961 } else if (type == WLAN_FC_TYPE_CTRL) {
962 /* control:ACK does not have addr2 or addr3 */
963 memset(hdr->addr2, 0, ETH_ALEN);
964 memset(hdr->addr3, 0, ETH_ALEN);
965 } else {
966 memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* SA */
967 memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
968 }
969
970 hdr->frame_control = cpu_to_le16(fc);
971
972 meta = (struct hostap_skb_tx_data *) skb->cb;
973 memset(meta, 0, sizeof(*meta));
974 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
975 meta->iface = iface;
976 meta->tx_cb_idx = tx_cb_idx;
977
978 skb->dev = dev;
979 skb->mac.raw = skb->nh.raw = skb->data;
980 dev_queue_xmit(skb);
981}
982#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
983
984
985static int prism2_sta_proc_read(char *page, char **start, off_t off,
986 int count, int *eof, void *data)
987{
988 char *p = page;
989 struct sta_info *sta = (struct sta_info *) data;
990 int i;
991
992 /* FIX: possible race condition.. the STA data could have just expired,
993 * but proc entry was still here so that the read could have started;
994 * some locking should be done here.. */
995
996 if (off != 0) {
997 *eof = 1;
998 return 0;
999 }
1000
1001 p += sprintf(p, "%s=" MACSTR "\nusers=%d\naid=%d\n"
1002 "flags=0x%04x%s%s%s%s%s%s%s\n"
1003 "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
1004 sta->ap ? "AP" : "STA",
1005 MAC2STR(sta->addr), atomic_read(&sta->users), sta->aid,
1006 sta->flags,
1007 sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
1008 sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
1009 sta->flags & WLAN_STA_PS ? " PS" : "",
1010 sta->flags & WLAN_STA_TIM ? " TIM" : "",
1011 sta->flags & WLAN_STA_PERM ? " PERM" : "",
1012 sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
1013 sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
1014 sta->capability, sta->listen_interval);
1015 /* supported_rates: 500 kbit/s units with msb ignored */
1016 for (i = 0; i < sizeof(sta->supported_rates); i++)
1017 if (sta->supported_rates[i] != 0)
1018 p += sprintf(p, "%d%sMbps ",
1019 (sta->supported_rates[i] & 0x7f) / 2,
1020 sta->supported_rates[i] & 1 ? ".5" : "");
1021 p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
1022 "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
1023 "tx_packets=%lu\n"
1024 "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
1025 "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
1026 "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
1027 "tx[11M]=%d\n"
1028 "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
1029 jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
1030 sta->last_tx,
1031 sta->rx_packets, sta->tx_packets, sta->rx_bytes,
1032 sta->tx_bytes, skb_queue_len(&sta->tx_buf),
1033 sta->last_rx_silence,
1034 sta->last_rx_signal, sta->last_rx_rate / 10,
1035 sta->last_rx_rate % 10 ? ".5" : "",
1036 sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
1037 sta->tx_count[2], sta->tx_count[3], sta->rx_count[0],
1038 sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
1039 if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats)
1040 p = sta->crypt->ops->print_stats(p, sta->crypt->priv);
1041#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1042 if (sta->ap) {
1043 if (sta->u.ap.channel >= 0)
1044 p += sprintf(p, "channel=%d\n", sta->u.ap.channel);
1045 p += sprintf(p, "ssid=");
1046 for (i = 0; i < sta->u.ap.ssid_len; i++)
1047 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
1048 sta->u.ap.ssid[i] < 127) ?
1049 "%c" : "<%02x>"),
1050 sta->u.ap.ssid[i]);
1051 p += sprintf(p, "\n");
1052 }
1053#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1054
1055 return (p - page);
1056}
1057
1058
1059static void handle_add_proc_queue(void *data)
1060{
1061 struct ap_data *ap = (struct ap_data *) data;
1062 struct sta_info *sta;
1063 char name[20];
1064 struct add_sta_proc_data *entry, *prev;
1065
1066 entry = ap->add_sta_proc_entries;
1067 ap->add_sta_proc_entries = NULL;
1068
1069 while (entry) {
1070 spin_lock_bh(&ap->sta_table_lock);
1071 sta = ap_get_sta(ap, entry->addr);
1072 if (sta)
1073 atomic_inc(&sta->users);
1074 spin_unlock_bh(&ap->sta_table_lock);
1075
1076 if (sta) {
1077 sprintf(name, MACSTR, MAC2STR(sta->addr));
1078 sta->proc = create_proc_read_entry(
1079 name, 0, ap->proc,
1080 prism2_sta_proc_read, sta);
1081
1082 atomic_dec(&sta->users);
1083 }
1084
1085 prev = entry;
1086 entry = entry->next;
1087 kfree(prev);
1088 }
1089}
1090
1091
1092static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
1093{
1094 struct sta_info *sta;
1095
1096 sta = (struct sta_info *)
1097 kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
1098 if (sta == NULL) {
1099 PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
1100 return NULL;
1101 }
1102
1103 /* initialize STA info data */
1104 memset(sta, 0, sizeof(struct sta_info));
1105 sta->local = ap->local;
1106 skb_queue_head_init(&sta->tx_buf);
1107 memcpy(sta->addr, addr, ETH_ALEN);
1108
1109 atomic_inc(&sta->users);
1110 spin_lock_bh(&ap->sta_table_lock);
1111 list_add(&sta->list, &ap->sta_list);
1112 ap->num_sta++;
1113 ap_sta_hash_add(ap, sta);
1114 spin_unlock_bh(&ap->sta_table_lock);
1115
1116 if (ap->proc) {
1117 struct add_sta_proc_data *entry;
1118 /* schedule a non-interrupt context process to add a procfs
1119 * entry for the STA since procfs code use GFP_KERNEL */
1120 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
1121 if (entry) {
1122 memcpy(entry->addr, sta->addr, ETH_ALEN);
1123 entry->next = ap->add_sta_proc_entries;
1124 ap->add_sta_proc_entries = entry;
1125 schedule_work(&ap->add_sta_proc_queue);
1126 } else
1127 printk(KERN_DEBUG "Failed to add STA proc data\n");
1128 }
1129
1130#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1131 init_timer(&sta->timer);
1132 sta->timer.expires = jiffies + ap->max_inactivity;
1133 sta->timer.data = (unsigned long) sta;
1134 sta->timer.function = ap_handle_timer;
1135 if (!ap->local->hostapd)
1136 add_timer(&sta->timer);
1137#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1138
1139 return sta;
1140}
1141
1142
1143static int ap_tx_rate_ok(int rateidx, struct sta_info *sta,
1144 local_info_t *local)
1145{
1146 if (rateidx > sta->tx_max_rate ||
1147 !(sta->tx_supp_rates & (1 << rateidx)))
1148 return 0;
1149
1150 if (local->tx_rate_control != 0 &&
1151 !(local->tx_rate_control & (1 << rateidx)))
1152 return 0;
1153
1154 return 1;
1155}
1156
1157
1158static void prism2_check_tx_rates(struct sta_info *sta)
1159{
1160 int i;
1161
1162 sta->tx_supp_rates = 0;
1163 for (i = 0; i < sizeof(sta->supported_rates); i++) {
1164 if ((sta->supported_rates[i] & 0x7f) == 2)
1165 sta->tx_supp_rates |= WLAN_RATE_1M;
1166 if ((sta->supported_rates[i] & 0x7f) == 4)
1167 sta->tx_supp_rates |= WLAN_RATE_2M;
1168 if ((sta->supported_rates[i] & 0x7f) == 11)
1169 sta->tx_supp_rates |= WLAN_RATE_5M5;
1170 if ((sta->supported_rates[i] & 0x7f) == 22)
1171 sta->tx_supp_rates |= WLAN_RATE_11M;
1172 }
1173 sta->tx_max_rate = sta->tx_rate = sta->tx_rate_idx = 0;
1174 if (sta->tx_supp_rates & WLAN_RATE_1M) {
1175 sta->tx_max_rate = 0;
1176 if (ap_tx_rate_ok(0, sta, sta->local)) {
1177 sta->tx_rate = 10;
1178 sta->tx_rate_idx = 0;
1179 }
1180 }
1181 if (sta->tx_supp_rates & WLAN_RATE_2M) {
1182 sta->tx_max_rate = 1;
1183 if (ap_tx_rate_ok(1, sta, sta->local)) {
1184 sta->tx_rate = 20;
1185 sta->tx_rate_idx = 1;
1186 }
1187 }
1188 if (sta->tx_supp_rates & WLAN_RATE_5M5) {
1189 sta->tx_max_rate = 2;
1190 if (ap_tx_rate_ok(2, sta, sta->local)) {
1191 sta->tx_rate = 55;
1192 sta->tx_rate_idx = 2;
1193 }
1194 }
1195 if (sta->tx_supp_rates & WLAN_RATE_11M) {
1196 sta->tx_max_rate = 3;
1197 if (ap_tx_rate_ok(3, sta, sta->local)) {
1198 sta->tx_rate = 110;
1199 sta->tx_rate_idx = 3;
1200 }
1201 }
1202}
1203
1204
1205#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1206
1207static void ap_crypt_init(struct ap_data *ap)
1208{
1209 ap->crypt = hostap_get_crypto_ops("WEP");
1210
1211 if (ap->crypt) {
1212 if (ap->crypt->init) {
1213 ap->crypt_priv = ap->crypt->init(0);
1214 if (ap->crypt_priv == NULL)
1215 ap->crypt = NULL;
1216 else {
1217 u8 key[WEP_KEY_LEN];
1218 get_random_bytes(key, WEP_KEY_LEN);
1219 ap->crypt->set_key(key, WEP_KEY_LEN, NULL,
1220 ap->crypt_priv);
1221 }
1222 }
1223 }
1224
1225 if (ap->crypt == NULL) {
1226 printk(KERN_WARNING "AP could not initialize WEP: load module "
1227 "hostap_crypt_wep.o\n");
1228 }
1229}
1230
1231
1232/* Generate challenge data for shared key authentication. IEEE 802.11 specifies
1233 * that WEP algorithm is used for generating challange. This should be unique,
1234 * but otherwise there is not really need for randomness etc. Initialize WEP
1235 * with pseudo random key and then use increasing IV to get unique challenge
1236 * streams.
1237 *
1238 * Called only as a scheduled task for pending AP frames.
1239 */
1240static char * ap_auth_make_challenge(struct ap_data *ap)
1241{
1242 char *tmpbuf;
1243 struct sk_buff *skb;
1244
1245 if (ap->crypt == NULL) {
1246 ap_crypt_init(ap);
1247 if (ap->crypt == NULL)
1248 return NULL;
1249 }
1250
1251 tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
1252 if (tmpbuf == NULL) {
1253 PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
1254 return NULL;
1255 }
1256
1257 skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
1258 ap->crypt->extra_prefix_len +
1259 ap->crypt->extra_postfix_len);
1260 if (skb == NULL) {
1261 kfree(tmpbuf);
1262 return NULL;
1263 }
1264
1265 skb_reserve(skb, ap->crypt->extra_prefix_len);
1266 memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
1267 WLAN_AUTH_CHALLENGE_LEN);
1268 if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
1269 dev_kfree_skb(skb);
1270 kfree(tmpbuf);
1271 return NULL;
1272 }
1273
1274 memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
1275 WLAN_AUTH_CHALLENGE_LEN);
1276 dev_kfree_skb(skb);
1277
1278 return tmpbuf;
1279}
1280
1281
1282/* Called only as a scheduled task for pending AP frames. */
1283static void handle_authen(local_info_t *local, struct sk_buff *skb,
1284 struct hostap_80211_rx_status *rx_stats)
1285{
1286 struct net_device *dev = local->dev;
1287 struct hostap_ieee80211_hdr *hdr =
1288 (struct hostap_ieee80211_hdr *) skb->data;
1289 size_t hdrlen;
1290 struct ap_data *ap = local->ap;
1291 char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
1292 int len, olen;
1293 u16 auth_alg, auth_transaction, status_code, *pos;
1294 u16 resp = WLAN_STATUS_SUCCESS, fc;
1295 struct sta_info *sta = NULL;
1296 struct prism2_crypt_data *crypt;
1297 char *txt = "";
1298
1299 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1300
1301 fc = le16_to_cpu(hdr->frame_control);
1302 hdrlen = hostap_80211_get_hdrlen(fc);
1303
1304 if (len < 6) {
1305 PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
1306 "(len=%d) from " MACSTR "\n", dev->name, len,
1307 MAC2STR(hdr->addr2));
1308 return;
1309 }
1310
1311 spin_lock_bh(&local->ap->sta_table_lock);
1312 sta = ap_get_sta(local->ap, hdr->addr2);
1313 if (sta)
1314 atomic_inc(&sta->users);
1315 spin_unlock_bh(&local->ap->sta_table_lock);
1316
1317 if (sta && sta->crypt)
1318 crypt = sta->crypt;
1319 else {
1320 int idx = 0;
1321 if (skb->len >= hdrlen + 3)
1322 idx = skb->data[hdrlen + 3] >> 6;
1323 crypt = local->crypt[idx];
1324 }
1325
1326 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1327 auth_alg = __le16_to_cpu(*pos);
1328 pos++;
1329 auth_transaction = __le16_to_cpu(*pos);
1330 pos++;
1331 status_code = __le16_to_cpu(*pos);
1332 pos++;
1333
1334 if (memcmp(dev->dev_addr, hdr->addr2, ETH_ALEN) == 0 ||
1335 ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) {
1336 txt = "authentication denied";
1337 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1338 goto fail;
1339 }
1340
1341 if (((local->auth_algs & PRISM2_AUTH_OPEN) &&
1342 auth_alg == WLAN_AUTH_OPEN) ||
1343 ((local->auth_algs & PRISM2_AUTH_SHARED_KEY) &&
1344 crypt && auth_alg == WLAN_AUTH_SHARED_KEY)) {
1345 } else {
1346 txt = "unsupported algorithm";
1347 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1348 goto fail;
1349 }
1350
1351 if (len >= 8) {
1352 u8 *u = (u8 *) pos;
1353 if (*u == WLAN_EID_CHALLENGE) {
1354 if (*(u + 1) != WLAN_AUTH_CHALLENGE_LEN) {
1355 txt = "invalid challenge len";
1356 resp = WLAN_STATUS_CHALLENGE_FAIL;
1357 goto fail;
1358 }
1359 if (len - 8 < WLAN_AUTH_CHALLENGE_LEN) {
1360 txt = "challenge underflow";
1361 resp = WLAN_STATUS_CHALLENGE_FAIL;
1362 goto fail;
1363 }
1364 challenge = (char *) (u + 2);
1365 }
1366 }
1367
1368 if (sta && sta->ap) {
1369 if (time_after(jiffies, sta->u.ap.last_beacon +
1370 (10 * sta->listen_interval * HZ) / 1024)) {
1371 PDEBUG(DEBUG_AP, "%s: no beacons received for a while,"
1372 " assuming AP " MACSTR " is now STA\n",
1373 dev->name, MAC2STR(sta->addr));
1374 sta->ap = 0;
1375 sta->flags = 0;
1376 sta->u.sta.challenge = NULL;
1377 } else {
1378 txt = "AP trying to authenticate?";
1379 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1380 goto fail;
1381 }
1382 }
1383
1384 if ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) ||
1385 (auth_alg == WLAN_AUTH_SHARED_KEY &&
1386 (auth_transaction == 1 ||
1387 (auth_transaction == 3 && sta != NULL &&
1388 sta->u.sta.challenge != NULL)))) {
1389 } else {
1390 txt = "unknown authentication transaction number";
1391 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1392 goto fail;
1393 }
1394
1395 if (sta == NULL) {
1396 txt = "new STA";
1397
1398 if (local->ap->num_sta >= MAX_STA_COUNT) {
1399 /* FIX: might try to remove some old STAs first? */
1400 txt = "no more room for new STAs";
1401 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1402 goto fail;
1403 }
1404
1405 sta = ap_add_sta(local->ap, hdr->addr2);
1406 if (sta == NULL) {
1407 txt = "ap_add_sta failed";
1408 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1409 goto fail;
1410 }
1411 }
1412
1413 switch (auth_alg) {
1414 case WLAN_AUTH_OPEN:
1415 txt = "authOK";
1416 /* IEEE 802.11 standard is not completely clear about
1417 * whether STA is considered authenticated after
1418 * authentication OK frame has been send or after it
1419 * has been ACKed. In order to reduce interoperability
1420 * issues, mark the STA authenticated before ACK. */
1421 sta->flags |= WLAN_STA_AUTH;
1422 break;
1423
1424 case WLAN_AUTH_SHARED_KEY:
1425 if (auth_transaction == 1) {
1426 if (sta->u.sta.challenge == NULL) {
1427 sta->u.sta.challenge =
1428 ap_auth_make_challenge(local->ap);
1429 if (sta->u.sta.challenge == NULL) {
1430 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1431 goto fail;
1432 }
1433 }
1434 } else {
1435 if (sta->u.sta.challenge == NULL ||
1436 challenge == NULL ||
1437 memcmp(sta->u.sta.challenge, challenge,
1438 WLAN_AUTH_CHALLENGE_LEN) != 0 ||
1439 !(fc & WLAN_FC_ISWEP)) {
1440 txt = "challenge response incorrect";
1441 resp = WLAN_STATUS_CHALLENGE_FAIL;
1442 goto fail;
1443 }
1444
1445 txt = "challenge OK - authOK";
1446 /* IEEE 802.11 standard is not completely clear about
1447 * whether STA is considered authenticated after
1448 * authentication OK frame has been send or after it
1449 * has been ACKed. In order to reduce interoperability
1450 * issues, mark the STA authenticated before ACK. */
1451 sta->flags |= WLAN_STA_AUTH;
1452 kfree(sta->u.sta.challenge);
1453 sta->u.sta.challenge = NULL;
1454 }
1455 break;
1456 }
1457
1458 fail:
1459 pos = (u16 *) body;
1460 *pos = cpu_to_le16(auth_alg);
1461 pos++;
1462 *pos = cpu_to_le16(auth_transaction + 1);
1463 pos++;
1464 *pos = cpu_to_le16(resp); /* status_code */
1465 pos++;
1466 olen = 6;
1467
1468 if (resp == WLAN_STATUS_SUCCESS && sta != NULL &&
1469 sta->u.sta.challenge != NULL &&
1470 auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 1) {
1471 u8 *tmp = (u8 *) pos;
1472 *tmp++ = WLAN_EID_CHALLENGE;
1473 *tmp++ = WLAN_AUTH_CHALLENGE_LEN;
1474 pos++;
1475 memcpy(pos, sta->u.sta.challenge, WLAN_AUTH_CHALLENGE_LEN);
1476 olen += 2 + WLAN_AUTH_CHALLENGE_LEN;
1477 }
1478
1479 prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_AUTH,
1480 body, olen, hdr->addr2, ap->tx_callback_auth);
1481
1482 if (sta) {
1483 sta->last_rx = jiffies;
1484 atomic_dec(&sta->users);
1485 }
1486
1487 if (resp) {
1488 PDEBUG(DEBUG_AP, "%s: " MACSTR " auth (alg=%d trans#=%d "
1489 "stat=%d len=%d fc=%04x) ==> %d (%s)\n",
1490 dev->name, MAC2STR(hdr->addr2), auth_alg,
1491 auth_transaction, status_code, len, fc, resp, txt);
1492 }
1493}
1494
1495
1496/* Called only as a scheduled task for pending AP frames. */
1497static void handle_assoc(local_info_t *local, struct sk_buff *skb,
1498 struct hostap_80211_rx_status *rx_stats, int reassoc)
1499{
1500 struct net_device *dev = local->dev;
1501 struct hostap_ieee80211_hdr *hdr =
1502 (struct hostap_ieee80211_hdr *) skb->data;
1503 char body[12], *p, *lpos;
1504 int len, left;
1505 u16 *pos;
1506 u16 resp = WLAN_STATUS_SUCCESS;
1507 struct sta_info *sta = NULL;
1508 int send_deauth = 0;
1509 char *txt = "";
1510 u8 prev_ap[ETH_ALEN];
1511
1512 left = len = skb->len - IEEE80211_MGMT_HDR_LEN;
1513
1514 if (len < (reassoc ? 10 : 4)) {
1515 PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
1516 "(len=%d, reassoc=%d) from " MACSTR "\n",
1517 dev->name, len, reassoc, MAC2STR(hdr->addr2));
1518 return;
1519 }
1520
1521 spin_lock_bh(&local->ap->sta_table_lock);
1522 sta = ap_get_sta(local->ap, hdr->addr2);
1523 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
1524 spin_unlock_bh(&local->ap->sta_table_lock);
1525 txt = "trying to associate before authentication";
1526 send_deauth = 1;
1527 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1528 sta = NULL; /* do not decrement sta->users */
1529 goto fail;
1530 }
1531 atomic_inc(&sta->users);
1532 spin_unlock_bh(&local->ap->sta_table_lock);
1533
1534 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1535 sta->capability = __le16_to_cpu(*pos);
1536 pos++; left -= 2;
1537 sta->listen_interval = __le16_to_cpu(*pos);
1538 pos++; left -= 2;
1539
1540 if (reassoc) {
1541 memcpy(prev_ap, pos, ETH_ALEN);
1542 pos++; pos++; pos++; left -= 6;
1543 } else
1544 memset(prev_ap, 0, ETH_ALEN);
1545
1546 if (left >= 2) {
1547 unsigned int ileft;
1548 unsigned char *u = (unsigned char *) pos;
1549
1550 if (*u == WLAN_EID_SSID) {
1551 u++; left--;
1552 ileft = *u;
1553 u++; left--;
1554
1555 if (ileft > left || ileft > MAX_SSID_LEN) {
1556 txt = "SSID overflow";
1557 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1558 goto fail;
1559 }
1560
1561 if (ileft != strlen(local->essid) ||
1562 memcmp(local->essid, u, ileft) != 0) {
1563 txt = "not our SSID";
1564 resp = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1565 goto fail;
1566 }
1567
1568 u += ileft;
1569 left -= ileft;
1570 }
1571
1572 if (left >= 2 && *u == WLAN_EID_SUPP_RATES) {
1573 u++; left--;
1574 ileft = *u;
1575 u++; left--;
1576
1577 if (ileft > left || ileft == 0 ||
1578 ileft > WLAN_SUPP_RATES_MAX) {
1579 txt = "SUPP_RATES len error";
1580 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1581 goto fail;
1582 }
1583
1584 memset(sta->supported_rates, 0,
1585 sizeof(sta->supported_rates));
1586 memcpy(sta->supported_rates, u, ileft);
1587 prism2_check_tx_rates(sta);
1588
1589 u += ileft;
1590 left -= ileft;
1591 }
1592
1593 if (left > 0) {
1594 PDEBUG(DEBUG_AP, "%s: assoc from " MACSTR " with extra"
1595 " data (%d bytes) [",
1596 dev->name, MAC2STR(hdr->addr2), left);
1597 while (left > 0) {
1598 PDEBUG2(DEBUG_AP, "<%02x>", *u);
1599 u++; left--;
1600 }
1601 PDEBUG2(DEBUG_AP, "]\n");
1602 }
1603 } else {
1604 txt = "frame underflow";
1605 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1606 goto fail;
1607 }
1608
1609 /* get a unique AID */
1610 if (sta->aid > 0)
1611 txt = "OK, old AID";
1612 else {
1613 spin_lock_bh(&local->ap->sta_table_lock);
1614 for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
1615 if (local->ap->sta_aid[sta->aid - 1] == NULL)
1616 break;
1617 if (sta->aid > MAX_AID_TABLE_SIZE) {
1618 sta->aid = 0;
1619 spin_unlock_bh(&local->ap->sta_table_lock);
1620 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1621 txt = "no room for more AIDs";
1622 } else {
1623 local->ap->sta_aid[sta->aid - 1] = sta;
1624 spin_unlock_bh(&local->ap->sta_table_lock);
1625 txt = "OK, new AID";
1626 }
1627 }
1628
1629 fail:
1630 pos = (u16 *) body;
1631
1632 if (send_deauth) {
1633 *pos = __constant_cpu_to_le16(
1634 WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
1635 pos++;
1636 } else {
1637 /* FIX: CF-Pollable and CF-PollReq should be set to match the
1638 * values in beacons/probe responses */
1639 /* FIX: how about privacy and WEP? */
1640 /* capability */
1641 *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS);
1642 pos++;
1643
1644 /* status_code */
1645 *pos = __cpu_to_le16(resp);
1646 pos++;
1647
1648 *pos = __cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
1649 BIT(14) | BIT(15)); /* AID */
1650 pos++;
1651
1652 /* Supported rates (Information element) */
1653 p = (char *) pos;
1654 *p++ = WLAN_EID_SUPP_RATES;
1655 lpos = p;
1656 *p++ = 0; /* len */
1657 if (local->tx_rate_control & WLAN_RATE_1M) {
1658 *p++ = local->basic_rates & WLAN_RATE_1M ? 0x82 : 0x02;
1659 (*lpos)++;
1660 }
1661 if (local->tx_rate_control & WLAN_RATE_2M) {
1662 *p++ = local->basic_rates & WLAN_RATE_2M ? 0x84 : 0x04;
1663 (*lpos)++;
1664 }
1665 if (local->tx_rate_control & WLAN_RATE_5M5) {
1666 *p++ = local->basic_rates & WLAN_RATE_5M5 ?
1667 0x8b : 0x0b;
1668 (*lpos)++;
1669 }
1670 if (local->tx_rate_control & WLAN_RATE_11M) {
1671 *p++ = local->basic_rates & WLAN_RATE_11M ?
1672 0x96 : 0x16;
1673 (*lpos)++;
1674 }
1675 pos = (u16 *) p;
1676 }
1677
1678 prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT,
1679 (send_deauth ? WLAN_FC_STYPE_DEAUTH :
1680 (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
1681 WLAN_FC_STYPE_ASSOC_RESP)),
1682 body, (u8 *) pos - (u8 *) body,
1683 hdr->addr2,
1684 send_deauth ? 0 : local->ap->tx_callback_assoc);
1685
1686 if (sta) {
1687 if (resp == WLAN_STATUS_SUCCESS) {
1688 sta->last_rx = jiffies;
1689 /* STA will be marked associated from TX callback, if
1690 * AssocResp is ACKed */
1691 }
1692 atomic_dec(&sta->users);
1693 }
1694
1695#if 0
1696 PDEBUG(DEBUG_AP, "%s: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR
1697 ") => %d(%d) (%s)\n",
1698 dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len,
1699 MAC2STR(prev_ap), resp, send_deauth, txt);
1700#endif
1701}
1702
1703
1704/* Called only as a scheduled task for pending AP frames. */
1705static void handle_deauth(local_info_t *local, struct sk_buff *skb,
1706 struct hostap_80211_rx_status *rx_stats)
1707{
1708 struct net_device *dev = local->dev;
1709 struct hostap_ieee80211_hdr *hdr =
1710 (struct hostap_ieee80211_hdr *) skb->data;
1711 char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1712 int len;
1713 u16 reason_code, *pos;
1714 struct sta_info *sta = NULL;
1715
1716 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1717
1718 if (len < 2) {
1719 printk("handle_deauth - too short payload (len=%d)\n", len);
1720 return;
1721 }
1722
1723 pos = (u16 *) body;
1724 reason_code = __le16_to_cpu(*pos);
1725
1726 PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, "
1727 "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
1728 reason_code);
1729
1730 spin_lock_bh(&local->ap->sta_table_lock);
1731 sta = ap_get_sta(local->ap, hdr->addr2);
1732 if (sta != NULL) {
1733 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
1734 hostap_event_expired_sta(local->dev, sta);
1735 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1736 }
1737 spin_unlock_bh(&local->ap->sta_table_lock);
1738 if (sta == NULL) {
1739 printk("%s: deauthentication from " MACSTR ", "
1740 "reason_code=%d, but STA not authenticated\n", dev->name,
1741 MAC2STR(hdr->addr2), reason_code);
1742 }
1743}
1744
1745
1746/* Called only as a scheduled task for pending AP frames. */
1747static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
1748 struct hostap_80211_rx_status *rx_stats)
1749{
1750 struct net_device *dev = local->dev;
1751 struct hostap_ieee80211_hdr *hdr =
1752 (struct hostap_ieee80211_hdr *) skb->data;
1753 char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
1754 int len;
1755 u16 reason_code, *pos;
1756 struct sta_info *sta = NULL;
1757
1758 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1759
1760 if (len < 2) {
1761 printk("handle_disassoc - too short payload (len=%d)\n", len);
1762 return;
1763 }
1764
1765 pos = (u16 *) body;
1766 reason_code = __le16_to_cpu(*pos);
1767
1768 PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, "
1769 "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
1770 reason_code);
1771
1772 spin_lock_bh(&local->ap->sta_table_lock);
1773 sta = ap_get_sta(local->ap, hdr->addr2);
1774 if (sta != NULL) {
1775 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
1776 hostap_event_expired_sta(local->dev, sta);
1777 sta->flags &= ~WLAN_STA_ASSOC;
1778 }
1779 spin_unlock_bh(&local->ap->sta_table_lock);
1780 if (sta == NULL) {
1781 printk("%s: disassociation from " MACSTR ", "
1782 "reason_code=%d, but STA not authenticated\n",
1783 dev->name, MAC2STR(hdr->addr2), reason_code);
1784 }
1785}
1786
1787
1788/* Called only as a scheduled task for pending AP frames. */
1789static void ap_handle_data_nullfunc(local_info_t *local,
1790 struct hostap_ieee80211_hdr *hdr)
1791{
1792 struct net_device *dev = local->dev;
1793
1794 /* some STA f/w's seem to require control::ACK frame for
1795 * data::nullfunc, but at least Prism2 station f/w version 0.8.0 does
1796 * not send this..
1797 * send control::ACK for the data::nullfunc */
1798
1799 printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n");
1800 prism2_send_mgmt(dev, WLAN_FC_TYPE_CTRL, WLAN_FC_STYPE_ACK,
1801 NULL, 0, hdr->addr2, 0);
1802}
1803
1804
1805/* Called only as a scheduled task for pending AP frames. */
1806static void ap_handle_dropped_data(local_info_t *local,
1807 struct hostap_ieee80211_hdr *hdr)
1808{
1809 struct net_device *dev = local->dev;
1810 struct sta_info *sta;
1811 u16 reason;
1812
1813 spin_lock_bh(&local->ap->sta_table_lock);
1814 sta = ap_get_sta(local->ap, hdr->addr2);
1815 if (sta)
1816 atomic_inc(&sta->users);
1817 spin_unlock_bh(&local->ap->sta_table_lock);
1818
1819 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC)) {
1820 PDEBUG(DEBUG_AP, "ap_handle_dropped_data: STA is now okay?\n");
1821 atomic_dec(&sta->users);
1822 return;
1823 }
1824
1825 reason = __constant_cpu_to_le16(
1826 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1827 prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT,
1828 ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
1829 WLAN_FC_STYPE_DEAUTH : WLAN_FC_STYPE_DISASSOC),
1830 (char *) &reason, sizeof(reason), hdr->addr2, 0);
1831
1832 if (sta)
1833 atomic_dec(&sta->users);
1834}
1835
1836#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1837
1838
1839/* Called only as a scheduled task for pending AP frames. */
1840static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
1841 struct sk_buff *skb)
1842{
1843 if (!(sta->flags & WLAN_STA_PS)) {
1844 /* Station has moved to non-PS mode, so send all buffered
1845 * frames using normal device queue. */
1846 dev_queue_xmit(skb);
1847 return;
1848 }
1849
1850 /* add a flag for hostap_handle_sta_tx() to know that this skb should
1851 * be passed through even though STA is using PS */
1852 memcpy(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN);
1853 skb->cb[AP_SKB_CB_MAGIC_LEN] = AP_SKB_CB_BUFFERED_FRAME;
1854 if (!skb_queue_empty(&sta->tx_buf)) {
1855 /* indicate to STA that more frames follow */
1856 skb->cb[AP_SKB_CB_MAGIC_LEN] |= AP_SKB_CB_ADD_MOREDATA;
1857 }
1858 dev_queue_xmit(skb);
1859}
1860
1861
1862/* Called only as a scheduled task for pending AP frames. */
1863static void handle_pspoll(local_info_t *local,
1864 struct hostap_ieee80211_hdr *hdr,
1865 struct hostap_80211_rx_status *rx_stats)
1866{
1867 struct net_device *dev = local->dev;
1868 struct sta_info *sta;
1869 u16 aid;
1870 struct sk_buff *skb;
1871
1872 PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR
1873 " PWRMGT=%d\n",
1874 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
1875 !!(le16_to_cpu(hdr->frame_control) & WLAN_FC_PWRMGT));
1876
1877 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
1878 PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR
1879 " not own MAC\n", MAC2STR(hdr->addr1));
1880 return;
1881 }
1882
1883 aid = __le16_to_cpu(hdr->duration_id);
1884 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) {
1885 PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n");
1886 return;
1887 }
1888 aid &= ~BIT(15) & ~BIT(14);
1889 if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
1890 PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid);
1891 return;
1892 }
1893 PDEBUG(DEBUG_PS2, " aid=%d\n", aid);
1894
1895 spin_lock_bh(&local->ap->sta_table_lock);
1896 sta = ap_get_sta(local->ap, hdr->addr2);
1897 if (sta)
1898 atomic_inc(&sta->users);
1899 spin_unlock_bh(&local->ap->sta_table_lock);
1900
1901 if (sta == NULL) {
1902 PDEBUG(DEBUG_PS, " STA not found\n");
1903 return;
1904 }
1905 if (sta->aid != aid) {
1906 PDEBUG(DEBUG_PS, " received aid=%i does not match with "
1907 "assoc.aid=%d\n", aid, sta->aid);
1908 return;
1909 }
1910
1911 /* FIX: todo:
1912 * - add timeout for buffering (clear aid in TIM vector if buffer timed
1913 * out (expiry time must be longer than ListenInterval for
1914 * the corresponding STA; "8802-11: 11.2.1.9 AP aging function"
1915 * - what to do, if buffered, pspolled, and sent frame is not ACKed by
1916 * sta; store buffer for later use and leave TIM aid bit set? use
1917 * TX event to check whether frame was ACKed?
1918 */
1919
1920 while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) {
1921 /* send buffered frame .. */
1922 PDEBUG(DEBUG_PS2, "Sending buffered frame to STA after PS POLL"
1923 " (buffer_count=%d)\n", skb_queue_len(&sta->tx_buf));
1924
1925 pspoll_send_buffered(local, sta, skb);
1926
1927 if (sta->flags & WLAN_STA_PS) {
1928 /* send only one buffered packet per PS Poll */
1929 /* FIX: should ignore further PS Polls until the
1930 * buffered packet that was just sent is acknowledged
1931 * (Tx or TxExc event) */
1932 break;
1933 }
1934 }
1935
1936 if (skb_queue_empty(&sta->tx_buf)) {
1937 /* try to clear aid from TIM */
1938 if (!(sta->flags & WLAN_STA_TIM))
1939 PDEBUG(DEBUG_PS2, "Re-unsetting TIM for aid %d\n",
1940 aid);
1941 hostap_set_tim(local, aid, 0);
1942 sta->flags &= ~WLAN_STA_TIM;
1943 }
1944
1945 atomic_dec(&sta->users);
1946}
1947
1948
1949#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1950
1951static void handle_wds_oper_queue(void *data)
1952{
1953 local_info_t *local = data;
1954 struct wds_oper_data *entry, *prev;
1955
1956 spin_lock_bh(&local->lock);
1957 entry = local->ap->wds_oper_entries;
1958 local->ap->wds_oper_entries = NULL;
1959 spin_unlock_bh(&local->lock);
1960
1961 while (entry) {
1962 PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
1963 "to AP " MACSTR "\n",
1964 local->dev->name,
1965 entry->type == WDS_ADD ? "adding" : "removing",
1966 MAC2STR(entry->addr));
1967 if (entry->type == WDS_ADD)
1968 prism2_wds_add(local, entry->addr, 0);
1969 else if (entry->type == WDS_DEL)
1970 prism2_wds_del(local, entry->addr, 0, 1);
1971
1972 prev = entry;
1973 entry = entry->next;
1974 kfree(prev);
1975 }
1976}
1977
1978
1979/* Called only as a scheduled task for pending AP frames. */
1980static void handle_beacon(local_info_t *local, struct sk_buff *skb,
1981 struct hostap_80211_rx_status *rx_stats)
1982{
1983 struct hostap_ieee80211_hdr *hdr =
1984 (struct hostap_ieee80211_hdr *) skb->data;
1985 char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
1986 int len, left;
1987 u16 *pos, beacon_int, capability;
1988 char *ssid = NULL;
1989 unsigned char *supp_rates = NULL;
1990 int ssid_len = 0, supp_rates_len = 0;
1991 struct sta_info *sta = NULL;
1992 int new_sta = 0, channel = -1;
1993
1994 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1995
1996 if (len < 8 + 2 + 2) {
1997 printk(KERN_DEBUG "handle_beacon - too short payload "
1998 "(len=%d)\n", len);
1999 return;
2000 }
2001
2002 pos = (u16 *) body;
2003 left = len;
2004
2005 /* Timestamp (8 octets) */
2006 pos += 4; left -= 8;
2007 /* Beacon interval (2 octets) */
2008 beacon_int = __le16_to_cpu(*pos);
2009 pos++; left -= 2;
2010 /* Capability information (2 octets) */
2011 capability = __le16_to_cpu(*pos);
2012 pos++; left -= 2;
2013
2014 if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS &&
2015 capability & WLAN_CAPABILITY_IBSS)
2016 return;
2017
2018 if (left >= 2) {
2019 unsigned int ileft;
2020 unsigned char *u = (unsigned char *) pos;
2021
2022 if (*u == WLAN_EID_SSID) {
2023 u++; left--;
2024 ileft = *u;
2025 u++; left--;
2026
2027 if (ileft > left || ileft > MAX_SSID_LEN) {
2028 PDEBUG(DEBUG_AP, "SSID: overflow\n");
2029 return;
2030 }
2031
2032 if (local->ap->ap_policy == AP_OTHER_AP_SAME_SSID &&
2033 (ileft != strlen(local->essid) ||
2034 memcmp(local->essid, u, ileft) != 0)) {
2035 /* not our SSID */
2036 return;
2037 }
2038
2039 ssid = u;
2040 ssid_len = ileft;
2041
2042 u += ileft;
2043 left -= ileft;
2044 }
2045
2046 if (*u == WLAN_EID_SUPP_RATES) {
2047 u++; left--;
2048 ileft = *u;
2049 u++; left--;
2050
2051 if (ileft > left || ileft == 0 || ileft > 8) {
2052 PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n");
2053 return;
2054 }
2055
2056 supp_rates = u;
2057 supp_rates_len = ileft;
2058
2059 u += ileft;
2060 left -= ileft;
2061 }
2062
2063 if (*u == WLAN_EID_DS_PARAMS) {
2064 u++; left--;
2065 ileft = *u;
2066 u++; left--;
2067
2068 if (ileft > left || ileft != 1) {
2069 PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n");
2070 return;
2071 }
2072
2073 channel = *u;
2074
2075 u += ileft;
2076 left -= ileft;
2077 }
2078 }
2079
2080 spin_lock_bh(&local->ap->sta_table_lock);
2081 sta = ap_get_sta(local->ap, hdr->addr2);
2082 if (sta != NULL)
2083 atomic_inc(&sta->users);
2084 spin_unlock_bh(&local->ap->sta_table_lock);
2085
2086 if (sta == NULL) {
2087 /* add new AP */
2088 new_sta = 1;
2089 sta = ap_add_sta(local->ap, hdr->addr2);
2090 if (sta == NULL) {
2091 printk(KERN_INFO "prism2: kmalloc failed for AP "
2092 "data structure\n");
2093 return;
2094 }
2095 hostap_event_new_sta(local->dev, sta);
2096
2097 /* mark APs authentication and associated for pseudo ad-hoc
2098 * style communication */
2099 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
2100
2101 if (local->ap->autom_ap_wds) {
2102 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
2103 }
2104 }
2105
2106 sta->ap = 1;
2107 if (ssid) {
2108 sta->u.ap.ssid_len = ssid_len;
2109 memcpy(sta->u.ap.ssid, ssid, ssid_len);
2110 sta->u.ap.ssid[ssid_len] = '\0';
2111 } else {
2112 sta->u.ap.ssid_len = 0;
2113 sta->u.ap.ssid[0] = '\0';
2114 }
2115 sta->u.ap.channel = channel;
2116 sta->rx_packets++;
2117 sta->rx_bytes += len;
2118 sta->u.ap.last_beacon = sta->last_rx = jiffies;
2119 sta->capability = capability;
2120 sta->listen_interval = beacon_int;
2121
2122 atomic_dec(&sta->users);
2123
2124 if (new_sta) {
2125 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
2126 memcpy(sta->supported_rates, supp_rates, supp_rates_len);
2127 prism2_check_tx_rates(sta);
2128 }
2129}
2130
2131#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2132
2133
2134/* Called only as a tasklet. */
2135static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
2136 struct hostap_80211_rx_status *rx_stats)
2137{
2138#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2139 struct net_device *dev = local->dev;
2140#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2141 u16 fc, type, stype;
2142 struct hostap_ieee80211_hdr *hdr;
2143
2144 /* FIX: should give skb->len to handler functions and check that the
2145 * buffer is long enough */
2146 hdr = (struct hostap_ieee80211_hdr *) skb->data;
2147 fc = le16_to_cpu(hdr->frame_control);
2148 type = WLAN_FC_GET_TYPE(fc);
2149 stype = WLAN_FC_GET_STYPE(fc);
2150
2151#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2152 if (!local->hostapd && type == WLAN_FC_TYPE_DATA) {
2153 PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n");
2154
2155 if (!(fc & WLAN_FC_TODS) || (fc & WLAN_FC_FROMDS)) {
2156 if (stype == WLAN_FC_STYPE_NULLFUNC) {
2157 /* no ToDS nullfunc seems to be used to check
2158 * AP association; so send reject message to
2159 * speed up re-association */
2160 ap_handle_dropped_data(local, hdr);
2161 goto done;
2162 }
2163 PDEBUG(DEBUG_AP, " not ToDS frame (fc=0x%04x)\n",
2164 fc);
2165 goto done;
2166 }
2167
2168 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2169 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
2170 MACSTR " not own MAC\n",
2171 MAC2STR(hdr->addr1));
2172 goto done;
2173 }
2174
2175 if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC)
2176 ap_handle_data_nullfunc(local, hdr);
2177 else
2178 ap_handle_dropped_data(local, hdr);
2179 goto done;
2180 }
2181
2182 if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_BEACON) {
2183 handle_beacon(local, skb, rx_stats);
2184 goto done;
2185 }
2186#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2187
2188 if (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL) {
2189 handle_pspoll(local, hdr, rx_stats);
2190 goto done;
2191 }
2192
2193 if (local->hostapd) {
2194 PDEBUG(DEBUG_AP, "Unknown frame in AP queue: type=0x%02x "
2195 "subtype=0x%02x\n", type, stype);
2196 goto done;
2197 }
2198
2199#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2200 if (type != WLAN_FC_TYPE_MGMT) {
2201 PDEBUG(DEBUG_AP, "handle_ap_item - not a management frame?\n");
2202 goto done;
2203 }
2204
2205 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2206 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MACSTR
2207 " not own MAC\n", MAC2STR(hdr->addr1));
2208 goto done;
2209 }
2210
2211 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) {
2212 PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MACSTR
2213 " not own MAC\n", MAC2STR(hdr->addr3));
2214 goto done;
2215 }
2216
2217 switch (stype) {
2218 case WLAN_FC_STYPE_ASSOC_REQ:
2219 handle_assoc(local, skb, rx_stats, 0);
2220 break;
2221 case WLAN_FC_STYPE_ASSOC_RESP:
2222 PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n");
2223 break;
2224 case WLAN_FC_STYPE_REASSOC_REQ:
2225 handle_assoc(local, skb, rx_stats, 1);
2226 break;
2227 case WLAN_FC_STYPE_REASSOC_RESP:
2228 PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n");
2229 break;
2230 case WLAN_FC_STYPE_ATIM:
2231 PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n");
2232 break;
2233 case WLAN_FC_STYPE_DISASSOC:
2234 handle_disassoc(local, skb, rx_stats);
2235 break;
2236 case WLAN_FC_STYPE_AUTH:
2237 handle_authen(local, skb, rx_stats);
2238 break;
2239 case WLAN_FC_STYPE_DEAUTH:
2240 handle_deauth(local, skb, rx_stats);
2241 break;
2242 default:
2243 PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n", stype);
2244 break;
2245 }
2246#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2247
2248 done:
2249 dev_kfree_skb(skb);
2250}
2251
2252
2253/* Called only as a tasklet (software IRQ) */
2254void hostap_rx(struct net_device *dev, struct sk_buff *skb,
2255 struct hostap_80211_rx_status *rx_stats)
2256{
2257 struct hostap_interface *iface;
2258 local_info_t *local;
2259 u16 fc;
2260 struct hostap_ieee80211_hdr *hdr;
2261
2262 iface = netdev_priv(dev);
2263 local = iface->local;
2264
2265 if (skb->len < 16)
2266 goto drop;
2267
2268 local->stats.rx_packets++;
2269
2270 hdr = (struct hostap_ieee80211_hdr *) skb->data;
2271 fc = le16_to_cpu(hdr->frame_control);
2272
2273 if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
2274 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
2275 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
2276 goto drop;
2277
2278 skb->protocol = __constant_htons(ETH_P_HOSTAP);
2279 handle_ap_item(local, skb, rx_stats);
2280 return;
2281
2282 drop:
2283 dev_kfree_skb(skb);
2284}
2285
2286
2287/* Called only as a tasklet (software IRQ) */
2288static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
2289{
2290 struct sk_buff *skb;
2291 struct hostap_ieee80211_hdr *hdr;
2292 struct hostap_80211_rx_status rx_stats;
2293
2294 if (skb_queue_empty(&sta->tx_buf))
2295 return;
2296
2297 skb = dev_alloc_skb(16);
2298 if (skb == NULL) {
2299 printk(KERN_DEBUG "%s: schedule_packet_send: skb alloc "
2300 "failed\n", local->dev->name);
2301 return;
2302 }
2303
2304 hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, 16);
2305
2306 /* Generate a fake pspoll frame to start packet delivery */
2307 hdr->frame_control = __constant_cpu_to_le16(
2308 (WLAN_FC_TYPE_CTRL << 2) | (WLAN_FC_STYPE_PSPOLL << 4));
2309 memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
2310 memcpy(hdr->addr2, sta->addr, ETH_ALEN);
2311 hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));
2312
2313 PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for "
2314 "STA " MACSTR "\n", local->dev->name, MAC2STR(sta->addr));
2315
2316 skb->dev = local->dev;
2317
2318 memset(&rx_stats, 0, sizeof(rx_stats));
2319 hostap_rx(local->dev, skb, &rx_stats);
2320}
2321
2322
2323static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
2324 struct iw_quality qual[], int buf_size,
2325 int aplist)
2326{
2327 struct ap_data *ap = local->ap;
2328 struct list_head *ptr;
2329 int count = 0;
2330
2331 spin_lock_bh(&ap->sta_table_lock);
2332
2333 for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
2334 ptr = ptr->next) {
2335 struct sta_info *sta = (struct sta_info *) ptr;
2336
2337 if (aplist && !sta->ap)
2338 continue;
2339 addr[count].sa_family = ARPHRD_ETHER;
2340 memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
2341 if (sta->last_rx_silence == 0)
2342 qual[count].qual = sta->last_rx_signal < 27 ?
2343 0 : (sta->last_rx_signal - 27) * 92 / 127;
2344 else
2345 qual[count].qual = sta->last_rx_signal -
2346 sta->last_rx_silence - 35;
2347 qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
2348 qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2349 qual[count].updated = sta->last_rx_updated;
2350
2351 sta->last_rx_updated = 0;
2352
2353 count++;
2354 if (count >= buf_size)
2355 break;
2356 }
2357 spin_unlock_bh(&ap->sta_table_lock);
2358
2359 return count;
2360}
2361
2362
2363/* Translate our list of Access Points & Stations to a card independant
2364 * format that the Wireless Tools will understand - Jean II */
2365static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2366{
2367 struct hostap_interface *iface;
2368 local_info_t *local;
2369 struct ap_data *ap;
2370 struct list_head *ptr;
2371 struct iw_event iwe;
2372 char *current_ev = buffer;
2373 char *end_buf = buffer + IW_SCAN_MAX_DATA;
2374#if !defined(PRISM2_NO_KERNEL_IEEE80211_MGMT)
2375 char buf[64];
2376#endif
2377
2378 iface = netdev_priv(dev);
2379 local = iface->local;
2380 ap = local->ap;
2381
2382 spin_lock_bh(&ap->sta_table_lock);
2383
2384 for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
2385 ptr = ptr->next) {
2386 struct sta_info *sta = (struct sta_info *) ptr;
2387
2388 /* First entry *MUST* be the AP MAC address */
2389 memset(&iwe, 0, sizeof(iwe));
2390 iwe.cmd = SIOCGIWAP;
2391 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2392 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
2393 iwe.len = IW_EV_ADDR_LEN;
2394 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2395 IW_EV_ADDR_LEN);
2396
2397 /* Use the mode to indicate if it's a station or
2398 * an Access Point */
2399 memset(&iwe, 0, sizeof(iwe));
2400 iwe.cmd = SIOCGIWMODE;
2401 if (sta->ap)
2402 iwe.u.mode = IW_MODE_MASTER;
2403 else
2404 iwe.u.mode = IW_MODE_INFRA;
2405 iwe.len = IW_EV_UINT_LEN;
2406 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2407 IW_EV_UINT_LEN);
2408
2409 /* Some quality */
2410 memset(&iwe, 0, sizeof(iwe));
2411 iwe.cmd = IWEVQUAL;
2412 if (sta->last_rx_silence == 0)
2413 iwe.u.qual.qual = sta->last_rx_signal < 27 ?
2414 0 : (sta->last_rx_signal - 27) * 92 / 127;
2415 else
2416 iwe.u.qual.qual = sta->last_rx_signal -
2417 sta->last_rx_silence - 35;
2418 iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
2419 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2420 iwe.u.qual.updated = sta->last_rx_updated;
2421 iwe.len = IW_EV_QUAL_LEN;
2422 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2423 IW_EV_QUAL_LEN);
2424
2425#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2426 if (sta->ap) {
2427 memset(&iwe, 0, sizeof(iwe));
2428 iwe.cmd = SIOCGIWESSID;
2429 iwe.u.data.length = sta->u.ap.ssid_len;
2430 iwe.u.data.flags = 1;
2431 current_ev = iwe_stream_add_point(current_ev, end_buf,
2432 &iwe,
2433 sta->u.ap.ssid);
2434
2435 memset(&iwe, 0, sizeof(iwe));
2436 iwe.cmd = SIOCGIWENCODE;
2437 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
2438 iwe.u.data.flags =
2439 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2440 else
2441 iwe.u.data.flags = IW_ENCODE_DISABLED;
2442 current_ev = iwe_stream_add_point(current_ev, end_buf,
2443 &iwe,
2444 sta->u.ap.ssid
2445 /* 0 byte memcpy */);
2446
2447 if (sta->u.ap.channel > 0 &&
2448 sta->u.ap.channel <= FREQ_COUNT) {
2449 memset(&iwe, 0, sizeof(iwe));
2450 iwe.cmd = SIOCGIWFREQ;
2451 iwe.u.freq.m = freq_list[sta->u.ap.channel - 1]
2452 * 100000;
2453 iwe.u.freq.e = 1;
2454 current_ev = iwe_stream_add_event(
2455 current_ev, end_buf, &iwe,
2456 IW_EV_FREQ_LEN);
2457 }
2458
2459 memset(&iwe, 0, sizeof(iwe));
2460 iwe.cmd = IWEVCUSTOM;
2461 sprintf(buf, "beacon_interval=%d",
2462 sta->listen_interval);
2463 iwe.u.data.length = strlen(buf);
2464 current_ev = iwe_stream_add_point(current_ev, end_buf,
2465 &iwe, buf);
2466 }
2467#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2468
2469 sta->last_rx_updated = 0;
2470
2471 /* To be continued, we should make good use of IWEVCUSTOM */
2472 }
2473
2474 spin_unlock_bh(&ap->sta_table_lock);
2475
2476 return current_ev - buffer;
2477}
2478
2479
2480static int prism2_hostapd_add_sta(struct ap_data *ap,
2481 struct prism2_hostapd_param *param)
2482{
2483 struct sta_info *sta;
2484
2485 spin_lock_bh(&ap->sta_table_lock);
2486 sta = ap_get_sta(ap, param->sta_addr);
2487 if (sta)
2488 atomic_inc(&sta->users);
2489 spin_unlock_bh(&ap->sta_table_lock);
2490
2491 if (sta == NULL) {
2492 sta = ap_add_sta(ap, param->sta_addr);
2493 if (sta == NULL)
2494 return -1;
2495 }
2496
2497 if (!(sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
2498 hostap_event_new_sta(sta->local->dev, sta);
2499
2500 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
2501 sta->last_rx = jiffies;
2502 sta->aid = param->u.add_sta.aid;
2503 sta->capability = param->u.add_sta.capability;
2504 sta->tx_supp_rates = param->u.add_sta.tx_supp_rates;
2505 if (sta->tx_supp_rates & WLAN_RATE_1M)
2506 sta->supported_rates[0] = 2;
2507 if (sta->tx_supp_rates & WLAN_RATE_2M)
2508 sta->supported_rates[1] = 4;
2509 if (sta->tx_supp_rates & WLAN_RATE_5M5)
2510 sta->supported_rates[2] = 11;
2511 if (sta->tx_supp_rates & WLAN_RATE_11M)
2512 sta->supported_rates[3] = 22;
2513 prism2_check_tx_rates(sta);
2514 atomic_dec(&sta->users);
2515 return 0;
2516}
2517
2518
2519static int prism2_hostapd_remove_sta(struct ap_data *ap,
2520 struct prism2_hostapd_param *param)
2521{
2522 struct sta_info *sta;
2523
2524 spin_lock_bh(&ap->sta_table_lock);
2525 sta = ap_get_sta(ap, param->sta_addr);
2526 if (sta) {
2527 ap_sta_hash_del(ap, sta);
2528 list_del(&sta->list);
2529 }
2530 spin_unlock_bh(&ap->sta_table_lock);
2531
2532 if (!sta)
2533 return -ENOENT;
2534
2535 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
2536 hostap_event_expired_sta(sta->local->dev, sta);
2537 ap_free_sta(ap, sta);
2538
2539 return 0;
2540}
2541
2542
2543static int prism2_hostapd_get_info_sta(struct ap_data *ap,
2544 struct prism2_hostapd_param *param)
2545{
2546 struct sta_info *sta;
2547
2548 spin_lock_bh(&ap->sta_table_lock);
2549 sta = ap_get_sta(ap, param->sta_addr);
2550 if (sta)
2551 atomic_inc(&sta->users);
2552 spin_unlock_bh(&ap->sta_table_lock);
2553
2554 if (!sta)
2555 return -ENOENT;
2556
2557 param->u.get_info_sta.inactive_sec = (jiffies - sta->last_rx) / HZ;
2558
2559 atomic_dec(&sta->users);
2560
2561 return 1;
2562}
2563
2564
2565static int prism2_hostapd_set_flags_sta(struct ap_data *ap,
2566 struct prism2_hostapd_param *param)
2567{
2568 struct sta_info *sta;
2569
2570 spin_lock_bh(&ap->sta_table_lock);
2571 sta = ap_get_sta(ap, param->sta_addr);
2572 if (sta) {
2573 sta->flags |= param->u.set_flags_sta.flags_or;
2574 sta->flags &= param->u.set_flags_sta.flags_and;
2575 }
2576 spin_unlock_bh(&ap->sta_table_lock);
2577
2578 if (!sta)
2579 return -ENOENT;
2580
2581 return 0;
2582}
2583
2584
2585static int prism2_hostapd_sta_clear_stats(struct ap_data *ap,
2586 struct prism2_hostapd_param *param)
2587{
2588 struct sta_info *sta;
2589 int rate;
2590
2591 spin_lock_bh(&ap->sta_table_lock);
2592 sta = ap_get_sta(ap, param->sta_addr);
2593 if (sta) {
2594 sta->rx_packets = sta->tx_packets = 0;
2595 sta->rx_bytes = sta->tx_bytes = 0;
2596 for (rate = 0; rate < WLAN_RATE_COUNT; rate++) {
2597 sta->tx_count[rate] = 0;
2598 sta->rx_count[rate] = 0;
2599 }
2600 }
2601 spin_unlock_bh(&ap->sta_table_lock);
2602
2603 if (!sta)
2604 return -ENOENT;
2605
2606 return 0;
2607}
2608
2609
2610static int prism2_hostapd(struct ap_data *ap,
2611 struct prism2_hostapd_param *param)
2612{
2613 switch (param->cmd) {
2614 case PRISM2_HOSTAPD_FLUSH:
2615 ap_control_kickall(ap);
2616 return 0;
2617 case PRISM2_HOSTAPD_ADD_STA:
2618 return prism2_hostapd_add_sta(ap, param);
2619 case PRISM2_HOSTAPD_REMOVE_STA:
2620 return prism2_hostapd_remove_sta(ap, param);
2621 case PRISM2_HOSTAPD_GET_INFO_STA:
2622 return prism2_hostapd_get_info_sta(ap, param);
2623 case PRISM2_HOSTAPD_SET_FLAGS_STA:
2624 return prism2_hostapd_set_flags_sta(ap, param);
2625 case PRISM2_HOSTAPD_STA_CLEAR_STATS:
2626 return prism2_hostapd_sta_clear_stats(ap, param);
2627 default:
2628 printk(KERN_WARNING "prism2_hostapd: unknown cmd=%d\n",
2629 param->cmd);
2630 return -EOPNOTSUPP;
2631 }
2632}
2633
2634
2635/* Update station info for host-based TX rate control and return current
2636 * TX rate */
2637static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
2638{
2639 int ret = sta->tx_rate;
2640 struct hostap_interface *iface;
2641 local_info_t *local;
2642
2643 iface = netdev_priv(dev);
2644 local = iface->local;
2645
2646 sta->tx_count[sta->tx_rate_idx]++;
2647 sta->tx_since_last_failure++;
2648 sta->tx_consecutive_exc = 0;
2649 if (sta->tx_since_last_failure >= WLAN_RATE_UPDATE_COUNT &&
2650 sta->tx_rate_idx < sta->tx_max_rate) {
2651 /* use next higher rate */
2652 int old_rate, new_rate;
2653 old_rate = new_rate = sta->tx_rate_idx;
2654 while (new_rate < sta->tx_max_rate) {
2655 new_rate++;
2656 if (ap_tx_rate_ok(new_rate, sta, local)) {
2657 sta->tx_rate_idx = new_rate;
2658 break;
2659 }
2660 }
2661 if (old_rate != sta->tx_rate_idx) {
2662 switch (sta->tx_rate_idx) {
2663 case 0: sta->tx_rate = 10; break;
2664 case 1: sta->tx_rate = 20; break;
2665 case 2: sta->tx_rate = 55; break;
2666 case 3: sta->tx_rate = 110; break;
2667 default: sta->tx_rate = 0; break;
2668 }
2669 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate raised to"
2670 " %d\n", dev->name, MAC2STR(sta->addr),
2671 sta->tx_rate);
2672 }
2673 sta->tx_since_last_failure = 0;
2674 }
2675
2676 return ret;
2677}
2678
2679
2680/* Called only from software IRQ. Called for each TX frame prior possible
2681 * encryption and transmit. */
2682ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
2683{
2684 struct sta_info *sta = NULL;
2685 struct sk_buff *skb = tx->skb;
2686 int set_tim, ret;
2687 struct hostap_ieee80211_hdr *hdr;
2688 struct hostap_skb_tx_data *meta;
2689
2690 meta = (struct hostap_skb_tx_data *) skb->cb;
2691 ret = AP_TX_CONTINUE;
2692 if (local->ap == NULL || skb->len < 10 ||
2693 meta->iface->type == HOSTAP_INTERFACE_STA)
2694 goto out;
2695
2696 hdr = (struct hostap_ieee80211_hdr *) skb->data;
2697
2698 if (hdr->addr1[0] & 0x01) {
2699 /* broadcast/multicast frame - no AP related processing */
2700 goto out;
2701 }
2702
2703 /* unicast packet - check whether destination STA is associated */
2704 spin_lock(&local->ap->sta_table_lock);
2705 sta = ap_get_sta(local->ap, hdr->addr1);
2706 if (sta)
2707 atomic_inc(&sta->users);
2708 spin_unlock(&local->ap->sta_table_lock);
2709
2710 if (local->iw_mode == IW_MODE_MASTER && sta == NULL && !meta->wds &&
2711 meta->iface->type != HOSTAP_INTERFACE_MASTER &&
2712 meta->iface->type != HOSTAP_INTERFACE_AP) {
2713#if 0
2714 /* This can happen, e.g., when wlan0 is added to a bridge and
2715 * bridging code does not know which port is the correct target
2716 * for a unicast frame. In this case, the packet is send to all
2717 * ports of the bridge. Since this is a valid scenario, do not
2718 * print out any errors here. */
2719 if (net_ratelimit()) {
2720 printk(KERN_DEBUG "AP: drop packet to non-associated "
2721 "STA " MACSTR "\n", MAC2STR(hdr->addr1));
2722 }
2723#endif
2724 local->ap->tx_drop_nonassoc++;
2725 ret = AP_TX_DROP;
2726 goto out;
2727 }
2728
2729 if (sta == NULL)
2730 goto out;
2731
2732 if (!(sta->flags & WLAN_STA_AUTHORIZED))
2733 ret = AP_TX_CONTINUE_NOT_AUTHORIZED;
2734
2735 /* Set tx_rate if using host-based TX rate control */
2736 if (!local->fw_tx_rate_control)
2737 local->ap->last_tx_rate = meta->rate =
2738 ap_update_sta_tx_rate(sta, local->dev);
2739
2740 if (local->iw_mode != IW_MODE_MASTER)
2741 goto out;
2742
2743 if (!(sta->flags & WLAN_STA_PS))
2744 goto out;
2745
2746 if (memcmp(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN) == 0) {
2747 if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_ADD_MOREDATA) {
2748 /* indicate to STA that more frames follow */
2749 hdr->frame_control |=
2750 __constant_cpu_to_le16(WLAN_FC_MOREDATA);
2751 }
2752
2753 if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_BUFFERED_FRAME) {
2754 /* packet was already buffered and now send due to
2755 * PS poll, so do not rebuffer it */
2756 goto out;
2757 }
2758 }
2759
2760 if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {
2761 PDEBUG(DEBUG_PS, "%s: No more space in STA (" MACSTR ")'s PS "
2762 "mode buffer\n", local->dev->name, MAC2STR(sta->addr));
2763 /* Make sure that TIM is set for the station (it might not be
2764 * after AP wlan hw reset). */
2765 /* FIX: should fix hw reset to restore bits based on STA
2766 * buffer state.. */
2767 hostap_set_tim(local, sta->aid, 1);
2768 sta->flags |= WLAN_STA_TIM;
2769 ret = AP_TX_DROP;
2770 goto out;
2771 }
2772
2773 /* STA in PS mode, buffer frame for later delivery */
2774 set_tim = skb_queue_empty(&sta->tx_buf);
2775 skb_queue_tail(&sta->tx_buf, skb);
2776 /* FIX: could save RX time to skb and expire buffered frames after
2777 * some time if STA does not poll for them */
2778
2779 if (set_tim) {
2780 if (sta->flags & WLAN_STA_TIM)
2781 PDEBUG(DEBUG_PS2, "Re-setting TIM for aid %d\n",
2782 sta->aid);
2783 hostap_set_tim(local, sta->aid, 1);
2784 sta->flags |= WLAN_STA_TIM;
2785 }
2786
2787 ret = AP_TX_BUFFERED;
2788
2789 out:
2790 if (sta != NULL) {
2791 if (ret == AP_TX_CONTINUE ||
2792 ret == AP_TX_CONTINUE_NOT_AUTHORIZED) {
2793 sta->tx_packets++;
2794 sta->tx_bytes += skb->len;
2795 sta->last_tx = jiffies;
2796 }
2797
2798 if ((ret == AP_TX_CONTINUE ||
2799 ret == AP_TX_CONTINUE_NOT_AUTHORIZED) &&
2800 sta->crypt && tx->host_encrypt) {
2801 tx->crypt = sta->crypt;
2802 tx->sta_ptr = sta; /* hostap_handle_sta_release() will
2803 * be called to release sta info
2804 * later */
2805 } else
2806 atomic_dec(&sta->users);
2807 }
2808
2809 return ret;
2810}
2811
2812
2813void hostap_handle_sta_release(void *ptr)
2814{
2815 struct sta_info *sta = ptr;
2816 atomic_dec(&sta->users);
2817}
2818
2819
2820/* Called only as a tasklet (software IRQ) */
2821void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
2822{
2823 struct sta_info *sta;
2824 struct hostap_ieee80211_hdr *hdr;
2825 struct hostap_skb_tx_data *meta;
2826
2827 hdr = (struct hostap_ieee80211_hdr *) skb->data;
2828 meta = (struct hostap_skb_tx_data *) skb->cb;
2829
2830 spin_lock(&local->ap->sta_table_lock);
2831 sta = ap_get_sta(local->ap, hdr->addr1);
2832 if (!sta) {
2833 spin_unlock(&local->ap->sta_table_lock);
2834 PDEBUG(DEBUG_AP, "%s: Could not find STA " MACSTR " for this "
2835 "TX error (@%lu)\n",
2836 local->dev->name, MAC2STR(hdr->addr1), jiffies);
2837 return;
2838 }
2839
2840 sta->tx_since_last_failure = 0;
2841 sta->tx_consecutive_exc++;
2842
2843 if (sta->tx_consecutive_exc >= WLAN_RATE_DECREASE_THRESHOLD &&
2844 sta->tx_rate_idx > 0 && meta->rate <= sta->tx_rate) {
2845 /* use next lower rate */
2846 int old, rate;
2847 old = rate = sta->tx_rate_idx;
2848 while (rate > 0) {
2849 rate--;
2850 if (ap_tx_rate_ok(rate, sta, local)) {
2851 sta->tx_rate_idx = rate;
2852 break;
2853 }
2854 }
2855 if (old != sta->tx_rate_idx) {
2856 switch (sta->tx_rate_idx) {
2857 case 0: sta->tx_rate = 10; break;
2858 case 1: sta->tx_rate = 20; break;
2859 case 2: sta->tx_rate = 55; break;
2860 case 3: sta->tx_rate = 110; break;
2861 default: sta->tx_rate = 0; break;
2862 }
2863 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate lowered "
2864 "to %d\n", local->dev->name, MAC2STR(sta->addr),
2865 sta->tx_rate);
2866 }
2867 sta->tx_consecutive_exc = 0;
2868 }
2869 spin_unlock(&local->ap->sta_table_lock);
2870}
2871
2872
2873static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
2874 int pwrmgt, int type, int stype)
2875{
2876 if (pwrmgt && !(sta->flags & WLAN_STA_PS)) {
2877 sta->flags |= WLAN_STA_PS;
2878 PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to use PS "
2879 "mode (type=0x%02X, stype=0x%02X)\n",
2880 MAC2STR(sta->addr), type, stype);
2881 } else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) {
2882 sta->flags &= ~WLAN_STA_PS;
2883 PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to not use "
2884 "PS mode (type=0x%02X, stype=0x%02X)\n",
2885 MAC2STR(sta->addr), type, stype);
2886 if (type != WLAN_FC_TYPE_CTRL || stype != WLAN_FC_STYPE_PSPOLL)
2887 schedule_packet_send(local, sta);
2888 }
2889}
2890
2891
2892/* Called only as a tasklet (software IRQ). Called for each RX frame to update
2893 * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */
2894int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr)
2895{
2896 struct sta_info *sta;
2897 u16 fc;
2898
2899 spin_lock(&local->ap->sta_table_lock);
2900 sta = ap_get_sta(local->ap, hdr->addr2);
2901 if (sta)
2902 atomic_inc(&sta->users);
2903 spin_unlock(&local->ap->sta_table_lock);
2904
2905 if (!sta)
2906 return -1;
2907
2908 fc = le16_to_cpu(hdr->frame_control);
2909 hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT,
2910 WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
2911
2912 atomic_dec(&sta->users);
2913 return 0;
2914}
2915
2916
2917/* Called only as a tasklet (software IRQ). Called for each RX frame after
2918 * getting RX header and payload from hardware. */
2919ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
2920 struct sk_buff *skb,
2921 struct hostap_80211_rx_status *rx_stats,
2922 int wds)
2923{
2924 int ret;
2925 struct sta_info *sta;
2926 u16 fc, type, stype;
2927 struct hostap_ieee80211_hdr *hdr;
2928
2929 if (local->ap == NULL)
2930 return AP_RX_CONTINUE;
2931
2932 hdr = (struct hostap_ieee80211_hdr *) skb->data;
2933
2934 fc = le16_to_cpu(hdr->frame_control);
2935 type = WLAN_FC_GET_TYPE(fc);
2936 stype = WLAN_FC_GET_STYPE(fc);
2937
2938 spin_lock(&local->ap->sta_table_lock);
2939 sta = ap_get_sta(local->ap, hdr->addr2);
2940 if (sta)
2941 atomic_inc(&sta->users);
2942 spin_unlock(&local->ap->sta_table_lock);
2943
2944 if (sta && !(sta->flags & WLAN_STA_AUTHORIZED))
2945 ret = AP_RX_CONTINUE_NOT_AUTHORIZED;
2946 else
2947 ret = AP_RX_CONTINUE;
2948
2949
2950 if (fc & WLAN_FC_TODS) {
2951 if (!wds && (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
2952 if (local->hostapd) {
2953 prism2_rx_80211(local->apdev, skb, rx_stats,
2954 PRISM2_RX_NON_ASSOC);
2955#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2956 } else {
2957 printk(KERN_DEBUG "%s: dropped received packet"
2958 " from non-associated STA " MACSTR
2959 " (type=0x%02x, subtype=0x%02x)\n",
2960 dev->name, MAC2STR(hdr->addr2), type,
2961 stype);
2962 hostap_rx(dev, skb, rx_stats);
2963#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2964 }
2965 ret = AP_RX_EXIT;
2966 goto out;
2967 }
2968 } else if (fc & WLAN_FC_FROMDS) {
2969 if (!wds) {
2970 /* FromDS frame - not for us; probably
2971 * broadcast/multicast in another BSS - drop */
2972 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
2973 printk(KERN_DEBUG "Odd.. FromDS packet "
2974 "received with own BSSID\n");
2975 hostap_dump_rx_80211(dev->name, skb, rx_stats);
2976 }
2977 ret = AP_RX_DROP;
2978 goto out;
2979 }
2980 } else if (stype == WLAN_FC_STYPE_NULLFUNC && sta == NULL &&
2981 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
2982
2983 if (local->hostapd) {
2984 prism2_rx_80211(local->apdev, skb, rx_stats,
2985 PRISM2_RX_NON_ASSOC);
2986#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2987 } else {
2988 /* At least Lucent f/w seems to send data::nullfunc
2989 * frames with no ToDS flag when the current AP returns
2990 * after being unavailable for some time. Speed up
2991 * re-association by informing the station about it not
2992 * being associated. */
2993 printk(KERN_DEBUG "%s: rejected received nullfunc "
2994 "frame without ToDS from not associated STA "
2995 MACSTR "\n",
2996 dev->name, MAC2STR(hdr->addr2));
2997 hostap_rx(dev, skb, rx_stats);
2998#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2999 }
3000 ret = AP_RX_EXIT;
3001 goto out;
3002 } else if (stype == WLAN_FC_STYPE_NULLFUNC) {
3003 /* At least Lucent cards seem to send periodic nullfunc
3004 * frames with ToDS. Let these through to update SQ
3005 * stats and PS state. Nullfunc frames do not contain
3006 * any data and they will be dropped below. */
3007 } else {
3008 /* If BSSID (Addr3) is foreign, this frame is a normal
3009 * broadcast frame from an IBSS network. Drop it silently.
3010 * If BSSID is own, report the dropping of this frame. */
3011 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
3012 printk(KERN_DEBUG "%s: dropped received packet from "
3013 MACSTR " with no ToDS flag (type=0x%02x, "
3014 "subtype=0x%02x)\n", dev->name,
3015 MAC2STR(hdr->addr2), type, stype);
3016 hostap_dump_rx_80211(dev->name, skb, rx_stats);
3017 }
3018 ret = AP_RX_DROP;
3019 goto out;
3020 }
3021
3022 if (sta) {
3023 hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT,
3024 type, stype);
3025
3026 sta->rx_packets++;
3027 sta->rx_bytes += skb->len;
3028 sta->last_rx = jiffies;
3029 }
3030
3031 if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC &&
3032 fc & WLAN_FC_TODS) {
3033 if (local->hostapd) {
3034 prism2_rx_80211(local->apdev, skb, rx_stats,
3035 PRISM2_RX_NULLFUNC_ACK);
3036#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3037 } else {
3038 /* some STA f/w's seem to require control::ACK frame
3039 * for data::nullfunc, but Prism2 f/w 0.8.0 (at least
3040 * from Compaq) does not send this.. Try to generate
3041 * ACK for these frames from the host driver to make
3042 * power saving work with, e.g., Lucent WaveLAN f/w */
3043 hostap_rx(dev, skb, rx_stats);
3044#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3045 }
3046 ret = AP_RX_EXIT;
3047 goto out;
3048 }
3049
3050 out:
3051 if (sta)
3052 atomic_dec(&sta->users);
3053
3054 return ret;
3055}
3056
3057
3058/* Called only as a tasklet (software IRQ) */
3059int hostap_handle_sta_crypto(local_info_t *local,
3060 struct hostap_ieee80211_hdr *hdr,
3061 struct prism2_crypt_data **crypt, void **sta_ptr)
3062{
3063 struct sta_info *sta;
3064
3065 spin_lock(&local->ap->sta_table_lock);
3066 sta = ap_get_sta(local->ap, hdr->addr2);
3067 if (sta)
3068 atomic_inc(&sta->users);
3069 spin_unlock(&local->ap->sta_table_lock);
3070
3071 if (!sta)
3072 return -1;
3073
3074 if (sta->crypt) {
3075 *crypt = sta->crypt;
3076 *sta_ptr = sta;
3077 /* hostap_handle_sta_release() will be called to release STA
3078 * info */
3079 } else
3080 atomic_dec(&sta->users);
3081
3082 return 0;
3083}
3084
3085
3086/* Called only as a tasklet (software IRQ) */
3087int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr)
3088{
3089 struct sta_info *sta;
3090 int ret = 0;
3091
3092 spin_lock(&ap->sta_table_lock);
3093 sta = ap_get_sta(ap, sta_addr);
3094 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap)
3095 ret = 1;
3096 spin_unlock(&ap->sta_table_lock);
3097
3098 return ret;
3099}
3100
3101
3102/* Called only as a tasklet (software IRQ) */
3103int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr)
3104{
3105 struct sta_info *sta;
3106 int ret = 0;
3107
3108 spin_lock(&ap->sta_table_lock);
3109 sta = ap_get_sta(ap, sta_addr);
3110 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap &&
3111 ((sta->flags & WLAN_STA_AUTHORIZED) ||
3112 ap->local->ieee_802_1x == 0))
3113 ret = 1;
3114 spin_unlock(&ap->sta_table_lock);
3115
3116 return ret;
3117}
3118
3119
3120/* Called only as a tasklet (software IRQ) */
3121int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
3122{
3123 struct sta_info *sta;
3124 int ret = 1;
3125
3126 if (!ap)
3127 return -1;
3128
3129 spin_lock(&ap->sta_table_lock);
3130 sta = ap_get_sta(ap, sta_addr);
3131 if (sta)
3132 ret = 0;
3133 spin_unlock(&ap->sta_table_lock);
3134
3135 if (ret == 1) {
3136 sta = ap_add_sta(ap, sta_addr);
3137 if (!sta)
3138 ret = -1;
3139 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
3140 sta->ap = 1;
3141 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
3142 /* No way of knowing which rates are supported since we did not
3143 * get supported rates element from beacon/assoc req. Assume
3144 * that remote end supports all 802.11b rates. */
3145 sta->supported_rates[0] = 0x82;
3146 sta->supported_rates[1] = 0x84;
3147 sta->supported_rates[2] = 0x0b;
3148 sta->supported_rates[3] = 0x16;
3149 sta->tx_supp_rates = WLAN_RATE_1M | WLAN_RATE_2M |
3150 WLAN_RATE_5M5 | WLAN_RATE_11M;
3151 sta->tx_rate = 110;
3152 sta->tx_max_rate = sta->tx_rate_idx = 3;
3153 }
3154
3155 return ret;
3156}
3157
3158
3159/* Called only as a tasklet (software IRQ) */
3160int hostap_update_rx_stats(struct ap_data *ap,
3161 struct hostap_ieee80211_hdr *hdr,
3162 struct hostap_80211_rx_status *rx_stats)
3163{
3164 struct sta_info *sta;
3165
3166 if (!ap)
3167 return -1;
3168
3169 spin_lock(&ap->sta_table_lock);
3170 sta = ap_get_sta(ap, hdr->addr2);
3171 if (sta) {
3172 sta->last_rx_silence = rx_stats->noise;
3173 sta->last_rx_signal = rx_stats->signal;
3174 sta->last_rx_rate = rx_stats->rate;
3175 sta->last_rx_updated = 7;
3176 if (rx_stats->rate == 10)
3177 sta->rx_count[0]++;
3178 else if (rx_stats->rate == 20)
3179 sta->rx_count[1]++;
3180 else if (rx_stats->rate == 55)
3181 sta->rx_count[2]++;
3182 else if (rx_stats->rate == 110)
3183 sta->rx_count[3]++;
3184 }
3185 spin_unlock(&ap->sta_table_lock);
3186
3187 return sta ? 0 : -1;
3188}
3189
3190
3191void hostap_update_rates(local_info_t *local)
3192{
3193 struct list_head *ptr;
3194 struct ap_data *ap = local->ap;
3195
3196 if (!ap)
3197 return;
3198
3199 spin_lock_bh(&ap->sta_table_lock);
3200 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
3201 struct sta_info *sta = (struct sta_info *) ptr;
3202 prism2_check_tx_rates(sta);
3203 }
3204 spin_unlock_bh(&ap->sta_table_lock);
3205}
3206
3207
3208static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
3209 struct prism2_crypt_data ***crypt)
3210{
3211 struct sta_info *sta;
3212
3213 spin_lock_bh(&ap->sta_table_lock);
3214 sta = ap_get_sta(ap, addr);
3215 if (sta)
3216 atomic_inc(&sta->users);
3217 spin_unlock_bh(&ap->sta_table_lock);
3218
3219 if (!sta && permanent)
3220 sta = ap_add_sta(ap, addr);
3221
3222 if (!sta)
3223 return NULL;
3224
3225 if (permanent)
3226 sta->flags |= WLAN_STA_PERM;
3227
3228 *crypt = &sta->crypt;
3229
3230 return sta;
3231}
3232
3233
3234void hostap_add_wds_links(local_info_t *local)
3235{
3236 struct ap_data *ap = local->ap;
3237 struct list_head *ptr;
3238
3239 spin_lock_bh(&ap->sta_table_lock);
3240 list_for_each(ptr, &ap->sta_list) {
3241 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
3242 if (sta->ap)
3243 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
3244 }
3245 spin_unlock_bh(&ap->sta_table_lock);
3246
3247 schedule_work(&local->ap->wds_oper_queue);
3248}
3249
3250
3251void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type)
3252{
3253 struct wds_oper_data *entry;
3254
3255 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
3256 if (!entry)
3257 return;
3258 memcpy(entry->addr, addr, ETH_ALEN);
3259 entry->type = type;
3260 spin_lock_bh(&local->lock);
3261 entry->next = local->ap->wds_oper_entries;
3262 local->ap->wds_oper_entries = entry;
3263 spin_unlock_bh(&local->lock);
3264
3265 schedule_work(&local->ap->wds_oper_queue);
3266}
3267
3268
3269EXPORT_SYMBOL(hostap_init_data);
3270EXPORT_SYMBOL(hostap_init_ap_proc);
3271EXPORT_SYMBOL(hostap_free_data);
3272EXPORT_SYMBOL(hostap_check_sta_fw_version);
3273EXPORT_SYMBOL(hostap_handle_sta_tx);
3274EXPORT_SYMBOL(hostap_handle_sta_release);
3275EXPORT_SYMBOL(hostap_handle_sta_tx_exc);
3276EXPORT_SYMBOL(hostap_update_sta_ps);
3277EXPORT_SYMBOL(hostap_handle_sta_rx);
3278EXPORT_SYMBOL(hostap_is_sta_assoc);
3279EXPORT_SYMBOL(hostap_is_sta_authorized);
3280EXPORT_SYMBOL(hostap_add_sta);
3281EXPORT_SYMBOL(hostap_update_rates);
3282EXPORT_SYMBOL(hostap_add_wds_links);
3283EXPORT_SYMBOL(hostap_wds_link_oper);
3284#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3285EXPORT_SYMBOL(hostap_deauth_all_stas);
3286#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
new file mode 100644
index 000000000000..10137f44436d
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -0,0 +1,272 @@
1#ifndef HOSTAP_AP_H
2#define HOSTAP_AP_H
3
4/* AP data structures for STAs */
5
6/* maximum number of frames to buffer per STA */
7#define STA_MAX_TX_BUFFER 32
8
9/* Flags used in skb->cb[6] to control how the packet is handled in TX path.
10 * skb->cb[0..5] must contain magic value 'hostap' to indicate that cb[6] is
11 * used. */
12#define AP_SKB_CB_MAGIC "hostap"
13#define AP_SKB_CB_MAGIC_LEN 6
14#define AP_SKB_CB_BUFFERED_FRAME BIT(0)
15#define AP_SKB_CB_ADD_MOREDATA BIT(1)
16
17
18/* STA flags */
19#define WLAN_STA_AUTH BIT(0)
20#define WLAN_STA_ASSOC BIT(1)
21#define WLAN_STA_PS BIT(2)
22#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */
23#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */
24#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is
25 * controlling whether STA is authorized to
26 * send and receive non-IEEE 802.1X frames
27 */
28#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
29
30#define WLAN_RATE_1M BIT(0)
31#define WLAN_RATE_2M BIT(1)
32#define WLAN_RATE_5M5 BIT(2)
33#define WLAN_RATE_11M BIT(3)
34#define WLAN_RATE_COUNT 4
35
36/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8,
37 * but some pre-standard IEEE 802.11g products use longer elements. */
38#define WLAN_SUPP_RATES_MAX 32
39
40/* Try to increase TX rate after # successfully sent consecutive packets */
41#define WLAN_RATE_UPDATE_COUNT 50
42
43/* Decrease TX rate after # consecutive dropped packets */
44#define WLAN_RATE_DECREASE_THRESHOLD 2
45
46struct sta_info {
47 struct list_head list;
48 struct sta_info *hnext; /* next entry in hash table list */
49 atomic_t users; /* number of users (do not remove if > 0) */
50 struct proc_dir_entry *proc;
51
52 u8 addr[6];
53 u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
54 u32 flags;
55 u16 capability;
56 u16 listen_interval; /* or beacon_int for APs */
57 u8 supported_rates[WLAN_SUPP_RATES_MAX];
58
59 unsigned long last_auth;
60 unsigned long last_assoc;
61 unsigned long last_rx;
62 unsigned long last_tx;
63 unsigned long rx_packets, tx_packets;
64 unsigned long rx_bytes, tx_bytes;
65 struct sk_buff_head tx_buf;
66 /* FIX: timeout buffers with an expiry time somehow derived from
67 * listen_interval */
68
69 s8 last_rx_silence; /* Noise in dBm */
70 s8 last_rx_signal; /* Signal strength in dBm */
71 u8 last_rx_rate; /* TX rate in 0.1 Mbps */
72 u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */
73
74 u8 tx_supp_rates; /* bit field of supported TX rates */
75 u8 tx_rate; /* current TX rate (in 0.1 Mbps) */
76 u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */
77 u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */
78 u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */
79 u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate)
80 */
81 u32 tx_since_last_failure;
82 u32 tx_consecutive_exc;
83
84 struct prism2_crypt_data *crypt;
85
86 int ap; /* whether this station is an AP */
87
88 local_info_t *local;
89
90#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
91 union {
92 struct {
93 char *challenge; /* shared key authentication
94 * challenge */
95 } sta;
96 struct {
97 int ssid_len;
98 unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */
99 int channel;
100 unsigned long last_beacon; /* last RX beacon time */
101 } ap;
102 } u;
103
104 struct timer_list timer;
105 enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next;
106#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
107};
108
109
110#define MAX_STA_COUNT 1024
111
112/* Maximum number of AIDs to use for STAs; must be 2007 or lower
113 * (8802.11 limitation) */
114#define MAX_AID_TABLE_SIZE 128
115
116#define STA_HASH_SIZE 256
117#define STA_HASH(sta) (sta[5])
118
119
120/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC
121 * has passed since last received frame from the station, a nullfunc data
122 * frame is sent to the station. If this frame is not acknowledged and no other
123 * frames have been received, the station will be disassociated after
124 * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after
125 * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
126 * max inactivity timer. */
127#define AP_MAX_INACTIVITY_SEC (5 * 60)
128#define AP_DISASSOC_DELAY (HZ)
129#define AP_DEAUTH_DELAY (HZ)
130
131/* ap_policy: whether to accept frames to/from other APs/IBSS */
132typedef enum {
133 AP_OTHER_AP_SKIP_ALL = 0,
134 AP_OTHER_AP_SAME_SSID = 1,
135 AP_OTHER_AP_ALL = 2,
136 AP_OTHER_AP_EVEN_IBSS = 3
137} ap_policy_enum;
138
139#define PRISM2_AUTH_OPEN BIT(0)
140#define PRISM2_AUTH_SHARED_KEY BIT(1)
141
142
143/* MAC address-based restrictions */
144struct mac_entry {
145 struct list_head list;
146 u8 addr[6];
147};
148
149struct mac_restrictions {
150 enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy;
151 unsigned int entries;
152 struct list_head mac_list;
153 spinlock_t lock;
154};
155
156
157struct add_sta_proc_data {
158 u8 addr[ETH_ALEN];
159 struct add_sta_proc_data *next;
160};
161
162
163typedef enum { WDS_ADD, WDS_DEL } wds_oper_type;
164struct wds_oper_data {
165 wds_oper_type type;
166 u8 addr[ETH_ALEN];
167 struct wds_oper_data *next;
168};
169
170
171struct ap_data {
172 int initialized; /* whether ap_data has been initialized */
173 local_info_t *local;
174 int bridge_packets; /* send packet to associated STAs directly to the
175 * wireless media instead of higher layers in the
176 * kernel */
177 unsigned int bridged_unicast; /* number of unicast frames bridged on
178 * wireless media */
179 unsigned int bridged_multicast; /* number of non-unicast frames
180 * bridged on wireless media */
181 unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped
182 * because they were to an address that
183 * was not associated */
184 int nullfunc_ack; /* use workaround for nullfunc frame ACKs */
185
186 spinlock_t sta_table_lock;
187 int num_sta; /* number of entries in sta_list */
188 struct list_head sta_list; /* STA info list head */
189 struct sta_info *sta_hash[STA_HASH_SIZE];
190
191 struct proc_dir_entry *proc;
192
193 ap_policy_enum ap_policy;
194 unsigned int max_inactivity;
195 int autom_ap_wds;
196
197 struct mac_restrictions mac_restrictions; /* MAC-based auth */
198 int last_tx_rate;
199
200 struct work_struct add_sta_proc_queue;
201 struct add_sta_proc_data *add_sta_proc_entries;
202
203 struct work_struct wds_oper_queue;
204 struct wds_oper_data *wds_oper_entries;
205
206 u16 tx_callback_idx;
207
208#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
209 /* pointers to STA info; based on allocated AID or NULL if AID free
210 * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
211 * and so on
212 */
213 struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
214
215 u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll;
216
217 /* WEP operations for generating challenges to be used with shared key
218 * authentication */
219 struct hostap_crypto_ops *crypt;
220 void *crypt_priv;
221#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
222};
223
224
225void hostap_rx(struct net_device *dev, struct sk_buff *skb,
226 struct hostap_80211_rx_status *rx_stats);
227void hostap_init_data(local_info_t *local);
228void hostap_init_ap_proc(local_info_t *local);
229void hostap_free_data(struct ap_data *ap);
230void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver);
231
232typedef enum {
233 AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED,
234 AP_TX_CONTINUE_NOT_AUTHORIZED
235} ap_tx_ret;
236struct hostap_tx_data {
237 struct sk_buff *skb;
238 int host_encrypt;
239 struct prism2_crypt_data *crypt;
240 void *sta_ptr;
241};
242ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
243void hostap_handle_sta_release(void *ptr);
244void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
245int hostap_update_sta_ps(local_info_t *local,
246 struct hostap_ieee80211_hdr *hdr);
247typedef enum {
248 AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
249} ap_rx_ret;
250ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
251 struct sk_buff *skb,
252 struct hostap_80211_rx_status *rx_stats,
253 int wds);
254int hostap_handle_sta_crypto(local_info_t *local,
255 struct hostap_ieee80211_hdr *hdr,
256 struct prism2_crypt_data **crypt, void **sta_ptr);
257int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
258int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
259int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
260int hostap_update_rx_stats(struct ap_data *ap,
261 struct hostap_ieee80211_hdr *hdr,
262 struct hostap_80211_rx_status *rx_stats);
263void hostap_update_rates(local_info_t *local);
264void hostap_add_wds_links(local_info_t *local);
265void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type);
266
267#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
268void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
269 int resend);
270#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
271
272#endif /* HOSTAP_AP_H */
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
new file mode 100644
index 000000000000..1a9610add695
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -0,0 +1,557 @@
1#ifndef HOSTAP_COMMON_H
2#define HOSTAP_COMMON_H
3
4#define BIT(x) (1 << (x))
5
6#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
7#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
8
9
10#ifndef ETH_P_PAE
11#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
12#endif /* ETH_P_PAE */
13
14#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
15
16
17
18/* IEEE 802.11 defines */
19
20#define WLAN_FC_PVER (BIT(1) | BIT(0))
21#define WLAN_FC_TODS BIT(8)
22#define WLAN_FC_FROMDS BIT(9)
23#define WLAN_FC_MOREFRAG BIT(10)
24#define WLAN_FC_RETRY BIT(11)
25#define WLAN_FC_PWRMGT BIT(12)
26#define WLAN_FC_MOREDATA BIT(13)
27#define WLAN_FC_ISWEP BIT(14)
28#define WLAN_FC_ORDER BIT(15)
29
30#define WLAN_FC_GET_TYPE(fc) (((fc) & (BIT(3) | BIT(2))) >> 2)
31#define WLAN_FC_GET_STYPE(fc) \
32 (((fc) & (BIT(7) | BIT(6) | BIT(5) | BIT(4))) >> 4)
33
34#define WLAN_GET_SEQ_FRAG(seq) ((seq) & (BIT(3) | BIT(2) | BIT(1) | BIT(0)))
35#define WLAN_GET_SEQ_SEQ(seq) \
36 (((seq) & (~(BIT(3) | BIT(2) | BIT(1) | BIT(0)))) >> 4)
37
38#define WLAN_FC_TYPE_MGMT 0
39#define WLAN_FC_TYPE_CTRL 1
40#define WLAN_FC_TYPE_DATA 2
41
42/* management */
43#define WLAN_FC_STYPE_ASSOC_REQ 0
44#define WLAN_FC_STYPE_ASSOC_RESP 1
45#define WLAN_FC_STYPE_REASSOC_REQ 2
46#define WLAN_FC_STYPE_REASSOC_RESP 3
47#define WLAN_FC_STYPE_PROBE_REQ 4
48#define WLAN_FC_STYPE_PROBE_RESP 5
49#define WLAN_FC_STYPE_BEACON 8
50#define WLAN_FC_STYPE_ATIM 9
51#define WLAN_FC_STYPE_DISASSOC 10
52#define WLAN_FC_STYPE_AUTH 11
53#define WLAN_FC_STYPE_DEAUTH 12
54
55/* control */
56#define WLAN_FC_STYPE_PSPOLL 10
57#define WLAN_FC_STYPE_RTS 11
58#define WLAN_FC_STYPE_CTS 12
59#define WLAN_FC_STYPE_ACK 13
60#define WLAN_FC_STYPE_CFEND 14
61#define WLAN_FC_STYPE_CFENDACK 15
62
63/* data */
64#define WLAN_FC_STYPE_DATA 0
65#define WLAN_FC_STYPE_DATA_CFACK 1
66#define WLAN_FC_STYPE_DATA_CFPOLL 2
67#define WLAN_FC_STYPE_DATA_CFACKPOLL 3
68#define WLAN_FC_STYPE_NULLFUNC 4
69#define WLAN_FC_STYPE_CFACK 5
70#define WLAN_FC_STYPE_CFPOLL 6
71#define WLAN_FC_STYPE_CFACKPOLL 7
72
73/* Authentication algorithms */
74#define WLAN_AUTH_OPEN 0
75#define WLAN_AUTH_SHARED_KEY 1
76
77#define WLAN_AUTH_CHALLENGE_LEN 128
78
79#define WLAN_CAPABILITY_ESS BIT(0)
80#define WLAN_CAPABILITY_IBSS BIT(1)
81#define WLAN_CAPABILITY_CF_POLLABLE BIT(2)
82#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3)
83#define WLAN_CAPABILITY_PRIVACY BIT(4)
84
85/* Status codes */
86#define WLAN_STATUS_SUCCESS 0
87#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
88#define WLAN_STATUS_CAPS_UNSUPPORTED 10
89#define WLAN_STATUS_REASSOC_NO_ASSOC 11
90#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
91#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
92#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
93#define WLAN_STATUS_CHALLENGE_FAIL 15
94#define WLAN_STATUS_AUTH_TIMEOUT 16
95#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
96#define WLAN_STATUS_ASSOC_DENIED_RATES 18
97/* 802.11b */
98#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
99#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
100#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
101/* IEEE 802.11i */
102#define WLAN_STATUS_INVALID_IE 40
103#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41
104#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42
105#define WLAN_STATUS_AKMP_NOT_VALID 43
106#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44
107#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45
108#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46
109
110/* Reason codes */
111#define WLAN_REASON_UNSPECIFIED 1
112#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
113#define WLAN_REASON_DEAUTH_LEAVING 3
114#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
115#define WLAN_REASON_DISASSOC_AP_BUSY 5
116#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
117#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
118#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
119#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
120/* IEEE 802.11i */
121#define WLAN_REASON_INVALID_IE 13
122#define WLAN_REASON_MICHAEL_MIC_FAILURE 14
123#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15
124#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16
125#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17
126#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18
127#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19
128#define WLAN_REASON_AKMP_NOT_VALID 20
129#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21
130#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22
131#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23
132#define WLAN_REASON_CIPHER_SUITE_REJECTED 24
133
134
135/* Information Element IDs */
136#define WLAN_EID_SSID 0
137#define WLAN_EID_SUPP_RATES 1
138#define WLAN_EID_FH_PARAMS 2
139#define WLAN_EID_DS_PARAMS 3
140#define WLAN_EID_CF_PARAMS 4
141#define WLAN_EID_TIM 5
142#define WLAN_EID_IBSS_PARAMS 6
143#define WLAN_EID_CHALLENGE 16
144#define WLAN_EID_RSN 48
145#define WLAN_EID_GENERIC 221
146
147
148/* HFA384X Configuration RIDs */
149#define HFA384X_RID_CNFPORTTYPE 0xFC00
150#define HFA384X_RID_CNFOWNMACADDR 0xFC01
151#define HFA384X_RID_CNFDESIREDSSID 0xFC02
152#define HFA384X_RID_CNFOWNCHANNEL 0xFC03
153#define HFA384X_RID_CNFOWNSSID 0xFC04
154#define HFA384X_RID_CNFOWNATIMWINDOW 0xFC05
155#define HFA384X_RID_CNFSYSTEMSCALE 0xFC06
156#define HFA384X_RID_CNFMAXDATALEN 0xFC07
157#define HFA384X_RID_CNFWDSADDRESS 0xFC08
158#define HFA384X_RID_CNFPMENABLED 0xFC09
159#define HFA384X_RID_CNFPMEPS 0xFC0A
160#define HFA384X_RID_CNFMULTICASTRECEIVE 0xFC0B
161#define HFA384X_RID_CNFMAXSLEEPDURATION 0xFC0C
162#define HFA384X_RID_CNFPMHOLDOVERDURATION 0xFC0D
163#define HFA384X_RID_CNFOWNNAME 0xFC0E
164#define HFA384X_RID_CNFOWNDTIMPERIOD 0xFC10
165#define HFA384X_RID_CNFWDSADDRESS1 0xFC11 /* AP f/w only */
166#define HFA384X_RID_CNFWDSADDRESS2 0xFC12 /* AP f/w only */
167#define HFA384X_RID_CNFWDSADDRESS3 0xFC13 /* AP f/w only */
168#define HFA384X_RID_CNFWDSADDRESS4 0xFC14 /* AP f/w only */
169#define HFA384X_RID_CNFWDSADDRESS5 0xFC15 /* AP f/w only */
170#define HFA384X_RID_CNFWDSADDRESS6 0xFC16 /* AP f/w only */
171#define HFA384X_RID_CNFMULTICASTPMBUFFERING 0xFC17 /* AP f/w only */
172#define HFA384X_RID_UNKNOWN1 0xFC20
173#define HFA384X_RID_UNKNOWN2 0xFC21
174#define HFA384X_RID_CNFWEPDEFAULTKEYID 0xFC23
175#define HFA384X_RID_CNFDEFAULTKEY0 0xFC24
176#define HFA384X_RID_CNFDEFAULTKEY1 0xFC25
177#define HFA384X_RID_CNFDEFAULTKEY2 0xFC26
178#define HFA384X_RID_CNFDEFAULTKEY3 0xFC27
179#define HFA384X_RID_CNFWEPFLAGS 0xFC28
180#define HFA384X_RID_CNFWEPKEYMAPPINGTABLE 0xFC29
181#define HFA384X_RID_CNFAUTHENTICATION 0xFC2A
182#define HFA384X_RID_CNFMAXASSOCSTA 0xFC2B /* AP f/w only */
183#define HFA384X_RID_CNFTXCONTROL 0xFC2C
184#define HFA384X_RID_CNFROAMINGMODE 0xFC2D
185#define HFA384X_RID_CNFHOSTAUTHENTICATION 0xFC2E /* AP f/w only */
186#define HFA384X_RID_CNFRCVCRCERROR 0xFC30
187#define HFA384X_RID_CNFMMLIFE 0xFC31
188#define HFA384X_RID_CNFALTRETRYCOUNT 0xFC32
189#define HFA384X_RID_CNFBEACONINT 0xFC33
190#define HFA384X_RID_CNFAPPCFINFO 0xFC34 /* AP f/w only */
191#define HFA384X_RID_CNFSTAPCFINFO 0xFC35
192#define HFA384X_RID_CNFPRIORITYQUSAGE 0xFC37
193#define HFA384X_RID_CNFTIMCTRL 0xFC40
194#define HFA384X_RID_UNKNOWN3 0xFC41 /* added in STA f/w 0.7.x */
195#define HFA384X_RID_CNFTHIRTY2TALLY 0xFC42 /* added in STA f/w 0.8.0 */
196#define HFA384X_RID_CNFENHSECURITY 0xFC43 /* AP f/w or STA f/w >= 1.6.3 */
197#define HFA384X_RID_CNFDBMADJUST 0xFC46 /* added in STA f/w 1.3.1 */
198#define HFA384X_RID_GENERICELEMENT 0xFC48 /* added in STA f/w 1.7.0;
199 * write only */
200#define HFA384X_RID_PROPAGATIONDELAY 0xFC49 /* added in STA f/w 1.7.6 */
201#define HFA384X_RID_GROUPADDRESSES 0xFC80
202#define HFA384X_RID_CREATEIBSS 0xFC81
203#define HFA384X_RID_FRAGMENTATIONTHRESHOLD 0xFC82
204#define HFA384X_RID_RTSTHRESHOLD 0xFC83
205#define HFA384X_RID_TXRATECONTROL 0xFC84
206#define HFA384X_RID_PROMISCUOUSMODE 0xFC85
207#define HFA384X_RID_FRAGMENTATIONTHRESHOLD0 0xFC90 /* AP f/w only */
208#define HFA384X_RID_FRAGMENTATIONTHRESHOLD1 0xFC91 /* AP f/w only */
209#define HFA384X_RID_FRAGMENTATIONTHRESHOLD2 0xFC92 /* AP f/w only */
210#define HFA384X_RID_FRAGMENTATIONTHRESHOLD3 0xFC93 /* AP f/w only */
211#define HFA384X_RID_FRAGMENTATIONTHRESHOLD4 0xFC94 /* AP f/w only */
212#define HFA384X_RID_FRAGMENTATIONTHRESHOLD5 0xFC95 /* AP f/w only */
213#define HFA384X_RID_FRAGMENTATIONTHRESHOLD6 0xFC96 /* AP f/w only */
214#define HFA384X_RID_RTSTHRESHOLD0 0xFC97 /* AP f/w only */
215#define HFA384X_RID_RTSTHRESHOLD1 0xFC98 /* AP f/w only */
216#define HFA384X_RID_RTSTHRESHOLD2 0xFC99 /* AP f/w only */
217#define HFA384X_RID_RTSTHRESHOLD3 0xFC9A /* AP f/w only */
218#define HFA384X_RID_RTSTHRESHOLD4 0xFC9B /* AP f/w only */
219#define HFA384X_RID_RTSTHRESHOLD5 0xFC9C /* AP f/w only */
220#define HFA384X_RID_RTSTHRESHOLD6 0xFC9D /* AP f/w only */
221#define HFA384X_RID_TXRATECONTROL0 0xFC9E /* AP f/w only */
222#define HFA384X_RID_TXRATECONTROL1 0xFC9F /* AP f/w only */
223#define HFA384X_RID_TXRATECONTROL2 0xFCA0 /* AP f/w only */
224#define HFA384X_RID_TXRATECONTROL3 0xFCA1 /* AP f/w only */
225#define HFA384X_RID_TXRATECONTROL4 0xFCA2 /* AP f/w only */
226#define HFA384X_RID_TXRATECONTROL5 0xFCA3 /* AP f/w only */
227#define HFA384X_RID_TXRATECONTROL6 0xFCA4 /* AP f/w only */
228#define HFA384X_RID_CNFSHORTPREAMBLE 0xFCB0
229#define HFA384X_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1
230#define HFA384X_RID_CNFAUTHENTICATIONRSPTO 0xFCB2
231#define HFA384X_RID_CNFBASICRATES 0xFCB3
232#define HFA384X_RID_CNFSUPPORTEDRATES 0xFCB4
233#define HFA384X_RID_CNFFALLBACKCTRL 0xFCB5 /* added in STA f/w 1.3.1 */
234#define HFA384X_RID_WEPKEYDISABLE 0xFCB6 /* added in STA f/w 1.3.1 */
235#define HFA384X_RID_WEPKEYMAPINDEX 0xFCB7 /* ? */
236#define HFA384X_RID_BROADCASTKEYID 0xFCB8 /* ? */
237#define HFA384X_RID_ENTSECFLAGEYID 0xFCB9 /* ? */
238#define HFA384X_RID_CNFPASSIVESCANCTRL 0xFCBA /* added in STA f/w 1.5.0 */
239#define HFA384X_RID_SSNHANDLINGMODE 0xFCBB /* added in STA f/w 1.7.0 */
240#define HFA384X_RID_MDCCONTROL 0xFCBC /* added in STA f/w 1.7.0 */
241#define HFA384X_RID_MDCCOUNTRY 0xFCBD /* added in STA f/w 1.7.0 */
242#define HFA384X_RID_TXPOWERMAX 0xFCBE /* added in STA f/w 1.7.0 */
243#define HFA384X_RID_CNFLFOENABLED 0xFCBF /* added in STA f/w 1.6.3 */
244#define HFA384X_RID_CAPINFO 0xFCC0 /* added in STA f/w 1.7.0 */
245#define HFA384X_RID_LISTENINTERVAL 0xFCC1 /* added in STA f/w 1.7.0 */
246#define HFA384X_RID_SW_ANT_DIV 0xFCC2 /* added in STA f/w 1.7.0; Prism3 */
247#define HFA384X_RID_LED_CTRL 0xFCC4 /* added in STA f/w 1.7.6 */
248#define HFA384X_RID_HFODELAY 0xFCC5 /* added in STA f/w 1.7.6 */
249#define HFA384X_RID_DISALLOWEDBSSID 0xFCC6 /* added in STA f/w 1.8.0 */
250#define HFA384X_RID_TICKTIME 0xFCE0
251#define HFA384X_RID_SCANREQUEST 0xFCE1
252#define HFA384X_RID_JOINREQUEST 0xFCE2
253#define HFA384X_RID_AUTHENTICATESTATION 0xFCE3 /* AP f/w only */
254#define HFA384X_RID_CHANNELINFOREQUEST 0xFCE4 /* AP f/w only */
255#define HFA384X_RID_HOSTSCAN 0xFCE5 /* added in STA f/w 1.3.1 */
256
257/* HFA384X Information RIDs */
258#define HFA384X_RID_MAXLOADTIME 0xFD00
259#define HFA384X_RID_DOWNLOADBUFFER 0xFD01
260#define HFA384X_RID_PRIID 0xFD02
261#define HFA384X_RID_PRISUPRANGE 0xFD03
262#define HFA384X_RID_CFIACTRANGES 0xFD04
263#define HFA384X_RID_NICSERNUM 0xFD0A
264#define HFA384X_RID_NICID 0xFD0B
265#define HFA384X_RID_MFISUPRANGE 0xFD0C
266#define HFA384X_RID_CFISUPRANGE 0xFD0D
267#define HFA384X_RID_CHANNELLIST 0xFD10
268#define HFA384X_RID_REGULATORYDOMAINS 0xFD11
269#define HFA384X_RID_TEMPTYPE 0xFD12
270#define HFA384X_RID_CIS 0xFD13
271#define HFA384X_RID_STAID 0xFD20
272#define HFA384X_RID_STASUPRANGE 0xFD21
273#define HFA384X_RID_MFIACTRANGES 0xFD22
274#define HFA384X_RID_CFIACTRANGES2 0xFD23
275#define HFA384X_RID_PRODUCTNAME 0xFD24 /* added in STA f/w 1.3.1;
276 * only Prism2.5(?) */
277#define HFA384X_RID_PORTSTATUS 0xFD40
278#define HFA384X_RID_CURRENTSSID 0xFD41
279#define HFA384X_RID_CURRENTBSSID 0xFD42
280#define HFA384X_RID_COMMSQUALITY 0xFD43
281#define HFA384X_RID_CURRENTTXRATE 0xFD44
282#define HFA384X_RID_CURRENTBEACONINTERVAL 0xFD45
283#define HFA384X_RID_CURRENTSCALETHRESHOLDS 0xFD46
284#define HFA384X_RID_PROTOCOLRSPTIME 0xFD47
285#define HFA384X_RID_SHORTRETRYLIMIT 0xFD48
286#define HFA384X_RID_LONGRETRYLIMIT 0xFD49
287#define HFA384X_RID_MAXTRANSMITLIFETIME 0xFD4A
288#define HFA384X_RID_MAXRECEIVELIFETIME 0xFD4B
289#define HFA384X_RID_CFPOLLABLE 0xFD4C
290#define HFA384X_RID_AUTHENTICATIONALGORITHMS 0xFD4D
291#define HFA384X_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F
292#define HFA384X_RID_DBMCOMMSQUALITY 0xFD51 /* added in STA f/w 1.3.1 */
293#define HFA384X_RID_CURRENTTXRATE1 0xFD80 /* AP f/w only */
294#define HFA384X_RID_CURRENTTXRATE2 0xFD81 /* AP f/w only */
295#define HFA384X_RID_CURRENTTXRATE3 0xFD82 /* AP f/w only */
296#define HFA384X_RID_CURRENTTXRATE4 0xFD83 /* AP f/w only */
297#define HFA384X_RID_CURRENTTXRATE5 0xFD84 /* AP f/w only */
298#define HFA384X_RID_CURRENTTXRATE6 0xFD85 /* AP f/w only */
299#define HFA384X_RID_OWNMACADDR 0xFD86 /* AP f/w only */
300#define HFA384X_RID_SCANRESULTSTABLE 0xFD88 /* added in STA f/w 0.8.3 */
301#define HFA384X_RID_HOSTSCANRESULTS 0xFD89 /* added in STA f/w 1.3.1 */
302#define HFA384X_RID_AUTHENTICATIONUSED 0xFD8A /* added in STA f/w 1.3.4 */
303#define HFA384X_RID_CNFFAASWITCHCTRL 0xFD8B /* added in STA f/w 1.6.3 */
304#define HFA384X_RID_ASSOCIATIONFAILURE 0xFD8D /* added in STA f/w 1.8.0 */
305#define HFA384X_RID_PHYTYPE 0xFDC0
306#define HFA384X_RID_CURRENTCHANNEL 0xFDC1
307#define HFA384X_RID_CURRENTPOWERSTATE 0xFDC2
308#define HFA384X_RID_CCAMODE 0xFDC3
309#define HFA384X_RID_SUPPORTEDDATARATES 0xFDC6
310#define HFA384X_RID_LFO_VOLT_REG_TEST_RES 0xFDC7 /* added in STA f/w 1.7.1 */
311#define HFA384X_RID_BUILDSEQ 0xFFFE
312#define HFA384X_RID_FWID 0xFFFF
313
314
315struct hfa384x_comp_ident
316{
317 u16 id;
318 u16 variant;
319 u16 major;
320 u16 minor;
321} __attribute__ ((packed));
322
323#define HFA384X_COMP_ID_PRI 0x15
324#define HFA384X_COMP_ID_STA 0x1f
325#define HFA384X_COMP_ID_FW_AP 0x14b
326
327struct hfa384x_sup_range
328{
329 u16 role;
330 u16 id;
331 u16 variant;
332 u16 bottom;
333 u16 top;
334} __attribute__ ((packed));
335
336
337struct hfa384x_build_id
338{
339 u16 pri_seq;
340 u16 sec_seq;
341} __attribute__ ((packed));
342
343/* FD01 - Download Buffer */
344struct hfa384x_rid_download_buffer
345{
346 u16 page;
347 u16 offset;
348 u16 length;
349} __attribute__ ((packed));
350
351/* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */
352struct hfa384x_comms_quality {
353 u16 comm_qual; /* 0 .. 92 */
354 u16 signal_level; /* 27 .. 154 */
355 u16 noise_level; /* 27 .. 154 */
356} __attribute__ ((packed));
357
358
359/* netdevice private ioctls (used, e.g., with iwpriv from user space) */
360
361/* New wireless extensions API - SET/GET convention (even ioctl numbers are
362 * root only)
363 */
364#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
365#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1)
366#define PRISM2_IOCTL_WRITEMIF (SIOCIWFIRSTPRIV + 2)
367#define PRISM2_IOCTL_READMIF (SIOCIWFIRSTPRIV + 3)
368#define PRISM2_IOCTL_MONITOR (SIOCIWFIRSTPRIV + 4)
369#define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6)
370#define PRISM2_IOCTL_INQUIRE (SIOCIWFIRSTPRIV + 8)
371#define PRISM2_IOCTL_WDS_ADD (SIOCIWFIRSTPRIV + 10)
372#define PRISM2_IOCTL_WDS_DEL (SIOCIWFIRSTPRIV + 12)
373#define PRISM2_IOCTL_SET_RID_WORD (SIOCIWFIRSTPRIV + 14)
374#define PRISM2_IOCTL_MACCMD (SIOCIWFIRSTPRIV + 16)
375#define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18)
376#define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20)
377#define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22)
378
379/* following are not in SIOCGIWPRIV list; check permission in the driver code
380 */
381#define PRISM2_IOCTL_DOWNLOAD (SIOCDEVPRIVATE + 13)
382#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14)
383
384
385/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */
386enum {
387 /* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */
388 PRISM2_PARAM_TXRATECTRL = 2,
389 PRISM2_PARAM_BEACON_INT = 3,
390 PRISM2_PARAM_PSEUDO_IBSS = 4,
391 PRISM2_PARAM_ALC = 5,
392 /* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */
393 PRISM2_PARAM_DUMP = 7,
394 PRISM2_PARAM_OTHER_AP_POLICY = 8,
395 PRISM2_PARAM_AP_MAX_INACTIVITY = 9,
396 PRISM2_PARAM_AP_BRIDGE_PACKETS = 10,
397 PRISM2_PARAM_DTIM_PERIOD = 11,
398 PRISM2_PARAM_AP_NULLFUNC_ACK = 12,
399 PRISM2_PARAM_MAX_WDS = 13,
400 PRISM2_PARAM_AP_AUTOM_AP_WDS = 14,
401 PRISM2_PARAM_AP_AUTH_ALGS = 15,
402 PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16,
403 PRISM2_PARAM_HOST_ENCRYPT = 17,
404 PRISM2_PARAM_HOST_DECRYPT = 18,
405 PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19,
406 PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20,
407 PRISM2_PARAM_HOST_ROAMING = 21,
408 PRISM2_PARAM_BCRX_STA_KEY = 22,
409 PRISM2_PARAM_IEEE_802_1X = 23,
410 PRISM2_PARAM_ANTSEL_TX = 24,
411 PRISM2_PARAM_ANTSEL_RX = 25,
412 PRISM2_PARAM_MONITOR_TYPE = 26,
413 PRISM2_PARAM_WDS_TYPE = 27,
414 PRISM2_PARAM_HOSTSCAN = 28,
415 PRISM2_PARAM_AP_SCAN = 29,
416 PRISM2_PARAM_ENH_SEC = 30,
417 PRISM2_PARAM_IO_DEBUG = 31,
418 PRISM2_PARAM_BASIC_RATES = 32,
419 PRISM2_PARAM_OPER_RATES = 33,
420 PRISM2_PARAM_HOSTAPD = 34,
421 PRISM2_PARAM_HOSTAPD_STA = 35,
422 PRISM2_PARAM_WPA = 36,
423 PRISM2_PARAM_PRIVACY_INVOKED = 37,
424 PRISM2_PARAM_TKIP_COUNTERMEASURES = 38,
425 PRISM2_PARAM_DROP_UNENCRYPTED = 39,
426};
427
428enum { HOSTAP_ANTSEL_DO_NOT_TOUCH = 0, HOSTAP_ANTSEL_DIVERSITY = 1,
429 HOSTAP_ANTSEL_LOW = 2, HOSTAP_ANTSEL_HIGH = 3 };
430
431
432/* PRISM2_IOCTL_MACCMD ioctl() subcommands: */
433enum { AP_MAC_CMD_POLICY_OPEN = 0, AP_MAC_CMD_POLICY_ALLOW = 1,
434 AP_MAC_CMD_POLICY_DENY = 2, AP_MAC_CMD_FLUSH = 3,
435 AP_MAC_CMD_KICKALL = 4 };
436
437
438/* PRISM2_IOCTL_DOWNLOAD ioctl() dl_cmd: */
439enum {
440 PRISM2_DOWNLOAD_VOLATILE = 1 /* RAM */,
441 /* Note! Old versions of prism2_srec have a fatal error in CRC-16
442 * calculation, which will corrupt all non-volatile downloads.
443 * PRISM2_DOWNLOAD_NON_VOLATILE used to be 2, but it is now 3 to
444 * prevent use of old versions of prism2_srec for non-volatile
445 * download. */
446 PRISM2_DOWNLOAD_NON_VOLATILE = 3 /* FLASH */,
447 PRISM2_DOWNLOAD_VOLATILE_GENESIS = 4 /* RAM in Genesis mode */,
448 /* Persistent versions of volatile download commands (keep firmware
449 * data in memory and automatically re-download after hw_reset */
450 PRISM2_DOWNLOAD_VOLATILE_PERSISTENT = 5,
451 PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT = 6,
452};
453
454struct prism2_download_param {
455 u32 dl_cmd;
456 u32 start_addr;
457 u32 num_areas;
458 struct prism2_download_area {
459 u32 addr; /* wlan card address */
460 u32 len;
461 void __user *ptr; /* pointer to data in user space */
462 } data[0];
463};
464
465#define PRISM2_MAX_DOWNLOAD_AREA_LEN 131072
466#define PRISM2_MAX_DOWNLOAD_LEN 262144
467
468
469/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */
470enum {
471 PRISM2_HOSTAPD_FLUSH = 1,
472 PRISM2_HOSTAPD_ADD_STA = 2,
473 PRISM2_HOSTAPD_REMOVE_STA = 3,
474 PRISM2_HOSTAPD_GET_INFO_STA = 4,
475 /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */
476 PRISM2_SET_ENCRYPTION = 6,
477 PRISM2_GET_ENCRYPTION = 7,
478 PRISM2_HOSTAPD_SET_FLAGS_STA = 8,
479 PRISM2_HOSTAPD_GET_RID = 9,
480 PRISM2_HOSTAPD_SET_RID = 10,
481 PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11,
482 PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
483 PRISM2_HOSTAPD_MLME = 13,
484 PRISM2_HOSTAPD_SCAN_REQ = 14,
485 PRISM2_HOSTAPD_STA_CLEAR_STATS = 15,
486};
487
488#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
489#define PRISM2_HOSTAPD_RID_HDR_LEN \
490((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data))
491#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
492((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
493
494/* Maximum length for algorithm names (-1 for nul termination) used in ioctl()
495 */
496#define HOSTAP_CRYPT_ALG_NAME_LEN 16
497
498
499struct prism2_hostapd_param {
500 u32 cmd;
501 u8 sta_addr[ETH_ALEN];
502 union {
503 struct {
504 u16 aid;
505 u16 capability;
506 u8 tx_supp_rates;
507 } add_sta;
508 struct {
509 u32 inactive_sec;
510 } get_info_sta;
511 struct {
512 u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
513 u32 flags;
514 u32 err;
515 u8 idx;
516 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
517 u16 key_len;
518 u8 key[0];
519 } crypt;
520 struct {
521 u32 flags_and;
522 u32 flags_or;
523 } set_flags_sta;
524 struct {
525 u16 rid;
526 u16 len;
527 u8 data[0];
528 } rid;
529 struct {
530 u8 len;
531 u8 data[0];
532 } generic_elem;
533 struct {
534#define MLME_STA_DEAUTH 0
535#define MLME_STA_DISASSOC 1
536 u16 cmd;
537 u16 reason_code;
538 } mlme;
539 struct {
540 u8 ssid_len;
541 u8 ssid[32];
542 } scan_req;
543 } u;
544};
545
546#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0)
547#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1)
548
549#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
550#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
551#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
552#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
553#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
554#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
555
556
557#endif /* HOSTAP_COMMON_H */
diff --git a/drivers/net/wireless/hostap/hostap_config.h b/drivers/net/wireless/hostap/hostap_config.h
new file mode 100644
index 000000000000..fcf45781f4ad
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -0,0 +1,86 @@
1#ifndef HOSTAP_CONFIG_H
2#define HOSTAP_CONFIG_H
3
4#define PRISM2_VERSION "CVS"
5
6/* In the previous versions of Host AP driver, support for user space version
7 * of IEEE 802.11 management (hostapd) used to be disabled in the default
8 * configuration. From now on, support for hostapd is always included and it is
9 * possible to disable kernel driver version of IEEE 802.11 management with a
10 * separate define, PRISM2_NO_KERNEL_IEEE80211_MGMT. */
11/* #define PRISM2_NO_KERNEL_IEEE80211_MGMT */
12
13/* Maximum number of events handler per one interrupt */
14#define PRISM2_MAX_INTERRUPT_EVENTS 20
15
16/* Use PCI bus master to copy data to/from BAP (only available for
17 * hostap_pci.o).
18 *
19 * Note! This is extremely experimental. PCI bus master is not supported by
20 * Intersil and it seems to have some problems at least on TX path (see below).
21 * The driver code for implementing bus master support is based on guessing
22 * and experimenting suitable control bits and these might not be correct.
23 * This code is included because using bus master makes a huge difference in
24 * host CPU load (something like 40% host CPU usage to 5-10% when sending or
25 * receiving at maximum throughput).
26 *
27 * Note2! Station firmware version 1.3.5 and primary firmware version 1.0.7
28 * have some fixes for PCI corruption and these (or newer) versions are
29 * recommended especially when using bus mastering.
30 *
31 * NOTE: PCI bus mastering code has not been updated for long time and it is
32 * not likely to compile and it will _not_ work as is. Only enable this if you
33 * are prepared to first fix the implementation..
34 */
35/* #define PRISM2_BUS_MASTER */
36
37#ifdef PRISM2_BUS_MASTER
38
39/* PCI bus master implementation seems to be broken in current
40 * hardware/firmware versions. Enable this to use enable command to fix
41 * something before starting bus master operation on TX path. This will add
42 * some latency and an extra interrupt to each TX packet. */
43#define PRISM2_ENABLE_BEFORE_TX_BUS_MASTER
44
45#endif /* PRISM2_BUS_MASTER */
46
47/* Include code for downloading firmware images into volatile RAM. */
48#define PRISM2_DOWNLOAD_SUPPORT
49
50/* Allow kernel configuration to enable download support. */
51#if !defined(PRISM2_DOWNLOAD_SUPPORT) && defined(CONFIG_HOSTAP_FIRMWARE)
52#define PRISM2_DOWNLOAD_SUPPORT
53#endif
54
55#ifdef PRISM2_DOWNLOAD_SUPPORT
56/* Allow writing firmware images into flash, i.e., to non-volatile storage.
57 * Before you enable this option, you should make absolutely sure that you are
58 * using prism2_srec utility that comes with THIS version of the driver!
59 * In addition, please note that it is possible to kill your card with
60 * non-volatile download if you are using incorrect image. This feature has not
61 * been fully tested, so please be careful with it. */
62/* #define PRISM2_NON_VOLATILE_DOWNLOAD */
63#endif /* PRISM2_DOWNLOAD_SUPPORT */
64
65/* Save low-level I/O for debugging. This should not be enabled in normal use.
66 */
67/* #define PRISM2_IO_DEBUG */
68
69/* Following defines can be used to remove unneeded parts of the driver, e.g.,
70 * to limit the size of the kernel module. Definitions can be added here in
71 * hostap_config.h or they can be added to make command with EXTRA_CFLAGS,
72 * e.g.,
73 * 'make pccard EXTRA_CFLAGS="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"'
74 */
75
76/* Do not include debug messages into the driver */
77/* #define PRISM2_NO_DEBUG */
78
79/* Do not include /proc/net/prism2/wlan#/{registers,debug} */
80/* #define PRISM2_NO_PROCFS_DEBUG */
81
82/* Do not include station functionality (i.e., allow only Master (Host AP) mode
83 */
84/* #define PRISM2_NO_STATION_MODES */
85
86#endif /* HOSTAP_CONFIG_H */
diff --git a/drivers/net/wireless/hostap/hostap_crypt.c b/drivers/net/wireless/hostap/hostap_crypt.c
new file mode 100644
index 000000000000..de5390d502f1
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_crypt.c
@@ -0,0 +1,167 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12struct hostap_crypto_alg {
13 struct list_head list;
14 struct hostap_crypto_ops *ops;
15};
16
17
18struct hostap_crypto {
19 struct list_head algs;
20 spinlock_t lock;
21};
22
23static struct hostap_crypto *hcrypt;
24
25
26int hostap_register_crypto_ops(struct hostap_crypto_ops *ops)
27{
28 unsigned long flags;
29 struct hostap_crypto_alg *alg;
30
31 if (hcrypt == NULL)
32 return -1;
33
34 alg = (struct hostap_crypto_alg *) kmalloc(sizeof(*alg), GFP_KERNEL);
35 if (alg == NULL)
36 return -ENOMEM;
37
38 memset(alg, 0, sizeof(*alg));
39 alg->ops = ops;
40
41 spin_lock_irqsave(&hcrypt->lock, flags);
42 list_add(&alg->list, &hcrypt->algs);
43 spin_unlock_irqrestore(&hcrypt->lock, flags);
44
45 printk(KERN_DEBUG "hostap_crypt: registered algorithm '%s'\n",
46 ops->name);
47
48 return 0;
49}
50
51
52int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops)
53{
54 unsigned long flags;
55 struct list_head *ptr;
56 struct hostap_crypto_alg *del_alg = NULL;
57
58 if (hcrypt == NULL)
59 return -1;
60
61 spin_lock_irqsave(&hcrypt->lock, flags);
62 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
63 struct hostap_crypto_alg *alg =
64 (struct hostap_crypto_alg *) ptr;
65 if (alg->ops == ops) {
66 list_del(&alg->list);
67 del_alg = alg;
68 break;
69 }
70 }
71 spin_unlock_irqrestore(&hcrypt->lock, flags);
72
73 if (del_alg) {
74 printk(KERN_DEBUG "hostap_crypt: unregistered algorithm "
75 "'%s'\n", ops->name);
76 kfree(del_alg);
77 }
78
79 return del_alg ? 0 : -1;
80}
81
82
83struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name)
84{
85 unsigned long flags;
86 struct list_head *ptr;
87 struct hostap_crypto_alg *found_alg = NULL;
88
89 if (hcrypt == NULL)
90 return NULL;
91
92 spin_lock_irqsave(&hcrypt->lock, flags);
93 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
94 struct hostap_crypto_alg *alg =
95 (struct hostap_crypto_alg *) ptr;
96 if (strcmp(alg->ops->name, name) == 0) {
97 found_alg = alg;
98 break;
99 }
100 }
101 spin_unlock_irqrestore(&hcrypt->lock, flags);
102
103 if (found_alg)
104 return found_alg->ops;
105 else
106 return NULL;
107}
108
109
110static void * hostap_crypt_null_init(int keyidx) { return (void *) 1; }
111static void hostap_crypt_null_deinit(void *priv) {}
112
113static struct hostap_crypto_ops hostap_crypt_null = {
114 .name = "NULL",
115 .init = hostap_crypt_null_init,
116 .deinit = hostap_crypt_null_deinit,
117 .encrypt_mpdu = NULL,
118 .decrypt_mpdu = NULL,
119 .encrypt_msdu = NULL,
120 .decrypt_msdu = NULL,
121 .set_key = NULL,
122 .get_key = NULL,
123 .extra_prefix_len = 0,
124 .extra_postfix_len = 0
125};
126
127
128static int __init hostap_crypto_init(void)
129{
130 hcrypt = (struct hostap_crypto *) kmalloc(sizeof(*hcrypt), GFP_KERNEL);
131 if (hcrypt == NULL)
132 return -ENOMEM;
133
134 memset(hcrypt, 0, sizeof(*hcrypt));
135 INIT_LIST_HEAD(&hcrypt->algs);
136 spin_lock_init(&hcrypt->lock);
137
138 (void) hostap_register_crypto_ops(&hostap_crypt_null);
139
140 return 0;
141}
142
143
144static void __exit hostap_crypto_deinit(void)
145{
146 struct list_head *ptr, *n;
147
148 if (hcrypt == NULL)
149 return;
150
151 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
152 ptr = n, n = ptr->next) {
153 struct hostap_crypto_alg *alg =
154 (struct hostap_crypto_alg *) ptr;
155 list_del(ptr);
156 printk(KERN_DEBUG "hostap_crypt: unregistered algorithm "
157 "'%s' (deinit)\n", alg->ops->name);
158 kfree(alg);
159 }
160
161 kfree(hcrypt);
162}
163
164
165EXPORT_SYMBOL(hostap_register_crypto_ops);
166EXPORT_SYMBOL(hostap_unregister_crypto_ops);
167EXPORT_SYMBOL(hostap_get_crypto_ops);
diff --git a/drivers/net/wireless/hostap/hostap_crypt.h b/drivers/net/wireless/hostap/hostap_crypt.h
new file mode 100644
index 000000000000..45d66d0323b0
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_crypt.h
@@ -0,0 +1,50 @@
1#ifndef PRISM2_CRYPT_H
2#define PRISM2_CRYPT_H
3
4struct hostap_crypto_ops {
5 char *name;
6
7 /* init new crypto context (e.g., allocate private data space,
8 * select IV, etc.); returns NULL on failure or pointer to allocated
9 * private data on success */
10 void * (*init)(int keyidx);
11
12 /* deinitialize crypto context and free allocated private data */
13 void (*deinit)(void *priv);
14
15 /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
16 * value from decrypt_mpdu is passed as the keyidx value for
17 * decrypt_msdu. skb must have enough head and tail room for the
18 * encryption; if not, error will be returned; these functions are
19 * called for all MPDUs (i.e., fragments).
20 */
21 int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
22 int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
23
24 /* These functions are called for full MSDUs, i.e. full frames.
25 * These can be NULL if full MSDU operations are not needed. */
26 int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
27 int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
28 void *priv);
29
30 int (*set_key)(void *key, int len, u8 *seq, void *priv);
31 int (*get_key)(void *key, int len, u8 *seq, void *priv);
32
33 /* procfs handler for printing out key information and possible
34 * statistics */
35 char * (*print_stats)(char *p, void *priv);
36
37 /* maximum number of bytes added by encryption; encrypt buf is
38 * allocated with extra_prefix_len bytes, copy of in_buf, and
39 * extra_postfix_len; encrypt need not use all this space, but
40 * the result must start at the beginning of the buffer and correct
41 * length must be returned */
42 int extra_prefix_len, extra_postfix_len;
43};
44
45
46int hostap_register_crypto_ops(struct hostap_crypto_ops *ops);
47int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops);
48struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name);
49
50#endif /* PRISM2_CRYPT_H */
diff --git a/drivers/net/wireless/hostap/hostap_crypt_ccmp.c b/drivers/net/wireless/hostap/hostap_crypt_ccmp.c
new file mode 100644
index 000000000000..e95bcc73dbf1
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_crypt_ccmp.c
@@ -0,0 +1,486 @@
1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <linux/wireless.h>
23#include <net/iw_handler.h>
24#include <asm/string.h>
25
26#include "hostap_crypt.h"
27#include "hostap_wlan.h"
28#include "hostap_80211.h"
29
30#ifndef CONFIG_CRYPTO
31#error CONFIG_CRYPTO is required to build this module.
32#endif
33#include <linux/crypto.h>
34#include <asm/scatterlist.h>
35
36MODULE_AUTHOR("Jouni Malinen");
37MODULE_DESCRIPTION("Host AP crypt: CCMP");
38MODULE_LICENSE("GPL");
39
40
41#define AES_BLOCK_LEN 16
42#define CCMP_HDR_LEN 8
43#define CCMP_MIC_LEN 8
44#define CCMP_TK_LEN 16
45#define CCMP_PN_LEN 6
46
47
48struct hostap_ccmp_data {
49 u8 key[CCMP_TK_LEN];
50 int key_set;
51
52 u8 tx_pn[CCMP_PN_LEN];
53 u8 rx_pn[CCMP_PN_LEN];
54
55 u32 dot11RSNAStatsCCMPFormatErrors;
56 u32 dot11RSNAStatsCCMPReplays;
57 u32 dot11RSNAStatsCCMPDecryptErrors;
58
59 int key_idx;
60
61 struct crypto_tfm *tfm;
62
63 /* scratch buffers for virt_to_page() (crypto API) */
64 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
65 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
66 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
67};
68
69
70void hostap_ccmp_aes_encrypt(struct crypto_tfm *tfm,
71 const u8 pt[16], u8 ct[16])
72{
73 struct scatterlist src, dst;
74
75 src.page = virt_to_page(pt);
76 src.offset = offset_in_page(pt);
77 src.length = AES_BLOCK_LEN;
78
79 dst.page = virt_to_page(ct);
80 dst.offset = offset_in_page(ct);
81 dst.length = AES_BLOCK_LEN;
82
83 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
84}
85
86
87static void * hostap_ccmp_init(int key_idx)
88{
89 struct hostap_ccmp_data *priv;
90
91 if (!try_module_get(THIS_MODULE))
92 return NULL;
93
94 priv = (struct hostap_ccmp_data *) kmalloc(sizeof(*priv), GFP_ATOMIC);
95 if (priv == NULL) {
96 goto fail;
97 }
98 memset(priv, 0, sizeof(*priv));
99 priv->key_idx = key_idx;
100
101 priv->tfm = crypto_alloc_tfm("aes", 0);
102 if (priv->tfm == NULL) {
103 printk(KERN_DEBUG "hostap_crypt_ccmp: could not allocate "
104 "crypto API aes\n");
105 goto fail;
106 }
107
108 return priv;
109
110fail:
111 if (priv) {
112 if (priv->tfm)
113 crypto_free_tfm(priv->tfm);
114 kfree(priv);
115 }
116 module_put(THIS_MODULE);
117 return NULL;
118}
119
120
121static void hostap_ccmp_deinit(void *priv)
122{
123 struct hostap_ccmp_data *_priv = priv;
124 if (_priv && _priv->tfm)
125 crypto_free_tfm(_priv->tfm);
126 kfree(priv);
127 module_put(THIS_MODULE);
128}
129
130
131static inline void xor_block(u8 *b, u8 *a, size_t len)
132{
133 int i;
134 for (i = 0; i < len; i++)
135 b[i] ^= a[i];
136}
137
138
139static void ccmp_init_blocks(struct crypto_tfm *tfm,
140 struct hostap_ieee80211_hdr *hdr,
141 u8 *pn, size_t dlen, u8 *b0, u8 *auth,
142 u8 *s0)
143{
144 u8 *pos, qc = 0;
145 size_t aad_len;
146 u16 fc;
147 int a4_included, qc_included;
148 u8 aad[2 * AES_BLOCK_LEN];
149
150 fc = le16_to_cpu(hdr->frame_control);
151 a4_included = ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
152 (WLAN_FC_TODS | WLAN_FC_FROMDS));
153 qc_included = ((WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) &&
154 (WLAN_FC_GET_STYPE(fc) & 0x08));
155 aad_len = 22;
156 if (a4_included)
157 aad_len += 6;
158 if (qc_included) {
159 pos = (u8 *) &hdr->addr4;
160 if (a4_included)
161 pos += 6;
162 qc = *pos & 0x0f;
163 aad_len += 2;
164 }
165
166 /* CCM Initial Block:
167 * Flag (Include authentication header, M=3 (8-octet MIC),
168 * L=1 (2-octet Dlen))
169 * Nonce: 0x00 | A2 | PN
170 * Dlen */
171 b0[0] = 0x59;
172 b0[1] = qc;
173 memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
174 memcpy(b0 + 8, pn, CCMP_PN_LEN);
175 b0[14] = (dlen >> 8) & 0xff;
176 b0[15] = dlen & 0xff;
177
178 /* AAD:
179 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
180 * A1 | A2 | A3
181 * SC with bits 4..15 (seq#) masked to zero
182 * A4 (if present)
183 * QC (if present)
184 */
185 pos = (u8 *) hdr;
186 aad[0] = 0; /* aad_len >> 8 */
187 aad[1] = aad_len & 0xff;
188 aad[2] = pos[0] & 0x8f;
189 aad[3] = pos[1] & 0xc7;
190 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
191 pos = (u8 *) &hdr->seq_ctrl;
192 aad[22] = pos[0] & 0x0f;
193 aad[23] = 0; /* all bits masked */
194 memset(aad + 24, 0, 8);
195 if (a4_included)
196 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
197 if (qc_included) {
198 aad[a4_included ? 30 : 24] = qc;
199 /* rest of QC masked */
200 }
201
202 /* Start with the first block and AAD */
203 hostap_ccmp_aes_encrypt(tfm, b0, auth);
204 xor_block(auth, aad, AES_BLOCK_LEN);
205 hostap_ccmp_aes_encrypt(tfm, auth, auth);
206 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
207 hostap_ccmp_aes_encrypt(tfm, auth, auth);
208 b0[0] &= 0x07;
209 b0[14] = b0[15] = 0;
210 hostap_ccmp_aes_encrypt(tfm, b0, s0);
211}
212
213
214static int hostap_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
215{
216 struct hostap_ccmp_data *key = priv;
217 int data_len, i, blocks, last, len;
218 u8 *pos, *mic;
219 struct hostap_ieee80211_hdr *hdr;
220 u8 *b0 = key->tx_b0;
221 u8 *b = key->tx_b;
222 u8 *e = key->tx_e;
223 u8 *s0 = key->tx_s0;
224
225 if (skb_headroom(skb) < CCMP_HDR_LEN ||
226 skb_tailroom(skb) < CCMP_MIC_LEN ||
227 skb->len < hdr_len)
228 return -1;
229
230 data_len = skb->len - hdr_len;
231 pos = skb_push(skb, CCMP_HDR_LEN);
232 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
233 pos += hdr_len;
234 mic = skb_put(skb, CCMP_MIC_LEN);
235
236 i = CCMP_PN_LEN - 1;
237 while (i >= 0) {
238 key->tx_pn[i]++;
239 if (key->tx_pn[i] != 0)
240 break;
241 i--;
242 }
243
244 *pos++ = key->tx_pn[5];
245 *pos++ = key->tx_pn[4];
246 *pos++ = 0;
247 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
248 *pos++ = key->tx_pn[3];
249 *pos++ = key->tx_pn[2];
250 *pos++ = key->tx_pn[1];
251 *pos++ = key->tx_pn[0];
252
253 hdr = (struct hostap_ieee80211_hdr *) skb->data;
254 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
255
256 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
257 last = data_len % AES_BLOCK_LEN;
258
259 for (i = 1; i <= blocks; i++) {
260 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
261 /* Authentication */
262 xor_block(b, pos, len);
263 hostap_ccmp_aes_encrypt(key->tfm, b, b);
264 /* Encryption, with counter */
265 b0[14] = (i >> 8) & 0xff;
266 b0[15] = i & 0xff;
267 hostap_ccmp_aes_encrypt(key->tfm, b0, e);
268 xor_block(pos, e, len);
269 pos += len;
270 }
271
272 for (i = 0; i < CCMP_MIC_LEN; i++)
273 mic[i] = b[i] ^ s0[i];
274
275 return 0;
276}
277
278
279static int hostap_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
280{
281 struct hostap_ccmp_data *key = priv;
282 u8 keyidx, *pos;
283 struct hostap_ieee80211_hdr *hdr;
284 u8 *b0 = key->rx_b0;
285 u8 *b = key->rx_b;
286 u8 *a = key->rx_a;
287 u8 pn[6];
288 int i, blocks, last, len;
289 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
290 u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
291
292 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
293 key->dot11RSNAStatsCCMPFormatErrors++;
294 return -1;
295 }
296
297 hdr = (struct hostap_ieee80211_hdr *) skb->data;
298 pos = skb->data + hdr_len;
299 keyidx = pos[3];
300 if (!(keyidx & (1 << 5))) {
301 if (net_ratelimit()) {
302 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
303 " flag from " MACSTR "\n", MAC2STR(hdr->addr2));
304 }
305 key->dot11RSNAStatsCCMPFormatErrors++;
306 return -2;
307 }
308 keyidx >>= 6;
309 if (key->key_idx != keyidx) {
310 printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
311 "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
312 return -6;
313 }
314 if (!key->key_set) {
315 if (net_ratelimit()) {
316 printk(KERN_DEBUG "CCMP: received packet from " MACSTR
317 " with keyid=%d that does not have a configured"
318 " key\n", MAC2STR(hdr->addr2), keyidx);
319 }
320 return -3;
321 }
322
323 pn[0] = pos[7];
324 pn[1] = pos[6];
325 pn[2] = pos[5];
326 pn[3] = pos[4];
327 pn[4] = pos[1];
328 pn[5] = pos[0];
329 pos += 8;
330
331 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
332 if (net_ratelimit()) {
333 printk(KERN_DEBUG "CCMP: replay detected: STA=" MACSTR
334 " previous PN %02x%02x%02x%02x%02x%02x "
335 "received PN %02x%02x%02x%02x%02x%02x\n",
336 MAC2STR(hdr->addr2), MAC2STR(key->rx_pn),
337 MAC2STR(pn));
338 }
339 key->dot11RSNAStatsCCMPReplays++;
340 return -4;
341 }
342
343 ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
344 xor_block(mic, b, CCMP_MIC_LEN);
345
346 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
347 last = data_len % AES_BLOCK_LEN;
348
349 for (i = 1; i <= blocks; i++) {
350 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
351 /* Decrypt, with counter */
352 b0[14] = (i >> 8) & 0xff;
353 b0[15] = i & 0xff;
354 hostap_ccmp_aes_encrypt(key->tfm, b0, b);
355 xor_block(pos, b, len);
356 /* Authentication */
357 xor_block(a, pos, len);
358 hostap_ccmp_aes_encrypt(key->tfm, a, a);
359 pos += len;
360 }
361
362 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
363 if (net_ratelimit()) {
364 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
365 MACSTR "\n", MAC2STR(hdr->addr2));
366 }
367 key->dot11RSNAStatsCCMPDecryptErrors++;
368 return -5;
369 }
370
371 memcpy(key->rx_pn, pn, CCMP_PN_LEN);
372
373 /* Remove hdr and MIC */
374 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
375 skb_pull(skb, CCMP_HDR_LEN);
376 skb_trim(skb, skb->len - CCMP_MIC_LEN);
377
378 return keyidx;
379}
380
381
382static int hostap_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
383{
384 struct hostap_ccmp_data *data = priv;
385 int keyidx;
386 struct crypto_tfm *tfm = data->tfm;
387
388 keyidx = data->key_idx;
389 memset(data, 0, sizeof(*data));
390 data->key_idx = keyidx;
391 data->tfm = tfm;
392 if (len == CCMP_TK_LEN) {
393 memcpy(data->key, key, CCMP_TK_LEN);
394 data->key_set = 1;
395 if (seq) {
396 data->rx_pn[0] = seq[5];
397 data->rx_pn[1] = seq[4];
398 data->rx_pn[2] = seq[3];
399 data->rx_pn[3] = seq[2];
400 data->rx_pn[4] = seq[1];
401 data->rx_pn[5] = seq[0];
402 }
403 crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN);
404 } else if (len == 0) {
405 data->key_set = 0;
406 } else
407 return -1;
408
409 return 0;
410}
411
412
413static int hostap_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
414{
415 struct hostap_ccmp_data *data = priv;
416
417 if (len < CCMP_TK_LEN)
418 return -1;
419
420 if (!data->key_set)
421 return 0;
422 memcpy(key, data->key, CCMP_TK_LEN);
423
424 if (seq) {
425 seq[0] = data->tx_pn[5];
426 seq[1] = data->tx_pn[4];
427 seq[2] = data->tx_pn[3];
428 seq[3] = data->tx_pn[2];
429 seq[4] = data->tx_pn[1];
430 seq[5] = data->tx_pn[0];
431 }
432
433 return CCMP_TK_LEN;
434}
435
436
437static char * hostap_ccmp_print_stats(char *p, void *priv)
438{
439 struct hostap_ccmp_data *ccmp = priv;
440 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
441 "tx_pn=%02x%02x%02x%02x%02x%02x "
442 "rx_pn=%02x%02x%02x%02x%02x%02x "
443 "format_errors=%d replays=%d decrypt_errors=%d\n",
444 ccmp->key_idx, ccmp->key_set,
445 MAC2STR(ccmp->tx_pn), MAC2STR(ccmp->rx_pn),
446 ccmp->dot11RSNAStatsCCMPFormatErrors,
447 ccmp->dot11RSNAStatsCCMPReplays,
448 ccmp->dot11RSNAStatsCCMPDecryptErrors);
449
450 return p;
451}
452
453
454static struct hostap_crypto_ops hostap_crypt_ccmp = {
455 .name = "CCMP",
456 .init = hostap_ccmp_init,
457 .deinit = hostap_ccmp_deinit,
458 .encrypt_mpdu = hostap_ccmp_encrypt,
459 .decrypt_mpdu = hostap_ccmp_decrypt,
460 .encrypt_msdu = NULL,
461 .decrypt_msdu = NULL,
462 .set_key = hostap_ccmp_set_key,
463 .get_key = hostap_ccmp_get_key,
464 .print_stats = hostap_ccmp_print_stats,
465 .extra_prefix_len = CCMP_HDR_LEN,
466 .extra_postfix_len = CCMP_MIC_LEN
467};
468
469
470static int __init hostap_crypto_ccmp_init(void)
471{
472 if (hostap_register_crypto_ops(&hostap_crypt_ccmp) < 0)
473 return -1;
474
475 return 0;
476}
477
478
479static void __exit hostap_crypto_ccmp_exit(void)
480{
481 hostap_unregister_crypto_ops(&hostap_crypt_ccmp);
482}
483
484
485module_init(hostap_crypto_ccmp_init);
486module_exit(hostap_crypto_ccmp_exit);
diff --git a/drivers/net/wireless/hostap/hostap_crypt_tkip.c b/drivers/net/wireless/hostap/hostap_crypt_tkip.c
new file mode 100644
index 000000000000..e8d56bc280aa
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_crypt_tkip.c
@@ -0,0 +1,696 @@
1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <linux/wireless.h>
23#include <net/iw_handler.h>
24#include <asm/string.h>
25
26#include "hostap_crypt.h"
27#include "hostap_wlan.h"
28#include "hostap_80211.h"
29#include "hostap_config.h"
30
31#ifndef CONFIG_CRYPTO
32#error CONFIG_CRYPTO is required to build this module.
33#endif
34#include <linux/crypto.h>
35#include <asm/scatterlist.h>
36#include <linux/crc32.h>
37
38MODULE_AUTHOR("Jouni Malinen");
39MODULE_DESCRIPTION("Host AP crypt: TKIP");
40MODULE_LICENSE("GPL");
41
42
43struct hostap_tkip_data {
44#define TKIP_KEY_LEN 32
45 u8 key[TKIP_KEY_LEN];
46 int key_set;
47
48 u32 tx_iv32;
49 u16 tx_iv16;
50 u16 tx_ttak[5];
51 int tx_phase1_done;
52
53 u32 rx_iv32;
54 u16 rx_iv16;
55 u16 rx_ttak[5];
56 int rx_phase1_done;
57 u32 rx_iv32_new;
58 u16 rx_iv16_new;
59
60 u32 dot11RSNAStatsTKIPReplays;
61 u32 dot11RSNAStatsTKIPICVErrors;
62 u32 dot11RSNAStatsTKIPLocalMICFailures;
63
64 int key_idx;
65
66 struct crypto_tfm *tfm_arc4;
67 struct crypto_tfm *tfm_michael;
68
69 /* scratch buffers for virt_to_page() (crypto API) */
70 u8 rx_hdr[16], tx_hdr[16];
71};
72
73
74static void * hostap_tkip_init(int key_idx)
75{
76 struct hostap_tkip_data *priv;
77
78 if (!try_module_get(THIS_MODULE))
79 return NULL;
80
81 priv = (struct hostap_tkip_data *) kmalloc(sizeof(*priv), GFP_ATOMIC);
82 if (priv == NULL)
83 goto fail;
84 memset(priv, 0, sizeof(*priv));
85 priv->key_idx = key_idx;
86
87 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
88 if (priv->tfm_arc4 == NULL) {
89 printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate "
90 "crypto API arc4\n");
91 goto fail;
92 }
93
94 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
95 if (priv->tfm_michael == NULL) {
96 printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate "
97 "crypto API michael_mic\n");
98 goto fail;
99 }
100
101 return priv;
102
103fail:
104 if (priv) {
105 if (priv->tfm_michael)
106 crypto_free_tfm(priv->tfm_michael);
107 if (priv->tfm_arc4)
108 crypto_free_tfm(priv->tfm_arc4);
109 kfree(priv);
110 }
111 module_put(THIS_MODULE);
112 return NULL;
113}
114
115
116static void hostap_tkip_deinit(void *priv)
117{
118 struct hostap_tkip_data *_priv = priv;
119 if (_priv && _priv->tfm_michael)
120 crypto_free_tfm(_priv->tfm_michael);
121 if (_priv && _priv->tfm_arc4)
122 crypto_free_tfm(_priv->tfm_arc4);
123 kfree(priv);
124 module_put(THIS_MODULE);
125}
126
127
128static inline u16 RotR1(u16 val)
129{
130 return (val >> 1) | (val << 15);
131}
132
133
134static inline u8 Lo8(u16 val)
135{
136 return val & 0xff;
137}
138
139
140static inline u8 Hi8(u16 val)
141{
142 return val >> 8;
143}
144
145
146static inline u16 Lo16(u32 val)
147{
148 return val & 0xffff;
149}
150
151
152static inline u16 Hi16(u32 val)
153{
154 return val >> 16;
155}
156
157
158static inline u16 Mk16(u8 hi, u8 lo)
159{
160 return lo | (((u16) hi) << 8);
161}
162
163
164static inline u16 Mk16_le(u16 *v)
165{
166 return le16_to_cpu(*v);
167}
168
169
170static const u16 Sbox[256] =
171{
172 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
173 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
174 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
175 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
176 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
177 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
178 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
179 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
180 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
181 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
182 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
183 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
184 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
185 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
186 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
187 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
188 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
189 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
190 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
191 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
192 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
193 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
194 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
195 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
196 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
197 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
198 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
199 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
200 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
201 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
202 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
203 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
204};
205
206
207static inline u16 _S_(u16 v)
208{
209 u16 t = Sbox[Hi8(v)];
210 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
211}
212
213
214#define PHASE1_LOOP_COUNT 8
215
216static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
217{
218 int i, j;
219
220 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
221 TTAK[0] = Lo16(IV32);
222 TTAK[1] = Hi16(IV32);
223 TTAK[2] = Mk16(TA[1], TA[0]);
224 TTAK[3] = Mk16(TA[3], TA[2]);
225 TTAK[4] = Mk16(TA[5], TA[4]);
226
227 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
228 j = 2 * (i & 1);
229 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
230 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
231 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
232 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
233 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
234 }
235}
236
237
238static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
239 u16 IV16)
240{
241 /* Make temporary area overlap WEP seed so that the final copy can be
242 * avoided on little endian hosts. */
243 u16 *PPK = (u16 *) &WEPSeed[4];
244
245 /* Step 1 - make copy of TTAK and bring in TSC */
246 PPK[0] = TTAK[0];
247 PPK[1] = TTAK[1];
248 PPK[2] = TTAK[2];
249 PPK[3] = TTAK[3];
250 PPK[4] = TTAK[4];
251 PPK[5] = TTAK[4] + IV16;
252
253 /* Step 2 - 96-bit bijective mixing using S-box */
254 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
255 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
256 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
257 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
258 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
259 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
260
261 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
262 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
263 PPK[2] += RotR1(PPK[1]);
264 PPK[3] += RotR1(PPK[2]);
265 PPK[4] += RotR1(PPK[3]);
266 PPK[5] += RotR1(PPK[4]);
267
268 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
269 * WEPSeed[0..2] is transmitted as WEP IV */
270 WEPSeed[0] = Hi8(IV16);
271 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
272 WEPSeed[2] = Lo8(IV16);
273 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
274
275#ifdef __BIG_ENDIAN
276 {
277 int i;
278 for (i = 0; i < 6; i++)
279 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
280 }
281#endif
282}
283
284
285static int hostap_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
286{
287 struct hostap_tkip_data *tkey = priv;
288 int len;
289 u8 rc4key[16], *pos, *icv;
290 struct hostap_ieee80211_hdr *hdr;
291 u32 crc;
292 struct scatterlist sg;
293
294 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
295 skb->len < hdr_len)
296 return -1;
297
298 hdr = (struct hostap_ieee80211_hdr *) skb->data;
299 if (!tkey->tx_phase1_done) {
300 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
301 tkey->tx_iv32);
302 tkey->tx_phase1_done = 1;
303 }
304 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
305
306 len = skb->len - hdr_len;
307 pos = skb_push(skb, 8);
308 memmove(pos, pos + 8, hdr_len);
309 pos += hdr_len;
310 icv = skb_put(skb, 4);
311
312 *pos++ = rc4key[0];
313 *pos++ = rc4key[1];
314 *pos++ = rc4key[2];
315 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
316 *pos++ = tkey->tx_iv32 & 0xff;
317 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
318 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
319 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
320
321 crc = ~crc32_le(~0, pos, len);
322 icv[0] = crc;
323 icv[1] = crc >> 8;
324 icv[2] = crc >> 16;
325 icv[3] = crc >> 24;
326
327 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
328 sg.page = virt_to_page(pos);
329 sg.offset = offset_in_page(pos);
330 sg.length = len + 4;
331 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
332
333 tkey->tx_iv16++;
334 if (tkey->tx_iv16 == 0) {
335 tkey->tx_phase1_done = 0;
336 tkey->tx_iv32++;
337 }
338
339 return 0;
340}
341
342
343static int hostap_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
344{
345 struct hostap_tkip_data *tkey = priv;
346 u8 rc4key[16];
347 u8 keyidx, *pos, icv[4];
348 u32 iv32;
349 u16 iv16;
350 struct hostap_ieee80211_hdr *hdr;
351 u32 crc;
352 struct scatterlist sg;
353 int plen;
354
355 if (skb->len < hdr_len + 8 + 4)
356 return -1;
357
358 hdr = (struct hostap_ieee80211_hdr *) skb->data;
359 pos = skb->data + hdr_len;
360 keyidx = pos[3];
361 if (!(keyidx & (1 << 5))) {
362 if (net_ratelimit()) {
363 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
364 " flag from " MACSTR "\n", MAC2STR(hdr->addr2));
365 }
366 return -2;
367 }
368 keyidx >>= 6;
369 if (tkey->key_idx != keyidx) {
370 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
371 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
372 return -6;
373 }
374 if (!tkey->key_set) {
375 if (net_ratelimit()) {
376 printk(KERN_DEBUG "TKIP: received packet from " MACSTR
377 " with keyid=%d that does not have a configured"
378 " key\n", MAC2STR(hdr->addr2), keyidx);
379 }
380 return -3;
381 }
382 iv16 = (pos[0] << 8) | pos[2];
383 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
384 pos += 8;
385
386 if (iv32 < tkey->rx_iv32 ||
387 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
388 if (net_ratelimit()) {
389 printk(KERN_DEBUG "TKIP: replay detected: STA=" MACSTR
390 " previous TSC %08x%04x received TSC "
391 "%08x%04x\n", MAC2STR(hdr->addr2),
392 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
393 }
394 tkey->dot11RSNAStatsTKIPReplays++;
395 return -4;
396 }
397
398 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
399 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
400 tkey->rx_phase1_done = 1;
401 }
402 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
403
404 plen = skb->len - hdr_len - 12;
405
406 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
407 sg.page = virt_to_page(pos);
408 sg.offset = offset_in_page(pos);
409 sg.length = plen + 4;
410 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
411
412 crc = ~crc32_le(~0, pos, plen);
413 icv[0] = crc;
414 icv[1] = crc >> 8;
415 icv[2] = crc >> 16;
416 icv[3] = crc >> 24;
417 if (memcmp(icv, pos + plen, 4) != 0) {
418 if (iv32 != tkey->rx_iv32) {
419 /* Previously cached Phase1 result was already lost, so
420 * it needs to be recalculated for the next packet. */
421 tkey->rx_phase1_done = 0;
422 }
423 if (net_ratelimit()) {
424 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
425 MACSTR "\n", MAC2STR(hdr->addr2));
426 }
427 tkey->dot11RSNAStatsTKIPICVErrors++;
428 return -5;
429 }
430
431 /* Update real counters only after Michael MIC verification has
432 * completed */
433 tkey->rx_iv32_new = iv32;
434 tkey->rx_iv16_new = iv16;
435
436 /* Remove IV and ICV */
437 memmove(skb->data + 8, skb->data, hdr_len);
438 skb_pull(skb, 8);
439 skb_trim(skb, skb->len - 4);
440
441 return keyidx;
442}
443
444
445static int michael_mic(struct hostap_tkip_data *tkey, u8 *key, u8 *hdr,
446 u8 *data, size_t data_len, u8 *mic)
447{
448 struct scatterlist sg[2];
449
450 if (tkey->tfm_michael == NULL) {
451 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
452 return -1;
453 }
454 sg[0].page = virt_to_page(hdr);
455 sg[0].offset = offset_in_page(hdr);
456 sg[0].length = 16;
457
458 sg[1].page = virt_to_page(data);
459 sg[1].offset = offset_in_page(data);
460 sg[1].length = data_len;
461
462 crypto_digest_init(tkey->tfm_michael);
463 crypto_digest_setkey(tkey->tfm_michael, key, 8);
464 crypto_digest_update(tkey->tfm_michael, sg, 2);
465 crypto_digest_final(tkey->tfm_michael, mic);
466
467 return 0;
468}
469
470
471static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
472{
473 struct hostap_ieee80211_hdr *hdr11;
474
475 hdr11 = (struct hostap_ieee80211_hdr *) skb->data;
476 switch (le16_to_cpu(hdr11->frame_control) &
477 (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
478 case WLAN_FC_TODS:
479 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
480 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
481 break;
482 case WLAN_FC_FROMDS:
483 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
484 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
485 break;
486 case WLAN_FC_FROMDS | WLAN_FC_TODS:
487 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
488 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
489 break;
490 case 0:
491 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
492 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
493 break;
494 }
495
496 hdr[12] = 0; /* priority */
497 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
498}
499
500
501static int hostap_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
502{
503 struct hostap_tkip_data *tkey = priv;
504 u8 *pos;
505
506 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
507 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
508 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
509 skb_tailroom(skb), hdr_len, skb->len);
510 return -1;
511 }
512
513 michael_mic_hdr(skb, tkey->tx_hdr);
514 pos = skb_put(skb, 8);
515 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
516 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
517 return -1;
518
519 return 0;
520}
521
522
523static void hostap_michael_mic_failure(struct net_device *dev,
524 struct hostap_ieee80211_hdr *hdr,
525 int keyidx)
526{
527 union iwreq_data wrqu;
528 char buf[128];
529
530 /* TODO: needed parameters: count, keyid, key type, src address, TSC */
531 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
532 MACSTR ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
533 MAC2STR(hdr->addr2));
534 memset(&wrqu, 0, sizeof(wrqu));
535 wrqu.data.length = strlen(buf);
536 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
537}
538
539
540static int hostap_michael_mic_verify(struct sk_buff *skb, int keyidx,
541 int hdr_len, void *priv)
542{
543 struct hostap_tkip_data *tkey = priv;
544 u8 mic[8];
545
546 if (!tkey->key_set)
547 return -1;
548
549 michael_mic_hdr(skb, tkey->rx_hdr);
550 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
551 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
552 return -1;
553 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
554 struct hostap_ieee80211_hdr *hdr;
555 hdr = (struct hostap_ieee80211_hdr *) skb->data;
556 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
557 "MSDU from " MACSTR " keyidx=%d\n",
558 skb->dev ? skb->dev->name : "N/A", MAC2STR(hdr->addr2),
559 keyidx);
560 if (skb->dev)
561 hostap_michael_mic_failure(skb->dev, hdr, keyidx);
562 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
563 return -1;
564 }
565
566 /* Update TSC counters for RX now that the packet verification has
567 * completed. */
568 tkey->rx_iv32 = tkey->rx_iv32_new;
569 tkey->rx_iv16 = tkey->rx_iv16_new;
570
571 skb_trim(skb, skb->len - 8);
572
573 return 0;
574}
575
576
577static int hostap_tkip_set_key(void *key, int len, u8 *seq, void *priv)
578{
579 struct hostap_tkip_data *tkey = priv;
580 int keyidx;
581 struct crypto_tfm *tfm = tkey->tfm_michael;
582 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
583
584 keyidx = tkey->key_idx;
585 memset(tkey, 0, sizeof(*tkey));
586 tkey->key_idx = keyidx;
587 tkey->tfm_michael = tfm;
588 tkey->tfm_arc4 = tfm2;
589 if (len == TKIP_KEY_LEN) {
590 memcpy(tkey->key, key, TKIP_KEY_LEN);
591 tkey->key_set = 1;
592 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
593 if (seq) {
594 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
595 (seq[3] << 8) | seq[2];
596 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
597 }
598 } else if (len == 0) {
599 tkey->key_set = 0;
600 } else
601 return -1;
602
603 return 0;
604}
605
606
607static int hostap_tkip_get_key(void *key, int len, u8 *seq, void *priv)
608{
609 struct hostap_tkip_data *tkey = priv;
610
611 if (len < TKIP_KEY_LEN)
612 return -1;
613
614 if (!tkey->key_set)
615 return 0;
616 memcpy(key, tkey->key, TKIP_KEY_LEN);
617
618 if (seq) {
619 /* Return the sequence number of the last transmitted frame. */
620 u16 iv16 = tkey->tx_iv16;
621 u32 iv32 = tkey->tx_iv32;
622 if (iv16 == 0)
623 iv32--;
624 iv16--;
625 seq[0] = tkey->tx_iv16;
626 seq[1] = tkey->tx_iv16 >> 8;
627 seq[2] = tkey->tx_iv32;
628 seq[3] = tkey->tx_iv32 >> 8;
629 seq[4] = tkey->tx_iv32 >> 16;
630 seq[5] = tkey->tx_iv32 >> 24;
631 }
632
633 return TKIP_KEY_LEN;
634}
635
636
637static char * hostap_tkip_print_stats(char *p, void *priv)
638{
639 struct hostap_tkip_data *tkip = priv;
640 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
641 "tx_pn=%02x%02x%02x%02x%02x%02x "
642 "rx_pn=%02x%02x%02x%02x%02x%02x "
643 "replays=%d icv_errors=%d local_mic_failures=%d\n",
644 tkip->key_idx, tkip->key_set,
645 (tkip->tx_iv32 >> 24) & 0xff,
646 (tkip->tx_iv32 >> 16) & 0xff,
647 (tkip->tx_iv32 >> 8) & 0xff,
648 tkip->tx_iv32 & 0xff,
649 (tkip->tx_iv16 >> 8) & 0xff,
650 tkip->tx_iv16 & 0xff,
651 (tkip->rx_iv32 >> 24) & 0xff,
652 (tkip->rx_iv32 >> 16) & 0xff,
653 (tkip->rx_iv32 >> 8) & 0xff,
654 tkip->rx_iv32 & 0xff,
655 (tkip->rx_iv16 >> 8) & 0xff,
656 tkip->rx_iv16 & 0xff,
657 tkip->dot11RSNAStatsTKIPReplays,
658 tkip->dot11RSNAStatsTKIPICVErrors,
659 tkip->dot11RSNAStatsTKIPLocalMICFailures);
660 return p;
661}
662
663
664static struct hostap_crypto_ops hostap_crypt_tkip = {
665 .name = "TKIP",
666 .init = hostap_tkip_init,
667 .deinit = hostap_tkip_deinit,
668 .encrypt_mpdu = hostap_tkip_encrypt,
669 .decrypt_mpdu = hostap_tkip_decrypt,
670 .encrypt_msdu = hostap_michael_mic_add,
671 .decrypt_msdu = hostap_michael_mic_verify,
672 .set_key = hostap_tkip_set_key,
673 .get_key = hostap_tkip_get_key,
674 .print_stats = hostap_tkip_print_stats,
675 .extra_prefix_len = 4 + 4 /* IV + ExtIV */,
676 .extra_postfix_len = 8 + 4 /* MIC + ICV */
677};
678
679
680static int __init hostap_crypto_tkip_init(void)
681{
682 if (hostap_register_crypto_ops(&hostap_crypt_tkip) < 0)
683 return -1;
684
685 return 0;
686}
687
688
689static void __exit hostap_crypto_tkip_exit(void)
690{
691 hostap_unregister_crypto_ops(&hostap_crypt_tkip);
692}
693
694
695module_init(hostap_crypto_tkip_init);
696module_exit(hostap_crypto_tkip_exit);
diff --git a/drivers/net/wireless/hostap/hostap_crypt_wep.c b/drivers/net/wireless/hostap/hostap_crypt_wep.c
new file mode 100644
index 000000000000..a6783e067f1a
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_crypt_wep.c
@@ -0,0 +1,281 @@
1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <asm/string.h>
20
21#include "hostap_crypt.h"
22
23#ifndef CONFIG_CRYPTO
24#error CONFIG_CRYPTO is required to build this module.
25#endif
26#include <linux/crypto.h>
27#include <asm/scatterlist.h>
28#include <linux/crc32.h>
29
30MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Host AP crypt: WEP");
32MODULE_LICENSE("GPL");
33
34
35struct prism2_wep_data {
36 u32 iv;
37#define WEP_KEY_LEN 13
38 u8 key[WEP_KEY_LEN + 1];
39 u8 key_len;
40 u8 key_idx;
41 struct crypto_tfm *tfm;
42};
43
44
45static void * prism2_wep_init(int keyidx)
46{
47 struct prism2_wep_data *priv;
48
49 if (!try_module_get(THIS_MODULE))
50 return NULL;
51
52 priv = (struct prism2_wep_data *) kmalloc(sizeof(*priv), GFP_ATOMIC);
53 if (priv == NULL)
54 goto fail;
55 memset(priv, 0, sizeof(*priv));
56 priv->key_idx = keyidx;
57
58 priv->tfm = crypto_alloc_tfm("arc4", 0);
59 if (priv->tfm == NULL) {
60 printk(KERN_DEBUG "hostap_crypt_wep: could not allocate "
61 "crypto API arc4\n");
62 goto fail;
63 }
64
65 /* start WEP IV from a random value */
66 get_random_bytes(&priv->iv, 4);
67
68 return priv;
69
70fail:
71 if (priv) {
72 if (priv->tfm)
73 crypto_free_tfm(priv->tfm);
74 kfree(priv);
75 }
76 module_put(THIS_MODULE);
77 return NULL;
78}
79
80
81static void prism2_wep_deinit(void *priv)
82{
83 struct prism2_wep_data *_priv = priv;
84 if (_priv && _priv->tfm)
85 crypto_free_tfm(_priv->tfm);
86 kfree(priv);
87 module_put(THIS_MODULE);
88}
89
90
91/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
92 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
93 * so the payload length increases with 8 bytes.
94 *
95 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
96 */
97static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
98{
99 struct prism2_wep_data *wep = priv;
100 u32 crc, klen, len;
101 u8 key[WEP_KEY_LEN + 3];
102 u8 *pos, *icv;
103 struct scatterlist sg;
104
105 if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
106 skb->len < hdr_len)
107 return -1;
108
109 len = skb->len - hdr_len;
110 pos = skb_push(skb, 4);
111 memmove(pos, pos + 4, hdr_len);
112 pos += hdr_len;
113
114 klen = 3 + wep->key_len;
115
116 wep->iv++;
117
118 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
119 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
120 * can be used to speedup attacks, so avoid using them. */
121 if ((wep->iv & 0xff00) == 0xff00) {
122 u8 B = (wep->iv >> 16) & 0xff;
123 if (B >= 3 && B < klen)
124 wep->iv += 0x0100;
125 }
126
127 /* Prepend 24-bit IV to RC4 key and TX frame */
128 *pos++ = key[0] = (wep->iv >> 16) & 0xff;
129 *pos++ = key[1] = (wep->iv >> 8) & 0xff;
130 *pos++ = key[2] = wep->iv & 0xff;
131 *pos++ = wep->key_idx << 6;
132
133 /* Copy rest of the WEP key (the secret part) */
134 memcpy(key + 3, wep->key, wep->key_len);
135
136 /* Append little-endian CRC32 and encrypt it to produce ICV */
137 crc = ~crc32_le(~0, pos, len);
138 icv = skb_put(skb, 4);
139 icv[0] = crc;
140 icv[1] = crc >> 8;
141 icv[2] = crc >> 16;
142 icv[3] = crc >> 24;
143
144 crypto_cipher_setkey(wep->tfm, key, klen);
145 sg.page = virt_to_page(pos);
146 sg.offset = offset_in_page(pos);
147 sg.length = len + 4;
148 crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
149
150 return 0;
151}
152
153
154/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
155 * the frame: IV (4 bytes), encrypted payload (including SNAP header),
156 * ICV (4 bytes). len includes both IV and ICV.
157 *
158 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
159 * failure. If frame is OK, IV and ICV will be removed.
160 */
161static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
162{
163 struct prism2_wep_data *wep = priv;
164 u32 crc, klen, plen;
165 u8 key[WEP_KEY_LEN + 3];
166 u8 keyidx, *pos, icv[4];
167 struct scatterlist sg;
168
169 if (skb->len < hdr_len + 8)
170 return -1;
171
172 pos = skb->data + hdr_len;
173 key[0] = *pos++;
174 key[1] = *pos++;
175 key[2] = *pos++;
176 keyidx = *pos++ >> 6;
177 if (keyidx != wep->key_idx)
178 return -1;
179
180 klen = 3 + wep->key_len;
181
182 /* Copy rest of the WEP key (the secret part) */
183 memcpy(key + 3, wep->key, wep->key_len);
184
185 /* Apply RC4 to data and compute CRC32 over decrypted data */
186 plen = skb->len - hdr_len - 8;
187
188 crypto_cipher_setkey(wep->tfm, key, klen);
189 sg.page = virt_to_page(pos);
190 sg.offset = offset_in_page(pos);
191 sg.length = plen + 4;
192 crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
193
194 crc = ~crc32_le(~0, pos, plen);
195 icv[0] = crc;
196 icv[1] = crc >> 8;
197 icv[2] = crc >> 16;
198 icv[3] = crc >> 24;
199 if (memcmp(icv, pos + plen, 4) != 0) {
200 /* ICV mismatch - drop frame */
201 return -2;
202 }
203
204 /* Remove IV and ICV */
205 memmove(skb->data + 4, skb->data, hdr_len);
206 skb_pull(skb, 4);
207 skb_trim(skb, skb->len - 4);
208
209 return 0;
210}
211
212
213static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
214{
215 struct prism2_wep_data *wep = priv;
216
217 if (len < 0 || len > WEP_KEY_LEN)
218 return -1;
219
220 memcpy(wep->key, key, len);
221 wep->key_len = len;
222
223 return 0;
224}
225
226
227static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
228{
229 struct prism2_wep_data *wep = priv;
230
231 if (len < wep->key_len)
232 return -1;
233
234 memcpy(key, wep->key, wep->key_len);
235
236 return wep->key_len;
237}
238
239
240static char * prism2_wep_print_stats(char *p, void *priv)
241{
242 struct prism2_wep_data *wep = priv;
243 p += sprintf(p, "key[%d] alg=WEP len=%d\n",
244 wep->key_idx, wep->key_len);
245 return p;
246}
247
248
249static struct hostap_crypto_ops hostap_crypt_wep = {
250 .name = "WEP",
251 .init = prism2_wep_init,
252 .deinit = prism2_wep_deinit,
253 .encrypt_mpdu = prism2_wep_encrypt,
254 .decrypt_mpdu = prism2_wep_decrypt,
255 .encrypt_msdu = NULL,
256 .decrypt_msdu = NULL,
257 .set_key = prism2_wep_set_key,
258 .get_key = prism2_wep_get_key,
259 .print_stats = prism2_wep_print_stats,
260 .extra_prefix_len = 4 /* IV */,
261 .extra_postfix_len = 4 /* ICV */
262};
263
264
265static int __init hostap_crypto_wep_init(void)
266{
267 if (hostap_register_crypto_ops(&hostap_crypt_wep) < 0)
268 return -1;
269
270 return 0;
271}
272
273
274static void __exit hostap_crypto_wep_exit(void)
275{
276 hostap_unregister_crypto_ops(&hostap_crypt_wep);
277}
278
279
280module_init(hostap_crypto_wep_init);
281module_exit(hostap_crypto_wep_exit);
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
new file mode 100644
index 000000000000..e66c797bdc8b
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -0,0 +1,950 @@
1#define PRISM2_PCCARD
2
3#include <linux/config.h>
4#include <linux/version.h>
5#include <linux/module.h>
6#include <linux/init.h>
7#include <linux/if.h>
8#include <linux/wait.h>
9#include <linux/timer.h>
10#include <linux/skbuff.h>
11#include <linux/netdevice.h>
12#include <linux/workqueue.h>
13#include <linux/wireless.h>
14#include <net/iw_handler.h>
15
16#include <pcmcia/version.h>
17#include <pcmcia/cs_types.h>
18#include <pcmcia/cs.h>
19#include <pcmcia/cistpl.h>
20#include <pcmcia/cisreg.h>
21#include <pcmcia/ds.h>
22
23#include <asm/io.h>
24
25#include "hostap_wlan.h"
26
27
28static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
29static dev_info_t dev_info = "hostap_cs";
30static dev_link_t *dev_list = NULL;
31
32MODULE_AUTHOR("Jouni Malinen");
33MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
34 "cards (PC Card).");
35MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)");
36MODULE_LICENSE("GPL");
37
38
39static int irq_mask = 0xdeb8;
40module_param(irq_mask, int, 0444);
41
42static int irq_list[4] = { -1 };
43module_param_array(irq_list, int, NULL, 0444);
44
45static int ignore_cis_vcc;
46module_param(ignore_cis_vcc, int, 0444);
47MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
48
49
50#ifdef PRISM2_IO_DEBUG
51
52static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
53{
54 struct hostap_interface *iface;
55 local_info_t *local;
56 unsigned long flags;
57
58 iface = netdev_priv(dev);
59 local = iface->local;
60 spin_lock_irqsave(&local->lock, flags);
61 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
62 outb(v, dev->base_addr + a);
63 spin_unlock_irqrestore(&local->lock, flags);
64}
65
66static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
67{
68 struct hostap_interface *iface;
69 local_info_t *local;
70 unsigned long flags;
71 u8 v;
72
73 iface = netdev_priv(dev);
74 local = iface->local;
75 spin_lock_irqsave(&local->lock, flags);
76 v = inb(dev->base_addr + a);
77 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
78 spin_unlock_irqrestore(&local->lock, flags);
79 return v;
80}
81
82static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
83{
84 struct hostap_interface *iface;
85 local_info_t *local;
86 unsigned long flags;
87
88 iface = netdev_priv(dev);
89 local = iface->local;
90 spin_lock_irqsave(&local->lock, flags);
91 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
92 outw(v, dev->base_addr + a);
93 spin_unlock_irqrestore(&local->lock, flags);
94}
95
96static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
97{
98 struct hostap_interface *iface;
99 local_info_t *local;
100 unsigned long flags;
101 u16 v;
102
103 iface = netdev_priv(dev);
104 local = iface->local;
105 spin_lock_irqsave(&local->lock, flags);
106 v = inw(dev->base_addr + a);
107 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
108 spin_unlock_irqrestore(&local->lock, flags);
109 return v;
110}
111
112static inline void hfa384x_outsw_debug(struct net_device *dev, int a,
113 u8 *buf, int wc)
114{
115 struct hostap_interface *iface;
116 local_info_t *local;
117 unsigned long flags;
118
119 iface = netdev_priv(dev);
120 local = iface->local;
121 spin_lock_irqsave(&local->lock, flags);
122 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
123 outsw(dev->base_addr + a, buf, wc);
124 spin_unlock_irqrestore(&local->lock, flags);
125}
126
127static inline void hfa384x_insw_debug(struct net_device *dev, int a,
128 u8 *buf, int wc)
129{
130 struct hostap_interface *iface;
131 local_info_t *local;
132 unsigned long flags;
133
134 iface = netdev_priv(dev);
135 local = iface->local;
136 spin_lock_irqsave(&local->lock, flags);
137 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
138 insw(dev->base_addr + a, buf, wc);
139 spin_unlock_irqrestore(&local->lock, flags);
140}
141
142#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
143#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
144#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
145#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
146#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
147#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
148
149#else /* PRISM2_IO_DEBUG */
150
151#define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
152#define HFA384X_INB(a) inb(dev->base_addr + (a))
153#define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
154#define HFA384X_INW(a) inw(dev->base_addr + (a))
155#define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
156#define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
157
158#endif /* PRISM2_IO_DEBUG */
159
160
161static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
162 int len)
163{
164 u16 d_off;
165 u16 *pos;
166
167 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
168 pos = (u16 *) buf;
169
170 if (len / 2)
171 HFA384X_INSW(d_off, buf, len / 2);
172 pos += len / 2;
173
174 if (len & 1)
175 *((char *) pos) = HFA384X_INB(d_off);
176
177 return 0;
178}
179
180
181static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
182{
183 u16 d_off;
184 u16 *pos;
185
186 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
187 pos = (u16 *) buf;
188
189 if (len / 2)
190 HFA384X_OUTSW(d_off, buf, len / 2);
191 pos += len / 2;
192
193 if (len & 1)
194 HFA384X_OUTB(*((char *) pos), d_off);
195
196 return 0;
197}
198
199
200/* FIX: This might change at some point.. */
201#include "hostap_hw.c"
202
203
204
205static void prism2_detach(dev_link_t *link);
206static void prism2_release(u_long arg);
207static int prism2_event(event_t event, int priority,
208 event_callback_args_t *args);
209
210
211static int prism2_pccard_card_present(local_info_t *local)
212{
213 if (local->link != NULL &&
214 ((local->link->state & (DEV_PRESENT | DEV_CONFIG)) ==
215 (DEV_PRESENT | DEV_CONFIG)))
216 return 1;
217 return 0;
218}
219
220
221/*
222 * SanDisk CompactFlash WLAN Flashcard - Product Manual v1.0
223 * Document No. 20-10-00058, January 2004
224 * http://www.sandisk.com/pdf/industrial/ProdManualCFWLANv1.0.pdf
225 */
226#define SANDISK_WLAN_ACTIVATION_OFF 0x40
227#define SANDISK_HCR_OFF 0x42
228
229
230static void sandisk_set_iobase(local_info_t *local)
231{
232 int res;
233 conf_reg_t reg;
234
235 reg.Function = 0;
236 reg.Action = CS_WRITE;
237 reg.Offset = 0x10; /* 0x3f0 IO base 1 */
238 reg.Value = local->link->io.BasePort1 & 0x00ff;
239 res = pcmcia_access_configuration_register(local->link->handle, &reg);
240 if (res != CS_SUCCESS) {
241 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
242 " res=%d\n", res);
243 }
244 udelay(10);
245
246 reg.Function = 0;
247 reg.Action = CS_WRITE;
248 reg.Offset = 0x12; /* 0x3f2 IO base 2 */
249 reg.Value = (local->link->io.BasePort1 & 0xff00) >> 8;
250 res = pcmcia_access_configuration_register(local->link->handle, &reg);
251 if (res != CS_SUCCESS) {
252 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
253 " res=%d\n", res);
254 }
255}
256
257
258static void sandisk_write_hcr(local_info_t *local, int hcr)
259{
260 struct net_device *dev = local->dev;
261 int i;
262
263 HFA384X_OUTB(0x80, SANDISK_WLAN_ACTIVATION_OFF);
264 udelay(50);
265 for (i = 0; i < 10; i++) {
266 HFA384X_OUTB(hcr, SANDISK_HCR_OFF);
267 }
268 udelay(55);
269 HFA384X_OUTB(0x45, SANDISK_WLAN_ACTIVATION_OFF);
270}
271
272
273static int sandisk_enable_wireless(struct net_device *dev)
274{
275 int res, ret = 0;
276 conf_reg_t reg;
277 struct hostap_interface *iface = dev->priv;
278 local_info_t *local = iface->local;
279 tuple_t tuple;
280 cisparse_t *parse = NULL;
281 u_char buf[64];
282
283 if (local->link->io.NumPorts1 < 0x42) {
284 /* Not enough ports to be SanDisk multi-function card */
285 ret = -ENODEV;
286 goto done;
287 }
288
289 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
290 if (parse == NULL) {
291 ret = -ENOMEM;
292 goto done;
293 }
294
295 tuple.DesiredTuple = CISTPL_MANFID;
296 tuple.Attributes = TUPLE_RETURN_COMMON;
297 tuple.TupleData = buf;
298 tuple.TupleDataMax = sizeof(buf);
299 tuple.TupleOffset = 0;
300 if (pcmcia_get_first_tuple(local->link->handle, &tuple) ||
301 pcmcia_get_tuple_data(local->link->handle, &tuple) ||
302 pcmcia_parse_tuple(local->link->handle, &tuple, parse) ||
303 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
304 /* No SanDisk manfid found */
305 ret = -ENODEV;
306 goto done;
307 }
308
309 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
310 if (pcmcia_get_first_tuple(local->link->handle, &tuple) ||
311 pcmcia_get_tuple_data(local->link->handle, &tuple) ||
312 pcmcia_parse_tuple(local->link->handle, &tuple, parse) ||
313 parse->longlink_mfc.nfn < 2) {
314 /* No multi-function links found */
315 ret = -ENODEV;
316 goto done;
317 }
318
319 printk(KERN_DEBUG "%s: Multi-function SanDisk ConnectPlus detected"
320 " - using vendor-specific initialization\n", dev->name);
321 local->sandisk_connectplus = 1;
322
323 reg.Function = 0;
324 reg.Action = CS_WRITE;
325 reg.Offset = CISREG_COR;
326 reg.Value = COR_SOFT_RESET;
327 res = pcmcia_access_configuration_register(local->link->handle, &reg);
328 if (res != CS_SUCCESS) {
329 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
330 dev->name, res);
331 goto done;
332 }
333 mdelay(5);
334
335 reg.Function = 0;
336 reg.Action = CS_WRITE;
337 reg.Offset = CISREG_COR;
338 /*
339 * Do not enable interrupts here to avoid some bogus events. Interrupts
340 * will be enabled during the first cor_sreset call.
341 */
342 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
343 res = pcmcia_access_configuration_register(local->link->handle, &reg);
344 if (res != CS_SUCCESS) {
345 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
346 dev->name, res);
347 goto done;
348 }
349 mdelay(5);
350
351 sandisk_set_iobase(local);
352
353 HFA384X_OUTB(0xc5, SANDISK_WLAN_ACTIVATION_OFF);
354 udelay(10);
355 HFA384X_OUTB(0x4b, SANDISK_WLAN_ACTIVATION_OFF);
356 udelay(10);
357
358done:
359 kfree(parse);
360 return ret;
361}
362
363
364static void prism2_pccard_cor_sreset(local_info_t *local)
365{
366 int res;
367 conf_reg_t reg;
368
369 if (!prism2_pccard_card_present(local))
370 return;
371
372 reg.Function = 0;
373 reg.Action = CS_READ;
374 reg.Offset = CISREG_COR;
375 reg.Value = 0;
376 res = pcmcia_access_configuration_register(local->link->handle, &reg);
377 if (res != CS_SUCCESS) {
378 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
379 res);
380 return;
381 }
382 printk(KERN_DEBUG "prism2_pccard_cor_sreset: original COR %02x\n",
383 reg.Value);
384
385 reg.Action = CS_WRITE;
386 reg.Value |= COR_SOFT_RESET;
387 res = pcmcia_access_configuration_register(local->link->handle, &reg);
388 if (res != CS_SUCCESS) {
389 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
390 res);
391 return;
392 }
393
394 mdelay(local->sandisk_connectplus ? 5 : 2);
395
396 reg.Value &= ~COR_SOFT_RESET;
397 if (local->sandisk_connectplus)
398 reg.Value |= COR_IREQ_ENA;
399 res = pcmcia_access_configuration_register(local->link->handle, &reg);
400 if (res != CS_SUCCESS) {
401 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
402 res);
403 return;
404 }
405
406 mdelay(local->sandisk_connectplus ? 5 : 2);
407
408 if (local->sandisk_connectplus)
409 sandisk_set_iobase(local);
410}
411
412
413static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
414{
415 int res;
416 conf_reg_t reg;
417 int old_cor;
418
419 if (!prism2_pccard_card_present(local))
420 return;
421
422 if (local->sandisk_connectplus) {
423 sandisk_write_hcr(local, hcr);
424 return;
425 }
426
427 reg.Function = 0;
428 reg.Action = CS_READ;
429 reg.Offset = CISREG_COR;
430 reg.Value = 0;
431 res = pcmcia_access_configuration_register(local->link->handle, &reg);
432 if (res != CS_SUCCESS) {
433 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
434 "(%d)\n", res);
435 return;
436 }
437 printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n",
438 reg.Value);
439 old_cor = reg.Value;
440
441 reg.Action = CS_WRITE;
442 reg.Value |= COR_SOFT_RESET;
443 res = pcmcia_access_configuration_register(local->link->handle, &reg);
444 if (res != CS_SUCCESS) {
445 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
446 "(%d)\n", res);
447 return;
448 }
449
450 mdelay(10);
451
452 /* Setup Genesis mode */
453 reg.Action = CS_WRITE;
454 reg.Value = hcr;
455 reg.Offset = CISREG_CCSR;
456 res = pcmcia_access_configuration_register(local->link->handle, &reg);
457 if (res != CS_SUCCESS) {
458 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
459 "(%d)\n", res);
460 return;
461 }
462 mdelay(10);
463
464 reg.Action = CS_WRITE;
465 reg.Offset = CISREG_COR;
466 reg.Value = old_cor & ~COR_SOFT_RESET;
467 res = pcmcia_access_configuration_register(local->link->handle, &reg);
468 if (res != CS_SUCCESS) {
469 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
470 "(%d)\n", res);
471 return;
472 }
473
474 mdelay(10);
475}
476
477
478static int prism2_pccard_dev_open(local_info_t *local)
479{
480 local->link->open++;
481 return 0;
482}
483
484
485static int prism2_pccard_dev_close(local_info_t *local)
486{
487 if (local == NULL || local->link == NULL)
488 return 1;
489
490 if (!local->link->open) {
491 printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
492 "link not open?!\n", local->dev->name);
493 return 1;
494 }
495
496 local->link->open--;
497
498 return 0;
499}
500
501
502static struct prism2_helper_functions prism2_pccard_funcs =
503{
504 .card_present = prism2_pccard_card_present,
505 .cor_sreset = prism2_pccard_cor_sreset,
506 .dev_open = prism2_pccard_dev_open,
507 .dev_close = prism2_pccard_dev_close,
508 .genesis_reset = prism2_pccard_genesis_reset,
509 .hw_type = HOSTAP_HW_PCCARD,
510};
511
512
513/* allocate local data and register with CardServices
514 * initialize dev_link structure, but do not configure the card yet */
515static dev_link_t *prism2_attach(void)
516{
517 dev_link_t *link;
518 client_reg_t client_reg;
519 int ret;
520
521 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
522 if (link == NULL)
523 return NULL;
524
525 memset(link, 0, sizeof(dev_link_t));
526
527 PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
528 link->conf.Vcc = 33;
529 link->conf.IntType = INT_MEMORY_AND_IO;
530
531 /* register with CardServices */
532 link->next = dev_list;
533 dev_list = link;
534 client_reg.dev_info = &dev_info;
535 client_reg.Attributes = INFO_IO_CLIENT;
536 client_reg.EventMask = CS_EVENT_CARD_INSERTION |
537 CS_EVENT_CARD_REMOVAL |
538 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
539 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
540 client_reg.event_handler = &prism2_event;
541 client_reg.Version = 0x0210;
542 client_reg.event_callback_args.client_data = link;
543 ret = pcmcia_register_client(&link->handle, &client_reg);
544 if (ret != CS_SUCCESS) {
545 cs_error(link->handle, RegisterClient, ret);
546 prism2_detach(link);
547 return NULL;
548 }
549 return link;
550}
551
552
553static void prism2_detach(dev_link_t *link)
554{
555 dev_link_t **linkp;
556
557 PDEBUG(DEBUG_FLOW, "prism2_detach\n");
558
559 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
560 if (*linkp == link)
561 break;
562 if (*linkp == NULL) {
563 printk(KERN_WARNING "%s: Attempt to detach non-existing "
564 "PCMCIA client\n", dev_info);
565 return;
566 }
567
568 if (link->state & DEV_CONFIG) {
569 prism2_release((u_long)link);
570 }
571
572 if (link->handle) {
573 int res = pcmcia_deregister_client(link->handle);
574 if (res) {
575 printk("CardService(DeregisterClient) => %d\n", res);
576 cs_error(link->handle, DeregisterClient, res);
577 }
578 }
579
580 *linkp = link->next;
581 /* release net devices */
582 if (link->priv) {
583 prism2_free_local_data((struct net_device *) link->priv);
584
585 }
586 kfree(link);
587}
588
589
590#define CS_CHECK(fn, ret) \
591do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
592
593#define CFG_CHECK2(fn, retf) \
594do { int ret = (retf); \
595if (ret != 0) { \
596 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
597 cs_error(link->handle, fn, ret); \
598 goto next_entry; \
599} \
600} while (0)
601
602
603/* run after a CARD_INSERTION event is received to configure the PCMCIA
604 * socket and make the device available to the system */
605static int prism2_config(dev_link_t *link)
606{
607 struct net_device *dev;
608 struct hostap_interface *iface;
609 local_info_t *local;
610 int ret = 1;
611 tuple_t tuple;
612 cisparse_t *parse;
613 int last_fn, last_ret;
614 u_char buf[64];
615 config_info_t conf;
616 cistpl_cftable_entry_t dflt = { 0 };
617
618 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
619
620 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
621 if (parse == NULL) {
622 ret = -ENOMEM;
623 goto failed;
624 }
625
626 tuple.DesiredTuple = CISTPL_CONFIG;
627 tuple.Attributes = 0;
628 tuple.TupleData = buf;
629 tuple.TupleDataMax = sizeof(buf);
630 tuple.TupleOffset = 0;
631 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
632 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple));
633 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse));
634 link->conf.ConfigBase = parse->config.base;
635 link->conf.Present = parse->config.rmask[0];
636
637 CS_CHECK(GetConfigurationInfo,
638 pcmcia_get_configuration_info(link->handle, &conf));
639 PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info,
640 ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc);
641 link->conf.Vcc = conf.Vcc;
642
643 /* Look for an appropriate configuration table entry in the CIS */
644 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
645 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
646 for (;;) {
647 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
648 CFG_CHECK2(GetTupleData,
649 pcmcia_get_tuple_data(link->handle, &tuple));
650 CFG_CHECK2(ParseTuple,
651 pcmcia_parse_tuple(link->handle, &tuple, parse));
652
653 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
654 dflt = *cfg;
655 if (cfg->index == 0)
656 goto next_entry;
657 link->conf.ConfigIndex = cfg->index;
658 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
659 "(default 0x%02X)\n", cfg->index, dflt.index);
660
661 /* Does this card need audio output? */
662 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
663 link->conf.Attributes |= CONF_ENABLE_SPKR;
664 link->conf.Status = CCSR_AUDIO_ENA;
665 }
666
667 /* Use power settings for Vcc and Vpp if present */
668 /* Note that the CIS values need to be rescaled */
669 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
670 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
671 10000 && !ignore_cis_vcc) {
672 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
673 " this entry\n");
674 goto next_entry;
675 }
676 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
677 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
678 10000 && !ignore_cis_vcc) {
679 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
680 "- skipping this entry\n");
681 goto next_entry;
682 }
683 }
684
685 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
686 link->conf.Vpp1 = link->conf.Vpp2 =
687 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
688 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
689 link->conf.Vpp1 = link->conf.Vpp2 =
690 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
691
692 /* Do we need to allocate an interrupt? */
693 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
694 link->conf.Attributes |= CONF_ENABLE_IRQ;
695 else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
696 /* At least Compaq WL200 does not have IRQInfo1 set,
697 * but it does not work without interrupts.. */
698 printk("Config has no IRQ info, but trying to enable "
699 "IRQ anyway..\n");
700 link->conf.Attributes |= CONF_ENABLE_IRQ;
701 }
702
703 /* IO window settings */
704 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
705 "dflt.io.nwin=%d\n",
706 cfg->io.nwin, dflt.io.nwin);
707 link->io.NumPorts1 = link->io.NumPorts2 = 0;
708 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
709 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
710 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
711 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
712 "io.base=0x%04x, len=%d\n", io->flags,
713 io->win[0].base, io->win[0].len);
714 if (!(io->flags & CISTPL_IO_8BIT))
715 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
716 if (!(io->flags & CISTPL_IO_16BIT))
717 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
718 link->io.IOAddrLines = io->flags &
719 CISTPL_IO_LINES_MASK;
720 link->io.BasePort1 = io->win[0].base;
721 link->io.NumPorts1 = io->win[0].len;
722 if (io->nwin > 1) {
723 link->io.Attributes2 = link->io.Attributes1;
724 link->io.BasePort2 = io->win[1].base;
725 link->io.NumPorts2 = io->win[1].len;
726 }
727 }
728
729 /* This reserves IO space but doesn't actually enable it */
730 CFG_CHECK2(RequestIO,
731 pcmcia_request_io(link->handle, &link->io));
732
733 /* This configuration table entry is OK */
734 break;
735
736 next_entry:
737 CS_CHECK(GetNextTuple,
738 pcmcia_get_next_tuple(link->handle, &tuple));
739 }
740
741 /* Need to allocate net_device before requesting IRQ handler */
742 dev = prism2_init_local_data(&prism2_pccard_funcs, 0);
743 if (dev == NULL)
744 goto failed;
745 link->priv = dev;
746
747 /*
748 * Allocate an interrupt line. Note that this does not assign a
749 * handler to the interrupt, unless the 'Handler' member of the
750 * irq structure is initialized.
751 */
752 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
753 int i;
754 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
755 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
756 if (irq_list[0] == -1)
757 link->irq.IRQInfo2 = irq_mask;
758 else
759 for (i = 0; i < 4; i++)
760 link->irq.IRQInfo2 |= 1 << irq_list[i];
761 link->irq.Handler = prism2_interrupt;
762 link->irq.Instance = dev;
763 CS_CHECK(RequestIRQ,
764 pcmcia_request_irq(link->handle, &link->irq));
765 }
766
767 /*
768 * This actually configures the PCMCIA socket -- setting up
769 * the I/O windows and the interrupt mapping, and putting the
770 * card and host interface into "Memory and IO" mode.
771 */
772 CS_CHECK(RequestConfiguration,
773 pcmcia_request_configuration(link->handle, &link->conf));
774
775 dev->irq = link->irq.AssignedIRQ;
776 dev->base_addr = link->io.BasePort1;
777
778 /* Finally, report what we've done */
779 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
780 dev_info, link->conf.ConfigIndex,
781 link->conf.Vcc / 10, link->conf.Vcc % 10);
782 if (link->conf.Vpp1)
783 printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
784 link->conf.Vpp1 % 10);
785 if (link->conf.Attributes & CONF_ENABLE_IRQ)
786 printk(", irq %d", link->irq.AssignedIRQ);
787 if (link->io.NumPorts1)
788 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
789 link->io.BasePort1+link->io.NumPorts1-1);
790 if (link->io.NumPorts2)
791 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
792 link->io.BasePort2+link->io.NumPorts2-1);
793 printk("\n");
794
795 link->state |= DEV_CONFIG;
796 link->state &= ~DEV_CONFIG_PENDING;
797
798 iface = netdev_priv(dev);
799 local = iface->local;
800 local->link = link;
801 strcpy(local->node.dev_name, dev->name);
802 link->dev = &local->node;
803
804 local->shutdown = 0;
805
806 sandisk_enable_wireless(dev);
807
808 ret = prism2_hw_config(dev, 1);
809 if (!ret) {
810 ret = hostap_hw_ready(dev);
811 if (ret == 0 && local->ddev)
812 strcpy(local->node.dev_name, local->ddev->name);
813 }
814 kfree(parse);
815 return ret;
816
817 cs_failed:
818 cs_error(link->handle, last_fn, last_ret);
819
820 failed:
821 kfree(parse);
822 prism2_release((u_long)link);
823 return ret;
824}
825
826
827static void prism2_release(u_long arg)
828{
829 dev_link_t *link = (dev_link_t *)arg;
830
831 PDEBUG(DEBUG_FLOW, "prism2_release\n");
832
833 if (link->priv) {
834 struct net_device *dev = link->priv;
835 struct hostap_interface *iface;
836
837 iface = netdev_priv(dev);
838 if (link->state & DEV_CONFIG)
839 prism2_hw_shutdown(dev, 0);
840 iface->local->shutdown = 1;
841 }
842
843 if (link->win)
844 pcmcia_release_window(link->win);
845 pcmcia_release_configuration(link->handle);
846 if (link->io.NumPorts1)
847 pcmcia_release_io(link->handle, &link->io);
848 if (link->irq.AssignedIRQ)
849 pcmcia_release_irq(link->handle, &link->irq);
850
851 link->state &= ~DEV_CONFIG;
852
853 PDEBUG(DEBUG_FLOW, "release - done\n");
854}
855
856
857static int prism2_event(event_t event, int priority,
858 event_callback_args_t *args)
859{
860 dev_link_t *link = args->client_data;
861 struct net_device *dev = (struct net_device *) link->priv;
862
863 switch (event) {
864 case CS_EVENT_CARD_INSERTION:
865 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
866 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
867 if (prism2_config(link)) {
868 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
869 }
870 break;
871
872 case CS_EVENT_CARD_REMOVAL:
873 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
874 link->state &= ~DEV_PRESENT;
875 if (link->state & DEV_CONFIG) {
876 netif_stop_queue(dev);
877 netif_device_detach(dev);
878 prism2_release((u_long) link);
879 }
880 break;
881
882 case CS_EVENT_PM_SUSPEND:
883 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
884 link->state |= DEV_SUSPEND;
885 /* fall through */
886
887 case CS_EVENT_RESET_PHYSICAL:
888 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
889 if (link->state & DEV_CONFIG) {
890 if (link->open) {
891 netif_stop_queue(dev);
892 netif_device_detach(dev);
893 }
894 prism2_suspend(dev);
895 pcmcia_release_configuration(link->handle);
896 }
897 break;
898
899 case CS_EVENT_PM_RESUME:
900 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
901 link->state &= ~DEV_SUSPEND;
902 /* fall through */
903
904 case CS_EVENT_CARD_RESET:
905 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
906 if (link->state & DEV_CONFIG) {
907 pcmcia_request_configuration(link->handle,
908 &link->conf);
909 prism2_hw_shutdown(dev, 1);
910 prism2_hw_config(dev, link->open ? 0 : 1);
911 if (link->open) {
912 netif_device_attach(dev);
913 netif_start_queue(dev);
914 }
915 }
916 break;
917
918 default:
919 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
920 dev_info, event);
921 break;
922 }
923 return 0;
924}
925
926
927static struct pcmcia_driver hostap_driver = {
928 .drv = {
929 .name = "hostap_cs",
930 },
931 .attach = prism2_attach,
932 .detach = prism2_detach,
933 .owner = THIS_MODULE,
934};
935
936static int __init init_prism2_pccard(void)
937{
938 printk(KERN_INFO "%s: %s\n", dev_info, version);
939 return pcmcia_register_driver(&hostap_driver);
940}
941
942static void __exit exit_prism2_pccard(void)
943{
944 pcmcia_unregister_driver(&hostap_driver);
945 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
946}
947
948
949module_init(init_prism2_pccard);
950module_exit(exit_prism2_pccard);
diff --git a/drivers/net/wireless/hostap/hostap_download.c b/drivers/net/wireless/hostap/hostap_download.c
new file mode 100644
index 000000000000..ab26b52b3e76
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_download.c
@@ -0,0 +1,766 @@
1static int prism2_enable_aux_port(struct net_device *dev, int enable)
2{
3 u16 val, reg;
4 int i, tries;
5 unsigned long flags;
6 struct hostap_interface *iface;
7 local_info_t *local;
8
9 iface = netdev_priv(dev);
10 local = iface->local;
11
12 if (local->no_pri) {
13 if (enable) {
14 PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
15 "port is already enabled\n", dev->name);
16 }
17 return 0;
18 }
19
20 spin_lock_irqsave(&local->cmdlock, flags);
21
22 /* wait until busy bit is clear */
23 tries = HFA384X_CMD_BUSY_TIMEOUT;
24 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
25 tries--;
26 udelay(1);
27 }
28 if (tries == 0) {
29 reg = HFA384X_INW(HFA384X_CMD_OFF);
30 spin_unlock_irqrestore(&local->cmdlock, flags);
31 printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
32 dev->name, reg);
33 return -ETIMEDOUT;
34 }
35
36 val = HFA384X_INW(HFA384X_CONTROL_OFF);
37
38 if (enable) {
39 HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
40 HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
41 HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);
42
43 if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED)
44 printk("prism2_enable_aux_port: was not disabled!?\n");
45 val &= ~HFA384X_AUX_PORT_MASK;
46 val |= HFA384X_AUX_PORT_ENABLE;
47 } else {
48 HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
49 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
50 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
51
52 if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED)
53 printk("prism2_enable_aux_port: was not enabled!?\n");
54 val &= ~HFA384X_AUX_PORT_MASK;
55 val |= HFA384X_AUX_PORT_DISABLE;
56 }
57 HFA384X_OUTW(val, HFA384X_CONTROL_OFF);
58
59 udelay(5);
60
61 i = 10000;
62 while (i > 0) {
63 val = HFA384X_INW(HFA384X_CONTROL_OFF);
64 val &= HFA384X_AUX_PORT_MASK;
65
66 if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
67 (!enable && val == HFA384X_AUX_PORT_DISABLED))
68 break;
69
70 udelay(10);
71 i--;
72 }
73
74 spin_unlock_irqrestore(&local->cmdlock, flags);
75
76 if (i == 0) {
77 printk("prism2_enable_aux_port(%d) timed out\n",
78 enable);
79 return -ETIMEDOUT;
80 }
81
82 return 0;
83}
84
85
86static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
87 void *buf)
88{
89 u16 page, offset;
90 if (addr & 1 || len & 1)
91 return -1;
92
93 page = addr >> 7;
94 offset = addr & 0x7f;
95
96 HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
97 HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
98
99 udelay(5);
100
101#ifdef PRISM2_PCI
102 {
103 u16 *pos = (u16 *) buf;
104 while (len > 0) {
105 *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
106 len -= 2;
107 }
108 }
109#else /* PRISM2_PCI */
110 HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
111#endif /* PRISM2_PCI */
112
113 return 0;
114}
115
116
117static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
118 void *buf)
119{
120 u16 page, offset;
121 if (addr & 1 || len & 1)
122 return -1;
123
124 page = addr >> 7;
125 offset = addr & 0x7f;
126
127 HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
128 HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
129
130 udelay(5);
131
132#ifdef PRISM2_PCI
133 {
134 u16 *pos = (u16 *) buf;
135 while (len > 0) {
136 HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
137 len -= 2;
138 }
139 }
140#else /* PRISM2_PCI */
141 HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
142#endif /* PRISM2_PCI */
143
144 return 0;
145}
146
147
148static int prism2_pda_ok(u8 *buf)
149{
150 u16 *pda = (u16 *) buf;
151 int pos;
152 u16 len, pdr;
153
154 if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
155 buf[3] == 0x00)
156 return 0;
157
158 pos = 0;
159 while (pos + 1 < PRISM2_PDA_SIZE / 2) {
160 len = le16_to_cpu(pda[pos]);
161 pdr = le16_to_cpu(pda[pos + 1]);
162 if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
163 return 0;
164
165 if (pdr == 0x0000 && len == 2) {
166 /* PDA end found */
167 return 1;
168 }
169
170 pos += len + 1;
171 }
172
173 return 0;
174}
175
176
177static int prism2_download_aux_dump(struct net_device *dev,
178 unsigned int addr, int len, u8 *buf)
179{
180 int res;
181
182 prism2_enable_aux_port(dev, 1);
183 res = hfa384x_from_aux(dev, addr, len, buf);
184 prism2_enable_aux_port(dev, 0);
185 if (res)
186 return -1;
187
188 return 0;
189}
190
191
192static u8 * prism2_read_pda(struct net_device *dev)
193{
194 u8 *buf;
195 int res, i, found = 0;
196#define NUM_PDA_ADDRS 4
197 unsigned int pda_addr[NUM_PDA_ADDRS] = {
198 0x7f0000 /* others than HFA3841 */,
199 0x3f0000 /* HFA3841 */,
200 0x390000 /* apparently used in older cards */,
201 0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
202 };
203
204 buf = (u8 *) kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
205 if (buf == NULL)
206 return NULL;
207
208 /* Note: wlan card should be in initial state (just after init cmd)
209 * and no other operations should be performed concurrently. */
210
211 prism2_enable_aux_port(dev, 1);
212
213 for (i = 0; i < NUM_PDA_ADDRS; i++) {
214 PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
215 dev->name, pda_addr[i]);
216 res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
217 if (res)
218 continue;
219 if (res == 0 && prism2_pda_ok(buf)) {
220 PDEBUG2(DEBUG_EXTRA2, ": OK\n");
221 found = 1;
222 break;
223 } else {
224 PDEBUG2(DEBUG_EXTRA2, ": failed\n");
225 }
226 }
227
228 prism2_enable_aux_port(dev, 0);
229
230 if (!found) {
231 printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
232 kfree(buf);
233 buf = NULL;
234 }
235
236 return buf;
237}
238
239
240static int prism2_download_volatile(local_info_t *local,
241 struct prism2_download_data *param)
242{
243 struct net_device *dev = local->dev;
244 int ret = 0, i;
245 u16 param0, param1;
246
247 if (local->hw_downloading) {
248 printk(KERN_WARNING "%s: Already downloading - aborting new "
249 "request\n", dev->name);
250 return -1;
251 }
252
253 local->hw_downloading = 1;
254 if (local->pri_only) {
255 hfa384x_disable_interrupts(dev);
256 } else {
257 prism2_hw_shutdown(dev, 0);
258
259 if (prism2_hw_init(dev, 0)) {
260 printk(KERN_WARNING "%s: Could not initialize card for"
261 " download\n", dev->name);
262 ret = -1;
263 goto out;
264 }
265 }
266
267 if (prism2_enable_aux_port(dev, 1)) {
268 printk(KERN_WARNING "%s: Could not enable AUX port\n",
269 dev->name);
270 ret = -1;
271 goto out;
272 }
273
274 param0 = param->start_addr & 0xffff;
275 param1 = param->start_addr >> 16;
276
277 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
278 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
279 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
280 (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
281 param0)) {
282 printk(KERN_WARNING "%s: Download command execution failed\n",
283 dev->name);
284 ret = -1;
285 goto out;
286 }
287
288 for (i = 0; i < param->num_areas; i++) {
289 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
290 dev->name, param->data[i].len, param->data[i].addr);
291 if (hfa384x_to_aux(dev, param->data[i].addr,
292 param->data[i].len, param->data[i].data)) {
293 printk(KERN_WARNING "%s: RAM download at 0x%08x "
294 "(len=%d) failed\n", dev->name,
295 param->data[i].addr, param->data[i].len);
296 ret = -1;
297 goto out;
298 }
299 }
300
301 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
302 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
303 if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
304 (HFA384X_PROGMODE_DISABLE << 8), param0)) {
305 printk(KERN_WARNING "%s: Download command execution failed\n",
306 dev->name);
307 ret = -1;
308 goto out;
309 }
310 /* ProgMode disable causes the hardware to restart itself from the
311 * given starting address. Give hw some time and ACK command just in
312 * case restart did not happen. */
313 mdelay(5);
314 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
315
316 if (prism2_enable_aux_port(dev, 0)) {
317 printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
318 dev->name);
319 /* continue anyway.. restart should have taken care of this */
320 }
321
322 mdelay(5);
323 local->hw_downloading = 0;
324 if (prism2_hw_config(dev, 2)) {
325 printk(KERN_WARNING "%s: Card configuration after RAM "
326 "download failed\n", dev->name);
327 ret = -1;
328 goto out;
329 }
330
331 out:
332 local->hw_downloading = 0;
333 return ret;
334}
335
336
337static int prism2_enable_genesis(local_info_t *local, int hcr)
338{
339 struct net_device *dev = local->dev;
340 u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
341 u8 readbuf[4];
342
343 printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
344 dev->name, hcr);
345 local->func->cor_sreset(local);
346 hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
347 local->func->genesis_reset(local, hcr);
348
349 /* Readback test */
350 hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
351 hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
352 hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
353
354 if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
355 printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
356 hcr);
357 return 0;
358 } else {
359 printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
360 "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
361 hcr, initseq[0], initseq[1], initseq[2], initseq[3],
362 readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
363 return 1;
364 }
365}
366
367
368static int prism2_get_ram_size(local_info_t *local)
369{
370 int ret;
371
372 /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
373 if (prism2_enable_genesis(local, 0x1f) == 0)
374 ret = 8;
375 else if (prism2_enable_genesis(local, 0x0f) == 0)
376 ret = 16;
377 else
378 ret = -1;
379
380 /* Disable genesis mode */
381 local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
382
383 return ret;
384}
385
386
387static int prism2_download_genesis(local_info_t *local,
388 struct prism2_download_data *param)
389{
390 struct net_device *dev = local->dev;
391 int ram16 = 0, i;
392 int ret = 0;
393
394 if (local->hw_downloading) {
395 printk(KERN_WARNING "%s: Already downloading - aborting new "
396 "request\n", dev->name);
397 return -EBUSY;
398 }
399
400 if (!local->func->genesis_reset || !local->func->cor_sreset) {
401 printk(KERN_INFO "%s: Genesis mode downloading not supported "
402 "with this hwmodel\n", dev->name);
403 return -EOPNOTSUPP;
404 }
405
406 local->hw_downloading = 1;
407
408 if (prism2_enable_aux_port(dev, 1)) {
409 printk(KERN_DEBUG "%s: failed to enable AUX port\n",
410 dev->name);
411 ret = -EIO;
412 goto out;
413 }
414
415 if (local->sram_type == -1) {
416 /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
417 if (prism2_enable_genesis(local, 0x1f) == 0) {
418 ram16 = 0;
419 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
420 "SRAM\n", dev->name);
421 } else if (prism2_enable_genesis(local, 0x0f) == 0) {
422 ram16 = 1;
423 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
424 "SRAM\n", dev->name);
425 } else {
426 printk(KERN_DEBUG "%s: Could not initiate genesis "
427 "mode\n", dev->name);
428 ret = -EIO;
429 goto out;
430 }
431 } else {
432 if (prism2_enable_genesis(local, local->sram_type == 8 ?
433 0x1f : 0x0f)) {
434 printk(KERN_DEBUG "%s: Failed to set Genesis "
435 "mode (sram_type=%d)\n", dev->name,
436 local->sram_type);
437 ret = -EIO;
438 goto out;
439 }
440 ram16 = local->sram_type != 8;
441 }
442
443 for (i = 0; i < param->num_areas; i++) {
444 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
445 dev->name, param->data[i].len, param->data[i].addr);
446 if (hfa384x_to_aux(dev, param->data[i].addr,
447 param->data[i].len, param->data[i].data)) {
448 printk(KERN_WARNING "%s: RAM download at 0x%08x "
449 "(len=%d) failed\n", dev->name,
450 param->data[i].addr, param->data[i].len);
451 ret = -EIO;
452 goto out;
453 }
454 }
455
456 PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
457 local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
458 if (prism2_enable_aux_port(dev, 0)) {
459 printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
460 dev->name);
461 }
462
463 mdelay(5);
464 local->hw_downloading = 0;
465
466 PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
467 /*
468 * Make sure the INIT command does not generate a command completion
469 * event by disabling interrupts.
470 */
471 hfa384x_disable_interrupts(dev);
472 if (prism2_hw_init(dev, 1)) {
473 printk(KERN_DEBUG "%s: Initialization after genesis mode "
474 "download failed\n", dev->name);
475 ret = -EIO;
476 goto out;
477 }
478
479 PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
480 if (prism2_hw_init2(dev, 1)) {
481 printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
482 "download failed\n", dev->name);
483 ret = -EIO;
484 goto out;
485 }
486
487 out:
488 local->hw_downloading = 0;
489 return ret;
490}
491
492
493#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
494/* Note! Non-volatile downloading functionality has not yet been tested
495 * thoroughly and it may corrupt flash image and effectively kill the card that
496 * is being updated. You have been warned. */
497
498static inline int prism2_download_block(struct net_device *dev,
499 u32 addr, u8 *data,
500 u32 bufaddr, int rest_len)
501{
502 u16 param0, param1;
503 int block_len;
504
505 block_len = rest_len < 4096 ? rest_len : 4096;
506
507 param0 = addr & 0xffff;
508 param1 = addr >> 16;
509
510 HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
511 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
512
513 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
514 (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
515 param0)) {
516 printk(KERN_WARNING "%s: Flash download command execution "
517 "failed\n", dev->name);
518 return -1;
519 }
520
521 if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
522 printk(KERN_WARNING "%s: flash download at 0x%08x "
523 "(len=%d) failed\n", dev->name, addr, block_len);
524 return -1;
525 }
526
527 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
528 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
529 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
530 (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
531 0)) {
532 printk(KERN_WARNING "%s: Flash write command execution "
533 "failed\n", dev->name);
534 return -1;
535 }
536
537 return block_len;
538}
539
540
541static int prism2_download_nonvolatile(local_info_t *local,
542 struct prism2_download_data *dl)
543{
544 struct net_device *dev = local->dev;
545 int ret = 0, i;
546 struct {
547 u16 page;
548 u16 offset;
549 u16 len;
550 } dlbuffer;
551 u32 bufaddr;
552
553 if (local->hw_downloading) {
554 printk(KERN_WARNING "%s: Already downloading - aborting new "
555 "request\n", dev->name);
556 return -1;
557 }
558
559 ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
560 &dlbuffer, 6, 0);
561
562 if (ret < 0) {
563 printk(KERN_WARNING "%s: Could not read download buffer "
564 "parameters\n", dev->name);
565 goto out;
566 }
567
568 dlbuffer.page = le16_to_cpu(dlbuffer.page);
569 dlbuffer.offset = le16_to_cpu(dlbuffer.offset);
570 dlbuffer.len = le16_to_cpu(dlbuffer.len);
571
572 printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
573 dlbuffer.len, dlbuffer.page, dlbuffer.offset);
574
575 bufaddr = (dlbuffer.page << 7) + dlbuffer.offset;
576
577 local->hw_downloading = 1;
578
579 if (!local->pri_only) {
580 prism2_hw_shutdown(dev, 0);
581
582 if (prism2_hw_init(dev, 0)) {
583 printk(KERN_WARNING "%s: Could not initialize card for"
584 " download\n", dev->name);
585 ret = -1;
586 goto out;
587 }
588 }
589
590 hfa384x_disable_interrupts(dev);
591
592 if (prism2_enable_aux_port(dev, 1)) {
593 printk(KERN_WARNING "%s: Could not enable AUX port\n",
594 dev->name);
595 ret = -1;
596 goto out;
597 }
598
599 printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
600 for (i = 0; i < dl->num_areas; i++) {
601 int rest_len = dl->data[i].len;
602 int data_off = 0;
603
604 while (rest_len > 0) {
605 int block_len;
606
607 block_len = prism2_download_block(
608 dev, dl->data[i].addr + data_off,
609 dl->data[i].data + data_off, bufaddr,
610 rest_len);
611
612 if (block_len < 0) {
613 ret = -1;
614 goto out;
615 }
616
617 rest_len -= block_len;
618 data_off += block_len;
619 }
620 }
621
622 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
623 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
624 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
625 (HFA384X_PROGMODE_DISABLE << 8), 0)) {
626 printk(KERN_WARNING "%s: Download command execution failed\n",
627 dev->name);
628 ret = -1;
629 goto out;
630 }
631
632 if (prism2_enable_aux_port(dev, 0)) {
633 printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
634 dev->name);
635 /* continue anyway.. restart should have taken care of this */
636 }
637
638 mdelay(5);
639
640 local->func->hw_reset(dev);
641 local->hw_downloading = 0;
642 if (prism2_hw_config(dev, 2)) {
643 printk(KERN_WARNING "%s: Card configuration after flash "
644 "download failed\n", dev->name);
645 ret = -1;
646 } else {
647 printk(KERN_INFO "%s: Card initialized successfully after "
648 "flash download\n", dev->name);
649 }
650
651 out:
652 local->hw_downloading = 0;
653 return ret;
654}
655#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
656
657
658static void prism2_download_free_data(struct prism2_download_data *dl)
659{
660 int i;
661
662 if (dl == NULL)
663 return;
664
665 for (i = 0; i < dl->num_areas; i++)
666 kfree(dl->data[i].data);
667 kfree(dl);
668}
669
670
671static int prism2_download(local_info_t *local,
672 struct prism2_download_param *param)
673{
674 int ret = 0;
675 int i;
676 u32 total_len = 0;
677 struct prism2_download_data *dl = NULL;
678
679 printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
680 "num_areas=%d\n",
681 param->dl_cmd, param->start_addr, param->num_areas);
682
683 if (param->num_areas > 100) {
684 ret = -EINVAL;
685 goto out;
686 }
687
688 dl = kmalloc(sizeof(*dl) + param->num_areas *
689 sizeof(struct prism2_download_data_area), GFP_KERNEL);
690 if (dl == NULL) {
691 ret = -ENOMEM;
692 goto out;
693 }
694 memset(dl, 0, sizeof(*dl) + param->num_areas *
695 sizeof(struct prism2_download_data_area));
696 dl->dl_cmd = param->dl_cmd;
697 dl->start_addr = param->start_addr;
698 dl->num_areas = param->num_areas;
699 for (i = 0; i < param->num_areas; i++) {
700 PDEBUG(DEBUG_EXTRA2,
701 " area %d: addr=0x%08x len=%d ptr=0x%p\n",
702 i, param->data[i].addr, param->data[i].len,
703 param->data[i].ptr);
704
705 dl->data[i].addr = param->data[i].addr;
706 dl->data[i].len = param->data[i].len;
707
708 total_len += param->data[i].len;
709 if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
710 total_len > PRISM2_MAX_DOWNLOAD_LEN) {
711 ret = -E2BIG;
712 goto out;
713 }
714
715 dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
716 if (dl->data[i].data == NULL) {
717 ret = -ENOMEM;
718 goto out;
719 }
720
721 if (copy_from_user(dl->data[i].data, param->data[i].ptr,
722 param->data[i].len)) {
723 ret = -EFAULT;
724 goto out;
725 }
726 }
727
728 switch (param->dl_cmd) {
729 case PRISM2_DOWNLOAD_VOLATILE:
730 case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
731 ret = prism2_download_volatile(local, dl);
732 break;
733 case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
734 case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
735 ret = prism2_download_genesis(local, dl);
736 break;
737 case PRISM2_DOWNLOAD_NON_VOLATILE:
738#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
739 ret = prism2_download_nonvolatile(local, dl);
740#else /* PRISM2_NON_VOLATILE_DOWNLOAD */
741 printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
742 local->dev->name);
743 ret = -EOPNOTSUPP;
744#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
745 break;
746 default:
747 printk(KERN_DEBUG "%s: unsupported download command %d\n",
748 local->dev->name, param->dl_cmd);
749 ret = -EINVAL;
750 break;
751 };
752
753 out:
754 if (ret == 0 && dl &&
755 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
756 prism2_download_free_data(local->dl_pri);
757 local->dl_pri = dl;
758 } else if (ret == 0 && dl &&
759 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
760 prism2_download_free_data(local->dl_sec);
761 local->dl_sec = dl;
762 } else
763 prism2_download_free_data(dl);
764
765 return ret;
766}
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
new file mode 100644
index 000000000000..039ef7f61bee
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -0,0 +1,3631 @@
1/*
2 * Host AP (software wireless LAN access point) driver for
3 * Intersil Prism2/2.5/3.
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. See README and COPYING for
12 * more details.
13 *
14 * FIX:
15 * - there is currently no way of associating TX packets to correct wds device
16 * when TX Exc/OK event occurs, so all tx_packets and some
17 * tx_errors/tx_dropped are added to the main netdevice; using sw_support
18 * field in txdesc might be used to fix this (using Alloc event to increment
19 * tx_packets would need some further info in txfid table)
20 *
21 * Buffer Access Path (BAP) usage:
22 * Prism2 cards have two separate BAPs for accessing the card memory. These
23 * should allow concurrent access to two different frames and the driver
24 * previously used BAP0 for sending data and BAP1 for receiving data.
25 * However, there seems to be number of issues with concurrent access and at
26 * least one know hardware bug in using BAP0 and BAP1 concurrently with PCI
27 * Prism2.5. Therefore, the driver now only uses BAP0 for moving data between
28 * host and card memories. BAP0 accesses are protected with local->baplock
29 * (spin_lock_bh) to prevent concurrent use.
30 */
31
32
33#include <linux/config.h>
34#include <linux/version.h>
35
36#include <asm/delay.h>
37#include <asm/uaccess.h>
38
39#include <linux/slab.h>
40#include <linux/netdevice.h>
41#include <linux/etherdevice.h>
42#include <linux/proc_fs.h>
43#include <linux/if_arp.h>
44#include <linux/delay.h>
45#include <linux/random.h>
46#include <linux/wait.h>
47#include <linux/sched.h>
48#include <linux/rtnetlink.h>
49#include <linux/wireless.h>
50#include <net/iw_handler.h>
51#include <asm/irq.h>
52
53
54#include "hostap_80211.h"
55#include "hostap.h"
56#include "hostap_ap.h"
57
58
59/* #define final_version */
60
61static int mtu = 1500;
62module_param(mtu, int, 0444);
63MODULE_PARM_DESC(mtu, "Maximum transfer unit");
64
65static int channel[MAX_PARM_DEVICES] = { 3, DEF_INTS };
66module_param_array(channel, int, NULL, 0444);
67MODULE_PARM_DESC(channel, "Initial channel");
68
69static char essid[33] = "test";
70module_param_string(essid, essid, sizeof(essid), 0444);
71MODULE_PARM_DESC(essid, "Host AP's ESSID");
72
73static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS };
74module_param_array(iw_mode, int, NULL, 0444);
75MODULE_PARM_DESC(iw_mode, "Initial operation mode");
76
77static int beacon_int[MAX_PARM_DEVICES] = { 100, DEF_INTS };
78module_param_array(beacon_int, int, NULL, 0444);
79MODULE_PARM_DESC(beacon_int, "Beacon interval (1 = 1024 usec)");
80
81static int dtim_period[MAX_PARM_DEVICES] = { 1, DEF_INTS };
82module_param_array(dtim_period, int, NULL, 0444);
83MODULE_PARM_DESC(dtim_period, "DTIM period");
84
85#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
86static int bus_master_threshold_rx[MAX_PARM_DEVICES] = { 100, DEF_INTS };
87module_param_array(bus_master_threshold_rx, int, NULL, 0444);
88MODULE_PARM_DESC(bus_master_threshold_rx, "Packet length threshold for using "
89 "PCI bus master on RX");
90
91static int bus_master_threshold_tx[MAX_PARM_DEVICES] = { 100, DEF_INTS };
92module_param_array(bus_master_threshold_tx, int, NULL, 0444);
93MODULE_PARM_DESC(bus_master_threshold_tx, "Packet length threshold for using "
94 "PCI bus master on TX");
95#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
96
97static char dev_template[16] = "wlan%d";
98module_param_string(dev_template, dev_template, sizeof(dev_template), 0444);
99MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: "
100 "wlan%d)");
101
102#ifdef final_version
103#define EXTRA_EVENTS_WTERR 0
104#else
105/* check WTERR events (Wait Time-out) in development versions */
106#define EXTRA_EVENTS_WTERR HFA384X_EV_WTERR
107#endif
108
109#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
110#define EXTRA_EVENTS_BUS_MASTER (HFA384X_EV_PCI_M0 | HFA384X_EV_PCI_M1)
111#else
112#define EXTRA_EVENTS_BUS_MASTER 0
113#endif
114
115/* Events that will be using BAP0 */
116#define HFA384X_BAP0_EVENTS \
117 (HFA384X_EV_TXEXC | HFA384X_EV_RX | HFA384X_EV_INFO | HFA384X_EV_TX)
118
119/* event mask, i.e., events that will result in an interrupt */
120#define HFA384X_EVENT_MASK \
121 (HFA384X_BAP0_EVENTS | HFA384X_EV_ALLOC | HFA384X_EV_INFDROP | \
122 HFA384X_EV_CMD | HFA384X_EV_TICK | \
123 EXTRA_EVENTS_WTERR | EXTRA_EVENTS_BUS_MASTER)
124
125/* Default TX control flags: use 802.11 headers and request interrupt for
126 * failed transmits. Frames that request ACK callback, will add
127 * _TX_OK flag and _ALT_RTRY flag may be used to select different retry policy.
128 */
129#define HFA384X_TX_CTRL_FLAGS \
130 (HFA384X_TX_CTRL_802_11 | HFA384X_TX_CTRL_TX_EX)
131
132
133/* ca. 1 usec */
134#define HFA384X_CMD_BUSY_TIMEOUT 5000
135#define HFA384X_BAP_BUSY_TIMEOUT 50000
136
137/* ca. 10 usec */
138#define HFA384X_CMD_COMPL_TIMEOUT 20000
139#define HFA384X_DL_COMPL_TIMEOUT 1000000
140
141/* Wait times for initialization; yield to other processes to avoid busy
142 * waiting for long time. */
143#define HFA384X_INIT_TIMEOUT (HZ / 2) /* 500 ms */
144#define HFA384X_ALLOC_COMPL_TIMEOUT (HZ / 20) /* 50 ms */
145
146
147static void prism2_hw_reset(struct net_device *dev);
148static void prism2_check_sta_fw_version(local_info_t *local);
149
150#ifdef PRISM2_DOWNLOAD_SUPPORT
151/* hostap_download.c */
152static int prism2_download_aux_dump(struct net_device *dev,
153 unsigned int addr, int len, u8 *buf);
154static u8 * prism2_read_pda(struct net_device *dev);
155static int prism2_download(local_info_t *local,
156 struct prism2_download_param *param);
157static void prism2_download_free_data(struct prism2_download_data *dl);
158static int prism2_download_volatile(local_info_t *local,
159 struct prism2_download_data *param);
160static int prism2_download_genesis(local_info_t *local,
161 struct prism2_download_data *param);
162static int prism2_get_ram_size(local_info_t *local);
163#endif /* PRISM2_DOWNLOAD_SUPPORT */
164
165
166
167
168#ifndef final_version
169/* magic value written to SWSUPPORT0 reg. for detecting whether card is still
170 * present */
171#define HFA384X_MAGIC 0x8A32
172#endif
173
174
175static u16 hfa384x_read_reg(struct net_device *dev, u16 reg)
176{
177 return HFA384X_INW(reg);
178}
179
180
181static void hfa384x_read_regs(struct net_device *dev,
182 struct hfa384x_regs *regs)
183{
184 regs->cmd = HFA384X_INW(HFA384X_CMD_OFF);
185 regs->evstat = HFA384X_INW(HFA384X_EVSTAT_OFF);
186 regs->offset0 = HFA384X_INW(HFA384X_OFFSET0_OFF);
187 regs->offset1 = HFA384X_INW(HFA384X_OFFSET1_OFF);
188 regs->swsupport0 = HFA384X_INW(HFA384X_SWSUPPORT0_OFF);
189}
190
191
192/**
193 * __hostap_cmd_queue_free - Free Prism2 command queue entry (private)
194 * @local: pointer to private Host AP driver data
195 * @entry: Prism2 command queue entry to be freed
196 * @del_req: request the entry to be removed
197 *
198 * Internal helper function for freeing Prism2 command queue entries.
199 * Caller must have acquired local->cmdlock before calling this function.
200 */
201static inline void __hostap_cmd_queue_free(local_info_t *local,
202 struct hostap_cmd_queue *entry,
203 int del_req)
204{
205 if (del_req) {
206 entry->del_req = 1;
207 if (!list_empty(&entry->list)) {
208 list_del_init(&entry->list);
209 local->cmd_queue_len--;
210 }
211 }
212
213 if (atomic_dec_and_test(&entry->usecnt) && entry->del_req)
214 kfree(entry);
215}
216
217
218/**
219 * hostap_cmd_queue_free - Free Prism2 command queue entry
220 * @local: pointer to private Host AP driver data
221 * @entry: Prism2 command queue entry to be freed
222 * @del_req: request the entry to be removed
223 *
224 * Free a Prism2 command queue entry.
225 */
226static inline void hostap_cmd_queue_free(local_info_t *local,
227 struct hostap_cmd_queue *entry,
228 int del_req)
229{
230 unsigned long flags;
231
232 spin_lock_irqsave(&local->cmdlock, flags);
233 __hostap_cmd_queue_free(local, entry, del_req);
234 spin_unlock_irqrestore(&local->cmdlock, flags);
235}
236
237
238/**
239 * prism2_clear_cmd_queue - Free all pending Prism2 command queue entries
240 * @local: pointer to private Host AP driver data
241 */
242static void prism2_clear_cmd_queue(local_info_t *local)
243{
244 struct list_head *ptr, *n;
245 unsigned long flags;
246 struct hostap_cmd_queue *entry;
247
248 spin_lock_irqsave(&local->cmdlock, flags);
249 list_for_each_safe(ptr, n, &local->cmd_queue) {
250 entry = list_entry(ptr, struct hostap_cmd_queue, list);
251 atomic_inc(&entry->usecnt);
252 printk(KERN_DEBUG "%s: removed pending cmd_queue entry "
253 "(type=%d, cmd=0x%04x, param0=0x%04x)\n",
254 local->dev->name, entry->type, entry->cmd,
255 entry->param0);
256 __hostap_cmd_queue_free(local, entry, 1);
257 }
258 if (local->cmd_queue_len) {
259 /* This should not happen; print debug message and clear
260 * queue length. */
261 printk(KERN_DEBUG "%s: cmd_queue_len (%d) not zero after "
262 "flush\n", local->dev->name, local->cmd_queue_len);
263 local->cmd_queue_len = 0;
264 }
265 spin_unlock_irqrestore(&local->cmdlock, flags);
266}
267
268
269/**
270 * hfa384x_cmd_issue - Issue a Prism2 command to the hardware
271 * @dev: pointer to net_device
272 * @entry: Prism2 command queue entry to be issued
273 */
274static inline int hfa384x_cmd_issue(struct net_device *dev,
275 struct hostap_cmd_queue *entry)
276{
277 struct hostap_interface *iface;
278 local_info_t *local;
279 int tries;
280 u16 reg;
281 unsigned long flags;
282
283 iface = netdev_priv(dev);
284 local = iface->local;
285
286 if (local->func->card_present && !local->func->card_present(local))
287 return -ENODEV;
288
289 if (entry->issued) {
290 printk(KERN_DEBUG "%s: driver bug - re-issuing command @%p\n",
291 dev->name, entry);
292 }
293
294 /* wait until busy bit is clear; this should always be clear since the
295 * commands are serialized */
296 tries = HFA384X_CMD_BUSY_TIMEOUT;
297 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
298 tries--;
299 udelay(1);
300 }
301#ifndef final_version
302 if (tries != HFA384X_CMD_BUSY_TIMEOUT) {
303 prism2_io_debug_error(dev, 1);
304 printk(KERN_DEBUG "%s: hfa384x_cmd_issue: cmd reg was busy "
305 "for %d usec\n", dev->name,
306 HFA384X_CMD_BUSY_TIMEOUT - tries);
307 }
308#endif
309 if (tries == 0) {
310 reg = HFA384X_INW(HFA384X_CMD_OFF);
311 prism2_io_debug_error(dev, 2);
312 printk(KERN_DEBUG "%s: hfa384x_cmd_issue - timeout - "
313 "reg=0x%04x\n", dev->name, reg);
314 return -ETIMEDOUT;
315 }
316
317 /* write command */
318 spin_lock_irqsave(&local->cmdlock, flags);
319 HFA384X_OUTW(entry->param0, HFA384X_PARAM0_OFF);
320 HFA384X_OUTW(entry->param1, HFA384X_PARAM1_OFF);
321 HFA384X_OUTW(entry->cmd, HFA384X_CMD_OFF);
322 entry->issued = 1;
323 spin_unlock_irqrestore(&local->cmdlock, flags);
324
325 return 0;
326}
327
328
329/**
330 * hfa384x_cmd - Issue a Prism2 command and wait (sleep) for completion
331 * @dev: pointer to net_device
332 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
333 * @param0: value for Param0 register
334 * @param1: value for Param1 register (pointer; %NULL if not used)
335 * @resp0: pointer for Resp0 data or %NULL if Resp0 is not needed
336 *
337 * Issue given command (possibly after waiting in command queue) and sleep
338 * until the command is completed (or timed out or interrupted). This can be
339 * called only from user process context.
340 */
341static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
342 u16 *param1, u16 *resp0)
343{
344 struct hostap_interface *iface;
345 local_info_t *local;
346 int err, res, issue, issued = 0;
347 unsigned long flags;
348 struct hostap_cmd_queue *entry;
349 DECLARE_WAITQUEUE(wait, current);
350
351 iface = netdev_priv(dev);
352 local = iface->local;
353
354 if (in_interrupt()) {
355 printk(KERN_DEBUG "%s: hfa384x_cmd called from interrupt "
356 "context\n", dev->name);
357 return -1;
358 }
359
360 if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN) {
361 printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n",
362 dev->name);
363 return -1;
364 }
365
366 if (signal_pending(current))
367 return -EINTR;
368
369 entry = (struct hostap_cmd_queue *)
370 kmalloc(sizeof(*entry), GFP_ATOMIC);
371 if (entry == NULL) {
372 printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
373 dev->name);
374 return -ENOMEM;
375 }
376 memset(entry, 0, sizeof(*entry));
377 atomic_set(&entry->usecnt, 1);
378 entry->type = CMD_SLEEP;
379 entry->cmd = cmd;
380 entry->param0 = param0;
381 if (param1)
382 entry->param1 = *param1;
383 init_waitqueue_head(&entry->compl);
384
385 /* prepare to wait for command completion event, but do not sleep yet
386 */
387 add_wait_queue(&entry->compl, &wait);
388 set_current_state(TASK_INTERRUPTIBLE);
389
390 spin_lock_irqsave(&local->cmdlock, flags);
391 issue = list_empty(&local->cmd_queue);
392 if (issue)
393 entry->issuing = 1;
394 list_add_tail(&entry->list, &local->cmd_queue);
395 local->cmd_queue_len++;
396 spin_unlock_irqrestore(&local->cmdlock, flags);
397
398 err = 0;
399 if (!issue)
400 goto wait_completion;
401
402 if (signal_pending(current))
403 err = -EINTR;
404
405 if (!err) {
406 if (hfa384x_cmd_issue(dev, entry))
407 err = -ETIMEDOUT;
408 else
409 issued = 1;
410 }
411
412 wait_completion:
413 if (!err && entry->type != CMD_COMPLETED) {
414 /* sleep until command is completed or timed out */
415 res = schedule_timeout(2 * HZ);
416 } else
417 res = -1;
418
419 if (!err && signal_pending(current))
420 err = -EINTR;
421
422 if (err && issued) {
423 /* the command was issued, so a CmdCompl event should occur
424 * soon; however, there's a pending signal and
425 * schedule_timeout() would be interrupted; wait a short period
426 * of time to avoid removing entry from the list before
427 * CmdCompl event */
428 udelay(300);
429 }
430
431 set_current_state(TASK_RUNNING);
432 remove_wait_queue(&entry->compl, &wait);
433
434 /* If entry->list is still in the list, it must be removed
435 * first and in this case prism2_cmd_ev() does not yet have
436 * local reference to it, and the data can be kfree()'d
437 * here. If the command completion event is still generated,
438 * it will be assigned to next (possibly) pending command, but
439 * the driver will reset the card anyway due to timeout
440 *
441 * If the entry is not in the list prism2_cmd_ev() has a local
442 * reference to it, but keeps cmdlock as long as the data is
443 * needed, so the data can be kfree()'d here. */
444
445 /* FIX: if the entry->list is in the list, it has not been completed
446 * yet, so removing it here is somewhat wrong.. this could cause
447 * references to freed memory and next list_del() causing NULL pointer
448 * dereference.. it would probably be better to leave the entry in the
449 * list and the list should be emptied during hw reset */
450
451 spin_lock_irqsave(&local->cmdlock, flags);
452 if (!list_empty(&entry->list)) {
453 printk(KERN_DEBUG "%s: hfa384x_cmd: entry still in list? "
454 "(entry=%p, type=%d, res=%d)\n", dev->name, entry,
455 entry->type, res);
456 list_del_init(&entry->list);
457 local->cmd_queue_len--;
458 }
459 spin_unlock_irqrestore(&local->cmdlock, flags);
460
461 if (err) {
462 printk(KERN_DEBUG "%s: hfa384x_cmd: interrupted; err=%d\n",
463 dev->name, err);
464 res = err;
465 goto done;
466 }
467
468 if (entry->type != CMD_COMPLETED) {
469 u16 reg = HFA384X_INW(HFA384X_EVSTAT_OFF);
470 printk(KERN_DEBUG "%s: hfa384x_cmd: command was not "
471 "completed (res=%d, entry=%p, type=%d, cmd=0x%04x, "
472 "param0=0x%04x, EVSTAT=%04x INTEN=%04x)\n", dev->name,
473 res, entry, entry->type, entry->cmd, entry->param0, reg,
474 HFA384X_INW(HFA384X_INTEN_OFF));
475 if (reg & HFA384X_EV_CMD) {
476 /* Command completion event is pending, but the
477 * interrupt was not delivered - probably an issue
478 * with pcmcia-cs configuration. */
479 printk(KERN_WARNING "%s: interrupt delivery does not "
480 "seem to work\n", dev->name);
481 }
482 prism2_io_debug_error(dev, 3);
483 res = -ETIMEDOUT;
484 goto done;
485 }
486
487 if (resp0 != NULL)
488 *resp0 = entry->resp0;
489#ifndef final_version
490 if (entry->res) {
491 printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x, "
492 "resp0=0x%04x\n",
493 dev->name, cmd, entry->res, entry->resp0);
494 }
495#endif /* final_version */
496
497 res = entry->res;
498 done:
499 hostap_cmd_queue_free(local, entry, 1);
500 return res;
501}
502
503
504/**
505 * hfa384x_cmd_callback - Issue a Prism2 command; callback when completed
506 * @dev: pointer to net_device
507 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
508 * @param0: value for Param0 register
509 * @callback: command completion callback function (%NULL = no callback)
510 * @context: data pointer to be given to callback function
511 *
512 * Issue given command (possibly after waiting in command queue) and use
513 * callback function to indicate command completion. This can be called both
514 * from user and interrupt context. The callback function will be called in
515 * hardware IRQ context. It can be %NULL, when no function is called when
516 * command is completed.
517 */
518static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
519 void (*callback)(struct net_device *dev,
520 void *context, u16 resp0,
521 u16 status),
522 void *context)
523{
524 struct hostap_interface *iface;
525 local_info_t *local;
526 int issue, ret;
527 unsigned long flags;
528 struct hostap_cmd_queue *entry;
529
530 iface = netdev_priv(dev);
531 local = iface->local;
532
533 if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN + 2) {
534 printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n",
535 dev->name);
536 return -1;
537 }
538
539 entry = (struct hostap_cmd_queue *)
540 kmalloc(sizeof(*entry), GFP_ATOMIC);
541 if (entry == NULL) {
542 printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
543 "failed\n", dev->name);
544 return -ENOMEM;
545 }
546 memset(entry, 0, sizeof(*entry));
547 atomic_set(&entry->usecnt, 1);
548 entry->type = CMD_CALLBACK;
549 entry->cmd = cmd;
550 entry->param0 = param0;
551 entry->callback = callback;
552 entry->context = context;
553
554 spin_lock_irqsave(&local->cmdlock, flags);
555 issue = list_empty(&local->cmd_queue);
556 if (issue)
557 entry->issuing = 1;
558 list_add_tail(&entry->list, &local->cmd_queue);
559 local->cmd_queue_len++;
560 spin_unlock_irqrestore(&local->cmdlock, flags);
561
562 if (issue && hfa384x_cmd_issue(dev, entry))
563 ret = -ETIMEDOUT;
564 else
565 ret = 0;
566
567 hostap_cmd_queue_free(local, entry, ret);
568
569 return ret;
570}
571
572
573/**
574 * __hfa384x_cmd_no_wait - Issue a Prism2 command (private)
575 * @dev: pointer to net_device
576 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
577 * @param0: value for Param0 register
578 * @io_debug_num: I/O debug error number
579 *
580 * Shared helper function for hfa384x_cmd_wait() and hfa384x_cmd_no_wait().
581 */
582static int __hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd, u16 param0,
583 int io_debug_num)
584{
585 int tries;
586 u16 reg;
587
588 /* wait until busy bit is clear; this should always be clear since the
589 * commands are serialized */
590 tries = HFA384X_CMD_BUSY_TIMEOUT;
591 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
592 tries--;
593 udelay(1);
594 }
595 if (tries == 0) {
596 reg = HFA384X_INW(HFA384X_CMD_OFF);
597 prism2_io_debug_error(dev, io_debug_num);
598 printk(KERN_DEBUG "%s: __hfa384x_cmd_no_wait(%d) - timeout - "
599 "reg=0x%04x\n", dev->name, io_debug_num, reg);
600 return -ETIMEDOUT;
601 }
602
603 /* write command */
604 HFA384X_OUTW(param0, HFA384X_PARAM0_OFF);
605 HFA384X_OUTW(cmd, HFA384X_CMD_OFF);
606
607 return 0;
608}
609
610
611/**
612 * hfa384x_cmd_wait - Issue a Prism2 command and busy wait for completion
613 * @dev: pointer to net_device
614 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
615 * @param0: value for Param0 register
616 */
617static int hfa384x_cmd_wait(struct net_device *dev, u16 cmd, u16 param0)
618{
619 int res, tries;
620 u16 reg;
621
622 res = __hfa384x_cmd_no_wait(dev, cmd, param0, 4);
623 if (res)
624 return res;
625
626 /* wait for command completion */
627 if ((cmd & HFA384X_CMDCODE_MASK) == HFA384X_CMDCODE_DOWNLOAD)
628 tries = HFA384X_DL_COMPL_TIMEOUT;
629 else
630 tries = HFA384X_CMD_COMPL_TIMEOUT;
631
632 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) &&
633 tries > 0) {
634 tries--;
635 udelay(10);
636 }
637 if (tries == 0) {
638 reg = HFA384X_INW(HFA384X_EVSTAT_OFF);
639 prism2_io_debug_error(dev, 5);
640 printk(KERN_DEBUG "%s: hfa384x_cmd_wait - timeout2 - "
641 "reg=0x%04x\n", dev->name, reg);
642 return -ETIMEDOUT;
643 }
644
645 res = (HFA384X_INW(HFA384X_STATUS_OFF) &
646 (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) |
647 BIT(8))) >> 8;
648#ifndef final_version
649 if (res) {
650 printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x\n",
651 dev->name, cmd, res);
652 }
653#endif
654
655 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
656
657 return res;
658}
659
660
661/**
662 * hfa384x_cmd_no_wait - Issue a Prism2 command; do not wait for completion
663 * @dev: pointer to net_device
664 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
665 * @param0: value for Param0 register
666 */
667static inline int hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd,
668 u16 param0)
669{
670 return __hfa384x_cmd_no_wait(dev, cmd, param0, 6);
671}
672
673
674/**
675 * prism2_cmd_ev - Prism2 command completion event handler
676 * @dev: pointer to net_device
677 *
678 * Interrupt handler for command completion events. Called by the main
679 * interrupt handler in hardware IRQ context. Read Resp0 and status registers
680 * from the hardware and ACK the event. Depending on the issued command type
681 * either wake up the sleeping process that is waiting for command completion
682 * or call the callback function. Issue the next command, if one is pending.
683 */
684static void prism2_cmd_ev(struct net_device *dev)
685{
686 struct hostap_interface *iface;
687 local_info_t *local;
688 struct hostap_cmd_queue *entry = NULL;
689
690 iface = netdev_priv(dev);
691 local = iface->local;
692
693 spin_lock(&local->cmdlock);
694 if (!list_empty(&local->cmd_queue)) {
695 entry = list_entry(local->cmd_queue.next,
696 struct hostap_cmd_queue, list);
697 atomic_inc(&entry->usecnt);
698 list_del_init(&entry->list);
699 local->cmd_queue_len--;
700
701 if (!entry->issued) {
702 printk(KERN_DEBUG "%s: Command completion event, but "
703 "cmd not issued\n", dev->name);
704 __hostap_cmd_queue_free(local, entry, 1);
705 entry = NULL;
706 }
707 }
708 spin_unlock(&local->cmdlock);
709
710 if (!entry) {
711 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
712 printk(KERN_DEBUG "%s: Command completion event, but no "
713 "pending commands\n", dev->name);
714 return;
715 }
716
717 entry->resp0 = HFA384X_INW(HFA384X_RESP0_OFF);
718 entry->res = (HFA384X_INW(HFA384X_STATUS_OFF) &
719 (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) |
720 BIT(9) | BIT(8))) >> 8;
721 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
722
723 /* TODO: rest of the CmdEv handling could be moved to tasklet */
724 if (entry->type == CMD_SLEEP) {
725 entry->type = CMD_COMPLETED;
726 wake_up_interruptible(&entry->compl);
727 } else if (entry->type == CMD_CALLBACK) {
728 if (entry->callback)
729 entry->callback(dev, entry->context, entry->resp0,
730 entry->res);
731 } else {
732 printk(KERN_DEBUG "%s: Invalid command completion type %d\n",
733 dev->name, entry->type);
734 }
735 hostap_cmd_queue_free(local, entry, 1);
736
737 /* issue next command, if pending */
738 entry = NULL;
739 spin_lock(&local->cmdlock);
740 if (!list_empty(&local->cmd_queue)) {
741 entry = list_entry(local->cmd_queue.next,
742 struct hostap_cmd_queue, list);
743 if (entry->issuing) {
744 /* hfa384x_cmd() has already started issuing this
745 * command, so do not start here */
746 entry = NULL;
747 }
748 if (entry)
749 atomic_inc(&entry->usecnt);
750 }
751 spin_unlock(&local->cmdlock);
752
753 if (entry) {
754 /* issue next command; if command issuing fails, remove the
755 * entry from cmd_queue */
756 int res = hfa384x_cmd_issue(dev, entry);
757 spin_lock(&local->cmdlock);
758 __hostap_cmd_queue_free(local, entry, res);
759 spin_unlock(&local->cmdlock);
760 }
761}
762
763
764static inline int hfa384x_wait_offset(struct net_device *dev, u16 o_off)
765{
766 int tries = HFA384X_BAP_BUSY_TIMEOUT;
767 int res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
768
769 while (res && tries > 0) {
770 tries--;
771 udelay(1);
772 res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
773 }
774 return res;
775}
776
777
778/* Offset must be even */
779static int hfa384x_setup_bap(struct net_device *dev, u16 bap, u16 id,
780 int offset)
781{
782 u16 o_off, s_off;
783 int ret = 0;
784
785 if (offset % 2 || bap > 1)
786 return -EINVAL;
787
788 if (bap == BAP1) {
789 o_off = HFA384X_OFFSET1_OFF;
790 s_off = HFA384X_SELECT1_OFF;
791 } else {
792 o_off = HFA384X_OFFSET0_OFF;
793 s_off = HFA384X_SELECT0_OFF;
794 }
795
796 if (hfa384x_wait_offset(dev, o_off)) {
797 prism2_io_debug_error(dev, 7);
798 printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout before\n",
799 dev->name);
800 ret = -ETIMEDOUT;
801 goto out;
802 }
803
804 HFA384X_OUTW(id, s_off);
805 HFA384X_OUTW(offset, o_off);
806
807 if (hfa384x_wait_offset(dev, o_off)) {
808 prism2_io_debug_error(dev, 8);
809 printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout after\n",
810 dev->name);
811 ret = -ETIMEDOUT;
812 goto out;
813 }
814#ifndef final_version
815 if (HFA384X_INW(o_off) & HFA384X_OFFSET_ERR) {
816 prism2_io_debug_error(dev, 9);
817 printk(KERN_DEBUG "%s: hfa384x_setup_bap - offset error "
818 "(%d,0x04%x,%d); reg=0x%04x\n",
819 dev->name, bap, id, offset, HFA384X_INW(o_off));
820 ret = -EINVAL;
821 }
822#endif
823
824 out:
825 return ret;
826}
827
828
829static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
830 int exact_len)
831{
832 struct hostap_interface *iface;
833 local_info_t *local;
834 int res, rlen = 0;
835 struct hfa384x_rid_hdr rec;
836
837 iface = netdev_priv(dev);
838 local = iface->local;
839
840 if (local->no_pri) {
841 printk(KERN_DEBUG "%s: cannot get RID %04x (len=%d) - no PRI "
842 "f/w\n", dev->name, rid, len);
843 return -ENOTTY; /* Well.. not really correct, but return
844 * something unique enough.. */
845 }
846
847 if ((local->func->card_present && !local->func->card_present(local)) ||
848 local->hw_downloading)
849 return -ENODEV;
850
851 res = down_interruptible(&local->rid_bap_sem);
852 if (res)
853 return res;
854
855 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS, rid, NULL, NULL);
856 if (res) {
857 printk(KERN_DEBUG "%s: hfa384x_get_rid: CMDCODE_ACCESS failed "
858 "(res=%d, rid=%04x, len=%d)\n",
859 dev->name, res, rid, len);
860 up(&local->rid_bap_sem);
861 return res;
862 }
863
864 spin_lock_bh(&local->baplock);
865
866 res = hfa384x_setup_bap(dev, BAP0, rid, 0);
867 if (!res)
868 res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
869
870 if (le16_to_cpu(rec.len) == 0) {
871 /* RID not available */
872 res = -ENODATA;
873 }
874
875 rlen = (le16_to_cpu(rec.len) - 1) * 2;
876 if (!res && exact_len && rlen != len) {
877 printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: "
878 "rid=0x%04x, len=%d (expected %d)\n",
879 dev->name, rid, rlen, len);
880 res = -ENODATA;
881 }
882
883 if (!res)
884 res = hfa384x_from_bap(dev, BAP0, buf, len);
885
886 spin_unlock_bh(&local->baplock);
887 up(&local->rid_bap_sem);
888
889 if (res) {
890 if (res != -ENODATA)
891 printk(KERN_DEBUG "%s: hfa384x_get_rid (rid=%04x, "
892 "len=%d) - failed - res=%d\n", dev->name, rid,
893 len, res);
894 if (res == -ETIMEDOUT)
895 prism2_hw_reset(dev);
896 return res;
897 }
898
899 return rlen;
900}
901
902
903static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len)
904{
905 struct hostap_interface *iface;
906 local_info_t *local;
907 struct hfa384x_rid_hdr rec;
908 int res;
909
910 iface = netdev_priv(dev);
911 local = iface->local;
912
913 if (local->no_pri) {
914 printk(KERN_DEBUG "%s: cannot set RID %04x (len=%d) - no PRI "
915 "f/w\n", dev->name, rid, len);
916 return -ENOTTY; /* Well.. not really correct, but return
917 * something unique enough.. */
918 }
919
920 if ((local->func->card_present && !local->func->card_present(local)) ||
921 local->hw_downloading)
922 return -ENODEV;
923
924 rec.rid = cpu_to_le16(rid);
925 /* RID len in words and +1 for rec.rid */
926 rec.len = cpu_to_le16(len / 2 + len % 2 + 1);
927
928 res = down_interruptible(&local->rid_bap_sem);
929 if (res)
930 return res;
931
932 spin_lock_bh(&local->baplock);
933 res = hfa384x_setup_bap(dev, BAP0, rid, 0);
934 if (!res)
935 res = hfa384x_to_bap(dev, BAP0, &rec, sizeof(rec));
936 if (!res)
937 res = hfa384x_to_bap(dev, BAP0, buf, len);
938 spin_unlock_bh(&local->baplock);
939
940 if (res) {
941 printk(KERN_DEBUG "%s: hfa384x_set_rid (rid=%04x, len=%d) - "
942 "failed - res=%d\n", dev->name, rid, len, res);
943 up(&local->rid_bap_sem);
944 return res;
945 }
946
947 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL);
948 up(&local->rid_bap_sem);
949 if (res) {
950 printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE "
951 "failed (res=%d, rid=%04x, len=%d)\n",
952 dev->name, res, rid, len);
953 return res;
954 }
955
956 if (res == -ETIMEDOUT)
957 prism2_hw_reset(dev);
958
959 return res;
960}
961
962
963static void hfa384x_disable_interrupts(struct net_device *dev)
964{
965 /* disable interrupts and clear event status */
966 HFA384X_OUTW(0, HFA384X_INTEN_OFF);
967 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
968}
969
970
971static void hfa384x_enable_interrupts(struct net_device *dev)
972{
973 /* ack pending events and enable interrupts from selected events */
974 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
975 HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);
976}
977
978
979static void hfa384x_events_no_bap0(struct net_device *dev)
980{
981 HFA384X_OUTW(HFA384X_EVENT_MASK & ~HFA384X_BAP0_EVENTS,
982 HFA384X_INTEN_OFF);
983}
984
985
986static void hfa384x_events_all(struct net_device *dev)
987{
988 HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);
989}
990
991
992static void hfa384x_events_only_cmd(struct net_device *dev)
993{
994 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_INTEN_OFF);
995}
996
997
998static u16 hfa384x_allocate_fid(struct net_device *dev, int len)
999{
1000 u16 fid;
1001 unsigned long delay;
1002
1003 /* FIX: this could be replace with hfa384x_cmd() if the Alloc event
1004 * below would be handled like CmdCompl event (sleep here, wake up from
1005 * interrupt handler */
1006 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_ALLOC, len)) {
1007 printk(KERN_DEBUG "%s: cannot allocate fid, len=%d\n",
1008 dev->name, len);
1009 return 0xffff;
1010 }
1011
1012 delay = jiffies + HFA384X_ALLOC_COMPL_TIMEOUT;
1013 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC) &&
1014 time_before(jiffies, delay))
1015 yield();
1016 if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC)) {
1017 printk("%s: fid allocate, len=%d - timeout\n", dev->name, len);
1018 return 0xffff;
1019 }
1020
1021 fid = HFA384X_INW(HFA384X_ALLOCFID_OFF);
1022 HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
1023
1024 return fid;
1025}
1026
1027
1028static int prism2_reset_port(struct net_device *dev)
1029{
1030 struct hostap_interface *iface;
1031 local_info_t *local;
1032 int res;
1033
1034 iface = netdev_priv(dev);
1035 local = iface->local;
1036
1037 if (!local->dev_enabled)
1038 return 0;
1039
1040 res = hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0,
1041 NULL, NULL);
1042 if (res)
1043 printk(KERN_DEBUG "%s: reset port failed to disable port\n",
1044 dev->name);
1045 else {
1046 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0,
1047 NULL, NULL);
1048 if (res)
1049 printk(KERN_DEBUG "%s: reset port failed to enable "
1050 "port\n", dev->name);
1051 }
1052
1053 /* It looks like at least some STA firmware versions reset
1054 * fragmentation threshold back to 2346 after enable command. Restore
1055 * the configured value, if it differs from this default. */
1056 if (local->fragm_threshold != 2346 &&
1057 hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
1058 local->fragm_threshold)) {
1059 printk(KERN_DEBUG "%s: failed to restore fragmentation "
1060 "threshold (%d) after Port0 enable\n",
1061 dev->name, local->fragm_threshold);
1062 }
1063
1064 return res;
1065}
1066
1067
1068static int prism2_get_version_info(struct net_device *dev, u16 rid,
1069 const char *txt)
1070{
1071 struct hfa384x_comp_ident comp;
1072 struct hostap_interface *iface;
1073 local_info_t *local;
1074
1075 iface = netdev_priv(dev);
1076 local = iface->local;
1077
1078 if (local->no_pri) {
1079 /* PRI f/w not yet available - cannot read RIDs */
1080 return -1;
1081 }
1082 if (hfa384x_get_rid(dev, rid, &comp, sizeof(comp), 1) < 0) {
1083 printk(KERN_DEBUG "Could not get RID for component %s\n", txt);
1084 return -1;
1085 }
1086
1087 printk(KERN_INFO "%s: %s: id=0x%02x v%d.%d.%d\n", dev->name, txt,
1088 __le16_to_cpu(comp.id), __le16_to_cpu(comp.major),
1089 __le16_to_cpu(comp.minor), __le16_to_cpu(comp.variant));
1090 return 0;
1091}
1092
1093
1094static int prism2_setup_rids(struct net_device *dev)
1095{
1096 struct hostap_interface *iface;
1097 local_info_t *local;
1098 u16 tmp;
1099 int ret = 0;
1100
1101 iface = netdev_priv(dev);
1102 local = iface->local;
1103
1104 hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000);
1105
1106 if (!local->fw_ap) {
1107 tmp = hostap_get_porttype(local);
1108 ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp);
1109 if (ret) {
1110 printk("%s: Port type setting to %d failed\n",
1111 dev->name, tmp);
1112 goto fail;
1113 }
1114 }
1115
1116 /* Setting SSID to empty string seems to kill the card in Host AP mode
1117 */
1118 if (local->iw_mode != IW_MODE_MASTER || local->essid[0] != '\0') {
1119 ret = hostap_set_string(dev, HFA384X_RID_CNFOWNSSID,
1120 local->essid);
1121 if (ret) {
1122 printk("%s: AP own SSID setting failed\n", dev->name);
1123 goto fail;
1124 }
1125 }
1126
1127 ret = hostap_set_word(dev, HFA384X_RID_CNFMAXDATALEN,
1128 PRISM2_DATA_MAXLEN);
1129 if (ret) {
1130 printk("%s: MAC data length setting to %d failed\n",
1131 dev->name, PRISM2_DATA_MAXLEN);
1132 goto fail;
1133 }
1134
1135 if (hfa384x_get_rid(dev, HFA384X_RID_CHANNELLIST, &tmp, 2, 1) < 0) {
1136 printk("%s: Channel list read failed\n", dev->name);
1137 ret = -EINVAL;
1138 goto fail;
1139 }
1140 local->channel_mask = __le16_to_cpu(tmp);
1141
1142 if (local->channel < 1 || local->channel > 14 ||
1143 !(local->channel_mask & (1 << (local->channel - 1)))) {
1144 printk(KERN_WARNING "%s: Channel setting out of range "
1145 "(%d)!\n", dev->name, local->channel);
1146 ret = -EBUSY;
1147 goto fail;
1148 }
1149
1150 ret = hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel);
1151 if (ret) {
1152 printk("%s: Channel setting to %d failed\n",
1153 dev->name, local->channel);
1154 goto fail;
1155 }
1156
1157 ret = hostap_set_word(dev, HFA384X_RID_CNFBEACONINT,
1158 local->beacon_int);
1159 if (ret) {
1160 printk("%s: Beacon interval setting to %d failed\n",
1161 dev->name, local->beacon_int);
1162 /* this may fail with Symbol/Lucent firmware */
1163 if (ret == -ETIMEDOUT)
1164 goto fail;
1165 }
1166
1167 ret = hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD,
1168 local->dtim_period);
1169 if (ret) {
1170 printk("%s: DTIM period setting to %d failed\n",
1171 dev->name, local->dtim_period);
1172 /* this may fail with Symbol/Lucent firmware */
1173 if (ret == -ETIMEDOUT)
1174 goto fail;
1175 }
1176
1177 ret = hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
1178 local->is_promisc);
1179 if (ret)
1180 printk(KERN_INFO "%s: Setting promiscuous mode (%d) failed\n",
1181 dev->name, local->is_promisc);
1182
1183 if (!local->fw_ap) {
1184 ret = hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID,
1185 local->essid);
1186 if (ret) {
1187 printk("%s: Desired SSID setting failed\n", dev->name);
1188 goto fail;
1189 }
1190 }
1191
1192 /* Setup TXRateControl, defaults to allow use of 1, 2, 5.5, and
1193 * 11 Mbps in automatic TX rate fallback and 1 and 2 Mbps as basic
1194 * rates */
1195 if (local->tx_rate_control == 0) {
1196 local->tx_rate_control =
1197 HFA384X_RATES_1MBPS |
1198 HFA384X_RATES_2MBPS |
1199 HFA384X_RATES_5MBPS |
1200 HFA384X_RATES_11MBPS;
1201 }
1202 if (local->basic_rates == 0)
1203 local->basic_rates = HFA384X_RATES_1MBPS | HFA384X_RATES_2MBPS;
1204
1205 if (!local->fw_ap) {
1206 ret = hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
1207 local->tx_rate_control);
1208 if (ret) {
1209 printk("%s: TXRateControl setting to %d failed\n",
1210 dev->name, local->tx_rate_control);
1211 goto fail;
1212 }
1213
1214 ret = hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
1215 local->tx_rate_control);
1216 if (ret) {
1217 printk("%s: cnfSupportedRates setting to %d failed\n",
1218 dev->name, local->tx_rate_control);
1219 }
1220
1221 ret = hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
1222 local->basic_rates);
1223 if (ret) {
1224 printk("%s: cnfBasicRates setting to %d failed\n",
1225 dev->name, local->basic_rates);
1226 }
1227
1228 ret = hostap_set_word(dev, HFA384X_RID_CREATEIBSS, 1);
1229 if (ret) {
1230 printk("%s: Create IBSS setting to 1 failed\n",
1231 dev->name);
1232 }
1233 }
1234
1235 if (local->name_set)
1236 (void) hostap_set_string(dev, HFA384X_RID_CNFOWNNAME,
1237 local->name);
1238
1239 if (hostap_set_encryption(local)) {
1240 printk(KERN_INFO "%s: could not configure encryption\n",
1241 dev->name);
1242 }
1243
1244 (void) hostap_set_antsel(local);
1245
1246 if (hostap_set_roaming(local)) {
1247 printk(KERN_INFO "%s: could not set host roaming\n",
1248 dev->name);
1249 }
1250
1251 if (local->sta_fw_ver >= PRISM2_FW_VER(1,6,3) &&
1252 hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY, local->enh_sec))
1253 printk(KERN_INFO "%s: cnfEnhSecurity setting to 0x%x failed\n",
1254 dev->name, local->enh_sec);
1255
1256 /* 32-bit tallies were added in STA f/w 0.8.0, but they were apparently
1257 * not working correctly (last seven counters report bogus values).
1258 * This has been fixed in 0.8.2, so enable 32-bit tallies only
1259 * beginning with that firmware version. Another bug fix for 32-bit
1260 * tallies in 1.4.0; should 16-bit tallies be used for some other
1261 * versions, too? */
1262 if (local->sta_fw_ver >= PRISM2_FW_VER(0,8,2)) {
1263 if (hostap_set_word(dev, HFA384X_RID_CNFTHIRTY2TALLY, 1)) {
1264 printk(KERN_INFO "%s: cnfThirty2Tally setting "
1265 "failed\n", dev->name);
1266 local->tallies32 = 0;
1267 } else
1268 local->tallies32 = 1;
1269 } else
1270 local->tallies32 = 0;
1271
1272 hostap_set_auth_algs(local);
1273
1274 if (hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
1275 local->fragm_threshold)) {
1276 printk(KERN_INFO "%s: setting FragmentationThreshold to %d "
1277 "failed\n", dev->name, local->fragm_threshold);
1278 }
1279
1280 if (hostap_set_word(dev, HFA384X_RID_RTSTHRESHOLD,
1281 local->rts_threshold)) {
1282 printk(KERN_INFO "%s: setting RTSThreshold to %d failed\n",
1283 dev->name, local->rts_threshold);
1284 }
1285
1286 if (local->manual_retry_count >= 0 &&
1287 hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1288 local->manual_retry_count)) {
1289 printk(KERN_INFO "%s: setting cnfAltRetryCount to %d failed\n",
1290 dev->name, local->manual_retry_count);
1291 }
1292
1293 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1) &&
1294 hfa384x_get_rid(dev, HFA384X_RID_CNFDBMADJUST, &tmp, 2, 1) == 2) {
1295 local->rssi_to_dBm = le16_to_cpu(tmp);
1296 }
1297
1298 if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->wpa &&
1299 hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1)) {
1300 printk(KERN_INFO "%s: setting ssnHandlingMode to 1 failed\n",
1301 dev->name);
1302 }
1303
1304 if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->generic_elem &&
1305 hfa384x_set_rid(dev, HFA384X_RID_GENERICELEMENT,
1306 local->generic_elem, local->generic_elem_len)) {
1307 printk(KERN_INFO "%s: setting genericElement failed\n",
1308 dev->name);
1309 }
1310
1311 fail:
1312 return ret;
1313}
1314
1315
1316static int prism2_hw_init(struct net_device *dev, int initial)
1317{
1318 struct hostap_interface *iface;
1319 local_info_t *local;
1320 int ret, first = 1;
1321 unsigned long start, delay;
1322
1323 PDEBUG(DEBUG_FLOW, "prism2_hw_init()\n");
1324
1325 iface = netdev_priv(dev);
1326 local = iface->local;
1327
1328 clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits);
1329
1330 init:
1331 /* initialize HFA 384x */
1332 ret = hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_INIT, 0);
1333 if (ret) {
1334 printk(KERN_INFO "%s: first command failed - assuming card "
1335 "does not have primary firmware\n", dev_info);
1336 }
1337
1338 if (first && (HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) {
1339 /* EvStat has Cmd bit set in some cases, so retry once if no
1340 * wait was needed */
1341 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
1342 printk(KERN_DEBUG "%s: init command completed too quickly - "
1343 "retrying\n", dev->name);
1344 first = 0;
1345 goto init;
1346 }
1347
1348 start = jiffies;
1349 delay = jiffies + HFA384X_INIT_TIMEOUT;
1350 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) &&
1351 time_before(jiffies, delay))
1352 yield();
1353 if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) {
1354 printk(KERN_DEBUG "%s: assuming no Primary image in "
1355 "flash - card initialization not completed\n",
1356 dev_info);
1357 local->no_pri = 1;
1358#ifdef PRISM2_DOWNLOAD_SUPPORT
1359 if (local->sram_type == -1)
1360 local->sram_type = prism2_get_ram_size(local);
1361#endif /* PRISM2_DOWNLOAD_SUPPORT */
1362 return 1;
1363 }
1364 local->no_pri = 0;
1365 printk(KERN_DEBUG "prism2_hw_init: initialized in %lu ms\n",
1366 (jiffies - start) * 1000 / HZ);
1367 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
1368 return 0;
1369}
1370
1371
1372static int prism2_hw_init2(struct net_device *dev, int initial)
1373{
1374 struct hostap_interface *iface;
1375 local_info_t *local;
1376 int i;
1377
1378 iface = netdev_priv(dev);
1379 local = iface->local;
1380
1381#ifdef PRISM2_DOWNLOAD_SUPPORT
1382 kfree(local->pda);
1383 if (local->no_pri)
1384 local->pda = NULL;
1385 else
1386 local->pda = prism2_read_pda(dev);
1387#endif /* PRISM2_DOWNLOAD_SUPPORT */
1388
1389 hfa384x_disable_interrupts(dev);
1390
1391#ifndef final_version
1392 HFA384X_OUTW(HFA384X_MAGIC, HFA384X_SWSUPPORT0_OFF);
1393 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
1394 printk("SWSUPPORT0 write/read failed: %04X != %04X\n",
1395 HFA384X_INW(HFA384X_SWSUPPORT0_OFF), HFA384X_MAGIC);
1396 goto failed;
1397 }
1398#endif
1399
1400 if (initial || local->pri_only) {
1401 hfa384x_events_only_cmd(dev);
1402 /* get card version information */
1403 if (prism2_get_version_info(dev, HFA384X_RID_NICID, "NIC") ||
1404 prism2_get_version_info(dev, HFA384X_RID_PRIID, "PRI")) {
1405 hfa384x_disable_interrupts(dev);
1406 goto failed;
1407 }
1408
1409 if (prism2_get_version_info(dev, HFA384X_RID_STAID, "STA")) {
1410 printk(KERN_DEBUG "%s: Failed to read STA f/w version "
1411 "- only Primary f/w present\n", dev->name);
1412 local->pri_only = 1;
1413 return 0;
1414 }
1415 local->pri_only = 0;
1416 hfa384x_disable_interrupts(dev);
1417 }
1418
1419 /* FIX: could convert allocate_fid to use sleeping CmdCompl wait and
1420 * enable interrupts before this. This would also require some sort of
1421 * sleeping AllocEv waiting */
1422
1423 /* allocate TX FIDs */
1424 local->txfid_len = PRISM2_TXFID_LEN;
1425 for (i = 0; i < PRISM2_TXFID_COUNT; i++) {
1426 local->txfid[i] = hfa384x_allocate_fid(dev, local->txfid_len);
1427 if (local->txfid[i] == 0xffff && local->txfid_len > 1600) {
1428 local->txfid[i] = hfa384x_allocate_fid(dev, 1600);
1429 if (local->txfid[i] != 0xffff) {
1430 printk(KERN_DEBUG "%s: Using shorter TX FID "
1431 "(1600 bytes)\n", dev->name);
1432 local->txfid_len = 1600;
1433 }
1434 }
1435 if (local->txfid[i] == 0xffff)
1436 goto failed;
1437 local->intransmitfid[i] = PRISM2_TXFID_EMPTY;
1438 }
1439
1440 hfa384x_events_only_cmd(dev);
1441
1442 if (initial) {
1443 struct list_head *ptr;
1444 prism2_check_sta_fw_version(local);
1445
1446 if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR,
1447 &dev->dev_addr, 6, 1) < 0) {
1448 printk("%s: could not get own MAC address\n",
1449 dev->name);
1450 }
1451 list_for_each(ptr, &local->hostap_interfaces) {
1452 iface = list_entry(ptr, struct hostap_interface, list);
1453 memcpy(iface->dev->dev_addr, dev->dev_addr, ETH_ALEN);
1454 }
1455 } else if (local->fw_ap)
1456 prism2_check_sta_fw_version(local);
1457
1458 prism2_setup_rids(dev);
1459
1460 /* MAC is now configured, but port 0 is not yet enabled */
1461 return 0;
1462
1463 failed:
1464 if (!local->no_pri)
1465 printk(KERN_WARNING "%s: Initialization failed\n", dev_info);
1466 return 1;
1467}
1468
1469
1470static int prism2_hw_enable(struct net_device *dev, int initial)
1471{
1472 struct hostap_interface *iface;
1473 local_info_t *local;
1474 int was_resetting;
1475
1476 iface = netdev_priv(dev);
1477 local = iface->local;
1478 was_resetting = local->hw_resetting;
1479
1480 if (hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL, NULL)) {
1481 printk("%s: MAC port 0 enabling failed\n", dev->name);
1482 return 1;
1483 }
1484
1485 local->hw_ready = 1;
1486 local->hw_reset_tries = 0;
1487 local->hw_resetting = 0;
1488 hfa384x_enable_interrupts(dev);
1489
1490 /* at least D-Link DWL-650 seems to require additional port reset
1491 * before it starts acting as an AP, so reset port automatically
1492 * here just in case */
1493 if (initial && prism2_reset_port(dev)) {
1494 printk("%s: MAC port 0 reseting failed\n", dev->name);
1495 return 1;
1496 }
1497
1498 if (was_resetting && netif_queue_stopped(dev)) {
1499 /* If hw_reset() was called during pending transmit, netif
1500 * queue was stopped. Wake it up now since the wlan card has
1501 * been resetted. */
1502 netif_wake_queue(dev);
1503 }
1504
1505 return 0;
1506}
1507
1508
1509static int prism2_hw_config(struct net_device *dev, int initial)
1510{
1511 struct hostap_interface *iface;
1512 local_info_t *local;
1513
1514 iface = netdev_priv(dev);
1515 local = iface->local;
1516
1517 if (local->hw_downloading)
1518 return 1;
1519
1520 if (prism2_hw_init(dev, initial)) {
1521 return local->no_pri ? 0 : 1;
1522 }
1523
1524 if (prism2_hw_init2(dev, initial))
1525 return 1;
1526
1527 /* Enable firmware if secondary image is loaded and at least one of the
1528 * netdevices is up. */
1529 if (!local->pri_only &&
1530 (initial == 0 || (initial == 2 && local->num_dev_open > 0))) {
1531 if (!local->dev_enabled)
1532 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
1533 local->dev_enabled = 1;
1534 return prism2_hw_enable(dev, initial);
1535 }
1536
1537 return 0;
1538}
1539
1540
1541static void prism2_hw_shutdown(struct net_device *dev, int no_disable)
1542{
1543 struct hostap_interface *iface;
1544 local_info_t *local;
1545
1546 iface = netdev_priv(dev);
1547 local = iface->local;
1548
1549 /* Allow only command completion events during disable */
1550 hfa384x_events_only_cmd(dev);
1551
1552 local->hw_ready = 0;
1553 if (local->dev_enabled)
1554 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
1555 local->dev_enabled = 0;
1556
1557 if (local->func->card_present && !local->func->card_present(local)) {
1558 printk(KERN_DEBUG "%s: card already removed or not configured "
1559 "during shutdown\n", dev->name);
1560 return;
1561 }
1562
1563 if ((no_disable & HOSTAP_HW_NO_DISABLE) == 0 &&
1564 hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL, NULL))
1565 printk(KERN_WARNING "%s: Shutdown failed\n", dev_info);
1566
1567 hfa384x_disable_interrupts(dev);
1568
1569 if (no_disable & HOSTAP_HW_ENABLE_CMDCOMPL)
1570 hfa384x_events_only_cmd(dev);
1571 else
1572 prism2_clear_cmd_queue(local);
1573}
1574
1575
1576static void prism2_hw_reset(struct net_device *dev)
1577{
1578 struct hostap_interface *iface;
1579 local_info_t *local;
1580
1581#if 0
1582 static long last_reset = 0;
1583
1584 /* do not reset card more than once per second to avoid ending up in a
1585 * busy loop reseting the card */
1586 if (time_before_eq(jiffies, last_reset + HZ))
1587 return;
1588 last_reset = jiffies;
1589#endif
1590
1591 iface = netdev_priv(dev);
1592 local = iface->local;
1593
1594 if (in_interrupt()) {
1595 printk(KERN_DEBUG "%s: driver bug - prism2_hw_reset() called "
1596 "in interrupt context\n", dev->name);
1597 return;
1598 }
1599
1600 if (local->hw_downloading)
1601 return;
1602
1603 if (local->hw_resetting) {
1604 printk(KERN_WARNING "%s: %s: already resetting card - "
1605 "ignoring reset request\n", dev_info, dev->name);
1606 return;
1607 }
1608
1609 local->hw_reset_tries++;
1610 if (local->hw_reset_tries > 10) {
1611 printk(KERN_WARNING "%s: too many reset tries, skipping\n",
1612 dev->name);
1613 return;
1614 }
1615
1616 printk(KERN_WARNING "%s: %s: resetting card\n", dev_info, dev->name);
1617 hfa384x_disable_interrupts(dev);
1618 local->hw_resetting = 1;
1619 if (local->func->cor_sreset) {
1620 /* Host system seems to hang in some cases with high traffic
1621 * load or shared interrupts during COR sreset. Disable shared
1622 * interrupts during reset to avoid these crashes. COS sreset
1623 * takes quite a long time, so it is unfortunate that this
1624 * seems to be needed. Anyway, I do not know of any better way
1625 * of avoiding the crash. */
1626 disable_irq(dev->irq);
1627 local->func->cor_sreset(local);
1628 enable_irq(dev->irq);
1629 }
1630 prism2_hw_shutdown(dev, 1);
1631 prism2_hw_config(dev, 0);
1632 local->hw_resetting = 0;
1633
1634#ifdef PRISM2_DOWNLOAD_SUPPORT
1635 if (local->dl_pri) {
1636 printk(KERN_DEBUG "%s: persistent download of primary "
1637 "firmware\n", dev->name);
1638 if (prism2_download_genesis(local, local->dl_pri) < 0)
1639 printk(KERN_WARNING "%s: download (PRI) failed\n",
1640 dev->name);
1641 }
1642
1643 if (local->dl_sec) {
1644 printk(KERN_DEBUG "%s: persistent download of secondary "
1645 "firmware\n", dev->name);
1646 if (prism2_download_volatile(local, local->dl_sec) < 0)
1647 printk(KERN_WARNING "%s: download (SEC) failed\n",
1648 dev->name);
1649 }
1650#endif /* PRISM2_DOWNLOAD_SUPPORT */
1651
1652 /* TODO: restore beacon TIM bits for STAs that have buffered frames */
1653}
1654
1655
1656static void prism2_schedule_reset(local_info_t *local)
1657{
1658 schedule_work(&local->reset_queue);
1659}
1660
1661
1662/* Called only as scheduled task after noticing card timeout in interrupt
1663 * context */
1664static void handle_reset_queue(void *data)
1665{
1666 local_info_t *local = (local_info_t *) data;
1667
1668 printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name);
1669 prism2_hw_reset(local->dev);
1670
1671 if (netif_queue_stopped(local->dev)) {
1672 int i;
1673
1674 for (i = 0; i < PRISM2_TXFID_COUNT; i++)
1675 if (local->intransmitfid[i] == PRISM2_TXFID_EMPTY) {
1676 PDEBUG(DEBUG_EXTRA, "prism2_tx_timeout: "
1677 "wake up queue\n");
1678 netif_wake_queue(local->dev);
1679 break;
1680 }
1681 }
1682}
1683
1684
1685static int prism2_get_txfid_idx(local_info_t *local)
1686{
1687 int idx, end;
1688 unsigned long flags;
1689
1690 spin_lock_irqsave(&local->txfidlock, flags);
1691 end = idx = local->next_txfid;
1692 do {
1693 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) {
1694 local->intransmitfid[idx] = PRISM2_TXFID_RESERVED;
1695 spin_unlock_irqrestore(&local->txfidlock, flags);
1696 return idx;
1697 }
1698 idx++;
1699 if (idx >= PRISM2_TXFID_COUNT)
1700 idx = 0;
1701 } while (idx != end);
1702 spin_unlock_irqrestore(&local->txfidlock, flags);
1703
1704 PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: "
1705 "packet dropped\n");
1706 local->stats.tx_dropped++;
1707
1708 return -1;
1709}
1710
1711
1712/* Called only from hardware IRQ */
1713static void prism2_transmit_cb(struct net_device *dev, void *context,
1714 u16 resp0, u16 res)
1715{
1716 struct hostap_interface *iface;
1717 local_info_t *local;
1718 int idx = (int) context;
1719
1720 iface = netdev_priv(dev);
1721 local = iface->local;
1722
1723 if (res) {
1724 printk(KERN_DEBUG "%s: prism2_transmit_cb - res=0x%02x\n",
1725 dev->name, res);
1726 return;
1727 }
1728
1729 if (idx < 0 || idx >= PRISM2_TXFID_COUNT) {
1730 printk(KERN_DEBUG "%s: prism2_transmit_cb called with invalid "
1731 "idx=%d\n", dev->name, idx);
1732 return;
1733 }
1734
1735 if (!test_and_clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
1736 printk(KERN_DEBUG "%s: driver bug: prism2_transmit_cb called "
1737 "with no pending transmit\n", dev->name);
1738 }
1739
1740 if (netif_queue_stopped(dev)) {
1741 /* ready for next TX, so wake up queue that was stopped in
1742 * prism2_transmit() */
1743 netif_wake_queue(dev);
1744 }
1745
1746 spin_lock(&local->txfidlock);
1747
1748 /* With reclaim, Resp0 contains new txfid for transmit; the old txfid
1749 * will be automatically allocated for the next TX frame */
1750 local->intransmitfid[idx] = resp0;
1751
1752 PDEBUG(DEBUG_FID, "%s: prism2_transmit_cb: txfid[%d]=0x%04x, "
1753 "resp0=0x%04x, transmit_txfid=0x%04x\n",
1754 dev->name, idx, local->txfid[idx],
1755 resp0, local->intransmitfid[local->next_txfid]);
1756
1757 idx++;
1758 if (idx >= PRISM2_TXFID_COUNT)
1759 idx = 0;
1760 local->next_txfid = idx;
1761
1762 /* check if all TX buffers are occupied */
1763 do {
1764 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) {
1765 spin_unlock(&local->txfidlock);
1766 return;
1767 }
1768 idx++;
1769 if (idx >= PRISM2_TXFID_COUNT)
1770 idx = 0;
1771 } while (idx != local->next_txfid);
1772 spin_unlock(&local->txfidlock);
1773
1774 /* no empty TX buffers, stop queue */
1775 netif_stop_queue(dev);
1776}
1777
1778
1779/* Called only from software IRQ if PCI bus master is not used (with bus master
1780 * this can be called both from software and hardware IRQ) */
1781static int prism2_transmit(struct net_device *dev, int idx)
1782{
1783 struct hostap_interface *iface;
1784 local_info_t *local;
1785 int res;
1786
1787 iface = netdev_priv(dev);
1788 local = iface->local;
1789
1790 /* The driver tries to stop netif queue so that there would not be
1791 * more than one attempt to transmit frames going on; check that this
1792 * is really the case */
1793
1794 if (test_and_set_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
1795 printk(KERN_DEBUG "%s: driver bug - prism2_transmit() called "
1796 "when previous TX was pending\n", dev->name);
1797 return -1;
1798 }
1799
1800 /* stop the queue for the time that transmit is pending */
1801 netif_stop_queue(dev);
1802
1803 /* transmit packet */
1804 res = hfa384x_cmd_callback(
1805 dev,
1806 HFA384X_CMDCODE_TRANSMIT | HFA384X_CMD_TX_RECLAIM,
1807 local->txfid[idx],
1808 prism2_transmit_cb, (void *) idx);
1809
1810 if (res) {
1811 struct net_device_stats *stats;
1812 printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT "
1813 "failed (res=%d)\n", dev->name, res);
1814 stats = hostap_get_stats(dev);
1815 stats->tx_dropped++;
1816 netif_wake_queue(dev);
1817 return -1;
1818 }
1819 dev->trans_start = jiffies;
1820
1821 /* Since we did not wait for command completion, the card continues
1822 * to process on the background and we will finish handling when
1823 * command completion event is handled (prism2_cmd_ev() function) */
1824
1825 return 0;
1826}
1827
1828
1829#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
1830/* Called only from hardware IRQ */
1831static void prism2_tx_cb(struct net_device *dev, void *context,
1832 u16 resp0, u16 res)
1833{
1834 struct hostap_interface *iface;
1835 local_info_t *local;
1836 unsigned long addr;
1837 int buf_len = (int) context;
1838
1839 iface = netdev_priv(dev);
1840 local = iface->local;
1841
1842 if (res) {
1843 printk(KERN_DEBUG "%s: prism2_tx_cb - res=0x%02x\n",
1844 dev->name, res);
1845 return;
1846 }
1847
1848 addr = virt_to_phys(local->bus_m0_buf);
1849 HFA384X_OUTW((addr & 0xffff0000) >> 16, HFA384X_PCI_M0_ADDRH_OFF);
1850 HFA384X_OUTW(addr & 0x0000ffff, HFA384X_PCI_M0_ADDRL_OFF);
1851 HFA384X_OUTW(buf_len / 2, HFA384X_PCI_M0_LEN_OFF);
1852 HFA384X_OUTW(HFA384X_PCI_CTL_TO_BAP, HFA384X_PCI_M0_CTL_OFF);
1853}
1854#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
1855
1856
1857/* Send IEEE 802.11 frame (convert the header into Prism2 TX descriptor and
1858 * send the payload with this descriptor) */
1859/* Called only from software IRQ */
1860static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
1861{
1862 struct hostap_interface *iface;
1863 local_info_t *local;
1864 struct hfa384x_tx_frame txdesc;
1865 struct hostap_ieee80211_hdr *hdr;
1866 struct hostap_skb_tx_data *meta;
1867 int hdr_len, data_len, idx, res, ret = -1;
1868 u16 tx_control, fc;
1869
1870 iface = netdev_priv(dev);
1871 local = iface->local;
1872
1873 meta = (struct hostap_skb_tx_data *) skb->cb;
1874 hdr = (struct hostap_ieee80211_hdr *) skb->data;
1875
1876 prism2_callback(local, PRISM2_CALLBACK_TX_START);
1877
1878 if ((local->func->card_present && !local->func->card_present(local)) ||
1879 !local->hw_ready || local->hw_downloading || local->pri_only) {
1880 if (net_ratelimit()) {
1881 printk(KERN_DEBUG "%s: prism2_tx_80211: hw not ready -"
1882 " skipping\n", dev->name);
1883 }
1884 goto fail;
1885 }
1886
1887 memset(&txdesc, 0, sizeof(txdesc));
1888
1889 /* skb->data starts with txdesc->frame_control */
1890 hdr_len = 24;
1891 memcpy(&txdesc.frame_control, skb->data, hdr_len);
1892 fc = le16_to_cpu(txdesc.frame_control);
1893 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
1894 (fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS) && skb->len >= 30) {
1895 /* Addr4 */
1896 memcpy(txdesc.addr4, skb->data + hdr_len, ETH_ALEN);
1897 hdr_len += ETH_ALEN;
1898 }
1899
1900 tx_control = local->tx_control;
1901 if (meta->tx_cb_idx) {
1902 tx_control |= HFA384X_TX_CTRL_TX_OK;
1903 txdesc.sw_support = cpu_to_le16(meta->tx_cb_idx);
1904 }
1905 txdesc.tx_control = cpu_to_le16(tx_control);
1906 txdesc.tx_rate = meta->rate;
1907
1908 data_len = skb->len - hdr_len;
1909 txdesc.data_len = cpu_to_le16(data_len);
1910 txdesc.len = cpu_to_be16(data_len);
1911
1912 idx = prism2_get_txfid_idx(local);
1913 if (idx < 0)
1914 goto fail;
1915
1916 if (local->frame_dump & PRISM2_DUMP_TX_HDR)
1917 hostap_dump_tx_header(dev->name, &txdesc);
1918
1919 spin_lock(&local->baplock);
1920 res = hfa384x_setup_bap(dev, BAP0, local->txfid[idx], 0);
1921
1922#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
1923 if (!res && skb->len >= local->bus_master_threshold_tx) {
1924 u8 *pos;
1925 int buf_len;
1926
1927 local->bus_m0_tx_idx = idx;
1928
1929 /* FIX: BAP0 should be locked during bus master transfer, but
1930 * baplock with BH's disabled is not OK for this; netif queue
1931 * stopping is not enough since BAP0 is used also for RID
1932 * read/write */
1933
1934 /* stop the queue for the time that bus mastering on BAP0 is
1935 * in use */
1936 netif_stop_queue(dev);
1937
1938 spin_unlock(&local->baplock);
1939
1940 /* Copy frame data to bus_m0_buf */
1941 pos = local->bus_m0_buf;
1942 memcpy(pos, &txdesc, sizeof(txdesc));
1943 pos += sizeof(txdesc);
1944 memcpy(pos, skb->data + hdr_len, skb->len - hdr_len);
1945 pos += skb->len - hdr_len;
1946 buf_len = pos - local->bus_m0_buf;
1947 if (buf_len & 1)
1948 buf_len++;
1949
1950#ifdef PRISM2_ENABLE_BEFORE_TX_BUS_MASTER
1951 /* Any RX packet seems to break something with TX bus
1952 * mastering; enable command is enough to fix this.. */
1953 if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_ENABLE, 0,
1954 prism2_tx_cb, (void *) buf_len)) {
1955 printk(KERN_DEBUG "%s: TX: enable port0 failed\n",
1956 dev->name);
1957 }
1958#else /* PRISM2_ENABLE_BEFORE_TX_BUS_MASTER */
1959 prism2_tx_cb(dev, (void *) buf_len, 0, 0);
1960#endif /* PRISM2_ENABLE_BEFORE_TX_BUS_MASTER */
1961
1962 /* Bus master transfer will be started from command completion
1963 * event handler and TX handling will be finished by calling
1964 * prism2_transmit() from bus master event handler */
1965 goto tx_stats;
1966 }
1967#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
1968
1969 if (!res)
1970 res = hfa384x_to_bap(dev, BAP0, &txdesc, sizeof(txdesc));
1971 if (!res)
1972 res = hfa384x_to_bap(dev, BAP0, skb->data + hdr_len,
1973 skb->len - hdr_len);
1974 spin_unlock(&local->baplock);
1975
1976 if (!res)
1977 res = prism2_transmit(dev, idx);
1978 if (res) {
1979 printk(KERN_DEBUG "%s: prism2_tx_80211 - to BAP0 failed\n",
1980 dev->name);
1981 local->intransmitfid[idx] = PRISM2_TXFID_EMPTY;
1982 schedule_work(&local->reset_queue);
1983 goto fail;
1984 }
1985
1986 ret = 0;
1987
1988fail:
1989 prism2_callback(local, PRISM2_CALLBACK_TX_END);
1990 return ret;
1991}
1992
1993
1994/* Some SMP systems have reported number of odd errors with hostap_pci. fid
1995 * register has changed values between consecutive reads for an unknown reason.
1996 * This should really not happen, so more debugging is needed. This test
1997 * version is a big slower, but it will detect most of such register changes
1998 * and will try to get the correct fid eventually. */
1999#define EXTRA_FID_READ_TESTS
2000
2001static inline u16 prism2_read_fid_reg(struct net_device *dev, u16 reg)
2002{
2003#ifdef EXTRA_FID_READ_TESTS
2004 u16 val, val2, val3;
2005 int i;
2006
2007 for (i = 0; i < 10; i++) {
2008 val = HFA384X_INW(reg);
2009 val2 = HFA384X_INW(reg);
2010 val3 = HFA384X_INW(reg);
2011
2012 if (val == val2 && val == val3)
2013 return val;
2014
2015 printk(KERN_DEBUG "%s: detected fid change (try=%d, reg=%04x):"
2016 " %04x %04x %04x\n",
2017 dev->name, i, reg, val, val2, val3);
2018 if ((val == val2 || val == val3) && val != 0)
2019 return val;
2020 if (val2 == val3 && val2 != 0)
2021 return val2;
2022 }
2023 printk(KERN_WARNING "%s: Uhhuh.. could not read good fid from reg "
2024 "%04x (%04x %04x %04x)\n", dev->name, reg, val, val2, val3);
2025 return val;
2026#else /* EXTRA_FID_READ_TESTS */
2027 return HFA384X_INW(reg);
2028#endif /* EXTRA_FID_READ_TESTS */
2029}
2030
2031
2032/* Called only as a tasklet (software IRQ) */
2033static void prism2_rx(local_info_t *local)
2034{
2035 struct net_device *dev = local->dev;
2036 int res, rx_pending = 0;
2037 u16 len, hdr_len, rxfid, status, macport;
2038 struct net_device_stats *stats;
2039 struct hfa384x_rx_frame rxdesc;
2040 struct sk_buff *skb = NULL;
2041
2042 prism2_callback(local, PRISM2_CALLBACK_RX_START);
2043 stats = hostap_get_stats(dev);
2044
2045 rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF);
2046#ifndef final_version
2047 if (rxfid == 0) {
2048 rxfid = HFA384X_INW(HFA384X_RXFID_OFF);
2049 printk(KERN_DEBUG "prism2_rx: rxfid=0 (next 0x%04x)\n",
2050 rxfid);
2051 if (rxfid == 0) {
2052 schedule_work(&local->reset_queue);
2053 goto rx_dropped;
2054 }
2055 /* try to continue with the new rxfid value */
2056 }
2057#endif
2058
2059 spin_lock(&local->baplock);
2060 res = hfa384x_setup_bap(dev, BAP0, rxfid, 0);
2061 if (!res)
2062 res = hfa384x_from_bap(dev, BAP0, &rxdesc, sizeof(rxdesc));
2063
2064 if (res) {
2065 spin_unlock(&local->baplock);
2066 printk(KERN_DEBUG "%s: copy from BAP0 failed %d\n", dev->name,
2067 res);
2068 if (res == -ETIMEDOUT) {
2069 schedule_work(&local->reset_queue);
2070 }
2071 goto rx_dropped;
2072 }
2073
2074 len = le16_to_cpu(rxdesc.data_len);
2075 hdr_len = sizeof(rxdesc);
2076 status = le16_to_cpu(rxdesc.status);
2077 macport = (status >> 8) & 0x07;
2078
2079 /* Drop frames with too large reported payload length. Monitor mode
2080 * seems to sometimes pass frames (e.g., ctrl::ack) with signed and
2081 * negative value, so allow also values 65522 .. 65534 (-14 .. -2) for
2082 * macport 7 */
2083 if (len > PRISM2_DATA_MAXLEN + 8 /* WEP */) {
2084 if (macport == 7 && local->iw_mode == IW_MODE_MONITOR) {
2085 if (len >= (u16) -14) {
2086 hdr_len -= 65535 - len;
2087 hdr_len--;
2088 }
2089 len = 0;
2090 } else {
2091 spin_unlock(&local->baplock);
2092 printk(KERN_DEBUG "%s: Received frame with invalid "
2093 "length 0x%04x\n", dev->name, len);
2094 hostap_dump_rx_header(dev->name, &rxdesc);
2095 goto rx_dropped;
2096 }
2097 }
2098
2099 skb = dev_alloc_skb(len + hdr_len);
2100 if (!skb) {
2101 spin_unlock(&local->baplock);
2102 printk(KERN_DEBUG "%s: RX failed to allocate skb\n",
2103 dev->name);
2104 goto rx_dropped;
2105 }
2106 skb->dev = dev;
2107 memcpy(skb_put(skb, hdr_len), &rxdesc, hdr_len);
2108
2109#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
2110 if (len >= local->bus_master_threshold_rx) {
2111 unsigned long addr;
2112
2113 hfa384x_events_no_bap1(dev);
2114
2115 local->rx_skb = skb;
2116 /* Internal BAP0 offset points to the byte following rxdesc;
2117 * copy rest of the data using bus master */
2118 addr = virt_to_phys(skb_put(skb, len));
2119 HFA384X_OUTW((addr & 0xffff0000) >> 16,
2120 HFA384X_PCI_M0_ADDRH_OFF);
2121 HFA384X_OUTW(addr & 0x0000ffff, HFA384X_PCI_M0_ADDRL_OFF);
2122 if (len & 1)
2123 len++;
2124 HFA384X_OUTW(len / 2, HFA384X_PCI_M0_LEN_OFF);
2125 HFA384X_OUTW(HFA384X_PCI_CTL_FROM_BAP, HFA384X_PCI_M0_CTL_OFF);
2126
2127 /* pci_bus_m1 event will be generated when data transfer is
2128 * complete and the frame will then be added to rx_list and
2129 * rx_tasklet is scheduled */
2130 rx_pending = 1;
2131
2132 /* Have to release baplock before returning, although BAP0
2133 * should really not be used before DMA transfer has been
2134 * completed. */
2135 spin_unlock(&local->baplock);
2136 } else
2137#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
2138 {
2139 if (len > 0)
2140 res = hfa384x_from_bap(dev, BAP0, skb_put(skb, len),
2141 len);
2142 spin_unlock(&local->baplock);
2143 if (res) {
2144 printk(KERN_DEBUG "%s: RX failed to read "
2145 "frame data\n", dev->name);
2146 goto rx_dropped;
2147 }
2148
2149 skb_queue_tail(&local->rx_list, skb);
2150 tasklet_schedule(&local->rx_tasklet);
2151 }
2152
2153 rx_exit:
2154 prism2_callback(local, PRISM2_CALLBACK_RX_END);
2155 if (!rx_pending) {
2156 HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
2157 }
2158
2159 return;
2160
2161 rx_dropped:
2162 stats->rx_dropped++;
2163 if (skb)
2164 dev_kfree_skb(skb);
2165 goto rx_exit;
2166}
2167
2168
2169/* Called only as a tasklet (software IRQ) */
2170static void hostap_rx_skb(local_info_t *local, struct sk_buff *skb)
2171{
2172 struct hfa384x_rx_frame *rxdesc;
2173 struct net_device *dev = skb->dev;
2174 struct hostap_80211_rx_status stats;
2175 int hdrlen, rx_hdrlen;
2176
2177 rx_hdrlen = sizeof(*rxdesc);
2178 if (skb->len < sizeof(*rxdesc)) {
2179 /* Allow monitor mode to receive shorter frames */
2180 if (local->iw_mode == IW_MODE_MONITOR &&
2181 skb->len >= sizeof(*rxdesc) - 30) {
2182 rx_hdrlen = skb->len;
2183 } else {
2184 dev_kfree_skb(skb);
2185 return;
2186 }
2187 }
2188
2189 rxdesc = (struct hfa384x_rx_frame *) skb->data;
2190
2191 if (local->frame_dump & PRISM2_DUMP_RX_HDR &&
2192 skb->len >= sizeof(*rxdesc))
2193 hostap_dump_rx_header(dev->name, rxdesc);
2194
2195 if (le16_to_cpu(rxdesc->status) & HFA384X_RX_STATUS_FCSERR &&
2196 (!local->monitor_allow_fcserr ||
2197 local->iw_mode != IW_MODE_MONITOR))
2198 goto drop;
2199
2200 if (skb->len > PRISM2_DATA_MAXLEN) {
2201 printk(KERN_DEBUG "%s: RX: len(%d) > MAX(%d)\n",
2202 dev->name, skb->len, PRISM2_DATA_MAXLEN);
2203 goto drop;
2204 }
2205
2206 stats.mac_time = le32_to_cpu(rxdesc->time);
2207 stats.signal = rxdesc->signal - local->rssi_to_dBm;
2208 stats.noise = rxdesc->silence - local->rssi_to_dBm;
2209 stats.rate = rxdesc->rate;
2210
2211 /* Convert Prism2 RX structure into IEEE 802.11 header */
2212 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control));
2213 if (hdrlen > rx_hdrlen)
2214 hdrlen = rx_hdrlen;
2215
2216 memmove(skb_pull(skb, rx_hdrlen - hdrlen),
2217 &rxdesc->frame_control, hdrlen);
2218
2219 hostap_80211_rx(dev, skb, &stats);
2220 return;
2221
2222 drop:
2223 dev_kfree_skb(skb);
2224}
2225
2226
2227/* Called only as a tasklet (software IRQ) */
2228static void hostap_rx_tasklet(unsigned long data)
2229{
2230 local_info_t *local = (local_info_t *) data;
2231 struct sk_buff *skb;
2232
2233 while ((skb = skb_dequeue(&local->rx_list)) != NULL)
2234 hostap_rx_skb(local, skb);
2235}
2236
2237
2238/* Called only from hardware IRQ */
2239static void prism2_alloc_ev(struct net_device *dev)
2240{
2241 struct hostap_interface *iface;
2242 local_info_t *local;
2243 int idx;
2244 u16 fid;
2245
2246 iface = netdev_priv(dev);
2247 local = iface->local;
2248
2249 fid = prism2_read_fid_reg(dev, HFA384X_ALLOCFID_OFF);
2250
2251 PDEBUG(DEBUG_FID, "FID: interrupt: ALLOC - fid=0x%04x\n", fid);
2252
2253 spin_lock(&local->txfidlock);
2254 idx = local->next_alloc;
2255
2256 do {
2257 if (local->txfid[idx] == fid) {
2258 PDEBUG(DEBUG_FID, "FID: found matching txfid[%d]\n",
2259 idx);
2260
2261#ifndef final_version
2262 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY)
2263 printk("Already released txfid found at idx "
2264 "%d\n", idx);
2265 if (local->intransmitfid[idx] == PRISM2_TXFID_RESERVED)
2266 printk("Already reserved txfid found at idx "
2267 "%d\n", idx);
2268#endif
2269 local->intransmitfid[idx] = PRISM2_TXFID_EMPTY;
2270 idx++;
2271 local->next_alloc = idx >= PRISM2_TXFID_COUNT ? 0 :
2272 idx;
2273
2274 if (!test_bit(HOSTAP_BITS_TRANSMIT, &local->bits) &&
2275 netif_queue_stopped(dev))
2276 netif_wake_queue(dev);
2277
2278 spin_unlock(&local->txfidlock);
2279 return;
2280 }
2281
2282 idx++;
2283 if (idx >= PRISM2_TXFID_COUNT)
2284 idx = 0;
2285 } while (idx != local->next_alloc);
2286
2287 printk(KERN_WARNING "%s: could not find matching txfid (0x%04x, new "
2288 "read 0x%04x) for alloc event\n", dev->name, fid,
2289 HFA384X_INW(HFA384X_ALLOCFID_OFF));
2290 printk(KERN_DEBUG "TXFIDs:");
2291 for (idx = 0; idx < PRISM2_TXFID_COUNT; idx++)
2292 printk(" %04x[%04x]", local->txfid[idx],
2293 local->intransmitfid[idx]);
2294 printk("\n");
2295 spin_unlock(&local->txfidlock);
2296
2297 /* FIX: should probably schedule reset; reference to one txfid was lost
2298 * completely.. Bad things will happen if we run out of txfids
2299 * Actually, this will cause netdev watchdog to notice TX timeout and
2300 * then card reset after all txfids have been leaked. */
2301}
2302
2303
2304/* Called only as a tasklet (software IRQ) */
2305static void hostap_tx_callback(local_info_t *local,
2306 struct hfa384x_tx_frame *txdesc, int ok,
2307 char *payload)
2308{
2309 u16 sw_support, hdrlen, len;
2310 struct sk_buff *skb;
2311 struct hostap_tx_callback_info *cb;
2312
2313 /* Make sure that frame was from us. */
2314 if (memcmp(txdesc->addr2, local->dev->dev_addr, ETH_ALEN)) {
2315 printk(KERN_DEBUG "%s: TX callback - foreign frame\n",
2316 local->dev->name);
2317 return;
2318 }
2319
2320 sw_support = le16_to_cpu(txdesc->sw_support);
2321
2322 spin_lock(&local->lock);
2323 cb = local->tx_callback;
2324 while (cb != NULL && cb->idx != sw_support)
2325 cb = cb->next;
2326 spin_unlock(&local->lock);
2327
2328 if (cb == NULL) {
2329 printk(KERN_DEBUG "%s: could not find TX callback (idx %d)\n",
2330 local->dev->name, sw_support);
2331 return;
2332 }
2333
2334 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control));
2335 len = le16_to_cpu(txdesc->data_len);
2336 skb = dev_alloc_skb(hdrlen + len);
2337 if (skb == NULL) {
2338 printk(KERN_DEBUG "%s: hostap_tx_callback failed to allocate "
2339 "skb\n", local->dev->name);
2340 return;
2341 }
2342
2343 memcpy(skb_put(skb, hdrlen), (void *) &txdesc->frame_control, hdrlen);
2344 if (payload)
2345 memcpy(skb_put(skb, len), payload, len);
2346
2347 skb->dev = local->dev;
2348 skb->mac.raw = skb->data;
2349
2350 cb->func(skb, ok, cb->data);
2351}
2352
2353
2354/* Called only as a tasklet (software IRQ) */
2355static int hostap_tx_compl_read(local_info_t *local, int error,
2356 struct hfa384x_tx_frame *txdesc,
2357 char **payload)
2358{
2359 u16 fid, len;
2360 int res, ret = 0;
2361 struct net_device *dev = local->dev;
2362
2363 fid = prism2_read_fid_reg(dev, HFA384X_TXCOMPLFID_OFF);
2364
2365 PDEBUG(DEBUG_FID, "interrupt: TX (err=%d) - fid=0x%04x\n", fid, error);
2366
2367 spin_lock(&local->baplock);
2368 res = hfa384x_setup_bap(dev, BAP0, fid, 0);
2369 if (!res)
2370 res = hfa384x_from_bap(dev, BAP0, txdesc, sizeof(*txdesc));
2371 if (res) {
2372 PDEBUG(DEBUG_EXTRA, "%s: TX (err=%d) - fid=0x%04x - could not "
2373 "read txdesc\n", dev->name, error, fid);
2374 if (res == -ETIMEDOUT) {
2375 schedule_work(&local->reset_queue);
2376 }
2377 ret = -1;
2378 goto fail;
2379 }
2380 if (txdesc->sw_support) {
2381 len = le16_to_cpu(txdesc->data_len);
2382 if (len < PRISM2_DATA_MAXLEN) {
2383 *payload = (char *) kmalloc(len, GFP_ATOMIC);
2384 if (*payload == NULL ||
2385 hfa384x_from_bap(dev, BAP0, *payload, len)) {
2386 PDEBUG(DEBUG_EXTRA, "%s: could not read TX "
2387 "frame payload\n", dev->name);
2388 kfree(*payload);
2389 *payload = NULL;
2390 ret = -1;
2391 goto fail;
2392 }
2393 }
2394 }
2395
2396 fail:
2397 spin_unlock(&local->baplock);
2398
2399 return ret;
2400}
2401
2402
2403/* Called only as a tasklet (software IRQ) */
2404static void prism2_tx_ev(local_info_t *local)
2405{
2406 struct net_device *dev = local->dev;
2407 char *payload = NULL;
2408 struct hfa384x_tx_frame txdesc;
2409
2410 if (hostap_tx_compl_read(local, 0, &txdesc, &payload))
2411 goto fail;
2412
2413 if (local->frame_dump & PRISM2_DUMP_TX_HDR) {
2414 PDEBUG(DEBUG_EXTRA, "%s: TX - status=0x%04x "
2415 "retry_count=%d tx_rate=%d seq_ctrl=%d "
2416 "duration_id=%d\n",
2417 dev->name, le16_to_cpu(txdesc.status),
2418 txdesc.retry_count, txdesc.tx_rate,
2419 le16_to_cpu(txdesc.seq_ctrl),
2420 le16_to_cpu(txdesc.duration_id));
2421 }
2422
2423 if (txdesc.sw_support)
2424 hostap_tx_callback(local, &txdesc, 1, payload);
2425 kfree(payload);
2426
2427 fail:
2428 HFA384X_OUTW(HFA384X_EV_TX, HFA384X_EVACK_OFF);
2429}
2430
2431
2432/* Called only as a tasklet (software IRQ) */
2433static void hostap_sta_tx_exc_tasklet(unsigned long data)
2434{
2435 local_info_t *local = (local_info_t *) data;
2436 struct sk_buff *skb;
2437
2438 while ((skb = skb_dequeue(&local->sta_tx_exc_list)) != NULL) {
2439 struct hfa384x_tx_frame *txdesc =
2440 (struct hfa384x_tx_frame *) skb->data;
2441
2442 if (skb->len >= sizeof(*txdesc)) {
2443 /* Convert Prism2 RX structure into IEEE 802.11 header
2444 */
2445 u16 fc = le16_to_cpu(txdesc->frame_control);
2446 int hdrlen = hostap_80211_get_hdrlen(fc);
2447 memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen),
2448 &txdesc->frame_control, hdrlen);
2449
2450 hostap_handle_sta_tx_exc(local, skb);
2451 }
2452 dev_kfree_skb(skb);
2453 }
2454}
2455
2456
2457/* Called only as a tasklet (software IRQ) */
2458static void prism2_txexc(local_info_t *local)
2459{
2460 struct net_device *dev = local->dev;
2461 u16 status, fc;
2462 int show_dump, res;
2463 char *payload = NULL;
2464 struct hfa384x_tx_frame txdesc;
2465
2466 show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
2467 local->stats.tx_errors++;
2468
2469 res = hostap_tx_compl_read(local, 1, &txdesc, &payload);
2470 HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF);
2471 if (res)
2472 return;
2473
2474 status = le16_to_cpu(txdesc.status);
2475
2476 /* We produce a TXDROP event only for retry or lifetime
2477 * exceeded, because that's the only status that really mean
2478 * that this particular node went away.
2479 * Other errors means that *we* screwed up. - Jean II */
2480 if (status & (HFA384X_TX_STATUS_RETRYERR | HFA384X_TX_STATUS_AGEDERR))
2481 {
2482 union iwreq_data wrqu;
2483
2484 /* Copy 802.11 dest address. */
2485 memcpy(wrqu.addr.sa_data, txdesc.addr1, ETH_ALEN);
2486 wrqu.addr.sa_family = ARPHRD_ETHER;
2487 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
2488 } else
2489 show_dump = 1;
2490
2491 if (local->iw_mode == IW_MODE_MASTER ||
2492 local->iw_mode == IW_MODE_REPEAT ||
2493 local->wds_type & HOSTAP_WDS_AP_CLIENT) {
2494 struct sk_buff *skb;
2495 skb = dev_alloc_skb(sizeof(txdesc));
2496 if (skb) {
2497 memcpy(skb_put(skb, sizeof(txdesc)), &txdesc,
2498 sizeof(txdesc));
2499 skb_queue_tail(&local->sta_tx_exc_list, skb);
2500 tasklet_schedule(&local->sta_tx_exc_tasklet);
2501 }
2502 }
2503
2504 if (txdesc.sw_support)
2505 hostap_tx_callback(local, &txdesc, 0, payload);
2506 kfree(payload);
2507
2508 if (!show_dump)
2509 return;
2510
2511 PDEBUG(DEBUG_EXTRA, "%s: TXEXC - status=0x%04x (%s%s%s%s)"
2512 " tx_control=%04x\n",
2513 dev->name, status,
2514 status & HFA384X_TX_STATUS_RETRYERR ? "[RetryErr]" : "",
2515 status & HFA384X_TX_STATUS_AGEDERR ? "[AgedErr]" : "",
2516 status & HFA384X_TX_STATUS_DISCON ? "[Discon]" : "",
2517 status & HFA384X_TX_STATUS_FORMERR ? "[FormErr]" : "",
2518 le16_to_cpu(txdesc.tx_control));
2519
2520 fc = le16_to_cpu(txdesc.frame_control);
2521 PDEBUG(DEBUG_EXTRA, " retry_count=%d tx_rate=%d fc=0x%04x "
2522 "(%s%s%s::%d%s%s)\n",
2523 txdesc.retry_count, txdesc.tx_rate, fc,
2524 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT ? "Mgmt" : "",
2525 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_CTRL ? "Ctrl" : "",
2526 WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA ? "Data" : "",
2527 WLAN_FC_GET_STYPE(fc),
2528 fc & WLAN_FC_TODS ? " ToDS" : "",
2529 fc & WLAN_FC_FROMDS ? " FromDS" : "");
2530 PDEBUG(DEBUG_EXTRA, " A1=" MACSTR " A2=" MACSTR " A3="
2531 MACSTR " A4=" MACSTR "\n",
2532 MAC2STR(txdesc.addr1), MAC2STR(txdesc.addr2),
2533 MAC2STR(txdesc.addr3), MAC2STR(txdesc.addr4));
2534}
2535
2536
2537/* Called only as a tasklet (software IRQ) */
2538static void hostap_info_tasklet(unsigned long data)
2539{
2540 local_info_t *local = (local_info_t *) data;
2541 struct sk_buff *skb;
2542
2543 while ((skb = skb_dequeue(&local->info_list)) != NULL) {
2544 hostap_info_process(local, skb);
2545 dev_kfree_skb(skb);
2546 }
2547}
2548
2549
2550/* Called only as a tasklet (software IRQ) */
2551static void prism2_info(local_info_t *local)
2552{
2553 struct net_device *dev = local->dev;
2554 u16 fid;
2555 int res, left;
2556 struct hfa384x_info_frame info;
2557 struct sk_buff *skb;
2558
2559 fid = HFA384X_INW(HFA384X_INFOFID_OFF);
2560
2561 spin_lock(&local->baplock);
2562 res = hfa384x_setup_bap(dev, BAP0, fid, 0);
2563 if (!res)
2564 res = hfa384x_from_bap(dev, BAP0, &info, sizeof(info));
2565 if (res) {
2566 spin_unlock(&local->baplock);
2567 printk(KERN_DEBUG "Could not get info frame (fid=0x%04x)\n",
2568 fid);
2569 if (res == -ETIMEDOUT) {
2570 schedule_work(&local->reset_queue);
2571 }
2572 goto out;
2573 }
2574
2575 le16_to_cpus(&info.len);
2576 le16_to_cpus(&info.type);
2577 left = (info.len - 1) * 2;
2578
2579 if (info.len & 0x8000 || info.len == 0 || left > 2060) {
2580 /* data register seems to give 0x8000 in some error cases even
2581 * though busy bit is not set in offset register;
2582 * in addition, length must be at least 1 due to type field */
2583 spin_unlock(&local->baplock);
2584 printk(KERN_DEBUG "%s: Received info frame with invalid "
2585 "length 0x%04x (type 0x%04x)\n", dev->name, info.len,
2586 info.type);
2587 goto out;
2588 }
2589
2590 skb = dev_alloc_skb(sizeof(info) + left);
2591 if (skb == NULL) {
2592 spin_unlock(&local->baplock);
2593 printk(KERN_DEBUG "%s: Could not allocate skb for info "
2594 "frame\n", dev->name);
2595 goto out;
2596 }
2597
2598 memcpy(skb_put(skb, sizeof(info)), &info, sizeof(info));
2599 if (left > 0 && hfa384x_from_bap(dev, BAP0, skb_put(skb, left), left))
2600 {
2601 spin_unlock(&local->baplock);
2602 printk(KERN_WARNING "%s: Info frame read failed (fid=0x%04x, "
2603 "len=0x%04x, type=0x%04x\n",
2604 dev->name, fid, info.len, info.type);
2605 dev_kfree_skb(skb);
2606 goto out;
2607 }
2608 spin_unlock(&local->baplock);
2609
2610 skb_queue_tail(&local->info_list, skb);
2611 tasklet_schedule(&local->info_tasklet);
2612
2613 out:
2614 HFA384X_OUTW(HFA384X_EV_INFO, HFA384X_EVACK_OFF);
2615}
2616
2617
2618/* Called only as a tasklet (software IRQ) */
2619static void hostap_bap_tasklet(unsigned long data)
2620{
2621 local_info_t *local = (local_info_t *) data;
2622 struct net_device *dev = local->dev;
2623 u16 ev;
2624 int frames = 30;
2625
2626 if (local->func->card_present && !local->func->card_present(local))
2627 return;
2628
2629 set_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits);
2630
2631 /* Process all pending BAP events without generating new interrupts
2632 * for them */
2633 while (frames-- > 0) {
2634 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2635 if (ev == 0xffff || !(ev & HFA384X_BAP0_EVENTS))
2636 break;
2637 if (ev & HFA384X_EV_RX)
2638 prism2_rx(local);
2639 if (ev & HFA384X_EV_INFO)
2640 prism2_info(local);
2641 if (ev & HFA384X_EV_TX)
2642 prism2_tx_ev(local);
2643 if (ev & HFA384X_EV_TXEXC)
2644 prism2_txexc(local);
2645 }
2646
2647 set_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits);
2648 clear_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits);
2649
2650 /* Enable interrupts for new BAP events */
2651 hfa384x_events_all(dev);
2652 clear_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits);
2653}
2654
2655
2656#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
2657/* Called only from hardware IRQ */
2658static void prism2_bus_master_ev(struct net_device *dev, int bap)
2659{
2660 struct hostap_interface *iface;
2661 local_info_t *local;
2662
2663 iface = netdev_priv(dev);
2664 local = iface->local;
2665
2666 if (bap == BAP1) {
2667 /* FIX: frame payload was DMA'd to skb->data; might need to
2668 * invalidate data cache for that memory area */
2669 skb_queue_tail(&local->rx_list, local->rx_skb);
2670 tasklet_schedule(&local->rx_tasklet);
2671 HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
2672 } else {
2673 if (prism2_transmit(dev, local->bus_m0_tx_idx)) {
2674 printk(KERN_DEBUG "%s: prism2_transmit() failed "
2675 "when called from bus master event\n",
2676 dev->name);
2677 local->intransmitfid[local->bus_m0_tx_idx] =
2678 PRISM2_TXFID_EMPTY;
2679 schedule_work(&local->reset_queue);
2680 }
2681 }
2682}
2683#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
2684
2685
2686/* Called only from hardware IRQ */
2687static void prism2_infdrop(struct net_device *dev)
2688{
2689 static unsigned long last_inquire = 0;
2690
2691 PDEBUG(DEBUG_EXTRA, "%s: INFDROP event\n", dev->name);
2692
2693 /* some firmware versions seem to get stuck with
2694 * full CommTallies in high traffic load cases; every
2695 * packet will then cause INFDROP event and CommTallies
2696 * info frame will not be sent automatically. Try to
2697 * get out of this state by inquiring CommTallies. */
2698 if (!last_inquire || time_after(jiffies, last_inquire + HZ)) {
2699 hfa384x_cmd_callback(dev, HFA384X_CMDCODE_INQUIRE,
2700 HFA384X_INFO_COMMTALLIES, NULL, NULL);
2701 last_inquire = jiffies;
2702 }
2703}
2704
2705
2706/* Called only from hardware IRQ */
2707static void prism2_ev_tick(struct net_device *dev)
2708{
2709 struct hostap_interface *iface;
2710 local_info_t *local;
2711 u16 evstat, inten;
2712 static int prev_stuck = 0;
2713
2714 iface = netdev_priv(dev);
2715 local = iface->local;
2716
2717 if (time_after(jiffies, local->last_tick_timer + 5 * HZ) &&
2718 local->last_tick_timer) {
2719 evstat = HFA384X_INW(HFA384X_EVSTAT_OFF);
2720 inten = HFA384X_INW(HFA384X_INTEN_OFF);
2721 if (!prev_stuck) {
2722 printk(KERN_INFO "%s: SW TICK stuck? "
2723 "bits=0x%lx EvStat=%04x IntEn=%04x\n",
2724 dev->name, local->bits, evstat, inten);
2725 }
2726 local->sw_tick_stuck++;
2727 if ((evstat & HFA384X_BAP0_EVENTS) &&
2728 (inten & HFA384X_BAP0_EVENTS)) {
2729 printk(KERN_INFO "%s: trying to recover from IRQ "
2730 "hang\n", dev->name);
2731 hfa384x_events_no_bap0(dev);
2732 }
2733 prev_stuck = 1;
2734 } else
2735 prev_stuck = 0;
2736}
2737
2738
2739/* Called only from hardware IRQ */
2740static inline void prism2_check_magic(local_info_t *local)
2741{
2742 /* at least PCI Prism2.5 with bus mastering seems to sometimes
2743 * return 0x0000 in SWSUPPORT0 for unknown reason, but re-reading the
2744 * register once or twice seems to get the correct value.. PCI cards
2745 * cannot anyway be removed during normal operation, so there is not
2746 * really any need for this verification with them. */
2747
2748#ifndef PRISM2_PCI
2749#ifndef final_version
2750 static unsigned long last_magic_err = 0;
2751 struct net_device *dev = local->dev;
2752
2753 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
2754 if (!local->hw_ready)
2755 return;
2756 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
2757 if (time_after(jiffies, last_magic_err + 10 * HZ)) {
2758 printk("%s: Interrupt, but SWSUPPORT0 does not match: "
2759 "%04X != %04X - card removed?\n", dev->name,
2760 HFA384X_INW(HFA384X_SWSUPPORT0_OFF),
2761 HFA384X_MAGIC);
2762 last_magic_err = jiffies;
2763 } else if (net_ratelimit()) {
2764 printk(KERN_DEBUG "%s: interrupt - SWSUPPORT0=%04x "
2765 "MAGIC=%04x\n", dev->name,
2766 HFA384X_INW(HFA384X_SWSUPPORT0_OFF),
2767 HFA384X_MAGIC);
2768 }
2769 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != 0xffff)
2770 schedule_work(&local->reset_queue);
2771 return;
2772 }
2773#endif /* final_version */
2774#endif /* !PRISM2_PCI */
2775}
2776
2777
2778/* Called only from hardware IRQ */
2779static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2780{
2781 struct net_device *dev = (struct net_device *) dev_id;
2782 struct hostap_interface *iface;
2783 local_info_t *local;
2784 int events = 0;
2785 u16 ev;
2786
2787 iface = netdev_priv(dev);
2788 local = iface->local;
2789
2790 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
2791
2792 if (local->func->card_present && !local->func->card_present(local)) {
2793 if (net_ratelimit()) {
2794 printk(KERN_DEBUG "%s: Interrupt, but dev not OK\n",
2795 dev->name);
2796 }
2797 return IRQ_HANDLED;
2798 }
2799
2800 prism2_check_magic(local);
2801
2802 for (;;) {
2803 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2804 if (ev == 0xffff) {
2805 if (local->shutdown)
2806 return IRQ_HANDLED;
2807 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
2808 printk(KERN_DEBUG "%s: prism2_interrupt: ev=0xffff\n",
2809 dev->name);
2810 return IRQ_HANDLED;
2811 }
2812
2813 ev &= HFA384X_INW(HFA384X_INTEN_OFF);
2814 if (ev == 0)
2815 break;
2816
2817 if (ev & HFA384X_EV_CMD) {
2818 prism2_cmd_ev(dev);
2819 }
2820
2821 /* Above events are needed even before hw is ready, but other
2822 * events should be skipped during initialization. This may
2823 * change for AllocEv if allocate_fid is implemented without
2824 * busy waiting. */
2825 if (!local->hw_ready || local->hw_resetting ||
2826 !local->dev_enabled) {
2827 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2828 if (ev & HFA384X_EV_CMD)
2829 goto next_event;
2830 if ((ev & HFA384X_EVENT_MASK) == 0)
2831 return IRQ_HANDLED;
2832 if (local->dev_enabled && (ev & ~HFA384X_EV_TICK) &&
2833 net_ratelimit()) {
2834 printk(KERN_DEBUG "%s: prism2_interrupt: hw "
2835 "not ready; skipping events 0x%04x "
2836 "(IntEn=0x%04x)%s%s%s\n",
2837 dev->name, ev,
2838 HFA384X_INW(HFA384X_INTEN_OFF),
2839 !local->hw_ready ? " (!hw_ready)" : "",
2840 local->hw_resetting ?
2841 " (hw_resetting)" : "",
2842 !local->dev_enabled ?
2843 " (!dev_enabled)" : "");
2844 }
2845 HFA384X_OUTW(ev, HFA384X_EVACK_OFF);
2846 return IRQ_HANDLED;
2847 }
2848
2849 if (ev & HFA384X_EV_TICK) {
2850 prism2_ev_tick(dev);
2851 HFA384X_OUTW(HFA384X_EV_TICK, HFA384X_EVACK_OFF);
2852 }
2853
2854#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
2855 if (ev & HFA384X_EV_PCI_M0) {
2856 prism2_bus_master_ev(dev, BAP0);
2857 HFA384X_OUTW(HFA384X_EV_PCI_M0, HFA384X_EVACK_OFF);
2858 }
2859
2860 if (ev & HFA384X_EV_PCI_M1) {
2861 /* previous RX has been copied can be ACKed now */
2862 HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
2863
2864 prism2_bus_master_ev(dev, BAP1);
2865 HFA384X_OUTW(HFA384X_EV_PCI_M1, HFA384X_EVACK_OFF);
2866 }
2867#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
2868
2869 if (ev & HFA384X_EV_ALLOC) {
2870 prism2_alloc_ev(dev);
2871 HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
2872 }
2873
2874 /* Reading data from the card is quite time consuming, so do it
2875 * in tasklets. TX, TXEXC, RX, and INFO events will be ACKed
2876 * and unmasked after needed data has been read completely. */
2877 if (ev & HFA384X_BAP0_EVENTS) {
2878 hfa384x_events_no_bap0(dev);
2879 tasklet_schedule(&local->bap_tasklet);
2880 }
2881
2882#ifndef final_version
2883 if (ev & HFA384X_EV_WTERR) {
2884 PDEBUG(DEBUG_EXTRA, "%s: WTERR event\n", dev->name);
2885 HFA384X_OUTW(HFA384X_EV_WTERR, HFA384X_EVACK_OFF);
2886 }
2887#endif /* final_version */
2888
2889 if (ev & HFA384X_EV_INFDROP) {
2890 prism2_infdrop(dev);
2891 HFA384X_OUTW(HFA384X_EV_INFDROP, HFA384X_EVACK_OFF);
2892 }
2893
2894 next_event:
2895 events++;
2896 if (events >= PRISM2_MAX_INTERRUPT_EVENTS) {
2897 PDEBUG(DEBUG_EXTRA, "prism2_interrupt: >%d events "
2898 "(EvStat=0x%04x)\n",
2899 PRISM2_MAX_INTERRUPT_EVENTS,
2900 HFA384X_INW(HFA384X_EVSTAT_OFF));
2901 break;
2902 }
2903 }
2904 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 1);
2905 return IRQ_RETVAL(events);
2906}
2907
2908
2909static void prism2_check_sta_fw_version(local_info_t *local)
2910{
2911 struct hfa384x_comp_ident comp;
2912 int id, variant, major, minor;
2913
2914 if (hfa384x_get_rid(local->dev, HFA384X_RID_STAID,
2915 &comp, sizeof(comp), 1) < 0)
2916 return;
2917
2918 local->fw_ap = 0;
2919 id = le16_to_cpu(comp.id);
2920 if (id != HFA384X_COMP_ID_STA) {
2921 if (id == HFA384X_COMP_ID_FW_AP)
2922 local->fw_ap = 1;
2923 return;
2924 }
2925
2926 major = __le16_to_cpu(comp.major);
2927 minor = __le16_to_cpu(comp.minor);
2928 variant = __le16_to_cpu(comp.variant);
2929 local->sta_fw_ver = PRISM2_FW_VER(major, minor, variant);
2930
2931 /* Station firmware versions before 1.4.x seem to have a bug in
2932 * firmware-based WEP encryption when using Host AP mode, so use
2933 * host_encrypt as a default for them. Firmware version 1.4.9 is the
2934 * first one that has been seen to produce correct encryption, but the
2935 * bug might be fixed before that (although, at least 1.4.2 is broken).
2936 */
2937 local->fw_encrypt_ok = local->sta_fw_ver >= PRISM2_FW_VER(1,4,9);
2938
2939 if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
2940 !local->fw_encrypt_ok) {
2941 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
2942 "a workaround for firmware bug in Host AP mode WEP\n",
2943 local->dev->name);
2944 local->host_encrypt = 1;
2945 }
2946
2947 /* IEEE 802.11 standard compliant WDS frames (4 addresses) were broken
2948 * in station firmware versions before 1.5.x. With these versions, the
2949 * driver uses a workaround with bogus frame format (4th address after
2950 * the payload). This is not compatible with other AP devices. Since
2951 * the firmware bug is fixed in the latest station firmware versions,
2952 * automatically enable standard compliant mode for cards using station
2953 * firmware version 1.5.0 or newer. */
2954 if (local->sta_fw_ver >= PRISM2_FW_VER(1,5,0))
2955 local->wds_type |= HOSTAP_WDS_STANDARD_FRAME;
2956 else {
2957 printk(KERN_DEBUG "%s: defaulting to bogus WDS frame as a "
2958 "workaround for firmware bug in Host AP mode WDS\n",
2959 local->dev->name);
2960 }
2961
2962 hostap_check_sta_fw_version(local->ap, local->sta_fw_ver);
2963}
2964
2965
2966static void prism2_crypt_deinit_entries(local_info_t *local, int force)
2967{
2968 struct list_head *ptr, *n;
2969 struct prism2_crypt_data *entry;
2970
2971 for (ptr = local->crypt_deinit_list.next, n = ptr->next;
2972 ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
2973 entry = list_entry(ptr, struct prism2_crypt_data, list);
2974
2975 if (atomic_read(&entry->refcnt) != 0 && !force)
2976 continue;
2977
2978 list_del(ptr);
2979
2980 if (entry->ops)
2981 entry->ops->deinit(entry->priv);
2982 kfree(entry);
2983 }
2984}
2985
2986
2987static void prism2_crypt_deinit_handler(unsigned long data)
2988{
2989 local_info_t *local = (local_info_t *) data;
2990 unsigned long flags;
2991
2992 spin_lock_irqsave(&local->lock, flags);
2993 prism2_crypt_deinit_entries(local, 0);
2994 if (!list_empty(&local->crypt_deinit_list)) {
2995 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
2996 "deletion list\n", local->dev->name);
2997 local->crypt_deinit_timer.expires = jiffies + HZ;
2998 add_timer(&local->crypt_deinit_timer);
2999 }
3000 spin_unlock_irqrestore(&local->lock, flags);
3001
3002}
3003
3004
3005static void hostap_passive_scan(unsigned long data)
3006{
3007 local_info_t *local = (local_info_t *) data;
3008 struct net_device *dev = local->dev;
3009 u16 channel;
3010
3011 if (local->passive_scan_interval <= 0)
3012 return;
3013
3014 if (local->passive_scan_state == PASSIVE_SCAN_LISTEN) {
3015 int max_tries = 16;
3016
3017 /* Even though host system does not really know when the WLAN
3018 * MAC is sending frames, try to avoid changing channels for
3019 * passive scanning when a host-generated frame is being
3020 * transmitted */
3021 if (test_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
3022 printk(KERN_DEBUG "%s: passive scan detected pending "
3023 "TX - delaying\n", dev->name);
3024 local->passive_scan_timer.expires = jiffies + HZ / 10;
3025 add_timer(&local->passive_scan_timer);
3026 return;
3027 }
3028
3029 do {
3030 local->passive_scan_channel++;
3031 if (local->passive_scan_channel > 14)
3032 local->passive_scan_channel = 1;
3033 max_tries--;
3034 } while (!(local->channel_mask &
3035 (1 << (local->passive_scan_channel - 1))) &&
3036 max_tries > 0);
3037
3038 if (max_tries == 0) {
3039 printk(KERN_INFO "%s: no allowed passive scan channels"
3040 " found\n", dev->name);
3041 return;
3042 }
3043
3044 printk(KERN_DEBUG "%s: passive scan channel %d\n",
3045 dev->name, local->passive_scan_channel);
3046 channel = local->passive_scan_channel;
3047 local->passive_scan_state = PASSIVE_SCAN_WAIT;
3048 local->passive_scan_timer.expires = jiffies + HZ / 10;
3049 } else {
3050 channel = local->channel;
3051 local->passive_scan_state = PASSIVE_SCAN_LISTEN;
3052 local->passive_scan_timer.expires = jiffies +
3053 local->passive_scan_interval * HZ;
3054 }
3055
3056 if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST |
3057 (HFA384X_TEST_CHANGE_CHANNEL << 8),
3058 channel, NULL, NULL))
3059 printk(KERN_ERR "%s: passive scan channel set %d "
3060 "failed\n", dev->name, channel);
3061
3062 add_timer(&local->passive_scan_timer);
3063}
3064
3065
3066/* Called only as a scheduled task when communications quality values should
3067 * be updated. */
3068static void handle_comms_qual_update(void *data)
3069{
3070 local_info_t *local = data;
3071 prism2_update_comms_qual(local->dev);
3072}
3073
3074
3075/* Software watchdog - called as a timer. Hardware interrupt (Tick event) is
3076 * used to monitor that local->last_tick_timer is being updated. If not,
3077 * interrupt busy-loop is assumed and driver tries to recover by masking out
3078 * some events. */
3079static void hostap_tick_timer(unsigned long data)
3080{
3081 static unsigned long last_inquire = 0;
3082 local_info_t *local = (local_info_t *) data;
3083 local->last_tick_timer = jiffies;
3084
3085 /* Inquire CommTallies every 10 seconds to keep the statistics updated
3086 * more often during low load and when using 32-bit tallies. */
3087 if ((!last_inquire || time_after(jiffies, last_inquire + 10 * HZ)) &&
3088 !local->hw_downloading && local->hw_ready &&
3089 !local->hw_resetting && local->dev_enabled) {
3090 hfa384x_cmd_callback(local->dev, HFA384X_CMDCODE_INQUIRE,
3091 HFA384X_INFO_COMMTALLIES, NULL, NULL);
3092 last_inquire = jiffies;
3093 }
3094
3095 if ((local->last_comms_qual_update == 0 ||
3096 time_after(jiffies, local->last_comms_qual_update + 10 * HZ)) &&
3097 (local->iw_mode == IW_MODE_INFRA ||
3098 local->iw_mode == IW_MODE_ADHOC)) {
3099 schedule_work(&local->comms_qual_update);
3100 }
3101
3102 local->tick_timer.expires = jiffies + 2 * HZ;
3103 add_timer(&local->tick_timer);
3104}
3105
3106
3107#ifndef PRISM2_NO_PROCFS_DEBUG
3108static int prism2_registers_proc_read(char *page, char **start, off_t off,
3109 int count, int *eof, void *data)
3110{
3111 char *p = page;
3112 local_info_t *local = (local_info_t *) data;
3113
3114 if (off != 0) {
3115 *eof = 1;
3116 return 0;
3117 }
3118
3119#define SHOW_REG(n) \
3120p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF))
3121
3122 SHOW_REG(CMD);
3123 SHOW_REG(PARAM0);
3124 SHOW_REG(PARAM1);
3125 SHOW_REG(PARAM2);
3126 SHOW_REG(STATUS);
3127 SHOW_REG(RESP0);
3128 SHOW_REG(RESP1);
3129 SHOW_REG(RESP2);
3130 SHOW_REG(INFOFID);
3131 SHOW_REG(CONTROL);
3132 SHOW_REG(SELECT0);
3133 SHOW_REG(SELECT1);
3134 SHOW_REG(OFFSET0);
3135 SHOW_REG(OFFSET1);
3136 SHOW_REG(RXFID);
3137 SHOW_REG(ALLOCFID);
3138 SHOW_REG(TXCOMPLFID);
3139 SHOW_REG(SWSUPPORT0);
3140 SHOW_REG(SWSUPPORT1);
3141 SHOW_REG(SWSUPPORT2);
3142 SHOW_REG(EVSTAT);
3143 SHOW_REG(INTEN);
3144 SHOW_REG(EVACK);
3145 /* Do not read data registers, because they change the state of the
3146 * MAC (offset += 2) */
3147 /* SHOW_REG(DATA0); */
3148 /* SHOW_REG(DATA1); */
3149 SHOW_REG(AUXPAGE);
3150 SHOW_REG(AUXOFFSET);
3151 /* SHOW_REG(AUXDATA); */
3152#ifdef PRISM2_PCI
3153 SHOW_REG(PCICOR);
3154 SHOW_REG(PCIHCR);
3155 SHOW_REG(PCI_M0_ADDRH);
3156 SHOW_REG(PCI_M0_ADDRL);
3157 SHOW_REG(PCI_M0_LEN);
3158 SHOW_REG(PCI_M0_CTL);
3159 SHOW_REG(PCI_STATUS);
3160 SHOW_REG(PCI_M1_ADDRH);
3161 SHOW_REG(PCI_M1_ADDRL);
3162 SHOW_REG(PCI_M1_LEN);
3163 SHOW_REG(PCI_M1_CTL);
3164#endif /* PRISM2_PCI */
3165
3166 return (p - page);
3167}
3168#endif /* PRISM2_NO_PROCFS_DEBUG */
3169
3170
3171struct set_tim_data {
3172 struct list_head list;
3173 int aid;
3174 int set;
3175};
3176
3177static int prism2_set_tim(struct net_device *dev, int aid, int set)
3178{
3179 struct list_head *ptr;
3180 struct set_tim_data *new_entry;
3181 struct hostap_interface *iface;
3182 local_info_t *local;
3183
3184 iface = netdev_priv(dev);
3185 local = iface->local;
3186
3187 new_entry = (struct set_tim_data *)
3188 kmalloc(sizeof(*new_entry), GFP_ATOMIC);
3189 if (new_entry == NULL) {
3190 printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
3191 local->dev->name);
3192 return -ENOMEM;
3193 }
3194 memset(new_entry, 0, sizeof(*new_entry));
3195 new_entry->aid = aid;
3196 new_entry->set = set;
3197
3198 spin_lock_bh(&local->set_tim_lock);
3199 list_for_each(ptr, &local->set_tim_list) {
3200 struct set_tim_data *entry =
3201 list_entry(ptr, struct set_tim_data, list);
3202 if (entry->aid == aid) {
3203 PDEBUG(DEBUG_PS2, "%s: prism2_set_tim: aid=%d "
3204 "set=%d ==> %d\n",
3205 local->dev->name, aid, entry->set, set);
3206 entry->set = set;
3207 kfree(new_entry);
3208 new_entry = NULL;
3209 break;
3210 }
3211 }
3212 if (new_entry)
3213 list_add_tail(&new_entry->list, &local->set_tim_list);
3214 spin_unlock_bh(&local->set_tim_lock);
3215
3216 schedule_work(&local->set_tim_queue);
3217
3218 return 0;
3219}
3220
3221
3222static void handle_set_tim_queue(void *data)
3223{
3224 local_info_t *local = (local_info_t *) data;
3225 struct set_tim_data *entry;
3226 u16 val;
3227
3228 for (;;) {
3229 entry = NULL;
3230 spin_lock_bh(&local->set_tim_lock);
3231 if (!list_empty(&local->set_tim_list)) {
3232 entry = list_entry(local->set_tim_list.next,
3233 struct set_tim_data, list);
3234 list_del(&entry->list);
3235 }
3236 spin_unlock_bh(&local->set_tim_lock);
3237 if (!entry)
3238 break;
3239
3240 PDEBUG(DEBUG_PS2, "%s: handle_set_tim_queue: aid=%d set=%d\n",
3241 local->dev->name, entry->aid, entry->set);
3242
3243 val = entry->aid;
3244 if (entry->set)
3245 val |= 0x8000;
3246 if (hostap_set_word(local->dev, HFA384X_RID_CNFTIMCTRL, val)) {
3247 printk(KERN_DEBUG "%s: set_tim failed (aid=%d "
3248 "set=%d)\n",
3249 local->dev->name, entry->aid, entry->set);
3250 }
3251
3252 kfree(entry);
3253 }
3254}
3255
3256
3257static void prism2_clear_set_tim_queue(local_info_t *local)
3258{
3259 struct list_head *ptr, *n;
3260
3261 list_for_each_safe(ptr, n, &local->set_tim_list) {
3262 struct set_tim_data *entry;
3263 entry = list_entry(ptr, struct set_tim_data, list);
3264 list_del(&entry->list);
3265 kfree(entry);
3266 }
3267}
3268
3269
3270static struct net_device *
3271prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx)
3272{
3273 struct net_device *dev;
3274 struct hostap_interface *iface;
3275 struct local_info *local;
3276 int len, i, ret;
3277
3278 if (funcs == NULL)
3279 return NULL;
3280
3281 len = strlen(dev_template);
3282 if (len >= IFNAMSIZ || strstr(dev_template, "%d") == NULL) {
3283 printk(KERN_WARNING "hostap: Invalid dev_template='%s'\n",
3284 dev_template);
3285 return NULL;
3286 }
3287
3288 len = sizeof(struct hostap_interface) +
3289 3 + sizeof(struct local_info) +
3290 3 + sizeof(struct ap_data);
3291
3292 dev = alloc_etherdev(len);
3293 if (dev == NULL)
3294 return NULL;
3295
3296 iface = netdev_priv(dev);
3297 local = (struct local_info *) ((((long) (iface + 1)) + 3) & ~3);
3298 local->ap = (struct ap_data *) ((((long) (local + 1)) + 3) & ~3);
3299 local->dev = iface->dev = dev;
3300 iface->local = local;
3301 iface->type = HOSTAP_INTERFACE_MASTER;
3302 INIT_LIST_HEAD(&local->hostap_interfaces);
3303
3304 local->hw_module = THIS_MODULE;
3305
3306#ifdef PRISM2_IO_DEBUG
3307 local->io_debug_enabled = 1;
3308#endif /* PRISM2_IO_DEBUG */
3309
3310#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
3311 local->bus_m0_buf = (u8 *) kmalloc(sizeof(struct hfa384x_tx_frame) +
3312 PRISM2_DATA_MAXLEN, GFP_DMA);
3313 if (local->bus_m0_buf == NULL)
3314 goto fail;
3315#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
3316
3317 local->func = funcs;
3318 local->func->cmd = hfa384x_cmd;
3319 local->func->read_regs = hfa384x_read_regs;
3320 local->func->get_rid = hfa384x_get_rid;
3321 local->func->set_rid = hfa384x_set_rid;
3322 local->func->hw_enable = prism2_hw_enable;
3323 local->func->hw_config = prism2_hw_config;
3324 local->func->hw_reset = prism2_hw_reset;
3325 local->func->hw_shutdown = prism2_hw_shutdown;
3326 local->func->reset_port = prism2_reset_port;
3327 local->func->schedule_reset = prism2_schedule_reset;
3328#ifdef PRISM2_DOWNLOAD_SUPPORT
3329 local->func->read_aux = prism2_download_aux_dump;
3330 local->func->download = prism2_download;
3331#endif /* PRISM2_DOWNLOAD_SUPPORT */
3332 local->func->tx = prism2_tx_80211;
3333 local->func->set_tim = prism2_set_tim;
3334 local->func->need_tx_headroom = 0; /* no need to add txdesc in
3335 * skb->data (FIX: maybe for DMA bus
3336 * mastering? */
3337
3338 local->mtu = mtu;
3339
3340 rwlock_init(&local->iface_lock);
3341 spin_lock_init(&local->txfidlock);
3342 spin_lock_init(&local->cmdlock);
3343 spin_lock_init(&local->baplock);
3344 spin_lock_init(&local->lock);
3345 init_MUTEX(&local->rid_bap_sem);
3346
3347 if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES)
3348 card_idx = 0;
3349 local->card_idx = card_idx;
3350
3351 len = strlen(essid);
3352 memcpy(local->essid, essid,
3353 len > MAX_SSID_LEN ? MAX_SSID_LEN : len);
3354 local->essid[MAX_SSID_LEN] = '\0';
3355 i = GET_INT_PARM(iw_mode, card_idx);
3356 if ((i >= IW_MODE_ADHOC && i <= IW_MODE_REPEAT) ||
3357 i == IW_MODE_MONITOR) {
3358 local->iw_mode = i;
3359 } else {
3360 printk(KERN_WARNING "prism2: Unknown iw_mode %d; using "
3361 "IW_MODE_MASTER\n", i);
3362 local->iw_mode = IW_MODE_MASTER;
3363 }
3364 local->channel = GET_INT_PARM(channel, card_idx);
3365 local->beacon_int = GET_INT_PARM(beacon_int, card_idx);
3366 local->dtim_period = GET_INT_PARM(dtim_period, card_idx);
3367 local->wds_max_connections = 16;
3368 local->tx_control = HFA384X_TX_CTRL_FLAGS;
3369 local->manual_retry_count = -1;
3370 local->rts_threshold = 2347;
3371 local->fragm_threshold = 2346;
3372 local->rssi_to_dBm = 100; /* default; to be overriden by
3373 * cnfDbmAdjust, if available */
3374 local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY;
3375 local->sram_type = -1;
3376#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
3377 local->bus_master_threshold_rx = GET_INT_PARM(bus_master_threshold_rx,
3378 card_idx);
3379 local->bus_master_threshold_tx = GET_INT_PARM(bus_master_threshold_tx,
3380 card_idx);
3381#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
3382
3383 /* Initialize task queue structures */
3384 INIT_WORK(&local->reset_queue, handle_reset_queue, local);
3385 INIT_WORK(&local->set_multicast_list_queue,
3386 hostap_set_multicast_list_queue, local->dev);
3387
3388 INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local);
3389 INIT_LIST_HEAD(&local->set_tim_list);
3390 spin_lock_init(&local->set_tim_lock);
3391
3392 INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local);
3393
3394 /* Initialize tasklets for handling hardware IRQ related operations
3395 * outside hw IRQ handler */
3396#define HOSTAP_TASKLET_INIT(q, f, d) \
3397do { memset((q), 0, sizeof(*(q))); (q)->func = (f); (q)->data = (d); } \
3398while (0)
3399 HOSTAP_TASKLET_INIT(&local->bap_tasklet, hostap_bap_tasklet,
3400 (unsigned long) local);
3401
3402 HOSTAP_TASKLET_INIT(&local->info_tasklet, hostap_info_tasklet,
3403 (unsigned long) local);
3404 hostap_info_init(local);
3405
3406 HOSTAP_TASKLET_INIT(&local->rx_tasklet,
3407 hostap_rx_tasklet, (unsigned long) local);
3408 skb_queue_head_init(&local->rx_list);
3409
3410 HOSTAP_TASKLET_INIT(&local->sta_tx_exc_tasklet,
3411 hostap_sta_tx_exc_tasklet, (unsigned long) local);
3412 skb_queue_head_init(&local->sta_tx_exc_list);
3413
3414 INIT_LIST_HEAD(&local->cmd_queue);
3415 init_waitqueue_head(&local->hostscan_wq);
3416 INIT_LIST_HEAD(&local->crypt_deinit_list);
3417 init_timer(&local->crypt_deinit_timer);
3418 local->crypt_deinit_timer.data = (unsigned long) local;
3419 local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
3420
3421 init_timer(&local->passive_scan_timer);
3422 local->passive_scan_timer.data = (unsigned long) local;
3423 local->passive_scan_timer.function = hostap_passive_scan;
3424
3425 init_timer(&local->tick_timer);
3426 local->tick_timer.data = (unsigned long) local;
3427 local->tick_timer.function = hostap_tick_timer;
3428 local->tick_timer.expires = jiffies + 2 * HZ;
3429 add_timer(&local->tick_timer);
3430
3431 INIT_LIST_HEAD(&local->bss_list);
3432
3433 hostap_setup_dev(dev, local, 1);
3434 local->saved_eth_header_parse = dev->hard_header_parse;
3435
3436 dev->hard_start_xmit = hostap_master_start_xmit;
3437 dev->type = ARPHRD_IEEE80211;
3438 dev->hard_header_parse = hostap_80211_header_parse;
3439
3440 rtnl_lock();
3441 ret = dev_alloc_name(dev, "wifi%d");
3442 if (ret >= 0)
3443 ret = register_netdevice(dev);
3444 rtnl_unlock();
3445 if (ret < 0) {
3446 printk(KERN_WARNING "%s: register netdevice failed!\n",
3447 dev_info);
3448 goto fail;
3449 }
3450 printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name);
3451
3452#ifndef PRISM2_NO_PROCFS_DEBUG
3453 create_proc_read_entry("registers", 0, local->proc,
3454 prism2_registers_proc_read, local);
3455#endif /* PRISM2_NO_PROCFS_DEBUG */
3456
3457 hostap_init_data(local);
3458 return dev;
3459
3460 fail:
3461#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
3462 kfree(local->bus_m0_buf);
3463#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
3464 free_netdev(dev);
3465 return NULL;
3466}
3467
3468
3469static int hostap_hw_ready(struct net_device *dev)
3470{
3471 struct hostap_interface *iface;
3472 struct local_info *local;
3473
3474 iface = netdev_priv(dev);
3475 local = iface->local;
3476 local->ddev = hostap_add_interface(local, HOSTAP_INTERFACE_MAIN, 0,
3477 "", dev_template);
3478
3479 if (local->ddev) {
3480 if (local->iw_mode == IW_MODE_INFRA ||
3481 local->iw_mode == IW_MODE_ADHOC) {
3482 netif_carrier_off(local->dev);
3483 netif_carrier_off(local->ddev);
3484 }
3485 hostap_init_proc(local);
3486 hostap_init_ap_proc(local);
3487 return 0;
3488 }
3489
3490 return -1;
3491}
3492
3493
3494static void prism2_free_local_data(struct net_device *dev)
3495{
3496 struct hostap_tx_callback_info *tx_cb, *tx_cb_prev;
3497 int i;
3498 struct hostap_interface *iface;
3499 struct local_info *local;
3500 struct list_head *ptr, *n;
3501
3502 if (dev == NULL)
3503 return;
3504
3505 iface = netdev_priv(dev);
3506 local = iface->local;
3507
3508 flush_scheduled_work();
3509
3510 if (timer_pending(&local->crypt_deinit_timer))
3511 del_timer(&local->crypt_deinit_timer);
3512 prism2_crypt_deinit_entries(local, 1);
3513
3514 if (timer_pending(&local->passive_scan_timer))
3515 del_timer(&local->passive_scan_timer);
3516
3517 if (timer_pending(&local->tick_timer))
3518 del_timer(&local->tick_timer);
3519
3520 prism2_clear_cmd_queue(local);
3521
3522 skb_queue_purge(&local->info_list);
3523 skb_queue_purge(&local->rx_list);
3524 skb_queue_purge(&local->sta_tx_exc_list);
3525
3526 if (local->dev_enabled)
3527 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
3528
3529 for (i = 0; i < WEP_KEYS; i++) {
3530 struct prism2_crypt_data *crypt = local->crypt[i];
3531 if (crypt) {
3532 if (crypt->ops)
3533 crypt->ops->deinit(crypt->priv);
3534 kfree(crypt);
3535 local->crypt[i] = NULL;
3536 }
3537 }
3538
3539 if (local->ap != NULL)
3540 hostap_free_data(local->ap);
3541
3542#ifndef PRISM2_NO_PROCFS_DEBUG
3543 if (local->proc != NULL)
3544 remove_proc_entry("registers", local->proc);
3545#endif /* PRISM2_NO_PROCFS_DEBUG */
3546 hostap_remove_proc(local);
3547
3548 tx_cb = local->tx_callback;
3549 while (tx_cb != NULL) {
3550 tx_cb_prev = tx_cb;
3551 tx_cb = tx_cb->next;
3552 kfree(tx_cb_prev);
3553 }
3554
3555 hostap_set_hostapd(local, 0, 0);
3556 hostap_set_hostapd_sta(local, 0, 0);
3557
3558 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
3559 if (local->frag_cache[i].skb != NULL)
3560 dev_kfree_skb(local->frag_cache[i].skb);
3561 }
3562
3563#ifdef PRISM2_DOWNLOAD_SUPPORT
3564 prism2_download_free_data(local->dl_pri);
3565 prism2_download_free_data(local->dl_sec);
3566#endif /* PRISM2_DOWNLOAD_SUPPORT */
3567
3568 list_for_each_safe(ptr, n, &local->hostap_interfaces) {
3569 iface = list_entry(ptr, struct hostap_interface, list);
3570 if (iface->type == HOSTAP_INTERFACE_MASTER) {
3571 /* special handling for this interface below */
3572 continue;
3573 }
3574 hostap_remove_interface(iface->dev, 0, 1);
3575 }
3576
3577 prism2_clear_set_tim_queue(local);
3578
3579 list_for_each_safe(ptr, n, &local->bss_list) {
3580 struct hostap_bss_info *bss =
3581 list_entry(ptr, struct hostap_bss_info, list);
3582 kfree(bss);
3583 }
3584
3585#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
3586 kfree(local->bus_m0_buf);
3587#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
3588 kfree(local->pda);
3589 kfree(local->last_scan_results);
3590 kfree(local->generic_elem);
3591
3592 unregister_netdev(local->dev);
3593 free_netdev(local->dev);
3594}
3595
3596
3597#ifndef PRISM2_PLX
3598static void prism2_suspend(struct net_device *dev)
3599{
3600 struct hostap_interface *iface;
3601 struct local_info *local;
3602 union iwreq_data wrqu;
3603
3604 iface = dev->priv;
3605 local = iface->local;
3606
3607 /* Send disconnect event, e.g., to trigger reassociation after resume
3608 * if wpa_supplicant is used. */
3609 memset(&wrqu, 0, sizeof(wrqu));
3610 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3611 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
3612
3613 /* Disable hardware and firmware */
3614 prism2_hw_shutdown(dev, 0);
3615}
3616#endif /* PRISM2_PLX */
3617
3618
3619/* These might at some point be compiled separately and used as separate
3620 * kernel modules or linked into one */
3621#ifdef PRISM2_DOWNLOAD_SUPPORT
3622#include "hostap_download.c"
3623#endif /* PRISM2_DOWNLOAD_SUPPORT */
3624
3625#ifdef PRISM2_CALLBACK
3626/* External hostap_callback.c file can be used to, e.g., blink activity led.
3627 * This can use platform specific code and must define prism2_callback()
3628 * function (if PRISM2_CALLBACK is not defined, these function calls are not
3629 * used. */
3630#include "hostap_callback.c"
3631#endif /* PRISM2_CALLBACK */
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
new file mode 100644
index 000000000000..cf9e0898b57f
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -0,0 +1,478 @@
1/* Host AP driver Info Frame processing (part of hostap.o module) */
2
3
4/* Called only as a tasklet (software IRQ) */
5static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf,
6 int left)
7{
8 struct hfa384x_comm_tallies *tallies;
9
10 if (left < sizeof(struct hfa384x_comm_tallies)) {
11 printk(KERN_DEBUG "%s: too short (len=%d) commtallies "
12 "info frame\n", local->dev->name, left);
13 return;
14 }
15
16 tallies = (struct hfa384x_comm_tallies *) buf;
17#define ADD_COMM_TALLIES(name) \
18local->comm_tallies.name += le16_to_cpu(tallies->name)
19 ADD_COMM_TALLIES(tx_unicast_frames);
20 ADD_COMM_TALLIES(tx_multicast_frames);
21 ADD_COMM_TALLIES(tx_fragments);
22 ADD_COMM_TALLIES(tx_unicast_octets);
23 ADD_COMM_TALLIES(tx_multicast_octets);
24 ADD_COMM_TALLIES(tx_deferred_transmissions);
25 ADD_COMM_TALLIES(tx_single_retry_frames);
26 ADD_COMM_TALLIES(tx_multiple_retry_frames);
27 ADD_COMM_TALLIES(tx_retry_limit_exceeded);
28 ADD_COMM_TALLIES(tx_discards);
29 ADD_COMM_TALLIES(rx_unicast_frames);
30 ADD_COMM_TALLIES(rx_multicast_frames);
31 ADD_COMM_TALLIES(rx_fragments);
32 ADD_COMM_TALLIES(rx_unicast_octets);
33 ADD_COMM_TALLIES(rx_multicast_octets);
34 ADD_COMM_TALLIES(rx_fcs_errors);
35 ADD_COMM_TALLIES(rx_discards_no_buffer);
36 ADD_COMM_TALLIES(tx_discards_wrong_sa);
37 ADD_COMM_TALLIES(rx_discards_wep_undecryptable);
38 ADD_COMM_TALLIES(rx_message_in_msg_fragments);
39 ADD_COMM_TALLIES(rx_message_in_bad_msg_fragments);
40#undef ADD_COMM_TALLIES
41}
42
43
44/* Called only as a tasklet (software IRQ) */
45static void prism2_info_commtallies32(local_info_t *local, unsigned char *buf,
46 int left)
47{
48 struct hfa384x_comm_tallies32 *tallies;
49
50 if (left < sizeof(struct hfa384x_comm_tallies32)) {
51 printk(KERN_DEBUG "%s: too short (len=%d) commtallies32 "
52 "info frame\n", local->dev->name, left);
53 return;
54 }
55
56 tallies = (struct hfa384x_comm_tallies32 *) buf;
57#define ADD_COMM_TALLIES(name) \
58local->comm_tallies.name += le32_to_cpu(tallies->name)
59 ADD_COMM_TALLIES(tx_unicast_frames);
60 ADD_COMM_TALLIES(tx_multicast_frames);
61 ADD_COMM_TALLIES(tx_fragments);
62 ADD_COMM_TALLIES(tx_unicast_octets);
63 ADD_COMM_TALLIES(tx_multicast_octets);
64 ADD_COMM_TALLIES(tx_deferred_transmissions);
65 ADD_COMM_TALLIES(tx_single_retry_frames);
66 ADD_COMM_TALLIES(tx_multiple_retry_frames);
67 ADD_COMM_TALLIES(tx_retry_limit_exceeded);
68 ADD_COMM_TALLIES(tx_discards);
69 ADD_COMM_TALLIES(rx_unicast_frames);
70 ADD_COMM_TALLIES(rx_multicast_frames);
71 ADD_COMM_TALLIES(rx_fragments);
72 ADD_COMM_TALLIES(rx_unicast_octets);
73 ADD_COMM_TALLIES(rx_multicast_octets);
74 ADD_COMM_TALLIES(rx_fcs_errors);
75 ADD_COMM_TALLIES(rx_discards_no_buffer);
76 ADD_COMM_TALLIES(tx_discards_wrong_sa);
77 ADD_COMM_TALLIES(rx_discards_wep_undecryptable);
78 ADD_COMM_TALLIES(rx_message_in_msg_fragments);
79 ADD_COMM_TALLIES(rx_message_in_bad_msg_fragments);
80#undef ADD_COMM_TALLIES
81}
82
83
84/* Called only as a tasklet (software IRQ) */
85static void prism2_info_commtallies(local_info_t *local, unsigned char *buf,
86 int left)
87{
88 if (local->tallies32)
89 prism2_info_commtallies32(local, buf, left);
90 else
91 prism2_info_commtallies16(local, buf, left);
92}
93
94
95#ifndef PRISM2_NO_STATION_MODES
96#ifndef PRISM2_NO_DEBUG
97static const char* hfa384x_linkstatus_str(u16 linkstatus)
98{
99 switch (linkstatus) {
100 case HFA384X_LINKSTATUS_CONNECTED:
101 return "Connected";
102 case HFA384X_LINKSTATUS_DISCONNECTED:
103 return "Disconnected";
104 case HFA384X_LINKSTATUS_AP_CHANGE:
105 return "Access point change";
106 case HFA384X_LINKSTATUS_AP_OUT_OF_RANGE:
107 return "Access point out of range";
108 case HFA384X_LINKSTATUS_AP_IN_RANGE:
109 return "Access point in range";
110 case HFA384X_LINKSTATUS_ASSOC_FAILED:
111 return "Association failed";
112 default:
113 return "Unknown";
114 }
115}
116#endif /* PRISM2_NO_DEBUG */
117
118
119/* Called only as a tasklet (software IRQ) */
120static void prism2_info_linkstatus(local_info_t *local, unsigned char *buf,
121 int left)
122{
123 u16 val;
124 int non_sta_mode;
125
126 /* Alloc new JoinRequests to occur since LinkStatus for the previous
127 * has been received */
128 local->last_join_time = 0;
129
130 if (left != 2) {
131 printk(KERN_DEBUG "%s: invalid linkstatus info frame "
132 "length %d\n", local->dev->name, left);
133 return;
134 }
135
136 non_sta_mode = local->iw_mode == IW_MODE_MASTER ||
137 local->iw_mode == IW_MODE_REPEAT ||
138 local->iw_mode == IW_MODE_MONITOR;
139
140 val = buf[0] | (buf[1] << 8);
141 if (!non_sta_mode || val != HFA384X_LINKSTATUS_DISCONNECTED) {
142 PDEBUG(DEBUG_EXTRA, "%s: LinkStatus=%d (%s)\n",
143 local->dev->name, val, hfa384x_linkstatus_str(val));
144 }
145
146 if (non_sta_mode) {
147 netif_carrier_on(local->dev);
148 netif_carrier_on(local->ddev);
149 return;
150 }
151
152 /* Get current BSSID later in scheduled task */
153 set_bit(PRISM2_INFO_PENDING_LINKSTATUS, &local->pending_info);
154 local->prev_link_status = val;
155 schedule_work(&local->info_queue);
156}
157
158
159static void prism2_host_roaming(local_info_t *local)
160{
161 struct hfa384x_join_request req;
162 struct net_device *dev = local->dev;
163 struct hfa384x_scan_result *selected, *entry;
164 int i;
165 unsigned long flags;
166
167 if (local->last_join_time &&
168 time_before(jiffies, local->last_join_time + 10 * HZ)) {
169 PDEBUG(DEBUG_EXTRA, "%s: last join request has not yet been "
170 "completed - waiting for it before issuing new one\n",
171 dev->name);
172 return;
173 }
174
175 /* ScanResults are sorted: first ESS results in decreasing signal
176 * quality then IBSS results in similar order.
177 * Trivial roaming policy: just select the first entry.
178 * This could probably be improved by adding hysteresis to limit
179 * number of handoffs, etc.
180 *
181 * Could do periodic RID_SCANREQUEST or Inquire F101 to get new
182 * ScanResults */
183 spin_lock_irqsave(&local->lock, flags);
184 if (local->last_scan_results == NULL ||
185 local->last_scan_results_count == 0) {
186 spin_unlock_irqrestore(&local->lock, flags);
187 PDEBUG(DEBUG_EXTRA, "%s: no scan results for host roaming\n",
188 dev->name);
189 return;
190 }
191
192 selected = &local->last_scan_results[0];
193
194 if (local->preferred_ap[0] || local->preferred_ap[1] ||
195 local->preferred_ap[2] || local->preferred_ap[3] ||
196 local->preferred_ap[4] || local->preferred_ap[5]) {
197 /* Try to find preferred AP */
198 PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID " MACSTR "\n",
199 dev->name, MAC2STR(local->preferred_ap));
200 for (i = 0; i < local->last_scan_results_count; i++) {
201 entry = &local->last_scan_results[i];
202 if (memcmp(local->preferred_ap, entry->bssid, 6) == 0)
203 {
204 PDEBUG(DEBUG_EXTRA, "%s: using preferred AP "
205 "selection\n", dev->name);
206 selected = entry;
207 break;
208 }
209 }
210 }
211
212 memcpy(req.bssid, selected->bssid, 6);
213 req.channel = selected->chid;
214 spin_unlock_irqrestore(&local->lock, flags);
215
216 PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=" MACSTR " channel=%d\n",
217 dev->name, MAC2STR(req.bssid), le16_to_cpu(req.channel));
218 if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
219 sizeof(req))) {
220 printk(KERN_DEBUG "%s: JoinRequest failed\n", dev->name);
221 }
222 local->last_join_time = jiffies;
223}
224
225
226static void hostap_report_scan_complete(local_info_t *local)
227{
228 union iwreq_data wrqu;
229
230 /* Inform user space about new scan results (just empty event,
231 * SIOCGIWSCAN can be used to fetch data */
232 wrqu.data.length = 0;
233 wrqu.data.flags = 0;
234 wireless_send_event(local->dev, SIOCGIWSCAN, &wrqu, NULL);
235
236 /* Allow SIOCGIWSCAN handling to occur since we have received
237 * scanning result */
238 local->scan_timestamp = 0;
239}
240
241
242/* Called only as a tasklet (software IRQ) */
243static void prism2_info_scanresults(local_info_t *local, unsigned char *buf,
244 int left)
245{
246 u16 *pos;
247 int new_count;
248 unsigned long flags;
249 struct hfa384x_scan_result *results, *prev;
250
251 if (left < 4) {
252 printk(KERN_DEBUG "%s: invalid scanresult info frame "
253 "length %d\n", local->dev->name, left);
254 return;
255 }
256
257 pos = (u16 *) buf;
258 pos++;
259 pos++;
260 left -= 4;
261
262 new_count = left / sizeof(struct hfa384x_scan_result);
263 results = kmalloc(new_count * sizeof(struct hfa384x_scan_result),
264 GFP_ATOMIC);
265 if (results == NULL)
266 return;
267 memcpy(results, pos, new_count * sizeof(struct hfa384x_scan_result));
268
269 spin_lock_irqsave(&local->lock, flags);
270 local->last_scan_type = PRISM2_SCAN;
271 prev = local->last_scan_results;
272 local->last_scan_results = results;
273 local->last_scan_results_count = new_count;
274 spin_unlock_irqrestore(&local->lock, flags);
275 kfree(prev);
276
277 hostap_report_scan_complete(local);
278
279 /* Perform rest of ScanResults handling later in scheduled task */
280 set_bit(PRISM2_INFO_PENDING_SCANRESULTS, &local->pending_info);
281 schedule_work(&local->info_queue);
282}
283
284
285/* Called only as a tasklet (software IRQ) */
286static void prism2_info_hostscanresults(local_info_t *local,
287 unsigned char *buf, int left)
288{
289 int i, result_size, copy_len, new_count;
290 struct hfa384x_hostscan_result *results, *prev;
291 unsigned long flags;
292 u16 *pos;
293 u8 *ptr;
294
295 wake_up_interruptible(&local->hostscan_wq);
296
297 if (left < 4) {
298 printk(KERN_DEBUG "%s: invalid hostscanresult info frame "
299 "length %d\n", local->dev->name, left);
300 return;
301 }
302
303 pos = (u16 *) buf;
304 copy_len = result_size = le16_to_cpu(*pos);
305 if (result_size == 0) {
306 printk(KERN_DEBUG "%s: invalid result_size (0) in "
307 "hostscanresults\n", local->dev->name);
308 return;
309 }
310 if (copy_len > sizeof(struct hfa384x_hostscan_result))
311 copy_len = sizeof(struct hfa384x_hostscan_result);
312
313 pos++;
314 pos++;
315 left -= 4;
316 ptr = (u8 *) pos;
317
318 new_count = left / result_size;
319 results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
320 GFP_ATOMIC);
321 if (results == NULL)
322 return;
323 memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result));
324
325 for (i = 0; i < new_count; i++) {
326 memcpy(&results[i], ptr, copy_len);
327 ptr += result_size;
328 left -= result_size;
329 }
330
331 if (left) {
332 printk(KERN_DEBUG "%s: short HostScan result entry (%d/%d)\n",
333 local->dev->name, left, result_size);
334 }
335
336 spin_lock_irqsave(&local->lock, flags);
337 local->last_scan_type = PRISM2_HOSTSCAN;
338 prev = local->last_hostscan_results;
339 local->last_hostscan_results = results;
340 local->last_hostscan_results_count = new_count;
341 spin_unlock_irqrestore(&local->lock, flags);
342 kfree(prev);
343
344 hostap_report_scan_complete(local);
345}
346#endif /* PRISM2_NO_STATION_MODES */
347
348
349/* Called only as a tasklet (software IRQ) */
350void hostap_info_process(local_info_t *local, struct sk_buff *skb)
351{
352 struct hfa384x_info_frame *info;
353 unsigned char *buf;
354 int left;
355#ifndef PRISM2_NO_DEBUG
356 int i;
357#endif /* PRISM2_NO_DEBUG */
358
359 info = (struct hfa384x_info_frame *) skb->data;
360 buf = skb->data + sizeof(*info);
361 left = skb->len - sizeof(*info);
362
363 switch (info->type) {
364 case HFA384X_INFO_COMMTALLIES:
365 prism2_info_commtallies(local, buf, left);
366 break;
367
368#ifndef PRISM2_NO_STATION_MODES
369 case HFA384X_INFO_LINKSTATUS:
370 prism2_info_linkstatus(local, buf, left);
371 break;
372
373 case HFA384X_INFO_SCANRESULTS:
374 prism2_info_scanresults(local, buf, left);
375 break;
376
377 case HFA384X_INFO_HOSTSCANRESULTS:
378 prism2_info_hostscanresults(local, buf, left);
379 break;
380#endif /* PRISM2_NO_STATION_MODES */
381
382#ifndef PRISM2_NO_DEBUG
383 default:
384 PDEBUG(DEBUG_EXTRA, "%s: INFO - len=%d type=0x%04x\n",
385 local->dev->name, info->len, info->type);
386 PDEBUG(DEBUG_EXTRA, "Unknown info frame:");
387 for (i = 0; i < (left < 100 ? left : 100); i++)
388 PDEBUG2(DEBUG_EXTRA, " %02x", buf[i]);
389 PDEBUG2(DEBUG_EXTRA, "\n");
390 break;
391#endif /* PRISM2_NO_DEBUG */
392 }
393}
394
395
396#ifndef PRISM2_NO_STATION_MODES
397static void handle_info_queue_linkstatus(local_info_t *local)
398{
399 int val = local->prev_link_status;
400 int connected;
401 union iwreq_data wrqu;
402
403 connected =
404 val == HFA384X_LINKSTATUS_CONNECTED ||
405 val == HFA384X_LINKSTATUS_AP_CHANGE ||
406 val == HFA384X_LINKSTATUS_AP_IN_RANGE;
407
408 if (local->func->get_rid(local->dev, HFA384X_RID_CURRENTBSSID,
409 local->bssid, ETH_ALEN, 1) < 0) {
410 printk(KERN_DEBUG "%s: could not read CURRENTBSSID after "
411 "LinkStatus event\n", local->dev->name);
412 } else {
413 PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" MACSTR "\n",
414 local->dev->name,
415 MAC2STR((unsigned char *) local->bssid));
416 if (local->wds_type & HOSTAP_WDS_AP_CLIENT)
417 hostap_add_sta(local->ap, local->bssid);
418 }
419
420 /* Get BSSID if we have a valid AP address */
421 if (connected) {
422 netif_carrier_on(local->dev);
423 netif_carrier_on(local->ddev);
424 memcpy(wrqu.ap_addr.sa_data, local->bssid, ETH_ALEN);
425 } else {
426 netif_carrier_off(local->dev);
427 netif_carrier_off(local->ddev);
428 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
429 }
430 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
431
432 /*
433 * Filter out sequential disconnect events in order not to cause a
434 * flood of SIOCGIWAP events that have a race condition with EAPOL
435 * frames and can confuse wpa_supplicant about the current association
436 * status.
437 */
438 if (connected || local->prev_linkstatus_connected)
439 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
440 local->prev_linkstatus_connected = connected;
441}
442
443
444static void handle_info_queue_scanresults(local_info_t *local)
445{
446 if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA)
447 prism2_host_roaming(local);
448}
449
450
451/* Called only as scheduled task after receiving info frames (used to avoid
452 * pending too much time in HW IRQ handler). */
453static void handle_info_queue(void *data)
454{
455 local_info_t *local = (local_info_t *) data;
456
457 if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS,
458 &local->pending_info))
459 handle_info_queue_linkstatus(local);
460
461 if (test_and_clear_bit(PRISM2_INFO_PENDING_SCANRESULTS,
462 &local->pending_info))
463 handle_info_queue_scanresults(local);
464}
465#endif /* PRISM2_NO_STATION_MODES */
466
467
468void hostap_info_init(local_info_t *local)
469{
470 skb_queue_head_init(&local->info_list);
471#ifndef PRISM2_NO_STATION_MODES
472 INIT_WORK(&local->info_queue, handle_info_queue, local);
473#endif /* PRISM2_NO_STATION_MODES */
474}
475
476
477EXPORT_SYMBOL(hostap_info_init);
478EXPORT_SYMBOL(hostap_info_process);
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
new file mode 100644
index 000000000000..e545ac9c1b10
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -0,0 +1,4123 @@
1/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
2
3#ifdef in_atomic
4/* Get kernel_locked() for in_atomic() */
5#include <linux/smp_lock.h>
6#endif
7#include <linux/ethtool.h>
8
9
10static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
11{
12 struct hostap_interface *iface;
13 local_info_t *local;
14 struct iw_statistics *wstats;
15
16 iface = netdev_priv(dev);
17 local = iface->local;
18
19 /* Why are we doing that ? Jean II */
20 if (iface->type != HOSTAP_INTERFACE_MAIN)
21 return NULL;
22
23 wstats = &local->wstats;
24
25 wstats->status = 0;
26 wstats->discard.code =
27 local->comm_tallies.rx_discards_wep_undecryptable;
28 wstats->discard.misc =
29 local->comm_tallies.rx_fcs_errors +
30 local->comm_tallies.rx_discards_no_buffer +
31 local->comm_tallies.tx_discards_wrong_sa;
32
33 wstats->discard.retries =
34 local->comm_tallies.tx_retry_limit_exceeded;
35 wstats->discard.fragment =
36 local->comm_tallies.rx_message_in_bad_msg_fragments;
37
38 if (local->iw_mode != IW_MODE_MASTER &&
39 local->iw_mode != IW_MODE_REPEAT) {
40 int update = 1;
41#ifdef in_atomic
42 /* RID reading might sleep and it must not be called in
43 * interrupt context or while atomic. However, this
44 * function seems to be called while atomic (at least in Linux
45 * 2.5.59). Update signal quality values only if in suitable
46 * context. Otherwise, previous values read from tick timer
47 * will be used. */
48 if (in_atomic())
49 update = 0;
50#endif /* in_atomic */
51
52 if (update && prism2_update_comms_qual(dev) == 0)
53 wstats->qual.updated = 7;
54
55 wstats->qual.qual = local->comms_qual;
56 wstats->qual.level = local->avg_signal;
57 wstats->qual.noise = local->avg_noise;
58 } else {
59 wstats->qual.qual = 0;
60 wstats->qual.level = 0;
61 wstats->qual.noise = 0;
62 wstats->qual.updated = 0;
63 }
64
65 return wstats;
66}
67
68
69static int prism2_get_datarates(struct net_device *dev, u8 *rates)
70{
71 struct hostap_interface *iface;
72 local_info_t *local;
73 u8 buf[12];
74 int len;
75 u16 val;
76
77 iface = netdev_priv(dev);
78 local = iface->local;
79
80 len = local->func->get_rid(dev, HFA384X_RID_SUPPORTEDDATARATES, buf,
81 sizeof(buf), 0);
82 if (len < 2)
83 return 0;
84
85 val = le16_to_cpu(*(u16 *) buf); /* string length */
86
87 if (len - 2 < val || val > 10)
88 return 0;
89
90 memcpy(rates, buf + 2, val);
91 return val;
92}
93
94
95static int prism2_get_name(struct net_device *dev,
96 struct iw_request_info *info,
97 char *name, char *extra)
98{
99 u8 rates[10];
100 int len, i, over2 = 0;
101
102 len = prism2_get_datarates(dev, rates);
103
104 for (i = 0; i < len; i++) {
105 if (rates[i] == 0x0b || rates[i] == 0x16) {
106 over2 = 1;
107 break;
108 }
109 }
110
111 strcpy(name, over2 ? "IEEE 802.11b" : "IEEE 802.11-DS");
112
113 return 0;
114}
115
116
117static void prism2_crypt_delayed_deinit(local_info_t *local,
118 struct prism2_crypt_data **crypt)
119{
120 struct prism2_crypt_data *tmp;
121 unsigned long flags;
122
123 tmp = *crypt;
124 *crypt = NULL;
125
126 if (tmp == NULL)
127 return;
128
129 /* must not run ops->deinit() while there may be pending encrypt or
130 * decrypt operations. Use a list of delayed deinits to avoid needing
131 * locking. */
132
133 spin_lock_irqsave(&local->lock, flags);
134 list_add(&tmp->list, &local->crypt_deinit_list);
135 if (!timer_pending(&local->crypt_deinit_timer)) {
136 local->crypt_deinit_timer.expires = jiffies + HZ;
137 add_timer(&local->crypt_deinit_timer);
138 }
139 spin_unlock_irqrestore(&local->lock, flags);
140}
141
142
143static int prism2_ioctl_siwencode(struct net_device *dev,
144 struct iw_request_info *info,
145 struct iw_point *erq, char *keybuf)
146{
147 struct hostap_interface *iface;
148 local_info_t *local;
149 int i;
150 struct prism2_crypt_data **crypt;
151
152 iface = netdev_priv(dev);
153 local = iface->local;
154
155 i = erq->flags & IW_ENCODE_INDEX;
156 if (i < 1 || i > 4)
157 i = local->tx_keyidx;
158 else
159 i--;
160 if (i < 0 || i >= WEP_KEYS)
161 return -EINVAL;
162
163 crypt = &local->crypt[i];
164
165 if (erq->flags & IW_ENCODE_DISABLED) {
166 if (*crypt)
167 prism2_crypt_delayed_deinit(local, crypt);
168 goto done;
169 }
170
171 if (*crypt != NULL && (*crypt)->ops != NULL &&
172 strcmp((*crypt)->ops->name, "WEP") != 0) {
173 /* changing to use WEP; deinit previously used algorithm */
174 prism2_crypt_delayed_deinit(local, crypt);
175 }
176
177 if (*crypt == NULL) {
178 struct prism2_crypt_data *new_crypt;
179
180 /* take WEP into use */
181 new_crypt = (struct prism2_crypt_data *)
182 kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL);
183 if (new_crypt == NULL)
184 return -ENOMEM;
185 memset(new_crypt, 0, sizeof(struct prism2_crypt_data));
186 new_crypt->ops = hostap_get_crypto_ops("WEP");
187 if (!new_crypt->ops) {
188 request_module("hostap_crypt_wep");
189 new_crypt->ops = hostap_get_crypto_ops("WEP");
190 }
191 if (new_crypt->ops)
192 new_crypt->priv = new_crypt->ops->init(i);
193 if (!new_crypt->ops || !new_crypt->priv) {
194 kfree(new_crypt);
195 new_crypt = NULL;
196
197 printk(KERN_WARNING "%s: could not initialize WEP: "
198 "load module hostap_crypt_wep.o\n",
199 dev->name);
200 return -EOPNOTSUPP;
201 }
202 *crypt = new_crypt;
203 }
204
205 if (erq->length > 0) {
206 int len = erq->length <= 5 ? 5 : 13;
207 int first = 1, j;
208 if (len > erq->length)
209 memset(keybuf + erq->length, 0, len - erq->length);
210 (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
211 for (j = 0; j < WEP_KEYS; j++) {
212 if (j != i && local->crypt[j]) {
213 first = 0;
214 break;
215 }
216 }
217 if (first)
218 local->tx_keyidx = i;
219 } else {
220 /* No key data - just set the default TX key index */
221 local->tx_keyidx = i;
222 }
223
224 done:
225 local->open_wep = erq->flags & IW_ENCODE_OPEN;
226
227 if (hostap_set_encryption(local)) {
228 printk(KERN_DEBUG "%s: set_encryption failed\n", dev->name);
229 return -EINVAL;
230 }
231
232 /* Do not reset port0 if card is in Managed mode since resetting will
233 * generate new IEEE 802.11 authentication which may end up in looping
234 * with IEEE 802.1X. Prism2 documentation seem to require port reset
235 * after WEP configuration. However, keys are apparently changed at
236 * least in Managed mode. */
237 if (local->iw_mode != IW_MODE_INFRA && local->func->reset_port(dev)) {
238 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
239 return -EINVAL;
240 }
241
242 return 0;
243}
244
245
246static int prism2_ioctl_giwencode(struct net_device *dev,
247 struct iw_request_info *info,
248 struct iw_point *erq, char *key)
249{
250 struct hostap_interface *iface;
251 local_info_t *local;
252 int i, len;
253 u16 val;
254 struct prism2_crypt_data *crypt;
255
256 iface = netdev_priv(dev);
257 local = iface->local;
258
259 i = erq->flags & IW_ENCODE_INDEX;
260 if (i < 1 || i > 4)
261 i = local->tx_keyidx;
262 else
263 i--;
264 if (i < 0 || i >= WEP_KEYS)
265 return -EINVAL;
266
267 crypt = local->crypt[i];
268 erq->flags = i + 1;
269
270 if (crypt == NULL || crypt->ops == NULL) {
271 erq->length = 0;
272 erq->flags |= IW_ENCODE_DISABLED;
273 return 0;
274 }
275
276 if (strcmp(crypt->ops->name, "WEP") != 0) {
277 /* only WEP is supported with wireless extensions, so just
278 * report that encryption is used */
279 erq->length = 0;
280 erq->flags |= IW_ENCODE_ENABLED;
281 return 0;
282 }
283
284 /* Reads from HFA384X_RID_CNFDEFAULTKEY* return bogus values, so show
285 * the keys from driver buffer */
286 len = crypt->ops->get_key(key, WEP_KEY_LEN, NULL, crypt->priv);
287 erq->length = (len >= 0 ? len : 0);
288
289 if (local->func->get_rid(dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0)
290 {
291 printk("CNFWEPFLAGS reading failed\n");
292 return -EOPNOTSUPP;
293 }
294 le16_to_cpus(&val);
295 if (val & HFA384X_WEPFLAGS_PRIVACYINVOKED)
296 erq->flags |= IW_ENCODE_ENABLED;
297 else
298 erq->flags |= IW_ENCODE_DISABLED;
299 if (val & HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED)
300 erq->flags |= IW_ENCODE_RESTRICTED;
301 else
302 erq->flags |= IW_ENCODE_OPEN;
303
304 return 0;
305}
306
307
308static int hostap_set_rate(struct net_device *dev)
309{
310 struct hostap_interface *iface;
311 local_info_t *local;
312 int ret, basic_rates;
313
314 iface = netdev_priv(dev);
315 local = iface->local;
316
317 basic_rates = local->basic_rates & local->tx_rate_control;
318 if (!basic_rates || basic_rates != local->basic_rates) {
319 printk(KERN_INFO "%s: updating basic rate set automatically "
320 "to match with the new supported rate set\n",
321 dev->name);
322 if (!basic_rates)
323 basic_rates = local->tx_rate_control;
324
325 local->basic_rates = basic_rates;
326 if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
327 basic_rates))
328 printk(KERN_WARNING "%s: failed to set "
329 "cnfBasicRates\n", dev->name);
330 }
331
332 ret = (hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
333 local->tx_rate_control) ||
334 hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
335 local->tx_rate_control) ||
336 local->func->reset_port(dev));
337
338 if (ret) {
339 printk(KERN_WARNING "%s: TXRateControl/cnfSupportedRates "
340 "setting to 0x%x failed\n",
341 dev->name, local->tx_rate_control);
342 }
343
344 /* Update TX rate configuration for all STAs based on new operational
345 * rate set. */
346 hostap_update_rates(local);
347
348 return ret;
349}
350
351
352static int prism2_ioctl_siwrate(struct net_device *dev,
353 struct iw_request_info *info,
354 struct iw_param *rrq, char *extra)
355{
356 struct hostap_interface *iface;
357 local_info_t *local;
358
359 iface = netdev_priv(dev);
360 local = iface->local;
361
362 if (rrq->fixed) {
363 switch (rrq->value) {
364 case 11000000:
365 local->tx_rate_control = HFA384X_RATES_11MBPS;
366 break;
367 case 5500000:
368 local->tx_rate_control = HFA384X_RATES_5MBPS;
369 break;
370 case 2000000:
371 local->tx_rate_control = HFA384X_RATES_2MBPS;
372 break;
373 case 1000000:
374 local->tx_rate_control = HFA384X_RATES_1MBPS;
375 break;
376 default:
377 local->tx_rate_control = HFA384X_RATES_1MBPS |
378 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
379 HFA384X_RATES_11MBPS;
380 break;
381 }
382 } else {
383 switch (rrq->value) {
384 case 11000000:
385 local->tx_rate_control = HFA384X_RATES_1MBPS |
386 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
387 HFA384X_RATES_11MBPS;
388 break;
389 case 5500000:
390 local->tx_rate_control = HFA384X_RATES_1MBPS |
391 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS;
392 break;
393 case 2000000:
394 local->tx_rate_control = HFA384X_RATES_1MBPS |
395 HFA384X_RATES_2MBPS;
396 break;
397 case 1000000:
398 local->tx_rate_control = HFA384X_RATES_1MBPS;
399 break;
400 default:
401 local->tx_rate_control = HFA384X_RATES_1MBPS |
402 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
403 HFA384X_RATES_11MBPS;
404 break;
405 }
406 }
407
408 return hostap_set_rate(dev);
409}
410
411
412static int prism2_ioctl_giwrate(struct net_device *dev,
413 struct iw_request_info *info,
414 struct iw_param *rrq, char *extra)
415{
416 u16 val;
417 struct hostap_interface *iface;
418 local_info_t *local;
419 int ret = 0;
420
421 iface = netdev_priv(dev);
422 local = iface->local;
423
424 if (local->func->get_rid(dev, HFA384X_RID_TXRATECONTROL, &val, 2, 1) <
425 0)
426 return -EINVAL;
427
428 if ((val & 0x1) && (val > 1))
429 rrq->fixed = 0;
430 else
431 rrq->fixed = 1;
432
433 if (local->iw_mode == IW_MODE_MASTER && local->ap != NULL &&
434 !local->fw_tx_rate_control) {
435 /* HFA384X_RID_CURRENTTXRATE seems to always be 2 Mbps in
436 * Host AP mode, so use the recorded TX rate of the last sent
437 * frame */
438 rrq->value = local->ap->last_tx_rate > 0 ?
439 local->ap->last_tx_rate * 100000 : 11000000;
440 return 0;
441 }
442
443 if (local->func->get_rid(dev, HFA384X_RID_CURRENTTXRATE, &val, 2, 1) <
444 0)
445 return -EINVAL;
446
447 switch (val) {
448 case HFA384X_RATES_1MBPS:
449 rrq->value = 1000000;
450 break;
451 case HFA384X_RATES_2MBPS:
452 rrq->value = 2000000;
453 break;
454 case HFA384X_RATES_5MBPS:
455 rrq->value = 5500000;
456 break;
457 case HFA384X_RATES_11MBPS:
458 rrq->value = 11000000;
459 break;
460 default:
461 /* should not happen */
462 rrq->value = 11000000;
463 ret = -EINVAL;
464 break;
465 }
466
467 return ret;
468}
469
470
471static int prism2_ioctl_siwsens(struct net_device *dev,
472 struct iw_request_info *info,
473 struct iw_param *sens, char *extra)
474{
475 struct hostap_interface *iface;
476 local_info_t *local;
477
478 iface = netdev_priv(dev);
479 local = iface->local;
480
481 /* Set the desired AP density */
482 if (sens->value < 1 || sens->value > 3)
483 return -EINVAL;
484
485 if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) ||
486 local->func->reset_port(dev))
487 return -EINVAL;
488
489 return 0;
490}
491
492static int prism2_ioctl_giwsens(struct net_device *dev,
493 struct iw_request_info *info,
494 struct iw_param *sens, char *extra)
495{
496 struct hostap_interface *iface;
497 local_info_t *local;
498 u16 val;
499
500 iface = netdev_priv(dev);
501 local = iface->local;
502
503 /* Get the current AP density */
504 if (local->func->get_rid(dev, HFA384X_RID_CNFSYSTEMSCALE, &val, 2, 1) <
505 0)
506 return -EINVAL;
507
508 sens->value = __le16_to_cpu(val);
509 sens->fixed = 1;
510
511 return 0;
512}
513
514
515/* Deprecated in new wireless extension API */
516static int prism2_ioctl_giwaplist(struct net_device *dev,
517 struct iw_request_info *info,
518 struct iw_point *data, char *extra)
519{
520 struct hostap_interface *iface;
521 local_info_t *local;
522 struct sockaddr *addr;
523 struct iw_quality *qual;
524
525 iface = netdev_priv(dev);
526 local = iface->local;
527
528 if (local->iw_mode != IW_MODE_MASTER) {
529 printk(KERN_DEBUG "SIOCGIWAPLIST is currently only supported "
530 "in Host AP mode\n");
531 data->length = 0;
532 return -EOPNOTSUPP;
533 }
534
535 addr = kmalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
536 qual = kmalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
537 if (addr == NULL || qual == NULL) {
538 kfree(addr);
539 kfree(qual);
540 data->length = 0;
541 return -ENOMEM;
542 }
543
544 data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1);
545
546 memcpy(extra, &addr, sizeof(struct sockaddr) * data->length);
547 data->flags = 1; /* has quality information */
548 memcpy(extra + sizeof(struct sockaddr) * data->length, &qual,
549 sizeof(struct iw_quality) * data->length);
550
551 kfree(addr);
552 kfree(qual);
553
554 return 0;
555}
556
557
558static int prism2_ioctl_siwrts(struct net_device *dev,
559 struct iw_request_info *info,
560 struct iw_param *rts, char *extra)
561{
562 struct hostap_interface *iface;
563 local_info_t *local;
564 u16 val;
565
566 iface = netdev_priv(dev);
567 local = iface->local;
568
569 if (rts->disabled)
570 val = __constant_cpu_to_le16(2347);
571 else if (rts->value < 0 || rts->value > 2347)
572 return -EINVAL;
573 else
574 val = __cpu_to_le16(rts->value);
575
576 if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) ||
577 local->func->reset_port(dev))
578 return -EINVAL;
579
580 local->rts_threshold = rts->value;
581
582 return 0;
583}
584
585static int prism2_ioctl_giwrts(struct net_device *dev,
586 struct iw_request_info *info,
587 struct iw_param *rts, char *extra)
588{
589 struct hostap_interface *iface;
590 local_info_t *local;
591 u16 val;
592
593 iface = netdev_priv(dev);
594 local = iface->local;
595
596 if (local->func->get_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2, 1) <
597 0)
598 return -EINVAL;
599
600 rts->value = __le16_to_cpu(val);
601 rts->disabled = (rts->value == 2347);
602 rts->fixed = 1;
603
604 return 0;
605}
606
607
608static int prism2_ioctl_siwfrag(struct net_device *dev,
609 struct iw_request_info *info,
610 struct iw_param *rts, char *extra)
611{
612 struct hostap_interface *iface;
613 local_info_t *local;
614 u16 val;
615
616 iface = netdev_priv(dev);
617 local = iface->local;
618
619 if (rts->disabled)
620 val = __constant_cpu_to_le16(2346);
621 else if (rts->value < 256 || rts->value > 2346)
622 return -EINVAL;
623 else
624 val = __cpu_to_le16(rts->value & ~0x1); /* even numbers only */
625
626 local->fragm_threshold = rts->value & ~0x1;
627 if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val,
628 2)
629 || local->func->reset_port(dev))
630 return -EINVAL;
631
632 return 0;
633}
634
635static int prism2_ioctl_giwfrag(struct net_device *dev,
636 struct iw_request_info *info,
637 struct iw_param *rts, char *extra)
638{
639 struct hostap_interface *iface;
640 local_info_t *local;
641 u16 val;
642
643 iface = netdev_priv(dev);
644 local = iface->local;
645
646 if (local->func->get_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
647 &val, 2, 1) < 0)
648 return -EINVAL;
649
650 rts->value = __le16_to_cpu(val);
651 rts->disabled = (rts->value == 2346);
652 rts->fixed = 1;
653
654 return 0;
655}
656
657
658#ifndef PRISM2_NO_STATION_MODES
659static int hostap_join_ap(struct net_device *dev)
660{
661 struct hostap_interface *iface;
662 local_info_t *local;
663 struct hfa384x_join_request req;
664 unsigned long flags;
665 int i;
666 struct hfa384x_scan_result *entry;
667
668 iface = netdev_priv(dev);
669 local = iface->local;
670
671 memcpy(req.bssid, local->preferred_ap, ETH_ALEN);
672 req.channel = 0;
673
674 spin_lock_irqsave(&local->lock, flags);
675 for (i = 0; i < local->last_scan_results_count; i++) {
676 if (!local->last_scan_results)
677 break;
678 entry = &local->last_scan_results[i];
679 if (memcmp(local->preferred_ap, entry->bssid, ETH_ALEN) == 0) {
680 req.channel = entry->chid;
681 break;
682 }
683 }
684 spin_unlock_irqrestore(&local->lock, flags);
685
686 if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
687 sizeof(req))) {
688 printk(KERN_DEBUG "%s: JoinRequest " MACSTR
689 " failed\n",
690 dev->name, MAC2STR(local->preferred_ap));
691 return -1;
692 }
693
694 printk(KERN_DEBUG "%s: Trying to join BSSID " MACSTR "\n",
695 dev->name, MAC2STR(local->preferred_ap));
696
697 return 0;
698}
699#endif /* PRISM2_NO_STATION_MODES */
700
701
702static int prism2_ioctl_siwap(struct net_device *dev,
703 struct iw_request_info *info,
704 struct sockaddr *ap_addr, char *extra)
705{
706#ifdef PRISM2_NO_STATION_MODES
707 return -EOPNOTSUPP;
708#else /* PRISM2_NO_STATION_MODES */
709 struct hostap_interface *iface;
710 local_info_t *local;
711
712 iface = netdev_priv(dev);
713 local = iface->local;
714
715 memcpy(local->preferred_ap, &ap_addr->sa_data, ETH_ALEN);
716
717 if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) {
718 struct hfa384x_scan_request scan_req;
719 memset(&scan_req, 0, sizeof(scan_req));
720 scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
721 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
722 if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST,
723 &scan_req, sizeof(scan_req))) {
724 printk(KERN_DEBUG "%s: ScanResults request failed - "
725 "preferred AP delayed to next unsolicited "
726 "scan\n", dev->name);
727 }
728 } else if (local->host_roaming == 2 &&
729 local->iw_mode == IW_MODE_INFRA) {
730 if (hostap_join_ap(dev))
731 return -EINVAL;
732 } else {
733 printk(KERN_DEBUG "%s: Preferred AP (SIOCSIWAP) is used only "
734 "in Managed mode when host_roaming is enabled\n",
735 dev->name);
736 }
737
738 return 0;
739#endif /* PRISM2_NO_STATION_MODES */
740}
741
742static int prism2_ioctl_giwap(struct net_device *dev,
743 struct iw_request_info *info,
744 struct sockaddr *ap_addr, char *extra)
745{
746 struct hostap_interface *iface;
747 local_info_t *local;
748
749 iface = netdev_priv(dev);
750 local = iface->local;
751
752 ap_addr->sa_family = ARPHRD_ETHER;
753 switch (iface->type) {
754 case HOSTAP_INTERFACE_AP:
755 memcpy(&ap_addr->sa_data, dev->dev_addr, ETH_ALEN);
756 break;
757 case HOSTAP_INTERFACE_STA:
758 memcpy(&ap_addr->sa_data, local->assoc_ap_addr, ETH_ALEN);
759 break;
760 case HOSTAP_INTERFACE_WDS:
761 memcpy(&ap_addr->sa_data, iface->u.wds.remote_addr, ETH_ALEN);
762 break;
763 default:
764 if (local->func->get_rid(dev, HFA384X_RID_CURRENTBSSID,
765 &ap_addr->sa_data, ETH_ALEN, 1) < 0)
766 return -EOPNOTSUPP;
767
768 /* local->bssid is also updated in LinkStatus handler when in
769 * station mode */
770 memcpy(local->bssid, &ap_addr->sa_data, ETH_ALEN);
771 break;
772 }
773
774 return 0;
775}
776
777
778static int prism2_ioctl_siwnickn(struct net_device *dev,
779 struct iw_request_info *info,
780 struct iw_point *data, char *nickname)
781{
782 struct hostap_interface *iface;
783 local_info_t *local;
784
785 iface = netdev_priv(dev);
786 local = iface->local;
787
788 memset(local->name, 0, sizeof(local->name));
789 memcpy(local->name, nickname, data->length);
790 local->name_set = 1;
791
792 if (hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name) ||
793 local->func->reset_port(dev))
794 return -EINVAL;
795
796 return 0;
797}
798
799static int prism2_ioctl_giwnickn(struct net_device *dev,
800 struct iw_request_info *info,
801 struct iw_point *data, char *nickname)
802{
803 struct hostap_interface *iface;
804 local_info_t *local;
805 int len;
806 char name[MAX_NAME_LEN + 3];
807 u16 val;
808
809 iface = netdev_priv(dev);
810 local = iface->local;
811
812 len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME,
813 &name, MAX_NAME_LEN + 2, 0);
814 val = __le16_to_cpu(*(u16 *) name);
815 if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN)
816 return -EOPNOTSUPP;
817
818 name[val + 2] = '\0';
819 data->length = val + 1;
820 memcpy(nickname, name + 2, val + 1);
821
822 return 0;
823}
824
825
826static int prism2_ioctl_siwfreq(struct net_device *dev,
827 struct iw_request_info *info,
828 struct iw_freq *freq, char *extra)
829{
830 struct hostap_interface *iface;
831 local_info_t *local;
832
833 iface = netdev_priv(dev);
834 local = iface->local;
835
836 /* freq => chan. */
837 if (freq->e == 1 &&
838 freq->m / 100000 >= freq_list[0] &&
839 freq->m / 100000 <= freq_list[FREQ_COUNT - 1]) {
840 int ch;
841 int fr = freq->m / 100000;
842 for (ch = 0; ch < FREQ_COUNT; ch++) {
843 if (fr == freq_list[ch]) {
844 freq->e = 0;
845 freq->m = ch + 1;
846 break;
847 }
848 }
849 }
850
851 if (freq->e != 0 || freq->m < 1 || freq->m > FREQ_COUNT ||
852 !(local->channel_mask & (1 << (freq->m - 1))))
853 return -EINVAL;
854
855 local->channel = freq->m; /* channel is used in prism2_setup_rids() */
856 if (hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel) ||
857 local->func->reset_port(dev))
858 return -EINVAL;
859
860 return 0;
861}
862
863static int prism2_ioctl_giwfreq(struct net_device *dev,
864 struct iw_request_info *info,
865 struct iw_freq *freq, char *extra)
866{
867 struct hostap_interface *iface;
868 local_info_t *local;
869 u16 val;
870
871 iface = netdev_priv(dev);
872 local = iface->local;
873
874 if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) <
875 0)
876 return -EINVAL;
877
878 le16_to_cpus(&val);
879 if (val < 1 || val > FREQ_COUNT)
880 return -EINVAL;
881
882 freq->m = freq_list[val - 1] * 100000;
883 freq->e = 1;
884
885 return 0;
886}
887
888
889static void hostap_monitor_set_type(local_info_t *local)
890{
891 struct net_device *dev = local->ddev;
892
893 if (dev == NULL)
894 return;
895
896 if (local->monitor_type == PRISM2_MONITOR_PRISM ||
897 local->monitor_type == PRISM2_MONITOR_CAPHDR) {
898 dev->type = ARPHRD_IEEE80211_PRISM;
899 dev->hard_header_parse =
900 hostap_80211_prism_header_parse;
901 } else {
902 dev->type = ARPHRD_IEEE80211;
903 dev->hard_header_parse = hostap_80211_header_parse;
904 }
905}
906
907
908static int prism2_ioctl_siwessid(struct net_device *dev,
909 struct iw_request_info *info,
910 struct iw_point *data, char *ssid)
911{
912 struct hostap_interface *iface;
913 local_info_t *local;
914
915 iface = netdev_priv(dev);
916 local = iface->local;
917
918 if (iface->type == HOSTAP_INTERFACE_WDS)
919 return -EOPNOTSUPP;
920
921 if (data->flags == 0)
922 ssid[0] = '\0'; /* ANY */
923
924 if (local->iw_mode == IW_MODE_MASTER && ssid[0] == '\0') {
925 /* Setting SSID to empty string seems to kill the card in
926 * Host AP mode */
927 printk(KERN_DEBUG "%s: Host AP mode does not support "
928 "'Any' essid\n", dev->name);
929 return -EINVAL;
930 }
931
932 memcpy(local->essid, ssid, data->length);
933 local->essid[data->length] = '\0';
934
935 if ((!local->fw_ap &&
936 hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid))
937 || hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid) ||
938 local->func->reset_port(dev))
939 return -EINVAL;
940
941 return 0;
942}
943
944static int prism2_ioctl_giwessid(struct net_device *dev,
945 struct iw_request_info *info,
946 struct iw_point *data, char *essid)
947{
948 struct hostap_interface *iface;
949 local_info_t *local;
950 u16 val;
951
952 iface = netdev_priv(dev);
953 local = iface->local;
954
955 if (iface->type == HOSTAP_INTERFACE_WDS)
956 return -EOPNOTSUPP;
957
958 data->flags = 1; /* active */
959 if (local->iw_mode == IW_MODE_MASTER) {
960 data->length = strlen(local->essid);
961 memcpy(essid, local->essid, IW_ESSID_MAX_SIZE);
962 } else {
963 int len;
964 char ssid[MAX_SSID_LEN + 2];
965 memset(ssid, 0, sizeof(ssid));
966 len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID,
967 &ssid, MAX_SSID_LEN + 2, 0);
968 val = __le16_to_cpu(*(u16 *) ssid);
969 if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) {
970 return -EOPNOTSUPP;
971 }
972 data->length = val;
973 memcpy(essid, ssid + 2, IW_ESSID_MAX_SIZE);
974 }
975
976 return 0;
977}
978
979
980static int prism2_ioctl_giwrange(struct net_device *dev,
981 struct iw_request_info *info,
982 struct iw_point *data, char *extra)
983{
984 struct hostap_interface *iface;
985 local_info_t *local;
986 struct iw_range *range = (struct iw_range *) extra;
987 u8 rates[10];
988 u16 val;
989 int i, len, over2;
990
991 iface = netdev_priv(dev);
992 local = iface->local;
993
994 data->length = sizeof(struct iw_range);
995 memset(range, 0, sizeof(struct iw_range));
996
997 /* TODO: could fill num_txpower and txpower array with
998 * something; however, there are 128 different values.. */
999
1000 range->txpower_capa = IW_TXPOW_DBM;
1001
1002 if (local->iw_mode == IW_MODE_INFRA || local->iw_mode == IW_MODE_ADHOC)
1003 {
1004 range->min_pmp = 1 * 1024;
1005 range->max_pmp = 65535 * 1024;
1006 range->min_pmt = 1 * 1024;
1007 range->max_pmt = 1000 * 1024;
1008 range->pmp_flags = IW_POWER_PERIOD;
1009 range->pmt_flags = IW_POWER_TIMEOUT;
1010 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
1011 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
1012 }
1013
1014 range->we_version_compiled = WIRELESS_EXT;
1015 range->we_version_source = 18;
1016
1017 range->retry_capa = IW_RETRY_LIMIT;
1018 range->retry_flags = IW_RETRY_LIMIT;
1019 range->min_retry = 0;
1020 range->max_retry = 255;
1021
1022 range->num_channels = FREQ_COUNT;
1023
1024 val = 0;
1025 for (i = 0; i < FREQ_COUNT; i++) {
1026 if (local->channel_mask & (1 << i)) {
1027 range->freq[val].i = i + 1;
1028 range->freq[val].m = freq_list[i] * 100000;
1029 range->freq[val].e = 1;
1030 val++;
1031 }
1032 if (val == IW_MAX_FREQUENCIES)
1033 break;
1034 }
1035 range->num_frequency = val;
1036
1037 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1038 range->max_qual.qual = 70; /* what is correct max? This was not
1039 * documented exactly. At least
1040 * 69 has been observed. */
1041 range->max_qual.level = 0; /* dB */
1042 range->max_qual.noise = 0; /* dB */
1043
1044 /* What would be suitable values for "average/typical" qual? */
1045 range->avg_qual.qual = 20;
1046 range->avg_qual.level = -60;
1047 range->avg_qual.noise = -95;
1048 } else {
1049 range->max_qual.qual = 92; /* 0 .. 92 */
1050 range->max_qual.level = 154; /* 27 .. 154 */
1051 range->max_qual.noise = 154; /* 27 .. 154 */
1052 }
1053 range->sensitivity = 3;
1054
1055 range->max_encoding_tokens = WEP_KEYS;
1056 range->num_encoding_sizes = 2;
1057 range->encoding_size[0] = 5;
1058 range->encoding_size[1] = 13;
1059
1060 over2 = 0;
1061 len = prism2_get_datarates(dev, rates);
1062 range->num_bitrates = 0;
1063 for (i = 0; i < len; i++) {
1064 if (range->num_bitrates < IW_MAX_BITRATES) {
1065 range->bitrate[range->num_bitrates] =
1066 rates[i] * 500000;
1067 range->num_bitrates++;
1068 }
1069 if (rates[i] == 0x0b || rates[i] == 0x16)
1070 over2 = 1;
1071 }
1072 /* estimated maximum TCP throughput values (bps) */
1073 range->throughput = over2 ? 5500000 : 1500000;
1074
1075 range->min_rts = 0;
1076 range->max_rts = 2347;
1077 range->min_frag = 256;
1078 range->max_frag = 2346;
1079
1080 /* Event capability (kernel + driver) */
1081 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
1082 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
1083 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
1084 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
1085 range->event_capa[1] = IW_EVENT_CAPA_K_1;
1086 range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
1087 IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
1088 IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
1089 IW_EVENT_CAPA_MASK(IWEVEXPIRED));
1090
1091 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1092 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1093
1094 return 0;
1095}
1096
1097
1098static int hostap_monitor_mode_enable(local_info_t *local)
1099{
1100 struct net_device *dev = local->dev;
1101
1102 printk(KERN_DEBUG "Enabling monitor mode\n");
1103 hostap_monitor_set_type(local);
1104
1105 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1106 HFA384X_PORTTYPE_PSEUDO_IBSS)) {
1107 printk(KERN_DEBUG "Port type setting for monitor mode "
1108 "failed\n");
1109 return -EOPNOTSUPP;
1110 }
1111
1112 /* Host decrypt is needed to get the IV and ICV fields;
1113 * however, monitor mode seems to remove WEP flag from frame
1114 * control field */
1115 if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
1116 HFA384X_WEPFLAGS_HOSTENCRYPT |
1117 HFA384X_WEPFLAGS_HOSTDECRYPT)) {
1118 printk(KERN_DEBUG "WEP flags setting failed\n");
1119 return -EOPNOTSUPP;
1120 }
1121
1122 if (local->func->reset_port(dev) ||
1123 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1124 (HFA384X_TEST_MONITOR << 8),
1125 0, NULL, NULL)) {
1126 printk(KERN_DEBUG "Setting monitor mode failed\n");
1127 return -EOPNOTSUPP;
1128 }
1129
1130 return 0;
1131}
1132
1133
1134static int hostap_monitor_mode_disable(local_info_t *local)
1135{
1136 struct net_device *dev = local->ddev;
1137
1138 if (dev == NULL)
1139 return -1;
1140
1141 printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);
1142 dev->type = ARPHRD_ETHER;
1143 dev->hard_header_parse = local->saved_eth_header_parse;
1144 if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1145 (HFA384X_TEST_STOP << 8),
1146 0, NULL, NULL))
1147 return -1;
1148 return hostap_set_encryption(local);
1149}
1150
1151
1152static int prism2_ioctl_siwmode(struct net_device *dev,
1153 struct iw_request_info *info,
1154 __u32 *mode, char *extra)
1155{
1156 struct hostap_interface *iface;
1157 local_info_t *local;
1158 int double_reset = 0;
1159
1160 iface = netdev_priv(dev);
1161 local = iface->local;
1162
1163 if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
1164 *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&
1165 *mode != IW_MODE_MONITOR)
1166 return -EOPNOTSUPP;
1167
1168#ifdef PRISM2_NO_STATION_MODES
1169 if (*mode == IW_MODE_ADHOC || *mode == IW_MODE_INFRA)
1170 return -EOPNOTSUPP;
1171#endif /* PRISM2_NO_STATION_MODES */
1172
1173 if (*mode == local->iw_mode)
1174 return 0;
1175
1176 if (*mode == IW_MODE_MASTER && local->essid[0] == '\0') {
1177 printk(KERN_WARNING "%s: empty SSID not allowed in Master "
1178 "mode\n", dev->name);
1179 return -EINVAL;
1180 }
1181
1182 if (local->iw_mode == IW_MODE_MONITOR)
1183 hostap_monitor_mode_disable(local);
1184
1185 if (local->iw_mode == IW_MODE_ADHOC && *mode == IW_MODE_MASTER) {
1186 /* There seems to be a firmware bug in at least STA f/w v1.5.6
1187 * that leaves beacon frames to use IBSS type when moving from
1188 * IBSS to Host AP mode. Doing double Port0 reset seems to be
1189 * enough to workaround this. */
1190 double_reset = 1;
1191 }
1192
1193 printk(KERN_DEBUG "prism2: %s: operating mode changed "
1194 "%d -> %d\n", dev->name, local->iw_mode, *mode);
1195 local->iw_mode = *mode;
1196
1197 if (local->iw_mode == IW_MODE_MONITOR)
1198 hostap_monitor_mode_enable(local);
1199 else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
1200 !local->fw_encrypt_ok) {
1201 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
1202 "a workaround for firmware bug in Host AP mode WEP\n",
1203 dev->name);
1204 local->host_encrypt = 1;
1205 }
1206
1207 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1208 hostap_get_porttype(local)))
1209 return -EOPNOTSUPP;
1210
1211 if (local->func->reset_port(dev))
1212 return -EINVAL;
1213 if (double_reset && local->func->reset_port(dev))
1214 return -EINVAL;
1215
1216 if (local->iw_mode != IW_MODE_INFRA && local->iw_mode != IW_MODE_ADHOC)
1217 {
1218 /* netif_carrier is used only in client modes for now, so make
1219 * sure carrier is on when moving to non-client modes. */
1220 netif_carrier_on(local->dev);
1221 netif_carrier_on(local->ddev);
1222 }
1223 return 0;
1224}
1225
1226
1227static int prism2_ioctl_giwmode(struct net_device *dev,
1228 struct iw_request_info *info,
1229 __u32 *mode, char *extra)
1230{
1231 struct hostap_interface *iface;
1232 local_info_t *local;
1233
1234 iface = netdev_priv(dev);
1235 local = iface->local;
1236
1237 switch (iface->type) {
1238 case HOSTAP_INTERFACE_STA:
1239 *mode = IW_MODE_INFRA;
1240 break;
1241 case HOSTAP_INTERFACE_WDS:
1242 *mode = IW_MODE_REPEAT;
1243 break;
1244 default:
1245 *mode = local->iw_mode;
1246 break;
1247 }
1248 return 0;
1249}
1250
1251
1252static int prism2_ioctl_siwpower(struct net_device *dev,
1253 struct iw_request_info *info,
1254 struct iw_param *wrq, char *extra)
1255{
1256#ifdef PRISM2_NO_STATION_MODES
1257 return -EOPNOTSUPP;
1258#else /* PRISM2_NO_STATION_MODES */
1259 int ret = 0;
1260
1261 if (wrq->disabled)
1262 return hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 0);
1263
1264 switch (wrq->flags & IW_POWER_MODE) {
1265 case IW_POWER_UNICAST_R:
1266 ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 0);
1267 if (ret)
1268 return ret;
1269 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1270 if (ret)
1271 return ret;
1272 break;
1273 case IW_POWER_ALL_R:
1274 ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 1);
1275 if (ret)
1276 return ret;
1277 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1278 if (ret)
1279 return ret;
1280 break;
1281 case IW_POWER_ON:
1282 break;
1283 default:
1284 return -EINVAL;
1285 }
1286
1287 if (wrq->flags & IW_POWER_TIMEOUT) {
1288 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1289 if (ret)
1290 return ret;
1291 ret = hostap_set_word(dev, HFA384X_RID_CNFPMHOLDOVERDURATION,
1292 wrq->value / 1024);
1293 if (ret)
1294 return ret;
1295 }
1296 if (wrq->flags & IW_POWER_PERIOD) {
1297 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1298 if (ret)
1299 return ret;
1300 ret = hostap_set_word(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1301 wrq->value / 1024);
1302 if (ret)
1303 return ret;
1304 }
1305
1306 return ret;
1307#endif /* PRISM2_NO_STATION_MODES */
1308}
1309
1310
1311static int prism2_ioctl_giwpower(struct net_device *dev,
1312 struct iw_request_info *info,
1313 struct iw_param *rrq, char *extra)
1314{
1315#ifdef PRISM2_NO_STATION_MODES
1316 return -EOPNOTSUPP;
1317#else /* PRISM2_NO_STATION_MODES */
1318 struct hostap_interface *iface;
1319 local_info_t *local;
1320 u16 enable, mcast;
1321
1322 iface = netdev_priv(dev);
1323 local = iface->local;
1324
1325 if (local->func->get_rid(dev, HFA384X_RID_CNFPMENABLED, &enable, 2, 1)
1326 < 0)
1327 return -EINVAL;
1328
1329 if (!__le16_to_cpu(enable)) {
1330 rrq->disabled = 1;
1331 return 0;
1332 }
1333
1334 rrq->disabled = 0;
1335
1336 if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1337 u16 timeout;
1338 if (local->func->get_rid(dev,
1339 HFA384X_RID_CNFPMHOLDOVERDURATION,
1340 &timeout, 2, 1) < 0)
1341 return -EINVAL;
1342
1343 rrq->flags = IW_POWER_TIMEOUT;
1344 rrq->value = __le16_to_cpu(timeout) * 1024;
1345 } else {
1346 u16 period;
1347 if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1348 &period, 2, 1) < 0)
1349 return -EINVAL;
1350
1351 rrq->flags = IW_POWER_PERIOD;
1352 rrq->value = __le16_to_cpu(period) * 1024;
1353 }
1354
1355 if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast,
1356 2, 1) < 0)
1357 return -EINVAL;
1358
1359 if (__le16_to_cpu(mcast))
1360 rrq->flags |= IW_POWER_ALL_R;
1361 else
1362 rrq->flags |= IW_POWER_UNICAST_R;
1363
1364 return 0;
1365#endif /* PRISM2_NO_STATION_MODES */
1366}
1367
1368
1369static int prism2_ioctl_siwretry(struct net_device *dev,
1370 struct iw_request_info *info,
1371 struct iw_param *rrq, char *extra)
1372{
1373 struct hostap_interface *iface;
1374 local_info_t *local;
1375
1376 iface = netdev_priv(dev);
1377 local = iface->local;
1378
1379 if (rrq->disabled)
1380 return -EINVAL;
1381
1382 /* setting retry limits is not supported with the current station
1383 * firmware code; simulate this with alternative retry count for now */
1384 if (rrq->flags == IW_RETRY_LIMIT) {
1385 if (rrq->value < 0) {
1386 /* disable manual retry count setting and use firmware
1387 * defaults */
1388 local->manual_retry_count = -1;
1389 local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY;
1390 } else {
1391 if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1392 rrq->value)) {
1393 printk(KERN_DEBUG "%s: Alternate retry count "
1394 "setting to %d failed\n",
1395 dev->name, rrq->value);
1396 return -EOPNOTSUPP;
1397 }
1398
1399 local->manual_retry_count = rrq->value;
1400 local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;
1401 }
1402 return 0;
1403 }
1404
1405 return -EOPNOTSUPP;
1406
1407#if 0
1408 /* what could be done, if firmware would support this.. */
1409
1410 if (rrq->flags & IW_RETRY_LIMIT) {
1411 if (rrq->flags & IW_RETRY_MAX)
1412 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1413 else if (rrq->flags & IW_RETRY_MIN)
1414 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1415 else {
1416 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1417 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1418 }
1419
1420 }
1421
1422 if (rrq->flags & IW_RETRY_LIFETIME) {
1423 HFA384X_RID_MAXTRANSMITLIFETIME = rrq->value / 1024;
1424 }
1425
1426 return 0;
1427#endif /* 0 */
1428}
1429
1430static int prism2_ioctl_giwretry(struct net_device *dev,
1431 struct iw_request_info *info,
1432 struct iw_param *rrq, char *extra)
1433{
1434 struct hostap_interface *iface;
1435 local_info_t *local;
1436 u16 shortretry, longretry, lifetime, altretry;
1437
1438 iface = netdev_priv(dev);
1439 local = iface->local;
1440
1441 if (local->func->get_rid(dev, HFA384X_RID_SHORTRETRYLIMIT, &shortretry,
1442 2, 1) < 0 ||
1443 local->func->get_rid(dev, HFA384X_RID_LONGRETRYLIMIT, &longretry,
1444 2, 1) < 0 ||
1445 local->func->get_rid(dev, HFA384X_RID_MAXTRANSMITLIFETIME,
1446 &lifetime, 2, 1) < 0)
1447 return -EINVAL;
1448
1449 le16_to_cpus(&shortretry);
1450 le16_to_cpus(&longretry);
1451 le16_to_cpus(&lifetime);
1452
1453 rrq->disabled = 0;
1454
1455 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1456 rrq->flags = IW_RETRY_LIFETIME;
1457 rrq->value = lifetime * 1024;
1458 } else {
1459 if (local->manual_retry_count >= 0) {
1460 rrq->flags = IW_RETRY_LIMIT;
1461 if (local->func->get_rid(dev,
1462 HFA384X_RID_CNFALTRETRYCOUNT,
1463 &altretry, 2, 1) >= 0)
1464 rrq->value = le16_to_cpu(altretry);
1465 else
1466 rrq->value = local->manual_retry_count;
1467 } else if ((rrq->flags & IW_RETRY_MAX)) {
1468 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1469 rrq->value = longretry;
1470 } else {
1471 rrq->flags = IW_RETRY_LIMIT;
1472 rrq->value = shortretry;
1473 if (shortretry != longretry)
1474 rrq->flags |= IW_RETRY_MIN;
1475 }
1476 }
1477 return 0;
1478}
1479
1480
1481/* Note! This TX power controlling is experimental and should not be used in
1482 * production use. It just sets raw power register and does not use any kind of
1483 * feedback information from the measured TX power (CR58). This is now
1484 * commented out to make sure that it is not used by accident. TX power
1485 * configuration will be enabled again after proper algorithm using feedback
1486 * has been implemented. */
1487
1488#ifdef RAW_TXPOWER_SETTING
1489/* Map HFA386x's CR31 to and from dBm with some sort of ad hoc mapping..
1490 * This version assumes following mapping:
1491 * CR31 is 7-bit value with -64 to +63 range.
1492 * -64 is mapped into +20dBm and +63 into -43dBm.
1493 * This is certainly not an exact mapping for every card, but at least
1494 * increasing dBm value should correspond to increasing TX power.
1495 */
1496
1497static int prism2_txpower_hfa386x_to_dBm(u16 val)
1498{
1499 signed char tmp;
1500
1501 if (val > 255)
1502 val = 255;
1503
1504 tmp = val;
1505 tmp >>= 2;
1506
1507 return -12 - tmp;
1508}
1509
1510static u16 prism2_txpower_dBm_to_hfa386x(int val)
1511{
1512 signed char tmp;
1513
1514 if (val > 20)
1515 return 128;
1516 else if (val < -43)
1517 return 127;
1518
1519 tmp = val;
1520 tmp = -12 - tmp;
1521 tmp <<= 2;
1522
1523 return (unsigned char) tmp;
1524}
1525#endif /* RAW_TXPOWER_SETTING */
1526
1527
1528static int prism2_ioctl_siwtxpow(struct net_device *dev,
1529 struct iw_request_info *info,
1530 struct iw_param *rrq, char *extra)
1531{
1532 struct hostap_interface *iface;
1533 local_info_t *local;
1534#ifdef RAW_TXPOWER_SETTING
1535 char *tmp;
1536#endif
1537 u16 val;
1538 int ret = 0;
1539
1540 iface = netdev_priv(dev);
1541 local = iface->local;
1542
1543 if (rrq->disabled) {
1544 if (local->txpower_type != PRISM2_TXPOWER_OFF) {
1545 val = 0xff; /* use all standby and sleep modes */
1546 ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1547 HFA386X_CR_A_D_TEST_MODES2,
1548 &val, NULL);
1549 printk(KERN_DEBUG "%s: Turning radio off: %s\n",
1550 dev->name, ret ? "failed" : "OK");
1551 local->txpower_type = PRISM2_TXPOWER_OFF;
1552 }
1553 return (ret ? -EOPNOTSUPP : 0);
1554 }
1555
1556 if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1557 val = 0; /* disable all standby and sleep modes */
1558 ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1559 HFA386X_CR_A_D_TEST_MODES2, &val, NULL);
1560 printk(KERN_DEBUG "%s: Turning radio on: %s\n",
1561 dev->name, ret ? "failed" : "OK");
1562 local->txpower_type = PRISM2_TXPOWER_UNKNOWN;
1563 }
1564
1565#ifdef RAW_TXPOWER_SETTING
1566 if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) {
1567 printk(KERN_DEBUG "Setting ALC on\n");
1568 val = HFA384X_TEST_CFG_BIT_ALC;
1569 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1570 (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL);
1571 local->txpower_type = PRISM2_TXPOWER_AUTO;
1572 return 0;
1573 }
1574
1575 if (local->txpower_type != PRISM2_TXPOWER_FIXED) {
1576 printk(KERN_DEBUG "Setting ALC off\n");
1577 val = HFA384X_TEST_CFG_BIT_ALC;
1578 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1579 (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
1580 local->txpower_type = PRISM2_TXPOWER_FIXED;
1581 }
1582
1583 if (rrq->flags == IW_TXPOW_DBM)
1584 tmp = "dBm";
1585 else if (rrq->flags == IW_TXPOW_MWATT)
1586 tmp = "mW";
1587 else
1588 tmp = "UNKNOWN";
1589 printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp);
1590
1591 if (rrq->flags != IW_TXPOW_DBM) {
1592 printk("SIOCSIWTXPOW with mW is not supported; use dBm\n");
1593 return -EOPNOTSUPP;
1594 }
1595
1596 local->txpower = rrq->value;
1597 val = prism2_txpower_dBm_to_hfa386x(local->txpower);
1598 if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1599 HFA386X_CR_MANUAL_TX_POWER, &val, NULL))
1600 ret = -EOPNOTSUPP;
1601#else /* RAW_TXPOWER_SETTING */
1602 if (rrq->fixed)
1603 ret = -EOPNOTSUPP;
1604#endif /* RAW_TXPOWER_SETTING */
1605
1606 return ret;
1607}
1608
1609static int prism2_ioctl_giwtxpow(struct net_device *dev,
1610 struct iw_request_info *info,
1611 struct iw_param *rrq, char *extra)
1612{
1613#ifdef RAW_TXPOWER_SETTING
1614 struct hostap_interface *iface;
1615 local_info_t *local;
1616 u16 resp0;
1617
1618 iface = netdev_priv(dev);
1619 local = iface->local;
1620
1621 rrq->flags = IW_TXPOW_DBM;
1622 rrq->disabled = 0;
1623 rrq->fixed = 0;
1624
1625 if (local->txpower_type == PRISM2_TXPOWER_AUTO) {
1626 if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,
1627 HFA386X_CR_MANUAL_TX_POWER,
1628 NULL, &resp0) == 0) {
1629 rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);
1630 } else {
1631 /* Could not get real txpower; guess 15 dBm */
1632 rrq->value = 15;
1633 }
1634 } else if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1635 rrq->value = 0;
1636 rrq->disabled = 1;
1637 } else if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
1638 rrq->value = local->txpower;
1639 rrq->fixed = 1;
1640 } else {
1641 printk("SIOCGIWTXPOW - unknown txpower_type=%d\n",
1642 local->txpower_type);
1643 }
1644 return 0;
1645#else /* RAW_TXPOWER_SETTING */
1646 return -EOPNOTSUPP;
1647#endif /* RAW_TXPOWER_SETTING */
1648}
1649
1650
1651#ifndef PRISM2_NO_STATION_MODES
1652
1653/* HostScan request works with and without host_roaming mode. In addition, it
1654 * does not break current association. However, it requires newer station
1655 * firmware version (>= 1.3.1) than scan request. */
1656static int prism2_request_hostscan(struct net_device *dev,
1657 u8 *ssid, u8 ssid_len)
1658{
1659 struct hostap_interface *iface;
1660 local_info_t *local;
1661 struct hfa384x_hostscan_request scan_req;
1662
1663 iface = netdev_priv(dev);
1664 local = iface->local;
1665
1666 memset(&scan_req, 0, sizeof(scan_req));
1667 scan_req.channel_list = __constant_cpu_to_le16(local->channel_mask);
1668 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
1669 if (ssid) {
1670 if (ssid_len > 32)
1671 return -EINVAL;
1672 scan_req.target_ssid_len = cpu_to_le16(ssid_len);
1673 memcpy(scan_req.target_ssid, ssid, ssid_len);
1674 }
1675
1676 if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
1677 sizeof(scan_req))) {
1678 printk(KERN_DEBUG "%s: HOSTSCAN failed\n", dev->name);
1679 return -EINVAL;
1680 }
1681 return 0;
1682}
1683
1684
1685static int prism2_request_scan(struct net_device *dev)
1686{
1687 struct hostap_interface *iface;
1688 local_info_t *local;
1689 struct hfa384x_scan_request scan_req;
1690 int ret = 0;
1691
1692 iface = netdev_priv(dev);
1693 local = iface->local;
1694
1695 memset(&scan_req, 0, sizeof(scan_req));
1696 scan_req.channel_list = __constant_cpu_to_le16(local->channel_mask);
1697 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
1698
1699 /* FIX:
1700 * It seems to be enough to set roaming mode for a short moment to
1701 * host-based and then setup scanrequest data and return the mode to
1702 * firmware-based.
1703 *
1704 * Master mode would need to drop to Managed mode for a short while
1705 * to make scanning work.. Or sweep through the different channels and
1706 * use passive scan based on beacons. */
1707
1708 if (!local->host_roaming)
1709 hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1710 HFA384X_ROAMING_HOST);
1711
1712 if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req,
1713 sizeof(scan_req))) {
1714 printk(KERN_DEBUG "SCANREQUEST failed\n");
1715 ret = -EINVAL;
1716 }
1717
1718 if (!local->host_roaming)
1719 hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1720 HFA384X_ROAMING_FIRMWARE);
1721
1722 return 0;
1723}
1724
1725#else /* !PRISM2_NO_STATION_MODES */
1726
1727static inline int prism2_request_hostscan(struct net_device *dev,
1728 u8 *ssid, u8 ssid_len)
1729{
1730 return -EOPNOTSUPP;
1731}
1732
1733
1734static inline int prism2_request_scan(struct net_device *dev)
1735{
1736 return -EOPNOTSUPP;
1737}
1738
1739#endif /* !PRISM2_NO_STATION_MODES */
1740
1741
1742static int prism2_ioctl_siwscan(struct net_device *dev,
1743 struct iw_request_info *info,
1744 struct iw_point *data, char *extra)
1745{
1746 struct hostap_interface *iface;
1747 local_info_t *local;
1748 int ret;
1749 u8 *ssid = NULL, ssid_len = 0;
1750 struct iw_scan_req *req = (struct iw_scan_req *) extra;
1751
1752 iface = netdev_priv(dev);
1753 local = iface->local;
1754
1755 if (data->length < sizeof(struct iw_scan_req))
1756 req = NULL;
1757
1758 if (local->iw_mode == IW_MODE_MASTER) {
1759 /* In master mode, we just return the results of our local
1760 * tables, so we don't need to start anything...
1761 * Jean II */
1762 data->length = 0;
1763 return 0;
1764 }
1765
1766 if (!local->dev_enabled)
1767 return -ENETDOWN;
1768
1769 if (req && data->flags & IW_SCAN_THIS_ESSID) {
1770 ssid = req->essid;
1771 ssid_len = req->essid_len;
1772
1773 if (ssid_len &&
1774 ((local->iw_mode != IW_MODE_INFRA &&
1775 local->iw_mode != IW_MODE_ADHOC) ||
1776 (local->sta_fw_ver < PRISM2_FW_VER(1,3,1))))
1777 return -EOPNOTSUPP;
1778 }
1779
1780 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))
1781 ret = prism2_request_hostscan(dev, ssid, ssid_len);
1782 else
1783 ret = prism2_request_scan(dev);
1784
1785 if (ret == 0)
1786 local->scan_timestamp = jiffies;
1787
1788 /* Could inquire F101, F103 or wait for SIOCGIWSCAN and read RID */
1789
1790 return ret;
1791}
1792
1793
1794#ifndef PRISM2_NO_STATION_MODES
1795static char * __prism2_translate_scan(local_info_t *local,
1796 struct hfa384x_scan_result *scan,
1797 struct hfa384x_hostscan_result *hscan,
1798 int hostscan,
1799 struct hostap_bss_info *bss, u8 *bssid,
1800 char *current_ev, char *end_buf)
1801{
1802 int i, chan;
1803 struct iw_event iwe;
1804 char *current_val;
1805 u16 capabilities;
1806 u8 *pos;
1807 u8 *ssid;
1808 size_t ssid_len;
1809 char *buf;
1810
1811 if (bss) {
1812 ssid = bss->ssid;
1813 ssid_len = bss->ssid_len;
1814 } else {
1815 ssid = hostscan ? hscan->ssid : scan->ssid;
1816 ssid_len = le16_to_cpu(hostscan ? hscan->ssid_len :
1817 scan->ssid_len);
1818 }
1819 if (ssid_len > 32)
1820 ssid_len = 32;
1821
1822 /* First entry *MUST* be the AP MAC address */
1823 memset(&iwe, 0, sizeof(iwe));
1824 iwe.cmd = SIOCGIWAP;
1825 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1826 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
1827 /* FIX:
1828 * I do not know how this is possible, but iwe_stream_add_event
1829 * seems to re-order memcpy execution so that len is set only
1830 * after copying.. Pre-setting len here "fixes" this, but real
1831 * problems should be solved (after which these iwe.len
1832 * settings could be removed from this function). */
1833 iwe.len = IW_EV_ADDR_LEN;
1834 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1835 IW_EV_ADDR_LEN);
1836
1837 /* Other entries will be displayed in the order we give them */
1838
1839 memset(&iwe, 0, sizeof(iwe));
1840 iwe.cmd = SIOCGIWESSID;
1841 iwe.u.data.length = ssid_len;
1842 iwe.u.data.flags = 1;
1843 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1844 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
1845
1846 memset(&iwe, 0, sizeof(iwe));
1847 iwe.cmd = SIOCGIWMODE;
1848 if (bss) {
1849 capabilities = bss->capab_info;
1850 } else {
1851 capabilities = le16_to_cpu(hostscan ? hscan->capability :
1852 scan->capability);
1853 }
1854 if (capabilities & (WLAN_CAPABILITY_ESS |
1855 WLAN_CAPABILITY_IBSS)) {
1856 if (capabilities & WLAN_CAPABILITY_ESS)
1857 iwe.u.mode = IW_MODE_MASTER;
1858 else
1859 iwe.u.mode = IW_MODE_ADHOC;
1860 iwe.len = IW_EV_UINT_LEN;
1861 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1862 IW_EV_UINT_LEN);
1863 }
1864
1865 memset(&iwe, 0, sizeof(iwe));
1866 iwe.cmd = SIOCGIWFREQ;
1867 if (hscan || scan) {
1868 chan = hostscan ? hscan->chid : scan->chid;
1869 } else if (bss) {
1870 chan = bss->chan;
1871 } else {
1872 chan = 0;
1873 }
1874
1875 if (chan > 0) {
1876 iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
1877 iwe.u.freq.e = 1;
1878 iwe.len = IW_EV_FREQ_LEN;
1879 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1880 IW_EV_FREQ_LEN);
1881 }
1882
1883 if (scan || hscan) {
1884 memset(&iwe, 0, sizeof(iwe));
1885 iwe.cmd = IWEVQUAL;
1886 if (hostscan) {
1887 iwe.u.qual.level = le16_to_cpu(hscan->sl);
1888 iwe.u.qual.noise = le16_to_cpu(hscan->anl);
1889 } else {
1890 iwe.u.qual.level =
1891 HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl));
1892 iwe.u.qual.noise =
1893 HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
1894 }
1895 iwe.len = IW_EV_QUAL_LEN;
1896 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1897 IW_EV_QUAL_LEN);
1898 }
1899
1900 memset(&iwe, 0, sizeof(iwe));
1901 iwe.cmd = SIOCGIWENCODE;
1902 if (capabilities & WLAN_CAPABILITY_PRIVACY)
1903 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1904 else
1905 iwe.u.data.flags = IW_ENCODE_DISABLED;
1906 iwe.u.data.length = 0;
1907 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1908 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
1909
1910 /* TODO: add SuppRates into BSS table */
1911 if (scan || hscan) {
1912 memset(&iwe, 0, sizeof(iwe));
1913 iwe.cmd = SIOCGIWRATE;
1914 current_val = current_ev + IW_EV_LCP_LEN;
1915 pos = hostscan ? hscan->sup_rates : scan->sup_rates;
1916 for (i = 0; i < sizeof(scan->sup_rates); i++) {
1917 if (pos[i] == 0)
1918 break;
1919 /* Bit rate given in 500 kb/s units (+ 0x80) */
1920 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
1921 current_val = iwe_stream_add_value(
1922 current_ev, current_val, end_buf, &iwe,
1923 IW_EV_PARAM_LEN);
1924 }
1925 /* Check if we added any event */
1926 if ((current_val - current_ev) > IW_EV_LCP_LEN)
1927 current_ev = current_val;
1928 }
1929
1930 /* TODO: add BeaconInt,resp_rate,atim into BSS table */
1931 buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
1932 if (buf && (scan || hscan)) {
1933 memset(&iwe, 0, sizeof(iwe));
1934 iwe.cmd = IWEVCUSTOM;
1935 sprintf(buf, "bcn_int=%d",
1936 le16_to_cpu(hostscan ? hscan->beacon_interval :
1937 scan->beacon_interval));
1938 iwe.u.data.length = strlen(buf);
1939 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1940 buf);
1941
1942 memset(&iwe, 0, sizeof(iwe));
1943 iwe.cmd = IWEVCUSTOM;
1944 sprintf(buf, "resp_rate=%d", le16_to_cpu(hostscan ?
1945 hscan->rate :
1946 scan->rate));
1947 iwe.u.data.length = strlen(buf);
1948 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1949 buf);
1950
1951 if (hostscan && (capabilities & WLAN_CAPABILITY_IBSS)) {
1952 memset(&iwe, 0, sizeof(iwe));
1953 iwe.cmd = IWEVCUSTOM;
1954 sprintf(buf, "atim=%d", le16_to_cpu(hscan->atim));
1955 iwe.u.data.length = strlen(buf);
1956 current_ev = iwe_stream_add_point(current_ev, end_buf,
1957 &iwe, buf);
1958 }
1959 }
1960 kfree(buf);
1961
1962 if (bss && bss->wpa_ie_len > 0 && bss->wpa_ie_len <= MAX_WPA_IE_LEN) {
1963 memset(&iwe, 0, sizeof(iwe));
1964 iwe.cmd = IWEVGENIE;
1965 iwe.u.data.length = bss->wpa_ie_len;
1966 current_ev = iwe_stream_add_point(
1967 current_ev, end_buf, &iwe, bss->wpa_ie);
1968 }
1969
1970 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
1971 memset(&iwe, 0, sizeof(iwe));
1972 iwe.cmd = IWEVGENIE;
1973 iwe.u.data.length = bss->rsn_ie_len;
1974 current_ev = iwe_stream_add_point(
1975 current_ev, end_buf, &iwe, bss->rsn_ie);
1976 }
1977
1978 return current_ev;
1979}
1980
1981
1982/* Translate scan data returned from the card to a card independant
1983 * format that the Wireless Tools will understand - Jean II */
1984static inline int prism2_translate_scan(local_info_t *local,
1985 char *buffer, int buflen)
1986{
1987 struct hfa384x_scan_result *scan;
1988 struct hfa384x_hostscan_result *hscan;
1989 int entries, entry, hostscan;
1990 char *current_ev = buffer;
1991 char *end_buf = buffer + buflen;
1992 u8 *bssid;
1993 struct list_head *ptr;
1994
1995 spin_lock_bh(&local->lock);
1996
1997 list_for_each(ptr, &local->bss_list) {
1998 struct hostap_bss_info *bss;
1999 bss = list_entry(ptr, struct hostap_bss_info, list);
2000 bss->included = 0;
2001 }
2002
2003 hostscan = local->last_scan_type == PRISM2_HOSTSCAN;
2004 entries = hostscan ? local->last_hostscan_results_count :
2005 local->last_scan_results_count;
2006 for (entry = 0; entry < entries; entry++) {
2007 int found = 0;
2008 scan = &local->last_scan_results[entry];
2009 hscan = &local->last_hostscan_results[entry];
2010
2011 bssid = hostscan ? hscan->bssid : scan->bssid;
2012
2013 /* Report every SSID if the AP is using multiple SSIDs. If no
2014 * BSS record is found (e.g., when WPA mode is disabled),
2015 * report the AP once. */
2016 list_for_each(ptr, &local->bss_list) {
2017 struct hostap_bss_info *bss;
2018 bss = list_entry(ptr, struct hostap_bss_info, list);
2019 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
2020 bss->included = 1;
2021 current_ev = __prism2_translate_scan(
2022 local, scan, hscan, hostscan, bss,
2023 bssid, current_ev, end_buf);
2024 found++;
2025 }
2026 }
2027 if (!found) {
2028 current_ev = __prism2_translate_scan(
2029 local, scan, hscan, hostscan, NULL, bssid,
2030 current_ev, end_buf);
2031 }
2032 /* Check if there is space for one more entry */
2033 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2034 /* Ask user space to try again with a bigger buffer */
2035 spin_unlock_bh(&local->lock);
2036 return -E2BIG;
2037 }
2038 }
2039
2040 /* Prism2 firmware has limits (32 at least in some versions) for number
2041 * of BSSes in scan results. Extend this limit by using local BSS list.
2042 */
2043 list_for_each(ptr, &local->bss_list) {
2044 struct hostap_bss_info *bss;
2045 bss = list_entry(ptr, struct hostap_bss_info, list);
2046 if (bss->included)
2047 continue;
2048 current_ev = __prism2_translate_scan(local, NULL, NULL, 0, bss,
2049 bss->bssid, current_ev,
2050 end_buf);
2051 /* Check if there is space for one more entry */
2052 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2053 /* Ask user space to try again with a bigger buffer */
2054 spin_unlock_bh(&local->lock);
2055 return -E2BIG;
2056 }
2057 }
2058
2059 spin_unlock_bh(&local->lock);
2060
2061 return current_ev - buffer;
2062}
2063#endif /* PRISM2_NO_STATION_MODES */
2064
2065
2066static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
2067 struct iw_request_info *info,
2068 struct iw_point *data, char *extra)
2069{
2070#ifdef PRISM2_NO_STATION_MODES
2071 return -EOPNOTSUPP;
2072#else /* PRISM2_NO_STATION_MODES */
2073 struct hostap_interface *iface;
2074 local_info_t *local;
2075 int res;
2076
2077 iface = netdev_priv(dev);
2078 local = iface->local;
2079
2080 /* Wait until the scan is finished. We can probably do better
2081 * than that - Jean II */
2082 if (local->scan_timestamp &&
2083 time_before(jiffies, local->scan_timestamp + 3 * HZ)) {
2084 /* Important note : we don't want to block the caller
2085 * until results are ready for various reasons.
2086 * First, managing wait queues is complex and racy
2087 * (there may be multiple simultaneous callers).
2088 * Second, we grab some rtnetlink lock before comming
2089 * here (in dev_ioctl()).
2090 * Third, the caller can wait on the Wireless Event
2091 * - Jean II */
2092 return -EAGAIN;
2093 }
2094 local->scan_timestamp = 0;
2095
2096 res = prism2_translate_scan(local, extra, data->length);
2097
2098 if (res >= 0) {
2099 data->length = res;
2100 return 0;
2101 } else {
2102 data->length = 0;
2103 return res;
2104 }
2105#endif /* PRISM2_NO_STATION_MODES */
2106}
2107
2108
2109static int prism2_ioctl_giwscan(struct net_device *dev,
2110 struct iw_request_info *info,
2111 struct iw_point *data, char *extra)
2112{
2113 struct hostap_interface *iface;
2114 local_info_t *local;
2115 int res;
2116
2117 iface = netdev_priv(dev);
2118 local = iface->local;
2119
2120 if (local->iw_mode == IW_MODE_MASTER) {
2121 /* In MASTER mode, it doesn't make sense to go around
2122 * scanning the frequencies and make the stations we serve
2123 * wait when what the user is really interested about is the
2124 * list of stations and access points we are talking to.
2125 * So, just extract results from our cache...
2126 * Jean II */
2127
2128 /* Translate to WE format */
2129 res = prism2_ap_translate_scan(dev, extra);
2130 if (res >= 0) {
2131 printk(KERN_DEBUG "Scan result translation succeeded "
2132 "(length=%d)\n", res);
2133 data->length = res;
2134 return 0;
2135 } else {
2136 printk(KERN_DEBUG
2137 "Scan result translation failed (res=%d)\n",
2138 res);
2139 data->length = 0;
2140 return res;
2141 }
2142 } else {
2143 /* Station mode */
2144 return prism2_ioctl_giwscan_sta(dev, info, data, extra);
2145 }
2146}
2147
2148
2149static const struct iw_priv_args prism2_priv[] = {
2150 { PRISM2_IOCTL_MONITOR,
2151 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" },
2152 { PRISM2_IOCTL_READMIF,
2153 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
2154 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" },
2155 { PRISM2_IOCTL_WRITEMIF,
2156 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, 0, "writemif" },
2157 { PRISM2_IOCTL_RESET,
2158 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "reset" },
2159 { PRISM2_IOCTL_INQUIRE,
2160 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inquire" },
2161 { PRISM2_IOCTL_SET_RID_WORD,
2162 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_rid_word" },
2163 { PRISM2_IOCTL_MACCMD,
2164 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maccmd" },
2165 { PRISM2_IOCTL_WDS_ADD,
2166 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_add" },
2167 { PRISM2_IOCTL_WDS_DEL,
2168 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_del" },
2169 { PRISM2_IOCTL_ADDMAC,
2170 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addmac" },
2171 { PRISM2_IOCTL_DELMAC,
2172 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "delmac" },
2173 { PRISM2_IOCTL_KICKMAC,
2174 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "kickmac" },
2175 /* --- raw access to sub-ioctls --- */
2176 { PRISM2_IOCTL_PRISM2_PARAM,
2177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "prism2_param" },
2178 { PRISM2_IOCTL_GET_PRISM2_PARAM,
2179 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2180 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprism2_param" },
2181 /* --- sub-ioctls handlers --- */
2182 { PRISM2_IOCTL_PRISM2_PARAM,
2183 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2184 { PRISM2_IOCTL_GET_PRISM2_PARAM,
2185 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2186 /* --- sub-ioctls definitions --- */
2187 { PRISM2_PARAM_TXRATECTRL,
2188 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txratectrl" },
2189 { PRISM2_PARAM_TXRATECTRL,
2190 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettxratectrl" },
2191 { PRISM2_PARAM_BEACON_INT,
2192 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beacon_int" },
2193 { PRISM2_PARAM_BEACON_INT,
2194 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbeacon_int" },
2195#ifndef PRISM2_NO_STATION_MODES
2196 { PRISM2_PARAM_PSEUDO_IBSS,
2197 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "pseudo_ibss" },
2198 { PRISM2_PARAM_PSEUDO_IBSS,
2199 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpseudo_ibss" },
2200#endif /* PRISM2_NO_STATION_MODES */
2201 { PRISM2_PARAM_ALC,
2202 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "alc" },
2203 { PRISM2_PARAM_ALC,
2204 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getalc" },
2205 { PRISM2_PARAM_DUMP,
2206 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dump" },
2207 { PRISM2_PARAM_DUMP,
2208 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdump" },
2209 { PRISM2_PARAM_OTHER_AP_POLICY,
2210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "other_ap_policy" },
2211 { PRISM2_PARAM_OTHER_AP_POLICY,
2212 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getother_ap_pol" },
2213 { PRISM2_PARAM_AP_MAX_INACTIVITY,
2214 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_inactivity" },
2215 { PRISM2_PARAM_AP_MAX_INACTIVITY,
2216 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_inactivi" },
2217 { PRISM2_PARAM_AP_BRIDGE_PACKETS,
2218 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bridge_packets" },
2219 { PRISM2_PARAM_AP_BRIDGE_PACKETS,
2220 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbridge_packe" },
2221 { PRISM2_PARAM_DTIM_PERIOD,
2222 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dtim_period" },
2223 { PRISM2_PARAM_DTIM_PERIOD,
2224 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdtim_period" },
2225 { PRISM2_PARAM_AP_NULLFUNC_ACK,
2226 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "nullfunc_ack" },
2227 { PRISM2_PARAM_AP_NULLFUNC_ACK,
2228 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getnullfunc_ack" },
2229 { PRISM2_PARAM_MAX_WDS,
2230 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_wds" },
2231 { PRISM2_PARAM_MAX_WDS,
2232 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_wds" },
2233 { PRISM2_PARAM_AP_AUTOM_AP_WDS,
2234 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "autom_ap_wds" },
2235 { PRISM2_PARAM_AP_AUTOM_AP_WDS,
2236 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getautom_ap_wds" },
2237 { PRISM2_PARAM_AP_AUTH_ALGS,
2238 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_auth_algs" },
2239 { PRISM2_PARAM_AP_AUTH_ALGS,
2240 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_auth_algs" },
2241 { PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2242 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "allow_fcserr" },
2243 { PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2244 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getallow_fcserr" },
2245 { PRISM2_PARAM_HOST_ENCRYPT,
2246 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_encrypt" },
2247 { PRISM2_PARAM_HOST_ENCRYPT,
2248 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_encrypt" },
2249 { PRISM2_PARAM_HOST_DECRYPT,
2250 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_decrypt" },
2251 { PRISM2_PARAM_HOST_DECRYPT,
2252 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_decrypt" },
2253 { PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX,
2254 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "busmaster_rx" },
2255 { PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX,
2256 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbusmaster_rx" },
2257 { PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX,
2258 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "busmaster_tx" },
2259 { PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX,
2260 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbusmaster_tx" },
2261#ifndef PRISM2_NO_STATION_MODES
2262 { PRISM2_PARAM_HOST_ROAMING,
2263 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_roaming" },
2264 { PRISM2_PARAM_HOST_ROAMING,
2265 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_roaming" },
2266#endif /* PRISM2_NO_STATION_MODES */
2267 { PRISM2_PARAM_BCRX_STA_KEY,
2268 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bcrx_sta_key" },
2269 { PRISM2_PARAM_BCRX_STA_KEY,
2270 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbcrx_sta_key" },
2271 { PRISM2_PARAM_IEEE_802_1X,
2272 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ieee_802_1x" },
2273 { PRISM2_PARAM_IEEE_802_1X,
2274 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getieee_802_1x" },
2275 { PRISM2_PARAM_ANTSEL_TX,
2276 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_tx" },
2277 { PRISM2_PARAM_ANTSEL_TX,
2278 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_tx" },
2279 { PRISM2_PARAM_ANTSEL_RX,
2280 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_rx" },
2281 { PRISM2_PARAM_ANTSEL_RX,
2282 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_rx" },
2283 { PRISM2_PARAM_MONITOR_TYPE,
2284 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor_type" },
2285 { PRISM2_PARAM_MONITOR_TYPE,
2286 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmonitor_type" },
2287 { PRISM2_PARAM_WDS_TYPE,
2288 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wds_type" },
2289 { PRISM2_PARAM_WDS_TYPE,
2290 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwds_type" },
2291 { PRISM2_PARAM_HOSTSCAN,
2292 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostscan" },
2293 { PRISM2_PARAM_HOSTSCAN,
2294 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostscan" },
2295 { PRISM2_PARAM_AP_SCAN,
2296 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_scan" },
2297 { PRISM2_PARAM_AP_SCAN,
2298 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_scan" },
2299 { PRISM2_PARAM_ENH_SEC,
2300 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "enh_sec" },
2301 { PRISM2_PARAM_ENH_SEC,
2302 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getenh_sec" },
2303#ifdef PRISM2_IO_DEBUG
2304 { PRISM2_PARAM_IO_DEBUG,
2305 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "io_debug" },
2306 { PRISM2_PARAM_IO_DEBUG,
2307 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getio_debug" },
2308#endif /* PRISM2_IO_DEBUG */
2309 { PRISM2_PARAM_BASIC_RATES,
2310 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "basic_rates" },
2311 { PRISM2_PARAM_BASIC_RATES,
2312 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbasic_rates" },
2313 { PRISM2_PARAM_OPER_RATES,
2314 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oper_rates" },
2315 { PRISM2_PARAM_OPER_RATES,
2316 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getoper_rates" },
2317 { PRISM2_PARAM_HOSTAPD,
2318 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd" },
2319 { PRISM2_PARAM_HOSTAPD,
2320 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd" },
2321 { PRISM2_PARAM_HOSTAPD_STA,
2322 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd_sta" },
2323 { PRISM2_PARAM_HOSTAPD_STA,
2324 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd_sta" },
2325 { PRISM2_PARAM_WPA,
2326 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wpa" },
2327 { PRISM2_PARAM_WPA,
2328 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwpa" },
2329 { PRISM2_PARAM_PRIVACY_INVOKED,
2330 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "privacy_invoked" },
2331 { PRISM2_PARAM_PRIVACY_INVOKED,
2332 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprivacy_invo" },
2333 { PRISM2_PARAM_TKIP_COUNTERMEASURES,
2334 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "tkip_countermea" },
2335 { PRISM2_PARAM_TKIP_COUNTERMEASURES,
2336 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettkip_counter" },
2337 { PRISM2_PARAM_DROP_UNENCRYPTED,
2338 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypte" },
2339 { PRISM2_PARAM_DROP_UNENCRYPTED,
2340 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdrop_unencry" },
2341};
2342
2343
2344static int prism2_ioctl_priv_inquire(struct net_device *dev, int *i)
2345{
2346 struct hostap_interface *iface;
2347 local_info_t *local;
2348
2349 iface = netdev_priv(dev);
2350 local = iface->local;
2351
2352 if (local->func->cmd(dev, HFA384X_CMDCODE_INQUIRE, *i, NULL, NULL))
2353 return -EOPNOTSUPP;
2354
2355 return 0;
2356}
2357
2358
2359static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
2360 struct iw_request_info *info,
2361 void *wrqu, char *extra)
2362{
2363 struct hostap_interface *iface;
2364 local_info_t *local;
2365 int *i = (int *) extra;
2366 int param = *i;
2367 int value = *(i + 1);
2368 int ret = 0;
2369 u16 val;
2370
2371 iface = netdev_priv(dev);
2372 local = iface->local;
2373
2374 switch (param) {
2375 case PRISM2_PARAM_TXRATECTRL:
2376 local->fw_tx_rate_control = value;
2377 break;
2378
2379 case PRISM2_PARAM_BEACON_INT:
2380 if (hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, value) ||
2381 local->func->reset_port(dev))
2382 ret = -EINVAL;
2383 else
2384 local->beacon_int = value;
2385 break;
2386
2387#ifndef PRISM2_NO_STATION_MODES
2388 case PRISM2_PARAM_PSEUDO_IBSS:
2389 if (value == local->pseudo_adhoc)
2390 break;
2391
2392 if (value != 0 && value != 1) {
2393 ret = -EINVAL;
2394 break;
2395 }
2396
2397 printk(KERN_DEBUG "prism2: %s: pseudo IBSS change %d -> %d\n",
2398 dev->name, local->pseudo_adhoc, value);
2399 local->pseudo_adhoc = value;
2400 if (local->iw_mode != IW_MODE_ADHOC)
2401 break;
2402
2403 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2404 hostap_get_porttype(local))) {
2405 ret = -EOPNOTSUPP;
2406 break;
2407 }
2408
2409 if (local->func->reset_port(dev))
2410 ret = -EINVAL;
2411 break;
2412#endif /* PRISM2_NO_STATION_MODES */
2413
2414 case PRISM2_PARAM_ALC:
2415 printk(KERN_DEBUG "%s: %s ALC\n", dev->name,
2416 value == 0 ? "Disabling" : "Enabling");
2417 val = HFA384X_TEST_CFG_BIT_ALC;
2418 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
2419 (HFA384X_TEST_CFG_BITS << 8),
2420 value == 0 ? 0 : 1, &val, NULL);
2421 break;
2422
2423 case PRISM2_PARAM_DUMP:
2424 local->frame_dump = value;
2425 break;
2426
2427 case PRISM2_PARAM_OTHER_AP_POLICY:
2428 if (value < 0 || value > 3) {
2429 ret = -EINVAL;
2430 break;
2431 }
2432 if (local->ap != NULL)
2433 local->ap->ap_policy = value;
2434 break;
2435
2436 case PRISM2_PARAM_AP_MAX_INACTIVITY:
2437 if (value < 0 || value > 7 * 24 * 60 * 60) {
2438 ret = -EINVAL;
2439 break;
2440 }
2441 if (local->ap != NULL)
2442 local->ap->max_inactivity = value * HZ;
2443 break;
2444
2445 case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2446 if (local->ap != NULL)
2447 local->ap->bridge_packets = value;
2448 break;
2449
2450 case PRISM2_PARAM_DTIM_PERIOD:
2451 if (value < 0 || value > 65535) {
2452 ret = -EINVAL;
2453 break;
2454 }
2455 if (hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, value)
2456 || local->func->reset_port(dev))
2457 ret = -EINVAL;
2458 else
2459 local->dtim_period = value;
2460 break;
2461
2462 case PRISM2_PARAM_AP_NULLFUNC_ACK:
2463 if (local->ap != NULL)
2464 local->ap->nullfunc_ack = value;
2465 break;
2466
2467 case PRISM2_PARAM_MAX_WDS:
2468 local->wds_max_connections = value;
2469 break;
2470
2471 case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2472 if (local->ap != NULL) {
2473 if (!local->ap->autom_ap_wds && value) {
2474 /* add WDS link to all APs in STA table */
2475 hostap_add_wds_links(local);
2476 }
2477 local->ap->autom_ap_wds = value;
2478 }
2479 break;
2480
2481 case PRISM2_PARAM_AP_AUTH_ALGS:
2482 local->auth_algs = value;
2483 if (hostap_set_auth_algs(local))
2484 ret = -EINVAL;
2485 break;
2486
2487 case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2488 local->monitor_allow_fcserr = value;
2489 break;
2490
2491 case PRISM2_PARAM_HOST_ENCRYPT:
2492 local->host_encrypt = value;
2493 if (hostap_set_encryption(local) ||
2494 local->func->reset_port(dev))
2495 ret = -EINVAL;
2496 break;
2497
2498 case PRISM2_PARAM_HOST_DECRYPT:
2499 local->host_decrypt = value;
2500 if (hostap_set_encryption(local) ||
2501 local->func->reset_port(dev))
2502 ret = -EINVAL;
2503 break;
2504
2505 case PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX:
2506 local->bus_master_threshold_rx = value;
2507 break;
2508
2509 case PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX:
2510 local->bus_master_threshold_tx = value;
2511 break;
2512
2513#ifndef PRISM2_NO_STATION_MODES
2514 case PRISM2_PARAM_HOST_ROAMING:
2515 if (value < 0 || value > 2) {
2516 ret = -EINVAL;
2517 break;
2518 }
2519 local->host_roaming = value;
2520 if (hostap_set_roaming(local) || local->func->reset_port(dev))
2521 ret = -EINVAL;
2522 break;
2523#endif /* PRISM2_NO_STATION_MODES */
2524
2525 case PRISM2_PARAM_BCRX_STA_KEY:
2526 local->bcrx_sta_key = value;
2527 break;
2528
2529 case PRISM2_PARAM_IEEE_802_1X:
2530 local->ieee_802_1x = value;
2531 break;
2532
2533 case PRISM2_PARAM_ANTSEL_TX:
2534 if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2535 ret = -EINVAL;
2536 break;
2537 }
2538 local->antsel_tx = value;
2539 hostap_set_antsel(local);
2540 break;
2541
2542 case PRISM2_PARAM_ANTSEL_RX:
2543 if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2544 ret = -EINVAL;
2545 break;
2546 }
2547 local->antsel_rx = value;
2548 hostap_set_antsel(local);
2549 break;
2550
2551 case PRISM2_PARAM_MONITOR_TYPE:
2552 if (value != PRISM2_MONITOR_80211 &&
2553 value != PRISM2_MONITOR_CAPHDR &&
2554 value != PRISM2_MONITOR_PRISM) {
2555 ret = -EINVAL;
2556 break;
2557 }
2558 local->monitor_type = value;
2559 if (local->iw_mode == IW_MODE_MONITOR)
2560 hostap_monitor_set_type(local);
2561 break;
2562
2563 case PRISM2_PARAM_WDS_TYPE:
2564 local->wds_type = value;
2565 break;
2566
2567 case PRISM2_PARAM_HOSTSCAN:
2568 {
2569 struct hfa384x_hostscan_request scan_req;
2570 u16 rate;
2571
2572 memset(&scan_req, 0, sizeof(scan_req));
2573 scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
2574 switch (value) {
2575 case 1: rate = HFA384X_RATES_1MBPS; break;
2576 case 2: rate = HFA384X_RATES_2MBPS; break;
2577 case 3: rate = HFA384X_RATES_5MBPS; break;
2578 case 4: rate = HFA384X_RATES_11MBPS; break;
2579 default: rate = HFA384X_RATES_1MBPS; break;
2580 }
2581 scan_req.txrate = cpu_to_le16(rate);
2582 /* leave SSID empty to accept all SSIDs */
2583
2584 if (local->iw_mode == IW_MODE_MASTER) {
2585 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2586 HFA384X_PORTTYPE_BSS) ||
2587 local->func->reset_port(dev))
2588 printk(KERN_DEBUG "Leaving Host AP mode "
2589 "for HostScan failed\n");
2590 }
2591
2592 if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
2593 sizeof(scan_req))) {
2594 printk(KERN_DEBUG "HOSTSCAN failed\n");
2595 ret = -EINVAL;
2596 }
2597 if (local->iw_mode == IW_MODE_MASTER) {
2598 wait_queue_t __wait;
2599 init_waitqueue_entry(&__wait, current);
2600 add_wait_queue(&local->hostscan_wq, &__wait);
2601 set_current_state(TASK_INTERRUPTIBLE);
2602 schedule_timeout(HZ);
2603 if (signal_pending(current))
2604 ret = -EINTR;
2605 set_current_state(TASK_RUNNING);
2606 remove_wait_queue(&local->hostscan_wq, &__wait);
2607
2608 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2609 HFA384X_PORTTYPE_HOSTAP) ||
2610 local->func->reset_port(dev))
2611 printk(KERN_DEBUG "Returning to Host AP mode "
2612 "after HostScan failed\n");
2613 }
2614 break;
2615 }
2616
2617 case PRISM2_PARAM_AP_SCAN:
2618 local->passive_scan_interval = value;
2619 if (timer_pending(&local->passive_scan_timer))
2620 del_timer(&local->passive_scan_timer);
2621 if (value > 0) {
2622 local->passive_scan_timer.expires = jiffies +
2623 local->passive_scan_interval * HZ;
2624 add_timer(&local->passive_scan_timer);
2625 }
2626 break;
2627
2628 case PRISM2_PARAM_ENH_SEC:
2629 if (value < 0 || value > 3) {
2630 ret = -EINVAL;
2631 break;
2632 }
2633 local->enh_sec = value;
2634 if (hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY,
2635 local->enh_sec) ||
2636 local->func->reset_port(dev)) {
2637 printk(KERN_INFO "%s: cnfEnhSecurity requires STA f/w "
2638 "1.6.3 or newer\n", dev->name);
2639 ret = -EOPNOTSUPP;
2640 }
2641 break;
2642
2643#ifdef PRISM2_IO_DEBUG
2644 case PRISM2_PARAM_IO_DEBUG:
2645 local->io_debug_enabled = value;
2646 break;
2647#endif /* PRISM2_IO_DEBUG */
2648
2649 case PRISM2_PARAM_BASIC_RATES:
2650 if ((value & local->tx_rate_control) != value || value == 0) {
2651 printk(KERN_INFO "%s: invalid basic rate set - basic "
2652 "rates must be in supported rate set\n",
2653 dev->name);
2654 ret = -EINVAL;
2655 break;
2656 }
2657 local->basic_rates = value;
2658 if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
2659 local->basic_rates) ||
2660 local->func->reset_port(dev))
2661 ret = -EINVAL;
2662 break;
2663
2664 case PRISM2_PARAM_OPER_RATES:
2665 local->tx_rate_control = value;
2666 if (hostap_set_rate(dev))
2667 ret = -EINVAL;
2668 break;
2669
2670 case PRISM2_PARAM_HOSTAPD:
2671 ret = hostap_set_hostapd(local, value, 1);
2672 break;
2673
2674 case PRISM2_PARAM_HOSTAPD_STA:
2675 ret = hostap_set_hostapd_sta(local, value, 1);
2676 break;
2677
2678 case PRISM2_PARAM_WPA:
2679 local->wpa = value;
2680 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2681 ret = -EOPNOTSUPP;
2682 else if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
2683 value ? 1 : 0))
2684 ret = -EINVAL;
2685 break;
2686
2687 case PRISM2_PARAM_PRIVACY_INVOKED:
2688 local->privacy_invoked = value;
2689 if (hostap_set_encryption(local) ||
2690 local->func->reset_port(dev))
2691 ret = -EINVAL;
2692 break;
2693
2694 case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2695 local->tkip_countermeasures = value;
2696 break;
2697
2698 case PRISM2_PARAM_DROP_UNENCRYPTED:
2699 local->drop_unencrypted = value;
2700 break;
2701
2702 default:
2703 printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n",
2704 dev->name, param);
2705 ret = -EOPNOTSUPP;
2706 break;
2707 }
2708
2709 return ret;
2710}
2711
2712
2713static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev,
2714 struct iw_request_info *info,
2715 void *wrqu, char *extra)
2716{
2717 struct hostap_interface *iface;
2718 local_info_t *local;
2719 int *param = (int *) extra;
2720 int ret = 0;
2721
2722 iface = netdev_priv(dev);
2723 local = iface->local;
2724
2725 switch (*param) {
2726 case PRISM2_PARAM_TXRATECTRL:
2727 *param = local->fw_tx_rate_control;
2728 break;
2729
2730 case PRISM2_PARAM_BEACON_INT:
2731 *param = local->beacon_int;
2732 break;
2733
2734 case PRISM2_PARAM_PSEUDO_IBSS:
2735 *param = local->pseudo_adhoc;
2736 break;
2737
2738 case PRISM2_PARAM_ALC:
2739 ret = -EOPNOTSUPP; /* FIX */
2740 break;
2741
2742 case PRISM2_PARAM_DUMP:
2743 *param = local->frame_dump;
2744 break;
2745
2746 case PRISM2_PARAM_OTHER_AP_POLICY:
2747 if (local->ap != NULL)
2748 *param = local->ap->ap_policy;
2749 else
2750 ret = -EOPNOTSUPP;
2751 break;
2752
2753 case PRISM2_PARAM_AP_MAX_INACTIVITY:
2754 if (local->ap != NULL)
2755 *param = local->ap->max_inactivity / HZ;
2756 else
2757 ret = -EOPNOTSUPP;
2758 break;
2759
2760 case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2761 if (local->ap != NULL)
2762 *param = local->ap->bridge_packets;
2763 else
2764 ret = -EOPNOTSUPP;
2765 break;
2766
2767 case PRISM2_PARAM_DTIM_PERIOD:
2768 *param = local->dtim_period;
2769 break;
2770
2771 case PRISM2_PARAM_AP_NULLFUNC_ACK:
2772 if (local->ap != NULL)
2773 *param = local->ap->nullfunc_ack;
2774 else
2775 ret = -EOPNOTSUPP;
2776 break;
2777
2778 case PRISM2_PARAM_MAX_WDS:
2779 *param = local->wds_max_connections;
2780 break;
2781
2782 case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2783 if (local->ap != NULL)
2784 *param = local->ap->autom_ap_wds;
2785 else
2786 ret = -EOPNOTSUPP;
2787 break;
2788
2789 case PRISM2_PARAM_AP_AUTH_ALGS:
2790 *param = local->auth_algs;
2791 break;
2792
2793 case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2794 *param = local->monitor_allow_fcserr;
2795 break;
2796
2797 case PRISM2_PARAM_HOST_ENCRYPT:
2798 *param = local->host_encrypt;
2799 break;
2800
2801 case PRISM2_PARAM_HOST_DECRYPT:
2802 *param = local->host_decrypt;
2803 break;
2804
2805 case PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX:
2806 *param = local->bus_master_threshold_rx;
2807 break;
2808
2809 case PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX:
2810 *param = local->bus_master_threshold_tx;
2811 break;
2812
2813 case PRISM2_PARAM_HOST_ROAMING:
2814 *param = local->host_roaming;
2815 break;
2816
2817 case PRISM2_PARAM_BCRX_STA_KEY:
2818 *param = local->bcrx_sta_key;
2819 break;
2820
2821 case PRISM2_PARAM_IEEE_802_1X:
2822 *param = local->ieee_802_1x;
2823 break;
2824
2825 case PRISM2_PARAM_ANTSEL_TX:
2826 *param = local->antsel_tx;
2827 break;
2828
2829 case PRISM2_PARAM_ANTSEL_RX:
2830 *param = local->antsel_rx;
2831 break;
2832
2833 case PRISM2_PARAM_MONITOR_TYPE:
2834 *param = local->monitor_type;
2835 break;
2836
2837 case PRISM2_PARAM_WDS_TYPE:
2838 *param = local->wds_type;
2839 break;
2840
2841 case PRISM2_PARAM_HOSTSCAN:
2842 ret = -EOPNOTSUPP;
2843 break;
2844
2845 case PRISM2_PARAM_AP_SCAN:
2846 *param = local->passive_scan_interval;
2847 break;
2848
2849 case PRISM2_PARAM_ENH_SEC:
2850 *param = local->enh_sec;
2851 break;
2852
2853#ifdef PRISM2_IO_DEBUG
2854 case PRISM2_PARAM_IO_DEBUG:
2855 *param = local->io_debug_enabled;
2856 break;
2857#endif /* PRISM2_IO_DEBUG */
2858
2859 case PRISM2_PARAM_BASIC_RATES:
2860 *param = local->basic_rates;
2861 break;
2862
2863 case PRISM2_PARAM_OPER_RATES:
2864 *param = local->tx_rate_control;
2865 break;
2866
2867 case PRISM2_PARAM_HOSTAPD:
2868 *param = local->hostapd;
2869 break;
2870
2871 case PRISM2_PARAM_HOSTAPD_STA:
2872 *param = local->hostapd_sta;
2873 break;
2874
2875 case PRISM2_PARAM_WPA:
2876 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2877 ret = -EOPNOTSUPP;
2878 *param = local->wpa;
2879 break;
2880
2881 case PRISM2_PARAM_PRIVACY_INVOKED:
2882 *param = local->privacy_invoked;
2883 break;
2884
2885 case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2886 *param = local->tkip_countermeasures;
2887 break;
2888
2889 case PRISM2_PARAM_DROP_UNENCRYPTED:
2890 *param = local->drop_unencrypted;
2891 break;
2892
2893 default:
2894 printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n",
2895 dev->name, *param);
2896 ret = -EOPNOTSUPP;
2897 break;
2898 }
2899
2900 return ret;
2901}
2902
2903
2904static int prism2_ioctl_priv_readmif(struct net_device *dev,
2905 struct iw_request_info *info,
2906 void *wrqu, char *extra)
2907{
2908 struct hostap_interface *iface;
2909 local_info_t *local;
2910 u16 resp0;
2911
2912 iface = netdev_priv(dev);
2913 local = iface->local;
2914
2915 if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF, *extra, NULL,
2916 &resp0))
2917 return -EOPNOTSUPP;
2918 else
2919 *extra = resp0;
2920
2921 return 0;
2922}
2923
2924
2925static int prism2_ioctl_priv_writemif(struct net_device *dev,
2926 struct iw_request_info *info,
2927 void *wrqu, char *extra)
2928{
2929 struct hostap_interface *iface;
2930 local_info_t *local;
2931 u16 cr, val;
2932
2933 iface = netdev_priv(dev);
2934 local = iface->local;
2935
2936 cr = *extra;
2937 val = *(extra + 1);
2938 if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, cr, &val, NULL))
2939 return -EOPNOTSUPP;
2940
2941 return 0;
2942}
2943
2944
2945static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
2946{
2947 struct hostap_interface *iface;
2948 local_info_t *local;
2949 int ret = 0;
2950 u32 mode;
2951
2952 iface = netdev_priv(dev);
2953 local = iface->local;
2954
2955 printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
2956 "- update software to use iwconfig mode monitor\n",
2957 dev->name, current->pid, current->comm);
2958
2959 /* Backward compatibility code - this can be removed at some point */
2960
2961 if (*i == 0) {
2962 /* Disable monitor mode - old mode was not saved, so go to
2963 * Master mode */
2964 mode = IW_MODE_MASTER;
2965 ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
2966 } else if (*i == 1) {
2967 /* netlink socket mode is not supported anymore since it did
2968 * not separate different devices from each other and was not
2969 * best method for delivering large amount of packets to
2970 * user space */
2971 ret = -EOPNOTSUPP;
2972 } else if (*i == 2 || *i == 3) {
2973 switch (*i) {
2974 case 2:
2975 local->monitor_type = PRISM2_MONITOR_80211;
2976 break;
2977 case 3:
2978 local->monitor_type = PRISM2_MONITOR_PRISM;
2979 break;
2980 }
2981 mode = IW_MODE_MONITOR;
2982 ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
2983 hostap_monitor_mode_enable(local);
2984 } else
2985 ret = -EINVAL;
2986
2987 return ret;
2988}
2989
2990
2991static int prism2_ioctl_priv_reset(struct net_device *dev, int *i)
2992{
2993 struct hostap_interface *iface;
2994 local_info_t *local;
2995
2996 iface = netdev_priv(dev);
2997 local = iface->local;
2998
2999 printk(KERN_DEBUG "%s: manual reset request(%d)\n", dev->name, *i);
3000 switch (*i) {
3001 case 0:
3002 /* Disable and enable card */
3003 local->func->hw_shutdown(dev, 1);
3004 local->func->hw_config(dev, 0);
3005 break;
3006
3007 case 1:
3008 /* COR sreset */
3009 local->func->hw_reset(dev);
3010 break;
3011
3012 case 2:
3013 /* Disable and enable port 0 */
3014 local->func->reset_port(dev);
3015 break;
3016
3017 case 3:
3018 prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
3019 if (local->func->cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL,
3020 NULL))
3021 return -EINVAL;
3022 break;
3023
3024 case 4:
3025 if (local->func->cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL,
3026 NULL))
3027 return -EINVAL;
3028 break;
3029
3030 default:
3031 printk(KERN_DEBUG "Unknown reset request %d\n", *i);
3032 return -EOPNOTSUPP;
3033 }
3034
3035 return 0;
3036}
3037
3038
3039static int prism2_ioctl_priv_set_rid_word(struct net_device *dev, int *i)
3040{
3041 int rid = *i;
3042 int value = *(i + 1);
3043
3044 printk(KERN_DEBUG "%s: Set RID[0x%X] = %d\n", dev->name, rid, value);
3045
3046 if (hostap_set_word(dev, rid, value))
3047 return -EINVAL;
3048
3049 return 0;
3050}
3051
3052
3053#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3054static int ap_mac_cmd_ioctl(local_info_t *local, int *cmd)
3055{
3056 int ret = 0;
3057
3058 switch (*cmd) {
3059 case AP_MAC_CMD_POLICY_OPEN:
3060 local->ap->mac_restrictions.policy = MAC_POLICY_OPEN;
3061 break;
3062 case AP_MAC_CMD_POLICY_ALLOW:
3063 local->ap->mac_restrictions.policy = MAC_POLICY_ALLOW;
3064 break;
3065 case AP_MAC_CMD_POLICY_DENY:
3066 local->ap->mac_restrictions.policy = MAC_POLICY_DENY;
3067 break;
3068 case AP_MAC_CMD_FLUSH:
3069 ap_control_flush_macs(&local->ap->mac_restrictions);
3070 break;
3071 case AP_MAC_CMD_KICKALL:
3072 ap_control_kickall(local->ap);
3073 hostap_deauth_all_stas(local->dev, local->ap, 0);
3074 break;
3075 default:
3076 ret = -EOPNOTSUPP;
3077 break;
3078 }
3079
3080 return ret;
3081}
3082#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3083
3084
3085#ifdef PRISM2_DOWNLOAD_SUPPORT
3086static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
3087{
3088 struct prism2_download_param *param;
3089 int ret = 0;
3090
3091 if (p->length < sizeof(struct prism2_download_param) ||
3092 p->length > 1024 || !p->pointer)
3093 return -EINVAL;
3094
3095 param = (struct prism2_download_param *)
3096 kmalloc(p->length, GFP_KERNEL);
3097 if (param == NULL)
3098 return -ENOMEM;
3099
3100 if (copy_from_user(param, p->pointer, p->length)) {
3101 ret = -EFAULT;
3102 goto out;
3103 }
3104
3105 if (p->length < sizeof(struct prism2_download_param) +
3106 param->num_areas * sizeof(struct prism2_download_area)) {
3107 ret = -EINVAL;
3108 goto out;
3109 }
3110
3111 ret = local->func->download(local, param);
3112
3113 out:
3114 if (param != NULL)
3115 kfree(param);
3116
3117 return ret;
3118}
3119#endif /* PRISM2_DOWNLOAD_SUPPORT */
3120
3121
3122static int prism2_set_genericelement(struct net_device *dev, u8 *elem,
3123 size_t len)
3124{
3125 struct hostap_interface *iface = dev->priv;
3126 local_info_t *local = iface->local;
3127 u8 *buf;
3128
3129 /*
3130 * Add 16-bit length in the beginning of the buffer because Prism2 RID
3131 * includes it.
3132 */
3133 buf = kmalloc(len + 2, GFP_KERNEL);
3134 if (buf == NULL)
3135 return -ENOMEM;
3136
3137 *((u16 *) buf) = cpu_to_le16(len);
3138 memcpy(buf + 2, elem, len);
3139
3140 kfree(local->generic_elem);
3141 local->generic_elem = buf;
3142 local->generic_elem_len = len + 2;
3143
3144 return local->func->set_rid(local->dev, HFA384X_RID_GENERICELEMENT,
3145 buf, len + 2);
3146}
3147
3148
3149static int prism2_ioctl_siwauth(struct net_device *dev,
3150 struct iw_request_info *info,
3151 struct iw_param *data, char *extra)
3152{
3153 struct hostap_interface *iface = dev->priv;
3154 local_info_t *local = iface->local;
3155
3156 switch (data->flags & IW_AUTH_INDEX) {
3157 case IW_AUTH_WPA_VERSION:
3158 case IW_AUTH_CIPHER_PAIRWISE:
3159 case IW_AUTH_CIPHER_GROUP:
3160 case IW_AUTH_KEY_MGMT:
3161 /*
3162 * Host AP driver does not use these parameters and allows
3163 * wpa_supplicant to control them internally.
3164 */
3165 break;
3166 case IW_AUTH_TKIP_COUNTERMEASURES:
3167 local->tkip_countermeasures = data->value;
3168 break;
3169 case IW_AUTH_DROP_UNENCRYPTED:
3170 local->drop_unencrypted = data->value;
3171 break;
3172 case IW_AUTH_80211_AUTH_ALG:
3173 local->auth_algs = data->value;
3174 break;
3175 case IW_AUTH_WPA_ENABLED:
3176 if (data->value == 0) {
3177 local->wpa = 0;
3178 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3179 break;
3180 prism2_set_genericelement(dev, "", 0);
3181 local->host_roaming = 0;
3182 local->privacy_invoked = 0;
3183 if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
3184 0) ||
3185 hostap_set_roaming(local) ||
3186 hostap_set_encryption(local) ||
3187 local->func->reset_port(dev))
3188 return -EINVAL;
3189 break;
3190 }
3191 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3192 return -EOPNOTSUPP;
3193 local->host_roaming = 2;
3194 local->privacy_invoked = 1;
3195 local->wpa = 1;
3196 if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1) ||
3197 hostap_set_roaming(local) ||
3198 hostap_set_encryption(local) ||
3199 local->func->reset_port(dev))
3200 return -EINVAL;
3201 break;
3202 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3203 local->ieee_802_1x = data->value;
3204 break;
3205 case IW_AUTH_PRIVACY_INVOKED:
3206 local->privacy_invoked = data->value;
3207 break;
3208 default:
3209 return -EOPNOTSUPP;
3210 }
3211 return 0;
3212}
3213
3214
3215static int prism2_ioctl_giwauth(struct net_device *dev,
3216 struct iw_request_info *info,
3217 struct iw_param *data, char *extra)
3218{
3219 struct hostap_interface *iface = dev->priv;
3220 local_info_t *local = iface->local;
3221
3222 switch (data->flags & IW_AUTH_INDEX) {
3223 case IW_AUTH_WPA_VERSION:
3224 case IW_AUTH_CIPHER_PAIRWISE:
3225 case IW_AUTH_CIPHER_GROUP:
3226 case IW_AUTH_KEY_MGMT:
3227 /*
3228 * Host AP driver does not use these parameters and allows
3229 * wpa_supplicant to control them internally.
3230 */
3231 return -EOPNOTSUPP;
3232 case IW_AUTH_TKIP_COUNTERMEASURES:
3233 data->value = local->tkip_countermeasures;
3234 break;
3235 case IW_AUTH_DROP_UNENCRYPTED:
3236 data->value = local->drop_unencrypted;
3237 break;
3238 case IW_AUTH_80211_AUTH_ALG:
3239 data->value = local->auth_algs;
3240 break;
3241 case IW_AUTH_WPA_ENABLED:
3242 data->value = local->wpa;
3243 break;
3244 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3245 data->value = local->ieee_802_1x;
3246 break;
3247 default:
3248 return -EOPNOTSUPP;
3249 }
3250 return 0;
3251}
3252
3253
3254static int prism2_ioctl_siwencodeext(struct net_device *dev,
3255 struct iw_request_info *info,
3256 struct iw_point *erq, char *extra)
3257{
3258 struct hostap_interface *iface = dev->priv;
3259 local_info_t *local = iface->local;
3260 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3261 int i, ret = 0;
3262 struct hostap_crypto_ops *ops;
3263 struct prism2_crypt_data **crypt;
3264 void *sta_ptr;
3265 u8 *addr;
3266 const char *alg, *module;
3267
3268 i = erq->flags & IW_ENCODE_INDEX;
3269 if (i > WEP_KEYS)
3270 return -EINVAL;
3271 if (i < 1 || i > WEP_KEYS)
3272 i = local->tx_keyidx;
3273 else
3274 i--;
3275 if (i < 0 || i >= WEP_KEYS)
3276 return -EINVAL;
3277
3278 addr = ext->addr.sa_data;
3279 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3280 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3281 sta_ptr = NULL;
3282 crypt = &local->crypt[i];
3283 } else {
3284 if (i != 0)
3285 return -EINVAL;
3286 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3287 if (sta_ptr == NULL) {
3288 if (local->iw_mode == IW_MODE_INFRA) {
3289 /*
3290 * TODO: add STA entry for the current AP so
3291 * that unicast key can be used. For now, this
3292 * is emulated by using default key idx 0.
3293 */
3294 i = 0;
3295 crypt = &local->crypt[i];
3296 } else
3297 return -EINVAL;
3298 }
3299 }
3300
3301 if ((erq->flags & IW_ENCODE_DISABLED) ||
3302 ext->alg == IW_ENCODE_ALG_NONE) {
3303 if (*crypt)
3304 prism2_crypt_delayed_deinit(local, crypt);
3305 goto done;
3306 }
3307
3308 switch (ext->alg) {
3309 case IW_ENCODE_ALG_WEP:
3310 alg = "WEP";
3311 module = "hostap_crypt_wep";
3312 break;
3313 case IW_ENCODE_ALG_TKIP:
3314 alg = "TKIP";
3315 module = "hostap_crypt_tkip";
3316 break;
3317 case IW_ENCODE_ALG_CCMP:
3318 alg = "CCMP";
3319 module = "hostap_crypt_ccmp";
3320 break;
3321 default:
3322 printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
3323 local->dev->name, ext->alg);
3324 ret = -EOPNOTSUPP;
3325 goto done;
3326 }
3327
3328 ops = hostap_get_crypto_ops(alg);
3329 if (ops == NULL) {
3330 request_module(module);
3331 ops = hostap_get_crypto_ops(alg);
3332 }
3333 if (ops == NULL) {
3334 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3335 local->dev->name, alg);
3336 ret = -EOPNOTSUPP;
3337 goto done;
3338 }
3339
3340 if (sta_ptr || ext->alg != IW_ENCODE_ALG_WEP) {
3341 /*
3342 * Per station encryption and other than WEP algorithms
3343 * require host-based encryption, so force them on
3344 * automatically.
3345 */
3346 local->host_decrypt = local->host_encrypt = 1;
3347 }
3348
3349 if (*crypt == NULL || (*crypt)->ops != ops) {
3350 struct prism2_crypt_data *new_crypt;
3351
3352 prism2_crypt_delayed_deinit(local, crypt);
3353
3354 new_crypt = (struct prism2_crypt_data *)
3355 kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL);
3356 if (new_crypt == NULL) {
3357 ret = -ENOMEM;
3358 goto done;
3359 }
3360 memset(new_crypt, 0, sizeof(struct prism2_crypt_data));
3361 new_crypt->ops = ops;
3362 new_crypt->priv = new_crypt->ops->init(i);
3363 if (new_crypt->priv == NULL) {
3364 kfree(new_crypt);
3365 ret = -EINVAL;
3366 goto done;
3367 }
3368
3369 *crypt = new_crypt;
3370 }
3371
3372 /*
3373 * TODO: if ext_flags does not have IW_ENCODE_EXT_RX_SEQ_VALID, the
3374 * existing seq# should not be changed.
3375 * TODO: if ext_flags has IW_ENCODE_EXT_TX_SEQ_VALID, next TX seq#
3376 * should be changed to something else than zero.
3377 */
3378 if ((!(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) || ext->key_len > 0)
3379 && (*crypt)->ops->set_key &&
3380 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
3381 (*crypt)->priv) < 0) {
3382 printk(KERN_DEBUG "%s: key setting failed\n",
3383 local->dev->name);
3384 ret = -EINVAL;
3385 goto done;
3386 }
3387
3388 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3389 if (!sta_ptr)
3390 local->tx_keyidx = i;
3391 else if (i) {
3392 ret = -EINVAL;
3393 goto done;
3394 }
3395 }
3396
3397
3398 if (sta_ptr == NULL && ext->key_len > 0) {
3399 int first = 1, j;
3400 for (j = 0; j < WEP_KEYS; j++) {
3401 if (j != i && local->crypt[j]) {
3402 first = 0;
3403 break;
3404 }
3405 }
3406 if (first)
3407 local->tx_keyidx = i;
3408 }
3409
3410 done:
3411 if (sta_ptr)
3412 hostap_handle_sta_release(sta_ptr);
3413
3414 local->open_wep = erq->flags & IW_ENCODE_OPEN;
3415
3416 /*
3417 * Do not reset port0 if card is in Managed mode since resetting will
3418 * generate new IEEE 802.11 authentication which may end up in looping
3419 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3420 * after WEP configuration. However, keys are apparently changed at
3421 * least in Managed mode.
3422 */
3423 if (ret == 0 &&
3424 (hostap_set_encryption(local) ||
3425 (local->iw_mode != IW_MODE_INFRA &&
3426 local->func->reset_port(local->dev))))
3427 ret = -EINVAL;
3428
3429 return ret;
3430}
3431
3432
3433static int prism2_ioctl_giwencodeext(struct net_device *dev,
3434 struct iw_request_info *info,
3435 struct iw_point *erq, char *extra)
3436{
3437 struct hostap_interface *iface = dev->priv;
3438 local_info_t *local = iface->local;
3439 struct prism2_crypt_data **crypt;
3440 void *sta_ptr;
3441 int max_key_len, i;
3442 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3443 u8 *addr;
3444
3445 max_key_len = erq->length - sizeof(*ext);
3446 if (max_key_len < 0)
3447 return -EINVAL;
3448
3449 i = erq->flags & IW_ENCODE_INDEX;
3450 if (i < 1 || i > WEP_KEYS)
3451 i = local->tx_keyidx;
3452 else
3453 i--;
3454
3455 addr = ext->addr.sa_data;
3456 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3457 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3458 sta_ptr = NULL;
3459 crypt = &local->crypt[i];
3460 } else {
3461 i = 0;
3462 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3463 if (sta_ptr == NULL)
3464 return -EINVAL;
3465 }
3466 erq->flags = i + 1;
3467 memset(ext, 0, sizeof(*ext));
3468
3469 if (*crypt == NULL || (*crypt)->ops == NULL) {
3470 ext->alg = IW_ENCODE_ALG_NONE;
3471 ext->key_len = 0;
3472 erq->flags |= IW_ENCODE_DISABLED;
3473 } else {
3474 if (strcmp((*crypt)->ops->name, "WEP") == 0)
3475 ext->alg = IW_ENCODE_ALG_WEP;
3476 else if (strcmp((*crypt)->ops->name, "TKIP") == 0)
3477 ext->alg = IW_ENCODE_ALG_TKIP;
3478 else if (strcmp((*crypt)->ops->name, "CCMP") == 0)
3479 ext->alg = IW_ENCODE_ALG_CCMP;
3480 else
3481 return -EINVAL;
3482
3483 if ((*crypt)->ops->get_key) {
3484 ext->key_len =
3485 (*crypt)->ops->get_key(ext->key,
3486 max_key_len,
3487 ext->tx_seq,
3488 (*crypt)->priv);
3489 if (ext->key_len &&
3490 (ext->alg == IW_ENCODE_ALG_TKIP ||
3491 ext->alg == IW_ENCODE_ALG_CCMP))
3492 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
3493 }
3494 }
3495
3496 if (sta_ptr)
3497 hostap_handle_sta_release(sta_ptr);
3498
3499 return 0;
3500}
3501
3502
3503static int prism2_ioctl_set_encryption(local_info_t *local,
3504 struct prism2_hostapd_param *param,
3505 int param_len)
3506{
3507 int ret = 0;
3508 struct hostap_crypto_ops *ops;
3509 struct prism2_crypt_data **crypt;
3510 void *sta_ptr;
3511
3512 param->u.crypt.err = 0;
3513 param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0';
3514
3515 if (param_len !=
3516 (int) ((char *) param->u.crypt.key - (char *) param) +
3517 param->u.crypt.key_len)
3518 return -EINVAL;
3519
3520 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3521 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3522 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3523 if (param->u.crypt.idx >= WEP_KEYS)
3524 return -EINVAL;
3525 sta_ptr = NULL;
3526 crypt = &local->crypt[param->u.crypt.idx];
3527 } else {
3528 if (param->u.crypt.idx)
3529 return -EINVAL;
3530 sta_ptr = ap_crypt_get_ptrs(
3531 local->ap, param->sta_addr,
3532 (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_PERMANENT),
3533 &crypt);
3534
3535 if (sta_ptr == NULL) {
3536 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3537 return -EINVAL;
3538 }
3539 }
3540
3541 if (strcmp(param->u.crypt.alg, "none") == 0) {
3542 if (crypt)
3543 prism2_crypt_delayed_deinit(local, crypt);
3544 goto done;
3545 }
3546
3547 ops = hostap_get_crypto_ops(param->u.crypt.alg);
3548 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3549 request_module("hostap_crypt_wep");
3550 ops = hostap_get_crypto_ops(param->u.crypt.alg);
3551 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3552 request_module("hostap_crypt_tkip");
3553 ops = hostap_get_crypto_ops(param->u.crypt.alg);
3554 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3555 request_module("hostap_crypt_ccmp");
3556 ops = hostap_get_crypto_ops(param->u.crypt.alg);
3557 }
3558 if (ops == NULL) {
3559 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3560 local->dev->name, param->u.crypt.alg);
3561 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG;
3562 ret = -EINVAL;
3563 goto done;
3564 }
3565
3566 /* station based encryption and other than WEP algorithms require
3567 * host-based encryption, so force them on automatically */
3568 local->host_decrypt = local->host_encrypt = 1;
3569
3570 if (*crypt == NULL || (*crypt)->ops != ops) {
3571 struct prism2_crypt_data *new_crypt;
3572
3573 prism2_crypt_delayed_deinit(local, crypt);
3574
3575 new_crypt = (struct prism2_crypt_data *)
3576 kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL);
3577 if (new_crypt == NULL) {
3578 ret = -ENOMEM;
3579 goto done;
3580 }
3581 memset(new_crypt, 0, sizeof(struct prism2_crypt_data));
3582 new_crypt->ops = ops;
3583 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
3584 if (new_crypt->priv == NULL) {
3585 kfree(new_crypt);
3586 param->u.crypt.err =
3587 HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED;
3588 ret = -EINVAL;
3589 goto done;
3590 }
3591
3592 *crypt = new_crypt;
3593 }
3594
3595 if ((!(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) ||
3596 param->u.crypt.key_len > 0) && (*crypt)->ops->set_key &&
3597 (*crypt)->ops->set_key(param->u.crypt.key,
3598 param->u.crypt.key_len, param->u.crypt.seq,
3599 (*crypt)->priv) < 0) {
3600 printk(KERN_DEBUG "%s: key setting failed\n",
3601 local->dev->name);
3602 param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
3603 ret = -EINVAL;
3604 goto done;
3605 }
3606
3607 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
3608 if (!sta_ptr)
3609 local->tx_keyidx = param->u.crypt.idx;
3610 else if (param->u.crypt.idx) {
3611 printk(KERN_DEBUG "%s: TX key idx setting failed\n",
3612 local->dev->name);
3613 param->u.crypt.err =
3614 HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED;
3615 ret = -EINVAL;
3616 goto done;
3617 }
3618 }
3619
3620 done:
3621 if (sta_ptr)
3622 hostap_handle_sta_release(sta_ptr);
3623
3624 /* Do not reset port0 if card is in Managed mode since resetting will
3625 * generate new IEEE 802.11 authentication which may end up in looping
3626 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3627 * after WEP configuration. However, keys are apparently changed at
3628 * least in Managed mode. */
3629 if (ret == 0 &&
3630 (hostap_set_encryption(local) ||
3631 (local->iw_mode != IW_MODE_INFRA &&
3632 local->func->reset_port(local->dev)))) {
3633 param->u.crypt.err = HOSTAP_CRYPT_ERR_CARD_CONF_FAILED;
3634 return -EINVAL;
3635 }
3636
3637 return ret;
3638}
3639
3640
3641static int prism2_ioctl_get_encryption(local_info_t *local,
3642 struct prism2_hostapd_param *param,
3643 int param_len)
3644{
3645 struct prism2_crypt_data **crypt;
3646 void *sta_ptr;
3647 int max_key_len;
3648
3649 param->u.crypt.err = 0;
3650
3651 max_key_len = param_len -
3652 (int) ((char *) param->u.crypt.key - (char *) param);
3653 if (max_key_len < 0)
3654 return -EINVAL;
3655
3656 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3657 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3658 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3659 sta_ptr = NULL;
3660 if (param->u.crypt.idx >= WEP_KEYS)
3661 param->u.crypt.idx = local->tx_keyidx;
3662 crypt = &local->crypt[param->u.crypt.idx];
3663 } else {
3664 param->u.crypt.idx = 0;
3665 sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
3666 &crypt);
3667
3668 if (sta_ptr == NULL) {
3669 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3670 return -EINVAL;
3671 }
3672 }
3673
3674 if (*crypt == NULL || (*crypt)->ops == NULL) {
3675 memcpy(param->u.crypt.alg, "none", 5);
3676 param->u.crypt.key_len = 0;
3677 param->u.crypt.idx = 0xff;
3678 } else {
3679 strncpy(param->u.crypt.alg, (*crypt)->ops->name,
3680 HOSTAP_CRYPT_ALG_NAME_LEN);
3681 param->u.crypt.key_len = 0;
3682
3683 memset(param->u.crypt.seq, 0, 8);
3684 if ((*crypt)->ops->get_key) {
3685 param->u.crypt.key_len =
3686 (*crypt)->ops->get_key(param->u.crypt.key,
3687 max_key_len,
3688 param->u.crypt.seq,
3689 (*crypt)->priv);
3690 }
3691 }
3692
3693 if (sta_ptr)
3694 hostap_handle_sta_release(sta_ptr);
3695
3696 return 0;
3697}
3698
3699
3700static int prism2_ioctl_get_rid(local_info_t *local,
3701 struct prism2_hostapd_param *param,
3702 int param_len)
3703{
3704 int max_len, res;
3705
3706 max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3707 if (max_len < 0)
3708 return -EINVAL;
3709
3710 res = local->func->get_rid(local->dev, param->u.rid.rid,
3711 param->u.rid.data, param->u.rid.len, 0);
3712 if (res >= 0) {
3713 param->u.rid.len = res;
3714 return 0;
3715 }
3716
3717 return res;
3718}
3719
3720
3721static int prism2_ioctl_set_rid(local_info_t *local,
3722 struct prism2_hostapd_param *param,
3723 int param_len)
3724{
3725 int max_len;
3726
3727 max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3728 if (max_len < 0 || max_len < param->u.rid.len)
3729 return -EINVAL;
3730
3731 return local->func->set_rid(local->dev, param->u.rid.rid,
3732 param->u.rid.data, param->u.rid.len);
3733}
3734
3735
3736static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local,
3737 struct prism2_hostapd_param *param,
3738 int param_len)
3739{
3740 printk(KERN_DEBUG "%ssta: associated as client with AP " MACSTR "\n",
3741 local->dev->name, MAC2STR(param->sta_addr));
3742 memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN);
3743 return 0;
3744}
3745
3746
3747static int prism2_ioctl_siwgenie(struct net_device *dev,
3748 struct iw_request_info *info,
3749 struct iw_point *data, char *extra)
3750{
3751 return prism2_set_genericelement(dev, extra, data->length);
3752}
3753
3754
3755static int prism2_ioctl_giwgenie(struct net_device *dev,
3756 struct iw_request_info *info,
3757 struct iw_point *data, char *extra)
3758{
3759 struct hostap_interface *iface = dev->priv;
3760 local_info_t *local = iface->local;
3761 int len = local->generic_elem_len - 2;
3762
3763 if (len <= 0 || local->generic_elem == NULL) {
3764 data->length = 0;
3765 return 0;
3766 }
3767
3768 if (data->length < len)
3769 return -E2BIG;
3770
3771 data->length = len;
3772 memcpy(extra, local->generic_elem + 2, len);
3773
3774 return 0;
3775}
3776
3777
3778static int prism2_ioctl_set_generic_element(local_info_t *local,
3779 struct prism2_hostapd_param *param,
3780 int param_len)
3781{
3782 int max_len, len;
3783
3784 len = param->u.generic_elem.len;
3785 max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
3786 if (max_len < 0 || max_len < len)
3787 return -EINVAL;
3788
3789 return prism2_set_genericelement(local->dev,
3790 param->u.generic_elem.data, len);
3791}
3792
3793
3794static int prism2_ioctl_siwmlme(struct net_device *dev,
3795 struct iw_request_info *info,
3796 struct iw_point *data, char *extra)
3797{
3798 struct hostap_interface *iface = dev->priv;
3799 local_info_t *local = iface->local;
3800 struct iw_mlme *mlme = (struct iw_mlme *) extra;
3801 u16 reason;
3802
3803 reason = cpu_to_le16(mlme->reason_code);
3804
3805 switch (mlme->cmd) {
3806 case IW_MLME_DEAUTH:
3807 return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3808 WLAN_FC_STYPE_DEAUTH,
3809 (u8 *) &reason, 2);
3810 case IW_MLME_DISASSOC:
3811 return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3812 WLAN_FC_STYPE_DISASSOC,
3813 (u8 *) &reason, 2);
3814 default:
3815 return -EOPNOTSUPP;
3816 }
3817}
3818
3819
3820static int prism2_ioctl_mlme(local_info_t *local,
3821 struct prism2_hostapd_param *param)
3822{
3823 u16 reason;
3824
3825 reason = cpu_to_le16(param->u.mlme.reason_code);
3826 switch (param->u.mlme.cmd) {
3827 case MLME_STA_DEAUTH:
3828 return prism2_sta_send_mgmt(local, param->sta_addr,
3829 WLAN_FC_STYPE_DEAUTH,
3830 (u8 *) &reason, 2);
3831 case MLME_STA_DISASSOC:
3832 return prism2_sta_send_mgmt(local, param->sta_addr,
3833 WLAN_FC_STYPE_DISASSOC,
3834 (u8 *) &reason, 2);
3835 default:
3836 return -EOPNOTSUPP;
3837 }
3838}
3839
3840
3841static int prism2_ioctl_scan_req(local_info_t *local,
3842 struct prism2_hostapd_param *param)
3843{
3844#ifndef PRISM2_NO_STATION_MODES
3845 if ((local->iw_mode != IW_MODE_INFRA &&
3846 local->iw_mode != IW_MODE_ADHOC) ||
3847 (local->sta_fw_ver < PRISM2_FW_VER(1,3,1)))
3848 return -EOPNOTSUPP;
3849
3850 if (!local->dev_enabled)
3851 return -ENETDOWN;
3852
3853 return prism2_request_hostscan(local->dev, param->u.scan_req.ssid,
3854 param->u.scan_req.ssid_len);
3855#else /* PRISM2_NO_STATION_MODES */
3856 return -EOPNOTSUPP;
3857#endif /* PRISM2_NO_STATION_MODES */
3858}
3859
3860
3861static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
3862{
3863 struct prism2_hostapd_param *param;
3864 int ret = 0;
3865 int ap_ioctl = 0;
3866
3867 if (p->length < sizeof(struct prism2_hostapd_param) ||
3868 p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
3869 return -EINVAL;
3870
3871 param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
3872 if (param == NULL)
3873 return -ENOMEM;
3874
3875 if (copy_from_user(param, p->pointer, p->length)) {
3876 ret = -EFAULT;
3877 goto out;
3878 }
3879
3880 switch (param->cmd) {
3881 case PRISM2_SET_ENCRYPTION:
3882 ret = prism2_ioctl_set_encryption(local, param, p->length);
3883 break;
3884 case PRISM2_GET_ENCRYPTION:
3885 ret = prism2_ioctl_get_encryption(local, param, p->length);
3886 break;
3887 case PRISM2_HOSTAPD_GET_RID:
3888 ret = prism2_ioctl_get_rid(local, param, p->length);
3889 break;
3890 case PRISM2_HOSTAPD_SET_RID:
3891 ret = prism2_ioctl_set_rid(local, param, p->length);
3892 break;
3893 case PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR:
3894 ret = prism2_ioctl_set_assoc_ap_addr(local, param, p->length);
3895 break;
3896 case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
3897 ret = prism2_ioctl_set_generic_element(local, param,
3898 p->length);
3899 break;
3900 case PRISM2_HOSTAPD_MLME:
3901 ret = prism2_ioctl_mlme(local, param);
3902 break;
3903 case PRISM2_HOSTAPD_SCAN_REQ:
3904 ret = prism2_ioctl_scan_req(local, param);
3905 break;
3906 default:
3907 ret = prism2_hostapd(local->ap, param);
3908 ap_ioctl = 1;
3909 break;
3910 }
3911
3912 if (ret == 1 || !ap_ioctl) {
3913 if (copy_to_user(p->pointer, param, p->length)) {
3914 ret = -EFAULT;
3915 goto out;
3916 } else if (ap_ioctl)
3917 ret = 0;
3918 }
3919
3920 out:
3921 if (param != NULL)
3922 kfree(param);
3923
3924 return ret;
3925}
3926
3927
3928static void prism2_get_drvinfo(struct net_device *dev,
3929 struct ethtool_drvinfo *info)
3930{
3931 struct hostap_interface *iface;
3932 local_info_t *local;
3933
3934 iface = netdev_priv(dev);
3935 local = iface->local;
3936
3937 strncpy(info->driver, "hostap", sizeof(info->driver) - 1);
3938 strncpy(info->version, PRISM2_VERSION,
3939 sizeof(info->version) - 1);
3940 snprintf(info->fw_version, sizeof(info->fw_version) - 1,
3941 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
3942 (local->sta_fw_ver >> 8) & 0xff,
3943 local->sta_fw_ver & 0xff);
3944}
3945
3946static struct ethtool_ops prism2_ethtool_ops = {
3947 .get_drvinfo = prism2_get_drvinfo
3948};
3949
3950
3951/* Structures to export the Wireless Handlers */
3952
3953static const iw_handler prism2_handler[] =
3954{
3955 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3956 (iw_handler) prism2_get_name, /* SIOCGIWNAME */
3957 (iw_handler) NULL, /* SIOCSIWNWID */
3958 (iw_handler) NULL, /* SIOCGIWNWID */
3959 (iw_handler) prism2_ioctl_siwfreq, /* SIOCSIWFREQ */
3960 (iw_handler) prism2_ioctl_giwfreq, /* SIOCGIWFREQ */
3961 (iw_handler) prism2_ioctl_siwmode, /* SIOCSIWMODE */
3962 (iw_handler) prism2_ioctl_giwmode, /* SIOCGIWMODE */
3963 (iw_handler) prism2_ioctl_siwsens, /* SIOCSIWSENS */
3964 (iw_handler) prism2_ioctl_giwsens, /* SIOCGIWSENS */
3965 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3966 (iw_handler) prism2_ioctl_giwrange, /* SIOCGIWRANGE */
3967 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3968 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3969 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3970 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
3971 iw_handler_set_spy, /* SIOCSIWSPY */
3972 iw_handler_get_spy, /* SIOCGIWSPY */
3973 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
3974 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
3975 (iw_handler) prism2_ioctl_siwap, /* SIOCSIWAP */
3976 (iw_handler) prism2_ioctl_giwap, /* SIOCGIWAP */
3977 (iw_handler) prism2_ioctl_siwmlme, /* SIOCSIWMLME */
3978 (iw_handler) prism2_ioctl_giwaplist, /* SIOCGIWAPLIST */
3979 (iw_handler) prism2_ioctl_siwscan, /* SIOCSIWSCAN */
3980 (iw_handler) prism2_ioctl_giwscan, /* SIOCGIWSCAN */
3981 (iw_handler) prism2_ioctl_siwessid, /* SIOCSIWESSID */
3982 (iw_handler) prism2_ioctl_giwessid, /* SIOCGIWESSID */
3983 (iw_handler) prism2_ioctl_siwnickn, /* SIOCSIWNICKN */
3984 (iw_handler) prism2_ioctl_giwnickn, /* SIOCGIWNICKN */
3985 (iw_handler) NULL, /* -- hole -- */
3986 (iw_handler) NULL, /* -- hole -- */
3987 (iw_handler) prism2_ioctl_siwrate, /* SIOCSIWRATE */
3988 (iw_handler) prism2_ioctl_giwrate, /* SIOCGIWRATE */
3989 (iw_handler) prism2_ioctl_siwrts, /* SIOCSIWRTS */
3990 (iw_handler) prism2_ioctl_giwrts, /* SIOCGIWRTS */
3991 (iw_handler) prism2_ioctl_siwfrag, /* SIOCSIWFRAG */
3992 (iw_handler) prism2_ioctl_giwfrag, /* SIOCGIWFRAG */
3993 (iw_handler) prism2_ioctl_siwtxpow, /* SIOCSIWTXPOW */
3994 (iw_handler) prism2_ioctl_giwtxpow, /* SIOCGIWTXPOW */
3995 (iw_handler) prism2_ioctl_siwretry, /* SIOCSIWRETRY */
3996 (iw_handler) prism2_ioctl_giwretry, /* SIOCGIWRETRY */
3997 (iw_handler) prism2_ioctl_siwencode, /* SIOCSIWENCODE */
3998 (iw_handler) prism2_ioctl_giwencode, /* SIOCGIWENCODE */
3999 (iw_handler) prism2_ioctl_siwpower, /* SIOCSIWPOWER */
4000 (iw_handler) prism2_ioctl_giwpower, /* SIOCGIWPOWER */
4001 (iw_handler) NULL, /* -- hole -- */
4002 (iw_handler) NULL, /* -- hole -- */
4003 (iw_handler) prism2_ioctl_siwgenie, /* SIOCSIWGENIE */
4004 (iw_handler) prism2_ioctl_giwgenie, /* SIOCGIWGENIE */
4005 (iw_handler) prism2_ioctl_siwauth, /* SIOCSIWAUTH */
4006 (iw_handler) prism2_ioctl_giwauth, /* SIOCGIWAUTH */
4007 (iw_handler) prism2_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
4008 (iw_handler) prism2_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
4009 (iw_handler) NULL, /* SIOCSIWPMKSA */
4010 (iw_handler) NULL, /* -- hole -- */
4011};
4012
4013static const iw_handler prism2_private_handler[] =
4014{ /* SIOCIWFIRSTPRIV + */
4015 (iw_handler) prism2_ioctl_priv_prism2_param, /* 0 */
4016 (iw_handler) prism2_ioctl_priv_get_prism2_param, /* 1 */
4017 (iw_handler) prism2_ioctl_priv_writemif, /* 2 */
4018 (iw_handler) prism2_ioctl_priv_readmif, /* 3 */
4019};
4020
4021static const struct iw_handler_def hostap_iw_handler_def =
4022{
4023 .num_standard = sizeof(prism2_handler) / sizeof(iw_handler),
4024 .num_private = sizeof(prism2_private_handler) / sizeof(iw_handler),
4025 .num_private_args = sizeof(prism2_priv) / sizeof(struct iw_priv_args),
4026 .standard = (iw_handler *) prism2_handler,
4027 .private = (iw_handler *) prism2_private_handler,
4028 .private_args = (struct iw_priv_args *) prism2_priv,
4029 .get_wireless_stats = hostap_get_wireless_stats,
4030};
4031
4032
4033int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4034{
4035 struct iwreq *wrq = (struct iwreq *) ifr;
4036 struct hostap_interface *iface;
4037 local_info_t *local;
4038 int ret = 0;
4039
4040 iface = netdev_priv(dev);
4041 local = iface->local;
4042
4043 switch (cmd) {
4044 /* Private ioctls (iwpriv) that have not yet been converted
4045 * into new wireless extensions API */
4046
4047 case PRISM2_IOCTL_INQUIRE:
4048 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4049 else ret = prism2_ioctl_priv_inquire(dev, (int *) wrq->u.name);
4050 break;
4051
4052 case PRISM2_IOCTL_MONITOR:
4053 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4054 else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name);
4055 break;
4056
4057 case PRISM2_IOCTL_RESET:
4058 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4059 else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name);
4060 break;
4061
4062 case PRISM2_IOCTL_WDS_ADD:
4063 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4064 else ret = prism2_wds_add(local, wrq->u.ap_addr.sa_data, 1);
4065 break;
4066
4067 case PRISM2_IOCTL_WDS_DEL:
4068 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4069 else ret = prism2_wds_del(local, wrq->u.ap_addr.sa_data, 1, 0);
4070 break;
4071
4072 case PRISM2_IOCTL_SET_RID_WORD:
4073 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4074 else ret = prism2_ioctl_priv_set_rid_word(dev,
4075 (int *) wrq->u.name);
4076 break;
4077
4078#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
4079 case PRISM2_IOCTL_MACCMD:
4080 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4081 else ret = ap_mac_cmd_ioctl(local, (int *) wrq->u.name);
4082 break;
4083
4084 case PRISM2_IOCTL_ADDMAC:
4085 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4086 else ret = ap_control_add_mac(&local->ap->mac_restrictions,
4087 wrq->u.ap_addr.sa_data);
4088 break;
4089 case PRISM2_IOCTL_DELMAC:
4090 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4091 else ret = ap_control_del_mac(&local->ap->mac_restrictions,
4092 wrq->u.ap_addr.sa_data);
4093 break;
4094 case PRISM2_IOCTL_KICKMAC:
4095 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4096 else ret = ap_control_kick_mac(local->ap, local->dev,
4097 wrq->u.ap_addr.sa_data);
4098 break;
4099#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
4100
4101
4102 /* Private ioctls that are not used with iwpriv;
4103 * in SIOCDEVPRIVATE range */
4104
4105#ifdef PRISM2_DOWNLOAD_SUPPORT
4106 case PRISM2_IOCTL_DOWNLOAD:
4107 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4108 else ret = prism2_ioctl_priv_download(local, &wrq->u.data);
4109 break;
4110#endif /* PRISM2_DOWNLOAD_SUPPORT */
4111
4112 case PRISM2_IOCTL_HOSTAPD:
4113 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4114 else ret = prism2_ioctl_priv_hostapd(local, &wrq->u.data);
4115 break;
4116
4117 default:
4118 ret = -EOPNOTSUPP;
4119 break;
4120 }
4121
4122 return ret;
4123}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
new file mode 100644
index 000000000000..3a208989333e
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -0,0 +1,453 @@
1#define PRISM2_PCI
2
3/* Host AP driver's support for Intersil Prism2.5 PCI cards is based on
4 * driver patches from Reyk Floeter <reyk@vantronix.net> and
5 * Andy Warner <andyw@pobox.com> */
6
7#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/if.h>
12#include <linux/skbuff.h>
13#include <linux/netdevice.h>
14#include <linux/workqueue.h>
15#include <linux/wireless.h>
16#include <net/iw_handler.h>
17
18#include <linux/ioport.h>
19#include <linux/pci.h>
20#include <asm/io.h>
21
22#include "hostap_wlan.h"
23
24
25static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
26static char *dev_info = "hostap_pci";
27
28
29MODULE_AUTHOR("Jouni Malinen");
30MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN "
31 "PCI cards.");
32MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards");
33MODULE_LICENSE("GPL");
34
35
36/* FIX: do we need mb/wmb/rmb with memory operations? */
37
38
39static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
40 /* Intersil Prism3 ISL3872 11Mb/s WLAN Controller */
41 { 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID },
42 /* Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller */
43 { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID },
44 /* Samsung MagicLAN SWL-2210P */
45 { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID },
46 { 0 }
47};
48
49
50#ifdef PRISM2_IO_DEBUG
51
52static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
53{
54 struct hostap_interface *iface;
55 local_info_t *local;
56 unsigned long flags;
57
58 iface = netdev_priv(dev);
59 local = iface->local;
60
61 spin_lock_irqsave(&local->lock, flags);
62 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
63 writeb(v, local->mem_start + a);
64 spin_unlock_irqrestore(&local->lock, flags);
65}
66
67static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
68{
69 struct hostap_interface *iface;
70 local_info_t *local;
71 unsigned long flags;
72 u8 v;
73
74 iface = netdev_priv(dev);
75 local = iface->local;
76
77 spin_lock_irqsave(&local->lock, flags);
78 v = readb(local->mem_start + a);
79 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
80 spin_unlock_irqrestore(&local->lock, flags);
81 return v;
82}
83
84static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
85{
86 struct hostap_interface *iface;
87 local_info_t *local;
88 unsigned long flags;
89
90 iface = netdev_priv(dev);
91 local = iface->local;
92
93 spin_lock_irqsave(&local->lock, flags);
94 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
95 writew(v, local->mem_start + a);
96 spin_unlock_irqrestore(&local->lock, flags);
97}
98
99static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
100{
101 struct hostap_interface *iface;
102 local_info_t *local;
103 unsigned long flags;
104 u16 v;
105
106 iface = netdev_priv(dev);
107 local = iface->local;
108
109 spin_lock_irqsave(&local->lock, flags);
110 v = readw(local->mem_start + a);
111 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
112 spin_unlock_irqrestore(&local->lock, flags);
113 return v;
114}
115
116#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
117#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
118#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
119#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
120#define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), cpu_to_le16((v)))
121#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw_debug(dev, (a)))
122
123#else /* PRISM2_IO_DEBUG */
124
125static inline void hfa384x_outb(struct net_device *dev, int a, u8 v)
126{
127 struct hostap_interface *iface;
128 local_info_t *local;
129 iface = netdev_priv(dev);
130 local = iface->local;
131 writeb(v, local->mem_start + a);
132}
133
134static inline u8 hfa384x_inb(struct net_device *dev, int a)
135{
136 struct hostap_interface *iface;
137 local_info_t *local;
138 iface = netdev_priv(dev);
139 local = iface->local;
140 return readb(local->mem_start + a);
141}
142
143static inline void hfa384x_outw(struct net_device *dev, int a, u16 v)
144{
145 struct hostap_interface *iface;
146 local_info_t *local;
147 iface = netdev_priv(dev);
148 local = iface->local;
149 writew(v, local->mem_start + a);
150}
151
152static inline u16 hfa384x_inw(struct net_device *dev, int a)
153{
154 struct hostap_interface *iface;
155 local_info_t *local;
156 iface = netdev_priv(dev);
157 local = iface->local;
158 return readw(local->mem_start + a);
159}
160
161#define HFA384X_OUTB(v,a) hfa384x_outb(dev, (a), (v))
162#define HFA384X_INB(a) hfa384x_inb(dev, (a))
163#define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v))
164#define HFA384X_INW(a) hfa384x_inw(dev, (a))
165#define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), cpu_to_le16((v)))
166#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw(dev, (a)))
167
168#endif /* PRISM2_IO_DEBUG */
169
170
171static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
172 int len)
173{
174 u16 d_off;
175 u16 *pos;
176
177 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
178 pos = (u16 *) buf;
179
180 for ( ; len > 1; len -= 2)
181 *pos++ = HFA384X_INW_DATA(d_off);
182
183 if (len & 1)
184 *((char *) pos) = HFA384X_INB(d_off);
185
186 return 0;
187}
188
189
190static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
191{
192 u16 d_off;
193 u16 *pos;
194
195 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
196 pos = (u16 *) buf;
197
198 for ( ; len > 1; len -= 2)
199 HFA384X_OUTW_DATA(*pos++, d_off);
200
201 if (len & 1)
202 HFA384X_OUTB(*((char *) pos), d_off);
203
204 return 0;
205}
206
207
208/* FIX: This might change at some point.. */
209#include "hostap_hw.c"
210
211static void prism2_pci_cor_sreset(local_info_t *local)
212{
213 struct net_device *dev = local->dev;
214 u16 reg;
215
216 reg = HFA384X_INB(HFA384X_PCICOR_OFF);
217 printk(KERN_DEBUG "%s: Original COR value: 0x%0x\n", dev->name, reg);
218
219 /* linux-wlan-ng uses extremely long hold and settle times for
220 * COR sreset. A comment in the driver code mentions that the long
221 * delays appear to be necessary. However, at least IBM 22P6901 seems
222 * to work fine with shorter delays.
223 *
224 * Longer delays can be configured by uncommenting following line: */
225/* #define PRISM2_PCI_USE_LONG_DELAYS */
226
227#ifdef PRISM2_PCI_USE_LONG_DELAYS
228 int i;
229
230 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
231 mdelay(250);
232
233 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
234 mdelay(500);
235
236 /* Wait for f/w to complete initialization (CMD:BUSY == 0) */
237 i = 2000000 / 10;
238 while ((HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) && --i)
239 udelay(10);
240
241#else /* PRISM2_PCI_USE_LONG_DELAYS */
242
243 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
244 mdelay(2);
245 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
246 mdelay(2);
247
248#endif /* PRISM2_PCI_USE_LONG_DELAYS */
249
250 if (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) {
251 printk(KERN_DEBUG "%s: COR sreset timeout\n", dev->name);
252 }
253}
254
255
256static void prism2_pci_genesis_reset(local_info_t *local, int hcr)
257{
258 struct net_device *dev = local->dev;
259
260 HFA384X_OUTW(0x00C5, HFA384X_PCICOR_OFF);
261 mdelay(10);
262 HFA384X_OUTW(hcr, HFA384X_PCIHCR_OFF);
263 mdelay(10);
264 HFA384X_OUTW(0x0045, HFA384X_PCICOR_OFF);
265 mdelay(10);
266}
267
268
269static struct prism2_helper_functions prism2_pci_funcs =
270{
271 .card_present = NULL,
272 .cor_sreset = prism2_pci_cor_sreset,
273 .dev_open = NULL,
274 .dev_close = NULL,
275 .genesis_reset = prism2_pci_genesis_reset,
276 .hw_type = HOSTAP_HW_PCI,
277};
278
279
280static int prism2_pci_probe(struct pci_dev *pdev,
281 const struct pci_device_id *id)
282{
283 unsigned long phymem;
284 void __iomem *mem = NULL;
285 local_info_t *local = NULL;
286 struct net_device *dev = NULL;
287 static int cards_found /* = 0 */;
288 int irq_registered = 0;
289 struct hostap_interface *iface;
290
291 if (pci_enable_device(pdev))
292 return -EIO;
293
294 phymem = pci_resource_start(pdev, 0);
295
296 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
297 printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
298 goto err_out_disable;
299 }
300
301 mem = ioremap(phymem, pci_resource_len(pdev, 0));
302 if (mem == NULL) {
303 printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ;
304 goto fail;
305 }
306
307#ifdef PRISM2_BUS_MASTER
308 pci_set_master(pdev);
309#endif /* PRISM2_BUS_MASTER */
310
311 dev = prism2_init_local_data(&prism2_pci_funcs, cards_found);
312 if (dev == NULL)
313 goto fail;
314 iface = netdev_priv(dev);
315 local = iface->local;
316 cards_found++;
317
318 dev->irq = pdev->irq;
319 local->mem_start = mem;
320
321 prism2_pci_cor_sreset(local);
322
323 pci_set_drvdata(pdev, dev);
324
325 if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name,
326 dev)) {
327 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
328 goto fail;
329 } else
330 irq_registered = 1;
331
332 if (!local->pri_only && prism2_hw_config(dev, 1)) {
333 printk(KERN_DEBUG "%s: hardware initialization failed\n",
334 dev_info);
335 goto fail;
336 }
337
338 printk(KERN_INFO "%s: Intersil Prism2.5 PCI: "
339 "mem=0x%lx, irq=%d\n", dev->name, phymem, dev->irq);
340
341 return hostap_hw_ready(dev);
342
343 fail:
344 if (irq_registered && dev)
345 free_irq(dev->irq, dev);
346
347 if (mem)
348 iounmap(mem);
349
350 release_mem_region(phymem, pci_resource_len(pdev, 0));
351
352 err_out_disable:
353 pci_disable_device(pdev);
354 prism2_free_local_data(dev);
355
356 return -ENODEV;
357}
358
359
360static void prism2_pci_remove(struct pci_dev *pdev)
361{
362 struct net_device *dev;
363 struct hostap_interface *iface;
364 void __iomem *mem_start;
365
366 dev = pci_get_drvdata(pdev);
367 iface = netdev_priv(dev);
368
369 /* Reset the hardware, and ensure interrupts are disabled. */
370 prism2_pci_cor_sreset(iface->local);
371 hfa384x_disable_interrupts(dev);
372
373 if (dev->irq)
374 free_irq(dev->irq, dev);
375
376 mem_start = iface->local->mem_start;
377 prism2_free_local_data(dev);
378
379 iounmap(mem_start);
380
381 release_mem_region(pci_resource_start(pdev, 0),
382 pci_resource_len(pdev, 0));
383 pci_disable_device(pdev);
384}
385
386
387#ifdef CONFIG_PM
388static int prism2_pci_suspend(struct pci_dev *pdev, u32 state)
389{
390 struct net_device *dev = pci_get_drvdata(pdev);
391
392 if (netif_running(dev)) {
393 netif_stop_queue(dev);
394 netif_device_detach(dev);
395 }
396 prism2_suspend(dev);
397 pci_save_state(pdev);
398 pci_disable_device(pdev);
399 pci_set_power_state(pdev, 3);
400
401 return 0;
402}
403
404static int prism2_pci_resume(struct pci_dev *pdev)
405{
406 struct net_device *dev = pci_get_drvdata(pdev);
407
408 pci_enable_device(pdev);
409 pci_restore_state(pdev);
410 prism2_hw_config(dev, 0);
411 if (netif_running(dev)) {
412 netif_device_attach(dev);
413 netif_start_queue(dev);
414 }
415
416 return 0;
417}
418#endif /* CONFIG_PM */
419
420
421MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
422
423static struct pci_driver prism2_pci_drv_id = {
424 .name = "prism2_pci",
425 .id_table = prism2_pci_id_table,
426 .probe = prism2_pci_probe,
427 .remove = prism2_pci_remove,
428#ifdef CONFIG_PM
429 .suspend = prism2_pci_suspend,
430 .resume = prism2_pci_resume,
431#endif /* CONFIG_PM */
432 /* Linux 2.4.6 added save_state and enable_wake that are not used here
433 */
434};
435
436
437static int __init init_prism2_pci(void)
438{
439 printk(KERN_INFO "%s: %s\n", dev_info, version);
440
441 return pci_register_driver(&prism2_pci_drv_id);
442}
443
444
445static void __exit exit_prism2_pci(void)
446{
447 pci_unregister_driver(&prism2_pci_drv_id);
448 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
449}
450
451
452module_init(init_prism2_pci);
453module_exit(exit_prism2_pci);
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
new file mode 100644
index 000000000000..ec33501e094a
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -0,0 +1,620 @@
1#define PRISM2_PLX
2
3/* Host AP driver's support for PC Cards on PCI adapters using PLX9052 is
4 * based on:
5 * - Host AP driver patch from james@madingley.org
6 * - linux-wlan-ng driver, Copyright (C) AbsoluteValue Systems, Inc.
7 */
8
9
10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/if.h>
15#include <linux/skbuff.h>
16#include <linux/netdevice.h>
17#include <linux/workqueue.h>
18#include <linux/wireless.h>
19#include <net/iw_handler.h>
20
21#include <linux/ioport.h>
22#include <linux/pci.h>
23#include <asm/io.h>
24
25#include "hostap_wlan.h"
26
27
28static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
29static char *dev_info = "hostap_plx";
30
31
32MODULE_AUTHOR("Jouni Malinen");
33MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
34 "cards (PLX).");
35MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)");
36MODULE_LICENSE("GPL");
37
38
39static int ignore_cis;
40module_param(ignore_cis, int, 0444);
41MODULE_PARM_DESC(ignore_cis, "Do not verify manfid information in CIS");
42
43
44#define PLX_MIN_ATTR_LEN 512 /* at least 2 x 256 is needed for CIS */
45#define COR_SRESET 0x80
46#define COR_LEVLREQ 0x40
47#define COR_ENABLE_FUNC 0x01
48/* PCI Configuration Registers */
49#define PLX_PCIIPR 0x3d /* PCI Interrupt Pin */
50/* Local Configuration Registers */
51#define PLX_INTCSR 0x4c /* Interrupt Control/Status Register */
52#define PLX_INTCSR_PCI_INTEN BIT(6) /* PCI Interrupt Enable */
53#define PLX_CNTRL 0x50
54#define PLX_CNTRL_SERIAL_EEPROM_PRESENT BIT(28)
55
56
57#define PLXDEV(vendor,dev,str) { vendor, dev, PCI_ANY_ID, PCI_ANY_ID }
58
59static struct pci_device_id prism2_plx_id_table[] __devinitdata = {
60 PLXDEV(0x10b7, 0x7770, "3Com AirConnect PCI 777A"),
61 PLXDEV(0x111a, 0x1023, "Siemens SpeedStream SS1023"),
62 PLXDEV(0x126c, 0x8030, "Nortel emobility"),
63 PLXDEV(0x1385, 0x4100, "Netgear MA301"),
64 PLXDEV(0x15e8, 0x0130, "National Datacomm NCP130 (PLX9052)"),
65 PLXDEV(0x15e8, 0x0131, "National Datacomm NCP130 (TMD7160)"),
66 PLXDEV(0x1638, 0x1100, "Eumitcom WL11000"),
67 PLXDEV(0x16ab, 0x1101, "Global Sun Tech GL24110P (?)"),
68 PLXDEV(0x16ab, 0x1102, "Linksys WPC11 with WDT11"),
69 PLXDEV(0x16ab, 0x1103, "Longshine 8031"),
70 PLXDEV(0x16ec, 0x3685, "US Robotics USR2415"),
71 PLXDEV(0xec80, 0xec00, "Belkin F5D6000"),
72 { 0 }
73};
74
75
76/* Array of known Prism2/2.5 PC Card manufactured ids. If your card's manfid
77 * is not listed here, you will need to add it here to get the driver
78 * initialized. */
79static struct prism2_plx_manfid {
80 u16 manfid1, manfid2;
81} prism2_plx_known_manfids[] = {
82 { 0x000b, 0x7110 } /* D-Link DWL-650 Rev. P1 */,
83 { 0x000b, 0x7300 } /* Philips 802.11b WLAN PCMCIA */,
84 { 0x0101, 0x0777 } /* 3Com AirConnect PCI 777A */,
85 { 0x0126, 0x8000 } /* Proxim RangeLAN */,
86 { 0x0138, 0x0002 } /* Compaq WL100 */,
87 { 0x0156, 0x0002 } /* Intersil Prism II Ref. Design (and others) */,
88 { 0x026f, 0x030b } /* Buffalo WLI-CF-S11G */,
89 { 0x0274, 0x1612 } /* Linksys WPC11 Ver 2.5 */,
90 { 0x0274, 0x1613 } /* Linksys WPC11 Ver 3 */,
91 { 0x028a, 0x0002 } /* D-Link DRC-650 */,
92 { 0x0250, 0x0002 } /* Samsung SWL2000-N */,
93 { 0xc250, 0x0002 } /* EMTAC A2424i */,
94 { 0xd601, 0x0002 } /* Z-Com XI300 */,
95 { 0xd601, 0x0005 } /* Zcomax XI-325H 200mW */,
96 { 0, 0}
97};
98
99
100#ifdef PRISM2_IO_DEBUG
101
102static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
103{
104 struct hostap_interface *iface;
105 local_info_t *local;
106 unsigned long flags;
107
108 iface = netdev_priv(dev);
109 local = iface->local;
110
111 spin_lock_irqsave(&local->lock, flags);
112 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
113 outb(v, dev->base_addr + a);
114 spin_unlock_irqrestore(&local->lock, flags);
115}
116
117static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
118{
119 struct hostap_interface *iface;
120 local_info_t *local;
121 unsigned long flags;
122 u8 v;
123
124 iface = netdev_priv(dev);
125 local = iface->local;
126
127 spin_lock_irqsave(&local->lock, flags);
128 v = inb(dev->base_addr + a);
129 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
130 spin_unlock_irqrestore(&local->lock, flags);
131 return v;
132}
133
134static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
135{
136 struct hostap_interface *iface;
137 local_info_t *local;
138 unsigned long flags;
139
140 iface = netdev_priv(dev);
141 local = iface->local;
142
143 spin_lock_irqsave(&local->lock, flags);
144 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
145 outw(v, dev->base_addr + a);
146 spin_unlock_irqrestore(&local->lock, flags);
147}
148
149static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
150{
151 struct hostap_interface *iface;
152 local_info_t *local;
153 unsigned long flags;
154 u16 v;
155
156 iface = netdev_priv(dev);
157 local = iface->local;
158
159 spin_lock_irqsave(&local->lock, flags);
160 v = inw(dev->base_addr + a);
161 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
162 spin_unlock_irqrestore(&local->lock, flags);
163 return v;
164}
165
166static inline void hfa384x_outsw_debug(struct net_device *dev, int a,
167 u8 *buf, int wc)
168{
169 struct hostap_interface *iface;
170 local_info_t *local;
171 unsigned long flags;
172
173 iface = netdev_priv(dev);
174 local = iface->local;
175
176 spin_lock_irqsave(&local->lock, flags);
177 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
178 outsw(dev->base_addr + a, buf, wc);
179 spin_unlock_irqrestore(&local->lock, flags);
180}
181
182static inline void hfa384x_insw_debug(struct net_device *dev, int a,
183 u8 *buf, int wc)
184{
185 struct hostap_interface *iface;
186 local_info_t *local;
187 unsigned long flags;
188
189 iface = netdev_priv(dev);
190 local = iface->local;
191
192 spin_lock_irqsave(&local->lock, flags);
193 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
194 insw(dev->base_addr + a, buf, wc);
195 spin_unlock_irqrestore(&local->lock, flags);
196}
197
198#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
199#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
200#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
201#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
202#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
203#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
204
205#else /* PRISM2_IO_DEBUG */
206
207#define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
208#define HFA384X_INB(a) inb(dev->base_addr + (a))
209#define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
210#define HFA384X_INW(a) inw(dev->base_addr + (a))
211#define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
212#define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
213
214#endif /* PRISM2_IO_DEBUG */
215
216
217static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
218 int len)
219{
220 u16 d_off;
221 u16 *pos;
222
223 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
224 pos = (u16 *) buf;
225
226 if (len / 2)
227 HFA384X_INSW(d_off, buf, len / 2);
228 pos += len / 2;
229
230 if (len & 1)
231 *((char *) pos) = HFA384X_INB(d_off);
232
233 return 0;
234}
235
236
237static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
238{
239 u16 d_off;
240 u16 *pos;
241
242 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
243 pos = (u16 *) buf;
244
245 if (len / 2)
246 HFA384X_OUTSW(d_off, buf, len / 2);
247 pos += len / 2;
248
249 if (len & 1)
250 HFA384X_OUTB(*((char *) pos), d_off);
251
252 return 0;
253}
254
255
256/* FIX: This might change at some point.. */
257#include "hostap_hw.c"
258
259
260static void prism2_plx_cor_sreset(local_info_t *local)
261{
262 unsigned char corsave;
263
264 printk(KERN_DEBUG "%s: Doing reset via direct COR access.\n",
265 dev_info);
266
267 /* Set sreset bit of COR and clear it after hold time */
268
269 if (local->attr_mem == NULL) {
270 /* TMD7160 - COR at card's first I/O addr */
271 corsave = inb(local->cor_offset);
272 outb(corsave | COR_SRESET, local->cor_offset);
273 mdelay(2);
274 outb(corsave & ~COR_SRESET, local->cor_offset);
275 mdelay(2);
276 } else {
277 /* PLX9052 */
278 corsave = readb(local->attr_mem + local->cor_offset);
279 writeb(corsave | COR_SRESET,
280 local->attr_mem + local->cor_offset);
281 mdelay(2);
282 writeb(corsave & ~COR_SRESET,
283 local->attr_mem + local->cor_offset);
284 mdelay(2);
285 }
286}
287
288
289static void prism2_plx_genesis_reset(local_info_t *local, int hcr)
290{
291 unsigned char corsave;
292
293 if (local->attr_mem == NULL) {
294 /* TMD7160 - COR at card's first I/O addr */
295 corsave = inb(local->cor_offset);
296 outb(corsave | COR_SRESET, local->cor_offset);
297 mdelay(10);
298 outb(hcr, local->cor_offset + 2);
299 mdelay(10);
300 outb(corsave & ~COR_SRESET, local->cor_offset);
301 mdelay(10);
302 } else {
303 /* PLX9052 */
304 corsave = readb(local->attr_mem + local->cor_offset);
305 writeb(corsave | COR_SRESET,
306 local->attr_mem + local->cor_offset);
307 mdelay(10);
308 writeb(hcr, local->attr_mem + local->cor_offset + 2);
309 mdelay(10);
310 writeb(corsave & ~COR_SRESET,
311 local->attr_mem + local->cor_offset);
312 mdelay(10);
313 }
314}
315
316
317static struct prism2_helper_functions prism2_plx_funcs =
318{
319 .card_present = NULL,
320 .cor_sreset = prism2_plx_cor_sreset,
321 .dev_open = NULL,
322 .dev_close = NULL,
323 .genesis_reset = prism2_plx_genesis_reset,
324 .hw_type = HOSTAP_HW_PLX,
325};
326
327
328static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len,
329 unsigned int *cor_offset,
330 unsigned int *cor_index)
331{
332#define CISTPL_CONFIG 0x1A
333#define CISTPL_MANFID 0x20
334#define CISTPL_END 0xFF
335#define CIS_MAX_LEN 256
336 u8 *cis;
337 int i, pos;
338 unsigned int rmsz, rasz, manfid1, manfid2;
339 struct prism2_plx_manfid *manfid;
340
341 cis = kmalloc(CIS_MAX_LEN, GFP_KERNEL);
342 if (cis == NULL)
343 return -ENOMEM;
344
345 /* read CIS; it is in even offsets in the beginning of attr_mem */
346 for (i = 0; i < CIS_MAX_LEN; i++)
347 cis[i] = readb(attr_mem + 2 * i);
348 printk(KERN_DEBUG "%s: CIS: %02x %02x %02x %02x %02x %02x ...\n",
349 dev_info, cis[0], cis[1], cis[2], cis[3], cis[4], cis[5]);
350
351 /* set reasonable defaults for Prism2 cards just in case CIS parsing
352 * fails */
353 *cor_offset = 0x3e0;
354 *cor_index = 0x01;
355 manfid1 = manfid2 = 0;
356
357 pos = 0;
358 while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) {
359 if (pos + cis[pos + 1] >= CIS_MAX_LEN)
360 goto cis_error;
361
362 switch (cis[pos]) {
363 case CISTPL_CONFIG:
364 if (cis[pos + 1] < 1)
365 goto cis_error;
366 rmsz = (cis[pos + 2] & 0x3c) >> 2;
367 rasz = cis[pos + 2] & 0x03;
368 if (4 + rasz + rmsz > cis[pos + 1])
369 goto cis_error;
370 *cor_index = cis[pos + 3] & 0x3F;
371 *cor_offset = 0;
372 for (i = 0; i <= rasz; i++)
373 *cor_offset += cis[pos + 4 + i] << (8 * i);
374 printk(KERN_DEBUG "%s: cor_index=0x%x "
375 "cor_offset=0x%x\n", dev_info,
376 *cor_index, *cor_offset);
377 if (*cor_offset > attr_len) {
378 printk(KERN_ERR "%s: COR offset not within "
379 "attr_mem\n", dev_info);
380 kfree(cis);
381 return -1;
382 }
383 break;
384
385 case CISTPL_MANFID:
386 if (cis[pos + 1] < 4)
387 goto cis_error;
388 manfid1 = cis[pos + 2] + (cis[pos + 3] << 8);
389 manfid2 = cis[pos + 4] + (cis[pos + 5] << 8);
390 printk(KERN_DEBUG "%s: manfid=0x%04x, 0x%04x\n",
391 dev_info, manfid1, manfid2);
392 break;
393 }
394
395 pos += cis[pos + 1] + 2;
396 }
397
398 if (pos >= CIS_MAX_LEN || cis[pos] != CISTPL_END)
399 goto cis_error;
400
401 for (manfid = prism2_plx_known_manfids; manfid->manfid1 != 0; manfid++)
402 if (manfid1 == manfid->manfid1 && manfid2 == manfid->manfid2) {
403 kfree(cis);
404 return 0;
405 }
406
407 printk(KERN_INFO "%s: unknown manfid 0x%04x, 0x%04x - assuming this is"
408 " not supported card\n", dev_info, manfid1, manfid2);
409 goto fail;
410
411 cis_error:
412 printk(KERN_WARNING "%s: invalid CIS data\n", dev_info);
413
414 fail:
415 kfree(cis);
416 if (ignore_cis) {
417 printk(KERN_INFO "%s: ignore_cis parameter set - ignoring "
418 "errors during CIS verification\n", dev_info);
419 return 0;
420 }
421 return -1;
422}
423
424
425static int prism2_plx_probe(struct pci_dev *pdev,
426 const struct pci_device_id *id)
427{
428 unsigned int pccard_ioaddr, plx_ioaddr;
429 unsigned long pccard_attr_mem;
430 unsigned int pccard_attr_len;
431 void __iomem *attr_mem = NULL;
432 unsigned int cor_offset, cor_index;
433 u32 reg;
434 local_info_t *local = NULL;
435 struct net_device *dev = NULL;
436 struct hostap_interface *iface;
437 static int cards_found /* = 0 */;
438 int irq_registered = 0;
439 int tmd7160;
440
441 if (pci_enable_device(pdev))
442 return -EIO;
443
444 /* National Datacomm NCP130 based on TMD7160, not PLX9052. */
445 tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131);
446
447 plx_ioaddr = pci_resource_start(pdev, 1);
448 pccard_ioaddr = pci_resource_start(pdev, tmd7160 ? 2 : 3);
449
450 if (tmd7160) {
451 /* TMD7160 */
452 attr_mem = NULL; /* no access to PC Card attribute memory */
453
454 printk(KERN_INFO "TMD7160 PCI/PCMCIA adapter: io=0x%x, "
455 "irq=%d, pccard_io=0x%x\n",
456 plx_ioaddr, pdev->irq, pccard_ioaddr);
457
458 cor_offset = plx_ioaddr;
459 cor_index = 0x04;
460
461 outb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, plx_ioaddr);
462 mdelay(1);
463 reg = inb(plx_ioaddr);
464 if (reg != (cor_index | COR_LEVLREQ | COR_ENABLE_FUNC)) {
465 printk(KERN_ERR "%s: Error setting COR (expected="
466 "0x%02x, was=0x%02x)\n", dev_info,
467 cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, reg);
468 goto fail;
469 }
470 } else {
471 /* PLX9052 */
472 pccard_attr_mem = pci_resource_start(pdev, 2);
473 pccard_attr_len = pci_resource_len(pdev, 2);
474 if (pccard_attr_len < PLX_MIN_ATTR_LEN)
475 goto fail;
476
477
478 attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);
479 if (attr_mem == NULL) {
480 printk(KERN_ERR "%s: cannot remap attr_mem\n",
481 dev_info);
482 goto fail;
483 }
484
485 printk(KERN_INFO "PLX9052 PCI/PCMCIA adapter: "
486 "mem=0x%lx, plx_io=0x%x, irq=%d, pccard_io=0x%x\n",
487 pccard_attr_mem, plx_ioaddr, pdev->irq, pccard_ioaddr);
488
489 if (prism2_plx_check_cis(attr_mem, pccard_attr_len,
490 &cor_offset, &cor_index)) {
491 printk(KERN_INFO "Unknown PC Card CIS - not a "
492 "Prism2/2.5 card?\n");
493 goto fail;
494 }
495
496 printk(KERN_DEBUG "Prism2/2.5 PC Card detected in PLX9052 "
497 "adapter\n");
498
499 /* Write COR to enable PC Card */
500 writeb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC,
501 attr_mem + cor_offset);
502
503 /* Enable PCI interrupts if they are not already enabled */
504 reg = inl(plx_ioaddr + PLX_INTCSR);
505 printk(KERN_DEBUG "PLX_INTCSR=0x%x\n", reg);
506 if (!(reg & PLX_INTCSR_PCI_INTEN)) {
507 outl(reg | PLX_INTCSR_PCI_INTEN,
508 plx_ioaddr + PLX_INTCSR);
509 if (!(inl(plx_ioaddr + PLX_INTCSR) &
510 PLX_INTCSR_PCI_INTEN)) {
511 printk(KERN_WARNING "%s: Could not enable "
512 "Local Interrupts\n", dev_info);
513 goto fail;
514 }
515 }
516
517 reg = inl(plx_ioaddr + PLX_CNTRL);
518 printk(KERN_DEBUG "PLX_CNTRL=0x%x (Serial EEPROM "
519 "present=%d)\n",
520 reg, (reg & PLX_CNTRL_SERIAL_EEPROM_PRESENT) != 0);
521 /* should set PLX_PCIIPR to 0x01 (INTA#) if Serial EEPROM is
522 * not present; but are there really such cards in use(?) */
523 }
524
525 dev = prism2_init_local_data(&prism2_plx_funcs, cards_found);
526 if (dev == NULL)
527 goto fail;
528 iface = netdev_priv(dev);
529 local = iface->local;
530 cards_found++;
531
532 dev->irq = pdev->irq;
533 dev->base_addr = pccard_ioaddr;
534 local->attr_mem = attr_mem;
535 local->cor_offset = cor_offset;
536
537 pci_set_drvdata(pdev, dev);
538
539 if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name,
540 dev)) {
541 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
542 goto fail;
543 } else
544 irq_registered = 1;
545
546 if (prism2_hw_config(dev, 1)) {
547 printk(KERN_DEBUG "%s: hardware initialization failed\n",
548 dev_info);
549 goto fail;
550 }
551
552 return hostap_hw_ready(dev);
553
554 fail:
555 prism2_free_local_data(dev);
556
557 if (irq_registered && dev)
558 free_irq(dev->irq, dev);
559
560 if (attr_mem)
561 iounmap(attr_mem);
562
563 pci_disable_device(pdev);
564
565 return -ENODEV;
566}
567
568
569static void prism2_plx_remove(struct pci_dev *pdev)
570{
571 struct net_device *dev;
572 struct hostap_interface *iface;
573
574 dev = pci_get_drvdata(pdev);
575 iface = netdev_priv(dev);
576
577 /* Reset the hardware, and ensure interrupts are disabled. */
578 prism2_plx_cor_sreset(iface->local);
579 hfa384x_disable_interrupts(dev);
580
581 if (iface->local->attr_mem)
582 iounmap(iface->local->attr_mem);
583 if (dev->irq)
584 free_irq(dev->irq, dev);
585
586 prism2_free_local_data(dev);
587 pci_disable_device(pdev);
588}
589
590
591MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
592
593static struct pci_driver prism2_plx_drv_id = {
594 .name = "prism2_plx",
595 .id_table = prism2_plx_id_table,
596 .probe = prism2_plx_probe,
597 .remove = prism2_plx_remove,
598 .suspend = NULL,
599 .resume = NULL,
600 .enable_wake = NULL
601};
602
603
604static int __init init_prism2_plx(void)
605{
606 printk(KERN_INFO "%s: %s\n", dev_info, version);
607
608 return pci_register_driver(&prism2_plx_drv_id);
609}
610
611
612static void __exit exit_prism2_plx(void)
613{
614 pci_unregister_driver(&prism2_plx_drv_id);
615 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
616}
617
618
619module_init(init_prism2_plx);
620module_exit(exit_prism2_plx);
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c
new file mode 100644
index 000000000000..81b321ba189a
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -0,0 +1,466 @@
1/* /proc routines for Host AP driver */
2
3#define PROC_LIMIT (PAGE_SIZE - 80)
4
5
6#ifndef PRISM2_NO_PROCFS_DEBUG
7static int prism2_debug_proc_read(char *page, char **start, off_t off,
8 int count, int *eof, void *data)
9{
10 char *p = page;
11 local_info_t *local = (local_info_t *) data;
12 int i;
13
14 if (off != 0) {
15 *eof = 1;
16 return 0;
17 }
18
19 p += sprintf(p, "next_txfid=%d next_alloc=%d\n",
20 local->next_txfid, local->next_alloc);
21 for (i = 0; i < PRISM2_TXFID_COUNT; i++)
22 p += sprintf(p, "FID: tx=%04X intransmit=%04X\n",
23 local->txfid[i], local->intransmitfid[i]);
24 p += sprintf(p, "FW TX rate control: %d\n", local->fw_tx_rate_control);
25 p += sprintf(p, "beacon_int=%d\n", local->beacon_int);
26 p += sprintf(p, "dtim_period=%d\n", local->dtim_period);
27 p += sprintf(p, "wds_max_connections=%d\n",
28 local->wds_max_connections);
29 p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
30 p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
31 for (i = 0; i < WEP_KEYS; i++) {
32 if (local->crypt[i] && local->crypt[i]->ops) {
33 p += sprintf(p, "crypt[%d]=%s\n",
34 i, local->crypt[i]->ops->name);
35 }
36 }
37 p += sprintf(p, "pri_only=%d\n", local->pri_only);
38 p += sprintf(p, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI);
39 p += sprintf(p, "sram_type=%d\n", local->sram_type);
40 p += sprintf(p, "no_pri=%d\n", local->no_pri);
41
42 return (p - page);
43}
44#endif /* PRISM2_NO_PROCFS_DEBUG */
45
46
47static int prism2_stats_proc_read(char *page, char **start, off_t off,
48 int count, int *eof, void *data)
49{
50 char *p = page;
51 local_info_t *local = (local_info_t *) data;
52 struct comm_tallies_sums *sums = (struct comm_tallies_sums *)
53 &local->comm_tallies;
54
55 if (off != 0) {
56 *eof = 1;
57 return 0;
58 }
59
60 p += sprintf(p, "TxUnicastFrames=%u\n", sums->tx_unicast_frames);
61 p += sprintf(p, "TxMulticastframes=%u\n", sums->tx_multicast_frames);
62 p += sprintf(p, "TxFragments=%u\n", sums->tx_fragments);
63 p += sprintf(p, "TxUnicastOctets=%u\n", sums->tx_unicast_octets);
64 p += sprintf(p, "TxMulticastOctets=%u\n", sums->tx_multicast_octets);
65 p += sprintf(p, "TxDeferredTransmissions=%u\n",
66 sums->tx_deferred_transmissions);
67 p += sprintf(p, "TxSingleRetryFrames=%u\n",
68 sums->tx_single_retry_frames);
69 p += sprintf(p, "TxMultipleRetryFrames=%u\n",
70 sums->tx_multiple_retry_frames);
71 p += sprintf(p, "TxRetryLimitExceeded=%u\n",
72 sums->tx_retry_limit_exceeded);
73 p += sprintf(p, "TxDiscards=%u\n", sums->tx_discards);
74 p += sprintf(p, "RxUnicastFrames=%u\n", sums->rx_unicast_frames);
75 p += sprintf(p, "RxMulticastFrames=%u\n", sums->rx_multicast_frames);
76 p += sprintf(p, "RxFragments=%u\n", sums->rx_fragments);
77 p += sprintf(p, "RxUnicastOctets=%u\n", sums->rx_unicast_octets);
78 p += sprintf(p, "RxMulticastOctets=%u\n", sums->rx_multicast_octets);
79 p += sprintf(p, "RxFCSErrors=%u\n", sums->rx_fcs_errors);
80 p += sprintf(p, "RxDiscardsNoBuffer=%u\n",
81 sums->rx_discards_no_buffer);
82 p += sprintf(p, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa);
83 p += sprintf(p, "RxDiscardsWEPUndecryptable=%u\n",
84 sums->rx_discards_wep_undecryptable);
85 p += sprintf(p, "RxMessageInMsgFragments=%u\n",
86 sums->rx_message_in_msg_fragments);
87 p += sprintf(p, "RxMessageInBadMsgFragments=%u\n",
88 sums->rx_message_in_bad_msg_fragments);
89 /* FIX: this may grow too long for one page(?) */
90
91 return (p - page);
92}
93
94
95static int prism2_wds_proc_read(char *page, char **start, off_t off,
96 int count, int *eof, void *data)
97{
98 char *p = page;
99 local_info_t *local = (local_info_t *) data;
100 struct list_head *ptr;
101 struct hostap_interface *iface;
102
103 if (off > PROC_LIMIT) {
104 *eof = 1;
105 return 0;
106 }
107
108 read_lock_bh(&local->iface_lock);
109 list_for_each(ptr, &local->hostap_interfaces) {
110 iface = list_entry(ptr, struct hostap_interface, list);
111 if (iface->type != HOSTAP_INTERFACE_WDS)
112 continue;
113 p += sprintf(p, "%s\t" MACSTR "\n",
114 iface->dev->name,
115 MAC2STR(iface->u.wds.remote_addr));
116 if ((p - page) > PROC_LIMIT) {
117 printk(KERN_DEBUG "%s: wds proc did not fit\n",
118 local->dev->name);
119 break;
120 }
121 }
122 read_unlock_bh(&local->iface_lock);
123
124 if ((p - page) <= off) {
125 *eof = 1;
126 return 0;
127 }
128
129 *start = page + off;
130
131 return (p - page - off);
132}
133
134
135static int prism2_bss_list_proc_read(char *page, char **start, off_t off,
136 int count, int *eof, void *data)
137{
138 char *p = page;
139 local_info_t *local = (local_info_t *) data;
140 struct list_head *ptr;
141 struct hostap_bss_info *bss;
142 int i;
143
144 if (off > PROC_LIMIT) {
145 *eof = 1;
146 return 0;
147 }
148
149 p += sprintf(p, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t"
150 "SSID(hex)\tWPA IE\n");
151 spin_lock_bh(&local->lock);
152 list_for_each(ptr, &local->bss_list) {
153 bss = list_entry(ptr, struct hostap_bss_info, list);
154 p += sprintf(p, MACSTR "\t%lu\t%u\t0x%x\t",
155 MAC2STR(bss->bssid), bss->last_update,
156 bss->count, bss->capab_info);
157 for (i = 0; i < bss->ssid_len; i++) {
158 p += sprintf(p, "%c",
159 bss->ssid[i] >= 32 && bss->ssid[i] < 127 ?
160 bss->ssid[i] : '_');
161 }
162 p += sprintf(p, "\t");
163 for (i = 0; i < bss->ssid_len; i++) {
164 p += sprintf(p, "%02x", bss->ssid[i]);
165 }
166 p += sprintf(p, "\t");
167 for (i = 0; i < bss->wpa_ie_len; i++) {
168 p += sprintf(p, "%02x", bss->wpa_ie[i]);
169 }
170 p += sprintf(p, "\n");
171 if ((p - page) > PROC_LIMIT) {
172 printk(KERN_DEBUG "%s: BSS proc did not fit\n",
173 local->dev->name);
174 break;
175 }
176 }
177 spin_unlock_bh(&local->lock);
178
179 if ((p - page) <= off) {
180 *eof = 1;
181 return 0;
182 }
183
184 *start = page + off;
185
186 return (p - page - off);
187}
188
189
190static int prism2_crypt_proc_read(char *page, char **start, off_t off,
191 int count, int *eof, void *data)
192{
193 char *p = page;
194 local_info_t *local = (local_info_t *) data;
195 int i;
196
197 if (off > PROC_LIMIT) {
198 *eof = 1;
199 return 0;
200 }
201
202 p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx);
203 for (i = 0; i < WEP_KEYS; i++) {
204 if (local->crypt[i] && local->crypt[i]->ops &&
205 local->crypt[i]->ops->print_stats) {
206 p = local->crypt[i]->ops->print_stats(
207 p, local->crypt[i]->priv);
208 }
209 }
210
211 if ((p - page) <= off) {
212 *eof = 1;
213 return 0;
214 }
215
216 *start = page + off;
217
218 return (p - page - off);
219}
220
221
222static int prism2_pda_proc_read(char *page, char **start, off_t off,
223 int count, int *eof, void *data)
224{
225 local_info_t *local = (local_info_t *) data;
226
227 if (local->pda == NULL || off >= PRISM2_PDA_SIZE) {
228 *eof = 1;
229 return 0;
230 }
231
232 if (off + count > PRISM2_PDA_SIZE)
233 count = PRISM2_PDA_SIZE - off;
234
235 memcpy(page, local->pda + off, count);
236 return count;
237}
238
239
240static int prism2_aux_dump_proc_read(char *page, char **start, off_t off,
241 int count, int *eof, void *data)
242{
243 local_info_t *local = (local_info_t *) data;
244
245 if (local->func->read_aux == NULL) {
246 *eof = 1;
247 return 0;
248 }
249
250 if (local->func->read_aux(local->dev, off, count, page)) {
251 *eof = 1;
252 return 0;
253 }
254 *start = page;
255
256 return count;
257}
258
259
260#ifdef PRISM2_IO_DEBUG
261static int prism2_io_debug_proc_read(char *page, char **start, off_t off,
262 int count, int *eof, void *data)
263{
264 local_info_t *local = (local_info_t *) data;
265 int head = local->io_debug_head;
266 int start_bytes, left, copy, copied;
267
268 if (off + count > PRISM2_IO_DEBUG_SIZE * 4) {
269 *eof = 1;
270 if (off >= PRISM2_IO_DEBUG_SIZE * 4)
271 return 0;
272 count = PRISM2_IO_DEBUG_SIZE * 4 - off;
273 }
274
275 copied = 0;
276 start_bytes = (PRISM2_IO_DEBUG_SIZE - head) * 4;
277 left = count;
278
279 if (off < start_bytes) {
280 copy = start_bytes - off;
281 if (copy > count)
282 copy = count;
283 memcpy(page, ((u8 *) &local->io_debug[head]) + off, copy);
284 left -= copy;
285 if (left > 0)
286 memcpy(&page[copy], local->io_debug, left);
287 } else {
288 memcpy(page, ((u8 *) local->io_debug) + (off - start_bytes),
289 left);
290 }
291
292 *start = page;
293
294 return count;
295}
296#endif /* PRISM2_IO_DEBUG */
297
298
299#ifndef PRISM2_NO_STATION_MODES
300static int prism2_scan_results_proc_read(char *page, char **start, off_t off,
301 int count, int *eof, void *data)
302{
303 char *p = page;
304 local_info_t *local = (local_info_t *) data;
305 int entries, entry, i, len, total = 0, hostscan;
306 struct hfa384x_scan_result *scanres;
307 struct hfa384x_hostscan_result *hscanres;
308 u8 *pos;
309
310 p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates "
311 "SSID\n");
312
313 spin_lock_bh(&local->lock);
314 hostscan = local->last_scan_type == PRISM2_HOSTSCAN;
315 entries = hostscan ? local->last_hostscan_results_count :
316 local->last_scan_results_count;
317 for (entry = 0; entry < entries; entry++) {
318 hscanres = &local->last_hostscan_results[entry];
319 scanres = &local->last_scan_results[entry];
320
321 if (total + (p - page) <= off) {
322 total += p - page;
323 p = page;
324 }
325 if (total + (p - page) > off + count)
326 break;
327 if ((p - page) > (PAGE_SIZE - 200))
328 break;
329
330 if (hostscan) {
331 p += sprintf(p, "%d %d %d %d 0x%02x %d " MACSTR " %d ",
332 le16_to_cpu(hscanres->chid),
333 (s16) le16_to_cpu(hscanres->anl),
334 (s16) le16_to_cpu(hscanres->sl),
335 le16_to_cpu(hscanres->beacon_interval),
336 le16_to_cpu(hscanres->capability),
337 le16_to_cpu(hscanres->rate),
338 MAC2STR(hscanres->bssid),
339 le16_to_cpu(hscanres->atim));
340 } else {
341 p += sprintf(p, "%d %d %d %d 0x%02x %d " MACSTR
342 " N/A ",
343 le16_to_cpu(scanres->chid),
344 (s16) le16_to_cpu(scanres->anl),
345 (s16) le16_to_cpu(scanres->sl),
346 le16_to_cpu(scanres->beacon_interval),
347 le16_to_cpu(scanres->capability),
348 le16_to_cpu(scanres->rate),
349 MAC2STR(scanres->bssid));
350 }
351
352 pos = hostscan ? hscanres->sup_rates : scanres->sup_rates;
353 for (i = 0; i < sizeof(hscanres->sup_rates); i++) {
354 if (pos[i] == 0)
355 break;
356 p += sprintf(p, "<%02x>", pos[i]);
357 }
358 p += sprintf(p, " ");
359
360 pos = hostscan ? hscanres->ssid : scanres->ssid;
361 len = le16_to_cpu(hostscan ? hscanres->ssid_len :
362 scanres->ssid_len);
363 if (len > 32)
364 len = 32;
365 for (i = 0; i < len; i++) {
366 unsigned char c = pos[i];
367 if (c >= 32 && c < 127)
368 p += sprintf(p, "%c", c);
369 else
370 p += sprintf(p, "<%02x>", c);
371 }
372 p += sprintf(p, "\n");
373 }
374 spin_unlock_bh(&local->lock);
375
376 total += (p - page);
377 if (total >= off + count)
378 *eof = 1;
379
380 if (total < off) {
381 *eof = 1;
382 return 0;
383 }
384
385 len = total - off;
386 if (len > (p - page))
387 len = p - page;
388 *start = p - len;
389 if (len > count)
390 len = count;
391
392 return len;
393}
394#endif /* PRISM2_NO_STATION_MODES */
395
396
397void hostap_init_proc(local_info_t *local)
398{
399 local->proc = NULL;
400
401 if (hostap_proc == NULL) {
402 printk(KERN_WARNING "%s: hostap proc directory not created\n",
403 local->dev->name);
404 return;
405 }
406
407 local->proc = proc_mkdir(local->ddev->name, hostap_proc);
408 if (local->proc == NULL) {
409 printk(KERN_INFO "/proc/net/hostap/%s creation failed\n",
410 local->ddev->name);
411 return;
412 }
413
414#ifndef PRISM2_NO_PROCFS_DEBUG
415 create_proc_read_entry("debug", 0, local->proc,
416 prism2_debug_proc_read, local);
417#endif /* PRISM2_NO_PROCFS_DEBUG */
418 create_proc_read_entry("stats", 0, local->proc,
419 prism2_stats_proc_read, local);
420 create_proc_read_entry("wds", 0, local->proc,
421 prism2_wds_proc_read, local);
422 create_proc_read_entry("pda", 0, local->proc,
423 prism2_pda_proc_read, local);
424 create_proc_read_entry("aux_dump", 0, local->proc,
425 prism2_aux_dump_proc_read, local);
426 create_proc_read_entry("bss_list", 0, local->proc,
427 prism2_bss_list_proc_read, local);
428 create_proc_read_entry("crypt", 0, local->proc,
429 prism2_crypt_proc_read, local);
430#ifdef PRISM2_IO_DEBUG
431 create_proc_read_entry("io_debug", 0, local->proc,
432 prism2_io_debug_proc_read, local);
433#endif /* PRISM2_IO_DEBUG */
434#ifndef PRISM2_NO_STATION_MODES
435 create_proc_read_entry("scan_results", 0, local->proc,
436 prism2_scan_results_proc_read, local);
437#endif /* PRISM2_NO_STATION_MODES */
438}
439
440
441void hostap_remove_proc(local_info_t *local)
442{
443 if (local->proc != NULL) {
444#ifndef PRISM2_NO_STATION_MODES
445 remove_proc_entry("scan_results", local->proc);
446#endif /* PRISM2_NO_STATION_MODES */
447#ifdef PRISM2_IO_DEBUG
448 remove_proc_entry("io_debug", local->proc);
449#endif /* PRISM2_IO_DEBUG */
450 remove_proc_entry("pda", local->proc);
451 remove_proc_entry("aux_dump", local->proc);
452 remove_proc_entry("wds", local->proc);
453 remove_proc_entry("stats", local->proc);
454 remove_proc_entry("bss_list", local->proc);
455 remove_proc_entry("crypt", local->proc);
456#ifndef PRISM2_NO_PROCFS_DEBUG
457 remove_proc_entry("debug", local->proc);
458#endif /* PRISM2_NO_PROCFS_DEBUG */
459 if (hostap_proc != NULL)
460 remove_proc_entry(local->proc->name, hostap_proc);
461 }
462}
463
464
465EXPORT_SYMBOL(hostap_init_proc);
466EXPORT_SYMBOL(hostap_remove_proc);
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
new file mode 100644
index 000000000000..4b32e2e887ba
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -0,0 +1,1075 @@
1#ifndef HOSTAP_WLAN_H
2#define HOSTAP_WLAN_H
3
4#include "hostap_config.h"
5#include "hostap_crypt.h"
6#include "hostap_common.h"
7
8#define MAX_PARM_DEVICES 8
9#define PARM_MIN_MAX "1-" __MODULE_STRING(MAX_PARM_DEVICES)
10#define DEF_INTS -1, -1, -1, -1, -1, -1, -1
11#define GET_INT_PARM(var,idx) var[var[idx] < 0 ? 0 : idx]
12
13
14/* Specific skb->protocol value that indicates that the packet already contains
15 * txdesc header.
16 * FIX: This might need own value that would be allocated especially for Prism2
17 * txdesc; ETH_P_CONTROL is commented as "Card specific control frames".
18 * However, these skb's should have only minimal path in the kernel side since
19 * prism2_send_mgmt() sends these with dev_queue_xmit() to prism2_tx(). */
20#define ETH_P_HOSTAP ETH_P_CONTROL
21
22#ifndef ARPHRD_IEEE80211
23#define ARPHRD_IEEE80211 801
24#endif
25#ifndef ARPHRD_IEEE80211_PRISM
26#define ARPHRD_IEEE80211_PRISM 802
27#endif
28
29/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
30 * (from linux-wlan-ng) */
31struct linux_wlan_ng_val {
32 u32 did;
33 u16 status, len;
34 u32 data;
35} __attribute__ ((packed));
36
37struct linux_wlan_ng_prism_hdr {
38 u32 msgcode, msglen;
39 char devname[16];
40 struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
41 noise, rate, istx, frmlen;
42} __attribute__ ((packed));
43
44struct linux_wlan_ng_cap_hdr {
45 u32 version;
46 u32 length;
47 u64 mactime;
48 u64 hosttime;
49 u32 phytype;
50 u32 channel;
51 u32 datarate;
52 u32 antenna;
53 u32 priority;
54 u32 ssi_type;
55 s32 ssi_signal;
56 s32 ssi_noise;
57 u32 preamble;
58 u32 encoding;
59} __attribute__ ((packed));
60
61#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */
62#define LWNG_CAPHDR_VERSION 0x80211001
63
64struct hfa384x_rx_frame {
65 /* HFA384X RX frame descriptor */
66 u16 status; /* HFA384X_RX_STATUS_ flags */
67 u32 time; /* timestamp, 1 microsecond resolution */
68 u8 silence; /* 27 .. 154; seems to be 0 */
69 u8 signal; /* 27 .. 154 */
70 u8 rate; /* 10, 20, 55, or 110 */
71 u8 rxflow;
72 u32 reserved;
73
74 /* 802.11 */
75 u16 frame_control;
76 u16 duration_id;
77 u8 addr1[6];
78 u8 addr2[6];
79 u8 addr3[6];
80 u16 seq_ctrl;
81 u8 addr4[6];
82 u16 data_len;
83
84 /* 802.3 */
85 u8 dst_addr[6];
86 u8 src_addr[6];
87 u16 len;
88
89 /* followed by frame data; max 2304 bytes */
90} __attribute__ ((packed));
91
92
93struct hfa384x_tx_frame {
94 /* HFA384X TX frame descriptor */
95 u16 status; /* HFA384X_TX_STATUS_ flags */
96 u16 reserved1;
97 u16 reserved2;
98 u32 sw_support;
99 u8 retry_count; /* not yet implemented */
100 u8 tx_rate; /* Host AP only; 0 = firmware, or 10, 20, 55, 110 */
101 u16 tx_control; /* HFA384X_TX_CTRL_ flags */
102
103 /* 802.11 */
104 u16 frame_control; /* parts not used */
105 u16 duration_id;
106 u8 addr1[6];
107 u8 addr2[6]; /* filled by firmware */
108 u8 addr3[6];
109 u16 seq_ctrl; /* filled by firmware */
110 u8 addr4[6];
111 u16 data_len;
112
113 /* 802.3 */
114 u8 dst_addr[6];
115 u8 src_addr[6];
116 u16 len;
117
118 /* followed by frame data; max 2304 bytes */
119} __attribute__ ((packed));
120
121
122struct hfa384x_rid_hdr
123{
124 u16 len;
125 u16 rid;
126} __attribute__ ((packed));
127
128
129/* Macro for converting signal levels (range 27 .. 154) to wireless ext
130 * dBm value with some accuracy */
131#define HFA384X_LEVEL_TO_dBm(v) 0x100 + (v) * 100 / 255 - 100
132
133#define HFA384X_LEVEL_TO_dBm_sign(v) (v) * 100 / 255 - 100
134
135struct hfa384x_scan_request {
136 u16 channel_list;
137 u16 txrate; /* HFA384X_RATES_* */
138} __attribute__ ((packed));
139
140struct hfa384x_hostscan_request {
141 u16 channel_list;
142 u16 txrate;
143 u16 target_ssid_len;
144 u8 target_ssid[32];
145} __attribute__ ((packed));
146
147struct hfa384x_join_request {
148 u8 bssid[6];
149 u16 channel;
150} __attribute__ ((packed));
151
152struct hfa384x_info_frame {
153 u16 len;
154 u16 type;
155} __attribute__ ((packed));
156
157struct hfa384x_comm_tallies {
158 u16 tx_unicast_frames;
159 u16 tx_multicast_frames;
160 u16 tx_fragments;
161 u16 tx_unicast_octets;
162 u16 tx_multicast_octets;
163 u16 tx_deferred_transmissions;
164 u16 tx_single_retry_frames;
165 u16 tx_multiple_retry_frames;
166 u16 tx_retry_limit_exceeded;
167 u16 tx_discards;
168 u16 rx_unicast_frames;
169 u16 rx_multicast_frames;
170 u16 rx_fragments;
171 u16 rx_unicast_octets;
172 u16 rx_multicast_octets;
173 u16 rx_fcs_errors;
174 u16 rx_discards_no_buffer;
175 u16 tx_discards_wrong_sa;
176 u16 rx_discards_wep_undecryptable;
177 u16 rx_message_in_msg_fragments;
178 u16 rx_message_in_bad_msg_fragments;
179} __attribute__ ((packed));
180
181struct hfa384x_comm_tallies32 {
182 u32 tx_unicast_frames;
183 u32 tx_multicast_frames;
184 u32 tx_fragments;
185 u32 tx_unicast_octets;
186 u32 tx_multicast_octets;
187 u32 tx_deferred_transmissions;
188 u32 tx_single_retry_frames;
189 u32 tx_multiple_retry_frames;
190 u32 tx_retry_limit_exceeded;
191 u32 tx_discards;
192 u32 rx_unicast_frames;
193 u32 rx_multicast_frames;
194 u32 rx_fragments;
195 u32 rx_unicast_octets;
196 u32 rx_multicast_octets;
197 u32 rx_fcs_errors;
198 u32 rx_discards_no_buffer;
199 u32 tx_discards_wrong_sa;
200 u32 rx_discards_wep_undecryptable;
201 u32 rx_message_in_msg_fragments;
202 u32 rx_message_in_bad_msg_fragments;
203} __attribute__ ((packed));
204
205struct hfa384x_scan_result_hdr {
206 u16 reserved;
207 u16 scan_reason;
208#define HFA384X_SCAN_IN_PROGRESS 0 /* no results available yet */
209#define HFA384X_SCAN_HOST_INITIATED 1
210#define HFA384X_SCAN_FIRMWARE_INITIATED 2
211#define HFA384X_SCAN_INQUIRY_FROM_HOST 3
212} __attribute__ ((packed));
213
214#define HFA384X_SCAN_MAX_RESULTS 32
215
216struct hfa384x_scan_result {
217 u16 chid;
218 u16 anl;
219 u16 sl;
220 u8 bssid[6];
221 u16 beacon_interval;
222 u16 capability;
223 u16 ssid_len;
224 u8 ssid[32];
225 u8 sup_rates[10];
226 u16 rate;
227} __attribute__ ((packed));
228
229struct hfa384x_hostscan_result {
230 u16 chid;
231 u16 anl;
232 u16 sl;
233 u8 bssid[6];
234 u16 beacon_interval;
235 u16 capability;
236 u16 ssid_len;
237 u8 ssid[32];
238 u8 sup_rates[10];
239 u16 rate;
240 u16 atim;
241} __attribute__ ((packed));
242
243struct comm_tallies_sums {
244 unsigned int tx_unicast_frames;
245 unsigned int tx_multicast_frames;
246 unsigned int tx_fragments;
247 unsigned int tx_unicast_octets;
248 unsigned int tx_multicast_octets;
249 unsigned int tx_deferred_transmissions;
250 unsigned int tx_single_retry_frames;
251 unsigned int tx_multiple_retry_frames;
252 unsigned int tx_retry_limit_exceeded;
253 unsigned int tx_discards;
254 unsigned int rx_unicast_frames;
255 unsigned int rx_multicast_frames;
256 unsigned int rx_fragments;
257 unsigned int rx_unicast_octets;
258 unsigned int rx_multicast_octets;
259 unsigned int rx_fcs_errors;
260 unsigned int rx_discards_no_buffer;
261 unsigned int tx_discards_wrong_sa;
262 unsigned int rx_discards_wep_undecryptable;
263 unsigned int rx_message_in_msg_fragments;
264 unsigned int rx_message_in_bad_msg_fragments;
265};
266
267
268struct hfa384x_regs {
269 u16 cmd;
270 u16 evstat;
271 u16 offset0;
272 u16 offset1;
273 u16 swsupport0;
274};
275
276
277#if defined(PRISM2_PCCARD) || defined(PRISM2_PLX)
278/* I/O ports for HFA384X Controller access */
279#define HFA384X_CMD_OFF 0x00
280#define HFA384X_PARAM0_OFF 0x02
281#define HFA384X_PARAM1_OFF 0x04
282#define HFA384X_PARAM2_OFF 0x06
283#define HFA384X_STATUS_OFF 0x08
284#define HFA384X_RESP0_OFF 0x0A
285#define HFA384X_RESP1_OFF 0x0C
286#define HFA384X_RESP2_OFF 0x0E
287#define HFA384X_INFOFID_OFF 0x10
288#define HFA384X_CONTROL_OFF 0x14
289#define HFA384X_SELECT0_OFF 0x18
290#define HFA384X_SELECT1_OFF 0x1A
291#define HFA384X_OFFSET0_OFF 0x1C
292#define HFA384X_OFFSET1_OFF 0x1E
293#define HFA384X_RXFID_OFF 0x20
294#define HFA384X_ALLOCFID_OFF 0x22
295#define HFA384X_TXCOMPLFID_OFF 0x24
296#define HFA384X_SWSUPPORT0_OFF 0x28
297#define HFA384X_SWSUPPORT1_OFF 0x2A
298#define HFA384X_SWSUPPORT2_OFF 0x2C
299#define HFA384X_EVSTAT_OFF 0x30
300#define HFA384X_INTEN_OFF 0x32
301#define HFA384X_EVACK_OFF 0x34
302#define HFA384X_DATA0_OFF 0x36
303#define HFA384X_DATA1_OFF 0x38
304#define HFA384X_AUXPAGE_OFF 0x3A
305#define HFA384X_AUXOFFSET_OFF 0x3C
306#define HFA384X_AUXDATA_OFF 0x3E
307#endif /* PRISM2_PCCARD || PRISM2_PLX */
308
309#ifdef PRISM2_PCI
310/* Memory addresses for ISL3874 controller access */
311#define HFA384X_CMD_OFF 0x00
312#define HFA384X_PARAM0_OFF 0x04
313#define HFA384X_PARAM1_OFF 0x08
314#define HFA384X_PARAM2_OFF 0x0C
315#define HFA384X_STATUS_OFF 0x10
316#define HFA384X_RESP0_OFF 0x14
317#define HFA384X_RESP1_OFF 0x18
318#define HFA384X_RESP2_OFF 0x1C
319#define HFA384X_INFOFID_OFF 0x20
320#define HFA384X_CONTROL_OFF 0x28
321#define HFA384X_SELECT0_OFF 0x30
322#define HFA384X_SELECT1_OFF 0x34
323#define HFA384X_OFFSET0_OFF 0x38
324#define HFA384X_OFFSET1_OFF 0x3C
325#define HFA384X_RXFID_OFF 0x40
326#define HFA384X_ALLOCFID_OFF 0x44
327#define HFA384X_TXCOMPLFID_OFF 0x48
328#define HFA384X_PCICOR_OFF 0x4C
329#define HFA384X_SWSUPPORT0_OFF 0x50
330#define HFA384X_SWSUPPORT1_OFF 0x54
331#define HFA384X_SWSUPPORT2_OFF 0x58
332#define HFA384X_PCIHCR_OFF 0x5C
333#define HFA384X_EVSTAT_OFF 0x60
334#define HFA384X_INTEN_OFF 0x64
335#define HFA384X_EVACK_OFF 0x68
336#define HFA384X_DATA0_OFF 0x6C
337#define HFA384X_DATA1_OFF 0x70
338#define HFA384X_AUXPAGE_OFF 0x74
339#define HFA384X_AUXOFFSET_OFF 0x78
340#define HFA384X_AUXDATA_OFF 0x7C
341#define HFA384X_PCI_M0_ADDRH_OFF 0x80
342#define HFA384X_PCI_M0_ADDRL_OFF 0x84
343#define HFA384X_PCI_M0_LEN_OFF 0x88
344#define HFA384X_PCI_M0_CTL_OFF 0x8C
345#define HFA384X_PCI_STATUS_OFF 0x98
346#define HFA384X_PCI_M1_ADDRH_OFF 0xA0
347#define HFA384X_PCI_M1_ADDRL_OFF 0xA4
348#define HFA384X_PCI_M1_LEN_OFF 0xA8
349#define HFA384X_PCI_M1_CTL_OFF 0xAC
350
351/* PCI bus master control bits (these are undocumented; based on guessing and
352 * experimenting..) */
353#define HFA384X_PCI_CTL_FROM_BAP (BIT(5) | BIT(1) | BIT(0))
354#define HFA384X_PCI_CTL_TO_BAP (BIT(5) | BIT(0))
355
356#endif /* PRISM2_PCI */
357
358
359/* Command codes for CMD reg. */
360#define HFA384X_CMDCODE_INIT 0x00
361#define HFA384X_CMDCODE_ENABLE 0x01
362#define HFA384X_CMDCODE_DISABLE 0x02
363#define HFA384X_CMDCODE_ALLOC 0x0A
364#define HFA384X_CMDCODE_TRANSMIT 0x0B
365#define HFA384X_CMDCODE_INQUIRE 0x11
366#define HFA384X_CMDCODE_ACCESS 0x21
367#define HFA384X_CMDCODE_ACCESS_WRITE (0x21 | BIT(8))
368#define HFA384X_CMDCODE_DOWNLOAD 0x22
369#define HFA384X_CMDCODE_READMIF 0x30
370#define HFA384X_CMDCODE_WRITEMIF 0x31
371#define HFA384X_CMDCODE_TEST 0x38
372
373#define HFA384X_CMDCODE_MASK 0x3F
374
375/* Test mode operations */
376#define HFA384X_TEST_CHANGE_CHANNEL 0x08
377#define HFA384X_TEST_MONITOR 0x0B
378#define HFA384X_TEST_STOP 0x0F
379#define HFA384X_TEST_CFG_BITS 0x15
380#define HFA384X_TEST_CFG_BIT_ALC BIT(3)
381
382#define HFA384X_CMD_BUSY BIT(15)
383
384#define HFA384X_CMD_TX_RECLAIM BIT(8)
385
386#define HFA384X_OFFSET_ERR BIT(14)
387#define HFA384X_OFFSET_BUSY BIT(15)
388
389
390/* ProgMode for download command */
391#define HFA384X_PROGMODE_DISABLE 0
392#define HFA384X_PROGMODE_ENABLE_VOLATILE 1
393#define HFA384X_PROGMODE_ENABLE_NON_VOLATILE 2
394#define HFA384X_PROGMODE_PROGRAM_NON_VOLATILE 3
395
396#define HFA384X_AUX_MAGIC0 0xfe01
397#define HFA384X_AUX_MAGIC1 0xdc23
398#define HFA384X_AUX_MAGIC2 0xba45
399
400#define HFA384X_AUX_PORT_DISABLED 0
401#define HFA384X_AUX_PORT_DISABLE BIT(14)
402#define HFA384X_AUX_PORT_ENABLE BIT(15)
403#define HFA384X_AUX_PORT_ENABLED (BIT(14) | BIT(15))
404#define HFA384X_AUX_PORT_MASK (BIT(14) | BIT(15))
405
406#define PRISM2_PDA_SIZE 1024
407
408
409/* Events; EvStat, Interrupt mask (IntEn), and acknowledge bits (EvAck) */
410#define HFA384X_EV_TICK BIT(15)
411#define HFA384X_EV_WTERR BIT(14)
412#define HFA384X_EV_INFDROP BIT(13)
413#ifdef PRISM2_PCI
414#define HFA384X_EV_PCI_M1 BIT(9)
415#define HFA384X_EV_PCI_M0 BIT(8)
416#endif /* PRISM2_PCI */
417#define HFA384X_EV_INFO BIT(7)
418#define HFA384X_EV_DTIM BIT(5)
419#define HFA384X_EV_CMD BIT(4)
420#define HFA384X_EV_ALLOC BIT(3)
421#define HFA384X_EV_TXEXC BIT(2)
422#define HFA384X_EV_TX BIT(1)
423#define HFA384X_EV_RX BIT(0)
424
425
426/* HFA384X Information frames */
427#define HFA384X_INFO_HANDOVERADDR 0xF000 /* AP f/w ? */
428#define HFA384X_INFO_HANDOVERDEAUTHADDR 0xF001 /* AP f/w 1.3.7 */
429#define HFA384X_INFO_COMMTALLIES 0xF100
430#define HFA384X_INFO_SCANRESULTS 0xF101
431#define HFA384X_INFO_CHANNELINFORESULTS 0xF102 /* AP f/w only */
432#define HFA384X_INFO_HOSTSCANRESULTS 0xF103
433#define HFA384X_INFO_LINKSTATUS 0xF200
434#define HFA384X_INFO_ASSOCSTATUS 0xF201 /* ? */
435#define HFA384X_INFO_AUTHREQ 0xF202 /* ? */
436#define HFA384X_INFO_PSUSERCNT 0xF203 /* ? */
437#define HFA384X_INFO_KEYIDCHANGED 0xF204 /* ? */
438
439enum { HFA384X_LINKSTATUS_CONNECTED = 1,
440 HFA384X_LINKSTATUS_DISCONNECTED = 2,
441 HFA384X_LINKSTATUS_AP_CHANGE = 3,
442 HFA384X_LINKSTATUS_AP_OUT_OF_RANGE = 4,
443 HFA384X_LINKSTATUS_AP_IN_RANGE = 5,
444 HFA384X_LINKSTATUS_ASSOC_FAILED = 6 };
445
446enum { HFA384X_PORTTYPE_BSS = 1, HFA384X_PORTTYPE_WDS = 2,
447 HFA384X_PORTTYPE_PSEUDO_IBSS = 3, HFA384X_PORTTYPE_IBSS = 0,
448 HFA384X_PORTTYPE_HOSTAP = 6 };
449
450#define HFA384X_RATES_1MBPS BIT(0)
451#define HFA384X_RATES_2MBPS BIT(1)
452#define HFA384X_RATES_5MBPS BIT(2)
453#define HFA384X_RATES_11MBPS BIT(3)
454
455#define HFA384X_ROAMING_FIRMWARE 1
456#define HFA384X_ROAMING_HOST 2
457#define HFA384X_ROAMING_DISABLED 3
458
459#define HFA384X_WEPFLAGS_PRIVACYINVOKED BIT(0)
460#define HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED BIT(1)
461#define HFA384X_WEPFLAGS_HOSTENCRYPT BIT(4)
462#define HFA384X_WEPFLAGS_HOSTDECRYPT BIT(7)
463
464#define HFA384X_RX_STATUS_MSGTYPE (BIT(15) | BIT(14) | BIT(13))
465#define HFA384X_RX_STATUS_PCF BIT(12)
466#define HFA384X_RX_STATUS_MACPORT (BIT(10) | BIT(9) | BIT(8))
467#define HFA384X_RX_STATUS_UNDECR BIT(1)
468#define HFA384X_RX_STATUS_FCSERR BIT(0)
469
470#define HFA384X_RX_STATUS_GET_MSGTYPE(s) \
471(((s) & HFA384X_RX_STATUS_MSGTYPE) >> 13)
472#define HFA384X_RX_STATUS_GET_MACPORT(s) \
473(((s) & HFA384X_RX_STATUS_MACPORT) >> 8)
474
475enum { HFA384X_RX_MSGTYPE_NORMAL = 0, HFA384X_RX_MSGTYPE_RFC1042 = 1,
476 HFA384X_RX_MSGTYPE_BRIDGETUNNEL = 2, HFA384X_RX_MSGTYPE_MGMT = 4 };
477
478
479#define HFA384X_TX_CTRL_ALT_RTRY BIT(5)
480#define HFA384X_TX_CTRL_802_11 BIT(3)
481#define HFA384X_TX_CTRL_802_3 0
482#define HFA384X_TX_CTRL_TX_EX BIT(2)
483#define HFA384X_TX_CTRL_TX_OK BIT(1)
484
485#define HFA384X_TX_STATUS_RETRYERR BIT(0)
486#define HFA384X_TX_STATUS_AGEDERR BIT(1)
487#define HFA384X_TX_STATUS_DISCON BIT(2)
488#define HFA384X_TX_STATUS_FORMERR BIT(3)
489
490/* HFA3861/3863 (BBP) Control Registers */
491#define HFA386X_CR_TX_CONFIGURE 0x12 /* CR9 */
492#define HFA386X_CR_RX_CONFIGURE 0x14 /* CR10 */
493#define HFA386X_CR_A_D_TEST_MODES2 0x1A /* CR13 */
494#define HFA386X_CR_MANUAL_TX_POWER 0x3E /* CR31 */
495#define HFA386X_CR_MEASURED_TX_POWER 0x74 /* CR58 */
496
497
498#ifdef __KERNEL__
499
500#define PRISM2_TXFID_COUNT 8
501#define PRISM2_DATA_MAXLEN 2304
502#define PRISM2_TXFID_LEN (PRISM2_DATA_MAXLEN + sizeof(struct hfa384x_tx_frame))
503#define PRISM2_TXFID_EMPTY 0xffff
504#define PRISM2_TXFID_RESERVED 0xfffe
505#define PRISM2_DUMMY_FID 0xffff
506#define MAX_SSID_LEN 32
507#define MAX_NAME_LEN 32 /* this is assumed to be equal to MAX_SSID_LEN */
508
509#define PRISM2_DUMP_RX_HDR BIT(0)
510#define PRISM2_DUMP_TX_HDR BIT(1)
511#define PRISM2_DUMP_TXEXC_HDR BIT(2)
512
513struct hostap_tx_callback_info {
514 u16 idx;
515 void (*func)(struct sk_buff *, int ok, void *);
516 void *data;
517 struct hostap_tx_callback_info *next;
518};
519
520
521/* IEEE 802.11 requires that STA supports concurrent reception of at least
522 * three fragmented frames. This define can be increased to support more
523 * concurrent frames, but it should be noted that each entry can consume about
524 * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
525#define PRISM2_FRAG_CACHE_LEN 4
526
527struct prism2_frag_entry {
528 unsigned long first_frag_time;
529 unsigned int seq;
530 unsigned int last_frag;
531 struct sk_buff *skb;
532 u8 src_addr[ETH_ALEN];
533 u8 dst_addr[ETH_ALEN];
534};
535
536
537struct prism2_crypt_data {
538 struct list_head list; /* delayed deletion list */
539 struct hostap_crypto_ops *ops;
540 void *priv;
541 atomic_t refcnt;
542};
543
544struct hostap_cmd_queue {
545 struct list_head list;
546 wait_queue_head_t compl;
547 volatile enum { CMD_SLEEP, CMD_CALLBACK, CMD_COMPLETED } type;
548 void (*callback)(struct net_device *dev, void *context, u16 resp0,
549 u16 res);
550 void *context;
551 u16 cmd, param0, param1;
552 u16 resp0, res;
553 volatile int issued, issuing;
554
555 atomic_t usecnt;
556 int del_req;
557};
558
559/* options for hw_shutdown */
560#define HOSTAP_HW_NO_DISABLE BIT(0)
561#define HOSTAP_HW_ENABLE_CMDCOMPL BIT(1)
562
563typedef struct local_info local_info_t;
564
565struct prism2_helper_functions {
566 /* these functions are defined in hardware model specific files
567 * (hostap_{cs,plx,pci}.c */
568 int (*card_present)(local_info_t *local);
569 void (*cor_sreset)(local_info_t *local);
570 int (*dev_open)(local_info_t *local);
571 int (*dev_close)(local_info_t *local);
572 void (*genesis_reset)(local_info_t *local, int hcr);
573
574 /* the following functions are from hostap_hw.c, but they may have some
575 * hardware model specific code */
576
577 /* FIX: low-level commands like cmd might disappear at some point to
578 * make it easier to change them if needed (e.g., cmd would be replaced
579 * with write_mif/read_mif/testcmd/inquire); at least get_rid and
580 * set_rid might move to hostap_{cs,plx,pci}.c */
581 int (*cmd)(struct net_device *dev, u16 cmd, u16 param0, u16 *param1,
582 u16 *resp0);
583 void (*read_regs)(struct net_device *dev, struct hfa384x_regs *regs);
584 int (*get_rid)(struct net_device *dev, u16 rid, void *buf, int len,
585 int exact_len);
586 int (*set_rid)(struct net_device *dev, u16 rid, void *buf, int len);
587 int (*hw_enable)(struct net_device *dev, int initial);
588 int (*hw_config)(struct net_device *dev, int initial);
589 void (*hw_reset)(struct net_device *dev);
590 void (*hw_shutdown)(struct net_device *dev, int no_disable);
591 int (*reset_port)(struct net_device *dev);
592 void (*schedule_reset)(local_info_t *local);
593 int (*download)(local_info_t *local,
594 struct prism2_download_param *param);
595 int (*tx)(struct sk_buff *skb, struct net_device *dev);
596 int (*set_tim)(struct net_device *dev, int aid, int set);
597 int (*read_aux)(struct net_device *dev, unsigned addr, int len,
598 u8 *buf);
599
600 int need_tx_headroom; /* number of bytes of headroom needed before
601 * IEEE 802.11 header */
602 enum { HOSTAP_HW_PCCARD, HOSTAP_HW_PLX, HOSTAP_HW_PCI } hw_type;
603};
604
605
606struct prism2_download_data {
607 u32 dl_cmd;
608 u32 start_addr;
609 u32 num_areas;
610 struct prism2_download_data_area {
611 u32 addr; /* wlan card address */
612 u32 len;
613 u8 *data; /* allocated data */
614 } data[0];
615};
616
617
618#define HOSTAP_MAX_BSS_COUNT 64
619#define MAX_WPA_IE_LEN 64
620
621struct hostap_bss_info {
622 struct list_head list;
623 unsigned long last_update;
624 unsigned int count;
625 u8 bssid[ETH_ALEN];
626 u16 capab_info;
627 u8 ssid[32];
628 size_t ssid_len;
629 u8 wpa_ie[MAX_WPA_IE_LEN];
630 size_t wpa_ie_len;
631 u8 rsn_ie[MAX_WPA_IE_LEN];
632 size_t rsn_ie_len;
633 int chan;
634 int included;
635};
636
637
638/* Per radio private Host AP data - shared by all net devices interfaces used
639 * by each radio (wlan#, wlan#ap, wlan#sta, WDS).
640 * ((struct hostap_interface *) netdev_priv(dev))->local points to this
641 * structure. */
642struct local_info {
643 struct module *hw_module;
644 int card_idx;
645 int dev_enabled;
646 int master_dev_auto_open; /* was master device opened automatically */
647 int num_dev_open; /* number of open devices */
648 struct net_device *dev; /* master radio device */
649 struct net_device *ddev; /* main data device */
650 struct list_head hostap_interfaces; /* Host AP interface list (contains
651 * struct hostap_interface entries)
652 */
653 rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock
654 * when removing entries from the list.
655 * TX and RX paths can use read lock. */
656 spinlock_t cmdlock, baplock, lock;
657 struct semaphore rid_bap_sem;
658 u16 infofid; /* MAC buffer id for info frame */
659 /* txfid, intransmitfid, next_txtid, and next_alloc are protected by
660 * txfidlock */
661 spinlock_t txfidlock;
662 int txfid_len; /* length of allocated TX buffers */
663 u16 txfid[PRISM2_TXFID_COUNT]; /* buffer IDs for TX frames */
664 /* buffer IDs for intransmit frames or PRISM2_TXFID_EMPTY if
665 * corresponding txfid is free for next TX frame */
666 u16 intransmitfid[PRISM2_TXFID_COUNT];
667 int next_txfid; /* index to the next txfid to be checked for
668 * availability */
669 int next_alloc; /* index to the next intransmitfid to be checked for
670 * allocation events */
671
672 /* bitfield for atomic bitops */
673#define HOSTAP_BITS_TRANSMIT 0
674#define HOSTAP_BITS_BAP_TASKLET 1
675#define HOSTAP_BITS_BAP_TASKLET2 2
676 long bits;
677
678 struct ap_data *ap;
679
680 char essid[MAX_SSID_LEN + 1];
681 char name[MAX_NAME_LEN + 1];
682 int name_set;
683 u16 channel_mask;
684 struct comm_tallies_sums comm_tallies;
685 struct net_device_stats stats;
686 struct proc_dir_entry *proc;
687 int iw_mode; /* operating mode (IW_MODE_*) */
688 int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
689 * 1: IW_MODE_ADHOC is "pseudo IBSS" */
690 char bssid[ETH_ALEN];
691 int channel;
692 int beacon_int;
693 int dtim_period;
694 int mtu;
695 int frame_dump; /* dump RX/TX frame headers, PRISM2_DUMP_ flags */
696 int fw_tx_rate_control;
697 u16 tx_rate_control;
698 u16 basic_rates;
699 int hw_resetting;
700 int hw_ready;
701 int hw_reset_tries; /* how many times reset has been tried */
702 int hw_downloading;
703 int shutdown;
704 int pri_only;
705 int no_pri; /* no PRI f/w present */
706 int sram_type; /* 8 = x8 SRAM, 16 = x16 SRAM, -1 = unknown */
707
708 enum {
709 PRISM2_TXPOWER_AUTO = 0, PRISM2_TXPOWER_OFF,
710 PRISM2_TXPOWER_FIXED, PRISM2_TXPOWER_UNKNOWN
711 } txpower_type;
712 int txpower; /* if txpower_type == PRISM2_TXPOWER_FIXED */
713
714 /* command queue for hfa384x_cmd(); protected with cmdlock */
715 struct list_head cmd_queue;
716 /* max_len for cmd_queue; in addition, cmd_callback can use two
717 * additional entries to prevent sleeping commands from stopping
718 * transmits */
719#define HOSTAP_CMD_QUEUE_MAX_LEN 16
720 int cmd_queue_len; /* number of entries in cmd_queue */
721
722 /* if card timeout is detected in interrupt context, reset_queue is
723 * used to schedule card reseting to be done in user context */
724 struct work_struct reset_queue;
725
726 /* For scheduling a change of the promiscuous mode RID */
727 int is_promisc;
728 struct work_struct set_multicast_list_queue;
729
730 struct work_struct set_tim_queue;
731 struct list_head set_tim_list;
732 spinlock_t set_tim_lock;
733
734 int wds_max_connections;
735 int wds_connections;
736#define HOSTAP_WDS_BROADCAST_RA BIT(0)
737#define HOSTAP_WDS_AP_CLIENT BIT(1)
738#define HOSTAP_WDS_STANDARD_FRAME BIT(2)
739 u32 wds_type;
740 u16 tx_control; /* flags to be used in TX description */
741 int manual_retry_count; /* -1 = use f/w default; otherwise retry count
742 * to be used with all frames */
743
744 struct iw_statistics wstats;
745 unsigned long scan_timestamp; /* Time started to scan */
746 enum {
747 PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
748 PRISM2_MONITOR_CAPHDR = 2
749 } monitor_type;
750 int (*saved_eth_header_parse)(struct sk_buff *skb,
751 unsigned char *haddr);
752 int monitor_allow_fcserr;
753
754 int hostapd; /* whether user space daemon, hostapd, is used for AP
755 * management */
756 int hostapd_sta; /* whether hostapd is used with an extra STA interface
757 */
758 struct net_device *apdev;
759 struct net_device_stats apdevstats;
760
761 char assoc_ap_addr[ETH_ALEN];
762 struct net_device *stadev;
763 struct net_device_stats stadevstats;
764
765#define WEP_KEYS 4
766#define WEP_KEY_LEN 13
767 struct prism2_crypt_data *crypt[WEP_KEYS];
768 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
769 struct timer_list crypt_deinit_timer;
770 struct list_head crypt_deinit_list;
771
772 int open_wep; /* allow unencrypted frames */
773 int host_encrypt;
774 int host_decrypt;
775 int privacy_invoked; /* force privacy invoked flag even if no keys are
776 * configured */
777 int fw_encrypt_ok; /* whether firmware-based WEP encrypt is working
778 * in Host AP mode (STA f/w 1.4.9 or newer) */
779 int bcrx_sta_key; /* use individual keys to override default keys even
780 * with RX of broad/multicast frames */
781
782 struct prism2_frag_entry frag_cache[PRISM2_FRAG_CACHE_LEN];
783 unsigned int frag_next_idx;
784
785 int ieee_802_1x; /* is IEEE 802.1X used */
786
787 int antsel_tx, antsel_rx;
788 int rts_threshold; /* dot11RTSThreshold */
789 int fragm_threshold; /* dot11FragmentationThreshold */
790 int auth_algs; /* PRISM2_AUTH_ flags */
791
792 int enh_sec; /* cnfEnhSecurity options (broadcast SSID hide/ignore) */
793 int tallies32; /* 32-bit tallies in use */
794
795 struct prism2_helper_functions *func;
796
797 int bus_master_threshold_tx;
798 int bus_master_threshold_rx;
799 u8 *bus_m1_buf;
800
801 u8 *pda;
802 int fw_ap;
803#define PRISM2_FW_VER(major, minor, variant) \
804(((major) << 16) | ((minor) << 8) | variant)
805 u32 sta_fw_ver;
806
807 /* Tasklets for handling hardware IRQ related operations outside hw IRQ
808 * handler */
809 struct tasklet_struct bap_tasklet;
810
811 struct tasklet_struct info_tasklet;
812 struct sk_buff_head info_list; /* info frames as skb's for
813 * info_tasklet */
814
815 struct hostap_tx_callback_info *tx_callback; /* registered TX callbacks
816 */
817
818 struct tasklet_struct rx_tasklet;
819 struct sk_buff_head rx_list;
820
821 struct tasklet_struct sta_tx_exc_tasklet;
822 struct sk_buff_head sta_tx_exc_list;
823
824 int host_roaming;
825 unsigned long last_join_time; /* time of last JoinRequest */
826 struct hfa384x_scan_result *last_scan_results;
827 int last_scan_results_count;
828 struct hfa384x_hostscan_result *last_hostscan_results;
829 int last_hostscan_results_count;
830 enum { PRISM2_SCAN, PRISM2_HOSTSCAN } last_scan_type;
831 struct work_struct info_queue;
832 long pending_info; /* bit field of pending info_queue items */
833#define PRISM2_INFO_PENDING_LINKSTATUS 0
834#define PRISM2_INFO_PENDING_SCANRESULTS 1
835 int prev_link_status; /* previous received LinkStatus info */
836 int prev_linkstatus_connected;
837 u8 preferred_ap[6]; /* use this AP if possible */
838
839#ifdef PRISM2_CALLBACK
840 void *callback_data; /* Can be used in callbacks; e.g., allocate
841 * on enable event and free on disable event.
842 * Host AP driver code does not touch this. */
843#endif /* PRISM2_CALLBACK */
844
845 wait_queue_head_t hostscan_wq;
846
847 /* Passive scan in Host AP mode */
848 struct timer_list passive_scan_timer;
849 int passive_scan_interval; /* in seconds, 0 = disabled */
850 int passive_scan_channel;
851 enum { PASSIVE_SCAN_WAIT, PASSIVE_SCAN_LISTEN } passive_scan_state;
852
853 struct timer_list tick_timer;
854 unsigned long last_tick_timer;
855 unsigned int sw_tick_stuck;
856
857 /* commsQuality / dBmCommsQuality data from periodic polling; only
858 * valid for Managed and Ad-hoc modes */
859 unsigned long last_comms_qual_update;
860 int comms_qual; /* in some odd unit.. */
861 int avg_signal; /* in dB (note: negative) */
862 int avg_noise; /* in dB (note: negative) */
863 struct work_struct comms_qual_update;
864
865 /* RSSI to dBm adjustment (for RX descriptor fields) */
866 int rssi_to_dBm; /* substract from RSSI to get approximate dBm value */
867
868 /* BSS list / protected by local->lock */
869 struct list_head bss_list;
870 int num_bss_info;
871 int wpa; /* WPA support enabled */
872 int tkip_countermeasures;
873 int drop_unencrypted;
874 /* Generic IEEE 802.11 info element to be added to
875 * ProbeResp/Beacon/(Re)AssocReq */
876 u8 *generic_elem;
877 size_t generic_elem_len;
878
879#ifdef PRISM2_DOWNLOAD_SUPPORT
880 /* Persistent volatile download data */
881 struct prism2_download_data *dl_pri;
882 struct prism2_download_data *dl_sec;
883#endif /* PRISM2_DOWNLOAD_SUPPORT */
884
885#ifdef PRISM2_IO_DEBUG
886#define PRISM2_IO_DEBUG_SIZE 10000
887 u32 io_debug[PRISM2_IO_DEBUG_SIZE];
888 int io_debug_head;
889 int io_debug_enabled;
890#endif /* PRISM2_IO_DEBUG */
891
892 /* struct local_info is used also in hostap.o that does not define
893 * any PRISM2_{PCCARD,PLX,PCI}. Make sure that the hardware version
894 * specific fields are in the end of the struct (these could also be
895 * moved to void *priv or something like that). */
896#ifdef PRISM2_PCCARD
897 dev_node_t node;
898 dev_link_t *link;
899 int sandisk_connectplus;
900#endif /* PRISM2_PCCARD */
901
902#ifdef PRISM2_PLX
903 void __iomem *attr_mem;
904 unsigned int cor_offset;
905#endif /* PRISM2_PLX */
906
907#ifdef PRISM2_PCI
908 void __iomem *mem_start;
909#ifdef PRISM2_BUS_MASTER
910 /* bus master for BAP0 (TX) */
911 int bus_m0_tx_idx;
912 u8 *bus_m0_buf;
913
914 /* bus master for BAP1 (RX) */
915 struct sk_buff *rx_skb;
916#endif /* PRISM2_BUS_MASTER */
917#endif /* PRISM2_PCI */
918
919 /* NOTE! Do not add common entries here after hardware version
920 * specific blocks. */
921};
922
923
924/* Per interface private Host AP data
925 * Allocated for each net device that Host AP uses (wlan#, wlan#ap, wlan#sta,
926 * WDS) and netdev_priv(dev) points to this structure. */
927struct hostap_interface {
928 struct list_head list; /* list entry in Host AP interface list */
929 struct net_device *dev; /* pointer to this device */
930 struct local_info *local; /* pointer to shared private data */
931 struct net_device_stats stats;
932 struct iw_spy_data spy_data; /* iwspy support */
933 struct iw_public_data wireless_data;
934
935 enum {
936 HOSTAP_INTERFACE_MASTER,
937 HOSTAP_INTERFACE_MAIN,
938 HOSTAP_INTERFACE_AP,
939 HOSTAP_INTERFACE_STA,
940 HOSTAP_INTERFACE_WDS,
941 } type;
942
943 union {
944 struct hostap_interface_wds {
945 u8 remote_addr[ETH_ALEN];
946 } wds;
947 } u;
948};
949
950
951#define HOSTAP_SKB_TX_DATA_MAGIC 0xf08a36a2
952
953/* TX meta data - stored in skb->cb buffer, so this must be not increase over
954 * 48-byte limit */
955struct hostap_skb_tx_data {
956 unsigned int magic; /* HOSTAP_SKB_TX_DATA_MAGIC */
957 int rate; /* transmit rate */
958 struct hostap_interface *iface;
959 unsigned long jiffies; /* queueing timestamp */
960 int wds;
961 unsigned short ethertype;
962 int tx_cb_idx;
963};
964
965
966#ifndef PRISM2_NO_DEBUG
967
968#define DEBUG_FID BIT(0)
969#define DEBUG_PS BIT(1)
970#define DEBUG_FLOW BIT(2)
971#define DEBUG_AP BIT(3)
972#define DEBUG_HW BIT(4)
973#define DEBUG_EXTRA BIT(5)
974#define DEBUG_EXTRA2 BIT(6)
975#define DEBUG_PS2 BIT(7)
976#define DEBUG_MASK (DEBUG_PS | DEBUG_AP | DEBUG_HW | DEBUG_EXTRA)
977#define PDEBUG(n, args...) \
978do { if ((n) & DEBUG_MASK) printk(KERN_DEBUG args); } while (0)
979#define PDEBUG2(n, args...) \
980do { if ((n) & DEBUG_MASK) printk(args); } while (0)
981
982#else /* PRISM2_NO_DEBUG */
983
984#define PDEBUG(n, args...)
985#define PDEBUG2(n, args...)
986
987#endif /* PRISM2_NO_DEBUG */
988
989enum { BAP0 = 0, BAP1 = 1 };
990
991#define PRISM2_IO_DEBUG_CMD_INB 0
992#define PRISM2_IO_DEBUG_CMD_INW 1
993#define PRISM2_IO_DEBUG_CMD_INSW 2
994#define PRISM2_IO_DEBUG_CMD_OUTB 3
995#define PRISM2_IO_DEBUG_CMD_OUTW 4
996#define PRISM2_IO_DEBUG_CMD_OUTSW 5
997#define PRISM2_IO_DEBUG_CMD_ERROR 6
998#define PRISM2_IO_DEBUG_CMD_INTERRUPT 7
999
1000#ifdef PRISM2_IO_DEBUG
1001
1002#define PRISM2_IO_DEBUG_ENTRY(cmd, reg, value) \
1003(((cmd) << 24) | ((reg) << 16) | value)
1004
1005static inline void prism2_io_debug_add(struct net_device *dev, int cmd,
1006 int reg, int value)
1007{
1008 struct hostap_interface *iface = netdev_priv(dev);
1009 local_info_t *local = iface->local;
1010
1011 if (!local->io_debug_enabled)
1012 return;
1013
1014 local->io_debug[local->io_debug_head] = jiffies & 0xffffffff;
1015 if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
1016 local->io_debug_head = 0;
1017 local->io_debug[local->io_debug_head] =
1018 PRISM2_IO_DEBUG_ENTRY(cmd, reg, value);
1019 if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
1020 local->io_debug_head = 0;
1021}
1022
1023
1024static inline void prism2_io_debug_error(struct net_device *dev, int err)
1025{
1026 struct hostap_interface *iface = netdev_priv(dev);
1027 local_info_t *local = iface->local;
1028 unsigned long flags;
1029
1030 if (!local->io_debug_enabled)
1031 return;
1032
1033 spin_lock_irqsave(&local->lock, flags);
1034 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_ERROR, 0, err);
1035 if (local->io_debug_enabled == 1) {
1036 local->io_debug_enabled = 0;
1037 printk(KERN_DEBUG "%s: I/O debug stopped\n", dev->name);
1038 }
1039 spin_unlock_irqrestore(&local->lock, flags);
1040}
1041
1042#else /* PRISM2_IO_DEBUG */
1043
1044static inline void prism2_io_debug_add(struct net_device *dev, int cmd,
1045 int reg, int value)
1046{
1047}
1048
1049static inline void prism2_io_debug_error(struct net_device *dev, int err)
1050{
1051}
1052
1053#endif /* PRISM2_IO_DEBUG */
1054
1055
1056#ifdef PRISM2_CALLBACK
1057enum {
1058 /* Called when card is enabled */
1059 PRISM2_CALLBACK_ENABLE,
1060
1061 /* Called when card is disabled */
1062 PRISM2_CALLBACK_DISABLE,
1063
1064 /* Called when RX/TX starts/ends */
1065 PRISM2_CALLBACK_RX_START, PRISM2_CALLBACK_RX_END,
1066 PRISM2_CALLBACK_TX_START, PRISM2_CALLBACK_TX_END
1067};
1068void prism2_callback(local_info_t *local, int event);
1069#else /* PRISM2_CALLBACK */
1070#define prism2_callback(d, e) do { } while (0)
1071#endif /* PRISM2_CALLBACK */
1072
1073#endif /* __KERNEL__ */
1074
1075#endif /* HOSTAP_WLAN_H */
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index ec8cf29ffced..8f1e730963b7 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -209,7 +209,7 @@ enum {
209 NoStructure = 0, /* Really old firmware */ 209 NoStructure = 0, /* Really old firmware */
210 StructuredMessages = 1, /* Parsable AT response msgs */ 210 StructuredMessages = 1, /* Parsable AT response msgs */
211 ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */ 211 ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */
212} FirmwareLevel; 212};
213 213
214struct strip { 214struct strip {
215 int magic; 215 int magic;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index ec8329788e49..5914b637c0a6 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -59,6 +59,12 @@
59/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */ 59/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
60#include "wavelan_cs.p.h" /* Private header */ 60#include "wavelan_cs.p.h" /* Private header */
61 61
62#ifdef WAVELAN_ROAMING
63static void wl_cell_expiry(unsigned long data);
64static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp);
65static void wv_nwid_filter(unsigned char mode, net_local *lp);
66#endif /* WAVELAN_ROAMING */
67
62/************************* MISC SUBROUTINES **************************/ 68/************************* MISC SUBROUTINES **************************/
63/* 69/*
64 * Subroutines which won't fit in one of the following category 70 * Subroutines which won't fit in one of the following category
@@ -500,9 +506,9 @@ fee_write(u_long base, /* i/o port of the card */
500 506
501#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */ 507#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */
502 508
503unsigned char WAVELAN_BEACON_ADDRESS[]= {0x09,0x00,0x0e,0x20,0x03,0x00}; 509static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00};
504 510
505void wv_roam_init(struct net_device *dev) 511static void wv_roam_init(struct net_device *dev)
506{ 512{
507 net_local *lp= netdev_priv(dev); 513 net_local *lp= netdev_priv(dev);
508 514
@@ -531,7 +537,7 @@ void wv_roam_init(struct net_device *dev)
531 printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name); 537 printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
532} 538}
533 539
534void wv_roam_cleanup(struct net_device *dev) 540static void wv_roam_cleanup(struct net_device *dev)
535{ 541{
536 wavepoint_history *ptr,*old_ptr; 542 wavepoint_history *ptr,*old_ptr;
537 net_local *lp= netdev_priv(dev); 543 net_local *lp= netdev_priv(dev);
@@ -550,7 +556,7 @@ void wv_roam_cleanup(struct net_device *dev)
550} 556}
551 557
552/* Enable/Disable NWID promiscuous mode on a given device */ 558/* Enable/Disable NWID promiscuous mode on a given device */
553void wv_nwid_filter(unsigned char mode, net_local *lp) 559static void wv_nwid_filter(unsigned char mode, net_local *lp)
554{ 560{
555 mm_t m; 561 mm_t m;
556 unsigned long flags; 562 unsigned long flags;
@@ -575,7 +581,7 @@ void wv_nwid_filter(unsigned char mode, net_local *lp)
575} 581}
576 582
577/* Find a record in the WavePoint table matching a given NWID */ 583/* Find a record in the WavePoint table matching a given NWID */
578wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp) 584static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
579{ 585{
580 wavepoint_history *ptr=lp->wavepoint_table.head; 586 wavepoint_history *ptr=lp->wavepoint_table.head;
581 587
@@ -588,7 +594,7 @@ wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
588} 594}
589 595
590/* Create a new wavepoint table entry */ 596/* Create a new wavepoint table entry */
591wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp) 597static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
592{ 598{
593 wavepoint_history *new_wavepoint; 599 wavepoint_history *new_wavepoint;
594 600
@@ -624,7 +630,7 @@ wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_
624} 630}
625 631
626/* Remove a wavepoint entry from WavePoint table */ 632/* Remove a wavepoint entry from WavePoint table */
627void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp) 633static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
628{ 634{
629 if(wavepoint==NULL) 635 if(wavepoint==NULL)
630 return; 636 return;
@@ -646,7 +652,7 @@ void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
646} 652}
647 653
648/* Timer callback function - checks WavePoint table for stale entries */ 654/* Timer callback function - checks WavePoint table for stale entries */
649void wl_cell_expiry(unsigned long data) 655static void wl_cell_expiry(unsigned long data)
650{ 656{
651 net_local *lp=(net_local *)data; 657 net_local *lp=(net_local *)data;
652 wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point; 658 wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
@@ -686,7 +692,7 @@ void wl_cell_expiry(unsigned long data)
686} 692}
687 693
688/* Update SNR history of a wavepoint */ 694/* Update SNR history of a wavepoint */
689void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq) 695static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)
690{ 696{
691 int i=0,num_missed=0,ptr=0; 697 int i=0,num_missed=0,ptr=0;
692 int average_fast=0,average_slow=0; 698 int average_fast=0,average_slow=0;
@@ -723,7 +729,7 @@ void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsi
723} 729}
724 730
725/* Perform a handover to a new WavePoint */ 731/* Perform a handover to a new WavePoint */
726void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp) 732static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
727{ 733{
728 kio_addr_t base = lp->dev->base_addr; 734 kio_addr_t base = lp->dev->base_addr;
729 mm_t m; 735 mm_t m;
diff --git a/drivers/net/wireless/wavelan_cs.h b/drivers/net/wireless/wavelan_cs.h
index 29cff6daf860..fabc63ee153c 100644
--- a/drivers/net/wireless/wavelan_cs.h
+++ b/drivers/net/wireless/wavelan_cs.h
@@ -62,7 +62,7 @@
62 * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this 62 * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this
63 * part to accommodate your hardware... 63 * part to accommodate your hardware...
64 */ 64 */
65const unsigned char MAC_ADDRESSES[][3] = 65static const unsigned char MAC_ADDRESSES[][3] =
66{ 66{
67 { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */ 67 { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */
68 { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */ 68 { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */
@@ -79,14 +79,14 @@ const unsigned char MAC_ADDRESSES[][3] =
79 * (as read in the offset register of the dac area). 79 * (as read in the offset register of the dac area).
80 * Used to map channel numbers used by `wfreqsel' to frequencies 80 * Used to map channel numbers used by `wfreqsel' to frequencies
81 */ 81 */
82const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, 82static const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
83 0xD0, 0xF0, 0xF8, 0x150 }; 83 0xD0, 0xF0, 0xF8, 0x150 };
84 84
85/* Frequencies of the 1.0 modem (fixed frequencies). 85/* Frequencies of the 1.0 modem (fixed frequencies).
86 * Use to map the PSA `subband' to a frequency 86 * Use to map the PSA `subband' to a frequency
87 * Note : all frequencies apart from the first one need to be multiplied by 10 87 * Note : all frequencies apart from the first one need to be multiplied by 10
88 */ 88 */
89const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; 89static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
90 90
91 91
92/*************************** PC INTERFACE ****************************/ 92/*************************** PC INTERFACE ****************************/
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index ea2ef8dddb92..4ac359ed5b51 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -648,23 +648,6 @@ struct net_local
648 void __iomem *mem; 648 void __iomem *mem;
649}; 649};
650 650
651/**************************** PROTOTYPES ****************************/
652
653#ifdef WAVELAN_ROAMING
654/* ---------------------- ROAMING SUBROUTINES -----------------------*/
655
656wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp);
657wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local *lp);
658void wl_del_wavepoint(wavepoint_history *wavepoint, net_local *lp);
659void wl_cell_expiry(unsigned long data);
660wavepoint_history *wl_best_sigqual(int fast_search, net_local *lp);
661void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq);
662void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp);
663void wv_nwid_filter(unsigned char mode, net_local *lp);
664void wv_roam_init(struct net_device *dev);
665void wv_roam_cleanup(struct net_device *dev);
666#endif /* WAVELAN_ROAMING */
667
668/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ 651/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
669static inline u_char /* data */ 652static inline u_char /* data */
670 hasr_read(u_long); /* Read the host interface : base address */ 653 hasr_read(u_long); /* Read the host interface : base address */
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 1433e5aaf1b4..0e3afab62750 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -297,7 +297,8 @@ static int wl3501_get_flash_mac_addr(struct wl3501_card *this)
297 * 297 *
298 * Move 'size' bytes from PC to card. (Shouldn't be interrupted) 298 * Move 'size' bytes from PC to card. (Shouldn't be interrupted)
299 */ 299 */
300void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size) 300static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src,
301 int size)
301{ 302{
302 /* switch to SRAM Page 0 */ 303 /* switch to SRAM Page 0 */
303 wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 : 304 wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 :
@@ -318,8 +319,8 @@ void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size)
318 * 319 *
319 * Move 'size' bytes from card to PC. (Shouldn't be interrupted) 320 * Move 'size' bytes from card to PC. (Shouldn't be interrupted)
320 */ 321 */
321void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest, 322static void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest,
322 int size) 323 int size)
323{ 324{
324 /* switch to SRAM Page 0 */ 325 /* switch to SRAM Page 0 */
325 wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 : 326 wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 :
@@ -1439,14 +1440,14 @@ fail:
1439 goto out; 1440 goto out;
1440} 1441}
1441 1442
1442struct net_device_stats *wl3501_get_stats(struct net_device *dev) 1443static struct net_device_stats *wl3501_get_stats(struct net_device *dev)
1443{ 1444{
1444 struct wl3501_card *this = dev->priv; 1445 struct wl3501_card *this = dev->priv;
1445 1446
1446 return &this->stats; 1447 return &this->stats;
1447} 1448}
1448 1449
1449struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) 1450static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
1450{ 1451{
1451 struct wl3501_card *this = dev->priv; 1452 struct wl3501_card *this = dev->priv;
1452 struct iw_statistics *wstats = &this->wstats; 1453 struct iw_statistics *wstats = &this->wstats;