Staging: at76: convert to netdev_ops
[linux-2.6/mini2440.git] / drivers / staging / at76_usb / at76_usb.c
blobc8af9a868d6219bcf140b389c43d0b690338163e
1 /*
2 * at76c503/at76c505 USB driver
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>
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.
15 * This file is part of the Berlios driver for WLAN USB devices based on the
16 * Atmel AT76C503A/505/505A.
18 * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
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 <linux/ieee80211.h>
41 #include "at76_usb.h"
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"
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 */
80 #define DBG_DEFAULTS 0
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)
89 static int at76_debug = DBG_DEFAULTS;
91 /* Protect against concurrent firmware loading and parsing */
92 static struct mutex fw_mutex;
94 static 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"},
106 #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
108 static struct usb_device_id dev_table[] = {
110 * at76c503-i3861
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)},
143 * at76c503-i3863
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)},
150 * at76c503-rfmd
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)},
197 * at76c503-rfmd-acc
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)},
204 * at76c505-rfmd
206 /* Generic AT76C505/RFMD */
207 {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
209 * at76c505-rfmd2958
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)},
226 * at76c505a-rfmd2958
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 /* OQO Model 01+ Internal Wi-Fi */
235 {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)},
237 * at76c505amx-rfmd
239 /* Generic AT76C505AMX device */
240 {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
244 MODULE_DEVICE_TABLE(usb, dev_table);
246 /* Supported rates of this hardware, bit 7 marks basic rates */
247 static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
249 /* Frequency of each channel in MHz */
250 static const long channel_frequency[] = {
251 2412, 2417, 2422, 2427, 2432, 2437, 2442,
252 2447, 2452, 2457, 2462, 2467, 2472, 2484
255 #define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
257 static const char *const preambles[] = { "long", "short", "auto" };
259 static const char *const mac_states[] = {
260 [MAC_INIT] = "INIT",
261 [MAC_SCANNING] = "SCANNING",
262 [MAC_AUTH] = "AUTH",
263 [MAC_ASSOC] = "ASSOC",
264 [MAC_JOINING] = "JOINING",
265 [MAC_CONNECTED] = "CONNECTED",
266 [MAC_OWN_IBSS] = "OWN_IBSS"
269 /* Firmware download */
270 /* DFU states */
271 #define STATE_IDLE 0x00
272 #define STATE_DETACH 0x01
273 #define STATE_DFU_IDLE 0x02
274 #define STATE_DFU_DOWNLOAD_SYNC 0x03
275 #define STATE_DFU_DOWNLOAD_BUSY 0x04
276 #define STATE_DFU_DOWNLOAD_IDLE 0x05
277 #define STATE_DFU_MANIFEST_SYNC 0x06
278 #define STATE_DFU_MANIFEST 0x07
279 #define STATE_DFU_MANIFEST_WAIT_RESET 0x08
280 #define STATE_DFU_UPLOAD_IDLE 0x09
281 #define STATE_DFU_ERROR 0x0a
283 /* DFU commands */
284 #define DFU_DETACH 0
285 #define DFU_DNLOAD 1
286 #define DFU_UPLOAD 2
287 #define DFU_GETSTATUS 3
288 #define DFU_CLRSTATUS 4
289 #define DFU_GETSTATE 5
290 #define DFU_ABORT 6
292 #define FW_BLOCK_SIZE 1024
294 struct dfu_status {
295 unsigned char status;
296 unsigned char poll_timeout[3];
297 unsigned char state;
298 unsigned char string;
299 } __attribute__((packed));
301 static inline int at76_is_intersil(enum board_type board)
303 return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
306 static inline int at76_is_503rfmd(enum board_type board)
308 return (board == BOARD_503 || board == BOARD_503_ACC);
311 static inline int at76_is_505a(enum board_type board)
313 return (board == BOARD_505A || board == BOARD_505AMX);
316 /* Load a block of the first (internal) part of the firmware */
317 static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
318 void *block, int size)
320 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
321 USB_TYPE_CLASS | USB_DIR_OUT |
322 USB_RECIP_INTERFACE, blockno, 0, block, size,
323 USB_CTRL_GET_TIMEOUT);
326 static int at76_dfu_get_status(struct usb_device *udev,
327 struct dfu_status *status)
329 int ret;
331 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
332 USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
333 0, 0, status, sizeof(struct dfu_status),
334 USB_CTRL_GET_TIMEOUT);
335 return ret;
338 static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
340 int ret;
342 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
343 USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
344 0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
345 return ret;
348 /* Convert timeout from the DFU status to jiffies */
349 static inline unsigned long at76_get_timeout(struct dfu_status *s)
351 return msecs_to_jiffies((s->poll_timeout[2] << 16)
352 | (s->poll_timeout[1] << 8)
353 | (s->poll_timeout[0]));
356 /* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use
357 * its value in jiffies in the MANIFEST_SYNC state. */
358 static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
359 int manifest_sync_timeout)
361 u8 *block;
362 struct dfu_status dfu_stat_buf;
363 int ret = 0;
364 int need_dfu_state = 1;
365 int is_done = 0;
366 u8 dfu_state = 0;
367 u32 dfu_timeout = 0;
368 int bsize = 0;
369 int blockno = 0;
371 at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
372 manifest_sync_timeout);
374 if (!size) {
375 dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
376 return -EINVAL;
379 block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
380 if (!block)
381 return -ENOMEM;
383 do {
384 if (need_dfu_state) {
385 ret = at76_dfu_get_state(udev, &dfu_state);
386 if (ret < 0) {
387 dev_printk(KERN_ERR, &udev->dev,
388 "cannot get DFU state: %d\n", ret);
389 goto exit;
391 need_dfu_state = 0;
394 switch (dfu_state) {
395 case STATE_DFU_DOWNLOAD_SYNC:
396 at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
397 ret = at76_dfu_get_status(udev, &dfu_stat_buf);
398 if (ret >= 0) {
399 dfu_state = dfu_stat_buf.state;
400 dfu_timeout = at76_get_timeout(&dfu_stat_buf);
401 need_dfu_state = 0;
402 } else
403 dev_printk(KERN_ERR, &udev->dev,
404 "at76_dfu_get_status returned %d\n",
405 ret);
406 break;
408 case STATE_DFU_DOWNLOAD_BUSY:
409 at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
410 need_dfu_state = 1;
412 at76_dbg(DBG_DFU, "DFU: Resetting device");
413 schedule_timeout_interruptible(dfu_timeout);
414 break;
416 case STATE_DFU_DOWNLOAD_IDLE:
417 at76_dbg(DBG_DFU, "DOWNLOAD...");
418 /* fall through */
419 case STATE_DFU_IDLE:
420 at76_dbg(DBG_DFU, "DFU IDLE");
422 bsize = min_t(int, size, FW_BLOCK_SIZE);
423 memcpy(block, buf, bsize);
424 at76_dbg(DBG_DFU, "int fw, size left = %5d, "
425 "bsize = %4d, blockno = %2d", size, bsize,
426 blockno);
427 ret =
428 at76_load_int_fw_block(udev, blockno, block, bsize);
429 buf += bsize;
430 size -= bsize;
431 blockno++;
433 if (ret != bsize)
434 dev_printk(KERN_ERR, &udev->dev,
435 "at76_load_int_fw_block "
436 "returned %d\n", ret);
437 need_dfu_state = 1;
438 break;
440 case STATE_DFU_MANIFEST_SYNC:
441 at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
443 ret = at76_dfu_get_status(udev, &dfu_stat_buf);
444 if (ret < 0)
445 break;
447 dfu_state = dfu_stat_buf.state;
448 dfu_timeout = at76_get_timeout(&dfu_stat_buf);
449 need_dfu_state = 0;
451 /* override the timeout from the status response,
452 needed for AT76C505A */
453 if (manifest_sync_timeout > 0)
454 dfu_timeout = manifest_sync_timeout;
456 at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
457 schedule_timeout_interruptible(dfu_timeout);
458 break;
460 case STATE_DFU_MANIFEST:
461 at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
462 is_done = 1;
463 break;
465 case STATE_DFU_MANIFEST_WAIT_RESET:
466 at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
467 is_done = 1;
468 break;
470 case STATE_DFU_UPLOAD_IDLE:
471 at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
472 break;
474 case STATE_DFU_ERROR:
475 at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
476 ret = -EPIPE;
477 break;
479 default:
480 at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
481 ret = -EINVAL;
482 break;
484 } while (!is_done && (ret >= 0));
486 exit:
487 kfree(block);
488 if (ret >= 0)
489 ret = 0;
491 return ret;
494 /* Report that the scan results are ready */
495 static inline void at76_iwevent_scan_complete(struct net_device *netdev)
497 union iwreq_data wrqu;
498 wrqu.data.length = 0;
499 wrqu.data.flags = 0;
500 wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
501 at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
504 static inline void at76_iwevent_bss_connect(struct net_device *netdev,
505 u8 *bssid)
507 union iwreq_data wrqu;
508 wrqu.data.length = 0;
509 wrqu.data.flags = 0;
510 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
511 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
512 wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
513 at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
514 __func__);
517 static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
519 union iwreq_data wrqu;
520 wrqu.data.length = 0;
521 wrqu.data.flags = 0;
522 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
523 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
524 wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
525 at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
526 __func__);
529 #define HEX2STR_BUFFERS 4
530 #define HEX2STR_MAX_LEN 64
531 #define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
533 /* Convert binary data into hex string */
534 static char *hex2str(void *buf, int len)
536 static atomic_t a = ATOMIC_INIT(0);
537 static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
538 char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
539 char *obuf = ret;
540 u8 *ibuf = buf;
542 if (len > HEX2STR_MAX_LEN)
543 len = HEX2STR_MAX_LEN;
545 if (len <= 0) {
546 ret[0] = '\0';
547 return ret;
550 while (len--) {
551 *obuf++ = BIN2HEX(*ibuf >> 4);
552 *obuf++ = BIN2HEX(*ibuf & 0xf);
553 *obuf++ = '-';
554 ibuf++;
556 *(--obuf) = '\0';
558 return ret;
561 #define MAC2STR_BUFFERS 4
563 static inline char *mac2str(u8 *mac)
565 static atomic_t a = ATOMIC_INIT(0);
566 static char bufs[MAC2STR_BUFFERS][6 * 3];
567 char *str;
569 str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
570 sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
571 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
572 return str;
575 /* LED trigger */
576 static int tx_activity;
577 static void at76_ledtrig_tx_timerfunc(unsigned long data);
578 static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
579 DEFINE_LED_TRIGGER(ledtrig_tx);
581 static void at76_ledtrig_tx_timerfunc(unsigned long data)
583 static int tx_lastactivity;
585 if (tx_lastactivity != tx_activity) {
586 tx_lastactivity = tx_activity;
587 led_trigger_event(ledtrig_tx, LED_FULL);
588 mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
589 } else
590 led_trigger_event(ledtrig_tx, LED_OFF);
593 static void at76_ledtrig_tx_activity(void)
595 tx_activity++;
596 if (!timer_pending(&ledtrig_tx_timer))
597 mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
600 /* Check if the given ssid is hidden */
601 static inline int at76_is_hidden_ssid(u8 *ssid, int length)
603 static const u8 zeros[32];
605 if (length == 0)
606 return 1;
608 if (length == 1 && ssid[0] == ' ')
609 return 1;
611 return (memcmp(ssid, zeros, length) == 0);
614 static inline void at76_free_bss_list(struct at76_priv *priv)
616 struct list_head *next, *ptr;
617 unsigned long flags;
619 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
621 priv->curr_bss = NULL;
623 list_for_each_safe(ptr, next, &priv->bss_list) {
624 list_del(ptr);
625 kfree(list_entry(ptr, struct bss_info, list));
628 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
631 static int at76_remap(struct usb_device *udev)
633 int ret;
634 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
635 USB_TYPE_VENDOR | USB_DIR_OUT |
636 USB_RECIP_INTERFACE, 0, 0, NULL, 0,
637 USB_CTRL_GET_TIMEOUT);
638 if (ret < 0)
639 return ret;
640 return 0;
643 static int at76_get_op_mode(struct usb_device *udev)
645 int ret;
646 u8 saved;
647 u8 *op_mode;
649 op_mode = kmalloc(1, GFP_NOIO);
650 if (!op_mode)
651 return -ENOMEM;
652 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
653 USB_TYPE_VENDOR | USB_DIR_IN |
654 USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
655 USB_CTRL_GET_TIMEOUT);
656 saved = *op_mode;
657 kfree(op_mode);
659 if (ret < 0)
660 return ret;
661 else if (ret < 1)
662 return -EIO;
663 else
664 return saved;
667 /* Load a block of the second ("external") part of the firmware */
668 static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
669 void *block, int size)
671 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
672 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
673 0x0802, blockno, block, size,
674 USB_CTRL_GET_TIMEOUT);
677 static inline int at76_get_hw_cfg(struct usb_device *udev,
678 union at76_hwcfg *buf, int buf_size)
680 return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
681 USB_TYPE_VENDOR | USB_DIR_IN |
682 USB_RECIP_INTERFACE, 0x0a02, 0,
683 buf, buf_size, USB_CTRL_GET_TIMEOUT);
686 /* Intersil boards use a different "value" for GetHWConfig requests */
687 static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
688 union at76_hwcfg *buf, int buf_size)
690 return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
691 USB_TYPE_VENDOR | USB_DIR_IN |
692 USB_RECIP_INTERFACE, 0x0902, 0,
693 buf, buf_size, USB_CTRL_GET_TIMEOUT);
696 /* Get the hardware configuration for the adapter and put it to the appropriate
697 * fields of 'priv' (the GetHWConfig request and interpretation of the result
698 * depends on the board type) */
699 static int at76_get_hw_config(struct at76_priv *priv)
701 int ret;
702 union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
704 if (!hwcfg)
705 return -ENOMEM;
707 if (at76_is_intersil(priv->board_type)) {
708 ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
709 sizeof(hwcfg->i));
710 if (ret < 0)
711 goto exit;
712 memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
713 priv->regulatory_domain = hwcfg->i.regulatory_domain;
714 } else if (at76_is_503rfmd(priv->board_type)) {
715 ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
716 if (ret < 0)
717 goto exit;
718 memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
719 priv->regulatory_domain = hwcfg->r3.regulatory_domain;
720 } else {
721 ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
722 if (ret < 0)
723 goto exit;
724 memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
725 priv->regulatory_domain = hwcfg->r5.regulatory_domain;
728 exit:
729 kfree(hwcfg);
730 if (ret < 0)
731 printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
732 priv->netdev->name, ret);
734 return ret;
737 static struct reg_domain const *at76_get_reg_domain(u16 code)
739 int i;
740 static struct reg_domain const fd_tab[] = {
741 {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */
742 {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
743 {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */
744 {0x31, "Spain", 0x600}, /* ch 10-11 */
745 {0x32, "France", 0x1e00}, /* ch 10-13 */
746 {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
747 {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
748 {0x50, "Israel", 0x3fc}, /* ch 3-9 */
749 {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */
752 /* Last entry is fallback for unknown domain code */
753 for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
754 if (code == fd_tab[i].code)
755 break;
757 return &fd_tab[i];
760 static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
761 int buf_size)
763 int ret;
765 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
766 USB_TYPE_VENDOR | USB_DIR_IN |
767 USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
768 USB_CTRL_GET_TIMEOUT);
769 if (ret >= 0 && ret != buf_size)
770 return -EIO;
771 return ret;
774 /* Return positive number for status, negative for an error */
775 static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
777 u8 *stat_buf;
778 int ret;
780 stat_buf = kmalloc(40, GFP_NOIO);
781 if (!stat_buf)
782 return -ENOMEM;
784 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
785 USB_TYPE_VENDOR | USB_DIR_IN |
786 USB_RECIP_INTERFACE, cmd, 0, stat_buf,
787 40, USB_CTRL_GET_TIMEOUT);
788 if (ret >= 0)
789 ret = stat_buf[5];
790 kfree(stat_buf);
792 return ret;
795 static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
796 int buf_size)
798 int ret;
799 struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
800 buf_size, GFP_KERNEL);
802 if (!cmd_buf)
803 return -ENOMEM;
805 cmd_buf->cmd = cmd;
806 cmd_buf->reserved = 0;
807 cmd_buf->size = cpu_to_le16(buf_size);
808 memcpy(cmd_buf->data, buf, buf_size);
810 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
811 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
812 0, 0, cmd_buf,
813 sizeof(struct at76_command) + buf_size,
814 USB_CTRL_GET_TIMEOUT);
815 kfree(cmd_buf);
816 return ret;
819 #define MAKE_CMD_STATUS_CASE(c) case (c): return #c
820 static const char *at76_get_cmd_status_string(u8 cmd_status)
822 switch (cmd_status) {
823 MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
824 MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
825 MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
826 MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
827 MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
828 MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
829 MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
830 MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
831 MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
834 return "UNKNOWN";
837 /* Wait until the command is completed */
838 static int at76_wait_completion(struct at76_priv *priv, int cmd)
840 int status = 0;
841 unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
843 do {
844 status = at76_get_cmd_status(priv->udev, cmd);
845 if (status < 0) {
846 printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
847 priv->netdev->name, status);
848 break;
851 at76_dbg(DBG_WAIT_COMPLETE,
852 "%s: Waiting on cmd %d, status = %d (%s)",
853 priv->netdev->name, cmd, status,
854 at76_get_cmd_status_string(status));
856 if (status != CMD_STATUS_IN_PROGRESS
857 && status != CMD_STATUS_IDLE)
858 break;
860 schedule_timeout_interruptible(HZ / 10); /* 100 ms */
861 if (time_after(jiffies, timeout)) {
862 printk(KERN_ERR
863 "%s: completion timeout for command %d\n",
864 priv->netdev->name, cmd);
865 status = -ETIMEDOUT;
866 break;
868 } while (1);
870 return status;
873 static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
875 int ret;
877 ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
878 offsetof(struct set_mib_buffer,
879 data) + buf->size);
880 if (ret < 0)
881 return ret;
883 ret = at76_wait_completion(priv, CMD_SET_MIB);
884 if (ret != CMD_STATUS_COMPLETE) {
885 printk(KERN_INFO
886 "%s: set_mib: at76_wait_completion failed "
887 "with %d\n", priv->netdev->name, ret);
888 ret = -EIO;
891 return ret;
894 /* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
895 static int at76_set_radio(struct at76_priv *priv, int enable)
897 int ret;
898 int cmd;
900 if (priv->radio_on == enable)
901 return 0;
903 cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
905 ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
906 if (ret < 0)
907 printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
908 priv->netdev->name, cmd, ret);
909 else
910 ret = 1;
912 priv->radio_on = enable;
913 return ret;
916 /* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
917 static int at76_set_pm_mode(struct at76_priv *priv)
919 int ret = 0;
921 priv->mib_buf.type = MIB_MAC_MGMT;
922 priv->mib_buf.size = 1;
923 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
924 priv->mib_buf.data.byte = priv->pm_mode;
926 ret = at76_set_mib(priv, &priv->mib_buf);
927 if (ret < 0)
928 printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
929 priv->netdev->name, ret);
931 return ret;
934 /* Set the association id for power save mode */
935 static int at76_set_associd(struct at76_priv *priv, u16 id)
937 int ret = 0;
939 priv->mib_buf.type = MIB_MAC_MGMT;
940 priv->mib_buf.size = 2;
941 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
942 priv->mib_buf.data.word = cpu_to_le16(id);
944 ret = at76_set_mib(priv, &priv->mib_buf);
945 if (ret < 0)
946 printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
947 priv->netdev->name, ret);
949 return ret;
952 /* Set the listen interval for power save mode */
953 static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
955 int ret = 0;
957 priv->mib_buf.type = MIB_MAC;
958 priv->mib_buf.size = 2;
959 priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
960 priv->mib_buf.data.word = cpu_to_le16(interval);
962 ret = at76_set_mib(priv, &priv->mib_buf);
963 if (ret < 0)
964 printk(KERN_ERR
965 "%s: set_mib (listen_interval) failed: %d\n",
966 priv->netdev->name, ret);
968 return ret;
971 static int at76_set_preamble(struct at76_priv *priv, u8 type)
973 int ret = 0;
975 priv->mib_buf.type = MIB_LOCAL;
976 priv->mib_buf.size = 1;
977 priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
978 priv->mib_buf.data.byte = type;
980 ret = at76_set_mib(priv, &priv->mib_buf);
981 if (ret < 0)
982 printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
983 priv->netdev->name, ret);
985 return ret;
988 static int at76_set_frag(struct at76_priv *priv, u16 size)
990 int ret = 0;
992 priv->mib_buf.type = MIB_MAC;
993 priv->mib_buf.size = 2;
994 priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
995 priv->mib_buf.data.word = cpu_to_le16(size);
997 ret = at76_set_mib(priv, &priv->mib_buf);
998 if (ret < 0)
999 printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
1000 priv->netdev->name, ret);
1002 return ret;
1005 static int at76_set_rts(struct at76_priv *priv, u16 size)
1007 int ret = 0;
1009 priv->mib_buf.type = MIB_MAC;
1010 priv->mib_buf.size = 2;
1011 priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
1012 priv->mib_buf.data.word = cpu_to_le16(size);
1014 ret = at76_set_mib(priv, &priv->mib_buf);
1015 if (ret < 0)
1016 printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
1017 priv->netdev->name, ret);
1019 return ret;
1022 static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
1024 int ret = 0;
1026 priv->mib_buf.type = MIB_LOCAL;
1027 priv->mib_buf.size = 1;
1028 priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
1029 priv->mib_buf.data.byte = onoff;
1031 ret = at76_set_mib(priv, &priv->mib_buf);
1032 if (ret < 0)
1033 printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
1034 priv->netdev->name, ret);
1036 return ret;
1039 static int at76_add_mac_address(struct at76_priv *priv, void *addr)
1041 int ret = 0;
1043 priv->mib_buf.type = MIB_MAC_ADDR;
1044 priv->mib_buf.size = ETH_ALEN;
1045 priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
1046 memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
1048 ret = at76_set_mib(priv, &priv->mib_buf);
1049 if (ret < 0)
1050 printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
1051 priv->netdev->name, ret);
1053 return ret;
1056 static void at76_dump_mib_mac_addr(struct at76_priv *priv)
1058 int i;
1059 int ret;
1060 struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
1061 GFP_KERNEL);
1063 if (!m)
1064 return;
1066 ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
1067 sizeof(struct mib_mac_addr));
1068 if (ret < 0) {
1069 printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
1070 priv->netdev->name, ret);
1071 goto exit;
1074 at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
1075 priv->netdev->name,
1076 mac2str(m->mac_addr), m->res[0], m->res[1]);
1077 for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
1078 at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
1079 "status %d", priv->netdev->name, i,
1080 mac2str(m->group_addr[i]), m->group_addr_status[i]);
1081 exit:
1082 kfree(m);
1085 static void at76_dump_mib_mac_wep(struct at76_priv *priv)
1087 int i;
1088 int ret;
1089 int key_len;
1090 struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
1092 if (!m)
1093 return;
1095 ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
1096 sizeof(struct mib_mac_wep));
1097 if (ret < 0) {
1098 printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
1099 priv->netdev->name, ret);
1100 goto exit;
1103 at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
1104 "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
1105 "encr_level %u key %d", priv->netdev->name,
1106 m->privacy_invoked, m->wep_default_key_id,
1107 m->wep_key_mapping_len, m->exclude_unencrypted,
1108 le32_to_cpu(m->wep_icv_error_count),
1109 le32_to_cpu(m->wep_excluded_count), m->encryption_level,
1110 m->wep_default_key_id);
1112 key_len = (m->encryption_level == 1) ?
1113 WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
1115 for (i = 0; i < WEP_KEYS; i++)
1116 at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
1117 priv->netdev->name, i,
1118 hex2str(m->wep_default_keyvalue[i], key_len));
1119 exit:
1120 kfree(m);
1123 static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
1125 int ret;
1126 struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
1127 GFP_KERNEL);
1129 if (!m)
1130 return;
1132 ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
1133 sizeof(struct mib_mac_mgmt));
1134 if (ret < 0) {
1135 printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
1136 priv->netdev->name, ret);
1137 goto exit;
1140 at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
1141 "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
1142 "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
1143 "current_bssid %s current_essid %s current_bss_type %d "
1144 "pm_mode %d ibss_change %d res %d "
1145 "multi_domain_capability_implemented %d "
1146 "international_roaming %d country_string %.3s",
1147 priv->netdev->name, le16_to_cpu(m->beacon_period),
1148 le16_to_cpu(m->CFP_max_duration),
1149 le16_to_cpu(m->medium_occupancy_limit),
1150 le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
1151 m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
1152 m->CFP_period, mac2str(m->current_bssid),
1153 hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
1154 m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
1155 m->res, m->multi_domain_capability_implemented,
1156 m->multi_domain_capability_enabled, m->country_string);
1157 exit:
1158 kfree(m);
1161 static void at76_dump_mib_mac(struct at76_priv *priv)
1163 int ret;
1164 struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
1166 if (!m)
1167 return;
1169 ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
1170 if (ret < 0) {
1171 printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
1172 priv->netdev->name, ret);
1173 goto exit;
1176 at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
1177 "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
1178 "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
1179 "scan_type %d scan_channel %d probe_delay %u "
1180 "min_channel_time %d max_channel_time %d listen_int %d "
1181 "desired_ssid %s desired_bssid %s desired_bsstype %d",
1182 priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
1183 le32_to_cpu(m->max_rx_lifetime),
1184 le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
1185 le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
1186 m->short_retry_time, m->long_retry_time, m->scan_type,
1187 m->scan_channel, le16_to_cpu(m->probe_delay),
1188 le16_to_cpu(m->min_channel_time),
1189 le16_to_cpu(m->max_channel_time),
1190 le16_to_cpu(m->listen_interval),
1191 hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
1192 mac2str(m->desired_bssid), m->desired_bsstype);
1193 exit:
1194 kfree(m);
1197 static void at76_dump_mib_phy(struct at76_priv *priv)
1199 int ret;
1200 struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1202 if (!m)
1203 return;
1205 ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
1206 if (ret < 0) {
1207 printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
1208 priv->netdev->name, ret);
1209 goto exit;
1212 at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
1213 "sifs_time %d preamble_length %d plcp_header_length %d "
1214 "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
1215 "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
1216 "phy_type %d current_reg_domain %d",
1217 priv->netdev->name, le32_to_cpu(m->ed_threshold),
1218 le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
1219 le16_to_cpu(m->preamble_length),
1220 le16_to_cpu(m->plcp_header_length),
1221 le16_to_cpu(m->mpdu_max_length),
1222 le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
1223 m->operation_rate_set[1], m->operation_rate_set[2],
1224 m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
1225 m->phy_type, m->current_reg_domain);
1226 exit:
1227 kfree(m);
1230 static void at76_dump_mib_local(struct at76_priv *priv)
1232 int ret;
1233 struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1235 if (!m)
1236 return;
1238 ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
1239 if (ret < 0) {
1240 printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
1241 priv->netdev->name, ret);
1242 goto exit;
1245 at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
1246 "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
1247 "preamble_type %d", priv->netdev->name, m->beacon_enable,
1248 m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
1249 m->preamble_type);
1250 exit:
1251 kfree(m);
1254 static void at76_dump_mib_mdomain(struct at76_priv *priv)
1256 int ret;
1257 struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
1259 if (!m)
1260 return;
1262 ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
1263 sizeof(struct mib_mdomain));
1264 if (ret < 0) {
1265 printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
1266 priv->netdev->name, ret);
1267 goto exit;
1270 at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
1271 priv->netdev->name,
1272 hex2str(m->channel_list, sizeof(m->channel_list)));
1274 at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
1275 priv->netdev->name,
1276 hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
1277 exit:
1278 kfree(m);
1281 static int at76_get_current_bssid(struct at76_priv *priv)
1283 int ret = 0;
1284 struct mib_mac_mgmt *mac_mgmt =
1285 kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
1287 if (!mac_mgmt) {
1288 ret = -ENOMEM;
1289 goto exit;
1292 ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
1293 sizeof(struct mib_mac_mgmt));
1294 if (ret < 0) {
1295 printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
1296 priv->netdev->name, ret);
1297 goto error;
1299 memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
1300 printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
1301 mac2str(priv->bssid));
1302 error:
1303 kfree(mac_mgmt);
1304 exit:
1305 return ret;
1308 static int at76_get_current_channel(struct at76_priv *priv)
1310 int ret = 0;
1311 struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1313 if (!phy) {
1314 ret = -ENOMEM;
1315 goto exit;
1317 ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
1318 if (ret < 0) {
1319 printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
1320 priv->netdev->name, ret);
1321 goto error;
1323 priv->channel = phy->channel_id;
1324 error:
1325 kfree(phy);
1326 exit:
1327 return ret;
1331 * at76_start_scan - start a scan
1333 * @use_essid - use the configured ESSID in non passive mode
1335 static int at76_start_scan(struct at76_priv *priv, int use_essid)
1337 struct at76_req_scan scan;
1339 memset(&scan, 0, sizeof(struct at76_req_scan));
1340 memset(scan.bssid, 0xff, ETH_ALEN);
1342 if (use_essid) {
1343 memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
1344 scan.essid_size = priv->essid_size;
1345 } else
1346 scan.essid_size = 0;
1348 /* jal: why should we start at a certain channel? we do scan the whole
1349 range allowed by reg domain. */
1350 scan.channel = priv->channel;
1352 /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
1353 For ad-hoc mode, it uses type 0 only. */
1354 scan.scan_type = priv->scan_mode;
1356 /* INFO: For probe_delay, not multiplying by 1024 as this will be
1357 slightly less than min_channel_time
1358 (per spec: probe delay < min. channel time) */
1359 scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
1360 scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
1361 scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
1362 scan.international_scan = 0;
1364 /* other values are set to 0 for type 0 */
1366 at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
1367 "channel = %d, probe_delay = %d, scan_min_time = %d, "
1368 "scan_max_time = %d)",
1369 priv->netdev->name, use_essid,
1370 scan.international_scan, scan.channel,
1371 le16_to_cpu(scan.probe_delay),
1372 le16_to_cpu(scan.min_channel_time),
1373 le16_to_cpu(scan.max_channel_time));
1375 return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
1378 /* Enable monitor mode */
1379 static int at76_start_monitor(struct at76_priv *priv)
1381 struct at76_req_scan scan;
1382 int ret;
1384 memset(&scan, 0, sizeof(struct at76_req_scan));
1385 memset(scan.bssid, 0xff, ETH_ALEN);
1387 scan.channel = priv->channel;
1388 scan.scan_type = SCAN_TYPE_PASSIVE;
1389 scan.international_scan = 0;
1391 ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
1392 if (ret >= 0)
1393 ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
1395 return ret;
1398 static int at76_start_ibss(struct at76_priv *priv)
1400 struct at76_req_ibss bss;
1401 int ret;
1403 WARN_ON(priv->mac_state != MAC_OWN_IBSS);
1404 if (priv->mac_state != MAC_OWN_IBSS)
1405 return -EBUSY;
1407 memset(&bss, 0, sizeof(struct at76_req_ibss));
1408 memset(bss.bssid, 0xff, ETH_ALEN);
1409 memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
1410 bss.essid_size = priv->essid_size;
1411 bss.bss_type = ADHOC_MODE;
1412 bss.channel = priv->channel;
1414 ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
1415 sizeof(struct at76_req_ibss));
1416 if (ret < 0) {
1417 printk(KERN_ERR "%s: start_ibss failed: %d\n",
1418 priv->netdev->name, ret);
1419 return ret;
1422 ret = at76_wait_completion(priv, CMD_START_IBSS);
1423 if (ret != CMD_STATUS_COMPLETE) {
1424 printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
1425 priv->netdev->name, ret);
1426 return ret;
1429 ret = at76_get_current_bssid(priv);
1430 if (ret < 0)
1431 return ret;
1433 ret = at76_get_current_channel(priv);
1434 if (ret < 0)
1435 return ret;
1437 /* not sure what this is good for ??? */
1438 priv->mib_buf.type = MIB_MAC_MGMT;
1439 priv->mib_buf.size = 1;
1440 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
1441 priv->mib_buf.data.byte = 0;
1443 ret = at76_set_mib(priv, &priv->mib_buf);
1444 if (ret < 0) {
1445 printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
1446 priv->netdev->name, ret);
1447 return ret;
1450 netif_carrier_on(priv->netdev);
1451 netif_start_queue(priv->netdev);
1452 return 0;
1455 /* Request card to join BSS in managed or ad-hoc mode */
1456 static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
1458 struct at76_req_join join;
1460 BUG_ON(!ptr);
1462 memset(&join, 0, sizeof(struct at76_req_join));
1463 memcpy(join.bssid, ptr->bssid, ETH_ALEN);
1464 memcpy(join.essid, ptr->ssid, ptr->ssid_len);
1465 join.essid_size = ptr->ssid_len;
1466 join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
1467 join.channel = ptr->channel;
1468 join.timeout = cpu_to_le16(2000);
1470 at76_dbg(DBG_PROGRESS,
1471 "%s join addr %s ssid %s type %d ch %d timeout %d",
1472 priv->netdev->name, mac2str(join.bssid), join.essid,
1473 join.bss_type, join.channel, le16_to_cpu(join.timeout));
1474 return at76_set_card_command(priv->udev, CMD_JOIN, &join,
1475 sizeof(struct at76_req_join));
1478 /* Calculate padding from txbuf->wlength (which excludes the USB TX header),
1479 likely to compensate a flaw in the AT76C503A USB part ... */
1480 static inline int at76_calc_padding(int wlen)
1482 /* add the USB TX header */
1483 wlen += AT76_TX_HDRLEN;
1485 wlen = wlen % 64;
1487 if (wlen < 50)
1488 return 50 - wlen;
1490 if (wlen >= 61)
1491 return 64 + 50 - wlen;
1493 return 0;
1496 /* We are doing a lot of things here in an interrupt. Need
1497 a bh handler (Watching TV with a TV card is probably
1498 a good test: if you see flickers, we are doing too much.
1499 Currently I do see flickers... even with our tasklet :-( )
1500 Maybe because the bttv driver and usb-uhci use the same interrupt
1502 /* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
1503 * solve everything.. (alex) */
1504 static void at76_rx_callback(struct urb *urb)
1506 struct at76_priv *priv = urb->context;
1508 priv->rx_tasklet.data = (unsigned long)urb;
1509 tasklet_schedule(&priv->rx_tasklet);
1510 return;
1513 static void at76_tx_callback(struct urb *urb)
1515 struct at76_priv *priv = urb->context;
1516 struct net_device_stats *stats = &priv->stats;
1517 unsigned long flags;
1518 struct at76_tx_buffer *mgmt_buf;
1519 int ret;
1521 switch (urb->status) {
1522 case 0:
1523 stats->tx_packets++;
1524 break;
1525 case -ENOENT:
1526 case -ECONNRESET:
1527 /* urb has been unlinked */
1528 return;
1529 default:
1530 at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
1531 __func__, urb->status);
1532 stats->tx_errors++;
1533 break;
1536 spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1537 mgmt_buf = priv->next_mgmt_bulk;
1538 priv->next_mgmt_bulk = NULL;
1539 spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1541 if (!mgmt_buf) {
1542 netif_wake_queue(priv->netdev);
1543 return;
1546 /* we don't copy the padding bytes, but add them
1547 to the length */
1548 memcpy(priv->bulk_out_buffer, mgmt_buf,
1549 le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
1550 usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
1551 priv->bulk_out_buffer,
1552 le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
1553 AT76_TX_HDRLEN, at76_tx_callback, priv);
1554 ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
1555 if (ret)
1556 printk(KERN_ERR "%s: error in tx submit urb: %d\n",
1557 priv->netdev->name, ret);
1559 kfree(mgmt_buf);
1562 /* Send a management frame on bulk-out. txbuf->wlength must be set */
1563 static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
1565 unsigned long flags;
1566 int ret;
1567 int urb_status;
1568 void *oldbuf = NULL;
1570 netif_carrier_off(priv->netdev); /* stop netdev watchdog */
1571 netif_stop_queue(priv->netdev); /* stop tx data packets */
1573 spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1575 urb_status = priv->tx_urb->status;
1576 if (urb_status == -EINPROGRESS) {
1577 /* cannot transmit now, put in the queue */
1578 oldbuf = priv->next_mgmt_bulk;
1579 priv->next_mgmt_bulk = txbuf;
1581 spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1583 if (oldbuf) {
1584 /* a data/mgmt tx is already pending in the URB -
1585 if this is no error in some situations we must
1586 implement a queue or silently modify the old msg */
1587 printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
1588 priv->netdev->name, hex2str(oldbuf, 64));
1589 kfree(oldbuf);
1590 return 0;
1593 txbuf->tx_rate = TX_RATE_1MBIT;
1594 txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
1595 memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
1597 if (priv->next_mgmt_bulk)
1598 printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
1599 priv->netdev->name, urb_status);
1601 at76_dbg(DBG_TX_MGMT,
1602 "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
1603 priv->netdev->name, le16_to_cpu(txbuf->wlength),
1604 txbuf->tx_rate, txbuf->padding,
1605 hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
1607 /* txbuf was not consumed above -> send mgmt msg immediately */
1608 memcpy(priv->bulk_out_buffer, txbuf,
1609 le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
1610 usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
1611 priv->bulk_out_buffer,
1612 le16_to_cpu(txbuf->wlength) + txbuf->padding +
1613 AT76_TX_HDRLEN, at76_tx_callback, priv);
1614 ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
1615 if (ret)
1616 printk(KERN_ERR "%s: error in tx submit urb: %d\n",
1617 priv->netdev->name, ret);
1619 kfree(txbuf);
1621 return ret;
1624 /* Go to the next information element */
1625 static inline void next_ie(struct ieee80211_info_element **ie)
1627 *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
1630 /* Challenge is the challenge string (in TLV format)
1631 we got with seq_nr 2 for shared secret authentication only and
1632 send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
1633 otherwise it is NULL */
1634 static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
1635 int seq_nr, struct ieee80211_info_element *challenge)
1637 struct at76_tx_buffer *tx_buffer;
1638 struct ieee80211_hdr_3addr *mgmt;
1639 struct ieee80211_auth *req;
1640 int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
1641 AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
1643 BUG_ON(!bss);
1644 BUG_ON(seq_nr == 3 && !challenge);
1645 tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
1646 if (!tx_buffer)
1647 return -ENOMEM;
1649 req = (struct ieee80211_auth *)tx_buffer->packet;
1650 mgmt = &req->header;
1652 /* make wireless header */
1653 /* first auth msg is not encrypted, only the second (seq_nr == 3) */
1654 mgmt->frame_ctl =
1655 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
1656 (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
1658 mgmt->duration_id = cpu_to_le16(0x8000);
1659 memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
1660 memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
1661 memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
1662 mgmt->seq_ctl = cpu_to_le16(0);
1664 req->algorithm = cpu_to_le16(priv->auth_mode);
1665 req->transaction = cpu_to_le16(seq_nr);
1666 req->status = cpu_to_le16(0);
1668 if (seq_nr == 3)
1669 memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
1671 /* init. at76_priv tx header */
1672 tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
1673 at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
1674 priv->netdev->name, mac2str(mgmt->addr3),
1675 le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
1676 if (seq_nr == 3)
1677 at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
1678 priv->netdev->name, hex2str(req->info_element, 18));
1680 /* either send immediately (if no data tx is pending
1681 or put it in pending list */
1682 return at76_tx_mgmt(priv, tx_buffer);
1685 static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
1687 struct at76_tx_buffer *tx_buffer;
1688 struct ieee80211_hdr_3addr *mgmt;
1689 struct ieee80211_assoc_request *req;
1690 struct ieee80211_info_element *ie;
1691 char *essid;
1692 int essid_len;
1693 u16 capa;
1695 BUG_ON(!bss);
1697 tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
1698 if (!tx_buffer)
1699 return -ENOMEM;
1701 req = (struct ieee80211_assoc_request *)tx_buffer->packet;
1702 mgmt = &req->header;
1703 ie = req->info_element;
1705 /* make wireless header */
1706 mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1707 IEEE80211_STYPE_ASSOC_REQ);
1709 mgmt->duration_id = cpu_to_le16(0x8000);
1710 memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
1711 memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
1712 memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
1713 mgmt->seq_ctl = cpu_to_le16(0);
1715 /* we must set the Privacy bit in the capabilities to assure an
1716 Agere-based AP with optional WEP transmits encrypted frames
1717 to us. AP only set the Privacy bit in their capabilities
1718 if WEP is mandatory in the BSS! */
1719 capa = bss->capa;
1720 if (priv->wep_enabled)
1721 capa |= WLAN_CAPABILITY_PRIVACY;
1722 if (priv->preamble_type != PREAMBLE_TYPE_LONG)
1723 capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
1724 req->capability = cpu_to_le16(capa);
1726 req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
1728 /* write TLV data elements */
1730 ie->id = WLAN_EID_SSID;
1731 ie->len = bss->ssid_len;
1732 memcpy(ie->data, bss->ssid, bss->ssid_len);
1733 next_ie(&ie);
1735 ie->id = WLAN_EID_SUPP_RATES;
1736 ie->len = sizeof(hw_rates);
1737 memcpy(ie->data, hw_rates, sizeof(hw_rates));
1738 next_ie(&ie); /* ie points behind the supp_rates field */
1740 /* init. at76_priv tx header */
1741 tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
1743 ie = req->info_element;
1744 essid = ie->data;
1745 essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
1747 next_ie(&ie); /* points to IE of rates now */
1748 at76_dbg(DBG_TX_MGMT,
1749 "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
1750 priv->netdev->name, mac2str(mgmt->addr3),
1751 le16_to_cpu(req->capability), essid_len, essid,
1752 hex2str(ie->data, ie->len));
1754 /* either send immediately (if no data tx is pending
1755 or put it in pending list */
1756 return at76_tx_mgmt(priv, tx_buffer);
1759 /* We got to check the bss_list for old entries */
1760 static void at76_bss_list_timeout(unsigned long par)
1762 struct at76_priv *priv = (struct at76_priv *)par;
1763 unsigned long flags;
1764 struct list_head *lptr, *nptr;
1765 struct bss_info *ptr;
1767 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
1769 list_for_each_safe(lptr, nptr, &priv->bss_list) {
1771 ptr = list_entry(lptr, struct bss_info, list);
1773 if (ptr != priv->curr_bss
1774 && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
1775 at76_dbg(DBG_BSS_TABLE_RM,
1776 "%s: bss_list: removing old BSS %s ch %d",
1777 priv->netdev->name, mac2str(ptr->bssid),
1778 ptr->channel);
1779 list_del(&ptr->list);
1780 kfree(ptr);
1783 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
1784 /* restart the timer */
1785 mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
1788 static inline void at76_set_mac_state(struct at76_priv *priv,
1789 enum mac_state mac_state)
1791 at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
1792 mac_states[mac_state]);
1793 priv->mac_state = mac_state;
1796 static void at76_dump_bss_table(struct at76_priv *priv)
1798 struct bss_info *ptr;
1799 unsigned long flags;
1800 struct list_head *lptr;
1802 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
1804 at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
1805 priv->curr_bss);
1807 list_for_each(lptr, &priv->bss_list) {
1808 ptr = list_entry(lptr, struct bss_info, list);
1809 at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
1810 "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
1811 ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
1812 ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
1813 ptr->capa, hex2str(ptr->rates, ptr->rates_len),
1814 ptr->rssi, ptr->link_qual, ptr->noise_level);
1816 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
1819 /* Called upon successful association to mark interface as connected */
1820 static void at76_work_assoc_done(struct work_struct *work)
1822 struct at76_priv *priv = container_of(work, struct at76_priv,
1823 work_assoc_done);
1825 mutex_lock(&priv->mtx);
1827 WARN_ON(priv->mac_state != MAC_ASSOC);
1828 WARN_ON(!priv->curr_bss);
1829 if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
1830 goto exit;
1832 if (priv->iw_mode == IW_MODE_INFRA) {
1833 if (priv->pm_mode != AT76_PM_OFF) {
1834 /* calculate the listen interval in units of
1835 beacon intervals of the curr_bss */
1836 u32 pm_period_beacon = (priv->pm_period >> 10) /
1837 priv->curr_bss->beacon_interval;
1839 pm_period_beacon = max(pm_period_beacon, 2u);
1840 pm_period_beacon = min(pm_period_beacon, 0xffffu);
1842 at76_dbg(DBG_PM,
1843 "%s: pm_mode %d assoc id 0x%x listen int %d",
1844 priv->netdev->name, priv->pm_mode,
1845 priv->assoc_id, pm_period_beacon);
1847 at76_set_associd(priv, priv->assoc_id);
1848 at76_set_listen_interval(priv, (u16)pm_period_beacon);
1850 schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
1852 at76_set_pm_mode(priv);
1854 netif_carrier_on(priv->netdev);
1855 netif_wake_queue(priv->netdev);
1856 at76_set_mac_state(priv, MAC_CONNECTED);
1857 at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
1858 at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
1859 priv->netdev->name, mac2str(priv->curr_bss->bssid));
1861 exit:
1862 mutex_unlock(&priv->mtx);
1865 /* We only store the new mac address in netdev struct,
1866 it gets set when the netdev is opened. */
1867 static int at76_set_mac_address(struct net_device *netdev, void *addr)
1869 struct sockaddr *mac = addr;
1870 memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
1871 return 1;
1874 static struct net_device_stats *at76_get_stats(struct net_device *netdev)
1876 struct at76_priv *priv = netdev_priv(netdev);
1877 return &priv->stats;
1880 static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
1882 struct at76_priv *priv = netdev_priv(netdev);
1884 at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
1885 priv->wstats.qual.qual, priv->wstats.qual.level,
1886 priv->wstats.qual.noise, priv->wstats.qual.updated);
1888 return &priv->wstats;
1891 static void at76_set_multicast(struct net_device *netdev)
1893 struct at76_priv *priv = netdev_priv(netdev);
1894 int promisc;
1896 promisc = ((netdev->flags & IFF_PROMISC) != 0);
1897 if (promisc != priv->promisc) {
1898 /* This gets called in interrupt, must reschedule */
1899 priv->promisc = promisc;
1900 schedule_work(&priv->work_set_promisc);
1904 /* Stop all network activity, flush all pending tasks */
1905 static void at76_quiesce(struct at76_priv *priv)
1907 unsigned long flags;
1909 netif_stop_queue(priv->netdev);
1910 netif_carrier_off(priv->netdev);
1912 at76_set_mac_state(priv, MAC_INIT);
1914 cancel_delayed_work(&priv->dwork_get_scan);
1915 cancel_delayed_work(&priv->dwork_beacon);
1916 cancel_delayed_work(&priv->dwork_auth);
1917 cancel_delayed_work(&priv->dwork_assoc);
1918 cancel_delayed_work(&priv->dwork_restart);
1920 spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1921 kfree(priv->next_mgmt_bulk);
1922 priv->next_mgmt_bulk = NULL;
1923 spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1926 /*******************************************************************************
1927 * at76_priv implementations of iw_handler functions:
1929 static int at76_iw_handler_commit(struct net_device *netdev,
1930 struct iw_request_info *info,
1931 void *null, char *extra)
1933 struct at76_priv *priv = netdev_priv(netdev);
1935 at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
1936 __func__);
1938 if (priv->mac_state != MAC_INIT)
1939 at76_quiesce(priv);
1941 /* Wait half second before the restart to process subsequent
1942 * requests from the same iwconfig in a single restart */
1943 schedule_delayed_work(&priv->dwork_restart, HZ / 2);
1945 return 0;
1948 static int at76_iw_handler_get_name(struct net_device *netdev,
1949 struct iw_request_info *info,
1950 char *name, char *extra)
1952 strcpy(name, "IEEE 802.11b");
1953 at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
1954 return 0;
1957 static int at76_iw_handler_set_freq(struct net_device *netdev,
1958 struct iw_request_info *info,
1959 struct iw_freq *freq, char *extra)
1961 struct at76_priv *priv = netdev_priv(netdev);
1962 int chan = -1;
1963 int ret = -EIWCOMMIT;
1964 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
1965 netdev->name, freq->m, freq->e);
1967 if ((freq->e == 0) && (freq->m <= 1000))
1968 /* Setting by channel number */
1969 chan = freq->m;
1970 else {
1971 /* Setting by frequency - search the table */
1972 int mult = 1;
1973 int i;
1975 for (i = 0; i < (6 - freq->e); i++)
1976 mult *= 10;
1978 for (i = 0; i < NUM_CHANNELS; i++) {
1979 if (freq->m == (channel_frequency[i] * mult))
1980 chan = i + 1;
1984 if (chan < 1 || !priv->domain)
1985 /* non-positive channels are invalid
1986 * we need a domain info to set the channel
1987 * either that or an invalid frequency was
1988 * provided by the user */
1989 ret = -EINVAL;
1990 else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
1991 printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
1992 priv->netdev->name, chan, priv->domain->name);
1993 ret = -EINVAL;
1996 if (ret == -EIWCOMMIT) {
1997 priv->channel = chan;
1998 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
1999 chan);
2002 return ret;
2005 static int at76_iw_handler_get_freq(struct net_device *netdev,
2006 struct iw_request_info *info,
2007 struct iw_freq *freq, char *extra)
2009 struct at76_priv *priv = netdev_priv(netdev);
2011 freq->m = priv->channel;
2012 freq->e = 0;
2014 if (priv->channel)
2015 at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
2016 netdev->name, channel_frequency[priv->channel - 1], 6);
2018 at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
2019 priv->channel);
2021 return 0;
2024 static int at76_iw_handler_set_mode(struct net_device *netdev,
2025 struct iw_request_info *info,
2026 __u32 *mode, char *extra)
2028 struct at76_priv *priv = netdev_priv(netdev);
2030 at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
2032 if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
2033 (*mode != IW_MODE_MONITOR))
2034 return -EINVAL;
2036 priv->iw_mode = *mode;
2037 if (priv->iw_mode != IW_MODE_INFRA)
2038 priv->pm_mode = AT76_PM_OFF;
2040 return -EIWCOMMIT;
2043 static int at76_iw_handler_get_mode(struct net_device *netdev,
2044 struct iw_request_info *info,
2045 __u32 *mode, char *extra)
2047 struct at76_priv *priv = netdev_priv(netdev);
2049 *mode = priv->iw_mode;
2051 at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
2053 return 0;
2056 static int at76_iw_handler_get_range(struct net_device *netdev,
2057 struct iw_request_info *info,
2058 struct iw_point *data, char *extra)
2060 /* inspired by atmel.c */
2061 struct at76_priv *priv = netdev_priv(netdev);
2062 struct iw_range *range = (struct iw_range *)extra;
2063 int i;
2065 data->length = sizeof(struct iw_range);
2066 memset(range, 0, sizeof(struct iw_range));
2068 /* TODO: range->throughput = xxxxxx; */
2070 range->min_nwid = 0x0000;
2071 range->max_nwid = 0x0000;
2073 /* this driver doesn't maintain sensitivity information */
2074 range->sensitivity = 0;
2076 range->max_qual.qual = 100;
2077 range->max_qual.level = 100;
2078 range->max_qual.noise = 0;
2079 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2081 range->avg_qual.qual = 50;
2082 range->avg_qual.level = 50;
2083 range->avg_qual.noise = 0;
2084 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2086 range->bitrate[0] = 1000000;
2087 range->bitrate[1] = 2000000;
2088 range->bitrate[2] = 5500000;
2089 range->bitrate[3] = 11000000;
2090 range->num_bitrates = 4;
2092 range->min_rts = 0;
2093 range->max_rts = MAX_RTS_THRESHOLD;
2095 range->min_frag = MIN_FRAG_THRESHOLD;
2096 range->max_frag = MAX_FRAG_THRESHOLD;
2098 range->pmp_flags = IW_POWER_PERIOD;
2099 range->pmt_flags = IW_POWER_ON;
2100 range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
2102 range->encoding_size[0] = WEP_SMALL_KEY_LEN;
2103 range->encoding_size[1] = WEP_LARGE_KEY_LEN;
2104 range->num_encoding_sizes = 2;
2105 range->max_encoding_tokens = WEP_KEYS;
2107 /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
2108 - take this for all (ignore antenna gains) */
2109 range->txpower[0] = 15;
2110 range->num_txpower = 1;
2111 range->txpower_capa = IW_TXPOW_DBM;
2113 range->we_version_source = WIRELESS_EXT;
2114 range->we_version_compiled = WIRELESS_EXT;
2116 /* same as the values used in atmel.c */
2117 range->retry_capa = IW_RETRY_LIMIT;
2118 range->retry_flags = IW_RETRY_LIMIT;
2119 range->r_time_flags = 0;
2120 range->min_retry = 1;
2121 range->max_retry = 255;
2123 range->num_channels = NUM_CHANNELS;
2124 range->num_frequency = 0;
2126 for (i = 0; i < NUM_CHANNELS; i++) {
2127 /* test if channel map bit is raised */
2128 if (priv->domain->channel_map & (0x1 << i)) {
2129 range->num_frequency += 1;
2131 range->freq[i].i = i + 1;
2132 range->freq[i].m = channel_frequency[i] * 100000;
2133 range->freq[i].e = 1; /* freq * 10^1 */
2137 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
2139 return 0;
2142 static int at76_iw_handler_set_spy(struct net_device *netdev,
2143 struct iw_request_info *info,
2144 struct iw_point *data, char *extra)
2146 struct at76_priv *priv = netdev_priv(netdev);
2147 int ret = 0;
2149 at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
2150 netdev->name, data->length);
2152 spin_lock_bh(&priv->spy_spinlock);
2153 ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
2154 extra);
2155 spin_unlock_bh(&priv->spy_spinlock);
2157 return ret;
2160 static int at76_iw_handler_get_spy(struct net_device *netdev,
2161 struct iw_request_info *info,
2162 struct iw_point *data, char *extra)
2165 struct at76_priv *priv = netdev_priv(netdev);
2166 int ret = 0;
2168 spin_lock_bh(&priv->spy_spinlock);
2169 ret = iw_handler_get_spy(priv->netdev, info,
2170 (union iwreq_data *)data, extra);
2171 spin_unlock_bh(&priv->spy_spinlock);
2173 at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
2174 netdev->name, data->length);
2176 return ret;
2179 static int at76_iw_handler_set_thrspy(struct net_device *netdev,
2180 struct iw_request_info *info,
2181 struct iw_point *data, char *extra)
2183 struct at76_priv *priv = netdev_priv(netdev);
2184 int ret;
2186 at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
2187 netdev->name, data->length);
2189 spin_lock_bh(&priv->spy_spinlock);
2190 ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
2191 extra);
2192 spin_unlock_bh(&priv->spy_spinlock);
2194 return ret;
2197 static int at76_iw_handler_get_thrspy(struct net_device *netdev,
2198 struct iw_request_info *info,
2199 struct iw_point *data, char *extra)
2201 struct at76_priv *priv = netdev_priv(netdev);
2202 int ret;
2204 spin_lock_bh(&priv->spy_spinlock);
2205 ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
2206 extra);
2207 spin_unlock_bh(&priv->spy_spinlock);
2209 at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
2210 netdev->name, data->length);
2212 return ret;
2215 static int at76_iw_handler_set_wap(struct net_device *netdev,
2216 struct iw_request_info *info,
2217 struct sockaddr *ap_addr, char *extra)
2219 struct at76_priv *priv = netdev_priv(netdev);
2221 at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
2222 mac2str(ap_addr->sa_data));
2224 /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
2225 chosen any or auto AP preference */
2226 if (is_broadcast_ether_addr(ap_addr->sa_data)
2227 || is_zero_ether_addr(ap_addr->sa_data))
2228 priv->wanted_bssid_valid = 0;
2229 else {
2230 /* user wants to set a preferred AP address */
2231 priv->wanted_bssid_valid = 1;
2232 memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
2235 return -EIWCOMMIT;
2238 static int at76_iw_handler_get_wap(struct net_device *netdev,
2239 struct iw_request_info *info,
2240 struct sockaddr *ap_addr, char *extra)
2242 struct at76_priv *priv = netdev_priv(netdev);
2244 ap_addr->sa_family = ARPHRD_ETHER;
2245 memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
2247 at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
2248 mac2str(ap_addr->sa_data));
2250 return 0;
2253 static int at76_iw_handler_set_scan(struct net_device *netdev,
2254 struct iw_request_info *info,
2255 union iwreq_data *wrqu, char *extra)
2257 struct at76_priv *priv = netdev_priv(netdev);
2258 int ret = 0;
2260 at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
2262 if (mutex_lock_interruptible(&priv->mtx))
2263 return -EINTR;
2265 if (!netif_running(netdev)) {
2266 ret = -ENETDOWN;
2267 goto exit;
2270 /* jal: we don't allow "iwlist ethX scan" while we are
2271 in monitor mode */
2272 if (priv->iw_mode == IW_MODE_MONITOR) {
2273 ret = -EBUSY;
2274 goto exit;
2277 /* Discard old scan results */
2278 if ((jiffies - priv->last_scan) > (20 * HZ))
2279 priv->scan_state = SCAN_IDLE;
2280 priv->last_scan = jiffies;
2282 /* Initiate a scan command */
2283 if (priv->scan_state == SCAN_IN_PROGRESS) {
2284 ret = -EBUSY;
2285 goto exit;
2288 priv->scan_state = SCAN_IN_PROGRESS;
2290 at76_quiesce(priv);
2292 /* Try to do passive or active scan if WE asks as. */
2293 if (wrqu->data.length
2294 && wrqu->data.length == sizeof(struct iw_scan_req)) {
2295 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2297 if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2298 priv->scan_mode = SCAN_TYPE_PASSIVE;
2299 else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
2300 priv->scan_mode = SCAN_TYPE_ACTIVE;
2302 /* Sanity check values? */
2303 if (req->min_channel_time > 0)
2304 priv->scan_min_time = req->min_channel_time;
2306 if (req->max_channel_time > 0)
2307 priv->scan_max_time = req->max_channel_time;
2310 /* change to scanning state */
2311 at76_set_mac_state(priv, MAC_SCANNING);
2312 schedule_work(&priv->work_start_scan);
2314 exit:
2315 mutex_unlock(&priv->mtx);
2316 return ret;
2319 static int at76_iw_handler_get_scan(struct net_device *netdev,
2320 struct iw_request_info *info,
2321 struct iw_point *data, char *extra)
2323 struct at76_priv *priv = netdev_priv(netdev);
2324 unsigned long flags;
2325 struct list_head *lptr, *nptr;
2326 struct bss_info *curr_bss;
2327 struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
2328 char *curr_val, *curr_pos = extra;
2329 int i;
2331 at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
2333 if (!iwe)
2334 return -ENOMEM;
2336 if (priv->scan_state != SCAN_COMPLETED) {
2337 /* scan not yet finished */
2338 kfree(iwe);
2339 return -EAGAIN;
2342 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
2344 list_for_each_safe(lptr, nptr, &priv->bss_list) {
2345 curr_bss = list_entry(lptr, struct bss_info, list);
2347 iwe->cmd = SIOCGIWAP;
2348 iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
2349 memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
2350 curr_pos = iwe_stream_add_event(info, curr_pos,
2351 extra + IW_SCAN_MAX_DATA, iwe,
2352 IW_EV_ADDR_LEN);
2354 iwe->u.data.length = curr_bss->ssid_len;
2355 iwe->cmd = SIOCGIWESSID;
2356 iwe->u.data.flags = 1;
2358 curr_pos = iwe_stream_add_point(info, curr_pos,
2359 extra + IW_SCAN_MAX_DATA, iwe,
2360 curr_bss->ssid);
2362 iwe->cmd = SIOCGIWMODE;
2363 iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
2364 IW_MODE_ADHOC :
2365 (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
2366 IW_MODE_MASTER : IW_MODE_AUTO;
2367 /* IW_MODE_AUTO = 0 which I thought is
2368 * the most logical value to return in this case */
2369 curr_pos = iwe_stream_add_event(info, curr_pos,
2370 extra + IW_SCAN_MAX_DATA, iwe,
2371 IW_EV_UINT_LEN);
2373 iwe->cmd = SIOCGIWFREQ;
2374 iwe->u.freq.m = curr_bss->channel;
2375 iwe->u.freq.e = 0;
2376 curr_pos = iwe_stream_add_event(info, curr_pos,
2377 extra + IW_SCAN_MAX_DATA, iwe,
2378 IW_EV_FREQ_LEN);
2380 iwe->cmd = SIOCGIWENCODE;
2381 if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
2382 iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2383 else
2384 iwe->u.data.flags = IW_ENCODE_DISABLED;
2386 iwe->u.data.length = 0;
2387 curr_pos = iwe_stream_add_point(info, curr_pos,
2388 extra + IW_SCAN_MAX_DATA, iwe,
2389 NULL);
2391 /* Add quality statistics */
2392 iwe->cmd = IWEVQUAL;
2393 iwe->u.qual.noise = 0;
2394 iwe->u.qual.updated =
2395 IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
2396 iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
2397 if (iwe->u.qual.level > 100)
2398 iwe->u.qual.level = 100;
2399 if (at76_is_intersil(priv->board_type))
2400 iwe->u.qual.qual = curr_bss->link_qual;
2401 else {
2402 iwe->u.qual.qual = 0;
2403 iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
2405 /* Add new value to event */
2406 curr_pos = iwe_stream_add_event(info, curr_pos,
2407 extra + IW_SCAN_MAX_DATA, iwe,
2408 IW_EV_QUAL_LEN);
2410 /* Rate: stuffing multiple values in a single event requires
2411 * a bit more of magic - Jean II */
2412 curr_val = curr_pos + IW_EV_LCP_LEN;
2414 iwe->cmd = SIOCGIWRATE;
2415 /* Those two flags are ignored... */
2416 iwe->u.bitrate.fixed = 0;
2417 iwe->u.bitrate.disabled = 0;
2418 /* Max 8 values */
2419 for (i = 0; i < curr_bss->rates_len; i++) {
2420 /* Bit rate given in 500 kb/s units (+ 0x80) */
2421 iwe->u.bitrate.value =
2422 ((curr_bss->rates[i] & 0x7f) * 500000);
2423 /* Add new value to event */
2424 curr_val = iwe_stream_add_value(info, curr_pos,
2425 curr_val,
2426 extra +
2427 IW_SCAN_MAX_DATA, iwe,
2428 IW_EV_PARAM_LEN);
2431 /* Check if we added any event */
2432 if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
2433 curr_pos = curr_val;
2435 /* more information may be sent back using IWECUSTOM */
2439 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
2441 data->length = (curr_pos - extra);
2442 data->flags = 0;
2444 kfree(iwe);
2445 return 0;
2448 static int at76_iw_handler_set_essid(struct net_device *netdev,
2449 struct iw_request_info *info,
2450 struct iw_point *data, char *extra)
2452 struct at76_priv *priv = netdev_priv(netdev);
2454 at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
2456 if (data->flags) {
2457 memcpy(priv->essid, extra, data->length);
2458 priv->essid_size = data->length;
2459 } else
2460 priv->essid_size = 0; /* Use any SSID */
2462 return -EIWCOMMIT;
2465 static int at76_iw_handler_get_essid(struct net_device *netdev,
2466 struct iw_request_info *info,
2467 struct iw_point *data, char *extra)
2469 struct at76_priv *priv = netdev_priv(netdev);
2471 if (priv->essid_size) {
2472 /* not the ANY ssid in priv->essid */
2473 data->flags = 1;
2474 data->length = priv->essid_size;
2475 memcpy(extra, priv->essid, data->length);
2476 } else {
2477 /* the ANY ssid was specified */
2478 if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
2479 /* report the SSID we have found */
2480 data->flags = 1;
2481 data->length = priv->curr_bss->ssid_len;
2482 memcpy(extra, priv->curr_bss->ssid, data->length);
2483 } else {
2484 /* report ANY back */
2485 data->flags = 0;
2486 data->length = 0;
2490 at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
2491 data->length, extra);
2493 return 0;
2496 static int at76_iw_handler_set_rate(struct net_device *netdev,
2497 struct iw_request_info *info,
2498 struct iw_param *bitrate, char *extra)
2500 struct at76_priv *priv = netdev_priv(netdev);
2501 int ret = -EIWCOMMIT;
2503 at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
2504 bitrate->value);
2506 switch (bitrate->value) {
2507 case -1:
2508 priv->txrate = TX_RATE_AUTO;
2509 break; /* auto rate */
2510 case 1000000:
2511 priv->txrate = TX_RATE_1MBIT;
2512 break;
2513 case 2000000:
2514 priv->txrate = TX_RATE_2MBIT;
2515 break;
2516 case 5500000:
2517 priv->txrate = TX_RATE_5_5MBIT;
2518 break;
2519 case 11000000:
2520 priv->txrate = TX_RATE_11MBIT;
2521 break;
2522 default:
2523 ret = -EINVAL;
2526 return ret;
2529 static int at76_iw_handler_get_rate(struct net_device *netdev,
2530 struct iw_request_info *info,
2531 struct iw_param *bitrate, char *extra)
2533 struct at76_priv *priv = netdev_priv(netdev);
2534 int ret = 0;
2536 switch (priv->txrate) {
2537 /* return max rate if RATE_AUTO */
2538 case TX_RATE_AUTO:
2539 bitrate->value = 11000000;
2540 break;
2541 case TX_RATE_1MBIT:
2542 bitrate->value = 1000000;
2543 break;
2544 case TX_RATE_2MBIT:
2545 bitrate->value = 2000000;
2546 break;
2547 case TX_RATE_5_5MBIT:
2548 bitrate->value = 5500000;
2549 break;
2550 case TX_RATE_11MBIT:
2551 bitrate->value = 11000000;
2552 break;
2553 default:
2554 ret = -EINVAL;
2557 bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
2558 bitrate->disabled = 0;
2560 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
2561 bitrate->value);
2563 return ret;
2566 static int at76_iw_handler_set_rts(struct net_device *netdev,
2567 struct iw_request_info *info,
2568 struct iw_param *rts, char *extra)
2570 struct at76_priv *priv = netdev_priv(netdev);
2571 int ret = -EIWCOMMIT;
2572 int rthr = rts->value;
2574 at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
2575 netdev->name, rts->value, (rts->disabled) ? "true" : "false");
2577 if (rts->disabled)
2578 rthr = MAX_RTS_THRESHOLD;
2580 if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
2581 ret = -EINVAL;
2582 else
2583 priv->rts_threshold = rthr;
2585 return ret;
2588 static int at76_iw_handler_get_rts(struct net_device *netdev,
2589 struct iw_request_info *info,
2590 struct iw_param *rts, char *extra)
2592 struct at76_priv *priv = netdev_priv(netdev);
2594 rts->value = priv->rts_threshold;
2595 rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
2596 rts->fixed = 1;
2598 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
2599 netdev->name, rts->value, (rts->disabled) ? "true" : "false");
2601 return 0;
2604 static int at76_iw_handler_set_frag(struct net_device *netdev,
2605 struct iw_request_info *info,
2606 struct iw_param *frag, char *extra)
2608 struct at76_priv *priv = netdev_priv(netdev);
2609 int ret = -EIWCOMMIT;
2610 int fthr = frag->value;
2612 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
2613 netdev->name, frag->value,
2614 (frag->disabled) ? "true" : "false");
2616 if (frag->disabled)
2617 fthr = MAX_FRAG_THRESHOLD;
2619 if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
2620 ret = -EINVAL;
2621 else
2622 priv->frag_threshold = fthr & ~0x1; /* get an even value */
2624 return ret;
2627 static int at76_iw_handler_get_frag(struct net_device *netdev,
2628 struct iw_request_info *info,
2629 struct iw_param *frag, char *extra)
2631 struct at76_priv *priv = netdev_priv(netdev);
2633 frag->value = priv->frag_threshold;
2634 frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
2635 frag->fixed = 1;
2637 at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
2638 netdev->name, frag->value,
2639 (frag->disabled) ? "true" : "false");
2641 return 0;
2644 static int at76_iw_handler_get_txpow(struct net_device *netdev,
2645 struct iw_request_info *info,
2646 struct iw_param *power, char *extra)
2648 power->value = 15;
2649 power->fixed = 1; /* No power control */
2650 power->disabled = 0;
2651 power->flags = IW_TXPOW_DBM;
2653 at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
2654 power->value);
2656 return 0;
2659 /* jal: short retry is handled by the firmware (at least 0.90.x),
2660 while long retry is not (?) */
2661 static int at76_iw_handler_set_retry(struct net_device *netdev,
2662 struct iw_request_info *info,
2663 struct iw_param *retry, char *extra)
2665 struct at76_priv *priv = netdev_priv(netdev);
2666 int ret = -EIWCOMMIT;
2668 at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
2669 netdev->name, retry->disabled, retry->flags, retry->value);
2671 if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
2672 if ((retry->flags & IW_RETRY_MIN) ||
2673 !(retry->flags & IW_RETRY_MAX))
2674 priv->short_retry_limit = retry->value;
2675 else
2676 ret = -EINVAL;
2677 } else
2678 ret = -EINVAL;
2680 return ret;
2683 /* Adapted (ripped) from atmel.c */
2684 static int at76_iw_handler_get_retry(struct net_device *netdev,
2685 struct iw_request_info *info,
2686 struct iw_param *retry, char *extra)
2688 struct at76_priv *priv = netdev_priv(netdev);
2690 at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
2692 retry->disabled = 0; /* Can't be disabled */
2693 retry->flags = IW_RETRY_LIMIT;
2694 retry->value = priv->short_retry_limit;
2696 return 0;
2699 static int at76_iw_handler_set_encode(struct net_device *netdev,
2700 struct iw_request_info *info,
2701 struct iw_point *encoding, char *extra)
2703 struct at76_priv *priv = netdev_priv(netdev);
2704 int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
2705 int len = encoding->length;
2707 at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
2708 "pointer %p len %d", netdev->name, encoding->flags,
2709 encoding->pointer, encoding->length);
2710 at76_dbg(DBG_IOCTL,
2711 "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
2712 "auth_mode %s", netdev->name,
2713 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
2714 (priv->auth_mode ==
2715 WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
2717 /* take the old default key if index is invalid */
2718 if ((index < 0) || (index >= WEP_KEYS))
2719 index = priv->wep_key_id;
2721 if (len > 0) {
2722 if (len > WEP_LARGE_KEY_LEN)
2723 len = WEP_LARGE_KEY_LEN;
2725 memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
2726 memcpy(priv->wep_keys[index], extra, len);
2727 priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
2728 WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
2729 priv->wep_enabled = 1;
2732 priv->wep_key_id = index;
2733 priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
2735 if (encoding->flags & IW_ENCODE_RESTRICTED)
2736 priv->auth_mode = WLAN_AUTH_SHARED_KEY;
2737 if (encoding->flags & IW_ENCODE_OPEN)
2738 priv->auth_mode = WLAN_AUTH_OPEN;
2740 at76_dbg(DBG_IOCTL,
2741 "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
2742 "key_len %d auth_mode %s", netdev->name,
2743 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
2744 priv->wep_keys_len[priv->wep_key_id],
2745 (priv->auth_mode ==
2746 WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
2748 return -EIWCOMMIT;
2751 static int at76_iw_handler_get_encode(struct net_device *netdev,
2752 struct iw_request_info *info,
2753 struct iw_point *encoding, char *extra)
2755 struct at76_priv *priv = netdev_priv(netdev);
2756 int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
2758 if ((index < 0) || (index >= WEP_KEYS))
2759 index = priv->wep_key_id;
2761 encoding->flags =
2762 (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
2763 IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
2765 if (!priv->wep_enabled)
2766 encoding->flags |= IW_ENCODE_DISABLED;
2768 if (encoding->pointer) {
2769 encoding->length = priv->wep_keys_len[index];
2771 memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
2773 encoding->flags |= (index + 1);
2776 at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
2777 "pointer %p len %d", netdev->name, encoding->flags,
2778 encoding->pointer, encoding->length);
2779 at76_dbg(DBG_IOCTL,
2780 "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
2781 "key_len %d auth_mode %s", netdev->name,
2782 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
2783 priv->wep_keys_len[priv->wep_key_id],
2784 (priv->auth_mode ==
2785 WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
2787 return 0;
2790 static int at76_iw_handler_set_power(struct net_device *netdev,
2791 struct iw_request_info *info,
2792 struct iw_param *prq, char *extra)
2794 int err = -EIWCOMMIT;
2795 struct at76_priv *priv = netdev_priv(netdev);
2797 at76_dbg(DBG_IOCTL,
2798 "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
2799 netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
2800 prq->value);
2802 if (prq->disabled)
2803 priv->pm_mode = AT76_PM_OFF;
2804 else {
2805 switch (prq->flags & IW_POWER_MODE) {
2806 case IW_POWER_ALL_R:
2807 case IW_POWER_ON:
2808 break;
2809 default:
2810 err = -EINVAL;
2811 goto exit;
2813 if (prq->flags & IW_POWER_PERIOD)
2814 priv->pm_period = prq->value;
2816 if (prq->flags & IW_POWER_TIMEOUT) {
2817 err = -EINVAL;
2818 goto exit;
2820 priv->pm_mode = AT76_PM_ON;
2822 exit:
2823 return err;
2826 static int at76_iw_handler_get_power(struct net_device *netdev,
2827 struct iw_request_info *info,
2828 struct iw_param *power, char *extra)
2830 struct at76_priv *priv = netdev_priv(netdev);
2832 power->disabled = (priv->pm_mode == AT76_PM_OFF);
2833 if (!power->disabled) {
2834 power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
2835 power->value = priv->pm_period;
2838 at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
2839 netdev->name, power->disabled ? "disabled" : "enabled",
2840 power->flags, power->value);
2842 return 0;
2845 /*******************************************************************************
2846 * Private IOCTLS
2848 static int at76_iw_set_short_preamble(struct net_device *netdev,
2849 struct iw_request_info *info, char *name,
2850 char *extra)
2852 struct at76_priv *priv = netdev_priv(netdev);
2853 int val = *((int *)name);
2854 int ret = -EIWCOMMIT;
2856 at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
2857 netdev->name, val);
2859 if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
2860 ret = -EINVAL;
2861 else
2862 priv->preamble_type = val;
2864 return ret;
2867 static int at76_iw_get_short_preamble(struct net_device *netdev,
2868 struct iw_request_info *info,
2869 union iwreq_data *wrqu, char *extra)
2871 struct at76_priv *priv = netdev_priv(netdev);
2873 snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
2874 preambles[priv->preamble_type], priv->preamble_type);
2875 return 0;
2878 static int at76_iw_set_debug(struct net_device *netdev,
2879 struct iw_request_info *info,
2880 struct iw_point *data, char *extra)
2882 char *ptr;
2883 u32 val;
2885 if (data->length > 0) {
2886 val = simple_strtol(extra, &ptr, 0);
2888 if (ptr == extra)
2889 val = DBG_DEFAULTS;
2891 at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
2892 netdev->name, data->length, extra, val);
2893 } else
2894 val = DBG_DEFAULTS;
2896 at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
2897 netdev->name, at76_debug, val);
2899 /* jal: some more output to pin down lockups */
2900 at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
2901 "carrier_ok %d", netdev->name, netif_running(netdev),
2902 netif_queue_stopped(netdev), netif_carrier_ok(netdev));
2904 at76_debug = val;
2906 return 0;
2909 static int at76_iw_get_debug(struct net_device *netdev,
2910 struct iw_request_info *info,
2911 union iwreq_data *wrqu, char *extra)
2913 snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
2914 return 0;
2917 static int at76_iw_set_powersave_mode(struct net_device *netdev,
2918 struct iw_request_info *info, char *name,
2919 char *extra)
2921 struct at76_priv *priv = netdev_priv(netdev);
2922 int val = *((int *)name);
2923 int ret = -EIWCOMMIT;
2925 at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
2926 netdev->name, val,
2927 val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
2928 val == AT76_PM_SMART ? "smart save" : "<invalid>");
2929 if (val < AT76_PM_OFF || val > AT76_PM_SMART)
2930 ret = -EINVAL;
2931 else
2932 priv->pm_mode = val;
2934 return ret;
2937 static int at76_iw_get_powersave_mode(struct net_device *netdev,
2938 struct iw_request_info *info,
2939 union iwreq_data *wrqu, char *extra)
2941 struct at76_priv *priv = netdev_priv(netdev);
2942 int *param = (int *)extra;
2944 param[0] = priv->pm_mode;
2945 return 0;
2948 static int at76_iw_set_scan_times(struct net_device *netdev,
2949 struct iw_request_info *info, char *name,
2950 char *extra)
2952 struct at76_priv *priv = netdev_priv(netdev);
2953 int mint = *((int *)name);
2954 int maxt = *((int *)name + 1);
2955 int ret = -EIWCOMMIT;
2957 at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
2958 netdev->name, mint, maxt);
2959 if (mint <= 0 || maxt <= 0 || mint > maxt)
2960 ret = -EINVAL;
2961 else {
2962 priv->scan_min_time = mint;
2963 priv->scan_max_time = maxt;
2966 return ret;
2969 static int at76_iw_get_scan_times(struct net_device *netdev,
2970 struct iw_request_info *info,
2971 union iwreq_data *wrqu, char *extra)
2973 struct at76_priv *priv = netdev_priv(netdev);
2974 int *param = (int *)extra;
2976 param[0] = priv->scan_min_time;
2977 param[1] = priv->scan_max_time;
2978 return 0;
2981 static int at76_iw_set_scan_mode(struct net_device *netdev,
2982 struct iw_request_info *info, char *name,
2983 char *extra)
2985 struct at76_priv *priv = netdev_priv(netdev);
2986 int val = *((int *)name);
2987 int ret = -EIWCOMMIT;
2989 at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
2990 netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
2991 (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
2993 if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
2994 ret = -EINVAL;
2995 else
2996 priv->scan_mode = val;
2998 return ret;
3001 static int at76_iw_get_scan_mode(struct net_device *netdev,
3002 struct iw_request_info *info,
3003 union iwreq_data *wrqu, char *extra)
3005 struct at76_priv *priv = netdev_priv(netdev);
3006 int *param = (int *)extra;
3008 param[0] = priv->scan_mode;
3009 return 0;
3012 #define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
3014 /* Standard wireless handlers */
3015 static const iw_handler at76_handlers[] = {
3016 AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
3017 AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
3018 AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
3019 AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
3020 AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
3021 AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
3022 AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
3023 AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
3024 AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
3025 AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
3026 AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
3027 AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
3028 AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
3029 AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
3030 AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
3031 AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
3032 AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
3033 AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
3034 AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
3035 AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
3036 AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
3037 AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
3038 AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
3039 AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
3040 AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
3041 AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
3042 AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
3043 AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
3044 AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
3045 AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
3048 #define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
3050 /* Private wireless handlers */
3051 static const iw_handler at76_priv_handlers[] = {
3052 AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
3053 AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
3054 AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
3055 AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
3056 AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
3057 AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
3058 AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
3059 AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
3060 AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
3061 AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
3064 /* Names and arguments of private wireless handlers */
3065 static const struct iw_priv_args at76_priv_args[] = {
3066 /* 0 - long, 1 - short */
3067 {AT76_SET_SHORT_PREAMBLE,
3068 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
3070 {AT76_GET_SHORT_PREAMBLE,
3071 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
3073 /* we must pass the new debug mask as a string, because iwpriv cannot
3074 * parse hex numbers starting with 0x :-( */
3075 {AT76_SET_DEBUG,
3076 IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
3078 {AT76_GET_DEBUG,
3079 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
3081 /* 1 - active, 2 - power save, 3 - smart power save */
3082 {AT76_SET_POWERSAVE_MODE,
3083 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
3085 {AT76_GET_POWERSAVE_MODE,
3086 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
3088 /* min_channel_time, max_channel_time */
3089 {AT76_SET_SCAN_TIMES,
3090 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
3092 {AT76_GET_SCAN_TIMES,
3093 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
3095 /* 0 - active, 1 - passive scan */
3096 {AT76_SET_SCAN_MODE,
3097 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
3099 {AT76_GET_SCAN_MODE,
3100 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
3103 static const struct iw_handler_def at76_handler_def = {
3104 .num_standard = ARRAY_SIZE(at76_handlers),
3105 .num_private = ARRAY_SIZE(at76_priv_handlers),
3106 .num_private_args = ARRAY_SIZE(at76_priv_args),
3107 .standard = at76_handlers,
3108 .private = at76_priv_handlers,
3109 .private_args = at76_priv_args,
3110 .get_wireless_stats = at76_get_wireless_stats,
3113 static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
3115 /* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
3116 * a SNAP OID of 0 (0x00, 0x00, 0x00) */
3117 static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
3119 static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
3121 struct at76_priv *priv = netdev_priv(netdev);
3122 struct net_device_stats *stats = &priv->stats;
3123 int ret = 0;
3124 int wlen;
3125 int submit_len;
3126 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
3127 struct ieee80211_hdr_3addr *i802_11_hdr =
3128 (struct ieee80211_hdr_3addr *)tx_buffer->packet;
3129 u8 *payload = i802_11_hdr->payload;
3130 struct ethhdr *eh = (struct ethhdr *)skb->data;
3132 if (netif_queue_stopped(netdev)) {
3133 printk(KERN_ERR "%s: %s called while netdev is stopped\n",
3134 netdev->name, __func__);
3135 /* skip this packet */
3136 dev_kfree_skb(skb);
3137 return 0;
3140 if (priv->tx_urb->status == -EINPROGRESS) {
3141 printk(KERN_ERR "%s: %s called while tx urb is pending\n",
3142 netdev->name, __func__);
3143 /* skip this packet */
3144 dev_kfree_skb(skb);
3145 return 0;
3148 if (skb->len < ETH_HLEN) {
3149 printk(KERN_ERR "%s: %s: skb too short (%d)\n",
3150 netdev->name, __func__, skb->len);
3151 dev_kfree_skb(skb);
3152 return 0;
3155 at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
3157 /* we can get rid of memcpy if we set netdev->hard_header_len to
3158 reserve enough space, but we would need to keep the skb around */
3160 if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
3161 /* this is a 802.3 packet */
3162 if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
3163 && skb->data[ETH_HLEN] == rfc1042sig[0]
3164 && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
3165 /* higher layer delivered SNAP header - keep it */
3166 memcpy(payload, skb->data + ETH_HLEN,
3167 skb->len - ETH_HLEN);
3168 wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
3169 } else {
3170 printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
3171 "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
3172 priv->netdev->name, skb->data[ETH_HLEN],
3173 skb->data[ETH_HLEN + 1],
3174 skb->data[ETH_HLEN + 2]);
3175 dev_kfree_skb(skb);
3176 return 0;
3178 } else {
3179 /* add RFC 1042 header in front */
3180 memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
3181 memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
3182 skb->len - offsetof(struct ethhdr, h_proto));
3183 wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
3184 offsetof(struct ethhdr, h_proto);
3187 /* make wireless header */
3188 i802_11_hdr->frame_ctl =
3189 cpu_to_le16(IEEE80211_FTYPE_DATA |
3190 (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
3191 (priv->iw_mode ==
3192 IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
3194 if (priv->iw_mode == IW_MODE_ADHOC) {
3195 memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
3196 memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
3197 memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
3198 } else if (priv->iw_mode == IW_MODE_INFRA) {
3199 memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
3200 memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
3201 memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
3204 i802_11_hdr->duration_id = cpu_to_le16(0);
3205 i802_11_hdr->seq_ctl = cpu_to_le16(0);
3207 /* setup 'Atmel' header */
3208 tx_buffer->wlength = cpu_to_le16(wlen);
3209 tx_buffer->tx_rate = priv->txrate;
3210 /* for broadcast destination addresses, the firmware 0.100.x
3211 seems to choose the highest rate set with CMD_STARTUP in
3212 basic_rate_set replacing this value */
3214 memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
3216 tx_buffer->padding = at76_calc_padding(wlen);
3217 submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
3219 at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
3220 hex2str(skb->data, 32));
3221 at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
3222 priv->netdev->name,
3223 le16_to_cpu(tx_buffer->wlength),
3224 tx_buffer->padding, tx_buffer->tx_rate,
3225 hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
3226 at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
3227 hex2str(payload, 48));
3229 /* send stuff */
3230 netif_stop_queue(netdev);
3231 netdev->trans_start = jiffies;
3233 usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
3234 submit_len, at76_tx_callback, priv);
3235 ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
3236 if (ret) {
3237 stats->tx_errors++;
3238 printk(KERN_ERR "%s: error in tx submit urb: %d\n",
3239 netdev->name, ret);
3240 if (ret == -EINVAL)
3241 printk(KERN_ERR
3242 "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
3243 priv->netdev->name, priv->tx_urb,
3244 priv->tx_urb->hcpriv, priv->tx_urb->complete);
3245 } else {
3246 stats->tx_bytes += skb->len;
3247 dev_kfree_skb(skb);
3250 return ret;
3253 static void at76_tx_timeout(struct net_device *netdev)
3255 struct at76_priv *priv = netdev_priv(netdev);
3257 if (!priv)
3258 return;
3259 dev_warn(&netdev->dev, "tx timeout.");
3261 usb_unlink_urb(priv->tx_urb);
3262 priv->stats.tx_errors++;
3265 static int at76_submit_rx_urb(struct at76_priv *priv)
3267 int ret;
3268 int size;
3269 struct sk_buff *skb = priv->rx_skb;
3271 if (!priv->rx_urb) {
3272 printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
3273 priv->netdev->name, __func__);
3274 return -EFAULT;
3277 if (!skb) {
3278 skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
3279 if (!skb) {
3280 printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
3281 priv->netdev->name);
3282 ret = -ENOMEM;
3283 goto exit;
3285 priv->rx_skb = skb;
3286 } else {
3287 skb_push(skb, skb_headroom(skb));
3288 skb_trim(skb, 0);
3291 size = skb_tailroom(skb);
3292 usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
3293 skb_put(skb, size), size, at76_rx_callback, priv);
3294 ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
3295 if (ret < 0) {
3296 if (ret == -ENODEV)
3297 at76_dbg(DBG_DEVSTART,
3298 "usb_submit_urb returned -ENODEV");
3299 else
3300 printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
3301 priv->netdev->name, ret);
3304 exit:
3305 if (ret < 0 && ret != -ENODEV)
3306 printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
3307 "driver and/or power cycle the device\n",
3308 priv->netdev->name);
3310 return ret;
3313 static int at76_open(struct net_device *netdev)
3315 struct at76_priv *priv = netdev_priv(netdev);
3316 int ret = 0;
3318 at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
3320 if (mutex_lock_interruptible(&priv->mtx))
3321 return -EINTR;
3323 /* if netdev->dev_addr != priv->mac_addr we must
3324 set the mac address in the device ! */
3325 if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
3326 if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
3327 at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
3328 netdev->name, mac2str(netdev->dev_addr));
3331 priv->scan_state = SCAN_IDLE;
3332 priv->last_scan = jiffies;
3334 ret = at76_submit_rx_urb(priv);
3335 if (ret < 0) {
3336 printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
3337 netdev->name, ret);
3338 goto error;
3341 schedule_delayed_work(&priv->dwork_restart, 0);
3343 at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
3344 error:
3345 mutex_unlock(&priv->mtx);
3346 return ret < 0 ? ret : 0;
3349 static int at76_stop(struct net_device *netdev)
3351 struct at76_priv *priv = netdev_priv(netdev);
3353 at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
3355 if (mutex_lock_interruptible(&priv->mtx))
3356 return -EINTR;
3358 at76_quiesce(priv);
3360 if (!priv->device_unplugged) {
3361 /* We are called by "ifconfig ethX down", not because the
3362 * device is not available anymore. */
3363 at76_set_radio(priv, 0);
3365 /* We unlink rx_urb because at76_open() re-submits it.
3366 * If unplugged, at76_delete_device() takes care of it. */
3367 usb_kill_urb(priv->rx_urb);
3370 /* free the bss_list */
3371 at76_free_bss_list(priv);
3373 mutex_unlock(&priv->mtx);
3374 at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
3376 return 0;
3379 static void at76_ethtool_get_drvinfo(struct net_device *netdev,
3380 struct ethtool_drvinfo *info)
3382 struct at76_priv *priv = netdev_priv(netdev);
3384 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
3385 strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
3387 usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
3389 snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
3390 priv->fw_version.major, priv->fw_version.minor,
3391 priv->fw_version.patch, priv->fw_version.build);
3394 static u32 at76_ethtool_get_link(struct net_device *netdev)
3396 struct at76_priv *priv = netdev_priv(netdev);
3397 return priv->mac_state == MAC_CONNECTED;
3400 static struct ethtool_ops at76_ethtool_ops = {
3401 .get_drvinfo = at76_ethtool_get_drvinfo,
3402 .get_link = at76_ethtool_get_link,
3405 /* Download external firmware */
3406 static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
3408 int ret;
3409 int op_mode;
3410 int blockno = 0;
3411 int bsize;
3412 u8 *block;
3413 u8 *buf = fwe->extfw;
3414 int size = fwe->extfw_size;
3416 if (!buf || !size)
3417 return -ENOENT;
3419 op_mode = at76_get_op_mode(udev);
3420 at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
3422 if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
3423 dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
3424 op_mode);
3425 return -EINVAL;
3428 block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
3429 if (!block)
3430 return -ENOMEM;
3432 at76_dbg(DBG_DEVSTART, "downloading external firmware");
3434 /* for fw >= 0.100, the device needs an extra empty block */
3435 do {
3436 bsize = min_t(int, size, FW_BLOCK_SIZE);
3437 memcpy(block, buf, bsize);
3438 at76_dbg(DBG_DEVSTART,
3439 "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
3440 size, bsize, blockno);
3441 ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
3442 if (ret != bsize) {
3443 dev_printk(KERN_ERR, &udev->dev,
3444 "loading %dth firmware block failed: %d\n",
3445 blockno, ret);
3446 goto exit;
3448 buf += bsize;
3449 size -= bsize;
3450 blockno++;
3451 } while (bsize > 0);
3453 if (at76_is_505a(fwe->board_type)) {
3454 at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
3455 schedule_timeout_interruptible(HZ / 5 + 1);
3458 exit:
3459 kfree(block);
3460 if (ret < 0)
3461 dev_printk(KERN_ERR, &udev->dev,
3462 "downloading external firmware failed: %d\n", ret);
3463 return ret;
3466 /* Download internal firmware */
3467 static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
3469 int ret;
3470 int need_remap = !at76_is_505a(fwe->board_type);
3472 ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
3473 need_remap ? 0 : 2 * HZ);
3475 if (ret < 0) {
3476 dev_printk(KERN_ERR, &udev->dev,
3477 "downloading internal fw failed with %d\n", ret);
3478 goto exit;
3481 at76_dbg(DBG_DEVSTART, "sending REMAP");
3483 /* no REMAP for 505A (see SF driver) */
3484 if (need_remap) {
3485 ret = at76_remap(udev);
3486 if (ret < 0) {
3487 dev_printk(KERN_ERR, &udev->dev,
3488 "sending REMAP failed with %d\n", ret);
3489 goto exit;
3493 at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
3494 schedule_timeout_interruptible(2 * HZ + 1);
3495 usb_reset_device(udev);
3497 exit:
3498 return ret;
3501 static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
3503 /* common criteria for both modi */
3505 int ret = (priv->essid_size == 0 /* ANY ssid */ ||
3506 (priv->essid_size == ptr->ssid_len &&
3507 !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
3508 if (!ret)
3509 at76_dbg(DBG_BSS_MATCH,
3510 "%s bss table entry %p: essid didn't match",
3511 priv->netdev->name, ptr);
3512 return ret;
3515 static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
3517 int ret;
3519 if (priv->iw_mode == IW_MODE_ADHOC)
3520 ret = ptr->capa & WLAN_CAPABILITY_IBSS;
3521 else
3522 ret = ptr->capa & WLAN_CAPABILITY_ESS;
3523 if (!ret)
3524 at76_dbg(DBG_BSS_MATCH,
3525 "%s bss table entry %p: mode didn't match",
3526 priv->netdev->name, ptr);
3527 return ret;
3530 static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
3532 int i;
3534 for (i = 0; i < ptr->rates_len; i++) {
3535 u8 rate = ptr->rates[i];
3537 if (!(rate & 0x80))
3538 continue;
3540 /* this is a basic rate we have to support
3541 (see IEEE802.11, ch. 7.3.2.2) */
3542 if (rate != (0x80 | hw_rates[0])
3543 && rate != (0x80 | hw_rates[1])
3544 && rate != (0x80 | hw_rates[2])
3545 && rate != (0x80 | hw_rates[3])) {
3546 at76_dbg(DBG_BSS_MATCH,
3547 "%s: bss table entry %p: basic rate %02x not "
3548 "supported", priv->netdev->name, ptr, rate);
3549 return 0;
3553 /* if we use short preamble, the bss must support it */
3554 if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
3555 !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
3556 at76_dbg(DBG_BSS_MATCH,
3557 "%s: %p does not support short preamble",
3558 priv->netdev->name, ptr);
3559 return 0;
3560 } else
3561 return 1;
3564 static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
3566 if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
3567 /* we have disabled WEP, but the BSS signals privacy */
3568 at76_dbg(DBG_BSS_MATCH,
3569 "%s: bss table entry %p: requires encryption",
3570 priv->netdev->name, ptr);
3571 return 0;
3573 /* otherwise if the BSS does not signal privacy it may well
3574 accept encrypted packets from us ... */
3575 return 1;
3578 static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
3580 if (!priv->wanted_bssid_valid ||
3581 !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
3582 return 1;
3584 at76_dbg(DBG_BSS_MATCH,
3585 "%s: requested bssid - %s does not match",
3586 priv->netdev->name, mac2str(priv->wanted_bssid));
3587 at76_dbg(DBG_BSS_MATCH,
3588 " AP bssid - %s of bss table entry %p",
3589 mac2str(ptr->bssid), ptr);
3590 return 0;
3594 * at76_match_bss - try to find a matching bss in priv->bss
3596 * last - last bss tried
3598 * last == NULL signals a new round starting with priv->bss_list.next
3599 * this function must be called inside an acquired priv->bss_list_spinlock
3600 * otherwise the timeout on bss may remove the newly chosen entry
3602 static struct bss_info *at76_match_bss(struct at76_priv *priv,
3603 struct bss_info *last)
3605 struct bss_info *ptr = NULL;
3606 struct list_head *curr;
3608 curr = last ? last->list.next : priv->bss_list.next;
3609 while (curr != &priv->bss_list) {
3610 ptr = list_entry(curr, struct bss_info, list);
3611 if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
3612 && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
3613 && at76_match_bssid(priv, ptr))
3614 break;
3615 curr = curr->next;
3618 if (curr == &priv->bss_list)
3619 ptr = NULL;
3620 /* otherwise ptr points to the struct bss_info we have chosen */
3622 at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
3623 __func__, ptr);
3624 return ptr;
3627 /* Start joining a matching BSS, or create own IBSS */
3628 static void at76_work_join(struct work_struct *work)
3630 struct at76_priv *priv = container_of(work, struct at76_priv,
3631 work_join);
3632 int ret;
3633 unsigned long flags;
3635 mutex_lock(&priv->mtx);
3637 WARN_ON(priv->mac_state != MAC_JOINING);
3638 if (priv->mac_state != MAC_JOINING)
3639 goto exit;
3641 /* secure the access to priv->curr_bss ! */
3642 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
3643 priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
3644 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
3646 if (!priv->curr_bss) {
3647 /* here we haven't found a matching (i)bss ... */
3648 if (priv->iw_mode == IW_MODE_ADHOC) {
3649 at76_set_mac_state(priv, MAC_OWN_IBSS);
3650 at76_start_ibss(priv);
3651 goto exit;
3653 /* haven't found a matching BSS in infra mode - try again */
3654 at76_set_mac_state(priv, MAC_SCANNING);
3655 schedule_work(&priv->work_start_scan);
3656 goto exit;
3659 ret = at76_join_bss(priv, priv->curr_bss);
3660 if (ret < 0) {
3661 printk(KERN_ERR "%s: join_bss failed with %d\n",
3662 priv->netdev->name, ret);
3663 goto exit;
3666 ret = at76_wait_completion(priv, CMD_JOIN);
3667 if (ret != CMD_STATUS_COMPLETE) {
3668 if (ret != CMD_STATUS_TIME_OUT)
3669 printk(KERN_ERR "%s: join_bss completed with %d\n",
3670 priv->netdev->name, ret);
3671 else
3672 printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
3673 priv->netdev->name,
3674 mac2str(priv->curr_bss->bssid));
3676 /* retry next BSS immediately */
3677 schedule_work(&priv->work_join);
3678 goto exit;
3681 /* here we have joined the (I)BSS */
3682 if (priv->iw_mode == IW_MODE_ADHOC) {
3683 struct bss_info *bptr = priv->curr_bss;
3684 at76_set_mac_state(priv, MAC_CONNECTED);
3685 /* get ESSID, BSSID and channel for priv->curr_bss */
3686 priv->essid_size = bptr->ssid_len;
3687 memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
3688 memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
3689 priv->channel = bptr->channel;
3690 at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
3691 netif_carrier_on(priv->netdev);
3692 netif_start_queue(priv->netdev);
3693 /* just to be sure */
3694 cancel_delayed_work(&priv->dwork_get_scan);
3695 cancel_delayed_work(&priv->dwork_auth);
3696 cancel_delayed_work(&priv->dwork_assoc);
3697 } else {
3698 /* send auth req */
3699 priv->retries = AUTH_RETRIES;
3700 at76_set_mac_state(priv, MAC_AUTH);
3701 at76_auth_req(priv, priv->curr_bss, 1, NULL);
3702 at76_dbg(DBG_MGMT_TIMER,
3703 "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
3704 schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
3707 exit:
3708 mutex_unlock(&priv->mtx);
3711 /* Reap scan results */
3712 static void at76_dwork_get_scan(struct work_struct *work)
3714 int status;
3715 int ret;
3716 struct at76_priv *priv = container_of(work, struct at76_priv,
3717 dwork_get_scan.work);
3719 mutex_lock(&priv->mtx);
3720 WARN_ON(priv->mac_state != MAC_SCANNING);
3721 if (priv->mac_state != MAC_SCANNING)
3722 goto exit;
3724 status = at76_get_cmd_status(priv->udev, CMD_SCAN);
3725 if (status < 0) {
3726 printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
3727 priv->netdev->name, __func__, status);
3728 status = CMD_STATUS_IN_PROGRESS;
3729 /* INFO: Hope it was a one off error - if not, scanning
3730 further down the line and stop this cycle */
3732 at76_dbg(DBG_PROGRESS,
3733 "%s %s: got cmd_status %d (state %s, need_any %d)",
3734 priv->netdev->name, __func__, status,
3735 mac_states[priv->mac_state], priv->scan_need_any);
3737 if (status != CMD_STATUS_COMPLETE) {
3738 if ((status != CMD_STATUS_IN_PROGRESS) &&
3739 (status != CMD_STATUS_IDLE))
3740 printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
3741 priv->netdev->name, __func__,
3742 at76_get_cmd_status_string(status));
3744 /* the first cmd status after scan start is always a IDLE ->
3745 start the timer to poll again until COMPLETED */
3746 at76_dbg(DBG_MGMT_TIMER,
3747 "%s:%d: starting mgmt_timer for %d ticks",
3748 __func__, __LINE__, SCAN_POLL_INTERVAL);
3749 schedule_delayed_work(&priv->dwork_get_scan,
3750 SCAN_POLL_INTERVAL);
3751 goto exit;
3754 if (at76_debug & DBG_BSS_TABLE)
3755 at76_dump_bss_table(priv);
3757 if (priv->scan_need_any) {
3758 ret = at76_start_scan(priv, 0);
3759 if (ret < 0)
3760 printk(KERN_ERR
3761 "%s: %s: start_scan (ANY) failed with %d\n",
3762 priv->netdev->name, __func__, ret);
3763 at76_dbg(DBG_MGMT_TIMER,
3764 "%s:%d: starting mgmt_timer for %d ticks", __func__,
3765 __LINE__, SCAN_POLL_INTERVAL);
3766 schedule_delayed_work(&priv->dwork_get_scan,
3767 SCAN_POLL_INTERVAL);
3768 priv->scan_need_any = 0;
3769 } else {
3770 priv->scan_state = SCAN_COMPLETED;
3771 /* report the end of scan to user space */
3772 at76_iwevent_scan_complete(priv->netdev);
3773 at76_set_mac_state(priv, MAC_JOINING);
3774 schedule_work(&priv->work_join);
3777 exit:
3778 mutex_unlock(&priv->mtx);
3781 /* Handle loss of beacons from the AP */
3782 static void at76_dwork_beacon(struct work_struct *work)
3784 struct at76_priv *priv = container_of(work, struct at76_priv,
3785 dwork_beacon.work);
3787 mutex_lock(&priv->mtx);
3788 if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
3789 goto exit;
3791 /* We haven't received any beacons from out AP for BEACON_TIMEOUT */
3792 printk(KERN_INFO "%s: lost beacon bssid %s\n",
3793 priv->netdev->name, mac2str(priv->curr_bss->bssid));
3795 netif_carrier_off(priv->netdev);
3796 netif_stop_queue(priv->netdev);
3797 at76_iwevent_bss_disconnect(priv->netdev);
3798 at76_set_mac_state(priv, MAC_SCANNING);
3799 schedule_work(&priv->work_start_scan);
3801 exit:
3802 mutex_unlock(&priv->mtx);
3805 /* Handle authentication response timeout */
3806 static void at76_dwork_auth(struct work_struct *work)
3808 struct at76_priv *priv = container_of(work, struct at76_priv,
3809 dwork_auth.work);
3811 mutex_lock(&priv->mtx);
3812 WARN_ON(priv->mac_state != MAC_AUTH);
3813 if (priv->mac_state != MAC_AUTH)
3814 goto exit;
3816 at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
3817 priv->netdev->name);
3819 if (priv->retries-- >= 0) {
3820 at76_auth_req(priv, priv->curr_bss, 1, NULL);
3821 at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
3822 __func__, __LINE__);
3823 schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
3824 } else {
3825 /* try to get next matching BSS */
3826 at76_set_mac_state(priv, MAC_JOINING);
3827 schedule_work(&priv->work_join);
3830 exit:
3831 mutex_unlock(&priv->mtx);
3834 /* Handle association response timeout */
3835 static void at76_dwork_assoc(struct work_struct *work)
3837 struct at76_priv *priv = container_of(work, struct at76_priv,
3838 dwork_assoc.work);
3840 mutex_lock(&priv->mtx);
3841 WARN_ON(priv->mac_state != MAC_ASSOC);
3842 if (priv->mac_state != MAC_ASSOC)
3843 goto exit;
3845 at76_dbg(DBG_PROGRESS, "%s: association response timeout",
3846 priv->netdev->name);
3848 if (priv->retries-- >= 0) {
3849 at76_assoc_req(priv, priv->curr_bss);
3850 at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
3851 __func__, __LINE__);
3852 schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
3853 } else {
3854 /* try to get next matching BSS */
3855 at76_set_mac_state(priv, MAC_JOINING);
3856 schedule_work(&priv->work_join);
3859 exit:
3860 mutex_unlock(&priv->mtx);
3863 /* Read new bssid in ad-hoc mode */
3864 static void at76_work_new_bss(struct work_struct *work)
3866 struct at76_priv *priv = container_of(work, struct at76_priv,
3867 work_new_bss);
3868 int ret;
3869 struct mib_mac_mgmt mac_mgmt;
3871 mutex_lock(&priv->mtx);
3873 ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
3874 sizeof(struct mib_mac_mgmt));
3875 if (ret < 0) {
3876 printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
3877 priv->netdev->name, ret);
3878 goto exit;
3881 at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
3882 memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
3883 at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
3885 at76_iwevent_bss_connect(priv->netdev, priv->bssid);
3887 priv->mib_buf.type = MIB_MAC_MGMT;
3888 priv->mib_buf.size = 1;
3889 priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
3890 priv->mib_buf.data.byte = 0;
3892 ret = at76_set_mib(priv, &priv->mib_buf);
3893 if (ret < 0)
3894 printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
3895 priv->netdev->name, ret);
3897 exit:
3898 mutex_unlock(&priv->mtx);
3901 static int at76_startup_device(struct at76_priv *priv)
3903 struct at76_card_config *ccfg = &priv->card_config;
3904 int ret;
3906 at76_dbg(DBG_PARAMS,
3907 "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
3908 "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
3909 hex2str(priv->essid, IW_ESSID_MAX_SIZE),
3910 priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
3911 priv->channel, priv->wep_enabled ? "enabled" : "disabled",
3912 priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
3913 at76_dbg(DBG_PARAMS,
3914 "%s param: preamble %s rts %d retry %d frag %d "
3915 "txrate %s auth_mode %d", priv->netdev->name,
3916 preambles[priv->preamble_type], priv->rts_threshold,
3917 priv->short_retry_limit, priv->frag_threshold,
3918 priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
3919 TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
3920 TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
3921 TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
3922 TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
3923 at76_dbg(DBG_PARAMS,
3924 "%s param: pm_mode %d pm_period %d auth_mode %s "
3925 "scan_times %d %d scan_mode %s",
3926 priv->netdev->name, priv->pm_mode, priv->pm_period,
3927 priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
3928 priv->scan_min_time, priv->scan_max_time,
3929 priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
3931 memset(ccfg, 0, sizeof(struct at76_card_config));
3932 ccfg->promiscuous_mode = 0;
3933 ccfg->short_retry_limit = priv->short_retry_limit;
3935 if (priv->wep_enabled) {
3936 if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
3937 ccfg->encryption_type = 2;
3938 else
3939 ccfg->encryption_type = 1;
3941 /* jal: always exclude unencrypted if WEP is active */
3942 ccfg->exclude_unencrypted = 1;
3943 } else {
3944 ccfg->exclude_unencrypted = 0;
3945 ccfg->encryption_type = 0;
3948 ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
3949 ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
3951 memcpy(ccfg->basic_rate_set, hw_rates, 4);
3952 /* jal: really needed, we do a set_mib for autorate later ??? */
3953 ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
3954 ccfg->channel = priv->channel;
3955 ccfg->privacy_invoked = priv->wep_enabled;
3956 memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
3957 ccfg->ssid_len = priv->essid_size;
3959 ccfg->wep_default_key_id = priv->wep_key_id;
3960 memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
3962 ccfg->short_preamble = priv->preamble_type;
3963 ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
3965 ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
3966 sizeof(struct at76_card_config));
3967 if (ret < 0) {
3968 printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
3969 priv->netdev->name, ret);
3970 return ret;
3973 at76_wait_completion(priv, CMD_STARTUP);
3975 /* remove BSSID from previous run */
3976 memset(priv->bssid, 0, ETH_ALEN);
3978 if (at76_set_radio(priv, 1) == 1)
3979 at76_wait_completion(priv, CMD_RADIO_ON);
3981 ret = at76_set_preamble(priv, priv->preamble_type);
3982 if (ret < 0)
3983 return ret;
3985 ret = at76_set_frag(priv, priv->frag_threshold);
3986 if (ret < 0)
3987 return ret;
3989 ret = at76_set_rts(priv, priv->rts_threshold);
3990 if (ret < 0)
3991 return ret;
3993 ret = at76_set_autorate_fallback(priv,
3994 priv->txrate == TX_RATE_AUTO ? 1 : 0);
3995 if (ret < 0)
3996 return ret;
3998 ret = at76_set_pm_mode(priv);
3999 if (ret < 0)
4000 return ret;
4002 if (at76_debug & DBG_MIB) {
4003 at76_dump_mib_mac(priv);
4004 at76_dump_mib_mac_addr(priv);
4005 at76_dump_mib_mac_mgmt(priv);
4006 at76_dump_mib_mac_wep(priv);
4007 at76_dump_mib_mdomain(priv);
4008 at76_dump_mib_phy(priv);
4009 at76_dump_mib_local(priv);
4012 return 0;
4015 /* Restart the interface */
4016 static void at76_dwork_restart(struct work_struct *work)
4018 struct at76_priv *priv = container_of(work, struct at76_priv,
4019 dwork_restart.work);
4021 mutex_lock(&priv->mtx);
4023 netif_carrier_off(priv->netdev); /* stop netdev watchdog */
4024 netif_stop_queue(priv->netdev); /* stop tx data packets */
4026 at76_startup_device(priv);
4028 if (priv->iw_mode != IW_MODE_MONITOR) {
4029 priv->netdev->type = ARPHRD_ETHER;
4030 at76_set_mac_state(priv, MAC_SCANNING);
4031 schedule_work(&priv->work_start_scan);
4032 } else {
4033 priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
4034 at76_start_monitor(priv);
4037 mutex_unlock(&priv->mtx);
4040 /* Initiate scanning */
4041 static void at76_work_start_scan(struct work_struct *work)
4043 struct at76_priv *priv = container_of(work, struct at76_priv,
4044 work_start_scan);
4045 int ret;
4047 mutex_lock(&priv->mtx);
4049 WARN_ON(priv->mac_state != MAC_SCANNING);
4050 if (priv->mac_state != MAC_SCANNING)
4051 goto exit;
4053 /* only clear the bss list when a scan is actively initiated,
4054 * otherwise simply rely on at76_bss_list_timeout */
4055 if (priv->scan_state == SCAN_IN_PROGRESS) {
4056 at76_free_bss_list(priv);
4057 priv->scan_need_any = 1;
4058 } else
4059 priv->scan_need_any = 0;
4061 ret = at76_start_scan(priv, 1);
4063 if (ret < 0)
4064 printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
4065 priv->netdev->name, __func__, ret);
4066 else {
4067 at76_dbg(DBG_MGMT_TIMER,
4068 "%s:%d: starting mgmt_timer for %d ticks",
4069 __func__, __LINE__, SCAN_POLL_INTERVAL);
4070 schedule_delayed_work(&priv->dwork_get_scan,
4071 SCAN_POLL_INTERVAL);
4074 exit:
4075 mutex_unlock(&priv->mtx);
4078 /* Enable or disable promiscuous mode */
4079 static void at76_work_set_promisc(struct work_struct *work)
4081 struct at76_priv *priv = container_of(work, struct at76_priv,
4082 work_set_promisc);
4083 int ret = 0;
4085 mutex_lock(&priv->mtx);
4087 priv->mib_buf.type = MIB_LOCAL;
4088 priv->mib_buf.size = 1;
4089 priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
4090 priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
4092 ret = at76_set_mib(priv, &priv->mib_buf);
4093 if (ret < 0)
4094 printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
4095 priv->netdev->name, ret);
4097 mutex_unlock(&priv->mtx);
4100 /* Submit Rx urb back to the device */
4101 static void at76_work_submit_rx(struct work_struct *work)
4103 struct at76_priv *priv = container_of(work, struct at76_priv,
4104 work_submit_rx);
4106 mutex_lock(&priv->mtx);
4107 at76_submit_rx_urb(priv);
4108 mutex_unlock(&priv->mtx);
4111 /* We got an association response */
4112 static void at76_rx_mgmt_assoc(struct at76_priv *priv,
4113 struct at76_rx_buffer *buf)
4115 struct ieee80211_assoc_response *resp =
4116 (struct ieee80211_assoc_response *)buf->packet;
4117 u16 assoc_id = le16_to_cpu(resp->aid);
4118 u16 status = le16_to_cpu(resp->status);
4120 at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
4121 "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
4122 mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
4123 status, assoc_id, hex2str(resp->info_element->data,
4124 resp->info_element->len));
4126 if (priv->mac_state != MAC_ASSOC) {
4127 printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
4128 priv->netdev->name, mac_states[priv->mac_state]);
4129 return;
4132 BUG_ON(!priv->curr_bss);
4134 cancel_delayed_work(&priv->dwork_assoc);
4135 if (status == WLAN_STATUS_SUCCESS) {
4136 struct bss_info *ptr = priv->curr_bss;
4137 priv->assoc_id = assoc_id & 0x3fff;
4138 /* update iwconfig params */
4139 memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
4140 memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
4141 priv->essid_size = ptr->ssid_len;
4142 priv->channel = ptr->channel;
4143 schedule_work(&priv->work_assoc_done);
4144 } else {
4145 at76_set_mac_state(priv, MAC_JOINING);
4146 schedule_work(&priv->work_join);
4150 /* Process disassociation request from the AP */
4151 static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
4152 struct at76_rx_buffer *buf)
4154 struct ieee80211_disassoc *resp =
4155 (struct ieee80211_disassoc *)buf->packet;
4156 struct ieee80211_hdr_3addr *mgmt = &resp->header;
4158 at76_dbg(DBG_RX_MGMT,
4159 "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
4160 priv->netdev->name, mac2str(mgmt->addr3),
4161 le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
4163 /* We are not connected, ignore */
4164 if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
4165 || !priv->curr_bss)
4166 return;
4168 /* Not our BSSID, ignore */
4169 if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
4170 return;
4172 /* Not for our STA and not broadcast, ignore */
4173 if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
4174 && !is_broadcast_ether_addr(mgmt->addr1))
4175 return;
4177 if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
4178 && priv->mac_state != MAC_JOINING) {
4179 printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
4180 priv->netdev->name, mac_states[priv->mac_state]);
4181 return;
4184 if (priv->mac_state == MAC_CONNECTED) {
4185 netif_carrier_off(priv->netdev);
4186 netif_stop_queue(priv->netdev);
4187 at76_iwevent_bss_disconnect(priv->netdev);
4189 cancel_delayed_work(&priv->dwork_get_scan);
4190 cancel_delayed_work(&priv->dwork_beacon);
4191 cancel_delayed_work(&priv->dwork_auth);
4192 cancel_delayed_work(&priv->dwork_assoc);
4193 at76_set_mac_state(priv, MAC_JOINING);
4194 schedule_work(&priv->work_join);
4197 static void at76_rx_mgmt_auth(struct at76_priv *priv,
4198 struct at76_rx_buffer *buf)
4200 struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
4201 struct ieee80211_hdr_3addr *mgmt = &resp->header;
4202 int seq_nr = le16_to_cpu(resp->transaction);
4203 int alg = le16_to_cpu(resp->algorithm);
4204 int status = le16_to_cpu(resp->status);
4206 at76_dbg(DBG_RX_MGMT,
4207 "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
4208 "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
4209 alg, seq_nr, status, mac2str(mgmt->addr1));
4211 if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
4212 at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
4213 priv->netdev->name, hex2str(resp->info_element, 18));
4215 if (priv->mac_state != MAC_AUTH) {
4216 printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
4217 priv->netdev->name, mac_states[priv->mac_state]);
4218 return;
4220 if (priv->auth_mode != alg) {
4221 printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
4222 priv->netdev->name, alg);
4223 return;
4226 BUG_ON(!priv->curr_bss);
4228 /* Not our BSSID or not for our STA, ignore */
4229 if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
4230 || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
4231 return;
4233 cancel_delayed_work(&priv->dwork_auth);
4234 if (status != WLAN_STATUS_SUCCESS) {
4235 /* try to join next bss */
4236 at76_set_mac_state(priv, MAC_JOINING);
4237 schedule_work(&priv->work_join);
4238 return;
4241 if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
4242 priv->retries = ASSOC_RETRIES;
4243 at76_set_mac_state(priv, MAC_ASSOC);
4244 at76_assoc_req(priv, priv->curr_bss);
4245 at76_dbg(DBG_MGMT_TIMER,
4246 "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
4247 schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
4248 return;
4251 WARN_ON(seq_nr != 2);
4252 at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
4253 at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
4254 __LINE__);
4255 schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
4258 static void at76_rx_mgmt_deauth(struct at76_priv *priv,
4259 struct at76_rx_buffer *buf)
4261 struct ieee80211_disassoc *resp =
4262 (struct ieee80211_disassoc *)buf->packet;
4263 struct ieee80211_hdr_3addr *mgmt = &resp->header;
4265 at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
4266 "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
4267 priv->netdev->name, mac2str(mgmt->addr3),
4268 le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
4270 if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
4271 && priv->mac_state != MAC_CONNECTED) {
4272 printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
4273 priv->netdev->name, mac_states[priv->mac_state]);
4274 return;
4277 BUG_ON(!priv->curr_bss);
4279 /* Not our BSSID, ignore */
4280 if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
4281 return;
4283 /* Not for our STA and not broadcast, ignore */
4284 if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
4285 && !is_broadcast_ether_addr(mgmt->addr1))
4286 return;
4288 if (priv->mac_state == MAC_CONNECTED)
4289 at76_iwevent_bss_disconnect(priv->netdev);
4291 at76_set_mac_state(priv, MAC_JOINING);
4292 schedule_work(&priv->work_join);
4293 cancel_delayed_work(&priv->dwork_get_scan);
4294 cancel_delayed_work(&priv->dwork_beacon);
4295 cancel_delayed_work(&priv->dwork_auth);
4296 cancel_delayed_work(&priv->dwork_assoc);
4299 static void at76_rx_mgmt_beacon(struct at76_priv *priv,
4300 struct at76_rx_buffer *buf)
4302 int varpar_len;
4303 /* beacon content */
4304 struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
4305 struct ieee80211_hdr_3addr *mgmt = &bdata->header;
4307 struct list_head *lptr;
4308 struct bss_info *match; /* entry matching addr3 with its bssid */
4309 int new_entry = 0;
4310 int len;
4311 struct ieee80211_info_element *ie;
4312 int have_ssid = 0;
4313 int have_rates = 0;
4314 int have_channel = 0;
4315 int keep_going = 1;
4316 unsigned long flags;
4318 spin_lock_irqsave(&priv->bss_list_spinlock, flags);
4319 if (priv->mac_state == MAC_CONNECTED) {
4320 /* in state MAC_CONNECTED we use the mgmt_timer to control
4321 the beacon of the BSS */
4322 BUG_ON(!priv->curr_bss);
4324 if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
4325 /* We got our AP's beacon, defer the timeout handler.
4326 Kill pending work first, as schedule_delayed_work()
4327 won't do it. */
4328 cancel_delayed_work(&priv->dwork_beacon);
4329 schedule_delayed_work(&priv->dwork_beacon,
4330 BEACON_TIMEOUT);
4331 priv->curr_bss->rssi = buf->rssi;
4332 priv->beacons_received++;
4333 goto exit;
4337 /* look if we have this BSS already in the list */
4338 match = NULL;
4340 if (!list_empty(&priv->bss_list)) {
4341 list_for_each(lptr, &priv->bss_list) {
4342 struct bss_info *bss_ptr =
4343 list_entry(lptr, struct bss_info, list);
4344 if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
4345 match = bss_ptr;
4346 break;
4351 if (!match) {
4352 /* BSS not in the list - append it */
4353 match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
4354 if (!match) {
4355 at76_dbg(DBG_BSS_TABLE,
4356 "%s: cannot kmalloc new bss info (%zd byte)",
4357 priv->netdev->name, sizeof(struct bss_info));
4358 goto exit;
4360 new_entry = 1;
4361 list_add_tail(&match->list, &priv->bss_list);
4364 match->capa = le16_to_cpu(bdata->capability);
4365 match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
4366 match->rssi = buf->rssi;
4367 match->link_qual = buf->link_quality;
4368 match->noise_level = buf->noise_level;
4369 memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
4370 at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
4371 mac2str(match->bssid));
4373 ie = bdata->info_element;
4375 /* length of var length beacon parameters */
4376 varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
4377 sizeof(struct ieee80211_beacon),
4378 BEACON_MAX_DATA_LENGTH);
4380 /* This routine steps through the bdata->data array to get
4381 * some useful information about the access point.
4382 * Currently, this implementation supports receipt of: SSID,
4383 * supported transfer rates and channel, in any order, with some
4384 * tolerance for intermittent unknown codes (although this
4385 * functionality may not be necessary as the useful information will
4386 * usually arrive in consecutively, but there have been some
4387 * reports of some of the useful information fields arriving in a
4388 * different order).
4389 * It does not support any more IE types although MFIE_TYPE_TIM may
4390 * be supported (on my AP at least).
4391 * The bdata->data array is about 1500 bytes long but only ~36 of those
4392 * bytes are useful, hence the have_ssid etc optimizations. */
4394 while (keep_going &&
4395 ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
4396 varpar_len)) {
4398 switch (ie->id) {
4400 case WLAN_EID_SSID:
4401 if (have_ssid)
4402 break;
4404 len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
4406 /* we copy only if this is a new entry,
4407 or the incoming SSID is not a hidden SSID. This
4408 will protect us from overwriting a real SSID read
4409 in a ProbeResponse with a hidden one from a
4410 following beacon. */
4411 if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
4412 have_ssid = 1;
4413 break;
4416 match->ssid_len = len;
4417 memcpy(match->ssid, ie->data, len);
4418 at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
4419 priv->netdev->name, len, match->ssid);
4420 have_ssid = 1;
4421 break;
4423 case WLAN_EID_SUPP_RATES:
4424 if (have_rates)
4425 break;
4427 match->rates_len =
4428 min_t(int, sizeof(match->rates), ie->len);
4429 memcpy(match->rates, ie->data, match->rates_len);
4430 have_rates = 1;
4431 at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
4432 priv->netdev->name,
4433 hex2str(ie->data, ie->len));
4434 break;
4436 case WLAN_EID_DS_PARAMS:
4437 if (have_channel)
4438 break;
4440 match->channel = ie->data[0];
4441 have_channel = 1;
4442 at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
4443 priv->netdev->name, match->channel);
4444 break;
4446 case WLAN_EID_CF_PARAMS:
4447 case WLAN_EID_TIM:
4448 case WLAN_EID_IBSS_PARAMS:
4449 default:
4450 at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
4451 priv->netdev->name, ie->id, ie->len,
4452 hex2str(ie->data, ie->len));
4453 break;
4456 /* advance to the next informational element */
4457 next_ie(&ie);
4459 /* Optimization: after all, the bdata->data array is
4460 * varpar_len bytes long, whereas we get all of the useful
4461 * information after only ~36 bytes, this saves us a lot of
4462 * time (and trouble as the remaining portion of the array
4463 * could be full of junk)
4464 * Comment this out if you want to see what other information
4465 * comes from the AP - although little of it may be useful */
4468 at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
4469 priv->netdev->name);
4471 match->last_rx = jiffies; /* record last rx of beacon */
4473 exit:
4474 spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
4477 /* Calculate the link level from a given rx_buffer */
4478 static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
4479 struct iw_quality *qual)
4481 /* just a guess for now, might be different for other chips */
4482 int max_rssi = 42;
4484 qual->level = (buf->rssi * 100 / max_rssi);
4485 if (qual->level > 100)
4486 qual->level = 100;
4487 qual->updated |= IW_QUAL_LEVEL_UPDATED;
4490 /* Calculate the link quality from a given rx_buffer */
4491 static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
4492 struct iw_quality *qual)
4494 if (at76_is_intersil(priv->board_type))
4495 qual->qual = buf->link_quality;
4496 else {
4497 unsigned long elapsed;
4499 /* Update qual at most once a second */
4500 elapsed = jiffies - priv->beacons_last_qual;
4501 if (elapsed < 1 * HZ)
4502 return;
4504 qual->qual = qual->level * priv->beacons_received *
4505 msecs_to_jiffies(priv->beacon_period) / elapsed;
4507 priv->beacons_last_qual = jiffies;
4508 priv->beacons_received = 0;
4510 qual->qual = (qual->qual > 100) ? 100 : qual->qual;
4511 qual->updated |= IW_QUAL_QUAL_UPDATED;
4514 /* Calculate the noise quality from a given rx_buffer */
4515 static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
4516 struct iw_quality *qual)
4518 qual->noise = 0;
4519 qual->updated |= IW_QUAL_NOISE_INVALID;
4522 static void at76_update_wstats(struct at76_priv *priv,
4523 struct at76_rx_buffer *buf)
4525 struct iw_quality *qual = &priv->wstats.qual;
4527 if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
4528 qual->updated = 0;
4529 at76_calc_level(priv, buf, qual);
4530 at76_calc_qual(priv, buf, qual);
4531 at76_calc_noise(priv, buf, qual);
4532 } else {
4533 qual->qual = 0;
4534 qual->level = 0;
4535 qual->noise = 0;
4536 qual->updated = IW_QUAL_ALL_INVALID;
4540 static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
4542 struct ieee80211_hdr_3addr *mgmt =
4543 (struct ieee80211_hdr_3addr *)buf->packet;
4544 u16 framectl = le16_to_cpu(mgmt->frame_ctl);
4546 /* update wstats */
4547 if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
4548 /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
4549 /* Data packets always seem to have a 0 link level, so we
4550 only read link quality info from management packets.
4551 Atmel driver actually averages the present, and previous
4552 values, we just present the raw value at the moment - TJS */
4553 if (priv->iw_mode == IW_MODE_ADHOC
4554 || (priv->curr_bss
4555 && !compare_ether_addr(mgmt->addr3,
4556 priv->curr_bss->bssid)))
4557 at76_update_wstats(priv, buf);
4560 at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
4561 priv->netdev->name, framectl,
4562 hex2str(mgmt, le16_to_cpu(buf->wlength)));
4564 switch (framectl & IEEE80211_FCTL_STYPE) {
4565 case IEEE80211_STYPE_BEACON:
4566 case IEEE80211_STYPE_PROBE_RESP:
4567 at76_rx_mgmt_beacon(priv, buf);
4568 break;
4570 case IEEE80211_STYPE_ASSOC_RESP:
4571 at76_rx_mgmt_assoc(priv, buf);
4572 break;
4574 case IEEE80211_STYPE_DISASSOC:
4575 at76_rx_mgmt_disassoc(priv, buf);
4576 break;
4578 case IEEE80211_STYPE_AUTH:
4579 at76_rx_mgmt_auth(priv, buf);
4580 break;
4582 case IEEE80211_STYPE_DEAUTH:
4583 at76_rx_mgmt_deauth(priv, buf);
4584 break;
4586 default:
4587 printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
4588 priv->netdev->name, framectl);
4591 return;
4594 /* Convert the 802.11 header into an ethernet-style header, make skb
4595 * ready for consumption by netif_rx() */
4596 static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
4598 struct ieee80211_hdr_3addr *i802_11_hdr;
4599 struct ethhdr *eth_hdr_p;
4600 u8 *src_addr;
4601 u8 *dest_addr;
4603 i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
4605 /* That would be the ethernet header if the hardware converted
4606 * the frame for us. Make sure the source and the destination
4607 * match the 802.11 header. Which hardware does it? */
4608 eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
4610 dest_addr = i802_11_hdr->addr1;
4611 if (iw_mode == IW_MODE_ADHOC)
4612 src_addr = i802_11_hdr->addr2;
4613 else
4614 src_addr = i802_11_hdr->addr3;
4616 if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
4617 !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
4618 /* Yes, we already have an ethernet header */
4619 skb_reset_mac_header(skb);
4620 else {
4621 u16 len;
4623 /* Need to build an ethernet header */
4624 if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
4625 /* SNAP frame - decapsulate, keep proto */
4626 skb_push(skb, offsetof(struct ethhdr, h_proto) -
4627 sizeof(rfc1042sig));
4628 len = 0;
4629 } else {
4630 /* 802.3 frame, proto is length */
4631 len = skb->len;
4632 skb_push(skb, ETH_HLEN);
4635 skb_reset_mac_header(skb);
4636 eth_hdr_p = eth_hdr(skb);
4637 /* This needs to be done in this order (eth_hdr_p->h_dest may
4638 * overlap src_addr) */
4639 memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
4640 memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
4641 if (len)
4642 eth_hdr_p->h_proto = htons(len);
4645 skb->protocol = eth_type_trans(skb, skb->dev);
4648 /* Check for fragmented data in priv->rx_skb. If the packet was no fragment
4649 or it was the last of a fragment set a skb containing the whole packet
4650 is returned for further processing. Otherwise we get NULL and are
4651 done and the packet is either stored inside the fragment buffer
4652 or thrown away. Every returned skb starts with the ieee802_11 header
4653 and contains _no_ FCS at the end */
4654 static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
4656 struct sk_buff *skb = priv->rx_skb;
4657 struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
4658 struct ieee80211_hdr_3addr *i802_11_hdr =
4659 (struct ieee80211_hdr_3addr *)buf->packet;
4660 /* seq_ctrl, fragment_number, sequence number of new packet */
4661 u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
4662 u16 fragnr = sctl & 0xf;
4663 u16 seqnr = sctl >> 4;
4664 u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
4666 /* Length including the IEEE802.11 header, but without the trailing
4667 * FCS and without the Atmel Rx header */
4668 int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
4670 /* where does the data payload start in skb->data ? */
4671 u8 *data = i802_11_hdr->payload;
4673 /* length of payload, excl. the trailing FCS */
4674 int data_len = length - IEEE80211_3ADDR_LEN;
4676 int i;
4677 struct rx_data_buf *bptr, *optr;
4678 unsigned long oldest = ~0UL;
4680 at76_dbg(DBG_RX_FRAGS,
4681 "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
4682 "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
4683 mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
4684 hex2str(data, 32));
4686 at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
4687 "tail %p end %p len %d", priv->netdev->name, skb->head,
4688 skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
4689 skb->len);
4691 if (data_len < 0) {
4692 /* make sure data starts in the buffer */
4693 printk(KERN_INFO "%s: data frame too short\n",
4694 priv->netdev->name);
4695 return NULL;
4698 WARN_ON(length <= AT76_RX_HDRLEN);
4699 if (length <= AT76_RX_HDRLEN)
4700 return NULL;
4702 /* remove the at76_rx_buffer header - we don't need it anymore */
4703 /* we need the IEEE802.11 header (for the addresses) if this packet
4704 is the first of a chain */
4705 skb_pull(skb, AT76_RX_HDRLEN);
4707 /* remove FCS at end */
4708 skb_trim(skb, length);
4710 at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
4711 "end %p len %d data %p data_len %d", priv->netdev->name,
4712 skb->head, skb->data, skb_tail_pointer(skb),
4713 skb_end_pointer(skb), skb->len, data, data_len);
4715 if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
4716 /* unfragmented packet received */
4717 /* Use a new skb for the next receive */
4718 priv->rx_skb = NULL;
4719 at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
4720 return skb;
4723 /* look if we've got a chain for the sender address.
4724 afterwards optr points to first free or the oldest entry,
4725 or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
4726 sender address */
4727 /* determining the oldest entry doesn't cope with jiffies wrapping
4728 but I don't care to delete a young entry at these rare moments ... */
4730 bptr = priv->rx_data;
4731 optr = NULL;
4732 for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
4733 if (!bptr->skb) {
4734 optr = bptr;
4735 oldest = 0UL;
4736 continue;
4739 if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
4740 break;
4742 if (!optr) {
4743 optr = bptr;
4744 oldest = bptr->last_rx;
4745 } else if (bptr->last_rx < oldest)
4746 optr = bptr;
4749 if (i < NR_RX_DATA_BUF) {
4751 at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
4752 "matched sender addr",
4753 priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
4755 /* bptr points to an entry for the sender address */
4756 if (bptr->seqnr == seqnr) {
4757 int left;
4758 /* the fragment has the current sequence number */
4759 if (((bptr->fragnr + 1) & 0xf) != fragnr) {
4760 /* wrong fragment number -> ignore it */
4761 /* is & 0xf necessary above ??? */
4762 at76_dbg(DBG_RX_FRAGS,
4763 "%s: frag nr mismatch: %d + 1 != %d",
4764 priv->netdev->name, bptr->fragnr,
4765 fragnr);
4766 return NULL;
4768 bptr->last_rx = jiffies;
4769 /* the next following fragment number ->
4770 add the data at the end */
4772 /* for test only ??? */
4773 left = skb_tailroom(bptr->skb);
4774 if (left < data_len)
4775 printk(KERN_INFO
4776 "%s: only %d byte free (need %d)\n",
4777 priv->netdev->name, left, data_len);
4778 else
4779 memcpy(skb_put(bptr->skb, data_len), data,
4780 data_len);
4782 bptr->fragnr = fragnr;
4783 if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
4784 return NULL;
4786 /* this was the last fragment - send it */
4787 skb = bptr->skb;
4788 bptr->skb = NULL; /* free the entry */
4789 at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
4790 priv->netdev->name, seqnr);
4791 return skb;
4794 /* got another sequence number */
4795 if (fragnr == 0) {
4796 /* it's the start of a new chain - replace the
4797 old one by this */
4798 /* bptr->sender has the correct value already */
4799 at76_dbg(DBG_RX_FRAGS,
4800 "%s: start of new seq %d, removing old seq %d",
4801 priv->netdev->name, seqnr, bptr->seqnr);
4802 bptr->seqnr = seqnr;
4803 bptr->fragnr = 0;
4804 bptr->last_rx = jiffies;
4805 /* swap bptr->skb and priv->rx_skb */
4806 skb = bptr->skb;
4807 bptr->skb = priv->rx_skb;
4808 priv->rx_skb = skb;
4809 } else {
4810 /* it from the middle of a new chain ->
4811 delete the old entry and skip the new one */
4812 at76_dbg(DBG_RX_FRAGS,
4813 "%s: middle of new seq %d (%d) "
4814 "removing old seq %d",
4815 priv->netdev->name, seqnr, fragnr,
4816 bptr->seqnr);
4817 dev_kfree_skb(bptr->skb);
4818 bptr->skb = NULL;
4820 return NULL;
4823 /* if we didn't find a chain for the sender address, optr
4824 points either to the first free or the oldest entry */
4826 if (fragnr != 0) {
4827 /* this is not the begin of a fragment chain ... */
4828 at76_dbg(DBG_RX_FRAGS,
4829 "%s: no chain for non-first fragment (%d)",
4830 priv->netdev->name, fragnr);
4831 return NULL;
4834 BUG_ON(!optr);
4835 if (optr->skb) {
4836 /* swap the skb's */
4837 skb = optr->skb;
4838 optr->skb = priv->rx_skb;
4839 priv->rx_skb = skb;
4841 at76_dbg(DBG_RX_FRAGS,
4842 "%s: free old contents: sender %s seq/frag %d/%d",
4843 priv->netdev->name, mac2str(optr->sender),
4844 optr->seqnr, optr->fragnr);
4846 } else {
4847 /* take the skb from priv->rx_skb */
4848 optr->skb = priv->rx_skb;
4849 /* let at76_submit_rx_urb() allocate a new skb */
4850 priv->rx_skb = NULL;
4852 at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
4853 priv->netdev->name);
4855 memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
4856 optr->seqnr = seqnr;
4857 optr->fragnr = 0;
4858 optr->last_rx = jiffies;
4860 return NULL;
4863 /* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
4864 static void at76_rx_data(struct at76_priv *priv)
4866 struct net_device *netdev = priv->netdev;
4867 struct net_device_stats *stats = &priv->stats;
4868 struct sk_buff *skb = priv->rx_skb;
4869 struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
4870 struct ieee80211_hdr_3addr *i802_11_hdr;
4871 int length = le16_to_cpu(buf->wlength);
4873 at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
4874 hex2str(skb->data, AT76_RX_HDRLEN));
4876 at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
4877 hex2str(skb->data + AT76_RX_HDRLEN, length));
4879 skb = at76_check_for_rx_frags(priv);
4880 if (!skb)
4881 return;
4883 /* Atmel header and the FCS are already removed */
4884 i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
4886 skb->dev = netdev;
4887 skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
4889 if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
4890 if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
4891 skb->pkt_type = PACKET_BROADCAST;
4892 else
4893 skb->pkt_type = PACKET_MULTICAST;
4894 } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
4895 skb->pkt_type = PACKET_OTHERHOST;
4897 at76_ieee80211_to_eth(skb, priv->iw_mode);
4899 netdev->last_rx = jiffies;
4900 netif_rx(skb);
4901 stats->rx_packets++;
4902 stats->rx_bytes += length;
4904 return;
4907 static void at76_rx_monitor_mode(struct at76_priv *priv)
4909 struct at76_rx_radiotap *rt;
4910 u8 *payload;
4911 int skblen;
4912 struct net_device *netdev = priv->netdev;
4913 struct at76_rx_buffer *buf =
4914 (struct at76_rx_buffer *)priv->rx_skb->data;
4915 /* length including the IEEE802.11 header and the trailing FCS,
4916 but not at76_rx_buffer */
4917 int length = le16_to_cpu(buf->wlength);
4918 struct sk_buff *skb = priv->rx_skb;
4919 struct net_device_stats *stats = &priv->stats;
4921 if (length < IEEE80211_FCS_LEN) {
4922 /* buffer contains no data */
4923 at76_dbg(DBG_MONITOR_MODE,
4924 "%s: MONITOR MODE: rx skb without data",
4925 priv->netdev->name);
4926 return;
4929 skblen = sizeof(struct at76_rx_radiotap) + length;
4931 skb = dev_alloc_skb(skblen);
4932 if (!skb) {
4933 printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
4934 "header returned NULL\n", priv->netdev->name);
4935 return;
4938 skb_put(skb, skblen);
4940 rt = (struct at76_rx_radiotap *)skb->data;
4941 payload = skb->data + sizeof(struct at76_rx_radiotap);
4943 rt->rt_hdr.it_version = 0;
4944 rt->rt_hdr.it_pad = 0;
4945 rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
4946 rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
4948 rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
4949 rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
4950 rt->rt_signal = buf->rssi;
4951 rt->rt_noise = buf->noise_level;
4952 rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
4953 if (buf->fragmentation)
4954 rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
4956 memcpy(payload, buf->packet, length);
4957 skb->dev = netdev;
4958 skb->ip_summed = CHECKSUM_NONE;
4959 skb_reset_mac_header(skb);
4960 skb->pkt_type = PACKET_OTHERHOST;
4961 skb->protocol = htons(ETH_P_802_2);
4963 netdev->last_rx = jiffies;
4964 netif_rx(skb);
4965 stats->rx_packets++;
4966 stats->rx_bytes += length;
4969 /* Check if we spy on the sender address in buf and update stats */
4970 static void at76_iwspy_update(struct at76_priv *priv,
4971 struct at76_rx_buffer *buf)
4973 struct ieee80211_hdr_3addr *hdr =
4974 (struct ieee80211_hdr_3addr *)buf->packet;
4975 struct iw_quality qual;
4977 /* We can only set the level here */
4978 qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
4979 qual.level = 0;
4980 qual.noise = 0;
4981 at76_calc_level(priv, buf, &qual);
4983 spin_lock_bh(&priv->spy_spinlock);
4985 if (priv->spy_data.spy_number > 0)
4986 wireless_spy_update(priv->netdev, hdr->addr2, &qual);
4988 spin_unlock_bh(&priv->spy_spinlock);
4991 static void at76_rx_tasklet(unsigned long param)
4993 struct urb *urb = (struct urb *)param;
4994 struct at76_priv *priv = urb->context;
4995 struct net_device *netdev = priv->netdev;
4996 struct at76_rx_buffer *buf;
4997 struct ieee80211_hdr_3addr *i802_11_hdr;
4998 u16 frame_ctl;
5000 if (priv->device_unplugged) {
5001 at76_dbg(DBG_DEVSTART, "device unplugged");
5002 if (urb)
5003 at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
5004 return;
5007 if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
5008 return;
5010 buf = (struct at76_rx_buffer *)priv->rx_skb->data;
5012 i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
5014 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
5016 if (urb->status != 0) {
5017 if (urb->status != -ENOENT && urb->status != -ECONNRESET)
5018 at76_dbg(DBG_URB,
5019 "%s %s: - nonzero Rx bulk status received: %d",
5020 __func__, netdev->name, urb->status);
5021 return;
5024 at76_dbg(DBG_RX_ATMEL_HDR,
5025 "%s: rx frame: rate %d rssi %d noise %d link %d %s",
5026 priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
5027 buf->link_quality, hex2str(i802_11_hdr, 48));
5028 if (priv->iw_mode == IW_MODE_MONITOR) {
5029 at76_rx_monitor_mode(priv);
5030 goto exit;
5033 /* there is a new bssid around, accept it: */
5034 if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
5035 at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
5036 schedule_work(&priv->work_new_bss);
5039 switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
5040 case IEEE80211_FTYPE_DATA:
5041 at76_rx_data(priv);
5042 break;
5044 case IEEE80211_FTYPE_MGMT:
5045 /* jal: TODO: find out if we can update iwspy also on
5046 other frames than management (might depend on the
5047 radio chip / firmware version !) */
5049 at76_iwspy_update(priv, buf);
5051 at76_rx_mgmt(priv, buf);
5052 break;
5054 case IEEE80211_FTYPE_CTL:
5055 at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
5056 priv->netdev->name, frame_ctl);
5057 break;
5059 default:
5060 printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
5061 priv->netdev->name, frame_ctl);
5063 exit:
5064 at76_submit_rx_urb(priv);
5067 /* Load firmware into kernel memory and parse it */
5068 static struct fwentry *at76_load_firmware(struct usb_device *udev,
5069 enum board_type board_type)
5071 int ret;
5072 char *str;
5073 struct at76_fw_header *fwh;
5074 struct fwentry *fwe = &firmwares[board_type];
5076 mutex_lock(&fw_mutex);
5078 if (fwe->loaded) {
5079 at76_dbg(DBG_FW, "re-using previously loaded fw");
5080 goto exit;
5083 at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
5084 ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
5085 if (ret < 0) {
5086 dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
5087 fwe->fwname);
5088 dev_printk(KERN_ERR, &udev->dev,
5089 "you may need to download the firmware from "
5090 "http://developer.berlios.de/projects/at76c503a/");
5091 goto exit;
5094 at76_dbg(DBG_FW, "got it.");
5095 fwh = (struct at76_fw_header *)(fwe->fw->data);
5097 if (fwe->fw->size <= sizeof(*fwh)) {
5098 dev_printk(KERN_ERR, &udev->dev,
5099 "firmware is too short (0x%zx)\n", fwe->fw->size);
5100 goto exit;
5103 /* CRC currently not checked */
5104 fwe->board_type = le32_to_cpu(fwh->board_type);
5105 if (fwe->board_type != board_type) {
5106 dev_printk(KERN_ERR, &udev->dev,
5107 "board type mismatch, requested %u, got %u\n",
5108 board_type, fwe->board_type);
5109 goto exit;
5112 fwe->fw_version.major = fwh->major;
5113 fwe->fw_version.minor = fwh->minor;
5114 fwe->fw_version.patch = fwh->patch;
5115 fwe->fw_version.build = fwh->build;
5117 str = (char *)fwh + le32_to_cpu(fwh->str_offset);
5118 fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
5119 fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
5120 fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
5121 fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
5123 fwe->loaded = 1;
5125 dev_printk(KERN_DEBUG, &udev->dev,
5126 "using firmware %s (version %d.%d.%d-%d)\n",
5127 fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
5129 at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
5130 le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
5131 le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
5132 at76_dbg(DBG_DEVSTART, "firmware id %s", str);
5134 exit:
5135 mutex_unlock(&fw_mutex);
5137 if (fwe->loaded)
5138 return fwe;
5139 else
5140 return NULL;
5143 /* Allocate network device and initialize private data */
5144 static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
5146 struct net_device *netdev;
5147 struct at76_priv *priv;
5148 int i;
5150 /* allocate memory for our device state and initialize it */
5151 netdev = alloc_etherdev(sizeof(struct at76_priv));
5152 if (!netdev) {
5153 dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
5154 return NULL;
5157 priv = netdev_priv(netdev);
5159 priv->udev = udev;
5160 priv->netdev = netdev;
5162 mutex_init(&priv->mtx);
5163 INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
5164 INIT_WORK(&priv->work_join, at76_work_join);
5165 INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
5166 INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
5167 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
5168 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
5169 INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
5170 INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
5171 INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
5172 INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
5173 INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
5175 spin_lock_init(&priv->mgmt_spinlock);
5176 priv->next_mgmt_bulk = NULL;
5177 priv->mac_state = MAC_INIT;
5179 /* initialize empty BSS list */
5180 priv->curr_bss = NULL;
5181 INIT_LIST_HEAD(&priv->bss_list);
5182 spin_lock_init(&priv->bss_list_spinlock);
5184 init_timer(&priv->bss_list_timer);
5185 priv->bss_list_timer.data = (unsigned long)priv;
5186 priv->bss_list_timer.function = at76_bss_list_timeout;
5188 spin_lock_init(&priv->spy_spinlock);
5190 /* mark all rx data entries as unused */
5191 for (i = 0; i < NR_RX_DATA_BUF; i++)
5192 priv->rx_data[i].skb = NULL;
5194 priv->rx_tasklet.func = at76_rx_tasklet;
5195 priv->rx_tasklet.data = 0;
5197 priv->pm_mode = AT76_PM_OFF;
5198 priv->pm_period = 0;
5200 return priv;
5203 static int at76_alloc_urbs(struct at76_priv *priv,
5204 struct usb_interface *interface)
5206 struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
5207 int i;
5208 int buffer_size;
5209 struct usb_host_interface *iface_desc;
5211 at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
5213 at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
5214 interface->altsetting[0].desc.bNumEndpoints);
5216 ep_in = NULL;
5217 ep_out = NULL;
5218 iface_desc = interface->cur_altsetting;
5219 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
5220 endpoint = &iface_desc->endpoint[i].desc;
5222 at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
5223 __func__, i, endpoint->bEndpointAddress,
5224 endpoint->bmAttributes);
5226 if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
5227 ep_in = endpoint;
5229 if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
5230 ep_out = endpoint;
5233 if (!ep_in || !ep_out) {
5234 dev_printk(KERN_ERR, &interface->dev,
5235 "bulk endpoints missing\n");
5236 return -ENXIO;
5239 priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
5240 priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
5242 priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
5243 priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
5244 if (!priv->rx_urb || !priv->tx_urb) {
5245 dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
5246 return -ENOMEM;
5249 buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
5250 priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
5251 if (!priv->bulk_out_buffer) {
5252 dev_printk(KERN_ERR, &interface->dev,
5253 "cannot allocate output buffer\n");
5254 return -ENOMEM;
5257 at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
5259 return 0;
5262 static const struct net_device_ops at76_netdev_ops = {
5263 .ndo_open = at76_open,
5264 .ndo_stop = at76_stop,
5265 .ndo_get_stats = at76_get_stats,
5266 .ndo_start_xmit = at76_tx,
5267 .ndo_tx_timeout = at76_tx_timeout,
5268 .ndo_set_multicast_list = at76_set_multicast,
5269 .ndo_set_mac_address = at76_set_mac_address,
5270 .ndo_validate_addr = eth_validate_addr,
5271 .ndo_change_mtu = eth_change_mtu,
5274 /* Register network device and initialize the hardware */
5275 static int at76_init_new_device(struct at76_priv *priv,
5276 struct usb_interface *interface)
5278 struct net_device *netdev = priv->netdev;
5279 int ret;
5281 /* set up the endpoint information */
5282 /* check out the endpoints */
5284 at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
5285 interface->cur_altsetting->desc.bNumEndpoints);
5287 ret = at76_alloc_urbs(priv, interface);
5288 if (ret < 0)
5289 goto exit;
5291 /* MAC address */
5292 ret = at76_get_hw_config(priv);
5293 if (ret < 0) {
5294 dev_printk(KERN_ERR, &interface->dev,
5295 "cannot get MAC address\n");
5296 goto exit;
5299 priv->domain = at76_get_reg_domain(priv->regulatory_domain);
5300 /* init. netdev->dev_addr */
5301 memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
5303 priv->channel = DEF_CHANNEL;
5304 priv->iw_mode = IW_MODE_INFRA;
5305 priv->rts_threshold = DEF_RTS_THRESHOLD;
5306 priv->frag_threshold = DEF_FRAG_THRESHOLD;
5307 priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
5308 priv->txrate = TX_RATE_AUTO;
5309 priv->preamble_type = PREAMBLE_TYPE_LONG;
5310 priv->beacon_period = 100;
5311 priv->beacons_last_qual = jiffies;
5312 priv->auth_mode = WLAN_AUTH_OPEN;
5313 priv->scan_min_time = DEF_SCAN_MIN_TIME;
5314 priv->scan_max_time = DEF_SCAN_MAX_TIME;
5315 priv->scan_mode = SCAN_TYPE_ACTIVE;
5317 netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
5318 netdev->netdev_ops = &at76_netdev_ops;
5319 netdev->ethtool_ops = &at76_ethtool_ops;
5321 /* Add pointers to enable iwspy support. */
5322 priv->wireless_data.spy_data = &priv->spy_data;
5323 netdev->wireless_data = &priv->wireless_data;
5325 netdev->watchdog_timeo = 2 * HZ;
5326 netdev->wireless_handlers = &at76_handler_def;
5327 dev_alloc_name(netdev, "wlan%d");
5329 ret = register_netdev(priv->netdev);
5330 if (ret) {
5331 dev_printk(KERN_ERR, &interface->dev,
5332 "cannot register netdevice (status %d)!\n", ret);
5333 goto exit;
5335 priv->netdev_registered = 1;
5337 printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
5338 netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr),
5339 priv->fw_version.major, priv->fw_version.minor,
5340 priv->fw_version.patch, priv->fw_version.build);
5341 printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
5342 priv->regulatory_domain, priv->domain->name);
5344 /* we let this timer run the whole time this driver instance lives */
5345 mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
5347 exit:
5348 return ret;
5351 static void at76_delete_device(struct at76_priv *priv)
5353 int i;
5355 at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
5357 /* The device is gone, don't bother turning it off */
5358 priv->device_unplugged = 1;
5360 if (priv->netdev_registered)
5361 unregister_netdev(priv->netdev);
5363 /* assuming we used keventd, it must quiesce too */
5364 flush_scheduled_work();
5366 kfree(priv->bulk_out_buffer);
5368 if (priv->tx_urb) {
5369 usb_kill_urb(priv->tx_urb);
5370 usb_free_urb(priv->tx_urb);
5372 if (priv->rx_urb) {
5373 usb_kill_urb(priv->rx_urb);
5374 usb_free_urb(priv->rx_urb);
5377 at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
5379 kfree_skb(priv->rx_skb);
5381 at76_free_bss_list(priv);
5382 del_timer_sync(&priv->bss_list_timer);
5383 cancel_delayed_work(&priv->dwork_get_scan);
5384 cancel_delayed_work(&priv->dwork_beacon);
5385 cancel_delayed_work(&priv->dwork_auth);
5386 cancel_delayed_work(&priv->dwork_assoc);
5388 if (priv->mac_state == MAC_CONNECTED)
5389 at76_iwevent_bss_disconnect(priv->netdev);
5391 for (i = 0; i < NR_RX_DATA_BUF; i++)
5392 if (priv->rx_data[i].skb) {
5393 dev_kfree_skb(priv->rx_data[i].skb);
5394 priv->rx_data[i].skb = NULL;
5396 usb_put_dev(priv->udev);
5398 at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
5399 free_netdev(priv->netdev); /* priv is in netdev */
5401 at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
5404 static int at76_probe(struct usb_interface *interface,
5405 const struct usb_device_id *id)
5407 int ret;
5408 struct at76_priv *priv;
5409 struct fwentry *fwe;
5410 struct usb_device *udev;
5411 int op_mode;
5412 int need_ext_fw = 0;
5413 struct mib_fw_version fwv;
5414 int board_type = (int)id->driver_info;
5416 udev = usb_get_dev(interface_to_usbdev(interface));
5418 /* Load firmware into kernel memory */
5419 fwe = at76_load_firmware(udev, board_type);
5420 if (!fwe) {
5421 ret = -ENOENT;
5422 goto error;
5425 op_mode = at76_get_op_mode(udev);
5427 at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
5429 /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
5430 we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
5432 if (op_mode == OPMODE_HW_CONFIG_MODE) {
5433 dev_printk(KERN_ERR, &interface->dev,
5434 "cannot handle a device in HW_CONFIG_MODE\n");
5435 ret = -EBUSY;
5436 goto error;
5439 if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
5440 && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
5441 /* download internal firmware part */
5442 dev_printk(KERN_DEBUG, &interface->dev,
5443 "downloading internal firmware\n");
5444 ret = at76_load_internal_fw(udev, fwe);
5445 if (ret < 0) {
5446 dev_printk(KERN_ERR, &interface->dev,
5447 "error %d downloading internal firmware\n",
5448 ret);
5449 goto error;
5451 usb_put_dev(udev);
5452 return ret;
5455 /* Internal firmware already inside the device. Get firmware
5456 * version to test if external firmware is loaded.
5457 * This works only for newer firmware, e.g. the Intersil 0.90.x
5458 * says "control timeout on ep0in" and subsequent
5459 * at76_get_op_mode() fail too :-( */
5461 /* if version >= 0.100.x.y or device with built-in flash we can
5462 * query the device for the fw version */
5463 if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
5464 || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
5465 ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
5466 if (ret < 0 || (fwv.major | fwv.minor) == 0)
5467 need_ext_fw = 1;
5468 } else
5469 /* No way to check firmware version, reload to be sure */
5470 need_ext_fw = 1;
5472 if (need_ext_fw) {
5473 dev_printk(KERN_DEBUG, &interface->dev,
5474 "downloading external firmware\n");
5476 ret = at76_load_external_fw(udev, fwe);
5477 if (ret)
5478 goto error;
5480 /* Re-check firmware version */
5481 ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
5482 if (ret < 0) {
5483 dev_printk(KERN_ERR, &interface->dev,
5484 "error %d getting firmware version\n", ret);
5485 goto error;
5489 priv = at76_alloc_new_device(udev);
5490 if (!priv) {
5491 ret = -ENOMEM;
5492 goto error;
5495 SET_NETDEV_DEV(priv->netdev, &interface->dev);
5496 usb_set_intfdata(interface, priv);
5498 memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
5499 priv->board_type = board_type;
5501 ret = at76_init_new_device(priv, interface);
5502 if (ret < 0)
5503 at76_delete_device(priv);
5505 return ret;
5507 error:
5508 usb_put_dev(udev);
5509 return ret;
5512 static void at76_disconnect(struct usb_interface *interface)
5514 struct at76_priv *priv;
5516 priv = usb_get_intfdata(interface);
5517 usb_set_intfdata(interface, NULL);
5519 /* Disconnect after loading internal firmware */
5520 if (!priv)
5521 return;
5523 printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
5524 at76_delete_device(priv);
5525 dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
5528 /* Structure for registering this driver with the USB subsystem */
5529 static struct usb_driver at76_driver = {
5530 .name = DRIVER_NAME,
5531 .probe = at76_probe,
5532 .disconnect = at76_disconnect,
5533 .id_table = dev_table,
5536 static int __init at76_mod_init(void)
5538 int result;
5540 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
5542 mutex_init(&fw_mutex);
5544 /* register this driver with the USB subsystem */
5545 result = usb_register(&at76_driver);
5546 if (result < 0)
5547 printk(KERN_ERR DRIVER_NAME
5548 ": usb_register failed (status %d)\n", result);
5550 led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
5551 return result;
5554 static void __exit at76_mod_exit(void)
5556 int i;
5558 printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
5559 usb_deregister(&at76_driver);
5560 for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
5561 if (firmwares[i].fw)
5562 release_firmware(firmwares[i].fw);
5564 led_trigger_unregister_simple(ledtrig_tx);
5567 module_param_named(debug, at76_debug, int, 0600);
5568 MODULE_PARM_DESC(debug, "Debugging level");
5570 module_init(at76_mod_init);
5571 module_exit(at76_mod_exit);
5573 MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
5574 MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
5575 MODULE_AUTHOR("Alex <alex@foogod.com>");
5576 MODULE_AUTHOR("Nick Jones");
5577 MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
5578 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
5579 MODULE_DESCRIPTION(DRIVER_DESC);
5580 MODULE_LICENSE("GPL");