aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@evo.osdl.org>2005-09-02 03:48:33 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-02 03:48:33 -0400
commit5d8c397f304e1363f8ff9749b08172eb59e6534a (patch)
tree57ff502553918aa7309b7375e983f27f719e7b28 /drivers/net/wireless/hostap
parent44757223cd77f6e332dfa0b043c67df7b665bc19 (diff)
parentceeec3dc375e3b0618f16b34efc56fe093918f8b (diff)
Merge refs/heads/ieee80211-wifi from master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/wireless/hostap')
-rw-r--r--drivers/net/wireless/hostap/Kconfig71
-rw-r--r--drivers/net/wireless/hostap/Makefile5
-rw-r--r--drivers/net/wireless/hostap/hostap.c1198
-rw-r--r--drivers/net/wireless/hostap/hostap.h57
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h96
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c1091
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c524
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c3288
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h261
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h435
-rw-r--r--drivers/net/wireless/hostap/hostap_config.h55
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c1030
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c766
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c3445
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c499
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c4102
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c473
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c645
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c448
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h1033
20 files changed, 19522 insertions, 0 deletions
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig
new file mode 100644
index 000000000000..1445f3f2600f
--- /dev/null
+++ b/drivers/net/wireless/hostap/Kconfig
@@ -0,0 +1,71 @@
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 See <http://hostap.epitest.fi/> for more information about the
11 Host AP driver configuration and tools. This site includes
12 information and tools (hostapd and wpa_supplicant) for WPA/WPA2
13 support.
14
15 This option includes the base Host AP driver code that is shared by
16 different hardware models. You will also need to enable support for
17 PLX/PCI/CS version of the driver to actually use the driver.
18
19 The driver can be compiled as a module and it will be called
20 "hostap.ko".
21
22config HOSTAP_FIRMWARE
23 bool "Support downloading firmware images with Host AP driver"
24 depends on HOSTAP
25 ---help---
26 Configure Host AP driver to include support for firmware image
27 download. Current version supports only downloading to volatile, i.e.,
28 RAM memory. Flash upgrade is not yet supported.
29
30 Firmware image downloading needs user space tool, prism2_srec. It is
31 available from http://hostap.epitest.fi/.
32
33config HOSTAP_PLX
34 tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
35 depends on PCI && HOSTAP
36 ---help---
37 Host AP driver's version for Prism2/2.5/3 PC Cards in PLX9052 based
38 PCI adaptors.
39
40 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
41 driver and its help text includes more information about the Host AP
42 driver.
43
44 The driver can be compiled as a module and will be named
45 "hostap_plx.ko".
46
47config HOSTAP_PCI
48 tristate "Host AP driver for Prism2.5 PCI adaptors"
49 depends on PCI && HOSTAP
50 ---help---
51 Host AP driver's version for Prism2.5 PCI adaptors.
52
53 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
54 driver and its help text includes more information about the Host AP
55 driver.
56
57 The driver can be compiled as a module and will be named
58 "hostap_pci.ko".
59
60config HOSTAP_CS
61 tristate "Host AP driver for Prism2/2.5/3 PC Cards"
62 depends on PCMCIA!=n && HOSTAP
63 ---help---
64 Host AP driver's version for Prism2/2.5/3 PC Cards.
65
66 "Host AP support for Prism2/2.5/3 IEEE 802.11b" is required for this
67 driver and its help text includes more information about the Host AP
68 driver.
69
70 The driver can be compiled as a module and will be named
71 "hostap_cs.ko".
diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile
new file mode 100644
index 000000000000..fc62235bfc24
--- /dev/null
+++ b/drivers/net/wireless/hostap/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_HOSTAP) += hostap.o
2
3obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
4obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o
5obj-$(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..e7f5821b4942
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -0,0 +1,1198 @@
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-2005, 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#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/proc_fs.h>
21#include <linux/if_arp.h>
22#include <linux/delay.h>
23#include <linux/random.h>
24#include <linux/workqueue.h>
25#include <linux/kmod.h>
26#include <linux/rtnetlink.h>
27#include <linux/wireless.h>
28#include <net/iw_handler.h>
29#include <net/ieee80211.h>
30#include <net/ieee80211_crypt.h>
31#include <asm/uaccess.h>
32
33#include "hostap_wlan.h"
34#include "hostap_80211.h"
35#include "hostap_ap.h"
36#include "hostap.h"
37
38MODULE_AUTHOR("Jouni Malinen");
39MODULE_DESCRIPTION("Host AP common routines");
40MODULE_LICENSE("GPL");
41MODULE_VERSION(PRISM2_VERSION);
42
43#define TX_TIMEOUT (2 * HZ)
44
45#define PRISM2_MAX_FRAME_SIZE 2304
46#define PRISM2_MIN_MTU 256
47/* FIX: */
48#define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */))
49
50
51/* hostap.c */
52static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
53 int rtnl_locked);
54static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
55 int rtnl_locked, int do_not_remove);
56
57/* hostap_ap.c */
58static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
59 struct iw_quality qual[], int buf_size,
60 int aplist);
61static int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
62static int prism2_hostapd(struct ap_data *ap,
63 struct prism2_hostapd_param *param);
64static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
65 struct ieee80211_crypt_data ***crypt);
66static void ap_control_kickall(struct ap_data *ap);
67#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
68static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
69 u8 *mac);
70static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
71 u8 *mac);
72static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
73static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
74 u8 *mac);
75#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */
76
77
78static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
79 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
80#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
81
82
83/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
84/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
85static unsigned char rfc1042_header[] =
86{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
87/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
88static unsigned char bridge_tunnel_header[] =
89{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
90/* No encapsulation header if EtherType < 0x600 (=length) */
91
92
93/* FIX: these could be compiled separately and linked together to hostap.o */
94#include "hostap_ap.c"
95#include "hostap_info.c"
96#include "hostap_ioctl.c"
97#include "hostap_proc.c"
98#include "hostap_80211_rx.c"
99#include "hostap_80211_tx.c"
100
101
102struct net_device * hostap_add_interface(struct local_info *local,
103 int type, int rtnl_locked,
104 const char *prefix,
105 const char *name)
106{
107 struct net_device *dev, *mdev;
108 struct hostap_interface *iface;
109 int ret;
110
111 dev = alloc_etherdev(sizeof(struct hostap_interface));
112 if (dev == NULL)
113 return NULL;
114
115 iface = netdev_priv(dev);
116 iface->dev = dev;
117 iface->local = local;
118 iface->type = type;
119 list_add(&iface->list, &local->hostap_interfaces);
120
121 mdev = local->dev;
122 memcpy(dev->dev_addr, mdev->dev_addr, ETH_ALEN);
123 dev->base_addr = mdev->base_addr;
124 dev->irq = mdev->irq;
125 dev->mem_start = mdev->mem_start;
126 dev->mem_end = mdev->mem_end;
127
128 hostap_setup_dev(dev, local, 0);
129 dev->destructor = free_netdev;
130
131 sprintf(dev->name, "%s%s", prefix, name);
132 if (!rtnl_locked)
133 rtnl_lock();
134
135 ret = 0;
136 if (strchr(dev->name, '%'))
137 ret = dev_alloc_name(dev, dev->name);
138
139 SET_NETDEV_DEV(dev, mdev->class_dev.dev);
140 if (ret >= 0)
141 ret = register_netdevice(dev);
142
143 if (!rtnl_locked)
144 rtnl_unlock();
145
146 if (ret < 0) {
147 printk(KERN_WARNING "%s: failed to add new netdevice!\n",
148 dev->name);
149 free_netdev(dev);
150 return NULL;
151 }
152
153 printk(KERN_DEBUG "%s: registered netdevice %s\n",
154 mdev->name, dev->name);
155
156 return dev;
157}
158
159
160void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
161 int remove_from_list)
162{
163 struct hostap_interface *iface;
164
165 if (!dev)
166 return;
167
168 iface = netdev_priv(dev);
169
170 if (remove_from_list) {
171 list_del(&iface->list);
172 }
173
174 if (dev == iface->local->ddev)
175 iface->local->ddev = NULL;
176 else if (dev == iface->local->apdev)
177 iface->local->apdev = NULL;
178 else if (dev == iface->local->stadev)
179 iface->local->stadev = NULL;
180
181 if (rtnl_locked)
182 unregister_netdevice(dev);
183 else
184 unregister_netdev(dev);
185
186 /* dev->destructor = free_netdev() will free the device data, including
187 * private data, when removing the device */
188}
189
190
191static inline int prism2_wds_special_addr(u8 *addr)
192{
193 if (addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5])
194 return 0;
195
196 return 1;
197}
198
199
200static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
201 int rtnl_locked)
202{
203 struct net_device *dev;
204 struct list_head *ptr;
205 struct hostap_interface *iface, *empty, *match;
206
207 empty = match = NULL;
208 read_lock_bh(&local->iface_lock);
209 list_for_each(ptr, &local->hostap_interfaces) {
210 iface = list_entry(ptr, struct hostap_interface, list);
211 if (iface->type != HOSTAP_INTERFACE_WDS)
212 continue;
213
214 if (prism2_wds_special_addr(iface->u.wds.remote_addr))
215 empty = iface;
216 else if (memcmp(iface->u.wds.remote_addr, remote_addr,
217 ETH_ALEN) == 0) {
218 match = iface;
219 break;
220 }
221 }
222 if (!match && empty && !prism2_wds_special_addr(remote_addr)) {
223 /* take pre-allocated entry into use */
224 memcpy(empty->u.wds.remote_addr, remote_addr, ETH_ALEN);
225 read_unlock_bh(&local->iface_lock);
226 printk(KERN_DEBUG "%s: using pre-allocated WDS netdevice %s\n",
227 local->dev->name, empty->dev->name);
228 return 0;
229 }
230 read_unlock_bh(&local->iface_lock);
231
232 if (!prism2_wds_special_addr(remote_addr)) {
233 if (match)
234 return -EEXIST;
235 hostap_add_sta(local->ap, remote_addr);
236 }
237
238 if (local->wds_connections >= local->wds_max_connections)
239 return -ENOBUFS;
240
241 /* verify that there is room for wds# postfix in the interface name */
242 if (strlen(local->dev->name) > IFNAMSIZ - 5) {
243 printk(KERN_DEBUG "'%s' too long base device name\n",
244 local->dev->name);
245 return -EINVAL;
246 }
247
248 dev = hostap_add_interface(local, HOSTAP_INTERFACE_WDS, rtnl_locked,
249 local->ddev->name, "wds%d");
250 if (dev == NULL)
251 return -ENOMEM;
252
253 iface = netdev_priv(dev);
254 memcpy(iface->u.wds.remote_addr, remote_addr, ETH_ALEN);
255
256 local->wds_connections++;
257
258 return 0;
259}
260
261
262static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
263 int rtnl_locked, int do_not_remove)
264{
265 unsigned long flags;
266 struct list_head *ptr;
267 struct hostap_interface *iface, *selected = NULL;
268
269 write_lock_irqsave(&local->iface_lock, flags);
270 list_for_each(ptr, &local->hostap_interfaces) {
271 iface = list_entry(ptr, struct hostap_interface, list);
272 if (iface->type != HOSTAP_INTERFACE_WDS)
273 continue;
274
275 if (memcmp(iface->u.wds.remote_addr, remote_addr,
276 ETH_ALEN) == 0) {
277 selected = iface;
278 break;
279 }
280 }
281 if (selected && !do_not_remove)
282 list_del(&selected->list);
283 write_unlock_irqrestore(&local->iface_lock, flags);
284
285 if (selected) {
286 if (do_not_remove)
287 memset(selected->u.wds.remote_addr, 0, ETH_ALEN);
288 else {
289 hostap_remove_interface(selected->dev, rtnl_locked, 0);
290 local->wds_connections--;
291 }
292 }
293
294 return selected ? 0 : -ENODEV;
295}
296
297
298u16 hostap_tx_callback_register(local_info_t *local,
299 void (*func)(struct sk_buff *, int ok, void *),
300 void *data)
301{
302 unsigned long flags;
303 struct hostap_tx_callback_info *entry;
304
305 entry = (struct hostap_tx_callback_info *) kmalloc(sizeof(*entry),
306 GFP_ATOMIC);
307 if (entry == NULL)
308 return 0;
309
310 entry->func = func;
311 entry->data = data;
312
313 spin_lock_irqsave(&local->lock, flags);
314 entry->idx = local->tx_callback ? local->tx_callback->idx + 1 : 1;
315 entry->next = local->tx_callback;
316 local->tx_callback = entry;
317 spin_unlock_irqrestore(&local->lock, flags);
318
319 return entry->idx;
320}
321
322
323int hostap_tx_callback_unregister(local_info_t *local, u16 idx)
324{
325 unsigned long flags;
326 struct hostap_tx_callback_info *cb, *prev = NULL;
327
328 spin_lock_irqsave(&local->lock, flags);
329 cb = local->tx_callback;
330 while (cb != NULL && cb->idx != idx) {
331 prev = cb;
332 cb = cb->next;
333 }
334 if (cb) {
335 if (prev == NULL)
336 local->tx_callback = cb->next;
337 else
338 prev->next = cb->next;
339 kfree(cb);
340 }
341 spin_unlock_irqrestore(&local->lock, flags);
342
343 return cb ? 0 : -1;
344}
345
346
347/* val is in host byte order */
348int hostap_set_word(struct net_device *dev, int rid, u16 val)
349{
350 struct hostap_interface *iface;
351 u16 tmp = cpu_to_le16(val);
352 iface = netdev_priv(dev);
353 return iface->local->func->set_rid(dev, rid, &tmp, 2);
354}
355
356
357int hostap_set_string(struct net_device *dev, int rid, const char *val)
358{
359 struct hostap_interface *iface;
360 char buf[MAX_SSID_LEN + 2];
361 int len;
362
363 iface = netdev_priv(dev);
364 len = strlen(val);
365 if (len > MAX_SSID_LEN)
366 return -1;
367 memset(buf, 0, sizeof(buf));
368 buf[0] = len; /* little endian 16 bit word */
369 memcpy(buf + 2, val, len);
370
371 return iface->local->func->set_rid(dev, rid, &buf, MAX_SSID_LEN + 2);
372}
373
374
375u16 hostap_get_porttype(local_info_t *local)
376{
377 if (local->iw_mode == IW_MODE_ADHOC && local->pseudo_adhoc)
378 return HFA384X_PORTTYPE_PSEUDO_IBSS;
379 if (local->iw_mode == IW_MODE_ADHOC)
380 return HFA384X_PORTTYPE_IBSS;
381 if (local->iw_mode == IW_MODE_INFRA)
382 return HFA384X_PORTTYPE_BSS;
383 if (local->iw_mode == IW_MODE_REPEAT)
384 return HFA384X_PORTTYPE_WDS;
385 if (local->iw_mode == IW_MODE_MONITOR)
386 return HFA384X_PORTTYPE_PSEUDO_IBSS;
387 return HFA384X_PORTTYPE_HOSTAP;
388}
389
390
391int hostap_set_encryption(local_info_t *local)
392{
393 u16 val, old_val;
394 int i, keylen, len, idx;
395 char keybuf[WEP_KEY_LEN + 1];
396 enum { NONE, WEP, OTHER } encrypt_type;
397
398 idx = local->tx_keyidx;
399 if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL)
400 encrypt_type = NONE;
401 else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0)
402 encrypt_type = WEP;
403 else
404 encrypt_type = OTHER;
405
406 if (local->func->get_rid(local->dev, HFA384X_RID_CNFWEPFLAGS, &val, 2,
407 1) < 0) {
408 printk(KERN_DEBUG "Could not read current WEP flags.\n");
409 goto fail;
410 }
411 le16_to_cpus(&val);
412 old_val = val;
413
414 if (encrypt_type != NONE || local->privacy_invoked)
415 val |= HFA384X_WEPFLAGS_PRIVACYINVOKED;
416 else
417 val &= ~HFA384X_WEPFLAGS_PRIVACYINVOKED;
418
419 if (local->open_wep || encrypt_type == NONE ||
420 ((local->ieee_802_1x || local->wpa) && local->host_decrypt))
421 val &= ~HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED;
422 else
423 val |= HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED;
424
425 if ((encrypt_type != NONE || local->privacy_invoked) &&
426 (encrypt_type == OTHER || local->host_encrypt))
427 val |= HFA384X_WEPFLAGS_HOSTENCRYPT;
428 else
429 val &= ~HFA384X_WEPFLAGS_HOSTENCRYPT;
430 if ((encrypt_type != NONE || local->privacy_invoked) &&
431 (encrypt_type == OTHER || local->host_decrypt))
432 val |= HFA384X_WEPFLAGS_HOSTDECRYPT;
433 else
434 val &= ~HFA384X_WEPFLAGS_HOSTDECRYPT;
435
436 if (val != old_val &&
437 hostap_set_word(local->dev, HFA384X_RID_CNFWEPFLAGS, val)) {
438 printk(KERN_DEBUG "Could not write new WEP flags (0x%x)\n",
439 val);
440 goto fail;
441 }
442
443 if (encrypt_type != WEP)
444 return 0;
445
446 /* 104-bit support seems to require that all the keys are set to the
447 * same keylen */
448 keylen = 6; /* first 5 octets */
449 len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf),
450 NULL, local->crypt[idx]->priv);
451 if (idx >= 0 && idx < WEP_KEYS && len > 5)
452 keylen = WEP_KEY_LEN + 1; /* first 13 octets */
453
454 for (i = 0; i < WEP_KEYS; i++) {
455 memset(keybuf, 0, sizeof(keybuf));
456 if (local->crypt[i]) {
457 (void) local->crypt[i]->ops->get_key(
458 keybuf, sizeof(keybuf),
459 NULL, local->crypt[i]->priv);
460 }
461 if (local->func->set_rid(local->dev,
462 HFA384X_RID_CNFDEFAULTKEY0 + i,
463 keybuf, keylen)) {
464 printk(KERN_DEBUG "Could not set key %d (len=%d)\n",
465 i, keylen);
466 goto fail;
467 }
468 }
469 if (hostap_set_word(local->dev, HFA384X_RID_CNFWEPDEFAULTKEYID, idx)) {
470 printk(KERN_DEBUG "Could not set default keyid %d\n", idx);
471 goto fail;
472 }
473
474 return 0;
475
476 fail:
477 printk(KERN_DEBUG "%s: encryption setup failed\n", local->dev->name);
478 return -1;
479}
480
481
482int hostap_set_antsel(local_info_t *local)
483{
484 u16 val;
485 int ret = 0;
486
487 if (local->antsel_tx != HOSTAP_ANTSEL_DO_NOT_TOUCH &&
488 local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF,
489 HFA386X_CR_TX_CONFIGURE,
490 NULL, &val) == 0) {
491 val &= ~(BIT(2) | BIT(1));
492 switch (local->antsel_tx) {
493 case HOSTAP_ANTSEL_DIVERSITY:
494 val |= BIT(1);
495 break;
496 case HOSTAP_ANTSEL_LOW:
497 break;
498 case HOSTAP_ANTSEL_HIGH:
499 val |= BIT(2);
500 break;
501 }
502
503 if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF,
504 HFA386X_CR_TX_CONFIGURE, &val, NULL)) {
505 printk(KERN_INFO "%s: setting TX AntSel failed\n",
506 local->dev->name);
507 ret = -1;
508 }
509 }
510
511 if (local->antsel_rx != HOSTAP_ANTSEL_DO_NOT_TOUCH &&
512 local->func->cmd(local->dev, HFA384X_CMDCODE_READMIF,
513 HFA386X_CR_RX_CONFIGURE,
514 NULL, &val) == 0) {
515 val &= ~(BIT(1) | BIT(0));
516 switch (local->antsel_rx) {
517 case HOSTAP_ANTSEL_DIVERSITY:
518 break;
519 case HOSTAP_ANTSEL_LOW:
520 val |= BIT(0);
521 break;
522 case HOSTAP_ANTSEL_HIGH:
523 val |= BIT(0) | BIT(1);
524 break;
525 }
526
527 if (local->func->cmd(local->dev, HFA384X_CMDCODE_WRITEMIF,
528 HFA386X_CR_RX_CONFIGURE, &val, NULL)) {
529 printk(KERN_INFO "%s: setting RX AntSel failed\n",
530 local->dev->name);
531 ret = -1;
532 }
533 }
534
535 return ret;
536}
537
538
539int hostap_set_roaming(local_info_t *local)
540{
541 u16 val;
542
543 switch (local->host_roaming) {
544 case 1:
545 val = HFA384X_ROAMING_HOST;
546 break;
547 case 2:
548 val = HFA384X_ROAMING_DISABLED;
549 break;
550 case 0:
551 default:
552 val = HFA384X_ROAMING_FIRMWARE;
553 break;
554 }
555
556 return hostap_set_word(local->dev, HFA384X_RID_CNFROAMINGMODE, val);
557}
558
559
560int hostap_set_auth_algs(local_info_t *local)
561{
562 int val = local->auth_algs;
563 /* At least STA f/w v0.6.2 seems to have issues with cnfAuthentication
564 * set to include both Open and Shared Key flags. It tries to use
565 * Shared Key authentication in that case even if WEP keys are not
566 * configured.. STA f/w v0.7.6 is able to handle such configuration,
567 * but it is unknown when this was fixed between 0.6.2 .. 0.7.6. */
568 if (local->sta_fw_ver < PRISM2_FW_VER(0,7,0) &&
569 val != PRISM2_AUTH_OPEN && val != PRISM2_AUTH_SHARED_KEY)
570 val = PRISM2_AUTH_OPEN;
571
572 if (hostap_set_word(local->dev, HFA384X_RID_CNFAUTHENTICATION, val)) {
573 printk(KERN_INFO "%s: cnfAuthentication setting to 0x%x "
574 "failed\n", local->dev->name, local->auth_algs);
575 return -EINVAL;
576 }
577
578 return 0;
579}
580
581
582void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
583{
584 u16 status, fc;
585
586 status = __le16_to_cpu(rx->status);
587
588 printk(KERN_DEBUG "%s: RX status=0x%04x (port=%d, type=%d, "
589 "fcserr=%d) silence=%d signal=%d rate=%d rxflow=%d; "
590 "jiffies=%ld\n",
591 name, status, (status >> 8) & 0x07, status >> 13, status & 1,
592 rx->silence, rx->signal, rx->rate, rx->rxflow, jiffies);
593
594 fc = __le16_to_cpu(rx->frame_control);
595 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
596 "data_len=%d%s%s\n",
597 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
598 __le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl),
599 __le16_to_cpu(rx->data_len),
600 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
601 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
602
603 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4="
604 MACSTR "\n",
605 MAC2STR(rx->addr1), MAC2STR(rx->addr2), MAC2STR(rx->addr3),
606 MAC2STR(rx->addr4));
607
608 printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n",
609 MAC2STR(rx->dst_addr), MAC2STR(rx->src_addr),
610 __be16_to_cpu(rx->len));
611}
612
613
614void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
615{
616 u16 fc;
617
618 printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d "
619 "tx_control=0x%04x; jiffies=%ld\n",
620 name, __le16_to_cpu(tx->status), tx->retry_count, tx->tx_rate,
621 __le16_to_cpu(tx->tx_control), jiffies);
622
623 fc = __le16_to_cpu(tx->frame_control);
624 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
625 "data_len=%d%s%s\n",
626 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
627 __le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl),
628 __le16_to_cpu(tx->data_len),
629 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
630 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
631
632 printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4="
633 MACSTR "\n",
634 MAC2STR(tx->addr1), MAC2STR(tx->addr2), MAC2STR(tx->addr3),
635 MAC2STR(tx->addr4));
636
637 printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n",
638 MAC2STR(tx->dst_addr), MAC2STR(tx->src_addr),
639 __be16_to_cpu(tx->len));
640}
641
642
643int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr)
644{
645 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); /* addr2 */
646 return ETH_ALEN;
647}
648
649
650int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr)
651{
652 if (*(u32 *)skb->mac.raw == LWNG_CAP_DID_BASE) {
653 memcpy(haddr, skb->mac.raw +
654 sizeof(struct linux_wlan_ng_prism_hdr) + 10,
655 ETH_ALEN); /* addr2 */
656 } else { /* (*(u32 *)skb->mac.raw == htonl(LWNG_CAPHDR_VERSION)) */
657 memcpy(haddr, skb->mac.raw +
658 sizeof(struct linux_wlan_ng_cap_hdr) + 10,
659 ETH_ALEN); /* addr2 */
660 }
661 return ETH_ALEN;
662}
663
664
665int hostap_80211_get_hdrlen(u16 fc)
666{
667 int hdrlen = 24;
668
669 switch (WLAN_FC_GET_TYPE(fc)) {
670 case IEEE80211_FTYPE_DATA:
671 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
672 hdrlen = 30; /* Addr4 */
673 break;
674 case IEEE80211_FTYPE_CTL:
675 switch (WLAN_FC_GET_STYPE(fc)) {
676 case IEEE80211_STYPE_CTS:
677 case IEEE80211_STYPE_ACK:
678 hdrlen = 10;
679 break;
680 default:
681 hdrlen = 16;
682 break;
683 }
684 break;
685 }
686
687 return hdrlen;
688}
689
690
691struct net_device_stats *hostap_get_stats(struct net_device *dev)
692{
693 struct hostap_interface *iface;
694 iface = netdev_priv(dev);
695 return &iface->stats;
696}
697
698
699static int prism2_close(struct net_device *dev)
700{
701 struct hostap_interface *iface;
702 local_info_t *local;
703
704 PDEBUG(DEBUG_FLOW, "%s: prism2_close\n", dev->name);
705
706 iface = netdev_priv(dev);
707 local = iface->local;
708
709 if (dev == local->ddev) {
710 prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
711 }
712#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
713 if (!local->hostapd && dev == local->dev &&
714 (!local->func->card_present || local->func->card_present(local)) &&
715 local->hw_ready && local->ap && local->iw_mode == IW_MODE_MASTER)
716 hostap_deauth_all_stas(dev, local->ap, 1);
717#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
718
719 if (local->func->dev_close && local->func->dev_close(local))
720 return 0;
721
722 if (dev == local->dev) {
723 local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
724 }
725
726 if (netif_running(dev)) {
727 netif_stop_queue(dev);
728 netif_device_detach(dev);
729 }
730
731 flush_scheduled_work();
732
733 module_put(local->hw_module);
734
735 local->num_dev_open--;
736
737 if (dev != local->dev && local->dev->flags & IFF_UP &&
738 local->master_dev_auto_open && local->num_dev_open == 1) {
739 /* Close master radio interface automatically if it was also
740 * opened automatically and we are now closing the last
741 * remaining non-master device. */
742 dev_close(local->dev);
743 }
744
745 return 0;
746}
747
748
749static int prism2_open(struct net_device *dev)
750{
751 struct hostap_interface *iface;
752 local_info_t *local;
753
754 PDEBUG(DEBUG_FLOW, "%s: prism2_open\n", dev->name);
755
756 iface = netdev_priv(dev);
757 local = iface->local;
758
759 if (local->no_pri) {
760 printk(KERN_DEBUG "%s: could not set interface UP - no PRI "
761 "f/w\n", dev->name);
762 return 1;
763 }
764
765 if ((local->func->card_present && !local->func->card_present(local)) ||
766 local->hw_downloading)
767 return -ENODEV;
768
769 if (local->func->dev_open && local->func->dev_open(local))
770 return 1;
771
772 if (!try_module_get(local->hw_module))
773 return -ENODEV;
774 local->num_dev_open++;
775
776 if (!local->dev_enabled && local->func->hw_enable(dev, 1)) {
777 printk(KERN_WARNING "%s: could not enable MAC port\n",
778 dev->name);
779 prism2_close(dev);
780 return 1;
781 }
782 if (!local->dev_enabled)
783 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
784 local->dev_enabled = 1;
785
786 if (dev != local->dev && !(local->dev->flags & IFF_UP)) {
787 /* Master radio interface is needed for all operation, so open
788 * it automatically when any virtual net_device is opened. */
789 local->master_dev_auto_open = 1;
790 dev_open(local->dev);
791 }
792
793 netif_device_attach(dev);
794 netif_start_queue(dev);
795
796 return 0;
797}
798
799
800static int prism2_set_mac_address(struct net_device *dev, void *p)
801{
802 struct hostap_interface *iface;
803 local_info_t *local;
804 struct list_head *ptr;
805 struct sockaddr *addr = p;
806
807 iface = netdev_priv(dev);
808 local = iface->local;
809
810 if (local->func->set_rid(dev, HFA384X_RID_CNFOWNMACADDR, addr->sa_data,
811 ETH_ALEN) < 0 || local->func->reset_port(dev))
812 return -EINVAL;
813
814 read_lock_bh(&local->iface_lock);
815 list_for_each(ptr, &local->hostap_interfaces) {
816 iface = list_entry(ptr, struct hostap_interface, list);
817 memcpy(iface->dev->dev_addr, addr->sa_data, ETH_ALEN);
818 }
819 memcpy(local->dev->dev_addr, addr->sa_data, ETH_ALEN);
820 read_unlock_bh(&local->iface_lock);
821
822 return 0;
823}
824
825
826/* TODO: to be further implemented as soon as Prism2 fully supports
827 * GroupAddresses and correct documentation is available */
828void hostap_set_multicast_list_queue(void *data)
829{
830 struct net_device *dev = (struct net_device *) data;
831 struct hostap_interface *iface;
832 local_info_t *local;
833
834 iface = netdev_priv(dev);
835 local = iface->local;
836 if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
837 local->is_promisc)) {
838 printk(KERN_INFO "%s: %sabling promiscuous mode failed\n",
839 dev->name, local->is_promisc ? "en" : "dis");
840 }
841}
842
843
844static void hostap_set_multicast_list(struct net_device *dev)
845{
846#if 0
847 /* FIX: promiscuous mode seems to be causing a lot of problems with
848 * some station firmware versions (FCSErr frames, invalid MACPort, etc.
849 * corrupted incoming frames). This code is now commented out while the
850 * problems are investigated. */
851 struct hostap_interface *iface;
852 local_info_t *local;
853
854 iface = netdev_priv(dev);
855 local = iface->local;
856 if ((dev->flags & IFF_ALLMULTI) || (dev->flags & IFF_PROMISC)) {
857 local->is_promisc = 1;
858 } else {
859 local->is_promisc = 0;
860 }
861
862 schedule_work(&local->set_multicast_list_queue);
863#endif
864}
865
866
867static int prism2_change_mtu(struct net_device *dev, int new_mtu)
868{
869 if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU)
870 return -EINVAL;
871
872 dev->mtu = new_mtu;
873 return 0;
874}
875
876
877static void prism2_tx_timeout(struct net_device *dev)
878{
879 struct hostap_interface *iface;
880 local_info_t *local;
881 struct hfa384x_regs regs;
882
883 iface = netdev_priv(dev);
884 local = iface->local;
885
886 printk(KERN_WARNING "%s Tx timed out! Resetting card\n", dev->name);
887 netif_stop_queue(local->dev);
888
889 local->func->read_regs(dev, &regs);
890 printk(KERN_DEBUG "%s: CMD=%04x EVSTAT=%04x "
891 "OFFSET0=%04x OFFSET1=%04x SWSUPPORT0=%04x\n",
892 dev->name, regs.cmd, regs.evstat, regs.offset0, regs.offset1,
893 regs.swsupport0);
894
895 local->func->schedule_reset(local);
896}
897
898
899void hostap_setup_dev(struct net_device *dev, local_info_t *local,
900 int main_dev)
901{
902 struct hostap_interface *iface;
903
904 iface = netdev_priv(dev);
905 ether_setup(dev);
906
907 /* kernel callbacks */
908 dev->get_stats = hostap_get_stats;
909 if (iface) {
910 /* Currently, we point to the proper spy_data only on
911 * the main_dev. This could be fixed. Jean II */
912 iface->wireless_data.spy_data = &iface->spy_data;
913 dev->wireless_data = &iface->wireless_data;
914 }
915 dev->wireless_handlers =
916 (struct iw_handler_def *) &hostap_iw_handler_def;
917 dev->do_ioctl = hostap_ioctl;
918 dev->open = prism2_open;
919 dev->stop = prism2_close;
920 dev->hard_start_xmit = hostap_data_start_xmit;
921 dev->set_mac_address = prism2_set_mac_address;
922 dev->set_multicast_list = hostap_set_multicast_list;
923 dev->change_mtu = prism2_change_mtu;
924 dev->tx_timeout = prism2_tx_timeout;
925 dev->watchdog_timeo = TX_TIMEOUT;
926
927 dev->mtu = local->mtu;
928 if (!main_dev) {
929 /* use main radio device queue */
930 dev->tx_queue_len = 0;
931 }
932
933 SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
934
935 netif_stop_queue(dev);
936}
937
938
939static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
940{
941 struct net_device *dev = local->dev;
942
943 if (local->apdev)
944 return -EEXIST;
945
946 printk(KERN_DEBUG "%s: enabling hostapd mode\n", dev->name);
947
948 local->apdev = hostap_add_interface(local, HOSTAP_INTERFACE_AP,
949 rtnl_locked, local->ddev->name,
950 "ap");
951 if (local->apdev == NULL)
952 return -ENOMEM;
953
954 local->apdev->hard_start_xmit = hostap_mgmt_start_xmit;
955 local->apdev->type = ARPHRD_IEEE80211;
956 local->apdev->hard_header_parse = hostap_80211_header_parse;
957
958 return 0;
959}
960
961
962static int hostap_disable_hostapd(local_info_t *local, int rtnl_locked)
963{
964 struct net_device *dev = local->dev;
965
966 printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name);
967
968 hostap_remove_interface(local->apdev, rtnl_locked, 1);
969 local->apdev = NULL;
970
971 return 0;
972}
973
974
975static int hostap_enable_hostapd_sta(local_info_t *local, int rtnl_locked)
976{
977 struct net_device *dev = local->dev;
978
979 if (local->stadev)
980 return -EEXIST;
981
982 printk(KERN_DEBUG "%s: enabling hostapd STA mode\n", dev->name);
983
984 local->stadev = hostap_add_interface(local, HOSTAP_INTERFACE_STA,
985 rtnl_locked, local->ddev->name,
986 "sta");
987 if (local->stadev == NULL)
988 return -ENOMEM;
989
990 return 0;
991}
992
993
994static int hostap_disable_hostapd_sta(local_info_t *local, int rtnl_locked)
995{
996 struct net_device *dev = local->dev;
997
998 printk(KERN_DEBUG "%s: disabling hostapd mode\n", dev->name);
999
1000 hostap_remove_interface(local->stadev, rtnl_locked, 1);
1001 local->stadev = NULL;
1002
1003 return 0;
1004}
1005
1006
1007int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked)
1008{
1009 int ret;
1010
1011 if (val < 0 || val > 1)
1012 return -EINVAL;
1013
1014 if (local->hostapd == val)
1015 return 0;
1016
1017 if (val) {
1018 ret = hostap_enable_hostapd(local, rtnl_locked);
1019 if (ret == 0)
1020 local->hostapd = 1;
1021 } else {
1022 local->hostapd = 0;
1023 ret = hostap_disable_hostapd(local, rtnl_locked);
1024 if (ret != 0)
1025 local->hostapd = 1;
1026 }
1027
1028 return ret;
1029}
1030
1031
1032int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked)
1033{
1034 int ret;
1035
1036 if (val < 0 || val > 1)
1037 return -EINVAL;
1038
1039 if (local->hostapd_sta == val)
1040 return 0;
1041
1042 if (val) {
1043 ret = hostap_enable_hostapd_sta(local, rtnl_locked);
1044 if (ret == 0)
1045 local->hostapd_sta = 1;
1046 } else {
1047 local->hostapd_sta = 0;
1048 ret = hostap_disable_hostapd_sta(local, rtnl_locked);
1049 if (ret != 0)
1050 local->hostapd_sta = 1;
1051 }
1052
1053
1054 return ret;
1055}
1056
1057
1058int prism2_update_comms_qual(struct net_device *dev)
1059{
1060 struct hostap_interface *iface;
1061 local_info_t *local;
1062 int ret = 0;
1063 struct hfa384x_comms_quality sq;
1064
1065 iface = netdev_priv(dev);
1066 local = iface->local;
1067 if (!local->sta_fw_ver)
1068 ret = -1;
1069 else if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1070 if (local->func->get_rid(local->dev,
1071 HFA384X_RID_DBMCOMMSQUALITY,
1072 &sq, sizeof(sq), 1) >= 0) {
1073 local->comms_qual = (s16) le16_to_cpu(sq.comm_qual);
1074 local->avg_signal = (s16) le16_to_cpu(sq.signal_level);
1075 local->avg_noise = (s16) le16_to_cpu(sq.noise_level);
1076 local->last_comms_qual_update = jiffies;
1077 } else
1078 ret = -1;
1079 } else {
1080 if (local->func->get_rid(local->dev, HFA384X_RID_COMMSQUALITY,
1081 &sq, sizeof(sq), 1) >= 0) {
1082 local->comms_qual = le16_to_cpu(sq.comm_qual);
1083 local->avg_signal = HFA384X_LEVEL_TO_dBm(
1084 le16_to_cpu(sq.signal_level));
1085 local->avg_noise = HFA384X_LEVEL_TO_dBm(
1086 le16_to_cpu(sq.noise_level));
1087 local->last_comms_qual_update = jiffies;
1088 } else
1089 ret = -1;
1090 }
1091
1092 return ret;
1093}
1094
1095
1096int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype,
1097 u8 *body, size_t bodylen)
1098{
1099 struct sk_buff *skb;
1100 struct hostap_ieee80211_mgmt *mgmt;
1101 struct hostap_skb_tx_data *meta;
1102 struct net_device *dev = local->dev;
1103
1104 skb = dev_alloc_skb(IEEE80211_MGMT_HDR_LEN + bodylen);
1105 if (skb == NULL)
1106 return -ENOMEM;
1107
1108 mgmt = (struct hostap_ieee80211_mgmt *)
1109 skb_put(skb, IEEE80211_MGMT_HDR_LEN);
1110 memset(mgmt, 0, IEEE80211_MGMT_HDR_LEN);
1111 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
1112 memcpy(mgmt->da, dst, ETH_ALEN);
1113 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1114 memcpy(mgmt->bssid, dst, ETH_ALEN);
1115 if (body)
1116 memcpy(skb_put(skb, bodylen), body, bodylen);
1117
1118 meta = (struct hostap_skb_tx_data *) skb->cb;
1119 memset(meta, 0, sizeof(*meta));
1120 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
1121 meta->iface = netdev_priv(dev);
1122
1123 skb->dev = dev;
1124 skb->mac.raw = skb->nh.raw = skb->data;
1125 dev_queue_xmit(skb);
1126
1127 return 0;
1128}
1129
1130
1131int prism2_sta_deauth(local_info_t *local, u16 reason)
1132{
1133 union iwreq_data wrqu;
1134 int ret;
1135
1136 if (local->iw_mode != IW_MODE_INFRA ||
1137 memcmp(local->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 ||
1138 memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0)
1139 return 0;
1140
1141 reason = cpu_to_le16(reason);
1142 ret = prism2_sta_send_mgmt(local, local->bssid, IEEE80211_STYPE_DEAUTH,
1143 (u8 *) &reason, 2);
1144 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1145 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
1146 return ret;
1147}
1148
1149
1150struct proc_dir_entry *hostap_proc;
1151
1152static int __init hostap_init(void)
1153{
1154 if (proc_net != NULL) {
1155 hostap_proc = proc_mkdir("hostap", proc_net);
1156 if (!hostap_proc)
1157 printk(KERN_WARNING "Failed to mkdir "
1158 "/proc/net/hostap\n");
1159 } else
1160 hostap_proc = NULL;
1161
1162 return 0;
1163}
1164
1165
1166static void __exit hostap_exit(void)
1167{
1168 if (hostap_proc != NULL) {
1169 hostap_proc = NULL;
1170 remove_proc_entry("hostap", proc_net);
1171 }
1172}
1173
1174
1175EXPORT_SYMBOL(hostap_set_word);
1176EXPORT_SYMBOL(hostap_set_string);
1177EXPORT_SYMBOL(hostap_get_porttype);
1178EXPORT_SYMBOL(hostap_set_encryption);
1179EXPORT_SYMBOL(hostap_set_antsel);
1180EXPORT_SYMBOL(hostap_set_roaming);
1181EXPORT_SYMBOL(hostap_set_auth_algs);
1182EXPORT_SYMBOL(hostap_dump_rx_header);
1183EXPORT_SYMBOL(hostap_dump_tx_header);
1184EXPORT_SYMBOL(hostap_80211_header_parse);
1185EXPORT_SYMBOL(hostap_80211_prism_header_parse);
1186EXPORT_SYMBOL(hostap_80211_get_hdrlen);
1187EXPORT_SYMBOL(hostap_get_stats);
1188EXPORT_SYMBOL(hostap_setup_dev);
1189EXPORT_SYMBOL(hostap_proc);
1190EXPORT_SYMBOL(hostap_set_multicast_list_queue);
1191EXPORT_SYMBOL(hostap_set_hostapd);
1192EXPORT_SYMBOL(hostap_set_hostapd_sta);
1193EXPORT_SYMBOL(hostap_add_interface);
1194EXPORT_SYMBOL(hostap_remove_interface);
1195EXPORT_SYMBOL(prism2_update_comms_qual);
1196
1197module_init(hostap_init);
1198module_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..5fac89b8ce3a
--- /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, u16 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..bf506f50d722
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -0,0 +1,96 @@
1#ifndef HOSTAP_80211_H
2#define HOSTAP_80211_H
3
4struct hostap_ieee80211_mgmt {
5 u16 frame_control;
6 u16 duration;
7 u8 da[6];
8 u8 sa[6];
9 u8 bssid[6];
10 u16 seq_ctrl;
11 union {
12 struct {
13 u16 auth_alg;
14 u16 auth_transaction;
15 u16 status_code;
16 /* possibly followed by Challenge text */
17 u8 variable[0];
18 } __attribute__ ((packed)) auth;
19 struct {
20 u16 reason_code;
21 } __attribute__ ((packed)) deauth;
22 struct {
23 u16 capab_info;
24 u16 listen_interval;
25 /* followed by SSID and Supported rates */
26 u8 variable[0];
27 } __attribute__ ((packed)) assoc_req;
28 struct {
29 u16 capab_info;
30 u16 status_code;
31 u16 aid;
32 /* followed by Supported rates */
33 u8 variable[0];
34 } __attribute__ ((packed)) assoc_resp, reassoc_resp;
35 struct {
36 u16 capab_info;
37 u16 listen_interval;
38 u8 current_ap[6];
39 /* followed by SSID and Supported rates */
40 u8 variable[0];
41 } __attribute__ ((packed)) reassoc_req;
42 struct {
43 u16 reason_code;
44 } __attribute__ ((packed)) disassoc;
45 struct {
46 } __attribute__ ((packed)) probe_req;
47 struct {
48 u8 timestamp[8];
49 u16 beacon_int;
50 u16 capab_info;
51 /* followed by some of SSID, Supported rates,
52 * FH Params, DS Params, CF Params, IBSS Params, TIM */
53 u8 variable[0];
54 } __attribute__ ((packed)) beacon, probe_resp;
55 } u;
56} __attribute__ ((packed));
57
58
59#define IEEE80211_MGMT_HDR_LEN 24
60#define IEEE80211_DATA_HDR3_LEN 24
61#define IEEE80211_DATA_HDR4_LEN 30
62
63
64struct hostap_80211_rx_status {
65 u32 mac_time;
66 u8 signal;
67 u8 noise;
68 u16 rate; /* in 100 kbps */
69};
70
71
72void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
73 struct hostap_80211_rx_status *rx_stats);
74
75
76/* prism2_rx_80211 'type' argument */
77enum {
78 PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
79 PRISM2_RX_NULLFUNC_ACK
80};
81
82int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
83 struct hostap_80211_rx_status *rx_stats, int type);
84void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
85 struct hostap_80211_rx_status *rx_stats);
86void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
87 struct hostap_80211_rx_status *rx_stats);
88
89void hostap_dump_tx_80211(const char *name, struct sk_buff *skb);
90int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev);
91int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
92struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
93 struct ieee80211_crypt_data *crypt);
94int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
95
96#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..b0501243b175
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -0,0 +1,1091 @@
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 ieee80211_hdr *hdr;
10 u16 fc;
11
12 hdr = (struct 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_ctl);
23 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
24 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
25 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
26 fc & IEEE80211_FCTL_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_ctl));
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 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 ieee80211_hdr *) skb->data;
74 fc = le16_to_cpu(hdr->frame_ctl);
75
76 if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
77 printk(KERN_DEBUG "%s: dropped management frame with header "
78 "version %d\n", dev->name, fc & IEEE80211_FCTL_VERS);
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, 4, 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 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_ctl);
226 frag = WLAN_GET_SEQ_FRAG(sc);
227 seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
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 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 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_ctl);
277 seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
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 ieee80211_hdr *)
445 skb->data);
446 }
447
448 if (local->hostapd && type == IEEE80211_FTYPE_MGMT) {
449 if (stype == IEEE80211_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 != IEEE80211_FTYPE_MGMT &&
471 type != IEEE80211_FTYPE_CTL) {
472 printk(KERN_DEBUG "%s: unknown management frame "
473 "(type=0x%02x, stype=0x%02x) dropped\n",
474 skb->dev->name, type >> 2, stype >> 4);
475 return -1;
476 }
477
478 hostap_rx(skb->dev, skb, rx_stats);
479 return 0;
480 } else if (type == IEEE80211_FTYPE_MGMT &&
481 (stype == IEEE80211_STYPE_BEACON ||
482 stype == IEEE80211_STYPE_PROBE_RESP)) {
483 hostap_rx_sta_beacon(local, skb, stype);
484 return -1;
485 } else if (type == IEEE80211_FTYPE_MGMT &&
486 (stype == IEEE80211_STYPE_ASSOC_RESP ||
487 stype == IEEE80211_STYPE_REASSOC_RESP)) {
488 /* Ignore (Re)AssocResp silently since these are not currently
489 * needed but are still received when WPA/RSN mode is enabled.
490 */
491 return -1;
492 } else {
493 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: dropped unhandled"
494 " management frame in non-Host AP mode (type=%d:%d)\n",
495 skb->dev->name, type >> 2, stype >> 4);
496 return -1;
497 }
498}
499
500
501/* Called only as a tasklet (software IRQ) */
502static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
503 u8 *addr)
504{
505 struct hostap_interface *iface = NULL;
506 struct list_head *ptr;
507
508 read_lock_bh(&local->iface_lock);
509 list_for_each(ptr, &local->hostap_interfaces) {
510 iface = list_entry(ptr, struct hostap_interface, list);
511 if (iface->type == HOSTAP_INTERFACE_WDS &&
512 memcmp(iface->u.wds.remote_addr, addr, ETH_ALEN) == 0)
513 break;
514 iface = NULL;
515 }
516 read_unlock_bh(&local->iface_lock);
517
518 return iface ? iface->dev : NULL;
519}
520
521
522static inline int
523hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
524 u16 fc, struct net_device **wds)
525{
526 /* FIX: is this really supposed to accept WDS frames only in Master
527 * mode? What about Repeater or Managed with WDS frames? */
528 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) !=
529 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS) &&
530 (local->iw_mode != IW_MODE_MASTER || !(fc & IEEE80211_FCTL_TODS)))
531 return 0; /* not a WDS frame */
532
533 /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS)
534 * or own non-standard frame with 4th address after payload */
535 if (memcmp(hdr->addr1, local->dev->dev_addr, ETH_ALEN) != 0 &&
536 (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff ||
537 hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
538 hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
539 /* RA (or BSSID) is not ours - drop */
540 PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with "
541 "not own or broadcast %s=" MACSTR "\n",
542 local->dev->name,
543 fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID",
544 MAC2STR(hdr->addr1));
545 return -1;
546 }
547
548 /* check if the frame came from a registered WDS connection */
549 *wds = prism2_rx_get_wds(local, hdr->addr2);
550 if (*wds == NULL && fc & IEEE80211_FCTL_FROMDS &&
551 (local->iw_mode != IW_MODE_INFRA ||
552 !(local->wds_type & HOSTAP_WDS_AP_CLIENT) ||
553 memcmp(hdr->addr2, local->bssid, ETH_ALEN) != 0)) {
554 /* require that WDS link has been registered with TA or the
555 * frame is from current AP when using 'AP client mode' */
556 PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame "
557 "from unknown TA=" MACSTR "\n",
558 local->dev->name, MAC2STR(hdr->addr2));
559 if (local->ap && local->ap->autom_ap_wds)
560 hostap_wds_link_oper(local, hdr->addr2, WDS_ADD);
561 return -1;
562 }
563
564 if (*wds && !(fc & IEEE80211_FCTL_FROMDS) && local->ap &&
565 hostap_is_sta_assoc(local->ap, hdr->addr2)) {
566 /* STA is actually associated with us even though it has a
567 * registered WDS link. Assume it is in 'AP client' mode.
568 * Since this is a 3-addr frame, assume it is not (bogus) WDS
569 * frame and process it like any normal ToDS frame from
570 * associated STA. */
571 *wds = NULL;
572 }
573
574 return 0;
575}
576
577
578static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
579{
580 struct net_device *dev = local->dev;
581 u16 fc, ethertype;
582 struct ieee80211_hdr *hdr;
583 u8 *pos;
584
585 if (skb->len < 24)
586 return 0;
587
588 hdr = (struct ieee80211_hdr *) skb->data;
589 fc = le16_to_cpu(hdr->frame_ctl);
590
591 /* check that the frame is unicast frame to us */
592 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
593 IEEE80211_FCTL_TODS &&
594 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
595 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
596 /* ToDS frame with own addr BSSID and DA */
597 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
598 IEEE80211_FCTL_FROMDS &&
599 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
600 /* FromDS frame with own addr as DA */
601 } else
602 return 0;
603
604 if (skb->len < 24 + 8)
605 return 0;
606
607 /* check for port access entity Ethernet type */
608 pos = skb->data + 24;
609 ethertype = (pos[6] << 8) | pos[7];
610 if (ethertype == ETH_P_PAE)
611 return 1;
612
613 return 0;
614}
615
616
617/* Called only as a tasklet (software IRQ) */
618static inline int
619hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
620 struct ieee80211_crypt_data *crypt)
621{
622 struct ieee80211_hdr *hdr;
623 int res, hdrlen;
624
625 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
626 return 0;
627
628 hdr = (struct ieee80211_hdr *) skb->data;
629 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
630
631 if (local->tkip_countermeasures &&
632 strcmp(crypt->ops->name, "TKIP") == 0) {
633 if (net_ratelimit()) {
634 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
635 "received packet from " MACSTR "\n",
636 local->dev->name, MAC2STR(hdr->addr2));
637 }
638 return -1;
639 }
640
641 atomic_inc(&crypt->refcnt);
642 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
643 atomic_dec(&crypt->refcnt);
644 if (res < 0) {
645 printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR
646 ") res=%d\n",
647 local->dev->name, MAC2STR(hdr->addr2), res);
648 local->comm_tallies.rx_discards_wep_undecryptable++;
649 return -1;
650 }
651
652 return res;
653}
654
655
656/* Called only as a tasklet (software IRQ) */
657static inline int
658hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
659 int keyidx, struct ieee80211_crypt_data *crypt)
660{
661 struct ieee80211_hdr *hdr;
662 int res, hdrlen;
663
664 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
665 return 0;
666
667 hdr = (struct ieee80211_hdr *) skb->data;
668 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
669
670 atomic_inc(&crypt->refcnt);
671 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
672 atomic_dec(&crypt->refcnt);
673 if (res < 0) {
674 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
675 " (SA=" MACSTR " keyidx=%d)\n",
676 local->dev->name, MAC2STR(hdr->addr2), keyidx);
677 return -1;
678 }
679
680 return 0;
681}
682
683
684/* All received frames are sent to this function. @skb contains the frame in
685 * IEEE 802.11 format, i.e., in the format it was sent over air.
686 * This function is called only as a tasklet (software IRQ). */
687void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
688 struct hostap_80211_rx_status *rx_stats)
689{
690 struct hostap_interface *iface;
691 local_info_t *local;
692 struct ieee80211_hdr *hdr;
693 size_t hdrlen;
694 u16 fc, type, stype, sc;
695 struct net_device *wds = NULL;
696 struct net_device_stats *stats;
697 unsigned int frag;
698 u8 *payload;
699 struct sk_buff *skb2 = NULL;
700 u16 ethertype;
701 int frame_authorized = 0;
702 int from_assoc_ap = 0;
703 u8 dst[ETH_ALEN];
704 u8 src[ETH_ALEN];
705 struct ieee80211_crypt_data *crypt = NULL;
706 void *sta = NULL;
707 int keyidx = 0;
708
709 iface = netdev_priv(dev);
710 local = iface->local;
711 iface->stats.rx_packets++;
712 iface->stats.rx_bytes += skb->len;
713
714 /* dev is the master radio device; change this to be the default
715 * virtual interface (this may be changed to WDS device below) */
716 dev = local->ddev;
717 iface = netdev_priv(dev);
718
719 hdr = (struct ieee80211_hdr *) skb->data;
720 stats = hostap_get_stats(dev);
721
722 if (skb->len < 10)
723 goto rx_dropped;
724
725 fc = le16_to_cpu(hdr->frame_ctl);
726 type = WLAN_FC_GET_TYPE(fc);
727 stype = WLAN_FC_GET_STYPE(fc);
728 sc = le16_to_cpu(hdr->seq_ctl);
729 frag = WLAN_GET_SEQ_FRAG(sc);
730 hdrlen = hostap_80211_get_hdrlen(fc);
731
732 /* Put this code here so that we avoid duplicating it in all
733 * Rx paths. - Jean II */
734#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
735 /* If spy monitoring on */
736 if (iface->spy_data.spy_number > 0) {
737 struct iw_quality wstats;
738 wstats.level = rx_stats->signal;
739 wstats.noise = rx_stats->noise;
740 wstats.updated = 6; /* No qual value */
741 /* Update spy records */
742 wireless_spy_update(dev, hdr->addr2, &wstats);
743 }
744#endif /* IW_WIRELESS_SPY */
745 hostap_update_rx_stats(local->ap, hdr, rx_stats);
746
747 if (local->iw_mode == IW_MODE_MONITOR) {
748 monitor_rx(dev, skb, rx_stats);
749 return;
750 }
751
752 if (local->host_decrypt) {
753 int idx = 0;
754 if (skb->len >= hdrlen + 3)
755 idx = skb->data[hdrlen + 3] >> 6;
756 crypt = local->crypt[idx];
757 sta = NULL;
758
759 /* Use station specific key to override default keys if the
760 * receiver address is a unicast address ("individual RA"). If
761 * bcrx_sta_key parameter is set, station specific key is used
762 * even with broad/multicast targets (this is against IEEE
763 * 802.11, but makes it easier to use different keys with
764 * stations that do not support WEP key mapping). */
765
766 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
767 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
768 &sta);
769
770 /* allow NULL decrypt to indicate an station specific override
771 * for default encryption */
772 if (crypt && (crypt->ops == NULL ||
773 crypt->ops->decrypt_mpdu == NULL))
774 crypt = NULL;
775
776 if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
777#if 0
778 /* This seems to be triggered by some (multicast?)
779 * frames from other than current BSS, so just drop the
780 * frames silently instead of filling system log with
781 * these reports. */
782 printk(KERN_DEBUG "%s: WEP decryption failed (not set)"
783 " (SA=" MACSTR ")\n",
784 local->dev->name, MAC2STR(hdr->addr2));
785#endif
786 local->comm_tallies.rx_discards_wep_undecryptable++;
787 goto rx_dropped;
788 }
789 }
790
791 if (type != IEEE80211_FTYPE_DATA) {
792 if (type == IEEE80211_FTYPE_MGMT &&
793 stype == IEEE80211_STYPE_AUTH &&
794 fc & IEEE80211_FCTL_PROTECTED && local->host_decrypt &&
795 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
796 {
797 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
798 "from " MACSTR "\n", dev->name,
799 MAC2STR(hdr->addr2));
800 /* TODO: could inform hostapd about this so that it
801 * could send auth failure report */
802 goto rx_dropped;
803 }
804
805 if (hostap_rx_frame_mgmt(local, skb, rx_stats, type, stype))
806 goto rx_dropped;
807 else
808 goto rx_exit;
809 }
810
811 /* Data frame - extract src/dst addresses */
812 if (skb->len < IEEE80211_DATA_HDR3_LEN)
813 goto rx_dropped;
814
815 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
816 case IEEE80211_FCTL_FROMDS:
817 memcpy(dst, hdr->addr1, ETH_ALEN);
818 memcpy(src, hdr->addr3, ETH_ALEN);
819 break;
820 case IEEE80211_FCTL_TODS:
821 memcpy(dst, hdr->addr3, ETH_ALEN);
822 memcpy(src, hdr->addr2, ETH_ALEN);
823 break;
824 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
825 if (skb->len < IEEE80211_DATA_HDR4_LEN)
826 goto rx_dropped;
827 memcpy(dst, hdr->addr3, ETH_ALEN);
828 memcpy(src, hdr->addr4, ETH_ALEN);
829 break;
830 case 0:
831 memcpy(dst, hdr->addr1, ETH_ALEN);
832 memcpy(src, hdr->addr2, ETH_ALEN);
833 break;
834 }
835
836 if (hostap_rx_frame_wds(local, hdr, fc, &wds))
837 goto rx_dropped;
838 if (wds) {
839 skb->dev = dev = wds;
840 stats = hostap_get_stats(dev);
841 }
842
843 if (local->iw_mode == IW_MODE_MASTER && !wds &&
844 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
845 IEEE80211_FCTL_FROMDS &&
846 local->stadev &&
847 memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
848 /* Frame from BSSID of the AP for which we are a client */
849 skb->dev = dev = local->stadev;
850 stats = hostap_get_stats(dev);
851 from_assoc_ap = 1;
852 }
853
854 dev->last_rx = jiffies;
855
856 if ((local->iw_mode == IW_MODE_MASTER ||
857 local->iw_mode == IW_MODE_REPEAT) &&
858 !from_assoc_ap) {
859 switch (hostap_handle_sta_rx(local, dev, skb, rx_stats,
860 wds != NULL)) {
861 case AP_RX_CONTINUE_NOT_AUTHORIZED:
862 frame_authorized = 0;
863 break;
864 case AP_RX_CONTINUE:
865 frame_authorized = 1;
866 break;
867 case AP_RX_DROP:
868 goto rx_dropped;
869 case AP_RX_EXIT:
870 goto rx_exit;
871 }
872 }
873
874 /* Nullfunc frames may have PS-bit set, so they must be passed to
875 * hostap_handle_sta_rx() before being dropped here. */
876 if (stype != IEEE80211_STYPE_DATA &&
877 stype != IEEE80211_STYPE_DATA_CFACK &&
878 stype != IEEE80211_STYPE_DATA_CFPOLL &&
879 stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
880 if (stype != IEEE80211_STYPE_NULLFUNC)
881 printk(KERN_DEBUG "%s: RX: dropped data frame "
882 "with no data (type=0x%02x, subtype=0x%02x)\n",
883 dev->name, type >> 2, stype >> 4);
884 goto rx_dropped;
885 }
886
887 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
888
889 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
890 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
891 goto rx_dropped;
892 hdr = (struct ieee80211_hdr *) skb->data;
893
894 /* skb: hdr + (possibly fragmented) plaintext payload */
895
896 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
897 (frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
898 int flen;
899 struct sk_buff *frag_skb =
900 prism2_frag_cache_get(local, hdr);
901 if (!frag_skb) {
902 printk(KERN_DEBUG "%s: Rx cannot get skb from "
903 "fragment cache (morefrag=%d seq=%u frag=%u)\n",
904 dev->name, (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
905 WLAN_GET_SEQ_SEQ(sc) >> 4, frag);
906 goto rx_dropped;
907 }
908
909 flen = skb->len;
910 if (frag != 0)
911 flen -= hdrlen;
912
913 if (frag_skb->tail + flen > frag_skb->end) {
914 printk(KERN_WARNING "%s: host decrypted and "
915 "reassembled frame did not fit skb\n",
916 dev->name);
917 prism2_frag_cache_invalidate(local, hdr);
918 goto rx_dropped;
919 }
920
921 if (frag == 0) {
922 /* copy first fragment (including full headers) into
923 * beginning of the fragment cache skb */
924 memcpy(skb_put(frag_skb, flen), skb->data, flen);
925 } else {
926 /* append frame payload to the end of the fragment
927 * cache skb */
928 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
929 flen);
930 }
931 dev_kfree_skb(skb);
932 skb = NULL;
933
934 if (fc & IEEE80211_FCTL_MOREFRAGS) {
935 /* more fragments expected - leave the skb in fragment
936 * cache for now; it will be delivered to upper layers
937 * after all fragments have been received */
938 goto rx_exit;
939 }
940
941 /* this was the last fragment and the frame will be
942 * delivered, so remove skb from fragment cache */
943 skb = frag_skb;
944 hdr = (struct ieee80211_hdr *) skb->data;
945 prism2_frag_cache_invalidate(local, hdr);
946 }
947
948 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
949 * encrypted/authenticated */
950
951 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
952 hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
953 goto rx_dropped;
954
955 hdr = (struct ieee80211_hdr *) skb->data;
956 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
957 if (local->ieee_802_1x &&
958 hostap_is_eapol_frame(local, skb)) {
959 /* pass unencrypted EAPOL frames even if encryption is
960 * configured */
961 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X - passing "
962 "unencrypted EAPOL frame\n", local->dev->name);
963 } else {
964 printk(KERN_DEBUG "%s: encryption configured, but RX "
965 "frame not encrypted (SA=" MACSTR ")\n",
966 local->dev->name, MAC2STR(hdr->addr2));
967 goto rx_dropped;
968 }
969 }
970
971 if (local->drop_unencrypted && !(fc & IEEE80211_FCTL_PROTECTED) &&
972 !hostap_is_eapol_frame(local, skb)) {
973 if (net_ratelimit()) {
974 printk(KERN_DEBUG "%s: dropped unencrypted RX data "
975 "frame from " MACSTR " (drop_unencrypted=1)\n",
976 dev->name, MAC2STR(hdr->addr2));
977 }
978 goto rx_dropped;
979 }
980
981 /* skb: hdr + (possible reassembled) full plaintext payload */
982
983 payload = skb->data + hdrlen;
984 ethertype = (payload[6] << 8) | payload[7];
985
986 /* If IEEE 802.1X is used, check whether the port is authorized to send
987 * the received frame. */
988 if (local->ieee_802_1x && local->iw_mode == IW_MODE_MASTER) {
989 if (ethertype == ETH_P_PAE) {
990 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X frame\n",
991 dev->name);
992 if (local->hostapd && local->apdev) {
993 /* Send IEEE 802.1X frames to the user
994 * space daemon for processing */
995 prism2_rx_80211(local->apdev, skb, rx_stats,
996 PRISM2_RX_MGMT);
997 local->apdevstats.rx_packets++;
998 local->apdevstats.rx_bytes += skb->len;
999 goto rx_exit;
1000 }
1001 } else if (!frame_authorized) {
1002 printk(KERN_DEBUG "%s: dropped frame from "
1003 "unauthorized port (IEEE 802.1X): "
1004 "ethertype=0x%04x\n",
1005 dev->name, ethertype);
1006 goto rx_dropped;
1007 }
1008 }
1009
1010 /* convert hdr + possible LLC headers into Ethernet header */
1011 if (skb->len - hdrlen >= 8 &&
1012 ((memcmp(payload, rfc1042_header, 6) == 0 &&
1013 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1014 memcmp(payload, bridge_tunnel_header, 6) == 0)) {
1015 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1016 * replace EtherType */
1017 skb_pull(skb, hdrlen + 6);
1018 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1019 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1020 } else {
1021 u16 len;
1022 /* Leave Ethernet header part of hdr and full payload */
1023 skb_pull(skb, hdrlen);
1024 len = htons(skb->len);
1025 memcpy(skb_push(skb, 2), &len, 2);
1026 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1027 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1028 }
1029
1030 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
1031 IEEE80211_FCTL_TODS) &&
1032 skb->len >= ETH_HLEN + ETH_ALEN) {
1033 /* Non-standard frame: get addr4 from its bogus location after
1034 * the payload */
1035 memcpy(skb->data + ETH_ALEN,
1036 skb->data + skb->len - ETH_ALEN, ETH_ALEN);
1037 skb_trim(skb, skb->len - ETH_ALEN);
1038 }
1039
1040 stats->rx_packets++;
1041 stats->rx_bytes += skb->len;
1042
1043 if (local->iw_mode == IW_MODE_MASTER && !wds &&
1044 local->ap->bridge_packets) {
1045 if (dst[0] & 0x01) {
1046 /* copy multicast frame both to the higher layers and
1047 * to the wireless media */
1048 local->ap->bridged_multicast++;
1049 skb2 = skb_clone(skb, GFP_ATOMIC);
1050 if (skb2 == NULL)
1051 printk(KERN_DEBUG "%s: skb_clone failed for "
1052 "multicast frame\n", dev->name);
1053 } else if (hostap_is_sta_authorized(local->ap, dst)) {
1054 /* send frame directly to the associated STA using
1055 * wireless media and not passing to higher layers */
1056 local->ap->bridged_unicast++;
1057 skb2 = skb;
1058 skb = NULL;
1059 }
1060 }
1061
1062 if (skb2 != NULL) {
1063 /* send to wireless media */
1064 skb2->protocol = __constant_htons(ETH_P_802_3);
1065 skb2->mac.raw = skb2->nh.raw = skb2->data;
1066 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
1067 skb2->dev = dev;
1068 dev_queue_xmit(skb2);
1069 }
1070
1071 if (skb) {
1072 skb->protocol = eth_type_trans(skb, dev);
1073 memset(skb->cb, 0, sizeof(skb->cb));
1074 skb->dev = dev;
1075 netif_rx(skb);
1076 }
1077
1078 rx_exit:
1079 if (sta)
1080 hostap_handle_sta_release(sta);
1081 return;
1082
1083 rx_dropped:
1084 dev_kfree_skb(skb);
1085
1086 stats->rx_dropped++;
1087 goto rx_exit;
1088}
1089
1090
1091EXPORT_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..6358015f6526
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -0,0 +1,524 @@
1void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
2{
3 struct ieee80211_hdr *hdr;
4 u16 fc;
5
6 hdr = (struct 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_ctl);
15 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
16 fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
17 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
18 fc & IEEE80211_FCTL_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_ctl));
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 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 = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
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 |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_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 |= IEEE80211_FCTL_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 |= IEEE80211_FCTL_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 |= IEEE80211_FCTL_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_ctl = 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 if (use_wds)
230 meta->flags |= HOSTAP_TX_FLAGS_WDS;
231 meta->ethertype = ethertype;
232 meta->iface = iface;
233
234 /* Send IEEE 802.11 encapsulated frame using the master radio device */
235 skb->dev = local->dev;
236 dev_queue_xmit(skb);
237 return 0;
238}
239
240
241/* hard_start_xmit function for hostapd wlan#ap interfaces */
242int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
243{
244 struct hostap_interface *iface;
245 local_info_t *local;
246 struct hostap_skb_tx_data *meta;
247 struct ieee80211_hdr *hdr;
248 u16 fc;
249
250 iface = netdev_priv(dev);
251 local = iface->local;
252
253 if (skb->len < 10) {
254 printk(KERN_DEBUG "%s: hostap_mgmt_start_xmit: short skb "
255 "(len=%d)\n", dev->name, skb->len);
256 kfree_skb(skb);
257 return 0;
258 }
259
260 iface->stats.tx_packets++;
261 iface->stats.tx_bytes += skb->len;
262
263 meta = (struct hostap_skb_tx_data *) skb->cb;
264 memset(meta, 0, sizeof(*meta));
265 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
266 meta->iface = iface;
267
268 if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
269 hdr = (struct ieee80211_hdr *) skb->data;
270 fc = le16_to_cpu(hdr->frame_ctl);
271 if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
272 WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
273 u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
274 sizeof(rfc1042_header)];
275 meta->ethertype = (pos[0] << 8) | pos[1];
276 }
277 }
278
279 /* Send IEEE 802.11 encapsulated frame using the master radio device */
280 skb->dev = local->dev;
281 dev_queue_xmit(skb);
282 return 0;
283}
284
285
286/* Called only from software IRQ */
287struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
288 struct ieee80211_crypt_data *crypt)
289{
290 struct hostap_interface *iface;
291 local_info_t *local;
292 struct ieee80211_hdr *hdr;
293 u16 fc;
294 int hdr_len, res;
295
296 iface = netdev_priv(skb->dev);
297 local = iface->local;
298
299 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
300 kfree_skb(skb);
301 return NULL;
302 }
303
304 if (local->tkip_countermeasures &&
305 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
306 hdr = (struct ieee80211_hdr *) skb->data;
307 if (net_ratelimit()) {
308 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
309 "TX packet to " MACSTR "\n",
310 local->dev->name, MAC2STR(hdr->addr1));
311 }
312 kfree_skb(skb);
313 return NULL;
314 }
315
316 skb = skb_unshare(skb, GFP_ATOMIC);
317 if (skb == NULL)
318 return NULL;
319
320 if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
321 skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
322 pskb_expand_head(skb, crypt->ops->extra_prefix_len,
323 crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
324 kfree_skb(skb);
325 return NULL;
326 }
327
328 hdr = (struct ieee80211_hdr *) skb->data;
329 fc = le16_to_cpu(hdr->frame_ctl);
330 hdr_len = hostap_80211_get_hdrlen(fc);
331
332 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
333 * call both MSDU and MPDU encryption functions from here. */
334 atomic_inc(&crypt->refcnt);
335 res = 0;
336 if (crypt->ops->encrypt_msdu)
337 res = crypt->ops->encrypt_msdu(skb, hdr_len, crypt->priv);
338 if (res == 0 && crypt->ops->encrypt_mpdu)
339 res = crypt->ops->encrypt_mpdu(skb, hdr_len, crypt->priv);
340 atomic_dec(&crypt->refcnt);
341 if (res < 0) {
342 kfree_skb(skb);
343 return NULL;
344 }
345
346 return skb;
347}
348
349
350/* hard_start_xmit function for master radio interface wifi#.
351 * AP processing (TX rate control, power save buffering, etc.).
352 * Use hardware TX function to send the frame. */
353int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
354{
355 struct hostap_interface *iface;
356 local_info_t *local;
357 int ret = 1;
358 u16 fc;
359 struct hostap_tx_data tx;
360 ap_tx_ret tx_ret;
361 struct hostap_skb_tx_data *meta;
362 int no_encrypt = 0;
363 struct ieee80211_hdr *hdr;
364
365 iface = netdev_priv(dev);
366 local = iface->local;
367
368 tx.skb = skb;
369 tx.sta_ptr = NULL;
370
371 meta = (struct hostap_skb_tx_data *) skb->cb;
372 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
373 printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
374 "expected 0x%08x)\n",
375 dev->name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC);
376 ret = 0;
377 iface->stats.tx_dropped++;
378 goto fail;
379 }
380
381 if (local->host_encrypt) {
382 /* Set crypt to default algorithm and key; will be replaced in
383 * AP code if STA has own alg/key */
384 tx.crypt = local->crypt[local->tx_keyidx];
385 tx.host_encrypt = 1;
386 } else {
387 tx.crypt = NULL;
388 tx.host_encrypt = 0;
389 }
390
391 if (skb->len < 24) {
392 printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
393 "(len=%d)\n", dev->name, skb->len);
394 ret = 0;
395 iface->stats.tx_dropped++;
396 goto fail;
397 }
398
399 /* FIX (?):
400 * Wi-Fi 802.11b test plan suggests that AP should ignore power save
401 * bit in authentication and (re)association frames and assume tha
402 * STA remains awake for the response. */
403 tx_ret = hostap_handle_sta_tx(local, &tx);
404 skb = tx.skb;
405 meta = (struct hostap_skb_tx_data *) skb->cb;
406 hdr = (struct ieee80211_hdr *) skb->data;
407 fc = le16_to_cpu(hdr->frame_ctl);
408 switch (tx_ret) {
409 case AP_TX_CONTINUE:
410 break;
411 case AP_TX_CONTINUE_NOT_AUTHORIZED:
412 if (local->ieee_802_1x &&
413 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
414 meta->ethertype != ETH_P_PAE &&
415 !(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
416 printk(KERN_DEBUG "%s: dropped frame to unauthorized "
417 "port (IEEE 802.1X): ethertype=0x%04x\n",
418 dev->name, meta->ethertype);
419 hostap_dump_tx_80211(dev->name, skb);
420
421 ret = 0; /* drop packet */
422 iface->stats.tx_dropped++;
423 goto fail;
424 }
425 break;
426 case AP_TX_DROP:
427 ret = 0; /* drop packet */
428 iface->stats.tx_dropped++;
429 goto fail;
430 case AP_TX_RETRY:
431 goto fail;
432 case AP_TX_BUFFERED:
433 /* do not free skb here, it will be freed when the
434 * buffered frame is sent/timed out */
435 ret = 0;
436 goto tx_exit;
437 }
438
439 /* Request TX callback if protocol version is 2 in 802.11 header;
440 * this version 2 is a special case used between hostapd and kernel
441 * driver */
442 if (((fc & IEEE80211_FCTL_VERS) == BIT(1)) &&
443 local->ap && local->ap->tx_callback_idx && meta->tx_cb_idx == 0) {
444 meta->tx_cb_idx = local->ap->tx_callback_idx;
445
446 /* remove special version from the frame header */
447 fc &= ~IEEE80211_FCTL_VERS;
448 hdr->frame_ctl = cpu_to_le16(fc);
449 }
450
451 if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_DATA) {
452 no_encrypt = 1;
453 tx.crypt = NULL;
454 }
455
456 if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt &&
457 !(fc & IEEE80211_FCTL_VERS)) {
458 no_encrypt = 1;
459 PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing "
460 "unencrypted EAPOL frame\n", dev->name);
461 tx.crypt = NULL; /* no encryption for IEEE 802.1X frames */
462 }
463
464 if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
465 tx.crypt = NULL;
466 else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) {
467 /* Add ISWEP flag both for firmware and host based encryption
468 */
469 fc |= IEEE80211_FCTL_PROTECTED;
470 hdr->frame_ctl = cpu_to_le16(fc);
471 } else if (local->drop_unencrypted &&
472 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
473 meta->ethertype != ETH_P_PAE) {
474 if (net_ratelimit()) {
475 printk(KERN_DEBUG "%s: dropped unencrypted TX data "
476 "frame (drop_unencrypted=1)\n", dev->name);
477 }
478 iface->stats.tx_dropped++;
479 ret = 0;
480 goto fail;
481 }
482
483 if (tx.crypt) {
484 skb = hostap_tx_encrypt(skb, tx.crypt);
485 if (skb == NULL) {
486 printk(KERN_DEBUG "%s: TX - encryption failed\n",
487 dev->name);
488 ret = 0;
489 goto fail;
490 }
491 meta = (struct hostap_skb_tx_data *) skb->cb;
492 if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
493 printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
494 "expected 0x%08x) after hostap_tx_encrypt\n",
495 dev->name, meta->magic,
496 HOSTAP_SKB_TX_DATA_MAGIC);
497 ret = 0;
498 iface->stats.tx_dropped++;
499 goto fail;
500 }
501 }
502
503 if (local->func->tx == NULL || local->func->tx(skb, dev)) {
504 ret = 0;
505 iface->stats.tx_dropped++;
506 } else {
507 ret = 0;
508 iface->stats.tx_packets++;
509 iface->stats.tx_bytes += skb->len;
510 }
511
512 fail:
513 if (!ret && skb)
514 dev_kfree_skb(skb);
515 tx_exit:
516 if (tx.sta_ptr)
517 hostap_handle_sta_release(tx.sta_ptr);
518 return ret;
519}
520
521
522EXPORT_SYMBOL(hostap_dump_tx_80211);
523EXPORT_SYMBOL(hostap_tx_encrypt);
524EXPORT_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..930cef8367f2
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -0,0 +1,3288 @@
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-2005, 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 u16 type_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: IEEE80211_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, IEEE80211_FTYPE_DATA |
245 IEEE80211_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, IEEE80211_FTYPE_MGMT |
259 (deauth ? IEEE80211_STYPE_DEAUTH :
260 IEEE80211_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, IEEE80211_FTYPE_MGMT |
304 IEEE80211_STYPE_DEAUTH,
305 (char *) &resp, 2, addr, 0);
306
307 if (!resend || ap->num_sta <= 0)
308 return;
309
310 mdelay(50);
311 }
312}
313
314
315static int ap_control_proc_read(char *page, char **start, off_t off,
316 int count, int *eof, void *data)
317{
318 char *p = page;
319 struct ap_data *ap = (struct ap_data *) data;
320 char *policy_txt;
321 struct list_head *ptr;
322 struct mac_entry *entry;
323
324 if (off != 0) {
325 *eof = 1;
326 return 0;
327 }
328
329 switch (ap->mac_restrictions.policy) {
330 case MAC_POLICY_OPEN:
331 policy_txt = "open";
332 break;
333 case MAC_POLICY_ALLOW:
334 policy_txt = "allow";
335 break;
336 case MAC_POLICY_DENY:
337 policy_txt = "deny";
338 break;
339 default:
340 policy_txt = "unknown";
341 break;
342 };
343 p += sprintf(p, "MAC policy: %s\n", policy_txt);
344 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
345 p += sprintf(p, "MAC list:\n");
346 spin_lock_bh(&ap->mac_restrictions.lock);
347 for (ptr = ap->mac_restrictions.mac_list.next;
348 ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) {
349 if (p - page > PAGE_SIZE - 80) {
350 p += sprintf(p, "All entries did not fit one page.\n");
351 break;
352 }
353
354 entry = list_entry(ptr, struct mac_entry, list);
355 p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
356 }
357 spin_unlock_bh(&ap->mac_restrictions.lock);
358
359 return (p - page);
360}
361
362
363static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
364 u8 *mac)
365{
366 struct mac_entry *entry;
367
368 entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
369 if (entry == NULL)
370 return -1;
371
372 memcpy(entry->addr, mac, ETH_ALEN);
373
374 spin_lock_bh(&mac_restrictions->lock);
375 list_add_tail(&entry->list, &mac_restrictions->mac_list);
376 mac_restrictions->entries++;
377 spin_unlock_bh(&mac_restrictions->lock);
378
379 return 0;
380}
381
382
383static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
384 u8 *mac)
385{
386 struct list_head *ptr;
387 struct mac_entry *entry;
388
389 spin_lock_bh(&mac_restrictions->lock);
390 for (ptr = mac_restrictions->mac_list.next;
391 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
392 entry = list_entry(ptr, struct mac_entry, list);
393
394 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
395 list_del(ptr);
396 kfree(entry);
397 mac_restrictions->entries--;
398 spin_unlock_bh(&mac_restrictions->lock);
399 return 0;
400 }
401 }
402 spin_unlock_bh(&mac_restrictions->lock);
403 return -1;
404}
405
406
407static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
408 u8 *mac)
409{
410 struct list_head *ptr;
411 struct mac_entry *entry;
412 int found = 0;
413
414 if (mac_restrictions->policy == MAC_POLICY_OPEN)
415 return 0;
416
417 spin_lock_bh(&mac_restrictions->lock);
418 for (ptr = mac_restrictions->mac_list.next;
419 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
420 entry = list_entry(ptr, struct mac_entry, list);
421
422 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
423 found = 1;
424 break;
425 }
426 }
427 spin_unlock_bh(&mac_restrictions->lock);
428
429 if (mac_restrictions->policy == MAC_POLICY_ALLOW)
430 return !found;
431 else
432 return found;
433}
434
435
436static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
437{
438 struct list_head *ptr, *n;
439 struct mac_entry *entry;
440
441 if (mac_restrictions->entries == 0)
442 return;
443
444 spin_lock_bh(&mac_restrictions->lock);
445 for (ptr = mac_restrictions->mac_list.next, n = ptr->next;
446 ptr != &mac_restrictions->mac_list;
447 ptr = n, n = ptr->next) {
448 entry = list_entry(ptr, struct mac_entry, list);
449 list_del(ptr);
450 kfree(entry);
451 }
452 mac_restrictions->entries = 0;
453 spin_unlock_bh(&mac_restrictions->lock);
454}
455
456
457static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
458 u8 *mac)
459{
460 struct sta_info *sta;
461 u16 resp;
462
463 spin_lock_bh(&ap->sta_table_lock);
464 sta = ap_get_sta(ap, mac);
465 if (sta) {
466 ap_sta_hash_del(ap, sta);
467 list_del(&sta->list);
468 }
469 spin_unlock_bh(&ap->sta_table_lock);
470
471 if (!sta)
472 return -EINVAL;
473
474 resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
475 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH,
476 (char *) &resp, 2, sta->addr, 0);
477
478 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
479 hostap_event_expired_sta(dev, sta);
480
481 ap_free_sta(ap, sta);
482
483 return 0;
484}
485
486#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
487
488
489static void ap_control_kickall(struct ap_data *ap)
490{
491 struct list_head *ptr, *n;
492 struct sta_info *sta;
493
494 spin_lock_bh(&ap->sta_table_lock);
495 for (ptr = ap->sta_list.next, n = ptr->next; ptr != &ap->sta_list;
496 ptr = n, n = ptr->next) {
497 sta = list_entry(ptr, struct sta_info, list);
498 ap_sta_hash_del(ap, sta);
499 list_del(&sta->list);
500 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
501 hostap_event_expired_sta(sta->local->dev, sta);
502 ap_free_sta(ap, sta);
503 }
504 spin_unlock_bh(&ap->sta_table_lock);
505}
506
507
508#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
509
510#define PROC_LIMIT (PAGE_SIZE - 80)
511
512static int prism2_ap_proc_read(char *page, char **start, off_t off,
513 int count, int *eof, void *data)
514{
515 char *p = page;
516 struct ap_data *ap = (struct ap_data *) data;
517 struct list_head *ptr;
518 int i;
519
520 if (off > PROC_LIMIT) {
521 *eof = 1;
522 return 0;
523 }
524
525 p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
526 spin_lock_bh(&ap->sta_table_lock);
527 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
528 struct sta_info *sta = (struct sta_info *) ptr;
529
530 if (!sta->ap)
531 continue;
532
533 p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(sta->addr),
534 sta->u.ap.channel, sta->last_rx_signal,
535 sta->last_rx_silence, sta->last_rx_rate);
536 for (i = 0; i < sta->u.ap.ssid_len; i++)
537 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
538 sta->u.ap.ssid[i] < 127) ?
539 "%c" : "<%02x>"),
540 sta->u.ap.ssid[i]);
541 p += sprintf(p, "'");
542 if (sta->capability & WLAN_CAPABILITY_ESS)
543 p += sprintf(p, " [ESS]");
544 if (sta->capability & WLAN_CAPABILITY_IBSS)
545 p += sprintf(p, " [IBSS]");
546 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
547 p += sprintf(p, " [WEP]");
548 p += sprintf(p, "\n");
549
550 if ((p - page) > PROC_LIMIT) {
551 printk(KERN_DEBUG "hostap: ap proc did not fit\n");
552 break;
553 }
554 }
555 spin_unlock_bh(&ap->sta_table_lock);
556
557 if ((p - page) <= off) {
558 *eof = 1;
559 return 0;
560 }
561
562 *start = page + off;
563
564 return (p - page - off);
565}
566#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
567
568
569void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
570{
571 if (!ap)
572 return;
573
574 if (sta_fw_ver == PRISM2_FW_VER(0,8,0)) {
575 PDEBUG(DEBUG_AP, "Using data::nullfunc ACK workaround - "
576 "firmware upgrade recommended\n");
577 ap->nullfunc_ack = 1;
578 } else
579 ap->nullfunc_ack = 0;
580
581 if (sta_fw_ver == PRISM2_FW_VER(1,4,2)) {
582 printk(KERN_WARNING "%s: Warning: secondary station firmware "
583 "version 1.4.2 does not seem to work in Host AP mode\n",
584 ap->local->dev->name);
585 }
586}
587
588
589/* Called only as a tasklet (software IRQ) */
590static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
591{
592 struct ap_data *ap = data;
593 u16 fc;
594 struct ieee80211_hdr *hdr;
595
596 if (!ap->local->hostapd || !ap->local->apdev) {
597 dev_kfree_skb(skb);
598 return;
599 }
600
601 hdr = (struct ieee80211_hdr *) skb->data;
602 fc = le16_to_cpu(hdr->frame_ctl);
603
604 /* Pass the TX callback frame to the hostapd; use 802.11 header version
605 * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
606
607 fc &= ~IEEE80211_FCTL_VERS;
608 fc |= ok ? BIT(1) : BIT(0);
609 hdr->frame_ctl = cpu_to_le16(fc);
610
611 skb->dev = ap->local->apdev;
612 skb_pull(skb, hostap_80211_get_hdrlen(fc));
613 skb->pkt_type = PACKET_OTHERHOST;
614 skb->protocol = __constant_htons(ETH_P_802_2);
615 memset(skb->cb, 0, sizeof(skb->cb));
616 netif_rx(skb);
617}
618
619
620#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
621/* Called only as a tasklet (software IRQ) */
622static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
623{
624 struct ap_data *ap = data;
625 struct net_device *dev = ap->local->dev;
626 struct ieee80211_hdr *hdr;
627 u16 fc, *pos, auth_alg, auth_transaction, status;
628 struct sta_info *sta = NULL;
629 char *txt = NULL;
630
631 if (ap->local->hostapd) {
632 dev_kfree_skb(skb);
633 return;
634 }
635
636 hdr = (struct ieee80211_hdr *) skb->data;
637 fc = le16_to_cpu(hdr->frame_ctl);
638 if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
639 WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
640 skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
641 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
642 "frame\n", dev->name);
643 dev_kfree_skb(skb);
644 return;
645 }
646
647 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
648 auth_alg = le16_to_cpu(*pos++);
649 auth_transaction = le16_to_cpu(*pos++);
650 status = le16_to_cpu(*pos++);
651
652 if (!ok) {
653 txt = "frame was not ACKed";
654 goto done;
655 }
656
657 spin_lock(&ap->sta_table_lock);
658 sta = ap_get_sta(ap, hdr->addr1);
659 if (sta)
660 atomic_inc(&sta->users);
661 spin_unlock(&ap->sta_table_lock);
662
663 if (!sta) {
664 txt = "STA not found";
665 goto done;
666 }
667
668 if (status == WLAN_STATUS_SUCCESS &&
669 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
670 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
671 txt = "STA authenticated";
672 sta->flags |= WLAN_STA_AUTH;
673 sta->last_auth = jiffies;
674 } else if (status != WLAN_STATUS_SUCCESS)
675 txt = "authentication failed";
676
677 done:
678 if (sta)
679 atomic_dec(&sta->users);
680 if (txt) {
681 PDEBUG(DEBUG_AP, "%s: " MACSTR " auth_cb - alg=%d trans#=%d "
682 "status=%d - %s\n",
683 dev->name, MAC2STR(hdr->addr1), auth_alg,
684 auth_transaction, status, txt);
685 }
686 dev_kfree_skb(skb);
687}
688
689
690/* Called only as a tasklet (software IRQ) */
691static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
692{
693 struct ap_data *ap = data;
694 struct net_device *dev = ap->local->dev;
695 struct ieee80211_hdr *hdr;
696 u16 fc, *pos, status;
697 struct sta_info *sta = NULL;
698 char *txt = NULL;
699
700 if (ap->local->hostapd) {
701 dev_kfree_skb(skb);
702 return;
703 }
704
705 hdr = (struct ieee80211_hdr *) skb->data;
706 fc = le16_to_cpu(hdr->frame_ctl);
707 if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
708 (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
709 WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_REASSOC_RESP) ||
710 skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
711 printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
712 "frame\n", dev->name);
713 dev_kfree_skb(skb);
714 return;
715 }
716
717 if (!ok) {
718 txt = "frame was not ACKed";
719 goto done;
720 }
721
722 spin_lock(&ap->sta_table_lock);
723 sta = ap_get_sta(ap, hdr->addr1);
724 if (sta)
725 atomic_inc(&sta->users);
726 spin_unlock(&ap->sta_table_lock);
727
728 if (!sta) {
729 txt = "STA not found";
730 goto done;
731 }
732
733 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
734 pos++;
735 status = le16_to_cpu(*pos++);
736 if (status == WLAN_STATUS_SUCCESS) {
737 if (!(sta->flags & WLAN_STA_ASSOC))
738 hostap_event_new_sta(dev, sta);
739 txt = "STA associated";
740 sta->flags |= WLAN_STA_ASSOC;
741 sta->last_assoc = jiffies;
742 } else
743 txt = "association failed";
744
745 done:
746 if (sta)
747 atomic_dec(&sta->users);
748 if (txt) {
749 PDEBUG(DEBUG_AP, "%s: " MACSTR " assoc_cb - %s\n",
750 dev->name, MAC2STR(hdr->addr1), txt);
751 }
752 dev_kfree_skb(skb);
753}
754
755/* Called only as a tasklet (software IRQ); TX callback for poll frames used
756 * in verifying whether the STA is still present. */
757static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
758{
759 struct ap_data *ap = data;
760 struct ieee80211_hdr *hdr;
761 struct sta_info *sta;
762
763 if (skb->len < 24)
764 goto fail;
765 hdr = (struct ieee80211_hdr *) skb->data;
766 if (ok) {
767 spin_lock(&ap->sta_table_lock);
768 sta = ap_get_sta(ap, hdr->addr1);
769 if (sta)
770 sta->flags &= ~WLAN_STA_PENDING_POLL;
771 spin_unlock(&ap->sta_table_lock);
772 } else {
773 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " did not ACK activity "
774 "poll frame\n", ap->local->dev->name,
775 MAC2STR(hdr->addr1));
776 }
777
778 fail:
779 dev_kfree_skb(skb);
780}
781#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
782
783
784void hostap_init_data(local_info_t *local)
785{
786 struct ap_data *ap = local->ap;
787
788 if (ap == NULL) {
789 printk(KERN_WARNING "hostap_init_data: ap == NULL\n");
790 return;
791 }
792 memset(ap, 0, sizeof(struct ap_data));
793 ap->local = local;
794
795 ap->ap_policy = GET_INT_PARM(other_ap_policy, local->card_idx);
796 ap->bridge_packets = GET_INT_PARM(ap_bridge_packets, local->card_idx);
797 ap->max_inactivity =
798 GET_INT_PARM(ap_max_inactivity, local->card_idx) * HZ;
799 ap->autom_ap_wds = GET_INT_PARM(autom_ap_wds, local->card_idx);
800
801 spin_lock_init(&ap->sta_table_lock);
802 INIT_LIST_HEAD(&ap->sta_list);
803
804 /* Initialize task queue structure for AP management */
805 INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap);
806
807 ap->tx_callback_idx =
808 hostap_tx_callback_register(local, hostap_ap_tx_cb, ap);
809 if (ap->tx_callback_idx == 0)
810 printk(KERN_WARNING "%s: failed to register TX callback for "
811 "AP\n", local->dev->name);
812#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
813 INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local);
814
815 ap->tx_callback_auth =
816 hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap);
817 ap->tx_callback_assoc =
818 hostap_tx_callback_register(local, hostap_ap_tx_cb_assoc, ap);
819 ap->tx_callback_poll =
820 hostap_tx_callback_register(local, hostap_ap_tx_cb_poll, ap);
821 if (ap->tx_callback_auth == 0 || ap->tx_callback_assoc == 0 ||
822 ap->tx_callback_poll == 0)
823 printk(KERN_WARNING "%s: failed to register TX callback for "
824 "AP\n", local->dev->name);
825
826 spin_lock_init(&ap->mac_restrictions.lock);
827 INIT_LIST_HEAD(&ap->mac_restrictions.mac_list);
828#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
829
830 ap->initialized = 1;
831}
832
833
834void hostap_init_ap_proc(local_info_t *local)
835{
836 struct ap_data *ap = local->ap;
837
838 ap->proc = local->proc;
839 if (ap->proc == NULL)
840 return;
841
842#ifndef PRISM2_NO_PROCFS_DEBUG
843 create_proc_read_entry("ap_debug", 0, ap->proc,
844 ap_debug_proc_read, ap);
845#endif /* PRISM2_NO_PROCFS_DEBUG */
846
847#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
848 create_proc_read_entry("ap_control", 0, ap->proc,
849 ap_control_proc_read, ap);
850 create_proc_read_entry("ap", 0, ap->proc,
851 prism2_ap_proc_read, ap);
852#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
853
854}
855
856
857void hostap_free_data(struct ap_data *ap)
858{
859 struct list_head *n, *ptr;
860
861 if (ap == NULL || !ap->initialized) {
862 printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
863 "initialized - skip resource freeing\n");
864 return;
865 }
866
867#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
868 if (ap->crypt)
869 ap->crypt->deinit(ap->crypt_priv);
870 ap->crypt = ap->crypt_priv = NULL;
871#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
872
873 list_for_each_safe(ptr, n, &ap->sta_list) {
874 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
875 ap_sta_hash_del(ap, sta);
876 list_del(&sta->list);
877 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
878 hostap_event_expired_sta(sta->local->dev, sta);
879 ap_free_sta(ap, sta);
880 }
881
882#ifndef PRISM2_NO_PROCFS_DEBUG
883 if (ap->proc != NULL) {
884 remove_proc_entry("ap_debug", ap->proc);
885 }
886#endif /* PRISM2_NO_PROCFS_DEBUG */
887
888#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
889 if (ap->proc != NULL) {
890 remove_proc_entry("ap", ap->proc);
891 remove_proc_entry("ap_control", ap->proc);
892 }
893 ap_control_flush_macs(&ap->mac_restrictions);
894#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
895
896 ap->initialized = 0;
897}
898
899
900/* caller should have mutex for AP STA list handling */
901static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
902{
903 struct sta_info *s;
904
905 s = ap->sta_hash[STA_HASH(sta)];
906 while (s != NULL && memcmp(s->addr, sta, ETH_ALEN) != 0)
907 s = s->hnext;
908 return s;
909}
910
911
912#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
913
914/* Called from timer handler and from scheduled AP queue handlers */
915static void prism2_send_mgmt(struct net_device *dev,
916 u16 type_subtype, char *body,
917 int body_len, u8 *addr, u16 tx_cb_idx)
918{
919 struct hostap_interface *iface;
920 local_info_t *local;
921 struct ieee80211_hdr *hdr;
922 u16 fc;
923 struct sk_buff *skb;
924 struct hostap_skb_tx_data *meta;
925 int hdrlen;
926
927 iface = netdev_priv(dev);
928 local = iface->local;
929 dev = local->dev; /* always use master radio device */
930 iface = netdev_priv(dev);
931
932 if (!(dev->flags & IFF_UP)) {
933 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt - device is not UP - "
934 "cannot send frame\n", dev->name);
935 return;
936 }
937
938 skb = dev_alloc_skb(sizeof(*hdr) + body_len);
939 if (skb == NULL) {
940 PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt failed to allocate "
941 "skb\n", dev->name);
942 return;
943 }
944
945 fc = type_subtype;
946 hdrlen = hostap_80211_get_hdrlen(fc);
947 hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
948 if (body)
949 memcpy(skb_put(skb, body_len), body, body_len);
950
951 memset(hdr, 0, hdrlen);
952
953 /* FIX: ctrl::ack sending used special HFA384X_TX_CTRL_802_11
954 * tx_control instead of using local->tx_control */
955
956
957 memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
958 if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) {
959 fc |= IEEE80211_FCTL_FROMDS;
960 memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
961 memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
962 } else if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL) {
963 /* control:ACK does not have addr2 or addr3 */
964 memset(hdr->addr2, 0, ETH_ALEN);
965 memset(hdr->addr3, 0, ETH_ALEN);
966 } else {
967 memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* SA */
968 memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
969 }
970
971 hdr->frame_ctl = cpu_to_le16(fc);
972
973 meta = (struct hostap_skb_tx_data *) skb->cb;
974 memset(meta, 0, sizeof(*meta));
975 meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
976 meta->iface = iface;
977 meta->tx_cb_idx = tx_cb_idx;
978
979 skb->dev = dev;
980 skb->mac.raw = skb->nh.raw = skb->data;
981 dev_queue_xmit(skb);
982}
983#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
984
985
986static int prism2_sta_proc_read(char *page, char **start, off_t off,
987 int count, int *eof, void *data)
988{
989 char *p = page;
990 struct sta_info *sta = (struct sta_info *) data;
991 int i;
992
993 /* FIX: possible race condition.. the STA data could have just expired,
994 * but proc entry was still here so that the read could have started;
995 * some locking should be done here.. */
996
997 if (off != 0) {
998 *eof = 1;
999 return 0;
1000 }
1001
1002 p += sprintf(p, "%s=" MACSTR "\nusers=%d\naid=%d\n"
1003 "flags=0x%04x%s%s%s%s%s%s%s\n"
1004 "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
1005 sta->ap ? "AP" : "STA",
1006 MAC2STR(sta->addr), atomic_read(&sta->users), sta->aid,
1007 sta->flags,
1008 sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
1009 sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
1010 sta->flags & WLAN_STA_PS ? " PS" : "",
1011 sta->flags & WLAN_STA_TIM ? " TIM" : "",
1012 sta->flags & WLAN_STA_PERM ? " PERM" : "",
1013 sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
1014 sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
1015 sta->capability, sta->listen_interval);
1016 /* supported_rates: 500 kbit/s units with msb ignored */
1017 for (i = 0; i < sizeof(sta->supported_rates); i++)
1018 if (sta->supported_rates[i] != 0)
1019 p += sprintf(p, "%d%sMbps ",
1020 (sta->supported_rates[i] & 0x7f) / 2,
1021 sta->supported_rates[i] & 1 ? ".5" : "");
1022 p += sprintf(p, "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
1023 "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
1024 "tx_packets=%lu\n"
1025 "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
1026 "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
1027 "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
1028 "tx[11M]=%d\n"
1029 "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
1030 jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
1031 sta->last_tx,
1032 sta->rx_packets, sta->tx_packets, sta->rx_bytes,
1033 sta->tx_bytes, skb_queue_len(&sta->tx_buf),
1034 sta->last_rx_silence,
1035 sta->last_rx_signal, sta->last_rx_rate / 10,
1036 sta->last_rx_rate % 10 ? ".5" : "",
1037 sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
1038 sta->tx_count[2], sta->tx_count[3], sta->rx_count[0],
1039 sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
1040 if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats)
1041 p = sta->crypt->ops->print_stats(p, sta->crypt->priv);
1042#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1043 if (sta->ap) {
1044 if (sta->u.ap.channel >= 0)
1045 p += sprintf(p, "channel=%d\n", sta->u.ap.channel);
1046 p += sprintf(p, "ssid=");
1047 for (i = 0; i < sta->u.ap.ssid_len; i++)
1048 p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
1049 sta->u.ap.ssid[i] < 127) ?
1050 "%c" : "<%02x>"),
1051 sta->u.ap.ssid[i]);
1052 p += sprintf(p, "\n");
1053 }
1054#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1055
1056 return (p - page);
1057}
1058
1059
1060static void handle_add_proc_queue(void *data)
1061{
1062 struct ap_data *ap = (struct ap_data *) data;
1063 struct sta_info *sta;
1064 char name[20];
1065 struct add_sta_proc_data *entry, *prev;
1066
1067 entry = ap->add_sta_proc_entries;
1068 ap->add_sta_proc_entries = NULL;
1069
1070 while (entry) {
1071 spin_lock_bh(&ap->sta_table_lock);
1072 sta = ap_get_sta(ap, entry->addr);
1073 if (sta)
1074 atomic_inc(&sta->users);
1075 spin_unlock_bh(&ap->sta_table_lock);
1076
1077 if (sta) {
1078 sprintf(name, MACSTR, MAC2STR(sta->addr));
1079 sta->proc = create_proc_read_entry(
1080 name, 0, ap->proc,
1081 prism2_sta_proc_read, sta);
1082
1083 atomic_dec(&sta->users);
1084 }
1085
1086 prev = entry;
1087 entry = entry->next;
1088 kfree(prev);
1089 }
1090}
1091
1092
1093static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
1094{
1095 struct sta_info *sta;
1096
1097 sta = (struct sta_info *)
1098 kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
1099 if (sta == NULL) {
1100 PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
1101 return NULL;
1102 }
1103
1104 /* initialize STA info data */
1105 memset(sta, 0, sizeof(struct sta_info));
1106 sta->local = ap->local;
1107 skb_queue_head_init(&sta->tx_buf);
1108 memcpy(sta->addr, addr, ETH_ALEN);
1109
1110 atomic_inc(&sta->users);
1111 spin_lock_bh(&ap->sta_table_lock);
1112 list_add(&sta->list, &ap->sta_list);
1113 ap->num_sta++;
1114 ap_sta_hash_add(ap, sta);
1115 spin_unlock_bh(&ap->sta_table_lock);
1116
1117 if (ap->proc) {
1118 struct add_sta_proc_data *entry;
1119 /* schedule a non-interrupt context process to add a procfs
1120 * entry for the STA since procfs code use GFP_KERNEL */
1121 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
1122 if (entry) {
1123 memcpy(entry->addr, sta->addr, ETH_ALEN);
1124 entry->next = ap->add_sta_proc_entries;
1125 ap->add_sta_proc_entries = entry;
1126 schedule_work(&ap->add_sta_proc_queue);
1127 } else
1128 printk(KERN_DEBUG "Failed to add STA proc data\n");
1129 }
1130
1131#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1132 init_timer(&sta->timer);
1133 sta->timer.expires = jiffies + ap->max_inactivity;
1134 sta->timer.data = (unsigned long) sta;
1135 sta->timer.function = ap_handle_timer;
1136 if (!ap->local->hostapd)
1137 add_timer(&sta->timer);
1138#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1139
1140 return sta;
1141}
1142
1143
1144static int ap_tx_rate_ok(int rateidx, struct sta_info *sta,
1145 local_info_t *local)
1146{
1147 if (rateidx > sta->tx_max_rate ||
1148 !(sta->tx_supp_rates & (1 << rateidx)))
1149 return 0;
1150
1151 if (local->tx_rate_control != 0 &&
1152 !(local->tx_rate_control & (1 << rateidx)))
1153 return 0;
1154
1155 return 1;
1156}
1157
1158
1159static void prism2_check_tx_rates(struct sta_info *sta)
1160{
1161 int i;
1162
1163 sta->tx_supp_rates = 0;
1164 for (i = 0; i < sizeof(sta->supported_rates); i++) {
1165 if ((sta->supported_rates[i] & 0x7f) == 2)
1166 sta->tx_supp_rates |= WLAN_RATE_1M;
1167 if ((sta->supported_rates[i] & 0x7f) == 4)
1168 sta->tx_supp_rates |= WLAN_RATE_2M;
1169 if ((sta->supported_rates[i] & 0x7f) == 11)
1170 sta->tx_supp_rates |= WLAN_RATE_5M5;
1171 if ((sta->supported_rates[i] & 0x7f) == 22)
1172 sta->tx_supp_rates |= WLAN_RATE_11M;
1173 }
1174 sta->tx_max_rate = sta->tx_rate = sta->tx_rate_idx = 0;
1175 if (sta->tx_supp_rates & WLAN_RATE_1M) {
1176 sta->tx_max_rate = 0;
1177 if (ap_tx_rate_ok(0, sta, sta->local)) {
1178 sta->tx_rate = 10;
1179 sta->tx_rate_idx = 0;
1180 }
1181 }
1182 if (sta->tx_supp_rates & WLAN_RATE_2M) {
1183 sta->tx_max_rate = 1;
1184 if (ap_tx_rate_ok(1, sta, sta->local)) {
1185 sta->tx_rate = 20;
1186 sta->tx_rate_idx = 1;
1187 }
1188 }
1189 if (sta->tx_supp_rates & WLAN_RATE_5M5) {
1190 sta->tx_max_rate = 2;
1191 if (ap_tx_rate_ok(2, sta, sta->local)) {
1192 sta->tx_rate = 55;
1193 sta->tx_rate_idx = 2;
1194 }
1195 }
1196 if (sta->tx_supp_rates & WLAN_RATE_11M) {
1197 sta->tx_max_rate = 3;
1198 if (ap_tx_rate_ok(3, sta, sta->local)) {
1199 sta->tx_rate = 110;
1200 sta->tx_rate_idx = 3;
1201 }
1202 }
1203}
1204
1205
1206#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1207
1208static void ap_crypt_init(struct ap_data *ap)
1209{
1210 ap->crypt = ieee80211_get_crypto_ops("WEP");
1211
1212 if (ap->crypt) {
1213 if (ap->crypt->init) {
1214 ap->crypt_priv = ap->crypt->init(0);
1215 if (ap->crypt_priv == NULL)
1216 ap->crypt = NULL;
1217 else {
1218 u8 key[WEP_KEY_LEN];
1219 get_random_bytes(key, WEP_KEY_LEN);
1220 ap->crypt->set_key(key, WEP_KEY_LEN, NULL,
1221 ap->crypt_priv);
1222 }
1223 }
1224 }
1225
1226 if (ap->crypt == NULL) {
1227 printk(KERN_WARNING "AP could not initialize WEP: load module "
1228 "ieee80211_crypt_wep.ko\n");
1229 }
1230}
1231
1232
1233/* Generate challenge data for shared key authentication. IEEE 802.11 specifies
1234 * that WEP algorithm is used for generating challange. This should be unique,
1235 * but otherwise there is not really need for randomness etc. Initialize WEP
1236 * with pseudo random key and then use increasing IV to get unique challenge
1237 * streams.
1238 *
1239 * Called only as a scheduled task for pending AP frames.
1240 */
1241static char * ap_auth_make_challenge(struct ap_data *ap)
1242{
1243 char *tmpbuf;
1244 struct sk_buff *skb;
1245
1246 if (ap->crypt == NULL) {
1247 ap_crypt_init(ap);
1248 if (ap->crypt == NULL)
1249 return NULL;
1250 }
1251
1252 tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
1253 if (tmpbuf == NULL) {
1254 PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
1255 return NULL;
1256 }
1257
1258 skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
1259 ap->crypt->extra_prefix_len +
1260 ap->crypt->extra_postfix_len);
1261 if (skb == NULL) {
1262 kfree(tmpbuf);
1263 return NULL;
1264 }
1265
1266 skb_reserve(skb, ap->crypt->extra_prefix_len);
1267 memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
1268 WLAN_AUTH_CHALLENGE_LEN);
1269 if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
1270 dev_kfree_skb(skb);
1271 kfree(tmpbuf);
1272 return NULL;
1273 }
1274
1275 memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
1276 WLAN_AUTH_CHALLENGE_LEN);
1277 dev_kfree_skb(skb);
1278
1279 return tmpbuf;
1280}
1281
1282
1283/* Called only as a scheduled task for pending AP frames. */
1284static void handle_authen(local_info_t *local, struct sk_buff *skb,
1285 struct hostap_80211_rx_status *rx_stats)
1286{
1287 struct net_device *dev = local->dev;
1288 struct ieee80211_hdr *hdr = (struct 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 ieee80211_crypt_data *crypt;
1297 char *txt = "";
1298
1299 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1300
1301 fc = le16_to_cpu(hdr->frame_ctl);
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 & IEEE80211_FCTL_PROTECTED)) {
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, IEEE80211_FTYPE_MGMT | IEEE80211_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 ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1502 char body[12], *p, *lpos;
1503 int len, left;
1504 u16 *pos;
1505 u16 resp = WLAN_STATUS_SUCCESS;
1506 struct sta_info *sta = NULL;
1507 int send_deauth = 0;
1508 char *txt = "";
1509 u8 prev_ap[ETH_ALEN];
1510
1511 left = len = skb->len - IEEE80211_MGMT_HDR_LEN;
1512
1513 if (len < (reassoc ? 10 : 4)) {
1514 PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
1515 "(len=%d, reassoc=%d) from " MACSTR "\n",
1516 dev->name, len, reassoc, MAC2STR(hdr->addr2));
1517 return;
1518 }
1519
1520 spin_lock_bh(&local->ap->sta_table_lock);
1521 sta = ap_get_sta(local->ap, hdr->addr2);
1522 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
1523 spin_unlock_bh(&local->ap->sta_table_lock);
1524 txt = "trying to associate before authentication";
1525 send_deauth = 1;
1526 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1527 sta = NULL; /* do not decrement sta->users */
1528 goto fail;
1529 }
1530 atomic_inc(&sta->users);
1531 spin_unlock_bh(&local->ap->sta_table_lock);
1532
1533 pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1534 sta->capability = __le16_to_cpu(*pos);
1535 pos++; left -= 2;
1536 sta->listen_interval = __le16_to_cpu(*pos);
1537 pos++; left -= 2;
1538
1539 if (reassoc) {
1540 memcpy(prev_ap, pos, ETH_ALEN);
1541 pos++; pos++; pos++; left -= 6;
1542 } else
1543 memset(prev_ap, 0, ETH_ALEN);
1544
1545 if (left >= 2) {
1546 unsigned int ileft;
1547 unsigned char *u = (unsigned char *) pos;
1548
1549 if (*u == WLAN_EID_SSID) {
1550 u++; left--;
1551 ileft = *u;
1552 u++; left--;
1553
1554 if (ileft > left || ileft > MAX_SSID_LEN) {
1555 txt = "SSID overflow";
1556 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1557 goto fail;
1558 }
1559
1560 if (ileft != strlen(local->essid) ||
1561 memcmp(local->essid, u, ileft) != 0) {
1562 txt = "not our SSID";
1563 resp = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1564 goto fail;
1565 }
1566
1567 u += ileft;
1568 left -= ileft;
1569 }
1570
1571 if (left >= 2 && *u == WLAN_EID_SUPP_RATES) {
1572 u++; left--;
1573 ileft = *u;
1574 u++; left--;
1575
1576 if (ileft > left || ileft == 0 ||
1577 ileft > WLAN_SUPP_RATES_MAX) {
1578 txt = "SUPP_RATES len error";
1579 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1580 goto fail;
1581 }
1582
1583 memset(sta->supported_rates, 0,
1584 sizeof(sta->supported_rates));
1585 memcpy(sta->supported_rates, u, ileft);
1586 prism2_check_tx_rates(sta);
1587
1588 u += ileft;
1589 left -= ileft;
1590 }
1591
1592 if (left > 0) {
1593 PDEBUG(DEBUG_AP, "%s: assoc from " MACSTR " with extra"
1594 " data (%d bytes) [",
1595 dev->name, MAC2STR(hdr->addr2), left);
1596 while (left > 0) {
1597 PDEBUG2(DEBUG_AP, "<%02x>", *u);
1598 u++; left--;
1599 }
1600 PDEBUG2(DEBUG_AP, "]\n");
1601 }
1602 } else {
1603 txt = "frame underflow";
1604 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1605 goto fail;
1606 }
1607
1608 /* get a unique AID */
1609 if (sta->aid > 0)
1610 txt = "OK, old AID";
1611 else {
1612 spin_lock_bh(&local->ap->sta_table_lock);
1613 for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
1614 if (local->ap->sta_aid[sta->aid - 1] == NULL)
1615 break;
1616 if (sta->aid > MAX_AID_TABLE_SIZE) {
1617 sta->aid = 0;
1618 spin_unlock_bh(&local->ap->sta_table_lock);
1619 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1620 txt = "no room for more AIDs";
1621 } else {
1622 local->ap->sta_aid[sta->aid - 1] = sta;
1623 spin_unlock_bh(&local->ap->sta_table_lock);
1624 txt = "OK, new AID";
1625 }
1626 }
1627
1628 fail:
1629 pos = (u16 *) body;
1630
1631 if (send_deauth) {
1632 *pos = __constant_cpu_to_le16(
1633 WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
1634 pos++;
1635 } else {
1636 /* FIX: CF-Pollable and CF-PollReq should be set to match the
1637 * values in beacons/probe responses */
1638 /* FIX: how about privacy and WEP? */
1639 /* capability */
1640 *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS);
1641 pos++;
1642
1643 /* status_code */
1644 *pos = __cpu_to_le16(resp);
1645 pos++;
1646
1647 *pos = __cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
1648 BIT(14) | BIT(15)); /* AID */
1649 pos++;
1650
1651 /* Supported rates (Information element) */
1652 p = (char *) pos;
1653 *p++ = WLAN_EID_SUPP_RATES;
1654 lpos = p;
1655 *p++ = 0; /* len */
1656 if (local->tx_rate_control & WLAN_RATE_1M) {
1657 *p++ = local->basic_rates & WLAN_RATE_1M ? 0x82 : 0x02;
1658 (*lpos)++;
1659 }
1660 if (local->tx_rate_control & WLAN_RATE_2M) {
1661 *p++ = local->basic_rates & WLAN_RATE_2M ? 0x84 : 0x04;
1662 (*lpos)++;
1663 }
1664 if (local->tx_rate_control & WLAN_RATE_5M5) {
1665 *p++ = local->basic_rates & WLAN_RATE_5M5 ?
1666 0x8b : 0x0b;
1667 (*lpos)++;
1668 }
1669 if (local->tx_rate_control & WLAN_RATE_11M) {
1670 *p++ = local->basic_rates & WLAN_RATE_11M ?
1671 0x96 : 0x16;
1672 (*lpos)++;
1673 }
1674 pos = (u16 *) p;
1675 }
1676
1677 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
1678 (send_deauth ? IEEE80211_STYPE_DEAUTH :
1679 (reassoc ? IEEE80211_STYPE_REASSOC_RESP :
1680 IEEE80211_STYPE_ASSOC_RESP)),
1681 body, (u8 *) pos - (u8 *) body,
1682 hdr->addr2,
1683 send_deauth ? 0 : local->ap->tx_callback_assoc);
1684
1685 if (sta) {
1686 if (resp == WLAN_STATUS_SUCCESS) {
1687 sta->last_rx = jiffies;
1688 /* STA will be marked associated from TX callback, if
1689 * AssocResp is ACKed */
1690 }
1691 atomic_dec(&sta->users);
1692 }
1693
1694#if 0
1695 PDEBUG(DEBUG_AP, "%s: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR
1696 ") => %d(%d) (%s)\n",
1697 dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len,
1698 MAC2STR(prev_ap), resp, send_deauth, txt);
1699#endif
1700}
1701
1702
1703/* Called only as a scheduled task for pending AP frames. */
1704static void handle_deauth(local_info_t *local, struct sk_buff *skb,
1705 struct hostap_80211_rx_status *rx_stats)
1706{
1707 struct net_device *dev = local->dev;
1708 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1709 char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
1710 int len;
1711 u16 reason_code, *pos;
1712 struct sta_info *sta = NULL;
1713
1714 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1715
1716 if (len < 2) {
1717 printk("handle_deauth - too short payload (len=%d)\n", len);
1718 return;
1719 }
1720
1721 pos = (u16 *) body;
1722 reason_code = __le16_to_cpu(*pos);
1723
1724 PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, "
1725 "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
1726 reason_code);
1727
1728 spin_lock_bh(&local->ap->sta_table_lock);
1729 sta = ap_get_sta(local->ap, hdr->addr2);
1730 if (sta != NULL) {
1731 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
1732 hostap_event_expired_sta(local->dev, sta);
1733 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1734 }
1735 spin_unlock_bh(&local->ap->sta_table_lock);
1736 if (sta == NULL) {
1737 printk("%s: deauthentication from " MACSTR ", "
1738 "reason_code=%d, but STA not authenticated\n", dev->name,
1739 MAC2STR(hdr->addr2), reason_code);
1740 }
1741}
1742
1743
1744/* Called only as a scheduled task for pending AP frames. */
1745static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
1746 struct hostap_80211_rx_status *rx_stats)
1747{
1748 struct net_device *dev = local->dev;
1749 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1750 char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
1751 int len;
1752 u16 reason_code, *pos;
1753 struct sta_info *sta = NULL;
1754
1755 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1756
1757 if (len < 2) {
1758 printk("handle_disassoc - too short payload (len=%d)\n", len);
1759 return;
1760 }
1761
1762 pos = (u16 *) body;
1763 reason_code = __le16_to_cpu(*pos);
1764
1765 PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, "
1766 "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len,
1767 reason_code);
1768
1769 spin_lock_bh(&local->ap->sta_table_lock);
1770 sta = ap_get_sta(local->ap, hdr->addr2);
1771 if (sta != NULL) {
1772 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
1773 hostap_event_expired_sta(local->dev, sta);
1774 sta->flags &= ~WLAN_STA_ASSOC;
1775 }
1776 spin_unlock_bh(&local->ap->sta_table_lock);
1777 if (sta == NULL) {
1778 printk("%s: disassociation from " MACSTR ", "
1779 "reason_code=%d, but STA not authenticated\n",
1780 dev->name, MAC2STR(hdr->addr2), reason_code);
1781 }
1782}
1783
1784
1785/* Called only as a scheduled task for pending AP frames. */
1786static void ap_handle_data_nullfunc(local_info_t *local,
1787 struct ieee80211_hdr *hdr)
1788{
1789 struct net_device *dev = local->dev;
1790
1791 /* some STA f/w's seem to require control::ACK frame for
1792 * data::nullfunc, but at least Prism2 station f/w version 0.8.0 does
1793 * not send this..
1794 * send control::ACK for the data::nullfunc */
1795
1796 printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n");
1797 prism2_send_mgmt(dev, IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK,
1798 NULL, 0, hdr->addr2, 0);
1799}
1800
1801
1802/* Called only as a scheduled task for pending AP frames. */
1803static void ap_handle_dropped_data(local_info_t *local,
1804 struct ieee80211_hdr *hdr)
1805{
1806 struct net_device *dev = local->dev;
1807 struct sta_info *sta;
1808 u16 reason;
1809
1810 spin_lock_bh(&local->ap->sta_table_lock);
1811 sta = ap_get_sta(local->ap, hdr->addr2);
1812 if (sta)
1813 atomic_inc(&sta->users);
1814 spin_unlock_bh(&local->ap->sta_table_lock);
1815
1816 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC)) {
1817 PDEBUG(DEBUG_AP, "ap_handle_dropped_data: STA is now okay?\n");
1818 atomic_dec(&sta->users);
1819 return;
1820 }
1821
1822 reason = __constant_cpu_to_le16(
1823 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1824 prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
1825 ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
1826 IEEE80211_STYPE_DEAUTH : IEEE80211_STYPE_DISASSOC),
1827 (char *) &reason, sizeof(reason), hdr->addr2, 0);
1828
1829 if (sta)
1830 atomic_dec(&sta->users);
1831}
1832
1833#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1834
1835
1836/* Called only as a scheduled task for pending AP frames. */
1837static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
1838 struct sk_buff *skb)
1839{
1840 struct hostap_skb_tx_data *meta;
1841
1842 if (!(sta->flags & WLAN_STA_PS)) {
1843 /* Station has moved to non-PS mode, so send all buffered
1844 * frames using normal device queue. */
1845 dev_queue_xmit(skb);
1846 return;
1847 }
1848
1849 /* add a flag for hostap_handle_sta_tx() to know that this skb should
1850 * be passed through even though STA is using PS */
1851 meta = (struct hostap_skb_tx_data *) skb->cb;
1852 meta->flags |= HOSTAP_TX_FLAGS_BUFFERED_FRAME;
1853 if (!skb_queue_empty(&sta->tx_buf)) {
1854 /* indicate to STA that more frames follow */
1855 meta->flags |= HOSTAP_TX_FLAGS_ADD_MOREDATA;
1856 }
1857 dev_queue_xmit(skb);
1858}
1859
1860
1861/* Called only as a scheduled task for pending AP frames. */
1862static void handle_pspoll(local_info_t *local,
1863 struct ieee80211_hdr *hdr,
1864 struct hostap_80211_rx_status *rx_stats)
1865{
1866 struct net_device *dev = local->dev;
1867 struct sta_info *sta;
1868 u16 aid;
1869 struct sk_buff *skb;
1870
1871 PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR
1872 " PWRMGT=%d\n",
1873 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
1874 !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
1875
1876 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
1877 PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR
1878 " not own MAC\n", MAC2STR(hdr->addr1));
1879 return;
1880 }
1881
1882 aid = __le16_to_cpu(hdr->duration_id);
1883 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) {
1884 PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n");
1885 return;
1886 }
1887 aid &= ~BIT(15) & ~BIT(14);
1888 if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
1889 PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid);
1890 return;
1891 }
1892 PDEBUG(DEBUG_PS2, " aid=%d\n", aid);
1893
1894 spin_lock_bh(&local->ap->sta_table_lock);
1895 sta = ap_get_sta(local->ap, hdr->addr2);
1896 if (sta)
1897 atomic_inc(&sta->users);
1898 spin_unlock_bh(&local->ap->sta_table_lock);
1899
1900 if (sta == NULL) {
1901 PDEBUG(DEBUG_PS, " STA not found\n");
1902 return;
1903 }
1904 if (sta->aid != aid) {
1905 PDEBUG(DEBUG_PS, " received aid=%i does not match with "
1906 "assoc.aid=%d\n", aid, sta->aid);
1907 return;
1908 }
1909
1910 /* FIX: todo:
1911 * - add timeout for buffering (clear aid in TIM vector if buffer timed
1912 * out (expiry time must be longer than ListenInterval for
1913 * the corresponding STA; "8802-11: 11.2.1.9 AP aging function"
1914 * - what to do, if buffered, pspolled, and sent frame is not ACKed by
1915 * sta; store buffer for later use and leave TIM aid bit set? use
1916 * TX event to check whether frame was ACKed?
1917 */
1918
1919 while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) {
1920 /* send buffered frame .. */
1921 PDEBUG(DEBUG_PS2, "Sending buffered frame to STA after PS POLL"
1922 " (buffer_count=%d)\n", skb_queue_len(&sta->tx_buf));
1923
1924 pspoll_send_buffered(local, sta, skb);
1925
1926 if (sta->flags & WLAN_STA_PS) {
1927 /* send only one buffered packet per PS Poll */
1928 /* FIX: should ignore further PS Polls until the
1929 * buffered packet that was just sent is acknowledged
1930 * (Tx or TxExc event) */
1931 break;
1932 }
1933 }
1934
1935 if (skb_queue_empty(&sta->tx_buf)) {
1936 /* try to clear aid from TIM */
1937 if (!(sta->flags & WLAN_STA_TIM))
1938 PDEBUG(DEBUG_PS2, "Re-unsetting TIM for aid %d\n",
1939 aid);
1940 hostap_set_tim(local, aid, 0);
1941 sta->flags &= ~WLAN_STA_TIM;
1942 }
1943
1944 atomic_dec(&sta->users);
1945}
1946
1947
1948#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
1949
1950static void handle_wds_oper_queue(void *data)
1951{
1952 local_info_t *local = data;
1953 struct wds_oper_data *entry, *prev;
1954
1955 spin_lock_bh(&local->lock);
1956 entry = local->ap->wds_oper_entries;
1957 local->ap->wds_oper_entries = NULL;
1958 spin_unlock_bh(&local->lock);
1959
1960 while (entry) {
1961 PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
1962 "to AP " MACSTR "\n",
1963 local->dev->name,
1964 entry->type == WDS_ADD ? "adding" : "removing",
1965 MAC2STR(entry->addr));
1966 if (entry->type == WDS_ADD)
1967 prism2_wds_add(local, entry->addr, 0);
1968 else if (entry->type == WDS_DEL)
1969 prism2_wds_del(local, entry->addr, 0, 1);
1970
1971 prev = entry;
1972 entry = entry->next;
1973 kfree(prev);
1974 }
1975}
1976
1977
1978/* Called only as a scheduled task for pending AP frames. */
1979static void handle_beacon(local_info_t *local, struct sk_buff *skb,
1980 struct hostap_80211_rx_status *rx_stats)
1981{
1982 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1983 char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
1984 int len, left;
1985 u16 *pos, beacon_int, capability;
1986 char *ssid = NULL;
1987 unsigned char *supp_rates = NULL;
1988 int ssid_len = 0, supp_rates_len = 0;
1989 struct sta_info *sta = NULL;
1990 int new_sta = 0, channel = -1;
1991
1992 len = skb->len - IEEE80211_MGMT_HDR_LEN;
1993
1994 if (len < 8 + 2 + 2) {
1995 printk(KERN_DEBUG "handle_beacon - too short payload "
1996 "(len=%d)\n", len);
1997 return;
1998 }
1999
2000 pos = (u16 *) body;
2001 left = len;
2002
2003 /* Timestamp (8 octets) */
2004 pos += 4; left -= 8;
2005 /* Beacon interval (2 octets) */
2006 beacon_int = __le16_to_cpu(*pos);
2007 pos++; left -= 2;
2008 /* Capability information (2 octets) */
2009 capability = __le16_to_cpu(*pos);
2010 pos++; left -= 2;
2011
2012 if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS &&
2013 capability & WLAN_CAPABILITY_IBSS)
2014 return;
2015
2016 if (left >= 2) {
2017 unsigned int ileft;
2018 unsigned char *u = (unsigned char *) pos;
2019
2020 if (*u == WLAN_EID_SSID) {
2021 u++; left--;
2022 ileft = *u;
2023 u++; left--;
2024
2025 if (ileft > left || ileft > MAX_SSID_LEN) {
2026 PDEBUG(DEBUG_AP, "SSID: overflow\n");
2027 return;
2028 }
2029
2030 if (local->ap->ap_policy == AP_OTHER_AP_SAME_SSID &&
2031 (ileft != strlen(local->essid) ||
2032 memcmp(local->essid, u, ileft) != 0)) {
2033 /* not our SSID */
2034 return;
2035 }
2036
2037 ssid = u;
2038 ssid_len = ileft;
2039
2040 u += ileft;
2041 left -= ileft;
2042 }
2043
2044 if (*u == WLAN_EID_SUPP_RATES) {
2045 u++; left--;
2046 ileft = *u;
2047 u++; left--;
2048
2049 if (ileft > left || ileft == 0 || ileft > 8) {
2050 PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n");
2051 return;
2052 }
2053
2054 supp_rates = u;
2055 supp_rates_len = ileft;
2056
2057 u += ileft;
2058 left -= ileft;
2059 }
2060
2061 if (*u == WLAN_EID_DS_PARAMS) {
2062 u++; left--;
2063 ileft = *u;
2064 u++; left--;
2065
2066 if (ileft > left || ileft != 1) {
2067 PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n");
2068 return;
2069 }
2070
2071 channel = *u;
2072
2073 u += ileft;
2074 left -= ileft;
2075 }
2076 }
2077
2078 spin_lock_bh(&local->ap->sta_table_lock);
2079 sta = ap_get_sta(local->ap, hdr->addr2);
2080 if (sta != NULL)
2081 atomic_inc(&sta->users);
2082 spin_unlock_bh(&local->ap->sta_table_lock);
2083
2084 if (sta == NULL) {
2085 /* add new AP */
2086 new_sta = 1;
2087 sta = ap_add_sta(local->ap, hdr->addr2);
2088 if (sta == NULL) {
2089 printk(KERN_INFO "prism2: kmalloc failed for AP "
2090 "data structure\n");
2091 return;
2092 }
2093 hostap_event_new_sta(local->dev, sta);
2094
2095 /* mark APs authentication and associated for pseudo ad-hoc
2096 * style communication */
2097 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
2098
2099 if (local->ap->autom_ap_wds) {
2100 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
2101 }
2102 }
2103
2104 sta->ap = 1;
2105 if (ssid) {
2106 sta->u.ap.ssid_len = ssid_len;
2107 memcpy(sta->u.ap.ssid, ssid, ssid_len);
2108 sta->u.ap.ssid[ssid_len] = '\0';
2109 } else {
2110 sta->u.ap.ssid_len = 0;
2111 sta->u.ap.ssid[0] = '\0';
2112 }
2113 sta->u.ap.channel = channel;
2114 sta->rx_packets++;
2115 sta->rx_bytes += len;
2116 sta->u.ap.last_beacon = sta->last_rx = jiffies;
2117 sta->capability = capability;
2118 sta->listen_interval = beacon_int;
2119
2120 atomic_dec(&sta->users);
2121
2122 if (new_sta) {
2123 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
2124 memcpy(sta->supported_rates, supp_rates, supp_rates_len);
2125 prism2_check_tx_rates(sta);
2126 }
2127}
2128
2129#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2130
2131
2132/* Called only as a tasklet. */
2133static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
2134 struct hostap_80211_rx_status *rx_stats)
2135{
2136#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2137 struct net_device *dev = local->dev;
2138#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2139 u16 fc, type, stype;
2140 struct ieee80211_hdr *hdr;
2141
2142 /* FIX: should give skb->len to handler functions and check that the
2143 * buffer is long enough */
2144 hdr = (struct ieee80211_hdr *) skb->data;
2145 fc = le16_to_cpu(hdr->frame_ctl);
2146 type = WLAN_FC_GET_TYPE(fc);
2147 stype = WLAN_FC_GET_STYPE(fc);
2148
2149#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2150 if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
2151 PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n");
2152
2153 if (!(fc & IEEE80211_FCTL_TODS) ||
2154 (fc & IEEE80211_FCTL_FROMDS)) {
2155 if (stype == IEEE80211_STYPE_NULLFUNC) {
2156 /* no ToDS nullfunc seems to be used to check
2157 * AP association; so send reject message to
2158 * speed up re-association */
2159 ap_handle_dropped_data(local, hdr);
2160 goto done;
2161 }
2162 PDEBUG(DEBUG_AP, " not ToDS frame (fc=0x%04x)\n",
2163 fc);
2164 goto done;
2165 }
2166
2167 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2168 PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
2169 MACSTR " not own MAC\n",
2170 MAC2STR(hdr->addr1));
2171 goto done;
2172 }
2173
2174 if (local->ap->nullfunc_ack &&
2175 stype == IEEE80211_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 == IEEE80211_FTYPE_MGMT && stype == IEEE80211_STYPE_BEACON) {
2183 handle_beacon(local, skb, rx_stats);
2184 goto done;
2185 }
2186#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2187
2188 if (type == IEEE80211_FTYPE_CTL && stype == IEEE80211_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 != IEEE80211_FTYPE_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 IEEE80211_STYPE_ASSOC_REQ:
2219 handle_assoc(local, skb, rx_stats, 0);
2220 break;
2221 case IEEE80211_STYPE_ASSOC_RESP:
2222 PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n");
2223 break;
2224 case IEEE80211_STYPE_REASSOC_REQ:
2225 handle_assoc(local, skb, rx_stats, 1);
2226 break;
2227 case IEEE80211_STYPE_REASSOC_RESP:
2228 PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n");
2229 break;
2230 case IEEE80211_STYPE_ATIM:
2231 PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n");
2232 break;
2233 case IEEE80211_STYPE_DISASSOC:
2234 handle_disassoc(local, skb, rx_stats);
2235 break;
2236 case IEEE80211_STYPE_AUTH:
2237 handle_authen(local, skb, rx_stats);
2238 break;
2239 case IEEE80211_STYPE_DEAUTH:
2240 handle_deauth(local, skb, rx_stats);
2241 break;
2242 default:
2243 PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n",
2244 stype >> 4);
2245 break;
2246 }
2247#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2248
2249 done:
2250 dev_kfree_skb(skb);
2251}
2252
2253
2254/* Called only as a tasklet (software IRQ) */
2255void hostap_rx(struct net_device *dev, struct sk_buff *skb,
2256 struct hostap_80211_rx_status *rx_stats)
2257{
2258 struct hostap_interface *iface;
2259 local_info_t *local;
2260 u16 fc;
2261 struct ieee80211_hdr *hdr;
2262
2263 iface = netdev_priv(dev);
2264 local = iface->local;
2265
2266 if (skb->len < 16)
2267 goto drop;
2268
2269 local->stats.rx_packets++;
2270
2271 hdr = (struct ieee80211_hdr *) skb->data;
2272 fc = le16_to_cpu(hdr->frame_ctl);
2273
2274 if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
2275 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT &&
2276 WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_BEACON)
2277 goto drop;
2278
2279 skb->protocol = __constant_htons(ETH_P_HOSTAP);
2280 handle_ap_item(local, skb, rx_stats);
2281 return;
2282
2283 drop:
2284 dev_kfree_skb(skb);
2285}
2286
2287
2288/* Called only as a tasklet (software IRQ) */
2289static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
2290{
2291 struct sk_buff *skb;
2292 struct ieee80211_hdr *hdr;
2293 struct hostap_80211_rx_status rx_stats;
2294
2295 if (skb_queue_empty(&sta->tx_buf))
2296 return;
2297
2298 skb = dev_alloc_skb(16);
2299 if (skb == NULL) {
2300 printk(KERN_DEBUG "%s: schedule_packet_send: skb alloc "
2301 "failed\n", local->dev->name);
2302 return;
2303 }
2304
2305 hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
2306
2307 /* Generate a fake pspoll frame to start packet delivery */
2308 hdr->frame_ctl = __constant_cpu_to_le16(
2309 IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
2310 memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
2311 memcpy(hdr->addr2, sta->addr, ETH_ALEN);
2312 hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));
2313
2314 PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for "
2315 "STA " MACSTR "\n", local->dev->name, MAC2STR(sta->addr));
2316
2317 skb->dev = local->dev;
2318
2319 memset(&rx_stats, 0, sizeof(rx_stats));
2320 hostap_rx(local->dev, skb, &rx_stats);
2321}
2322
2323
2324static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
2325 struct iw_quality qual[], int buf_size,
2326 int aplist)
2327{
2328 struct ap_data *ap = local->ap;
2329 struct list_head *ptr;
2330 int count = 0;
2331
2332 spin_lock_bh(&ap->sta_table_lock);
2333
2334 for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
2335 ptr = ptr->next) {
2336 struct sta_info *sta = (struct sta_info *) ptr;
2337
2338 if (aplist && !sta->ap)
2339 continue;
2340 addr[count].sa_family = ARPHRD_ETHER;
2341 memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
2342 if (sta->last_rx_silence == 0)
2343 qual[count].qual = sta->last_rx_signal < 27 ?
2344 0 : (sta->last_rx_signal - 27) * 92 / 127;
2345 else
2346 qual[count].qual = sta->last_rx_signal -
2347 sta->last_rx_silence - 35;
2348 qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
2349 qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2350 qual[count].updated = sta->last_rx_updated;
2351
2352 sta->last_rx_updated = 0;
2353
2354 count++;
2355 if (count >= buf_size)
2356 break;
2357 }
2358 spin_unlock_bh(&ap->sta_table_lock);
2359
2360 return count;
2361}
2362
2363
2364/* Translate our list of Access Points & Stations to a card independant
2365 * format that the Wireless Tools will understand - Jean II */
2366static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2367{
2368 struct hostap_interface *iface;
2369 local_info_t *local;
2370 struct ap_data *ap;
2371 struct list_head *ptr;
2372 struct iw_event iwe;
2373 char *current_ev = buffer;
2374 char *end_buf = buffer + IW_SCAN_MAX_DATA;
2375#if !defined(PRISM2_NO_KERNEL_IEEE80211_MGMT)
2376 char buf[64];
2377#endif
2378
2379 iface = netdev_priv(dev);
2380 local = iface->local;
2381 ap = local->ap;
2382
2383 spin_lock_bh(&ap->sta_table_lock);
2384
2385 for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
2386 ptr = ptr->next) {
2387 struct sta_info *sta = (struct sta_info *) ptr;
2388
2389 /* First entry *MUST* be the AP MAC address */
2390 memset(&iwe, 0, sizeof(iwe));
2391 iwe.cmd = SIOCGIWAP;
2392 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2393 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
2394 iwe.len = IW_EV_ADDR_LEN;
2395 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2396 IW_EV_ADDR_LEN);
2397
2398 /* Use the mode to indicate if it's a station or
2399 * an Access Point */
2400 memset(&iwe, 0, sizeof(iwe));
2401 iwe.cmd = SIOCGIWMODE;
2402 if (sta->ap)
2403 iwe.u.mode = IW_MODE_MASTER;
2404 else
2405 iwe.u.mode = IW_MODE_INFRA;
2406 iwe.len = IW_EV_UINT_LEN;
2407 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2408 IW_EV_UINT_LEN);
2409
2410 /* Some quality */
2411 memset(&iwe, 0, sizeof(iwe));
2412 iwe.cmd = IWEVQUAL;
2413 if (sta->last_rx_silence == 0)
2414 iwe.u.qual.qual = sta->last_rx_signal < 27 ?
2415 0 : (sta->last_rx_signal - 27) * 92 / 127;
2416 else
2417 iwe.u.qual.qual = sta->last_rx_signal -
2418 sta->last_rx_silence - 35;
2419 iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
2420 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2421 iwe.u.qual.updated = sta->last_rx_updated;
2422 iwe.len = IW_EV_QUAL_LEN;
2423 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
2424 IW_EV_QUAL_LEN);
2425
2426#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2427 if (sta->ap) {
2428 memset(&iwe, 0, sizeof(iwe));
2429 iwe.cmd = SIOCGIWESSID;
2430 iwe.u.data.length = sta->u.ap.ssid_len;
2431 iwe.u.data.flags = 1;
2432 current_ev = iwe_stream_add_point(current_ev, end_buf,
2433 &iwe,
2434 sta->u.ap.ssid);
2435
2436 memset(&iwe, 0, sizeof(iwe));
2437 iwe.cmd = SIOCGIWENCODE;
2438 if (sta->capability & WLAN_CAPABILITY_PRIVACY)
2439 iwe.u.data.flags =
2440 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2441 else
2442 iwe.u.data.flags = IW_ENCODE_DISABLED;
2443 current_ev = iwe_stream_add_point(current_ev, end_buf,
2444 &iwe,
2445 sta->u.ap.ssid
2446 /* 0 byte memcpy */);
2447
2448 if (sta->u.ap.channel > 0 &&
2449 sta->u.ap.channel <= FREQ_COUNT) {
2450 memset(&iwe, 0, sizeof(iwe));
2451 iwe.cmd = SIOCGIWFREQ;
2452 iwe.u.freq.m = freq_list[sta->u.ap.channel - 1]
2453 * 100000;
2454 iwe.u.freq.e = 1;
2455 current_ev = iwe_stream_add_event(
2456 current_ev, end_buf, &iwe,
2457 IW_EV_FREQ_LEN);
2458 }
2459
2460 memset(&iwe, 0, sizeof(iwe));
2461 iwe.cmd = IWEVCUSTOM;
2462 sprintf(buf, "beacon_interval=%d",
2463 sta->listen_interval);
2464 iwe.u.data.length = strlen(buf);
2465 current_ev = iwe_stream_add_point(current_ev, end_buf,
2466 &iwe, buf);
2467 }
2468#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2469
2470 sta->last_rx_updated = 0;
2471
2472 /* To be continued, we should make good use of IWEVCUSTOM */
2473 }
2474
2475 spin_unlock_bh(&ap->sta_table_lock);
2476
2477 return current_ev - buffer;
2478}
2479
2480
2481static int prism2_hostapd_add_sta(struct ap_data *ap,
2482 struct prism2_hostapd_param *param)
2483{
2484 struct sta_info *sta;
2485
2486 spin_lock_bh(&ap->sta_table_lock);
2487 sta = ap_get_sta(ap, param->sta_addr);
2488 if (sta)
2489 atomic_inc(&sta->users);
2490 spin_unlock_bh(&ap->sta_table_lock);
2491
2492 if (sta == NULL) {
2493 sta = ap_add_sta(ap, param->sta_addr);
2494 if (sta == NULL)
2495 return -1;
2496 }
2497
2498 if (!(sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
2499 hostap_event_new_sta(sta->local->dev, sta);
2500
2501 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
2502 sta->last_rx = jiffies;
2503 sta->aid = param->u.add_sta.aid;
2504 sta->capability = param->u.add_sta.capability;
2505 sta->tx_supp_rates = param->u.add_sta.tx_supp_rates;
2506 if (sta->tx_supp_rates & WLAN_RATE_1M)
2507 sta->supported_rates[0] = 2;
2508 if (sta->tx_supp_rates & WLAN_RATE_2M)
2509 sta->supported_rates[1] = 4;
2510 if (sta->tx_supp_rates & WLAN_RATE_5M5)
2511 sta->supported_rates[2] = 11;
2512 if (sta->tx_supp_rates & WLAN_RATE_11M)
2513 sta->supported_rates[3] = 22;
2514 prism2_check_tx_rates(sta);
2515 atomic_dec(&sta->users);
2516 return 0;
2517}
2518
2519
2520static int prism2_hostapd_remove_sta(struct ap_data *ap,
2521 struct prism2_hostapd_param *param)
2522{
2523 struct sta_info *sta;
2524
2525 spin_lock_bh(&ap->sta_table_lock);
2526 sta = ap_get_sta(ap, param->sta_addr);
2527 if (sta) {
2528 ap_sta_hash_del(ap, sta);
2529 list_del(&sta->list);
2530 }
2531 spin_unlock_bh(&ap->sta_table_lock);
2532
2533 if (!sta)
2534 return -ENOENT;
2535
2536 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
2537 hostap_event_expired_sta(sta->local->dev, sta);
2538 ap_free_sta(ap, sta);
2539
2540 return 0;
2541}
2542
2543
2544static int prism2_hostapd_get_info_sta(struct ap_data *ap,
2545 struct prism2_hostapd_param *param)
2546{
2547 struct sta_info *sta;
2548
2549 spin_lock_bh(&ap->sta_table_lock);
2550 sta = ap_get_sta(ap, param->sta_addr);
2551 if (sta)
2552 atomic_inc(&sta->users);
2553 spin_unlock_bh(&ap->sta_table_lock);
2554
2555 if (!sta)
2556 return -ENOENT;
2557
2558 param->u.get_info_sta.inactive_sec = (jiffies - sta->last_rx) / HZ;
2559
2560 atomic_dec(&sta->users);
2561
2562 return 1;
2563}
2564
2565
2566static int prism2_hostapd_set_flags_sta(struct ap_data *ap,
2567 struct prism2_hostapd_param *param)
2568{
2569 struct sta_info *sta;
2570
2571 spin_lock_bh(&ap->sta_table_lock);
2572 sta = ap_get_sta(ap, param->sta_addr);
2573 if (sta) {
2574 sta->flags |= param->u.set_flags_sta.flags_or;
2575 sta->flags &= param->u.set_flags_sta.flags_and;
2576 }
2577 spin_unlock_bh(&ap->sta_table_lock);
2578
2579 if (!sta)
2580 return -ENOENT;
2581
2582 return 0;
2583}
2584
2585
2586static int prism2_hostapd_sta_clear_stats(struct ap_data *ap,
2587 struct prism2_hostapd_param *param)
2588{
2589 struct sta_info *sta;
2590 int rate;
2591
2592 spin_lock_bh(&ap->sta_table_lock);
2593 sta = ap_get_sta(ap, param->sta_addr);
2594 if (sta) {
2595 sta->rx_packets = sta->tx_packets = 0;
2596 sta->rx_bytes = sta->tx_bytes = 0;
2597 for (rate = 0; rate < WLAN_RATE_COUNT; rate++) {
2598 sta->tx_count[rate] = 0;
2599 sta->rx_count[rate] = 0;
2600 }
2601 }
2602 spin_unlock_bh(&ap->sta_table_lock);
2603
2604 if (!sta)
2605 return -ENOENT;
2606
2607 return 0;
2608}
2609
2610
2611static int prism2_hostapd(struct ap_data *ap,
2612 struct prism2_hostapd_param *param)
2613{
2614 switch (param->cmd) {
2615 case PRISM2_HOSTAPD_FLUSH:
2616 ap_control_kickall(ap);
2617 return 0;
2618 case PRISM2_HOSTAPD_ADD_STA:
2619 return prism2_hostapd_add_sta(ap, param);
2620 case PRISM2_HOSTAPD_REMOVE_STA:
2621 return prism2_hostapd_remove_sta(ap, param);
2622 case PRISM2_HOSTAPD_GET_INFO_STA:
2623 return prism2_hostapd_get_info_sta(ap, param);
2624 case PRISM2_HOSTAPD_SET_FLAGS_STA:
2625 return prism2_hostapd_set_flags_sta(ap, param);
2626 case PRISM2_HOSTAPD_STA_CLEAR_STATS:
2627 return prism2_hostapd_sta_clear_stats(ap, param);
2628 default:
2629 printk(KERN_WARNING "prism2_hostapd: unknown cmd=%d\n",
2630 param->cmd);
2631 return -EOPNOTSUPP;
2632 }
2633}
2634
2635
2636/* Update station info for host-based TX rate control and return current
2637 * TX rate */
2638static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
2639{
2640 int ret = sta->tx_rate;
2641 struct hostap_interface *iface;
2642 local_info_t *local;
2643
2644 iface = netdev_priv(dev);
2645 local = iface->local;
2646
2647 sta->tx_count[sta->tx_rate_idx]++;
2648 sta->tx_since_last_failure++;
2649 sta->tx_consecutive_exc = 0;
2650 if (sta->tx_since_last_failure >= WLAN_RATE_UPDATE_COUNT &&
2651 sta->tx_rate_idx < sta->tx_max_rate) {
2652 /* use next higher rate */
2653 int old_rate, new_rate;
2654 old_rate = new_rate = sta->tx_rate_idx;
2655 while (new_rate < sta->tx_max_rate) {
2656 new_rate++;
2657 if (ap_tx_rate_ok(new_rate, sta, local)) {
2658 sta->tx_rate_idx = new_rate;
2659 break;
2660 }
2661 }
2662 if (old_rate != sta->tx_rate_idx) {
2663 switch (sta->tx_rate_idx) {
2664 case 0: sta->tx_rate = 10; break;
2665 case 1: sta->tx_rate = 20; break;
2666 case 2: sta->tx_rate = 55; break;
2667 case 3: sta->tx_rate = 110; break;
2668 default: sta->tx_rate = 0; break;
2669 }
2670 PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate raised to"
2671 " %d\n", dev->name, MAC2STR(sta->addr),
2672 sta->tx_rate);
2673 }
2674 sta->tx_since_last_failure = 0;
2675 }
2676
2677 return ret;
2678}
2679
2680
2681/* Called only from software IRQ. Called for each TX frame prior possible
2682 * encryption and transmit. */
2683ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
2684{
2685 struct sta_info *sta = NULL;
2686 struct sk_buff *skb = tx->skb;
2687 int set_tim, ret;
2688 struct ieee80211_hdr *hdr;
2689 struct hostap_skb_tx_data *meta;
2690
2691 meta = (struct hostap_skb_tx_data *) skb->cb;
2692 ret = AP_TX_CONTINUE;
2693 if (local->ap == NULL || skb->len < 10 ||
2694 meta->iface->type == HOSTAP_INTERFACE_STA)
2695 goto out;
2696
2697 hdr = (struct ieee80211_hdr *) skb->data;
2698
2699 if (hdr->addr1[0] & 0x01) {
2700 /* broadcast/multicast frame - no AP related processing */
2701 goto out;
2702 }
2703
2704 /* unicast packet - check whether destination STA is associated */
2705 spin_lock(&local->ap->sta_table_lock);
2706 sta = ap_get_sta(local->ap, hdr->addr1);
2707 if (sta)
2708 atomic_inc(&sta->users);
2709 spin_unlock(&local->ap->sta_table_lock);
2710
2711 if (local->iw_mode == IW_MODE_MASTER && sta == NULL &&
2712 !(meta->flags & HOSTAP_TX_FLAGS_WDS) &&
2713 meta->iface->type != HOSTAP_INTERFACE_MASTER &&
2714 meta->iface->type != HOSTAP_INTERFACE_AP) {
2715#if 0
2716 /* This can happen, e.g., when wlan0 is added to a bridge and
2717 * bridging code does not know which port is the correct target
2718 * for a unicast frame. In this case, the packet is send to all
2719 * ports of the bridge. Since this is a valid scenario, do not
2720 * print out any errors here. */
2721 if (net_ratelimit()) {
2722 printk(KERN_DEBUG "AP: drop packet to non-associated "
2723 "STA " MACSTR "\n", MAC2STR(hdr->addr1));
2724 }
2725#endif
2726 local->ap->tx_drop_nonassoc++;
2727 ret = AP_TX_DROP;
2728 goto out;
2729 }
2730
2731 if (sta == NULL)
2732 goto out;
2733
2734 if (!(sta->flags & WLAN_STA_AUTHORIZED))
2735 ret = AP_TX_CONTINUE_NOT_AUTHORIZED;
2736
2737 /* Set tx_rate if using host-based TX rate control */
2738 if (!local->fw_tx_rate_control)
2739 local->ap->last_tx_rate = meta->rate =
2740 ap_update_sta_tx_rate(sta, local->dev);
2741
2742 if (local->iw_mode != IW_MODE_MASTER)
2743 goto out;
2744
2745 if (!(sta->flags & WLAN_STA_PS))
2746 goto out;
2747
2748 if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
2749 /* indicate to STA that more frames follow */
2750 hdr->frame_ctl |=
2751 __constant_cpu_to_le16(IEEE80211_FCTL_MOREDATA);
2752 }
2753
2754 if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
2755 /* packet was already buffered and now send due to
2756 * PS poll, so do not rebuffer it */
2757 goto out;
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 ieee80211_hdr *hdr;
2825 struct hostap_skb_tx_data *meta;
2826
2827 hdr = (struct 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 >> 2, stype >> 4);
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 >> 2, stype >> 4);
2886 if (type != IEEE80211_FTYPE_CTL ||
2887 stype != IEEE80211_STYPE_PSPOLL)
2888 schedule_packet_send(local, sta);
2889 }
2890}
2891
2892
2893/* Called only as a tasklet (software IRQ). Called for each RX frame to update
2894 * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
2895int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
2896{
2897 struct sta_info *sta;
2898 u16 fc;
2899
2900 spin_lock(&local->ap->sta_table_lock);
2901 sta = ap_get_sta(local->ap, hdr->addr2);
2902 if (sta)
2903 atomic_inc(&sta->users);
2904 spin_unlock(&local->ap->sta_table_lock);
2905
2906 if (!sta)
2907 return -1;
2908
2909 fc = le16_to_cpu(hdr->frame_ctl);
2910 hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
2911 WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
2912
2913 atomic_dec(&sta->users);
2914 return 0;
2915}
2916
2917
2918/* Called only as a tasklet (software IRQ). Called for each RX frame after
2919 * getting RX header and payload from hardware. */
2920ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
2921 struct sk_buff *skb,
2922 struct hostap_80211_rx_status *rx_stats,
2923 int wds)
2924{
2925 int ret;
2926 struct sta_info *sta;
2927 u16 fc, type, stype;
2928 struct ieee80211_hdr *hdr;
2929
2930 if (local->ap == NULL)
2931 return AP_RX_CONTINUE;
2932
2933 hdr = (struct ieee80211_hdr *) skb->data;
2934
2935 fc = le16_to_cpu(hdr->frame_ctl);
2936 type = WLAN_FC_GET_TYPE(fc);
2937 stype = WLAN_FC_GET_STYPE(fc);
2938
2939 spin_lock(&local->ap->sta_table_lock);
2940 sta = ap_get_sta(local->ap, hdr->addr2);
2941 if (sta)
2942 atomic_inc(&sta->users);
2943 spin_unlock(&local->ap->sta_table_lock);
2944
2945 if (sta && !(sta->flags & WLAN_STA_AUTHORIZED))
2946 ret = AP_RX_CONTINUE_NOT_AUTHORIZED;
2947 else
2948 ret = AP_RX_CONTINUE;
2949
2950
2951 if (fc & IEEE80211_FCTL_TODS) {
2952 if (!wds && (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
2953 if (local->hostapd) {
2954 prism2_rx_80211(local->apdev, skb, rx_stats,
2955 PRISM2_RX_NON_ASSOC);
2956#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2957 } else {
2958 printk(KERN_DEBUG "%s: dropped received packet"
2959 " from non-associated STA " MACSTR
2960 " (type=0x%02x, subtype=0x%02x)\n",
2961 dev->name, MAC2STR(hdr->addr2),
2962 type >> 2, stype >> 4);
2963 hostap_rx(dev, skb, rx_stats);
2964#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2965 }
2966 ret = AP_RX_EXIT;
2967 goto out;
2968 }
2969 } else if (fc & IEEE80211_FCTL_FROMDS) {
2970 if (!wds) {
2971 /* FromDS frame - not for us; probably
2972 * broadcast/multicast in another BSS - drop */
2973 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
2974 printk(KERN_DEBUG "Odd.. FromDS packet "
2975 "received with own BSSID\n");
2976 hostap_dump_rx_80211(dev->name, skb, rx_stats);
2977 }
2978 ret = AP_RX_DROP;
2979 goto out;
2980 }
2981 } else if (stype == IEEE80211_STYPE_NULLFUNC && sta == NULL &&
2982 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
2983
2984 if (local->hostapd) {
2985 prism2_rx_80211(local->apdev, skb, rx_stats,
2986 PRISM2_RX_NON_ASSOC);
2987#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2988 } else {
2989 /* At least Lucent f/w seems to send data::nullfunc
2990 * frames with no ToDS flag when the current AP returns
2991 * after being unavailable for some time. Speed up
2992 * re-association by informing the station about it not
2993 * being associated. */
2994 printk(KERN_DEBUG "%s: rejected received nullfunc "
2995 "frame without ToDS from not associated STA "
2996 MACSTR "\n",
2997 dev->name, MAC2STR(hdr->addr2));
2998 hostap_rx(dev, skb, rx_stats);
2999#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3000 }
3001 ret = AP_RX_EXIT;
3002 goto out;
3003 } else if (stype == IEEE80211_STYPE_NULLFUNC) {
3004 /* At least Lucent cards seem to send periodic nullfunc
3005 * frames with ToDS. Let these through to update SQ
3006 * stats and PS state. Nullfunc frames do not contain
3007 * any data and they will be dropped below. */
3008 } else {
3009 /* If BSSID (Addr3) is foreign, this frame is a normal
3010 * broadcast frame from an IBSS network. Drop it silently.
3011 * If BSSID is own, report the dropping of this frame. */
3012 if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
3013 printk(KERN_DEBUG "%s: dropped received packet from "
3014 MACSTR " with no ToDS flag (type=0x%02x, "
3015 "subtype=0x%02x)\n", dev->name,
3016 MAC2STR(hdr->addr2), type >> 2, stype >> 4);
3017 hostap_dump_rx_80211(dev->name, skb, rx_stats);
3018 }
3019 ret = AP_RX_DROP;
3020 goto out;
3021 }
3022
3023 if (sta) {
3024 hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
3025 type, stype);
3026
3027 sta->rx_packets++;
3028 sta->rx_bytes += skb->len;
3029 sta->last_rx = jiffies;
3030 }
3031
3032 if (local->ap->nullfunc_ack && stype == IEEE80211_STYPE_NULLFUNC &&
3033 fc & IEEE80211_FCTL_TODS) {
3034 if (local->hostapd) {
3035 prism2_rx_80211(local->apdev, skb, rx_stats,
3036 PRISM2_RX_NULLFUNC_ACK);
3037#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3038 } else {
3039 /* some STA f/w's seem to require control::ACK frame
3040 * for data::nullfunc, but Prism2 f/w 0.8.0 (at least
3041 * from Compaq) does not send this.. Try to generate
3042 * ACK for these frames from the host driver to make
3043 * power saving work with, e.g., Lucent WaveLAN f/w */
3044 hostap_rx(dev, skb, rx_stats);
3045#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3046 }
3047 ret = AP_RX_EXIT;
3048 goto out;
3049 }
3050
3051 out:
3052 if (sta)
3053 atomic_dec(&sta->users);
3054
3055 return ret;
3056}
3057
3058
3059/* Called only as a tasklet (software IRQ) */
3060int hostap_handle_sta_crypto(local_info_t *local,
3061 struct ieee80211_hdr *hdr,
3062 struct ieee80211_crypt_data **crypt,
3063 void **sta_ptr)
3064{
3065 struct sta_info *sta;
3066
3067 spin_lock(&local->ap->sta_table_lock);
3068 sta = ap_get_sta(local->ap, hdr->addr2);
3069 if (sta)
3070 atomic_inc(&sta->users);
3071 spin_unlock(&local->ap->sta_table_lock);
3072
3073 if (!sta)
3074 return -1;
3075
3076 if (sta->crypt) {
3077 *crypt = sta->crypt;
3078 *sta_ptr = sta;
3079 /* hostap_handle_sta_release() will be called to release STA
3080 * info */
3081 } else
3082 atomic_dec(&sta->users);
3083
3084 return 0;
3085}
3086
3087
3088/* Called only as a tasklet (software IRQ) */
3089int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr)
3090{
3091 struct sta_info *sta;
3092 int ret = 0;
3093
3094 spin_lock(&ap->sta_table_lock);
3095 sta = ap_get_sta(ap, sta_addr);
3096 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap)
3097 ret = 1;
3098 spin_unlock(&ap->sta_table_lock);
3099
3100 return ret;
3101}
3102
3103
3104/* Called only as a tasklet (software IRQ) */
3105int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr)
3106{
3107 struct sta_info *sta;
3108 int ret = 0;
3109
3110 spin_lock(&ap->sta_table_lock);
3111 sta = ap_get_sta(ap, sta_addr);
3112 if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap &&
3113 ((sta->flags & WLAN_STA_AUTHORIZED) ||
3114 ap->local->ieee_802_1x == 0))
3115 ret = 1;
3116 spin_unlock(&ap->sta_table_lock);
3117
3118 return ret;
3119}
3120
3121
3122/* Called only as a tasklet (software IRQ) */
3123int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
3124{
3125 struct sta_info *sta;
3126 int ret = 1;
3127
3128 if (!ap)
3129 return -1;
3130
3131 spin_lock(&ap->sta_table_lock);
3132 sta = ap_get_sta(ap, sta_addr);
3133 if (sta)
3134 ret = 0;
3135 spin_unlock(&ap->sta_table_lock);
3136
3137 if (ret == 1) {
3138 sta = ap_add_sta(ap, sta_addr);
3139 if (!sta)
3140 ret = -1;
3141 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
3142 sta->ap = 1;
3143 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
3144 /* No way of knowing which rates are supported since we did not
3145 * get supported rates element from beacon/assoc req. Assume
3146 * that remote end supports all 802.11b rates. */
3147 sta->supported_rates[0] = 0x82;
3148 sta->supported_rates[1] = 0x84;
3149 sta->supported_rates[2] = 0x0b;
3150 sta->supported_rates[3] = 0x16;
3151 sta->tx_supp_rates = WLAN_RATE_1M | WLAN_RATE_2M |
3152 WLAN_RATE_5M5 | WLAN_RATE_11M;
3153 sta->tx_rate = 110;
3154 sta->tx_max_rate = sta->tx_rate_idx = 3;
3155 }
3156
3157 return ret;
3158}
3159
3160
3161/* Called only as a tasklet (software IRQ) */
3162int hostap_update_rx_stats(struct ap_data *ap,
3163 struct ieee80211_hdr *hdr,
3164 struct hostap_80211_rx_status *rx_stats)
3165{
3166 struct sta_info *sta;
3167
3168 if (!ap)
3169 return -1;
3170
3171 spin_lock(&ap->sta_table_lock);
3172 sta = ap_get_sta(ap, hdr->addr2);
3173 if (sta) {
3174 sta->last_rx_silence = rx_stats->noise;
3175 sta->last_rx_signal = rx_stats->signal;
3176 sta->last_rx_rate = rx_stats->rate;
3177 sta->last_rx_updated = 7;
3178 if (rx_stats->rate == 10)
3179 sta->rx_count[0]++;
3180 else if (rx_stats->rate == 20)
3181 sta->rx_count[1]++;
3182 else if (rx_stats->rate == 55)
3183 sta->rx_count[2]++;
3184 else if (rx_stats->rate == 110)
3185 sta->rx_count[3]++;
3186 }
3187 spin_unlock(&ap->sta_table_lock);
3188
3189 return sta ? 0 : -1;
3190}
3191
3192
3193void hostap_update_rates(local_info_t *local)
3194{
3195 struct list_head *ptr;
3196 struct ap_data *ap = local->ap;
3197
3198 if (!ap)
3199 return;
3200
3201 spin_lock_bh(&ap->sta_table_lock);
3202 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) {
3203 struct sta_info *sta = (struct sta_info *) ptr;
3204 prism2_check_tx_rates(sta);
3205 }
3206 spin_unlock_bh(&ap->sta_table_lock);
3207}
3208
3209
3210static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
3211 struct ieee80211_crypt_data ***crypt)
3212{
3213 struct sta_info *sta;
3214
3215 spin_lock_bh(&ap->sta_table_lock);
3216 sta = ap_get_sta(ap, addr);
3217 if (sta)
3218 atomic_inc(&sta->users);
3219 spin_unlock_bh(&ap->sta_table_lock);
3220
3221 if (!sta && permanent)
3222 sta = ap_add_sta(ap, addr);
3223
3224 if (!sta)
3225 return NULL;
3226
3227 if (permanent)
3228 sta->flags |= WLAN_STA_PERM;
3229
3230 *crypt = &sta->crypt;
3231
3232 return sta;
3233}
3234
3235
3236void hostap_add_wds_links(local_info_t *local)
3237{
3238 struct ap_data *ap = local->ap;
3239 struct list_head *ptr;
3240
3241 spin_lock_bh(&ap->sta_table_lock);
3242 list_for_each(ptr, &ap->sta_list) {
3243 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
3244 if (sta->ap)
3245 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
3246 }
3247 spin_unlock_bh(&ap->sta_table_lock);
3248
3249 schedule_work(&local->ap->wds_oper_queue);
3250}
3251
3252
3253void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type)
3254{
3255 struct wds_oper_data *entry;
3256
3257 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
3258 if (!entry)
3259 return;
3260 memcpy(entry->addr, addr, ETH_ALEN);
3261 entry->type = type;
3262 spin_lock_bh(&local->lock);
3263 entry->next = local->ap->wds_oper_entries;
3264 local->ap->wds_oper_entries = entry;
3265 spin_unlock_bh(&local->lock);
3266
3267 schedule_work(&local->ap->wds_oper_queue);
3268}
3269
3270
3271EXPORT_SYMBOL(hostap_init_data);
3272EXPORT_SYMBOL(hostap_init_ap_proc);
3273EXPORT_SYMBOL(hostap_free_data);
3274EXPORT_SYMBOL(hostap_check_sta_fw_version);
3275EXPORT_SYMBOL(hostap_handle_sta_tx);
3276EXPORT_SYMBOL(hostap_handle_sta_release);
3277EXPORT_SYMBOL(hostap_handle_sta_tx_exc);
3278EXPORT_SYMBOL(hostap_update_sta_ps);
3279EXPORT_SYMBOL(hostap_handle_sta_rx);
3280EXPORT_SYMBOL(hostap_is_sta_assoc);
3281EXPORT_SYMBOL(hostap_is_sta_authorized);
3282EXPORT_SYMBOL(hostap_add_sta);
3283EXPORT_SYMBOL(hostap_update_rates);
3284EXPORT_SYMBOL(hostap_add_wds_links);
3285EXPORT_SYMBOL(hostap_wds_link_oper);
3286#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3287EXPORT_SYMBOL(hostap_deauth_all_stas);
3288#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..816a52bcea8f
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -0,0 +1,261 @@
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/* STA flags */
10#define WLAN_STA_AUTH BIT(0)
11#define WLAN_STA_ASSOC BIT(1)
12#define WLAN_STA_PS BIT(2)
13#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */
14#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */
15#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is
16 * controlling whether STA is authorized to
17 * send and receive non-IEEE 802.1X frames
18 */
19#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
20
21#define WLAN_RATE_1M BIT(0)
22#define WLAN_RATE_2M BIT(1)
23#define WLAN_RATE_5M5 BIT(2)
24#define WLAN_RATE_11M BIT(3)
25#define WLAN_RATE_COUNT 4
26
27/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8,
28 * but some pre-standard IEEE 802.11g products use longer elements. */
29#define WLAN_SUPP_RATES_MAX 32
30
31/* Try to increase TX rate after # successfully sent consecutive packets */
32#define WLAN_RATE_UPDATE_COUNT 50
33
34/* Decrease TX rate after # consecutive dropped packets */
35#define WLAN_RATE_DECREASE_THRESHOLD 2
36
37struct sta_info {
38 struct list_head list;
39 struct sta_info *hnext; /* next entry in hash table list */
40 atomic_t users; /* number of users (do not remove if > 0) */
41 struct proc_dir_entry *proc;
42
43 u8 addr[6];
44 u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
45 u32 flags;
46 u16 capability;
47 u16 listen_interval; /* or beacon_int for APs */
48 u8 supported_rates[WLAN_SUPP_RATES_MAX];
49
50 unsigned long last_auth;
51 unsigned long last_assoc;
52 unsigned long last_rx;
53 unsigned long last_tx;
54 unsigned long rx_packets, tx_packets;
55 unsigned long rx_bytes, tx_bytes;
56 struct sk_buff_head tx_buf;
57 /* FIX: timeout buffers with an expiry time somehow derived from
58 * listen_interval */
59
60 s8 last_rx_silence; /* Noise in dBm */
61 s8 last_rx_signal; /* Signal strength in dBm */
62 u8 last_rx_rate; /* TX rate in 0.1 Mbps */
63 u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */
64
65 u8 tx_supp_rates; /* bit field of supported TX rates */
66 u8 tx_rate; /* current TX rate (in 0.1 Mbps) */
67 u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */
68 u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */
69 u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */
70 u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate)
71 */
72 u32 tx_since_last_failure;
73 u32 tx_consecutive_exc;
74
75 struct ieee80211_crypt_data *crypt;
76
77 int ap; /* whether this station is an AP */
78
79 local_info_t *local;
80
81#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
82 union {
83 struct {
84 char *challenge; /* shared key authentication
85 * challenge */
86 } sta;
87 struct {
88 int ssid_len;
89 unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */
90 int channel;
91 unsigned long last_beacon; /* last RX beacon time */
92 } ap;
93 } u;
94
95 struct timer_list timer;
96 enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next;
97#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
98};
99
100
101#define MAX_STA_COUNT 1024
102
103/* Maximum number of AIDs to use for STAs; must be 2007 or lower
104 * (8802.11 limitation) */
105#define MAX_AID_TABLE_SIZE 128
106
107#define STA_HASH_SIZE 256
108#define STA_HASH(sta) (sta[5])
109
110
111/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC
112 * has passed since last received frame from the station, a nullfunc data
113 * frame is sent to the station. If this frame is not acknowledged and no other
114 * frames have been received, the station will be disassociated after
115 * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after
116 * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
117 * max inactivity timer. */
118#define AP_MAX_INACTIVITY_SEC (5 * 60)
119#define AP_DISASSOC_DELAY (HZ)
120#define AP_DEAUTH_DELAY (HZ)
121
122/* ap_policy: whether to accept frames to/from other APs/IBSS */
123typedef enum {
124 AP_OTHER_AP_SKIP_ALL = 0,
125 AP_OTHER_AP_SAME_SSID = 1,
126 AP_OTHER_AP_ALL = 2,
127 AP_OTHER_AP_EVEN_IBSS = 3
128} ap_policy_enum;
129
130#define PRISM2_AUTH_OPEN BIT(0)
131#define PRISM2_AUTH_SHARED_KEY BIT(1)
132
133
134/* MAC address-based restrictions */
135struct mac_entry {
136 struct list_head list;
137 u8 addr[6];
138};
139
140struct mac_restrictions {
141 enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy;
142 unsigned int entries;
143 struct list_head mac_list;
144 spinlock_t lock;
145};
146
147
148struct add_sta_proc_data {
149 u8 addr[ETH_ALEN];
150 struct add_sta_proc_data *next;
151};
152
153
154typedef enum { WDS_ADD, WDS_DEL } wds_oper_type;
155struct wds_oper_data {
156 wds_oper_type type;
157 u8 addr[ETH_ALEN];
158 struct wds_oper_data *next;
159};
160
161
162struct ap_data {
163 int initialized; /* whether ap_data has been initialized */
164 local_info_t *local;
165 int bridge_packets; /* send packet to associated STAs directly to the
166 * wireless media instead of higher layers in the
167 * kernel */
168 unsigned int bridged_unicast; /* number of unicast frames bridged on
169 * wireless media */
170 unsigned int bridged_multicast; /* number of non-unicast frames
171 * bridged on wireless media */
172 unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped
173 * because they were to an address that
174 * was not associated */
175 int nullfunc_ack; /* use workaround for nullfunc frame ACKs */
176
177 spinlock_t sta_table_lock;
178 int num_sta; /* number of entries in sta_list */
179 struct list_head sta_list; /* STA info list head */
180 struct sta_info *sta_hash[STA_HASH_SIZE];
181
182 struct proc_dir_entry *proc;
183
184 ap_policy_enum ap_policy;
185 unsigned int max_inactivity;
186 int autom_ap_wds;
187
188 struct mac_restrictions mac_restrictions; /* MAC-based auth */
189 int last_tx_rate;
190
191 struct work_struct add_sta_proc_queue;
192 struct add_sta_proc_data *add_sta_proc_entries;
193
194 struct work_struct wds_oper_queue;
195 struct wds_oper_data *wds_oper_entries;
196
197 u16 tx_callback_idx;
198
199#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
200 /* pointers to STA info; based on allocated AID or NULL if AID free
201 * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
202 * and so on
203 */
204 struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
205
206 u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll;
207
208 /* WEP operations for generating challenges to be used with shared key
209 * authentication */
210 struct ieee80211_crypto_ops *crypt;
211 void *crypt_priv;
212#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
213};
214
215
216void hostap_rx(struct net_device *dev, struct sk_buff *skb,
217 struct hostap_80211_rx_status *rx_stats);
218void hostap_init_data(local_info_t *local);
219void hostap_init_ap_proc(local_info_t *local);
220void hostap_free_data(struct ap_data *ap);
221void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver);
222
223typedef enum {
224 AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED,
225 AP_TX_CONTINUE_NOT_AUTHORIZED
226} ap_tx_ret;
227struct hostap_tx_data {
228 struct sk_buff *skb;
229 int host_encrypt;
230 struct ieee80211_crypt_data *crypt;
231 void *sta_ptr;
232};
233ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
234void hostap_handle_sta_release(void *ptr);
235void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
236int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
237typedef enum {
238 AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
239} ap_rx_ret;
240ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
241 struct sk_buff *skb,
242 struct hostap_80211_rx_status *rx_stats,
243 int wds);
244int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
245 struct ieee80211_crypt_data **crypt,
246 void **sta_ptr);
247int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
248int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
249int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
250int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
251 struct hostap_80211_rx_status *rx_stats);
252void hostap_update_rates(local_info_t *local);
253void hostap_add_wds_links(local_info_t *local);
254void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type);
255
256#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
257void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
258 int resend);
259#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
260
261#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..6f4fa9dc308f
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -0,0 +1,435 @@
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/* IEEE 802.11 defines */
11
12/* Information Element IDs */
13#define WLAN_EID_SSID 0
14#define WLAN_EID_SUPP_RATES 1
15#define WLAN_EID_FH_PARAMS 2
16#define WLAN_EID_DS_PARAMS 3
17#define WLAN_EID_CF_PARAMS 4
18#define WLAN_EID_TIM 5
19#define WLAN_EID_IBSS_PARAMS 6
20#define WLAN_EID_CHALLENGE 16
21#define WLAN_EID_RSN 48
22#define WLAN_EID_GENERIC 221
23
24
25/* HFA384X Configuration RIDs */
26#define HFA384X_RID_CNFPORTTYPE 0xFC00
27#define HFA384X_RID_CNFOWNMACADDR 0xFC01
28#define HFA384X_RID_CNFDESIREDSSID 0xFC02
29#define HFA384X_RID_CNFOWNCHANNEL 0xFC03
30#define HFA384X_RID_CNFOWNSSID 0xFC04
31#define HFA384X_RID_CNFOWNATIMWINDOW 0xFC05
32#define HFA384X_RID_CNFSYSTEMSCALE 0xFC06
33#define HFA384X_RID_CNFMAXDATALEN 0xFC07
34#define HFA384X_RID_CNFWDSADDRESS 0xFC08
35#define HFA384X_RID_CNFPMENABLED 0xFC09
36#define HFA384X_RID_CNFPMEPS 0xFC0A
37#define HFA384X_RID_CNFMULTICASTRECEIVE 0xFC0B
38#define HFA384X_RID_CNFMAXSLEEPDURATION 0xFC0C
39#define HFA384X_RID_CNFPMHOLDOVERDURATION 0xFC0D
40#define HFA384X_RID_CNFOWNNAME 0xFC0E
41#define HFA384X_RID_CNFOWNDTIMPERIOD 0xFC10
42#define HFA384X_RID_CNFWDSADDRESS1 0xFC11 /* AP f/w only */
43#define HFA384X_RID_CNFWDSADDRESS2 0xFC12 /* AP f/w only */
44#define HFA384X_RID_CNFWDSADDRESS3 0xFC13 /* AP f/w only */
45#define HFA384X_RID_CNFWDSADDRESS4 0xFC14 /* AP f/w only */
46#define HFA384X_RID_CNFWDSADDRESS5 0xFC15 /* AP f/w only */
47#define HFA384X_RID_CNFWDSADDRESS6 0xFC16 /* AP f/w only */
48#define HFA384X_RID_CNFMULTICASTPMBUFFERING 0xFC17 /* AP f/w only */
49#define HFA384X_RID_UNKNOWN1 0xFC20
50#define HFA384X_RID_UNKNOWN2 0xFC21
51#define HFA384X_RID_CNFWEPDEFAULTKEYID 0xFC23
52#define HFA384X_RID_CNFDEFAULTKEY0 0xFC24
53#define HFA384X_RID_CNFDEFAULTKEY1 0xFC25
54#define HFA384X_RID_CNFDEFAULTKEY2 0xFC26
55#define HFA384X_RID_CNFDEFAULTKEY3 0xFC27
56#define HFA384X_RID_CNFWEPFLAGS 0xFC28
57#define HFA384X_RID_CNFWEPKEYMAPPINGTABLE 0xFC29
58#define HFA384X_RID_CNFAUTHENTICATION 0xFC2A
59#define HFA384X_RID_CNFMAXASSOCSTA 0xFC2B /* AP f/w only */
60#define HFA384X_RID_CNFTXCONTROL 0xFC2C
61#define HFA384X_RID_CNFROAMINGMODE 0xFC2D
62#define HFA384X_RID_CNFHOSTAUTHENTICATION 0xFC2E /* AP f/w only */
63#define HFA384X_RID_CNFRCVCRCERROR 0xFC30
64#define HFA384X_RID_CNFMMLIFE 0xFC31
65#define HFA384X_RID_CNFALTRETRYCOUNT 0xFC32
66#define HFA384X_RID_CNFBEACONINT 0xFC33
67#define HFA384X_RID_CNFAPPCFINFO 0xFC34 /* AP f/w only */
68#define HFA384X_RID_CNFSTAPCFINFO 0xFC35
69#define HFA384X_RID_CNFPRIORITYQUSAGE 0xFC37
70#define HFA384X_RID_CNFTIMCTRL 0xFC40
71#define HFA384X_RID_UNKNOWN3 0xFC41 /* added in STA f/w 0.7.x */
72#define HFA384X_RID_CNFTHIRTY2TALLY 0xFC42 /* added in STA f/w 0.8.0 */
73#define HFA384X_RID_CNFENHSECURITY 0xFC43 /* AP f/w or STA f/w >= 1.6.3 */
74#define HFA384X_RID_CNFDBMADJUST 0xFC46 /* added in STA f/w 1.3.1 */
75#define HFA384X_RID_GENERICELEMENT 0xFC48 /* added in STA f/w 1.7.0;
76 * write only */
77#define HFA384X_RID_PROPAGATIONDELAY 0xFC49 /* added in STA f/w 1.7.6 */
78#define HFA384X_RID_GROUPADDRESSES 0xFC80
79#define HFA384X_RID_CREATEIBSS 0xFC81
80#define HFA384X_RID_FRAGMENTATIONTHRESHOLD 0xFC82
81#define HFA384X_RID_RTSTHRESHOLD 0xFC83
82#define HFA384X_RID_TXRATECONTROL 0xFC84
83#define HFA384X_RID_PROMISCUOUSMODE 0xFC85
84#define HFA384X_RID_FRAGMENTATIONTHRESHOLD0 0xFC90 /* AP f/w only */
85#define HFA384X_RID_FRAGMENTATIONTHRESHOLD1 0xFC91 /* AP f/w only */
86#define HFA384X_RID_FRAGMENTATIONTHRESHOLD2 0xFC92 /* AP f/w only */
87#define HFA384X_RID_FRAGMENTATIONTHRESHOLD3 0xFC93 /* AP f/w only */
88#define HFA384X_RID_FRAGMENTATIONTHRESHOLD4 0xFC94 /* AP f/w only */
89#define HFA384X_RID_FRAGMENTATIONTHRESHOLD5 0xFC95 /* AP f/w only */
90#define HFA384X_RID_FRAGMENTATIONTHRESHOLD6 0xFC96 /* AP f/w only */
91#define HFA384X_RID_RTSTHRESHOLD0 0xFC97 /* AP f/w only */
92#define HFA384X_RID_RTSTHRESHOLD1 0xFC98 /* AP f/w only */
93#define HFA384X_RID_RTSTHRESHOLD2 0xFC99 /* AP f/w only */
94#define HFA384X_RID_RTSTHRESHOLD3 0xFC9A /* AP f/w only */
95#define HFA384X_RID_RTSTHRESHOLD4 0xFC9B /* AP f/w only */
96#define HFA384X_RID_RTSTHRESHOLD5 0xFC9C /* AP f/w only */
97#define HFA384X_RID_RTSTHRESHOLD6 0xFC9D /* AP f/w only */
98#define HFA384X_RID_TXRATECONTROL0 0xFC9E /* AP f/w only */
99#define HFA384X_RID_TXRATECONTROL1 0xFC9F /* AP f/w only */
100#define HFA384X_RID_TXRATECONTROL2 0xFCA0 /* AP f/w only */
101#define HFA384X_RID_TXRATECONTROL3 0xFCA1 /* AP f/w only */
102#define HFA384X_RID_TXRATECONTROL4 0xFCA2 /* AP f/w only */
103#define HFA384X_RID_TXRATECONTROL5 0xFCA3 /* AP f/w only */
104#define HFA384X_RID_TXRATECONTROL6 0xFCA4 /* AP f/w only */
105#define HFA384X_RID_CNFSHORTPREAMBLE 0xFCB0
106#define HFA384X_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1
107#define HFA384X_RID_CNFAUTHENTICATIONRSPTO 0xFCB2
108#define HFA384X_RID_CNFBASICRATES 0xFCB3
109#define HFA384X_RID_CNFSUPPORTEDRATES 0xFCB4
110#define HFA384X_RID_CNFFALLBACKCTRL 0xFCB5 /* added in STA f/w 1.3.1 */
111#define HFA384X_RID_WEPKEYDISABLE 0xFCB6 /* added in STA f/w 1.3.1 */
112#define HFA384X_RID_WEPKEYMAPINDEX 0xFCB7 /* ? */
113#define HFA384X_RID_BROADCASTKEYID 0xFCB8 /* ? */
114#define HFA384X_RID_ENTSECFLAGEYID 0xFCB9 /* ? */
115#define HFA384X_RID_CNFPASSIVESCANCTRL 0xFCBA /* added in STA f/w 1.5.0 */
116#define HFA384X_RID_SSNHANDLINGMODE 0xFCBB /* added in STA f/w 1.7.0 */
117#define HFA384X_RID_MDCCONTROL 0xFCBC /* added in STA f/w 1.7.0 */
118#define HFA384X_RID_MDCCOUNTRY 0xFCBD /* added in STA f/w 1.7.0 */
119#define HFA384X_RID_TXPOWERMAX 0xFCBE /* added in STA f/w 1.7.0 */
120#define HFA384X_RID_CNFLFOENABLED 0xFCBF /* added in STA f/w 1.6.3 */
121#define HFA384X_RID_CAPINFO 0xFCC0 /* added in STA f/w 1.7.0 */
122#define HFA384X_RID_LISTENINTERVAL 0xFCC1 /* added in STA f/w 1.7.0 */
123#define HFA384X_RID_SW_ANT_DIV 0xFCC2 /* added in STA f/w 1.7.0; Prism3 */
124#define HFA384X_RID_LED_CTRL 0xFCC4 /* added in STA f/w 1.7.6 */
125#define HFA384X_RID_HFODELAY 0xFCC5 /* added in STA f/w 1.7.6 */
126#define HFA384X_RID_DISALLOWEDBSSID 0xFCC6 /* added in STA f/w 1.8.0 */
127#define HFA384X_RID_TICKTIME 0xFCE0
128#define HFA384X_RID_SCANREQUEST 0xFCE1
129#define HFA384X_RID_JOINREQUEST 0xFCE2
130#define HFA384X_RID_AUTHENTICATESTATION 0xFCE3 /* AP f/w only */
131#define HFA384X_RID_CHANNELINFOREQUEST 0xFCE4 /* AP f/w only */
132#define HFA384X_RID_HOSTSCAN 0xFCE5 /* added in STA f/w 1.3.1 */
133
134/* HFA384X Information RIDs */
135#define HFA384X_RID_MAXLOADTIME 0xFD00
136#define HFA384X_RID_DOWNLOADBUFFER 0xFD01
137#define HFA384X_RID_PRIID 0xFD02
138#define HFA384X_RID_PRISUPRANGE 0xFD03
139#define HFA384X_RID_CFIACTRANGES 0xFD04
140#define HFA384X_RID_NICSERNUM 0xFD0A
141#define HFA384X_RID_NICID 0xFD0B
142#define HFA384X_RID_MFISUPRANGE 0xFD0C
143#define HFA384X_RID_CFISUPRANGE 0xFD0D
144#define HFA384X_RID_CHANNELLIST 0xFD10
145#define HFA384X_RID_REGULATORYDOMAINS 0xFD11
146#define HFA384X_RID_TEMPTYPE 0xFD12
147#define HFA384X_RID_CIS 0xFD13
148#define HFA384X_RID_STAID 0xFD20
149#define HFA384X_RID_STASUPRANGE 0xFD21
150#define HFA384X_RID_MFIACTRANGES 0xFD22
151#define HFA384X_RID_CFIACTRANGES2 0xFD23
152#define HFA384X_RID_PRODUCTNAME 0xFD24 /* added in STA f/w 1.3.1;
153 * only Prism2.5(?) */
154#define HFA384X_RID_PORTSTATUS 0xFD40
155#define HFA384X_RID_CURRENTSSID 0xFD41
156#define HFA384X_RID_CURRENTBSSID 0xFD42
157#define HFA384X_RID_COMMSQUALITY 0xFD43
158#define HFA384X_RID_CURRENTTXRATE 0xFD44
159#define HFA384X_RID_CURRENTBEACONINTERVAL 0xFD45
160#define HFA384X_RID_CURRENTSCALETHRESHOLDS 0xFD46
161#define HFA384X_RID_PROTOCOLRSPTIME 0xFD47
162#define HFA384X_RID_SHORTRETRYLIMIT 0xFD48
163#define HFA384X_RID_LONGRETRYLIMIT 0xFD49
164#define HFA384X_RID_MAXTRANSMITLIFETIME 0xFD4A
165#define HFA384X_RID_MAXRECEIVELIFETIME 0xFD4B
166#define HFA384X_RID_CFPOLLABLE 0xFD4C
167#define HFA384X_RID_AUTHENTICATIONALGORITHMS 0xFD4D
168#define HFA384X_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F
169#define HFA384X_RID_DBMCOMMSQUALITY 0xFD51 /* added in STA f/w 1.3.1 */
170#define HFA384X_RID_CURRENTTXRATE1 0xFD80 /* AP f/w only */
171#define HFA384X_RID_CURRENTTXRATE2 0xFD81 /* AP f/w only */
172#define HFA384X_RID_CURRENTTXRATE3 0xFD82 /* AP f/w only */
173#define HFA384X_RID_CURRENTTXRATE4 0xFD83 /* AP f/w only */
174#define HFA384X_RID_CURRENTTXRATE5 0xFD84 /* AP f/w only */
175#define HFA384X_RID_CURRENTTXRATE6 0xFD85 /* AP f/w only */
176#define HFA384X_RID_OWNMACADDR 0xFD86 /* AP f/w only */
177#define HFA384X_RID_SCANRESULTSTABLE 0xFD88 /* added in STA f/w 0.8.3 */
178#define HFA384X_RID_HOSTSCANRESULTS 0xFD89 /* added in STA f/w 1.3.1 */
179#define HFA384X_RID_AUTHENTICATIONUSED 0xFD8A /* added in STA f/w 1.3.4 */
180#define HFA384X_RID_CNFFAASWITCHCTRL 0xFD8B /* added in STA f/w 1.6.3 */
181#define HFA384X_RID_ASSOCIATIONFAILURE 0xFD8D /* added in STA f/w 1.8.0 */
182#define HFA384X_RID_PHYTYPE 0xFDC0
183#define HFA384X_RID_CURRENTCHANNEL 0xFDC1
184#define HFA384X_RID_CURRENTPOWERSTATE 0xFDC2
185#define HFA384X_RID_CCAMODE 0xFDC3
186#define HFA384X_RID_SUPPORTEDDATARATES 0xFDC6
187#define HFA384X_RID_LFO_VOLT_REG_TEST_RES 0xFDC7 /* added in STA f/w 1.7.1 */
188#define HFA384X_RID_BUILDSEQ 0xFFFE
189#define HFA384X_RID_FWID 0xFFFF
190
191
192struct hfa384x_comp_ident
193{
194 u16 id;
195 u16 variant;
196 u16 major;
197 u16 minor;
198} __attribute__ ((packed));
199
200#define HFA384X_COMP_ID_PRI 0x15
201#define HFA384X_COMP_ID_STA 0x1f
202#define HFA384X_COMP_ID_FW_AP 0x14b
203
204struct hfa384x_sup_range
205{
206 u16 role;
207 u16 id;
208 u16 variant;
209 u16 bottom;
210 u16 top;
211} __attribute__ ((packed));
212
213
214struct hfa384x_build_id
215{
216 u16 pri_seq;
217 u16 sec_seq;
218} __attribute__ ((packed));
219
220/* FD01 - Download Buffer */
221struct hfa384x_rid_download_buffer
222{
223 u16 page;
224 u16 offset;
225 u16 length;
226} __attribute__ ((packed));
227
228/* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */
229struct hfa384x_comms_quality {
230 u16 comm_qual; /* 0 .. 92 */
231 u16 signal_level; /* 27 .. 154 */
232 u16 noise_level; /* 27 .. 154 */
233} __attribute__ ((packed));
234
235
236/* netdevice private ioctls (used, e.g., with iwpriv from user space) */
237
238/* New wireless extensions API - SET/GET convention (even ioctl numbers are
239 * root only)
240 */
241#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
242#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1)
243#define PRISM2_IOCTL_WRITEMIF (SIOCIWFIRSTPRIV + 2)
244#define PRISM2_IOCTL_READMIF (SIOCIWFIRSTPRIV + 3)
245#define PRISM2_IOCTL_MONITOR (SIOCIWFIRSTPRIV + 4)
246#define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6)
247#define PRISM2_IOCTL_INQUIRE (SIOCIWFIRSTPRIV + 8)
248#define PRISM2_IOCTL_WDS_ADD (SIOCIWFIRSTPRIV + 10)
249#define PRISM2_IOCTL_WDS_DEL (SIOCIWFIRSTPRIV + 12)
250#define PRISM2_IOCTL_SET_RID_WORD (SIOCIWFIRSTPRIV + 14)
251#define PRISM2_IOCTL_MACCMD (SIOCIWFIRSTPRIV + 16)
252#define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18)
253#define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20)
254#define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22)
255
256/* following are not in SIOCGIWPRIV list; check permission in the driver code
257 */
258#define PRISM2_IOCTL_DOWNLOAD (SIOCDEVPRIVATE + 13)
259#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14)
260
261
262/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */
263enum {
264 /* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */
265 PRISM2_PARAM_TXRATECTRL = 2,
266 PRISM2_PARAM_BEACON_INT = 3,
267 PRISM2_PARAM_PSEUDO_IBSS = 4,
268 PRISM2_PARAM_ALC = 5,
269 /* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */
270 PRISM2_PARAM_DUMP = 7,
271 PRISM2_PARAM_OTHER_AP_POLICY = 8,
272 PRISM2_PARAM_AP_MAX_INACTIVITY = 9,
273 PRISM2_PARAM_AP_BRIDGE_PACKETS = 10,
274 PRISM2_PARAM_DTIM_PERIOD = 11,
275 PRISM2_PARAM_AP_NULLFUNC_ACK = 12,
276 PRISM2_PARAM_MAX_WDS = 13,
277 PRISM2_PARAM_AP_AUTOM_AP_WDS = 14,
278 PRISM2_PARAM_AP_AUTH_ALGS = 15,
279 PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16,
280 PRISM2_PARAM_HOST_ENCRYPT = 17,
281 PRISM2_PARAM_HOST_DECRYPT = 18,
282 /* PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19, REMOVED 2005-08-14 */
283 /* PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20, REMOVED 2005-08-14 */
284 PRISM2_PARAM_HOST_ROAMING = 21,
285 PRISM2_PARAM_BCRX_STA_KEY = 22,
286 PRISM2_PARAM_IEEE_802_1X = 23,
287 PRISM2_PARAM_ANTSEL_TX = 24,
288 PRISM2_PARAM_ANTSEL_RX = 25,
289 PRISM2_PARAM_MONITOR_TYPE = 26,
290 PRISM2_PARAM_WDS_TYPE = 27,
291 PRISM2_PARAM_HOSTSCAN = 28,
292 PRISM2_PARAM_AP_SCAN = 29,
293 PRISM2_PARAM_ENH_SEC = 30,
294 PRISM2_PARAM_IO_DEBUG = 31,
295 PRISM2_PARAM_BASIC_RATES = 32,
296 PRISM2_PARAM_OPER_RATES = 33,
297 PRISM2_PARAM_HOSTAPD = 34,
298 PRISM2_PARAM_HOSTAPD_STA = 35,
299 PRISM2_PARAM_WPA = 36,
300 PRISM2_PARAM_PRIVACY_INVOKED = 37,
301 PRISM2_PARAM_TKIP_COUNTERMEASURES = 38,
302 PRISM2_PARAM_DROP_UNENCRYPTED = 39,
303 PRISM2_PARAM_SCAN_CHANNEL_MASK = 40,
304};
305
306enum { HOSTAP_ANTSEL_DO_NOT_TOUCH = 0, HOSTAP_ANTSEL_DIVERSITY = 1,
307 HOSTAP_ANTSEL_LOW = 2, HOSTAP_ANTSEL_HIGH = 3 };
308
309
310/* PRISM2_IOCTL_MACCMD ioctl() subcommands: */
311enum { AP_MAC_CMD_POLICY_OPEN = 0, AP_MAC_CMD_POLICY_ALLOW = 1,
312 AP_MAC_CMD_POLICY_DENY = 2, AP_MAC_CMD_FLUSH = 3,
313 AP_MAC_CMD_KICKALL = 4 };
314
315
316/* PRISM2_IOCTL_DOWNLOAD ioctl() dl_cmd: */
317enum {
318 PRISM2_DOWNLOAD_VOLATILE = 1 /* RAM */,
319 /* Note! Old versions of prism2_srec have a fatal error in CRC-16
320 * calculation, which will corrupt all non-volatile downloads.
321 * PRISM2_DOWNLOAD_NON_VOLATILE used to be 2, but it is now 3 to
322 * prevent use of old versions of prism2_srec for non-volatile
323 * download. */
324 PRISM2_DOWNLOAD_NON_VOLATILE = 3 /* FLASH */,
325 PRISM2_DOWNLOAD_VOLATILE_GENESIS = 4 /* RAM in Genesis mode */,
326 /* Persistent versions of volatile download commands (keep firmware
327 * data in memory and automatically re-download after hw_reset */
328 PRISM2_DOWNLOAD_VOLATILE_PERSISTENT = 5,
329 PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT = 6,
330};
331
332struct prism2_download_param {
333 u32 dl_cmd;
334 u32 start_addr;
335 u32 num_areas;
336 struct prism2_download_area {
337 u32 addr; /* wlan card address */
338 u32 len;
339 void __user *ptr; /* pointer to data in user space */
340 } data[0];
341};
342
343#define PRISM2_MAX_DOWNLOAD_AREA_LEN 131072
344#define PRISM2_MAX_DOWNLOAD_LEN 262144
345
346
347/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */
348enum {
349 PRISM2_HOSTAPD_FLUSH = 1,
350 PRISM2_HOSTAPD_ADD_STA = 2,
351 PRISM2_HOSTAPD_REMOVE_STA = 3,
352 PRISM2_HOSTAPD_GET_INFO_STA = 4,
353 /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */
354 PRISM2_SET_ENCRYPTION = 6,
355 PRISM2_GET_ENCRYPTION = 7,
356 PRISM2_HOSTAPD_SET_FLAGS_STA = 8,
357 PRISM2_HOSTAPD_GET_RID = 9,
358 PRISM2_HOSTAPD_SET_RID = 10,
359 PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11,
360 PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
361 PRISM2_HOSTAPD_MLME = 13,
362 PRISM2_HOSTAPD_SCAN_REQ = 14,
363 PRISM2_HOSTAPD_STA_CLEAR_STATS = 15,
364};
365
366#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
367#define PRISM2_HOSTAPD_RID_HDR_LEN \
368((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data))
369#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
370((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
371
372/* Maximum length for algorithm names (-1 for nul termination) used in ioctl()
373 */
374#define HOSTAP_CRYPT_ALG_NAME_LEN 16
375
376
377struct prism2_hostapd_param {
378 u32 cmd;
379 u8 sta_addr[ETH_ALEN];
380 union {
381 struct {
382 u16 aid;
383 u16 capability;
384 u8 tx_supp_rates;
385 } add_sta;
386 struct {
387 u32 inactive_sec;
388 } get_info_sta;
389 struct {
390 u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
391 u32 flags;
392 u32 err;
393 u8 idx;
394 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
395 u16 key_len;
396 u8 key[0];
397 } crypt;
398 struct {
399 u32 flags_and;
400 u32 flags_or;
401 } set_flags_sta;
402 struct {
403 u16 rid;
404 u16 len;
405 u8 data[0];
406 } rid;
407 struct {
408 u8 len;
409 u8 data[0];
410 } generic_elem;
411 struct {
412#define MLME_STA_DEAUTH 0
413#define MLME_STA_DISASSOC 1
414 u16 cmd;
415 u16 reason_code;
416 } mlme;
417 struct {
418 u8 ssid_len;
419 u8 ssid[32];
420 } scan_req;
421 } u;
422};
423
424#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0)
425#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1)
426
427#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
428#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
429#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
430#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
431#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
432#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
433
434
435#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..7ed3425d08c1
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -0,0 +1,55 @@
1#ifndef HOSTAP_CONFIG_H
2#define HOSTAP_CONFIG_H
3
4#define PRISM2_VERSION "0.4.4-kernel"
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/* Include code for downloading firmware images into volatile RAM. */
17#define PRISM2_DOWNLOAD_SUPPORT
18
19/* Allow kernel configuration to enable download support. */
20#if !defined(PRISM2_DOWNLOAD_SUPPORT) && defined(CONFIG_HOSTAP_FIRMWARE)
21#define PRISM2_DOWNLOAD_SUPPORT
22#endif
23
24#ifdef PRISM2_DOWNLOAD_SUPPORT
25/* Allow writing firmware images into flash, i.e., to non-volatile storage.
26 * Before you enable this option, you should make absolutely sure that you are
27 * using prism2_srec utility that comes with THIS version of the driver!
28 * In addition, please note that it is possible to kill your card with
29 * non-volatile download if you are using incorrect image. This feature has not
30 * been fully tested, so please be careful with it. */
31/* #define PRISM2_NON_VOLATILE_DOWNLOAD */
32#endif /* PRISM2_DOWNLOAD_SUPPORT */
33
34/* Save low-level I/O for debugging. This should not be enabled in normal use.
35 */
36/* #define PRISM2_IO_DEBUG */
37
38/* Following defines can be used to remove unneeded parts of the driver, e.g.,
39 * to limit the size of the kernel module. Definitions can be added here in
40 * hostap_config.h or they can be added to make command with EXTRA_CFLAGS,
41 * e.g.,
42 * 'make pccard EXTRA_CFLAGS="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"'
43 */
44
45/* Do not include debug messages into the driver */
46/* #define PRISM2_NO_DEBUG */
47
48/* Do not include /proc/net/prism2/wlan#/{registers,debug} */
49/* #define PRISM2_NO_PROCFS_DEBUG */
50
51/* Do not include station functionality (i.e., allow only Master (Host AP) mode
52 */
53/* #define PRISM2_NO_STATION_MODES */
54
55#endif /* HOSTAP_CONFIG_H */
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
new file mode 100644
index 000000000000..faa83badf0a1
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -0,0 +1,1030 @@
1#define PRISM2_PCCARD
2
3#include <linux/config.h>
4#include <linux/module.h>
5#include <linux/init.h>
6#include <linux/if.h>
7#include <linux/wait.h>
8#include <linux/timer.h>
9#include <linux/skbuff.h>
10#include <linux/netdevice.h>
11#include <linux/workqueue.h>
12#include <linux/wireless.h>
13#include <net/iw_handler.h>
14
15#include <pcmcia/cs_types.h>
16#include <pcmcia/cs.h>
17#include <pcmcia/cistpl.h>
18#include <pcmcia/cisreg.h>
19#include <pcmcia/ds.h>
20
21#include <asm/io.h>
22
23#include "hostap_wlan.h"
24
25
26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
27static dev_info_t dev_info = "hostap_cs";
28static dev_link_t *dev_list = NULL;
29
30MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
32 "cards (PC Card).");
33MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)");
34MODULE_LICENSE("GPL");
35MODULE_VERSION(PRISM2_VERSION);
36
37
38static int ignore_cis_vcc;
39module_param(ignore_cis_vcc, int, 0444);
40MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
41
42
43/* struct local_info::hw_priv */
44struct hostap_cs_priv {
45 dev_node_t node;
46 dev_link_t *link;
47 int sandisk_connectplus;
48};
49
50
51#ifdef PRISM2_IO_DEBUG
52
53static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
54{
55 struct hostap_interface *iface;
56 local_info_t *local;
57 unsigned long flags;
58
59 iface = netdev_priv(dev);
60 local = iface->local;
61 spin_lock_irqsave(&local->lock, flags);
62 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
63 outb(v, dev->base_addr + 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 spin_lock_irqsave(&local->lock, flags);
77 v = inb(dev->base_addr + a);
78 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
79 spin_unlock_irqrestore(&local->lock, flags);
80 return v;
81}
82
83static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
84{
85 struct hostap_interface *iface;
86 local_info_t *local;
87 unsigned long flags;
88
89 iface = netdev_priv(dev);
90 local = iface->local;
91 spin_lock_irqsave(&local->lock, flags);
92 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
93 outw(v, dev->base_addr + a);
94 spin_unlock_irqrestore(&local->lock, flags);
95}
96
97static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
98{
99 struct hostap_interface *iface;
100 local_info_t *local;
101 unsigned long flags;
102 u16 v;
103
104 iface = netdev_priv(dev);
105 local = iface->local;
106 spin_lock_irqsave(&local->lock, flags);
107 v = inw(dev->base_addr + a);
108 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
109 spin_unlock_irqrestore(&local->lock, flags);
110 return v;
111}
112
113static inline void hfa384x_outsw_debug(struct net_device *dev, int a,
114 u8 *buf, int wc)
115{
116 struct hostap_interface *iface;
117 local_info_t *local;
118 unsigned long flags;
119
120 iface = netdev_priv(dev);
121 local = iface->local;
122 spin_lock_irqsave(&local->lock, flags);
123 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
124 outsw(dev->base_addr + a, buf, wc);
125 spin_unlock_irqrestore(&local->lock, flags);
126}
127
128static inline void hfa384x_insw_debug(struct net_device *dev, int a,
129 u8 *buf, int wc)
130{
131 struct hostap_interface *iface;
132 local_info_t *local;
133 unsigned long flags;
134
135 iface = netdev_priv(dev);
136 local = iface->local;
137 spin_lock_irqsave(&local->lock, flags);
138 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
139 insw(dev->base_addr + a, buf, wc);
140 spin_unlock_irqrestore(&local->lock, flags);
141}
142
143#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
144#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
145#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
146#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
147#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
148#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
149
150#else /* PRISM2_IO_DEBUG */
151
152#define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
153#define HFA384X_INB(a) inb(dev->base_addr + (a))
154#define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
155#define HFA384X_INW(a) inw(dev->base_addr + (a))
156#define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
157#define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
158
159#endif /* PRISM2_IO_DEBUG */
160
161
162static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
163 int len)
164{
165 u16 d_off;
166 u16 *pos;
167
168 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
169 pos = (u16 *) buf;
170
171 if (len / 2)
172 HFA384X_INSW(d_off, buf, len / 2);
173 pos += len / 2;
174
175 if (len & 1)
176 *((char *) pos) = HFA384X_INB(d_off);
177
178 return 0;
179}
180
181
182static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
183{
184 u16 d_off;
185 u16 *pos;
186
187 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
188 pos = (u16 *) buf;
189
190 if (len / 2)
191 HFA384X_OUTSW(d_off, buf, len / 2);
192 pos += len / 2;
193
194 if (len & 1)
195 HFA384X_OUTB(*((char *) pos), d_off);
196
197 return 0;
198}
199
200
201/* FIX: This might change at some point.. */
202#include "hostap_hw.c"
203
204
205
206static void prism2_detach(dev_link_t *link);
207static void prism2_release(u_long arg);
208static int prism2_event(event_t event, int priority,
209 event_callback_args_t *args);
210
211
212static int prism2_pccard_card_present(local_info_t *local)
213{
214 struct hostap_cs_priv *hw_priv = local->hw_priv;
215 if (hw_priv != NULL && hw_priv->link != NULL &&
216 ((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) ==
217 (DEV_PRESENT | DEV_CONFIG)))
218 return 1;
219 return 0;
220}
221
222
223/*
224 * SanDisk CompactFlash WLAN Flashcard - Product Manual v1.0
225 * Document No. 20-10-00058, January 2004
226 * http://www.sandisk.com/pdf/industrial/ProdManualCFWLANv1.0.pdf
227 */
228#define SANDISK_WLAN_ACTIVATION_OFF 0x40
229#define SANDISK_HCR_OFF 0x42
230
231
232static void sandisk_set_iobase(local_info_t *local)
233{
234 int res;
235 conf_reg_t reg;
236 struct hostap_cs_priv *hw_priv = local->hw_priv;
237
238 reg.Function = 0;
239 reg.Action = CS_WRITE;
240 reg.Offset = 0x10; /* 0x3f0 IO base 1 */
241 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
242 res = pcmcia_access_configuration_register(hw_priv->link->handle,
243 &reg);
244 if (res != CS_SUCCESS) {
245 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
246 " res=%d\n", res);
247 }
248 udelay(10);
249
250 reg.Function = 0;
251 reg.Action = CS_WRITE;
252 reg.Offset = 0x12; /* 0x3f2 IO base 2 */
253 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
254 res = pcmcia_access_configuration_register(hw_priv->link->handle,
255 &reg);
256 if (res != CS_SUCCESS) {
257 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
258 " res=%d\n", res);
259 }
260}
261
262
263static void sandisk_write_hcr(local_info_t *local, int hcr)
264{
265 struct net_device *dev = local->dev;
266 int i;
267
268 HFA384X_OUTB(0x80, SANDISK_WLAN_ACTIVATION_OFF);
269 udelay(50);
270 for (i = 0; i < 10; i++) {
271 HFA384X_OUTB(hcr, SANDISK_HCR_OFF);
272 }
273 udelay(55);
274 HFA384X_OUTB(0x45, SANDISK_WLAN_ACTIVATION_OFF);
275}
276
277
278static int sandisk_enable_wireless(struct net_device *dev)
279{
280 int res, ret = 0;
281 conf_reg_t reg;
282 struct hostap_interface *iface = dev->priv;
283 local_info_t *local = iface->local;
284 tuple_t tuple;
285 cisparse_t *parse = NULL;
286 u_char buf[64];
287 struct hostap_cs_priv *hw_priv = local->hw_priv;
288
289 if (hw_priv->link->io.NumPorts1 < 0x42) {
290 /* Not enough ports to be SanDisk multi-function card */
291 ret = -ENODEV;
292 goto done;
293 }
294
295 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
296 if (parse == NULL) {
297 ret = -ENOMEM;
298 goto done;
299 }
300
301 tuple.DesiredTuple = CISTPL_MANFID;
302 tuple.Attributes = TUPLE_RETURN_COMMON;
303 tuple.TupleData = buf;
304 tuple.TupleDataMax = sizeof(buf);
305 tuple.TupleOffset = 0;
306 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
307 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
308 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
309 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
310 /* No SanDisk manfid found */
311 ret = -ENODEV;
312 goto done;
313 }
314
315 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
316 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) ||
317 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) ||
318 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) ||
319 parse->longlink_mfc.nfn < 2) {
320 /* No multi-function links found */
321 ret = -ENODEV;
322 goto done;
323 }
324
325 printk(KERN_DEBUG "%s: Multi-function SanDisk ConnectPlus detected"
326 " - using vendor-specific initialization\n", dev->name);
327 hw_priv->sandisk_connectplus = 1;
328
329 reg.Function = 0;
330 reg.Action = CS_WRITE;
331 reg.Offset = CISREG_COR;
332 reg.Value = COR_SOFT_RESET;
333 res = pcmcia_access_configuration_register(hw_priv->link->handle,
334 &reg);
335 if (res != CS_SUCCESS) {
336 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
337 dev->name, res);
338 goto done;
339 }
340 mdelay(5);
341
342 reg.Function = 0;
343 reg.Action = CS_WRITE;
344 reg.Offset = CISREG_COR;
345 /*
346 * Do not enable interrupts here to avoid some bogus events. Interrupts
347 * will be enabled during the first cor_sreset call.
348 */
349 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
350 res = pcmcia_access_configuration_register(hw_priv->link->handle,
351 &reg);
352 if (res != CS_SUCCESS) {
353 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
354 dev->name, res);
355 goto done;
356 }
357 mdelay(5);
358
359 sandisk_set_iobase(local);
360
361 HFA384X_OUTB(0xc5, SANDISK_WLAN_ACTIVATION_OFF);
362 udelay(10);
363 HFA384X_OUTB(0x4b, SANDISK_WLAN_ACTIVATION_OFF);
364 udelay(10);
365
366done:
367 kfree(parse);
368 return ret;
369}
370
371
372static void prism2_pccard_cor_sreset(local_info_t *local)
373{
374 int res;
375 conf_reg_t reg;
376 struct hostap_cs_priv *hw_priv = local->hw_priv;
377
378 if (!prism2_pccard_card_present(local))
379 return;
380
381 reg.Function = 0;
382 reg.Action = CS_READ;
383 reg.Offset = CISREG_COR;
384 reg.Value = 0;
385 res = pcmcia_access_configuration_register(hw_priv->link->handle,
386 &reg);
387 if (res != CS_SUCCESS) {
388 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
389 res);
390 return;
391 }
392 printk(KERN_DEBUG "prism2_pccard_cor_sreset: original COR %02x\n",
393 reg.Value);
394
395 reg.Action = CS_WRITE;
396 reg.Value |= COR_SOFT_RESET;
397 res = pcmcia_access_configuration_register(hw_priv->link->handle,
398 &reg);
399 if (res != CS_SUCCESS) {
400 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
401 res);
402 return;
403 }
404
405 mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
406
407 reg.Value &= ~COR_SOFT_RESET;
408 if (hw_priv->sandisk_connectplus)
409 reg.Value |= COR_IREQ_ENA;
410 res = pcmcia_access_configuration_register(hw_priv->link->handle,
411 &reg);
412 if (res != CS_SUCCESS) {
413 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
414 res);
415 return;
416 }
417
418 mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
419
420 if (hw_priv->sandisk_connectplus)
421 sandisk_set_iobase(local);
422}
423
424
425static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
426{
427 int res;
428 conf_reg_t reg;
429 int old_cor;
430 struct hostap_cs_priv *hw_priv = local->hw_priv;
431
432 if (!prism2_pccard_card_present(local))
433 return;
434
435 if (hw_priv->sandisk_connectplus) {
436 sandisk_write_hcr(local, hcr);
437 return;
438 }
439
440 reg.Function = 0;
441 reg.Action = CS_READ;
442 reg.Offset = CISREG_COR;
443 reg.Value = 0;
444 res = pcmcia_access_configuration_register(hw_priv->link->handle,
445 &reg);
446 if (res != CS_SUCCESS) {
447 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
448 "(%d)\n", res);
449 return;
450 }
451 printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n",
452 reg.Value);
453 old_cor = reg.Value;
454
455 reg.Action = CS_WRITE;
456 reg.Value |= COR_SOFT_RESET;
457 res = pcmcia_access_configuration_register(hw_priv->link->handle,
458 &reg);
459 if (res != CS_SUCCESS) {
460 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
461 "(%d)\n", res);
462 return;
463 }
464
465 mdelay(10);
466
467 /* Setup Genesis mode */
468 reg.Action = CS_WRITE;
469 reg.Value = hcr;
470 reg.Offset = CISREG_CCSR;
471 res = pcmcia_access_configuration_register(hw_priv->link->handle,
472 &reg);
473 if (res != CS_SUCCESS) {
474 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
475 "(%d)\n", res);
476 return;
477 }
478 mdelay(10);
479
480 reg.Action = CS_WRITE;
481 reg.Offset = CISREG_COR;
482 reg.Value = old_cor & ~COR_SOFT_RESET;
483 res = pcmcia_access_configuration_register(hw_priv->link->handle,
484 &reg);
485 if (res != CS_SUCCESS) {
486 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
487 "(%d)\n", res);
488 return;
489 }
490
491 mdelay(10);
492}
493
494
495static int prism2_pccard_dev_open(local_info_t *local)
496{
497 struct hostap_cs_priv *hw_priv = local->hw_priv;
498 hw_priv->link->open++;
499 return 0;
500}
501
502
503static int prism2_pccard_dev_close(local_info_t *local)
504{
505 struct hostap_cs_priv *hw_priv;
506
507 if (local == NULL || local->hw_priv == NULL)
508 return 1;
509 hw_priv = local->hw_priv;
510 if (hw_priv->link == NULL)
511 return 1;
512
513 if (!hw_priv->link->open) {
514 printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
515 "link not open?!\n", local->dev->name);
516 return 1;
517 }
518
519 hw_priv->link->open--;
520
521 return 0;
522}
523
524
525static struct prism2_helper_functions prism2_pccard_funcs =
526{
527 .card_present = prism2_pccard_card_present,
528 .cor_sreset = prism2_pccard_cor_sreset,
529 .dev_open = prism2_pccard_dev_open,
530 .dev_close = prism2_pccard_dev_close,
531 .genesis_reset = prism2_pccard_genesis_reset,
532 .hw_type = HOSTAP_HW_PCCARD,
533};
534
535
536/* allocate local data and register with CardServices
537 * initialize dev_link structure, but do not configure the card yet */
538static dev_link_t *prism2_attach(void)
539{
540 dev_link_t *link;
541 client_reg_t client_reg;
542 int ret;
543
544 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
545 if (link == NULL)
546 return NULL;
547
548 memset(link, 0, sizeof(dev_link_t));
549
550 PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
551 link->conf.Vcc = 33;
552 link->conf.IntType = INT_MEMORY_AND_IO;
553
554 /* register with CardServices */
555 link->next = dev_list;
556 dev_list = link;
557 client_reg.dev_info = &dev_info;
558 client_reg.Version = 0x0210;
559 client_reg.event_callback_args.client_data = link;
560 ret = pcmcia_register_client(&link->handle, &client_reg);
561 if (ret != CS_SUCCESS) {
562 cs_error(link->handle, RegisterClient, ret);
563 prism2_detach(link);
564 return NULL;
565 }
566 return link;
567}
568
569
570static void prism2_detach(dev_link_t *link)
571{
572 dev_link_t **linkp;
573
574 PDEBUG(DEBUG_FLOW, "prism2_detach\n");
575
576 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
577 if (*linkp == link)
578 break;
579 if (*linkp == NULL) {
580 printk(KERN_WARNING "%s: Attempt to detach non-existing "
581 "PCMCIA client\n", dev_info);
582 return;
583 }
584
585 if (link->state & DEV_CONFIG) {
586 prism2_release((u_long)link);
587 }
588
589 if (link->handle) {
590 int res = pcmcia_deregister_client(link->handle);
591 if (res) {
592 printk("CardService(DeregisterClient) => %d\n", res);
593 cs_error(link->handle, DeregisterClient, res);
594 }
595 }
596
597 *linkp = link->next;
598 /* release net devices */
599 if (link->priv) {
600 struct net_device *dev;
601 struct hostap_interface *iface;
602 dev = link->priv;
603 iface = netdev_priv(dev);
604 kfree(iface->local->hw_priv);
605 iface->local->hw_priv = NULL;
606 prism2_free_local_data(dev);
607 }
608 kfree(link);
609}
610
611
612#define CS_CHECK(fn, ret) \
613do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
614
615#define CFG_CHECK2(fn, retf) \
616do { int ret = (retf); \
617if (ret != 0) { \
618 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
619 cs_error(link->handle, fn, ret); \
620 goto next_entry; \
621} \
622} while (0)
623
624
625/* run after a CARD_INSERTION event is received to configure the PCMCIA
626 * socket and make the device available to the system */
627static int prism2_config(dev_link_t *link)
628{
629 struct net_device *dev;
630 struct hostap_interface *iface;
631 local_info_t *local;
632 int ret = 1;
633 tuple_t tuple;
634 cisparse_t *parse;
635 int last_fn, last_ret;
636 u_char buf[64];
637 config_info_t conf;
638 cistpl_cftable_entry_t dflt = { 0 };
639 struct hostap_cs_priv *hw_priv;
640
641 PDEBUG(DEBUG_FLOW, "prism2_config()\n");
642
643 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
644 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
645 if (parse == NULL || hw_priv == NULL) {
646 kfree(parse);
647 kfree(hw_priv);
648 ret = -ENOMEM;
649 goto failed;
650 }
651 memset(hw_priv, 0, sizeof(*hw_priv));
652
653 tuple.DesiredTuple = CISTPL_CONFIG;
654 tuple.Attributes = 0;
655 tuple.TupleData = buf;
656 tuple.TupleDataMax = sizeof(buf);
657 tuple.TupleOffset = 0;
658 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
659 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple));
660 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse));
661 link->conf.ConfigBase = parse->config.base;
662 link->conf.Present = parse->config.rmask[0];
663
664 CS_CHECK(GetConfigurationInfo,
665 pcmcia_get_configuration_info(link->handle, &conf));
666 PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info,
667 ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc);
668 link->conf.Vcc = conf.Vcc;
669
670 /* Look for an appropriate configuration table entry in the CIS */
671 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
672 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple));
673 for (;;) {
674 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
675 CFG_CHECK2(GetTupleData,
676 pcmcia_get_tuple_data(link->handle, &tuple));
677 CFG_CHECK2(ParseTuple,
678 pcmcia_parse_tuple(link->handle, &tuple, parse));
679
680 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
681 dflt = *cfg;
682 if (cfg->index == 0)
683 goto next_entry;
684 link->conf.ConfigIndex = cfg->index;
685 PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
686 "(default 0x%02X)\n", cfg->index, dflt.index);
687
688 /* Does this card need audio output? */
689 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
690 link->conf.Attributes |= CONF_ENABLE_SPKR;
691 link->conf.Status = CCSR_AUDIO_ENA;
692 }
693
694 /* Use power settings for Vcc and Vpp if present */
695 /* Note that the CIS values need to be rescaled */
696 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
697 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
698 10000 && !ignore_cis_vcc) {
699 PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
700 " this entry\n");
701 goto next_entry;
702 }
703 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
704 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
705 10000 && !ignore_cis_vcc) {
706 PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
707 "- skipping this entry\n");
708 goto next_entry;
709 }
710 }
711
712 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
713 link->conf.Vpp1 = link->conf.Vpp2 =
714 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
715 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
716 link->conf.Vpp1 = link->conf.Vpp2 =
717 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
718
719 /* Do we need to allocate an interrupt? */
720 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
721 link->conf.Attributes |= CONF_ENABLE_IRQ;
722 else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
723 /* At least Compaq WL200 does not have IRQInfo1 set,
724 * but it does not work without interrupts.. */
725 printk("Config has no IRQ info, but trying to enable "
726 "IRQ anyway..\n");
727 link->conf.Attributes |= CONF_ENABLE_IRQ;
728 }
729
730 /* IO window settings */
731 PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
732 "dflt.io.nwin=%d\n",
733 cfg->io.nwin, dflt.io.nwin);
734 link->io.NumPorts1 = link->io.NumPorts2 = 0;
735 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
736 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
737 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
738 PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
739 "io.base=0x%04x, len=%d\n", io->flags,
740 io->win[0].base, io->win[0].len);
741 if (!(io->flags & CISTPL_IO_8BIT))
742 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
743 if (!(io->flags & CISTPL_IO_16BIT))
744 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
745 link->io.IOAddrLines = io->flags &
746 CISTPL_IO_LINES_MASK;
747 link->io.BasePort1 = io->win[0].base;
748 link->io.NumPorts1 = io->win[0].len;
749 if (io->nwin > 1) {
750 link->io.Attributes2 = link->io.Attributes1;
751 link->io.BasePort2 = io->win[1].base;
752 link->io.NumPorts2 = io->win[1].len;
753 }
754 }
755
756 /* This reserves IO space but doesn't actually enable it */
757 CFG_CHECK2(RequestIO,
758 pcmcia_request_io(link->handle, &link->io));
759
760 /* This configuration table entry is OK */
761 break;
762
763 next_entry:
764 CS_CHECK(GetNextTuple,
765 pcmcia_get_next_tuple(link->handle, &tuple));
766 }
767
768 /* Need to allocate net_device before requesting IRQ handler */
769 dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
770 &handle_to_dev(link->handle));
771 if (dev == NULL)
772 goto failed;
773 link->priv = dev;
774
775 iface = netdev_priv(dev);
776 local = iface->local;
777 local->hw_priv = hw_priv;
778 hw_priv->link = link;
779 strcpy(hw_priv->node.dev_name, dev->name);
780 link->dev = &hw_priv->node;
781
782 /*
783 * Allocate an interrupt line. Note that this does not assign a
784 * handler to the interrupt, unless the 'Handler' member of the
785 * irq structure is initialized.
786 */
787 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
788 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
789 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
790 link->irq.Handler = prism2_interrupt;
791 link->irq.Instance = dev;
792 CS_CHECK(RequestIRQ,
793 pcmcia_request_irq(link->handle, &link->irq));
794 }
795
796 /*
797 * This actually configures the PCMCIA socket -- setting up
798 * the I/O windows and the interrupt mapping, and putting the
799 * card and host interface into "Memory and IO" mode.
800 */
801 CS_CHECK(RequestConfiguration,
802 pcmcia_request_configuration(link->handle, &link->conf));
803
804 dev->irq = link->irq.AssignedIRQ;
805 dev->base_addr = link->io.BasePort1;
806
807 /* Finally, report what we've done */
808 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
809 dev_info, link->conf.ConfigIndex,
810 link->conf.Vcc / 10, link->conf.Vcc % 10);
811 if (link->conf.Vpp1)
812 printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
813 link->conf.Vpp1 % 10);
814 if (link->conf.Attributes & CONF_ENABLE_IRQ)
815 printk(", irq %d", link->irq.AssignedIRQ);
816 if (link->io.NumPorts1)
817 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
818 link->io.BasePort1+link->io.NumPorts1-1);
819 if (link->io.NumPorts2)
820 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
821 link->io.BasePort2+link->io.NumPorts2-1);
822 printk("\n");
823
824 link->state |= DEV_CONFIG;
825 link->state &= ~DEV_CONFIG_PENDING;
826
827 local->shutdown = 0;
828
829 sandisk_enable_wireless(dev);
830
831 ret = prism2_hw_config(dev, 1);
832 if (!ret) {
833 ret = hostap_hw_ready(dev);
834 if (ret == 0 && local->ddev)
835 strcpy(hw_priv->node.dev_name, local->ddev->name);
836 }
837 kfree(parse);
838 return ret;
839
840 cs_failed:
841 cs_error(link->handle, last_fn, last_ret);
842
843 failed:
844 kfree(parse);
845 kfree(hw_priv);
846 prism2_release((u_long)link);
847 return ret;
848}
849
850
851static void prism2_release(u_long arg)
852{
853 dev_link_t *link = (dev_link_t *)arg;
854
855 PDEBUG(DEBUG_FLOW, "prism2_release\n");
856
857 if (link->priv) {
858 struct net_device *dev = link->priv;
859 struct hostap_interface *iface;
860
861 iface = netdev_priv(dev);
862 if (link->state & DEV_CONFIG)
863 prism2_hw_shutdown(dev, 0);
864 iface->local->shutdown = 1;
865 }
866
867 if (link->win)
868 pcmcia_release_window(link->win);
869 pcmcia_release_configuration(link->handle);
870 if (link->io.NumPorts1)
871 pcmcia_release_io(link->handle, &link->io);
872 if (link->irq.AssignedIRQ)
873 pcmcia_release_irq(link->handle, &link->irq);
874
875 link->state &= ~DEV_CONFIG;
876
877 PDEBUG(DEBUG_FLOW, "release - done\n");
878}
879
880
881static int prism2_event(event_t event, int priority,
882 event_callback_args_t *args)
883{
884 dev_link_t *link = args->client_data;
885 struct net_device *dev = (struct net_device *) link->priv;
886
887 switch (event) {
888 case CS_EVENT_CARD_INSERTION:
889 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
890 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
891 if (prism2_config(link)) {
892 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
893 }
894 break;
895
896 case CS_EVENT_CARD_REMOVAL:
897 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
898 link->state &= ~DEV_PRESENT;
899 if (link->state & DEV_CONFIG) {
900 netif_stop_queue(dev);
901 netif_device_detach(dev);
902 prism2_release((u_long) link);
903 }
904 break;
905
906 case CS_EVENT_PM_SUSPEND:
907 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
908 link->state |= DEV_SUSPEND;
909 /* fall through */
910
911 case CS_EVENT_RESET_PHYSICAL:
912 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
913 if (link->state & DEV_CONFIG) {
914 if (link->open) {
915 netif_stop_queue(dev);
916 netif_device_detach(dev);
917 }
918 prism2_suspend(dev);
919 pcmcia_release_configuration(link->handle);
920 }
921 break;
922
923 case CS_EVENT_PM_RESUME:
924 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
925 link->state &= ~DEV_SUSPEND;
926 /* fall through */
927
928 case CS_EVENT_CARD_RESET:
929 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
930 if (link->state & DEV_CONFIG) {
931 pcmcia_request_configuration(link->handle,
932 &link->conf);
933 prism2_hw_shutdown(dev, 1);
934 prism2_hw_config(dev, link->open ? 0 : 1);
935 if (link->open) {
936 netif_device_attach(dev);
937 netif_start_queue(dev);
938 }
939 }
940 break;
941
942 default:
943 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
944 dev_info, event);
945 break;
946 }
947 return 0;
948}
949
950
951static struct pcmcia_device_id hostap_cs_ids[] = {
952 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
953 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
954 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777),
955 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000),
956 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
957 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
958 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002),
959 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b),
960 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612),
961 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
962 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
963 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
964 PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001),
965 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001),
966 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
967 PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000),
968 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
969 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
970 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010),
971 PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
972 0x7a954bd9, 0x74be00c6),
973 PCMCIA_DEVICE_PROD_ID1234(
974 "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P",
975 "Eval-RevA",
976 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e),
977 PCMCIA_DEVICE_PROD_ID123(
978 "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02",
979 0xe6ec52ce, 0x08649af2, 0x4b74baa0),
980 PCMCIA_DEVICE_PROD_ID123(
981 "D", "Link DWL-650 11Mbps WLAN Card", "Version 01.02",
982 0x71b18589, 0xb6f1b0ab, 0x4b74baa0),
983 PCMCIA_DEVICE_PROD_ID123(
984 "Instant Wireless ", " Network PC CARD", "Version 01.02",
985 0x11d901af, 0x6e9bd926, 0x4b74baa0),
986 PCMCIA_DEVICE_PROD_ID123(
987 "SMC", "SMC2632W", "Version 01.02",
988 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0),
989 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G",
990 0x2decece3, 0x82067c18),
991 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card",
992 0x54f7c49c, 0x15a75e5b),
993 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE",
994 0x74c5e40d, 0xdb472a18),
995 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card",
996 0x0733cc81, 0x0c52f395),
997 PCMCIA_DEVICE_PROD_ID12(
998 "ZoomAir 11Mbps High", "Rate wireless Networking",
999 0x273fe3db, 0x32a1eaee),
1000 PCMCIA_DEVICE_NULL
1001};
1002MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
1003
1004
1005static struct pcmcia_driver hostap_driver = {
1006 .drv = {
1007 .name = "hostap_cs",
1008 },
1009 .attach = prism2_attach,
1010 .detach = prism2_detach,
1011 .owner = THIS_MODULE,
1012 .event = prism2_event,
1013 .id_table = hostap_cs_ids,
1014};
1015
1016static int __init init_prism2_pccard(void)
1017{
1018 printk(KERN_INFO "%s: %s\n", dev_info, version);
1019 return pcmcia_register_driver(&hostap_driver);
1020}
1021
1022static void __exit exit_prism2_pccard(void)
1023{
1024 pcmcia_unregister_driver(&hostap_driver);
1025 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
1026}
1027
1028
1029module_init(init_prism2_pccard);
1030module_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..e533a663deda
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -0,0 +1,3445 @@
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-2005, 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 <net/ieee80211.h>
52#include <net/ieee80211_crypt.h>
53#include <asm/irq.h>
54
55#include "hostap_80211.h"
56#include "hostap.h"
57#include "hostap_ap.h"
58
59
60/* #define final_version */
61
62static int mtu = 1500;
63module_param(mtu, int, 0444);
64MODULE_PARM_DESC(mtu, "Maximum transfer unit");
65
66static int channel[MAX_PARM_DEVICES] = { 3, DEF_INTS };
67module_param_array(channel, int, NULL, 0444);
68MODULE_PARM_DESC(channel, "Initial channel");
69
70static char essid[33] = "test";
71module_param_string(essid, essid, sizeof(essid), 0444);
72MODULE_PARM_DESC(essid, "Host AP's ESSID");
73
74static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS };
75module_param_array(iw_mode, int, NULL, 0444);
76MODULE_PARM_DESC(iw_mode, "Initial operation mode");
77
78static int beacon_int[MAX_PARM_DEVICES] = { 100, DEF_INTS };
79module_param_array(beacon_int, int, NULL, 0444);
80MODULE_PARM_DESC(beacon_int, "Beacon interval (1 = 1024 usec)");
81
82static int dtim_period[MAX_PARM_DEVICES] = { 1, DEF_INTS };
83module_param_array(dtim_period, int, NULL, 0444);
84MODULE_PARM_DESC(dtim_period, "DTIM period");
85
86static char dev_template[16] = "wlan%d";
87module_param_string(dev_template, dev_template, sizeof(dev_template), 0444);
88MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: "
89 "wlan%d)");
90
91#ifdef final_version
92#define EXTRA_EVENTS_WTERR 0
93#else
94/* check WTERR events (Wait Time-out) in development versions */
95#define EXTRA_EVENTS_WTERR HFA384X_EV_WTERR
96#endif
97
98/* Events that will be using BAP0 */
99#define HFA384X_BAP0_EVENTS \
100 (HFA384X_EV_TXEXC | HFA384X_EV_RX | HFA384X_EV_INFO | HFA384X_EV_TX)
101
102/* event mask, i.e., events that will result in an interrupt */
103#define HFA384X_EVENT_MASK \
104 (HFA384X_BAP0_EVENTS | HFA384X_EV_ALLOC | HFA384X_EV_INFDROP | \
105 HFA384X_EV_CMD | HFA384X_EV_TICK | \
106 EXTRA_EVENTS_WTERR)
107
108/* Default TX control flags: use 802.11 headers and request interrupt for
109 * failed transmits. Frames that request ACK callback, will add
110 * _TX_OK flag and _ALT_RTRY flag may be used to select different retry policy.
111 */
112#define HFA384X_TX_CTRL_FLAGS \
113 (HFA384X_TX_CTRL_802_11 | HFA384X_TX_CTRL_TX_EX)
114
115
116/* ca. 1 usec */
117#define HFA384X_CMD_BUSY_TIMEOUT 5000
118#define HFA384X_BAP_BUSY_TIMEOUT 50000
119
120/* ca. 10 usec */
121#define HFA384X_CMD_COMPL_TIMEOUT 20000
122#define HFA384X_DL_COMPL_TIMEOUT 1000000
123
124/* Wait times for initialization; yield to other processes to avoid busy
125 * waiting for long time. */
126#define HFA384X_INIT_TIMEOUT (HZ / 2) /* 500 ms */
127#define HFA384X_ALLOC_COMPL_TIMEOUT (HZ / 20) /* 50 ms */
128
129
130static void prism2_hw_reset(struct net_device *dev);
131static void prism2_check_sta_fw_version(local_info_t *local);
132
133#ifdef PRISM2_DOWNLOAD_SUPPORT
134/* hostap_download.c */
135static int prism2_download_aux_dump(struct net_device *dev,
136 unsigned int addr, int len, u8 *buf);
137static u8 * prism2_read_pda(struct net_device *dev);
138static int prism2_download(local_info_t *local,
139 struct prism2_download_param *param);
140static void prism2_download_free_data(struct prism2_download_data *dl);
141static int prism2_download_volatile(local_info_t *local,
142 struct prism2_download_data *param);
143static int prism2_download_genesis(local_info_t *local,
144 struct prism2_download_data *param);
145static int prism2_get_ram_size(local_info_t *local);
146#endif /* PRISM2_DOWNLOAD_SUPPORT */
147
148
149
150
151#ifndef final_version
152/* magic value written to SWSUPPORT0 reg. for detecting whether card is still
153 * present */
154#define HFA384X_MAGIC 0x8A32
155#endif
156
157
158static u16 hfa384x_read_reg(struct net_device *dev, u16 reg)
159{
160 return HFA384X_INW(reg);
161}
162
163
164static void hfa384x_read_regs(struct net_device *dev,
165 struct hfa384x_regs *regs)
166{
167 regs->cmd = HFA384X_INW(HFA384X_CMD_OFF);
168 regs->evstat = HFA384X_INW(HFA384X_EVSTAT_OFF);
169 regs->offset0 = HFA384X_INW(HFA384X_OFFSET0_OFF);
170 regs->offset1 = HFA384X_INW(HFA384X_OFFSET1_OFF);
171 regs->swsupport0 = HFA384X_INW(HFA384X_SWSUPPORT0_OFF);
172}
173
174
175/**
176 * __hostap_cmd_queue_free - Free Prism2 command queue entry (private)
177 * @local: pointer to private Host AP driver data
178 * @entry: Prism2 command queue entry to be freed
179 * @del_req: request the entry to be removed
180 *
181 * Internal helper function for freeing Prism2 command queue entries.
182 * Caller must have acquired local->cmdlock before calling this function.
183 */
184static inline void __hostap_cmd_queue_free(local_info_t *local,
185 struct hostap_cmd_queue *entry,
186 int del_req)
187{
188 if (del_req) {
189 entry->del_req = 1;
190 if (!list_empty(&entry->list)) {
191 list_del_init(&entry->list);
192 local->cmd_queue_len--;
193 }
194 }
195
196 if (atomic_dec_and_test(&entry->usecnt) && entry->del_req)
197 kfree(entry);
198}
199
200
201/**
202 * hostap_cmd_queue_free - Free Prism2 command queue entry
203 * @local: pointer to private Host AP driver data
204 * @entry: Prism2 command queue entry to be freed
205 * @del_req: request the entry to be removed
206 *
207 * Free a Prism2 command queue entry.
208 */
209static inline void hostap_cmd_queue_free(local_info_t *local,
210 struct hostap_cmd_queue *entry,
211 int del_req)
212{
213 unsigned long flags;
214
215 spin_lock_irqsave(&local->cmdlock, flags);
216 __hostap_cmd_queue_free(local, entry, del_req);
217 spin_unlock_irqrestore(&local->cmdlock, flags);
218}
219
220
221/**
222 * prism2_clear_cmd_queue - Free all pending Prism2 command queue entries
223 * @local: pointer to private Host AP driver data
224 */
225static void prism2_clear_cmd_queue(local_info_t *local)
226{
227 struct list_head *ptr, *n;
228 unsigned long flags;
229 struct hostap_cmd_queue *entry;
230
231 spin_lock_irqsave(&local->cmdlock, flags);
232 list_for_each_safe(ptr, n, &local->cmd_queue) {
233 entry = list_entry(ptr, struct hostap_cmd_queue, list);
234 atomic_inc(&entry->usecnt);
235 printk(KERN_DEBUG "%s: removed pending cmd_queue entry "
236 "(type=%d, cmd=0x%04x, param0=0x%04x)\n",
237 local->dev->name, entry->type, entry->cmd,
238 entry->param0);
239 __hostap_cmd_queue_free(local, entry, 1);
240 }
241 if (local->cmd_queue_len) {
242 /* This should not happen; print debug message and clear
243 * queue length. */
244 printk(KERN_DEBUG "%s: cmd_queue_len (%d) not zero after "
245 "flush\n", local->dev->name, local->cmd_queue_len);
246 local->cmd_queue_len = 0;
247 }
248 spin_unlock_irqrestore(&local->cmdlock, flags);
249}
250
251
252/**
253 * hfa384x_cmd_issue - Issue a Prism2 command to the hardware
254 * @dev: pointer to net_device
255 * @entry: Prism2 command queue entry to be issued
256 */
257static inline int hfa384x_cmd_issue(struct net_device *dev,
258 struct hostap_cmd_queue *entry)
259{
260 struct hostap_interface *iface;
261 local_info_t *local;
262 int tries;
263 u16 reg;
264 unsigned long flags;
265
266 iface = netdev_priv(dev);
267 local = iface->local;
268
269 if (local->func->card_present && !local->func->card_present(local))
270 return -ENODEV;
271
272 if (entry->issued) {
273 printk(KERN_DEBUG "%s: driver bug - re-issuing command @%p\n",
274 dev->name, entry);
275 }
276
277 /* wait until busy bit is clear; this should always be clear since the
278 * commands are serialized */
279 tries = HFA384X_CMD_BUSY_TIMEOUT;
280 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
281 tries--;
282 udelay(1);
283 }
284#ifndef final_version
285 if (tries != HFA384X_CMD_BUSY_TIMEOUT) {
286 prism2_io_debug_error(dev, 1);
287 printk(KERN_DEBUG "%s: hfa384x_cmd_issue: cmd reg was busy "
288 "for %d usec\n", dev->name,
289 HFA384X_CMD_BUSY_TIMEOUT - tries);
290 }
291#endif
292 if (tries == 0) {
293 reg = HFA384X_INW(HFA384X_CMD_OFF);
294 prism2_io_debug_error(dev, 2);
295 printk(KERN_DEBUG "%s: hfa384x_cmd_issue - timeout - "
296 "reg=0x%04x\n", dev->name, reg);
297 return -ETIMEDOUT;
298 }
299
300 /* write command */
301 spin_lock_irqsave(&local->cmdlock, flags);
302 HFA384X_OUTW(entry->param0, HFA384X_PARAM0_OFF);
303 HFA384X_OUTW(entry->param1, HFA384X_PARAM1_OFF);
304 HFA384X_OUTW(entry->cmd, HFA384X_CMD_OFF);
305 entry->issued = 1;
306 spin_unlock_irqrestore(&local->cmdlock, flags);
307
308 return 0;
309}
310
311
312/**
313 * hfa384x_cmd - Issue a Prism2 command and wait (sleep) for completion
314 * @dev: pointer to net_device
315 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
316 * @param0: value for Param0 register
317 * @param1: value for Param1 register (pointer; %NULL if not used)
318 * @resp0: pointer for Resp0 data or %NULL if Resp0 is not needed
319 *
320 * Issue given command (possibly after waiting in command queue) and sleep
321 * until the command is completed (or timed out or interrupted). This can be
322 * called only from user process context.
323 */
324static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
325 u16 *param1, u16 *resp0)
326{
327 struct hostap_interface *iface;
328 local_info_t *local;
329 int err, res, issue, issued = 0;
330 unsigned long flags;
331 struct hostap_cmd_queue *entry;
332 DECLARE_WAITQUEUE(wait, current);
333
334 iface = netdev_priv(dev);
335 local = iface->local;
336
337 if (in_interrupt()) {
338 printk(KERN_DEBUG "%s: hfa384x_cmd called from interrupt "
339 "context\n", dev->name);
340 return -1;
341 }
342
343 if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN) {
344 printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n",
345 dev->name);
346 return -1;
347 }
348
349 if (signal_pending(current))
350 return -EINTR;
351
352 entry = (struct hostap_cmd_queue *)
353 kmalloc(sizeof(*entry), GFP_ATOMIC);
354 if (entry == NULL) {
355 printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
356 dev->name);
357 return -ENOMEM;
358 }
359 memset(entry, 0, sizeof(*entry));
360 atomic_set(&entry->usecnt, 1);
361 entry->type = CMD_SLEEP;
362 entry->cmd = cmd;
363 entry->param0 = param0;
364 if (param1)
365 entry->param1 = *param1;
366 init_waitqueue_head(&entry->compl);
367
368 /* prepare to wait for command completion event, but do not sleep yet
369 */
370 add_wait_queue(&entry->compl, &wait);
371 set_current_state(TASK_INTERRUPTIBLE);
372
373 spin_lock_irqsave(&local->cmdlock, flags);
374 issue = list_empty(&local->cmd_queue);
375 if (issue)
376 entry->issuing = 1;
377 list_add_tail(&entry->list, &local->cmd_queue);
378 local->cmd_queue_len++;
379 spin_unlock_irqrestore(&local->cmdlock, flags);
380
381 err = 0;
382 if (!issue)
383 goto wait_completion;
384
385 if (signal_pending(current))
386 err = -EINTR;
387
388 if (!err) {
389 if (hfa384x_cmd_issue(dev, entry))
390 err = -ETIMEDOUT;
391 else
392 issued = 1;
393 }
394
395 wait_completion:
396 if (!err && entry->type != CMD_COMPLETED) {
397 /* sleep until command is completed or timed out */
398 res = schedule_timeout(2 * HZ);
399 } else
400 res = -1;
401
402 if (!err && signal_pending(current))
403 err = -EINTR;
404
405 if (err && issued) {
406 /* the command was issued, so a CmdCompl event should occur
407 * soon; however, there's a pending signal and
408 * schedule_timeout() would be interrupted; wait a short period
409 * of time to avoid removing entry from the list before
410 * CmdCompl event */
411 udelay(300);
412 }
413
414 set_current_state(TASK_RUNNING);
415 remove_wait_queue(&entry->compl, &wait);
416
417 /* If entry->list is still in the list, it must be removed
418 * first and in this case prism2_cmd_ev() does not yet have
419 * local reference to it, and the data can be kfree()'d
420 * here. If the command completion event is still generated,
421 * it will be assigned to next (possibly) pending command, but
422 * the driver will reset the card anyway due to timeout
423 *
424 * If the entry is not in the list prism2_cmd_ev() has a local
425 * reference to it, but keeps cmdlock as long as the data is
426 * needed, so the data can be kfree()'d here. */
427
428 /* FIX: if the entry->list is in the list, it has not been completed
429 * yet, so removing it here is somewhat wrong.. this could cause
430 * references to freed memory and next list_del() causing NULL pointer
431 * dereference.. it would probably be better to leave the entry in the
432 * list and the list should be emptied during hw reset */
433
434 spin_lock_irqsave(&local->cmdlock, flags);
435 if (!list_empty(&entry->list)) {
436 printk(KERN_DEBUG "%s: hfa384x_cmd: entry still in list? "
437 "(entry=%p, type=%d, res=%d)\n", dev->name, entry,
438 entry->type, res);
439 list_del_init(&entry->list);
440 local->cmd_queue_len--;
441 }
442 spin_unlock_irqrestore(&local->cmdlock, flags);
443
444 if (err) {
445 printk(KERN_DEBUG "%s: hfa384x_cmd: interrupted; err=%d\n",
446 dev->name, err);
447 res = err;
448 goto done;
449 }
450
451 if (entry->type != CMD_COMPLETED) {
452 u16 reg = HFA384X_INW(HFA384X_EVSTAT_OFF);
453 printk(KERN_DEBUG "%s: hfa384x_cmd: command was not "
454 "completed (res=%d, entry=%p, type=%d, cmd=0x%04x, "
455 "param0=0x%04x, EVSTAT=%04x INTEN=%04x)\n", dev->name,
456 res, entry, entry->type, entry->cmd, entry->param0, reg,
457 HFA384X_INW(HFA384X_INTEN_OFF));
458 if (reg & HFA384X_EV_CMD) {
459 /* Command completion event is pending, but the
460 * interrupt was not delivered - probably an issue
461 * with pcmcia-cs configuration. */
462 printk(KERN_WARNING "%s: interrupt delivery does not "
463 "seem to work\n", dev->name);
464 }
465 prism2_io_debug_error(dev, 3);
466 res = -ETIMEDOUT;
467 goto done;
468 }
469
470 if (resp0 != NULL)
471 *resp0 = entry->resp0;
472#ifndef final_version
473 if (entry->res) {
474 printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x, "
475 "resp0=0x%04x\n",
476 dev->name, cmd, entry->res, entry->resp0);
477 }
478#endif /* final_version */
479
480 res = entry->res;
481 done:
482 hostap_cmd_queue_free(local, entry, 1);
483 return res;
484}
485
486
487/**
488 * hfa384x_cmd_callback - Issue a Prism2 command; callback when completed
489 * @dev: pointer to net_device
490 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
491 * @param0: value for Param0 register
492 * @callback: command completion callback function (%NULL = no callback)
493 * @context: context data to be given to the callback function
494 *
495 * Issue given command (possibly after waiting in command queue) and use
496 * callback function to indicate command completion. This can be called both
497 * from user and interrupt context. The callback function will be called in
498 * hardware IRQ context. It can be %NULL, when no function is called when
499 * command is completed.
500 */
501static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
502 void (*callback)(struct net_device *dev,
503 long context, u16 resp0,
504 u16 status),
505 long context)
506{
507 struct hostap_interface *iface;
508 local_info_t *local;
509 int issue, ret;
510 unsigned long flags;
511 struct hostap_cmd_queue *entry;
512
513 iface = netdev_priv(dev);
514 local = iface->local;
515
516 if (local->cmd_queue_len >= HOSTAP_CMD_QUEUE_MAX_LEN + 2) {
517 printk(KERN_DEBUG "%s: hfa384x_cmd: cmd_queue full\n",
518 dev->name);
519 return -1;
520 }
521
522 entry = (struct hostap_cmd_queue *)
523 kmalloc(sizeof(*entry), GFP_ATOMIC);
524 if (entry == NULL) {
525 printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
526 "failed\n", dev->name);
527 return -ENOMEM;
528 }
529 memset(entry, 0, sizeof(*entry));
530 atomic_set(&entry->usecnt, 1);
531 entry->type = CMD_CALLBACK;
532 entry->cmd = cmd;
533 entry->param0 = param0;
534 entry->callback = callback;
535 entry->context = context;
536
537 spin_lock_irqsave(&local->cmdlock, flags);
538 issue = list_empty(&local->cmd_queue);
539 if (issue)
540 entry->issuing = 1;
541 list_add_tail(&entry->list, &local->cmd_queue);
542 local->cmd_queue_len++;
543 spin_unlock_irqrestore(&local->cmdlock, flags);
544
545 if (issue && hfa384x_cmd_issue(dev, entry))
546 ret = -ETIMEDOUT;
547 else
548 ret = 0;
549
550 hostap_cmd_queue_free(local, entry, ret);
551
552 return ret;
553}
554
555
556/**
557 * __hfa384x_cmd_no_wait - Issue a Prism2 command (private)
558 * @dev: pointer to net_device
559 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
560 * @param0: value for Param0 register
561 * @io_debug_num: I/O debug error number
562 *
563 * Shared helper function for hfa384x_cmd_wait() and hfa384x_cmd_no_wait().
564 */
565static int __hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd, u16 param0,
566 int io_debug_num)
567{
568 int tries;
569 u16 reg;
570
571 /* wait until busy bit is clear; this should always be clear since the
572 * commands are serialized */
573 tries = HFA384X_CMD_BUSY_TIMEOUT;
574 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
575 tries--;
576 udelay(1);
577 }
578 if (tries == 0) {
579 reg = HFA384X_INW(HFA384X_CMD_OFF);
580 prism2_io_debug_error(dev, io_debug_num);
581 printk(KERN_DEBUG "%s: __hfa384x_cmd_no_wait(%d) - timeout - "
582 "reg=0x%04x\n", dev->name, io_debug_num, reg);
583 return -ETIMEDOUT;
584 }
585
586 /* write command */
587 HFA384X_OUTW(param0, HFA384X_PARAM0_OFF);
588 HFA384X_OUTW(cmd, HFA384X_CMD_OFF);
589
590 return 0;
591}
592
593
594/**
595 * hfa384x_cmd_wait - Issue a Prism2 command and busy wait for completion
596 * @dev: pointer to net_device
597 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
598 * @param0: value for Param0 register
599 */
600static int hfa384x_cmd_wait(struct net_device *dev, u16 cmd, u16 param0)
601{
602 int res, tries;
603 u16 reg;
604
605 res = __hfa384x_cmd_no_wait(dev, cmd, param0, 4);
606 if (res)
607 return res;
608
609 /* wait for command completion */
610 if ((cmd & HFA384X_CMDCODE_MASK) == HFA384X_CMDCODE_DOWNLOAD)
611 tries = HFA384X_DL_COMPL_TIMEOUT;
612 else
613 tries = HFA384X_CMD_COMPL_TIMEOUT;
614
615 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) &&
616 tries > 0) {
617 tries--;
618 udelay(10);
619 }
620 if (tries == 0) {
621 reg = HFA384X_INW(HFA384X_EVSTAT_OFF);
622 prism2_io_debug_error(dev, 5);
623 printk(KERN_DEBUG "%s: hfa384x_cmd_wait - timeout2 - "
624 "reg=0x%04x\n", dev->name, reg);
625 return -ETIMEDOUT;
626 }
627
628 res = (HFA384X_INW(HFA384X_STATUS_OFF) &
629 (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) |
630 BIT(8))) >> 8;
631#ifndef final_version
632 if (res) {
633 printk(KERN_DEBUG "%s: CMD=0x%04x => res=0x%02x\n",
634 dev->name, cmd, res);
635 }
636#endif
637
638 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
639
640 return res;
641}
642
643
644/**
645 * hfa384x_cmd_no_wait - Issue a Prism2 command; do not wait for completion
646 * @dev: pointer to net_device
647 * @cmd: Prism2 command code (HFA384X_CMD_CODE_*)
648 * @param0: value for Param0 register
649 */
650static inline int hfa384x_cmd_no_wait(struct net_device *dev, u16 cmd,
651 u16 param0)
652{
653 return __hfa384x_cmd_no_wait(dev, cmd, param0, 6);
654}
655
656
657/**
658 * prism2_cmd_ev - Prism2 command completion event handler
659 * @dev: pointer to net_device
660 *
661 * Interrupt handler for command completion events. Called by the main
662 * interrupt handler in hardware IRQ context. Read Resp0 and status registers
663 * from the hardware and ACK the event. Depending on the issued command type
664 * either wake up the sleeping process that is waiting for command completion
665 * or call the callback function. Issue the next command, if one is pending.
666 */
667static void prism2_cmd_ev(struct net_device *dev)
668{
669 struct hostap_interface *iface;
670 local_info_t *local;
671 struct hostap_cmd_queue *entry = NULL;
672
673 iface = netdev_priv(dev);
674 local = iface->local;
675
676 spin_lock(&local->cmdlock);
677 if (!list_empty(&local->cmd_queue)) {
678 entry = list_entry(local->cmd_queue.next,
679 struct hostap_cmd_queue, list);
680 atomic_inc(&entry->usecnt);
681 list_del_init(&entry->list);
682 local->cmd_queue_len--;
683
684 if (!entry->issued) {
685 printk(KERN_DEBUG "%s: Command completion event, but "
686 "cmd not issued\n", dev->name);
687 __hostap_cmd_queue_free(local, entry, 1);
688 entry = NULL;
689 }
690 }
691 spin_unlock(&local->cmdlock);
692
693 if (!entry) {
694 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
695 printk(KERN_DEBUG "%s: Command completion event, but no "
696 "pending commands\n", dev->name);
697 return;
698 }
699
700 entry->resp0 = HFA384X_INW(HFA384X_RESP0_OFF);
701 entry->res = (HFA384X_INW(HFA384X_STATUS_OFF) &
702 (BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) |
703 BIT(9) | BIT(8))) >> 8;
704 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
705
706 /* TODO: rest of the CmdEv handling could be moved to tasklet */
707 if (entry->type == CMD_SLEEP) {
708 entry->type = CMD_COMPLETED;
709 wake_up_interruptible(&entry->compl);
710 } else if (entry->type == CMD_CALLBACK) {
711 if (entry->callback)
712 entry->callback(dev, entry->context, entry->resp0,
713 entry->res);
714 } else {
715 printk(KERN_DEBUG "%s: Invalid command completion type %d\n",
716 dev->name, entry->type);
717 }
718 hostap_cmd_queue_free(local, entry, 1);
719
720 /* issue next command, if pending */
721 entry = NULL;
722 spin_lock(&local->cmdlock);
723 if (!list_empty(&local->cmd_queue)) {
724 entry = list_entry(local->cmd_queue.next,
725 struct hostap_cmd_queue, list);
726 if (entry->issuing) {
727 /* hfa384x_cmd() has already started issuing this
728 * command, so do not start here */
729 entry = NULL;
730 }
731 if (entry)
732 atomic_inc(&entry->usecnt);
733 }
734 spin_unlock(&local->cmdlock);
735
736 if (entry) {
737 /* issue next command; if command issuing fails, remove the
738 * entry from cmd_queue */
739 int res = hfa384x_cmd_issue(dev, entry);
740 spin_lock(&local->cmdlock);
741 __hostap_cmd_queue_free(local, entry, res);
742 spin_unlock(&local->cmdlock);
743 }
744}
745
746
747static inline int hfa384x_wait_offset(struct net_device *dev, u16 o_off)
748{
749 int tries = HFA384X_BAP_BUSY_TIMEOUT;
750 int res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
751
752 while (res && tries > 0) {
753 tries--;
754 udelay(1);
755 res = HFA384X_INW(o_off) & HFA384X_OFFSET_BUSY;
756 }
757 return res;
758}
759
760
761/* Offset must be even */
762static int hfa384x_setup_bap(struct net_device *dev, u16 bap, u16 id,
763 int offset)
764{
765 u16 o_off, s_off;
766 int ret = 0;
767
768 if (offset % 2 || bap > 1)
769 return -EINVAL;
770
771 if (bap == BAP1) {
772 o_off = HFA384X_OFFSET1_OFF;
773 s_off = HFA384X_SELECT1_OFF;
774 } else {
775 o_off = HFA384X_OFFSET0_OFF;
776 s_off = HFA384X_SELECT0_OFF;
777 }
778
779 if (hfa384x_wait_offset(dev, o_off)) {
780 prism2_io_debug_error(dev, 7);
781 printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout before\n",
782 dev->name);
783 ret = -ETIMEDOUT;
784 goto out;
785 }
786
787 HFA384X_OUTW(id, s_off);
788 HFA384X_OUTW(offset, o_off);
789
790 if (hfa384x_wait_offset(dev, o_off)) {
791 prism2_io_debug_error(dev, 8);
792 printk(KERN_DEBUG "%s: hfa384x_setup_bap - timeout after\n",
793 dev->name);
794 ret = -ETIMEDOUT;
795 goto out;
796 }
797#ifndef final_version
798 if (HFA384X_INW(o_off) & HFA384X_OFFSET_ERR) {
799 prism2_io_debug_error(dev, 9);
800 printk(KERN_DEBUG "%s: hfa384x_setup_bap - offset error "
801 "(%d,0x04%x,%d); reg=0x%04x\n",
802 dev->name, bap, id, offset, HFA384X_INW(o_off));
803 ret = -EINVAL;
804 }
805#endif
806
807 out:
808 return ret;
809}
810
811
812static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
813 int exact_len)
814{
815 struct hostap_interface *iface;
816 local_info_t *local;
817 int res, rlen = 0;
818 struct hfa384x_rid_hdr rec;
819
820 iface = netdev_priv(dev);
821 local = iface->local;
822
823 if (local->no_pri) {
824 printk(KERN_DEBUG "%s: cannot get RID %04x (len=%d) - no PRI "
825 "f/w\n", dev->name, rid, len);
826 return -ENOTTY; /* Well.. not really correct, but return
827 * something unique enough.. */
828 }
829
830 if ((local->func->card_present && !local->func->card_present(local)) ||
831 local->hw_downloading)
832 return -ENODEV;
833
834 res = down_interruptible(&local->rid_bap_sem);
835 if (res)
836 return res;
837
838 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS, rid, NULL, NULL);
839 if (res) {
840 printk(KERN_DEBUG "%s: hfa384x_get_rid: CMDCODE_ACCESS failed "
841 "(res=%d, rid=%04x, len=%d)\n",
842 dev->name, res, rid, len);
843 up(&local->rid_bap_sem);
844 return res;
845 }
846
847 spin_lock_bh(&local->baplock);
848
849 res = hfa384x_setup_bap(dev, BAP0, rid, 0);
850 if (!res)
851 res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
852
853 if (le16_to_cpu(rec.len) == 0) {
854 /* RID not available */
855 res = -ENODATA;
856 }
857
858 rlen = (le16_to_cpu(rec.len) - 1) * 2;
859 if (!res && exact_len && rlen != len) {
860 printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: "
861 "rid=0x%04x, len=%d (expected %d)\n",
862 dev->name, rid, rlen, len);
863 res = -ENODATA;
864 }
865
866 if (!res)
867 res = hfa384x_from_bap(dev, BAP0, buf, len);
868
869 spin_unlock_bh(&local->baplock);
870 up(&local->rid_bap_sem);
871
872 if (res) {
873 if (res != -ENODATA)
874 printk(KERN_DEBUG "%s: hfa384x_get_rid (rid=%04x, "
875 "len=%d) - failed - res=%d\n", dev->name, rid,
876 len, res);
877 if (res == -ETIMEDOUT)
878 prism2_hw_reset(dev);
879 return res;
880 }
881
882 return rlen;
883}
884
885
886static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len)
887{
888 struct hostap_interface *iface;
889 local_info_t *local;
890 struct hfa384x_rid_hdr rec;
891 int res;
892
893 iface = netdev_priv(dev);
894 local = iface->local;
895
896 if (local->no_pri) {
897 printk(KERN_DEBUG "%s: cannot set RID %04x (len=%d) - no PRI "
898 "f/w\n", dev->name, rid, len);
899 return -ENOTTY; /* Well.. not really correct, but return
900 * something unique enough.. */
901 }
902
903 if ((local->func->card_present && !local->func->card_present(local)) ||
904 local->hw_downloading)
905 return -ENODEV;
906
907 rec.rid = cpu_to_le16(rid);
908 /* RID len in words and +1 for rec.rid */
909 rec.len = cpu_to_le16(len / 2 + len % 2 + 1);
910
911 res = down_interruptible(&local->rid_bap_sem);
912 if (res)
913 return res;
914
915 spin_lock_bh(&local->baplock);
916 res = hfa384x_setup_bap(dev, BAP0, rid, 0);
917 if (!res)
918 res = hfa384x_to_bap(dev, BAP0, &rec, sizeof(rec));
919 if (!res)
920 res = hfa384x_to_bap(dev, BAP0, buf, len);
921 spin_unlock_bh(&local->baplock);
922
923 if (res) {
924 printk(KERN_DEBUG "%s: hfa384x_set_rid (rid=%04x, len=%d) - "
925 "failed - res=%d\n", dev->name, rid, len, res);
926 up(&local->rid_bap_sem);
927 return res;
928 }
929
930 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL);
931 up(&local->rid_bap_sem);
932 if (res) {
933 printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE "
934 "failed (res=%d, rid=%04x, len=%d)\n",
935 dev->name, res, rid, len);
936 return res;
937 }
938
939 if (res == -ETIMEDOUT)
940 prism2_hw_reset(dev);
941
942 return res;
943}
944
945
946static void hfa384x_disable_interrupts(struct net_device *dev)
947{
948 /* disable interrupts and clear event status */
949 HFA384X_OUTW(0, HFA384X_INTEN_OFF);
950 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
951}
952
953
954static void hfa384x_enable_interrupts(struct net_device *dev)
955{
956 /* ack pending events and enable interrupts from selected events */
957 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
958 HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);
959}
960
961
962static void hfa384x_events_no_bap0(struct net_device *dev)
963{
964 HFA384X_OUTW(HFA384X_EVENT_MASK & ~HFA384X_BAP0_EVENTS,
965 HFA384X_INTEN_OFF);
966}
967
968
969static void hfa384x_events_all(struct net_device *dev)
970{
971 HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);
972}
973
974
975static void hfa384x_events_only_cmd(struct net_device *dev)
976{
977 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_INTEN_OFF);
978}
979
980
981static u16 hfa384x_allocate_fid(struct net_device *dev, int len)
982{
983 u16 fid;
984 unsigned long delay;
985
986 /* FIX: this could be replace with hfa384x_cmd() if the Alloc event
987 * below would be handled like CmdCompl event (sleep here, wake up from
988 * interrupt handler */
989 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_ALLOC, len)) {
990 printk(KERN_DEBUG "%s: cannot allocate fid, len=%d\n",
991 dev->name, len);
992 return 0xffff;
993 }
994
995 delay = jiffies + HFA384X_ALLOC_COMPL_TIMEOUT;
996 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC) &&
997 time_before(jiffies, delay))
998 yield();
999 if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC)) {
1000 printk("%s: fid allocate, len=%d - timeout\n", dev->name, len);
1001 return 0xffff;
1002 }
1003
1004 fid = HFA384X_INW(HFA384X_ALLOCFID_OFF);
1005 HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
1006
1007 return fid;
1008}
1009
1010
1011static int prism2_reset_port(struct net_device *dev)
1012{
1013 struct hostap_interface *iface;
1014 local_info_t *local;
1015 int res;
1016
1017 iface = netdev_priv(dev);
1018 local = iface->local;
1019
1020 if (!local->dev_enabled)
1021 return 0;
1022
1023 res = hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0,
1024 NULL, NULL);
1025 if (res)
1026 printk(KERN_DEBUG "%s: reset port failed to disable port\n",
1027 dev->name);
1028 else {
1029 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0,
1030 NULL, NULL);
1031 if (res)
1032 printk(KERN_DEBUG "%s: reset port failed to enable "
1033 "port\n", dev->name);
1034 }
1035
1036 /* It looks like at least some STA firmware versions reset
1037 * fragmentation threshold back to 2346 after enable command. Restore
1038 * the configured value, if it differs from this default. */
1039 if (local->fragm_threshold != 2346 &&
1040 hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
1041 local->fragm_threshold)) {
1042 printk(KERN_DEBUG "%s: failed to restore fragmentation "
1043 "threshold (%d) after Port0 enable\n",
1044 dev->name, local->fragm_threshold);
1045 }
1046
1047 return res;
1048}
1049
1050
1051static int prism2_get_version_info(struct net_device *dev, u16 rid,
1052 const char *txt)
1053{
1054 struct hfa384x_comp_ident comp;
1055 struct hostap_interface *iface;
1056 local_info_t *local;
1057
1058 iface = netdev_priv(dev);
1059 local = iface->local;
1060
1061 if (local->no_pri) {
1062 /* PRI f/w not yet available - cannot read RIDs */
1063 return -1;
1064 }
1065 if (hfa384x_get_rid(dev, rid, &comp, sizeof(comp), 1) < 0) {
1066 printk(KERN_DEBUG "Could not get RID for component %s\n", txt);
1067 return -1;
1068 }
1069
1070 printk(KERN_INFO "%s: %s: id=0x%02x v%d.%d.%d\n", dev->name, txt,
1071 __le16_to_cpu(comp.id), __le16_to_cpu(comp.major),
1072 __le16_to_cpu(comp.minor), __le16_to_cpu(comp.variant));
1073 return 0;
1074}
1075
1076
1077static int prism2_setup_rids(struct net_device *dev)
1078{
1079 struct hostap_interface *iface;
1080 local_info_t *local;
1081 u16 tmp;
1082 int ret = 0;
1083
1084 iface = netdev_priv(dev);
1085 local = iface->local;
1086
1087 hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000);
1088
1089 if (!local->fw_ap) {
1090 tmp = hostap_get_porttype(local);
1091 ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp);
1092 if (ret) {
1093 printk("%s: Port type setting to %d failed\n",
1094 dev->name, tmp);
1095 goto fail;
1096 }
1097 }
1098
1099 /* Setting SSID to empty string seems to kill the card in Host AP mode
1100 */
1101 if (local->iw_mode != IW_MODE_MASTER || local->essid[0] != '\0') {
1102 ret = hostap_set_string(dev, HFA384X_RID_CNFOWNSSID,
1103 local->essid);
1104 if (ret) {
1105 printk("%s: AP own SSID setting failed\n", dev->name);
1106 goto fail;
1107 }
1108 }
1109
1110 ret = hostap_set_word(dev, HFA384X_RID_CNFMAXDATALEN,
1111 PRISM2_DATA_MAXLEN);
1112 if (ret) {
1113 printk("%s: MAC data length setting to %d failed\n",
1114 dev->name, PRISM2_DATA_MAXLEN);
1115 goto fail;
1116 }
1117
1118 if (hfa384x_get_rid(dev, HFA384X_RID_CHANNELLIST, &tmp, 2, 1) < 0) {
1119 printk("%s: Channel list read failed\n", dev->name);
1120 ret = -EINVAL;
1121 goto fail;
1122 }
1123 local->channel_mask = __le16_to_cpu(tmp);
1124
1125 if (local->channel < 1 || local->channel > 14 ||
1126 !(local->channel_mask & (1 << (local->channel - 1)))) {
1127 printk(KERN_WARNING "%s: Channel setting out of range "
1128 "(%d)!\n", dev->name, local->channel);
1129 ret = -EBUSY;
1130 goto fail;
1131 }
1132
1133 ret = hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel);
1134 if (ret) {
1135 printk("%s: Channel setting to %d failed\n",
1136 dev->name, local->channel);
1137 goto fail;
1138 }
1139
1140 ret = hostap_set_word(dev, HFA384X_RID_CNFBEACONINT,
1141 local->beacon_int);
1142 if (ret) {
1143 printk("%s: Beacon interval setting to %d failed\n",
1144 dev->name, local->beacon_int);
1145 /* this may fail with Symbol/Lucent firmware */
1146 if (ret == -ETIMEDOUT)
1147 goto fail;
1148 }
1149
1150 ret = hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD,
1151 local->dtim_period);
1152 if (ret) {
1153 printk("%s: DTIM period setting to %d failed\n",
1154 dev->name, local->dtim_period);
1155 /* this may fail with Symbol/Lucent firmware */
1156 if (ret == -ETIMEDOUT)
1157 goto fail;
1158 }
1159
1160 ret = hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
1161 local->is_promisc);
1162 if (ret)
1163 printk(KERN_INFO "%s: Setting promiscuous mode (%d) failed\n",
1164 dev->name, local->is_promisc);
1165
1166 if (!local->fw_ap) {
1167 ret = hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID,
1168 local->essid);
1169 if (ret) {
1170 printk("%s: Desired SSID setting failed\n", dev->name);
1171 goto fail;
1172 }
1173 }
1174
1175 /* Setup TXRateControl, defaults to allow use of 1, 2, 5.5, and
1176 * 11 Mbps in automatic TX rate fallback and 1 and 2 Mbps as basic
1177 * rates */
1178 if (local->tx_rate_control == 0) {
1179 local->tx_rate_control =
1180 HFA384X_RATES_1MBPS |
1181 HFA384X_RATES_2MBPS |
1182 HFA384X_RATES_5MBPS |
1183 HFA384X_RATES_11MBPS;
1184 }
1185 if (local->basic_rates == 0)
1186 local->basic_rates = HFA384X_RATES_1MBPS | HFA384X_RATES_2MBPS;
1187
1188 if (!local->fw_ap) {
1189 ret = hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
1190 local->tx_rate_control);
1191 if (ret) {
1192 printk("%s: TXRateControl setting to %d failed\n",
1193 dev->name, local->tx_rate_control);
1194 goto fail;
1195 }
1196
1197 ret = hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
1198 local->tx_rate_control);
1199 if (ret) {
1200 printk("%s: cnfSupportedRates setting to %d failed\n",
1201 dev->name, local->tx_rate_control);
1202 }
1203
1204 ret = hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
1205 local->basic_rates);
1206 if (ret) {
1207 printk("%s: cnfBasicRates setting to %d failed\n",
1208 dev->name, local->basic_rates);
1209 }
1210
1211 ret = hostap_set_word(dev, HFA384X_RID_CREATEIBSS, 1);
1212 if (ret) {
1213 printk("%s: Create IBSS setting to 1 failed\n",
1214 dev->name);
1215 }
1216 }
1217
1218 if (local->name_set)
1219 (void) hostap_set_string(dev, HFA384X_RID_CNFOWNNAME,
1220 local->name);
1221
1222 if (hostap_set_encryption(local)) {
1223 printk(KERN_INFO "%s: could not configure encryption\n",
1224 dev->name);
1225 }
1226
1227 (void) hostap_set_antsel(local);
1228
1229 if (hostap_set_roaming(local)) {
1230 printk(KERN_INFO "%s: could not set host roaming\n",
1231 dev->name);
1232 }
1233
1234 if (local->sta_fw_ver >= PRISM2_FW_VER(1,6,3) &&
1235 hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY, local->enh_sec))
1236 printk(KERN_INFO "%s: cnfEnhSecurity setting to 0x%x failed\n",
1237 dev->name, local->enh_sec);
1238
1239 /* 32-bit tallies were added in STA f/w 0.8.0, but they were apparently
1240 * not working correctly (last seven counters report bogus values).
1241 * This has been fixed in 0.8.2, so enable 32-bit tallies only
1242 * beginning with that firmware version. Another bug fix for 32-bit
1243 * tallies in 1.4.0; should 16-bit tallies be used for some other
1244 * versions, too? */
1245 if (local->sta_fw_ver >= PRISM2_FW_VER(0,8,2)) {
1246 if (hostap_set_word(dev, HFA384X_RID_CNFTHIRTY2TALLY, 1)) {
1247 printk(KERN_INFO "%s: cnfThirty2Tally setting "
1248 "failed\n", dev->name);
1249 local->tallies32 = 0;
1250 } else
1251 local->tallies32 = 1;
1252 } else
1253 local->tallies32 = 0;
1254
1255 hostap_set_auth_algs(local);
1256
1257 if (hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
1258 local->fragm_threshold)) {
1259 printk(KERN_INFO "%s: setting FragmentationThreshold to %d "
1260 "failed\n", dev->name, local->fragm_threshold);
1261 }
1262
1263 if (hostap_set_word(dev, HFA384X_RID_RTSTHRESHOLD,
1264 local->rts_threshold)) {
1265 printk(KERN_INFO "%s: setting RTSThreshold to %d failed\n",
1266 dev->name, local->rts_threshold);
1267 }
1268
1269 if (local->manual_retry_count >= 0 &&
1270 hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1271 local->manual_retry_count)) {
1272 printk(KERN_INFO "%s: setting cnfAltRetryCount to %d failed\n",
1273 dev->name, local->manual_retry_count);
1274 }
1275
1276 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1) &&
1277 hfa384x_get_rid(dev, HFA384X_RID_CNFDBMADJUST, &tmp, 2, 1) == 2) {
1278 local->rssi_to_dBm = le16_to_cpu(tmp);
1279 }
1280
1281 if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->wpa &&
1282 hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1)) {
1283 printk(KERN_INFO "%s: setting ssnHandlingMode to 1 failed\n",
1284 dev->name);
1285 }
1286
1287 if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->generic_elem &&
1288 hfa384x_set_rid(dev, HFA384X_RID_GENERICELEMENT,
1289 local->generic_elem, local->generic_elem_len)) {
1290 printk(KERN_INFO "%s: setting genericElement failed\n",
1291 dev->name);
1292 }
1293
1294 fail:
1295 return ret;
1296}
1297
1298
1299static int prism2_hw_init(struct net_device *dev, int initial)
1300{
1301 struct hostap_interface *iface;
1302 local_info_t *local;
1303 int ret, first = 1;
1304 unsigned long start, delay;
1305
1306 PDEBUG(DEBUG_FLOW, "prism2_hw_init()\n");
1307
1308 iface = netdev_priv(dev);
1309 local = iface->local;
1310
1311 clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits);
1312
1313 init:
1314 /* initialize HFA 384x */
1315 ret = hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_INIT, 0);
1316 if (ret) {
1317 printk(KERN_INFO "%s: first command failed - assuming card "
1318 "does not have primary firmware\n", dev_info);
1319 }
1320
1321 if (first && (HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) {
1322 /* EvStat has Cmd bit set in some cases, so retry once if no
1323 * wait was needed */
1324 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
1325 printk(KERN_DEBUG "%s: init command completed too quickly - "
1326 "retrying\n", dev->name);
1327 first = 0;
1328 goto init;
1329 }
1330
1331 start = jiffies;
1332 delay = jiffies + HFA384X_INIT_TIMEOUT;
1333 while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) &&
1334 time_before(jiffies, delay))
1335 yield();
1336 if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) {
1337 printk(KERN_DEBUG "%s: assuming no Primary image in "
1338 "flash - card initialization not completed\n",
1339 dev_info);
1340 local->no_pri = 1;
1341#ifdef PRISM2_DOWNLOAD_SUPPORT
1342 if (local->sram_type == -1)
1343 local->sram_type = prism2_get_ram_size(local);
1344#endif /* PRISM2_DOWNLOAD_SUPPORT */
1345 return 1;
1346 }
1347 local->no_pri = 0;
1348 printk(KERN_DEBUG "prism2_hw_init: initialized in %lu ms\n",
1349 (jiffies - start) * 1000 / HZ);
1350 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
1351 return 0;
1352}
1353
1354
1355static int prism2_hw_init2(struct net_device *dev, int initial)
1356{
1357 struct hostap_interface *iface;
1358 local_info_t *local;
1359 int i;
1360
1361 iface = netdev_priv(dev);
1362 local = iface->local;
1363
1364#ifdef PRISM2_DOWNLOAD_SUPPORT
1365 kfree(local->pda);
1366 if (local->no_pri)
1367 local->pda = NULL;
1368 else
1369 local->pda = prism2_read_pda(dev);
1370#endif /* PRISM2_DOWNLOAD_SUPPORT */
1371
1372 hfa384x_disable_interrupts(dev);
1373
1374#ifndef final_version
1375 HFA384X_OUTW(HFA384X_MAGIC, HFA384X_SWSUPPORT0_OFF);
1376 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
1377 printk("SWSUPPORT0 write/read failed: %04X != %04X\n",
1378 HFA384X_INW(HFA384X_SWSUPPORT0_OFF), HFA384X_MAGIC);
1379 goto failed;
1380 }
1381#endif
1382
1383 if (initial || local->pri_only) {
1384 hfa384x_events_only_cmd(dev);
1385 /* get card version information */
1386 if (prism2_get_version_info(dev, HFA384X_RID_NICID, "NIC") ||
1387 prism2_get_version_info(dev, HFA384X_RID_PRIID, "PRI")) {
1388 hfa384x_disable_interrupts(dev);
1389 goto failed;
1390 }
1391
1392 if (prism2_get_version_info(dev, HFA384X_RID_STAID, "STA")) {
1393 printk(KERN_DEBUG "%s: Failed to read STA f/w version "
1394 "- only Primary f/w present\n", dev->name);
1395 local->pri_only = 1;
1396 return 0;
1397 }
1398 local->pri_only = 0;
1399 hfa384x_disable_interrupts(dev);
1400 }
1401
1402 /* FIX: could convert allocate_fid to use sleeping CmdCompl wait and
1403 * enable interrupts before this. This would also require some sort of
1404 * sleeping AllocEv waiting */
1405
1406 /* allocate TX FIDs */
1407 local->txfid_len = PRISM2_TXFID_LEN;
1408 for (i = 0; i < PRISM2_TXFID_COUNT; i++) {
1409 local->txfid[i] = hfa384x_allocate_fid(dev, local->txfid_len);
1410 if (local->txfid[i] == 0xffff && local->txfid_len > 1600) {
1411 local->txfid[i] = hfa384x_allocate_fid(dev, 1600);
1412 if (local->txfid[i] != 0xffff) {
1413 printk(KERN_DEBUG "%s: Using shorter TX FID "
1414 "(1600 bytes)\n", dev->name);
1415 local->txfid_len = 1600;
1416 }
1417 }
1418 if (local->txfid[i] == 0xffff)
1419 goto failed;
1420 local->intransmitfid[i] = PRISM2_TXFID_EMPTY;
1421 }
1422
1423 hfa384x_events_only_cmd(dev);
1424
1425 if (initial) {
1426 struct list_head *ptr;
1427 prism2_check_sta_fw_version(local);
1428
1429 if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR,
1430 &dev->dev_addr, 6, 1) < 0) {
1431 printk("%s: could not get own MAC address\n",
1432 dev->name);
1433 }
1434 list_for_each(ptr, &local->hostap_interfaces) {
1435 iface = list_entry(ptr, struct hostap_interface, list);
1436 memcpy(iface->dev->dev_addr, dev->dev_addr, ETH_ALEN);
1437 }
1438 } else if (local->fw_ap)
1439 prism2_check_sta_fw_version(local);
1440
1441 prism2_setup_rids(dev);
1442
1443 /* MAC is now configured, but port 0 is not yet enabled */
1444 return 0;
1445
1446 failed:
1447 if (!local->no_pri)
1448 printk(KERN_WARNING "%s: Initialization failed\n", dev_info);
1449 return 1;
1450}
1451
1452
1453static int prism2_hw_enable(struct net_device *dev, int initial)
1454{
1455 struct hostap_interface *iface;
1456 local_info_t *local;
1457 int was_resetting;
1458
1459 iface = netdev_priv(dev);
1460 local = iface->local;
1461 was_resetting = local->hw_resetting;
1462
1463 if (hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL, NULL)) {
1464 printk("%s: MAC port 0 enabling failed\n", dev->name);
1465 return 1;
1466 }
1467
1468 local->hw_ready = 1;
1469 local->hw_reset_tries = 0;
1470 local->hw_resetting = 0;
1471 hfa384x_enable_interrupts(dev);
1472
1473 /* at least D-Link DWL-650 seems to require additional port reset
1474 * before it starts acting as an AP, so reset port automatically
1475 * here just in case */
1476 if (initial && prism2_reset_port(dev)) {
1477 printk("%s: MAC port 0 reseting failed\n", dev->name);
1478 return 1;
1479 }
1480
1481 if (was_resetting && netif_queue_stopped(dev)) {
1482 /* If hw_reset() was called during pending transmit, netif
1483 * queue was stopped. Wake it up now since the wlan card has
1484 * been resetted. */
1485 netif_wake_queue(dev);
1486 }
1487
1488 return 0;
1489}
1490
1491
1492static int prism2_hw_config(struct net_device *dev, int initial)
1493{
1494 struct hostap_interface *iface;
1495 local_info_t *local;
1496
1497 iface = netdev_priv(dev);
1498 local = iface->local;
1499
1500 if (local->hw_downloading)
1501 return 1;
1502
1503 if (prism2_hw_init(dev, initial)) {
1504 return local->no_pri ? 0 : 1;
1505 }
1506
1507 if (prism2_hw_init2(dev, initial))
1508 return 1;
1509
1510 /* Enable firmware if secondary image is loaded and at least one of the
1511 * netdevices is up. */
1512 if (!local->pri_only &&
1513 (initial == 0 || (initial == 2 && local->num_dev_open > 0))) {
1514 if (!local->dev_enabled)
1515 prism2_callback(local, PRISM2_CALLBACK_ENABLE);
1516 local->dev_enabled = 1;
1517 return prism2_hw_enable(dev, initial);
1518 }
1519
1520 return 0;
1521}
1522
1523
1524static void prism2_hw_shutdown(struct net_device *dev, int no_disable)
1525{
1526 struct hostap_interface *iface;
1527 local_info_t *local;
1528
1529 iface = netdev_priv(dev);
1530 local = iface->local;
1531
1532 /* Allow only command completion events during disable */
1533 hfa384x_events_only_cmd(dev);
1534
1535 local->hw_ready = 0;
1536 if (local->dev_enabled)
1537 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
1538 local->dev_enabled = 0;
1539
1540 if (local->func->card_present && !local->func->card_present(local)) {
1541 printk(KERN_DEBUG "%s: card already removed or not configured "
1542 "during shutdown\n", dev->name);
1543 return;
1544 }
1545
1546 if ((no_disable & HOSTAP_HW_NO_DISABLE) == 0 &&
1547 hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL, NULL))
1548 printk(KERN_WARNING "%s: Shutdown failed\n", dev_info);
1549
1550 hfa384x_disable_interrupts(dev);
1551
1552 if (no_disable & HOSTAP_HW_ENABLE_CMDCOMPL)
1553 hfa384x_events_only_cmd(dev);
1554 else
1555 prism2_clear_cmd_queue(local);
1556}
1557
1558
1559static void prism2_hw_reset(struct net_device *dev)
1560{
1561 struct hostap_interface *iface;
1562 local_info_t *local;
1563
1564#if 0
1565 static long last_reset = 0;
1566
1567 /* do not reset card more than once per second to avoid ending up in a
1568 * busy loop reseting the card */
1569 if (time_before_eq(jiffies, last_reset + HZ))
1570 return;
1571 last_reset = jiffies;
1572#endif
1573
1574 iface = netdev_priv(dev);
1575 local = iface->local;
1576
1577 if (in_interrupt()) {
1578 printk(KERN_DEBUG "%s: driver bug - prism2_hw_reset() called "
1579 "in interrupt context\n", dev->name);
1580 return;
1581 }
1582
1583 if (local->hw_downloading)
1584 return;
1585
1586 if (local->hw_resetting) {
1587 printk(KERN_WARNING "%s: %s: already resetting card - "
1588 "ignoring reset request\n", dev_info, dev->name);
1589 return;
1590 }
1591
1592 local->hw_reset_tries++;
1593 if (local->hw_reset_tries > 10) {
1594 printk(KERN_WARNING "%s: too many reset tries, skipping\n",
1595 dev->name);
1596 return;
1597 }
1598
1599 printk(KERN_WARNING "%s: %s: resetting card\n", dev_info, dev->name);
1600 hfa384x_disable_interrupts(dev);
1601 local->hw_resetting = 1;
1602 if (local->func->cor_sreset) {
1603 /* Host system seems to hang in some cases with high traffic
1604 * load or shared interrupts during COR sreset. Disable shared
1605 * interrupts during reset to avoid these crashes. COS sreset
1606 * takes quite a long time, so it is unfortunate that this
1607 * seems to be needed. Anyway, I do not know of any better way
1608 * of avoiding the crash. */
1609 disable_irq(dev->irq);
1610 local->func->cor_sreset(local);
1611 enable_irq(dev->irq);
1612 }
1613 prism2_hw_shutdown(dev, 1);
1614 prism2_hw_config(dev, 0);
1615 local->hw_resetting = 0;
1616
1617#ifdef PRISM2_DOWNLOAD_SUPPORT
1618 if (local->dl_pri) {
1619 printk(KERN_DEBUG "%s: persistent download of primary "
1620 "firmware\n", dev->name);
1621 if (prism2_download_genesis(local, local->dl_pri) < 0)
1622 printk(KERN_WARNING "%s: download (PRI) failed\n",
1623 dev->name);
1624 }
1625
1626 if (local->dl_sec) {
1627 printk(KERN_DEBUG "%s: persistent download of secondary "
1628 "firmware\n", dev->name);
1629 if (prism2_download_volatile(local, local->dl_sec) < 0)
1630 printk(KERN_WARNING "%s: download (SEC) failed\n",
1631 dev->name);
1632 }
1633#endif /* PRISM2_DOWNLOAD_SUPPORT */
1634
1635 /* TODO: restore beacon TIM bits for STAs that have buffered frames */
1636}
1637
1638
1639static void prism2_schedule_reset(local_info_t *local)
1640{
1641 schedule_work(&local->reset_queue);
1642}
1643
1644
1645/* Called only as scheduled task after noticing card timeout in interrupt
1646 * context */
1647static void handle_reset_queue(void *data)
1648{
1649 local_info_t *local = (local_info_t *) data;
1650
1651 printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name);
1652 prism2_hw_reset(local->dev);
1653
1654 if (netif_queue_stopped(local->dev)) {
1655 int i;
1656
1657 for (i = 0; i < PRISM2_TXFID_COUNT; i++)
1658 if (local->intransmitfid[i] == PRISM2_TXFID_EMPTY) {
1659 PDEBUG(DEBUG_EXTRA, "prism2_tx_timeout: "
1660 "wake up queue\n");
1661 netif_wake_queue(local->dev);
1662 break;
1663 }
1664 }
1665}
1666
1667
1668static int prism2_get_txfid_idx(local_info_t *local)
1669{
1670 int idx, end;
1671 unsigned long flags;
1672
1673 spin_lock_irqsave(&local->txfidlock, flags);
1674 end = idx = local->next_txfid;
1675 do {
1676 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) {
1677 local->intransmitfid[idx] = PRISM2_TXFID_RESERVED;
1678 spin_unlock_irqrestore(&local->txfidlock, flags);
1679 return idx;
1680 }
1681 idx++;
1682 if (idx >= PRISM2_TXFID_COUNT)
1683 idx = 0;
1684 } while (idx != end);
1685 spin_unlock_irqrestore(&local->txfidlock, flags);
1686
1687 PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: "
1688 "packet dropped\n");
1689 local->stats.tx_dropped++;
1690
1691 return -1;
1692}
1693
1694
1695/* Called only from hardware IRQ */
1696static void prism2_transmit_cb(struct net_device *dev, long context,
1697 u16 resp0, u16 res)
1698{
1699 struct hostap_interface *iface;
1700 local_info_t *local;
1701 int idx = (int) context;
1702
1703 iface = netdev_priv(dev);
1704 local = iface->local;
1705
1706 if (res) {
1707 printk(KERN_DEBUG "%s: prism2_transmit_cb - res=0x%02x\n",
1708 dev->name, res);
1709 return;
1710 }
1711
1712 if (idx < 0 || idx >= PRISM2_TXFID_COUNT) {
1713 printk(KERN_DEBUG "%s: prism2_transmit_cb called with invalid "
1714 "idx=%d\n", dev->name, idx);
1715 return;
1716 }
1717
1718 if (!test_and_clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
1719 printk(KERN_DEBUG "%s: driver bug: prism2_transmit_cb called "
1720 "with no pending transmit\n", dev->name);
1721 }
1722
1723 if (netif_queue_stopped(dev)) {
1724 /* ready for next TX, so wake up queue that was stopped in
1725 * prism2_transmit() */
1726 netif_wake_queue(dev);
1727 }
1728
1729 spin_lock(&local->txfidlock);
1730
1731 /* With reclaim, Resp0 contains new txfid for transmit; the old txfid
1732 * will be automatically allocated for the next TX frame */
1733 local->intransmitfid[idx] = resp0;
1734
1735 PDEBUG(DEBUG_FID, "%s: prism2_transmit_cb: txfid[%d]=0x%04x, "
1736 "resp0=0x%04x, transmit_txfid=0x%04x\n",
1737 dev->name, idx, local->txfid[idx],
1738 resp0, local->intransmitfid[local->next_txfid]);
1739
1740 idx++;
1741 if (idx >= PRISM2_TXFID_COUNT)
1742 idx = 0;
1743 local->next_txfid = idx;
1744
1745 /* check if all TX buffers are occupied */
1746 do {
1747 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY) {
1748 spin_unlock(&local->txfidlock);
1749 return;
1750 }
1751 idx++;
1752 if (idx >= PRISM2_TXFID_COUNT)
1753 idx = 0;
1754 } while (idx != local->next_txfid);
1755 spin_unlock(&local->txfidlock);
1756
1757 /* no empty TX buffers, stop queue */
1758 netif_stop_queue(dev);
1759}
1760
1761
1762/* Called only from software IRQ if PCI bus master is not used (with bus master
1763 * this can be called both from software and hardware IRQ) */
1764static int prism2_transmit(struct net_device *dev, int idx)
1765{
1766 struct hostap_interface *iface;
1767 local_info_t *local;
1768 int res;
1769
1770 iface = netdev_priv(dev);
1771 local = iface->local;
1772
1773 /* The driver tries to stop netif queue so that there would not be
1774 * more than one attempt to transmit frames going on; check that this
1775 * is really the case */
1776
1777 if (test_and_set_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
1778 printk(KERN_DEBUG "%s: driver bug - prism2_transmit() called "
1779 "when previous TX was pending\n", dev->name);
1780 return -1;
1781 }
1782
1783 /* stop the queue for the time that transmit is pending */
1784 netif_stop_queue(dev);
1785
1786 /* transmit packet */
1787 res = hfa384x_cmd_callback(
1788 dev,
1789 HFA384X_CMDCODE_TRANSMIT | HFA384X_CMD_TX_RECLAIM,
1790 local->txfid[idx],
1791 prism2_transmit_cb, (long) idx);
1792
1793 if (res) {
1794 struct net_device_stats *stats;
1795 printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT "
1796 "failed (res=%d)\n", dev->name, res);
1797 stats = hostap_get_stats(dev);
1798 stats->tx_dropped++;
1799 netif_wake_queue(dev);
1800 return -1;
1801 }
1802 dev->trans_start = jiffies;
1803
1804 /* Since we did not wait for command completion, the card continues
1805 * to process on the background and we will finish handling when
1806 * command completion event is handled (prism2_cmd_ev() function) */
1807
1808 return 0;
1809}
1810
1811
1812/* Send IEEE 802.11 frame (convert the header into Prism2 TX descriptor and
1813 * send the payload with this descriptor) */
1814/* Called only from software IRQ */
1815static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
1816{
1817 struct hostap_interface *iface;
1818 local_info_t *local;
1819 struct hfa384x_tx_frame txdesc;
1820 struct hostap_skb_tx_data *meta;
1821 int hdr_len, data_len, idx, res, ret = -1;
1822 u16 tx_control, fc;
1823
1824 iface = netdev_priv(dev);
1825 local = iface->local;
1826
1827 meta = (struct hostap_skb_tx_data *) skb->cb;
1828
1829 prism2_callback(local, PRISM2_CALLBACK_TX_START);
1830
1831 if ((local->func->card_present && !local->func->card_present(local)) ||
1832 !local->hw_ready || local->hw_downloading || local->pri_only) {
1833 if (net_ratelimit()) {
1834 printk(KERN_DEBUG "%s: prism2_tx_80211: hw not ready -"
1835 " skipping\n", dev->name);
1836 }
1837 goto fail;
1838 }
1839
1840 memset(&txdesc, 0, sizeof(txdesc));
1841
1842 /* skb->data starts with txdesc->frame_control */
1843 hdr_len = 24;
1844 memcpy(&txdesc.frame_control, skb->data, hdr_len);
1845 fc = le16_to_cpu(txdesc.frame_control);
1846 if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
1847 (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS) &&
1848 skb->len >= 30) {
1849 /* Addr4 */
1850 memcpy(txdesc.addr4, skb->data + hdr_len, ETH_ALEN);
1851 hdr_len += ETH_ALEN;
1852 }
1853
1854 tx_control = local->tx_control;
1855 if (meta->tx_cb_idx) {
1856 tx_control |= HFA384X_TX_CTRL_TX_OK;
1857 txdesc.sw_support = cpu_to_le16(meta->tx_cb_idx);
1858 }
1859 txdesc.tx_control = cpu_to_le16(tx_control);
1860 txdesc.tx_rate = meta->rate;
1861
1862 data_len = skb->len - hdr_len;
1863 txdesc.data_len = cpu_to_le16(data_len);
1864 txdesc.len = cpu_to_be16(data_len);
1865
1866 idx = prism2_get_txfid_idx(local);
1867 if (idx < 0)
1868 goto fail;
1869
1870 if (local->frame_dump & PRISM2_DUMP_TX_HDR)
1871 hostap_dump_tx_header(dev->name, &txdesc);
1872
1873 spin_lock(&local->baplock);
1874 res = hfa384x_setup_bap(dev, BAP0, local->txfid[idx], 0);
1875
1876 if (!res)
1877 res = hfa384x_to_bap(dev, BAP0, &txdesc, sizeof(txdesc));
1878 if (!res)
1879 res = hfa384x_to_bap(dev, BAP0, skb->data + hdr_len,
1880 skb->len - hdr_len);
1881 spin_unlock(&local->baplock);
1882
1883 if (!res)
1884 res = prism2_transmit(dev, idx);
1885 if (res) {
1886 printk(KERN_DEBUG "%s: prism2_tx_80211 - to BAP0 failed\n",
1887 dev->name);
1888 local->intransmitfid[idx] = PRISM2_TXFID_EMPTY;
1889 schedule_work(&local->reset_queue);
1890 goto fail;
1891 }
1892
1893 ret = 0;
1894
1895fail:
1896 prism2_callback(local, PRISM2_CALLBACK_TX_END);
1897 return ret;
1898}
1899
1900
1901/* Some SMP systems have reported number of odd errors with hostap_pci. fid
1902 * register has changed values between consecutive reads for an unknown reason.
1903 * This should really not happen, so more debugging is needed. This test
1904 * version is a big slower, but it will detect most of such register changes
1905 * and will try to get the correct fid eventually. */
1906#define EXTRA_FID_READ_TESTS
1907
1908static inline u16 prism2_read_fid_reg(struct net_device *dev, u16 reg)
1909{
1910#ifdef EXTRA_FID_READ_TESTS
1911 u16 val, val2, val3;
1912 int i;
1913
1914 for (i = 0; i < 10; i++) {
1915 val = HFA384X_INW(reg);
1916 val2 = HFA384X_INW(reg);
1917 val3 = HFA384X_INW(reg);
1918
1919 if (val == val2 && val == val3)
1920 return val;
1921
1922 printk(KERN_DEBUG "%s: detected fid change (try=%d, reg=%04x):"
1923 " %04x %04x %04x\n",
1924 dev->name, i, reg, val, val2, val3);
1925 if ((val == val2 || val == val3) && val != 0)
1926 return val;
1927 if (val2 == val3 && val2 != 0)
1928 return val2;
1929 }
1930 printk(KERN_WARNING "%s: Uhhuh.. could not read good fid from reg "
1931 "%04x (%04x %04x %04x)\n", dev->name, reg, val, val2, val3);
1932 return val;
1933#else /* EXTRA_FID_READ_TESTS */
1934 return HFA384X_INW(reg);
1935#endif /* EXTRA_FID_READ_TESTS */
1936}
1937
1938
1939/* Called only as a tasklet (software IRQ) */
1940static void prism2_rx(local_info_t *local)
1941{
1942 struct net_device *dev = local->dev;
1943 int res, rx_pending = 0;
1944 u16 len, hdr_len, rxfid, status, macport;
1945 struct net_device_stats *stats;
1946 struct hfa384x_rx_frame rxdesc;
1947 struct sk_buff *skb = NULL;
1948
1949 prism2_callback(local, PRISM2_CALLBACK_RX_START);
1950 stats = hostap_get_stats(dev);
1951
1952 rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF);
1953#ifndef final_version
1954 if (rxfid == 0) {
1955 rxfid = HFA384X_INW(HFA384X_RXFID_OFF);
1956 printk(KERN_DEBUG "prism2_rx: rxfid=0 (next 0x%04x)\n",
1957 rxfid);
1958 if (rxfid == 0) {
1959 schedule_work(&local->reset_queue);
1960 goto rx_dropped;
1961 }
1962 /* try to continue with the new rxfid value */
1963 }
1964#endif
1965
1966 spin_lock(&local->baplock);
1967 res = hfa384x_setup_bap(dev, BAP0, rxfid, 0);
1968 if (!res)
1969 res = hfa384x_from_bap(dev, BAP0, &rxdesc, sizeof(rxdesc));
1970
1971 if (res) {
1972 spin_unlock(&local->baplock);
1973 printk(KERN_DEBUG "%s: copy from BAP0 failed %d\n", dev->name,
1974 res);
1975 if (res == -ETIMEDOUT) {
1976 schedule_work(&local->reset_queue);
1977 }
1978 goto rx_dropped;
1979 }
1980
1981 len = le16_to_cpu(rxdesc.data_len);
1982 hdr_len = sizeof(rxdesc);
1983 status = le16_to_cpu(rxdesc.status);
1984 macport = (status >> 8) & 0x07;
1985
1986 /* Drop frames with too large reported payload length. Monitor mode
1987 * seems to sometimes pass frames (e.g., ctrl::ack) with signed and
1988 * negative value, so allow also values 65522 .. 65534 (-14 .. -2) for
1989 * macport 7 */
1990 if (len > PRISM2_DATA_MAXLEN + 8 /* WEP */) {
1991 if (macport == 7 && local->iw_mode == IW_MODE_MONITOR) {
1992 if (len >= (u16) -14) {
1993 hdr_len -= 65535 - len;
1994 hdr_len--;
1995 }
1996 len = 0;
1997 } else {
1998 spin_unlock(&local->baplock);
1999 printk(KERN_DEBUG "%s: Received frame with invalid "
2000 "length 0x%04x\n", dev->name, len);
2001 hostap_dump_rx_header(dev->name, &rxdesc);
2002 goto rx_dropped;
2003 }
2004 }
2005
2006 skb = dev_alloc_skb(len + hdr_len);
2007 if (!skb) {
2008 spin_unlock(&local->baplock);
2009 printk(KERN_DEBUG "%s: RX failed to allocate skb\n",
2010 dev->name);
2011 goto rx_dropped;
2012 }
2013 skb->dev = dev;
2014 memcpy(skb_put(skb, hdr_len), &rxdesc, hdr_len);
2015
2016 if (len > 0)
2017 res = hfa384x_from_bap(dev, BAP0, skb_put(skb, len), len);
2018 spin_unlock(&local->baplock);
2019 if (res) {
2020 printk(KERN_DEBUG "%s: RX failed to read "
2021 "frame data\n", dev->name);
2022 goto rx_dropped;
2023 }
2024
2025 skb_queue_tail(&local->rx_list, skb);
2026 tasklet_schedule(&local->rx_tasklet);
2027
2028 rx_exit:
2029 prism2_callback(local, PRISM2_CALLBACK_RX_END);
2030 if (!rx_pending) {
2031 HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
2032 }
2033
2034 return;
2035
2036 rx_dropped:
2037 stats->rx_dropped++;
2038 if (skb)
2039 dev_kfree_skb(skb);
2040 goto rx_exit;
2041}
2042
2043
2044/* Called only as a tasklet (software IRQ) */
2045static void hostap_rx_skb(local_info_t *local, struct sk_buff *skb)
2046{
2047 struct hfa384x_rx_frame *rxdesc;
2048 struct net_device *dev = skb->dev;
2049 struct hostap_80211_rx_status stats;
2050 int hdrlen, rx_hdrlen;
2051
2052 rx_hdrlen = sizeof(*rxdesc);
2053 if (skb->len < sizeof(*rxdesc)) {
2054 /* Allow monitor mode to receive shorter frames */
2055 if (local->iw_mode == IW_MODE_MONITOR &&
2056 skb->len >= sizeof(*rxdesc) - 30) {
2057 rx_hdrlen = skb->len;
2058 } else {
2059 dev_kfree_skb(skb);
2060 return;
2061 }
2062 }
2063
2064 rxdesc = (struct hfa384x_rx_frame *) skb->data;
2065
2066 if (local->frame_dump & PRISM2_DUMP_RX_HDR &&
2067 skb->len >= sizeof(*rxdesc))
2068 hostap_dump_rx_header(dev->name, rxdesc);
2069
2070 if (le16_to_cpu(rxdesc->status) & HFA384X_RX_STATUS_FCSERR &&
2071 (!local->monitor_allow_fcserr ||
2072 local->iw_mode != IW_MODE_MONITOR))
2073 goto drop;
2074
2075 if (skb->len > PRISM2_DATA_MAXLEN) {
2076 printk(KERN_DEBUG "%s: RX: len(%d) > MAX(%d)\n",
2077 dev->name, skb->len, PRISM2_DATA_MAXLEN);
2078 goto drop;
2079 }
2080
2081 stats.mac_time = le32_to_cpu(rxdesc->time);
2082 stats.signal = rxdesc->signal - local->rssi_to_dBm;
2083 stats.noise = rxdesc->silence - local->rssi_to_dBm;
2084 stats.rate = rxdesc->rate;
2085
2086 /* Convert Prism2 RX structure into IEEE 802.11 header */
2087 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control));
2088 if (hdrlen > rx_hdrlen)
2089 hdrlen = rx_hdrlen;
2090
2091 memmove(skb_pull(skb, rx_hdrlen - hdrlen),
2092 &rxdesc->frame_control, hdrlen);
2093
2094 hostap_80211_rx(dev, skb, &stats);
2095 return;
2096
2097 drop:
2098 dev_kfree_skb(skb);
2099}
2100
2101
2102/* Called only as a tasklet (software IRQ) */
2103static void hostap_rx_tasklet(unsigned long data)
2104{
2105 local_info_t *local = (local_info_t *) data;
2106 struct sk_buff *skb;
2107
2108 while ((skb = skb_dequeue(&local->rx_list)) != NULL)
2109 hostap_rx_skb(local, skb);
2110}
2111
2112
2113/* Called only from hardware IRQ */
2114static void prism2_alloc_ev(struct net_device *dev)
2115{
2116 struct hostap_interface *iface;
2117 local_info_t *local;
2118 int idx;
2119 u16 fid;
2120
2121 iface = netdev_priv(dev);
2122 local = iface->local;
2123
2124 fid = prism2_read_fid_reg(dev, HFA384X_ALLOCFID_OFF);
2125
2126 PDEBUG(DEBUG_FID, "FID: interrupt: ALLOC - fid=0x%04x\n", fid);
2127
2128 spin_lock(&local->txfidlock);
2129 idx = local->next_alloc;
2130
2131 do {
2132 if (local->txfid[idx] == fid) {
2133 PDEBUG(DEBUG_FID, "FID: found matching txfid[%d]\n",
2134 idx);
2135
2136#ifndef final_version
2137 if (local->intransmitfid[idx] == PRISM2_TXFID_EMPTY)
2138 printk("Already released txfid found at idx "
2139 "%d\n", idx);
2140 if (local->intransmitfid[idx] == PRISM2_TXFID_RESERVED)
2141 printk("Already reserved txfid found at idx "
2142 "%d\n", idx);
2143#endif
2144 local->intransmitfid[idx] = PRISM2_TXFID_EMPTY;
2145 idx++;
2146 local->next_alloc = idx >= PRISM2_TXFID_COUNT ? 0 :
2147 idx;
2148
2149 if (!test_bit(HOSTAP_BITS_TRANSMIT, &local->bits) &&
2150 netif_queue_stopped(dev))
2151 netif_wake_queue(dev);
2152
2153 spin_unlock(&local->txfidlock);
2154 return;
2155 }
2156
2157 idx++;
2158 if (idx >= PRISM2_TXFID_COUNT)
2159 idx = 0;
2160 } while (idx != local->next_alloc);
2161
2162 printk(KERN_WARNING "%s: could not find matching txfid (0x%04x, new "
2163 "read 0x%04x) for alloc event\n", dev->name, fid,
2164 HFA384X_INW(HFA384X_ALLOCFID_OFF));
2165 printk(KERN_DEBUG "TXFIDs:");
2166 for (idx = 0; idx < PRISM2_TXFID_COUNT; idx++)
2167 printk(" %04x[%04x]", local->txfid[idx],
2168 local->intransmitfid[idx]);
2169 printk("\n");
2170 spin_unlock(&local->txfidlock);
2171
2172 /* FIX: should probably schedule reset; reference to one txfid was lost
2173 * completely.. Bad things will happen if we run out of txfids
2174 * Actually, this will cause netdev watchdog to notice TX timeout and
2175 * then card reset after all txfids have been leaked. */
2176}
2177
2178
2179/* Called only as a tasklet (software IRQ) */
2180static void hostap_tx_callback(local_info_t *local,
2181 struct hfa384x_tx_frame *txdesc, int ok,
2182 char *payload)
2183{
2184 u16 sw_support, hdrlen, len;
2185 struct sk_buff *skb;
2186 struct hostap_tx_callback_info *cb;
2187
2188 /* Make sure that frame was from us. */
2189 if (memcmp(txdesc->addr2, local->dev->dev_addr, ETH_ALEN)) {
2190 printk(KERN_DEBUG "%s: TX callback - foreign frame\n",
2191 local->dev->name);
2192 return;
2193 }
2194
2195 sw_support = le16_to_cpu(txdesc->sw_support);
2196
2197 spin_lock(&local->lock);
2198 cb = local->tx_callback;
2199 while (cb != NULL && cb->idx != sw_support)
2200 cb = cb->next;
2201 spin_unlock(&local->lock);
2202
2203 if (cb == NULL) {
2204 printk(KERN_DEBUG "%s: could not find TX callback (idx %d)\n",
2205 local->dev->name, sw_support);
2206 return;
2207 }
2208
2209 hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control));
2210 len = le16_to_cpu(txdesc->data_len);
2211 skb = dev_alloc_skb(hdrlen + len);
2212 if (skb == NULL) {
2213 printk(KERN_DEBUG "%s: hostap_tx_callback failed to allocate "
2214 "skb\n", local->dev->name);
2215 return;
2216 }
2217
2218 memcpy(skb_put(skb, hdrlen), (void *) &txdesc->frame_control, hdrlen);
2219 if (payload)
2220 memcpy(skb_put(skb, len), payload, len);
2221
2222 skb->dev = local->dev;
2223 skb->mac.raw = skb->data;
2224
2225 cb->func(skb, ok, cb->data);
2226}
2227
2228
2229/* Called only as a tasklet (software IRQ) */
2230static int hostap_tx_compl_read(local_info_t *local, int error,
2231 struct hfa384x_tx_frame *txdesc,
2232 char **payload)
2233{
2234 u16 fid, len;
2235 int res, ret = 0;
2236 struct net_device *dev = local->dev;
2237
2238 fid = prism2_read_fid_reg(dev, HFA384X_TXCOMPLFID_OFF);
2239
2240 PDEBUG(DEBUG_FID, "interrupt: TX (err=%d) - fid=0x%04x\n", fid, error);
2241
2242 spin_lock(&local->baplock);
2243 res = hfa384x_setup_bap(dev, BAP0, fid, 0);
2244 if (!res)
2245 res = hfa384x_from_bap(dev, BAP0, txdesc, sizeof(*txdesc));
2246 if (res) {
2247 PDEBUG(DEBUG_EXTRA, "%s: TX (err=%d) - fid=0x%04x - could not "
2248 "read txdesc\n", dev->name, error, fid);
2249 if (res == -ETIMEDOUT) {
2250 schedule_work(&local->reset_queue);
2251 }
2252 ret = -1;
2253 goto fail;
2254 }
2255 if (txdesc->sw_support) {
2256 len = le16_to_cpu(txdesc->data_len);
2257 if (len < PRISM2_DATA_MAXLEN) {
2258 *payload = (char *) kmalloc(len, GFP_ATOMIC);
2259 if (*payload == NULL ||
2260 hfa384x_from_bap(dev, BAP0, *payload, len)) {
2261 PDEBUG(DEBUG_EXTRA, "%s: could not read TX "
2262 "frame payload\n", dev->name);
2263 kfree(*payload);
2264 *payload = NULL;
2265 ret = -1;
2266 goto fail;
2267 }
2268 }
2269 }
2270
2271 fail:
2272 spin_unlock(&local->baplock);
2273
2274 return ret;
2275}
2276
2277
2278/* Called only as a tasklet (software IRQ) */
2279static void prism2_tx_ev(local_info_t *local)
2280{
2281 struct net_device *dev = local->dev;
2282 char *payload = NULL;
2283 struct hfa384x_tx_frame txdesc;
2284
2285 if (hostap_tx_compl_read(local, 0, &txdesc, &payload))
2286 goto fail;
2287
2288 if (local->frame_dump & PRISM2_DUMP_TX_HDR) {
2289 PDEBUG(DEBUG_EXTRA, "%s: TX - status=0x%04x "
2290 "retry_count=%d tx_rate=%d seq_ctrl=%d "
2291 "duration_id=%d\n",
2292 dev->name, le16_to_cpu(txdesc.status),
2293 txdesc.retry_count, txdesc.tx_rate,
2294 le16_to_cpu(txdesc.seq_ctrl),
2295 le16_to_cpu(txdesc.duration_id));
2296 }
2297
2298 if (txdesc.sw_support)
2299 hostap_tx_callback(local, &txdesc, 1, payload);
2300 kfree(payload);
2301
2302 fail:
2303 HFA384X_OUTW(HFA384X_EV_TX, HFA384X_EVACK_OFF);
2304}
2305
2306
2307/* Called only as a tasklet (software IRQ) */
2308static void hostap_sta_tx_exc_tasklet(unsigned long data)
2309{
2310 local_info_t *local = (local_info_t *) data;
2311 struct sk_buff *skb;
2312
2313 while ((skb = skb_dequeue(&local->sta_tx_exc_list)) != NULL) {
2314 struct hfa384x_tx_frame *txdesc =
2315 (struct hfa384x_tx_frame *) skb->data;
2316
2317 if (skb->len >= sizeof(*txdesc)) {
2318 /* Convert Prism2 RX structure into IEEE 802.11 header
2319 */
2320 u16 fc = le16_to_cpu(txdesc->frame_control);
2321 int hdrlen = hostap_80211_get_hdrlen(fc);
2322 memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen),
2323 &txdesc->frame_control, hdrlen);
2324
2325 hostap_handle_sta_tx_exc(local, skb);
2326 }
2327 dev_kfree_skb(skb);
2328 }
2329}
2330
2331
2332/* Called only as a tasklet (software IRQ) */
2333static void prism2_txexc(local_info_t *local)
2334{
2335 struct net_device *dev = local->dev;
2336 u16 status, fc;
2337 int show_dump, res;
2338 char *payload = NULL;
2339 struct hfa384x_tx_frame txdesc;
2340
2341 show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
2342 local->stats.tx_errors++;
2343
2344 res = hostap_tx_compl_read(local, 1, &txdesc, &payload);
2345 HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF);
2346 if (res)
2347 return;
2348
2349 status = le16_to_cpu(txdesc.status);
2350
2351 /* We produce a TXDROP event only for retry or lifetime
2352 * exceeded, because that's the only status that really mean
2353 * that this particular node went away.
2354 * Other errors means that *we* screwed up. - Jean II */
2355 if (status & (HFA384X_TX_STATUS_RETRYERR | HFA384X_TX_STATUS_AGEDERR))
2356 {
2357 union iwreq_data wrqu;
2358
2359 /* Copy 802.11 dest address. */
2360 memcpy(wrqu.addr.sa_data, txdesc.addr1, ETH_ALEN);
2361 wrqu.addr.sa_family = ARPHRD_ETHER;
2362 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
2363 } else
2364 show_dump = 1;
2365
2366 if (local->iw_mode == IW_MODE_MASTER ||
2367 local->iw_mode == IW_MODE_REPEAT ||
2368 local->wds_type & HOSTAP_WDS_AP_CLIENT) {
2369 struct sk_buff *skb;
2370 skb = dev_alloc_skb(sizeof(txdesc));
2371 if (skb) {
2372 memcpy(skb_put(skb, sizeof(txdesc)), &txdesc,
2373 sizeof(txdesc));
2374 skb_queue_tail(&local->sta_tx_exc_list, skb);
2375 tasklet_schedule(&local->sta_tx_exc_tasklet);
2376 }
2377 }
2378
2379 if (txdesc.sw_support)
2380 hostap_tx_callback(local, &txdesc, 0, payload);
2381 kfree(payload);
2382
2383 if (!show_dump)
2384 return;
2385
2386 PDEBUG(DEBUG_EXTRA, "%s: TXEXC - status=0x%04x (%s%s%s%s)"
2387 " tx_control=%04x\n",
2388 dev->name, status,
2389 status & HFA384X_TX_STATUS_RETRYERR ? "[RetryErr]" : "",
2390 status & HFA384X_TX_STATUS_AGEDERR ? "[AgedErr]" : "",
2391 status & HFA384X_TX_STATUS_DISCON ? "[Discon]" : "",
2392 status & HFA384X_TX_STATUS_FORMERR ? "[FormErr]" : "",
2393 le16_to_cpu(txdesc.tx_control));
2394
2395 fc = le16_to_cpu(txdesc.frame_control);
2396 PDEBUG(DEBUG_EXTRA, " retry_count=%d tx_rate=%d fc=0x%04x "
2397 "(%s%s%s::%d%s%s)\n",
2398 txdesc.retry_count, txdesc.tx_rate, fc,
2399 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT ? "Mgmt" : "",
2400 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL ? "Ctrl" : "",
2401 WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA ? "Data" : "",
2402 WLAN_FC_GET_STYPE(fc) >> 4,
2403 fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
2404 fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
2405 PDEBUG(DEBUG_EXTRA, " A1=" MACSTR " A2=" MACSTR " A3="
2406 MACSTR " A4=" MACSTR "\n",
2407 MAC2STR(txdesc.addr1), MAC2STR(txdesc.addr2),
2408 MAC2STR(txdesc.addr3), MAC2STR(txdesc.addr4));
2409}
2410
2411
2412/* Called only as a tasklet (software IRQ) */
2413static void hostap_info_tasklet(unsigned long data)
2414{
2415 local_info_t *local = (local_info_t *) data;
2416 struct sk_buff *skb;
2417
2418 while ((skb = skb_dequeue(&local->info_list)) != NULL) {
2419 hostap_info_process(local, skb);
2420 dev_kfree_skb(skb);
2421 }
2422}
2423
2424
2425/* Called only as a tasklet (software IRQ) */
2426static void prism2_info(local_info_t *local)
2427{
2428 struct net_device *dev = local->dev;
2429 u16 fid;
2430 int res, left;
2431 struct hfa384x_info_frame info;
2432 struct sk_buff *skb;
2433
2434 fid = HFA384X_INW(HFA384X_INFOFID_OFF);
2435
2436 spin_lock(&local->baplock);
2437 res = hfa384x_setup_bap(dev, BAP0, fid, 0);
2438 if (!res)
2439 res = hfa384x_from_bap(dev, BAP0, &info, sizeof(info));
2440 if (res) {
2441 spin_unlock(&local->baplock);
2442 printk(KERN_DEBUG "Could not get info frame (fid=0x%04x)\n",
2443 fid);
2444 if (res == -ETIMEDOUT) {
2445 schedule_work(&local->reset_queue);
2446 }
2447 goto out;
2448 }
2449
2450 le16_to_cpus(&info.len);
2451 le16_to_cpus(&info.type);
2452 left = (info.len - 1) * 2;
2453
2454 if (info.len & 0x8000 || info.len == 0 || left > 2060) {
2455 /* data register seems to give 0x8000 in some error cases even
2456 * though busy bit is not set in offset register;
2457 * in addition, length must be at least 1 due to type field */
2458 spin_unlock(&local->baplock);
2459 printk(KERN_DEBUG "%s: Received info frame with invalid "
2460 "length 0x%04x (type 0x%04x)\n", dev->name, info.len,
2461 info.type);
2462 goto out;
2463 }
2464
2465 skb = dev_alloc_skb(sizeof(info) + left);
2466 if (skb == NULL) {
2467 spin_unlock(&local->baplock);
2468 printk(KERN_DEBUG "%s: Could not allocate skb for info "
2469 "frame\n", dev->name);
2470 goto out;
2471 }
2472
2473 memcpy(skb_put(skb, sizeof(info)), &info, sizeof(info));
2474 if (left > 0 && hfa384x_from_bap(dev, BAP0, skb_put(skb, left), left))
2475 {
2476 spin_unlock(&local->baplock);
2477 printk(KERN_WARNING "%s: Info frame read failed (fid=0x%04x, "
2478 "len=0x%04x, type=0x%04x\n",
2479 dev->name, fid, info.len, info.type);
2480 dev_kfree_skb(skb);
2481 goto out;
2482 }
2483 spin_unlock(&local->baplock);
2484
2485 skb_queue_tail(&local->info_list, skb);
2486 tasklet_schedule(&local->info_tasklet);
2487
2488 out:
2489 HFA384X_OUTW(HFA384X_EV_INFO, HFA384X_EVACK_OFF);
2490}
2491
2492
2493/* Called only as a tasklet (software IRQ) */
2494static void hostap_bap_tasklet(unsigned long data)
2495{
2496 local_info_t *local = (local_info_t *) data;
2497 struct net_device *dev = local->dev;
2498 u16 ev;
2499 int frames = 30;
2500
2501 if (local->func->card_present && !local->func->card_present(local))
2502 return;
2503
2504 set_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits);
2505
2506 /* Process all pending BAP events without generating new interrupts
2507 * for them */
2508 while (frames-- > 0) {
2509 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2510 if (ev == 0xffff || !(ev & HFA384X_BAP0_EVENTS))
2511 break;
2512 if (ev & HFA384X_EV_RX)
2513 prism2_rx(local);
2514 if (ev & HFA384X_EV_INFO)
2515 prism2_info(local);
2516 if (ev & HFA384X_EV_TX)
2517 prism2_tx_ev(local);
2518 if (ev & HFA384X_EV_TXEXC)
2519 prism2_txexc(local);
2520 }
2521
2522 set_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits);
2523 clear_bit(HOSTAP_BITS_BAP_TASKLET, &local->bits);
2524
2525 /* Enable interrupts for new BAP events */
2526 hfa384x_events_all(dev);
2527 clear_bit(HOSTAP_BITS_BAP_TASKLET2, &local->bits);
2528}
2529
2530
2531/* Called only from hardware IRQ */
2532static void prism2_infdrop(struct net_device *dev)
2533{
2534 static unsigned long last_inquire = 0;
2535
2536 PDEBUG(DEBUG_EXTRA, "%s: INFDROP event\n", dev->name);
2537
2538 /* some firmware versions seem to get stuck with
2539 * full CommTallies in high traffic load cases; every
2540 * packet will then cause INFDROP event and CommTallies
2541 * info frame will not be sent automatically. Try to
2542 * get out of this state by inquiring CommTallies. */
2543 if (!last_inquire || time_after(jiffies, last_inquire + HZ)) {
2544 hfa384x_cmd_callback(dev, HFA384X_CMDCODE_INQUIRE,
2545 HFA384X_INFO_COMMTALLIES, NULL, 0);
2546 last_inquire = jiffies;
2547 }
2548}
2549
2550
2551/* Called only from hardware IRQ */
2552static void prism2_ev_tick(struct net_device *dev)
2553{
2554 struct hostap_interface *iface;
2555 local_info_t *local;
2556 u16 evstat, inten;
2557 static int prev_stuck = 0;
2558
2559 iface = netdev_priv(dev);
2560 local = iface->local;
2561
2562 if (time_after(jiffies, local->last_tick_timer + 5 * HZ) &&
2563 local->last_tick_timer) {
2564 evstat = HFA384X_INW(HFA384X_EVSTAT_OFF);
2565 inten = HFA384X_INW(HFA384X_INTEN_OFF);
2566 if (!prev_stuck) {
2567 printk(KERN_INFO "%s: SW TICK stuck? "
2568 "bits=0x%lx EvStat=%04x IntEn=%04x\n",
2569 dev->name, local->bits, evstat, inten);
2570 }
2571 local->sw_tick_stuck++;
2572 if ((evstat & HFA384X_BAP0_EVENTS) &&
2573 (inten & HFA384X_BAP0_EVENTS)) {
2574 printk(KERN_INFO "%s: trying to recover from IRQ "
2575 "hang\n", dev->name);
2576 hfa384x_events_no_bap0(dev);
2577 }
2578 prev_stuck = 1;
2579 } else
2580 prev_stuck = 0;
2581}
2582
2583
2584/* Called only from hardware IRQ */
2585static inline void prism2_check_magic(local_info_t *local)
2586{
2587 /* at least PCI Prism2.5 with bus mastering seems to sometimes
2588 * return 0x0000 in SWSUPPORT0 for unknown reason, but re-reading the
2589 * register once or twice seems to get the correct value.. PCI cards
2590 * cannot anyway be removed during normal operation, so there is not
2591 * really any need for this verification with them. */
2592
2593#ifndef PRISM2_PCI
2594#ifndef final_version
2595 static unsigned long last_magic_err = 0;
2596 struct net_device *dev = local->dev;
2597
2598 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) {
2599 if (!local->hw_ready)
2600 return;
2601 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
2602 if (time_after(jiffies, last_magic_err + 10 * HZ)) {
2603 printk("%s: Interrupt, but SWSUPPORT0 does not match: "
2604 "%04X != %04X - card removed?\n", dev->name,
2605 HFA384X_INW(HFA384X_SWSUPPORT0_OFF),
2606 HFA384X_MAGIC);
2607 last_magic_err = jiffies;
2608 } else if (net_ratelimit()) {
2609 printk(KERN_DEBUG "%s: interrupt - SWSUPPORT0=%04x "
2610 "MAGIC=%04x\n", dev->name,
2611 HFA384X_INW(HFA384X_SWSUPPORT0_OFF),
2612 HFA384X_MAGIC);
2613 }
2614 if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != 0xffff)
2615 schedule_work(&local->reset_queue);
2616 return;
2617 }
2618#endif /* final_version */
2619#endif /* !PRISM2_PCI */
2620}
2621
2622
2623/* Called only from hardware IRQ */
2624static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2625{
2626 struct net_device *dev = (struct net_device *) dev_id;
2627 struct hostap_interface *iface;
2628 local_info_t *local;
2629 int events = 0;
2630 u16 ev;
2631
2632 iface = netdev_priv(dev);
2633 local = iface->local;
2634
2635 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
2636
2637 if (local->func->card_present && !local->func->card_present(local)) {
2638 if (net_ratelimit()) {
2639 printk(KERN_DEBUG "%s: Interrupt, but dev not OK\n",
2640 dev->name);
2641 }
2642 return IRQ_HANDLED;
2643 }
2644
2645 prism2_check_magic(local);
2646
2647 for (;;) {
2648 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2649 if (ev == 0xffff) {
2650 if (local->shutdown)
2651 return IRQ_HANDLED;
2652 HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);
2653 printk(KERN_DEBUG "%s: prism2_interrupt: ev=0xffff\n",
2654 dev->name);
2655 return IRQ_HANDLED;
2656 }
2657
2658 ev &= HFA384X_INW(HFA384X_INTEN_OFF);
2659 if (ev == 0)
2660 break;
2661
2662 if (ev & HFA384X_EV_CMD) {
2663 prism2_cmd_ev(dev);
2664 }
2665
2666 /* Above events are needed even before hw is ready, but other
2667 * events should be skipped during initialization. This may
2668 * change for AllocEv if allocate_fid is implemented without
2669 * busy waiting. */
2670 if (!local->hw_ready || local->hw_resetting ||
2671 !local->dev_enabled) {
2672 ev = HFA384X_INW(HFA384X_EVSTAT_OFF);
2673 if (ev & HFA384X_EV_CMD)
2674 goto next_event;
2675 if ((ev & HFA384X_EVENT_MASK) == 0)
2676 return IRQ_HANDLED;
2677 if (local->dev_enabled && (ev & ~HFA384X_EV_TICK) &&
2678 net_ratelimit()) {
2679 printk(KERN_DEBUG "%s: prism2_interrupt: hw "
2680 "not ready; skipping events 0x%04x "
2681 "(IntEn=0x%04x)%s%s%s\n",
2682 dev->name, ev,
2683 HFA384X_INW(HFA384X_INTEN_OFF),
2684 !local->hw_ready ? " (!hw_ready)" : "",
2685 local->hw_resetting ?
2686 " (hw_resetting)" : "",
2687 !local->dev_enabled ?
2688 " (!dev_enabled)" : "");
2689 }
2690 HFA384X_OUTW(ev, HFA384X_EVACK_OFF);
2691 return IRQ_HANDLED;
2692 }
2693
2694 if (ev & HFA384X_EV_TICK) {
2695 prism2_ev_tick(dev);
2696 HFA384X_OUTW(HFA384X_EV_TICK, HFA384X_EVACK_OFF);
2697 }
2698
2699 if (ev & HFA384X_EV_ALLOC) {
2700 prism2_alloc_ev(dev);
2701 HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
2702 }
2703
2704 /* Reading data from the card is quite time consuming, so do it
2705 * in tasklets. TX, TXEXC, RX, and INFO events will be ACKed
2706 * and unmasked after needed data has been read completely. */
2707 if (ev & HFA384X_BAP0_EVENTS) {
2708 hfa384x_events_no_bap0(dev);
2709 tasklet_schedule(&local->bap_tasklet);
2710 }
2711
2712#ifndef final_version
2713 if (ev & HFA384X_EV_WTERR) {
2714 PDEBUG(DEBUG_EXTRA, "%s: WTERR event\n", dev->name);
2715 HFA384X_OUTW(HFA384X_EV_WTERR, HFA384X_EVACK_OFF);
2716 }
2717#endif /* final_version */
2718
2719 if (ev & HFA384X_EV_INFDROP) {
2720 prism2_infdrop(dev);
2721 HFA384X_OUTW(HFA384X_EV_INFDROP, HFA384X_EVACK_OFF);
2722 }
2723
2724 next_event:
2725 events++;
2726 if (events >= PRISM2_MAX_INTERRUPT_EVENTS) {
2727 PDEBUG(DEBUG_EXTRA, "prism2_interrupt: >%d events "
2728 "(EvStat=0x%04x)\n",
2729 PRISM2_MAX_INTERRUPT_EVENTS,
2730 HFA384X_INW(HFA384X_EVSTAT_OFF));
2731 break;
2732 }
2733 }
2734 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 1);
2735 return IRQ_RETVAL(events);
2736}
2737
2738
2739static void prism2_check_sta_fw_version(local_info_t *local)
2740{
2741 struct hfa384x_comp_ident comp;
2742 int id, variant, major, minor;
2743
2744 if (hfa384x_get_rid(local->dev, HFA384X_RID_STAID,
2745 &comp, sizeof(comp), 1) < 0)
2746 return;
2747
2748 local->fw_ap = 0;
2749 id = le16_to_cpu(comp.id);
2750 if (id != HFA384X_COMP_ID_STA) {
2751 if (id == HFA384X_COMP_ID_FW_AP)
2752 local->fw_ap = 1;
2753 return;
2754 }
2755
2756 major = __le16_to_cpu(comp.major);
2757 minor = __le16_to_cpu(comp.minor);
2758 variant = __le16_to_cpu(comp.variant);
2759 local->sta_fw_ver = PRISM2_FW_VER(major, minor, variant);
2760
2761 /* Station firmware versions before 1.4.x seem to have a bug in
2762 * firmware-based WEP encryption when using Host AP mode, so use
2763 * host_encrypt as a default for them. Firmware version 1.4.9 is the
2764 * first one that has been seen to produce correct encryption, but the
2765 * bug might be fixed before that (although, at least 1.4.2 is broken).
2766 */
2767 local->fw_encrypt_ok = local->sta_fw_ver >= PRISM2_FW_VER(1,4,9);
2768
2769 if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
2770 !local->fw_encrypt_ok) {
2771 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
2772 "a workaround for firmware bug in Host AP mode WEP\n",
2773 local->dev->name);
2774 local->host_encrypt = 1;
2775 }
2776
2777 /* IEEE 802.11 standard compliant WDS frames (4 addresses) were broken
2778 * in station firmware versions before 1.5.x. With these versions, the
2779 * driver uses a workaround with bogus frame format (4th address after
2780 * the payload). This is not compatible with other AP devices. Since
2781 * the firmware bug is fixed in the latest station firmware versions,
2782 * automatically enable standard compliant mode for cards using station
2783 * firmware version 1.5.0 or newer. */
2784 if (local->sta_fw_ver >= PRISM2_FW_VER(1,5,0))
2785 local->wds_type |= HOSTAP_WDS_STANDARD_FRAME;
2786 else {
2787 printk(KERN_DEBUG "%s: defaulting to bogus WDS frame as a "
2788 "workaround for firmware bug in Host AP mode WDS\n",
2789 local->dev->name);
2790 }
2791
2792 hostap_check_sta_fw_version(local->ap, local->sta_fw_ver);
2793}
2794
2795
2796static void prism2_crypt_deinit_entries(local_info_t *local, int force)
2797{
2798 struct list_head *ptr, *n;
2799 struct ieee80211_crypt_data *entry;
2800
2801 for (ptr = local->crypt_deinit_list.next, n = ptr->next;
2802 ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
2803 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
2804
2805 if (atomic_read(&entry->refcnt) != 0 && !force)
2806 continue;
2807
2808 list_del(ptr);
2809
2810 if (entry->ops)
2811 entry->ops->deinit(entry->priv);
2812 kfree(entry);
2813 }
2814}
2815
2816
2817static void prism2_crypt_deinit_handler(unsigned long data)
2818{
2819 local_info_t *local = (local_info_t *) data;
2820 unsigned long flags;
2821
2822 spin_lock_irqsave(&local->lock, flags);
2823 prism2_crypt_deinit_entries(local, 0);
2824 if (!list_empty(&local->crypt_deinit_list)) {
2825 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
2826 "deletion list\n", local->dev->name);
2827 local->crypt_deinit_timer.expires = jiffies + HZ;
2828 add_timer(&local->crypt_deinit_timer);
2829 }
2830 spin_unlock_irqrestore(&local->lock, flags);
2831
2832}
2833
2834
2835static void hostap_passive_scan(unsigned long data)
2836{
2837 local_info_t *local = (local_info_t *) data;
2838 struct net_device *dev = local->dev;
2839 u16 channel;
2840
2841 if (local->passive_scan_interval <= 0)
2842 return;
2843
2844 if (local->passive_scan_state == PASSIVE_SCAN_LISTEN) {
2845 int max_tries = 16;
2846
2847 /* Even though host system does not really know when the WLAN
2848 * MAC is sending frames, try to avoid changing channels for
2849 * passive scanning when a host-generated frame is being
2850 * transmitted */
2851 if (test_bit(HOSTAP_BITS_TRANSMIT, &local->bits)) {
2852 printk(KERN_DEBUG "%s: passive scan detected pending "
2853 "TX - delaying\n", dev->name);
2854 local->passive_scan_timer.expires = jiffies + HZ / 10;
2855 add_timer(&local->passive_scan_timer);
2856 return;
2857 }
2858
2859 do {
2860 local->passive_scan_channel++;
2861 if (local->passive_scan_channel > 14)
2862 local->passive_scan_channel = 1;
2863 max_tries--;
2864 } while (!(local->channel_mask &
2865 (1 << (local->passive_scan_channel - 1))) &&
2866 max_tries > 0);
2867
2868 if (max_tries == 0) {
2869 printk(KERN_INFO "%s: no allowed passive scan channels"
2870 " found\n", dev->name);
2871 return;
2872 }
2873
2874 printk(KERN_DEBUG "%s: passive scan channel %d\n",
2875 dev->name, local->passive_scan_channel);
2876 channel = local->passive_scan_channel;
2877 local->passive_scan_state = PASSIVE_SCAN_WAIT;
2878 local->passive_scan_timer.expires = jiffies + HZ / 10;
2879 } else {
2880 channel = local->channel;
2881 local->passive_scan_state = PASSIVE_SCAN_LISTEN;
2882 local->passive_scan_timer.expires = jiffies +
2883 local->passive_scan_interval * HZ;
2884 }
2885
2886 if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST |
2887 (HFA384X_TEST_CHANGE_CHANNEL << 8),
2888 channel, NULL, 0))
2889 printk(KERN_ERR "%s: passive scan channel set %d "
2890 "failed\n", dev->name, channel);
2891
2892 add_timer(&local->passive_scan_timer);
2893}
2894
2895
2896/* Called only as a scheduled task when communications quality values should
2897 * be updated. */
2898static void handle_comms_qual_update(void *data)
2899{
2900 local_info_t *local = data;
2901 prism2_update_comms_qual(local->dev);
2902}
2903
2904
2905/* Software watchdog - called as a timer. Hardware interrupt (Tick event) is
2906 * used to monitor that local->last_tick_timer is being updated. If not,
2907 * interrupt busy-loop is assumed and driver tries to recover by masking out
2908 * some events. */
2909static void hostap_tick_timer(unsigned long data)
2910{
2911 static unsigned long last_inquire = 0;
2912 local_info_t *local = (local_info_t *) data;
2913 local->last_tick_timer = jiffies;
2914
2915 /* Inquire CommTallies every 10 seconds to keep the statistics updated
2916 * more often during low load and when using 32-bit tallies. */
2917 if ((!last_inquire || time_after(jiffies, last_inquire + 10 * HZ)) &&
2918 !local->hw_downloading && local->hw_ready &&
2919 !local->hw_resetting && local->dev_enabled) {
2920 hfa384x_cmd_callback(local->dev, HFA384X_CMDCODE_INQUIRE,
2921 HFA384X_INFO_COMMTALLIES, NULL, 0);
2922 last_inquire = jiffies;
2923 }
2924
2925 if ((local->last_comms_qual_update == 0 ||
2926 time_after(jiffies, local->last_comms_qual_update + 10 * HZ)) &&
2927 (local->iw_mode == IW_MODE_INFRA ||
2928 local->iw_mode == IW_MODE_ADHOC)) {
2929 schedule_work(&local->comms_qual_update);
2930 }
2931
2932 local->tick_timer.expires = jiffies + 2 * HZ;
2933 add_timer(&local->tick_timer);
2934}
2935
2936
2937#ifndef PRISM2_NO_PROCFS_DEBUG
2938static int prism2_registers_proc_read(char *page, char **start, off_t off,
2939 int count, int *eof, void *data)
2940{
2941 char *p = page;
2942 local_info_t *local = (local_info_t *) data;
2943
2944 if (off != 0) {
2945 *eof = 1;
2946 return 0;
2947 }
2948
2949#define SHOW_REG(n) \
2950p += sprintf(p, #n "=%04x\n", hfa384x_read_reg(local->dev, HFA384X_##n##_OFF))
2951
2952 SHOW_REG(CMD);
2953 SHOW_REG(PARAM0);
2954 SHOW_REG(PARAM1);
2955 SHOW_REG(PARAM2);
2956 SHOW_REG(STATUS);
2957 SHOW_REG(RESP0);
2958 SHOW_REG(RESP1);
2959 SHOW_REG(RESP2);
2960 SHOW_REG(INFOFID);
2961 SHOW_REG(CONTROL);
2962 SHOW_REG(SELECT0);
2963 SHOW_REG(SELECT1);
2964 SHOW_REG(OFFSET0);
2965 SHOW_REG(OFFSET1);
2966 SHOW_REG(RXFID);
2967 SHOW_REG(ALLOCFID);
2968 SHOW_REG(TXCOMPLFID);
2969 SHOW_REG(SWSUPPORT0);
2970 SHOW_REG(SWSUPPORT1);
2971 SHOW_REG(SWSUPPORT2);
2972 SHOW_REG(EVSTAT);
2973 SHOW_REG(INTEN);
2974 SHOW_REG(EVACK);
2975 /* Do not read data registers, because they change the state of the
2976 * MAC (offset += 2) */
2977 /* SHOW_REG(DATA0); */
2978 /* SHOW_REG(DATA1); */
2979 SHOW_REG(AUXPAGE);
2980 SHOW_REG(AUXOFFSET);
2981 /* SHOW_REG(AUXDATA); */
2982#ifdef PRISM2_PCI
2983 SHOW_REG(PCICOR);
2984 SHOW_REG(PCIHCR);
2985 SHOW_REG(PCI_M0_ADDRH);
2986 SHOW_REG(PCI_M0_ADDRL);
2987 SHOW_REG(PCI_M0_LEN);
2988 SHOW_REG(PCI_M0_CTL);
2989 SHOW_REG(PCI_STATUS);
2990 SHOW_REG(PCI_M1_ADDRH);
2991 SHOW_REG(PCI_M1_ADDRL);
2992 SHOW_REG(PCI_M1_LEN);
2993 SHOW_REG(PCI_M1_CTL);
2994#endif /* PRISM2_PCI */
2995
2996 return (p - page);
2997}
2998#endif /* PRISM2_NO_PROCFS_DEBUG */
2999
3000
3001struct set_tim_data {
3002 struct list_head list;
3003 int aid;
3004 int set;
3005};
3006
3007static int prism2_set_tim(struct net_device *dev, int aid, int set)
3008{
3009 struct list_head *ptr;
3010 struct set_tim_data *new_entry;
3011 struct hostap_interface *iface;
3012 local_info_t *local;
3013
3014 iface = netdev_priv(dev);
3015 local = iface->local;
3016
3017 new_entry = (struct set_tim_data *)
3018 kmalloc(sizeof(*new_entry), GFP_ATOMIC);
3019 if (new_entry == NULL) {
3020 printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
3021 local->dev->name);
3022 return -ENOMEM;
3023 }
3024 memset(new_entry, 0, sizeof(*new_entry));
3025 new_entry->aid = aid;
3026 new_entry->set = set;
3027
3028 spin_lock_bh(&local->set_tim_lock);
3029 list_for_each(ptr, &local->set_tim_list) {
3030 struct set_tim_data *entry =
3031 list_entry(ptr, struct set_tim_data, list);
3032 if (entry->aid == aid) {
3033 PDEBUG(DEBUG_PS2, "%s: prism2_set_tim: aid=%d "
3034 "set=%d ==> %d\n",
3035 local->dev->name, aid, entry->set, set);
3036 entry->set = set;
3037 kfree(new_entry);
3038 new_entry = NULL;
3039 break;
3040 }
3041 }
3042 if (new_entry)
3043 list_add_tail(&new_entry->list, &local->set_tim_list);
3044 spin_unlock_bh(&local->set_tim_lock);
3045
3046 schedule_work(&local->set_tim_queue);
3047
3048 return 0;
3049}
3050
3051
3052static void handle_set_tim_queue(void *data)
3053{
3054 local_info_t *local = (local_info_t *) data;
3055 struct set_tim_data *entry;
3056 u16 val;
3057
3058 for (;;) {
3059 entry = NULL;
3060 spin_lock_bh(&local->set_tim_lock);
3061 if (!list_empty(&local->set_tim_list)) {
3062 entry = list_entry(local->set_tim_list.next,
3063 struct set_tim_data, list);
3064 list_del(&entry->list);
3065 }
3066 spin_unlock_bh(&local->set_tim_lock);
3067 if (!entry)
3068 break;
3069
3070 PDEBUG(DEBUG_PS2, "%s: handle_set_tim_queue: aid=%d set=%d\n",
3071 local->dev->name, entry->aid, entry->set);
3072
3073 val = entry->aid;
3074 if (entry->set)
3075 val |= 0x8000;
3076 if (hostap_set_word(local->dev, HFA384X_RID_CNFTIMCTRL, val)) {
3077 printk(KERN_DEBUG "%s: set_tim failed (aid=%d "
3078 "set=%d)\n",
3079 local->dev->name, entry->aid, entry->set);
3080 }
3081
3082 kfree(entry);
3083 }
3084}
3085
3086
3087static void prism2_clear_set_tim_queue(local_info_t *local)
3088{
3089 struct list_head *ptr, *n;
3090
3091 list_for_each_safe(ptr, n, &local->set_tim_list) {
3092 struct set_tim_data *entry;
3093 entry = list_entry(ptr, struct set_tim_data, list);
3094 list_del(&entry->list);
3095 kfree(entry);
3096 }
3097}
3098
3099
3100static struct net_device *
3101prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
3102 struct device *sdev)
3103{
3104 struct net_device *dev;
3105 struct hostap_interface *iface;
3106 struct local_info *local;
3107 int len, i, ret;
3108
3109 if (funcs == NULL)
3110 return NULL;
3111
3112 len = strlen(dev_template);
3113 if (len >= IFNAMSIZ || strstr(dev_template, "%d") == NULL) {
3114 printk(KERN_WARNING "hostap: Invalid dev_template='%s'\n",
3115 dev_template);
3116 return NULL;
3117 }
3118
3119 len = sizeof(struct hostap_interface) +
3120 3 + sizeof(struct local_info) +
3121 3 + sizeof(struct ap_data);
3122
3123 dev = alloc_etherdev(len);
3124 if (dev == NULL)
3125 return NULL;
3126
3127 iface = netdev_priv(dev);
3128 local = (struct local_info *) ((((long) (iface + 1)) + 3) & ~3);
3129 local->ap = (struct ap_data *) ((((long) (local + 1)) + 3) & ~3);
3130 local->dev = iface->dev = dev;
3131 iface->local = local;
3132 iface->type = HOSTAP_INTERFACE_MASTER;
3133 INIT_LIST_HEAD(&local->hostap_interfaces);
3134
3135 local->hw_module = THIS_MODULE;
3136
3137#ifdef PRISM2_IO_DEBUG
3138 local->io_debug_enabled = 1;
3139#endif /* PRISM2_IO_DEBUG */
3140
3141 local->func = funcs;
3142 local->func->cmd = hfa384x_cmd;
3143 local->func->read_regs = hfa384x_read_regs;
3144 local->func->get_rid = hfa384x_get_rid;
3145 local->func->set_rid = hfa384x_set_rid;
3146 local->func->hw_enable = prism2_hw_enable;
3147 local->func->hw_config = prism2_hw_config;
3148 local->func->hw_reset = prism2_hw_reset;
3149 local->func->hw_shutdown = prism2_hw_shutdown;
3150 local->func->reset_port = prism2_reset_port;
3151 local->func->schedule_reset = prism2_schedule_reset;
3152#ifdef PRISM2_DOWNLOAD_SUPPORT
3153 local->func->read_aux = prism2_download_aux_dump;
3154 local->func->download = prism2_download;
3155#endif /* PRISM2_DOWNLOAD_SUPPORT */
3156 local->func->tx = prism2_tx_80211;
3157 local->func->set_tim = prism2_set_tim;
3158 local->func->need_tx_headroom = 0; /* no need to add txdesc in
3159 * skb->data (FIX: maybe for DMA bus
3160 * mastering? */
3161
3162 local->mtu = mtu;
3163
3164 rwlock_init(&local->iface_lock);
3165 spin_lock_init(&local->txfidlock);
3166 spin_lock_init(&local->cmdlock);
3167 spin_lock_init(&local->baplock);
3168 spin_lock_init(&local->lock);
3169 init_MUTEX(&local->rid_bap_sem);
3170
3171 if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES)
3172 card_idx = 0;
3173 local->card_idx = card_idx;
3174
3175 len = strlen(essid);
3176 memcpy(local->essid, essid,
3177 len > MAX_SSID_LEN ? MAX_SSID_LEN : len);
3178 local->essid[MAX_SSID_LEN] = '\0';
3179 i = GET_INT_PARM(iw_mode, card_idx);
3180 if ((i >= IW_MODE_ADHOC && i <= IW_MODE_REPEAT) ||
3181 i == IW_MODE_MONITOR) {
3182 local->iw_mode = i;
3183 } else {
3184 printk(KERN_WARNING "prism2: Unknown iw_mode %d; using "
3185 "IW_MODE_MASTER\n", i);
3186 local->iw_mode = IW_MODE_MASTER;
3187 }
3188 local->channel = GET_INT_PARM(channel, card_idx);
3189 local->beacon_int = GET_INT_PARM(beacon_int, card_idx);
3190 local->dtim_period = GET_INT_PARM(dtim_period, card_idx);
3191 local->wds_max_connections = 16;
3192 local->tx_control = HFA384X_TX_CTRL_FLAGS;
3193 local->manual_retry_count = -1;
3194 local->rts_threshold = 2347;
3195 local->fragm_threshold = 2346;
3196 local->rssi_to_dBm = 100; /* default; to be overriden by
3197 * cnfDbmAdjust, if available */
3198 local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY;
3199 local->sram_type = -1;
3200 local->scan_channel_mask = 0xffff;
3201
3202 /* Initialize task queue structures */
3203 INIT_WORK(&local->reset_queue, handle_reset_queue, local);
3204 INIT_WORK(&local->set_multicast_list_queue,
3205 hostap_set_multicast_list_queue, local->dev);
3206
3207 INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local);
3208 INIT_LIST_HEAD(&local->set_tim_list);
3209 spin_lock_init(&local->set_tim_lock);
3210
3211 INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local);
3212
3213 /* Initialize tasklets for handling hardware IRQ related operations
3214 * outside hw IRQ handler */
3215#define HOSTAP_TASKLET_INIT(q, f, d) \
3216do { memset((q), 0, sizeof(*(q))); (q)->func = (f); (q)->data = (d); } \
3217while (0)
3218 HOSTAP_TASKLET_INIT(&local->bap_tasklet, hostap_bap_tasklet,
3219 (unsigned long) local);
3220
3221 HOSTAP_TASKLET_INIT(&local->info_tasklet, hostap_info_tasklet,
3222 (unsigned long) local);
3223 hostap_info_init(local);
3224
3225 HOSTAP_TASKLET_INIT(&local->rx_tasklet,
3226 hostap_rx_tasklet, (unsigned long) local);
3227 skb_queue_head_init(&local->rx_list);
3228
3229 HOSTAP_TASKLET_INIT(&local->sta_tx_exc_tasklet,
3230 hostap_sta_tx_exc_tasklet, (unsigned long) local);
3231 skb_queue_head_init(&local->sta_tx_exc_list);
3232
3233 INIT_LIST_HEAD(&local->cmd_queue);
3234 init_waitqueue_head(&local->hostscan_wq);
3235 INIT_LIST_HEAD(&local->crypt_deinit_list);
3236 init_timer(&local->crypt_deinit_timer);
3237 local->crypt_deinit_timer.data = (unsigned long) local;
3238 local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
3239
3240 init_timer(&local->passive_scan_timer);
3241 local->passive_scan_timer.data = (unsigned long) local;
3242 local->passive_scan_timer.function = hostap_passive_scan;
3243
3244 init_timer(&local->tick_timer);
3245 local->tick_timer.data = (unsigned long) local;
3246 local->tick_timer.function = hostap_tick_timer;
3247 local->tick_timer.expires = jiffies + 2 * HZ;
3248 add_timer(&local->tick_timer);
3249
3250 INIT_LIST_HEAD(&local->bss_list);
3251
3252 hostap_setup_dev(dev, local, 1);
3253 local->saved_eth_header_parse = dev->hard_header_parse;
3254
3255 dev->hard_start_xmit = hostap_master_start_xmit;
3256 dev->type = ARPHRD_IEEE80211;
3257 dev->hard_header_parse = hostap_80211_header_parse;
3258
3259 rtnl_lock();
3260 ret = dev_alloc_name(dev, "wifi%d");
3261 SET_NETDEV_DEV(dev, sdev);
3262 if (ret >= 0)
3263 ret = register_netdevice(dev);
3264 rtnl_unlock();
3265 if (ret < 0) {
3266 printk(KERN_WARNING "%s: register netdevice failed!\n",
3267 dev_info);
3268 goto fail;
3269 }
3270 printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name);
3271
3272#ifndef PRISM2_NO_PROCFS_DEBUG
3273 create_proc_read_entry("registers", 0, local->proc,
3274 prism2_registers_proc_read, local);
3275#endif /* PRISM2_NO_PROCFS_DEBUG */
3276
3277 hostap_init_data(local);
3278 return dev;
3279
3280 fail:
3281 free_netdev(dev);
3282 return NULL;
3283}
3284
3285
3286static int hostap_hw_ready(struct net_device *dev)
3287{
3288 struct hostap_interface *iface;
3289 struct local_info *local;
3290
3291 iface = netdev_priv(dev);
3292 local = iface->local;
3293 local->ddev = hostap_add_interface(local, HOSTAP_INTERFACE_MAIN, 0,
3294 "", dev_template);
3295
3296 if (local->ddev) {
3297 if (local->iw_mode == IW_MODE_INFRA ||
3298 local->iw_mode == IW_MODE_ADHOC) {
3299 netif_carrier_off(local->dev);
3300 netif_carrier_off(local->ddev);
3301 }
3302 hostap_init_proc(local);
3303 hostap_init_ap_proc(local);
3304 return 0;
3305 }
3306
3307 return -1;
3308}
3309
3310
3311static void prism2_free_local_data(struct net_device *dev)
3312{
3313 struct hostap_tx_callback_info *tx_cb, *tx_cb_prev;
3314 int i;
3315 struct hostap_interface *iface;
3316 struct local_info *local;
3317 struct list_head *ptr, *n;
3318
3319 if (dev == NULL)
3320 return;
3321
3322 iface = netdev_priv(dev);
3323 local = iface->local;
3324
3325 flush_scheduled_work();
3326
3327 if (timer_pending(&local->crypt_deinit_timer))
3328 del_timer(&local->crypt_deinit_timer);
3329 prism2_crypt_deinit_entries(local, 1);
3330
3331 if (timer_pending(&local->passive_scan_timer))
3332 del_timer(&local->passive_scan_timer);
3333
3334 if (timer_pending(&local->tick_timer))
3335 del_timer(&local->tick_timer);
3336
3337 prism2_clear_cmd_queue(local);
3338
3339 skb_queue_purge(&local->info_list);
3340 skb_queue_purge(&local->rx_list);
3341 skb_queue_purge(&local->sta_tx_exc_list);
3342
3343 if (local->dev_enabled)
3344 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
3345
3346 for (i = 0; i < WEP_KEYS; i++) {
3347 struct ieee80211_crypt_data *crypt = local->crypt[i];
3348 if (crypt) {
3349 if (crypt->ops)
3350 crypt->ops->deinit(crypt->priv);
3351 kfree(crypt);
3352 local->crypt[i] = NULL;
3353 }
3354 }
3355
3356 if (local->ap != NULL)
3357 hostap_free_data(local->ap);
3358
3359#ifndef PRISM2_NO_PROCFS_DEBUG
3360 if (local->proc != NULL)
3361 remove_proc_entry("registers", local->proc);
3362#endif /* PRISM2_NO_PROCFS_DEBUG */
3363 hostap_remove_proc(local);
3364
3365 tx_cb = local->tx_callback;
3366 while (tx_cb != NULL) {
3367 tx_cb_prev = tx_cb;
3368 tx_cb = tx_cb->next;
3369 kfree(tx_cb_prev);
3370 }
3371
3372 hostap_set_hostapd(local, 0, 0);
3373 hostap_set_hostapd_sta(local, 0, 0);
3374
3375 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
3376 if (local->frag_cache[i].skb != NULL)
3377 dev_kfree_skb(local->frag_cache[i].skb);
3378 }
3379
3380#ifdef PRISM2_DOWNLOAD_SUPPORT
3381 prism2_download_free_data(local->dl_pri);
3382 prism2_download_free_data(local->dl_sec);
3383#endif /* PRISM2_DOWNLOAD_SUPPORT */
3384
3385 list_for_each_safe(ptr, n, &local->hostap_interfaces) {
3386 iface = list_entry(ptr, struct hostap_interface, list);
3387 if (iface->type == HOSTAP_INTERFACE_MASTER) {
3388 /* special handling for this interface below */
3389 continue;
3390 }
3391 hostap_remove_interface(iface->dev, 0, 1);
3392 }
3393
3394 prism2_clear_set_tim_queue(local);
3395
3396 list_for_each_safe(ptr, n, &local->bss_list) {
3397 struct hostap_bss_info *bss =
3398 list_entry(ptr, struct hostap_bss_info, list);
3399 kfree(bss);
3400 }
3401
3402 kfree(local->pda);
3403 kfree(local->last_scan_results);
3404 kfree(local->generic_elem);
3405
3406 unregister_netdev(local->dev);
3407 free_netdev(local->dev);
3408}
3409
3410
3411#ifndef PRISM2_PLX
3412static void prism2_suspend(struct net_device *dev)
3413{
3414 struct hostap_interface *iface;
3415 struct local_info *local;
3416 union iwreq_data wrqu;
3417
3418 iface = dev->priv;
3419 local = iface->local;
3420
3421 /* Send disconnect event, e.g., to trigger reassociation after resume
3422 * if wpa_supplicant is used. */
3423 memset(&wrqu, 0, sizeof(wrqu));
3424 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3425 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
3426
3427 /* Disable hardware and firmware */
3428 prism2_hw_shutdown(dev, 0);
3429}
3430#endif /* PRISM2_PLX */
3431
3432
3433/* These might at some point be compiled separately and used as separate
3434 * kernel modules or linked into one */
3435#ifdef PRISM2_DOWNLOAD_SUPPORT
3436#include "hostap_download.c"
3437#endif /* PRISM2_DOWNLOAD_SUPPORT */
3438
3439#ifdef PRISM2_CALLBACK
3440/* External hostap_callback.c file can be used to, e.g., blink activity led.
3441 * This can use platform specific code and must define prism2_callback()
3442 * function (if PRISM2_CALLBACK is not defined, these function calls are not
3443 * used. */
3444#include "hostap_callback.c"
3445#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..5aa998fdf1c4
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -0,0 +1,499 @@
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_hostscan_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, i;
248 unsigned long flags;
249 struct hfa384x_scan_result *res;
250 struct hfa384x_hostscan_result *results, *prev;
251
252 if (left < 4) {
253 printk(KERN_DEBUG "%s: invalid scanresult info frame "
254 "length %d\n", local->dev->name, left);
255 return;
256 }
257
258 pos = (u16 *) buf;
259 pos++;
260 pos++;
261 left -= 4;
262
263 new_count = left / sizeof(struct hfa384x_scan_result);
264 results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
265 GFP_ATOMIC);
266 if (results == NULL)
267 return;
268
269 /* Convert to hostscan result format. */
270 res = (struct hfa384x_scan_result *) pos;
271 for (i = 0; i < new_count; i++) {
272 memcpy(&results[i], &res[i],
273 sizeof(struct hfa384x_scan_result));
274 results[i].atim = 0;
275 }
276
277 spin_lock_irqsave(&local->lock, flags);
278 local->last_scan_type = PRISM2_SCAN;
279 prev = local->last_scan_results;
280 local->last_scan_results = results;
281 local->last_scan_results_count = new_count;
282 spin_unlock_irqrestore(&local->lock, flags);
283 kfree(prev);
284
285 hostap_report_scan_complete(local);
286
287 /* Perform rest of ScanResults handling later in scheduled task */
288 set_bit(PRISM2_INFO_PENDING_SCANRESULTS, &local->pending_info);
289 schedule_work(&local->info_queue);
290}
291
292
293/* Called only as a tasklet (software IRQ) */
294static void prism2_info_hostscanresults(local_info_t *local,
295 unsigned char *buf, int left)
296{
297 int i, result_size, copy_len, new_count;
298 struct hfa384x_hostscan_result *results, *prev;
299 unsigned long flags;
300 u16 *pos;
301 u8 *ptr;
302
303 wake_up_interruptible(&local->hostscan_wq);
304
305 if (left < 4) {
306 printk(KERN_DEBUG "%s: invalid hostscanresult info frame "
307 "length %d\n", local->dev->name, left);
308 return;
309 }
310
311 pos = (u16 *) buf;
312 copy_len = result_size = le16_to_cpu(*pos);
313 if (result_size == 0) {
314 printk(KERN_DEBUG "%s: invalid result_size (0) in "
315 "hostscanresults\n", local->dev->name);
316 return;
317 }
318 if (copy_len > sizeof(struct hfa384x_hostscan_result))
319 copy_len = sizeof(struct hfa384x_hostscan_result);
320
321 pos++;
322 pos++;
323 left -= 4;
324 ptr = (u8 *) pos;
325
326 new_count = left / result_size;
327 results = kmalloc(new_count * sizeof(struct hfa384x_hostscan_result),
328 GFP_ATOMIC);
329 if (results == NULL)
330 return;
331 memset(results, 0, new_count * sizeof(struct hfa384x_hostscan_result));
332
333 for (i = 0; i < new_count; i++) {
334 memcpy(&results[i], ptr, copy_len);
335 ptr += result_size;
336 left -= result_size;
337 }
338
339 if (left) {
340 printk(KERN_DEBUG "%s: short HostScan result entry (%d/%d)\n",
341 local->dev->name, left, result_size);
342 }
343
344 spin_lock_irqsave(&local->lock, flags);
345 local->last_scan_type = PRISM2_HOSTSCAN;
346 prev = local->last_scan_results;
347 local->last_scan_results = results;
348 local->last_scan_results_count = new_count;
349 spin_unlock_irqrestore(&local->lock, flags);
350 kfree(prev);
351
352 hostap_report_scan_complete(local);
353}
354#endif /* PRISM2_NO_STATION_MODES */
355
356
357/* Called only as a tasklet (software IRQ) */
358void hostap_info_process(local_info_t *local, struct sk_buff *skb)
359{
360 struct hfa384x_info_frame *info;
361 unsigned char *buf;
362 int left;
363#ifndef PRISM2_NO_DEBUG
364 int i;
365#endif /* PRISM2_NO_DEBUG */
366
367 info = (struct hfa384x_info_frame *) skb->data;
368 buf = skb->data + sizeof(*info);
369 left = skb->len - sizeof(*info);
370
371 switch (info->type) {
372 case HFA384X_INFO_COMMTALLIES:
373 prism2_info_commtallies(local, buf, left);
374 break;
375
376#ifndef PRISM2_NO_STATION_MODES
377 case HFA384X_INFO_LINKSTATUS:
378 prism2_info_linkstatus(local, buf, left);
379 break;
380
381 case HFA384X_INFO_SCANRESULTS:
382 prism2_info_scanresults(local, buf, left);
383 break;
384
385 case HFA384X_INFO_HOSTSCANRESULTS:
386 prism2_info_hostscanresults(local, buf, left);
387 break;
388#endif /* PRISM2_NO_STATION_MODES */
389
390#ifndef PRISM2_NO_DEBUG
391 default:
392 PDEBUG(DEBUG_EXTRA, "%s: INFO - len=%d type=0x%04x\n",
393 local->dev->name, info->len, info->type);
394 PDEBUG(DEBUG_EXTRA, "Unknown info frame:");
395 for (i = 0; i < (left < 100 ? left : 100); i++)
396 PDEBUG2(DEBUG_EXTRA, " %02x", buf[i]);
397 PDEBUG2(DEBUG_EXTRA, "\n");
398 break;
399#endif /* PRISM2_NO_DEBUG */
400 }
401}
402
403
404#ifndef PRISM2_NO_STATION_MODES
405static void handle_info_queue_linkstatus(local_info_t *local)
406{
407 int val = local->prev_link_status;
408 int connected;
409 union iwreq_data wrqu;
410
411 connected =
412 val == HFA384X_LINKSTATUS_CONNECTED ||
413 val == HFA384X_LINKSTATUS_AP_CHANGE ||
414 val == HFA384X_LINKSTATUS_AP_IN_RANGE;
415
416 if (local->func->get_rid(local->dev, HFA384X_RID_CURRENTBSSID,
417 local->bssid, ETH_ALEN, 1) < 0) {
418 printk(KERN_DEBUG "%s: could not read CURRENTBSSID after "
419 "LinkStatus event\n", local->dev->name);
420 } else {
421 PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" MACSTR "\n",
422 local->dev->name,
423 MAC2STR((unsigned char *) local->bssid));
424 if (local->wds_type & HOSTAP_WDS_AP_CLIENT)
425 hostap_add_sta(local->ap, local->bssid);
426 }
427
428 /* Get BSSID if we have a valid AP address */
429 if (connected) {
430 netif_carrier_on(local->dev);
431 netif_carrier_on(local->ddev);
432 memcpy(wrqu.ap_addr.sa_data, local->bssid, ETH_ALEN);
433 } else {
434 netif_carrier_off(local->dev);
435 netif_carrier_off(local->ddev);
436 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
437 }
438 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
439
440 /*
441 * Filter out sequential disconnect events in order not to cause a
442 * flood of SIOCGIWAP events that have a race condition with EAPOL
443 * frames and can confuse wpa_supplicant about the current association
444 * status.
445 */
446 if (connected || local->prev_linkstatus_connected)
447 wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
448 local->prev_linkstatus_connected = connected;
449}
450
451
452static void handle_info_queue_scanresults(local_info_t *local)
453{
454 if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA)
455 prism2_host_roaming(local);
456
457 if (local->host_roaming == 2 && local->iw_mode == IW_MODE_INFRA &&
458 memcmp(local->preferred_ap, "\x00\x00\x00\x00\x00\x00",
459 ETH_ALEN) != 0) {
460 /*
461 * Firmware seems to be getting into odd state in host_roaming
462 * mode 2 when hostscan is used without join command, so try
463 * to fix this by re-joining the current AP. This does not
464 * actually trigger a new association if the current AP is
465 * still in the scan results.
466 */
467 prism2_host_roaming(local);
468 }
469}
470
471
472/* Called only as scheduled task after receiving info frames (used to avoid
473 * pending too much time in HW IRQ handler). */
474static void handle_info_queue(void *data)
475{
476 local_info_t *local = (local_info_t *) data;
477
478 if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS,
479 &local->pending_info))
480 handle_info_queue_linkstatus(local);
481
482 if (test_and_clear_bit(PRISM2_INFO_PENDING_SCANRESULTS,
483 &local->pending_info))
484 handle_info_queue_scanresults(local);
485}
486#endif /* PRISM2_NO_STATION_MODES */
487
488
489void hostap_info_init(local_info_t *local)
490{
491 skb_queue_head_init(&local->info_list);
492#ifndef PRISM2_NO_STATION_MODES
493 INIT_WORK(&local->info_queue, handle_info_queue, local);
494#endif /* PRISM2_NO_STATION_MODES */
495}
496
497
498EXPORT_SYMBOL(hostap_info_init);
499EXPORT_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..e720369a3515
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -0,0 +1,4102 @@
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 ieee80211_crypt_data **crypt)
119{
120 struct ieee80211_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 ieee80211_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 ieee80211_crypt_data *new_crypt;
179
180 /* take WEP into use */
181 new_crypt = (struct ieee80211_crypt_data *)
182 kmalloc(sizeof(struct ieee80211_crypt_data),
183 GFP_KERNEL);
184 if (new_crypt == NULL)
185 return -ENOMEM;
186 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
187 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
188 if (!new_crypt->ops) {
189 request_module("ieee80211_crypt_wep");
190 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
191 }
192 if (new_crypt->ops)
193 new_crypt->priv = new_crypt->ops->init(i);
194 if (!new_crypt->ops || !new_crypt->priv) {
195 kfree(new_crypt);
196 new_crypt = NULL;
197
198 printk(KERN_WARNING "%s: could not initialize WEP: "
199 "load module hostap_crypt_wep.o\n",
200 dev->name);
201 return -EOPNOTSUPP;
202 }
203 *crypt = new_crypt;
204 }
205
206 if (erq->length > 0) {
207 int len = erq->length <= 5 ? 5 : 13;
208 int first = 1, j;
209 if (len > erq->length)
210 memset(keybuf + erq->length, 0, len - erq->length);
211 (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
212 for (j = 0; j < WEP_KEYS; j++) {
213 if (j != i && local->crypt[j]) {
214 first = 0;
215 break;
216 }
217 }
218 if (first)
219 local->tx_keyidx = i;
220 } else {
221 /* No key data - just set the default TX key index */
222 local->tx_keyidx = i;
223 }
224
225 done:
226 local->open_wep = erq->flags & IW_ENCODE_OPEN;
227
228 if (hostap_set_encryption(local)) {
229 printk(KERN_DEBUG "%s: set_encryption failed\n", dev->name);
230 return -EINVAL;
231 }
232
233 /* Do not reset port0 if card is in Managed mode since resetting will
234 * generate new IEEE 802.11 authentication which may end up in looping
235 * with IEEE 802.1X. Prism2 documentation seem to require port reset
236 * after WEP configuration. However, keys are apparently changed at
237 * least in Managed mode. */
238 if (local->iw_mode != IW_MODE_INFRA && local->func->reset_port(dev)) {
239 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
240 return -EINVAL;
241 }
242
243 return 0;
244}
245
246
247static int prism2_ioctl_giwencode(struct net_device *dev,
248 struct iw_request_info *info,
249 struct iw_point *erq, char *key)
250{
251 struct hostap_interface *iface;
252 local_info_t *local;
253 int i, len;
254 u16 val;
255 struct ieee80211_crypt_data *crypt;
256
257 iface = netdev_priv(dev);
258 local = iface->local;
259
260 i = erq->flags & IW_ENCODE_INDEX;
261 if (i < 1 || i > 4)
262 i = local->tx_keyidx;
263 else
264 i--;
265 if (i < 0 || i >= WEP_KEYS)
266 return -EINVAL;
267
268 crypt = local->crypt[i];
269 erq->flags = i + 1;
270
271 if (crypt == NULL || crypt->ops == NULL) {
272 erq->length = 0;
273 erq->flags |= IW_ENCODE_DISABLED;
274 return 0;
275 }
276
277 if (strcmp(crypt->ops->name, "WEP") != 0) {
278 /* only WEP is supported with wireless extensions, so just
279 * report that encryption is used */
280 erq->length = 0;
281 erq->flags |= IW_ENCODE_ENABLED;
282 return 0;
283 }
284
285 /* Reads from HFA384X_RID_CNFDEFAULTKEY* return bogus values, so show
286 * the keys from driver buffer */
287 len = crypt->ops->get_key(key, WEP_KEY_LEN, NULL, crypt->priv);
288 erq->length = (len >= 0 ? len : 0);
289
290 if (local->func->get_rid(dev, HFA384X_RID_CNFWEPFLAGS, &val, 2, 1) < 0)
291 {
292 printk("CNFWEPFLAGS reading failed\n");
293 return -EOPNOTSUPP;
294 }
295 le16_to_cpus(&val);
296 if (val & HFA384X_WEPFLAGS_PRIVACYINVOKED)
297 erq->flags |= IW_ENCODE_ENABLED;
298 else
299 erq->flags |= IW_ENCODE_DISABLED;
300 if (val & HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED)
301 erq->flags |= IW_ENCODE_RESTRICTED;
302 else
303 erq->flags |= IW_ENCODE_OPEN;
304
305 return 0;
306}
307
308
309static int hostap_set_rate(struct net_device *dev)
310{
311 struct hostap_interface *iface;
312 local_info_t *local;
313 int ret, basic_rates;
314
315 iface = netdev_priv(dev);
316 local = iface->local;
317
318 basic_rates = local->basic_rates & local->tx_rate_control;
319 if (!basic_rates || basic_rates != local->basic_rates) {
320 printk(KERN_INFO "%s: updating basic rate set automatically "
321 "to match with the new supported rate set\n",
322 dev->name);
323 if (!basic_rates)
324 basic_rates = local->tx_rate_control;
325
326 local->basic_rates = basic_rates;
327 if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
328 basic_rates))
329 printk(KERN_WARNING "%s: failed to set "
330 "cnfBasicRates\n", dev->name);
331 }
332
333 ret = (hostap_set_word(dev, HFA384X_RID_TXRATECONTROL,
334 local->tx_rate_control) ||
335 hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES,
336 local->tx_rate_control) ||
337 local->func->reset_port(dev));
338
339 if (ret) {
340 printk(KERN_WARNING "%s: TXRateControl/cnfSupportedRates "
341 "setting to 0x%x failed\n",
342 dev->name, local->tx_rate_control);
343 }
344
345 /* Update TX rate configuration for all STAs based on new operational
346 * rate set. */
347 hostap_update_rates(local);
348
349 return ret;
350}
351
352
353static int prism2_ioctl_siwrate(struct net_device *dev,
354 struct iw_request_info *info,
355 struct iw_param *rrq, char *extra)
356{
357 struct hostap_interface *iface;
358 local_info_t *local;
359
360 iface = netdev_priv(dev);
361 local = iface->local;
362
363 if (rrq->fixed) {
364 switch (rrq->value) {
365 case 11000000:
366 local->tx_rate_control = HFA384X_RATES_11MBPS;
367 break;
368 case 5500000:
369 local->tx_rate_control = HFA384X_RATES_5MBPS;
370 break;
371 case 2000000:
372 local->tx_rate_control = HFA384X_RATES_2MBPS;
373 break;
374 case 1000000:
375 local->tx_rate_control = HFA384X_RATES_1MBPS;
376 break;
377 default:
378 local->tx_rate_control = HFA384X_RATES_1MBPS |
379 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
380 HFA384X_RATES_11MBPS;
381 break;
382 }
383 } else {
384 switch (rrq->value) {
385 case 11000000:
386 local->tx_rate_control = HFA384X_RATES_1MBPS |
387 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
388 HFA384X_RATES_11MBPS;
389 break;
390 case 5500000:
391 local->tx_rate_control = HFA384X_RATES_1MBPS |
392 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS;
393 break;
394 case 2000000:
395 local->tx_rate_control = HFA384X_RATES_1MBPS |
396 HFA384X_RATES_2MBPS;
397 break;
398 case 1000000:
399 local->tx_rate_control = HFA384X_RATES_1MBPS;
400 break;
401 default:
402 local->tx_rate_control = HFA384X_RATES_1MBPS |
403 HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
404 HFA384X_RATES_11MBPS;
405 break;
406 }
407 }
408
409 return hostap_set_rate(dev);
410}
411
412
413static int prism2_ioctl_giwrate(struct net_device *dev,
414 struct iw_request_info *info,
415 struct iw_param *rrq, char *extra)
416{
417 u16 val;
418 struct hostap_interface *iface;
419 local_info_t *local;
420 int ret = 0;
421
422 iface = netdev_priv(dev);
423 local = iface->local;
424
425 if (local->func->get_rid(dev, HFA384X_RID_TXRATECONTROL, &val, 2, 1) <
426 0)
427 return -EINVAL;
428
429 if ((val & 0x1) && (val > 1))
430 rrq->fixed = 0;
431 else
432 rrq->fixed = 1;
433
434 if (local->iw_mode == IW_MODE_MASTER && local->ap != NULL &&
435 !local->fw_tx_rate_control) {
436 /* HFA384X_RID_CURRENTTXRATE seems to always be 2 Mbps in
437 * Host AP mode, so use the recorded TX rate of the last sent
438 * frame */
439 rrq->value = local->ap->last_tx_rate > 0 ?
440 local->ap->last_tx_rate * 100000 : 11000000;
441 return 0;
442 }
443
444 if (local->func->get_rid(dev, HFA384X_RID_CURRENTTXRATE, &val, 2, 1) <
445 0)
446 return -EINVAL;
447
448 switch (val) {
449 case HFA384X_RATES_1MBPS:
450 rrq->value = 1000000;
451 break;
452 case HFA384X_RATES_2MBPS:
453 rrq->value = 2000000;
454 break;
455 case HFA384X_RATES_5MBPS:
456 rrq->value = 5500000;
457 break;
458 case HFA384X_RATES_11MBPS:
459 rrq->value = 11000000;
460 break;
461 default:
462 /* should not happen */
463 rrq->value = 11000000;
464 ret = -EINVAL;
465 break;
466 }
467
468 return ret;
469}
470
471
472static int prism2_ioctl_siwsens(struct net_device *dev,
473 struct iw_request_info *info,
474 struct iw_param *sens, char *extra)
475{
476 struct hostap_interface *iface;
477 local_info_t *local;
478
479 iface = netdev_priv(dev);
480 local = iface->local;
481
482 /* Set the desired AP density */
483 if (sens->value < 1 || sens->value > 3)
484 return -EINVAL;
485
486 if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) ||
487 local->func->reset_port(dev))
488 return -EINVAL;
489
490 return 0;
491}
492
493static int prism2_ioctl_giwsens(struct net_device *dev,
494 struct iw_request_info *info,
495 struct iw_param *sens, char *extra)
496{
497 struct hostap_interface *iface;
498 local_info_t *local;
499 u16 val;
500
501 iface = netdev_priv(dev);
502 local = iface->local;
503
504 /* Get the current AP density */
505 if (local->func->get_rid(dev, HFA384X_RID_CNFSYSTEMSCALE, &val, 2, 1) <
506 0)
507 return -EINVAL;
508
509 sens->value = __le16_to_cpu(val);
510 sens->fixed = 1;
511
512 return 0;
513}
514
515
516/* Deprecated in new wireless extension API */
517static int prism2_ioctl_giwaplist(struct net_device *dev,
518 struct iw_request_info *info,
519 struct iw_point *data, char *extra)
520{
521 struct hostap_interface *iface;
522 local_info_t *local;
523 struct sockaddr *addr;
524 struct iw_quality *qual;
525
526 iface = netdev_priv(dev);
527 local = iface->local;
528
529 if (local->iw_mode != IW_MODE_MASTER) {
530 printk(KERN_DEBUG "SIOCGIWAPLIST is currently only supported "
531 "in Host AP mode\n");
532 data->length = 0;
533 return -EOPNOTSUPP;
534 }
535
536 addr = kmalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL);
537 qual = kmalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL);
538 if (addr == NULL || qual == NULL) {
539 kfree(addr);
540 kfree(qual);
541 data->length = 0;
542 return -ENOMEM;
543 }
544
545 data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1);
546
547 memcpy(extra, &addr, sizeof(struct sockaddr) * data->length);
548 data->flags = 1; /* has quality information */
549 memcpy(extra + sizeof(struct sockaddr) * data->length, &qual,
550 sizeof(struct iw_quality) * data->length);
551
552 kfree(addr);
553 kfree(qual);
554
555 return 0;
556}
557
558
559static int prism2_ioctl_siwrts(struct net_device *dev,
560 struct iw_request_info *info,
561 struct iw_param *rts, char *extra)
562{
563 struct hostap_interface *iface;
564 local_info_t *local;
565 u16 val;
566
567 iface = netdev_priv(dev);
568 local = iface->local;
569
570 if (rts->disabled)
571 val = __constant_cpu_to_le16(2347);
572 else if (rts->value < 0 || rts->value > 2347)
573 return -EINVAL;
574 else
575 val = __cpu_to_le16(rts->value);
576
577 if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) ||
578 local->func->reset_port(dev))
579 return -EINVAL;
580
581 local->rts_threshold = rts->value;
582
583 return 0;
584}
585
586static int prism2_ioctl_giwrts(struct net_device *dev,
587 struct iw_request_info *info,
588 struct iw_param *rts, char *extra)
589{
590 struct hostap_interface *iface;
591 local_info_t *local;
592 u16 val;
593
594 iface = netdev_priv(dev);
595 local = iface->local;
596
597 if (local->func->get_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2, 1) <
598 0)
599 return -EINVAL;
600
601 rts->value = __le16_to_cpu(val);
602 rts->disabled = (rts->value == 2347);
603 rts->fixed = 1;
604
605 return 0;
606}
607
608
609static int prism2_ioctl_siwfrag(struct net_device *dev,
610 struct iw_request_info *info,
611 struct iw_param *rts, char *extra)
612{
613 struct hostap_interface *iface;
614 local_info_t *local;
615 u16 val;
616
617 iface = netdev_priv(dev);
618 local = iface->local;
619
620 if (rts->disabled)
621 val = __constant_cpu_to_le16(2346);
622 else if (rts->value < 256 || rts->value > 2346)
623 return -EINVAL;
624 else
625 val = __cpu_to_le16(rts->value & ~0x1); /* even numbers only */
626
627 local->fragm_threshold = rts->value & ~0x1;
628 if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val,
629 2)
630 || local->func->reset_port(dev))
631 return -EINVAL;
632
633 return 0;
634}
635
636static int prism2_ioctl_giwfrag(struct net_device *dev,
637 struct iw_request_info *info,
638 struct iw_param *rts, char *extra)
639{
640 struct hostap_interface *iface;
641 local_info_t *local;
642 u16 val;
643
644 iface = netdev_priv(dev);
645 local = iface->local;
646
647 if (local->func->get_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD,
648 &val, 2, 1) < 0)
649 return -EINVAL;
650
651 rts->value = __le16_to_cpu(val);
652 rts->disabled = (rts->value == 2346);
653 rts->fixed = 1;
654
655 return 0;
656}
657
658
659#ifndef PRISM2_NO_STATION_MODES
660static int hostap_join_ap(struct net_device *dev)
661{
662 struct hostap_interface *iface;
663 local_info_t *local;
664 struct hfa384x_join_request req;
665 unsigned long flags;
666 int i;
667 struct hfa384x_hostscan_result *entry;
668
669 iface = netdev_priv(dev);
670 local = iface->local;
671
672 memcpy(req.bssid, local->preferred_ap, ETH_ALEN);
673 req.channel = 0;
674
675 spin_lock_irqsave(&local->lock, flags);
676 for (i = 0; i < local->last_scan_results_count; i++) {
677 if (!local->last_scan_results)
678 break;
679 entry = &local->last_scan_results[i];
680 if (memcmp(local->preferred_ap, entry->bssid, ETH_ALEN) == 0) {
681 req.channel = entry->chid;
682 break;
683 }
684 }
685 spin_unlock_irqrestore(&local->lock, flags);
686
687 if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
688 sizeof(req))) {
689 printk(KERN_DEBUG "%s: JoinRequest " MACSTR
690 " failed\n",
691 dev->name, MAC2STR(local->preferred_ap));
692 return -1;
693 }
694
695 printk(KERN_DEBUG "%s: Trying to join BSSID " MACSTR "\n",
696 dev->name, MAC2STR(local->preferred_ap));
697
698 return 0;
699}
700#endif /* PRISM2_NO_STATION_MODES */
701
702
703static int prism2_ioctl_siwap(struct net_device *dev,
704 struct iw_request_info *info,
705 struct sockaddr *ap_addr, char *extra)
706{
707#ifdef PRISM2_NO_STATION_MODES
708 return -EOPNOTSUPP;
709#else /* PRISM2_NO_STATION_MODES */
710 struct hostap_interface *iface;
711 local_info_t *local;
712
713 iface = netdev_priv(dev);
714 local = iface->local;
715
716 memcpy(local->preferred_ap, &ap_addr->sa_data, ETH_ALEN);
717
718 if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) {
719 struct hfa384x_scan_request scan_req;
720 memset(&scan_req, 0, sizeof(scan_req));
721 scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
722 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
723 if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST,
724 &scan_req, sizeof(scan_req))) {
725 printk(KERN_DEBUG "%s: ScanResults request failed - "
726 "preferred AP delayed to next unsolicited "
727 "scan\n", dev->name);
728 }
729 } else if (local->host_roaming == 2 &&
730 local->iw_mode == IW_MODE_INFRA) {
731 if (hostap_join_ap(dev))
732 return -EINVAL;
733 } else {
734 printk(KERN_DEBUG "%s: Preferred AP (SIOCSIWAP) is used only "
735 "in Managed mode when host_roaming is enabled\n",
736 dev->name);
737 }
738
739 return 0;
740#endif /* PRISM2_NO_STATION_MODES */
741}
742
743static int prism2_ioctl_giwap(struct net_device *dev,
744 struct iw_request_info *info,
745 struct sockaddr *ap_addr, char *extra)
746{
747 struct hostap_interface *iface;
748 local_info_t *local;
749
750 iface = netdev_priv(dev);
751 local = iface->local;
752
753 ap_addr->sa_family = ARPHRD_ETHER;
754 switch (iface->type) {
755 case HOSTAP_INTERFACE_AP:
756 memcpy(&ap_addr->sa_data, dev->dev_addr, ETH_ALEN);
757 break;
758 case HOSTAP_INTERFACE_STA:
759 memcpy(&ap_addr->sa_data, local->assoc_ap_addr, ETH_ALEN);
760 break;
761 case HOSTAP_INTERFACE_WDS:
762 memcpy(&ap_addr->sa_data, iface->u.wds.remote_addr, ETH_ALEN);
763 break;
764 default:
765 if (local->func->get_rid(dev, HFA384X_RID_CURRENTBSSID,
766 &ap_addr->sa_data, ETH_ALEN, 1) < 0)
767 return -EOPNOTSUPP;
768
769 /* local->bssid is also updated in LinkStatus handler when in
770 * station mode */
771 memcpy(local->bssid, &ap_addr->sa_data, ETH_ALEN);
772 break;
773 }
774
775 return 0;
776}
777
778
779static int prism2_ioctl_siwnickn(struct net_device *dev,
780 struct iw_request_info *info,
781 struct iw_point *data, char *nickname)
782{
783 struct hostap_interface *iface;
784 local_info_t *local;
785
786 iface = netdev_priv(dev);
787 local = iface->local;
788
789 memset(local->name, 0, sizeof(local->name));
790 memcpy(local->name, nickname, data->length);
791 local->name_set = 1;
792
793 if (hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name) ||
794 local->func->reset_port(dev))
795 return -EINVAL;
796
797 return 0;
798}
799
800static int prism2_ioctl_giwnickn(struct net_device *dev,
801 struct iw_request_info *info,
802 struct iw_point *data, char *nickname)
803{
804 struct hostap_interface *iface;
805 local_info_t *local;
806 int len;
807 char name[MAX_NAME_LEN + 3];
808 u16 val;
809
810 iface = netdev_priv(dev);
811 local = iface->local;
812
813 len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME,
814 &name, MAX_NAME_LEN + 2, 0);
815 val = __le16_to_cpu(*(u16 *) name);
816 if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN)
817 return -EOPNOTSUPP;
818
819 name[val + 2] = '\0';
820 data->length = val + 1;
821 memcpy(nickname, name + 2, val + 1);
822
823 return 0;
824}
825
826
827static int prism2_ioctl_siwfreq(struct net_device *dev,
828 struct iw_request_info *info,
829 struct iw_freq *freq, char *extra)
830{
831 struct hostap_interface *iface;
832 local_info_t *local;
833
834 iface = netdev_priv(dev);
835 local = iface->local;
836
837 /* freq => chan. */
838 if (freq->e == 1 &&
839 freq->m / 100000 >= freq_list[0] &&
840 freq->m / 100000 <= freq_list[FREQ_COUNT - 1]) {
841 int ch;
842 int fr = freq->m / 100000;
843 for (ch = 0; ch < FREQ_COUNT; ch++) {
844 if (fr == freq_list[ch]) {
845 freq->e = 0;
846 freq->m = ch + 1;
847 break;
848 }
849 }
850 }
851
852 if (freq->e != 0 || freq->m < 1 || freq->m > FREQ_COUNT ||
853 !(local->channel_mask & (1 << (freq->m - 1))))
854 return -EINVAL;
855
856 local->channel = freq->m; /* channel is used in prism2_setup_rids() */
857 if (hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel) ||
858 local->func->reset_port(dev))
859 return -EINVAL;
860
861 return 0;
862}
863
864static int prism2_ioctl_giwfreq(struct net_device *dev,
865 struct iw_request_info *info,
866 struct iw_freq *freq, char *extra)
867{
868 struct hostap_interface *iface;
869 local_info_t *local;
870 u16 val;
871
872 iface = netdev_priv(dev);
873 local = iface->local;
874
875 if (local->func->get_rid(dev, HFA384X_RID_CURRENTCHANNEL, &val, 2, 1) <
876 0)
877 return -EINVAL;
878
879 le16_to_cpus(&val);
880 if (val < 1 || val > FREQ_COUNT)
881 return -EINVAL;
882
883 freq->m = freq_list[val - 1] * 100000;
884 freq->e = 1;
885
886 return 0;
887}
888
889
890static void hostap_monitor_set_type(local_info_t *local)
891{
892 struct net_device *dev = local->ddev;
893
894 if (dev == NULL)
895 return;
896
897 if (local->monitor_type == PRISM2_MONITOR_PRISM ||
898 local->monitor_type == PRISM2_MONITOR_CAPHDR) {
899 dev->type = ARPHRD_IEEE80211_PRISM;
900 dev->hard_header_parse =
901 hostap_80211_prism_header_parse;
902 } else {
903 dev->type = ARPHRD_IEEE80211;
904 dev->hard_header_parse = hostap_80211_header_parse;
905 }
906}
907
908
909static int prism2_ioctl_siwessid(struct net_device *dev,
910 struct iw_request_info *info,
911 struct iw_point *data, char *ssid)
912{
913 struct hostap_interface *iface;
914 local_info_t *local;
915
916 iface = netdev_priv(dev);
917 local = iface->local;
918
919 if (iface->type == HOSTAP_INTERFACE_WDS)
920 return -EOPNOTSUPP;
921
922 if (data->flags == 0)
923 ssid[0] = '\0'; /* ANY */
924
925 if (local->iw_mode == IW_MODE_MASTER && ssid[0] == '\0') {
926 /* Setting SSID to empty string seems to kill the card in
927 * Host AP mode */
928 printk(KERN_DEBUG "%s: Host AP mode does not support "
929 "'Any' essid\n", dev->name);
930 return -EINVAL;
931 }
932
933 memcpy(local->essid, ssid, data->length);
934 local->essid[data->length] = '\0';
935
936 if ((!local->fw_ap &&
937 hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid))
938 || hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid) ||
939 local->func->reset_port(dev))
940 return -EINVAL;
941
942 return 0;
943}
944
945static int prism2_ioctl_giwessid(struct net_device *dev,
946 struct iw_request_info *info,
947 struct iw_point *data, char *essid)
948{
949 struct hostap_interface *iface;
950 local_info_t *local;
951 u16 val;
952
953 iface = netdev_priv(dev);
954 local = iface->local;
955
956 if (iface->type == HOSTAP_INTERFACE_WDS)
957 return -EOPNOTSUPP;
958
959 data->flags = 1; /* active */
960 if (local->iw_mode == IW_MODE_MASTER) {
961 data->length = strlen(local->essid);
962 memcpy(essid, local->essid, IW_ESSID_MAX_SIZE);
963 } else {
964 int len;
965 char ssid[MAX_SSID_LEN + 2];
966 memset(ssid, 0, sizeof(ssid));
967 len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID,
968 &ssid, MAX_SSID_LEN + 2, 0);
969 val = __le16_to_cpu(*(u16 *) ssid);
970 if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) {
971 return -EOPNOTSUPP;
972 }
973 data->length = val;
974 memcpy(essid, ssid + 2, IW_ESSID_MAX_SIZE);
975 }
976
977 return 0;
978}
979
980
981static int prism2_ioctl_giwrange(struct net_device *dev,
982 struct iw_request_info *info,
983 struct iw_point *data, char *extra)
984{
985 struct hostap_interface *iface;
986 local_info_t *local;
987 struct iw_range *range = (struct iw_range *) extra;
988 u8 rates[10];
989 u16 val;
990 int i, len, over2;
991
992 iface = netdev_priv(dev);
993 local = iface->local;
994
995 data->length = sizeof(struct iw_range);
996 memset(range, 0, sizeof(struct iw_range));
997
998 /* TODO: could fill num_txpower and txpower array with
999 * something; however, there are 128 different values.. */
1000
1001 range->txpower_capa = IW_TXPOW_DBM;
1002
1003 if (local->iw_mode == IW_MODE_INFRA || local->iw_mode == IW_MODE_ADHOC)
1004 {
1005 range->min_pmp = 1 * 1024;
1006 range->max_pmp = 65535 * 1024;
1007 range->min_pmt = 1 * 1024;
1008 range->max_pmt = 1000 * 1024;
1009 range->pmp_flags = IW_POWER_PERIOD;
1010 range->pmt_flags = IW_POWER_TIMEOUT;
1011 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
1012 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
1013 }
1014
1015 range->we_version_compiled = WIRELESS_EXT;
1016 range->we_version_source = 18;
1017
1018 range->retry_capa = IW_RETRY_LIMIT;
1019 range->retry_flags = IW_RETRY_LIMIT;
1020 range->min_retry = 0;
1021 range->max_retry = 255;
1022
1023 range->num_channels = FREQ_COUNT;
1024
1025 val = 0;
1026 for (i = 0; i < FREQ_COUNT; i++) {
1027 if (local->channel_mask & (1 << i)) {
1028 range->freq[val].i = i + 1;
1029 range->freq[val].m = freq_list[i] * 100000;
1030 range->freq[val].e = 1;
1031 val++;
1032 }
1033 if (val == IW_MAX_FREQUENCIES)
1034 break;
1035 }
1036 range->num_frequency = val;
1037
1038 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1)) {
1039 range->max_qual.qual = 70; /* what is correct max? This was not
1040 * documented exactly. At least
1041 * 69 has been observed. */
1042 range->max_qual.level = 0; /* dB */
1043 range->max_qual.noise = 0; /* dB */
1044
1045 /* What would be suitable values for "average/typical" qual? */
1046 range->avg_qual.qual = 20;
1047 range->avg_qual.level = -60;
1048 range->avg_qual.noise = -95;
1049 } else {
1050 range->max_qual.qual = 92; /* 0 .. 92 */
1051 range->max_qual.level = 154; /* 27 .. 154 */
1052 range->max_qual.noise = 154; /* 27 .. 154 */
1053 }
1054 range->sensitivity = 3;
1055
1056 range->max_encoding_tokens = WEP_KEYS;
1057 range->num_encoding_sizes = 2;
1058 range->encoding_size[0] = 5;
1059 range->encoding_size[1] = 13;
1060
1061 over2 = 0;
1062 len = prism2_get_datarates(dev, rates);
1063 range->num_bitrates = 0;
1064 for (i = 0; i < len; i++) {
1065 if (range->num_bitrates < IW_MAX_BITRATES) {
1066 range->bitrate[range->num_bitrates] =
1067 rates[i] * 500000;
1068 range->num_bitrates++;
1069 }
1070 if (rates[i] == 0x0b || rates[i] == 0x16)
1071 over2 = 1;
1072 }
1073 /* estimated maximum TCP throughput values (bps) */
1074 range->throughput = over2 ? 5500000 : 1500000;
1075
1076 range->min_rts = 0;
1077 range->max_rts = 2347;
1078 range->min_frag = 256;
1079 range->max_frag = 2346;
1080
1081 /* Event capability (kernel + driver) */
1082 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
1083 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
1084 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
1085 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
1086 range->event_capa[1] = IW_EVENT_CAPA_K_1;
1087 range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
1088 IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
1089 IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
1090 IW_EVENT_CAPA_MASK(IWEVEXPIRED));
1091
1092 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1093 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1094
1095 return 0;
1096}
1097
1098
1099static int hostap_monitor_mode_enable(local_info_t *local)
1100{
1101 struct net_device *dev = local->dev;
1102
1103 printk(KERN_DEBUG "Enabling monitor mode\n");
1104 hostap_monitor_set_type(local);
1105
1106 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1107 HFA384X_PORTTYPE_PSEUDO_IBSS)) {
1108 printk(KERN_DEBUG "Port type setting for monitor mode "
1109 "failed\n");
1110 return -EOPNOTSUPP;
1111 }
1112
1113 /* Host decrypt is needed to get the IV and ICV fields;
1114 * however, monitor mode seems to remove WEP flag from frame
1115 * control field */
1116 if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
1117 HFA384X_WEPFLAGS_HOSTENCRYPT |
1118 HFA384X_WEPFLAGS_HOSTDECRYPT)) {
1119 printk(KERN_DEBUG "WEP flags setting failed\n");
1120 return -EOPNOTSUPP;
1121 }
1122
1123 if (local->func->reset_port(dev) ||
1124 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1125 (HFA384X_TEST_MONITOR << 8),
1126 0, NULL, NULL)) {
1127 printk(KERN_DEBUG "Setting monitor mode failed\n");
1128 return -EOPNOTSUPP;
1129 }
1130
1131 return 0;
1132}
1133
1134
1135static int hostap_monitor_mode_disable(local_info_t *local)
1136{
1137 struct net_device *dev = local->ddev;
1138
1139 if (dev == NULL)
1140 return -1;
1141
1142 printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);
1143 dev->type = ARPHRD_ETHER;
1144 dev->hard_header_parse = local->saved_eth_header_parse;
1145 if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1146 (HFA384X_TEST_STOP << 8),
1147 0, NULL, NULL))
1148 return -1;
1149 return hostap_set_encryption(local);
1150}
1151
1152
1153static int prism2_ioctl_siwmode(struct net_device *dev,
1154 struct iw_request_info *info,
1155 __u32 *mode, char *extra)
1156{
1157 struct hostap_interface *iface;
1158 local_info_t *local;
1159 int double_reset = 0;
1160
1161 iface = netdev_priv(dev);
1162 local = iface->local;
1163
1164 if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
1165 *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&
1166 *mode != IW_MODE_MONITOR)
1167 return -EOPNOTSUPP;
1168
1169#ifdef PRISM2_NO_STATION_MODES
1170 if (*mode == IW_MODE_ADHOC || *mode == IW_MODE_INFRA)
1171 return -EOPNOTSUPP;
1172#endif /* PRISM2_NO_STATION_MODES */
1173
1174 if (*mode == local->iw_mode)
1175 return 0;
1176
1177 if (*mode == IW_MODE_MASTER && local->essid[0] == '\0') {
1178 printk(KERN_WARNING "%s: empty SSID not allowed in Master "
1179 "mode\n", dev->name);
1180 return -EINVAL;
1181 }
1182
1183 if (local->iw_mode == IW_MODE_MONITOR)
1184 hostap_monitor_mode_disable(local);
1185
1186 if ((local->iw_mode == IW_MODE_ADHOC ||
1187 local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) {
1188 /* There seems to be a firmware bug in at least STA f/w v1.5.6
1189 * that leaves beacon frames to use IBSS type when moving from
1190 * IBSS to Host AP mode. Doing double Port0 reset seems to be
1191 * enough to workaround this. */
1192 double_reset = 1;
1193 }
1194
1195 printk(KERN_DEBUG "prism2: %s: operating mode changed "
1196 "%d -> %d\n", dev->name, local->iw_mode, *mode);
1197 local->iw_mode = *mode;
1198
1199 if (local->iw_mode == IW_MODE_MONITOR)
1200 hostap_monitor_mode_enable(local);
1201 else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
1202 !local->fw_encrypt_ok) {
1203 printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
1204 "a workaround for firmware bug in Host AP mode WEP\n",
1205 dev->name);
1206 local->host_encrypt = 1;
1207 }
1208
1209 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
1210 hostap_get_porttype(local)))
1211 return -EOPNOTSUPP;
1212
1213 if (local->func->reset_port(dev))
1214 return -EINVAL;
1215 if (double_reset && local->func->reset_port(dev))
1216 return -EINVAL;
1217
1218 if (local->iw_mode != IW_MODE_INFRA && local->iw_mode != IW_MODE_ADHOC)
1219 {
1220 /* netif_carrier is used only in client modes for now, so make
1221 * sure carrier is on when moving to non-client modes. */
1222 netif_carrier_on(local->dev);
1223 netif_carrier_on(local->ddev);
1224 }
1225 return 0;
1226}
1227
1228
1229static int prism2_ioctl_giwmode(struct net_device *dev,
1230 struct iw_request_info *info,
1231 __u32 *mode, char *extra)
1232{
1233 struct hostap_interface *iface;
1234 local_info_t *local;
1235
1236 iface = netdev_priv(dev);
1237 local = iface->local;
1238
1239 switch (iface->type) {
1240 case HOSTAP_INTERFACE_STA:
1241 *mode = IW_MODE_INFRA;
1242 break;
1243 case HOSTAP_INTERFACE_WDS:
1244 *mode = IW_MODE_REPEAT;
1245 break;
1246 default:
1247 *mode = local->iw_mode;
1248 break;
1249 }
1250 return 0;
1251}
1252
1253
1254static int prism2_ioctl_siwpower(struct net_device *dev,
1255 struct iw_request_info *info,
1256 struct iw_param *wrq, char *extra)
1257{
1258#ifdef PRISM2_NO_STATION_MODES
1259 return -EOPNOTSUPP;
1260#else /* PRISM2_NO_STATION_MODES */
1261 int ret = 0;
1262
1263 if (wrq->disabled)
1264 return hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 0);
1265
1266 switch (wrq->flags & IW_POWER_MODE) {
1267 case IW_POWER_UNICAST_R:
1268 ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 0);
1269 if (ret)
1270 return ret;
1271 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1272 if (ret)
1273 return ret;
1274 break;
1275 case IW_POWER_ALL_R:
1276 ret = hostap_set_word(dev, HFA384X_RID_CNFMULTICASTRECEIVE, 1);
1277 if (ret)
1278 return ret;
1279 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1280 if (ret)
1281 return ret;
1282 break;
1283 case IW_POWER_ON:
1284 break;
1285 default:
1286 return -EINVAL;
1287 }
1288
1289 if (wrq->flags & IW_POWER_TIMEOUT) {
1290 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1291 if (ret)
1292 return ret;
1293 ret = hostap_set_word(dev, HFA384X_RID_CNFPMHOLDOVERDURATION,
1294 wrq->value / 1024);
1295 if (ret)
1296 return ret;
1297 }
1298 if (wrq->flags & IW_POWER_PERIOD) {
1299 ret = hostap_set_word(dev, HFA384X_RID_CNFPMENABLED, 1);
1300 if (ret)
1301 return ret;
1302 ret = hostap_set_word(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1303 wrq->value / 1024);
1304 if (ret)
1305 return ret;
1306 }
1307
1308 return ret;
1309#endif /* PRISM2_NO_STATION_MODES */
1310}
1311
1312
1313static int prism2_ioctl_giwpower(struct net_device *dev,
1314 struct iw_request_info *info,
1315 struct iw_param *rrq, char *extra)
1316{
1317#ifdef PRISM2_NO_STATION_MODES
1318 return -EOPNOTSUPP;
1319#else /* PRISM2_NO_STATION_MODES */
1320 struct hostap_interface *iface;
1321 local_info_t *local;
1322 u16 enable, mcast;
1323
1324 iface = netdev_priv(dev);
1325 local = iface->local;
1326
1327 if (local->func->get_rid(dev, HFA384X_RID_CNFPMENABLED, &enable, 2, 1)
1328 < 0)
1329 return -EINVAL;
1330
1331 if (!__le16_to_cpu(enable)) {
1332 rrq->disabled = 1;
1333 return 0;
1334 }
1335
1336 rrq->disabled = 0;
1337
1338 if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
1339 u16 timeout;
1340 if (local->func->get_rid(dev,
1341 HFA384X_RID_CNFPMHOLDOVERDURATION,
1342 &timeout, 2, 1) < 0)
1343 return -EINVAL;
1344
1345 rrq->flags = IW_POWER_TIMEOUT;
1346 rrq->value = __le16_to_cpu(timeout) * 1024;
1347 } else {
1348 u16 period;
1349 if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
1350 &period, 2, 1) < 0)
1351 return -EINVAL;
1352
1353 rrq->flags = IW_POWER_PERIOD;
1354 rrq->value = __le16_to_cpu(period) * 1024;
1355 }
1356
1357 if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast,
1358 2, 1) < 0)
1359 return -EINVAL;
1360
1361 if (__le16_to_cpu(mcast))
1362 rrq->flags |= IW_POWER_ALL_R;
1363 else
1364 rrq->flags |= IW_POWER_UNICAST_R;
1365
1366 return 0;
1367#endif /* PRISM2_NO_STATION_MODES */
1368}
1369
1370
1371static int prism2_ioctl_siwretry(struct net_device *dev,
1372 struct iw_request_info *info,
1373 struct iw_param *rrq, char *extra)
1374{
1375 struct hostap_interface *iface;
1376 local_info_t *local;
1377
1378 iface = netdev_priv(dev);
1379 local = iface->local;
1380
1381 if (rrq->disabled)
1382 return -EINVAL;
1383
1384 /* setting retry limits is not supported with the current station
1385 * firmware code; simulate this with alternative retry count for now */
1386 if (rrq->flags == IW_RETRY_LIMIT) {
1387 if (rrq->value < 0) {
1388 /* disable manual retry count setting and use firmware
1389 * defaults */
1390 local->manual_retry_count = -1;
1391 local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY;
1392 } else {
1393 if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
1394 rrq->value)) {
1395 printk(KERN_DEBUG "%s: Alternate retry count "
1396 "setting to %d failed\n",
1397 dev->name, rrq->value);
1398 return -EOPNOTSUPP;
1399 }
1400
1401 local->manual_retry_count = rrq->value;
1402 local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;
1403 }
1404 return 0;
1405 }
1406
1407 return -EOPNOTSUPP;
1408
1409#if 0
1410 /* what could be done, if firmware would support this.. */
1411
1412 if (rrq->flags & IW_RETRY_LIMIT) {
1413 if (rrq->flags & IW_RETRY_MAX)
1414 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1415 else if (rrq->flags & IW_RETRY_MIN)
1416 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1417 else {
1418 HFA384X_RID_LONGRETRYLIMIT = rrq->value;
1419 HFA384X_RID_SHORTRETRYLIMIT = rrq->value;
1420 }
1421
1422 }
1423
1424 if (rrq->flags & IW_RETRY_LIFETIME) {
1425 HFA384X_RID_MAXTRANSMITLIFETIME = rrq->value / 1024;
1426 }
1427
1428 return 0;
1429#endif /* 0 */
1430}
1431
1432static int prism2_ioctl_giwretry(struct net_device *dev,
1433 struct iw_request_info *info,
1434 struct iw_param *rrq, char *extra)
1435{
1436 struct hostap_interface *iface;
1437 local_info_t *local;
1438 u16 shortretry, longretry, lifetime, altretry;
1439
1440 iface = netdev_priv(dev);
1441 local = iface->local;
1442
1443 if (local->func->get_rid(dev, HFA384X_RID_SHORTRETRYLIMIT, &shortretry,
1444 2, 1) < 0 ||
1445 local->func->get_rid(dev, HFA384X_RID_LONGRETRYLIMIT, &longretry,
1446 2, 1) < 0 ||
1447 local->func->get_rid(dev, HFA384X_RID_MAXTRANSMITLIFETIME,
1448 &lifetime, 2, 1) < 0)
1449 return -EINVAL;
1450
1451 le16_to_cpus(&shortretry);
1452 le16_to_cpus(&longretry);
1453 le16_to_cpus(&lifetime);
1454
1455 rrq->disabled = 0;
1456
1457 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1458 rrq->flags = IW_RETRY_LIFETIME;
1459 rrq->value = lifetime * 1024;
1460 } else {
1461 if (local->manual_retry_count >= 0) {
1462 rrq->flags = IW_RETRY_LIMIT;
1463 if (local->func->get_rid(dev,
1464 HFA384X_RID_CNFALTRETRYCOUNT,
1465 &altretry, 2, 1) >= 0)
1466 rrq->value = le16_to_cpu(altretry);
1467 else
1468 rrq->value = local->manual_retry_count;
1469 } else if ((rrq->flags & IW_RETRY_MAX)) {
1470 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1471 rrq->value = longretry;
1472 } else {
1473 rrq->flags = IW_RETRY_LIMIT;
1474 rrq->value = shortretry;
1475 if (shortretry != longretry)
1476 rrq->flags |= IW_RETRY_MIN;
1477 }
1478 }
1479 return 0;
1480}
1481
1482
1483/* Note! This TX power controlling is experimental and should not be used in
1484 * production use. It just sets raw power register and does not use any kind of
1485 * feedback information from the measured TX power (CR58). This is now
1486 * commented out to make sure that it is not used by accident. TX power
1487 * configuration will be enabled again after proper algorithm using feedback
1488 * has been implemented. */
1489
1490#ifdef RAW_TXPOWER_SETTING
1491/* Map HFA386x's CR31 to and from dBm with some sort of ad hoc mapping..
1492 * This version assumes following mapping:
1493 * CR31 is 7-bit value with -64 to +63 range.
1494 * -64 is mapped into +20dBm and +63 into -43dBm.
1495 * This is certainly not an exact mapping for every card, but at least
1496 * increasing dBm value should correspond to increasing TX power.
1497 */
1498
1499static int prism2_txpower_hfa386x_to_dBm(u16 val)
1500{
1501 signed char tmp;
1502
1503 if (val > 255)
1504 val = 255;
1505
1506 tmp = val;
1507 tmp >>= 2;
1508
1509 return -12 - tmp;
1510}
1511
1512static u16 prism2_txpower_dBm_to_hfa386x(int val)
1513{
1514 signed char tmp;
1515
1516 if (val > 20)
1517 return 128;
1518 else if (val < -43)
1519 return 127;
1520
1521 tmp = val;
1522 tmp = -12 - tmp;
1523 tmp <<= 2;
1524
1525 return (unsigned char) tmp;
1526}
1527#endif /* RAW_TXPOWER_SETTING */
1528
1529
1530static int prism2_ioctl_siwtxpow(struct net_device *dev,
1531 struct iw_request_info *info,
1532 struct iw_param *rrq, char *extra)
1533{
1534 struct hostap_interface *iface;
1535 local_info_t *local;
1536#ifdef RAW_TXPOWER_SETTING
1537 char *tmp;
1538#endif
1539 u16 val;
1540 int ret = 0;
1541
1542 iface = netdev_priv(dev);
1543 local = iface->local;
1544
1545 if (rrq->disabled) {
1546 if (local->txpower_type != PRISM2_TXPOWER_OFF) {
1547 val = 0xff; /* use all standby and sleep modes */
1548 ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1549 HFA386X_CR_A_D_TEST_MODES2,
1550 &val, NULL);
1551 printk(KERN_DEBUG "%s: Turning radio off: %s\n",
1552 dev->name, ret ? "failed" : "OK");
1553 local->txpower_type = PRISM2_TXPOWER_OFF;
1554 }
1555 return (ret ? -EOPNOTSUPP : 0);
1556 }
1557
1558 if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1559 val = 0; /* disable all standby and sleep modes */
1560 ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1561 HFA386X_CR_A_D_TEST_MODES2, &val, NULL);
1562 printk(KERN_DEBUG "%s: Turning radio on: %s\n",
1563 dev->name, ret ? "failed" : "OK");
1564 local->txpower_type = PRISM2_TXPOWER_UNKNOWN;
1565 }
1566
1567#ifdef RAW_TXPOWER_SETTING
1568 if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) {
1569 printk(KERN_DEBUG "Setting ALC on\n");
1570 val = HFA384X_TEST_CFG_BIT_ALC;
1571 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1572 (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL);
1573 local->txpower_type = PRISM2_TXPOWER_AUTO;
1574 return 0;
1575 }
1576
1577 if (local->txpower_type != PRISM2_TXPOWER_FIXED) {
1578 printk(KERN_DEBUG "Setting ALC off\n");
1579 val = HFA384X_TEST_CFG_BIT_ALC;
1580 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
1581 (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
1582 local->txpower_type = PRISM2_TXPOWER_FIXED;
1583 }
1584
1585 if (rrq->flags == IW_TXPOW_DBM)
1586 tmp = "dBm";
1587 else if (rrq->flags == IW_TXPOW_MWATT)
1588 tmp = "mW";
1589 else
1590 tmp = "UNKNOWN";
1591 printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp);
1592
1593 if (rrq->flags != IW_TXPOW_DBM) {
1594 printk("SIOCSIWTXPOW with mW is not supported; use dBm\n");
1595 return -EOPNOTSUPP;
1596 }
1597
1598 local->txpower = rrq->value;
1599 val = prism2_txpower_dBm_to_hfa386x(local->txpower);
1600 if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
1601 HFA386X_CR_MANUAL_TX_POWER, &val, NULL))
1602 ret = -EOPNOTSUPP;
1603#else /* RAW_TXPOWER_SETTING */
1604 if (rrq->fixed)
1605 ret = -EOPNOTSUPP;
1606#endif /* RAW_TXPOWER_SETTING */
1607
1608 return ret;
1609}
1610
1611static int prism2_ioctl_giwtxpow(struct net_device *dev,
1612 struct iw_request_info *info,
1613 struct iw_param *rrq, char *extra)
1614{
1615#ifdef RAW_TXPOWER_SETTING
1616 struct hostap_interface *iface;
1617 local_info_t *local;
1618 u16 resp0;
1619
1620 iface = netdev_priv(dev);
1621 local = iface->local;
1622
1623 rrq->flags = IW_TXPOW_DBM;
1624 rrq->disabled = 0;
1625 rrq->fixed = 0;
1626
1627 if (local->txpower_type == PRISM2_TXPOWER_AUTO) {
1628 if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,
1629 HFA386X_CR_MANUAL_TX_POWER,
1630 NULL, &resp0) == 0) {
1631 rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);
1632 } else {
1633 /* Could not get real txpower; guess 15 dBm */
1634 rrq->value = 15;
1635 }
1636 } else if (local->txpower_type == PRISM2_TXPOWER_OFF) {
1637 rrq->value = 0;
1638 rrq->disabled = 1;
1639 } else if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
1640 rrq->value = local->txpower;
1641 rrq->fixed = 1;
1642 } else {
1643 printk("SIOCGIWTXPOW - unknown txpower_type=%d\n",
1644 local->txpower_type);
1645 }
1646 return 0;
1647#else /* RAW_TXPOWER_SETTING */
1648 return -EOPNOTSUPP;
1649#endif /* RAW_TXPOWER_SETTING */
1650}
1651
1652
1653#ifndef PRISM2_NO_STATION_MODES
1654
1655/* HostScan request works with and without host_roaming mode. In addition, it
1656 * does not break current association. However, it requires newer station
1657 * firmware version (>= 1.3.1) than scan request. */
1658static int prism2_request_hostscan(struct net_device *dev,
1659 u8 *ssid, u8 ssid_len)
1660{
1661 struct hostap_interface *iface;
1662 local_info_t *local;
1663 struct hfa384x_hostscan_request scan_req;
1664
1665 iface = netdev_priv(dev);
1666 local = iface->local;
1667
1668 memset(&scan_req, 0, sizeof(scan_req));
1669 scan_req.channel_list = cpu_to_le16(local->channel_mask &
1670 local->scan_channel_mask);
1671 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
1672 if (ssid) {
1673 if (ssid_len > 32)
1674 return -EINVAL;
1675 scan_req.target_ssid_len = cpu_to_le16(ssid_len);
1676 memcpy(scan_req.target_ssid, ssid, ssid_len);
1677 }
1678
1679 if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
1680 sizeof(scan_req))) {
1681 printk(KERN_DEBUG "%s: HOSTSCAN failed\n", dev->name);
1682 return -EINVAL;
1683 }
1684 return 0;
1685}
1686
1687
1688static int prism2_request_scan(struct net_device *dev)
1689{
1690 struct hostap_interface *iface;
1691 local_info_t *local;
1692 struct hfa384x_scan_request scan_req;
1693 int ret = 0;
1694
1695 iface = netdev_priv(dev);
1696 local = iface->local;
1697
1698 memset(&scan_req, 0, sizeof(scan_req));
1699 scan_req.channel_list = cpu_to_le16(local->channel_mask &
1700 local->scan_channel_mask);
1701 scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
1702
1703 /* FIX:
1704 * It seems to be enough to set roaming mode for a short moment to
1705 * host-based and then setup scanrequest data and return the mode to
1706 * firmware-based.
1707 *
1708 * Master mode would need to drop to Managed mode for a short while
1709 * to make scanning work.. Or sweep through the different channels and
1710 * use passive scan based on beacons. */
1711
1712 if (!local->host_roaming)
1713 hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1714 HFA384X_ROAMING_HOST);
1715
1716 if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST, &scan_req,
1717 sizeof(scan_req))) {
1718 printk(KERN_DEBUG "SCANREQUEST failed\n");
1719 ret = -EINVAL;
1720 }
1721
1722 if (!local->host_roaming)
1723 hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE,
1724 HFA384X_ROAMING_FIRMWARE);
1725
1726 return 0;
1727}
1728
1729#else /* !PRISM2_NO_STATION_MODES */
1730
1731static inline int prism2_request_hostscan(struct net_device *dev,
1732 u8 *ssid, u8 ssid_len)
1733{
1734 return -EOPNOTSUPP;
1735}
1736
1737
1738static inline int prism2_request_scan(struct net_device *dev)
1739{
1740 return -EOPNOTSUPP;
1741}
1742
1743#endif /* !PRISM2_NO_STATION_MODES */
1744
1745
1746static int prism2_ioctl_siwscan(struct net_device *dev,
1747 struct iw_request_info *info,
1748 struct iw_point *data, char *extra)
1749{
1750 struct hostap_interface *iface;
1751 local_info_t *local;
1752 int ret;
1753 u8 *ssid = NULL, ssid_len = 0;
1754 struct iw_scan_req *req = (struct iw_scan_req *) extra;
1755
1756 iface = netdev_priv(dev);
1757 local = iface->local;
1758
1759 if (data->length < sizeof(struct iw_scan_req))
1760 req = NULL;
1761
1762 if (local->iw_mode == IW_MODE_MASTER) {
1763 /* In master mode, we just return the results of our local
1764 * tables, so we don't need to start anything...
1765 * Jean II */
1766 data->length = 0;
1767 return 0;
1768 }
1769
1770 if (!local->dev_enabled)
1771 return -ENETDOWN;
1772
1773 if (req && data->flags & IW_SCAN_THIS_ESSID) {
1774 ssid = req->essid;
1775 ssid_len = req->essid_len;
1776
1777 if (ssid_len &&
1778 ((local->iw_mode != IW_MODE_INFRA &&
1779 local->iw_mode != IW_MODE_ADHOC) ||
1780 (local->sta_fw_ver < PRISM2_FW_VER(1,3,1))))
1781 return -EOPNOTSUPP;
1782 }
1783
1784 if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))
1785 ret = prism2_request_hostscan(dev, ssid, ssid_len);
1786 else
1787 ret = prism2_request_scan(dev);
1788
1789 if (ret == 0)
1790 local->scan_timestamp = jiffies;
1791
1792 /* Could inquire F101, F103 or wait for SIOCGIWSCAN and read RID */
1793
1794 return ret;
1795}
1796
1797
1798#ifndef PRISM2_NO_STATION_MODES
1799static char * __prism2_translate_scan(local_info_t *local,
1800 struct hfa384x_hostscan_result *scan,
1801 struct hostap_bss_info *bss,
1802 char *current_ev, char *end_buf)
1803{
1804 int i, chan;
1805 struct iw_event iwe;
1806 char *current_val;
1807 u16 capabilities;
1808 u8 *pos;
1809 u8 *ssid, *bssid;
1810 size_t ssid_len;
1811 char *buf;
1812
1813 if (bss) {
1814 ssid = bss->ssid;
1815 ssid_len = bss->ssid_len;
1816 bssid = bss->bssid;
1817 } else {
1818 ssid = scan->ssid;
1819 ssid_len = le16_to_cpu(scan->ssid_len);
1820 bssid = scan->bssid;
1821 }
1822 if (ssid_len > 32)
1823 ssid_len = 32;
1824
1825 /* First entry *MUST* be the AP MAC address */
1826 memset(&iwe, 0, sizeof(iwe));
1827 iwe.cmd = SIOCGIWAP;
1828 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1829 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
1830 /* FIX:
1831 * I do not know how this is possible, but iwe_stream_add_event
1832 * seems to re-order memcpy execution so that len is set only
1833 * after copying.. Pre-setting len here "fixes" this, but real
1834 * problems should be solved (after which these iwe.len
1835 * settings could be removed from this function). */
1836 iwe.len = IW_EV_ADDR_LEN;
1837 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1838 IW_EV_ADDR_LEN);
1839
1840 /* Other entries will be displayed in the order we give them */
1841
1842 memset(&iwe, 0, sizeof(iwe));
1843 iwe.cmd = SIOCGIWESSID;
1844 iwe.u.data.length = ssid_len;
1845 iwe.u.data.flags = 1;
1846 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1847 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
1848
1849 memset(&iwe, 0, sizeof(iwe));
1850 iwe.cmd = SIOCGIWMODE;
1851 if (bss) {
1852 capabilities = bss->capab_info;
1853 } else {
1854 capabilities = le16_to_cpu(scan->capability);
1855 }
1856 if (capabilities & (WLAN_CAPABILITY_ESS |
1857 WLAN_CAPABILITY_IBSS)) {
1858 if (capabilities & WLAN_CAPABILITY_ESS)
1859 iwe.u.mode = IW_MODE_MASTER;
1860 else
1861 iwe.u.mode = IW_MODE_ADHOC;
1862 iwe.len = IW_EV_UINT_LEN;
1863 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1864 IW_EV_UINT_LEN);
1865 }
1866
1867 memset(&iwe, 0, sizeof(iwe));
1868 iwe.cmd = SIOCGIWFREQ;
1869 if (scan) {
1870 chan = scan->chid;
1871 } else if (bss) {
1872 chan = bss->chan;
1873 } else {
1874 chan = 0;
1875 }
1876
1877 if (chan > 0) {
1878 iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
1879 iwe.u.freq.e = 1;
1880 iwe.len = IW_EV_FREQ_LEN;
1881 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1882 IW_EV_FREQ_LEN);
1883 }
1884
1885 if (scan) {
1886 memset(&iwe, 0, sizeof(iwe));
1887 iwe.cmd = IWEVQUAL;
1888 if (local->last_scan_type == PRISM2_HOSTSCAN) {
1889 iwe.u.qual.level = le16_to_cpu(scan->sl);
1890 iwe.u.qual.noise = le16_to_cpu(scan->anl);
1891 } else {
1892 iwe.u.qual.level =
1893 HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl));
1894 iwe.u.qual.noise =
1895 HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
1896 }
1897 iwe.len = IW_EV_QUAL_LEN;
1898 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1899 IW_EV_QUAL_LEN);
1900 }
1901
1902 memset(&iwe, 0, sizeof(iwe));
1903 iwe.cmd = SIOCGIWENCODE;
1904 if (capabilities & WLAN_CAPABILITY_PRIVACY)
1905 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1906 else
1907 iwe.u.data.flags = IW_ENCODE_DISABLED;
1908 iwe.u.data.length = 0;
1909 iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
1910 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
1911
1912 /* TODO: add SuppRates into BSS table */
1913 if (scan) {
1914 memset(&iwe, 0, sizeof(iwe));
1915 iwe.cmd = SIOCGIWRATE;
1916 current_val = current_ev + IW_EV_LCP_LEN;
1917 pos = scan->sup_rates;
1918 for (i = 0; i < sizeof(scan->sup_rates); i++) {
1919 if (pos[i] == 0)
1920 break;
1921 /* Bit rate given in 500 kb/s units (+ 0x80) */
1922 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
1923 current_val = iwe_stream_add_value(
1924 current_ev, current_val, end_buf, &iwe,
1925 IW_EV_PARAM_LEN);
1926 }
1927 /* Check if we added any event */
1928 if ((current_val - current_ev) > IW_EV_LCP_LEN)
1929 current_ev = current_val;
1930 }
1931
1932 /* TODO: add BeaconInt,resp_rate,atim into BSS table */
1933 buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
1934 if (buf && scan) {
1935 memset(&iwe, 0, sizeof(iwe));
1936 iwe.cmd = IWEVCUSTOM;
1937 sprintf(buf, "bcn_int=%d", le16_to_cpu(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(scan->rate));
1945 iwe.u.data.length = strlen(buf);
1946 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
1947 buf);
1948
1949 if (local->last_scan_type == PRISM2_HOSTSCAN &&
1950 (capabilities & WLAN_CAPABILITY_IBSS)) {
1951 memset(&iwe, 0, sizeof(iwe));
1952 iwe.cmd = IWEVCUSTOM;
1953 sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
1954 iwe.u.data.length = strlen(buf);
1955 current_ev = iwe_stream_add_point(current_ev, end_buf,
1956 &iwe, buf);
1957 }
1958 }
1959 kfree(buf);
1960
1961 if (bss && bss->wpa_ie_len > 0 && bss->wpa_ie_len <= MAX_WPA_IE_LEN) {
1962 memset(&iwe, 0, sizeof(iwe));
1963 iwe.cmd = IWEVGENIE;
1964 iwe.u.data.length = bss->wpa_ie_len;
1965 current_ev = iwe_stream_add_point(
1966 current_ev, end_buf, &iwe, bss->wpa_ie);
1967 }
1968
1969 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
1970 memset(&iwe, 0, sizeof(iwe));
1971 iwe.cmd = IWEVGENIE;
1972 iwe.u.data.length = bss->rsn_ie_len;
1973 current_ev = iwe_stream_add_point(
1974 current_ev, end_buf, &iwe, bss->rsn_ie);
1975 }
1976
1977 return current_ev;
1978}
1979
1980
1981/* Translate scan data returned from the card to a card independant
1982 * format that the Wireless Tools will understand - Jean II */
1983static inline int prism2_translate_scan(local_info_t *local,
1984 char *buffer, int buflen)
1985{
1986 struct hfa384x_hostscan_result *scan;
1987 int entry, hostscan;
1988 char *current_ev = buffer;
1989 char *end_buf = buffer + buflen;
1990 struct list_head *ptr;
1991
1992 spin_lock_bh(&local->lock);
1993
1994 list_for_each(ptr, &local->bss_list) {
1995 struct hostap_bss_info *bss;
1996 bss = list_entry(ptr, struct hostap_bss_info, list);
1997 bss->included = 0;
1998 }
1999
2000 hostscan = local->last_scan_type == PRISM2_HOSTSCAN;
2001 for (entry = 0; entry < local->last_scan_results_count; entry++) {
2002 int found = 0;
2003 scan = &local->last_scan_results[entry];
2004
2005 /* Report every SSID if the AP is using multiple SSIDs. If no
2006 * BSS record is found (e.g., when WPA mode is disabled),
2007 * report the AP once. */
2008 list_for_each(ptr, &local->bss_list) {
2009 struct hostap_bss_info *bss;
2010 bss = list_entry(ptr, struct hostap_bss_info, list);
2011 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
2012 bss->included = 1;
2013 current_ev = __prism2_translate_scan(
2014 local, scan, bss, current_ev, end_buf);
2015 found++;
2016 }
2017 }
2018 if (!found) {
2019 current_ev = __prism2_translate_scan(
2020 local, scan, NULL, current_ev, end_buf);
2021 }
2022 /* Check if there is space for one more entry */
2023 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2024 /* Ask user space to try again with a bigger buffer */
2025 spin_unlock_bh(&local->lock);
2026 return -E2BIG;
2027 }
2028 }
2029
2030 /* Prism2 firmware has limits (32 at least in some versions) for number
2031 * of BSSes in scan results. Extend this limit by using local BSS list.
2032 */
2033 list_for_each(ptr, &local->bss_list) {
2034 struct hostap_bss_info *bss;
2035 bss = list_entry(ptr, struct hostap_bss_info, list);
2036 if (bss->included)
2037 continue;
2038 current_ev = __prism2_translate_scan(local, NULL, bss,
2039 current_ev, end_buf);
2040 /* Check if there is space for one more entry */
2041 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
2042 /* Ask user space to try again with a bigger buffer */
2043 spin_unlock_bh(&local->lock);
2044 return -E2BIG;
2045 }
2046 }
2047
2048 spin_unlock_bh(&local->lock);
2049
2050 return current_ev - buffer;
2051}
2052#endif /* PRISM2_NO_STATION_MODES */
2053
2054
2055static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
2056 struct iw_request_info *info,
2057 struct iw_point *data, char *extra)
2058{
2059#ifdef PRISM2_NO_STATION_MODES
2060 return -EOPNOTSUPP;
2061#else /* PRISM2_NO_STATION_MODES */
2062 struct hostap_interface *iface;
2063 local_info_t *local;
2064 int res;
2065
2066 iface = netdev_priv(dev);
2067 local = iface->local;
2068
2069 /* Wait until the scan is finished. We can probably do better
2070 * than that - Jean II */
2071 if (local->scan_timestamp &&
2072 time_before(jiffies, local->scan_timestamp + 3 * HZ)) {
2073 /* Important note : we don't want to block the caller
2074 * until results are ready for various reasons.
2075 * First, managing wait queues is complex and racy
2076 * (there may be multiple simultaneous callers).
2077 * Second, we grab some rtnetlink lock before comming
2078 * here (in dev_ioctl()).
2079 * Third, the caller can wait on the Wireless Event
2080 * - Jean II */
2081 return -EAGAIN;
2082 }
2083 local->scan_timestamp = 0;
2084
2085 res = prism2_translate_scan(local, extra, data->length);
2086
2087 if (res >= 0) {
2088 data->length = res;
2089 return 0;
2090 } else {
2091 data->length = 0;
2092 return res;
2093 }
2094#endif /* PRISM2_NO_STATION_MODES */
2095}
2096
2097
2098static int prism2_ioctl_giwscan(struct net_device *dev,
2099 struct iw_request_info *info,
2100 struct iw_point *data, char *extra)
2101{
2102 struct hostap_interface *iface;
2103 local_info_t *local;
2104 int res;
2105
2106 iface = netdev_priv(dev);
2107 local = iface->local;
2108
2109 if (local->iw_mode == IW_MODE_MASTER) {
2110 /* In MASTER mode, it doesn't make sense to go around
2111 * scanning the frequencies and make the stations we serve
2112 * wait when what the user is really interested about is the
2113 * list of stations and access points we are talking to.
2114 * So, just extract results from our cache...
2115 * Jean II */
2116
2117 /* Translate to WE format */
2118 res = prism2_ap_translate_scan(dev, extra);
2119 if (res >= 0) {
2120 printk(KERN_DEBUG "Scan result translation succeeded "
2121 "(length=%d)\n", res);
2122 data->length = res;
2123 return 0;
2124 } else {
2125 printk(KERN_DEBUG
2126 "Scan result translation failed (res=%d)\n",
2127 res);
2128 data->length = 0;
2129 return res;
2130 }
2131 } else {
2132 /* Station mode */
2133 return prism2_ioctl_giwscan_sta(dev, info, data, extra);
2134 }
2135}
2136
2137
2138static const struct iw_priv_args prism2_priv[] = {
2139 { PRISM2_IOCTL_MONITOR,
2140 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" },
2141 { PRISM2_IOCTL_READMIF,
2142 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
2143 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" },
2144 { PRISM2_IOCTL_WRITEMIF,
2145 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, 0, "writemif" },
2146 { PRISM2_IOCTL_RESET,
2147 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "reset" },
2148 { PRISM2_IOCTL_INQUIRE,
2149 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "inquire" },
2150 { PRISM2_IOCTL_SET_RID_WORD,
2151 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_rid_word" },
2152 { PRISM2_IOCTL_MACCMD,
2153 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maccmd" },
2154 { PRISM2_IOCTL_WDS_ADD,
2155 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_add" },
2156 { PRISM2_IOCTL_WDS_DEL,
2157 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "wds_del" },
2158 { PRISM2_IOCTL_ADDMAC,
2159 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "addmac" },
2160 { PRISM2_IOCTL_DELMAC,
2161 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "delmac" },
2162 { PRISM2_IOCTL_KICKMAC,
2163 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "kickmac" },
2164 /* --- raw access to sub-ioctls --- */
2165 { PRISM2_IOCTL_PRISM2_PARAM,
2166 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "prism2_param" },
2167 { PRISM2_IOCTL_GET_PRISM2_PARAM,
2168 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2169 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprism2_param" },
2170 /* --- sub-ioctls handlers --- */
2171 { PRISM2_IOCTL_PRISM2_PARAM,
2172 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
2173 { PRISM2_IOCTL_GET_PRISM2_PARAM,
2174 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
2175 /* --- sub-ioctls definitions --- */
2176 { PRISM2_PARAM_TXRATECTRL,
2177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "txratectrl" },
2178 { PRISM2_PARAM_TXRATECTRL,
2179 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettxratectrl" },
2180 { PRISM2_PARAM_BEACON_INT,
2181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beacon_int" },
2182 { PRISM2_PARAM_BEACON_INT,
2183 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbeacon_int" },
2184#ifndef PRISM2_NO_STATION_MODES
2185 { PRISM2_PARAM_PSEUDO_IBSS,
2186 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "pseudo_ibss" },
2187 { PRISM2_PARAM_PSEUDO_IBSS,
2188 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpseudo_ibss" },
2189#endif /* PRISM2_NO_STATION_MODES */
2190 { PRISM2_PARAM_ALC,
2191 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "alc" },
2192 { PRISM2_PARAM_ALC,
2193 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getalc" },
2194 { PRISM2_PARAM_DUMP,
2195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dump" },
2196 { PRISM2_PARAM_DUMP,
2197 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdump" },
2198 { PRISM2_PARAM_OTHER_AP_POLICY,
2199 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "other_ap_policy" },
2200 { PRISM2_PARAM_OTHER_AP_POLICY,
2201 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getother_ap_pol" },
2202 { PRISM2_PARAM_AP_MAX_INACTIVITY,
2203 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_inactivity" },
2204 { PRISM2_PARAM_AP_MAX_INACTIVITY,
2205 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_inactivi" },
2206 { PRISM2_PARAM_AP_BRIDGE_PACKETS,
2207 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bridge_packets" },
2208 { PRISM2_PARAM_AP_BRIDGE_PACKETS,
2209 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbridge_packe" },
2210 { PRISM2_PARAM_DTIM_PERIOD,
2211 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dtim_period" },
2212 { PRISM2_PARAM_DTIM_PERIOD,
2213 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdtim_period" },
2214 { PRISM2_PARAM_AP_NULLFUNC_ACK,
2215 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "nullfunc_ack" },
2216 { PRISM2_PARAM_AP_NULLFUNC_ACK,
2217 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getnullfunc_ack" },
2218 { PRISM2_PARAM_MAX_WDS,
2219 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "max_wds" },
2220 { PRISM2_PARAM_MAX_WDS,
2221 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmax_wds" },
2222 { PRISM2_PARAM_AP_AUTOM_AP_WDS,
2223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "autom_ap_wds" },
2224 { PRISM2_PARAM_AP_AUTOM_AP_WDS,
2225 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getautom_ap_wds" },
2226 { PRISM2_PARAM_AP_AUTH_ALGS,
2227 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_auth_algs" },
2228 { PRISM2_PARAM_AP_AUTH_ALGS,
2229 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_auth_algs" },
2230 { PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2231 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "allow_fcserr" },
2232 { PRISM2_PARAM_MONITOR_ALLOW_FCSERR,
2233 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getallow_fcserr" },
2234 { PRISM2_PARAM_HOST_ENCRYPT,
2235 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_encrypt" },
2236 { PRISM2_PARAM_HOST_ENCRYPT,
2237 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_encrypt" },
2238 { PRISM2_PARAM_HOST_DECRYPT,
2239 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_decrypt" },
2240 { PRISM2_PARAM_HOST_DECRYPT,
2241 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_decrypt" },
2242#ifndef PRISM2_NO_STATION_MODES
2243 { PRISM2_PARAM_HOST_ROAMING,
2244 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "host_roaming" },
2245 { PRISM2_PARAM_HOST_ROAMING,
2246 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethost_roaming" },
2247#endif /* PRISM2_NO_STATION_MODES */
2248 { PRISM2_PARAM_BCRX_STA_KEY,
2249 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bcrx_sta_key" },
2250 { PRISM2_PARAM_BCRX_STA_KEY,
2251 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbcrx_sta_key" },
2252 { PRISM2_PARAM_IEEE_802_1X,
2253 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ieee_802_1x" },
2254 { PRISM2_PARAM_IEEE_802_1X,
2255 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getieee_802_1x" },
2256 { PRISM2_PARAM_ANTSEL_TX,
2257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_tx" },
2258 { PRISM2_PARAM_ANTSEL_TX,
2259 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_tx" },
2260 { PRISM2_PARAM_ANTSEL_RX,
2261 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_rx" },
2262 { PRISM2_PARAM_ANTSEL_RX,
2263 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_rx" },
2264 { PRISM2_PARAM_MONITOR_TYPE,
2265 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor_type" },
2266 { PRISM2_PARAM_MONITOR_TYPE,
2267 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmonitor_type" },
2268 { PRISM2_PARAM_WDS_TYPE,
2269 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wds_type" },
2270 { PRISM2_PARAM_WDS_TYPE,
2271 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwds_type" },
2272 { PRISM2_PARAM_HOSTSCAN,
2273 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostscan" },
2274 { PRISM2_PARAM_HOSTSCAN,
2275 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostscan" },
2276 { PRISM2_PARAM_AP_SCAN,
2277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ap_scan" },
2278 { PRISM2_PARAM_AP_SCAN,
2279 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getap_scan" },
2280 { PRISM2_PARAM_ENH_SEC,
2281 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "enh_sec" },
2282 { PRISM2_PARAM_ENH_SEC,
2283 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getenh_sec" },
2284#ifdef PRISM2_IO_DEBUG
2285 { PRISM2_PARAM_IO_DEBUG,
2286 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "io_debug" },
2287 { PRISM2_PARAM_IO_DEBUG,
2288 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getio_debug" },
2289#endif /* PRISM2_IO_DEBUG */
2290 { PRISM2_PARAM_BASIC_RATES,
2291 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "basic_rates" },
2292 { PRISM2_PARAM_BASIC_RATES,
2293 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getbasic_rates" },
2294 { PRISM2_PARAM_OPER_RATES,
2295 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oper_rates" },
2296 { PRISM2_PARAM_OPER_RATES,
2297 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getoper_rates" },
2298 { PRISM2_PARAM_HOSTAPD,
2299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd" },
2300 { PRISM2_PARAM_HOSTAPD,
2301 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd" },
2302 { PRISM2_PARAM_HOSTAPD_STA,
2303 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hostapd_sta" },
2304 { PRISM2_PARAM_HOSTAPD_STA,
2305 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostapd_sta" },
2306 { PRISM2_PARAM_WPA,
2307 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wpa" },
2308 { PRISM2_PARAM_WPA,
2309 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwpa" },
2310 { PRISM2_PARAM_PRIVACY_INVOKED,
2311 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "privacy_invoked" },
2312 { PRISM2_PARAM_PRIVACY_INVOKED,
2313 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getprivacy_invo" },
2314 { PRISM2_PARAM_TKIP_COUNTERMEASURES,
2315 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "tkip_countermea" },
2316 { PRISM2_PARAM_TKIP_COUNTERMEASURES,
2317 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gettkip_counter" },
2318 { PRISM2_PARAM_DROP_UNENCRYPTED,
2319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypte" },
2320 { PRISM2_PARAM_DROP_UNENCRYPTED,
2321 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdrop_unencry" },
2322 { PRISM2_PARAM_SCAN_CHANNEL_MASK,
2323 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "scan_channels" },
2324 { PRISM2_PARAM_SCAN_CHANNEL_MASK,
2325 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getscan_channel" },
2326};
2327
2328
2329static int prism2_ioctl_priv_inquire(struct net_device *dev, int *i)
2330{
2331 struct hostap_interface *iface;
2332 local_info_t *local;
2333
2334 iface = netdev_priv(dev);
2335 local = iface->local;
2336
2337 if (local->func->cmd(dev, HFA384X_CMDCODE_INQUIRE, *i, NULL, NULL))
2338 return -EOPNOTSUPP;
2339
2340 return 0;
2341}
2342
2343
2344static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
2345 struct iw_request_info *info,
2346 void *wrqu, char *extra)
2347{
2348 struct hostap_interface *iface;
2349 local_info_t *local;
2350 int *i = (int *) extra;
2351 int param = *i;
2352 int value = *(i + 1);
2353 int ret = 0;
2354 u16 val;
2355
2356 iface = netdev_priv(dev);
2357 local = iface->local;
2358
2359 switch (param) {
2360 case PRISM2_PARAM_TXRATECTRL:
2361 local->fw_tx_rate_control = value;
2362 break;
2363
2364 case PRISM2_PARAM_BEACON_INT:
2365 if (hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, value) ||
2366 local->func->reset_port(dev))
2367 ret = -EINVAL;
2368 else
2369 local->beacon_int = value;
2370 break;
2371
2372#ifndef PRISM2_NO_STATION_MODES
2373 case PRISM2_PARAM_PSEUDO_IBSS:
2374 if (value == local->pseudo_adhoc)
2375 break;
2376
2377 if (value != 0 && value != 1) {
2378 ret = -EINVAL;
2379 break;
2380 }
2381
2382 printk(KERN_DEBUG "prism2: %s: pseudo IBSS change %d -> %d\n",
2383 dev->name, local->pseudo_adhoc, value);
2384 local->pseudo_adhoc = value;
2385 if (local->iw_mode != IW_MODE_ADHOC)
2386 break;
2387
2388 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2389 hostap_get_porttype(local))) {
2390 ret = -EOPNOTSUPP;
2391 break;
2392 }
2393
2394 if (local->func->reset_port(dev))
2395 ret = -EINVAL;
2396 break;
2397#endif /* PRISM2_NO_STATION_MODES */
2398
2399 case PRISM2_PARAM_ALC:
2400 printk(KERN_DEBUG "%s: %s ALC\n", dev->name,
2401 value == 0 ? "Disabling" : "Enabling");
2402 val = HFA384X_TEST_CFG_BIT_ALC;
2403 local->func->cmd(dev, HFA384X_CMDCODE_TEST |
2404 (HFA384X_TEST_CFG_BITS << 8),
2405 value == 0 ? 0 : 1, &val, NULL);
2406 break;
2407
2408 case PRISM2_PARAM_DUMP:
2409 local->frame_dump = value;
2410 break;
2411
2412 case PRISM2_PARAM_OTHER_AP_POLICY:
2413 if (value < 0 || value > 3) {
2414 ret = -EINVAL;
2415 break;
2416 }
2417 if (local->ap != NULL)
2418 local->ap->ap_policy = value;
2419 break;
2420
2421 case PRISM2_PARAM_AP_MAX_INACTIVITY:
2422 if (value < 0 || value > 7 * 24 * 60 * 60) {
2423 ret = -EINVAL;
2424 break;
2425 }
2426 if (local->ap != NULL)
2427 local->ap->max_inactivity = value * HZ;
2428 break;
2429
2430 case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2431 if (local->ap != NULL)
2432 local->ap->bridge_packets = value;
2433 break;
2434
2435 case PRISM2_PARAM_DTIM_PERIOD:
2436 if (value < 0 || value > 65535) {
2437 ret = -EINVAL;
2438 break;
2439 }
2440 if (hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, value)
2441 || local->func->reset_port(dev))
2442 ret = -EINVAL;
2443 else
2444 local->dtim_period = value;
2445 break;
2446
2447 case PRISM2_PARAM_AP_NULLFUNC_ACK:
2448 if (local->ap != NULL)
2449 local->ap->nullfunc_ack = value;
2450 break;
2451
2452 case PRISM2_PARAM_MAX_WDS:
2453 local->wds_max_connections = value;
2454 break;
2455
2456 case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2457 if (local->ap != NULL) {
2458 if (!local->ap->autom_ap_wds && value) {
2459 /* add WDS link to all APs in STA table */
2460 hostap_add_wds_links(local);
2461 }
2462 local->ap->autom_ap_wds = value;
2463 }
2464 break;
2465
2466 case PRISM2_PARAM_AP_AUTH_ALGS:
2467 local->auth_algs = value;
2468 if (hostap_set_auth_algs(local))
2469 ret = -EINVAL;
2470 break;
2471
2472 case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2473 local->monitor_allow_fcserr = value;
2474 break;
2475
2476 case PRISM2_PARAM_HOST_ENCRYPT:
2477 local->host_encrypt = value;
2478 if (hostap_set_encryption(local) ||
2479 local->func->reset_port(dev))
2480 ret = -EINVAL;
2481 break;
2482
2483 case PRISM2_PARAM_HOST_DECRYPT:
2484 local->host_decrypt = value;
2485 if (hostap_set_encryption(local) ||
2486 local->func->reset_port(dev))
2487 ret = -EINVAL;
2488 break;
2489
2490#ifndef PRISM2_NO_STATION_MODES
2491 case PRISM2_PARAM_HOST_ROAMING:
2492 if (value < 0 || value > 2) {
2493 ret = -EINVAL;
2494 break;
2495 }
2496 local->host_roaming = value;
2497 if (hostap_set_roaming(local) || local->func->reset_port(dev))
2498 ret = -EINVAL;
2499 break;
2500#endif /* PRISM2_NO_STATION_MODES */
2501
2502 case PRISM2_PARAM_BCRX_STA_KEY:
2503 local->bcrx_sta_key = value;
2504 break;
2505
2506 case PRISM2_PARAM_IEEE_802_1X:
2507 local->ieee_802_1x = value;
2508 break;
2509
2510 case PRISM2_PARAM_ANTSEL_TX:
2511 if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2512 ret = -EINVAL;
2513 break;
2514 }
2515 local->antsel_tx = value;
2516 hostap_set_antsel(local);
2517 break;
2518
2519 case PRISM2_PARAM_ANTSEL_RX:
2520 if (value < 0 || value > HOSTAP_ANTSEL_HIGH) {
2521 ret = -EINVAL;
2522 break;
2523 }
2524 local->antsel_rx = value;
2525 hostap_set_antsel(local);
2526 break;
2527
2528 case PRISM2_PARAM_MONITOR_TYPE:
2529 if (value != PRISM2_MONITOR_80211 &&
2530 value != PRISM2_MONITOR_CAPHDR &&
2531 value != PRISM2_MONITOR_PRISM) {
2532 ret = -EINVAL;
2533 break;
2534 }
2535 local->monitor_type = value;
2536 if (local->iw_mode == IW_MODE_MONITOR)
2537 hostap_monitor_set_type(local);
2538 break;
2539
2540 case PRISM2_PARAM_WDS_TYPE:
2541 local->wds_type = value;
2542 break;
2543
2544 case PRISM2_PARAM_HOSTSCAN:
2545 {
2546 struct hfa384x_hostscan_request scan_req;
2547 u16 rate;
2548
2549 memset(&scan_req, 0, sizeof(scan_req));
2550 scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
2551 switch (value) {
2552 case 1: rate = HFA384X_RATES_1MBPS; break;
2553 case 2: rate = HFA384X_RATES_2MBPS; break;
2554 case 3: rate = HFA384X_RATES_5MBPS; break;
2555 case 4: rate = HFA384X_RATES_11MBPS; break;
2556 default: rate = HFA384X_RATES_1MBPS; break;
2557 }
2558 scan_req.txrate = cpu_to_le16(rate);
2559 /* leave SSID empty to accept all SSIDs */
2560
2561 if (local->iw_mode == IW_MODE_MASTER) {
2562 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2563 HFA384X_PORTTYPE_BSS) ||
2564 local->func->reset_port(dev))
2565 printk(KERN_DEBUG "Leaving Host AP mode "
2566 "for HostScan failed\n");
2567 }
2568
2569 if (local->func->set_rid(dev, HFA384X_RID_HOSTSCAN, &scan_req,
2570 sizeof(scan_req))) {
2571 printk(KERN_DEBUG "HOSTSCAN failed\n");
2572 ret = -EINVAL;
2573 }
2574 if (local->iw_mode == IW_MODE_MASTER) {
2575 wait_queue_t __wait;
2576 init_waitqueue_entry(&__wait, current);
2577 add_wait_queue(&local->hostscan_wq, &__wait);
2578 set_current_state(TASK_INTERRUPTIBLE);
2579 schedule_timeout(HZ);
2580 if (signal_pending(current))
2581 ret = -EINTR;
2582 set_current_state(TASK_RUNNING);
2583 remove_wait_queue(&local->hostscan_wq, &__wait);
2584
2585 if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
2586 HFA384X_PORTTYPE_HOSTAP) ||
2587 local->func->reset_port(dev))
2588 printk(KERN_DEBUG "Returning to Host AP mode "
2589 "after HostScan failed\n");
2590 }
2591 break;
2592 }
2593
2594 case PRISM2_PARAM_AP_SCAN:
2595 local->passive_scan_interval = value;
2596 if (timer_pending(&local->passive_scan_timer))
2597 del_timer(&local->passive_scan_timer);
2598 if (value > 0) {
2599 local->passive_scan_timer.expires = jiffies +
2600 local->passive_scan_interval * HZ;
2601 add_timer(&local->passive_scan_timer);
2602 }
2603 break;
2604
2605 case PRISM2_PARAM_ENH_SEC:
2606 if (value < 0 || value > 3) {
2607 ret = -EINVAL;
2608 break;
2609 }
2610 local->enh_sec = value;
2611 if (hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY,
2612 local->enh_sec) ||
2613 local->func->reset_port(dev)) {
2614 printk(KERN_INFO "%s: cnfEnhSecurity requires STA f/w "
2615 "1.6.3 or newer\n", dev->name);
2616 ret = -EOPNOTSUPP;
2617 }
2618 break;
2619
2620#ifdef PRISM2_IO_DEBUG
2621 case PRISM2_PARAM_IO_DEBUG:
2622 local->io_debug_enabled = value;
2623 break;
2624#endif /* PRISM2_IO_DEBUG */
2625
2626 case PRISM2_PARAM_BASIC_RATES:
2627 if ((value & local->tx_rate_control) != value || value == 0) {
2628 printk(KERN_INFO "%s: invalid basic rate set - basic "
2629 "rates must be in supported rate set\n",
2630 dev->name);
2631 ret = -EINVAL;
2632 break;
2633 }
2634 local->basic_rates = value;
2635 if (hostap_set_word(dev, HFA384X_RID_CNFBASICRATES,
2636 local->basic_rates) ||
2637 local->func->reset_port(dev))
2638 ret = -EINVAL;
2639 break;
2640
2641 case PRISM2_PARAM_OPER_RATES:
2642 local->tx_rate_control = value;
2643 if (hostap_set_rate(dev))
2644 ret = -EINVAL;
2645 break;
2646
2647 case PRISM2_PARAM_HOSTAPD:
2648 ret = hostap_set_hostapd(local, value, 1);
2649 break;
2650
2651 case PRISM2_PARAM_HOSTAPD_STA:
2652 ret = hostap_set_hostapd_sta(local, value, 1);
2653 break;
2654
2655 case PRISM2_PARAM_WPA:
2656 local->wpa = value;
2657 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2658 ret = -EOPNOTSUPP;
2659 else if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
2660 value ? 1 : 0))
2661 ret = -EINVAL;
2662 break;
2663
2664 case PRISM2_PARAM_PRIVACY_INVOKED:
2665 local->privacy_invoked = value;
2666 if (hostap_set_encryption(local) ||
2667 local->func->reset_port(dev))
2668 ret = -EINVAL;
2669 break;
2670
2671 case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2672 local->tkip_countermeasures = value;
2673 break;
2674
2675 case PRISM2_PARAM_DROP_UNENCRYPTED:
2676 local->drop_unencrypted = value;
2677 break;
2678
2679 case PRISM2_PARAM_SCAN_CHANNEL_MASK:
2680 local->scan_channel_mask = value;
2681 break;
2682
2683 default:
2684 printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n",
2685 dev->name, param);
2686 ret = -EOPNOTSUPP;
2687 break;
2688 }
2689
2690 return ret;
2691}
2692
2693
2694static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev,
2695 struct iw_request_info *info,
2696 void *wrqu, char *extra)
2697{
2698 struct hostap_interface *iface;
2699 local_info_t *local;
2700 int *param = (int *) extra;
2701 int ret = 0;
2702
2703 iface = netdev_priv(dev);
2704 local = iface->local;
2705
2706 switch (*param) {
2707 case PRISM2_PARAM_TXRATECTRL:
2708 *param = local->fw_tx_rate_control;
2709 break;
2710
2711 case PRISM2_PARAM_BEACON_INT:
2712 *param = local->beacon_int;
2713 break;
2714
2715 case PRISM2_PARAM_PSEUDO_IBSS:
2716 *param = local->pseudo_adhoc;
2717 break;
2718
2719 case PRISM2_PARAM_ALC:
2720 ret = -EOPNOTSUPP; /* FIX */
2721 break;
2722
2723 case PRISM2_PARAM_DUMP:
2724 *param = local->frame_dump;
2725 break;
2726
2727 case PRISM2_PARAM_OTHER_AP_POLICY:
2728 if (local->ap != NULL)
2729 *param = local->ap->ap_policy;
2730 else
2731 ret = -EOPNOTSUPP;
2732 break;
2733
2734 case PRISM2_PARAM_AP_MAX_INACTIVITY:
2735 if (local->ap != NULL)
2736 *param = local->ap->max_inactivity / HZ;
2737 else
2738 ret = -EOPNOTSUPP;
2739 break;
2740
2741 case PRISM2_PARAM_AP_BRIDGE_PACKETS:
2742 if (local->ap != NULL)
2743 *param = local->ap->bridge_packets;
2744 else
2745 ret = -EOPNOTSUPP;
2746 break;
2747
2748 case PRISM2_PARAM_DTIM_PERIOD:
2749 *param = local->dtim_period;
2750 break;
2751
2752 case PRISM2_PARAM_AP_NULLFUNC_ACK:
2753 if (local->ap != NULL)
2754 *param = local->ap->nullfunc_ack;
2755 else
2756 ret = -EOPNOTSUPP;
2757 break;
2758
2759 case PRISM2_PARAM_MAX_WDS:
2760 *param = local->wds_max_connections;
2761 break;
2762
2763 case PRISM2_PARAM_AP_AUTOM_AP_WDS:
2764 if (local->ap != NULL)
2765 *param = local->ap->autom_ap_wds;
2766 else
2767 ret = -EOPNOTSUPP;
2768 break;
2769
2770 case PRISM2_PARAM_AP_AUTH_ALGS:
2771 *param = local->auth_algs;
2772 break;
2773
2774 case PRISM2_PARAM_MONITOR_ALLOW_FCSERR:
2775 *param = local->monitor_allow_fcserr;
2776 break;
2777
2778 case PRISM2_PARAM_HOST_ENCRYPT:
2779 *param = local->host_encrypt;
2780 break;
2781
2782 case PRISM2_PARAM_HOST_DECRYPT:
2783 *param = local->host_decrypt;
2784 break;
2785
2786 case PRISM2_PARAM_HOST_ROAMING:
2787 *param = local->host_roaming;
2788 break;
2789
2790 case PRISM2_PARAM_BCRX_STA_KEY:
2791 *param = local->bcrx_sta_key;
2792 break;
2793
2794 case PRISM2_PARAM_IEEE_802_1X:
2795 *param = local->ieee_802_1x;
2796 break;
2797
2798 case PRISM2_PARAM_ANTSEL_TX:
2799 *param = local->antsel_tx;
2800 break;
2801
2802 case PRISM2_PARAM_ANTSEL_RX:
2803 *param = local->antsel_rx;
2804 break;
2805
2806 case PRISM2_PARAM_MONITOR_TYPE:
2807 *param = local->monitor_type;
2808 break;
2809
2810 case PRISM2_PARAM_WDS_TYPE:
2811 *param = local->wds_type;
2812 break;
2813
2814 case PRISM2_PARAM_HOSTSCAN:
2815 ret = -EOPNOTSUPP;
2816 break;
2817
2818 case PRISM2_PARAM_AP_SCAN:
2819 *param = local->passive_scan_interval;
2820 break;
2821
2822 case PRISM2_PARAM_ENH_SEC:
2823 *param = local->enh_sec;
2824 break;
2825
2826#ifdef PRISM2_IO_DEBUG
2827 case PRISM2_PARAM_IO_DEBUG:
2828 *param = local->io_debug_enabled;
2829 break;
2830#endif /* PRISM2_IO_DEBUG */
2831
2832 case PRISM2_PARAM_BASIC_RATES:
2833 *param = local->basic_rates;
2834 break;
2835
2836 case PRISM2_PARAM_OPER_RATES:
2837 *param = local->tx_rate_control;
2838 break;
2839
2840 case PRISM2_PARAM_HOSTAPD:
2841 *param = local->hostapd;
2842 break;
2843
2844 case PRISM2_PARAM_HOSTAPD_STA:
2845 *param = local->hostapd_sta;
2846 break;
2847
2848 case PRISM2_PARAM_WPA:
2849 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
2850 ret = -EOPNOTSUPP;
2851 *param = local->wpa;
2852 break;
2853
2854 case PRISM2_PARAM_PRIVACY_INVOKED:
2855 *param = local->privacy_invoked;
2856 break;
2857
2858 case PRISM2_PARAM_TKIP_COUNTERMEASURES:
2859 *param = local->tkip_countermeasures;
2860 break;
2861
2862 case PRISM2_PARAM_DROP_UNENCRYPTED:
2863 *param = local->drop_unencrypted;
2864 break;
2865
2866 case PRISM2_PARAM_SCAN_CHANNEL_MASK:
2867 *param = local->scan_channel_mask;
2868 break;
2869
2870 default:
2871 printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n",
2872 dev->name, *param);
2873 ret = -EOPNOTSUPP;
2874 break;
2875 }
2876
2877 return ret;
2878}
2879
2880
2881static int prism2_ioctl_priv_readmif(struct net_device *dev,
2882 struct iw_request_info *info,
2883 void *wrqu, char *extra)
2884{
2885 struct hostap_interface *iface;
2886 local_info_t *local;
2887 u16 resp0;
2888
2889 iface = netdev_priv(dev);
2890 local = iface->local;
2891
2892 if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF, *extra, NULL,
2893 &resp0))
2894 return -EOPNOTSUPP;
2895 else
2896 *extra = resp0;
2897
2898 return 0;
2899}
2900
2901
2902static int prism2_ioctl_priv_writemif(struct net_device *dev,
2903 struct iw_request_info *info,
2904 void *wrqu, char *extra)
2905{
2906 struct hostap_interface *iface;
2907 local_info_t *local;
2908 u16 cr, val;
2909
2910 iface = netdev_priv(dev);
2911 local = iface->local;
2912
2913 cr = *extra;
2914 val = *(extra + 1);
2915 if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, cr, &val, NULL))
2916 return -EOPNOTSUPP;
2917
2918 return 0;
2919}
2920
2921
2922static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
2923{
2924 struct hostap_interface *iface;
2925 local_info_t *local;
2926 int ret = 0;
2927 u32 mode;
2928
2929 iface = netdev_priv(dev);
2930 local = iface->local;
2931
2932 printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
2933 "- update software to use iwconfig mode monitor\n",
2934 dev->name, current->pid, current->comm);
2935
2936 /* Backward compatibility code - this can be removed at some point */
2937
2938 if (*i == 0) {
2939 /* Disable monitor mode - old mode was not saved, so go to
2940 * Master mode */
2941 mode = IW_MODE_MASTER;
2942 ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
2943 } else if (*i == 1) {
2944 /* netlink socket mode is not supported anymore since it did
2945 * not separate different devices from each other and was not
2946 * best method for delivering large amount of packets to
2947 * user space */
2948 ret = -EOPNOTSUPP;
2949 } else if (*i == 2 || *i == 3) {
2950 switch (*i) {
2951 case 2:
2952 local->monitor_type = PRISM2_MONITOR_80211;
2953 break;
2954 case 3:
2955 local->monitor_type = PRISM2_MONITOR_PRISM;
2956 break;
2957 }
2958 mode = IW_MODE_MONITOR;
2959 ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
2960 hostap_monitor_mode_enable(local);
2961 } else
2962 ret = -EINVAL;
2963
2964 return ret;
2965}
2966
2967
2968static int prism2_ioctl_priv_reset(struct net_device *dev, int *i)
2969{
2970 struct hostap_interface *iface;
2971 local_info_t *local;
2972
2973 iface = netdev_priv(dev);
2974 local = iface->local;
2975
2976 printk(KERN_DEBUG "%s: manual reset request(%d)\n", dev->name, *i);
2977 switch (*i) {
2978 case 0:
2979 /* Disable and enable card */
2980 local->func->hw_shutdown(dev, 1);
2981 local->func->hw_config(dev, 0);
2982 break;
2983
2984 case 1:
2985 /* COR sreset */
2986 local->func->hw_reset(dev);
2987 break;
2988
2989 case 2:
2990 /* Disable and enable port 0 */
2991 local->func->reset_port(dev);
2992 break;
2993
2994 case 3:
2995 prism2_sta_deauth(local, WLAN_REASON_DEAUTH_LEAVING);
2996 if (local->func->cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL,
2997 NULL))
2998 return -EINVAL;
2999 break;
3000
3001 case 4:
3002 if (local->func->cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL,
3003 NULL))
3004 return -EINVAL;
3005 break;
3006
3007 default:
3008 printk(KERN_DEBUG "Unknown reset request %d\n", *i);
3009 return -EOPNOTSUPP;
3010 }
3011
3012 return 0;
3013}
3014
3015
3016static int prism2_ioctl_priv_set_rid_word(struct net_device *dev, int *i)
3017{
3018 int rid = *i;
3019 int value = *(i + 1);
3020
3021 printk(KERN_DEBUG "%s: Set RID[0x%X] = %d\n", dev->name, rid, value);
3022
3023 if (hostap_set_word(dev, rid, value))
3024 return -EINVAL;
3025
3026 return 0;
3027}
3028
3029
3030#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
3031static int ap_mac_cmd_ioctl(local_info_t *local, int *cmd)
3032{
3033 int ret = 0;
3034
3035 switch (*cmd) {
3036 case AP_MAC_CMD_POLICY_OPEN:
3037 local->ap->mac_restrictions.policy = MAC_POLICY_OPEN;
3038 break;
3039 case AP_MAC_CMD_POLICY_ALLOW:
3040 local->ap->mac_restrictions.policy = MAC_POLICY_ALLOW;
3041 break;
3042 case AP_MAC_CMD_POLICY_DENY:
3043 local->ap->mac_restrictions.policy = MAC_POLICY_DENY;
3044 break;
3045 case AP_MAC_CMD_FLUSH:
3046 ap_control_flush_macs(&local->ap->mac_restrictions);
3047 break;
3048 case AP_MAC_CMD_KICKALL:
3049 ap_control_kickall(local->ap);
3050 hostap_deauth_all_stas(local->dev, local->ap, 0);
3051 break;
3052 default:
3053 ret = -EOPNOTSUPP;
3054 break;
3055 }
3056
3057 return ret;
3058}
3059#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
3060
3061
3062#ifdef PRISM2_DOWNLOAD_SUPPORT
3063static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
3064{
3065 struct prism2_download_param *param;
3066 int ret = 0;
3067
3068 if (p->length < sizeof(struct prism2_download_param) ||
3069 p->length > 1024 || !p->pointer)
3070 return -EINVAL;
3071
3072 param = (struct prism2_download_param *)
3073 kmalloc(p->length, GFP_KERNEL);
3074 if (param == NULL)
3075 return -ENOMEM;
3076
3077 if (copy_from_user(param, p->pointer, p->length)) {
3078 ret = -EFAULT;
3079 goto out;
3080 }
3081
3082 if (p->length < sizeof(struct prism2_download_param) +
3083 param->num_areas * sizeof(struct prism2_download_area)) {
3084 ret = -EINVAL;
3085 goto out;
3086 }
3087
3088 ret = local->func->download(local, param);
3089
3090 out:
3091 if (param != NULL)
3092 kfree(param);
3093
3094 return ret;
3095}
3096#endif /* PRISM2_DOWNLOAD_SUPPORT */
3097
3098
3099static int prism2_set_genericelement(struct net_device *dev, u8 *elem,
3100 size_t len)
3101{
3102 struct hostap_interface *iface = dev->priv;
3103 local_info_t *local = iface->local;
3104 u8 *buf;
3105
3106 /*
3107 * Add 16-bit length in the beginning of the buffer because Prism2 RID
3108 * includes it.
3109 */
3110 buf = kmalloc(len + 2, GFP_KERNEL);
3111 if (buf == NULL)
3112 return -ENOMEM;
3113
3114 *((u16 *) buf) = cpu_to_le16(len);
3115 memcpy(buf + 2, elem, len);
3116
3117 kfree(local->generic_elem);
3118 local->generic_elem = buf;
3119 local->generic_elem_len = len + 2;
3120
3121 return local->func->set_rid(local->dev, HFA384X_RID_GENERICELEMENT,
3122 buf, len + 2);
3123}
3124
3125
3126static int prism2_ioctl_siwauth(struct net_device *dev,
3127 struct iw_request_info *info,
3128 struct iw_param *data, char *extra)
3129{
3130 struct hostap_interface *iface = dev->priv;
3131 local_info_t *local = iface->local;
3132
3133 switch (data->flags & IW_AUTH_INDEX) {
3134 case IW_AUTH_WPA_VERSION:
3135 case IW_AUTH_CIPHER_PAIRWISE:
3136 case IW_AUTH_CIPHER_GROUP:
3137 case IW_AUTH_KEY_MGMT:
3138 /*
3139 * Host AP driver does not use these parameters and allows
3140 * wpa_supplicant to control them internally.
3141 */
3142 break;
3143 case IW_AUTH_TKIP_COUNTERMEASURES:
3144 local->tkip_countermeasures = data->value;
3145 break;
3146 case IW_AUTH_DROP_UNENCRYPTED:
3147 local->drop_unencrypted = data->value;
3148 break;
3149 case IW_AUTH_80211_AUTH_ALG:
3150 local->auth_algs = data->value;
3151 break;
3152 case IW_AUTH_WPA_ENABLED:
3153 if (data->value == 0) {
3154 local->wpa = 0;
3155 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3156 break;
3157 prism2_set_genericelement(dev, "", 0);
3158 local->host_roaming = 0;
3159 local->privacy_invoked = 0;
3160 if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE,
3161 0) ||
3162 hostap_set_roaming(local) ||
3163 hostap_set_encryption(local) ||
3164 local->func->reset_port(dev))
3165 return -EINVAL;
3166 break;
3167 }
3168 if (local->sta_fw_ver < PRISM2_FW_VER(1,7,0))
3169 return -EOPNOTSUPP;
3170 local->host_roaming = 2;
3171 local->privacy_invoked = 1;
3172 local->wpa = 1;
3173 if (hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1) ||
3174 hostap_set_roaming(local) ||
3175 hostap_set_encryption(local) ||
3176 local->func->reset_port(dev))
3177 return -EINVAL;
3178 break;
3179 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3180 local->ieee_802_1x = data->value;
3181 break;
3182 case IW_AUTH_PRIVACY_INVOKED:
3183 local->privacy_invoked = data->value;
3184 break;
3185 default:
3186 return -EOPNOTSUPP;
3187 }
3188 return 0;
3189}
3190
3191
3192static int prism2_ioctl_giwauth(struct net_device *dev,
3193 struct iw_request_info *info,
3194 struct iw_param *data, char *extra)
3195{
3196 struct hostap_interface *iface = dev->priv;
3197 local_info_t *local = iface->local;
3198
3199 switch (data->flags & IW_AUTH_INDEX) {
3200 case IW_AUTH_WPA_VERSION:
3201 case IW_AUTH_CIPHER_PAIRWISE:
3202 case IW_AUTH_CIPHER_GROUP:
3203 case IW_AUTH_KEY_MGMT:
3204 /*
3205 * Host AP driver does not use these parameters and allows
3206 * wpa_supplicant to control them internally.
3207 */
3208 return -EOPNOTSUPP;
3209 case IW_AUTH_TKIP_COUNTERMEASURES:
3210 data->value = local->tkip_countermeasures;
3211 break;
3212 case IW_AUTH_DROP_UNENCRYPTED:
3213 data->value = local->drop_unencrypted;
3214 break;
3215 case IW_AUTH_80211_AUTH_ALG:
3216 data->value = local->auth_algs;
3217 break;
3218 case IW_AUTH_WPA_ENABLED:
3219 data->value = local->wpa;
3220 break;
3221 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3222 data->value = local->ieee_802_1x;
3223 break;
3224 default:
3225 return -EOPNOTSUPP;
3226 }
3227 return 0;
3228}
3229
3230
3231static int prism2_ioctl_siwencodeext(struct net_device *dev,
3232 struct iw_request_info *info,
3233 struct iw_point *erq, char *extra)
3234{
3235 struct hostap_interface *iface = dev->priv;
3236 local_info_t *local = iface->local;
3237 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3238 int i, ret = 0;
3239 struct ieee80211_crypto_ops *ops;
3240 struct ieee80211_crypt_data **crypt;
3241 void *sta_ptr;
3242 u8 *addr;
3243 const char *alg, *module;
3244
3245 i = erq->flags & IW_ENCODE_INDEX;
3246 if (i > WEP_KEYS)
3247 return -EINVAL;
3248 if (i < 1 || i > WEP_KEYS)
3249 i = local->tx_keyidx;
3250 else
3251 i--;
3252 if (i < 0 || i >= WEP_KEYS)
3253 return -EINVAL;
3254
3255 addr = ext->addr.sa_data;
3256 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3257 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3258 sta_ptr = NULL;
3259 crypt = &local->crypt[i];
3260 } else {
3261 if (i != 0)
3262 return -EINVAL;
3263 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3264 if (sta_ptr == NULL) {
3265 if (local->iw_mode == IW_MODE_INFRA) {
3266 /*
3267 * TODO: add STA entry for the current AP so
3268 * that unicast key can be used. For now, this
3269 * is emulated by using default key idx 0.
3270 */
3271 i = 0;
3272 crypt = &local->crypt[i];
3273 } else
3274 return -EINVAL;
3275 }
3276 }
3277
3278 if ((erq->flags & IW_ENCODE_DISABLED) ||
3279 ext->alg == IW_ENCODE_ALG_NONE) {
3280 if (*crypt)
3281 prism2_crypt_delayed_deinit(local, crypt);
3282 goto done;
3283 }
3284
3285 switch (ext->alg) {
3286 case IW_ENCODE_ALG_WEP:
3287 alg = "WEP";
3288 module = "ieee80211_crypt_wep";
3289 break;
3290 case IW_ENCODE_ALG_TKIP:
3291 alg = "TKIP";
3292 module = "ieee80211_crypt_tkip";
3293 break;
3294 case IW_ENCODE_ALG_CCMP:
3295 alg = "CCMP";
3296 module = "ieee80211_crypt_ccmp";
3297 break;
3298 default:
3299 printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
3300 local->dev->name, ext->alg);
3301 ret = -EOPNOTSUPP;
3302 goto done;
3303 }
3304
3305 ops = ieee80211_get_crypto_ops(alg);
3306 if (ops == NULL) {
3307 request_module(module);
3308 ops = ieee80211_get_crypto_ops(alg);
3309 }
3310 if (ops == NULL) {
3311 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3312 local->dev->name, alg);
3313 ret = -EOPNOTSUPP;
3314 goto done;
3315 }
3316
3317 if (sta_ptr || ext->alg != IW_ENCODE_ALG_WEP) {
3318 /*
3319 * Per station encryption and other than WEP algorithms
3320 * require host-based encryption, so force them on
3321 * automatically.
3322 */
3323 local->host_decrypt = local->host_encrypt = 1;
3324 }
3325
3326 if (*crypt == NULL || (*crypt)->ops != ops) {
3327 struct ieee80211_crypt_data *new_crypt;
3328
3329 prism2_crypt_delayed_deinit(local, crypt);
3330
3331 new_crypt = (struct ieee80211_crypt_data *)
3332 kmalloc(sizeof(struct ieee80211_crypt_data),
3333 GFP_KERNEL);
3334 if (new_crypt == NULL) {
3335 ret = -ENOMEM;
3336 goto done;
3337 }
3338 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3339 new_crypt->ops = ops;
3340 new_crypt->priv = new_crypt->ops->init(i);
3341 if (new_crypt->priv == NULL) {
3342 kfree(new_crypt);
3343 ret = -EINVAL;
3344 goto done;
3345 }
3346
3347 *crypt = new_crypt;
3348 }
3349
3350 /*
3351 * TODO: if ext_flags does not have IW_ENCODE_EXT_RX_SEQ_VALID, the
3352 * existing seq# should not be changed.
3353 * TODO: if ext_flags has IW_ENCODE_EXT_TX_SEQ_VALID, next TX seq#
3354 * should be changed to something else than zero.
3355 */
3356 if ((!(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) || ext->key_len > 0)
3357 && (*crypt)->ops->set_key &&
3358 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
3359 (*crypt)->priv) < 0) {
3360 printk(KERN_DEBUG "%s: key setting failed\n",
3361 local->dev->name);
3362 ret = -EINVAL;
3363 goto done;
3364 }
3365
3366 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3367 if (!sta_ptr)
3368 local->tx_keyidx = i;
3369 else if (i) {
3370 ret = -EINVAL;
3371 goto done;
3372 }
3373 }
3374
3375
3376 if (sta_ptr == NULL && ext->key_len > 0) {
3377 int first = 1, j;
3378 for (j = 0; j < WEP_KEYS; j++) {
3379 if (j != i && local->crypt[j]) {
3380 first = 0;
3381 break;
3382 }
3383 }
3384 if (first)
3385 local->tx_keyidx = i;
3386 }
3387
3388 done:
3389 if (sta_ptr)
3390 hostap_handle_sta_release(sta_ptr);
3391
3392 local->open_wep = erq->flags & IW_ENCODE_OPEN;
3393
3394 /*
3395 * Do not reset port0 if card is in Managed mode since resetting will
3396 * generate new IEEE 802.11 authentication which may end up in looping
3397 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3398 * after WEP configuration. However, keys are apparently changed at
3399 * least in Managed mode.
3400 */
3401 if (ret == 0 &&
3402 (hostap_set_encryption(local) ||
3403 (local->iw_mode != IW_MODE_INFRA &&
3404 local->func->reset_port(local->dev))))
3405 ret = -EINVAL;
3406
3407 return ret;
3408}
3409
3410
3411static int prism2_ioctl_giwencodeext(struct net_device *dev,
3412 struct iw_request_info *info,
3413 struct iw_point *erq, char *extra)
3414{
3415 struct hostap_interface *iface = dev->priv;
3416 local_info_t *local = iface->local;
3417 struct ieee80211_crypt_data **crypt;
3418 void *sta_ptr;
3419 int max_key_len, i;
3420 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3421 u8 *addr;
3422
3423 max_key_len = erq->length - sizeof(*ext);
3424 if (max_key_len < 0)
3425 return -EINVAL;
3426
3427 i = erq->flags & IW_ENCODE_INDEX;
3428 if (i < 1 || i > WEP_KEYS)
3429 i = local->tx_keyidx;
3430 else
3431 i--;
3432
3433 addr = ext->addr.sa_data;
3434 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3435 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3436 sta_ptr = NULL;
3437 crypt = &local->crypt[i];
3438 } else {
3439 i = 0;
3440 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
3441 if (sta_ptr == NULL)
3442 return -EINVAL;
3443 }
3444 erq->flags = i + 1;
3445 memset(ext, 0, sizeof(*ext));
3446
3447 if (*crypt == NULL || (*crypt)->ops == NULL) {
3448 ext->alg = IW_ENCODE_ALG_NONE;
3449 ext->key_len = 0;
3450 erq->flags |= IW_ENCODE_DISABLED;
3451 } else {
3452 if (strcmp((*crypt)->ops->name, "WEP") == 0)
3453 ext->alg = IW_ENCODE_ALG_WEP;
3454 else if (strcmp((*crypt)->ops->name, "TKIP") == 0)
3455 ext->alg = IW_ENCODE_ALG_TKIP;
3456 else if (strcmp((*crypt)->ops->name, "CCMP") == 0)
3457 ext->alg = IW_ENCODE_ALG_CCMP;
3458 else
3459 return -EINVAL;
3460
3461 if ((*crypt)->ops->get_key) {
3462 ext->key_len =
3463 (*crypt)->ops->get_key(ext->key,
3464 max_key_len,
3465 ext->tx_seq,
3466 (*crypt)->priv);
3467 if (ext->key_len &&
3468 (ext->alg == IW_ENCODE_ALG_TKIP ||
3469 ext->alg == IW_ENCODE_ALG_CCMP))
3470 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
3471 }
3472 }
3473
3474 if (sta_ptr)
3475 hostap_handle_sta_release(sta_ptr);
3476
3477 return 0;
3478}
3479
3480
3481static int prism2_ioctl_set_encryption(local_info_t *local,
3482 struct prism2_hostapd_param *param,
3483 int param_len)
3484{
3485 int ret = 0;
3486 struct ieee80211_crypto_ops *ops;
3487 struct ieee80211_crypt_data **crypt;
3488 void *sta_ptr;
3489
3490 param->u.crypt.err = 0;
3491 param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0';
3492
3493 if (param_len !=
3494 (int) ((char *) param->u.crypt.key - (char *) param) +
3495 param->u.crypt.key_len)
3496 return -EINVAL;
3497
3498 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3499 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3500 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3501 if (param->u.crypt.idx >= WEP_KEYS)
3502 return -EINVAL;
3503 sta_ptr = NULL;
3504 crypt = &local->crypt[param->u.crypt.idx];
3505 } else {
3506 if (param->u.crypt.idx)
3507 return -EINVAL;
3508 sta_ptr = ap_crypt_get_ptrs(
3509 local->ap, param->sta_addr,
3510 (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_PERMANENT),
3511 &crypt);
3512
3513 if (sta_ptr == NULL) {
3514 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3515 return -EINVAL;
3516 }
3517 }
3518
3519 if (strcmp(param->u.crypt.alg, "none") == 0) {
3520 if (crypt)
3521 prism2_crypt_delayed_deinit(local, crypt);
3522 goto done;
3523 }
3524
3525 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3526 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3527 request_module("ieee80211_crypt_wep");
3528 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3529 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3530 request_module("ieee80211_crypt_tkip");
3531 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3532 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3533 request_module("ieee80211_crypt_ccmp");
3534 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3535 }
3536 if (ops == NULL) {
3537 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
3538 local->dev->name, param->u.crypt.alg);
3539 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG;
3540 ret = -EINVAL;
3541 goto done;
3542 }
3543
3544 /* station based encryption and other than WEP algorithms require
3545 * host-based encryption, so force them on automatically */
3546 local->host_decrypt = local->host_encrypt = 1;
3547
3548 if (*crypt == NULL || (*crypt)->ops != ops) {
3549 struct ieee80211_crypt_data *new_crypt;
3550
3551 prism2_crypt_delayed_deinit(local, crypt);
3552
3553 new_crypt = (struct ieee80211_crypt_data *)
3554 kmalloc(sizeof(struct ieee80211_crypt_data),
3555 GFP_KERNEL);
3556 if (new_crypt == NULL) {
3557 ret = -ENOMEM;
3558 goto done;
3559 }
3560 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3561 new_crypt->ops = ops;
3562 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
3563 if (new_crypt->priv == NULL) {
3564 kfree(new_crypt);
3565 param->u.crypt.err =
3566 HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED;
3567 ret = -EINVAL;
3568 goto done;
3569 }
3570
3571 *crypt = new_crypt;
3572 }
3573
3574 if ((!(param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) ||
3575 param->u.crypt.key_len > 0) && (*crypt)->ops->set_key &&
3576 (*crypt)->ops->set_key(param->u.crypt.key,
3577 param->u.crypt.key_len, param->u.crypt.seq,
3578 (*crypt)->priv) < 0) {
3579 printk(KERN_DEBUG "%s: key setting failed\n",
3580 local->dev->name);
3581 param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
3582 ret = -EINVAL;
3583 goto done;
3584 }
3585
3586 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
3587 if (!sta_ptr)
3588 local->tx_keyidx = param->u.crypt.idx;
3589 else if (param->u.crypt.idx) {
3590 printk(KERN_DEBUG "%s: TX key idx setting failed\n",
3591 local->dev->name);
3592 param->u.crypt.err =
3593 HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED;
3594 ret = -EINVAL;
3595 goto done;
3596 }
3597 }
3598
3599 done:
3600 if (sta_ptr)
3601 hostap_handle_sta_release(sta_ptr);
3602
3603 /* Do not reset port0 if card is in Managed mode since resetting will
3604 * generate new IEEE 802.11 authentication which may end up in looping
3605 * with IEEE 802.1X. Prism2 documentation seem to require port reset
3606 * after WEP configuration. However, keys are apparently changed at
3607 * least in Managed mode. */
3608 if (ret == 0 &&
3609 (hostap_set_encryption(local) ||
3610 (local->iw_mode != IW_MODE_INFRA &&
3611 local->func->reset_port(local->dev)))) {
3612 param->u.crypt.err = HOSTAP_CRYPT_ERR_CARD_CONF_FAILED;
3613 return -EINVAL;
3614 }
3615
3616 return ret;
3617}
3618
3619
3620static int prism2_ioctl_get_encryption(local_info_t *local,
3621 struct prism2_hostapd_param *param,
3622 int param_len)
3623{
3624 struct ieee80211_crypt_data **crypt;
3625 void *sta_ptr;
3626 int max_key_len;
3627
3628 param->u.crypt.err = 0;
3629
3630 max_key_len = param_len -
3631 (int) ((char *) param->u.crypt.key - (char *) param);
3632 if (max_key_len < 0)
3633 return -EINVAL;
3634
3635 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3636 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3637 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3638 sta_ptr = NULL;
3639 if (param->u.crypt.idx >= WEP_KEYS)
3640 param->u.crypt.idx = local->tx_keyidx;
3641 crypt = &local->crypt[param->u.crypt.idx];
3642 } else {
3643 param->u.crypt.idx = 0;
3644 sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
3645 &crypt);
3646
3647 if (sta_ptr == NULL) {
3648 param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
3649 return -EINVAL;
3650 }
3651 }
3652
3653 if (*crypt == NULL || (*crypt)->ops == NULL) {
3654 memcpy(param->u.crypt.alg, "none", 5);
3655 param->u.crypt.key_len = 0;
3656 param->u.crypt.idx = 0xff;
3657 } else {
3658 strncpy(param->u.crypt.alg, (*crypt)->ops->name,
3659 HOSTAP_CRYPT_ALG_NAME_LEN);
3660 param->u.crypt.key_len = 0;
3661
3662 memset(param->u.crypt.seq, 0, 8);
3663 if ((*crypt)->ops->get_key) {
3664 param->u.crypt.key_len =
3665 (*crypt)->ops->get_key(param->u.crypt.key,
3666 max_key_len,
3667 param->u.crypt.seq,
3668 (*crypt)->priv);
3669 }
3670 }
3671
3672 if (sta_ptr)
3673 hostap_handle_sta_release(sta_ptr);
3674
3675 return 0;
3676}
3677
3678
3679static int prism2_ioctl_get_rid(local_info_t *local,
3680 struct prism2_hostapd_param *param,
3681 int param_len)
3682{
3683 int max_len, res;
3684
3685 max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3686 if (max_len < 0)
3687 return -EINVAL;
3688
3689 res = local->func->get_rid(local->dev, param->u.rid.rid,
3690 param->u.rid.data, param->u.rid.len, 0);
3691 if (res >= 0) {
3692 param->u.rid.len = res;
3693 return 0;
3694 }
3695
3696 return res;
3697}
3698
3699
3700static int prism2_ioctl_set_rid(local_info_t *local,
3701 struct prism2_hostapd_param *param,
3702 int param_len)
3703{
3704 int max_len;
3705
3706 max_len = param_len - PRISM2_HOSTAPD_RID_HDR_LEN;
3707 if (max_len < 0 || max_len < param->u.rid.len)
3708 return -EINVAL;
3709
3710 return local->func->set_rid(local->dev, param->u.rid.rid,
3711 param->u.rid.data, param->u.rid.len);
3712}
3713
3714
3715static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local,
3716 struct prism2_hostapd_param *param,
3717 int param_len)
3718{
3719 printk(KERN_DEBUG "%ssta: associated as client with AP " MACSTR "\n",
3720 local->dev->name, MAC2STR(param->sta_addr));
3721 memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN);
3722 return 0;
3723}
3724
3725
3726static int prism2_ioctl_siwgenie(struct net_device *dev,
3727 struct iw_request_info *info,
3728 struct iw_point *data, char *extra)
3729{
3730 return prism2_set_genericelement(dev, extra, data->length);
3731}
3732
3733
3734static int prism2_ioctl_giwgenie(struct net_device *dev,
3735 struct iw_request_info *info,
3736 struct iw_point *data, char *extra)
3737{
3738 struct hostap_interface *iface = dev->priv;
3739 local_info_t *local = iface->local;
3740 int len = local->generic_elem_len - 2;
3741
3742 if (len <= 0 || local->generic_elem == NULL) {
3743 data->length = 0;
3744 return 0;
3745 }
3746
3747 if (data->length < len)
3748 return -E2BIG;
3749
3750 data->length = len;
3751 memcpy(extra, local->generic_elem + 2, len);
3752
3753 return 0;
3754}
3755
3756
3757static int prism2_ioctl_set_generic_element(local_info_t *local,
3758 struct prism2_hostapd_param *param,
3759 int param_len)
3760{
3761 int max_len, len;
3762
3763 len = param->u.generic_elem.len;
3764 max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
3765 if (max_len < 0 || max_len < len)
3766 return -EINVAL;
3767
3768 return prism2_set_genericelement(local->dev,
3769 param->u.generic_elem.data, len);
3770}
3771
3772
3773static int prism2_ioctl_siwmlme(struct net_device *dev,
3774 struct iw_request_info *info,
3775 struct iw_point *data, char *extra)
3776{
3777 struct hostap_interface *iface = dev->priv;
3778 local_info_t *local = iface->local;
3779 struct iw_mlme *mlme = (struct iw_mlme *) extra;
3780 u16 reason;
3781
3782 reason = cpu_to_le16(mlme->reason_code);
3783
3784 switch (mlme->cmd) {
3785 case IW_MLME_DEAUTH:
3786 return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3787 IEEE80211_STYPE_DEAUTH,
3788 (u8 *) &reason, 2);
3789 case IW_MLME_DISASSOC:
3790 return prism2_sta_send_mgmt(local, mlme->addr.sa_data,
3791 IEEE80211_STYPE_DISASSOC,
3792 (u8 *) &reason, 2);
3793 default:
3794 return -EOPNOTSUPP;
3795 }
3796}
3797
3798
3799static int prism2_ioctl_mlme(local_info_t *local,
3800 struct prism2_hostapd_param *param)
3801{
3802 u16 reason;
3803
3804 reason = cpu_to_le16(param->u.mlme.reason_code);
3805 switch (param->u.mlme.cmd) {
3806 case MLME_STA_DEAUTH:
3807 return prism2_sta_send_mgmt(local, param->sta_addr,
3808 IEEE80211_STYPE_DEAUTH,
3809 (u8 *) &reason, 2);
3810 case MLME_STA_DISASSOC:
3811 return prism2_sta_send_mgmt(local, param->sta_addr,
3812 IEEE80211_STYPE_DISASSOC,
3813 (u8 *) &reason, 2);
3814 default:
3815 return -EOPNOTSUPP;
3816 }
3817}
3818
3819
3820static int prism2_ioctl_scan_req(local_info_t *local,
3821 struct prism2_hostapd_param *param)
3822{
3823#ifndef PRISM2_NO_STATION_MODES
3824 if ((local->iw_mode != IW_MODE_INFRA &&
3825 local->iw_mode != IW_MODE_ADHOC) ||
3826 (local->sta_fw_ver < PRISM2_FW_VER(1,3,1)))
3827 return -EOPNOTSUPP;
3828
3829 if (!local->dev_enabled)
3830 return -ENETDOWN;
3831
3832 return prism2_request_hostscan(local->dev, param->u.scan_req.ssid,
3833 param->u.scan_req.ssid_len);
3834#else /* PRISM2_NO_STATION_MODES */
3835 return -EOPNOTSUPP;
3836#endif /* PRISM2_NO_STATION_MODES */
3837}
3838
3839
3840static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
3841{
3842 struct prism2_hostapd_param *param;
3843 int ret = 0;
3844 int ap_ioctl = 0;
3845
3846 if (p->length < sizeof(struct prism2_hostapd_param) ||
3847 p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
3848 return -EINVAL;
3849
3850 param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
3851 if (param == NULL)
3852 return -ENOMEM;
3853
3854 if (copy_from_user(param, p->pointer, p->length)) {
3855 ret = -EFAULT;
3856 goto out;
3857 }
3858
3859 switch (param->cmd) {
3860 case PRISM2_SET_ENCRYPTION:
3861 ret = prism2_ioctl_set_encryption(local, param, p->length);
3862 break;
3863 case PRISM2_GET_ENCRYPTION:
3864 ret = prism2_ioctl_get_encryption(local, param, p->length);
3865 break;
3866 case PRISM2_HOSTAPD_GET_RID:
3867 ret = prism2_ioctl_get_rid(local, param, p->length);
3868 break;
3869 case PRISM2_HOSTAPD_SET_RID:
3870 ret = prism2_ioctl_set_rid(local, param, p->length);
3871 break;
3872 case PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR:
3873 ret = prism2_ioctl_set_assoc_ap_addr(local, param, p->length);
3874 break;
3875 case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
3876 ret = prism2_ioctl_set_generic_element(local, param,
3877 p->length);
3878 break;
3879 case PRISM2_HOSTAPD_MLME:
3880 ret = prism2_ioctl_mlme(local, param);
3881 break;
3882 case PRISM2_HOSTAPD_SCAN_REQ:
3883 ret = prism2_ioctl_scan_req(local, param);
3884 break;
3885 default:
3886 ret = prism2_hostapd(local->ap, param);
3887 ap_ioctl = 1;
3888 break;
3889 }
3890
3891 if (ret == 1 || !ap_ioctl) {
3892 if (copy_to_user(p->pointer, param, p->length)) {
3893 ret = -EFAULT;
3894 goto out;
3895 } else if (ap_ioctl)
3896 ret = 0;
3897 }
3898
3899 out:
3900 if (param != NULL)
3901 kfree(param);
3902
3903 return ret;
3904}
3905
3906
3907static void prism2_get_drvinfo(struct net_device *dev,
3908 struct ethtool_drvinfo *info)
3909{
3910 struct hostap_interface *iface;
3911 local_info_t *local;
3912
3913 iface = netdev_priv(dev);
3914 local = iface->local;
3915
3916 strncpy(info->driver, "hostap", sizeof(info->driver) - 1);
3917 strncpy(info->version, PRISM2_VERSION,
3918 sizeof(info->version) - 1);
3919 snprintf(info->fw_version, sizeof(info->fw_version) - 1,
3920 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
3921 (local->sta_fw_ver >> 8) & 0xff,
3922 local->sta_fw_ver & 0xff);
3923}
3924
3925static struct ethtool_ops prism2_ethtool_ops = {
3926 .get_drvinfo = prism2_get_drvinfo
3927};
3928
3929
3930/* Structures to export the Wireless Handlers */
3931
3932static const iw_handler prism2_handler[] =
3933{
3934 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3935 (iw_handler) prism2_get_name, /* SIOCGIWNAME */
3936 (iw_handler) NULL, /* SIOCSIWNWID */
3937 (iw_handler) NULL, /* SIOCGIWNWID */
3938 (iw_handler) prism2_ioctl_siwfreq, /* SIOCSIWFREQ */
3939 (iw_handler) prism2_ioctl_giwfreq, /* SIOCGIWFREQ */
3940 (iw_handler) prism2_ioctl_siwmode, /* SIOCSIWMODE */
3941 (iw_handler) prism2_ioctl_giwmode, /* SIOCGIWMODE */
3942 (iw_handler) prism2_ioctl_siwsens, /* SIOCSIWSENS */
3943 (iw_handler) prism2_ioctl_giwsens, /* SIOCGIWSENS */
3944 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3945 (iw_handler) prism2_ioctl_giwrange, /* SIOCGIWRANGE */
3946 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3947 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3948 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3949 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
3950 iw_handler_set_spy, /* SIOCSIWSPY */
3951 iw_handler_get_spy, /* SIOCGIWSPY */
3952 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
3953 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
3954 (iw_handler) prism2_ioctl_siwap, /* SIOCSIWAP */
3955 (iw_handler) prism2_ioctl_giwap, /* SIOCGIWAP */
3956 (iw_handler) prism2_ioctl_siwmlme, /* SIOCSIWMLME */
3957 (iw_handler) prism2_ioctl_giwaplist, /* SIOCGIWAPLIST */
3958 (iw_handler) prism2_ioctl_siwscan, /* SIOCSIWSCAN */
3959 (iw_handler) prism2_ioctl_giwscan, /* SIOCGIWSCAN */
3960 (iw_handler) prism2_ioctl_siwessid, /* SIOCSIWESSID */
3961 (iw_handler) prism2_ioctl_giwessid, /* SIOCGIWESSID */
3962 (iw_handler) prism2_ioctl_siwnickn, /* SIOCSIWNICKN */
3963 (iw_handler) prism2_ioctl_giwnickn, /* SIOCGIWNICKN */
3964 (iw_handler) NULL, /* -- hole -- */
3965 (iw_handler) NULL, /* -- hole -- */
3966 (iw_handler) prism2_ioctl_siwrate, /* SIOCSIWRATE */
3967 (iw_handler) prism2_ioctl_giwrate, /* SIOCGIWRATE */
3968 (iw_handler) prism2_ioctl_siwrts, /* SIOCSIWRTS */
3969 (iw_handler) prism2_ioctl_giwrts, /* SIOCGIWRTS */
3970 (iw_handler) prism2_ioctl_siwfrag, /* SIOCSIWFRAG */
3971 (iw_handler) prism2_ioctl_giwfrag, /* SIOCGIWFRAG */
3972 (iw_handler) prism2_ioctl_siwtxpow, /* SIOCSIWTXPOW */
3973 (iw_handler) prism2_ioctl_giwtxpow, /* SIOCGIWTXPOW */
3974 (iw_handler) prism2_ioctl_siwretry, /* SIOCSIWRETRY */
3975 (iw_handler) prism2_ioctl_giwretry, /* SIOCGIWRETRY */
3976 (iw_handler) prism2_ioctl_siwencode, /* SIOCSIWENCODE */
3977 (iw_handler) prism2_ioctl_giwencode, /* SIOCGIWENCODE */
3978 (iw_handler) prism2_ioctl_siwpower, /* SIOCSIWPOWER */
3979 (iw_handler) prism2_ioctl_giwpower, /* SIOCGIWPOWER */
3980 (iw_handler) NULL, /* -- hole -- */
3981 (iw_handler) NULL, /* -- hole -- */
3982 (iw_handler) prism2_ioctl_siwgenie, /* SIOCSIWGENIE */
3983 (iw_handler) prism2_ioctl_giwgenie, /* SIOCGIWGENIE */
3984 (iw_handler) prism2_ioctl_siwauth, /* SIOCSIWAUTH */
3985 (iw_handler) prism2_ioctl_giwauth, /* SIOCGIWAUTH */
3986 (iw_handler) prism2_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3987 (iw_handler) prism2_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3988 (iw_handler) NULL, /* SIOCSIWPMKSA */
3989 (iw_handler) NULL, /* -- hole -- */
3990};
3991
3992static const iw_handler prism2_private_handler[] =
3993{ /* SIOCIWFIRSTPRIV + */
3994 (iw_handler) prism2_ioctl_priv_prism2_param, /* 0 */
3995 (iw_handler) prism2_ioctl_priv_get_prism2_param, /* 1 */
3996 (iw_handler) prism2_ioctl_priv_writemif, /* 2 */
3997 (iw_handler) prism2_ioctl_priv_readmif, /* 3 */
3998};
3999
4000static const struct iw_handler_def hostap_iw_handler_def =
4001{
4002 .num_standard = sizeof(prism2_handler) / sizeof(iw_handler),
4003 .num_private = sizeof(prism2_private_handler) / sizeof(iw_handler),
4004 .num_private_args = sizeof(prism2_priv) / sizeof(struct iw_priv_args),
4005 .standard = (iw_handler *) prism2_handler,
4006 .private = (iw_handler *) prism2_private_handler,
4007 .private_args = (struct iw_priv_args *) prism2_priv,
4008 .get_wireless_stats = hostap_get_wireless_stats,
4009};
4010
4011
4012int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4013{
4014 struct iwreq *wrq = (struct iwreq *) ifr;
4015 struct hostap_interface *iface;
4016 local_info_t *local;
4017 int ret = 0;
4018
4019 iface = netdev_priv(dev);
4020 local = iface->local;
4021
4022 switch (cmd) {
4023 /* Private ioctls (iwpriv) that have not yet been converted
4024 * into new wireless extensions API */
4025
4026 case PRISM2_IOCTL_INQUIRE:
4027 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4028 else ret = prism2_ioctl_priv_inquire(dev, (int *) wrq->u.name);
4029 break;
4030
4031 case PRISM2_IOCTL_MONITOR:
4032 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4033 else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name);
4034 break;
4035
4036 case PRISM2_IOCTL_RESET:
4037 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4038 else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name);
4039 break;
4040
4041 case PRISM2_IOCTL_WDS_ADD:
4042 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4043 else ret = prism2_wds_add(local, wrq->u.ap_addr.sa_data, 1);
4044 break;
4045
4046 case PRISM2_IOCTL_WDS_DEL:
4047 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4048 else ret = prism2_wds_del(local, wrq->u.ap_addr.sa_data, 1, 0);
4049 break;
4050
4051 case PRISM2_IOCTL_SET_RID_WORD:
4052 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4053 else ret = prism2_ioctl_priv_set_rid_word(dev,
4054 (int *) wrq->u.name);
4055 break;
4056
4057#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
4058 case PRISM2_IOCTL_MACCMD:
4059 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4060 else ret = ap_mac_cmd_ioctl(local, (int *) wrq->u.name);
4061 break;
4062
4063 case PRISM2_IOCTL_ADDMAC:
4064 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4065 else ret = ap_control_add_mac(&local->ap->mac_restrictions,
4066 wrq->u.ap_addr.sa_data);
4067 break;
4068 case PRISM2_IOCTL_DELMAC:
4069 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4070 else ret = ap_control_del_mac(&local->ap->mac_restrictions,
4071 wrq->u.ap_addr.sa_data);
4072 break;
4073 case PRISM2_IOCTL_KICKMAC:
4074 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4075 else ret = ap_control_kick_mac(local->ap, local->dev,
4076 wrq->u.ap_addr.sa_data);
4077 break;
4078#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
4079
4080
4081 /* Private ioctls that are not used with iwpriv;
4082 * in SIOCDEVPRIVATE range */
4083
4084#ifdef PRISM2_DOWNLOAD_SUPPORT
4085 case PRISM2_IOCTL_DOWNLOAD:
4086 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4087 else ret = prism2_ioctl_priv_download(local, &wrq->u.data);
4088 break;
4089#endif /* PRISM2_DOWNLOAD_SUPPORT */
4090
4091 case PRISM2_IOCTL_HOSTAPD:
4092 if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
4093 else ret = prism2_ioctl_priv_hostapd(local, &wrq->u.data);
4094 break;
4095
4096 default:
4097 ret = -EOPNOTSUPP;
4098 break;
4099 }
4100
4101 return ret;
4102}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
new file mode 100644
index 000000000000..4f567ef6178d
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -0,0 +1,473 @@
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");
34MODULE_VERSION(PRISM2_VERSION);
35
36
37/* struct local_info::hw_priv */
38struct hostap_pci_priv {
39 void __iomem *mem_start;
40};
41
42
43/* FIX: do we need mb/wmb/rmb with memory operations? */
44
45
46static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
47 /* Intersil Prism3 ISL3872 11Mb/s WLAN Controller */
48 { 0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID },
49 /* Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller */
50 { 0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID },
51 /* Samsung MagicLAN SWL-2210P */
52 { 0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID },
53 { 0 }
54};
55
56
57#ifdef PRISM2_IO_DEBUG
58
59static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
60{
61 struct hostap_interface *iface;
62 local_info_t *local;
63 unsigned long flags;
64
65 iface = netdev_priv(dev);
66 local = iface->local;
67
68 spin_lock_irqsave(&local->lock, flags);
69 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
70 writeb(v, hw_priv->mem_start + a);
71 spin_unlock_irqrestore(&local->lock, flags);
72}
73
74static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
75{
76 struct hostap_interface *iface;
77 local_info_t *local;
78 unsigned long flags;
79 u8 v;
80
81 iface = netdev_priv(dev);
82 local = iface->local;
83
84 spin_lock_irqsave(&local->lock, flags);
85 v = readb(hw_priv->mem_start + a);
86 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
87 spin_unlock_irqrestore(&local->lock, flags);
88 return v;
89}
90
91static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
92{
93 struct hostap_interface *iface;
94 local_info_t *local;
95 unsigned long flags;
96
97 iface = netdev_priv(dev);
98 local = iface->local;
99
100 spin_lock_irqsave(&local->lock, flags);
101 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
102 writew(v, hw_priv->mem_start + a);
103 spin_unlock_irqrestore(&local->lock, flags);
104}
105
106static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
107{
108 struct hostap_interface *iface;
109 local_info_t *local;
110 unsigned long flags;
111 u16 v;
112
113 iface = netdev_priv(dev);
114 local = iface->local;
115
116 spin_lock_irqsave(&local->lock, flags);
117 v = readw(hw_priv->mem_start + a);
118 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
119 spin_unlock_irqrestore(&local->lock, flags);
120 return v;
121}
122
123#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
124#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
125#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
126#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
127#define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), cpu_to_le16((v)))
128#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw_debug(dev, (a)))
129
130#else /* PRISM2_IO_DEBUG */
131
132static inline void hfa384x_outb(struct net_device *dev, int a, u8 v)
133{
134 struct hostap_interface *iface;
135 struct hostap_pci_priv *hw_priv;
136 iface = netdev_priv(dev);
137 hw_priv = iface->local->hw_priv;
138 writeb(v, hw_priv->mem_start + a);
139}
140
141static inline u8 hfa384x_inb(struct net_device *dev, int a)
142{
143 struct hostap_interface *iface;
144 struct hostap_pci_priv *hw_priv;
145 iface = netdev_priv(dev);
146 hw_priv = iface->local->hw_priv;
147 return readb(hw_priv->mem_start + a);
148}
149
150static inline void hfa384x_outw(struct net_device *dev, int a, u16 v)
151{
152 struct hostap_interface *iface;
153 struct hostap_pci_priv *hw_priv;
154 iface = netdev_priv(dev);
155 hw_priv = iface->local->hw_priv;
156 writew(v, hw_priv->mem_start + a);
157}
158
159static inline u16 hfa384x_inw(struct net_device *dev, int a)
160{
161 struct hostap_interface *iface;
162 struct hostap_pci_priv *hw_priv;
163 iface = netdev_priv(dev);
164 hw_priv = iface->local->hw_priv;
165 return readw(hw_priv->mem_start + a);
166}
167
168#define HFA384X_OUTB(v,a) hfa384x_outb(dev, (a), (v))
169#define HFA384X_INB(a) hfa384x_inb(dev, (a))
170#define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v))
171#define HFA384X_INW(a) hfa384x_inw(dev, (a))
172#define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), cpu_to_le16((v)))
173#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw(dev, (a)))
174
175#endif /* PRISM2_IO_DEBUG */
176
177
178static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
179 int len)
180{
181 u16 d_off;
182 u16 *pos;
183
184 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
185 pos = (u16 *) buf;
186
187 for ( ; len > 1; len -= 2)
188 *pos++ = HFA384X_INW_DATA(d_off);
189
190 if (len & 1)
191 *((char *) pos) = HFA384X_INB(d_off);
192
193 return 0;
194}
195
196
197static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
198{
199 u16 d_off;
200 u16 *pos;
201
202 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
203 pos = (u16 *) buf;
204
205 for ( ; len > 1; len -= 2)
206 HFA384X_OUTW_DATA(*pos++, d_off);
207
208 if (len & 1)
209 HFA384X_OUTB(*((char *) pos), d_off);
210
211 return 0;
212}
213
214
215/* FIX: This might change at some point.. */
216#include "hostap_hw.c"
217
218static void prism2_pci_cor_sreset(local_info_t *local)
219{
220 struct net_device *dev = local->dev;
221 u16 reg;
222
223 reg = HFA384X_INB(HFA384X_PCICOR_OFF);
224 printk(KERN_DEBUG "%s: Original COR value: 0x%0x\n", dev->name, reg);
225
226 /* linux-wlan-ng uses extremely long hold and settle times for
227 * COR sreset. A comment in the driver code mentions that the long
228 * delays appear to be necessary. However, at least IBM 22P6901 seems
229 * to work fine with shorter delays.
230 *
231 * Longer delays can be configured by uncommenting following line: */
232/* #define PRISM2_PCI_USE_LONG_DELAYS */
233
234#ifdef PRISM2_PCI_USE_LONG_DELAYS
235 int i;
236
237 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
238 mdelay(250);
239
240 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
241 mdelay(500);
242
243 /* Wait for f/w to complete initialization (CMD:BUSY == 0) */
244 i = 2000000 / 10;
245 while ((HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) && --i)
246 udelay(10);
247
248#else /* PRISM2_PCI_USE_LONG_DELAYS */
249
250 HFA384X_OUTW(reg | 0x0080, HFA384X_PCICOR_OFF);
251 mdelay(2);
252 HFA384X_OUTW(reg & ~0x0080, HFA384X_PCICOR_OFF);
253 mdelay(2);
254
255#endif /* PRISM2_PCI_USE_LONG_DELAYS */
256
257 if (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY) {
258 printk(KERN_DEBUG "%s: COR sreset timeout\n", dev->name);
259 }
260}
261
262
263static void prism2_pci_genesis_reset(local_info_t *local, int hcr)
264{
265 struct net_device *dev = local->dev;
266
267 HFA384X_OUTW(0x00C5, HFA384X_PCICOR_OFF);
268 mdelay(10);
269 HFA384X_OUTW(hcr, HFA384X_PCIHCR_OFF);
270 mdelay(10);
271 HFA384X_OUTW(0x0045, HFA384X_PCICOR_OFF);
272 mdelay(10);
273}
274
275
276static struct prism2_helper_functions prism2_pci_funcs =
277{
278 .card_present = NULL,
279 .cor_sreset = prism2_pci_cor_sreset,
280 .dev_open = NULL,
281 .dev_close = NULL,
282 .genesis_reset = prism2_pci_genesis_reset,
283 .hw_type = HOSTAP_HW_PCI,
284};
285
286
287static int prism2_pci_probe(struct pci_dev *pdev,
288 const struct pci_device_id *id)
289{
290 unsigned long phymem;
291 void __iomem *mem = NULL;
292 local_info_t *local = NULL;
293 struct net_device *dev = NULL;
294 static int cards_found /* = 0 */;
295 int irq_registered = 0;
296 struct hostap_interface *iface;
297 struct hostap_pci_priv *hw_priv;
298
299 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
300 if (hw_priv == NULL)
301 return -ENOMEM;
302 memset(hw_priv, 0, sizeof(*hw_priv));
303
304 if (pci_enable_device(pdev))
305 return -EIO;
306
307 phymem = pci_resource_start(pdev, 0);
308
309 if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
310 printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
311 goto err_out_disable;
312 }
313
314 mem = ioremap(phymem, pci_resource_len(pdev, 0));
315 if (mem == NULL) {
316 printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ;
317 goto fail;
318 }
319
320 dev = prism2_init_local_data(&prism2_pci_funcs, cards_found,
321 &pdev->dev);
322 if (dev == NULL)
323 goto fail;
324 iface = netdev_priv(dev);
325 local = iface->local;
326 local->hw_priv = hw_priv;
327 cards_found++;
328
329 dev->irq = pdev->irq;
330 hw_priv->mem_start = mem;
331
332 prism2_pci_cor_sreset(local);
333
334 pci_set_drvdata(pdev, dev);
335
336 if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name,
337 dev)) {
338 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
339 goto fail;
340 } else
341 irq_registered = 1;
342
343 if (!local->pri_only && prism2_hw_config(dev, 1)) {
344 printk(KERN_DEBUG "%s: hardware initialization failed\n",
345 dev_info);
346 goto fail;
347 }
348
349 printk(KERN_INFO "%s: Intersil Prism2.5 PCI: "
350 "mem=0x%lx, irq=%d\n", dev->name, phymem, dev->irq);
351
352 return hostap_hw_ready(dev);
353
354 fail:
355 kfree(hw_priv);
356
357 if (irq_registered && dev)
358 free_irq(dev->irq, dev);
359
360 if (mem)
361 iounmap(mem);
362
363 release_mem_region(phymem, pci_resource_len(pdev, 0));
364
365 err_out_disable:
366 pci_disable_device(pdev);
367 kfree(hw_priv);
368 if (local)
369 local->hw_priv = NULL;
370 prism2_free_local_data(dev);
371
372 return -ENODEV;
373}
374
375
376static void prism2_pci_remove(struct pci_dev *pdev)
377{
378 struct net_device *dev;
379 struct hostap_interface *iface;
380 void __iomem *mem_start;
381 struct hostap_pci_priv *hw_priv;
382
383 dev = pci_get_drvdata(pdev);
384 iface = netdev_priv(dev);
385 hw_priv = iface->local->hw_priv;
386
387 /* Reset the hardware, and ensure interrupts are disabled. */
388 prism2_pci_cor_sreset(iface->local);
389 hfa384x_disable_interrupts(dev);
390
391 if (dev->irq)
392 free_irq(dev->irq, dev);
393
394 mem_start = hw_priv->mem_start;
395 kfree(hw_priv);
396 iface->local->hw_priv = NULL;
397 prism2_free_local_data(dev);
398
399 iounmap(mem_start);
400
401 release_mem_region(pci_resource_start(pdev, 0),
402 pci_resource_len(pdev, 0));
403 pci_disable_device(pdev);
404}
405
406
407#ifdef CONFIG_PM
408static int prism2_pci_suspend(struct pci_dev *pdev, pm_message_t state)
409{
410 struct net_device *dev = pci_get_drvdata(pdev);
411
412 if (netif_running(dev)) {
413 netif_stop_queue(dev);
414 netif_device_detach(dev);
415 }
416 prism2_suspend(dev);
417 pci_save_state(pdev);
418 pci_disable_device(pdev);
419 pci_set_power_state(pdev, 3);
420
421 return 0;
422}
423
424static int prism2_pci_resume(struct pci_dev *pdev)
425{
426 struct net_device *dev = pci_get_drvdata(pdev);
427
428 pci_enable_device(pdev);
429 pci_restore_state(pdev);
430 prism2_hw_config(dev, 0);
431 if (netif_running(dev)) {
432 netif_device_attach(dev);
433 netif_start_queue(dev);
434 }
435
436 return 0;
437}
438#endif /* CONFIG_PM */
439
440
441MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
442
443static struct pci_driver prism2_pci_drv_id = {
444 .name = "prism2_pci",
445 .id_table = prism2_pci_id_table,
446 .probe = prism2_pci_probe,
447 .remove = prism2_pci_remove,
448#ifdef CONFIG_PM
449 .suspend = prism2_pci_suspend,
450 .resume = prism2_pci_resume,
451#endif /* CONFIG_PM */
452 /* Linux 2.4.6 added save_state and enable_wake that are not used here
453 */
454};
455
456
457static int __init init_prism2_pci(void)
458{
459 printk(KERN_INFO "%s: %s\n", dev_info, version);
460
461 return pci_register_driver(&prism2_pci_drv_id);
462}
463
464
465static void __exit exit_prism2_pci(void)
466{
467 pci_unregister_driver(&prism2_pci_drv_id);
468 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
469}
470
471
472module_init(init_prism2_pci);
473module_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..474ef83d813e
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -0,0 +1,645 @@
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");
37MODULE_VERSION(PRISM2_VERSION);
38
39
40static int ignore_cis;
41module_param(ignore_cis, int, 0444);
42MODULE_PARM_DESC(ignore_cis, "Do not verify manfid information in CIS");
43
44
45/* struct local_info::hw_priv */
46struct hostap_plx_priv {
47 void __iomem *attr_mem;
48 unsigned int cor_offset;
49};
50
51
52#define PLX_MIN_ATTR_LEN 512 /* at least 2 x 256 is needed for CIS */
53#define COR_SRESET 0x80
54#define COR_LEVLREQ 0x40
55#define COR_ENABLE_FUNC 0x01
56/* PCI Configuration Registers */
57#define PLX_PCIIPR 0x3d /* PCI Interrupt Pin */
58/* Local Configuration Registers */
59#define PLX_INTCSR 0x4c /* Interrupt Control/Status Register */
60#define PLX_INTCSR_PCI_INTEN BIT(6) /* PCI Interrupt Enable */
61#define PLX_CNTRL 0x50
62#define PLX_CNTRL_SERIAL_EEPROM_PRESENT BIT(28)
63
64
65#define PLXDEV(vendor,dev,str) { vendor, dev, PCI_ANY_ID, PCI_ANY_ID }
66
67static struct pci_device_id prism2_plx_id_table[] __devinitdata = {
68 PLXDEV(0x10b7, 0x7770, "3Com AirConnect PCI 777A"),
69 PLXDEV(0x111a, 0x1023, "Siemens SpeedStream SS1023"),
70 PLXDEV(0x126c, 0x8030, "Nortel emobility"),
71 PLXDEV(0x1385, 0x4100, "Netgear MA301"),
72 PLXDEV(0x15e8, 0x0130, "National Datacomm NCP130 (PLX9052)"),
73 PLXDEV(0x15e8, 0x0131, "National Datacomm NCP130 (TMD7160)"),
74 PLXDEV(0x1638, 0x1100, "Eumitcom WL11000"),
75 PLXDEV(0x16ab, 0x1101, "Global Sun Tech GL24110P (?)"),
76 PLXDEV(0x16ab, 0x1102, "Linksys WPC11 with WDT11"),
77 PLXDEV(0x16ab, 0x1103, "Longshine 8031"),
78 PLXDEV(0x16ec, 0x3685, "US Robotics USR2415"),
79 PLXDEV(0xec80, 0xec00, "Belkin F5D6000"),
80 { 0 }
81};
82
83
84/* Array of known Prism2/2.5 PC Card manufactured ids. If your card's manfid
85 * is not listed here, you will need to add it here to get the driver
86 * initialized. */
87static struct prism2_plx_manfid {
88 u16 manfid1, manfid2;
89} prism2_plx_known_manfids[] = {
90 { 0x000b, 0x7110 } /* D-Link DWL-650 Rev. P1 */,
91 { 0x000b, 0x7300 } /* Philips 802.11b WLAN PCMCIA */,
92 { 0x0101, 0x0777 } /* 3Com AirConnect PCI 777A */,
93 { 0x0126, 0x8000 } /* Proxim RangeLAN */,
94 { 0x0138, 0x0002 } /* Compaq WL100 */,
95 { 0x0156, 0x0002 } /* Intersil Prism II Ref. Design (and others) */,
96 { 0x026f, 0x030b } /* Buffalo WLI-CF-S11G */,
97 { 0x0274, 0x1612 } /* Linksys WPC11 Ver 2.5 */,
98 { 0x0274, 0x1613 } /* Linksys WPC11 Ver 3 */,
99 { 0x028a, 0x0002 } /* D-Link DRC-650 */,
100 { 0x0250, 0x0002 } /* Samsung SWL2000-N */,
101 { 0xc250, 0x0002 } /* EMTAC A2424i */,
102 { 0xd601, 0x0002 } /* Z-Com XI300 */,
103 { 0xd601, 0x0005 } /* Zcomax XI-325H 200mW */,
104 { 0, 0}
105};
106
107
108#ifdef PRISM2_IO_DEBUG
109
110static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
111{
112 struct hostap_interface *iface;
113 local_info_t *local;
114 unsigned long flags;
115
116 iface = netdev_priv(dev);
117 local = iface->local;
118
119 spin_lock_irqsave(&local->lock, flags);
120 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
121 outb(v, dev->base_addr + a);
122 spin_unlock_irqrestore(&local->lock, flags);
123}
124
125static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
126{
127 struct hostap_interface *iface;
128 local_info_t *local;
129 unsigned long flags;
130 u8 v;
131
132 iface = netdev_priv(dev);
133 local = iface->local;
134
135 spin_lock_irqsave(&local->lock, flags);
136 v = inb(dev->base_addr + a);
137 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INB, a, v);
138 spin_unlock_irqrestore(&local->lock, flags);
139 return v;
140}
141
142static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
143{
144 struct hostap_interface *iface;
145 local_info_t *local;
146 unsigned long flags;
147
148 iface = netdev_priv(dev);
149 local = iface->local;
150
151 spin_lock_irqsave(&local->lock, flags);
152 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
153 outw(v, dev->base_addr + a);
154 spin_unlock_irqrestore(&local->lock, flags);
155}
156
157static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
158{
159 struct hostap_interface *iface;
160 local_info_t *local;
161 unsigned long flags;
162 u16 v;
163
164 iface = netdev_priv(dev);
165 local = iface->local;
166
167 spin_lock_irqsave(&local->lock, flags);
168 v = inw(dev->base_addr + a);
169 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INW, a, v);
170 spin_unlock_irqrestore(&local->lock, flags);
171 return v;
172}
173
174static inline void hfa384x_outsw_debug(struct net_device *dev, int a,
175 u8 *buf, int wc)
176{
177 struct hostap_interface *iface;
178 local_info_t *local;
179 unsigned long flags;
180
181 iface = netdev_priv(dev);
182 local = iface->local;
183
184 spin_lock_irqsave(&local->lock, flags);
185 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTSW, a, wc);
186 outsw(dev->base_addr + a, buf, wc);
187 spin_unlock_irqrestore(&local->lock, flags);
188}
189
190static inline void hfa384x_insw_debug(struct net_device *dev, int a,
191 u8 *buf, int wc)
192{
193 struct hostap_interface *iface;
194 local_info_t *local;
195 unsigned long flags;
196
197 iface = netdev_priv(dev);
198 local = iface->local;
199
200 spin_lock_irqsave(&local->lock, flags);
201 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INSW, a, wc);
202 insw(dev->base_addr + a, buf, wc);
203 spin_unlock_irqrestore(&local->lock, flags);
204}
205
206#define HFA384X_OUTB(v,a) hfa384x_outb_debug(dev, (a), (v))
207#define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
208#define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
209#define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
210#define HFA384X_OUTSW(a, buf, wc) hfa384x_outsw_debug(dev, (a), (buf), (wc))
211#define HFA384X_INSW(a, buf, wc) hfa384x_insw_debug(dev, (a), (buf), (wc))
212
213#else /* PRISM2_IO_DEBUG */
214
215#define HFA384X_OUTB(v,a) outb((v), dev->base_addr + (a))
216#define HFA384X_INB(a) inb(dev->base_addr + (a))
217#define HFA384X_OUTW(v,a) outw((v), dev->base_addr + (a))
218#define HFA384X_INW(a) inw(dev->base_addr + (a))
219#define HFA384X_INSW(a, buf, wc) insw(dev->base_addr + (a), buf, wc)
220#define HFA384X_OUTSW(a, buf, wc) outsw(dev->base_addr + (a), buf, wc)
221
222#endif /* PRISM2_IO_DEBUG */
223
224
225static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
226 int len)
227{
228 u16 d_off;
229 u16 *pos;
230
231 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
232 pos = (u16 *) buf;
233
234 if (len / 2)
235 HFA384X_INSW(d_off, buf, len / 2);
236 pos += len / 2;
237
238 if (len & 1)
239 *((char *) pos) = HFA384X_INB(d_off);
240
241 return 0;
242}
243
244
245static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
246{
247 u16 d_off;
248 u16 *pos;
249
250 d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
251 pos = (u16 *) buf;
252
253 if (len / 2)
254 HFA384X_OUTSW(d_off, buf, len / 2);
255 pos += len / 2;
256
257 if (len & 1)
258 HFA384X_OUTB(*((char *) pos), d_off);
259
260 return 0;
261}
262
263
264/* FIX: This might change at some point.. */
265#include "hostap_hw.c"
266
267
268static void prism2_plx_cor_sreset(local_info_t *local)
269{
270 unsigned char corsave;
271 struct hostap_plx_priv *hw_priv = local->hw_priv;
272
273 printk(KERN_DEBUG "%s: Doing reset via direct COR access.\n",
274 dev_info);
275
276 /* Set sreset bit of COR and clear it after hold time */
277
278 if (hw_priv->attr_mem == NULL) {
279 /* TMD7160 - COR at card's first I/O addr */
280 corsave = inb(hw_priv->cor_offset);
281 outb(corsave | COR_SRESET, hw_priv->cor_offset);
282 mdelay(2);
283 outb(corsave & ~COR_SRESET, hw_priv->cor_offset);
284 mdelay(2);
285 } else {
286 /* PLX9052 */
287 corsave = readb(hw_priv->attr_mem + hw_priv->cor_offset);
288 writeb(corsave | COR_SRESET,
289 hw_priv->attr_mem + hw_priv->cor_offset);
290 mdelay(2);
291 writeb(corsave & ~COR_SRESET,
292 hw_priv->attr_mem + hw_priv->cor_offset);
293 mdelay(2);
294 }
295}
296
297
298static void prism2_plx_genesis_reset(local_info_t *local, int hcr)
299{
300 unsigned char corsave;
301 struct hostap_plx_priv *hw_priv = local->hw_priv;
302
303 if (hw_priv->attr_mem == NULL) {
304 /* TMD7160 - COR at card's first I/O addr */
305 corsave = inb(hw_priv->cor_offset);
306 outb(corsave | COR_SRESET, hw_priv->cor_offset);
307 mdelay(10);
308 outb(hcr, hw_priv->cor_offset + 2);
309 mdelay(10);
310 outb(corsave & ~COR_SRESET, hw_priv->cor_offset);
311 mdelay(10);
312 } else {
313 /* PLX9052 */
314 corsave = readb(hw_priv->attr_mem + hw_priv->cor_offset);
315 writeb(corsave | COR_SRESET,
316 hw_priv->attr_mem + hw_priv->cor_offset);
317 mdelay(10);
318 writeb(hcr, hw_priv->attr_mem + hw_priv->cor_offset + 2);
319 mdelay(10);
320 writeb(corsave & ~COR_SRESET,
321 hw_priv->attr_mem + hw_priv->cor_offset);
322 mdelay(10);
323 }
324}
325
326
327static struct prism2_helper_functions prism2_plx_funcs =
328{
329 .card_present = NULL,
330 .cor_sreset = prism2_plx_cor_sreset,
331 .dev_open = NULL,
332 .dev_close = NULL,
333 .genesis_reset = prism2_plx_genesis_reset,
334 .hw_type = HOSTAP_HW_PLX,
335};
336
337
338static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len,
339 unsigned int *cor_offset,
340 unsigned int *cor_index)
341{
342#define CISTPL_CONFIG 0x1A
343#define CISTPL_MANFID 0x20
344#define CISTPL_END 0xFF
345#define CIS_MAX_LEN 256
346 u8 *cis;
347 int i, pos;
348 unsigned int rmsz, rasz, manfid1, manfid2;
349 struct prism2_plx_manfid *manfid;
350
351 cis = kmalloc(CIS_MAX_LEN, GFP_KERNEL);
352 if (cis == NULL)
353 return -ENOMEM;
354
355 /* read CIS; it is in even offsets in the beginning of attr_mem */
356 for (i = 0; i < CIS_MAX_LEN; i++)
357 cis[i] = readb(attr_mem + 2 * i);
358 printk(KERN_DEBUG "%s: CIS: %02x %02x %02x %02x %02x %02x ...\n",
359 dev_info, cis[0], cis[1], cis[2], cis[3], cis[4], cis[5]);
360
361 /* set reasonable defaults for Prism2 cards just in case CIS parsing
362 * fails */
363 *cor_offset = 0x3e0;
364 *cor_index = 0x01;
365 manfid1 = manfid2 = 0;
366
367 pos = 0;
368 while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) {
369 if (pos + cis[pos + 1] >= CIS_MAX_LEN)
370 goto cis_error;
371
372 switch (cis[pos]) {
373 case CISTPL_CONFIG:
374 if (cis[pos + 1] < 1)
375 goto cis_error;
376 rmsz = (cis[pos + 2] & 0x3c) >> 2;
377 rasz = cis[pos + 2] & 0x03;
378 if (4 + rasz + rmsz > cis[pos + 1])
379 goto cis_error;
380 *cor_index = cis[pos + 3] & 0x3F;
381 *cor_offset = 0;
382 for (i = 0; i <= rasz; i++)
383 *cor_offset += cis[pos + 4 + i] << (8 * i);
384 printk(KERN_DEBUG "%s: cor_index=0x%x "
385 "cor_offset=0x%x\n", dev_info,
386 *cor_index, *cor_offset);
387 if (*cor_offset > attr_len) {
388 printk(KERN_ERR "%s: COR offset not within "
389 "attr_mem\n", dev_info);
390 kfree(cis);
391 return -1;
392 }
393 break;
394
395 case CISTPL_MANFID:
396 if (cis[pos + 1] < 4)
397 goto cis_error;
398 manfid1 = cis[pos + 2] + (cis[pos + 3] << 8);
399 manfid2 = cis[pos + 4] + (cis[pos + 5] << 8);
400 printk(KERN_DEBUG "%s: manfid=0x%04x, 0x%04x\n",
401 dev_info, manfid1, manfid2);
402 break;
403 }
404
405 pos += cis[pos + 1] + 2;
406 }
407
408 if (pos >= CIS_MAX_LEN || cis[pos] != CISTPL_END)
409 goto cis_error;
410
411 for (manfid = prism2_plx_known_manfids; manfid->manfid1 != 0; manfid++)
412 if (manfid1 == manfid->manfid1 && manfid2 == manfid->manfid2) {
413 kfree(cis);
414 return 0;
415 }
416
417 printk(KERN_INFO "%s: unknown manfid 0x%04x, 0x%04x - assuming this is"
418 " not supported card\n", dev_info, manfid1, manfid2);
419 goto fail;
420
421 cis_error:
422 printk(KERN_WARNING "%s: invalid CIS data\n", dev_info);
423
424 fail:
425 kfree(cis);
426 if (ignore_cis) {
427 printk(KERN_INFO "%s: ignore_cis parameter set - ignoring "
428 "errors during CIS verification\n", dev_info);
429 return 0;
430 }
431 return -1;
432}
433
434
435static int prism2_plx_probe(struct pci_dev *pdev,
436 const struct pci_device_id *id)
437{
438 unsigned int pccard_ioaddr, plx_ioaddr;
439 unsigned long pccard_attr_mem;
440 unsigned int pccard_attr_len;
441 void __iomem *attr_mem = NULL;
442 unsigned int cor_offset, cor_index;
443 u32 reg;
444 local_info_t *local = NULL;
445 struct net_device *dev = NULL;
446 struct hostap_interface *iface;
447 static int cards_found /* = 0 */;
448 int irq_registered = 0;
449 int tmd7160;
450 struct hostap_plx_priv *hw_priv;
451
452 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
453 if (hw_priv == NULL)
454 return -ENOMEM;
455 memset(hw_priv, 0, sizeof(*hw_priv));
456
457 if (pci_enable_device(pdev))
458 return -EIO;
459
460 /* National Datacomm NCP130 based on TMD7160, not PLX9052. */
461 tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131);
462
463 plx_ioaddr = pci_resource_start(pdev, 1);
464 pccard_ioaddr = pci_resource_start(pdev, tmd7160 ? 2 : 3);
465
466 if (tmd7160) {
467 /* TMD7160 */
468 attr_mem = NULL; /* no access to PC Card attribute memory */
469
470 printk(KERN_INFO "TMD7160 PCI/PCMCIA adapter: io=0x%x, "
471 "irq=%d, pccard_io=0x%x\n",
472 plx_ioaddr, pdev->irq, pccard_ioaddr);
473
474 cor_offset = plx_ioaddr;
475 cor_index = 0x04;
476
477 outb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, plx_ioaddr);
478 mdelay(1);
479 reg = inb(plx_ioaddr);
480 if (reg != (cor_index | COR_LEVLREQ | COR_ENABLE_FUNC)) {
481 printk(KERN_ERR "%s: Error setting COR (expected="
482 "0x%02x, was=0x%02x)\n", dev_info,
483 cor_index | COR_LEVLREQ | COR_ENABLE_FUNC, reg);
484 goto fail;
485 }
486 } else {
487 /* PLX9052 */
488 pccard_attr_mem = pci_resource_start(pdev, 2);
489 pccard_attr_len = pci_resource_len(pdev, 2);
490 if (pccard_attr_len < PLX_MIN_ATTR_LEN)
491 goto fail;
492
493
494 attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);
495 if (attr_mem == NULL) {
496 printk(KERN_ERR "%s: cannot remap attr_mem\n",
497 dev_info);
498 goto fail;
499 }
500
501 printk(KERN_INFO "PLX9052 PCI/PCMCIA adapter: "
502 "mem=0x%lx, plx_io=0x%x, irq=%d, pccard_io=0x%x\n",
503 pccard_attr_mem, plx_ioaddr, pdev->irq, pccard_ioaddr);
504
505 if (prism2_plx_check_cis(attr_mem, pccard_attr_len,
506 &cor_offset, &cor_index)) {
507 printk(KERN_INFO "Unknown PC Card CIS - not a "
508 "Prism2/2.5 card?\n");
509 goto fail;
510 }
511
512 printk(KERN_DEBUG "Prism2/2.5 PC Card detected in PLX9052 "
513 "adapter\n");
514
515 /* Write COR to enable PC Card */
516 writeb(cor_index | COR_LEVLREQ | COR_ENABLE_FUNC,
517 attr_mem + cor_offset);
518
519 /* Enable PCI interrupts if they are not already enabled */
520 reg = inl(plx_ioaddr + PLX_INTCSR);
521 printk(KERN_DEBUG "PLX_INTCSR=0x%x\n", reg);
522 if (!(reg & PLX_INTCSR_PCI_INTEN)) {
523 outl(reg | PLX_INTCSR_PCI_INTEN,
524 plx_ioaddr + PLX_INTCSR);
525 if (!(inl(plx_ioaddr + PLX_INTCSR) &
526 PLX_INTCSR_PCI_INTEN)) {
527 printk(KERN_WARNING "%s: Could not enable "
528 "Local Interrupts\n", dev_info);
529 goto fail;
530 }
531 }
532
533 reg = inl(plx_ioaddr + PLX_CNTRL);
534 printk(KERN_DEBUG "PLX_CNTRL=0x%x (Serial EEPROM "
535 "present=%d)\n",
536 reg, (reg & PLX_CNTRL_SERIAL_EEPROM_PRESENT) != 0);
537 /* should set PLX_PCIIPR to 0x01 (INTA#) if Serial EEPROM is
538 * not present; but are there really such cards in use(?) */
539 }
540
541 dev = prism2_init_local_data(&prism2_plx_funcs, cards_found,
542 &pdev->dev);
543 if (dev == NULL)
544 goto fail;
545 iface = netdev_priv(dev);
546 local = iface->local;
547 local->hw_priv = hw_priv;
548 cards_found++;
549
550 dev->irq = pdev->irq;
551 dev->base_addr = pccard_ioaddr;
552 hw_priv->attr_mem = attr_mem;
553 hw_priv->cor_offset = cor_offset;
554
555 pci_set_drvdata(pdev, dev);
556
557 if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name,
558 dev)) {
559 printk(KERN_WARNING "%s: request_irq failed\n", dev->name);
560 goto fail;
561 } else
562 irq_registered = 1;
563
564 if (prism2_hw_config(dev, 1)) {
565 printk(KERN_DEBUG "%s: hardware initialization failed\n",
566 dev_info);
567 goto fail;
568 }
569
570 return hostap_hw_ready(dev);
571
572 fail:
573 kfree(hw_priv);
574 if (local)
575 local->hw_priv = NULL;
576 prism2_free_local_data(dev);
577
578 if (irq_registered && dev)
579 free_irq(dev->irq, dev);
580
581 if (attr_mem)
582 iounmap(attr_mem);
583
584 pci_disable_device(pdev);
585
586 return -ENODEV;
587}
588
589
590static void prism2_plx_remove(struct pci_dev *pdev)
591{
592 struct net_device *dev;
593 struct hostap_interface *iface;
594 struct hostap_plx_priv *hw_priv;
595
596 dev = pci_get_drvdata(pdev);
597 iface = netdev_priv(dev);
598 hw_priv = iface->local->hw_priv;
599
600 /* Reset the hardware, and ensure interrupts are disabled. */
601 prism2_plx_cor_sreset(iface->local);
602 hfa384x_disable_interrupts(dev);
603
604 if (hw_priv->attr_mem)
605 iounmap(hw_priv->attr_mem);
606 if (dev->irq)
607 free_irq(dev->irq, dev);
608
609 kfree(iface->local->hw_priv);
610 iface->local->hw_priv = NULL;
611 prism2_free_local_data(dev);
612 pci_disable_device(pdev);
613}
614
615
616MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
617
618static struct pci_driver prism2_plx_drv_id = {
619 .name = "prism2_plx",
620 .id_table = prism2_plx_id_table,
621 .probe = prism2_plx_probe,
622 .remove = prism2_plx_remove,
623 .suspend = NULL,
624 .resume = NULL,
625 .enable_wake = NULL
626};
627
628
629static int __init init_prism2_plx(void)
630{
631 printk(KERN_INFO "%s: %s\n", dev_info, version);
632
633 return pci_register_driver(&prism2_plx_drv_id);
634}
635
636
637static void __exit exit_prism2_plx(void)
638{
639 pci_unregister_driver(&prism2_plx_drv_id);
640 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
641}
642
643
644module_init(init_prism2_plx);
645module_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..a0a4cbd4937a
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -0,0 +1,448 @@
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 entry, i, len, total = 0;
306 struct hfa384x_hostscan_result *scanres;
307 u8 *pos;
308
309 p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates "
310 "SSID\n");
311
312 spin_lock_bh(&local->lock);
313 for (entry = 0; entry < local->last_scan_results_count; entry++) {
314 scanres = &local->last_scan_results[entry];
315
316 if (total + (p - page) <= off) {
317 total += p - page;
318 p = page;
319 }
320 if (total + (p - page) > off + count)
321 break;
322 if ((p - page) > (PAGE_SIZE - 200))
323 break;
324
325 p += sprintf(p, "%d %d %d %d 0x%02x %d " MACSTR " %d ",
326 le16_to_cpu(scanres->chid),
327 (s16) le16_to_cpu(scanres->anl),
328 (s16) le16_to_cpu(scanres->sl),
329 le16_to_cpu(scanres->beacon_interval),
330 le16_to_cpu(scanres->capability),
331 le16_to_cpu(scanres->rate),
332 MAC2STR(scanres->bssid),
333 le16_to_cpu(scanres->atim));
334
335 pos = scanres->sup_rates;
336 for (i = 0; i < sizeof(scanres->sup_rates); i++) {
337 if (pos[i] == 0)
338 break;
339 p += sprintf(p, "<%02x>", pos[i]);
340 }
341 p += sprintf(p, " ");
342
343 pos = scanres->ssid;
344 len = le16_to_cpu(scanres->ssid_len);
345 if (len > 32)
346 len = 32;
347 for (i = 0; i < len; i++) {
348 unsigned char c = pos[i];
349 if (c >= 32 && c < 127)
350 p += sprintf(p, "%c", c);
351 else
352 p += sprintf(p, "<%02x>", c);
353 }
354 p += sprintf(p, "\n");
355 }
356 spin_unlock_bh(&local->lock);
357
358 total += (p - page);
359 if (total >= off + count)
360 *eof = 1;
361
362 if (total < off) {
363 *eof = 1;
364 return 0;
365 }
366
367 len = total - off;
368 if (len > (p - page))
369 len = p - page;
370 *start = p - len;
371 if (len > count)
372 len = count;
373
374 return len;
375}
376#endif /* PRISM2_NO_STATION_MODES */
377
378
379void hostap_init_proc(local_info_t *local)
380{
381 local->proc = NULL;
382
383 if (hostap_proc == NULL) {
384 printk(KERN_WARNING "%s: hostap proc directory not created\n",
385 local->dev->name);
386 return;
387 }
388
389 local->proc = proc_mkdir(local->ddev->name, hostap_proc);
390 if (local->proc == NULL) {
391 printk(KERN_INFO "/proc/net/hostap/%s creation failed\n",
392 local->ddev->name);
393 return;
394 }
395
396#ifndef PRISM2_NO_PROCFS_DEBUG
397 create_proc_read_entry("debug", 0, local->proc,
398 prism2_debug_proc_read, local);
399#endif /* PRISM2_NO_PROCFS_DEBUG */
400 create_proc_read_entry("stats", 0, local->proc,
401 prism2_stats_proc_read, local);
402 create_proc_read_entry("wds", 0, local->proc,
403 prism2_wds_proc_read, local);
404 create_proc_read_entry("pda", 0, local->proc,
405 prism2_pda_proc_read, local);
406 create_proc_read_entry("aux_dump", 0, local->proc,
407 prism2_aux_dump_proc_read, local);
408 create_proc_read_entry("bss_list", 0, local->proc,
409 prism2_bss_list_proc_read, local);
410 create_proc_read_entry("crypt", 0, local->proc,
411 prism2_crypt_proc_read, local);
412#ifdef PRISM2_IO_DEBUG
413 create_proc_read_entry("io_debug", 0, local->proc,
414 prism2_io_debug_proc_read, local);
415#endif /* PRISM2_IO_DEBUG */
416#ifndef PRISM2_NO_STATION_MODES
417 create_proc_read_entry("scan_results", 0, local->proc,
418 prism2_scan_results_proc_read, local);
419#endif /* PRISM2_NO_STATION_MODES */
420}
421
422
423void hostap_remove_proc(local_info_t *local)
424{
425 if (local->proc != NULL) {
426#ifndef PRISM2_NO_STATION_MODES
427 remove_proc_entry("scan_results", local->proc);
428#endif /* PRISM2_NO_STATION_MODES */
429#ifdef PRISM2_IO_DEBUG
430 remove_proc_entry("io_debug", local->proc);
431#endif /* PRISM2_IO_DEBUG */
432 remove_proc_entry("pda", local->proc);
433 remove_proc_entry("aux_dump", local->proc);
434 remove_proc_entry("wds", local->proc);
435 remove_proc_entry("stats", local->proc);
436 remove_proc_entry("bss_list", local->proc);
437 remove_proc_entry("crypt", local->proc);
438#ifndef PRISM2_NO_PROCFS_DEBUG
439 remove_proc_entry("debug", local->proc);
440#endif /* PRISM2_NO_PROCFS_DEBUG */
441 if (hostap_proc != NULL)
442 remove_proc_entry(local->proc->name, hostap_proc);
443 }
444}
445
446
447EXPORT_SYMBOL(hostap_init_proc);
448EXPORT_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..cc061e1560d3
--- /dev/null
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -0,0 +1,1033 @@
1#ifndef HOSTAP_WLAN_H
2#define HOSTAP_WLAN_H
3
4#include "hostap_config.h"
5#include "hostap_common.h"
6
7#define MAX_PARM_DEVICES 8
8#define PARM_MIN_MAX "1-" __MODULE_STRING(MAX_PARM_DEVICES)
9#define DEF_INTS -1, -1, -1, -1, -1, -1, -1
10#define GET_INT_PARM(var,idx) var[var[idx] < 0 ? 0 : idx]
11
12
13/* Specific skb->protocol value that indicates that the packet already contains
14 * txdesc header.
15 * FIX: This might need own value that would be allocated especially for Prism2
16 * txdesc; ETH_P_CONTROL is commented as "Card specific control frames".
17 * However, these skb's should have only minimal path in the kernel side since
18 * prism2_send_mgmt() sends these with dev_queue_xmit() to prism2_tx(). */
19#define ETH_P_HOSTAP ETH_P_CONTROL
20
21/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
22 * (from linux-wlan-ng) */
23struct linux_wlan_ng_val {
24 u32 did;
25 u16 status, len;
26 u32 data;
27} __attribute__ ((packed));
28
29struct linux_wlan_ng_prism_hdr {
30 u32 msgcode, msglen;
31 char devname[16];
32 struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
33 noise, rate, istx, frmlen;
34} __attribute__ ((packed));
35
36struct linux_wlan_ng_cap_hdr {
37 u32 version;
38 u32 length;
39 u64 mactime;
40 u64 hosttime;
41 u32 phytype;
42 u32 channel;
43 u32 datarate;
44 u32 antenna;
45 u32 priority;
46 u32 ssi_type;
47 s32 ssi_signal;
48 s32 ssi_noise;
49 u32 preamble;
50 u32 encoding;
51} __attribute__ ((packed));
52
53#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */
54#define LWNG_CAPHDR_VERSION 0x80211001
55
56struct hfa384x_rx_frame {
57 /* HFA384X RX frame descriptor */
58 u16 status; /* HFA384X_RX_STATUS_ flags */
59 u32 time; /* timestamp, 1 microsecond resolution */
60 u8 silence; /* 27 .. 154; seems to be 0 */
61 u8 signal; /* 27 .. 154 */
62 u8 rate; /* 10, 20, 55, or 110 */
63 u8 rxflow;
64 u32 reserved;
65
66 /* 802.11 */
67 u16 frame_control;
68 u16 duration_id;
69 u8 addr1[6];
70 u8 addr2[6];
71 u8 addr3[6];
72 u16 seq_ctrl;
73 u8 addr4[6];
74 u16 data_len;
75
76 /* 802.3 */
77 u8 dst_addr[6];
78 u8 src_addr[6];
79 u16 len;
80
81 /* followed by frame data; max 2304 bytes */
82} __attribute__ ((packed));
83
84
85struct hfa384x_tx_frame {
86 /* HFA384X TX frame descriptor */
87 u16 status; /* HFA384X_TX_STATUS_ flags */
88 u16 reserved1;
89 u16 reserved2;
90 u32 sw_support;
91 u8 retry_count; /* not yet implemented */
92 u8 tx_rate; /* Host AP only; 0 = firmware, or 10, 20, 55, 110 */
93 u16 tx_control; /* HFA384X_TX_CTRL_ flags */
94
95 /* 802.11 */
96 u16 frame_control; /* parts not used */
97 u16 duration_id;
98 u8 addr1[6];
99 u8 addr2[6]; /* filled by firmware */
100 u8 addr3[6];
101 u16 seq_ctrl; /* filled by firmware */
102 u8 addr4[6];
103 u16 data_len;
104
105 /* 802.3 */
106 u8 dst_addr[6];
107 u8 src_addr[6];
108 u16 len;
109
110 /* followed by frame data; max 2304 bytes */
111} __attribute__ ((packed));
112
113
114struct hfa384x_rid_hdr
115{
116 u16 len;
117 u16 rid;
118} __attribute__ ((packed));
119
120
121/* Macro for converting signal levels (range 27 .. 154) to wireless ext
122 * dBm value with some accuracy */
123#define HFA384X_LEVEL_TO_dBm(v) 0x100 + (v) * 100 / 255 - 100
124
125#define HFA384X_LEVEL_TO_dBm_sign(v) (v) * 100 / 255 - 100
126
127struct hfa384x_scan_request {
128 u16 channel_list;
129 u16 txrate; /* HFA384X_RATES_* */
130} __attribute__ ((packed));
131
132struct hfa384x_hostscan_request {
133 u16 channel_list;
134 u16 txrate;
135 u16 target_ssid_len;
136 u8 target_ssid[32];
137} __attribute__ ((packed));
138
139struct hfa384x_join_request {
140 u8 bssid[6];
141 u16 channel;
142} __attribute__ ((packed));
143
144struct hfa384x_info_frame {
145 u16 len;
146 u16 type;
147} __attribute__ ((packed));
148
149struct hfa384x_comm_tallies {
150 u16 tx_unicast_frames;
151 u16 tx_multicast_frames;
152 u16 tx_fragments;
153 u16 tx_unicast_octets;
154 u16 tx_multicast_octets;
155 u16 tx_deferred_transmissions;
156 u16 tx_single_retry_frames;
157 u16 tx_multiple_retry_frames;
158 u16 tx_retry_limit_exceeded;
159 u16 tx_discards;
160 u16 rx_unicast_frames;
161 u16 rx_multicast_frames;
162 u16 rx_fragments;
163 u16 rx_unicast_octets;
164 u16 rx_multicast_octets;
165 u16 rx_fcs_errors;
166 u16 rx_discards_no_buffer;
167 u16 tx_discards_wrong_sa;
168 u16 rx_discards_wep_undecryptable;
169 u16 rx_message_in_msg_fragments;
170 u16 rx_message_in_bad_msg_fragments;
171} __attribute__ ((packed));
172
173struct hfa384x_comm_tallies32 {
174 u32 tx_unicast_frames;
175 u32 tx_multicast_frames;
176 u32 tx_fragments;
177 u32 tx_unicast_octets;
178 u32 tx_multicast_octets;
179 u32 tx_deferred_transmissions;
180 u32 tx_single_retry_frames;
181 u32 tx_multiple_retry_frames;
182 u32 tx_retry_limit_exceeded;
183 u32 tx_discards;
184 u32 rx_unicast_frames;
185 u32 rx_multicast_frames;
186 u32 rx_fragments;
187 u32 rx_unicast_octets;
188 u32 rx_multicast_octets;
189 u32 rx_fcs_errors;
190 u32 rx_discards_no_buffer;
191 u32 tx_discards_wrong_sa;
192 u32 rx_discards_wep_undecryptable;
193 u32 rx_message_in_msg_fragments;
194 u32 rx_message_in_bad_msg_fragments;
195} __attribute__ ((packed));
196
197struct hfa384x_scan_result_hdr {
198 u16 reserved;
199 u16 scan_reason;
200#define HFA384X_SCAN_IN_PROGRESS 0 /* no results available yet */
201#define HFA384X_SCAN_HOST_INITIATED 1
202#define HFA384X_SCAN_FIRMWARE_INITIATED 2
203#define HFA384X_SCAN_INQUIRY_FROM_HOST 3
204} __attribute__ ((packed));
205
206#define HFA384X_SCAN_MAX_RESULTS 32
207
208struct hfa384x_scan_result {
209 u16 chid;
210 u16 anl;
211 u16 sl;
212 u8 bssid[6];
213 u16 beacon_interval;
214 u16 capability;
215 u16 ssid_len;
216 u8 ssid[32];
217 u8 sup_rates[10];
218 u16 rate;
219} __attribute__ ((packed));
220
221struct hfa384x_hostscan_result {
222 u16 chid;
223 u16 anl;
224 u16 sl;
225 u8 bssid[6];
226 u16 beacon_interval;
227 u16 capability;
228 u16 ssid_len;
229 u8 ssid[32];
230 u8 sup_rates[10];
231 u16 rate;
232 u16 atim;
233} __attribute__ ((packed));
234
235struct comm_tallies_sums {
236 unsigned int tx_unicast_frames;
237 unsigned int tx_multicast_frames;
238 unsigned int tx_fragments;
239 unsigned int tx_unicast_octets;
240 unsigned int tx_multicast_octets;
241 unsigned int tx_deferred_transmissions;
242 unsigned int tx_single_retry_frames;
243 unsigned int tx_multiple_retry_frames;
244 unsigned int tx_retry_limit_exceeded;
245 unsigned int tx_discards;
246 unsigned int rx_unicast_frames;
247 unsigned int rx_multicast_frames;
248 unsigned int rx_fragments;
249 unsigned int rx_unicast_octets;
250 unsigned int rx_multicast_octets;
251 unsigned int rx_fcs_errors;
252 unsigned int rx_discards_no_buffer;
253 unsigned int tx_discards_wrong_sa;
254 unsigned int rx_discards_wep_undecryptable;
255 unsigned int rx_message_in_msg_fragments;
256 unsigned int rx_message_in_bad_msg_fragments;
257};
258
259
260struct hfa384x_regs {
261 u16 cmd;
262 u16 evstat;
263 u16 offset0;
264 u16 offset1;
265 u16 swsupport0;
266};
267
268
269#if defined(PRISM2_PCCARD) || defined(PRISM2_PLX)
270/* I/O ports for HFA384X Controller access */
271#define HFA384X_CMD_OFF 0x00
272#define HFA384X_PARAM0_OFF 0x02
273#define HFA384X_PARAM1_OFF 0x04
274#define HFA384X_PARAM2_OFF 0x06
275#define HFA384X_STATUS_OFF 0x08
276#define HFA384X_RESP0_OFF 0x0A
277#define HFA384X_RESP1_OFF 0x0C
278#define HFA384X_RESP2_OFF 0x0E
279#define HFA384X_INFOFID_OFF 0x10
280#define HFA384X_CONTROL_OFF 0x14
281#define HFA384X_SELECT0_OFF 0x18
282#define HFA384X_SELECT1_OFF 0x1A
283#define HFA384X_OFFSET0_OFF 0x1C
284#define HFA384X_OFFSET1_OFF 0x1E
285#define HFA384X_RXFID_OFF 0x20
286#define HFA384X_ALLOCFID_OFF 0x22
287#define HFA384X_TXCOMPLFID_OFF 0x24
288#define HFA384X_SWSUPPORT0_OFF 0x28
289#define HFA384X_SWSUPPORT1_OFF 0x2A
290#define HFA384X_SWSUPPORT2_OFF 0x2C
291#define HFA384X_EVSTAT_OFF 0x30
292#define HFA384X_INTEN_OFF 0x32
293#define HFA384X_EVACK_OFF 0x34
294#define HFA384X_DATA0_OFF 0x36
295#define HFA384X_DATA1_OFF 0x38
296#define HFA384X_AUXPAGE_OFF 0x3A
297#define HFA384X_AUXOFFSET_OFF 0x3C
298#define HFA384X_AUXDATA_OFF 0x3E
299#endif /* PRISM2_PCCARD || PRISM2_PLX */
300
301#ifdef PRISM2_PCI
302/* Memory addresses for ISL3874 controller access */
303#define HFA384X_CMD_OFF 0x00
304#define HFA384X_PARAM0_OFF 0x04
305#define HFA384X_PARAM1_OFF 0x08
306#define HFA384X_PARAM2_OFF 0x0C
307#define HFA384X_STATUS_OFF 0x10
308#define HFA384X_RESP0_OFF 0x14
309#define HFA384X_RESP1_OFF 0x18
310#define HFA384X_RESP2_OFF 0x1C
311#define HFA384X_INFOFID_OFF 0x20
312#define HFA384X_CONTROL_OFF 0x28
313#define HFA384X_SELECT0_OFF 0x30
314#define HFA384X_SELECT1_OFF 0x34
315#define HFA384X_OFFSET0_OFF 0x38
316#define HFA384X_OFFSET1_OFF 0x3C
317#define HFA384X_RXFID_OFF 0x40
318#define HFA384X_ALLOCFID_OFF 0x44
319#define HFA384X_TXCOMPLFID_OFF 0x48
320#define HFA384X_PCICOR_OFF 0x4C
321#define HFA384X_SWSUPPORT0_OFF 0x50
322#define HFA384X_SWSUPPORT1_OFF 0x54
323#define HFA384X_SWSUPPORT2_OFF 0x58
324#define HFA384X_PCIHCR_OFF 0x5C
325#define HFA384X_EVSTAT_OFF 0x60
326#define HFA384X_INTEN_OFF 0x64
327#define HFA384X_EVACK_OFF 0x68
328#define HFA384X_DATA0_OFF 0x6C
329#define HFA384X_DATA1_OFF 0x70
330#define HFA384X_AUXPAGE_OFF 0x74
331#define HFA384X_AUXOFFSET_OFF 0x78
332#define HFA384X_AUXDATA_OFF 0x7C
333#define HFA384X_PCI_M0_ADDRH_OFF 0x80
334#define HFA384X_PCI_M0_ADDRL_OFF 0x84
335#define HFA384X_PCI_M0_LEN_OFF 0x88
336#define HFA384X_PCI_M0_CTL_OFF 0x8C
337#define HFA384X_PCI_STATUS_OFF 0x98
338#define HFA384X_PCI_M1_ADDRH_OFF 0xA0
339#define HFA384X_PCI_M1_ADDRL_OFF 0xA4
340#define HFA384X_PCI_M1_LEN_OFF 0xA8
341#define HFA384X_PCI_M1_CTL_OFF 0xAC
342
343/* PCI bus master control bits (these are undocumented; based on guessing and
344 * experimenting..) */
345#define HFA384X_PCI_CTL_FROM_BAP (BIT(5) | BIT(1) | BIT(0))
346#define HFA384X_PCI_CTL_TO_BAP (BIT(5) | BIT(0))
347
348#endif /* PRISM2_PCI */
349
350
351/* Command codes for CMD reg. */
352#define HFA384X_CMDCODE_INIT 0x00
353#define HFA384X_CMDCODE_ENABLE 0x01
354#define HFA384X_CMDCODE_DISABLE 0x02
355#define HFA384X_CMDCODE_ALLOC 0x0A
356#define HFA384X_CMDCODE_TRANSMIT 0x0B
357#define HFA384X_CMDCODE_INQUIRE 0x11
358#define HFA384X_CMDCODE_ACCESS 0x21
359#define HFA384X_CMDCODE_ACCESS_WRITE (0x21 | BIT(8))
360#define HFA384X_CMDCODE_DOWNLOAD 0x22
361#define HFA384X_CMDCODE_READMIF 0x30
362#define HFA384X_CMDCODE_WRITEMIF 0x31
363#define HFA384X_CMDCODE_TEST 0x38
364
365#define HFA384X_CMDCODE_MASK 0x3F
366
367/* Test mode operations */
368#define HFA384X_TEST_CHANGE_CHANNEL 0x08
369#define HFA384X_TEST_MONITOR 0x0B
370#define HFA384X_TEST_STOP 0x0F
371#define HFA384X_TEST_CFG_BITS 0x15
372#define HFA384X_TEST_CFG_BIT_ALC BIT(3)
373
374#define HFA384X_CMD_BUSY BIT(15)
375
376#define HFA384X_CMD_TX_RECLAIM BIT(8)
377
378#define HFA384X_OFFSET_ERR BIT(14)
379#define HFA384X_OFFSET_BUSY BIT(15)
380
381
382/* ProgMode for download command */
383#define HFA384X_PROGMODE_DISABLE 0
384#define HFA384X_PROGMODE_ENABLE_VOLATILE 1
385#define HFA384X_PROGMODE_ENABLE_NON_VOLATILE 2
386#define HFA384X_PROGMODE_PROGRAM_NON_VOLATILE 3
387
388#define HFA384X_AUX_MAGIC0 0xfe01
389#define HFA384X_AUX_MAGIC1 0xdc23
390#define HFA384X_AUX_MAGIC2 0xba45
391
392#define HFA384X_AUX_PORT_DISABLED 0
393#define HFA384X_AUX_PORT_DISABLE BIT(14)
394#define HFA384X_AUX_PORT_ENABLE BIT(15)
395#define HFA384X_AUX_PORT_ENABLED (BIT(14) | BIT(15))
396#define HFA384X_AUX_PORT_MASK (BIT(14) | BIT(15))
397
398#define PRISM2_PDA_SIZE 1024
399
400
401/* Events; EvStat, Interrupt mask (IntEn), and acknowledge bits (EvAck) */
402#define HFA384X_EV_TICK BIT(15)
403#define HFA384X_EV_WTERR BIT(14)
404#define HFA384X_EV_INFDROP BIT(13)
405#ifdef PRISM2_PCI
406#define HFA384X_EV_PCI_M1 BIT(9)
407#define HFA384X_EV_PCI_M0 BIT(8)
408#endif /* PRISM2_PCI */
409#define HFA384X_EV_INFO BIT(7)
410#define HFA384X_EV_DTIM BIT(5)
411#define HFA384X_EV_CMD BIT(4)
412#define HFA384X_EV_ALLOC BIT(3)
413#define HFA384X_EV_TXEXC BIT(2)
414#define HFA384X_EV_TX BIT(1)
415#define HFA384X_EV_RX BIT(0)
416
417
418/* HFA384X Information frames */
419#define HFA384X_INFO_HANDOVERADDR 0xF000 /* AP f/w ? */
420#define HFA384X_INFO_HANDOVERDEAUTHADDR 0xF001 /* AP f/w 1.3.7 */
421#define HFA384X_INFO_COMMTALLIES 0xF100
422#define HFA384X_INFO_SCANRESULTS 0xF101
423#define HFA384X_INFO_CHANNELINFORESULTS 0xF102 /* AP f/w only */
424#define HFA384X_INFO_HOSTSCANRESULTS 0xF103
425#define HFA384X_INFO_LINKSTATUS 0xF200
426#define HFA384X_INFO_ASSOCSTATUS 0xF201 /* ? */
427#define HFA384X_INFO_AUTHREQ 0xF202 /* ? */
428#define HFA384X_INFO_PSUSERCNT 0xF203 /* ? */
429#define HFA384X_INFO_KEYIDCHANGED 0xF204 /* ? */
430
431enum { HFA384X_LINKSTATUS_CONNECTED = 1,
432 HFA384X_LINKSTATUS_DISCONNECTED = 2,
433 HFA384X_LINKSTATUS_AP_CHANGE = 3,
434 HFA384X_LINKSTATUS_AP_OUT_OF_RANGE = 4,
435 HFA384X_LINKSTATUS_AP_IN_RANGE = 5,
436 HFA384X_LINKSTATUS_ASSOC_FAILED = 6 };
437
438enum { HFA384X_PORTTYPE_BSS = 1, HFA384X_PORTTYPE_WDS = 2,
439 HFA384X_PORTTYPE_PSEUDO_IBSS = 3, HFA384X_PORTTYPE_IBSS = 0,
440 HFA384X_PORTTYPE_HOSTAP = 6 };
441
442#define HFA384X_RATES_1MBPS BIT(0)
443#define HFA384X_RATES_2MBPS BIT(1)
444#define HFA384X_RATES_5MBPS BIT(2)
445#define HFA384X_RATES_11MBPS BIT(3)
446
447#define HFA384X_ROAMING_FIRMWARE 1
448#define HFA384X_ROAMING_HOST 2
449#define HFA384X_ROAMING_DISABLED 3
450
451#define HFA384X_WEPFLAGS_PRIVACYINVOKED BIT(0)
452#define HFA384X_WEPFLAGS_EXCLUDEUNENCRYPTED BIT(1)
453#define HFA384X_WEPFLAGS_HOSTENCRYPT BIT(4)
454#define HFA384X_WEPFLAGS_HOSTDECRYPT BIT(7)
455
456#define HFA384X_RX_STATUS_MSGTYPE (BIT(15) | BIT(14) | BIT(13))
457#define HFA384X_RX_STATUS_PCF BIT(12)
458#define HFA384X_RX_STATUS_MACPORT (BIT(10) | BIT(9) | BIT(8))
459#define HFA384X_RX_STATUS_UNDECR BIT(1)
460#define HFA384X_RX_STATUS_FCSERR BIT(0)
461
462#define HFA384X_RX_STATUS_GET_MSGTYPE(s) \
463(((s) & HFA384X_RX_STATUS_MSGTYPE) >> 13)
464#define HFA384X_RX_STATUS_GET_MACPORT(s) \
465(((s) & HFA384X_RX_STATUS_MACPORT) >> 8)
466
467enum { HFA384X_RX_MSGTYPE_NORMAL = 0, HFA384X_RX_MSGTYPE_RFC1042 = 1,
468 HFA384X_RX_MSGTYPE_BRIDGETUNNEL = 2, HFA384X_RX_MSGTYPE_MGMT = 4 };
469
470
471#define HFA384X_TX_CTRL_ALT_RTRY BIT(5)
472#define HFA384X_TX_CTRL_802_11 BIT(3)
473#define HFA384X_TX_CTRL_802_3 0
474#define HFA384X_TX_CTRL_TX_EX BIT(2)
475#define HFA384X_TX_CTRL_TX_OK BIT(1)
476
477#define HFA384X_TX_STATUS_RETRYERR BIT(0)
478#define HFA384X_TX_STATUS_AGEDERR BIT(1)
479#define HFA384X_TX_STATUS_DISCON BIT(2)
480#define HFA384X_TX_STATUS_FORMERR BIT(3)
481
482/* HFA3861/3863 (BBP) Control Registers */
483#define HFA386X_CR_TX_CONFIGURE 0x12 /* CR9 */
484#define HFA386X_CR_RX_CONFIGURE 0x14 /* CR10 */
485#define HFA386X_CR_A_D_TEST_MODES2 0x1A /* CR13 */
486#define HFA386X_CR_MANUAL_TX_POWER 0x3E /* CR31 */
487#define HFA386X_CR_MEASURED_TX_POWER 0x74 /* CR58 */
488
489
490#ifdef __KERNEL__
491
492#define PRISM2_TXFID_COUNT 8
493#define PRISM2_DATA_MAXLEN 2304
494#define PRISM2_TXFID_LEN (PRISM2_DATA_MAXLEN + sizeof(struct hfa384x_tx_frame))
495#define PRISM2_TXFID_EMPTY 0xffff
496#define PRISM2_TXFID_RESERVED 0xfffe
497#define PRISM2_DUMMY_FID 0xffff
498#define MAX_SSID_LEN 32
499#define MAX_NAME_LEN 32 /* this is assumed to be equal to MAX_SSID_LEN */
500
501#define PRISM2_DUMP_RX_HDR BIT(0)
502#define PRISM2_DUMP_TX_HDR BIT(1)
503#define PRISM2_DUMP_TXEXC_HDR BIT(2)
504
505struct hostap_tx_callback_info {
506 u16 idx;
507 void (*func)(struct sk_buff *, int ok, void *);
508 void *data;
509 struct hostap_tx_callback_info *next;
510};
511
512
513/* IEEE 802.11 requires that STA supports concurrent reception of at least
514 * three fragmented frames. This define can be increased to support more
515 * concurrent frames, but it should be noted that each entry can consume about
516 * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
517#define PRISM2_FRAG_CACHE_LEN 4
518
519struct prism2_frag_entry {
520 unsigned long first_frag_time;
521 unsigned int seq;
522 unsigned int last_frag;
523 struct sk_buff *skb;
524 u8 src_addr[ETH_ALEN];
525 u8 dst_addr[ETH_ALEN];
526};
527
528
529struct hostap_cmd_queue {
530 struct list_head list;
531 wait_queue_head_t compl;
532 volatile enum { CMD_SLEEP, CMD_CALLBACK, CMD_COMPLETED } type;
533 void (*callback)(struct net_device *dev, long context, u16 resp0,
534 u16 res);
535 long context;
536 u16 cmd, param0, param1;
537 u16 resp0, res;
538 volatile int issued, issuing;
539
540 atomic_t usecnt;
541 int del_req;
542};
543
544/* options for hw_shutdown */
545#define HOSTAP_HW_NO_DISABLE BIT(0)
546#define HOSTAP_HW_ENABLE_CMDCOMPL BIT(1)
547
548typedef struct local_info local_info_t;
549
550struct prism2_helper_functions {
551 /* these functions are defined in hardware model specific files
552 * (hostap_{cs,plx,pci}.c */
553 int (*card_present)(local_info_t *local);
554 void (*cor_sreset)(local_info_t *local);
555 int (*dev_open)(local_info_t *local);
556 int (*dev_close)(local_info_t *local);
557 void (*genesis_reset)(local_info_t *local, int hcr);
558
559 /* the following functions are from hostap_hw.c, but they may have some
560 * hardware model specific code */
561
562 /* FIX: low-level commands like cmd might disappear at some point to
563 * make it easier to change them if needed (e.g., cmd would be replaced
564 * with write_mif/read_mif/testcmd/inquire); at least get_rid and
565 * set_rid might move to hostap_{cs,plx,pci}.c */
566 int (*cmd)(struct net_device *dev, u16 cmd, u16 param0, u16 *param1,
567 u16 *resp0);
568 void (*read_regs)(struct net_device *dev, struct hfa384x_regs *regs);
569 int (*get_rid)(struct net_device *dev, u16 rid, void *buf, int len,
570 int exact_len);
571 int (*set_rid)(struct net_device *dev, u16 rid, void *buf, int len);
572 int (*hw_enable)(struct net_device *dev, int initial);
573 int (*hw_config)(struct net_device *dev, int initial);
574 void (*hw_reset)(struct net_device *dev);
575 void (*hw_shutdown)(struct net_device *dev, int no_disable);
576 int (*reset_port)(struct net_device *dev);
577 void (*schedule_reset)(local_info_t *local);
578 int (*download)(local_info_t *local,
579 struct prism2_download_param *param);
580 int (*tx)(struct sk_buff *skb, struct net_device *dev);
581 int (*set_tim)(struct net_device *dev, int aid, int set);
582 int (*read_aux)(struct net_device *dev, unsigned addr, int len,
583 u8 *buf);
584
585 int need_tx_headroom; /* number of bytes of headroom needed before
586 * IEEE 802.11 header */
587 enum { HOSTAP_HW_PCCARD, HOSTAP_HW_PLX, HOSTAP_HW_PCI } hw_type;
588};
589
590
591struct prism2_download_data {
592 u32 dl_cmd;
593 u32 start_addr;
594 u32 num_areas;
595 struct prism2_download_data_area {
596 u32 addr; /* wlan card address */
597 u32 len;
598 u8 *data; /* allocated data */
599 } data[0];
600};
601
602
603#define HOSTAP_MAX_BSS_COUNT 64
604#define MAX_WPA_IE_LEN 64
605
606struct hostap_bss_info {
607 struct list_head list;
608 unsigned long last_update;
609 unsigned int count;
610 u8 bssid[ETH_ALEN];
611 u16 capab_info;
612 u8 ssid[32];
613 size_t ssid_len;
614 u8 wpa_ie[MAX_WPA_IE_LEN];
615 size_t wpa_ie_len;
616 u8 rsn_ie[MAX_WPA_IE_LEN];
617 size_t rsn_ie_len;
618 int chan;
619 int included;
620};
621
622
623/* Per radio private Host AP data - shared by all net devices interfaces used
624 * by each radio (wlan#, wlan#ap, wlan#sta, WDS).
625 * ((struct hostap_interface *) netdev_priv(dev))->local points to this
626 * structure. */
627struct local_info {
628 struct module *hw_module;
629 int card_idx;
630 int dev_enabled;
631 int master_dev_auto_open; /* was master device opened automatically */
632 int num_dev_open; /* number of open devices */
633 struct net_device *dev; /* master radio device */
634 struct net_device *ddev; /* main data device */
635 struct list_head hostap_interfaces; /* Host AP interface list (contains
636 * struct hostap_interface entries)
637 */
638 rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock
639 * when removing entries from the list.
640 * TX and RX paths can use read lock. */
641 spinlock_t cmdlock, baplock, lock;
642 struct semaphore rid_bap_sem;
643 u16 infofid; /* MAC buffer id for info frame */
644 /* txfid, intransmitfid, next_txtid, and next_alloc are protected by
645 * txfidlock */
646 spinlock_t txfidlock;
647 int txfid_len; /* length of allocated TX buffers */
648 u16 txfid[PRISM2_TXFID_COUNT]; /* buffer IDs for TX frames */
649 /* buffer IDs for intransmit frames or PRISM2_TXFID_EMPTY if
650 * corresponding txfid is free for next TX frame */
651 u16 intransmitfid[PRISM2_TXFID_COUNT];
652 int next_txfid; /* index to the next txfid to be checked for
653 * availability */
654 int next_alloc; /* index to the next intransmitfid to be checked for
655 * allocation events */
656
657 /* bitfield for atomic bitops */
658#define HOSTAP_BITS_TRANSMIT 0
659#define HOSTAP_BITS_BAP_TASKLET 1
660#define HOSTAP_BITS_BAP_TASKLET2 2
661 long bits;
662
663 struct ap_data *ap;
664
665 char essid[MAX_SSID_LEN + 1];
666 char name[MAX_NAME_LEN + 1];
667 int name_set;
668 u16 channel_mask; /* mask of allowed channels */
669 u16 scan_channel_mask; /* mask of channels to be scanned */
670 struct comm_tallies_sums comm_tallies;
671 struct net_device_stats stats;
672 struct proc_dir_entry *proc;
673 int iw_mode; /* operating mode (IW_MODE_*) */
674 int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
675 * 1: IW_MODE_ADHOC is "pseudo IBSS" */
676 char bssid[ETH_ALEN];
677 int channel;
678 int beacon_int;
679 int dtim_period;
680 int mtu;
681 int frame_dump; /* dump RX/TX frame headers, PRISM2_DUMP_ flags */
682 int fw_tx_rate_control;
683 u16 tx_rate_control;
684 u16 basic_rates;
685 int hw_resetting;
686 int hw_ready;
687 int hw_reset_tries; /* how many times reset has been tried */
688 int hw_downloading;
689 int shutdown;
690 int pri_only;
691 int no_pri; /* no PRI f/w present */
692 int sram_type; /* 8 = x8 SRAM, 16 = x16 SRAM, -1 = unknown */
693
694 enum {
695 PRISM2_TXPOWER_AUTO = 0, PRISM2_TXPOWER_OFF,
696 PRISM2_TXPOWER_FIXED, PRISM2_TXPOWER_UNKNOWN
697 } txpower_type;
698 int txpower; /* if txpower_type == PRISM2_TXPOWER_FIXED */
699
700 /* command queue for hfa384x_cmd(); protected with cmdlock */
701 struct list_head cmd_queue;
702 /* max_len for cmd_queue; in addition, cmd_callback can use two
703 * additional entries to prevent sleeping commands from stopping
704 * transmits */
705#define HOSTAP_CMD_QUEUE_MAX_LEN 16
706 int cmd_queue_len; /* number of entries in cmd_queue */
707
708 /* if card timeout is detected in interrupt context, reset_queue is
709 * used to schedule card reseting to be done in user context */
710 struct work_struct reset_queue;
711
712 /* For scheduling a change of the promiscuous mode RID */
713 int is_promisc;
714 struct work_struct set_multicast_list_queue;
715
716 struct work_struct set_tim_queue;
717 struct list_head set_tim_list;
718 spinlock_t set_tim_lock;
719
720 int wds_max_connections;
721 int wds_connections;
722#define HOSTAP_WDS_BROADCAST_RA BIT(0)
723#define HOSTAP_WDS_AP_CLIENT BIT(1)
724#define HOSTAP_WDS_STANDARD_FRAME BIT(2)
725 u32 wds_type;
726 u16 tx_control; /* flags to be used in TX description */
727 int manual_retry_count; /* -1 = use f/w default; otherwise retry count
728 * to be used with all frames */
729
730 struct iw_statistics wstats;
731 unsigned long scan_timestamp; /* Time started to scan */
732 enum {
733 PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
734 PRISM2_MONITOR_CAPHDR = 2
735 } monitor_type;
736 int (*saved_eth_header_parse)(struct sk_buff *skb,
737 unsigned char *haddr);
738 int monitor_allow_fcserr;
739
740 int hostapd; /* whether user space daemon, hostapd, is used for AP
741 * management */
742 int hostapd_sta; /* whether hostapd is used with an extra STA interface
743 */
744 struct net_device *apdev;
745 struct net_device_stats apdevstats;
746
747 char assoc_ap_addr[ETH_ALEN];
748 struct net_device *stadev;
749 struct net_device_stats stadevstats;
750
751#define WEP_KEYS 4
752#define WEP_KEY_LEN 13
753 struct ieee80211_crypt_data *crypt[WEP_KEYS];
754 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
755 struct timer_list crypt_deinit_timer;
756 struct list_head crypt_deinit_list;
757
758 int open_wep; /* allow unencrypted frames */
759 int host_encrypt;
760 int host_decrypt;
761 int privacy_invoked; /* force privacy invoked flag even if no keys are
762 * configured */
763 int fw_encrypt_ok; /* whether firmware-based WEP encrypt is working
764 * in Host AP mode (STA f/w 1.4.9 or newer) */
765 int bcrx_sta_key; /* use individual keys to override default keys even
766 * with RX of broad/multicast frames */
767
768 struct prism2_frag_entry frag_cache[PRISM2_FRAG_CACHE_LEN];
769 unsigned int frag_next_idx;
770
771 int ieee_802_1x; /* is IEEE 802.1X used */
772
773 int antsel_tx, antsel_rx;
774 int rts_threshold; /* dot11RTSThreshold */
775 int fragm_threshold; /* dot11FragmentationThreshold */
776 int auth_algs; /* PRISM2_AUTH_ flags */
777
778 int enh_sec; /* cnfEnhSecurity options (broadcast SSID hide/ignore) */
779 int tallies32; /* 32-bit tallies in use */
780
781 struct prism2_helper_functions *func;
782
783 u8 *pda;
784 int fw_ap;
785#define PRISM2_FW_VER(major, minor, variant) \
786(((major) << 16) | ((minor) << 8) | variant)
787 u32 sta_fw_ver;
788
789 /* Tasklets for handling hardware IRQ related operations outside hw IRQ
790 * handler */
791 struct tasklet_struct bap_tasklet;
792
793 struct tasklet_struct info_tasklet;
794 struct sk_buff_head info_list; /* info frames as skb's for
795 * info_tasklet */
796
797 struct hostap_tx_callback_info *tx_callback; /* registered TX callbacks
798 */
799
800 struct tasklet_struct rx_tasklet;
801 struct sk_buff_head rx_list;
802
803 struct tasklet_struct sta_tx_exc_tasklet;
804 struct sk_buff_head sta_tx_exc_list;
805
806 int host_roaming;
807 unsigned long last_join_time; /* time of last JoinRequest */
808 struct hfa384x_hostscan_result *last_scan_results;
809 int last_scan_results_count;
810 enum { PRISM2_SCAN, PRISM2_HOSTSCAN } last_scan_type;
811 struct work_struct info_queue;
812 long pending_info; /* bit field of pending info_queue items */
813#define PRISM2_INFO_PENDING_LINKSTATUS 0
814#define PRISM2_INFO_PENDING_SCANRESULTS 1
815 int prev_link_status; /* previous received LinkStatus info */
816 int prev_linkstatus_connected;
817 u8 preferred_ap[6]; /* use this AP if possible */
818
819#ifdef PRISM2_CALLBACK
820 void *callback_data; /* Can be used in callbacks; e.g., allocate
821 * on enable event and free on disable event.
822 * Host AP driver code does not touch this. */
823#endif /* PRISM2_CALLBACK */
824
825 wait_queue_head_t hostscan_wq;
826
827 /* Passive scan in Host AP mode */
828 struct timer_list passive_scan_timer;
829 int passive_scan_interval; /* in seconds, 0 = disabled */
830 int passive_scan_channel;
831 enum { PASSIVE_SCAN_WAIT, PASSIVE_SCAN_LISTEN } passive_scan_state;
832
833 struct timer_list tick_timer;
834 unsigned long last_tick_timer;
835 unsigned int sw_tick_stuck;
836
837 /* commsQuality / dBmCommsQuality data from periodic polling; only
838 * valid for Managed and Ad-hoc modes */
839 unsigned long last_comms_qual_update;
840 int comms_qual; /* in some odd unit.. */
841 int avg_signal; /* in dB (note: negative) */
842 int avg_noise; /* in dB (note: negative) */
843 struct work_struct comms_qual_update;
844
845 /* RSSI to dBm adjustment (for RX descriptor fields) */
846 int rssi_to_dBm; /* substract from RSSI to get approximate dBm value */
847
848 /* BSS list / protected by local->lock */
849 struct list_head bss_list;
850 int num_bss_info;
851 int wpa; /* WPA support enabled */
852 int tkip_countermeasures;
853 int drop_unencrypted;
854 /* Generic IEEE 802.11 info element to be added to
855 * ProbeResp/Beacon/(Re)AssocReq */
856 u8 *generic_elem;
857 size_t generic_elem_len;
858
859#ifdef PRISM2_DOWNLOAD_SUPPORT
860 /* Persistent volatile download data */
861 struct prism2_download_data *dl_pri;
862 struct prism2_download_data *dl_sec;
863#endif /* PRISM2_DOWNLOAD_SUPPORT */
864
865#ifdef PRISM2_IO_DEBUG
866#define PRISM2_IO_DEBUG_SIZE 10000
867 u32 io_debug[PRISM2_IO_DEBUG_SIZE];
868 int io_debug_head;
869 int io_debug_enabled;
870#endif /* PRISM2_IO_DEBUG */
871
872 /* Pointer to hardware model specific (cs,pci,plx) private data. */
873 void *hw_priv;
874};
875
876
877/* Per interface private Host AP data
878 * Allocated for each net device that Host AP uses (wlan#, wlan#ap, wlan#sta,
879 * WDS) and netdev_priv(dev) points to this structure. */
880struct hostap_interface {
881 struct list_head list; /* list entry in Host AP interface list */
882 struct net_device *dev; /* pointer to this device */
883 struct local_info *local; /* pointer to shared private data */
884 struct net_device_stats stats;
885 struct iw_spy_data spy_data; /* iwspy support */
886 struct iw_public_data wireless_data;
887
888 enum {
889 HOSTAP_INTERFACE_MASTER,
890 HOSTAP_INTERFACE_MAIN,
891 HOSTAP_INTERFACE_AP,
892 HOSTAP_INTERFACE_STA,
893 HOSTAP_INTERFACE_WDS,
894 } type;
895
896 union {
897 struct hostap_interface_wds {
898 u8 remote_addr[ETH_ALEN];
899 } wds;
900 } u;
901};
902
903
904#define HOSTAP_SKB_TX_DATA_MAGIC 0xf08a36a2
905
906/*
907 * TX meta data - stored in skb->cb buffer, so this must not be increased over
908 * the 40-byte limit
909 */
910struct hostap_skb_tx_data {
911 u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */
912 u8 rate; /* transmit rate */
913#define HOSTAP_TX_FLAGS_WDS BIT(0)
914#define HOSTAP_TX_FLAGS_BUFFERED_FRAME BIT(1)
915#define HOSTAP_TX_FLAGS_ADD_MOREDATA BIT(2)
916 u8 flags; /* HOSTAP_TX_FLAGS_* */
917 u16 tx_cb_idx;
918 struct hostap_interface *iface;
919 unsigned long jiffies; /* queueing timestamp */
920 unsigned short ethertype;
921};
922
923
924#ifndef PRISM2_NO_DEBUG
925
926#define DEBUG_FID BIT(0)
927#define DEBUG_PS BIT(1)
928#define DEBUG_FLOW BIT(2)
929#define DEBUG_AP BIT(3)
930#define DEBUG_HW BIT(4)
931#define DEBUG_EXTRA BIT(5)
932#define DEBUG_EXTRA2 BIT(6)
933#define DEBUG_PS2 BIT(7)
934#define DEBUG_MASK (DEBUG_PS | DEBUG_AP | DEBUG_HW | DEBUG_EXTRA)
935#define PDEBUG(n, args...) \
936do { if ((n) & DEBUG_MASK) printk(KERN_DEBUG args); } while (0)
937#define PDEBUG2(n, args...) \
938do { if ((n) & DEBUG_MASK) printk(args); } while (0)
939
940#else /* PRISM2_NO_DEBUG */
941
942#define PDEBUG(n, args...)
943#define PDEBUG2(n, args...)
944
945#endif /* PRISM2_NO_DEBUG */
946
947enum { BAP0 = 0, BAP1 = 1 };
948
949#define PRISM2_IO_DEBUG_CMD_INB 0
950#define PRISM2_IO_DEBUG_CMD_INW 1
951#define PRISM2_IO_DEBUG_CMD_INSW 2
952#define PRISM2_IO_DEBUG_CMD_OUTB 3
953#define PRISM2_IO_DEBUG_CMD_OUTW 4
954#define PRISM2_IO_DEBUG_CMD_OUTSW 5
955#define PRISM2_IO_DEBUG_CMD_ERROR 6
956#define PRISM2_IO_DEBUG_CMD_INTERRUPT 7
957
958#ifdef PRISM2_IO_DEBUG
959
960#define PRISM2_IO_DEBUG_ENTRY(cmd, reg, value) \
961(((cmd) << 24) | ((reg) << 16) | value)
962
963static inline void prism2_io_debug_add(struct net_device *dev, int cmd,
964 int reg, int value)
965{
966 struct hostap_interface *iface = netdev_priv(dev);
967 local_info_t *local = iface->local;
968
969 if (!local->io_debug_enabled)
970 return;
971
972 local->io_debug[local->io_debug_head] = jiffies & 0xffffffff;
973 if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
974 local->io_debug_head = 0;
975 local->io_debug[local->io_debug_head] =
976 PRISM2_IO_DEBUG_ENTRY(cmd, reg, value);
977 if (++local->io_debug_head >= PRISM2_IO_DEBUG_SIZE)
978 local->io_debug_head = 0;
979}
980
981
982static inline void prism2_io_debug_error(struct net_device *dev, int err)
983{
984 struct hostap_interface *iface = netdev_priv(dev);
985 local_info_t *local = iface->local;
986 unsigned long flags;
987
988 if (!local->io_debug_enabled)
989 return;
990
991 spin_lock_irqsave(&local->lock, flags);
992 prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_ERROR, 0, err);
993 if (local->io_debug_enabled == 1) {
994 local->io_debug_enabled = 0;
995 printk(KERN_DEBUG "%s: I/O debug stopped\n", dev->name);
996 }
997 spin_unlock_irqrestore(&local->lock, flags);
998}
999
1000#else /* PRISM2_IO_DEBUG */
1001
1002static inline void prism2_io_debug_add(struct net_device *dev, int cmd,
1003 int reg, int value)
1004{
1005}
1006
1007static inline void prism2_io_debug_error(struct net_device *dev, int err)
1008{
1009}
1010
1011#endif /* PRISM2_IO_DEBUG */
1012
1013
1014#ifdef PRISM2_CALLBACK
1015enum {
1016 /* Called when card is enabled */
1017 PRISM2_CALLBACK_ENABLE,
1018
1019 /* Called when card is disabled */
1020 PRISM2_CALLBACK_DISABLE,
1021
1022 /* Called when RX/TX starts/ends */
1023 PRISM2_CALLBACK_RX_START, PRISM2_CALLBACK_RX_END,
1024 PRISM2_CALLBACK_TX_START, PRISM2_CALLBACK_TX_END
1025};
1026void prism2_callback(local_info_t *local, int event);
1027#else /* PRISM2_CALLBACK */
1028#define prism2_callback(d, e) do { } while (0)
1029#endif /* PRISM2_CALLBACK */
1030
1031#endif /* __KERNEL__ */
1032
1033#endif /* HOSTAP_WLAN_H */