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