aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPavel Roskin <proski@gnu.org>2008-10-13 17:33:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-13 17:33:13 -0400
commit99e06e372378c5833a0c60274b645dfb2e4a4b08 (patch)
tree2c79260e0308f26649d06b388a91f7366663c46f /drivers
parent86f69fe9c069dd8608d238581eea259caa1dfc99 (diff)
staging: at76_usb wireless driver
Add the at76_usb wireless driver to the staging tree while the other kernel driver (out of tree) gets rewritten to use the internal wireless stack. This patch comes directly from the Fedora kernel tree, with only the directory placement of the files changed. Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/at76_usb/Kconfig8
-rw-r--r--drivers/staging/at76_usb/Makefile1
-rw-r--r--drivers/staging/at76_usb/TODO2
-rw-r--r--drivers/staging/at76_usb/at76_usb.c5559
-rw-r--r--drivers/staging/at76_usb/at76_usb.h619
7 files changed, 6192 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 25338b7eac98..2a79decd7dfc 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -41,4 +41,6 @@ source "drivers/staging/wlan-ng/Kconfig"
41 41
42source "drivers/staging/echo/Kconfig" 42source "drivers/staging/echo/Kconfig"
43 43
44source "drivers/staging/at76_usb/Kconfig"
45
44endif # STAGING 46endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 7c466e94fd93..325bca4f71c0 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_USB_IP_COMMON) += usbip/
12obj-$(CONFIG_W35UND) += winbond/ 12obj-$(CONFIG_W35UND) += winbond/
13obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 13obj-$(CONFIG_PRISM2_USB) += wlan-ng/
14obj-$(CONFIG_ECHO) += echo/ 14obj-$(CONFIG_ECHO) += echo/
15obj-$(CONFIG_USB_ATMEL) += at76_usb/
diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig
new file mode 100644
index 000000000000..8606f9621624
--- /dev/null
+++ b/drivers/staging/at76_usb/Kconfig
@@ -0,0 +1,8 @@
1config USB_ATMEL
2 tristate "Atmel at76c503/at76c505/at76c505a USB cards"
3 depends on WLAN_80211 && USB
4 default N
5 select FW_LOADER
6 ---help---
7 Enable support for USB Wireless devices using Atmel at76c503,
8 at76c505 or at76c505a chips.
diff --git a/drivers/staging/at76_usb/Makefile b/drivers/staging/at76_usb/Makefile
new file mode 100644
index 000000000000..6a47e8872309
--- /dev/null
+++ b/drivers/staging/at76_usb/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_USB_ATMEL) += at76_usb.o
diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO
new file mode 100644
index 000000000000..6911ca71a41a
--- /dev/null
+++ b/drivers/staging/at76_usb/TODO
@@ -0,0 +1,2 @@
1rewrite the driver to use the proper in-kernel wireless stack
2instead of using its own.
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
new file mode 100644
index 000000000000..52df0c665183
--- /dev/null
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -0,0 +1,5559 @@
1/*
2 * at76c503/at76c505 USB driver
3 *
4 * Copyright (c) 2002 - 2003 Oliver Kurth
5 * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
6 * Copyright (c) 2004 Nick Jones
7 * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
8 * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This file is part of the Berlios driver for WLAN USB devices based on the
16 * Atmel AT76C503A/505/505A.
17 *
18 * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
19 */
20
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/errno.h>
25#include <linux/slab.h>
26#include <linux/module.h>
27#include <linux/spinlock.h>
28#include <linux/list.h>
29#include <linux/usb.h>
30#include <linux/netdevice.h>
31#include <linux/if_arp.h>
32#include <linux/etherdevice.h>
33#include <linux/ethtool.h>
34#include <linux/wireless.h>
35#include <net/iw_handler.h>
36#include <net/ieee80211_radiotap.h>
37#include <linux/firmware.h>
38#include <linux/leds.h>
39#include <net/ieee80211.h>
40
41#include "at76_usb.h"
42
43/* Version information */
44#define DRIVER_NAME "at76_usb"
45#define DRIVER_VERSION "0.17"
46#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
47
48/* at76_debug bits */
49#define DBG_PROGRESS 0x00000001 /* authentication/accociation */
50#define DBG_BSS_TABLE 0x00000002 /* show BSS table after scans */
51#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */
52#define DBG_MAC_STATE 0x00000008 /* MAC state transitions */
53#define DBG_TX_DATA 0x00000010 /* tx header */
54#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */
55#define DBG_TX_MGMT 0x00000040 /* tx management */
56#define DBG_RX_DATA 0x00000080 /* rx data header */
57#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */
58#define DBG_RX_MGMT 0x00000200 /* rx mgmt frame headers */
59#define DBG_RX_BEACON 0x00000400 /* rx beacon */
60#define DBG_RX_CTRL 0x00000800 /* rx control */
61#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */
62#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */
63#define DBG_DEVSTART 0x00004000 /* fw download, device start */
64#define DBG_URB 0x00008000 /* rx urb status, ... */
65#define DBG_RX_ATMEL_HDR 0x00010000 /* Atmel-specific Rx headers */
66#define DBG_PROC_ENTRY 0x00020000 /* procedure entries/exits */
67#define DBG_PM 0x00040000 /* power management settings */
68#define DBG_BSS_MATCH 0x00080000 /* BSS match failures */
69#define DBG_PARAMS 0x00100000 /* show configured parameters */
70#define DBG_WAIT_COMPLETE 0x00200000 /* command completion */
71#define DBG_RX_FRAGS_SKB 0x00400000 /* skb header of Rx fragments */
72#define DBG_BSS_TABLE_RM 0x00800000 /* purging bss table entries */
73#define DBG_MONITOR_MODE 0x01000000 /* monitor mode */
74#define DBG_MIB 0x02000000 /* dump all MIBs on startup */
75#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */
76#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
77#define DBG_FW 0x10000000 /* firmware download */
78#define DBG_DFU 0x20000000 /* device firmware upgrade */
79
80#define DBG_DEFAULTS 0
81
82/* Use our own dbg macro */
83#define at76_dbg(bits, format, arg...) \
84 do { \
85 if (at76_debug & (bits)) \
86 printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
87 } while (0)
88
89static int at76_debug = DBG_DEFAULTS;
90
91/* Protect against concurrent firmware loading and parsing */
92static struct mutex fw_mutex;
93
94static struct fwentry firmwares[] = {
95 [0] = {""},
96 [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"},
97 [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"},
98 [BOARD_503] = {"atmel_at76c503-rfmd.bin"},
99 [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"},
100 [BOARD_505] = {"atmel_at76c505-rfmd.bin"},
101 [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"},
102 [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"},
103 [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"},
104};
105
106#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
107
108static struct usb_device_id dev_table[] = {
109 /*
110 * at76c503-i3861
111 */
112 /* Generic AT76C503/3861 device */
113 {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
114 /* Linksys WUSB11 v2.1/v2.6 */
115 {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
116 /* Netgear MA101 rev. A */
117 {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
118 /* Tekram U300C / Allnet ALL0193 */
119 {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
120 /* HP HN210W J7801A */
121 {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
122 /* Sitecom/Z-Com/Zyxel M4Y-750 */
123 {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
124 /* Dynalink/Askey WLL013 (intersil) */
125 {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
126 /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
127 {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
128 /* BenQ AWL300 */
129 {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
130 /* Addtron AWU-120, Compex WLU11 */
131 {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
132 /* Intel AP310 AnyPoint II USB */
133 {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
134 /* Dynalink L11U */
135 {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
136 /* Arescom WL-210, FCC id 07J-GL2411USB */
137 {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
138 /* I-O DATA WN-B11/USB */
139 {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
140 /* BT Voyager 1010 */
141 {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
142 /*
143 * at76c503-i3863
144 */
145 /* Generic AT76C503/3863 device */
146 {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
147 /* Samsung SWL-2100U */
148 {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
149 /*
150 * at76c503-rfmd
151 */
152 /* Generic AT76C503/RFMD device */
153 {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
154 /* Dynalink/Askey WLL013 (rfmd) */
155 {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
156 /* Linksys WUSB11 v2.6 */
157 {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
158 /* Network Everywhere NWU11B */
159 {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
160 /* Netgear MA101 rev. B */
161 {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
162 /* D-Link DWL-120 rev. E */
163 {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
164 /* Actiontec 802UAT1, HWU01150-01UK */
165 {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
166 /* AirVast W-Buddie WN210 */
167 {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
168 /* Dick Smith Electronics XH1153 802.11b USB adapter */
169 {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
170 /* CNet CNUSB611 */
171 {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
172 /* FiberLine FL-WL200U */
173 {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
174 /* BenQ AWL400 USB stick */
175 {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
176 /* 3Com 3CRSHEW696 */
177 {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
178 /* Siemens Santis ADSL WLAN USB adapter WLL 013 */
179 {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
180 /* Belkin F5D6050, version 2 */
181 {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
182 /* iBlitzz, BWU613 (not *B or *SB) */
183 {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
184 /* Gigabyte GN-WLBM101 */
185 {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
186 /* Planex GW-US11S */
187 {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
188 /* Internal WLAN adapter in h5[4,5]xx series iPAQs */
189 {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
190 /* Corega Wireless LAN USB-11 mini */
191 {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
192 /* Corega Wireless LAN USB-11 mini2 */
193 {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
194 /* Uniden PCW100 */
195 {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
196 /*
197 * at76c503-rfmd-acc
198 */
199 /* SMC2664W */
200 {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
201 /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
202 {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
203 /*
204 * at76c505-rfmd
205 */
206 /* Generic AT76C505/RFMD */
207 {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
208 /*
209 * at76c505-rfmd2958
210 */
211 /* Generic AT76C505/RFMD, OvisLink WL-1130USB */
212 {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
213 /* Fiberline FL-WL240U */
214 {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
215 /* CNet CNUSB-611G */
216 {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
217 /* Linksys WUSB11 v2.8 */
218 {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
219 /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
220 {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
221 /* Corega WLAN USB Stick 11 */
222 {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
223 /* Microstar MSI Box MS6978 */
224 {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
225 /*
226 * at76c505a-rfmd2958
227 */
228 /* Generic AT76C505A device */
229 {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
230 /* Generic AT76C505AS device */
231 {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
232 /* Siemens Gigaset USB WLAN Adapter 11 */
233 {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
234 /*
235 * at76c505amx-rfmd
236 */
237 /* Generic AT76C505AMX device */
238 {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
239 {}
240};
241
242MODULE_DEVICE_TABLE(usb, dev_table);
243
244/* Supported rates of this hardware, bit 7 marks basic rates */
245static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
246
247/* Frequency of each channel in MHz */
248static const long channel_frequency[] = {
249 2412, 2417, 2422, 2427, 2432, 2437, 2442,
250 2447, 2452, 2457, 2462, 2467, 2472, 2484
251};
252
253#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
254
255static const char *const preambles[] = { "long", "short", "auto" };
256
257static const char *const mac_states[] = {
258 [MAC_INIT] = "INIT",
259 [MAC_SCANNING] = "SCANNING",
260 [MAC_AUTH] = "AUTH",
261 [MAC_ASSOC] = "ASSOC",
262 [MAC_JOINING] = "JOINING",
263 [MAC_CONNECTED] = "CONNECTED",
264 [MAC_OWN_IBSS] = "OWN_IBSS"
265};
266
267/* Firmware download */
268/* DFU states */
269#define STATE_IDLE 0x00
270#define STATE_DETACH 0x01
271#define STATE_DFU_IDLE 0x02
272#define STATE_DFU_DOWNLOAD_SYNC 0x03
273#define STATE_DFU_DOWNLOAD_BUSY 0x04
274#define STATE_DFU_DOWNLOAD_IDLE 0x05
275#define STATE_DFU_MANIFEST_SYNC 0x06
276#define STATE_DFU_MANIFEST 0x07
277#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
278#define STATE_DFU_UPLOAD_IDLE 0x09
279#define STATE_DFU_ERROR 0x0a
280
281/* DFU commands */
282#define DFU_DETACH 0
283#define DFU_DNLOAD 1
284#define DFU_UPLOAD 2
285#define DFU_GETSTATUS 3
286#define DFU_CLRSTATUS 4
287#define DFU_GETSTATE 5
288#define DFU_ABORT 6
289
290#define FW_BLOCK_SIZE 1024
291
292struct dfu_status {
293 unsigned char status;
294 unsigned char poll_timeout[3];
295 unsigned char state;
296 unsigned char string;
297} __attribute__((packed));
298
299static inline int at76_is_intersil(enum board_type board)
300{
301 return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
302}
303
304static inline int at76_is_503rfmd(enum board_type board)
305{
306 return (board == BOARD_503 || board == BOARD_503_ACC);
307}
308
309static inline int at76_is_505a(enum board_type board)
310{
311 return (board == BOARD_505A || board == BOARD_505AMX);
312}
313
314/* Load a block of the first (internal) part of the firmware */
315static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
316 void *block, int size)
317{
318 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
319 USB_TYPE_CLASS | USB_DIR_OUT |
320 USB_RECIP_INTERFACE, blockno, 0, block, size,
321 USB_CTRL_GET_TIMEOUT);
322}
323
324static int at76_dfu_get_status(struct usb_device *udev,
325 struct dfu_status *status)
326{
327 int ret;
328
329 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
330 USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
331 0, 0, status, sizeof(struct dfu_status),
332 USB_CTRL_GET_TIMEOUT);
333 return ret;
334}
335
336static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
337{
338 int ret;
339
340 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
341 USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
342 0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
343 return ret;
344}
345
346/* Convert timeout from the DFU status to jiffies */
347static inline unsigned long at76_get_timeout(struct dfu_status *s)
348{
349 return msecs_to_jiffies((s->poll_timeout[2] << 16)
350 | (s->poll_timeout[1] << 8)
351 | (s->poll_timeout[0]));
352}
353
354/* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use
355 * its value in jiffies in the MANIFEST_SYNC state. */
356static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
357 int manifest_sync_timeout)
358{
359 u8 *block;
360 struct dfu_status dfu_stat_buf;
361 int ret = 0;
362 int need_dfu_state = 1;
363 int is_done = 0;
364 u8 dfu_state = 0;
365 u32 dfu_timeout = 0;
366 int bsize = 0;
367 int blockno = 0;
368
369 at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
370 manifest_sync_timeout);
371
372 if (!size) {
373 dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
374 return -EINVAL;
375 }
376
377 block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
378 if (!block)
379 return -ENOMEM;
380
381 do {
382 if (need_dfu_state) {
383 ret = at76_dfu_get_state(udev, &dfu_state);
384 if (ret < 0) {
385 dev_printk(KERN_ERR, &udev->dev,
386 "cannot get DFU state: %d\n", ret);
387 goto exit;
388 }
389 need_dfu_state = 0;
390 }
391
392 switch (dfu_state) {
393 case STATE_DFU_DOWNLOAD_SYNC:
394 at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
395 ret = at76_dfu_get_status(udev, &dfu_stat_buf);
396 if (ret >= 0) {
397 dfu_state = dfu_stat_buf.state;
398 dfu_timeout = at76_get_timeout(&dfu_stat_buf);
399 need_dfu_state = 0;
400 } else
401 dev_printk(KERN_ERR, &udev->dev,
402 "at76_dfu_get_status returned %d\n",
403 ret);
404 break;
405
406 case STATE_DFU_DOWNLOAD_BUSY:
407 at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
408 need_dfu_state = 1;
409
410 at76_dbg(DBG_DFU, "DFU: Resetting device");
411 schedule_timeout_interruptible(dfu_timeout);
412 break;
413
414 case STATE_DFU_DOWNLOAD_IDLE:
415 at76_dbg(DBG_DFU, "DOWNLOAD...");
416 /* fall through */
417 case STATE_DFU_IDLE:
418 at76_dbg(DBG_DFU, "DFU IDLE");
419
420 bsize = min_t(int, size, FW_BLOCK_SIZE);
421 memcpy(block, buf, bsize);
422 at76_dbg(DBG_DFU, "int fw, size left = %5d, "
423 "bsize = %4d, blockno = %2d", size, bsize,
424 blockno);
425 ret =
426 at76_load_int_fw_block(udev, blockno, block, bsize);
427 buf += bsize;
428 size -= bsize;
429 blockno++;
430
431 if (ret != bsize)
432 dev_printk(KERN_ERR, &udev->dev,
433 "at76_load_int_fw_block "
434 "returned %d\n", ret);
435 need_dfu_state = 1;
436 break;
437
438 case STATE_DFU_MANIFEST_SYNC:
439 at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
440
441 ret = at76_dfu_get_status(udev, &dfu_stat_buf);
442 if (ret < 0)
443 break;
444
445 dfu_state = dfu_stat_buf.state;
446 dfu_timeout = at76_get_timeout(&dfu_stat_buf);
447 need_dfu_state = 0;
448
449 /* override the timeout from the status response,
450 needed for AT76C505A */
451 if (manifest_sync_timeout > 0)
452 dfu_timeout = manifest_sync_timeout;
453
454 at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
455 schedule_timeout_interruptible(dfu_timeout);
456 break;
457
458 case STATE_DFU_MANIFEST:
459 at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
460 is_done = 1;
461 break;
462
463 case STATE_DFU_MANIFEST_WAIT_RESET:
464 at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
465 is_done = 1;
466 break;
467
468 case STATE_DFU_UPLOAD_IDLE:
469 at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
470 break;
471
472 case STATE_DFU_ERROR:
473 at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
474 ret = -EPIPE;
475 break;
476
477 default:
478 at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
479 ret = -EINVAL;
480 break;
481 }
482 } while (!is_done && (ret >= 0));
483
484exit:
485 kfree(block);
486 if (ret >= 0)
487 ret = 0;
488
489 return ret;
490}
491
492/* Report that the scan results are ready */
493static inline void at76_iwevent_scan_complete(struct net_device *netdev)
494{
495 union iwreq_data wrqu;
496 wrqu.data.length = 0;
497 wrqu.data.flags = 0;
498 wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
499 at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
500}
501
502static inline void at76_iwevent_bss_connect(struct net_device *netdev,
503 u8 *bssid)
504{
505 union iwreq_data wrqu;
506 wrqu.data.length = 0;
507 wrqu.data.flags = 0;
508 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
509 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
510 wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
511 at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
512 __func__);
513}
514
515static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
516{
517 union iwreq_data wrqu;
518 wrqu.data.length = 0;
519 wrqu.data.flags = 0;
520 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
521 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
522 wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
523 at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
524 __func__);
525}
526
527#define HEX2STR_BUFFERS 4
528#define HEX2STR_MAX_LEN 64
529#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
530
531/* Convert binary data into hex string */
532static char *hex2str(void *buf, int len)
533{
534 static atomic_t a = ATOMIC_INIT(0);
535 static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
536 char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
537 char *obuf = ret;
538 u8 *ibuf = buf;
539
540 if (len > HEX2STR_MAX_LEN)
541 len = HEX2STR_MAX_LEN;
542
543 if (len <= 0) {
544 ret[0] = '\0';
545 return ret;
546 }
547
548 while (len--) {
549 *obuf++ = BIN2HEX(*ibuf >> 4);
550 *obuf++ = BIN2HEX(*ibuf & 0xf);
551 *obuf++ = '-';
552 ibuf++;
553 }
554 *(--obuf) = '\0';
555
556 return ret;
557}
558
559#define MAC2STR_BUFFERS 4
560
561static inline char *mac2str(u8 *mac)
562{
563 static atomic_t a = ATOMIC_INIT(0);
564 static char bufs[MAC2STR_BUFFERS][6 * 3];
565 char *str;
566
567 str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
568 sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
569 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
570 return str;
571}
572
573/* LED trigger */
574static int tx_activity;
575static void at76_ledtrig_tx_timerfunc(unsigned long data);
576static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
577DEFINE_LED_TRIGGER(ledtrig_tx);
578
579static void at76_ledtrig_tx_timerfunc(unsigned long data)
580{
581 static int tx_lastactivity;
582
583 if (tx_lastactivity != tx_activity) {
584 tx_lastactivity = tx_activity;
585 led_trigger_event(ledtrig_tx, LED_FULL);
586 mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
587 } else
588 led_trigger_event(ledtrig_tx, LED_OFF);
589}
590
591static void at76_ledtrig_tx_activity(void)
592{
593 tx_activity++;
594 if (!timer_pending(&ledtrig_tx_timer))
595 mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
596}
597
598/* Check if the given ssid is hidden */
599static inline int at76_is_hidden_ssid(u8 *ssid, int length)
600{
601 static const u8 zeros[32];
602
603 if (length == 0)
604 return 1;
605
606 if (length == 1 && ssid[0] == ' ')
607 return 1;
608
609 return (memcmp(ssid, zeros, length) == 0);
610}
611
612static inline void at76_free_bss_list(struct at76_priv *priv)
613{
614 struct list_head *next, *ptr;
615 unsigned long flags;
616
617 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
618
619 priv->curr_bss = NULL;
620
621 list_for_each_safe(ptr, next, &priv->bss_list) {
622 list_del(ptr);
623 kfree(list_entry(ptr, struct bss_info, list));
624 }
625
626 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
627}
628
629static int at76_remap(struct usb_device *udev)
630{
631 int ret;
632 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
633 USB_TYPE_VENDOR | USB_DIR_OUT |
634 USB_RECIP_INTERFACE, 0, 0, NULL, 0,
635 USB_CTRL_GET_TIMEOUT);
636 if (ret < 0)
637 return ret;
638 return 0;
639}
640
641static int at76_get_op_mode(struct usb_device *udev)
642{
643 int ret;
644 u8 op_mode;
645
646 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
647 USB_TYPE_VENDOR | USB_DIR_IN |
648 USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
649 USB_CTRL_GET_TIMEOUT);
650 if (ret < 0)
651 return ret;
652 else if (ret < 1)
653 return -EIO;
654 else
655 return op_mode;
656}
657
658/* Load a block of the second ("external") part of the firmware */
659static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
660 void *block, int size)
661{
662 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
663 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
664 0x0802, blockno, block, size,
665 USB_CTRL_GET_TIMEOUT);
666}
667
668static inline int at76_get_hw_cfg(struct usb_device *udev,
669 union at76_hwcfg *buf, int buf_size)
670{
671 return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
672 USB_TYPE_VENDOR | USB_DIR_IN |
673 USB_RECIP_INTERFACE, 0x0a02, 0,
674 buf, buf_size, USB_CTRL_GET_TIMEOUT);
675}
676
677/* Intersil boards use a different "value" for GetHWConfig requests */
678static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
679 union at76_hwcfg *buf, int buf_size)
680{
681 return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
682 USB_TYPE_VENDOR | USB_DIR_IN |
683 USB_RECIP_INTERFACE, 0x0902, 0,
684 buf, buf_size, USB_CTRL_GET_TIMEOUT);
685}
686
687/* Get the hardware configuration for the adapter and put it to the appropriate
688 * fields of 'priv' (the GetHWConfig request and interpretation of the result
689 * depends on the board type) */
690static int at76_get_hw_config(struct at76_priv *priv)
691{
692 int ret;
693 union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
694
695 if (!hwcfg)
696 return -ENOMEM;
697
698 if (at76_is_intersil(priv->board_type)) {
699 ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
700 sizeof(hwcfg->i));
701 if (ret < 0)
702 goto exit;
703 memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
704 priv->regulatory_domain = hwcfg->i.regulatory_domain;
705 } else if (at76_is_503rfmd(priv->board_type)) {
706 ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
707 if (ret < 0)
708 goto exit;
709 memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
710 priv->regulatory_domain = hwcfg->r3.regulatory_domain;
711 } else {
712 ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
713 if (ret < 0)
714 goto exit;
715 memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
716 priv->regulatory_domain = hwcfg->r5.regulatory_domain;
717 }
718
719exit:
720 kfree(hwcfg);
721 if (ret < 0)
722 printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
723 priv->netdev->name, ret);
724
725 return ret;
726}
727
728static struct reg_domain const *at76_get_reg_domain(u16 code)
729{
730 int i;
731 static struct reg_domain const fd_tab[] = {
732 {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */
733 {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
734 {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */
735 {0x31, "Spain", 0x600}, /* ch 10-11 */
736 {0x32, "France", 0x1e00}, /* ch 10-13 */
737 {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
738 {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
739 {0x50, "Israel", 0x3fc}, /* ch 3-9 */
740 {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */
741 };
742
743 /* Last entry is fallback for unknown domain code */
744 for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
745 if (code == fd_tab[i].code)
746 break;
747
748 return &fd_tab[i];
749}
750
751static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
752 int buf_size)
753{
754 int ret;
755
756 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
757 USB_TYPE_VENDOR | USB_DIR_IN |
758 USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
759 USB_CTRL_GET_TIMEOUT);
760 if (ret >= 0 && ret != buf_size)
761 return -EIO;
762 return ret;
763}
764
765/* Return positive number for status, negative for an error */
766static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
767{
768 u8 stat_buf[40];
769 int ret;
770
771 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
772 USB_TYPE_VENDOR | USB_DIR_IN |
773 USB_RECIP_INTERFACE, cmd, 0, stat_buf,
774 sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
775 if (ret < 0)
776 return ret;
777
778 return stat_buf[5];
779}
780
781static int at76_set_card_command(struct usb_device *udev, int cmd, void *buf,
782 int buf_size)
783{
784 int ret;
785 struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
786 buf_size, GFP_KERNEL);
787
788 if (!cmd_buf)
789 return -ENOMEM;
790
791 cmd_buf->cmd = cmd;
792 cmd_buf->reserved = 0;
793 cmd_buf->size = cpu_to_le16(buf_size);
794 memcpy(cmd_buf->data, buf, buf_size);
795
796 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
797 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
798 0, 0, cmd_buf,
799 sizeof(struct at76_command) + buf_size,
800 USB_CTRL_GET_TIMEOUT);
801 kfree(cmd_buf);
802 return ret;
803}
804
805#define MAKE_CMD_STATUS_CASE(c) case (c): return #c
806static const char *at76_get_cmd_status_string(u8 cmd_status)
807{
808 switch (cmd_status) {
809 MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
810 MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
811 MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
812 MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
813 MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
814 MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
815 MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
816 MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
817 MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
818 }
819
820 return "UNKNOWN";
821}
822
823/* Wait until the command is completed */
824static int at76_wait_completion(struct at76_priv *priv, int cmd)
825{
826 int status = 0;
827 unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
828
829 do {
830 status = at76_get_cmd_status(priv->udev, cmd);
831 if (status < 0) {
832 printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
833 priv->netdev->name, status);
834 break;
835 }
836
837 at76_dbg(DBG_WAIT_COMPLETE,
838 "%s: Waiting on cmd %d, status = %d (%s)",
839 priv->netdev->name, cmd, status,
840 at76_get_cmd_status_string(status));
841
842 if (status != CMD_STATUS_IN_PROGRESS
843 && status != CMD_STATUS_IDLE)
844 break;
845
846 schedule_timeout_interruptible(HZ / 10); /* 100 ms */
847 if (time_after(jiffies, timeout)) {
848 printk(KERN_ERR
849 "%s: completion timeout for command %d\n",
850 priv->netdev->name, cmd);
851 status = -ETIMEDOUT;
852 break;
853 }
854 } while (1);
855
856 return status;
857}
858
859static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
860{
861 int ret;
862
863 ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
864 offsetof(struct set_mib_buffer,
865 data) + buf->size);
866 if (ret < 0)
867 return ret;
868
869 ret = at76_wait_completion(priv, CMD_SET_MIB);
870 if (ret != CMD_STATUS_COMPLETE) {
871 printk(KERN_INFO
872 "%s: set_mib: at76_wait_completion failed "
873 "with %d\n", priv->netdev->name, ret);
874 ret = -EIO;
875 }
876
877 return ret;
878}
879
880/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
881static int at76_set_radio(struct at76_priv *priv, int enable)
882{
883 int ret;
884 int cmd;
885
886 if (priv->radio_on == enable)
887 return 0;
888
889 cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
890
891 ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
892 if (ret < 0)
893 printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
894 priv->netdev->name, cmd, ret);
895 else
896 ret = 1;
897
898 priv->radio_on = enable;
899 return ret;
900}
901
902/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
903static int at76_set_pm_mode(struct at76_priv *priv)
904{
905 int ret = 0;
906
907 priv->mib_buf.type = MIB_MAC_MGMT;
908 priv->mib_buf.size = 1;
909 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
910 priv->mib_buf.data.byte = priv->pm_mode;
911
912 ret = at76_set_mib(priv, &priv->mib_buf);
913 if (ret < 0)
914 printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
915 priv->netdev->name, ret);
916
917 return ret;
918}
919
920/* Set the association id for power save mode */
921static int at76_set_associd(struct at76_priv *priv, u16 id)
922{
923 int ret = 0;
924
925 priv->mib_buf.type = MIB_MAC_MGMT;
926 priv->mib_buf.size = 2;
927 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
928 priv->mib_buf.data.word = cpu_to_le16(id);
929
930 ret = at76_set_mib(priv, &priv->mib_buf);
931 if (ret < 0)
932 printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
933 priv->netdev->name, ret);
934
935 return ret;
936}
937
938/* Set the listen interval for power save mode */
939static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
940{
941 int ret = 0;
942
943 priv->mib_buf.type = MIB_MAC;
944 priv->mib_buf.size = 2;
945 priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
946 priv->mib_buf.data.word = cpu_to_le16(interval);
947
948 ret = at76_set_mib(priv, &priv->mib_buf);
949 if (ret < 0)
950 printk(KERN_ERR
951 "%s: set_mib (listen_interval) failed: %d\n",
952 priv->netdev->name, ret);
953
954 return ret;
955}
956
957static int at76_set_preamble(struct at76_priv *priv, u8 type)
958{
959 int ret = 0;
960
961 priv->mib_buf.type = MIB_LOCAL;
962 priv->mib_buf.size = 1;
963 priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
964 priv->mib_buf.data.byte = type;
965
966 ret = at76_set_mib(priv, &priv->mib_buf);
967 if (ret < 0)
968 printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
969 priv->netdev->name, ret);
970
971 return ret;
972}
973
974static int at76_set_frag(struct at76_priv *priv, u16 size)
975{
976 int ret = 0;
977
978 priv->mib_buf.type = MIB_MAC;
979 priv->mib_buf.size = 2;
980 priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
981 priv->mib_buf.data.word = cpu_to_le16(size);
982
983 ret = at76_set_mib(priv, &priv->mib_buf);
984 if (ret < 0)
985 printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
986 priv->netdev->name, ret);
987
988 return ret;
989}
990
991static int at76_set_rts(struct at76_priv *priv, u16 size)
992{
993 int ret = 0;
994
995 priv->mib_buf.type = MIB_MAC;
996 priv->mib_buf.size = 2;
997 priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
998 priv->mib_buf.data.word = cpu_to_le16(size);
999
1000 ret = at76_set_mib(priv, &priv->mib_buf);
1001 if (ret < 0)
1002 printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
1003 priv->netdev->name, ret);
1004
1005 return ret;
1006}
1007
1008static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
1009{
1010 int ret = 0;
1011
1012 priv->mib_buf.type = MIB_LOCAL;
1013 priv->mib_buf.size = 1;
1014 priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
1015 priv->mib_buf.data.byte = onoff;
1016
1017 ret = at76_set_mib(priv, &priv->mib_buf);
1018 if (ret < 0)
1019 printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
1020 priv->netdev->name, ret);
1021
1022 return ret;
1023}
1024
1025static int at76_add_mac_address(struct at76_priv *priv, void *addr)
1026{
1027 int ret = 0;
1028
1029 priv->mib_buf.type = MIB_MAC_ADDR;
1030 priv->mib_buf.size = ETH_ALEN;
1031 priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
1032 memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
1033
1034 ret = at76_set_mib(priv, &priv->mib_buf);
1035 if (ret < 0)
1036 printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
1037 priv->netdev->name, ret);
1038
1039 return ret;
1040}
1041
1042static void at76_dump_mib_mac_addr(struct at76_priv *priv)
1043{
1044 int i;
1045 int ret;
1046 struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
1047 GFP_KERNEL);
1048
1049 if (!m)
1050 return;
1051
1052 ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
1053 sizeof(struct mib_mac_addr));
1054 if (ret < 0) {
1055 printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
1056 priv->netdev->name, ret);
1057 goto exit;
1058 }
1059
1060 at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
1061 priv->netdev->name,
1062 mac2str(m->mac_addr), m->res[0], m->res[1]);
1063 for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
1064 at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
1065 "status %d", priv->netdev->name, i,
1066 mac2str(m->group_addr[i]), m->group_addr_status[i]);
1067exit:
1068 kfree(m);
1069}
1070
1071static void at76_dump_mib_mac_wep(struct at76_priv *priv)
1072{
1073 int i;
1074 int ret;
1075 int key_len;
1076 struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
1077
1078 if (!m)
1079 return;
1080
1081 ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
1082 sizeof(struct mib_mac_wep));
1083 if (ret < 0) {
1084 printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
1085 priv->netdev->name, ret);
1086 goto exit;
1087 }
1088
1089 at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
1090 "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
1091 "encr_level %u key %d", priv->netdev->name,
1092 m->privacy_invoked, m->wep_default_key_id,
1093 m->wep_key_mapping_len, m->exclude_unencrypted,
1094 le32_to_cpu(m->wep_icv_error_count),
1095 le32_to_cpu(m->wep_excluded_count), m->encryption_level,
1096 m->wep_default_key_id);
1097
1098 key_len = (m->encryption_level == 1) ?
1099 WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
1100
1101 for (i = 0; i < WEP_KEYS; i++)
1102 at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
1103 priv->netdev->name, i,
1104 hex2str(m->wep_default_keyvalue[i], key_len));
1105exit:
1106 kfree(m);
1107}
1108
1109static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
1110{
1111 int ret;
1112 struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
1113 GFP_KERNEL);
1114
1115 if (!m)
1116 return;
1117
1118 ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
1119 sizeof(struct mib_mac_mgmt));
1120 if (ret < 0) {
1121 printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
1122 priv->netdev->name, ret);
1123 goto exit;
1124 }
1125
1126 at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
1127 "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
1128 "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
1129 "current_bssid %s current_essid %s current_bss_type %d "
1130 "pm_mode %d ibss_change %d res %d "
1131 "multi_domain_capability_implemented %d "
1132 "international_roaming %d country_string %.3s",
1133 priv->netdev->name, le16_to_cpu(m->beacon_period),
1134 le16_to_cpu(m->CFP_max_duration),
1135 le16_to_cpu(m->medium_occupancy_limit),
1136 le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
1137 m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
1138 m->CFP_period, mac2str(m->current_bssid),
1139 hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
1140 m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
1141 m->res, m->multi_domain_capability_implemented,
1142 m->multi_domain_capability_enabled, m->country_string);
1143exit:
1144 kfree(m);
1145}
1146
1147static void at76_dump_mib_mac(struct at76_priv *priv)
1148{
1149 int ret;
1150 struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
1151
1152 if (!m)
1153 return;
1154
1155 ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
1156 if (ret < 0) {
1157 printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
1158 priv->netdev->name, ret);
1159 goto exit;
1160 }
1161
1162 at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
1163 "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
1164 "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
1165 "scan_type %d scan_channel %d probe_delay %u "
1166 "min_channel_time %d max_channel_time %d listen_int %d "
1167 "desired_ssid %s desired_bssid %s desired_bsstype %d",
1168 priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
1169 le32_to_cpu(m->max_rx_lifetime),
1170 le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
1171 le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
1172 m->short_retry_time, m->long_retry_time, m->scan_type,
1173 m->scan_channel, le16_to_cpu(m->probe_delay),
1174 le16_to_cpu(m->min_channel_time),
1175 le16_to_cpu(m->max_channel_time),
1176 le16_to_cpu(m->listen_interval),
1177 hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
1178 mac2str(m->desired_bssid), m->desired_bsstype);
1179exit:
1180 kfree(m);
1181}
1182
1183static void at76_dump_mib_phy(struct at76_priv *priv)
1184{
1185 int ret;
1186 struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1187
1188 if (!m)
1189 return;
1190
1191 ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
1192 if (ret < 0) {
1193 printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
1194 priv->netdev->name, ret);
1195 goto exit;
1196 }
1197
1198 at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
1199 "sifs_time %d preamble_length %d plcp_header_length %d "
1200 "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
1201 "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
1202 "phy_type %d current_reg_domain %d",
1203 priv->netdev->name, le32_to_cpu(m->ed_threshold),
1204 le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
1205 le16_to_cpu(m->preamble_length),
1206 le16_to_cpu(m->plcp_header_length),
1207 le16_to_cpu(m->mpdu_max_length),
1208 le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
1209 m->operation_rate_set[1], m->operation_rate_set[2],
1210 m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
1211 m->phy_type, m->current_reg_domain);
1212exit:
1213 kfree(m);
1214}
1215
1216static void at76_dump_mib_local(struct at76_priv *priv)
1217{
1218 int ret;
1219 struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1220
1221 if (!m)
1222 return;
1223
1224 ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
1225 if (ret < 0) {
1226 printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
1227 priv->netdev->name, ret);
1228 goto exit;
1229 }
1230
1231 at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
1232 "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
1233 "preamble_type %d", priv->netdev->name, m->beacon_enable,
1234 m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
1235 m->preamble_type);
1236exit:
1237 kfree(m);
1238}
1239
1240static void at76_dump_mib_mdomain(struct at76_priv *priv)
1241{
1242 int ret;
1243 struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
1244
1245 if (!m)
1246 return;
1247
1248 ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
1249 sizeof(struct mib_mdomain));
1250 if (ret < 0) {
1251 printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
1252 priv->netdev->name, ret);
1253 goto exit;
1254 }
1255
1256 at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
1257 priv->netdev->name,
1258 hex2str(m->channel_list, sizeof(m->channel_list)));
1259
1260 at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
1261 priv->netdev->name,
1262 hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
1263exit:
1264 kfree(m);
1265}
1266
1267static int at76_get_current_bssid(struct at76_priv *priv)
1268{
1269 int ret = 0;
1270 struct mib_mac_mgmt *mac_mgmt =
1271 kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
1272
1273 if (!mac_mgmt) {
1274 ret = -ENOMEM;
1275 goto exit;
1276 }
1277
1278 ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
1279 sizeof(struct mib_mac_mgmt));
1280 if (ret < 0) {
1281 printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
1282 priv->netdev->name, ret);
1283 goto error;
1284 }
1285 memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
1286 printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
1287 mac2str(priv->bssid));
1288error:
1289 kfree(mac_mgmt);
1290exit:
1291 return ret;
1292}
1293
1294static int at76_get_current_channel(struct at76_priv *priv)
1295{
1296 int ret = 0;
1297 struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1298
1299 if (!phy) {
1300 ret = -ENOMEM;
1301 goto exit;
1302 }
1303 ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
1304 if (ret < 0) {
1305 printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
1306 priv->netdev->name, ret);
1307 goto error;
1308 }
1309 priv->channel = phy->channel_id;
1310error:
1311 kfree(phy);
1312exit:
1313 return ret;
1314}
1315
1316/**
1317 * at76_start_scan - start a scan
1318 *
1319 * @use_essid - use the configured ESSID in non passive mode
1320 */
1321static int at76_start_scan(struct at76_priv *priv, int use_essid)
1322{
1323 struct at76_req_scan scan;
1324
1325 memset(&scan, 0, sizeof(struct at76_req_scan));
1326 memset(scan.bssid, 0xff, ETH_ALEN);
1327
1328 if (use_essid) {
1329 memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
1330 scan.essid_size = priv->essid_size;
1331 } else
1332 scan.essid_size = 0;
1333
1334 /* jal: why should we start at a certain channel? we do scan the whole
1335 range allowed by reg domain. */
1336 scan.channel = priv->channel;
1337
1338 /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
1339 For ad-hoc mode, it uses type 0 only. */
1340 scan.scan_type = priv->scan_mode;
1341
1342 /* INFO: For probe_delay, not multiplying by 1024 as this will be
1343 slightly less than min_channel_time
1344 (per spec: probe delay < min. channel time) */
1345 scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
1346 scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
1347 scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
1348 scan.international_scan = 0;
1349
1350 /* other values are set to 0 for type 0 */
1351
1352 at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
1353 "channel = %d, probe_delay = %d, scan_min_time = %d, "
1354 "scan_max_time = %d)",
1355 priv->netdev->name, use_essid,
1356 scan.international_scan, scan.channel,
1357 le16_to_cpu(scan.probe_delay),
1358 le16_to_cpu(scan.min_channel_time),
1359 le16_to_cpu(scan.max_channel_time));
1360
1361 return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
1362}
1363
1364/* Enable monitor mode */
1365static int at76_start_monitor(struct at76_priv *priv)
1366{
1367 struct at76_req_scan scan;
1368 int ret;
1369
1370 memset(&scan, 0, sizeof(struct at76_req_scan));
1371 memset(scan.bssid, 0xff, ETH_ALEN);
1372
1373 scan.channel = priv->channel;
1374 scan.scan_type = SCAN_TYPE_PASSIVE;
1375 scan.international_scan = 0;
1376
1377 ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
1378 if (ret >= 0)
1379 ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
1380
1381 return ret;
1382}
1383
1384static int at76_start_ibss(struct at76_priv *priv)
1385{
1386 struct at76_req_ibss bss;
1387 int ret;
1388
1389 WARN_ON(priv->mac_state != MAC_OWN_IBSS);
1390 if (priv->mac_state != MAC_OWN_IBSS)
1391 return -EBUSY;
1392
1393 memset(&bss, 0, sizeof(struct at76_req_ibss));
1394 memset(bss.bssid, 0xff, ETH_ALEN);
1395 memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
1396 bss.essid_size = priv->essid_size;
1397 bss.bss_type = ADHOC_MODE;
1398 bss.channel = priv->channel;
1399
1400 ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
1401 sizeof(struct at76_req_ibss));
1402 if (ret < 0) {
1403 printk(KERN_ERR "%s: start_ibss failed: %d\n",
1404 priv->netdev->name, ret);
1405 return ret;
1406 }
1407
1408 ret = at76_wait_completion(priv, CMD_START_IBSS);
1409 if (ret != CMD_STATUS_COMPLETE) {
1410 printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
1411 priv->netdev->name, ret);
1412 return ret;
1413 }
1414
1415 ret = at76_get_current_bssid(priv);
1416 if (ret < 0)
1417 return ret;
1418
1419 ret = at76_get_current_channel(priv);
1420 if (ret < 0)
1421 return ret;
1422
1423 /* not sure what this is good for ??? */
1424 priv->mib_buf.type = MIB_MAC_MGMT;
1425 priv->mib_buf.size = 1;
1426 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
1427 priv->mib_buf.data.byte = 0;
1428
1429 ret = at76_set_mib(priv, &priv->mib_buf);
1430 if (ret < 0) {
1431 printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
1432 priv->netdev->name, ret);
1433 return ret;
1434 }
1435
1436 netif_carrier_on(priv->netdev);
1437 netif_start_queue(priv->netdev);
1438 return 0;
1439}
1440
1441/* Request card to join BSS in managed or ad-hoc mode */
1442static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
1443{
1444 struct at76_req_join join;
1445
1446 BUG_ON(!ptr);
1447
1448 memset(&join, 0, sizeof(struct at76_req_join));
1449 memcpy(join.bssid, ptr->bssid, ETH_ALEN);
1450 memcpy(join.essid, ptr->ssid, ptr->ssid_len);
1451 join.essid_size = ptr->ssid_len;
1452 join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
1453 join.channel = ptr->channel;
1454 join.timeout = cpu_to_le16(2000);
1455
1456 at76_dbg(DBG_PROGRESS,
1457 "%s join addr %s ssid %s type %d ch %d timeout %d",
1458 priv->netdev->name, mac2str(join.bssid), join.essid,
1459 join.bss_type, join.channel, le16_to_cpu(join.timeout));
1460 return at76_set_card_command(priv->udev, CMD_JOIN, &join,
1461 sizeof(struct at76_req_join));
1462}
1463
1464/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
1465 likely to compensate a flaw in the AT76C503A USB part ... */
1466static inline int at76_calc_padding(int wlen)
1467{
1468 /* add the USB TX header */
1469 wlen += AT76_TX_HDRLEN;
1470
1471 wlen = wlen % 64;
1472
1473 if (wlen < 50)
1474 return 50 - wlen;
1475
1476 if (wlen >= 61)
1477 return 64 + 50 - wlen;
1478
1479 return 0;
1480}
1481
1482/* We are doing a lot of things here in an interrupt. Need
1483 a bh handler (Watching TV with a TV card is probably
1484 a good test: if you see flickers, we are doing too much.
1485 Currently I do see flickers... even with our tasklet :-( )
1486 Maybe because the bttv driver and usb-uhci use the same interrupt
1487*/
1488/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
1489 * solve everything.. (alex) */
1490static void at76_rx_callback(struct urb *urb)
1491{
1492 struct at76_priv *priv = urb->context;
1493
1494 priv->rx_tasklet.data = (unsigned long)urb;
1495 tasklet_schedule(&priv->rx_tasklet);
1496 return;
1497}
1498
1499static void at76_tx_callback(struct urb *urb)
1500{
1501 struct at76_priv *priv = urb->context;
1502 struct net_device_stats *stats = &priv->stats;
1503 unsigned long flags;
1504 struct at76_tx_buffer *mgmt_buf;
1505 int ret;
1506
1507 switch (urb->status) {
1508 case 0:
1509 stats->tx_packets++;
1510 break;
1511 case -ENOENT:
1512 case -ECONNRESET:
1513 /* urb has been unlinked */
1514 return;
1515 default:
1516 at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
1517 __func__, urb->status);
1518 stats->tx_errors++;
1519 break;
1520 }
1521
1522 spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1523 mgmt_buf = priv->next_mgmt_bulk;
1524 priv->next_mgmt_bulk = NULL;
1525 spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1526
1527 if (!mgmt_buf) {
1528 netif_wake_queue(priv->netdev);
1529 return;
1530 }
1531
1532 /* we don't copy the padding bytes, but add them
1533 to the length */
1534 memcpy(priv->bulk_out_buffer, mgmt_buf,
1535 le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
1536 usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
1537 priv->bulk_out_buffer,
1538 le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
1539 AT76_TX_HDRLEN, at76_tx_callback, priv);
1540 ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
1541 if (ret)
1542 printk(KERN_ERR "%s: error in tx submit urb: %d\n",
1543 priv->netdev->name, ret);
1544
1545 kfree(mgmt_buf);
1546}
1547
1548/* Send a management frame on bulk-out. txbuf->wlength must be set */
1549static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
1550{
1551 unsigned long flags;
1552 int ret;
1553 int urb_status;
1554 void *oldbuf = NULL;
1555
1556 netif_carrier_off(priv->netdev); /* stop netdev watchdog */
1557 netif_stop_queue(priv->netdev); /* stop tx data packets */
1558
1559 spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1560
1561 urb_status = priv->tx_urb->status;
1562 if (urb_status == -EINPROGRESS) {
1563 /* cannot transmit now, put in the queue */
1564 oldbuf = priv->next_mgmt_bulk;
1565 priv->next_mgmt_bulk = txbuf;
1566 }
1567 spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1568
1569 if (oldbuf) {
1570 /* a data/mgmt tx is already pending in the URB -
1571 if this is no error in some situations we must
1572 implement a queue or silently modify the old msg */
1573 printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
1574 priv->netdev->name, hex2str(oldbuf, 64));
1575 kfree(oldbuf);
1576 return 0;
1577 }
1578
1579 txbuf->tx_rate = TX_RATE_1MBIT;
1580 txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
1581 memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
1582
1583 if (priv->next_mgmt_bulk)
1584 printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
1585 priv->netdev->name, urb_status);
1586
1587 at76_dbg(DBG_TX_MGMT,
1588 "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
1589 priv->netdev->name, le16_to_cpu(txbuf->wlength),
1590 txbuf->tx_rate, txbuf->padding,
1591 hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
1592
1593 /* txbuf was not consumed above -> send mgmt msg immediately */
1594 memcpy(priv->bulk_out_buffer, txbuf,
1595 le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
1596 usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
1597 priv->bulk_out_buffer,
1598 le16_to_cpu(txbuf->wlength) + txbuf->padding +
1599 AT76_TX_HDRLEN, at76_tx_callback, priv);
1600 ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
1601 if (ret)
1602 printk(KERN_ERR "%s: error in tx submit urb: %d\n",
1603 priv->netdev->name, ret);
1604
1605 kfree(txbuf);
1606
1607 return ret;
1608}
1609
1610/* Go to the next information element */
1611static inline void next_ie(struct ieee80211_info_element **ie)
1612{
1613 *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
1614}
1615
1616/* Challenge is the challenge string (in TLV format)
1617 we got with seq_nr 2 for shared secret authentication only and
1618 send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
1619 otherwise it is NULL */
1620static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
1621 int seq_nr, struct ieee80211_info_element *challenge)
1622{
1623 struct at76_tx_buffer *tx_buffer;
1624 struct ieee80211_hdr_3addr *mgmt;
1625 struct ieee80211_auth *req;
1626 int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
1627 AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
1628
1629 BUG_ON(!bss);
1630 BUG_ON(seq_nr == 3 && !challenge);
1631 tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
1632 if (!tx_buffer)
1633 return -ENOMEM;
1634
1635 req = (struct ieee80211_auth *)tx_buffer->packet;
1636 mgmt = &req->header;
1637
1638 /* make wireless header */
1639 /* first auth msg is not encrypted, only the second (seq_nr == 3) */
1640 mgmt->frame_ctl =
1641 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
1642 (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
1643
1644 mgmt->duration_id = cpu_to_le16(0x8000);
1645 memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
1646 memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
1647 memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
1648 mgmt->seq_ctl = cpu_to_le16(0);
1649
1650 req->algorithm = cpu_to_le16(priv->auth_mode);
1651 req->transaction = cpu_to_le16(seq_nr);
1652 req->status = cpu_to_le16(0);
1653
1654 if (seq_nr == 3)
1655 memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
1656
1657 /* init. at76_priv tx header */
1658 tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
1659 at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
1660 priv->netdev->name, mac2str(mgmt->addr3),
1661 le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
1662 if (seq_nr == 3)
1663 at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
1664 priv->netdev->name, hex2str(req->info_element, 18));
1665
1666 /* either send immediately (if no data tx is pending
1667 or put it in pending list */
1668 return at76_tx_mgmt(priv, tx_buffer);
1669}
1670
1671static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
1672{
1673 struct at76_tx_buffer *tx_buffer;
1674 struct ieee80211_hdr_3addr *mgmt;
1675 struct ieee80211_assoc_request *req;
1676 struct ieee80211_info_element *ie;
1677 char *essid;
1678 int essid_len;
1679 u16 capa;
1680
1681 BUG_ON(!bss);
1682
1683 tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
1684 if (!tx_buffer)
1685 return -ENOMEM;
1686
1687 req = (struct ieee80211_assoc_request *)tx_buffer->packet;
1688 mgmt = &req->header;
1689 ie = req->info_element;
1690
1691 /* make wireless header */
1692 mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1693 IEEE80211_STYPE_ASSOC_REQ);
1694
1695 mgmt->duration_id = cpu_to_le16(0x8000);
1696 memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
1697 memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
1698 memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
1699 mgmt->seq_ctl = cpu_to_le16(0);
1700
1701 /* we must set the Privacy bit in the capabilities to assure an
1702 Agere-based AP with optional WEP transmits encrypted frames
1703 to us. AP only set the Privacy bit in their capabilities
1704 if WEP is mandatory in the BSS! */
1705 capa = bss->capa;
1706 if (priv->wep_enabled)
1707 capa |= WLAN_CAPABILITY_PRIVACY;
1708 if (priv->preamble_type != PREAMBLE_TYPE_LONG)
1709 capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
1710 req->capability = cpu_to_le16(capa);
1711
1712 req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
1713
1714 /* write TLV data elements */
1715
1716 ie->id = MFIE_TYPE_SSID;
1717 ie->len = bss->ssid_len;
1718 memcpy(ie->data, bss->ssid, bss->ssid_len);
1719 next_ie(&ie);
1720
1721 ie->id = MFIE_TYPE_RATES;
1722 ie->len = sizeof(hw_rates);
1723 memcpy(ie->data, hw_rates, sizeof(hw_rates));
1724 next_ie(&ie); /* ie points behind the supp_rates field */
1725
1726 /* init. at76_priv tx header */
1727 tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
1728
1729 ie = req->info_element;
1730 essid = ie->data;
1731 essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
1732
1733 next_ie(&ie); /* points to IE of rates now */
1734 at76_dbg(DBG_TX_MGMT,
1735 "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
1736 priv->netdev->name, mac2str(mgmt->addr3),
1737 le16_to_cpu(req->capability), essid_len, essid,
1738 hex2str(ie->data, ie->len));
1739
1740 /* either send immediately (if no data tx is pending
1741 or put it in pending list */
1742 return at76_tx_mgmt(priv, tx_buffer);
1743}
1744
1745/* We got to check the bss_list for old entries */
1746static void at76_bss_list_timeout(unsigned long par)
1747{
1748 struct at76_priv *priv = (struct at76_priv *)par;
1749 unsigned long flags;
1750 struct list_head *lptr, *nptr;
1751 struct bss_info *ptr;
1752
1753 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
1754
1755 list_for_each_safe(lptr, nptr, &priv->bss_list) {
1756
1757 ptr = list_entry(lptr, struct bss_info, list);
1758
1759 if (ptr != priv->curr_bss
1760 && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
1761 at76_dbg(DBG_BSS_TABLE_RM,
1762 "%s: bss_list: removing old BSS %s ch %d",
1763 priv->netdev->name, mac2str(ptr->bssid),
1764 ptr->channel);
1765 list_del(&ptr->list);
1766 kfree(ptr);
1767 }
1768 }
1769 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
1770 /* restart the timer */
1771 mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
1772}
1773
1774static inline void at76_set_mac_state(struct at76_priv *priv,
1775 enum mac_state mac_state)
1776{
1777 at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
1778 mac_states[mac_state]);
1779 priv->mac_state = mac_state;
1780}
1781
1782static void at76_dump_bss_table(struct at76_priv *priv)
1783{
1784 struct bss_info *ptr;
1785 unsigned long flags;
1786 struct list_head *lptr;
1787
1788 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
1789
1790 at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
1791 priv->curr_bss);
1792
1793 list_for_each(lptr, &priv->bss_list) {
1794 ptr = list_entry(lptr, struct bss_info, list);
1795 at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
1796 "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
1797 ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
1798 ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
1799 ptr->capa, hex2str(ptr->rates, ptr->rates_len),
1800 ptr->rssi, ptr->link_qual, ptr->noise_level);
1801 }
1802 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
1803}
1804
1805/* Called upon successful association to mark interface as connected */
1806static void at76_work_assoc_done(struct work_struct *work)
1807{
1808 struct at76_priv *priv = container_of(work, struct at76_priv,
1809 work_assoc_done);
1810
1811 mutex_lock(&priv->mtx);
1812
1813 WARN_ON(priv->mac_state != MAC_ASSOC);
1814 WARN_ON(!priv->curr_bss);
1815 if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
1816 goto exit;
1817
1818 if (priv->iw_mode == IW_MODE_INFRA) {
1819 if (priv->pm_mode != AT76_PM_OFF) {
1820 /* calculate the listen interval in units of
1821 beacon intervals of the curr_bss */
1822 u32 pm_period_beacon = (priv->pm_period >> 10) /
1823 priv->curr_bss->beacon_interval;
1824
1825 pm_period_beacon = max(pm_period_beacon, 2u);
1826 pm_period_beacon = min(pm_period_beacon, 0xffffu);
1827
1828 at76_dbg(DBG_PM,
1829 "%s: pm_mode %d assoc id 0x%x listen int %d",
1830 priv->netdev->name, priv->pm_mode,
1831 priv->assoc_id, pm_period_beacon);
1832
1833 at76_set_associd(priv, priv->assoc_id);
1834 at76_set_listen_interval(priv, (u16)pm_period_beacon);
1835 }
1836 schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
1837 }
1838 at76_set_pm_mode(priv);
1839
1840 netif_carrier_on(priv->netdev);
1841 netif_wake_queue(priv->netdev);
1842 at76_set_mac_state(priv, MAC_CONNECTED);
1843 at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
1844 at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
1845 priv->netdev->name, mac2str(priv->curr_bss->bssid));
1846
1847exit:
1848 mutex_unlock(&priv->mtx);
1849}
1850
1851/* We only store the new mac address in netdev struct,
1852 it gets set when the netdev is opened. */
1853static int at76_set_mac_address(struct net_device *netdev, void *addr)
1854{
1855 struct sockaddr *mac = addr;
1856 memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
1857 return 1;
1858}
1859
1860static struct net_device_stats *at76_get_stats(struct net_device *netdev)
1861{
1862 struct at76_priv *priv = netdev_priv(netdev);
1863 return &priv->stats;
1864}
1865
1866static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
1867{
1868 struct at76_priv *priv = netdev_priv(netdev);
1869
1870 at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
1871 priv->wstats.qual.qual, priv->wstats.qual.level,
1872 priv->wstats.qual.noise, priv->wstats.qual.updated);
1873
1874 return &priv->wstats;
1875}
1876
1877static void at76_set_multicast(struct net_device *netdev)
1878{
1879 struct at76_priv *priv = netdev_priv(netdev);
1880 int promisc;
1881
1882 promisc = ((netdev->flags & IFF_PROMISC) != 0);
1883 if (promisc != priv->promisc) {
1884 /* This gets called in interrupt, must reschedule */
1885 priv->promisc = promisc;
1886 schedule_work(&priv->work_set_promisc);
1887 }
1888}
1889
1890/* Stop all network activity, flush all pending tasks */
1891static void at76_quiesce(struct at76_priv *priv)
1892{
1893 unsigned long flags;
1894
1895 netif_stop_queue(priv->netdev);
1896 netif_carrier_off(priv->netdev);
1897
1898 at76_set_mac_state(priv, MAC_INIT);
1899
1900 cancel_delayed_work(&priv->dwork_get_scan);
1901 cancel_delayed_work(&priv->dwork_beacon);
1902 cancel_delayed_work(&priv->dwork_auth);
1903 cancel_delayed_work(&priv->dwork_assoc);
1904 cancel_delayed_work(&priv->dwork_restart);
1905
1906 spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1907 kfree(priv->next_mgmt_bulk);
1908 priv->next_mgmt_bulk = NULL;
1909 spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1910}
1911
1912/*******************************************************************************
1913 * at76_priv implementations of iw_handler functions:
1914 */
1915static int at76_iw_handler_commit(struct net_device *netdev,
1916 struct iw_request_info *info,
1917 void *null, char *extra)
1918{
1919 struct at76_priv *priv = netdev_priv(netdev);
1920
1921 at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
1922 __func__);
1923
1924 if (priv->mac_state != MAC_INIT)
1925 at76_quiesce(priv);
1926
1927 /* Wait half second before the restart to process subsequent
1928 * requests from the same iwconfig in a single restart */
1929 schedule_delayed_work(&priv->dwork_restart, HZ / 2);
1930
1931 return 0;
1932}
1933
1934static int at76_iw_handler_get_name(struct net_device *netdev,
1935 struct iw_request_info *info,
1936 char *name, char *extra)
1937{
1938 strcpy(name, "IEEE 802.11b");
1939 at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
1940 return 0;
1941}
1942
1943static int at76_iw_handler_set_freq(struct net_device *netdev,
1944 struct iw_request_info *info,
1945 struct iw_freq *freq, char *extra)
1946{
1947 struct at76_priv *priv = netdev_priv(netdev);
1948 int chan = -1;
1949 int ret = -EIWCOMMIT;
1950 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
1951 netdev->name, freq->m, freq->e);
1952
1953 if ((freq->e == 0) && (freq->m <= 1000))
1954 /* Setting by channel number */
1955 chan = freq->m;
1956 else {
1957 /* Setting by frequency - search the table */
1958 int mult = 1;
1959 int i;
1960
1961 for (i = 0; i < (6 - freq->e); i++)
1962 mult *= 10;
1963
1964 for (i = 0; i < NUM_CHANNELS; i++) {
1965 if (freq->m == (channel_frequency[i] * mult))
1966 chan = i + 1;
1967 }
1968 }
1969
1970 if (chan < 1 || !priv->domain)
1971 /* non-positive channels are invalid
1972 * we need a domain info to set the channel
1973 * either that or an invalid frequency was
1974 * provided by the user */
1975 ret = -EINVAL;
1976 else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
1977 printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
1978 priv->netdev->name, chan, priv->domain->name);
1979 ret = -EINVAL;
1980 }
1981
1982 if (ret == -EIWCOMMIT) {
1983 priv->channel = chan;
1984 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
1985 chan);
1986 }
1987
1988 return ret;
1989}
1990
1991static int at76_iw_handler_get_freq(struct net_device *netdev,
1992 struct iw_request_info *info,
1993 struct iw_freq *freq, char *extra)
1994{
1995 struct at76_priv *priv = netdev_priv(netdev);
1996
1997 freq->m = priv->channel;
1998 freq->e = 0;
1999
2000 if (priv->channel)
2001 at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
2002 netdev->name, channel_frequency[priv->channel - 1], 6);
2003
2004 at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
2005 priv->channel);
2006
2007 return 0;
2008}
2009
2010static int at76_iw_handler_set_mode(struct net_device *netdev,
2011 struct iw_request_info *info,
2012 __u32 *mode, char *extra)
2013{
2014 struct at76_priv *priv = netdev_priv(netdev);
2015
2016 at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
2017
2018 if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
2019 (*mode != IW_MODE_MONITOR))
2020 return -EINVAL;
2021
2022 priv->iw_mode = *mode;
2023 if (priv->iw_mode != IW_MODE_INFRA)
2024 priv->pm_mode = AT76_PM_OFF;
2025
2026 return -EIWCOMMIT;
2027}
2028
2029static int at76_iw_handler_get_mode(struct net_device *netdev,
2030 struct iw_request_info *info,
2031 __u32 *mode, char *extra)
2032{
2033 struct at76_priv *priv = netdev_priv(netdev);
2034
2035 *mode = priv->iw_mode;
2036
2037 at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
2038
2039 return 0;
2040}
2041
2042static int at76_iw_handler_get_range(struct net_device *netdev,
2043 struct iw_request_info *info,
2044 struct iw_point *data, char *extra)
2045{
2046 /* inspired by atmel.c */
2047 struct at76_priv *priv = netdev_priv(netdev);
2048 struct iw_range *range = (struct iw_range *)extra;
2049 int i;
2050
2051 data->length = sizeof(struct iw_range);
2052 memset(range, 0, sizeof(struct iw_range));
2053
2054 /* TODO: range->throughput = xxxxxx; */
2055
2056 range->min_nwid = 0x0000;
2057 range->max_nwid = 0x0000;
2058
2059 /* this driver doesn't maintain sensitivity information */
2060 range->sensitivity = 0;
2061
2062 range->max_qual.qual = 100;
2063 range->max_qual.level = 100;
2064 range->max_qual.noise = 0;
2065 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2066
2067 range->avg_qual.qual = 50;
2068 range->avg_qual.level = 50;
2069 range->avg_qual.noise = 0;
2070 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2071
2072 range->bitrate[0] = 1000000;
2073 range->bitrate[1] = 2000000;
2074 range->bitrate[2] = 5500000;
2075 range->bitrate[3] = 11000000;
2076 range->num_bitrates = 4;
2077
2078 range->min_rts = 0;
2079 range->max_rts = MAX_RTS_THRESHOLD;
2080
2081 range->min_frag = MIN_FRAG_THRESHOLD;
2082 range->max_frag = MAX_FRAG_THRESHOLD;
2083
2084 range->pmp_flags = IW_POWER_PERIOD;
2085 range->pmt_flags = IW_POWER_ON;
2086 range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
2087
2088 range->encoding_size[0] = WEP_SMALL_KEY_LEN;
2089 range->encoding_size[1] = WEP_LARGE_KEY_LEN;
2090 range->num_encoding_sizes = 2;
2091 range->max_encoding_tokens = WEP_KEYS;
2092
2093 /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
2094 - take this for all (ignore antenna gains) */
2095 range->txpower[0] = 15;
2096 range->num_txpower = 1;
2097 range->txpower_capa = IW_TXPOW_DBM;
2098
2099 range->we_version_source = WIRELESS_EXT;
2100 range->we_version_compiled = WIRELESS_EXT;
2101
2102 /* same as the values used in atmel.c */
2103 range->retry_capa = IW_RETRY_LIMIT;
2104 range->retry_flags = IW_RETRY_LIMIT;
2105 range->r_time_flags = 0;
2106 range->min_retry = 1;
2107 range->max_retry = 255;
2108
2109 range->num_channels = NUM_CHANNELS;
2110 range->num_frequency = 0;
2111
2112 for (i = 0; i < NUM_CHANNELS; i++) {
2113 /* test if channel map bit is raised */
2114 if (priv->domain->channel_map & (0x1 << i)) {
2115 range->num_frequency += 1;
2116
2117 range->freq[i].i = i + 1;
2118 range->freq[i].m = channel_frequency[i] * 100000;
2119 range->freq[i].e = 1; /* freq * 10^1 */
2120 }
2121 }
2122
2123 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
2124
2125 return 0;
2126}
2127
2128static int at76_iw_handler_set_spy(struct net_device *netdev,
2129 struct iw_request_info *info,
2130 struct iw_point *data, char *extra)
2131{
2132 struct at76_priv *priv = netdev_priv(netdev);
2133 int ret = 0;
2134
2135 at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
2136 netdev->name, data->length);
2137
2138 spin_lock_bh(&priv->spy_spinlock);
2139 ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
2140 extra);
2141 spin_unlock_bh(&priv->spy_spinlock);
2142
2143 return ret;
2144}
2145
2146static int at76_iw_handler_get_spy(struct net_device *netdev,
2147 struct iw_request_info *info,
2148 struct iw_point *data, char *extra)
2149{
2150
2151 struct at76_priv *priv = netdev_priv(netdev);
2152 int ret = 0;
2153
2154 spin_lock_bh(&priv->spy_spinlock);
2155 ret = iw_handler_get_spy(priv->netdev, info,
2156 (union iwreq_data *)data, extra);
2157 spin_unlock_bh(&priv->spy_spinlock);
2158
2159 at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
2160 netdev->name, data->length);
2161
2162 return ret;
2163}
2164
2165static int at76_iw_handler_set_thrspy(struct net_device *netdev,
2166 struct iw_request_info *info,
2167 struct iw_point *data, char *extra)
2168{
2169 struct at76_priv *priv = netdev_priv(netdev);
2170 int ret;
2171
2172 at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
2173 netdev->name, data->length);
2174
2175 spin_lock_bh(&priv->spy_spinlock);
2176 ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
2177 extra);
2178 spin_unlock_bh(&priv->spy_spinlock);
2179
2180 return ret;
2181}
2182
2183static int at76_iw_handler_get_thrspy(struct net_device *netdev,
2184 struct iw_request_info *info,
2185 struct iw_point *data, char *extra)
2186{
2187 struct at76_priv *priv = netdev_priv(netdev);
2188 int ret;
2189
2190 spin_lock_bh(&priv->spy_spinlock);
2191 ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
2192 extra);
2193 spin_unlock_bh(&priv->spy_spinlock);
2194
2195 at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
2196 netdev->name, data->length);
2197
2198 return ret;
2199}
2200
2201static int at76_iw_handler_set_wap(struct net_device *netdev,
2202 struct iw_request_info *info,
2203 struct sockaddr *ap_addr, char *extra)
2204{
2205 struct at76_priv *priv = netdev_priv(netdev);
2206
2207 at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
2208 mac2str(ap_addr->sa_data));
2209
2210 /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
2211 chosen any or auto AP preference */
2212 if (is_broadcast_ether_addr(ap_addr->sa_data)
2213 || is_zero_ether_addr(ap_addr->sa_data))
2214 priv->wanted_bssid_valid = 0;
2215 else {
2216 /* user wants to set a preferred AP address */
2217 priv->wanted_bssid_valid = 1;
2218 memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
2219 }
2220
2221 return -EIWCOMMIT;
2222}
2223
2224static int at76_iw_handler_get_wap(struct net_device *netdev,
2225 struct iw_request_info *info,
2226 struct sockaddr *ap_addr, char *extra)
2227{
2228 struct at76_priv *priv = netdev_priv(netdev);
2229
2230 ap_addr->sa_family = ARPHRD_ETHER;
2231 memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
2232
2233 at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
2234 mac2str(ap_addr->sa_data));
2235
2236 return 0;
2237}
2238
2239static int at76_iw_handler_set_scan(struct net_device *netdev,
2240 struct iw_request_info *info,
2241 union iwreq_data *wrqu, char *extra)
2242{
2243 struct at76_priv *priv = netdev_priv(netdev);
2244 int ret = 0;
2245
2246 at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
2247
2248 if (mutex_lock_interruptible(&priv->mtx))
2249 return -EINTR;
2250
2251 if (!netif_running(netdev)) {
2252 ret = -ENETDOWN;
2253 goto exit;
2254 }
2255
2256 /* jal: we don't allow "iwlist ethX scan" while we are
2257 in monitor mode */
2258 if (priv->iw_mode == IW_MODE_MONITOR) {
2259 ret = -EBUSY;
2260 goto exit;
2261 }
2262
2263 /* Discard old scan results */
2264 if ((jiffies - priv->last_scan) > (20 * HZ))
2265 priv->scan_state = SCAN_IDLE;
2266 priv->last_scan = jiffies;
2267
2268 /* Initiate a scan command */
2269 if (priv->scan_state == SCAN_IN_PROGRESS) {
2270 ret = -EBUSY;
2271 goto exit;
2272 }
2273
2274 priv->scan_state = SCAN_IN_PROGRESS;
2275
2276 at76_quiesce(priv);
2277
2278 /* Try to do passive or active scan if WE asks as. */
2279 if (wrqu->data.length
2280 && wrqu->data.length == sizeof(struct iw_scan_req)) {
2281 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2282
2283 if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2284 priv->scan_mode = SCAN_TYPE_PASSIVE;
2285 else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
2286 priv->scan_mode = SCAN_TYPE_ACTIVE;
2287
2288 /* Sanity check values? */
2289 if (req->min_channel_time > 0)
2290 priv->scan_min_time = req->min_channel_time;
2291
2292 if (req->max_channel_time > 0)
2293 priv->scan_max_time = req->max_channel_time;
2294 }
2295
2296 /* change to scanning state */
2297 at76_set_mac_state(priv, MAC_SCANNING);
2298 schedule_work(&priv->work_start_scan);
2299
2300exit:
2301 mutex_unlock(&priv->mtx);
2302 return ret;
2303}
2304
2305static int at76_iw_handler_get_scan(struct net_device *netdev,
2306 struct iw_request_info *info,
2307 struct iw_point *data, char *extra)
2308{
2309 struct at76_priv *priv = netdev_priv(netdev);
2310 unsigned long flags;
2311 struct list_head *lptr, *nptr;
2312 struct bss_info *curr_bss;
2313 struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
2314 char *curr_val, *curr_pos = extra;
2315 int i;
2316
2317 at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
2318
2319 if (!iwe)
2320 return -ENOMEM;
2321
2322 if (priv->scan_state != SCAN_COMPLETED)
2323 /* scan not yet finished */
2324 return -EAGAIN;
2325
2326 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
2327
2328 list_for_each_safe(lptr, nptr, &priv->bss_list) {
2329 curr_bss = list_entry(lptr, struct bss_info, list);
2330
2331 iwe->cmd = SIOCGIWAP;
2332 iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
2333 memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
2334 curr_pos = iwe_stream_add_event(info, curr_pos,
2335 extra + IW_SCAN_MAX_DATA, iwe,
2336 IW_EV_ADDR_LEN);
2337
2338 iwe->u.data.length = curr_bss->ssid_len;
2339 iwe->cmd = SIOCGIWESSID;
2340 iwe->u.data.flags = 1;
2341
2342 curr_pos = iwe_stream_add_point(info, curr_pos,
2343 extra + IW_SCAN_MAX_DATA, iwe,
2344 curr_bss->ssid);
2345
2346 iwe->cmd = SIOCGIWMODE;
2347 iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
2348 IW_MODE_ADHOC :
2349 (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
2350 IW_MODE_MASTER : IW_MODE_AUTO;
2351 /* IW_MODE_AUTO = 0 which I thought is
2352 * the most logical value to return in this case */
2353 curr_pos = iwe_stream_add_event(info, curr_pos,
2354 extra + IW_SCAN_MAX_DATA, iwe,
2355 IW_EV_UINT_LEN);
2356
2357 iwe->cmd = SIOCGIWFREQ;
2358 iwe->u.freq.m = curr_bss->channel;
2359 iwe->u.freq.e = 0;
2360 curr_pos = iwe_stream_add_event(info, curr_pos,
2361 extra + IW_SCAN_MAX_DATA, iwe,
2362 IW_EV_FREQ_LEN);
2363
2364 iwe->cmd = SIOCGIWENCODE;
2365 if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
2366 iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2367 else
2368 iwe->u.data.flags = IW_ENCODE_DISABLED;
2369
2370 iwe->u.data.length = 0;
2371 curr_pos = iwe_stream_add_point(info, curr_pos,
2372 extra + IW_SCAN_MAX_DATA, iwe,
2373 NULL);
2374
2375 /* Add quality statistics */
2376 iwe->cmd = IWEVQUAL;
2377 iwe->u.qual.noise = 0;
2378 iwe->u.qual.updated =
2379 IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
2380 iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
2381 if (iwe->u.qual.level > 100)
2382 iwe->u.qual.level = 100;
2383 if (at76_is_intersil(priv->board_type))
2384 iwe->u.qual.qual = curr_bss->link_qual;
2385 else {
2386 iwe->u.qual.qual = 0;
2387 iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
2388 }
2389 /* Add new value to event */
2390 curr_pos = iwe_stream_add_event(info, curr_pos,
2391 extra + IW_SCAN_MAX_DATA, iwe,
2392 IW_EV_QUAL_LEN);
2393
2394 /* Rate: stuffing multiple values in a single event requires
2395 * a bit more of magic - Jean II */
2396 curr_val = curr_pos + IW_EV_LCP_LEN;
2397
2398 iwe->cmd = SIOCGIWRATE;
2399 /* Those two flags are ignored... */
2400 iwe->u.bitrate.fixed = 0;
2401 iwe->u.bitrate.disabled = 0;
2402 /* Max 8 values */
2403 for (i = 0; i < curr_bss->rates_len; i++) {
2404 /* Bit rate given in 500 kb/s units (+ 0x80) */
2405 iwe->u.bitrate.value =
2406 ((curr_bss->rates[i] & 0x7f) * 500000);
2407 /* Add new value to event */
2408 curr_val = iwe_stream_add_value(info, curr_pos,
2409 curr_val,
2410 extra +
2411 IW_SCAN_MAX_DATA, iwe,
2412 IW_EV_PARAM_LEN);
2413 }
2414
2415 /* Check if we added any event */
2416 if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
2417 curr_pos = curr_val;
2418
2419 /* more information may be sent back using IWECUSTOM */
2420
2421 }
2422
2423 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
2424
2425 data->length = (curr_pos - extra);
2426 data->flags = 0;
2427
2428 kfree(iwe);
2429 return 0;
2430}
2431
2432static int at76_iw_handler_set_essid(struct net_device *netdev,
2433 struct iw_request_info *info,
2434 struct iw_point *data, char *extra)
2435{
2436 struct at76_priv *priv = netdev_priv(netdev);
2437
2438 at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
2439
2440 if (data->flags) {
2441 memcpy(priv->essid, extra, data->length);
2442 priv->essid_size = data->length;
2443 } else
2444 priv->essid_size = 0; /* Use any SSID */
2445
2446 return -EIWCOMMIT;
2447}
2448
2449static int at76_iw_handler_get_essid(struct net_device *netdev,
2450 struct iw_request_info *info,
2451 struct iw_point *data, char *extra)
2452{
2453 struct at76_priv *priv = netdev_priv(netdev);
2454
2455 if (priv->essid_size) {
2456 /* not the ANY ssid in priv->essid */
2457 data->flags = 1;
2458 data->length = priv->essid_size;
2459 memcpy(extra, priv->essid, data->length);
2460 } else {
2461 /* the ANY ssid was specified */
2462 if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
2463 /* report the SSID we have found */
2464 data->flags = 1;
2465 data->length = priv->curr_bss->ssid_len;
2466 memcpy(extra, priv->curr_bss->ssid, data->length);
2467 } else {
2468 /* report ANY back */
2469 data->flags = 0;
2470 data->length = 0;
2471 }
2472 }
2473
2474 at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
2475 data->length, extra);
2476
2477 return 0;
2478}
2479
2480static int at76_iw_handler_set_rate(struct net_device *netdev,
2481 struct iw_request_info *info,
2482 struct iw_param *bitrate, char *extra)
2483{
2484 struct at76_priv *priv = netdev_priv(netdev);
2485 int ret = -EIWCOMMIT;
2486
2487 at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
2488 bitrate->value);
2489
2490 switch (bitrate->value) {
2491 case -1:
2492 priv->txrate = TX_RATE_AUTO;
2493 break; /* auto rate */
2494 case 1000000:
2495 priv->txrate = TX_RATE_1MBIT;
2496 break;
2497 case 2000000:
2498 priv->txrate = TX_RATE_2MBIT;
2499 break;
2500 case 5500000:
2501 priv->txrate = TX_RATE_5_5MBIT;
2502 break;
2503 case 11000000:
2504 priv->txrate = TX_RATE_11MBIT;
2505 break;
2506 default:
2507 ret = -EINVAL;
2508 }
2509
2510 return ret;
2511}
2512
2513static int at76_iw_handler_get_rate(struct net_device *netdev,
2514 struct iw_request_info *info,
2515 struct iw_param *bitrate, char *extra)
2516{
2517 struct at76_priv *priv = netdev_priv(netdev);
2518 int ret = 0;
2519
2520 switch (priv->txrate) {
2521 /* return max rate if RATE_AUTO */
2522 case TX_RATE_AUTO:
2523 bitrate->value = 11000000;
2524 break;
2525 case TX_RATE_1MBIT:
2526 bitrate->value = 1000000;
2527 break;
2528 case TX_RATE_2MBIT:
2529 bitrate->value = 2000000;
2530 break;
2531 case TX_RATE_5_5MBIT:
2532 bitrate->value = 5500000;
2533 break;
2534 case TX_RATE_11MBIT:
2535 bitrate->value = 11000000;
2536 break;
2537 default:
2538 ret = -EINVAL;
2539 }
2540
2541 bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
2542 bitrate->disabled = 0;
2543
2544 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
2545 bitrate->value);
2546
2547 return ret;
2548}
2549
2550static int at76_iw_handler_set_rts(struct net_device *netdev,
2551 struct iw_request_info *info,
2552 struct iw_param *rts, char *extra)
2553{
2554 struct at76_priv *priv = netdev_priv(netdev);
2555 int ret = -EIWCOMMIT;
2556 int rthr = rts->value;
2557
2558 at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
2559 netdev->name, rts->value, (rts->disabled) ? "true" : "false");
2560
2561 if (rts->disabled)
2562 rthr = MAX_RTS_THRESHOLD;
2563
2564 if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
2565 ret = -EINVAL;
2566 else
2567 priv->rts_threshold = rthr;
2568
2569 return ret;
2570}
2571
2572static int at76_iw_handler_get_rts(struct net_device *netdev,
2573 struct iw_request_info *info,
2574 struct iw_param *rts, char *extra)
2575{
2576 struct at76_priv *priv = netdev_priv(netdev);
2577
2578 rts->value = priv->rts_threshold;
2579 rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
2580 rts->fixed = 1;
2581
2582 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
2583 netdev->name, rts->value, (rts->disabled) ? "true" : "false");
2584
2585 return 0;
2586}
2587
2588static int at76_iw_handler_set_frag(struct net_device *netdev,
2589 struct iw_request_info *info,
2590 struct iw_param *frag, char *extra)
2591{
2592 struct at76_priv *priv = netdev_priv(netdev);
2593 int ret = -EIWCOMMIT;
2594 int fthr = frag->value;
2595
2596 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
2597 netdev->name, frag->value,
2598 (frag->disabled) ? "true" : "false");
2599
2600 if (frag->disabled)
2601 fthr = MAX_FRAG_THRESHOLD;
2602
2603 if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
2604 ret = -EINVAL;
2605 else
2606 priv->frag_threshold = fthr & ~0x1; /* get an even value */
2607
2608 return ret;
2609}
2610
2611static int at76_iw_handler_get_frag(struct net_device *netdev,
2612 struct iw_request_info *info,
2613 struct iw_param *frag, char *extra)
2614{
2615 struct at76_priv *priv = netdev_priv(netdev);
2616
2617 frag->value = priv->frag_threshold;
2618 frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
2619 frag->fixed = 1;
2620
2621 at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
2622 netdev->name, frag->value,
2623 (frag->disabled) ? "true" : "false");
2624
2625 return 0;
2626}
2627
2628static int at76_iw_handler_get_txpow(struct net_device *netdev,
2629 struct iw_request_info *info,
2630 struct iw_param *power, char *extra)
2631{
2632 power->value = 15;
2633 power->fixed = 1; /* No power control */
2634 power->disabled = 0;
2635 power->flags = IW_TXPOW_DBM;
2636
2637 at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
2638 power->value);
2639
2640 return 0;
2641}
2642
2643/* jal: short retry is handled by the firmware (at least 0.90.x),
2644 while long retry is not (?) */
2645static int at76_iw_handler_set_retry(struct net_device *netdev,
2646 struct iw_request_info *info,
2647 struct iw_param *retry, char *extra)
2648{
2649 struct at76_priv *priv = netdev_priv(netdev);
2650 int ret = -EIWCOMMIT;
2651
2652 at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
2653 netdev->name, retry->disabled, retry->flags, retry->value);
2654
2655 if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
2656 if ((retry->flags & IW_RETRY_MIN) ||
2657 !(retry->flags & IW_RETRY_MAX))
2658 priv->short_retry_limit = retry->value;
2659 else
2660 ret = -EINVAL;
2661 } else
2662 ret = -EINVAL;
2663
2664 return ret;
2665}
2666
2667/* Adapted (ripped) from atmel.c */
2668static int at76_iw_handler_get_retry(struct net_device *netdev,
2669 struct iw_request_info *info,
2670 struct iw_param *retry, char *extra)
2671{
2672 struct at76_priv *priv = netdev_priv(netdev);
2673
2674 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
2675
2676 retry->disabled = 0; /* Can't be disabled */
2677 retry->flags = IW_RETRY_LIMIT;
2678 retry->value = priv->short_retry_limit;
2679
2680 return 0;
2681}
2682
2683static int at76_iw_handler_set_encode(struct net_device *netdev,
2684 struct iw_request_info *info,
2685 struct iw_point *encoding, char *extra)
2686{
2687 struct at76_priv *priv = netdev_priv(netdev);
2688 int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
2689 int len = encoding->length;
2690
2691 at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
2692 "pointer %p len %d", netdev->name, encoding->flags,
2693 encoding->pointer, encoding->length);
2694 at76_dbg(DBG_IOCTL,
2695 "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
2696 "auth_mode %s", netdev->name,
2697 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
2698 (priv->auth_mode ==
2699 WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
2700
2701 /* take the old default key if index is invalid */
2702 if ((index < 0) || (index >= WEP_KEYS))
2703 index = priv->wep_key_id;
2704
2705 if (len > 0) {
2706 if (len > WEP_LARGE_KEY_LEN)
2707 len = WEP_LARGE_KEY_LEN;
2708
2709 memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
2710 memcpy(priv->wep_keys[index], extra, len);
2711 priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
2712 WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
2713 priv->wep_enabled = 1;
2714 }
2715
2716 priv->wep_key_id = index;
2717 priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
2718
2719 if (encoding->flags & IW_ENCODE_RESTRICTED)
2720 priv->auth_mode = WLAN_AUTH_SHARED_KEY;
2721 if (encoding->flags & IW_ENCODE_OPEN)
2722 priv->auth_mode = WLAN_AUTH_OPEN;
2723
2724 at76_dbg(DBG_IOCTL,
2725 "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
2726 "key_len %d auth_mode %s", netdev->name,
2727 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
2728 priv->wep_keys_len[priv->wep_key_id],
2729 (priv->auth_mode ==
2730 WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
2731
2732 return -EIWCOMMIT;
2733}
2734
2735static int at76_iw_handler_get_encode(struct net_device *netdev,
2736 struct iw_request_info *info,
2737 struct iw_point *encoding, char *extra)
2738{
2739 struct at76_priv *priv = netdev_priv(netdev);
2740 int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
2741
2742 if ((index < 0) || (index >= WEP_KEYS))
2743 index = priv->wep_key_id;
2744
2745 encoding->flags =
2746 (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
2747 IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
2748
2749 if (!priv->wep_enabled)
2750 encoding->flags |= IW_ENCODE_DISABLED;
2751
2752 if (encoding->pointer) {
2753 encoding->length = priv->wep_keys_len[index];
2754
2755 memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
2756
2757 encoding->flags |= (index + 1);
2758 }
2759
2760 at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
2761 "pointer %p len %d", netdev->name, encoding->flags,
2762 encoding->pointer, encoding->length);
2763 at76_dbg(DBG_IOCTL,
2764 "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
2765 "key_len %d auth_mode %s", netdev->name,
2766 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
2767 priv->wep_keys_len[priv->wep_key_id],
2768 (priv->auth_mode ==
2769 WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
2770
2771 return 0;
2772}
2773
2774static int at76_iw_handler_set_power(struct net_device *netdev,
2775 struct iw_request_info *info,
2776 struct iw_param *prq, char *extra)
2777{
2778 int err = -EIWCOMMIT;
2779 struct at76_priv *priv = netdev_priv(netdev);
2780
2781 at76_dbg(DBG_IOCTL,
2782 "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
2783 netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
2784 prq->value);
2785
2786 if (prq->disabled)
2787 priv->pm_mode = AT76_PM_OFF;
2788 else {
2789 switch (prq->flags & IW_POWER_MODE) {
2790 case IW_POWER_ALL_R:
2791 case IW_POWER_ON:
2792 break;
2793 default:
2794 err = -EINVAL;
2795 goto exit;
2796 }
2797 if (prq->flags & IW_POWER_PERIOD)
2798 priv->pm_period = prq->value;
2799
2800 if (prq->flags & IW_POWER_TIMEOUT) {
2801 err = -EINVAL;
2802 goto exit;
2803 }
2804 priv->pm_mode = AT76_PM_ON;
2805 }
2806exit:
2807 return err;
2808}
2809
2810static int at76_iw_handler_get_power(struct net_device *netdev,
2811 struct iw_request_info *info,
2812 struct iw_param *power, char *extra)
2813{
2814 struct at76_priv *priv = netdev_priv(netdev);
2815
2816 power->disabled = (priv->pm_mode == AT76_PM_OFF);
2817 if (!power->disabled) {
2818 power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
2819 power->value = priv->pm_period;
2820 }
2821
2822 at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
2823 netdev->name, power->disabled ? "disabled" : "enabled",
2824 power->flags, power->value);
2825
2826 return 0;
2827}
2828
2829/*******************************************************************************
2830 * Private IOCTLS
2831 */
2832static int at76_iw_set_short_preamble(struct net_device *netdev,
2833 struct iw_request_info *info, char *name,
2834 char *extra)
2835{
2836 struct at76_priv *priv = netdev_priv(netdev);
2837 int val = *((int *)name);
2838 int ret = -EIWCOMMIT;
2839
2840 at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
2841 netdev->name, val);
2842
2843 if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
2844 ret = -EINVAL;
2845 else
2846 priv->preamble_type = val;
2847
2848 return ret;
2849}
2850
2851static int at76_iw_get_short_preamble(struct net_device *netdev,
2852 struct iw_request_info *info,
2853 union iwreq_data *wrqu, char *extra)
2854{
2855 struct at76_priv *priv = netdev_priv(netdev);
2856
2857 snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
2858 preambles[priv->preamble_type], priv->preamble_type);
2859 return 0;
2860}
2861
2862static int at76_iw_set_debug(struct net_device *netdev,
2863 struct iw_request_info *info,
2864 struct iw_point *data, char *extra)
2865{
2866 char *ptr;
2867 u32 val;
2868
2869 if (data->length > 0) {
2870 val = simple_strtol(extra, &ptr, 0);
2871
2872 if (ptr == extra)
2873 val = DBG_DEFAULTS;
2874
2875 at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
2876 netdev->name, data->length, extra, val);
2877 } else
2878 val = DBG_DEFAULTS;
2879
2880 at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
2881 netdev->name, at76_debug, val);
2882
2883 /* jal: some more output to pin down lockups */
2884 at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
2885 "carrier_ok %d", netdev->name, netif_running(netdev),
2886 netif_queue_stopped(netdev), netif_carrier_ok(netdev));
2887
2888 at76_debug = val;
2889
2890 return 0;
2891}
2892
2893static int at76_iw_get_debug(struct net_device *netdev,
2894 struct iw_request_info *info,
2895 union iwreq_data *wrqu, char *extra)
2896{
2897 snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
2898 return 0;
2899}
2900
2901static int at76_iw_set_powersave_mode(struct net_device *netdev,
2902 struct iw_request_info *info, char *name,
2903 char *extra)
2904{
2905 struct at76_priv *priv = netdev_priv(netdev);
2906 int val = *((int *)name);
2907 int ret = -EIWCOMMIT;
2908
2909 at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
2910 netdev->name, val,
2911 val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
2912 val == AT76_PM_SMART ? "smart save" : "<invalid>");
2913 if (val < AT76_PM_OFF || val > AT76_PM_SMART)
2914 ret = -EINVAL;
2915 else
2916 priv->pm_mode = val;
2917
2918 return ret;
2919}
2920
2921static int at76_iw_get_powersave_mode(struct net_device *netdev,
2922 struct iw_request_info *info,
2923 union iwreq_data *wrqu, char *extra)
2924{
2925 struct at76_priv *priv = netdev_priv(netdev);
2926 int *param = (int *)extra;
2927
2928 param[0] = priv->pm_mode;
2929 return 0;
2930}
2931
2932static int at76_iw_set_scan_times(struct net_device *netdev,
2933 struct iw_request_info *info, char *name,
2934 char *extra)
2935{
2936 struct at76_priv *priv = netdev_priv(netdev);
2937 int mint = *((int *)name);
2938 int maxt = *((int *)name + 1);
2939 int ret = -EIWCOMMIT;
2940
2941 at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
2942 netdev->name, mint, maxt);
2943 if (mint <= 0 || maxt <= 0 || mint > maxt)
2944 ret = -EINVAL;
2945 else {
2946 priv->scan_min_time = mint;
2947 priv->scan_max_time = maxt;
2948 }
2949
2950 return ret;
2951}
2952
2953static int at76_iw_get_scan_times(struct net_device *netdev,
2954 struct iw_request_info *info,
2955 union iwreq_data *wrqu, char *extra)
2956{
2957 struct at76_priv *priv = netdev_priv(netdev);
2958 int *param = (int *)extra;
2959
2960 param[0] = priv->scan_min_time;
2961 param[1] = priv->scan_max_time;
2962 return 0;
2963}
2964
2965static int at76_iw_set_scan_mode(struct net_device *netdev,
2966 struct iw_request_info *info, char *name,
2967 char *extra)
2968{
2969 struct at76_priv *priv = netdev_priv(netdev);
2970 int val = *((int *)name);
2971 int ret = -EIWCOMMIT;
2972
2973 at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
2974 netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
2975 (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
2976
2977 if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
2978 ret = -EINVAL;
2979 else
2980 priv->scan_mode = val;
2981
2982 return ret;
2983}
2984
2985static int at76_iw_get_scan_mode(struct net_device *netdev,
2986 struct iw_request_info *info,
2987 union iwreq_data *wrqu, char *extra)
2988{
2989 struct at76_priv *priv = netdev_priv(netdev);
2990 int *param = (int *)extra;
2991
2992 param[0] = priv->scan_mode;
2993 return 0;
2994}
2995
2996#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
2997
2998/* Standard wireless handlers */
2999static const iw_handler at76_handlers[] = {
3000 AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
3001 AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
3002 AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
3003 AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
3004 AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
3005 AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
3006 AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
3007 AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
3008 AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
3009 AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
3010 AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
3011 AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
3012 AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
3013 AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
3014 AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
3015 AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
3016 AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
3017 AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
3018 AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
3019 AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
3020 AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
3021 AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
3022 AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
3023 AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
3024 AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
3025 AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
3026 AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
3027 AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
3028 AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
3029 AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
3030};
3031
3032#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
3033
3034/* Private wireless handlers */
3035static const iw_handler at76_priv_handlers[] = {
3036 AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
3037 AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
3038 AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
3039 AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
3040 AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
3041 AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
3042 AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
3043 AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
3044 AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
3045 AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
3046};
3047
3048/* Names and arguments of private wireless handlers */
3049static const struct iw_priv_args at76_priv_args[] = {
3050 /* 0 - long, 1 - short */
3051 {AT76_SET_SHORT_PREAMBLE,
3052 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
3053
3054 {AT76_GET_SHORT_PREAMBLE,
3055 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
3056
3057 /* we must pass the new debug mask as a string, because iwpriv cannot
3058 * parse hex numbers starting with 0x :-( */
3059 {AT76_SET_DEBUG,
3060 IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
3061
3062 {AT76_GET_DEBUG,
3063 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
3064
3065 /* 1 - active, 2 - power save, 3 - smart power save */
3066 {AT76_SET_POWERSAVE_MODE,
3067 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
3068
3069 {AT76_GET_POWERSAVE_MODE,
3070 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
3071
3072 /* min_channel_time, max_channel_time */
3073 {AT76_SET_SCAN_TIMES,
3074 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
3075
3076 {AT76_GET_SCAN_TIMES,
3077 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
3078
3079 /* 0 - active, 1 - passive scan */
3080 {AT76_SET_SCAN_MODE,
3081 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
3082
3083 {AT76_GET_SCAN_MODE,
3084 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
3085};
3086
3087static const struct iw_handler_def at76_handler_def = {
3088 .num_standard = ARRAY_SIZE(at76_handlers),
3089 .num_private = ARRAY_SIZE(at76_priv_handlers),
3090 .num_private_args = ARRAY_SIZE(at76_priv_args),
3091 .standard = at76_handlers,
3092 .private = at76_priv_handlers,
3093 .private_args = at76_priv_args,
3094 .get_wireless_stats = at76_get_wireless_stats,
3095};
3096
3097static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
3098
3099/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
3100 * a SNAP OID of 0 (0x00, 0x00, 0x00) */
3101static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
3102
3103static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
3104{
3105 struct at76_priv *priv = netdev_priv(netdev);
3106 struct net_device_stats *stats = &priv->stats;
3107 int ret = 0;
3108 int wlen;
3109 int submit_len;
3110 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
3111 struct ieee80211_hdr_3addr *i802_11_hdr =
3112 (struct ieee80211_hdr_3addr *)tx_buffer->packet;
3113 u8 *payload = i802_11_hdr->payload;
3114 struct ethhdr *eh = (struct ethhdr *)skb->data;
3115
3116 if (netif_queue_stopped(netdev)) {
3117 printk(KERN_ERR "%s: %s called while netdev is stopped\n",
3118 netdev->name, __func__);
3119 /* skip this packet */
3120 dev_kfree_skb(skb);
3121 return 0;
3122 }
3123
3124 if (priv->tx_urb->status == -EINPROGRESS) {
3125 printk(KERN_ERR "%s: %s called while tx urb is pending\n",
3126 netdev->name, __func__);
3127 /* skip this packet */
3128 dev_kfree_skb(skb);
3129 return 0;
3130 }
3131
3132 if (skb->len < ETH_HLEN) {
3133 printk(KERN_ERR "%s: %s: skb too short (%d)\n",
3134 netdev->name, __func__, skb->len);
3135 dev_kfree_skb(skb);
3136 return 0;
3137 }
3138
3139 at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
3140
3141 /* we can get rid of memcpy if we set netdev->hard_header_len to
3142 reserve enough space, but we would need to keep the skb around */
3143
3144 if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
3145 /* this is a 802.3 packet */
3146 if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
3147 && skb->data[ETH_HLEN] == rfc1042sig[0]
3148 && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
3149 /* higher layer delivered SNAP header - keep it */
3150 memcpy(payload, skb->data + ETH_HLEN,
3151 skb->len - ETH_HLEN);
3152 wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
3153 } else {
3154 printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
3155 "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
3156 priv->netdev->name, skb->data[ETH_HLEN],
3157 skb->data[ETH_HLEN + 1],
3158 skb->data[ETH_HLEN + 2]);
3159 dev_kfree_skb(skb);
3160 return 0;
3161 }
3162 } else {
3163 /* add RFC 1042 header in front */
3164 memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
3165 memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
3166 skb->len - offsetof(struct ethhdr, h_proto));
3167 wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
3168 offsetof(struct ethhdr, h_proto);
3169 }
3170
3171 /* make wireless header */
3172 i802_11_hdr->frame_ctl =
3173 cpu_to_le16(IEEE80211_FTYPE_DATA |
3174 (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
3175 (priv->iw_mode ==
3176 IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
3177
3178 if (priv->iw_mode == IW_MODE_ADHOC) {
3179 memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
3180 memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
3181 memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
3182 } else if (priv->iw_mode == IW_MODE_INFRA) {
3183 memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
3184 memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
3185 memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
3186 }
3187
3188 i802_11_hdr->duration_id = cpu_to_le16(0);
3189 i802_11_hdr->seq_ctl = cpu_to_le16(0);
3190
3191 /* setup 'Atmel' header */
3192 tx_buffer->wlength = cpu_to_le16(wlen);
3193 tx_buffer->tx_rate = priv->txrate;
3194 /* for broadcast destination addresses, the firmware 0.100.x
3195 seems to choose the highest rate set with CMD_STARTUP in
3196 basic_rate_set replacing this value */
3197
3198 memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
3199
3200 tx_buffer->padding = at76_calc_padding(wlen);
3201 submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
3202
3203 at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
3204 hex2str(skb->data, 32));
3205 at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
3206 priv->netdev->name,
3207 le16_to_cpu(tx_buffer->wlength),
3208 tx_buffer->padding, tx_buffer->tx_rate,
3209 hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
3210 at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
3211 hex2str(payload, 48));
3212
3213 /* send stuff */
3214 netif_stop_queue(netdev);
3215 netdev->trans_start = jiffies;
3216
3217 usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
3218 submit_len, at76_tx_callback, priv);
3219 ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
3220 if (ret) {
3221 stats->tx_errors++;
3222 printk(KERN_ERR "%s: error in tx submit urb: %d\n",
3223 netdev->name, ret);
3224 if (ret == -EINVAL)
3225 printk(KERN_ERR
3226 "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
3227 priv->netdev->name, priv->tx_urb,
3228 priv->tx_urb->hcpriv, priv->tx_urb->complete);
3229 } else {
3230 stats->tx_bytes += skb->len;
3231 dev_kfree_skb(skb);
3232 }
3233
3234 return ret;
3235}
3236
3237static void at76_tx_timeout(struct net_device *netdev)
3238{
3239 struct at76_priv *priv = netdev_priv(netdev);
3240
3241 if (!priv)
3242 return;
3243 dev_warn(&netdev->dev, "tx timeout.");
3244
3245 usb_unlink_urb(priv->tx_urb);
3246 priv->stats.tx_errors++;
3247}
3248
3249static int at76_submit_rx_urb(struct at76_priv *priv)
3250{
3251 int ret;
3252 int size;
3253 struct sk_buff *skb = priv->rx_skb;
3254
3255 if (!priv->rx_urb) {
3256 printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
3257 priv->netdev->name, __func__);
3258 return -EFAULT;
3259 }
3260
3261 if (!skb) {
3262 skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
3263 if (!skb) {
3264 printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
3265 priv->netdev->name);
3266 ret = -ENOMEM;
3267 goto exit;
3268 }
3269 priv->rx_skb = skb;
3270 } else {
3271 skb_push(skb, skb_headroom(skb));
3272 skb_trim(skb, 0);
3273 }
3274
3275 size = skb_tailroom(skb);
3276 usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
3277 skb_put(skb, size), size, at76_rx_callback, priv);
3278 ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
3279 if (ret < 0) {
3280 if (ret == -ENODEV)
3281 at76_dbg(DBG_DEVSTART,
3282 "usb_submit_urb returned -ENODEV");
3283 else
3284 printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
3285 priv->netdev->name, ret);
3286 }
3287
3288exit:
3289 if (ret < 0 && ret != -ENODEV)
3290 printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
3291 "driver and/or power cycle the device\n",
3292 priv->netdev->name);
3293
3294 return ret;
3295}
3296
3297static int at76_open(struct net_device *netdev)
3298{
3299 struct at76_priv *priv = netdev_priv(netdev);
3300 int ret = 0;
3301
3302 at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
3303
3304 if (mutex_lock_interruptible(&priv->mtx))
3305 return -EINTR;
3306
3307 /* if netdev->dev_addr != priv->mac_addr we must
3308 set the mac address in the device ! */
3309 if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
3310 if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
3311 at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
3312 netdev->name, mac2str(netdev->dev_addr));
3313 }
3314
3315 priv->scan_state = SCAN_IDLE;
3316 priv->last_scan = jiffies;
3317
3318 ret = at76_submit_rx_urb(priv);
3319 if (ret < 0) {
3320 printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
3321 netdev->name, ret);
3322 goto error;
3323 }
3324
3325 schedule_delayed_work(&priv->dwork_restart, 0);
3326
3327 at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
3328error:
3329 mutex_unlock(&priv->mtx);
3330 return ret < 0 ? ret : 0;
3331}
3332
3333static int at76_stop(struct net_device *netdev)
3334{
3335 struct at76_priv *priv = netdev_priv(netdev);
3336
3337 at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
3338
3339 if (mutex_lock_interruptible(&priv->mtx))
3340 return -EINTR;
3341
3342 at76_quiesce(priv);
3343
3344 if (!priv->device_unplugged) {
3345 /* We are called by "ifconfig ethX down", not because the
3346 * device is not available anymore. */
3347 at76_set_radio(priv, 0);
3348
3349 /* We unlink rx_urb because at76_open() re-submits it.
3350 * If unplugged, at76_delete_device() takes care of it. */
3351 usb_kill_urb(priv->rx_urb);
3352 }
3353
3354 /* free the bss_list */
3355 at76_free_bss_list(priv);
3356
3357 mutex_unlock(&priv->mtx);
3358 at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
3359
3360 return 0;
3361}
3362
3363static void at76_ethtool_get_drvinfo(struct net_device *netdev,
3364 struct ethtool_drvinfo *info)
3365{
3366 struct at76_priv *priv = netdev_priv(netdev);
3367
3368 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
3369 strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
3370
3371 usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
3372
3373 snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
3374 priv->fw_version.major, priv->fw_version.minor,
3375 priv->fw_version.patch, priv->fw_version.build);
3376}
3377
3378static u32 at76_ethtool_get_link(struct net_device *netdev)
3379{
3380 struct at76_priv *priv = netdev_priv(netdev);
3381 return priv->mac_state == MAC_CONNECTED;
3382}
3383
3384static struct ethtool_ops at76_ethtool_ops = {
3385 .get_drvinfo = at76_ethtool_get_drvinfo,
3386 .get_link = at76_ethtool_get_link,
3387};
3388
3389/* Download external firmware */
3390static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
3391{
3392 int ret;
3393 int op_mode;
3394 int blockno = 0;
3395 int bsize;
3396 u8 *block;
3397 u8 *buf = fwe->extfw;
3398 int size = fwe->extfw_size;
3399
3400 if (!buf || !size)
3401 return -ENOENT;
3402
3403 op_mode = at76_get_op_mode(udev);
3404 at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
3405
3406 if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
3407 dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
3408 op_mode);
3409 return -EINVAL;
3410 }
3411
3412 block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
3413 if (!block)
3414 return -ENOMEM;
3415
3416 at76_dbg(DBG_DEVSTART, "downloading external firmware");
3417
3418 /* for fw >= 0.100, the device needs an extra empty block */
3419 do {
3420 bsize = min_t(int, size, FW_BLOCK_SIZE);
3421 memcpy(block, buf, bsize);
3422 at76_dbg(DBG_DEVSTART,
3423 "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
3424 size, bsize, blockno);
3425 ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
3426 if (ret != bsize) {
3427 dev_printk(KERN_ERR, &udev->dev,
3428 "loading %dth firmware block failed: %d\n",
3429 blockno, ret);
3430 goto exit;
3431 }
3432 buf += bsize;
3433 size -= bsize;
3434 blockno++;
3435 } while (bsize > 0);
3436
3437 if (at76_is_505a(fwe->board_type)) {
3438 at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
3439 schedule_timeout_interruptible(HZ / 5 + 1);
3440 }
3441
3442exit:
3443 kfree(block);
3444 if (ret < 0)
3445 dev_printk(KERN_ERR, &udev->dev,
3446 "downloading external firmware failed: %d\n", ret);
3447 return ret;
3448}
3449
3450/* Download internal firmware */
3451static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
3452{
3453 int ret;
3454 int need_remap = !at76_is_505a(fwe->board_type);
3455
3456 ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
3457 need_remap ? 0 : 2 * HZ);
3458
3459 if (ret < 0) {
3460 dev_printk(KERN_ERR, &udev->dev,
3461 "downloading internal fw failed with %d\n", ret);
3462 goto exit;
3463 }
3464
3465 at76_dbg(DBG_DEVSTART, "sending REMAP");
3466
3467 /* no REMAP for 505A (see SF driver) */
3468 if (need_remap) {
3469 ret = at76_remap(udev);
3470 if (ret < 0) {
3471 dev_printk(KERN_ERR, &udev->dev,
3472 "sending REMAP failed with %d\n", ret);
3473 goto exit;
3474 }
3475 }
3476
3477 at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
3478 schedule_timeout_interruptible(2 * HZ + 1);
3479 usb_reset_device(udev);
3480
3481exit:
3482 return ret;
3483}
3484
3485static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
3486{
3487 /* common criteria for both modi */
3488
3489 int ret = (priv->essid_size == 0 /* ANY ssid */ ||
3490 (priv->essid_size == ptr->ssid_len &&
3491 !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
3492 if (!ret)
3493 at76_dbg(DBG_BSS_MATCH,
3494 "%s bss table entry %p: essid didn't match",
3495 priv->netdev->name, ptr);
3496 return ret;
3497}
3498
3499static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
3500{
3501 int ret;
3502
3503 if (priv->iw_mode == IW_MODE_ADHOC)
3504 ret = ptr->capa & WLAN_CAPABILITY_IBSS;
3505 else
3506 ret = ptr->capa & WLAN_CAPABILITY_ESS;
3507 if (!ret)
3508 at76_dbg(DBG_BSS_MATCH,
3509 "%s bss table entry %p: mode didn't match",
3510 priv->netdev->name, ptr);
3511 return ret;
3512}
3513
3514static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
3515{
3516 int i;
3517
3518 for (i = 0; i < ptr->rates_len; i++) {
3519 u8 rate = ptr->rates[i];
3520
3521 if (!(rate & 0x80))
3522 continue;
3523
3524 /* this is a basic rate we have to support
3525 (see IEEE802.11, ch. 7.3.2.2) */
3526 if (rate != (0x80 | hw_rates[0])
3527 && rate != (0x80 | hw_rates[1])
3528 && rate != (0x80 | hw_rates[2])
3529 && rate != (0x80 | hw_rates[3])) {
3530 at76_dbg(DBG_BSS_MATCH,
3531 "%s: bss table entry %p: basic rate %02x not "
3532 "supported", priv->netdev->name, ptr, rate);
3533 return 0;
3534 }
3535 }
3536
3537 /* if we use short preamble, the bss must support it */
3538 if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
3539 !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
3540 at76_dbg(DBG_BSS_MATCH,
3541 "%s: %p does not support short preamble",
3542 priv->netdev->name, ptr);
3543 return 0;
3544 } else
3545 return 1;
3546}
3547
3548static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
3549{
3550 if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
3551 /* we have disabled WEP, but the BSS signals privacy */
3552 at76_dbg(DBG_BSS_MATCH,
3553 "%s: bss table entry %p: requires encryption",
3554 priv->netdev->name, ptr);
3555 return 0;
3556 }
3557 /* otherwise if the BSS does not signal privacy it may well
3558 accept encrypted packets from us ... */
3559 return 1;
3560}
3561
3562static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
3563{
3564 if (!priv->wanted_bssid_valid ||
3565 !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
3566 return 1;
3567
3568 at76_dbg(DBG_BSS_MATCH,
3569 "%s: requested bssid - %s does not match",
3570 priv->netdev->name, mac2str(priv->wanted_bssid));
3571 at76_dbg(DBG_BSS_MATCH,
3572 " AP bssid - %s of bss table entry %p",
3573 mac2str(ptr->bssid), ptr);
3574 return 0;
3575}
3576
3577/**
3578 * at76_match_bss - try to find a matching bss in priv->bss
3579 *
3580 * last - last bss tried
3581 *
3582 * last == NULL signals a new round starting with priv->bss_list.next
3583 * this function must be called inside an acquired priv->bss_list_spinlock
3584 * otherwise the timeout on bss may remove the newly chosen entry
3585 */
3586static struct bss_info *at76_match_bss(struct at76_priv *priv,
3587 struct bss_info *last)
3588{
3589 struct bss_info *ptr = NULL;
3590 struct list_head *curr;
3591
3592 curr = last ? last->list.next : priv->bss_list.next;
3593 while (curr != &priv->bss_list) {
3594 ptr = list_entry(curr, struct bss_info, list);
3595 if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
3596 && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
3597 && at76_match_bssid(priv, ptr))
3598 break;
3599 curr = curr->next;
3600 }
3601
3602 if (curr == &priv->bss_list)
3603 ptr = NULL;
3604 /* otherwise ptr points to the struct bss_info we have chosen */
3605
3606 at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
3607 __func__, ptr);
3608 return ptr;
3609}
3610
3611/* Start joining a matching BSS, or create own IBSS */
3612static void at76_work_join(struct work_struct *work)
3613{
3614 struct at76_priv *priv = container_of(work, struct at76_priv,
3615 work_join);
3616 int ret;
3617 unsigned long flags;
3618
3619 mutex_lock(&priv->mtx);
3620
3621 WARN_ON(priv->mac_state != MAC_JOINING);
3622 if (priv->mac_state != MAC_JOINING)
3623 goto exit;
3624
3625 /* secure the access to priv->curr_bss ! */
3626 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
3627 priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
3628 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
3629
3630 if (!priv->curr_bss) {
3631 /* here we haven't found a matching (i)bss ... */
3632 if (priv->iw_mode == IW_MODE_ADHOC) {
3633 at76_set_mac_state(priv, MAC_OWN_IBSS);
3634 at76_start_ibss(priv);
3635 goto exit;
3636 }
3637 /* haven't found a matching BSS in infra mode - try again */
3638 at76_set_mac_state(priv, MAC_SCANNING);
3639 schedule_work(&priv->work_start_scan);
3640 goto exit;
3641 }
3642
3643 ret = at76_join_bss(priv, priv->curr_bss);
3644 if (ret < 0) {
3645 printk(KERN_ERR "%s: join_bss failed with %d\n",
3646 priv->netdev->name, ret);
3647 goto exit;
3648 }
3649
3650 ret = at76_wait_completion(priv, CMD_JOIN);
3651 if (ret != CMD_STATUS_COMPLETE) {
3652 if (ret != CMD_STATUS_TIME_OUT)
3653 printk(KERN_ERR "%s: join_bss completed with %d\n",
3654 priv->netdev->name, ret);
3655 else
3656 printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
3657 priv->netdev->name,
3658 mac2str(priv->curr_bss->bssid));
3659
3660 /* retry next BSS immediately */
3661 schedule_work(&priv->work_join);
3662 goto exit;
3663 }
3664
3665 /* here we have joined the (I)BSS */
3666 if (priv->iw_mode == IW_MODE_ADHOC) {
3667 struct bss_info *bptr = priv->curr_bss;
3668 at76_set_mac_state(priv, MAC_CONNECTED);
3669 /* get ESSID, BSSID and channel for priv->curr_bss */
3670 priv->essid_size = bptr->ssid_len;
3671 memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
3672 memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
3673 priv->channel = bptr->channel;
3674 at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
3675 netif_carrier_on(priv->netdev);
3676 netif_start_queue(priv->netdev);
3677 /* just to be sure */
3678 cancel_delayed_work(&priv->dwork_get_scan);
3679 cancel_delayed_work(&priv->dwork_auth);
3680 cancel_delayed_work(&priv->dwork_assoc);
3681 } else {
3682 /* send auth req */
3683 priv->retries = AUTH_RETRIES;
3684 at76_set_mac_state(priv, MAC_AUTH);
3685 at76_auth_req(priv, priv->curr_bss, 1, NULL);
3686 at76_dbg(DBG_MGMT_TIMER,
3687 "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
3688 schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
3689 }
3690
3691exit:
3692 mutex_unlock(&priv->mtx);
3693}
3694
3695/* Reap scan results */
3696static void at76_dwork_get_scan(struct work_struct *work)
3697{
3698 int status;
3699 int ret;
3700 struct at76_priv *priv = container_of(work, struct at76_priv,
3701 dwork_get_scan.work);
3702
3703 mutex_lock(&priv->mtx);
3704 WARN_ON(priv->mac_state != MAC_SCANNING);
3705 if (priv->mac_state != MAC_SCANNING)
3706 goto exit;
3707
3708 status = at76_get_cmd_status(priv->udev, CMD_SCAN);
3709 if (status < 0) {
3710 printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
3711 priv->netdev->name, __func__, status);
3712 status = CMD_STATUS_IN_PROGRESS;
3713 /* INFO: Hope it was a one off error - if not, scanning
3714 further down the line and stop this cycle */
3715 }
3716 at76_dbg(DBG_PROGRESS,
3717 "%s %s: got cmd_status %d (state %s, need_any %d)",
3718 priv->netdev->name, __func__, status,
3719 mac_states[priv->mac_state], priv->scan_need_any);
3720
3721 if (status != CMD_STATUS_COMPLETE) {
3722 if ((status != CMD_STATUS_IN_PROGRESS) &&
3723 (status != CMD_STATUS_IDLE))
3724 printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
3725 priv->netdev->name, __func__,
3726 at76_get_cmd_status_string(status));
3727
3728 /* the first cmd status after scan start is always a IDLE ->
3729 start the timer to poll again until COMPLETED */
3730 at76_dbg(DBG_MGMT_TIMER,
3731 "%s:%d: starting mgmt_timer for %d ticks",
3732 __func__, __LINE__, SCAN_POLL_INTERVAL);
3733 schedule_delayed_work(&priv->dwork_get_scan,
3734 SCAN_POLL_INTERVAL);
3735 goto exit;
3736 }
3737
3738 if (at76_debug & DBG_BSS_TABLE)
3739 at76_dump_bss_table(priv);
3740
3741 if (priv->scan_need_any) {
3742 ret = at76_start_scan(priv, 0);
3743 if (ret < 0)
3744 printk(KERN_ERR
3745 "%s: %s: start_scan (ANY) failed with %d\n",
3746 priv->netdev->name, __func__, ret);
3747 at76_dbg(DBG_MGMT_TIMER,
3748 "%s:%d: starting mgmt_timer for %d ticks", __func__,
3749 __LINE__, SCAN_POLL_INTERVAL);
3750 schedule_delayed_work(&priv->dwork_get_scan,
3751 SCAN_POLL_INTERVAL);
3752 priv->scan_need_any = 0;
3753 } else {
3754 priv->scan_state = SCAN_COMPLETED;
3755 /* report the end of scan to user space */
3756 at76_iwevent_scan_complete(priv->netdev);
3757 at76_set_mac_state(priv, MAC_JOINING);
3758 schedule_work(&priv->work_join);
3759 }
3760
3761exit:
3762 mutex_unlock(&priv->mtx);
3763}
3764
3765/* Handle loss of beacons from the AP */
3766static void at76_dwork_beacon(struct work_struct *work)
3767{
3768 struct at76_priv *priv = container_of(work, struct at76_priv,
3769 dwork_beacon.work);
3770
3771 mutex_lock(&priv->mtx);
3772 if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
3773 goto exit;
3774
3775 /* We haven't received any beacons from out AP for BEACON_TIMEOUT */
3776 printk(KERN_INFO "%s: lost beacon bssid %s\n",
3777 priv->netdev->name, mac2str(priv->curr_bss->bssid));
3778
3779 netif_carrier_off(priv->netdev);
3780 netif_stop_queue(priv->netdev);
3781 at76_iwevent_bss_disconnect(priv->netdev);
3782 at76_set_mac_state(priv, MAC_SCANNING);
3783 schedule_work(&priv->work_start_scan);
3784
3785exit:
3786 mutex_unlock(&priv->mtx);
3787}
3788
3789/* Handle authentication response timeout */
3790static void at76_dwork_auth(struct work_struct *work)
3791{
3792 struct at76_priv *priv = container_of(work, struct at76_priv,
3793 dwork_auth.work);
3794
3795 mutex_lock(&priv->mtx);
3796 WARN_ON(priv->mac_state != MAC_AUTH);
3797 if (priv->mac_state != MAC_AUTH)
3798 goto exit;
3799
3800 at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
3801 priv->netdev->name);
3802
3803 if (priv->retries-- >= 0) {
3804 at76_auth_req(priv, priv->curr_bss, 1, NULL);
3805 at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
3806 __func__, __LINE__);
3807 schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
3808 } else {
3809 /* try to get next matching BSS */
3810 at76_set_mac_state(priv, MAC_JOINING);
3811 schedule_work(&priv->work_join);
3812 }
3813
3814exit:
3815 mutex_unlock(&priv->mtx);
3816}
3817
3818/* Handle association response timeout */
3819static void at76_dwork_assoc(struct work_struct *work)
3820{
3821 struct at76_priv *priv = container_of(work, struct at76_priv,
3822 dwork_assoc.work);
3823
3824 mutex_lock(&priv->mtx);
3825 WARN_ON(priv->mac_state != MAC_ASSOC);
3826 if (priv->mac_state != MAC_ASSOC)
3827 goto exit;
3828
3829 at76_dbg(DBG_PROGRESS, "%s: association response timeout",
3830 priv->netdev->name);
3831
3832 if (priv->retries-- >= 0) {
3833 at76_assoc_req(priv, priv->curr_bss);
3834 at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
3835 __func__, __LINE__);
3836 schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
3837 } else {
3838 /* try to get next matching BSS */
3839 at76_set_mac_state(priv, MAC_JOINING);
3840 schedule_work(&priv->work_join);
3841 }
3842
3843exit:
3844 mutex_unlock(&priv->mtx);
3845}
3846
3847/* Read new bssid in ad-hoc mode */
3848static void at76_work_new_bss(struct work_struct *work)
3849{
3850 struct at76_priv *priv = container_of(work, struct at76_priv,
3851 work_new_bss);
3852 int ret;
3853 struct mib_mac_mgmt mac_mgmt;
3854
3855 mutex_lock(&priv->mtx);
3856
3857 ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
3858 sizeof(struct mib_mac_mgmt));
3859 if (ret < 0) {
3860 printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
3861 priv->netdev->name, ret);
3862 goto exit;
3863 }
3864
3865 at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
3866 memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
3867 at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
3868
3869 at76_iwevent_bss_connect(priv->netdev, priv->bssid);
3870
3871 priv->mib_buf.type = MIB_MAC_MGMT;
3872 priv->mib_buf.size = 1;
3873 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
3874 priv->mib_buf.data.byte = 0;
3875
3876 ret = at76_set_mib(priv, &priv->mib_buf);
3877 if (ret < 0)
3878 printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
3879 priv->netdev->name, ret);
3880
3881exit:
3882 mutex_unlock(&priv->mtx);
3883}
3884
3885static int at76_startup_device(struct at76_priv *priv)
3886{
3887 struct at76_card_config *ccfg = &priv->card_config;
3888 int ret;
3889
3890 at76_dbg(DBG_PARAMS,
3891 "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
3892 "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
3893 hex2str(priv->essid, IW_ESSID_MAX_SIZE),
3894 priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
3895 priv->channel, priv->wep_enabled ? "enabled" : "disabled",
3896 priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
3897 at76_dbg(DBG_PARAMS,
3898 "%s param: preamble %s rts %d retry %d frag %d "
3899 "txrate %s auth_mode %d", priv->netdev->name,
3900 preambles[priv->preamble_type], priv->rts_threshold,
3901 priv->short_retry_limit, priv->frag_threshold,
3902 priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
3903 TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
3904 TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
3905 TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
3906 TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
3907 at76_dbg(DBG_PARAMS,
3908 "%s param: pm_mode %d pm_period %d auth_mode %s "
3909 "scan_times %d %d scan_mode %s",
3910 priv->netdev->name, priv->pm_mode, priv->pm_period,
3911 priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
3912 priv->scan_min_time, priv->scan_max_time,
3913 priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
3914
3915 memset(ccfg, 0, sizeof(struct at76_card_config));
3916 ccfg->promiscuous_mode = 0;
3917 ccfg->short_retry_limit = priv->short_retry_limit;
3918
3919 if (priv->wep_enabled) {
3920 if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
3921 ccfg->encryption_type = 2;
3922 else
3923 ccfg->encryption_type = 1;
3924
3925 /* jal: always exclude unencrypted if WEP is active */
3926 ccfg->exclude_unencrypted = 1;
3927 } else {
3928 ccfg->exclude_unencrypted = 0;
3929 ccfg->encryption_type = 0;
3930 }
3931
3932 ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
3933 ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
3934
3935 memcpy(ccfg->basic_rate_set, hw_rates, 4);
3936 /* jal: really needed, we do a set_mib for autorate later ??? */
3937 ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
3938 ccfg->channel = priv->channel;
3939 ccfg->privacy_invoked = priv->wep_enabled;
3940 memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
3941 ccfg->ssid_len = priv->essid_size;
3942
3943 ccfg->wep_default_key_id = priv->wep_key_id;
3944 memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
3945
3946 ccfg->short_preamble = priv->preamble_type;
3947 ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
3948
3949 ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
3950 sizeof(struct at76_card_config));
3951 if (ret < 0) {
3952 printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
3953 priv->netdev->name, ret);
3954 return ret;
3955 }
3956
3957 at76_wait_completion(priv, CMD_STARTUP);
3958
3959 /* remove BSSID from previous run */
3960 memset(priv->bssid, 0, ETH_ALEN);
3961
3962 if (at76_set_radio(priv, 1) == 1)
3963 at76_wait_completion(priv, CMD_RADIO_ON);
3964
3965 ret = at76_set_preamble(priv, priv->preamble_type);
3966 if (ret < 0)
3967 return ret;
3968
3969 ret = at76_set_frag(priv, priv->frag_threshold);
3970 if (ret < 0)
3971 return ret;
3972
3973 ret = at76_set_rts(priv, priv->rts_threshold);
3974 if (ret < 0)
3975 return ret;
3976
3977 ret = at76_set_autorate_fallback(priv,
3978 priv->txrate == TX_RATE_AUTO ? 1 : 0);
3979 if (ret < 0)
3980 return ret;
3981
3982 ret = at76_set_pm_mode(priv);
3983 if (ret < 0)
3984 return ret;
3985
3986 if (at76_debug & DBG_MIB) {
3987 at76_dump_mib_mac(priv);
3988 at76_dump_mib_mac_addr(priv);
3989 at76_dump_mib_mac_mgmt(priv);
3990 at76_dump_mib_mac_wep(priv);
3991 at76_dump_mib_mdomain(priv);
3992 at76_dump_mib_phy(priv);
3993 at76_dump_mib_local(priv);
3994 }
3995
3996 return 0;
3997}
3998
3999/* Restart the interface */
4000static void at76_dwork_restart(struct work_struct *work)
4001{
4002 struct at76_priv *priv = container_of(work, struct at76_priv,
4003 dwork_restart.work);
4004
4005 mutex_lock(&priv->mtx);
4006
4007 netif_carrier_off(priv->netdev); /* stop netdev watchdog */
4008 netif_stop_queue(priv->netdev); /* stop tx data packets */
4009
4010 at76_startup_device(priv);
4011
4012 if (priv->iw_mode != IW_MODE_MONITOR) {
4013 priv->netdev->type = ARPHRD_ETHER;
4014 at76_set_mac_state(priv, MAC_SCANNING);
4015 schedule_work(&priv->work_start_scan);
4016 } else {
4017 priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
4018 at76_start_monitor(priv);
4019 }
4020
4021 mutex_unlock(&priv->mtx);
4022}
4023
4024/* Initiate scanning */
4025static void at76_work_start_scan(struct work_struct *work)
4026{
4027 struct at76_priv *priv = container_of(work, struct at76_priv,
4028 work_start_scan);
4029 int ret;
4030
4031 mutex_lock(&priv->mtx);
4032
4033 WARN_ON(priv->mac_state != MAC_SCANNING);
4034 if (priv->mac_state != MAC_SCANNING)
4035 goto exit;
4036
4037 /* only clear the bss list when a scan is actively initiated,
4038 * otherwise simply rely on at76_bss_list_timeout */
4039 if (priv->scan_state == SCAN_IN_PROGRESS) {
4040 at76_free_bss_list(priv);
4041 priv->scan_need_any = 1;
4042 } else
4043 priv->scan_need_any = 0;
4044
4045 ret = at76_start_scan(priv, 1);
4046
4047 if (ret < 0)
4048 printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
4049 priv->netdev->name, __func__, ret);
4050 else {
4051 at76_dbg(DBG_MGMT_TIMER,
4052 "%s:%d: starting mgmt_timer for %d ticks",
4053 __func__, __LINE__, SCAN_POLL_INTERVAL);
4054 schedule_delayed_work(&priv->dwork_get_scan,
4055 SCAN_POLL_INTERVAL);
4056 }
4057
4058exit:
4059 mutex_unlock(&priv->mtx);
4060}
4061
4062/* Enable or disable promiscuous mode */
4063static void at76_work_set_promisc(struct work_struct *work)
4064{
4065 struct at76_priv *priv = container_of(work, struct at76_priv,
4066 work_set_promisc);
4067 int ret = 0;
4068
4069 mutex_lock(&priv->mtx);
4070
4071 priv->mib_buf.type = MIB_LOCAL;
4072 priv->mib_buf.size = 1;
4073 priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
4074 priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
4075
4076 ret = at76_set_mib(priv, &priv->mib_buf);
4077 if (ret < 0)
4078 printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
4079 priv->netdev->name, ret);
4080
4081 mutex_unlock(&priv->mtx);
4082}
4083
4084/* Submit Rx urb back to the device */
4085static void at76_work_submit_rx(struct work_struct *work)
4086{
4087 struct at76_priv *priv = container_of(work, struct at76_priv,
4088 work_submit_rx);
4089
4090 mutex_lock(&priv->mtx);
4091 at76_submit_rx_urb(priv);
4092 mutex_unlock(&priv->mtx);
4093}
4094
4095/* We got an association response */
4096static void at76_rx_mgmt_assoc(struct at76_priv *priv,
4097 struct at76_rx_buffer *buf)
4098{
4099 struct ieee80211_assoc_response *resp =
4100 (struct ieee80211_assoc_response *)buf->packet;
4101 u16 assoc_id = le16_to_cpu(resp->aid);
4102 u16 status = le16_to_cpu(resp->status);
4103
4104 at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
4105 "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
4106 mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
4107 status, assoc_id, hex2str(resp->info_element->data,
4108 resp->info_element->len));
4109
4110 if (priv->mac_state != MAC_ASSOC) {
4111 printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
4112 priv->netdev->name, mac_states[priv->mac_state]);
4113 return;
4114 }
4115
4116 BUG_ON(!priv->curr_bss);
4117
4118 cancel_delayed_work(&priv->dwork_assoc);
4119 if (status == WLAN_STATUS_SUCCESS) {
4120 struct bss_info *ptr = priv->curr_bss;
4121 priv->assoc_id = assoc_id & 0x3fff;
4122 /* update iwconfig params */
4123 memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
4124 memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
4125 priv->essid_size = ptr->ssid_len;
4126 priv->channel = ptr->channel;
4127 schedule_work(&priv->work_assoc_done);
4128 } else {
4129 at76_set_mac_state(priv, MAC_JOINING);
4130 schedule_work(&priv->work_join);
4131 }
4132}
4133
4134/* Process disassociation request from the AP */
4135static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
4136 struct at76_rx_buffer *buf)
4137{
4138 struct ieee80211_disassoc *resp =
4139 (struct ieee80211_disassoc *)buf->packet;
4140 struct ieee80211_hdr_3addr *mgmt = &resp->header;
4141
4142 at76_dbg(DBG_RX_MGMT,
4143 "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
4144 priv->netdev->name, mac2str(mgmt->addr3),
4145 le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
4146
4147 /* We are not connected, ignore */
4148 if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
4149 || !priv->curr_bss)
4150 return;
4151
4152 /* Not our BSSID, ignore */
4153 if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
4154 return;
4155
4156 /* Not for our STA and not broadcast, ignore */
4157 if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
4158 && !is_broadcast_ether_addr(mgmt->addr1))
4159 return;
4160
4161 if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
4162 && priv->mac_state != MAC_JOINING) {
4163 printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
4164 priv->netdev->name, mac_states[priv->mac_state]);
4165 return;
4166 }
4167
4168 if (priv->mac_state == MAC_CONNECTED) {
4169 netif_carrier_off(priv->netdev);
4170 netif_stop_queue(priv->netdev);
4171 at76_iwevent_bss_disconnect(priv->netdev);
4172 }
4173 cancel_delayed_work(&priv->dwork_get_scan);
4174 cancel_delayed_work(&priv->dwork_beacon);
4175 cancel_delayed_work(&priv->dwork_auth);
4176 cancel_delayed_work(&priv->dwork_assoc);
4177 at76_set_mac_state(priv, MAC_JOINING);
4178 schedule_work(&priv->work_join);
4179}
4180
4181static void at76_rx_mgmt_auth(struct at76_priv *priv,
4182 struct at76_rx_buffer *buf)
4183{
4184 struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
4185 struct ieee80211_hdr_3addr *mgmt = &resp->header;
4186 int seq_nr = le16_to_cpu(resp->transaction);
4187 int alg = le16_to_cpu(resp->algorithm);
4188 int status = le16_to_cpu(resp->status);
4189
4190 at76_dbg(DBG_RX_MGMT,
4191 "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
4192 "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
4193 alg, seq_nr, status, mac2str(mgmt->addr1));
4194
4195 if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
4196 at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
4197 priv->netdev->name, hex2str(resp->info_element, 18));
4198
4199 if (priv->mac_state != MAC_AUTH) {
4200 printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
4201 priv->netdev->name, mac_states[priv->mac_state]);
4202 return;
4203 }
4204 if (priv->auth_mode != alg) {
4205 printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
4206 priv->netdev->name, alg);
4207 return;
4208 }
4209
4210 BUG_ON(!priv->curr_bss);
4211
4212 /* Not our BSSID or not for our STA, ignore */
4213 if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
4214 || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
4215 return;
4216
4217 cancel_delayed_work(&priv->dwork_auth);
4218 if (status != WLAN_STATUS_SUCCESS) {
4219 /* try to join next bss */
4220 at76_set_mac_state(priv, MAC_JOINING);
4221 schedule_work(&priv->work_join);
4222 return;
4223 }
4224
4225 if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
4226 priv->retries = ASSOC_RETRIES;
4227 at76_set_mac_state(priv, MAC_ASSOC);
4228 at76_assoc_req(priv, priv->curr_bss);
4229 at76_dbg(DBG_MGMT_TIMER,
4230 "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
4231 schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
4232 return;
4233 }
4234
4235 WARN_ON(seq_nr != 2);
4236 at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
4237 at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
4238 __LINE__);
4239 schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
4240}
4241
4242static void at76_rx_mgmt_deauth(struct at76_priv *priv,
4243 struct at76_rx_buffer *buf)
4244{
4245 struct ieee80211_disassoc *resp =
4246 (struct ieee80211_disassoc *)buf->packet;
4247 struct ieee80211_hdr_3addr *mgmt = &resp->header;
4248
4249 at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
4250 "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
4251 priv->netdev->name, mac2str(mgmt->addr3),
4252 le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
4253
4254 if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
4255 && priv->mac_state != MAC_CONNECTED) {
4256 printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
4257 priv->netdev->name, mac_states[priv->mac_state]);
4258 return;
4259 }
4260
4261 BUG_ON(!priv->curr_bss);
4262
4263 /* Not our BSSID, ignore */
4264 if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
4265 return;
4266
4267 /* Not for our STA and not broadcast, ignore */
4268 if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
4269 && !is_broadcast_ether_addr(mgmt->addr1))
4270 return;
4271
4272 if (priv->mac_state == MAC_CONNECTED)
4273 at76_iwevent_bss_disconnect(priv->netdev);
4274
4275 at76_set_mac_state(priv, MAC_JOINING);
4276 schedule_work(&priv->work_join);
4277 cancel_delayed_work(&priv->dwork_get_scan);
4278 cancel_delayed_work(&priv->dwork_beacon);
4279 cancel_delayed_work(&priv->dwork_auth);
4280 cancel_delayed_work(&priv->dwork_assoc);
4281}
4282
4283static void at76_rx_mgmt_beacon(struct at76_priv *priv,
4284 struct at76_rx_buffer *buf)
4285{
4286 int varpar_len;
4287 /* beacon content */
4288 struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
4289 struct ieee80211_hdr_3addr *mgmt = &bdata->header;
4290
4291 struct list_head *lptr;
4292 struct bss_info *match; /* entry matching addr3 with its bssid */
4293 int new_entry = 0;
4294 int len;
4295 struct ieee80211_info_element *ie;
4296 int have_ssid = 0;
4297 int have_rates = 0;
4298 int have_channel = 0;
4299 int keep_going = 1;
4300 unsigned long flags;
4301
4302 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
4303 if (priv->mac_state == MAC_CONNECTED) {
4304 /* in state MAC_CONNECTED we use the mgmt_timer to control
4305 the beacon of the BSS */
4306 BUG_ON(!priv->curr_bss);
4307
4308 if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
4309 /* We got our AP's beacon, defer the timeout handler.
4310 Kill pending work first, as schedule_delayed_work()
4311 won't do it. */
4312 cancel_delayed_work(&priv->dwork_beacon);
4313 schedule_delayed_work(&priv->dwork_beacon,
4314 BEACON_TIMEOUT);
4315 priv->curr_bss->rssi = buf->rssi;
4316 priv->beacons_received++;
4317 goto exit;
4318 }
4319 }
4320
4321 /* look if we have this BSS already in the list */
4322 match = NULL;
4323
4324 if (!list_empty(&priv->bss_list)) {
4325 list_for_each(lptr, &priv->bss_list) {
4326 struct bss_info *bss_ptr =
4327 list_entry(lptr, struct bss_info, list);
4328 if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
4329 match = bss_ptr;
4330 break;
4331 }
4332 }
4333 }
4334
4335 if (!match) {
4336 /* BSS not in the list - append it */
4337 match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
4338 if (!match) {
4339 at76_dbg(DBG_BSS_TABLE,
4340 "%s: cannot kmalloc new bss info (%zd byte)",
4341 priv->netdev->name, sizeof(struct bss_info));
4342 goto exit;
4343 }
4344 new_entry = 1;
4345 list_add_tail(&match->list, &priv->bss_list);
4346 }
4347
4348 match->capa = le16_to_cpu(bdata->capability);
4349 match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
4350 match->rssi = buf->rssi;
4351 match->link_qual = buf->link_quality;
4352 match->noise_level = buf->noise_level;
4353 memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
4354 at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
4355 mac2str(match->bssid));
4356
4357 ie = bdata->info_element;
4358
4359 /* length of var length beacon parameters */
4360 varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
4361 sizeof(struct ieee80211_beacon),
4362 BEACON_MAX_DATA_LENGTH);
4363
4364 /* This routine steps through the bdata->data array to get
4365 * some useful information about the access point.
4366 * Currently, this implementation supports receipt of: SSID,
4367 * supported transfer rates and channel, in any order, with some
4368 * tolerance for intermittent unknown codes (although this
4369 * functionality may not be necessary as the useful information will
4370 * usually arrive in consecutively, but there have been some
4371 * reports of some of the useful information fields arriving in a
4372 * different order).
4373 * It does not support any more IE types although MFIE_TYPE_TIM may
4374 * be supported (on my AP at least).
4375 * The bdata->data array is about 1500 bytes long but only ~36 of those
4376 * bytes are useful, hence the have_ssid etc optimizations. */
4377
4378 while (keep_going &&
4379 ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
4380 varpar_len)) {
4381
4382 switch (ie->id) {
4383
4384 case MFIE_TYPE_SSID:
4385 if (have_ssid)
4386 break;
4387
4388 len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
4389
4390 /* we copy only if this is a new entry,
4391 or the incoming SSID is not a hidden SSID. This
4392 will protect us from overwriting a real SSID read
4393 in a ProbeResponse with a hidden one from a
4394 following beacon. */
4395 if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
4396 have_ssid = 1;
4397 break;
4398 }
4399
4400 match->ssid_len = len;
4401 memcpy(match->ssid, ie->data, len);
4402 at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
4403 priv->netdev->name, len, match->ssid);
4404 have_ssid = 1;
4405 break;
4406
4407 case MFIE_TYPE_RATES:
4408 if (have_rates)
4409 break;
4410
4411 match->rates_len =
4412 min_t(int, sizeof(match->rates), ie->len);
4413 memcpy(match->rates, ie->data, match->rates_len);
4414 have_rates = 1;
4415 at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
4416 priv->netdev->name,
4417 hex2str(ie->data, ie->len));
4418 break;
4419
4420 case MFIE_TYPE_DS_SET:
4421 if (have_channel)
4422 break;
4423
4424 match->channel = ie->data[0];
4425 have_channel = 1;
4426 at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
4427 priv->netdev->name, match->channel);
4428 break;
4429
4430 case MFIE_TYPE_CF_SET:
4431 case MFIE_TYPE_TIM:
4432 case MFIE_TYPE_IBSS_SET:
4433 default:
4434 at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
4435 priv->netdev->name, ie->id, ie->len,
4436 hex2str(ie->data, ie->len));
4437 break;
4438 }
4439
4440 /* advance to the next informational element */
4441 next_ie(&ie);
4442
4443 /* Optimization: after all, the bdata->data array is
4444 * varpar_len bytes long, whereas we get all of the useful
4445 * information after only ~36 bytes, this saves us a lot of
4446 * time (and trouble as the remaining portion of the array
4447 * could be full of junk)
4448 * Comment this out if you want to see what other information
4449 * comes from the AP - although little of it may be useful */
4450 }
4451
4452 at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
4453 priv->netdev->name);
4454
4455 match->last_rx = jiffies; /* record last rx of beacon */
4456
4457exit:
4458 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
4459}
4460
4461/* Calculate the link level from a given rx_buffer */
4462static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
4463 struct iw_quality *qual)
4464{
4465 /* just a guess for now, might be different for other chips */
4466 int max_rssi = 42;
4467
4468 qual->level = (buf->rssi * 100 / max_rssi);
4469 if (qual->level > 100)
4470 qual->level = 100;
4471 qual->updated |= IW_QUAL_LEVEL_UPDATED;
4472}
4473
4474/* Calculate the link quality from a given rx_buffer */
4475static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
4476 struct iw_quality *qual)
4477{
4478 if (at76_is_intersil(priv->board_type))
4479 qual->qual = buf->link_quality;
4480 else {
4481 unsigned long elapsed;
4482
4483 /* Update qual at most once a second */
4484 elapsed = jiffies - priv->beacons_last_qual;
4485 if (elapsed < 1 * HZ)
4486 return;
4487
4488 qual->qual = qual->level * priv->beacons_received *
4489 msecs_to_jiffies(priv->beacon_period) / elapsed;
4490
4491 priv->beacons_last_qual = jiffies;
4492 priv->beacons_received = 0;
4493 }
4494 qual->qual = (qual->qual > 100) ? 100 : qual->qual;
4495 qual->updated |= IW_QUAL_QUAL_UPDATED;
4496}
4497
4498/* Calculate the noise quality from a given rx_buffer */
4499static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
4500 struct iw_quality *qual)
4501{
4502 qual->noise = 0;
4503 qual->updated |= IW_QUAL_NOISE_INVALID;
4504}
4505
4506static void at76_update_wstats(struct at76_priv *priv,
4507 struct at76_rx_buffer *buf)
4508{
4509 struct iw_quality *qual = &priv->wstats.qual;
4510
4511 if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
4512 qual->updated = 0;
4513 at76_calc_level(priv, buf, qual);
4514 at76_calc_qual(priv, buf, qual);
4515 at76_calc_noise(priv, buf, qual);
4516 } else {
4517 qual->qual = 0;
4518 qual->level = 0;
4519 qual->noise = 0;
4520 qual->updated = IW_QUAL_ALL_INVALID;
4521 }
4522}
4523
4524static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
4525{
4526 struct ieee80211_hdr_3addr *mgmt =
4527 (struct ieee80211_hdr_3addr *)buf->packet;
4528 u16 framectl = le16_to_cpu(mgmt->frame_ctl);
4529
4530 /* update wstats */
4531 if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
4532 /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
4533 /* Data packets always seem to have a 0 link level, so we
4534 only read link quality info from management packets.
4535 Atmel driver actually averages the present, and previous
4536 values, we just present the raw value at the moment - TJS */
4537 if (priv->iw_mode == IW_MODE_ADHOC
4538 || (priv->curr_bss
4539 && !compare_ether_addr(mgmt->addr3,
4540 priv->curr_bss->bssid)))
4541 at76_update_wstats(priv, buf);
4542 }
4543
4544 at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
4545 priv->netdev->name, framectl,
4546 hex2str(mgmt, le16_to_cpu(buf->wlength)));
4547
4548 switch (framectl & IEEE80211_FCTL_STYPE) {
4549 case IEEE80211_STYPE_BEACON:
4550 case IEEE80211_STYPE_PROBE_RESP:
4551 at76_rx_mgmt_beacon(priv, buf);
4552 break;
4553
4554 case IEEE80211_STYPE_ASSOC_RESP:
4555 at76_rx_mgmt_assoc(priv, buf);
4556 break;
4557
4558 case IEEE80211_STYPE_DISASSOC:
4559 at76_rx_mgmt_disassoc(priv, buf);
4560 break;
4561
4562 case IEEE80211_STYPE_AUTH:
4563 at76_rx_mgmt_auth(priv, buf);
4564 break;
4565
4566 case IEEE80211_STYPE_DEAUTH:
4567 at76_rx_mgmt_deauth(priv, buf);
4568 break;
4569
4570 default:
4571 printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
4572 priv->netdev->name, framectl);
4573 }
4574
4575 return;
4576}
4577
4578/* Convert the 802.11 header into an ethernet-style header, make skb
4579 * ready for consumption by netif_rx() */
4580static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
4581{
4582 struct ieee80211_hdr_3addr *i802_11_hdr;
4583 struct ethhdr *eth_hdr_p;
4584 u8 *src_addr;
4585 u8 *dest_addr;
4586
4587 i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
4588
4589 /* That would be the ethernet header if the hardware converted
4590 * the frame for us. Make sure the source and the destination
4591 * match the 802.11 header. Which hardware does it? */
4592 eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
4593
4594 dest_addr = i802_11_hdr->addr1;
4595 if (iw_mode == IW_MODE_ADHOC)
4596 src_addr = i802_11_hdr->addr2;
4597 else
4598 src_addr = i802_11_hdr->addr3;
4599
4600 if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
4601 !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
4602 /* Yes, we already have an ethernet header */
4603 skb_reset_mac_header(skb);
4604 else {
4605 u16 len;
4606
4607 /* Need to build an ethernet header */
4608 if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
4609 /* SNAP frame - decapsulate, keep proto */
4610 skb_push(skb, offsetof(struct ethhdr, h_proto) -
4611 sizeof(rfc1042sig));
4612 len = 0;
4613 } else {
4614 /* 802.3 frame, proto is length */
4615 len = skb->len;
4616 skb_push(skb, ETH_HLEN);
4617 }
4618
4619 skb_reset_mac_header(skb);
4620 eth_hdr_p = eth_hdr(skb);
4621 /* This needs to be done in this order (eth_hdr_p->h_dest may
4622 * overlap src_addr) */
4623 memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
4624 memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
4625 if (len)
4626 eth_hdr_p->h_proto = htons(len);
4627 }
4628
4629 skb->protocol = eth_type_trans(skb, skb->dev);
4630}
4631
4632/* Check for fragmented data in priv->rx_skb. If the packet was no fragment
4633 or it was the last of a fragment set a skb containing the whole packet
4634 is returned for further processing. Otherwise we get NULL and are
4635 done and the packet is either stored inside the fragment buffer
4636 or thrown away. Every returned skb starts with the ieee802_11 header
4637 and contains _no_ FCS at the end */
4638static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
4639{
4640 struct sk_buff *skb = priv->rx_skb;
4641 struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
4642 struct ieee80211_hdr_3addr *i802_11_hdr =
4643 (struct ieee80211_hdr_3addr *)buf->packet;
4644 /* seq_ctrl, fragment_number, sequence number of new packet */
4645 u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
4646 u16 fragnr = sctl & 0xf;
4647 u16 seqnr = sctl >> 4;
4648 u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
4649
4650 /* Length including the IEEE802.11 header, but without the trailing
4651 * FCS and without the Atmel Rx header */
4652 int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
4653
4654 /* where does the data payload start in skb->data ? */
4655 u8 *data = i802_11_hdr->payload;
4656
4657 /* length of payload, excl. the trailing FCS */
4658 int data_len = length - IEEE80211_3ADDR_LEN;
4659
4660 int i;
4661 struct rx_data_buf *bptr, *optr;
4662 unsigned long oldest = ~0UL;
4663
4664 at76_dbg(DBG_RX_FRAGS,
4665 "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
4666 "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
4667 mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
4668 hex2str(data, 32));
4669
4670 at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
4671 "tail %p end %p len %d", priv->netdev->name, skb->head,
4672 skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
4673 skb->len);
4674
4675 if (data_len < 0) {
4676 /* make sure data starts in the buffer */
4677 printk(KERN_INFO "%s: data frame too short\n",
4678 priv->netdev->name);
4679 return NULL;
4680 }
4681
4682 WARN_ON(length <= AT76_RX_HDRLEN);
4683 if (length <= AT76_RX_HDRLEN)
4684 return NULL;
4685
4686 /* remove the at76_rx_buffer header - we don't need it anymore */
4687 /* we need the IEEE802.11 header (for the addresses) if this packet
4688 is the first of a chain */
4689 skb_pull(skb, AT76_RX_HDRLEN);
4690
4691 /* remove FCS at end */
4692 skb_trim(skb, length);
4693
4694 at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
4695 "end %p len %d data %p data_len %d", priv->netdev->name,
4696 skb->head, skb->data, skb_tail_pointer(skb),
4697 skb_end_pointer(skb), skb->len, data, data_len);
4698
4699 if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
4700 /* unfragmented packet received */
4701 /* Use a new skb for the next receive */
4702 priv->rx_skb = NULL;
4703 at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
4704 return skb;
4705 }
4706
4707 /* look if we've got a chain for the sender address.
4708 afterwards optr points to first free or the oldest entry,
4709 or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
4710 sender address */
4711 /* determining the oldest entry doesn't cope with jiffies wrapping
4712 but I don't care to delete a young entry at these rare moments ... */
4713
4714 bptr = priv->rx_data;
4715 optr = NULL;
4716 for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
4717 if (!bptr->skb) {
4718 optr = bptr;
4719 oldest = 0UL;
4720 continue;
4721 }
4722
4723 if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
4724 break;
4725
4726 if (!optr) {
4727 optr = bptr;
4728 oldest = bptr->last_rx;
4729 } else if (bptr->last_rx < oldest)
4730 optr = bptr;
4731 }
4732
4733 if (i < NR_RX_DATA_BUF) {
4734
4735 at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
4736 "matched sender addr",
4737 priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
4738
4739 /* bptr points to an entry for the sender address */
4740 if (bptr->seqnr == seqnr) {
4741 int left;
4742 /* the fragment has the current sequence number */
4743 if (((bptr->fragnr + 1) & 0xf) != fragnr) {
4744 /* wrong fragment number -> ignore it */
4745 /* is & 0xf necessary above ??? */
4746 at76_dbg(DBG_RX_FRAGS,
4747 "%s: frag nr mismatch: %d + 1 != %d",
4748 priv->netdev->name, bptr->fragnr,
4749 fragnr);
4750 return NULL;
4751 }
4752 bptr->last_rx = jiffies;
4753 /* the next following fragment number ->
4754 add the data at the end */
4755
4756 /* for test only ??? */
4757 left = skb_tailroom(bptr->skb);
4758 if (left < data_len)
4759 printk(KERN_INFO
4760 "%s: only %d byte free (need %d)\n",
4761 priv->netdev->name, left, data_len);
4762 else
4763 memcpy(skb_put(bptr->skb, data_len), data,
4764 data_len);
4765
4766 bptr->fragnr = fragnr;
4767 if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
4768 return NULL;
4769
4770 /* this was the last fragment - send it */
4771 skb = bptr->skb;
4772 bptr->skb = NULL; /* free the entry */
4773 at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
4774 priv->netdev->name, seqnr);
4775 return skb;
4776 }
4777
4778 /* got another sequence number */
4779 if (fragnr == 0) {
4780 /* it's the start of a new chain - replace the
4781 old one by this */
4782 /* bptr->sender has the correct value already */
4783 at76_dbg(DBG_RX_FRAGS,
4784 "%s: start of new seq %d, removing old seq %d",
4785 priv->netdev->name, seqnr, bptr->seqnr);
4786 bptr->seqnr = seqnr;
4787 bptr->fragnr = 0;
4788 bptr->last_rx = jiffies;
4789 /* swap bptr->skb and priv->rx_skb */
4790 skb = bptr->skb;
4791 bptr->skb = priv->rx_skb;
4792 priv->rx_skb = skb;
4793 } else {
4794 /* it from the middle of a new chain ->
4795 delete the old entry and skip the new one */
4796 at76_dbg(DBG_RX_FRAGS,
4797 "%s: middle of new seq %d (%d) "
4798 "removing old seq %d",
4799 priv->netdev->name, seqnr, fragnr,
4800 bptr->seqnr);
4801 dev_kfree_skb(bptr->skb);
4802 bptr->skb = NULL;
4803 }
4804 return NULL;
4805 }
4806
4807 /* if we didn't find a chain for the sender address, optr
4808 points either to the first free or the oldest entry */
4809
4810 if (fragnr != 0) {
4811 /* this is not the begin of a fragment chain ... */
4812 at76_dbg(DBG_RX_FRAGS,
4813 "%s: no chain for non-first fragment (%d)",
4814 priv->netdev->name, fragnr);
4815 return NULL;
4816 }
4817
4818 BUG_ON(!optr);
4819 if (optr->skb) {
4820 /* swap the skb's */
4821 skb = optr->skb;
4822 optr->skb = priv->rx_skb;
4823 priv->rx_skb = skb;
4824
4825 at76_dbg(DBG_RX_FRAGS,
4826 "%s: free old contents: sender %s seq/frag %d/%d",
4827 priv->netdev->name, mac2str(optr->sender),
4828 optr->seqnr, optr->fragnr);
4829
4830 } else {
4831 /* take the skb from priv->rx_skb */
4832 optr->skb = priv->rx_skb;
4833 /* let at76_submit_rx_urb() allocate a new skb */
4834 priv->rx_skb = NULL;
4835
4836 at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
4837 priv->netdev->name);
4838 }
4839 memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
4840 optr->seqnr = seqnr;
4841 optr->fragnr = 0;
4842 optr->last_rx = jiffies;
4843
4844 return NULL;
4845}
4846
4847/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
4848static void at76_rx_data(struct at76_priv *priv)
4849{
4850 struct net_device *netdev = priv->netdev;
4851 struct net_device_stats *stats = &priv->stats;
4852 struct sk_buff *skb = priv->rx_skb;
4853 struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
4854 struct ieee80211_hdr_3addr *i802_11_hdr;
4855 int length = le16_to_cpu(buf->wlength);
4856
4857 at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
4858 hex2str(skb->data, AT76_RX_HDRLEN));
4859
4860 at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
4861 hex2str(skb->data + AT76_RX_HDRLEN, length));
4862
4863 skb = at76_check_for_rx_frags(priv);
4864 if (!skb)
4865 return;
4866
4867 /* Atmel header and the FCS are already removed */
4868 i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
4869
4870 skb->dev = netdev;
4871 skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
4872
4873 if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
4874 if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
4875 skb->pkt_type = PACKET_BROADCAST;
4876 else
4877 skb->pkt_type = PACKET_MULTICAST;
4878 } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
4879 skb->pkt_type = PACKET_OTHERHOST;
4880
4881 at76_ieee80211_to_eth(skb, priv->iw_mode);
4882
4883 netdev->last_rx = jiffies;
4884 netif_rx(skb);
4885 stats->rx_packets++;
4886 stats->rx_bytes += length;
4887
4888 return;
4889}
4890
4891static void at76_rx_monitor_mode(struct at76_priv *priv)
4892{
4893 struct at76_rx_radiotap *rt;
4894 u8 *payload;
4895 int skblen;
4896 struct net_device *netdev = priv->netdev;
4897 struct at76_rx_buffer *buf =
4898 (struct at76_rx_buffer *)priv->rx_skb->data;
4899 /* length including the IEEE802.11 header and the trailing FCS,
4900 but not at76_rx_buffer */
4901 int length = le16_to_cpu(buf->wlength);
4902 struct sk_buff *skb = priv->rx_skb;
4903 struct net_device_stats *stats = &priv->stats;
4904
4905 if (length < IEEE80211_FCS_LEN) {
4906 /* buffer contains no data */
4907 at76_dbg(DBG_MONITOR_MODE,
4908 "%s: MONITOR MODE: rx skb without data",
4909 priv->netdev->name);
4910 return;
4911 }
4912
4913 skblen = sizeof(struct at76_rx_radiotap) + length;
4914
4915 skb = dev_alloc_skb(skblen);
4916 if (!skb) {
4917 printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
4918 "header returned NULL\n", priv->netdev->name);
4919 return;
4920 }
4921
4922 skb_put(skb, skblen);
4923
4924 rt = (struct at76_rx_radiotap *)skb->data;
4925 payload = skb->data + sizeof(struct at76_rx_radiotap);
4926
4927 rt->rt_hdr.it_version = 0;
4928 rt->rt_hdr.it_pad = 0;
4929 rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
4930 rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
4931
4932 rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
4933 rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
4934 rt->rt_signal = buf->rssi;
4935 rt->rt_noise = buf->noise_level;
4936 rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
4937 if (buf->fragmentation)
4938 rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
4939
4940 memcpy(payload, buf->packet, length);
4941 skb->dev = netdev;
4942 skb->ip_summed = CHECKSUM_NONE;
4943 skb_reset_mac_header(skb);
4944 skb->pkt_type = PACKET_OTHERHOST;
4945 skb->protocol = htons(ETH_P_802_2);
4946
4947 netdev->last_rx = jiffies;
4948 netif_rx(skb);
4949 stats->rx_packets++;
4950 stats->rx_bytes += length;
4951}
4952
4953/* Check if we spy on the sender address in buf and update stats */
4954static void at76_iwspy_update(struct at76_priv *priv,
4955 struct at76_rx_buffer *buf)
4956{
4957 struct ieee80211_hdr_3addr *hdr =
4958 (struct ieee80211_hdr_3addr *)buf->packet;
4959 struct iw_quality qual;
4960
4961 /* We can only set the level here */
4962 qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
4963 qual.level = 0;
4964 qual.noise = 0;
4965 at76_calc_level(priv, buf, &qual);
4966
4967 spin_lock_bh(&priv->spy_spinlock);
4968
4969 if (priv->spy_data.spy_number > 0)
4970 wireless_spy_update(priv->netdev, hdr->addr2, &qual);
4971
4972 spin_unlock_bh(&priv->spy_spinlock);
4973}
4974
4975static void at76_rx_tasklet(unsigned long param)
4976{
4977 struct urb *urb = (struct urb *)param;
4978 struct at76_priv *priv = urb->context;
4979 struct net_device *netdev = priv->netdev;
4980 struct at76_rx_buffer *buf;
4981 struct ieee80211_hdr_3addr *i802_11_hdr;
4982 u16 frame_ctl;
4983
4984 if (priv->device_unplugged) {
4985 at76_dbg(DBG_DEVSTART, "device unplugged");
4986 if (urb)
4987 at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
4988 return;
4989 }
4990
4991 if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
4992 return;
4993
4994 buf = (struct at76_rx_buffer *)priv->rx_skb->data;
4995
4996 i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
4997
4998 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
4999
5000 if (urb->status != 0) {
5001 if (urb->status != -ENOENT && urb->status != -ECONNRESET)
5002 at76_dbg(DBG_URB,
5003 "%s %s: - nonzero Rx bulk status received: %d",
5004 __func__, netdev->name, urb->status);
5005 return;
5006 }
5007
5008 at76_dbg(DBG_RX_ATMEL_HDR,
5009 "%s: rx frame: rate %d rssi %d noise %d link %d %s",
5010 priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
5011 buf->link_quality, hex2str(i802_11_hdr, 48));
5012 if (priv->iw_mode == IW_MODE_MONITOR) {
5013 at76_rx_monitor_mode(priv);
5014 goto exit;
5015 }
5016
5017 /* there is a new bssid around, accept it: */
5018 if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
5019 at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
5020 schedule_work(&priv->work_new_bss);
5021 }
5022
5023 switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
5024 case IEEE80211_FTYPE_DATA:
5025 at76_rx_data(priv);
5026 break;
5027
5028 case IEEE80211_FTYPE_MGMT:
5029 /* jal: TODO: find out if we can update iwspy also on
5030 other frames than management (might depend on the
5031 radio chip / firmware version !) */
5032
5033 at76_iwspy_update(priv, buf);
5034
5035 at76_rx_mgmt(priv, buf);
5036 break;
5037
5038 case IEEE80211_FTYPE_CTL:
5039 at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
5040 priv->netdev->name, frame_ctl);
5041 break;
5042
5043 default:
5044 printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
5045 priv->netdev->name, frame_ctl);
5046 }
5047exit:
5048 at76_submit_rx_urb(priv);
5049}
5050
5051/* Load firmware into kernel memory and parse it */
5052static struct fwentry *at76_load_firmware(struct usb_device *udev,
5053 enum board_type board_type)
5054{
5055 int ret;
5056 char *str;
5057 struct at76_fw_header *fwh;
5058 struct fwentry *fwe = &firmwares[board_type];
5059
5060 mutex_lock(&fw_mutex);
5061
5062 if (fwe->loaded) {
5063 at76_dbg(DBG_FW, "re-using previously loaded fw");
5064 goto exit;
5065 }
5066
5067 at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
5068 ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
5069 if (ret < 0) {
5070 dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
5071 fwe->fwname);
5072 dev_printk(KERN_ERR, &udev->dev,
5073 "you may need to download the firmware from "
5074 "http://developer.berlios.de/projects/at76c503a/");
5075 goto exit;
5076 }
5077
5078 at76_dbg(DBG_FW, "got it.");
5079 fwh = (struct at76_fw_header *)(fwe->fw->data);
5080
5081 if (fwe->fw->size <= sizeof(*fwh)) {
5082 dev_printk(KERN_ERR, &udev->dev,
5083 "firmware is too short (0x%zx)\n", fwe->fw->size);
5084 goto exit;
5085 }
5086
5087 /* CRC currently not checked */
5088 fwe->board_type = le32_to_cpu(fwh->board_type);
5089 if (fwe->board_type != board_type) {
5090 dev_printk(KERN_ERR, &udev->dev,
5091 "board type mismatch, requested %u, got %u\n",
5092 board_type, fwe->board_type);
5093 goto exit;
5094 }
5095
5096 fwe->fw_version.major = fwh->major;
5097 fwe->fw_version.minor = fwh->minor;
5098 fwe->fw_version.patch = fwh->patch;
5099 fwe->fw_version.build = fwh->build;
5100
5101 str = (char *)fwh + le32_to_cpu(fwh->str_offset);
5102 fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
5103 fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
5104 fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
5105 fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
5106
5107 fwe->loaded = 1;
5108
5109 dev_printk(KERN_DEBUG, &udev->dev,
5110 "using firmware %s (version %d.%d.%d-%d)\n",
5111 fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
5112
5113 at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
5114 le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
5115 le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
5116 at76_dbg(DBG_DEVSTART, "firmware id %s", str);
5117
5118exit:
5119 mutex_unlock(&fw_mutex);
5120
5121 if (fwe->loaded)
5122 return fwe;
5123 else
5124 return NULL;
5125}
5126
5127/* Allocate network device and initialize private data */
5128static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
5129{
5130 struct net_device *netdev;
5131 struct at76_priv *priv;
5132 int i;
5133
5134 /* allocate memory for our device state and initialize it */
5135 netdev = alloc_etherdev(sizeof(struct at76_priv));
5136 if (!netdev) {
5137 dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
5138 return NULL;
5139 }
5140
5141 priv = netdev_priv(netdev);
5142
5143 priv->udev = udev;
5144 priv->netdev = netdev;
5145
5146 mutex_init(&priv->mtx);
5147 INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
5148 INIT_WORK(&priv->work_join, at76_work_join);
5149 INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
5150 INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
5151 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
5152 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
5153 INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
5154 INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
5155 INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
5156 INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
5157 INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
5158
5159 spin_lock_init(&priv->mgmt_spinlock);
5160 priv->next_mgmt_bulk = NULL;
5161 priv->mac_state = MAC_INIT;
5162
5163 /* initialize empty BSS list */
5164 priv->curr_bss = NULL;
5165 INIT_LIST_HEAD(&priv->bss_list);
5166 spin_lock_init(&priv->bss_list_spinlock);
5167
5168 init_timer(&priv->bss_list_timer);
5169 priv->bss_list_timer.data = (unsigned long)priv;
5170 priv->bss_list_timer.function = at76_bss_list_timeout;
5171
5172 spin_lock_init(&priv->spy_spinlock);
5173
5174 /* mark all rx data entries as unused */
5175 for (i = 0; i < NR_RX_DATA_BUF; i++)
5176 priv->rx_data[i].skb = NULL;
5177
5178 priv->rx_tasklet.func = at76_rx_tasklet;
5179 priv->rx_tasklet.data = 0;
5180
5181 priv->pm_mode = AT76_PM_OFF;
5182 priv->pm_period = 0;
5183
5184 return priv;
5185}
5186
5187static int at76_alloc_urbs(struct at76_priv *priv,
5188 struct usb_interface *interface)
5189{
5190 struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
5191 int i;
5192 int buffer_size;
5193 struct usb_host_interface *iface_desc;
5194
5195 at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
5196
5197 at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
5198 interface->altsetting[0].desc.bNumEndpoints);
5199
5200 ep_in = NULL;
5201 ep_out = NULL;
5202 iface_desc = interface->cur_altsetting;
5203 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
5204 endpoint = &iface_desc->endpoint[i].desc;
5205
5206 at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
5207 __func__, i, endpoint->bEndpointAddress,
5208 endpoint->bmAttributes);
5209
5210 if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
5211 ep_in = endpoint;
5212
5213 if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
5214 ep_out = endpoint;
5215 }
5216
5217 if (!ep_in || !ep_out) {
5218 dev_printk(KERN_ERR, &interface->dev,
5219 "bulk endpoints missing\n");
5220 return -ENXIO;
5221 }
5222
5223 priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
5224 priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
5225
5226 priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
5227 priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
5228 if (!priv->rx_urb || !priv->tx_urb) {
5229 dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
5230 return -ENOMEM;
5231 }
5232
5233 buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
5234 priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
5235 if (!priv->bulk_out_buffer) {
5236 dev_printk(KERN_ERR, &interface->dev,
5237 "cannot allocate output buffer\n");
5238 return -ENOMEM;
5239 }
5240
5241 at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
5242
5243 return 0;
5244}
5245
5246/* Register network device and initialize the hardware */
5247static int at76_init_new_device(struct at76_priv *priv,
5248 struct usb_interface *interface)
5249{
5250 struct net_device *netdev = priv->netdev;
5251 int ret;
5252
5253 /* set up the endpoint information */
5254 /* check out the endpoints */
5255
5256 at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
5257 interface->cur_altsetting->desc.bNumEndpoints);
5258
5259 ret = at76_alloc_urbs(priv, interface);
5260 if (ret < 0)
5261 goto exit;
5262
5263 /* MAC address */
5264 ret = at76_get_hw_config(priv);
5265 if (ret < 0) {
5266 dev_printk(KERN_ERR, &interface->dev,
5267 "cannot get MAC address\n");
5268 goto exit;
5269 }
5270
5271 priv->domain = at76_get_reg_domain(priv->regulatory_domain);
5272 /* init. netdev->dev_addr */
5273 memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
5274
5275 priv->channel = DEF_CHANNEL;
5276 priv->iw_mode = IW_MODE_INFRA;
5277 priv->rts_threshold = DEF_RTS_THRESHOLD;
5278 priv->frag_threshold = DEF_FRAG_THRESHOLD;
5279 priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
5280 priv->txrate = TX_RATE_AUTO;
5281 priv->preamble_type = PREAMBLE_TYPE_LONG;
5282 priv->beacon_period = 100;
5283 priv->beacons_last_qual = jiffies;
5284 priv->auth_mode = WLAN_AUTH_OPEN;
5285 priv->scan_min_time = DEF_SCAN_MIN_TIME;
5286 priv->scan_max_time = DEF_SCAN_MAX_TIME;
5287 priv->scan_mode = SCAN_TYPE_ACTIVE;
5288
5289 netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
5290 netdev->open = at76_open;
5291 netdev->stop = at76_stop;
5292 netdev->get_stats = at76_get_stats;
5293 netdev->ethtool_ops = &at76_ethtool_ops;
5294
5295 /* Add pointers to enable iwspy support. */
5296 priv->wireless_data.spy_data = &priv->spy_data;
5297 netdev->wireless_data = &priv->wireless_data;
5298
5299 netdev->hard_start_xmit = at76_tx;
5300 netdev->tx_timeout = at76_tx_timeout;
5301 netdev->watchdog_timeo = 2 * HZ;
5302 netdev->wireless_handlers = &at76_handler_def;
5303 netdev->set_multicast_list = at76_set_multicast;
5304 netdev->set_mac_address = at76_set_mac_address;
5305 dev_alloc_name(netdev, "wlan%d");
5306
5307 ret = register_netdev(priv->netdev);
5308 if (ret) {
5309 dev_printk(KERN_ERR, &interface->dev,
5310 "cannot register netdevice (status %d)!\n", ret);
5311 goto exit;
5312 }
5313 priv->netdev_registered = 1;
5314
5315 printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
5316 netdev->name, interface->dev.bus_id, mac2str(priv->mac_addr),
5317 priv->fw_version.major, priv->fw_version.minor,
5318 priv->fw_version.patch, priv->fw_version.build);
5319 printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
5320 priv->regulatory_domain, priv->domain->name);
5321
5322 /* we let this timer run the whole time this driver instance lives */
5323 mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
5324
5325exit:
5326 return ret;
5327}
5328
5329static void at76_delete_device(struct at76_priv *priv)
5330{
5331 int i;
5332
5333 at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
5334
5335 /* The device is gone, don't bother turning it off */
5336 priv->device_unplugged = 1;
5337
5338 if (priv->netdev_registered)
5339 unregister_netdev(priv->netdev);
5340
5341 /* assuming we used keventd, it must quiesce too */
5342 flush_scheduled_work();
5343
5344 kfree(priv->bulk_out_buffer);
5345
5346 if (priv->tx_urb) {
5347 usb_kill_urb(priv->tx_urb);
5348 usb_free_urb(priv->tx_urb);
5349 }
5350 if (priv->rx_urb) {
5351 usb_kill_urb(priv->rx_urb);
5352 usb_free_urb(priv->rx_urb);
5353 }
5354
5355 at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
5356
5357 if (priv->rx_skb)
5358 kfree_skb(priv->rx_skb);
5359
5360 at76_free_bss_list(priv);
5361 del_timer_sync(&priv->bss_list_timer);
5362 cancel_delayed_work(&priv->dwork_get_scan);
5363 cancel_delayed_work(&priv->dwork_beacon);
5364 cancel_delayed_work(&priv->dwork_auth);
5365 cancel_delayed_work(&priv->dwork_assoc);
5366
5367 if (priv->mac_state == MAC_CONNECTED)
5368 at76_iwevent_bss_disconnect(priv->netdev);
5369
5370 for (i = 0; i < NR_RX_DATA_BUF; i++)
5371 if (priv->rx_data[i].skb) {
5372 dev_kfree_skb(priv->rx_data[i].skb);
5373 priv->rx_data[i].skb = NULL;
5374 }
5375 usb_put_dev(priv->udev);
5376
5377 at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
5378 free_netdev(priv->netdev); /* priv is in netdev */
5379
5380 at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
5381}
5382
5383static int at76_probe(struct usb_interface *interface,
5384 const struct usb_device_id *id)
5385{
5386 int ret;
5387 struct at76_priv *priv;
5388 struct fwentry *fwe;
5389 struct usb_device *udev;
5390 int op_mode;
5391 int need_ext_fw = 0;
5392 struct mib_fw_version fwv;
5393 int board_type = (int)id->driver_info;
5394
5395 udev = usb_get_dev(interface_to_usbdev(interface));
5396
5397 /* Load firmware into kernel memory */
5398 fwe = at76_load_firmware(udev, board_type);
5399 if (!fwe) {
5400 ret = -ENOENT;
5401 goto error;
5402 }
5403
5404 op_mode = at76_get_op_mode(udev);
5405
5406 at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
5407
5408 /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
5409 we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
5410
5411 if (op_mode == OPMODE_HW_CONFIG_MODE) {
5412 dev_printk(KERN_ERR, &interface->dev,
5413 "cannot handle a device in HW_CONFIG_MODE\n");
5414 ret = -EBUSY;
5415 goto error;
5416 }
5417
5418 if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
5419 && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
5420 /* download internal firmware part */
5421 dev_printk(KERN_DEBUG, &interface->dev,
5422 "downloading internal firmware\n");
5423 ret = at76_load_internal_fw(udev, fwe);
5424 if (ret < 0) {
5425 dev_printk(KERN_ERR, &interface->dev,
5426 "error %d downloading internal firmware\n",
5427 ret);
5428 goto error;
5429 }
5430 usb_put_dev(udev);
5431 return ret;
5432 }
5433
5434 /* Internal firmware already inside the device. Get firmware
5435 * version to test if external firmware is loaded.
5436 * This works only for newer firmware, e.g. the Intersil 0.90.x
5437 * says "control timeout on ep0in" and subsequent
5438 * at76_get_op_mode() fail too :-( */
5439
5440 /* if version >= 0.100.x.y or device with built-in flash we can
5441 * query the device for the fw version */
5442 if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
5443 || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
5444 ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
5445 if (ret < 0 || (fwv.major | fwv.minor) == 0)
5446 need_ext_fw = 1;
5447 } else
5448 /* No way to check firmware version, reload to be sure */
5449 need_ext_fw = 1;
5450
5451 if (need_ext_fw) {
5452 dev_printk(KERN_DEBUG, &interface->dev,
5453 "downloading external firmware\n");
5454
5455 ret = at76_load_external_fw(udev, fwe);
5456 if (ret)
5457 goto error;
5458
5459 /* Re-check firmware version */
5460 ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
5461 if (ret < 0) {
5462 dev_printk(KERN_ERR, &interface->dev,
5463 "error %d getting firmware version\n", ret);
5464 goto error;
5465 }
5466 }
5467
5468 priv = at76_alloc_new_device(udev);
5469 if (!priv) {
5470 ret = -ENOMEM;
5471 goto error;
5472 }
5473
5474 SET_NETDEV_DEV(priv->netdev, &interface->dev);
5475 usb_set_intfdata(interface, priv);
5476
5477 memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
5478 priv->board_type = board_type;
5479
5480 ret = at76_init_new_device(priv, interface);
5481 if (ret < 0)
5482 at76_delete_device(priv);
5483
5484 return ret;
5485
5486error:
5487 usb_put_dev(udev);
5488 return ret;
5489}
5490
5491static void at76_disconnect(struct usb_interface *interface)
5492{
5493 struct at76_priv *priv;
5494
5495 priv = usb_get_intfdata(interface);
5496 usb_set_intfdata(interface, NULL);
5497
5498 /* Disconnect after loading internal firmware */
5499 if (!priv)
5500 return;
5501
5502 printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
5503 at76_delete_device(priv);
5504 dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
5505}
5506
5507/* Structure for registering this driver with the USB subsystem */
5508static struct usb_driver at76_driver = {
5509 .name = DRIVER_NAME,
5510 .probe = at76_probe,
5511 .disconnect = at76_disconnect,
5512 .id_table = dev_table,
5513};
5514
5515static int __init at76_mod_init(void)
5516{
5517 int result;
5518
5519 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
5520
5521 mutex_init(&fw_mutex);
5522
5523 /* register this driver with the USB subsystem */
5524 result = usb_register(&at76_driver);
5525 if (result < 0)
5526 printk(KERN_ERR DRIVER_NAME
5527 ": usb_register failed (status %d)\n", result);
5528
5529 led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
5530 return result;
5531}
5532
5533static void __exit at76_mod_exit(void)
5534{
5535 int i;
5536
5537 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
5538 usb_deregister(&at76_driver);
5539 for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
5540 if (firmwares[i].fw)
5541 release_firmware(firmwares[i].fw);
5542 }
5543 led_trigger_unregister_simple(ledtrig_tx);
5544}
5545
5546module_param_named(debug, at76_debug, int, 0600);
5547MODULE_PARM_DESC(debug, "Debugging level");
5548
5549module_init(at76_mod_init);
5550module_exit(at76_mod_exit);
5551
5552MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
5553MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
5554MODULE_AUTHOR("Alex <alex@foogod.com>");
5555MODULE_AUTHOR("Nick Jones");
5556MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
5557MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
5558MODULE_DESCRIPTION(DRIVER_DESC);
5559MODULE_LICENSE("GPL");
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
new file mode 100644
index 000000000000..b20be9da1fa1
--- /dev/null
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -0,0 +1,619 @@
1/*
2 * Copyright (c) 2002,2003 Oliver Kurth
3 * (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
4 * (c) 2007 Guido Guenther <agx@sigxcpu.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This driver was based on information from the Sourceforge driver
12 * released and maintained by Atmel:
13 *
14 * http://sourceforge.net/projects/atmelwlandriver/
15 *
16 * Although the code was completely re-written,
17 * it would have been impossible without Atmel's decision to
18 * release an Open Source driver (unfortunately the firmware was
19 * kept binary only). Thanks for that decision to Atmel!
20 */
21
22#ifndef _AT76_USB_H
23#define _AT76_USB_H
24
25/* Board types */
26enum board_type {
27 BOARD_503_ISL3861 = 1,
28 BOARD_503_ISL3863 = 2,
29 BOARD_503 = 3,
30 BOARD_503_ACC = 4,
31 BOARD_505 = 5,
32 BOARD_505_2958 = 6,
33 BOARD_505A = 7,
34 BOARD_505AMX = 8
35};
36
37/* our private ioctl's */
38/* preamble length (0 - long, 1 - short, 2 - auto) */
39#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0)
40#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1)
41/* which debug channels are enabled */
42#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2)
43#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3)
44/* power save mode (incl. the Atmel proprietary smart save mode) */
45#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4)
46#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5)
47/* min and max channel times for scan */
48#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6)
49#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7)
50/* scan mode (0 - active, 1 - passive) */
51#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8)
52#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9)
53
54#define CMD_STATUS_IDLE 0x00
55#define CMD_STATUS_COMPLETE 0x01
56#define CMD_STATUS_UNKNOWN 0x02
57#define CMD_STATUS_INVALID_PARAMETER 0x03
58#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
59#define CMD_STATUS_TIME_OUT 0x07
60#define CMD_STATUS_IN_PROGRESS 0x08
61#define CMD_STATUS_HOST_FAILURE 0xff
62#define CMD_STATUS_SCAN_FAILED 0xf0
63
64/* answers to get op mode */
65#define OPMODE_NONE 0x00
66#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
67#define OPMODE_HW_CONFIG_MODE 0x02
68#define OPMODE_DFU_MODE_WITH_FLASH 0x03
69#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
70
71#define CMD_SET_MIB 0x01
72#define CMD_GET_MIB 0x02
73#define CMD_SCAN 0x03
74#define CMD_JOIN 0x04
75#define CMD_START_IBSS 0x05
76#define CMD_RADIO_ON 0x06
77#define CMD_RADIO_OFF 0x07
78#define CMD_STARTUP 0x0B
79
80#define MIB_LOCAL 0x01
81#define MIB_MAC_ADDR 0x02
82#define MIB_MAC 0x03
83#define MIB_MAC_MGMT 0x05
84#define MIB_MAC_WEP 0x06
85#define MIB_PHY 0x07
86#define MIB_FW_VERSION 0x08
87#define MIB_MDOMAIN 0x09
88
89#define ADHOC_MODE 1
90#define INFRASTRUCTURE_MODE 2
91
92/* values for struct mib_local, field preamble_type */
93#define PREAMBLE_TYPE_LONG 0
94#define PREAMBLE_TYPE_SHORT 1
95#define PREAMBLE_TYPE_AUTO 2
96
97/* values for tx_rate */
98#define TX_RATE_1MBIT 0
99#define TX_RATE_2MBIT 1
100#define TX_RATE_5_5MBIT 2
101#define TX_RATE_11MBIT 3
102#define TX_RATE_AUTO 4
103
104/* power management modes */
105#define AT76_PM_OFF 1
106#define AT76_PM_ON 2
107#define AT76_PM_SMART 3
108
109struct hwcfg_r505 {
110 u8 cr39_values[14];
111 u8 reserved1[14];
112 u8 bb_cr[14];
113 u8 pidvid[4];
114 u8 mac_addr[ETH_ALEN];
115 u8 regulatory_domain;
116 u8 reserved2[14];
117 u8 cr15_values[14];
118 u8 reserved3[3];
119} __attribute__((packed));
120
121struct hwcfg_rfmd {
122 u8 cr20_values[14];
123 u8 cr21_values[14];
124 u8 bb_cr[14];
125 u8 pidvid[4];
126 u8 mac_addr[ETH_ALEN];
127 u8 regulatory_domain;
128 u8 low_power_values[14];
129 u8 normal_power_values[14];
130 u8 reserved1[3];
131} __attribute__((packed));
132
133struct hwcfg_intersil {
134 u8 mac_addr[ETH_ALEN];
135 u8 cr31_values[14];
136 u8 cr58_values[14];
137 u8 pidvid[4];
138 u8 regulatory_domain;
139 u8 reserved[1];
140} __attribute__((packed));
141
142union at76_hwcfg {
143 struct hwcfg_intersil i;
144 struct hwcfg_rfmd r3;
145 struct hwcfg_r505 r5;
146};
147
148#define WEP_SMALL_KEY_LEN (40 / 8)
149#define WEP_LARGE_KEY_LEN (104 / 8)
150
151struct at76_card_config {
152 u8 exclude_unencrypted;
153 u8 promiscuous_mode;
154 u8 short_retry_limit;
155 u8 encryption_type;
156 __le16 rts_threshold;
157 __le16 fragmentation_threshold; /* 256..2346 */
158 u8 basic_rate_set[4];
159 u8 auto_rate_fallback; /* 0,1 */
160 u8 channel;
161 u8 privacy_invoked;
162 u8 wep_default_key_id; /* 0..3 */
163 u8 current_ssid[32];
164 u8 wep_default_key_value[4][WEP_KEY_LEN];
165 u8 ssid_len;
166 u8 short_preamble;
167 __le16 beacon_period;
168} __attribute__((packed));
169
170struct at76_command {
171 u8 cmd;
172 u8 reserved;
173 __le16 size;
174 u8 data[0];
175} __attribute__((packed));
176
177/* Length of Atmel-specific Rx header before 802.11 frame */
178#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
179
180struct at76_rx_buffer {
181 __le16 wlength;
182 u8 rx_rate;
183 u8 newbss;
184 u8 fragmentation;
185 u8 rssi;
186 u8 link_quality;
187 u8 noise_level;
188 __le32 rx_time;
189 u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
190} __attribute__((packed));
191
192/* Length of Atmel-specific Tx header before 802.11 frame */
193#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
194
195struct at76_tx_buffer {
196 __le16 wlength;
197 u8 tx_rate;
198 u8 padding;
199 u8 reserved[4];
200 u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
201} __attribute__((packed));
202
203/* defines for scan_type below */
204#define SCAN_TYPE_ACTIVE 0
205#define SCAN_TYPE_PASSIVE 1
206
207struct at76_req_scan {
208 u8 bssid[ETH_ALEN];
209 u8 essid[32];
210 u8 scan_type;
211 u8 channel;
212 __le16 probe_delay;
213 __le16 min_channel_time;
214 __le16 max_channel_time;
215 u8 essid_size;
216 u8 international_scan;
217} __attribute__((packed));
218
219struct at76_req_ibss {
220 u8 bssid[ETH_ALEN];
221 u8 essid[32];
222 u8 bss_type;
223 u8 channel;
224 u8 essid_size;
225 u8 reserved[3];
226} __attribute__((packed));
227
228struct at76_req_join {
229 u8 bssid[ETH_ALEN];
230 u8 essid[32];
231 u8 bss_type;
232 u8 channel;
233 __le16 timeout;
234 u8 essid_size;
235 u8 reserved;
236} __attribute__((packed));
237
238struct set_mib_buffer {
239 u8 type;
240 u8 size;
241 u8 index;
242 u8 reserved;
243 union {
244 u8 byte;
245 __le16 word;
246 u8 addr[ETH_ALEN];
247 } data;
248} __attribute__((packed));
249
250struct mib_local {
251 u16 reserved0;
252 u8 beacon_enable;
253 u8 txautorate_fallback;
254 u8 reserved1;
255 u8 ssid_size;
256 u8 promiscuous_mode;
257 u16 reserved2;
258 u8 preamble_type;
259 u16 reserved3;
260} __attribute__((packed));
261
262struct mib_mac_addr {
263 u8 mac_addr[ETH_ALEN];
264 u8 res[2]; /* ??? */
265 u8 group_addr[4][ETH_ALEN];
266 u8 group_addr_status[4];
267} __attribute__((packed));
268
269struct mib_mac {
270 __le32 max_tx_msdu_lifetime;
271 __le32 max_rx_lifetime;
272 __le16 frag_threshold;
273 __le16 rts_threshold;
274 __le16 cwmin;
275 __le16 cwmax;
276 u8 short_retry_time;
277 u8 long_retry_time;
278 u8 scan_type; /* active or passive */
279 u8 scan_channel;
280 __le16 probe_delay; /* delay before ProbeReq in active scan, RO */
281 __le16 min_channel_time;
282 __le16 max_channel_time;
283 __le16 listen_interval;
284 u8 desired_ssid[32];
285 u8 desired_bssid[ETH_ALEN];
286 u8 desired_bsstype; /* ad-hoc or infrastructure */
287 u8 reserved2;
288} __attribute__((packed));
289
290struct mib_mac_mgmt {
291 __le16 beacon_period;
292 __le16 CFP_max_duration;
293 __le16 medium_occupancy_limit;
294 __le16 station_id; /* assoc id */
295 __le16 ATIM_window;
296 u8 CFP_mode;
297 u8 privacy_option_implemented;
298 u8 DTIM_period;
299 u8 CFP_period;
300 u8 current_bssid[ETH_ALEN];
301 u8 current_essid[32];
302 u8 current_bss_type;
303 u8 power_mgmt_mode;
304 /* rfmd and 505 */
305 u8 ibss_change;
306 u8 res;
307 u8 multi_domain_capability_implemented;
308 u8 multi_domain_capability_enabled;
309 u8 country_string[3];
310 u8 reserved[3];
311} __attribute__((packed));
312
313struct mib_mac_wep {
314 u8 privacy_invoked; /* 0 disable encr., 1 enable encr */
315 u8 wep_default_key_id;
316 u8 wep_key_mapping_len;
317 u8 exclude_unencrypted;
318 __le32 wep_icv_error_count;
319 __le32 wep_excluded_count;
320 u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
321 u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
322} __attribute__((packed));
323
324struct mib_phy {
325 __le32 ed_threshold;
326
327 __le16 slot_time;
328 __le16 sifs_time;
329 __le16 preamble_length;
330 __le16 plcp_header_length;
331 __le16 mpdu_max_length;
332 __le16 cca_mode_supported;
333
334 u8 operation_rate_set[4];
335 u8 channel_id;
336 u8 current_cca_mode;
337 u8 phy_type;
338 u8 current_reg_domain;
339} __attribute__((packed));
340
341struct mib_fw_version {
342 u8 major;
343 u8 minor;
344 u8 patch;
345 u8 build;
346} __attribute__((packed));
347
348struct mib_mdomain {
349 u8 tx_powerlevel[14];
350 u8 channel_list[14]; /* 0 for invalid channels */
351} __attribute__((packed));
352
353struct at76_fw_header {
354 __le32 crc; /* CRC32 of the whole image */
355 __le32 board_type; /* firmware compatibility code */
356 u8 build; /* firmware build number */
357 u8 patch; /* firmware patch level */
358 u8 minor; /* firmware minor version */
359 u8 major; /* firmware major version */
360 __le32 str_offset; /* offset of the copyright string */
361 __le32 int_fw_offset; /* internal firmware image offset */
362 __le32 int_fw_len; /* internal firmware image length */
363 __le32 ext_fw_offset; /* external firmware image offset */
364 __le32 ext_fw_len; /* external firmware image length */
365} __attribute__((packed));
366
367enum mac_state {
368 MAC_INIT,
369 MAC_SCANNING,
370 MAC_AUTH,
371 MAC_ASSOC,
372 MAC_JOINING,
373 MAC_CONNECTED,
374 MAC_OWN_IBSS
375};
376
377/* a description of a regulatory domain and the allowed channels */
378struct reg_domain {
379 u16 code;
380 char const *name;
381 u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
382};
383
384/* how long do we keep a (I)BSS in the bss_list in jiffies
385 this should be long enough for the user to retrieve the table
386 (by iwlist ?) after the device started, because all entries from
387 other channels than the one the device locks on get removed, too */
388#define BSS_LIST_TIMEOUT (120 * HZ)
389/* struct to store BSS info found during scan */
390#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
391
392struct bss_info {
393 struct list_head list;
394
395 u8 bssid[ETH_ALEN]; /* bssid */
396 u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */
397 u8 ssid_len; /* length of ssid above */
398 u8 channel;
399 u16 capa; /* BSS capabilities */
400 u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */
401 u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of
402 500 kbps, ORed with 0x80 for
403 basic rates */
404 u8 rates_len;
405
406 /* quality of received beacon */
407 u8 rssi;
408 u8 link_qual;
409 u8 noise_level;
410
411 unsigned long last_rx; /* time (jiffies) of last beacon received */
412};
413
414/* a rx data buffer to collect rx fragments */
415struct rx_data_buf {
416 u8 sender[ETH_ALEN]; /* sender address */
417 u16 seqnr; /* sequence number */
418 u16 fragnr; /* last fragment received */
419 unsigned long last_rx; /* jiffies of last rx */
420 struct sk_buff *skb; /* == NULL if entry is free */
421};
422
423#define NR_RX_DATA_BUF 8
424
425/* Data for one loaded firmware file */
426struct fwentry {
427 const char *const fwname;
428 const struct firmware *fw;
429 int extfw_size;
430 int intfw_size;
431 /* pointer to loaded firmware, no need to free */
432 u8 *extfw; /* external firmware, extfw_size bytes long */
433 u8 *intfw; /* internal firmware, intfw_size bytes long */
434 enum board_type board_type; /* board type */
435 struct mib_fw_version fw_version;
436 int loaded; /* Loaded and parsed successfully */
437};
438
439struct at76_priv {
440 struct usb_device *udev; /* USB device pointer */
441 struct net_device *netdev; /* net device pointer */
442 struct net_device_stats stats; /* net device stats */
443 struct iw_statistics wstats; /* wireless stats */
444
445 struct sk_buff *rx_skb; /* skbuff for receiving data */
446 void *bulk_out_buffer; /* buffer for sending data */
447
448 struct urb *tx_urb; /* URB for sending data */
449 struct urb *rx_urb; /* URB for receiving data */
450
451 unsigned int tx_pipe; /* bulk out pipe */
452 unsigned int rx_pipe; /* bulk in pipe */
453
454 struct mutex mtx; /* locks this structure */
455
456 /* work queues */
457 struct work_struct work_assoc_done;
458 struct work_struct work_join;
459 struct work_struct work_new_bss;
460 struct work_struct work_start_scan;
461 struct work_struct work_set_promisc;
462 struct work_struct work_submit_rx;
463 struct delayed_work dwork_restart;
464 struct delayed_work dwork_get_scan;
465 struct delayed_work dwork_beacon;
466 struct delayed_work dwork_auth;
467 struct delayed_work dwork_assoc;
468
469 struct tasklet_struct rx_tasklet;
470
471 /* the WEP stuff */
472 int wep_enabled; /* 1 if WEP is enabled */
473 int wep_key_id; /* key id to be used */
474 u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
475 5 or 13 bytes are used */
476 u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
477
478 int channel;
479 int iw_mode;
480 u8 bssid[ETH_ALEN];
481 u8 essid[IW_ESSID_MAX_SIZE];
482 int essid_size;
483 int radio_on;
484 int promisc;
485
486 int preamble_type; /* 0 - long, 1 - short, 2 - auto */
487 int auth_mode; /* authentication type: 0 open, 1 shared key */
488 int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
489 int frag_threshold; /* threshold for fragmentation of tx packets */
490 int rts_threshold; /* threshold for RTS mechanism */
491 int short_retry_limit;
492
493 int scan_min_time; /* scan min channel time */
494 int scan_max_time; /* scan max channel time */
495 int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
496 int scan_need_any; /* if set, need to scan for any ESSID */
497
498 /* the list we got from scanning */
499 spinlock_t bss_list_spinlock; /* protects bss_list operations */
500 struct list_head bss_list; /* list of BSS we got beacons from */
501 struct timer_list bss_list_timer; /* timer to purge old entries
502 from bss_list */
503 struct bss_info *curr_bss; /* current BSS */
504 u16 assoc_id; /* current association ID, if associated */
505
506 u8 wanted_bssid[ETH_ALEN];
507 int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
508
509 /* some data for infrastructure mode only */
510 spinlock_t mgmt_spinlock; /* this spinlock protects access to
511 next_mgmt_bulk */
512
513 struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to
514 send via bulk out */
515 enum mac_state mac_state;
516 enum {
517 SCAN_IDLE,
518 SCAN_IN_PROGRESS,
519 SCAN_COMPLETED
520 } scan_state;
521 time_t last_scan;
522
523 int retries; /* remaining retries in case of timeout when
524 * sending AuthReq or AssocReq */
525 u8 pm_mode; /* power management mode */
526 u32 pm_period; /* power management period in microseconds */
527
528 struct reg_domain const *domain; /* reg domain description */
529
530 /* iwspy support */
531 spinlock_t spy_spinlock;
532 struct iw_spy_data spy_data;
533
534 struct iw_public_data wireless_data;
535
536 /* These fields contain HW config provided by the device (not all of
537 * these fields are used by all board types) */
538 u8 mac_addr[ETH_ALEN];
539 u8 regulatory_domain;
540
541 struct at76_card_config card_config;
542
543 /* store rx fragments until complete */
544 struct rx_data_buf rx_data[NR_RX_DATA_BUF];
545
546 enum board_type board_type;
547 struct mib_fw_version fw_version;
548
549 unsigned int device_unplugged:1;
550 unsigned int netdev_registered:1;
551 struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
552
553 /* beacon counting */
554 int beacon_period; /* period of mgmt beacons, Kus */
555 int beacons_received;
556 unsigned long beacons_last_qual; /* time we restarted counting
557 beacons */
558};
559
560struct at76_rx_radiotap {
561 struct ieee80211_radiotap_header rt_hdr;
562 __le64 rt_tsft;
563 u8 rt_flags;
564 u8 rt_rate;
565 s8 rt_signal;
566 s8 rt_noise;
567};
568
569#define AT76_RX_RADIOTAP_PRESENT \
570 ((1 << IEEE80211_RADIOTAP_TSFT) | \
571 (1 << IEEE80211_RADIOTAP_FLAGS) | \
572 (1 << IEEE80211_RADIOTAP_RATE) | \
573 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
574 (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
575
576#define BEACON_MAX_DATA_LENGTH 1500
577
578/* the maximum size of an AssocReq packet */
579#define ASSOCREQ_MAX_SIZE \
580 (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
581 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
582
583/* for shared secret auth, add the challenge text size */
584#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
585
586/* Maximal number of AuthReq retries */
587#define AUTH_RETRIES 3
588
589/* Maximal number of AssocReq retries */
590#define ASSOC_RETRIES 3
591
592/* Beacon timeout in managed mode when we are connected */
593#define BEACON_TIMEOUT (10 * HZ)
594
595/* Timeout for authentication response */
596#define AUTH_TIMEOUT (1 * HZ)
597
598/* Timeout for association response */
599#define ASSOC_TIMEOUT (1 * HZ)
600
601/* Polling interval when scan is running */
602#define SCAN_POLL_INTERVAL (HZ / 4)
603
604/* Command completion timeout */
605#define CMD_COMPLETION_TIMEOUT (5 * HZ)
606
607#define DEF_RTS_THRESHOLD 1536
608#define DEF_FRAG_THRESHOLD 1536
609#define DEF_SHORT_RETRY_LIMIT 8
610#define DEF_CHANNEL 10
611#define DEF_SCAN_MIN_TIME 10
612#define DEF_SCAN_MAX_TIME 120
613
614#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
615
616/* the max padding size for tx in bytes (see calc_padding) */
617#define MAX_PADDING_SIZE 53
618
619#endif /* _AT76_USB_H */