Staging: at76_usb: convert to use linux/ieee80211.h
[linux-2.6.git] / drivers / staging / at76_usb / at76_usb.c
1 /*
2  * at76c503/at76c505 USB driver
3  *
4  * Copyright (c) 2002 - 2003 Oliver Kurth
5  * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
6  * Copyright (c) 2004 Nick Jones
7  * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
8  * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This file is part of the Berlios driver for WLAN USB devices based on the
16  * Atmel AT76C503A/505/505A.
17  *
18  * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
19  */
20
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/sched.h>
24 #include <linux/errno.h>
25 #include <linux/slab.h>
26 #include <linux/module.h>
27 #include <linux/spinlock.h>
28 #include <linux/list.h>
29 #include <linux/usb.h>
30 #include <linux/netdevice.h>
31 #include <linux/if_arp.h>
32 #include <linux/etherdevice.h>
33 #include <linux/ethtool.h>
34 #include <linux/wireless.h>
35 #include <net/iw_handler.h>
36 #include <net/ieee80211_radiotap.h>
37 #include <linux/firmware.h>
38 #include <linux/leds.h>
39 #include <linux/ieee80211.h>
40
41 #include "at76_usb.h"
42
43 /* Version information */
44 #define DRIVER_NAME "at76_usb"
45 #define DRIVER_VERSION  "0.17"
46 #define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
47
48 /* at76_debug bits */
49 #define DBG_PROGRESS            0x00000001      /* authentication/accociation */
50 #define DBG_BSS_TABLE           0x00000002      /* show BSS table after scans */
51 #define DBG_IOCTL               0x00000004      /* ioctl calls / settings */
52 #define DBG_MAC_STATE           0x00000008      /* MAC state transitions */
53 #define DBG_TX_DATA             0x00000010      /* tx header */
54 #define DBG_TX_DATA_CONTENT     0x00000020      /* tx content */
55 #define DBG_TX_MGMT             0x00000040      /* tx management */
56 #define DBG_RX_DATA             0x00000080      /* rx data header */
57 #define DBG_RX_DATA_CONTENT     0x00000100      /* rx data content */
58 #define DBG_RX_MGMT             0x00000200      /* rx mgmt frame headers */
59 #define DBG_RX_BEACON           0x00000400      /* rx beacon */
60 #define DBG_RX_CTRL             0x00000800      /* rx control */
61 #define DBG_RX_MGMT_CONTENT     0x00001000      /* rx mgmt content */
62 #define DBG_RX_FRAGS            0x00002000      /* rx data fragment handling */
63 #define DBG_DEVSTART            0x00004000      /* fw download, device start */
64 #define DBG_URB                 0x00008000      /* rx urb status, ... */
65 #define DBG_RX_ATMEL_HDR        0x00010000      /* Atmel-specific Rx headers */
66 #define DBG_PROC_ENTRY          0x00020000      /* procedure entries/exits */
67 #define DBG_PM                  0x00040000      /* power management settings */
68 #define DBG_BSS_MATCH           0x00080000      /* BSS match failures */
69 #define DBG_PARAMS              0x00100000      /* show configured parameters */
70 #define DBG_WAIT_COMPLETE       0x00200000      /* command completion */
71 #define DBG_RX_FRAGS_SKB        0x00400000      /* skb header of Rx fragments */
72 #define DBG_BSS_TABLE_RM        0x00800000      /* purging bss table entries */
73 #define DBG_MONITOR_MODE        0x01000000      /* monitor mode */
74 #define DBG_MIB                 0x02000000      /* dump all MIBs on startup */
75 #define DBG_MGMT_TIMER          0x04000000      /* dump mgmt_timer ops */
76 #define DBG_WE_EVENTS           0x08000000      /* dump wireless events */
77 #define DBG_FW                  0x10000000      /* firmware download */
78 #define DBG_DFU                 0x20000000      /* device firmware upgrade */
79
80 #define DBG_DEFAULTS            0
81
82 /* Use our own dbg macro */
83 #define at76_dbg(bits, format, arg...) \
84         do { \
85                 if (at76_debug & (bits)) \
86                 printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
87         } while (0)
88
89 static int at76_debug = DBG_DEFAULTS;
90
91 /* Protect against concurrent firmware loading and parsing */
92 static struct mutex fw_mutex;
93
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"},
104 };
105
106 #define USB_DEVICE_DATA(__ops)  .driver_info = (kernel_ulong_t)(__ops)
107
108 static struct usb_device_id dev_table[] = {
109         /*
110          * at76c503-i3861
111          */
112         /* Generic AT76C503/3861 device */
113         {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
114         /* Linksys WUSB11 v2.1/v2.6 */
115         {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
116         /* Netgear MA101 rev. A */
117         {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
118         /* Tekram U300C / Allnet ALL0193 */
119         {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
120         /* HP HN210W J7801A */
121         {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
122         /* Sitecom/Z-Com/Zyxel M4Y-750 */
123         {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
124         /* Dynalink/Askey WLL013 (intersil) */
125         {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
126         /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
127         {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
128         /* BenQ AWL300 */
129         {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
130         /* Addtron AWU-120, Compex WLU11 */
131         {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
132         /* Intel AP310 AnyPoint II USB */
133         {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
134         /* Dynalink L11U */
135         {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
136         /* Arescom WL-210, FCC id 07J-GL2411USB */
137         {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
138         /* I-O DATA WN-B11/USB */
139         {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
140         /* BT Voyager 1010 */
141         {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
142         /*
143          * at76c503-i3863
144          */
145         /* Generic AT76C503/3863 device */
146         {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
147         /* Samsung SWL-2100U */
148         {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
149         /*
150          * at76c503-rfmd
151          */
152         /* Generic AT76C503/RFMD device */
153         {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
154         /* Dynalink/Askey WLL013 (rfmd) */
155         {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
156         /* Linksys WUSB11 v2.6 */
157         {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
158         /* Network Everywhere NWU11B */
159         {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
160         /* Netgear MA101 rev. B */
161         {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
162         /* D-Link DWL-120 rev. E */
163         {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
164         /* Actiontec 802UAT1, HWU01150-01UK */
165         {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
166         /* AirVast W-Buddie WN210 */
167         {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
168         /* Dick Smith Electronics XH1153 802.11b USB adapter */
169         {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
170         /* CNet CNUSB611 */
171         {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
172         /* FiberLine FL-WL200U */
173         {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
174         /* BenQ AWL400 USB stick */
175         {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
176         /* 3Com 3CRSHEW696 */
177         {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
178         /* Siemens Santis ADSL WLAN USB adapter WLL 013 */
179         {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
180         /* Belkin F5D6050, version 2 */
181         {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
182         /* iBlitzz, BWU613 (not *B or *SB) */
183         {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
184         /* Gigabyte GN-WLBM101 */
185         {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
186         /* Planex GW-US11S */
187         {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
188         /* Internal WLAN adapter in h5[4,5]xx series iPAQs */
189         {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
190         /* Corega Wireless LAN USB-11 mini */
191         {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
192         /* Corega Wireless LAN USB-11 mini2 */
193         {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
194         /* Uniden PCW100 */
195         {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
196         /*
197          * at76c503-rfmd-acc
198          */
199         /* SMC2664W */
200         {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
201         /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
202         {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
203         /*
204          * at76c505-rfmd
205          */
206         /* Generic AT76C505/RFMD */
207         {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
208         /*
209          * at76c505-rfmd2958
210          */
211         /* Generic AT76C505/RFMD, OvisLink WL-1130USB */
212         {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
213         /* Fiberline FL-WL240U */
214         {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
215         /* CNet CNUSB-611G */
216         {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
217         /* Linksys WUSB11 v2.8 */
218         {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
219         /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
220         {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
221         /* Corega WLAN USB Stick 11 */
222         {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
223         /* Microstar MSI Box MS6978 */
224         {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
225         /*
226          * at76c505a-rfmd2958
227          */
228         /* Generic AT76C505A device */
229         {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
230         /* Generic AT76C505AS device */
231         {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
232         /* Siemens Gigaset USB WLAN Adapter 11 */
233         {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
234         /* OQO Model 01+ Internal Wi-Fi */
235         {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)},
236         /*
237          * at76c505amx-rfmd
238          */
239         /* Generic AT76C505AMX device */
240         {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
241         {}
242 };
243
244 MODULE_DEVICE_TABLE(usb, dev_table);
245
246 /* Supported rates of this hardware, bit 7 marks basic rates */
247 static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
248
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
253 };
254
255 #define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
256
257 static const char *const preambles[] = { "long", "short", "auto" };
258
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"
267 };
268
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
282
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
291
292 #define FW_BLOCK_SIZE 1024
293
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));
300
301 static inline int at76_is_intersil(enum board_type board)
302 {
303         return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
304 }
305
306 static inline int at76_is_503rfmd(enum board_type board)
307 {
308         return (board == BOARD_503 || board == BOARD_503_ACC);
309 }
310
311 static inline int at76_is_505a(enum board_type board)
312 {
313         return (board == BOARD_505A || board == BOARD_505AMX);
314 }
315
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)
319 {
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);
324 }
325
326 static int at76_dfu_get_status(struct usb_device *udev,
327                                struct dfu_status *status)
328 {
329         int ret;
330
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;
336 }
337
338 static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
339 {
340         int ret;
341
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;
346 }
347
348 /* Convert timeout from the DFU status to jiffies */
349 static inline unsigned long at76_get_timeout(struct dfu_status *s)
350 {
351         return msecs_to_jiffies((s->poll_timeout[2] << 16)
352                                 | (s->poll_timeout[1] << 8)
353                                 | (s->poll_timeout[0]));
354 }
355
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)
360 {
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;
370
371         at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
372                  manifest_sync_timeout);
373
374         if (!size) {
375                 dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
376                 return -EINVAL;
377         }
378
379         block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
380         if (!block)
381                 return -ENOMEM;
382
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;
390                         }
391                         need_dfu_state = 0;
392                 }
393
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;
407
408                 case STATE_DFU_DOWNLOAD_BUSY:
409                         at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
410                         need_dfu_state = 1;
411
412                         at76_dbg(DBG_DFU, "DFU: Resetting device");
413                         schedule_timeout_interruptible(dfu_timeout);
414                         break;
415
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");
421
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++;
432
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;
439
440                 case STATE_DFU_MANIFEST_SYNC:
441                         at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
442
443                         ret = at76_dfu_get_status(udev, &dfu_stat_buf);
444                         if (ret < 0)
445                                 break;
446
447                         dfu_state = dfu_stat_buf.state;
448                         dfu_timeout = at76_get_timeout(&dfu_stat_buf);
449                         need_dfu_state = 0;
450
451                         /* override the timeout from the status response,
452                            needed for AT76C505A */
453                         if (manifest_sync_timeout > 0)
454                                 dfu_timeout = manifest_sync_timeout;
455
456                         at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
457                         schedule_timeout_interruptible(dfu_timeout);
458                         break;
459
460                 case STATE_DFU_MANIFEST:
461                         at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
462                         is_done = 1;
463                         break;
464
465                 case STATE_DFU_MANIFEST_WAIT_RESET:
466                         at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
467                         is_done = 1;
468                         break;
469
470                 case STATE_DFU_UPLOAD_IDLE:
471                         at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
472                         break;
473
474                 case STATE_DFU_ERROR:
475                         at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
476                         ret = -EPIPE;
477                         break;
478
479                 default:
480                         at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
481                         ret = -EINVAL;
482                         break;
483                 }
484         } while (!is_done && (ret >= 0));
485
486 exit:
487         kfree(block);
488         if (ret >= 0)
489                 ret = 0;
490
491         return ret;
492 }
493
494 /* Report that the scan results are ready */
495 static inline void at76_iwevent_scan_complete(struct net_device *netdev)
496 {
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);
502 }
503
504 static inline void at76_iwevent_bss_connect(struct net_device *netdev,
505                                             u8 *bssid)
506 {
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__);
515 }
516
517 static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
518 {
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__);
527 }
528
529 #define HEX2STR_BUFFERS 4
530 #define HEX2STR_MAX_LEN 64
531 #define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
532
533 /* Convert binary data into hex string */
534 static char *hex2str(void *buf, int len)
535 {
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;
541
542         if (len > HEX2STR_MAX_LEN)
543                 len = HEX2STR_MAX_LEN;
544
545         if (len <= 0) {
546                 ret[0] = '\0';
547                 return ret;
548         }
549
550         while (len--) {
551                 *obuf++ = BIN2HEX(*ibuf >> 4);
552                 *obuf++ = BIN2HEX(*ibuf & 0xf);
553                 *obuf++ = '-';
554                 ibuf++;
555         }
556         *(--obuf) = '\0';
557
558         return ret;
559 }
560
561 #define MAC2STR_BUFFERS 4
562
563 static inline char *mac2str(u8 *mac)
564 {
565         static atomic_t a = ATOMIC_INIT(0);
566         static char bufs[MAC2STR_BUFFERS][6 * 3];
567         char *str;
568
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;
573 }
574
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);
580
581 static void at76_ledtrig_tx_timerfunc(unsigned long data)
582 {
583         static int tx_lastactivity;
584
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);
591 }
592
593 static void at76_ledtrig_tx_activity(void)
594 {
595         tx_activity++;
596         if (!timer_pending(&ledtrig_tx_timer))
597                 mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
598 }
599
600 /* Check if the given ssid is hidden */
601 static inline int at76_is_hidden_ssid(u8 *ssid, int length)
602 {
603         static const u8 zeros[32];
604
605         if (length == 0)
606                 return 1;
607
608         if (length == 1 && ssid[0] == ' ')
609                 return 1;
610
611         return (memcmp(ssid, zeros, length) == 0);
612 }
613
614 static inline void at76_free_bss_list(struct at76_priv *priv)
615 {
616         struct list_head *next, *ptr;
617         unsigned long flags;
618
619         spin_lock_irqsave(&priv->bss_list_spinlock, flags);
620
621         priv->curr_bss = NULL;
622
623         list_for_each_safe(ptr, next, &priv->bss_list) {
624                 list_del(ptr);
625                 kfree(list_entry(ptr, struct bss_info, list));
626         }
627
628         spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
629 }
630
631 static int at76_remap(struct usb_device *udev)
632 {
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;
641 }
642
643 static int at76_get_op_mode(struct usb_device *udev)
644 {
645         int ret;
646         u8 saved;
647         u8 *op_mode;
648
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);
658
659         if (ret < 0)
660                 return ret;
661         else if (ret < 1)
662                 return -EIO;
663         else
664                 return saved;
665 }
666
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)
670 {
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);
675 }
676
677 static inline int at76_get_hw_cfg(struct usb_device *udev,
678                                   union at76_hwcfg *buf, int buf_size)
679 {
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);
684 }
685
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)
689 {
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);
694 }
695
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)
700 {
701         int ret;
702         union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
703
704         if (!hwcfg)
705                 return -ENOMEM;
706
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;
726         }
727
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);
733
734         return ret;
735 }
736
737 static struct reg_domain const *at76_get_reg_domain(u16 code)
738 {
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 */
750         };
751
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;
756
757         return &fd_tab[i];
758 }
759
760 static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
761                                int buf_size)
762 {
763         int ret;
764
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;
772 }
773
774 /* Return positive number for status, negative for an error */
775 static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
776 {
777         u8 *stat_buf;
778         int ret;
779
780         stat_buf = kmalloc(40, GFP_NOIO);
781         if (!stat_buf)
782                 return -ENOMEM;
783
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);
791
792         return ret;
793 }
794
795 static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
796                                  int buf_size)
797 {
798         int ret;
799         struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
800                                                buf_size, GFP_KERNEL);
801
802         if (!cmd_buf)
803                 return -ENOMEM;
804
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);
809
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;
817 }
818
819 #define MAKE_CMD_STATUS_CASE(c) case (c): return #c
820 static const char *at76_get_cmd_status_string(u8 cmd_status)
821 {
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);
832         }
833
834         return "UNKNOWN";
835 }
836
837 /* Wait until the command is completed */
838 static int at76_wait_completion(struct at76_priv *priv, int cmd)
839 {
840         int status = 0;
841         unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
842
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;
849                 }
850
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));
855
856                 if (status != CMD_STATUS_IN_PROGRESS
857                     && status != CMD_STATUS_IDLE)
858                         break;
859
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;
867                 }
868         } while (1);
869
870         return status;
871 }
872
873 static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
874 {
875         int ret;
876
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;
882
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;
889         }
890
891         return ret;
892 }
893
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)
896 {
897         int ret;
898         int cmd;
899
900         if (priv->radio_on == enable)
901                 return 0;
902
903         cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
904
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;
911
912         priv->radio_on = enable;
913         return ret;
914 }
915
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)
918 {
919         int ret = 0;
920
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;
925
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);
930
931         return ret;
932 }
933
934 /* Set the association id for power save mode */
935 static int at76_set_associd(struct at76_priv *priv, u16 id)
936 {
937         int ret = 0;
938
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);
943
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);
948
949         return ret;
950 }
951
952 /* Set the listen interval for power save mode */
953 static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
954 {
955         int ret = 0;
956
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);
961
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);
967
968         return ret;
969 }
970
971 static int at76_set_preamble(struct at76_priv *priv, u8 type)
972 {
973         int ret = 0;
974
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;
979
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);
984
985         return ret;
986 }
987
988 static int at76_set_frag(struct at76_priv *priv, u16 size)
989 {
990         int ret = 0;
991
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);
996
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);
1001
1002         return ret;
1003 }
1004
1005 static int at76_set_rts(struct at76_priv *priv, u16 size)
1006 {
1007         int ret = 0;
1008
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);
1013
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);
1018
1019         return ret;
1020 }
1021
1022 static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
1023 {
1024         int ret = 0;
1025
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;
1030
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);
1035
1036         return ret;
1037 }
1038
1039 static int at76_add_mac_address(struct at76_priv *priv, void *addr)
1040 {
1041         int ret = 0;
1042
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);
1047
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);
1052
1053         return ret;
1054 }
1055
1056 static void at76_dump_mib_mac_addr(struct at76_priv *priv)
1057 {
1058         int i;
1059         int ret;
1060         struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
1061                                          GFP_KERNEL);
1062
1063         if (!m)
1064                 return;
1065
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;
1072         }
1073
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);
1083 }
1084
1085 static void at76_dump_mib_mac_wep(struct at76_priv *priv)
1086 {
1087         int i;
1088         int ret;
1089         int key_len;
1090         struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
1091
1092         if (!m)
1093                 return;
1094
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;
1101         }
1102
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);
1111
1112         key_len = (m->encryption_level == 1) ?
1113             WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
1114
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);
1121 }
1122
1123 static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
1124 {
1125         int ret;
1126         struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
1127                                          GFP_KERNEL);
1128
1129         if (!m)
1130                 return;
1131
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;
1138         }
1139
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);
1159 }
1160
1161 static void at76_dump_mib_mac(struct at76_priv *priv)
1162 {
1163         int ret;
1164         struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
1165
1166         if (!m)
1167                 return;
1168
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;
1174         }
1175
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);
1195 }
1196
1197 static void at76_dump_mib_phy(struct at76_priv *priv)
1198 {
1199         int ret;
1200         struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1201
1202         if (!m)
1203                 return;
1204
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;
1210         }
1211
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);
1228 }
1229
1230 static void at76_dump_mib_local(struct at76_priv *priv)
1231 {
1232         int ret;
1233         struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1234
1235         if (!m)
1236                 return;
1237
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;
1243         }
1244
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);
1252 }
1253
1254 static void at76_dump_mib_mdomain(struct at76_priv *priv)
1255 {
1256         int ret;
1257         struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
1258
1259         if (!m)
1260                 return;
1261
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;
1268         }
1269
1270         at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
1271                  priv->netdev->name,
1272                  hex2str(m->channel_list, sizeof(m->channel_list)));
1273
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);
1279 }
1280
1281 static int at76_get_current_bssid(struct at76_priv *priv)
1282 {
1283         int ret = 0;
1284         struct mib_mac_mgmt *mac_mgmt =
1285             kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
1286
1287         if (!mac_mgmt) {
1288                 ret = -ENOMEM;
1289                 goto exit;
1290         }
1291
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;
1298         }
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;
1306 }
1307
1308 static int at76_get_current_channel(struct at76_priv *priv)
1309 {
1310         int ret = 0;
1311         struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
1312
1313         if (!phy) {
1314                 ret = -ENOMEM;
1315                 goto exit;
1316         }
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;
1322         }
1323         priv->channel = phy->channel_id;
1324 error:
1325         kfree(phy);
1326 exit:
1327         return ret;
1328 }
1329
1330 /**
1331  * at76_start_scan - start a scan
1332  *
1333  * @use_essid - use the configured ESSID in non passive mode
1334  */
1335 static int at76_start_scan(struct at76_priv *priv, int use_essid)
1336 {
1337         struct at76_req_scan scan;
1338
1339         memset(&scan, 0, sizeof(struct at76_req_scan));
1340         memset(scan.bssid, 0xff, ETH_ALEN);
1341
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;
1347
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;
1351
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;
1355
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;
1363
1364         /* other values are set to 0 for type 0 */
1365
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));
1374
1375         return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
1376 }
1377
1378 /* Enable monitor mode */
1379 static int at76_start_monitor(struct at76_priv *priv)
1380 {
1381         struct at76_req_scan scan;
1382         int ret;
1383
1384         memset(&scan, 0, sizeof(struct at76_req_scan));
1385         memset(scan.bssid, 0xff, ETH_ALEN);
1386
1387         scan.channel = priv->channel;
1388         scan.scan_type = SCAN_TYPE_PASSIVE;
1389         scan.international_scan = 0;
1390
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);
1394
1395         return ret;
1396 }
1397
1398 static int at76_start_ibss(struct at76_priv *priv)
1399 {
1400         struct at76_req_ibss bss;
1401         int ret;
1402
1403         WARN_ON(priv->mac_state != MAC_OWN_IBSS);
1404         if (priv->mac_state != MAC_OWN_IBSS)
1405                 return -EBUSY;
1406
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;
1413
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;
1420         }
1421
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;
1427         }
1428
1429         ret = at76_get_current_bssid(priv);
1430         if (ret < 0)
1431                 return ret;
1432
1433         ret = at76_get_current_channel(priv);
1434         if (ret < 0)
1435                 return ret;
1436
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;
1442
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;
1448         }
1449
1450         netif_carrier_on(priv->netdev);
1451         netif_start_queue(priv->netdev);
1452         return 0;
1453 }
1454
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)
1457 {
1458         struct at76_req_join join;
1459
1460         BUG_ON(!ptr);
1461
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);
1469
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));
1476 }
1477
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)
1481 {
1482         /* add the USB TX header */
1483         wlen += AT76_TX_HDRLEN;
1484
1485         wlen = wlen % 64;
1486
1487         if (wlen < 50)
1488                 return 50 - wlen;
1489
1490         if (wlen >= 61)
1491                 return 64 + 50 - wlen;
1492
1493         return 0;
1494 }
1495
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
1501 */
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)
1505 {
1506         struct at76_priv *priv = urb->context;
1507
1508         priv->rx_tasklet.data = (unsigned long)urb;
1509         tasklet_schedule(&priv->rx_tasklet);
1510         return;
1511 }
1512
1513 static void at76_tx_callback(struct urb *urb)
1514 {
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;
1520
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;
1534         }
1535
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);
1540
1541         if (!mgmt_buf) {
1542                 netif_wake_queue(priv->netdev);
1543                 return;
1544         }
1545
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);
1558
1559         kfree(mgmt_buf);
1560 }
1561
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)
1564 {
1565         unsigned long flags;
1566         int ret;
1567         int urb_status;
1568         void *oldbuf = NULL;
1569
1570         netif_carrier_off(priv->netdev);        /* stop netdev watchdog */
1571         netif_stop_queue(priv->netdev); /* stop tx data packets */
1572
1573         spin_lock_irqsave(&priv->mgmt_spinlock, flags);
1574
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;
1580         }
1581         spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
1582
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;
1591         }
1592
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));
1596
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);
1600
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)));
1606
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);
1618
1619         kfree(txbuf);
1620
1621         return ret;
1622 }
1623
1624 /* Go to the next information element */
1625 static inline void next_ie(struct ieee80211_info_element **ie)
1626 {
1627         *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
1628 }
1629
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)
1636 {
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);
1642
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;
1648
1649         req = (struct ieee80211_auth *)tx_buffer->packet;
1650         mgmt = &req->header;
1651
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));
1657
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);
1663
1664         req->algorithm = cpu_to_le16(priv->auth_mode);
1665         req->transaction = cpu_to_le16(seq_nr);
1666         req->status = cpu_to_le16(0);
1667
1668         if (seq_nr == 3)
1669                 memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
1670
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));
1679
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);
1683 }
1684
1685 static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
1686 {
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;
1694
1695         BUG_ON(!bss);
1696
1697         tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
1698         if (!tx_buffer)
1699                 return -ENOMEM;
1700
1701         req = (struct ieee80211_assoc_request *)tx_buffer->packet;
1702         mgmt = &req->header;
1703         ie = req->info_element;
1704
1705         /* make wireless header */
1706         mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1707                                       IEEE80211_STYPE_ASSOC_REQ);
1708
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);
1714
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);
1725
1726         req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
1727
1728         /* write TLV data elements */
1729
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);
1734
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 */
1739
1740         /* init. at76_priv tx header */
1741         tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
1742
1743         ie = req->info_element;
1744         essid = ie->data;
1745         essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
1746
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));
1753
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);
1757 }
1758
1759 /* We got to check the bss_list for old entries */
1760 static void at76_bss_list_timeout(unsigned long par)
1761 {
1762         struct at76_priv *priv = (struct at76_priv *)par;
1763         unsigned long flags;
1764         struct list_head *lptr, *nptr;
1765         struct bss_info *ptr;
1766
1767         spin_lock_irqsave(&priv->bss_list_spinlock, flags);
1768
1769         list_for_each_safe(lptr, nptr, &priv->bss_list) {
1770
1771                 ptr = list_entry(lptr, struct bss_info, list);
1772
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);
1781                 }
1782         }
1783         spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
1784         /* restart the timer */
1785         mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
1786 }
1787
1788 static inline void at76_set_mac_state(struct at76_priv *priv,
1789                                       enum mac_state mac_state)
1790 {
1791         at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
1792                  mac_states[mac_state]);
1793         priv->mac_state = mac_state;
1794 }
1795
1796 static void at76_dump_bss_table(struct at76_priv *priv)
1797 {
1798         struct bss_info *ptr;
1799         unsigned long flags;
1800         struct list_head *lptr;
1801
1802         spin_lock_irqsave(&priv->bss_list_spinlock, flags);
1803
1804         at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
1805                  priv->curr_bss);
1806
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);
1815         }
1816         spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
1817 }
1818
1819 /* Called upon successful association to mark interface as connected */
1820 static void at76_work_assoc_done(struct work_struct *work)
1821 {
1822         struct at76_priv *priv = container_of(work, struct at76_priv,
1823                                               work_assoc_done);
1824
1825         mutex_lock(&priv->mtx);
1826
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;
1831
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;
1838
1839                         pm_period_beacon = max(pm_period_beacon, 2u);
1840                         pm_period_beacon = min(pm_period_beacon, 0xffffu);
1841
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);
1846
1847                         at76_set_associd(priv, priv->assoc_id);
1848                         at76_set_listen_interval(priv, (u16)pm_period_beacon);
1849                 }
1850                 schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
1851         }
1852         at76_set_pm_mode(priv);
1853
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));
1860
1861 exit:
1862         mutex_unlock(&priv->mtx);
1863 }
1864
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)
1868 {
1869         struct sockaddr *mac = addr;
1870         memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
1871         return 1;
1872 }
1873
1874 static struct net_device_stats *at76_get_stats(struct net_device *netdev)
1875 {
1876         struct at76_priv *priv = netdev_priv(netdev);
1877         return &priv->stats;
1878 }
1879
1880 static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
1881 {
1882         struct at76_priv *priv = netdev_priv(netdev);
1883
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);
1887
1888         return &priv->wstats;
1889 }
1890
1891 static void at76_set_multicast(struct net_device *netdev)
1892 {
1893         struct at76_priv *priv = netdev_priv(netdev);
1894         int promisc;
1895
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);
1901         }
1902 }
1903
1904 /* Stop all network activity, flush all pending tasks */
1905 static void at76_quiesce(struct at76_priv *priv)
1906 {
1907         unsigned long flags;
1908
1909         netif_stop_queue(priv->netdev);
1910         netif_carrier_off(priv->netdev);
1911
1912         at76_set_mac_state(priv, MAC_INIT);
1913
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);
1919
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);
1924 }
1925
1926 /*******************************************************************************
1927  * at76_priv implementations of iw_handler functions:
1928  */
1929 static int at76_iw_handler_commit(struct net_device *netdev,
1930                                   struct iw_request_info *info,
1931                                   void *null, char *extra)
1932 {
1933         struct at76_priv *priv = netdev_priv(netdev);
1934
1935         at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
1936                  __func__);
1937
1938         if (priv->mac_state != MAC_INIT)
1939                 at76_quiesce(priv);
1940
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);
1944
1945         return 0;
1946 }
1947
1948 static int at76_iw_handler_get_name(struct net_device *netdev,
1949                                     struct iw_request_info *info,
1950                                     char *name, char *extra)
1951 {
1952         strcpy(name, "IEEE 802.11b");
1953         at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
1954         return 0;
1955 }
1956
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)
1960 {
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);
1966
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;
1974
1975                 for (i = 0; i < (6 - freq->e); i++)
1976                         mult *= 10;
1977
1978                 for (i = 0; i < NUM_CHANNELS; i++) {
1979                         if (freq->m == (channel_frequency[i] * mult))
1980                                 chan = i + 1;
1981                 }
1982         }
1983
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;
1994         }
1995
1996         if (ret == -EIWCOMMIT) {
1997                 priv->channel = chan;
1998                 at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
1999                          chan);
2000         }
2001
2002         return ret;
2003 }
2004
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)
2008 {
2009         struct at76_priv *priv = netdev_priv(netdev);
2010
2011         freq->m = priv->channel;
2012         freq->e = 0;
2013
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);
2017
2018         at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
2019                  priv->channel);
2020
2021         return 0;
2022 }
2023
2024 static int at76_iw_handler_set_mode(struct net_device *netdev,
2025                                     struct iw_request_info *info,
2026                                     __u32 *mode, char *extra)
2027 {
2028         struct at76_priv *priv = netdev_priv(netdev);
2029
2030         at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
2031
2032         if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
2033             (*mode != IW_MODE_MONITOR))
2034                 return -EINVAL;
2035
2036         priv->iw_mode = *mode;
2037         if (priv->iw_mode != IW_MODE_INFRA)
2038                 priv->pm_mode = AT76_PM_OFF;
2039
2040         return -EIWCOMMIT;
2041 }
2042
2043 static int at76_iw_handler_get_mode(struct net_device *netdev,
2044                                     struct iw_request_info *info,
2045                                     __u32 *mode, char *extra)
2046 {
2047         struct at76_priv *priv = netdev_priv(netdev);
2048
2049         *mode = priv->iw_mode;
2050
2051         at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
2052
2053         return 0;
2054 }
2055
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)
2059 {
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;
2064
2065         data->length = sizeof(struct iw_range);
2066         memset(range, 0, sizeof(struct iw_range));
2067
2068         /* TODO: range->throughput = xxxxxx; */
2069
2070         range->min_nwid = 0x0000;
2071         range->max_nwid = 0x0000;
2072
2073         /* this driver doesn't maintain sensitivity information */
2074         range->sensitivity = 0;
2075
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;
2080
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;
2085
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;
2091
2092         range->min_rts = 0;
2093         range->max_rts = MAX_RTS_THRESHOLD;
2094
2095         range->min_frag = MIN_FRAG_THRESHOLD;
2096         range->max_frag = MAX_FRAG_THRESHOLD;
2097
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;
2101
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;
2106
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;
2112
2113         range->we_version_source = WIRELESS_EXT;
2114         range->we_version_compiled = WIRELESS_EXT;
2115
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;
2122
2123         range->num_channels = NUM_CHANNELS;
2124         range->num_frequency = 0;
2125
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;
2130
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 */
2134                 }
2135         }
2136
2137         at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
2138
2139         return 0;
2140 }
2141
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)
2145 {
2146         struct at76_priv *priv = netdev_priv(netdev);
2147         int ret = 0;
2148
2149         at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
2150                  netdev->name, data->length);
2151
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);
2156
2157         return ret;
2158 }
2159
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)
2163 {
2164
2165         struct at76_priv *priv = netdev_priv(netdev);
2166         int ret = 0;
2167
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);
2172
2173         at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
2174                  netdev->name, data->length);
2175
2176         return ret;
2177 }
2178
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)
2182 {
2183         struct at76_priv *priv = netdev_priv(netdev);
2184         int ret;
2185
2186         at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
2187                  netdev->name, data->length);
2188
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);
2193
2194         return ret;
2195 }
2196
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)
2200 {
2201         struct at76_priv *priv = netdev_priv(netdev);
2202         int ret;
2203
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);
2208
2209         at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
2210                  netdev->name, data->length);
2211
2212         return ret;
2213 }
2214
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)
2218 {
2219         struct at76_priv *priv = netdev_priv(netdev);
2220
2221         at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
2222                  mac2str(ap_addr->sa_data));
2223
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);
2233         }
2234
2235         return -EIWCOMMIT;
2236 }
2237
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)
2241 {
2242         struct at76_priv *priv = netdev_priv(netdev);
2243
2244         ap_addr->sa_family = ARPHRD_ETHER;
2245         memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
2246
2247         at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
2248                  mac2str(ap_addr->sa_data));
2249
2250         return 0;
2251 }
2252
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)
2256 {
2257         struct at76_priv *priv = netdev_priv(netdev);
2258         int ret = 0;
2259
2260         at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
2261
2262         if (mutex_lock_interruptible(&priv->mtx))
2263                 return -EINTR;
2264
2265         if (!netif_running(netdev)) {
2266                 ret = -ENETDOWN;
2267                 goto exit;
2268         }
2269
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;
2275         }
2276
2277         /* Discard old scan results */
2278         if ((jiffies - priv->last_scan) > (20 * HZ))
2279                 priv->scan_state = SCAN_IDLE;
2280         priv->last_scan = jiffies;
2281
2282         /* Initiate a scan command */
2283         if (priv->scan_state == SCAN_IN_PROGRESS) {
2284                 ret = -EBUSY;
2285                 goto exit;
2286         }
2287
2288         priv->scan_state = SCAN_IN_PROGRESS;
2289
2290         at76_quiesce(priv);
2291
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;
2296
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;
2301
2302                 /* Sanity check values? */
2303                 if (req->min_channel_time > 0)
2304                         priv->scan_min_time = req->min_channel_time;
2305
2306                 if (req->max_channel_time > 0)
2307                         priv->scan_max_time = req->max_channel_time;
2308         }
2309
2310         /* change to scanning state */
2311         at76_set_mac_state(priv, MAC_SCANNING);
2312         schedule_work(&priv->work_start_scan);
2313
2314 exit:
2315         mutex_unlock(&priv->mtx);
2316         return ret;
2317 }
2318
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)
2322 {
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;
2330
2331         at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
2332
2333         if (!iwe)
2334                 return -ENOMEM;
2335
2336         if (priv->scan_state != SCAN_COMPLETED) {
2337                 /* scan not yet finished */
2338                 kfree(iwe);
2339                 return -EAGAIN;
2340         }
2341
2342         spin_lock_irqsave(&priv->bss_list_spinlock, flags);
2343
2344         list_for_each_safe(lptr, nptr, &priv->bss_list) {
2345                 curr_bss = list_entry(lptr, struct bss_info, list);
2346
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);
2353
2354                 iwe->u.data.length = curr_bss->ssid_len;
2355                 iwe->cmd = SIOCGIWESSID;
2356                 iwe->u.data.flags = 1;
2357
2358                 curr_pos = iwe_stream_add_point(info, curr_pos,
2359                                                 extra + IW_SCAN_MAX_DATA, iwe,
2360                                                 curr_bss->ssid);
2361
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);
2372
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);
2379
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;
2385
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);
2390
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;
2404                 }
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);
2409
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;
2413
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);
2429                 }
2430
2431                 /* Check if we added any event */
2432                 if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
2433                         curr_pos = curr_val;
2434
2435                 /* more information may be sent back using IWECUSTOM */
2436
2437         }
2438
2439         spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
2440
2441         data->length = (curr_pos - extra);
2442         data->flags = 0;
2443
2444         kfree(iwe);
2445         return 0;
2446 }
2447
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)
2451 {
2452         struct at76_priv *priv = netdev_priv(netdev);
2453
2454         at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
2455
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 */
2461
2462         return -EIWCOMMIT;
2463 }
2464
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)
2468 {
2469         struct at76_priv *priv = netdev_priv(netdev);
2470
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;
2487                 }
2488         }
2489
2490         at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
2491                  data->length, extra);
2492
2493         return 0;
2494 }
2495
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)
2499 {
2500         struct at76_priv *priv = netdev_priv(netdev);
2501         int ret = -EIWCOMMIT;
2502
2503         at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
2504                  bitrate->value);
2505
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;
2524         }
2525
2526         return ret;
2527 }
2528
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)
2532 {
2533         struct at76_priv *priv = netdev_priv(netdev);
2534         int ret = 0;
2535
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;
2555         }
2556
2557         bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
2558         bitrate->disabled = 0;
2559
2560         at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
2561                  bitrate->value);
2562
2563         return ret;
2564 }
2565
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)
2569 {
2570         struct at76_priv *priv = netdev_priv(netdev);
2571         int ret = -EIWCOMMIT;
2572         int rthr = rts->value;
2573
2574         at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
2575                  netdev->name, rts->value, (rts->disabled) ? "true" : "false");
2576
2577         if (rts->disabled)
2578                 rthr = MAX_RTS_THRESHOLD;
2579
2580         if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
2581                 ret = -EINVAL;
2582         else
2583                 priv->rts_threshold = rthr;
2584
2585         return ret;
2586 }
2587
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)
2591 {
2592         struct at76_priv *priv = netdev_priv(netdev);
2593
2594         rts->value = priv->rts_threshold;
2595         rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
2596         rts->fixed = 1;
2597
2598         at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
2599                  netdev->name, rts->value, (rts->disabled) ? "true" : "false");
2600
2601         return 0;
2602 }
2603
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)
2607 {
2608         struct at76_priv *priv = netdev_priv(netdev);
2609         int ret = -EIWCOMMIT;
2610         int fthr = frag->value;
2611
2612         at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
2613                  netdev->name, frag->value,
2614                  (frag->disabled) ? "true" : "false");
2615
2616         if (frag->disabled)
2617                 fthr = MAX_FRAG_THRESHOLD;
2618
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 */
2623
2624         return ret;
2625 }
2626
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)
2630 {
2631         struct at76_priv *priv = netdev_priv(netdev);
2632
2633         frag->value = priv->frag_threshold;
2634         frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
2635         frag->fixed = 1;
2636
2637         at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
2638                  netdev->name, frag->value,
2639                  (frag->disabled) ? "true" : "false");
2640
2641         return 0;
2642 }
2643
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)
2647 {
2648         power->value = 15;
2649         power->fixed = 1;       /* No power control */
2650         power->disabled = 0;
2651         power->flags = IW_TXPOW_DBM;
2652
2653         at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
2654                  power->value);
2655
2656         return 0;
2657 }
2658
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)
2664 {
2665         struct at76_priv *priv = netdev_priv(netdev);
2666         int ret = -EIWCOMMIT;
2667
2668         at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
2669                  netdev->name, retry->disabled, retry->flags, retry->value);
2670
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;
2679
2680         return ret;
2681 }
2682
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)
2687 {
2688         struct at76_priv *priv = netdev_priv(netdev);
2689
2690         at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
2691
2692         retry->disabled = 0;    /* Can't be disabled */
2693         retry->flags = IW_RETRY_LIMIT;
2694         retry->value = priv->short_retry_limit;
2695
2696         return 0;
2697 }
2698
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)
2702 {
2703         struct at76_priv *priv = netdev_priv(netdev);
2704         int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
2705         int len = encoding->length;
2706
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");
2716
2717         /* take the old default key if index is invalid */
2718         if ((index < 0) || (index >= WEP_KEYS))
2719                 index = priv->wep_key_id;
2720
2721         if (len > 0) {
2722                 if (len > WEP_LARGE_KEY_LEN)
2723                         len = WEP_LARGE_KEY_LEN;
2724
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;
2730         }
2731
2732         priv->wep_key_id = index;
2733         priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
2734
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;
2739
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");
2747
2748         return -EIWCOMMIT;
2749 }
2750
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)
2754 {
2755         struct at76_priv *priv = netdev_priv(netdev);
2756         int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
2757
2758         if ((index < 0) || (index >= WEP_KEYS))
2759                 index = priv->wep_key_id;
2760
2761         encoding->flags =
2762             (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
2763             IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
2764
2765         if (!priv->wep_enabled)
2766                 encoding->flags |= IW_ENCODE_DISABLED;
2767
2768         if (encoding->pointer) {
2769                 encoding->length = priv->wep_keys_len[index];
2770
2771                 memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
2772
2773                 encoding->flags |= (index + 1);
2774         }
2775
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");
2786
2787         return 0;
2788 }
2789
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)
2793 {
2794         int err = -EIWCOMMIT;
2795         struct at76_priv *priv = netdev_priv(netdev);
2796
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);
2801
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;
2812                 }
2813                 if (prq->flags & IW_POWER_PERIOD)
2814                         priv->pm_period = prq->value;
2815
2816                 if (prq->flags & IW_POWER_TIMEOUT) {
2817                         err = -EINVAL;
2818                         goto exit;
2819                 }
2820                 priv->pm_mode = AT76_PM_ON;
2821         }
2822 exit:
2823         return err;
2824 }
2825
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)
2829 {
2830         struct at76_priv *priv = netdev_priv(netdev);
2831
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;
2836         }
2837
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);
2841
2842         return 0;
2843 }
2844
2845 /*******************************************************************************
2846  * Private IOCTLS
2847  */
2848 static int at76_iw_set_short_preamble(struct net_device *netdev,
2849                                       struct iw_request_info *info, char *name,
2850                                       char *extra)
2851 {
2852         struct at76_priv *priv = netdev_priv(netdev);
2853         int val = *((int *)name);
2854         int ret = -EIWCOMMIT;
2855
2856         at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
2857                  netdev->name, val);
2858
2859         if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
2860                 ret = -EINVAL;
2861         else
2862                 priv->preamble_type = val;
2863
2864         return ret;
2865 }
2866
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)
2870 {
2871         struct at76_priv *priv = netdev_priv(netdev);
2872
2873         snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
2874                  preambles[priv->preamble_type], priv->preamble_type);
2875         return 0;
2876 }
2877
2878 static int at76_iw_set_debug(struct net_device *netdev,
2879                              struct iw_request_info *info,
2880                              struct iw_point *data, char *extra)
2881 {
2882         char *ptr;
2883         u32 val;
2884
2885         if (data->length > 0) {
2886                 val = simple_strtol(extra, &ptr, 0);
2887
2888                 if (ptr == extra)
2889                         val = DBG_DEFAULTS;
2890
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;
2895
2896         at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
2897                  netdev->name, at76_debug, val);
2898
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));
2903
2904         at76_debug = val;
2905
2906         return 0;
2907 }
2908
2909 static int at76_iw_get_debug(struct net_device *netdev,
2910                              struct iw_request_info *info,
2911                              union iwreq_data *wrqu, char *extra)
2912 {
2913         snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
2914         return 0;
2915 }
2916
2917 static int at76_iw_set_powersave_mode(struct net_device *netdev,
2918                                       struct iw_request_info *info, char *name,
2919                                       char *extra)
2920 {
2921         struct at76_priv *priv = netdev_priv(netdev);
2922         int val = *((int *)name);
2923         int ret = -EIWCOMMIT;
2924
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;
2933
2934         return ret;
2935 }
2936
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)
2940 {
2941         struct at76_priv *priv = netdev_priv(netdev);
2942         int *param = (int *)extra;
2943
2944         param[0] = priv->pm_mode;
2945         return 0;
2946 }
2947
2948 static int at76_iw_set_scan_times(struct net_device *netdev,
2949                                   struct iw_request_info *info, char *name,
2950                                   char *extra)
2951 {
2952         struct at76_priv *priv = netdev_priv(netdev);
2953         int mint = *((int *)name);
2954         int maxt = *((int *)name + 1);
2955         int ret = -EIWCOMMIT;
2956
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;
2964         }
2965
2966         return ret;
2967 }
2968
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)
2972 {
2973         struct at76_priv *priv = netdev_priv(netdev);
2974         int *param = (int *)extra;
2975
2976         param[0] = priv->scan_min_time;
2977         param[1] = priv->scan_max_time;
2978         return 0;
2979 }
2980
2981 static int at76_iw_set_scan_mode(struct net_device *netdev,
2982                                  struct iw_request_info *info, char *name,
2983                                  char *extra)
2984 {
2985         struct at76_priv *priv = netdev_priv(netdev);
2986         int val = *((int *)name);
2987         int ret = -EIWCOMMIT;
2988
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>");
2992
2993         if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
2994                 ret = -EINVAL;
2995         else
2996                 priv->scan_mode = val;
2997
2998         return ret;
2999 }
3000
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)
3004 {
3005         struct at76_priv *priv = netdev_priv(netdev);
3006         int *param = (int *)extra;
3007
3008         param[0] = priv->scan_mode;
3009         return 0;
3010 }
3011
3012 #define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
3013
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)
3046 };
3047
3048 #define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
3049
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),
3062 };
3063
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"},
3069
3070         {AT76_GET_SHORT_PREAMBLE,
3071          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
3072
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"},
3077
3078         {AT76_GET_DEBUG,
3079          0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
3080
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"},
3084
3085         {AT76_GET_POWERSAVE_MODE,
3086          0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
3087
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"},
3091
3092         {AT76_GET_SCAN_TIMES,
3093          0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
3094
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"},
3098
3099         {AT76_GET_SCAN_MODE,
3100          0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
3101 };
3102
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,
3111 };
3112
3113 static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
3114
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 };
3118
3119 static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
3120 {
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;
3131
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;
3138         }
3139
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;
3146         }
3147
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;
3153         }
3154
3155         at76_ledtrig_tx_activity();     /* tell ledtrigger we send a packet */
3156
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 */
3159
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                         &