1 /*** -*- linux-c -*- **********************************************************
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
5 Copyright 2000-2001 ATMEL Corporation.
6 Copyright 2003-2004 Simon Kelley.
8 This code was developed from version 2.1.1 of the Atmel drivers,
9 released by Atmel corp. under the GPL in December 2002. It also
10 includes code from the Linux aironet drivers (C) Benjamin Reed,
11 and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
12 extensions, (C) Jean Tourrilhes.
14 The firmware module for reading the MAC address of the card comes from
15 net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright
16 by him. net.russotto.AtmelMACFW is used under the GPL license version 2.
17 This file contains the module in binary form and, under the terms
18 of the GPL, in source form. The source is located at the end of the file.
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
25 This software is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with Atmel wireless lan drivers; if not, see
32 <http://www.gnu.org/licenses/>.
34 For all queries about this code, please contact the current author,
35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
37 Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
38 hardware used during development of this driver.
40 ******************************************************************************/
42 #include <linux/interrupt.h>
44 #include <linux/kernel.h>
45 #include <linux/ptrace.h>
46 #include <linux/slab.h>
47 #include <linux/string.h>
48 #include <linux/timer.h>
49 #include <asm/byteorder.h>
51 #include <linux/uaccess.h>
52 #include <linux/module.h>
53 #include <linux/netdevice.h>
54 #include <linux/etherdevice.h>
55 #include <linux/skbuff.h>
56 #include <linux/if_arp.h>
57 #include <linux/ioport.h>
58 #include <linux/fcntl.h>
59 #include <linux/delay.h>
60 #include <linux/wireless.h>
61 #include <net/iw_handler.h>
62 #include <linux/crc32.h>
63 #include <linux/proc_fs.h>
64 #include <linux/seq_file.h>
65 #include <linux/device.h>
66 #include <linux/moduleparam.h>
67 #include <linux/firmware.h>
68 #include <linux/jiffies.h>
69 #include <net/cfg80211.h>
72 #define DRIVER_MAJOR 0
73 #define DRIVER_MINOR 98
75 MODULE_AUTHOR("Simon Kelley");
76 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
77 MODULE_LICENSE("GPL");
78 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
80 /* The name of the firmware file to be loaded
81 over-rides any automatic selection */
82 static char *firmware = NULL;
83 module_param(firmware, charp, 0);
85 /* table of firmware file names */
89 const char *fw_file_ext;
91 { ATMEL_FW_TYPE_502, "/*(DEBLOBBED)*/", "bin" },
92 { ATMEL_FW_TYPE_502D, "/*(DEBLOBBED)*/", "bin" },
93 { ATMEL_FW_TYPE_502E, "/*(DEBLOBBED)*/", "bin" },
94 { ATMEL_FW_TYPE_502_3COM, "/*(DEBLOBBED)*/", "bin" },
95 { ATMEL_FW_TYPE_504, "/*(DEBLOBBED)*/", "bin" },
96 { ATMEL_FW_TYPE_504_2958, "/*(DEBLOBBED)*/", "bin" },
97 { ATMEL_FW_TYPE_504A_2958, "/*(DEBLOBBED)*/", "bin" },
98 { ATMEL_FW_TYPE_506, "/*(DEBLOBBED)*/", "bin" },
99 { ATMEL_FW_TYPE_NONE, NULL, NULL }
103 #define MAX_SSID_LENGTH 32
104 #define MGMT_JIFFIES (256 * HZ / 100)
106 #define MAX_BSS_ENTRIES 64
109 #define GCR 0x00 /* (SIR0) General Configuration Register */
110 #define BSR 0x02 /* (SIR1) Bank Switching Select Register */
113 #define MR1 0x12 /* Mirror Register 1 */
114 #define MR2 0x14 /* Mirror Register 2 */
115 #define MR3 0x16 /* Mirror Register 3 */
116 #define MR4 0x18 /* Mirror Register 4 */
122 * Constants for the GCR register.
124 #define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */
125 #define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */
126 #define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */
127 #define GCR_ENINT 0x0002 /* Enable Interrupts */
128 #define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */
130 #define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */
131 #define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */
133 *Constants for the MR registers.
135 #define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */
136 #define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */
137 #define MAC_INIT_OK 0x0002 /* MAC boot has been completed */
139 #define MIB_MAX_DATA_BYTES 212
140 #define MIB_HEADER_SIZE 4 /* first four fields */
147 u8 data[MIB_MAX_DATA_BYTES];
165 #define RX_DESC_FLAG_VALID 0x80
166 #define RX_DESC_FLAG_CONSUMED 0x40
167 #define RX_DESC_FLAG_IDLE 0x00
169 #define RX_STATUS_SUCCESS 0x00
171 #define RX_DESC_MSDU_POS_OFFSET 4
172 #define RX_DESC_MSDU_SIZE_OFFSET 6
173 #define RX_DESC_FLAGS_OFFSET 8
174 #define RX_DESC_STATUS_OFFSET 9
175 #define RX_DESC_RSSI_OFFSET 11
176 #define RX_DESC_LINK_QUALITY_OFFSET 12
177 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
178 #define RX_DESC_DURATION_OFFSET 14
179 #define RX_DESC_RX_TIME_OFFSET 16
202 #define TX_DESC_NEXT_OFFSET 0
203 #define TX_DESC_POS_OFFSET 4
204 #define TX_DESC_SIZE_OFFSET 6
205 #define TX_DESC_FLAGS_OFFSET 8
206 #define TX_DESC_STATUS_OFFSET 9
207 #define TX_DESC_RETRY_OFFSET 10
208 #define TX_DESC_RATE_OFFSET 11
209 #define TX_DESC_KEY_INDEX_OFFSET 12
210 #define TX_DESC_CIPHER_TYPE_OFFSET 13
211 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
212 #define TX_DESC_PACKET_TYPE_OFFSET 17
213 #define TX_DESC_HOST_LENGTH_OFFSET 18
219 #define TX_STATUS_SUCCESS 0x00
221 #define TX_FIRM_OWN 0x80
224 #define TX_ERROR 0x01
226 #define TX_PACKET_TYPE_DATA 0x01
227 #define TX_PACKET_TYPE_MGMT 0x02
229 #define ISR_EMPTY 0x00 /* no bits set in ISR */
230 #define ISR_TxCOMPLETE 0x01 /* packet transmitted */
231 #define ISR_RxCOMPLETE 0x02 /* packet received */
232 #define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */
233 #define ISR_FATAL_ERROR 0x08 /* Fatal error */
234 #define ISR_COMMAND_COMPLETE 0x10 /* command completed */
235 #define ISR_OUT_OF_RANGE 0x20 /* command completed */
236 #define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */
237 #define ISR_GENERIC_IRQ 0x80
239 #define Local_Mib_Type 0x01
240 #define Mac_Address_Mib_Type 0x02
241 #define Mac_Mib_Type 0x03
242 #define Statistics_Mib_Type 0x04
243 #define Mac_Mgmt_Mib_Type 0x05
244 #define Mac_Wep_Mib_Type 0x06
245 #define Phy_Mib_Type 0x07
246 #define Multi_Domain_MIB 0x08
248 #define MAC_MGMT_MIB_CUR_BSSID_POS 14
249 #define MAC_MIB_FRAG_THRESHOLD_POS 8
250 #define MAC_MIB_RTS_THRESHOLD_POS 10
251 #define MAC_MIB_SHORT_RETRY_POS 16
252 #define MAC_MIB_LONG_RETRY_POS 17
253 #define MAC_MIB_SHORT_RETRY_LIMIT_POS 16
254 #define MAC_MGMT_MIB_BEACON_PER_POS 0
255 #define MAC_MGMT_MIB_STATION_ID_POS 6
256 #define MAC_MGMT_MIB_CUR_PRIVACY_POS 11
257 #define MAC_MGMT_MIB_CUR_BSSID_POS 14
258 #define MAC_MGMT_MIB_PS_MODE_POS 53
259 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS 54
260 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
261 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED 57
262 #define PHY_MIB_CHANNEL_POS 14
263 #define PHY_MIB_RATE_SET_POS 20
264 #define PHY_MIB_REG_DOMAIN_POS 26
265 #define LOCAL_MIB_AUTO_TX_RATE_POS 3
266 #define LOCAL_MIB_SSID_SIZE 5
267 #define LOCAL_MIB_TX_PROMISCUOUS_POS 6
268 #define LOCAL_MIB_TX_MGMT_RATE_POS 7
269 #define LOCAL_MIB_TX_CONTROL_RATE_POS 8
270 #define LOCAL_MIB_PREAMBLE_TYPE 9
271 #define MAC_ADDR_MIB_MAC_ADDR_POS 0
273 #define CMD_Set_MIB_Vars 0x01
274 #define CMD_Get_MIB_Vars 0x02
275 #define CMD_Scan 0x03
276 #define CMD_Join 0x04
277 #define CMD_Start 0x05
278 #define CMD_EnableRadio 0x06
279 #define CMD_DisableRadio 0x07
280 #define CMD_SiteSurvey 0x0B
282 #define CMD_STATUS_IDLE 0x00
283 #define CMD_STATUS_COMPLETE 0x01
284 #define CMD_STATUS_UNKNOWN 0x02
285 #define CMD_STATUS_INVALID_PARAMETER 0x03
286 #define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
287 #define CMD_STATUS_TIME_OUT 0x07
288 #define CMD_STATUS_IN_PROGRESS 0x08
289 #define CMD_STATUS_REJECTED_RADIO_OFF 0x09
290 #define CMD_STATUS_HOST_ERROR 0xFF
291 #define CMD_STATUS_BUSY 0xFE
293 #define CMD_BLOCK_COMMAND_OFFSET 0
294 #define CMD_BLOCK_STATUS_OFFSET 1
295 #define CMD_BLOCK_PARAMETERS_OFFSET 4
297 #define SCAN_OPTIONS_SITE_SURVEY 0x80
299 #define MGMT_FRAME_BODY_OFFSET 24
300 #define MAX_AUTHENTICATION_RETRIES 3
301 #define MAX_ASSOCIATION_RETRIES 3
303 #define AUTHENTICATION_RESPONSE_TIME_OUT 1000
305 #define MAX_WIRELESS_BODY 2316 /* mtu is 2312, CRC is 4 */
306 #define LOOP_RETRY_LIMIT 500000
308 #define ACTIVE_MODE 1
311 #define MAX_ENCRYPTION_KEYS 4
312 #define MAX_ENCRYPTION_KEY_SIZE 40
315 * 802.11 related definitions
322 #define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */
323 #define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */
324 #define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */
325 #define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */
326 #define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */
327 #define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
328 #define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */
329 #define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */
331 #define BSS_TYPE_AD_HOC 1
332 #define BSS_TYPE_INFRASTRUCTURE 2
334 #define SCAN_TYPE_ACTIVE 0
335 #define SCAN_TYPE_PASSIVE 1
337 #define LONG_PREAMBLE 0
338 #define SHORT_PREAMBLE 1
339 #define AUTO_PREAMBLE 2
341 #define DATA_FRAME_WS_HEADER_SIZE 30
343 /* promiscuous mode control */
344 #define PROM_MODE_OFF 0x0
345 #define PROM_MODE_UNKNOWN 0x1
346 #define PROM_MODE_CRC_FAILED 0x2
347 #define PROM_MODE_DUPLICATED 0x4
348 #define PROM_MODE_MGMT 0x8
349 #define PROM_MODE_CTRL 0x10
350 #define PROM_MODE_BAD_PROTOCOL 0x20
352 #define IFACE_INT_STATUS_OFFSET 0
353 #define IFACE_INT_MASK_OFFSET 1
354 #define IFACE_LOCKOUT_HOST_OFFSET 2
355 #define IFACE_LOCKOUT_MAC_OFFSET 3
356 #define IFACE_FUNC_CTRL_OFFSET 28
357 #define IFACE_MAC_STAT_OFFSET 30
358 #define IFACE_GENERIC_INT_TYPE_OFFSET 32
360 #define CIPHER_SUITE_NONE 0
361 #define CIPHER_SUITE_WEP_64 1
362 #define CIPHER_SUITE_TKIP 2
363 #define CIPHER_SUITE_AES 3
364 #define CIPHER_SUITE_CCX 4
365 #define CIPHER_SUITE_WEP_128 5
368 * IFACE MACROS & definitions
374 #define FUNC_CTRL_TxENABLE 0x10
375 #define FUNC_CTRL_RxENABLE 0x20
376 #define FUNC_CTRL_INIT_COMPLETE 0x01
378 /* A stub firmware image which reads the MAC address from NVRAM on the card.
379 For copyright information and source see the end of this file. */
380 static u8 mac_reader[] = {
381 0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
382 0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
383 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
384 0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
385 0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
386 0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
387 0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
388 0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
389 0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
390 0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
391 0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
392 0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
393 0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
394 0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
395 0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
396 0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
397 0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
398 0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
399 0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
400 0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
401 0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
402 0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
403 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
404 0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
405 0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
406 0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
407 0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
408 0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
409 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
410 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
411 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
412 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
413 0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
414 0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
415 0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
416 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
417 0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
418 0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
419 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
420 0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
421 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
422 0x00, 0x01, 0x00, 0x02
425 struct atmel_private {
426 void *card; /* Bus dependent structure varies for PCcard */
427 int (*present_callback)(void *); /* And callback which uses it */
428 char firmware_id[32];
429 AtmelFWType firmware_type;
432 struct timer_list management_timer;
433 struct net_device *dev;
434 struct device *sys_dev;
435 struct iw_statistics wstats;
436 spinlock_t irqlock, timerlock; /* spinlocks */
437 enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
439 CARD_TYPE_PARALLEL_FLASH,
443 int do_rx_crc; /* If we need to CRC incoming packets */
444 int probe_crc; /* set if we don't yet know */
445 int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
447 u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
448 u16 tx_free_mem, tx_buff_head, tx_buff_tail;
450 u16 frag_seq, frag_len, frag_no;
453 u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
454 u8 group_cipher_suite, pairwise_cipher_suite;
455 u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
456 int wep_key_len[MAX_ENCRYPTION_KEYS];
457 int use_wpa, radio_on_broken; /* firmware dependent stuff. */
460 struct host_info_struct {
461 /* NB this is matched to the hardware, don't change. */
462 u8 volatile int_status;
463 u8 volatile int_mask;
464 u8 volatile lockout_host;
465 u8 volatile lockout_mac;
485 u16 generic_IRQ_type;
490 STATION_STATE_SCANNING,
491 STATION_STATE_JOINNING,
492 STATION_STATE_AUTHENTICATING,
493 STATION_STATE_ASSOCIATING,
495 STATION_STATE_REASSOCIATING,
497 STATION_STATE_MGMT_ERROR
500 int operating_mode, power_mode;
501 unsigned long last_qual;
502 int beacons_this_sec;
504 int reg_domain, config_reg_domain;
509 int long_retry, short_retry;
511 int default_beacon_period, beacon_period, listen_interval;
512 int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
513 int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
516 SITE_SURVEY_IN_PROGRESS,
517 SITE_SURVEY_COMPLETED
519 unsigned long last_survey;
521 int station_was_associated, station_is_associated;
533 u8 SSID[MAX_SSID_LENGTH];
534 } BSSinfo[MAX_BSS_ENTRIES];
535 int BSS_list_entries, current_BSS;
536 int connect_to_any_BSS;
537 int SSID_size, new_SSID_size;
538 u8 CurrentBSSID[6], BSSID[6];
539 u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
540 u64 last_beacon_timestamp;
541 u8 rx_buf[MAX_WIRELESS_BODY];
544 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
546 static const struct {
550 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
551 { REG_DOMAIN_DOC, 1, 11, "Canada" },
552 { REG_DOMAIN_ETSI, 1, 13, "Europe" },
553 { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
554 { REG_DOMAIN_FRANCE, 10, 13, "France" },
555 { REG_DOMAIN_MKK, 14, 14, "MKK" },
556 { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
557 { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
559 static void build_wpa_mib(struct atmel_private *priv);
560 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
561 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
562 const unsigned char *src, u16 len);
563 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
565 static void atmel_set_gcr(struct net_device *dev, u16 mask);
566 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
567 static int atmel_lock_mac(struct atmel_private *priv);
568 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
569 static void atmel_command_irq(struct atmel_private *priv);
570 static int atmel_validate_channel(struct atmel_private *priv, int channel);
571 static void atmel_management_frame(struct atmel_private *priv,
572 struct ieee80211_hdr *header,
573 u16 frame_len, u8 rssi);
574 static void atmel_management_timer(struct timer_list *t);
575 static void atmel_send_command(struct atmel_private *priv, int command,
576 void *cmd, int cmd_size);
577 static int atmel_send_command_wait(struct atmel_private *priv, int command,
578 void *cmd, int cmd_size);
579 static void atmel_transmit_management_frame(struct atmel_private *priv,
580 struct ieee80211_hdr *header,
581 u8 *body, int body_len);
583 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
584 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
586 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
588 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
589 u8 *data, int data_len);
590 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
591 u8 *data, int data_len);
592 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
593 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
594 static void atmel_smooth_qual(struct atmel_private *priv);
595 static void atmel_writeAR(struct net_device *dev, u16 data);
596 static int probe_atmel_card(struct net_device *dev);
597 static int reset_atmel_card(struct net_device *dev);
598 static void atmel_enter_state(struct atmel_private *priv, int new_state);
599 int atmel_open (struct net_device *dev);
601 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
603 return priv->host_info_base + offset;
606 static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
608 return priv->host_info.command_pos + offset;
611 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
613 return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
616 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
618 return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
621 static inline u8 atmel_read8(struct net_device *dev, u16 offset)
623 return inb(dev->base_addr + offset);
626 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
628 outb(data, dev->base_addr + offset);
631 static inline u16 atmel_read16(struct net_device *dev, u16 offset)
633 return inw(dev->base_addr + offset);
636 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
638 outw(data, dev->base_addr + offset);
641 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
643 atmel_writeAR(priv->dev, pos);
644 return atmel_read8(priv->dev, DR);
647 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
649 atmel_writeAR(priv->dev, pos);
650 atmel_write8(priv->dev, DR, data);
653 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
655 atmel_writeAR(priv->dev, pos);
656 return atmel_read16(priv->dev, DR);
659 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
661 atmel_writeAR(priv->dev, pos);
662 atmel_write16(priv->dev, DR, data);
665 static const struct iw_handler_def atmel_handler_def;
667 static void tx_done_irq(struct atmel_private *priv)
672 atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
673 i < priv->host_info.tx_desc_count;
675 u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
676 u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
677 u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
679 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
681 priv->tx_free_mem += msdu_size;
682 priv->tx_desc_free++;
684 if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
685 priv->tx_buff_head = 0;
687 priv->tx_buff_head += msdu_size;
689 if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
690 priv->tx_desc_head++ ;
692 priv->tx_desc_head = 0;
694 if (type == TX_PACKET_TYPE_DATA) {
695 if (status == TX_STATUS_SUCCESS)
696 priv->dev->stats.tx_packets++;
698 priv->dev->stats.tx_errors++;
699 netif_wake_queue(priv->dev);
704 static u16 find_tx_buff(struct atmel_private *priv, u16 len)
706 u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
708 if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
711 if (bottom_free >= len)
712 return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
714 if (priv->tx_free_mem - bottom_free >= len) {
715 priv->tx_buff_tail = 0;
716 return priv->host_info.tx_buff_pos;
722 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
723 u16 len, u16 buff, u8 type)
725 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
726 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
728 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
729 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
730 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
731 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
733 int cipher_type, cipher_length;
735 cipher_type = priv->group_cipher_suite;
736 if (cipher_type == CIPHER_SUITE_WEP_64 ||
737 cipher_type == CIPHER_SUITE_WEP_128)
739 else if (cipher_type == CIPHER_SUITE_TKIP)
741 else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
742 priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
743 cipher_type = priv->pairwise_cipher_suite;
746 cipher_type = CIPHER_SUITE_NONE;
750 cipher_type = priv->pairwise_cipher_suite;
751 if (cipher_type == CIPHER_SUITE_WEP_64 ||
752 cipher_type == CIPHER_SUITE_WEP_128)
754 else if (cipher_type == CIPHER_SUITE_TKIP)
756 else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
757 priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
758 cipher_type = priv->group_cipher_suite;
761 cipher_type = CIPHER_SUITE_NONE;
766 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
768 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
771 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
772 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
773 if (priv->tx_desc_previous != priv->tx_desc_tail)
774 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
775 priv->tx_desc_previous = priv->tx_desc_tail;
776 if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
777 priv->tx_desc_tail++;
779 priv->tx_desc_tail = 0;
780 priv->tx_desc_free--;
781 priv->tx_free_mem -= len;
784 static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
786 static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
787 struct atmel_private *priv = netdev_priv(dev);
788 struct ieee80211_hdr header;
790 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
792 if (priv->card && priv->present_callback &&
793 !(*priv->present_callback)(priv->card)) {
794 dev->stats.tx_errors++;
799 if (priv->station_state != STATION_STATE_READY) {
800 dev->stats.tx_errors++;
805 /* first ensure the timer func cannot run */
806 spin_lock_bh(&priv->timerlock);
807 /* then stop the hardware ISR */
808 spin_lock_irqsave(&priv->irqlock, flags);
809 /* nb doing the above in the opposite order will deadlock */
811 /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
812 12 first bytes (containing DA/SA) and put them in the appropriate
813 fields of the Wireless Header. Thus the packet length is then the
814 initial + 18 (+30-12) */
816 if (!(buff = find_tx_buff(priv, len + 18))) {
817 dev->stats.tx_dropped++;
818 spin_unlock_irqrestore(&priv->irqlock, flags);
819 spin_unlock_bh(&priv->timerlock);
820 netif_stop_queue(dev);
821 return NETDEV_TX_BUSY;
824 frame_ctl = IEEE80211_FTYPE_DATA;
825 header.duration_id = 0;
828 frame_ctl |= IEEE80211_FCTL_PROTECTED;
829 if (priv->operating_mode == IW_MODE_ADHOC) {
830 skb_copy_from_linear_data(skb, &header.addr1, ETH_ALEN);
831 memcpy(&header.addr2, dev->dev_addr, ETH_ALEN);
832 memcpy(&header.addr3, priv->BSSID, ETH_ALEN);
834 frame_ctl |= IEEE80211_FCTL_TODS;
835 memcpy(&header.addr1, priv->CurrentBSSID, ETH_ALEN);
836 memcpy(&header.addr2, dev->dev_addr, ETH_ALEN);
837 skb_copy_from_linear_data(skb, &header.addr3, ETH_ALEN);
841 memcpy(&header.addr4, SNAP_RFC1024, ETH_ALEN);
843 header.frame_control = cpu_to_le16(frame_ctl);
844 /* Copy the wireless header into the card */
845 atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
846 /* Copy the packet sans its 802.3 header addresses which have been replaced */
847 atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
848 priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
850 /* low bit of first byte of destination tells us if broadcast */
851 tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
852 dev->stats.tx_bytes += len;
854 spin_unlock_irqrestore(&priv->irqlock, flags);
855 spin_unlock_bh(&priv->timerlock);
861 static void atmel_transmit_management_frame(struct atmel_private *priv,
862 struct ieee80211_hdr *header,
863 u8 *body, int body_len)
866 int len = MGMT_FRAME_BODY_OFFSET + body_len;
868 if (!(buff = find_tx_buff(priv, len)))
871 atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
872 atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
873 priv->tx_buff_tail += len;
874 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
877 static void fast_rx_path(struct atmel_private *priv,
878 struct ieee80211_hdr *header,
879 u16 msdu_size, u16 rx_packet_loc, u32 crc)
881 /* fast path: unfragmented packet copy directly into skbuf */
886 /* get the final, mac 4 header field, this tells us encapsulation */
887 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
890 if (priv->do_rx_crc) {
891 crc = crc32_le(crc, mac4, 6);
895 if (!(skb = dev_alloc_skb(msdu_size + 14))) {
896 priv->dev->stats.rx_dropped++;
901 skbp = skb_put(skb, msdu_size + 12);
902 atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
904 if (priv->do_rx_crc) {
906 crc = crc32_le(crc, skbp + 12, msdu_size);
907 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
908 if ((crc ^ 0xffffffff) != netcrc) {
909 priv->dev->stats.rx_crc_errors++;
915 memcpy(skbp, header->addr1, ETH_ALEN); /* destination address */
916 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
917 memcpy(&skbp[ETH_ALEN], header->addr3, ETH_ALEN);
919 memcpy(&skbp[ETH_ALEN], header->addr2, ETH_ALEN); /* source address */
921 skb->protocol = eth_type_trans(skb, priv->dev);
922 skb->ip_summed = CHECKSUM_NONE;
924 priv->dev->stats.rx_bytes += 12 + msdu_size;
925 priv->dev->stats.rx_packets++;
928 /* Test to see if the packet in card memory at packet_loc has a valid CRC
929 It doesn't matter that this is slow: it is only used to proble the first few
931 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
933 int i = msdu_size - 4;
934 u32 netcrc, crc = 0xffffffff;
939 atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
941 atmel_writeAR(priv->dev, packet_loc);
943 u8 octet = atmel_read8(priv->dev, DR);
944 crc = crc32_le(crc, &octet, 1);
947 return (crc ^ 0xffffffff) == netcrc;
950 static void frag_rx_path(struct atmel_private *priv,
951 struct ieee80211_hdr *header,
952 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
953 u8 frag_no, int more_frags)
959 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
960 memcpy(source, header->addr3, ETH_ALEN);
962 memcpy(source, header->addr2, ETH_ALEN);
964 rx_packet_loc += 24; /* skip header */
969 if (frag_no == 0) { /* first fragment */
970 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, ETH_ALEN);
971 msdu_size -= ETH_ALEN;
972 rx_packet_loc += ETH_ALEN;
975 crc = crc32_le(crc, mac4, 6);
977 priv->frag_seq = seq_no;
979 priv->frag_len = msdu_size;
980 memcpy(priv->frag_source, source, ETH_ALEN);
981 memcpy(&priv->rx_buf[ETH_ALEN], source, ETH_ALEN);
982 memcpy(priv->rx_buf, header->addr1, ETH_ALEN);
984 atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
986 if (priv->do_rx_crc) {
988 crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
989 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
990 if ((crc ^ 0xffffffff) != netcrc) {
991 priv->dev->stats.rx_crc_errors++;
992 eth_broadcast_addr(priv->frag_source);
996 } else if (priv->frag_no == frag_no &&
997 priv->frag_seq == seq_no &&
998 memcmp(priv->frag_source, source, ETH_ALEN) == 0) {
1000 atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1001 rx_packet_loc, msdu_size);
1002 if (priv->do_rx_crc) {
1005 &priv->rx_buf[12 + priv->frag_len],
1007 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1008 if ((crc ^ 0xffffffff) != netcrc) {
1009 priv->dev->stats.rx_crc_errors++;
1010 eth_broadcast_addr(priv->frag_source);
1011 more_frags = 1; /* don't send broken assembly */
1015 priv->frag_len += msdu_size;
1018 if (!more_frags) { /* last one */
1019 eth_broadcast_addr(priv->frag_source);
1020 if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1021 priv->dev->stats.rx_dropped++;
1023 skb_reserve(skb, 2);
1024 skb_put_data(skb, priv->rx_buf,
1025 priv->frag_len + 12);
1026 skb->protocol = eth_type_trans(skb, priv->dev);
1027 skb->ip_summed = CHECKSUM_NONE;
1029 priv->dev->stats.rx_bytes += priv->frag_len + 12;
1030 priv->dev->stats.rx_packets++;
1034 priv->wstats.discard.fragment++;
1037 static void rx_done_irq(struct atmel_private *priv)
1040 struct ieee80211_hdr header;
1043 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1044 i < priv->host_info.rx_desc_count;
1047 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1048 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1049 u32 crc = 0xffffffff;
1051 if (status != RX_STATUS_SUCCESS) {
1052 if (status == 0xc1) /* determined by experiment */
1053 priv->wstats.discard.nwid++;
1055 priv->dev->stats.rx_errors++;
1059 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1060 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1062 if (msdu_size < 30) {
1063 priv->dev->stats.rx_errors++;
1067 /* Get header as far as end of seq_ctrl */
1068 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1069 frame_ctl = le16_to_cpu(header.frame_control);
1070 seq_control = le16_to_cpu(header.seq_ctrl);
1072 /* probe for CRC use here if needed once five packets have
1073 arrived with the same crc status, we assume we know what's
1074 happening and stop probing */
1075 if (priv->probe_crc) {
1076 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1077 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1079 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1081 if (priv->do_rx_crc) {
1082 if (priv->crc_ok_cnt++ > 5)
1083 priv->probe_crc = 0;
1085 if (priv->crc_ko_cnt++ > 5)
1086 priv->probe_crc = 0;
1090 /* don't CRC header when WEP in use */
1091 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1092 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1094 msdu_size -= 24; /* header */
1096 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1097 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1098 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1099 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1101 if (!more_fragments && packet_fragment_no == 0) {
1102 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1104 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1105 packet_sequence_no, packet_fragment_no, more_fragments);
1109 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1110 /* copy rest of packet into buffer */
1111 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1113 /* we use the same buffer for frag reassembly and control packets */
1114 eth_broadcast_addr(priv->frag_source);
1116 if (priv->do_rx_crc) {
1117 /* last 4 octets is crc */
1119 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1120 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1121 priv->dev->stats.rx_crc_errors++;
1126 atmel_management_frame(priv, &header, msdu_size,
1127 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1131 /* release descriptor */
1132 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1134 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1135 priv->rx_desc_head++;
1137 priv->rx_desc_head = 0;
1141 static irqreturn_t service_interrupt(int irq, void *dev_id)
1143 struct net_device *dev = (struct net_device *) dev_id;
1144 struct atmel_private *priv = netdev_priv(dev);
1147 static const u8 irq_order[] = {
1153 ISR_COMMAND_COMPLETE,
1158 if (priv->card && priv->present_callback &&
1159 !(*priv->present_callback)(priv->card))
1162 /* In this state upper-level code assumes it can mess with
1163 the card unhampered by interrupts which may change register state.
1164 Note that even though the card shouldn't generate interrupts
1165 the inturrupt line may be shared. This allows card setup
1166 to go on without disabling interrupts for a long time. */
1167 if (priv->station_state == STATION_STATE_DOWN)
1170 atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1173 if (!atmel_lock_mac(priv)) {
1174 /* failed to contact card */
1175 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1179 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1180 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1183 atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1184 return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1187 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1189 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1190 if (isr & irq_order[i])
1193 if (!atmel_lock_mac(priv)) {
1194 /* failed to contact card */
1195 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1199 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1200 isr ^= irq_order[i];
1201 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1202 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1204 switch (irq_order[i]) {
1206 case ISR_OUT_OF_RANGE:
1207 if (priv->operating_mode == IW_MODE_INFRA &&
1208 priv->station_state == STATION_STATE_READY) {
1209 priv->station_is_associated = 0;
1210 atmel_scan(priv, 1);
1214 case ISR_RxFRAMELOST:
1215 priv->wstats.discard.misc++;
1217 case ISR_RxCOMPLETE:
1221 case ISR_TxCOMPLETE:
1225 case ISR_FATAL_ERROR:
1226 printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1227 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1230 case ISR_COMMAND_COMPLETE:
1231 atmel_command_irq(priv);
1234 case ISR_IBSS_MERGE:
1235 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1236 priv->CurrentBSSID, 6);
1237 /* The WPA stuff cares about the current AP address */
1239 build_wpa_mib(priv);
1241 case ISR_GENERIC_IRQ:
1242 printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1248 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1250 struct atmel_private *priv = netdev_priv(dev);
1252 /* update the link quality here in case we are seeing no beacons
1253 at all to drive the process */
1254 atmel_smooth_qual(priv);
1256 priv->wstats.status = priv->station_state;
1258 if (priv->operating_mode == IW_MODE_INFRA) {
1259 if (priv->station_state != STATION_STATE_READY) {
1260 priv->wstats.qual.qual = 0;
1261 priv->wstats.qual.level = 0;
1262 priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1263 | IW_QUAL_LEVEL_INVALID);
1265 priv->wstats.qual.noise = 0;
1266 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1268 /* Quality levels cannot be determined in ad-hoc mode,
1269 because we can 'hear' more that one remote station. */
1270 priv->wstats.qual.qual = 0;
1271 priv->wstats.qual.level = 0;
1272 priv->wstats.qual.noise = 0;
1273 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1274 | IW_QUAL_LEVEL_INVALID
1275 | IW_QUAL_NOISE_INVALID;
1276 priv->wstats.miss.beacon = 0;
1279 return &priv->wstats;
1282 static int atmel_set_mac_address(struct net_device *dev, void *p)
1284 struct sockaddr *addr = p;
1286 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1287 return atmel_open(dev);
1290 EXPORT_SYMBOL(atmel_open);
1292 int atmel_open(struct net_device *dev)
1294 struct atmel_private *priv = netdev_priv(dev);
1295 int i, channel, err;
1297 /* any scheduled timer is no longer needed and might screw things up.. */
1298 del_timer_sync(&priv->management_timer);
1300 /* Interrupts will not touch the card once in this state... */
1301 priv->station_state = STATION_STATE_DOWN;
1303 if (priv->new_SSID_size) {
1304 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1305 priv->SSID_size = priv->new_SSID_size;
1306 priv->new_SSID_size = 0;
1308 priv->BSS_list_entries = 0;
1310 priv->AuthenticationRequestRetryCnt = 0;
1311 priv->AssociationRequestRetryCnt = 0;
1312 priv->ReAssociationRequestRetryCnt = 0;
1313 priv->CurrentAuthentTransactionSeqNum = 0x0001;
1314 priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1316 priv->site_survey_state = SITE_SURVEY_IDLE;
1317 priv->station_is_associated = 0;
1319 err = reset_atmel_card(dev);
1323 if (priv->config_reg_domain) {
1324 priv->reg_domain = priv->config_reg_domain;
1325 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1327 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1328 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1329 if (priv->reg_domain == channel_table[i].reg_domain)
1331 if (i == ARRAY_SIZE(channel_table)) {
1332 priv->reg_domain = REG_DOMAIN_MKK1;
1333 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1337 if ((channel = atmel_validate_channel(priv, priv->channel)))
1338 priv->channel = channel;
1340 /* this moves station_state on.... */
1341 atmel_scan(priv, 1);
1343 atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1347 static int atmel_close(struct net_device *dev)
1349 struct atmel_private *priv = netdev_priv(dev);
1351 /* Send event to userspace that we are disassociating */
1352 if (priv->station_state == STATION_STATE_READY) {
1353 union iwreq_data wrqu;
1355 wrqu.data.length = 0;
1356 wrqu.data.flags = 0;
1357 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1358 eth_zero_addr(wrqu.ap_addr.sa_data);
1359 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1362 atmel_enter_state(priv, STATION_STATE_DOWN);
1364 if (priv->bus_type == BUS_TYPE_PCCARD)
1365 atmel_write16(dev, GCR, 0x0060);
1366 atmel_write16(dev, GCR, 0x0040);
1370 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1372 /* check that channel is OK, if so return zero,
1373 else return suitable default channel */
1376 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1377 if (priv->reg_domain == channel_table[i].reg_domain) {
1378 if (channel >= channel_table[i].min &&
1379 channel <= channel_table[i].max)
1382 return channel_table[i].min;
1387 #ifdef CONFIG_PROC_FS
1388 static int atmel_proc_show(struct seq_file *m, void *v)
1390 struct atmel_private *priv = m->private;
1394 seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1396 if (priv->station_state != STATION_STATE_DOWN) {
1398 "Firmware version:\t%d.%d build %d\n"
1399 "Firmware location:\t",
1400 priv->host_info.major_version,
1401 priv->host_info.minor_version,
1402 priv->host_info.build_version);
1404 if (priv->card_type != CARD_TYPE_EEPROM)
1405 seq_puts(m, "on card\n");
1406 else if (priv->firmware)
1407 seq_printf(m, "%s loaded by host\n", priv->firmware_id);
1409 seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
1411 switch (priv->card_type) {
1412 case CARD_TYPE_PARALLEL_FLASH:
1413 c = "Parallel flash";
1415 case CARD_TYPE_SPI_FLASH:
1418 case CARD_TYPE_EEPROM:
1426 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1427 if (priv->reg_domain == channel_table[i].reg_domain)
1428 r = channel_table[i].name;
1430 seq_printf(m, "MAC memory type:\t%s\n", c);
1431 seq_printf(m, "Regulatory domain:\t%s\n", r);
1432 seq_printf(m, "Host CRC checking:\t%s\n",
1433 priv->do_rx_crc ? "On" : "Off");
1434 seq_printf(m, "WPA-capable firmware:\t%s\n",
1435 priv->use_wpa ? "Yes" : "No");
1438 switch (priv->station_state) {
1439 case STATION_STATE_SCANNING:
1442 case STATION_STATE_JOINNING:
1445 case STATION_STATE_AUTHENTICATING:
1446 s = "Authenticating";
1448 case STATION_STATE_ASSOCIATING:
1451 case STATION_STATE_READY:
1454 case STATION_STATE_REASSOCIATING:
1455 s = "Reassociating";
1457 case STATION_STATE_MGMT_ERROR:
1458 s = "Management error";
1460 case STATION_STATE_DOWN:
1467 seq_printf(m, "Current state:\t\t%s\n", s);
1472 static const struct net_device_ops atmel_netdev_ops = {
1473 .ndo_open = atmel_open,
1474 .ndo_stop = atmel_close,
1475 .ndo_set_mac_address = atmel_set_mac_address,
1476 .ndo_start_xmit = start_tx,
1477 .ndo_do_ioctl = atmel_ioctl,
1478 .ndo_validate_addr = eth_validate_addr,
1481 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1482 const AtmelFWType fw_type,
1483 struct device *sys_dev,
1484 int (*card_present)(void *), void *card)
1486 struct net_device *dev;
1487 struct atmel_private *priv;
1490 /* Create the network device object. */
1491 dev = alloc_etherdev(sizeof(*priv));
1495 if (dev_alloc_name(dev, dev->name) < 0) {
1496 printk(KERN_ERR "atmel: Couldn't get name!\n");
1500 priv = netdev_priv(dev);
1502 priv->sys_dev = sys_dev;
1503 priv->present_callback = card_present;
1505 priv->firmware = NULL;
1506 priv->firmware_type = fw_type;
1507 if (firmware) /* module parameter */
1508 strlcpy(priv->firmware_id, firmware, sizeof(priv->firmware_id));
1509 priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1510 priv->station_state = STATION_STATE_DOWN;
1511 priv->do_rx_crc = 0;
1512 /* For PCMCIA cards, some chips need CRC, some don't
1513 so we have to probe. */
1514 if (priv->bus_type == BUS_TYPE_PCCARD) {
1515 priv->probe_crc = 1;
1516 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1518 priv->probe_crc = 0;
1519 priv->last_qual = jiffies;
1520 priv->last_beacon_timestamp = 0;
1521 memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1522 eth_zero_addr(priv->BSSID);
1523 priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1524 priv->station_was_associated = 0;
1526 priv->last_survey = jiffies;
1527 priv->preamble = LONG_PREAMBLE;
1528 priv->operating_mode = IW_MODE_INFRA;
1529 priv->connect_to_any_BSS = 0;
1530 priv->config_reg_domain = 0;
1531 priv->reg_domain = 0;
1533 priv->auto_tx_rate = 1;
1535 priv->power_mode = 0;
1536 priv->SSID[0] = '\0';
1537 priv->SSID_size = 0;
1538 priv->new_SSID_size = 0;
1539 priv->frag_threshold = 2346;
1540 priv->rts_threshold = 2347;
1541 priv->short_retry = 7;
1542 priv->long_retry = 4;
1544 priv->wep_is_on = 0;
1545 priv->default_key = 0;
1546 priv->encryption_level = 0;
1547 priv->exclude_unencrypted = 0;
1548 priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1550 memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1551 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1553 priv->default_beacon_period = priv->beacon_period = 100;
1554 priv->listen_interval = 1;
1556 timer_setup(&priv->management_timer, atmel_management_timer, 0);
1557 spin_lock_init(&priv->irqlock);
1558 spin_lock_init(&priv->timerlock);
1560 dev->netdev_ops = &atmel_netdev_ops;
1561 dev->wireless_handlers = &atmel_handler_def;
1563 dev->base_addr = port;
1565 /* MTU range: 68 - 2312 */
1567 dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
1569 SET_NETDEV_DEV(dev, sys_dev);
1571 if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1572 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1576 if (!request_region(dev->base_addr, 32,
1577 priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) {
1581 if (register_netdev(dev))
1584 if (!probe_atmel_card(dev)) {
1585 unregister_netdev(dev);
1589 netif_carrier_off(dev);
1591 if (!proc_create_single_data("driver/atmel", 0, NULL, atmel_proc_show,
1593 printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1595 printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1596 dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1601 release_region(dev->base_addr, 32);
1603 free_irq(dev->irq, dev);
1609 EXPORT_SYMBOL(init_atmel_card);
1611 void stop_atmel_card(struct net_device *dev)
1613 struct atmel_private *priv = netdev_priv(dev);
1615 /* put a brick on it... */
1616 if (priv->bus_type == BUS_TYPE_PCCARD)
1617 atmel_write16(dev, GCR, 0x0060);
1618 atmel_write16(dev, GCR, 0x0040);
1620 del_timer_sync(&priv->management_timer);
1621 unregister_netdev(dev);
1622 remove_proc_entry("driver/atmel", NULL);
1623 free_irq(dev->irq, dev);
1624 kfree(priv->firmware);
1625 release_region(dev->base_addr, 32);
1629 EXPORT_SYMBOL(stop_atmel_card);
1631 static int atmel_set_essid(struct net_device *dev,
1632 struct iw_request_info *info,
1633 struct iw_point *dwrq,
1636 struct atmel_private *priv = netdev_priv(dev);
1638 /* Check if we asked for `any' */
1639 if (dwrq->flags == 0) {
1640 priv->connect_to_any_BSS = 1;
1642 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1644 priv->connect_to_any_BSS = 0;
1646 /* Check the size of the string */
1647 if (dwrq->length > MAX_SSID_LENGTH)
1652 memcpy(priv->new_SSID, extra, dwrq->length);
1653 priv->new_SSID_size = dwrq->length;
1656 return -EINPROGRESS;
1659 static int atmel_get_essid(struct net_device *dev,
1660 struct iw_request_info *info,
1661 struct iw_point *dwrq,
1664 struct atmel_private *priv = netdev_priv(dev);
1666 /* Get the current SSID */
1667 if (priv->new_SSID_size != 0) {
1668 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1669 dwrq->length = priv->new_SSID_size;
1671 memcpy(extra, priv->SSID, priv->SSID_size);
1672 dwrq->length = priv->SSID_size;
1675 dwrq->flags = !priv->connect_to_any_BSS; /* active */
1680 static int atmel_get_wap(struct net_device *dev,
1681 struct iw_request_info *info,
1682 struct sockaddr *awrq,
1685 struct atmel_private *priv = netdev_priv(dev);
1686 memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1687 awrq->sa_family = ARPHRD_ETHER;
1692 static int atmel_set_encode(struct net_device *dev,
1693 struct iw_request_info *info,
1694 struct iw_point *dwrq,
1697 struct atmel_private *priv = netdev_priv(dev);
1699 /* Basic checking: do we have a key to set ?
1700 * Note : with the new API, it's impossible to get a NULL pointer.
1701 * Therefore, we need to check a key size == 0 instead.
1702 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1703 * when no key is present (only change flags), but older versions
1704 * don't do it. - Jean II */
1705 if (dwrq->length > 0) {
1706 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1707 int current_index = priv->default_key;
1708 /* Check the size of the key */
1709 if (dwrq->length > 13) {
1712 /* Check the index (none -> use current) */
1713 if (index < 0 || index >= 4)
1714 index = current_index;
1716 priv->default_key = index;
1717 /* Set the length */
1718 if (dwrq->length > 5)
1719 priv->wep_key_len[index] = 13;
1721 if (dwrq->length > 0)
1722 priv->wep_key_len[index] = 5;
1724 /* Disable the key */
1725 priv->wep_key_len[index] = 0;
1726 /* Check if the key is not marked as invalid */
1727 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1729 memset(priv->wep_keys[index], 0, 13);
1730 /* Copy the key in the driver */
1731 memcpy(priv->wep_keys[index], extra, dwrq->length);
1733 /* WE specify that if a valid key is set, encryption
1734 * should be enabled (user may turn it off later)
1735 * This is also how "iwconfig ethX key on" works */
1736 if (index == current_index &&
1737 priv->wep_key_len[index] > 0) {
1738 priv->wep_is_on = 1;
1739 priv->exclude_unencrypted = 1;
1740 if (priv->wep_key_len[index] > 5) {
1741 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1742 priv->encryption_level = 2;
1744 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1745 priv->encryption_level = 1;
1749 /* Do we want to just set the transmit key index ? */
1750 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1751 if (index >= 0 && index < 4) {
1752 priv->default_key = index;
1754 /* Don't complain if only change the mode */
1755 if (!(dwrq->flags & IW_ENCODE_MODE))
1758 /* Read the flags */
1759 if (dwrq->flags & IW_ENCODE_DISABLED) {
1760 priv->wep_is_on = 0;
1761 priv->encryption_level = 0;
1762 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1764 priv->wep_is_on = 1;
1765 if (priv->wep_key_len[priv->default_key] > 5) {
1766 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1767 priv->encryption_level = 2;
1769 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1770 priv->encryption_level = 1;
1773 if (dwrq->flags & IW_ENCODE_RESTRICTED)
1774 priv->exclude_unencrypted = 1;
1775 if (dwrq->flags & IW_ENCODE_OPEN)
1776 priv->exclude_unencrypted = 0;
1778 return -EINPROGRESS; /* Call commit handler */
1781 static int atmel_get_encode(struct net_device *dev,
1782 struct iw_request_info *info,
1783 struct iw_point *dwrq,
1786 struct atmel_private *priv = netdev_priv(dev);
1787 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1789 if (!priv->wep_is_on)
1790 dwrq->flags = IW_ENCODE_DISABLED;
1792 if (priv->exclude_unencrypted)
1793 dwrq->flags = IW_ENCODE_RESTRICTED;
1795 dwrq->flags = IW_ENCODE_OPEN;
1797 /* Which key do we want ? -1 -> tx index */
1798 if (index < 0 || index >= 4)
1799 index = priv->default_key;
1800 dwrq->flags |= index + 1;
1801 /* Copy the key to the user buffer */
1802 dwrq->length = priv->wep_key_len[index];
1803 if (dwrq->length > 16) {
1806 memset(extra, 0, 16);
1807 memcpy(extra, priv->wep_keys[index], dwrq->length);
1813 static int atmel_set_encodeext(struct net_device *dev,
1814 struct iw_request_info *info,
1815 union iwreq_data *wrqu,
1818 struct atmel_private *priv = netdev_priv(dev);
1819 struct iw_point *encoding = &wrqu->encoding;
1820 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1821 int idx, key_len, alg = ext->alg, set_key = 1;
1823 /* Determine and validate the key index */
1824 idx = encoding->flags & IW_ENCODE_INDEX;
1826 if (idx < 1 || idx > 4)
1830 idx = priv->default_key;
1832 if (encoding->flags & IW_ENCODE_DISABLED)
1833 alg = IW_ENCODE_ALG_NONE;
1835 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1836 priv->default_key = idx;
1837 set_key = ext->key_len > 0 ? 1 : 0;
1841 /* Set the requested key first */
1843 case IW_ENCODE_ALG_NONE:
1844 priv->wep_is_on = 0;
1845 priv->encryption_level = 0;
1846 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1848 case IW_ENCODE_ALG_WEP:
1849 if (ext->key_len > 5) {
1850 priv->wep_key_len[idx] = 13;
1851 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1852 priv->encryption_level = 2;
1853 } else if (ext->key_len > 0) {
1854 priv->wep_key_len[idx] = 5;
1855 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1856 priv->encryption_level = 1;
1860 priv->wep_is_on = 1;
1861 memset(priv->wep_keys[idx], 0, 13);
1862 key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1863 memcpy(priv->wep_keys[idx], ext->key, key_len);
1870 return -EINPROGRESS;
1873 static int atmel_get_encodeext(struct net_device *dev,
1874 struct iw_request_info *info,
1875 union iwreq_data *wrqu,
1878 struct atmel_private *priv = netdev_priv(dev);
1879 struct iw_point *encoding = &wrqu->encoding;
1880 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1881 int idx, max_key_len;
1883 max_key_len = encoding->length - sizeof(*ext);
1884 if (max_key_len < 0)
1887 idx = encoding->flags & IW_ENCODE_INDEX;
1889 if (idx < 1 || idx > 4)
1893 idx = priv->default_key;
1895 encoding->flags = idx + 1;
1896 memset(ext, 0, sizeof(*ext));
1898 if (!priv->wep_is_on) {
1899 ext->alg = IW_ENCODE_ALG_NONE;
1901 encoding->flags |= IW_ENCODE_DISABLED;
1903 if (priv->encryption_level > 0)
1904 ext->alg = IW_ENCODE_ALG_WEP;
1908 ext->key_len = priv->wep_key_len[idx];
1909 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1910 encoding->flags |= IW_ENCODE_ENABLED;
1916 static int atmel_set_auth(struct net_device *dev,
1917 struct iw_request_info *info,
1918 union iwreq_data *wrqu, char *extra)
1920 struct atmel_private *priv = netdev_priv(dev);
1921 struct iw_param *param = &wrqu->param;
1923 switch (param->flags & IW_AUTH_INDEX) {
1924 case IW_AUTH_WPA_VERSION:
1925 case IW_AUTH_CIPHER_PAIRWISE:
1926 case IW_AUTH_CIPHER_GROUP:
1927 case IW_AUTH_KEY_MGMT:
1928 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1929 case IW_AUTH_PRIVACY_INVOKED:
1931 * atmel does not use these parameters
1935 case IW_AUTH_DROP_UNENCRYPTED:
1936 priv->exclude_unencrypted = param->value ? 1 : 0;
1939 case IW_AUTH_80211_AUTH_ALG: {
1940 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1941 priv->exclude_unencrypted = 1;
1942 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1943 priv->exclude_unencrypted = 0;
1949 case IW_AUTH_WPA_ENABLED:
1950 /* Silently accept disable of WPA */
1951 if (param->value > 0)
1958 return -EINPROGRESS;
1961 static int atmel_get_auth(struct net_device *dev,
1962 struct iw_request_info *info,
1963 union iwreq_data *wrqu, char *extra)
1965 struct atmel_private *priv = netdev_priv(dev);
1966 struct iw_param *param = &wrqu->param;
1968 switch (param->flags & IW_AUTH_INDEX) {
1969 case IW_AUTH_DROP_UNENCRYPTED:
1970 param->value = priv->exclude_unencrypted;
1973 case IW_AUTH_80211_AUTH_ALG:
1974 if (priv->exclude_unencrypted == 1)
1975 param->value = IW_AUTH_ALG_SHARED_KEY;
1977 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1980 case IW_AUTH_WPA_ENABLED:
1991 static int atmel_get_name(struct net_device *dev,
1992 struct iw_request_info *info,
1996 strcpy(cwrq, "IEEE 802.11-DS");
2000 static int atmel_set_rate(struct net_device *dev,
2001 struct iw_request_info *info,
2002 struct iw_param *vwrq,
2005 struct atmel_private *priv = netdev_priv(dev);
2007 if (vwrq->fixed == 0) {
2009 priv->auto_tx_rate = 1;
2011 priv->auto_tx_rate = 0;
2013 /* Which type of value ? */
2014 if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2015 /* Setting by rate index */
2016 priv->tx_rate = vwrq->value;
2018 /* Setting by frequency value */
2019 switch (vwrq->value) {
2038 return -EINPROGRESS;
2041 static int atmel_set_mode(struct net_device *dev,
2042 struct iw_request_info *info,
2046 struct atmel_private *priv = netdev_priv(dev);
2048 if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2051 priv->operating_mode = *uwrq;
2052 return -EINPROGRESS;
2055 static int atmel_get_mode(struct net_device *dev,
2056 struct iw_request_info *info,
2060 struct atmel_private *priv = netdev_priv(dev);
2062 *uwrq = priv->operating_mode;
2066 static int atmel_get_rate(struct net_device *dev,
2067 struct iw_request_info *info,
2068 struct iw_param *vwrq,
2071 struct atmel_private *priv = netdev_priv(dev);
2073 if (priv->auto_tx_rate) {
2075 vwrq->value = 11000000;
2078 switch (priv->tx_rate) {
2080 vwrq->value = 1000000;
2083 vwrq->value = 2000000;
2086 vwrq->value = 5500000;
2089 vwrq->value = 11000000;
2096 static int atmel_set_power(struct net_device *dev,
2097 struct iw_request_info *info,
2098 struct iw_param *vwrq,
2101 struct atmel_private *priv = netdev_priv(dev);
2102 priv->power_mode = vwrq->disabled ? 0 : 1;
2103 return -EINPROGRESS;
2106 static int atmel_get_power(struct net_device *dev,
2107 struct iw_request_info *info,
2108 struct iw_param *vwrq,
2111 struct atmel_private *priv = netdev_priv(dev);
2112 vwrq->disabled = priv->power_mode ? 0 : 1;
2113 vwrq->flags = IW_POWER_ON;
2117 static int atmel_set_retry(struct net_device *dev,
2118 struct iw_request_info *info,
2119 struct iw_param *vwrq,
2122 struct atmel_private *priv = netdev_priv(dev);
2124 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2125 if (vwrq->flags & IW_RETRY_LONG)
2126 priv->long_retry = vwrq->value;
2127 else if (vwrq->flags & IW_RETRY_SHORT)
2128 priv->short_retry = vwrq->value;
2130 /* No modifier : set both */
2131 priv->long_retry = vwrq->value;
2132 priv->short_retry = vwrq->value;
2134 return -EINPROGRESS;
2140 static int atmel_get_retry(struct net_device *dev,
2141 struct iw_request_info *info,
2142 struct iw_param *vwrq,
2145 struct atmel_private *priv = netdev_priv(dev);
2147 vwrq->disabled = 0; /* Can't be disabled */
2149 /* Note : by default, display the short retry number */
2150 if (vwrq->flags & IW_RETRY_LONG) {
2151 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2152 vwrq->value = priv->long_retry;
2154 vwrq->flags = IW_RETRY_LIMIT;
2155 vwrq->value = priv->short_retry;
2156 if (priv->long_retry != priv->short_retry)
2157 vwrq->flags |= IW_RETRY_SHORT;
2163 static int atmel_set_rts(struct net_device *dev,
2164 struct iw_request_info *info,
2165 struct iw_param *vwrq,
2168 struct atmel_private *priv = netdev_priv(dev);
2169 int rthr = vwrq->value;
2173 if ((rthr < 0) || (rthr > 2347)) {
2176 priv->rts_threshold = rthr;
2178 return -EINPROGRESS; /* Call commit handler */
2181 static int atmel_get_rts(struct net_device *dev,
2182 struct iw_request_info *info,
2183 struct iw_param *vwrq,
2186 struct atmel_private *priv = netdev_priv(dev);
2188 vwrq->value = priv->rts_threshold;
2189 vwrq->disabled = (vwrq->value >= 2347);
2195 static int atmel_set_frag(struct net_device *dev,
2196 struct iw_request_info *info,
2197 struct iw_param *vwrq,
2200 struct atmel_private *priv = netdev_priv(dev);
2201 int fthr = vwrq->value;
2205 if ((fthr < 256) || (fthr > 2346)) {
2208 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
2209 priv->frag_threshold = fthr;
2211 return -EINPROGRESS; /* Call commit handler */
2214 static int atmel_get_frag(struct net_device *dev,
2215 struct iw_request_info *info,
2216 struct iw_param *vwrq,
2219 struct atmel_private *priv = netdev_priv(dev);
2221 vwrq->value = priv->frag_threshold;
2222 vwrq->disabled = (vwrq->value >= 2346);
2228 static int atmel_set_freq(struct net_device *dev,
2229 struct iw_request_info *info,
2230 struct iw_freq *fwrq,
2233 struct atmel_private *priv = netdev_priv(dev);
2234 int rc = -EINPROGRESS; /* Call commit handler */
2236 /* If setting by frequency, convert to a channel */
2238 int f = fwrq->m / 100000;
2240 /* Hack to fall through... */
2242 fwrq->m = ieee80211_frequency_to_channel(f);
2244 /* Setting by channel number */
2245 if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2248 int channel = fwrq->m;
2249 if (atmel_validate_channel(priv, channel) == 0) {
2250 priv->channel = channel;
2258 static int atmel_get_freq(struct net_device *dev,
2259 struct iw_request_info *info,
2260 struct iw_freq *fwrq,
2263 struct atmel_private *priv = netdev_priv(dev);
2265 fwrq->m = priv->channel;
2270 static int atmel_set_scan(struct net_device *dev,
2271 struct iw_request_info *info,
2272 struct iw_point *dwrq,
2275 struct atmel_private *priv = netdev_priv(dev);
2276 unsigned long flags;
2278 /* Note : you may have realised that, as this is a SET operation,
2279 * this is privileged and therefore a normal user can't
2281 * This is not an error, while the device perform scanning,
2282 * traffic doesn't flow, so it's a perfect DoS...
2285 if (priv->station_state == STATION_STATE_DOWN)
2288 /* Timeout old surveys. */
2289 if (time_after(jiffies, priv->last_survey + 20 * HZ))
2290 priv->site_survey_state = SITE_SURVEY_IDLE;
2291 priv->last_survey = jiffies;
2293 /* Initiate a scan command */
2294 if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2297 del_timer_sync(&priv->management_timer);
2298 spin_lock_irqsave(&priv->irqlock, flags);
2300 priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2301 priv->fast_scan = 0;
2302 atmel_scan(priv, 0);
2303 spin_unlock_irqrestore(&priv->irqlock, flags);
2308 static int atmel_get_scan(struct net_device *dev,
2309 struct iw_request_info *info,
2310 struct iw_point *dwrq,
2313 struct atmel_private *priv = netdev_priv(dev);
2315 char *current_ev = extra;
2316 struct iw_event iwe;
2318 if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2321 for (i = 0; i < priv->BSS_list_entries; i++) {
2322 iwe.cmd = SIOCGIWAP;
2323 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2324 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2325 current_ev = iwe_stream_add_event(info, current_ev,
2326 extra + IW_SCAN_MAX_DATA,
2327 &iwe, IW_EV_ADDR_LEN);
2329 iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
2330 if (iwe.u.data.length > 32)
2331 iwe.u.data.length = 32;
2332 iwe.cmd = SIOCGIWESSID;
2333 iwe.u.data.flags = 1;
2334 current_ev = iwe_stream_add_point(info, current_ev,
2335 extra + IW_SCAN_MAX_DATA,
2336 &iwe, priv->BSSinfo[i].SSID);
2338 iwe.cmd = SIOCGIWMODE;
2339 iwe.u.mode = priv->BSSinfo[i].BSStype;
2340 current_ev = iwe_stream_add_event(info, current_ev,
2341 extra + IW_SCAN_MAX_DATA,
2342 &iwe, IW_EV_UINT_LEN);
2344 iwe.cmd = SIOCGIWFREQ;
2345 iwe.u.freq.m = priv->BSSinfo[i].channel;
2347 current_ev = iwe_stream_add_event(info, current_ev,
2348 extra + IW_SCAN_MAX_DATA,
2349 &iwe, IW_EV_FREQ_LEN);
2351 /* Add quality statistics */
2353 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2354 iwe.u.qual.qual = iwe.u.qual.level;
2355 /* iwe.u.qual.noise = SOMETHING */
2356 current_ev = iwe_stream_add_event(info, current_ev,
2357 extra + IW_SCAN_MAX_DATA,
2358 &iwe, IW_EV_QUAL_LEN);
2361 iwe.cmd = SIOCGIWENCODE;
2362 if (priv->BSSinfo[i].UsingWEP)
2363 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2365 iwe.u.data.flags = IW_ENCODE_DISABLED;
2366 iwe.u.data.length = 0;
2367 current_ev = iwe_stream_add_point(info, current_ev,
2368 extra + IW_SCAN_MAX_DATA,
2372 /* Length of data */
2373 dwrq->length = (current_ev - extra);
2379 static int atmel_get_range(struct net_device *dev,
2380 struct iw_request_info *info,
2381 struct iw_point *dwrq,
2384 struct atmel_private *priv = netdev_priv(dev);
2385 struct iw_range *range = (struct iw_range *) extra;
2388 dwrq->length = sizeof(struct iw_range);
2389 memset(range, 0, sizeof(struct iw_range));
2390 range->min_nwid = 0x0000;
2391 range->max_nwid = 0x0000;
2392 range->num_channels = 0;
2393 for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2394 if (priv->reg_domain == channel_table[j].reg_domain) {
2395 range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2398 if (range->num_channels != 0) {
2399 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2400 range->freq[k].i = i; /* List index */
2402 /* Values in MHz -> * 10^5 * 10 */
2403 range->freq[k].m = 100000 *
2404 ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2405 range->freq[k++].e = 1;
2407 range->num_frequency = k;
2410 range->max_qual.qual = 100;
2411 range->max_qual.level = 100;
2412 range->max_qual.noise = 0;
2413 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2415 range->avg_qual.qual = 50;
2416 range->avg_qual.level = 50;
2417 range->avg_qual.noise = 0;
2418 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2420 range->sensitivity = 0;
2422 range->bitrate[0] = 1000000;
2423 range->bitrate[1] = 2000000;
2424 range->bitrate[2] = 5500000;
2425 range->bitrate[3] = 11000000;
2426 range->num_bitrates = 4;
2429 range->max_rts = 2347;
2430 range->min_frag = 256;
2431 range->max_frag = 2346;
2433 range->encoding_size[0] = 5;
2434 range->encoding_size[1] = 13;
2435 range->num_encoding_sizes = 2;
2436 range->max_encoding_tokens = 4;
2438 range->pmp_flags = IW_POWER_ON;
2439 range->pmt_flags = IW_POWER_ON;
2442 range->we_version_source = WIRELESS_EXT;
2443 range->we_version_compiled = WIRELESS_EXT;
2444 range->retry_capa = IW_RETRY_LIMIT ;
2445 range->retry_flags = IW_RETRY_LIMIT;
2446 range->r_time_flags = 0;
2447 range->min_retry = 1;
2448 range->max_retry = 65535;
2453 static int atmel_set_wap(struct net_device *dev,
2454 struct iw_request_info *info,
2455 struct sockaddr *awrq,
2458 struct atmel_private *priv = netdev_priv(dev);
2460 static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2461 static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2462 unsigned long flags;
2464 if (awrq->sa_family != ARPHRD_ETHER)
2467 if (!memcmp(any, awrq->sa_data, 6) ||
2468 !memcmp(off, awrq->sa_data, 6)) {
2469 del_timer_sync(&priv->management_timer);
2470 spin_lock_irqsave(&priv->irqlock, flags);
2471 atmel_scan(priv, 1);
2472 spin_unlock_irqrestore(&priv->irqlock, flags);
2476 for (i = 0; i < priv->BSS_list_entries; i++) {
2477 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2478 if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2480 } else if (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2483 del_timer_sync(&priv->management_timer);
2484 spin_lock_irqsave(&priv->irqlock, flags);
2485 atmel_join_bss(priv, i);
2486 spin_unlock_irqrestore(&priv->irqlock, flags);
2495 static int atmel_config_commit(struct net_device *dev,
2496 struct iw_request_info *info, /* NULL */
2497 void *zwrq, /* NULL */
2498 char *extra) /* NULL */
2500 return atmel_open(dev);
2503 static const iw_handler atmel_handler[] =
2505 (iw_handler) atmel_config_commit, /* SIOCSIWCOMMIT */
2506 (iw_handler) atmel_get_name, /* SIOCGIWNAME */
2507 (iw_handler) NULL, /* SIOCSIWNWID */
2508 (iw_handler) NULL, /* SIOCGIWNWID */
2509 (iw_handler) atmel_set_freq, /* SIOCSIWFREQ */
2510 (iw_handler) atmel_get_freq, /* SIOCGIWFREQ */
2511 (iw_handler) atmel_set_mode, /* SIOCSIWMODE */
2512 (iw_handler) atmel_get_mode, /* SIOCGIWMODE */
2513 (iw_handler) NULL, /* SIOCSIWSENS */
2514 (iw_handler) NULL, /* SIOCGIWSENS */
2515 (iw_handler) NULL, /* SIOCSIWRANGE */
2516 (iw_handler) atmel_get_range, /* SIOCGIWRANGE */
2517 (iw_handler) NULL, /* SIOCSIWPRIV */
2518 (iw_handler) NULL, /* SIOCGIWPRIV */
2519 (iw_handler) NULL, /* SIOCSIWSTATS */
2520 (iw_handler) NULL, /* SIOCGIWSTATS */
2521 (iw_handler) NULL, /* SIOCSIWSPY */
2522 (iw_handler) NULL, /* SIOCGIWSPY */
2523 (iw_handler) NULL, /* -- hole -- */
2524 (iw_handler) NULL, /* -- hole -- */
2525 (iw_handler) atmel_set_wap, /* SIOCSIWAP */
2526 (iw_handler) atmel_get_wap, /* SIOCGIWAP */
2527 (iw_handler) NULL, /* -- hole -- */
2528 (iw_handler) NULL, /* SIOCGIWAPLIST */
2529 (iw_handler) atmel_set_scan, /* SIOCSIWSCAN */
2530 (iw_handler) atmel_get_scan, /* SIOCGIWSCAN */
2531 (iw_handler) atmel_set_essid, /* SIOCSIWESSID */
2532 (iw_handler) atmel_get_essid, /* SIOCGIWESSID */
2533 (iw_handler) NULL, /* SIOCSIWNICKN */
2534 (iw_handler) NULL, /* SIOCGIWNICKN */
2535 (iw_handler) NULL, /* -- hole -- */
2536 (iw_handler) NULL, /* -- hole -- */
2537 (iw_handler) atmel_set_rate, /* SIOCSIWRATE */
2538 (iw_handler) atmel_get_rate, /* SIOCGIWRATE */
2539 (iw_handler) atmel_set_rts, /* SIOCSIWRTS */
2540 (iw_handler) atmel_get_rts, /* SIOCGIWRTS */
2541 (iw_handler) atmel_set_frag, /* SIOCSIWFRAG */
2542 (iw_handler) atmel_get_frag, /* SIOCGIWFRAG */
2543 (iw_handler) NULL, /* SIOCSIWTXPOW */
2544 (iw_handler) NULL, /* SIOCGIWTXPOW */
2545 (iw_handler) atmel_set_retry, /* SIOCSIWRETRY */
2546 (iw_handler) atmel_get_retry, /* SIOCGIWRETRY */
2547 (iw_handler) atmel_set_encode, /* SIOCSIWENCODE */
2548 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */
2549 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */
2550 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */
2551 (iw_handler) NULL, /* -- hole -- */
2552 (iw_handler) NULL, /* -- hole -- */
2553 (iw_handler) NULL, /* SIOCSIWGENIE */
2554 (iw_handler) NULL, /* SIOCGIWGENIE */
2555 (iw_handler) atmel_set_auth, /* SIOCSIWAUTH */
2556 (iw_handler) atmel_get_auth, /* SIOCGIWAUTH */
2557 (iw_handler) atmel_set_encodeext, /* SIOCSIWENCODEEXT */
2558 (iw_handler) atmel_get_encodeext, /* SIOCGIWENCODEEXT */
2559 (iw_handler) NULL, /* SIOCSIWPMKSA */
2562 static const iw_handler atmel_private_handler[] =
2564 NULL, /* SIOCIWFIRSTPRIV */
2567 struct atmel_priv_ioctl {
2569 unsigned char __user *data;
2573 #define ATMELFWL SIOCIWFIRSTPRIV
2574 #define ATMELIDIFC ATMELFWL + 1
2575 #define ATMELRD ATMELFWL + 2
2576 #define ATMELMAGIC 0x51807
2577 #define REGDOMAINSZ 20
2579 static const struct iw_priv_args atmel_private_args[] = {
2582 .set_args = IW_PRIV_TYPE_BYTE
2583 | IW_PRIV_SIZE_FIXED
2584 | sizeof(struct atmel_priv_ioctl),
2585 .get_args = IW_PRIV_TYPE_NONE,
2589 .set_args = IW_PRIV_TYPE_NONE,
2590 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2591 .name = "atmelidifc"
2594 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2595 .get_args = IW_PRIV_TYPE_NONE,
2600 static const struct iw_handler_def atmel_handler_def = {
2601 .num_standard = ARRAY_SIZE(atmel_handler),
2602 .num_private = ARRAY_SIZE(atmel_private_handler),
2603 .num_private_args = ARRAY_SIZE(atmel_private_args),
2604 .standard = (iw_handler *) atmel_handler,
2605 .private = (iw_handler *) atmel_private_handler,
2606 .private_args = (struct iw_priv_args *) atmel_private_args,
2607 .get_wireless_stats = atmel_get_wireless_stats
2610 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2613 struct atmel_private *priv = netdev_priv(dev);
2614 struct atmel_priv_ioctl com;
2615 struct iwreq *wrq = (struct iwreq *) rq;
2616 unsigned char *new_firmware;
2617 char domain[REGDOMAINSZ + 1];
2621 wrq->u.param.value = ATMELMAGIC;
2625 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2630 if (!capable(CAP_NET_ADMIN)) {
2635 new_firmware = memdup_user(com.data, com.len);
2636 if (IS_ERR(new_firmware)) {
2637 rc = PTR_ERR(new_firmware);
2641 kfree(priv->firmware);
2643 priv->firmware = new_firmware;
2644 priv->firmware_length = com.len;
2645 strncpy(priv->firmware_id, com.id, 31);
2646 priv->firmware_id[31] = '\0';
2650 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2655 if (!capable(CAP_NET_ADMIN)) {
2660 domain[REGDOMAINSZ] = 0;
2662 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2663 if (!strcasecmp(channel_table[i].name, domain)) {
2664 priv->config_reg_domain = channel_table[i].reg_domain;
2669 if (rc == 0 && priv->station_state != STATION_STATE_DOWN)
2670 rc = atmel_open(dev);
2689 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2691 int old_state = priv->station_state;
2693 if (new_state == old_state)
2696 priv->station_state = new_state;
2698 if (new_state == STATION_STATE_READY) {
2699 netif_start_queue(priv->dev);
2700 netif_carrier_on(priv->dev);
2703 if (old_state == STATION_STATE_READY) {
2704 netif_carrier_off(priv->dev);
2705 if (netif_running(priv->dev))
2706 netif_stop_queue(priv->dev);
2707 priv->last_beacon_timestamp = 0;
2711 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2715 u8 SSID[MAX_SSID_LENGTH];
2719 __le16 min_channel_time;
2720 __le16 max_channel_time;
2725 eth_broadcast_addr(cmd.BSSID);
2727 if (priv->fast_scan) {
2728 cmd.SSID_size = priv->SSID_size;
2729 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2730 cmd.min_channel_time = cpu_to_le16(10);
2731 cmd.max_channel_time = cpu_to_le16(50);
2733 priv->BSS_list_entries = 0;
2735 cmd.min_channel_time = cpu_to_le16(10);
2736 cmd.max_channel_time = cpu_to_le16(120);
2742 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2744 cmd.channel = (priv->channel & 0x7f);
2745 cmd.scan_type = SCAN_TYPE_ACTIVE;
2746 cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2747 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2749 atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2751 /* This must come after all hardware access to avoid being messed up
2752 by stuff happening in interrupt context after we leave STATE_DOWN */
2753 atmel_enter_state(priv, STATION_STATE_SCANNING);
2756 static void join(struct atmel_private *priv, int type)
2760 u8 SSID[MAX_SSID_LENGTH];
2761 u8 BSS_type; /* this is a short in a scan command - weird */
2768 cmd.SSID_size = priv->SSID_size;
2769 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2770 memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2771 cmd.channel = (priv->channel & 0x7f);
2772 cmd.BSS_type = type;
2773 cmd.timeout = cpu_to_le16(2000);
2775 atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2778 static void start(struct atmel_private *priv, int type)
2782 u8 SSID[MAX_SSID_LENGTH];
2789 cmd.SSID_size = priv->SSID_size;
2790 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2791 memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2792 cmd.BSS_type = type;
2793 cmd.channel = (priv->channel & 0x7f);
2795 atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2798 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2802 int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2803 SHORT_PREAMBLE : LONG_PREAMBLE;
2805 if (priv->preamble != new) {
2806 priv->preamble = new;
2808 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2811 if (priv->channel != channel) {
2812 priv->channel = channel;
2814 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2818 priv->station_is_associated = 0;
2819 atmel_enter_state(priv, STATION_STATE_JOINNING);
2821 if (priv->operating_mode == IW_MODE_INFRA)
2822 join(priv, BSS_TYPE_INFRASTRUCTURE);
2824 join(priv, BSS_TYPE_AD_HOC);
2828 static void send_authentication_request(struct atmel_private *priv, u16 system,
2829 u8 *challenge, int challenge_len)
2831 struct ieee80211_hdr header;
2832 struct auth_body auth;
2834 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2835 header.duration_id = cpu_to_le16(0x8000);
2836 header.seq_ctrl = 0;
2837 memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2838 memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2839 memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2841 if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2842 /* no WEP for authentication frames with TrSeqNo 1 */
2843 header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2845 auth.alg = cpu_to_le16(system);
2848 auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2849 priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2850 priv->CurrentAuthentTransactionSeqNum += 2;
2852 if (challenge_len != 0) {
2853 auth.el_id = 16; /* challenge_text */
2854 auth.chall_text_len = challenge_len;
2855 memcpy(auth.chall_text, challenge, challenge_len);
2856 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2858 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2862 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2866 struct ieee80211_hdr header;
2867 struct ass_req_format {
2869 __le16 listen_interval;
2870 u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2873 u8 ssid[MAX_SSID_LENGTH];
2879 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2880 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2881 header.duration_id = cpu_to_le16(0x8000);
2882 header.seq_ctrl = 0;
2884 memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2885 memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2886 memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2888 body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2889 if (priv->wep_is_on)
2890 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2891 if (priv->preamble == SHORT_PREAMBLE)
2892 body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2894 body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2896 /* current AP address - only in reassoc frame */
2898 memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2899 ssid_el_p = &body.ssid_el_id;
2900 bodysize = 18 + priv->SSID_size;
2902 ssid_el_p = &body.ap[0];
2903 bodysize = 12 + priv->SSID_size;
2906 ssid_el_p[0] = WLAN_EID_SSID;
2907 ssid_el_p[1] = priv->SSID_size;
2908 memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2909 ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2910 ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2911 memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2913 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2916 static int is_frame_from_current_bss(struct atmel_private *priv,
2917 struct ieee80211_hdr *header)
2919 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2920 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2922 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2925 static int retrieve_bss(struct atmel_private *priv)
2928 int max_rssi = -128;
2931 if (priv->BSS_list_entries == 0)
2934 if (priv->connect_to_any_BSS) {
2935 /* Select a BSS with the max-RSSI but of the same type and of
2936 the same WEP mode and that it is not marked as 'bad' (i.e.
2937 we had previously failed to connect to this BSS with the
2938 settings that we currently use) */
2939 priv->current_BSS = 0;
2940 for (i = 0; i < priv->BSS_list_entries; i++) {
2941 if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2942 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2943 (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2944 !(priv->BSSinfo[i].channel & 0x80)) {
2945 max_rssi = priv->BSSinfo[i].RSSI;
2946 priv->current_BSS = max_index = i;
2952 for (i = 0; i < priv->BSS_list_entries; i++) {
2953 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2954 memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2955 priv->operating_mode == priv->BSSinfo[i].BSStype &&
2956 atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2957 if (priv->BSSinfo[i].RSSI >= max_rssi) {
2958 max_rssi = priv->BSSinfo[i].RSSI;
2966 static void store_bss_info(struct atmel_private *priv,
2967 struct ieee80211_hdr *header, u16 capability,
2968 u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2969 u8 *ssid, int is_beacon)
2971 u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2974 for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2975 if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
2978 /* If we process a probe and an entry from this BSS exists
2979 we will update the BSS entry with the info from this BSS.
2980 If we process a beacon we will only update RSSI */
2983 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2985 index = priv->BSS_list_entries++;
2986 memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
2987 priv->BSSinfo[index].RSSI = rssi;
2989 if (rssi > priv->BSSinfo[index].RSSI)
2990 priv->BSSinfo[index].RSSI = rssi;
2995 priv->BSSinfo[index].channel = channel;
2996 priv->BSSinfo[index].beacon_period = beacon_period;
2997 priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
2998 memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
2999 priv->BSSinfo[index].SSIDsize = ssid_len;
3001 if (capability & WLAN_CAPABILITY_IBSS)
3002 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3003 else if (capability & WLAN_CAPABILITY_ESS)
3004 priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3006 priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3007 SHORT_PREAMBLE : LONG_PREAMBLE;
3010 static void authenticate(struct atmel_private *priv, u16 frame_len)
3012 struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3013 u16 status = le16_to_cpu(auth->status);
3014 u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3015 u16 system = le16_to_cpu(auth->alg);
3017 if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3019 if (priv->station_was_associated) {
3020 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3021 send_association_request(priv, 1);
3024 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3025 send_association_request(priv, 0);
3030 if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3031 int should_associate = 0;
3033 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3036 if (system == WLAN_AUTH_OPEN) {
3037 if (trans_seq_no == 0x0002) {
3038 should_associate = 1;
3040 } else if (system == WLAN_AUTH_SHARED_KEY) {
3041 if (trans_seq_no == 0x0002 &&
3042 auth->el_id == WLAN_EID_CHALLENGE) {
3043 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3045 } else if (trans_seq_no == 0x0004) {
3046 should_associate = 1;
3050 if (should_associate) {
3051 if (priv->station_was_associated) {
3052 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3053 send_association_request(priv, 1);
3056 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3057 send_association_request(priv, 0);
3063 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3064 /* Flip back and forth between WEP auth modes until the max
3065 * authentication tries has been exceeded.
3067 if (system == WLAN_AUTH_OPEN) {
3068 priv->CurrentAuthentTransactionSeqNum = 0x001;
3069 priv->exclude_unencrypted = 1;
3070 send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3072 } else if (system == WLAN_AUTH_SHARED_KEY
3073 && priv->wep_is_on) {
3074 priv->CurrentAuthentTransactionSeqNum = 0x001;
3075 priv->exclude_unencrypted = 0;
3076 send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3078 } else if (priv->connect_to_any_BSS) {
3081 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3083 if ((bss_index = retrieve_bss(priv)) != -1) {
3084 atmel_join_bss(priv, bss_index);
3090 priv->AuthenticationRequestRetryCnt = 0;
3091 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3092 priv->station_is_associated = 0;
3095 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3097 struct ass_resp_format {
3104 } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3106 u16 status = le16_to_cpu(ass_resp->status);
3107 u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3108 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3110 union iwreq_data wrqu;
3112 if (frame_len < 8 + rates_len)
3115 if (status == WLAN_STATUS_SUCCESS) {
3116 if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3117 priv->AssociationRequestRetryCnt = 0;
3119 priv->ReAssociationRequestRetryCnt = 0;
3121 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3122 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3123 atmel_set_mib(priv, Phy_Mib_Type,
3124 PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3125 if (priv->power_mode == 0) {
3126 priv->listen_interval = 1;
3127 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3128 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3129 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3130 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3132 priv->listen_interval = 2;
3133 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3134 MAC_MGMT_MIB_PS_MODE_POS, PS_MODE);
3135 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3136 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3139 priv->station_is_associated = 1;
3140 priv->station_was_associated = 1;
3141 atmel_enter_state(priv, STATION_STATE_READY);
3143 /* Send association event to userspace */
3144 wrqu.data.length = 0;
3145 wrqu.data.flags = 0;
3146 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3147 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3148 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3153 if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3154 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3155 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3156 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3157 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3158 priv->AssociationRequestRetryCnt++;
3159 send_association_request(priv, 0);
3163 if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3164 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3165 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3166 priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3167 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3168 priv->ReAssociationRequestRetryCnt++;
3169 send_association_request(priv, 1);
3173 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3174 priv->station_is_associated = 0;
3176 if (priv->connect_to_any_BSS) {
3178 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3180 if ((bss_index = retrieve_bss(priv)) != -1)
3181 atmel_join_bss(priv, bss_index);
3185 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3187 struct bss_info *bss = &priv->BSSinfo[bss_index];
3189 memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3190 memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3192 /* The WPA stuff cares about the current AP address */
3194 build_wpa_mib(priv);
3196 /* When switching to AdHoc turn OFF Power Save if needed */
3198 if (bss->BSStype == IW_MODE_ADHOC &&
3199 priv->operating_mode != IW_MODE_ADHOC &&
3201 priv->power_mode = 0;
3202 priv->listen_interval = 1;
3203 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3204 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3205 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3206 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3209 priv->operating_mode = bss->BSStype;
3210 priv->channel = bss->channel & 0x7f;
3211 priv->beacon_period = bss->beacon_period;
3213 if (priv->preamble != bss->preamble) {
3214 priv->preamble = bss->preamble;
3215 atmel_set_mib8(priv, Local_Mib_Type,
3216 LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3219 if (!priv->wep_is_on && bss->UsingWEP) {
3220 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3221 priv->station_is_associated = 0;
3225 if (priv->wep_is_on && !bss->UsingWEP) {
3226 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3227 priv->station_is_associated = 0;
3231 atmel_enter_state(priv, STATION_STATE_JOINNING);
3233 if (priv->operating_mode == IW_MODE_INFRA)
3234 join(priv, BSS_TYPE_INFRASTRUCTURE);
3236 join(priv, BSS_TYPE_AD_HOC);
3239 static void restart_search(struct atmel_private *priv)
3243 if (!priv->connect_to_any_BSS) {
3244 atmel_scan(priv, 1);
3246 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3248 if ((bss_index = retrieve_bss(priv)) != -1)
3249 atmel_join_bss(priv, bss_index);
3251 atmel_scan(priv, 0);
3255 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3257 u8 old = priv->wstats.qual.level;
3258 u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3260 switch (priv->firmware_type) {
3261 case ATMEL_FW_TYPE_502E:
3262 max_rssi = 63; /* 502-rmfd-reve max by experiment */
3268 rssi = rssi * 100 / max_rssi;
3269 if ((rssi + old) % 2)
3270 priv->wstats.qual.level = (rssi + old) / 2 + 1;
3272 priv->wstats.qual.level = (rssi + old) / 2;
3273 priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3274 priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3277 static void atmel_smooth_qual(struct atmel_private *priv)
3279 unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3280 while (time_diff--) {
3281 priv->last_qual += HZ;
3282 priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3283 priv->wstats.qual.qual +=
3284 priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3285 priv->beacons_this_sec = 0;
3287 priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3288 priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3291 /* deals with incoming management frames. */
3292 static void atmel_management_frame(struct atmel_private *priv,
3293 struct ieee80211_hdr *header,
3294 u16 frame_len, u8 rssi)
3298 subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3300 case IEEE80211_STYPE_BEACON:
3301 case IEEE80211_STYPE_PROBE_RESP:
3303 /* beacon frame has multiple variable-length fields -
3304 never let an engineer loose with a data structure design. */
3306 struct beacon_format {
3319 } *beacon = (struct beacon_format *)priv->rx_buf;
3321 u8 channel, rates_length, ssid_length;
3322 u64 timestamp = le64_to_cpu(beacon->timestamp);
3323 u16 beacon_interval = le16_to_cpu(beacon->interval);
3324 u16 capability = le16_to_cpu(beacon->capability);
3325 u8 *beaconp = priv->rx_buf;
3326 ssid_length = beacon->ssid_length;
3327 /* this blows chunks. */
3328 if (frame_len < 14 || frame_len < ssid_length + 15)
3330 rates_length = beaconp[beacon->ssid_length + 15];
3331 if (frame_len < ssid_length + rates_length + 18)
3333 if (ssid_length > MAX_SSID_LENGTH)
3335 channel = beaconp[ssid_length + rates_length + 18];
3337 if (priv->station_state == STATION_STATE_READY) {
3338 smooth_rssi(priv, rssi);
3339 if (is_frame_from_current_bss(priv, header)) {
3340 priv->beacons_this_sec++;
3341 atmel_smooth_qual(priv);
3342 if (priv->last_beacon_timestamp) {
3343 /* Note truncate this to 32 bits - kernel can't divide a long long */
3344 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3345 int beacons = beacon_delay / (beacon_interval * 1000);
3347 priv->wstats.miss.beacon += beacons - 1;
3349 priv->last_beacon_timestamp = timestamp;
3350 handle_beacon_probe(priv, capability, channel);
3354 if (priv->station_state == STATION_STATE_SCANNING)
3355 store_bss_info(priv, header, capability,
3356 beacon_interval, channel, rssi,
3358 &beacon->rates_el_id,
3359 subtype == IEEE80211_STYPE_BEACON);
3363 case IEEE80211_STYPE_AUTH:
3365 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3366 authenticate(priv, frame_len);
3370 case IEEE80211_STYPE_ASSOC_RESP:
3371 case IEEE80211_STYPE_REASSOC_RESP:
3373 if (priv->station_state == STATION_STATE_ASSOCIATING ||
3374 priv->station_state == STATION_STATE_REASSOCIATING)
3375 associate(priv, frame_len, subtype);
3379 case IEEE80211_STYPE_DISASSOC:
3380 if (priv->station_is_associated &&
3381 priv->operating_mode == IW_MODE_INFRA &&
3382 is_frame_from_current_bss(priv, header)) {
3383 priv->station_was_associated = 0;
3384 priv->station_is_associated = 0;
3386 atmel_enter_state(priv, STATION_STATE_JOINNING);
3387 join(priv, BSS_TYPE_INFRASTRUCTURE);
3392 case IEEE80211_STYPE_DEAUTH:
3393 if (priv->operating_mode == IW_MODE_INFRA &&
3394 is_frame_from_current_bss(priv, header)) {
3395 priv->station_was_associated = 0;
3397 atmel_enter_state(priv, STATION_STATE_JOINNING);
3398 join(priv, BSS_TYPE_INFRASTRUCTURE);
3405 /* run when timer expires */
3406 static void atmel_management_timer(struct timer_list *t)
3408 struct atmel_private *priv = from_timer(priv, t, management_timer);
3409 unsigned long flags;
3411 /* Check if the card has been yanked. */
3412 if (priv->card && priv->present_callback &&
3413 !(*priv->present_callback)(priv->card))
3416 spin_lock_irqsave(&priv->irqlock, flags);
3418 switch (priv->station_state) {
3420 case STATION_STATE_AUTHENTICATING:
3421 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3422 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3423 priv->station_is_associated = 0;
3424 priv->AuthenticationRequestRetryCnt = 0;
3425 restart_search(priv);
3427 int auth = WLAN_AUTH_OPEN;
3428 priv->AuthenticationRequestRetryCnt++;
3429 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3430 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3431 if (priv->wep_is_on && priv->exclude_unencrypted)
3432 auth = WLAN_AUTH_SHARED_KEY;
3433 send_authentication_request(priv, auth, NULL, 0);
3437 case STATION_STATE_ASSOCIATING:
3438 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3439 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3440 priv->station_is_associated = 0;
3441 priv->AssociationRequestRetryCnt = 0;
3442 restart_search(priv);
3444 priv->AssociationRequestRetryCnt++;
3445 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3446 send_association_request(priv, 0);
3450 case STATION_STATE_REASSOCIATING:
3451 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3452 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3453 priv->station_is_associated = 0;
3454 priv->ReAssociationRequestRetryCnt = 0;
3455 restart_search(priv);
3457 priv->ReAssociationRequestRetryCnt++;
3458 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3459 send_association_request(priv, 1);
3467 spin_unlock_irqrestore(&priv->irqlock, flags);
3470 static void atmel_command_irq(struct atmel_private *priv)
3472 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3473 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3475 union iwreq_data wrqu;
3477 if (status == CMD_STATUS_IDLE ||
3478 status == CMD_STATUS_IN_PROGRESS)
3483 if (status == CMD_STATUS_COMPLETE) {
3484 priv->station_was_associated = priv->station_is_associated;
3485 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3486 (u8 *)priv->CurrentBSSID, 6);
3487 atmel_enter_state(priv, STATION_STATE_READY);
3492 fast_scan = priv->fast_scan;
3493 priv->fast_scan = 0;
3495 if (status != CMD_STATUS_COMPLETE) {
3496 atmel_scan(priv, 1);
3498 int bss_index = retrieve_bss(priv);
3499 int notify_scan_complete = 1;
3500 if (bss_index != -1) {
3501 atmel_join_bss(priv, bss_index);
3502 } else if (priv->operating_mode == IW_MODE_ADHOC &&
3503 priv->SSID_size != 0) {
3504 start(priv, BSS_TYPE_AD_HOC);
3506 priv->fast_scan = !fast_scan;
3507 atmel_scan(priv, 1);
3508 notify_scan_complete = 0;
3510 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3511 if (notify_scan_complete) {
3512 wrqu.data.length = 0;
3513 wrqu.data.flags = 0;
3514 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3519 case CMD_SiteSurvey:
3520 priv->fast_scan = 0;
3522 if (status != CMD_STATUS_COMPLETE)
3525 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3526 if (priv->station_is_associated) {
3527 atmel_enter_state(priv, STATION_STATE_READY);
3528 wrqu.data.length = 0;
3529 wrqu.data.flags = 0;
3530 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3532 atmel_scan(priv, 1);
3537 if (status == CMD_STATUS_COMPLETE) {
3538 if (priv->operating_mode == IW_MODE_ADHOC) {
3539 priv->station_was_associated = priv->station_is_associated;
3540 atmel_enter_state(priv, STATION_STATE_READY);
3542 int auth = WLAN_AUTH_OPEN;
3543 priv->AuthenticationRequestRetryCnt = 0;
3544 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3546 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3547 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3548 if (priv->wep_is_on && priv->exclude_unencrypted)
3549 auth = WLAN_AUTH_SHARED_KEY;
3550 send_authentication_request(priv, auth, NULL, 0);
3555 atmel_scan(priv, 1);
3559 static int atmel_wakeup_firmware(struct atmel_private *priv)
3561 struct host_info_struct *iface = &priv->host_info;
3565 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3566 atmel_set_gcr(priv->dev, GCR_REMAP);
3568 /* wake up on-board processor */
3569 atmel_clear_gcr(priv->dev, 0x0040);
3570 atmel_write16(priv->dev, BSR, BSS_SRAM);
3572 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3575 /* and wait for it */
3576 for (i = LOOP_RETRY_LIMIT; i; i--) {
3577 mr1 = atmel_read16(priv->dev, MR1);
3578 mr3 = atmel_read16(priv->dev, MR3);
3580 if (mr3 & MAC_BOOT_COMPLETE)
3582 if (mr1 & MAC_BOOT_COMPLETE &&
3583 priv->bus_type == BUS_TYPE_PCCARD)
3588 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3592 if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3593 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3597 /* now check for completion of MAC initialization through
3598 the FunCtrl field of the IFACE, poll MR1 to detect completion of
3599 MAC initialization, check completion status, set interrupt mask,
3600 enables interrupts and calls Tx and Rx initialization functions */
3602 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3604 for (i = LOOP_RETRY_LIMIT; i; i--) {
3605 mr1 = atmel_read16(priv->dev, MR1);
3606 mr3 = atmel_read16(priv->dev, MR3);
3608 if (mr3 & MAC_INIT_COMPLETE)
3610 if (mr1 & MAC_INIT_COMPLETE &&
3611 priv->bus_type == BUS_TYPE_PCCARD)
3616 printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3621 /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3622 if ((mr3 & MAC_INIT_COMPLETE) &&
3623 !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3624 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3627 if ((mr1 & MAC_INIT_COMPLETE) &&
3628 !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3629 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3633 atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3634 priv->host_info_base, sizeof(*iface));
3636 iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3637 iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3638 iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3639 iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3640 iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3641 iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3642 iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3643 iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3644 iface->build_version = le16_to_cpu(iface->build_version);
3645 iface->command_pos = le16_to_cpu(iface->command_pos);
3646 iface->major_version = le16_to_cpu(iface->major_version);
3647 iface->minor_version = le16_to_cpu(iface->minor_version);
3648 iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3649 iface->mac_status = le16_to_cpu(iface->mac_status);
3654 /* determine type of memory and MAC address */
3655 static int probe_atmel_card(struct net_device *dev)
3658 struct atmel_private *priv = netdev_priv(dev);
3661 if (priv->bus_type == BUS_TYPE_PCCARD)
3662 atmel_write16(dev, GCR, 0x0060);
3664 atmel_write16(dev, GCR, 0x0040);
3667 if (atmel_read16(dev, MR2) == 0) {
3668 /* No stored firmware so load a small stub which just
3669 tells us the MAC address */
3671 priv->card_type = CARD_TYPE_EEPROM;
3672 atmel_write16(dev, BSR, BSS_IRAM);
3673 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3674 atmel_set_gcr(dev, GCR_REMAP);
3675 atmel_clear_gcr(priv->dev, 0x0040);
3676 atmel_write16(dev, BSR, BSS_SRAM);
3677 for (i = LOOP_RETRY_LIMIT; i; i--)
3678 if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3681 printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3683 atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3684 /* got address, now squash it again until the network
3685 interface is opened */
3686 if (priv->bus_type == BUS_TYPE_PCCARD)
3687 atmel_write16(dev, GCR, 0x0060);
3688 atmel_write16(dev, GCR, 0x0040);
3691 } else if (atmel_read16(dev, MR4) == 0) {
3692 /* Mac address easy in this case. */
3693 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3694 atmel_write16(dev, BSR, 1);
3695 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3696 atmel_write16(dev, BSR, 0x200);
3699 /* Standard firmware in flash, boot it up and ask
3700 for the Mac Address */
3701 priv->card_type = CARD_TYPE_SPI_FLASH;
3702 if (atmel_wakeup_firmware(priv) == 0) {
3703 atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3705 /* got address, now squash it again until the network
3706 interface is opened */
3707 if (priv->bus_type == BUS_TYPE_PCCARD)
3708 atmel_write16(dev, GCR, 0x0060);
3709 atmel_write16(dev, GCR, 0x0040);
3715 if (dev->dev_addr[0] == 0xFF) {
3716 static const u8 default_mac[] = {
3717 0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3719 printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3720 memcpy(dev->dev_addr, default_mac, ETH_ALEN);
3727 /* Move the encyption information on the MIB structure.
3728 This routine is for the pre-WPA firmware: later firmware has
3729 a different format MIB and a different routine. */
3730 static void build_wep_mib(struct atmel_private *priv)
3732 struct { /* NB this is matched to the hardware, don't change. */
3734 u8 default_key; /* 0..3 */
3736 u8 exclude_unencrypted;
3738 u32 WEPICV_error_count;
3739 u32 WEP_excluded_count;
3741 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3742 u8 encryption_level; /* 0, 1, 2 */
3747 mib.wep_is_on = priv->wep_is_on;
3748 if (priv->wep_is_on) {
3749 if (priv->wep_key_len[priv->default_key] > 5)
3750 mib.encryption_level = 2;
3752 mib.encryption_level = 1;
3754 mib.encryption_level = 0;
3757 mib.default_key = priv->default_key;
3758 mib.exclude_unencrypted = priv->exclude_unencrypted;
3760 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3761 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3763 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3766 static void build_wpa_mib(struct atmel_private *priv)
3768 /* This is for the later (WPA enabled) firmware. */
3770 struct { /* NB this is matched to the hardware, don't change. */
3771 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3772 u8 receiver_address[ETH_ALEN];
3774 u8 default_key; /* 0..3 */
3776 u8 exclude_unencrypted;
3780 u32 WEPICV_error_count;
3781 u32 WEP_excluded_count;
3788 mib.wep_is_on = priv->wep_is_on;
3789 mib.exclude_unencrypted = priv->exclude_unencrypted;
3790 memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3792 /* zero all the keys before adding in valid ones. */
3793 memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3795 if (priv->wep_is_on) {
3796 /* There's a comment in the Atmel code to the effect that this
3797 is only valid when still using WEP, it may need to be set to
3798 something to use WPA */
3799 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3801 mib.default_key = mib.group_key = 255;
3802 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3803 if (priv->wep_key_len[i] > 0) {
3804 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3805 if (i == priv->default_key) {
3806 mib.default_key = i;
3807 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3808 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3811 priv->group_cipher_suite = priv->pairwise_cipher_suite;
3812 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3813 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3817 if (mib.default_key == 255)
3818 mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3819 if (mib.group_key == 255)
3820 mib.group_key = mib.default_key;
3824 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3827 static int reset_atmel_card(struct net_device *dev)
3829 /* do everything necessary to wake up the hardware, including
3830 waiting for the lightning strike and throwing the knife switch....
3832 set all the Mib values which matter in the card to match
3833 their settings in the atmel_private structure. Some of these
3834 can be altered on the fly, but many (WEP, infrastructure or ad-hoc)
3835 can only be changed by tearing down the world and coming back through
3838 This routine is also responsible for initialising some
3839 hardware-specific fields in the atmel_private structure,
3840 including a copy of the firmware's hostinfo structure
3841 which is the route into the rest of the firmware datastructures. */
3843 struct atmel_private *priv = netdev_priv(dev);
3845 int old_state = priv->station_state;
3848 /* data to add to the firmware names, in priority order
3849 this implemenents firmware versioning */
3851 static char *firmware_modifier[] = {
3858 if (priv->bus_type == BUS_TYPE_PCCARD)
3859 atmel_write16(priv->dev, GCR, 0x0060);
3861 /* stop card , disable interrupts */
3862 atmel_write16(priv->dev, GCR, 0x0040);
3864 if (priv->card_type == CARD_TYPE_EEPROM) {
3865 /* copy in firmware if needed */
3866 const struct firmware *fw_entry = NULL;
3867 const unsigned char *fw;
3868 int len = priv->firmware_length;
3869 if (!(fw = priv->firmware)) {
3870 if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3871 if (strlen(priv->firmware_id) == 0) {
3873 "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3876 "%s: if not, use the firmware= module parameter.\n",
3878 strcpy(priv->firmware_id, "/*(DEBLOBBED)*/");
3880 err = reject_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3883 "%s: firmware %s is missing, cannot continue.\n",
3884 dev->name, priv->firmware_id);
3891 /* get firmware filename entry based on firmware type ID */
3892 while (fw_table[fw_index].fw_type != priv->firmware_type
3893 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3896 /* construct the actual firmware file name */
3897 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3899 for (i = 0; firmware_modifier[i]; i++) {
3900 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3901 firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3902 priv->firmware_id[31] = '\0';
3903 if (reject_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3911 "%s: firmware %s is missing, cannot start.\n",
3912 dev->name, priv->firmware_id);
3913 priv->firmware_id[0] = '\0';
3918 fw = fw_entry->data;
3919 len = fw_entry->size;
3922 if (len <= 0x6000) {
3923 atmel_write16(priv->dev, BSR, BSS_IRAM);
3924 atmel_copy_to_card(priv->dev, 0, fw, len);
3925 atmel_set_gcr(priv->dev, GCR_REMAP);
3928 atmel_set_gcr(priv->dev, GCR_REMAP);
3929 atmel_write16(priv->dev, BSR, BSS_IRAM);
3930 atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3931 atmel_write16(priv->dev, BSR, 0x2ff);
3932 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3935 release_firmware(fw_entry);
3938 err = atmel_wakeup_firmware(priv);
3942 /* Check the version and set the correct flag for wpa stuff,
3943 old and new firmware is incompatible.
3944 The pre-wpa 3com firmware reports major version 5,
3945 the wpa 3com firmware is major version 4 and doesn't need
3946 the 3com broken-ness filter. */
3947 priv->use_wpa = (priv->host_info.major_version == 4);
3948 priv->radio_on_broken = (priv->host_info.major_version == 5);
3950 /* unmask all irq sources */
3951 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3953 /* int Tx system and enable Tx */
3954 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3955 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3956 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3957 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3959 priv->tx_desc_free = priv->host_info.tx_desc_count;
3960 priv->tx_desc_head = 0;
3961 priv->tx_desc_tail = 0;
3962 priv->tx_desc_previous = 0;
3963 priv->tx_free_mem = priv->host_info.tx_buff_size;
3964 priv->tx_buff_head = 0;
3965 priv->tx_buff_tail = 0;
3967 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3968 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3969 configuration | FUNC_CTRL_TxENABLE);
3971 /* init Rx system and enable */
3972 priv->rx_desc_head = 0;
3974 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3975 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3976 configuration | FUNC_CTRL_RxENABLE);
3978 if (!priv->radio_on_broken) {
3979 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3980 CMD_STATUS_REJECTED_RADIO_OFF) {
3981 printk(KERN_INFO "%s: cannot turn the radio on.\n",
3987 /* set up enough MIB values to run. */
3988 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
3989 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_TX_PROMISCUOUS_POS, PROM_MODE_OFF);
3990 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
3991 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
3992 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
3993 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
3994 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
3995 atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
3996 priv->dev->dev_addr, 6);
3997 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3998 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3999 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4000 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4001 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4003 build_wpa_mib(priv);
4005 build_wep_mib(priv);
4007 if (old_state == STATION_STATE_READY) {
4008 union iwreq_data wrqu;
4010 wrqu.data.length = 0;
4011 wrqu.data.flags = 0;
4012 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4013 eth_zero_addr(wrqu.ap_addr.sa_data);
4014 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4020 static void atmel_send_command(struct atmel_private *priv, int command,
4021 void *cmd, int cmd_size)
4024 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4027 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4028 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4031 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4032 void *cmd, int cmd_size)
4036 atmel_send_command(priv, command, cmd, cmd_size);
4038 for (i = 5000; i; i--) {
4039 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4040 if (status != CMD_STATUS_IDLE &&
4041 status != CMD_STATUS_IN_PROGRESS)
4047 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4048 status = CMD_STATUS_HOST_ERROR;
4050 if (command != CMD_EnableRadio)
4051 status = CMD_STATUS_COMPLETE;
4057 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4059 struct get_set_mib m;
4064 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4065 return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4068 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4070 struct get_set_mib m;
4076 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4079 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4082 struct get_set_mib m;
4087 m.data[1] = data >> 8;
4089 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4092 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4093 u8 *data, int data_len)
4095 struct get_set_mib m;
4100 if (data_len > MIB_MAX_DATA_BYTES)
4101 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4103 memcpy(m.data, data, data_len);
4104 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4107 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4108 u8 *data, int data_len)
4110 struct get_set_mib m;
4115 if (data_len > MIB_MAX_DATA_BYTES)
4116 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4118 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4119 atmel_copy_to_host(priv->dev, data,
4120 atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4123 static void atmel_writeAR(struct net_device *dev, u16 data)
4126 outw(data, dev->base_addr + AR);
4127 /* Address register appears to need some convincing..... */
4128 for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4129 outw(data, dev->base_addr + AR);
4132 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4133 const unsigned char *src, u16 len)
4136 atmel_writeAR(dev, dest);
4138 atmel_write8(dev, DR, *src);
4141 for (i = len; i > 1 ; i -= 2) {
4144 atmel_write16(dev, DR, lb | (hb << 8));
4147 atmel_write8(dev, DR, *src);
4150 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4154 atmel_writeAR(dev, src);
4156 *dest = atmel_read8(dev, DR);
4159 for (i = len; i > 1 ; i -= 2) {
4160 u16 hw = atmel_read16(dev, DR);
4165 *dest = atmel_read8(dev, DR);
4168 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4170 outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4173 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4175 outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4178 static int atmel_lock_mac(struct atmel_private *priv)
4182 for (i = 5000; i; i--) {
4183 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4189 return 0; /* timed out */
4191 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4192 if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4193 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4195 return 0; /* timed out */
4202 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4204 atmel_writeAR(priv->dev, pos);
4205 atmel_write16(priv->dev, DR, data); /* card is little-endian */
4206 atmel_write16(priv->dev, DR, data >> 16);
4209 /***************************************************************************/
4210 /* There follows the source form of the MAC address reading firmware */
4211 /***************************************************************************/
4214 /* Copyright 2003 Matthew T. Russotto */
4215 /* But derived from the Atmel 76C502 firmware written by Atmel and */
4216 /* included in "atmel wireless lan drivers" package */
4218 This file is part of net.russotto.AtmelMACFW, hereto referred to
4221 AtmelMACFW is free software; you can redistribute it and/or modify
4222 it under the terms of the GNU General Public License version 2
4223 as published by the Free Software Foundation.
4225 AtmelMACFW is distributed in the hope that it will be useful,
4226 but WITHOUT ANY WARRANTY; without even the implied warranty of
4227 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4228 GNU General Public License for more details.
4230 You should have received a copy of the GNU General Public License
4231 along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4233 ****************************************************************************/
4234 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */
4235 /* It will probably work on the 76C504 and 76C502 RFMD_3COM */
4236 /* It only works on SPI EEPROM versions of the card. */
4238 /* This firmware initializes the SPI controller and clock, reads the MAC */
4239 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC */
4240 /* address in MR2, and sets MR3 to 0x10 to indicate it is done */
4241 /* It also puts a complete copy of the EEPROM in SRAM with the offset in */
4242 /* MR4, for investigational purposes (maybe we can determine chip type */
4246 .set MRBASE, 0x8000000
4247 .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4248 .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4249 .set SRAM_BASE, 0x02000000
4250 .set SP_BASE, 0x0F300000
4251 .set UNK_BASE, 0x0F000000 /* Some internal device, but which one? */
4252 .set SPI_CGEN_BASE, 0x0E000000 /* Some internal device, but which one? */
4253 .set UNK3_BASE, 0x02014000 /* Some internal device, but which one? */
4254 .set STACK_BASE, 0x5600
4256 .set SP_TDRE, 2 /* status register bit -- TDR empty */
4257 .set SP_RDRF, 1 /* status register bit -- RDR full */
4260 .set SP_CR, 0 /* control register */
4261 .set SP_MR, 4 /* mode register */
4262 .set SP_RDR, 0x08 /* Read Data Register */
4263 .set SP_TDR, 0x0C /* Transmit Data Register */
4264 .set SP_CSR0, 0x30 /* chip select registers */
4268 .set NVRAM_CMD_RDSR, 5 /* read status register */
4269 .set NVRAM_CMD_READ, 3 /* read data */
4270 .set NVRAM_SR_RDY, 1 /* RDY bit. This bit is inverted */
4271 .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4272 serial output, since SO is normally high. But it
4273 does cause 8 clock cycles and thus 8 bits to be
4274 clocked in to the chip. See Atmel's SPI
4275 controller (e.g. AT91M55800) timing and 4K
4276 SPI EEPROM manuals */
4278 .set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */
4279 .set NVRAM_IMAGE, 0x02000200
4280 .set NVRAM_LENGTH, 0x0200
4281 .set MAC_ADDRESS_MIB, SRAM_BASE
4282 .set MAC_ADDRESS_LENGTH, 6
4283 .set MAC_BOOT_FLAG, 0x10
4305 mov r0, #CPSR_INITIAL
4306 msr CPSR_c, r0 /* This is probably unnecessary */
4308 /* I'm guessing this is initializing clock generator electronics for SPI */
4309 ldr r0, =SPI_CGEN_BASE
4334 ldr r1, =MAC_ADDRESS_MIB
4336 ldr r1, =NVRAM_IMAGE
4338 mov r1, #MAC_BOOT_FLAG
4341 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4344 mov r2, #0 /* 0th bytes of NVRAM */
4345 mov r3, #NVRAM_LENGTH
4346 mov r1, #0 /* not used in routine */
4347 ldr r0, =NVRAM_IMAGE
4353 .func Get_MAC_Addr, GET_MAC_ADDR
4356 mov r2, #0x120 /* address of MAC Address within NVRAM */
4357 mov r3, #MAC_ADDRESS_LENGTH
4358 mov r1, #0 /* not used in routine */
4359 ldr r0, =MAC_ADDRESS_MIB
4365 .func Delay9, DELAY9
4367 adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */
4376 .func SP_Init, SP_INIT
4380 str r1, [r0, #SP_CR] /* reset the SPI */
4382 str r1, [r0, #SP_CR] /* release SPI from reset state */
4384 str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4385 str r1, [r0, #SP_CR] /* enable the SPI */
4387 /* My guess would be this turns on the SPI clock */
4388 ldr r3, =SPI_CGEN_BASE
4394 str r1, [r0, #SP_CSR0]
4396 str r1, [r0, #SP_CSR1]
4397 str r1, [r0, #SP_CSR2]
4398 str r1, [r0, #SP_CSR3]
4399 ldr r1, [r0, #SP_SR]
4400 ldr r0, [r0, #SP_RDR]
4403 .func NVRAM_Init, NVRAM_INIT
4406 ldr r0, [r1, #SP_RDR]
4407 mov r0, #NVRAM_CMD_RDSR
4408 str r0, [r1, #SP_TDR]
4410 ldr r0, [r1, #SP_SR]
4414 mov r0, #SPI_8CLOCKS
4415 str r0, [r1, #SP_TDR]
4417 ldr r0, [r1, #SP_SR]
4421 ldr r0, [r1, #SP_RDR]
4423 ldr r0, [r1, #SP_SR]
4427 ldr r0, [r1, #SP_RDR]
4432 .func NVRAM_Xfer, NVRAM_XFER
4433 /* r0 = dest address */
4435 /* r2 = src address within NVRAM */
4438 stmdb sp!, {r4, r5, lr}
4439 mov r5, r0 /* save r0 (dest address) */
4440 mov r4, r3 /* save r3 (length) */
4441 mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */
4443 add r0, r0, #NVRAM_CMD_READ
4444 ldr r1, =NVRAM_SCRATCH
4445 strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */
4446 strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */
4449 tst r0, #NVRAM_SR_RDY
4453 mov r2, r4 /* length */
4454 mov r1, r5 /* dest address */
4455 mov r0, #2 /* bytes to transfer in command */
4457 ldmia sp!, {r4, r5, lr}
4461 .func NVRAM_Xfer2, NVRAM_XFER2
4463 stmdb sp!, {r4, r5, r6, lr}
4468 ldr r5, =NVRAM_SCRATCH
4471 str r6, [r4, #SP_TDR]
4473 ldr r6, [r4, #SP_SR]
4477 cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */
4480 mov r3, #SPI_8CLOCKS
4481 str r3, [r4, #SP_TDR]
4482 ldr r0, [r4, #SP_RDR]
4484 ldr r0, [r4, #SP_SR]
4487 ldr r0, [r4, #SP_RDR] /* what's this byte? It's the byte read while writing the TDR -- nonsense, because the NVRAM doesn't read and write at the same time */
4489 cmp r2, #0 /* r2 is # of bytes to copy in */
4492 ldr r5, [r4, #SP_SR]
4495 str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */
4497 ldr r5, [r4, #SP_SR]
4500 ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4501 strb r5, [r1], #1 /* postindexed */
4504 blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4508 ldmia sp!, {r4, r5, r6, lr}