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 <asm/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;
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(u_long a);
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 memcpy(skb_put(skb, priv->frag_len + 12),
1026 priv->frag_len + 12);
1027 skb->protocol = eth_type_trans(skb, priv->dev);
1028 skb->ip_summed = CHECKSUM_NONE;
1030 priv->dev->stats.rx_bytes += priv->frag_len + 12;
1031 priv->dev->stats.rx_packets++;
1035 priv->wstats.discard.fragment++;
1038 static void rx_done_irq(struct atmel_private *priv)
1041 struct ieee80211_hdr header;
1044 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1045 i < priv->host_info.rx_desc_count;
1048 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1049 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1050 u32 crc = 0xffffffff;
1052 if (status != RX_STATUS_SUCCESS) {
1053 if (status == 0xc1) /* determined by experiment */
1054 priv->wstats.discard.nwid++;
1056 priv->dev->stats.rx_errors++;
1060 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1061 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1063 if (msdu_size < 30) {
1064 priv->dev->stats.rx_errors++;
1068 /* Get header as far as end of seq_ctrl */
1069 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1070 frame_ctl = le16_to_cpu(header.frame_control);
1071 seq_control = le16_to_cpu(header.seq_ctrl);
1073 /* probe for CRC use here if needed once five packets have
1074 arrived with the same crc status, we assume we know what's
1075 happening and stop probing */
1076 if (priv->probe_crc) {
1077 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1078 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1080 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1082 if (priv->do_rx_crc) {
1083 if (priv->crc_ok_cnt++ > 5)
1084 priv->probe_crc = 0;
1086 if (priv->crc_ko_cnt++ > 5)
1087 priv->probe_crc = 0;
1091 /* don't CRC header when WEP in use */
1092 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1093 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1095 msdu_size -= 24; /* header */
1097 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1098 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1099 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1100 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1102 if (!more_fragments && packet_fragment_no == 0) {
1103 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1105 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1106 packet_sequence_no, packet_fragment_no, more_fragments);
1110 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1111 /* copy rest of packet into buffer */
1112 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1114 /* we use the same buffer for frag reassembly and control packets */
1115 eth_broadcast_addr(priv->frag_source);
1117 if (priv->do_rx_crc) {
1118 /* last 4 octets is crc */
1120 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1121 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1122 priv->dev->stats.rx_crc_errors++;
1127 atmel_management_frame(priv, &header, msdu_size,
1128 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1132 /* release descriptor */
1133 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1135 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1136 priv->rx_desc_head++;
1138 priv->rx_desc_head = 0;
1142 static irqreturn_t service_interrupt(int irq, void *dev_id)
1144 struct net_device *dev = (struct net_device *) dev_id;
1145 struct atmel_private *priv = netdev_priv(dev);
1148 static const u8 irq_order[] = {
1154 ISR_COMMAND_COMPLETE,
1159 if (priv->card && priv->present_callback &&
1160 !(*priv->present_callback)(priv->card))
1163 /* In this state upper-level code assumes it can mess with
1164 the card unhampered by interrupts which may change register state.
1165 Note that even though the card shouldn't generate interrupts
1166 the inturrupt line may be shared. This allows card setup
1167 to go on without disabling interrupts for a long time. */
1168 if (priv->station_state == STATION_STATE_DOWN)
1171 atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1174 if (!atmel_lock_mac(priv)) {
1175 /* failed to contact card */
1176 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1180 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1181 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1184 atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1185 return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1188 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1190 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1191 if (isr & irq_order[i])
1194 if (!atmel_lock_mac(priv)) {
1195 /* failed to contact card */
1196 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1200 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1201 isr ^= irq_order[i];
1202 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1203 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1205 switch (irq_order[i]) {
1207 case ISR_OUT_OF_RANGE:
1208 if (priv->operating_mode == IW_MODE_INFRA &&
1209 priv->station_state == STATION_STATE_READY) {
1210 priv->station_is_associated = 0;
1211 atmel_scan(priv, 1);
1215 case ISR_RxFRAMELOST:
1216 priv->wstats.discard.misc++;
1218 case ISR_RxCOMPLETE:
1222 case ISR_TxCOMPLETE:
1226 case ISR_FATAL_ERROR:
1227 printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1228 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1231 case ISR_COMMAND_COMPLETE:
1232 atmel_command_irq(priv);
1235 case ISR_IBSS_MERGE:
1236 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1237 priv->CurrentBSSID, 6);
1238 /* The WPA stuff cares about the current AP address */
1240 build_wpa_mib(priv);
1242 case ISR_GENERIC_IRQ:
1243 printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1249 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1251 struct atmel_private *priv = netdev_priv(dev);
1253 /* update the link quality here in case we are seeing no beacons
1254 at all to drive the process */
1255 atmel_smooth_qual(priv);
1257 priv->wstats.status = priv->station_state;
1259 if (priv->operating_mode == IW_MODE_INFRA) {
1260 if (priv->station_state != STATION_STATE_READY) {
1261 priv->wstats.qual.qual = 0;
1262 priv->wstats.qual.level = 0;
1263 priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1264 | IW_QUAL_LEVEL_INVALID);
1266 priv->wstats.qual.noise = 0;
1267 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1269 /* Quality levels cannot be determined in ad-hoc mode,
1270 because we can 'hear' more that one remote station. */
1271 priv->wstats.qual.qual = 0;
1272 priv->wstats.qual.level = 0;
1273 priv->wstats.qual.noise = 0;
1274 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1275 | IW_QUAL_LEVEL_INVALID
1276 | IW_QUAL_NOISE_INVALID;
1277 priv->wstats.miss.beacon = 0;
1280 return &priv->wstats;
1283 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
1285 if ((new_mtu < 68) || (new_mtu > 2312))
1291 static int atmel_set_mac_address(struct net_device *dev, void *p)
1293 struct sockaddr *addr = p;
1295 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1296 return atmel_open(dev);
1299 EXPORT_SYMBOL(atmel_open);
1301 int atmel_open(struct net_device *dev)
1303 struct atmel_private *priv = netdev_priv(dev);
1304 int i, channel, err;
1306 /* any scheduled timer is no longer needed and might screw things up.. */
1307 del_timer_sync(&priv->management_timer);
1309 /* Interrupts will not touch the card once in this state... */
1310 priv->station_state = STATION_STATE_DOWN;
1312 if (priv->new_SSID_size) {
1313 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1314 priv->SSID_size = priv->new_SSID_size;
1315 priv->new_SSID_size = 0;
1317 priv->BSS_list_entries = 0;
1319 priv->AuthenticationRequestRetryCnt = 0;
1320 priv->AssociationRequestRetryCnt = 0;
1321 priv->ReAssociationRequestRetryCnt = 0;
1322 priv->CurrentAuthentTransactionSeqNum = 0x0001;
1323 priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1325 priv->site_survey_state = SITE_SURVEY_IDLE;
1326 priv->station_is_associated = 0;
1328 err = reset_atmel_card(dev);
1332 if (priv->config_reg_domain) {
1333 priv->reg_domain = priv->config_reg_domain;
1334 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1336 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1337 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1338 if (priv->reg_domain == channel_table[i].reg_domain)
1340 if (i == ARRAY_SIZE(channel_table)) {
1341 priv->reg_domain = REG_DOMAIN_MKK1;
1342 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1346 if ((channel = atmel_validate_channel(priv, priv->channel)))
1347 priv->channel = channel;
1349 /* this moves station_state on.... */
1350 atmel_scan(priv, 1);
1352 atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1356 static int atmel_close(struct net_device *dev)
1358 struct atmel_private *priv = netdev_priv(dev);
1360 /* Send event to userspace that we are disassociating */
1361 if (priv->station_state == STATION_STATE_READY) {
1362 union iwreq_data wrqu;
1364 wrqu.data.length = 0;
1365 wrqu.data.flags = 0;
1366 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1367 eth_zero_addr(wrqu.ap_addr.sa_data);
1368 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1371 atmel_enter_state(priv, STATION_STATE_DOWN);
1373 if (priv->bus_type == BUS_TYPE_PCCARD)
1374 atmel_write16(dev, GCR, 0x0060);
1375 atmel_write16(dev, GCR, 0x0040);
1379 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1381 /* check that channel is OK, if so return zero,
1382 else return suitable default channel */
1385 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1386 if (priv->reg_domain == channel_table[i].reg_domain) {
1387 if (channel >= channel_table[i].min &&
1388 channel <= channel_table[i].max)
1391 return channel_table[i].min;
1396 static int atmel_proc_show(struct seq_file *m, void *v)
1398 struct atmel_private *priv = m->private;
1402 seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1404 if (priv->station_state != STATION_STATE_DOWN) {
1406 "Firmware version:\t%d.%d build %d\n"
1407 "Firmware location:\t",
1408 priv->host_info.major_version,
1409 priv->host_info.minor_version,
1410 priv->host_info.build_version);
1412 if (priv->card_type != CARD_TYPE_EEPROM)
1413 seq_puts(m, "on card\n");
1414 else if (priv->firmware)
1415 seq_printf(m, "%s loaded by host\n", priv->firmware_id);
1417 seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
1419 switch (priv->card_type) {
1420 case CARD_TYPE_PARALLEL_FLASH:
1421 c = "Parallel flash";
1423 case CARD_TYPE_SPI_FLASH:
1426 case CARD_TYPE_EEPROM:
1434 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1435 if (priv->reg_domain == channel_table[i].reg_domain)
1436 r = channel_table[i].name;
1438 seq_printf(m, "MAC memory type:\t%s\n", c);
1439 seq_printf(m, "Regulatory domain:\t%s\n", r);
1440 seq_printf(m, "Host CRC checking:\t%s\n",
1441 priv->do_rx_crc ? "On" : "Off");
1442 seq_printf(m, "WPA-capable firmware:\t%s\n",
1443 priv->use_wpa ? "Yes" : "No");
1446 switch (priv->station_state) {
1447 case STATION_STATE_SCANNING:
1450 case STATION_STATE_JOINNING:
1453 case STATION_STATE_AUTHENTICATING:
1454 s = "Authenticating";
1456 case STATION_STATE_ASSOCIATING:
1459 case STATION_STATE_READY:
1462 case STATION_STATE_REASSOCIATING:
1463 s = "Reassociating";
1465 case STATION_STATE_MGMT_ERROR:
1466 s = "Management error";
1468 case STATION_STATE_DOWN:
1475 seq_printf(m, "Current state:\t\t%s\n", s);
1479 static int atmel_proc_open(struct inode *inode, struct file *file)
1481 return single_open(file, atmel_proc_show, PDE_DATA(inode));
1484 static const struct file_operations atmel_proc_fops = {
1485 .open = atmel_proc_open,
1487 .llseek = seq_lseek,
1488 .release = single_release,
1491 static const struct net_device_ops atmel_netdev_ops = {
1492 .ndo_open = atmel_open,
1493 .ndo_stop = atmel_close,
1494 .ndo_change_mtu = atmel_change_mtu,
1495 .ndo_set_mac_address = atmel_set_mac_address,
1496 .ndo_start_xmit = start_tx,
1497 .ndo_do_ioctl = atmel_ioctl,
1498 .ndo_validate_addr = eth_validate_addr,
1501 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1502 const AtmelFWType fw_type,
1503 struct device *sys_dev,
1504 int (*card_present)(void *), void *card)
1506 struct net_device *dev;
1507 struct atmel_private *priv;
1510 /* Create the network device object. */
1511 dev = alloc_etherdev(sizeof(*priv));
1515 if (dev_alloc_name(dev, dev->name) < 0) {
1516 printk(KERN_ERR "atmel: Couldn't get name!\n");
1520 priv = netdev_priv(dev);
1522 priv->sys_dev = sys_dev;
1523 priv->present_callback = card_present;
1525 priv->firmware = NULL;
1526 priv->firmware_id[0] = '\0';
1527 priv->firmware_type = fw_type;
1528 if (firmware) /* module parameter */
1529 strcpy(priv->firmware_id, firmware);
1530 priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1531 priv->station_state = STATION_STATE_DOWN;
1532 priv->do_rx_crc = 0;
1533 /* For PCMCIA cards, some chips need CRC, some don't
1534 so we have to probe. */
1535 if (priv->bus_type == BUS_TYPE_PCCARD) {
1536 priv->probe_crc = 1;
1537 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1539 priv->probe_crc = 0;
1540 priv->last_qual = jiffies;
1541 priv->last_beacon_timestamp = 0;
1542 memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1543 eth_zero_addr(priv->BSSID);
1544 priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1545 priv->station_was_associated = 0;
1547 priv->last_survey = jiffies;
1548 priv->preamble = LONG_PREAMBLE;
1549 priv->operating_mode = IW_MODE_INFRA;
1550 priv->connect_to_any_BSS = 0;
1551 priv->config_reg_domain = 0;
1552 priv->reg_domain = 0;
1554 priv->auto_tx_rate = 1;
1556 priv->power_mode = 0;
1557 priv->SSID[0] = '\0';
1558 priv->SSID_size = 0;
1559 priv->new_SSID_size = 0;
1560 priv->frag_threshold = 2346;
1561 priv->rts_threshold = 2347;
1562 priv->short_retry = 7;
1563 priv->long_retry = 4;
1565 priv->wep_is_on = 0;
1566 priv->default_key = 0;
1567 priv->encryption_level = 0;
1568 priv->exclude_unencrypted = 0;
1569 priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1571 memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1572 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1574 priv->default_beacon_period = priv->beacon_period = 100;
1575 priv->listen_interval = 1;
1577 init_timer(&priv->management_timer);
1578 spin_lock_init(&priv->irqlock);
1579 spin_lock_init(&priv->timerlock);
1580 priv->management_timer.function = atmel_management_timer;
1581 priv->management_timer.data = (unsigned long) dev;
1583 dev->netdev_ops = &atmel_netdev_ops;
1584 dev->wireless_handlers = &atmel_handler_def;
1586 dev->base_addr = port;
1588 SET_NETDEV_DEV(dev, sys_dev);
1590 if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1591 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1595 if (!request_region(dev->base_addr, 32,
1596 priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) {
1600 if (register_netdev(dev))
1603 if (!probe_atmel_card(dev)) {
1604 unregister_netdev(dev);
1608 netif_carrier_off(dev);
1610 if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv))
1611 printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1613 printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1614 dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1619 release_region(dev->base_addr, 32);
1621 free_irq(dev->irq, dev);
1627 EXPORT_SYMBOL(init_atmel_card);
1629 void stop_atmel_card(struct net_device *dev)
1631 struct atmel_private *priv = netdev_priv(dev);
1633 /* put a brick on it... */
1634 if (priv->bus_type == BUS_TYPE_PCCARD)
1635 atmel_write16(dev, GCR, 0x0060);
1636 atmel_write16(dev, GCR, 0x0040);
1638 del_timer_sync(&priv->management_timer);
1639 unregister_netdev(dev);
1640 remove_proc_entry("driver/atmel", NULL);
1641 free_irq(dev->irq, dev);
1642 kfree(priv->firmware);
1643 release_region(dev->base_addr, 32);
1647 EXPORT_SYMBOL(stop_atmel_card);
1649 static int atmel_set_essid(struct net_device *dev,
1650 struct iw_request_info *info,
1651 struct iw_point *dwrq,
1654 struct atmel_private *priv = netdev_priv(dev);
1656 /* Check if we asked for `any' */
1657 if (dwrq->flags == 0) {
1658 priv->connect_to_any_BSS = 1;
1660 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1662 priv->connect_to_any_BSS = 0;
1664 /* Check the size of the string */
1665 if (dwrq->length > MAX_SSID_LENGTH)
1670 memcpy(priv->new_SSID, extra, dwrq->length);
1671 priv->new_SSID_size = dwrq->length;
1674 return -EINPROGRESS;
1677 static int atmel_get_essid(struct net_device *dev,
1678 struct iw_request_info *info,
1679 struct iw_point *dwrq,
1682 struct atmel_private *priv = netdev_priv(dev);
1684 /* Get the current SSID */
1685 if (priv->new_SSID_size != 0) {
1686 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1687 dwrq->length = priv->new_SSID_size;
1689 memcpy(extra, priv->SSID, priv->SSID_size);
1690 dwrq->length = priv->SSID_size;
1693 dwrq->flags = !priv->connect_to_any_BSS; /* active */
1698 static int atmel_get_wap(struct net_device *dev,
1699 struct iw_request_info *info,
1700 struct sockaddr *awrq,
1703 struct atmel_private *priv = netdev_priv(dev);
1704 memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1705 awrq->sa_family = ARPHRD_ETHER;
1710 static int atmel_set_encode(struct net_device *dev,
1711 struct iw_request_info *info,
1712 struct iw_point *dwrq,
1715 struct atmel_private *priv = netdev_priv(dev);
1717 /* Basic checking: do we have a key to set ?
1718 * Note : with the new API, it's impossible to get a NULL pointer.
1719 * Therefore, we need to check a key size == 0 instead.
1720 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1721 * when no key is present (only change flags), but older versions
1722 * don't do it. - Jean II */
1723 if (dwrq->length > 0) {
1724 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1725 int current_index = priv->default_key;
1726 /* Check the size of the key */
1727 if (dwrq->length > 13) {
1730 /* Check the index (none -> use current) */
1731 if (index < 0 || index >= 4)
1732 index = current_index;
1734 priv->default_key = index;
1735 /* Set the length */
1736 if (dwrq->length > 5)
1737 priv->wep_key_len[index] = 13;
1739 if (dwrq->length > 0)
1740 priv->wep_key_len[index] = 5;
1742 /* Disable the key */
1743 priv->wep_key_len[index] = 0;
1744 /* Check if the key is not marked as invalid */
1745 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1747 memset(priv->wep_keys[index], 0, 13);
1748 /* Copy the key in the driver */
1749 memcpy(priv->wep_keys[index], extra, dwrq->length);
1751 /* WE specify that if a valid key is set, encryption
1752 * should be enabled (user may turn it off later)
1753 * This is also how "iwconfig ethX key on" works */
1754 if (index == current_index &&
1755 priv->wep_key_len[index] > 0) {
1756 priv->wep_is_on = 1;
1757 priv->exclude_unencrypted = 1;
1758 if (priv->wep_key_len[index] > 5) {
1759 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1760 priv->encryption_level = 2;
1762 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1763 priv->encryption_level = 1;
1767 /* Do we want to just set the transmit key index ? */
1768 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1769 if (index >= 0 && index < 4) {
1770 priv->default_key = index;
1772 /* Don't complain if only change the mode */
1773 if (!(dwrq->flags & IW_ENCODE_MODE))
1776 /* Read the flags */
1777 if (dwrq->flags & IW_ENCODE_DISABLED) {
1778 priv->wep_is_on = 0;
1779 priv->encryption_level = 0;
1780 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1782 priv->wep_is_on = 1;
1783 if (priv->wep_key_len[priv->default_key] > 5) {
1784 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1785 priv->encryption_level = 2;
1787 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1788 priv->encryption_level = 1;
1791 if (dwrq->flags & IW_ENCODE_RESTRICTED)
1792 priv->exclude_unencrypted = 1;
1793 if (dwrq->flags & IW_ENCODE_OPEN)
1794 priv->exclude_unencrypted = 0;
1796 return -EINPROGRESS; /* Call commit handler */
1799 static int atmel_get_encode(struct net_device *dev,
1800 struct iw_request_info *info,
1801 struct iw_point *dwrq,
1804 struct atmel_private *priv = netdev_priv(dev);
1805 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1807 if (!priv->wep_is_on)
1808 dwrq->flags = IW_ENCODE_DISABLED;
1810 if (priv->exclude_unencrypted)
1811 dwrq->flags = IW_ENCODE_RESTRICTED;
1813 dwrq->flags = IW_ENCODE_OPEN;
1815 /* Which key do we want ? -1 -> tx index */
1816 if (index < 0 || index >= 4)
1817 index = priv->default_key;
1818 dwrq->flags |= index + 1;
1819 /* Copy the key to the user buffer */
1820 dwrq->length = priv->wep_key_len[index];
1821 if (dwrq->length > 16) {
1824 memset(extra, 0, 16);
1825 memcpy(extra, priv->wep_keys[index], dwrq->length);
1831 static int atmel_set_encodeext(struct net_device *dev,
1832 struct iw_request_info *info,
1833 union iwreq_data *wrqu,
1836 struct atmel_private *priv = netdev_priv(dev);
1837 struct iw_point *encoding = &wrqu->encoding;
1838 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1839 int idx, key_len, alg = ext->alg, set_key = 1;
1841 /* Determine and validate the key index */
1842 idx = encoding->flags & IW_ENCODE_INDEX;
1844 if (idx < 1 || idx > 4)
1848 idx = priv->default_key;
1850 if (encoding->flags & IW_ENCODE_DISABLED)
1851 alg = IW_ENCODE_ALG_NONE;
1853 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1854 priv->default_key = idx;
1855 set_key = ext->key_len > 0 ? 1 : 0;
1859 /* Set the requested key first */
1861 case IW_ENCODE_ALG_NONE:
1862 priv->wep_is_on = 0;
1863 priv->encryption_level = 0;
1864 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1866 case IW_ENCODE_ALG_WEP:
1867 if (ext->key_len > 5) {
1868 priv->wep_key_len[idx] = 13;
1869 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1870 priv->encryption_level = 2;
1871 } else if (ext->key_len > 0) {
1872 priv->wep_key_len[idx] = 5;
1873 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1874 priv->encryption_level = 1;
1878 priv->wep_is_on = 1;
1879 memset(priv->wep_keys[idx], 0, 13);
1880 key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1881 memcpy(priv->wep_keys[idx], ext->key, key_len);
1888 return -EINPROGRESS;
1891 static int atmel_get_encodeext(struct net_device *dev,
1892 struct iw_request_info *info,
1893 union iwreq_data *wrqu,
1896 struct atmel_private *priv = netdev_priv(dev);
1897 struct iw_point *encoding = &wrqu->encoding;
1898 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1899 int idx, max_key_len;
1901 max_key_len = encoding->length - sizeof(*ext);
1902 if (max_key_len < 0)
1905 idx = encoding->flags & IW_ENCODE_INDEX;
1907 if (idx < 1 || idx > 4)
1911 idx = priv->default_key;
1913 encoding->flags = idx + 1;
1914 memset(ext, 0, sizeof(*ext));
1916 if (!priv->wep_is_on) {
1917 ext->alg = IW_ENCODE_ALG_NONE;
1919 encoding->flags |= IW_ENCODE_DISABLED;
1921 if (priv->encryption_level > 0)
1922 ext->alg = IW_ENCODE_ALG_WEP;
1926 ext->key_len = priv->wep_key_len[idx];
1927 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1928 encoding->flags |= IW_ENCODE_ENABLED;
1934 static int atmel_set_auth(struct net_device *dev,
1935 struct iw_request_info *info,
1936 union iwreq_data *wrqu, char *extra)
1938 struct atmel_private *priv = netdev_priv(dev);
1939 struct iw_param *param = &wrqu->param;
1941 switch (param->flags & IW_AUTH_INDEX) {
1942 case IW_AUTH_WPA_VERSION:
1943 case IW_AUTH_CIPHER_PAIRWISE:
1944 case IW_AUTH_CIPHER_GROUP:
1945 case IW_AUTH_KEY_MGMT:
1946 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1947 case IW_AUTH_PRIVACY_INVOKED:
1949 * atmel does not use these parameters
1953 case IW_AUTH_DROP_UNENCRYPTED:
1954 priv->exclude_unencrypted = param->value ? 1 : 0;
1957 case IW_AUTH_80211_AUTH_ALG: {
1958 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1959 priv->exclude_unencrypted = 1;
1960 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1961 priv->exclude_unencrypted = 0;
1967 case IW_AUTH_WPA_ENABLED:
1968 /* Silently accept disable of WPA */
1969 if (param->value > 0)
1976 return -EINPROGRESS;
1979 static int atmel_get_auth(struct net_device *dev,
1980 struct iw_request_info *info,
1981 union iwreq_data *wrqu, char *extra)
1983 struct atmel_private *priv = netdev_priv(dev);
1984 struct iw_param *param = &wrqu->param;
1986 switch (param->flags & IW_AUTH_INDEX) {
1987 case IW_AUTH_DROP_UNENCRYPTED:
1988 param->value = priv->exclude_unencrypted;
1991 case IW_AUTH_80211_AUTH_ALG:
1992 if (priv->exclude_unencrypted == 1)
1993 param->value = IW_AUTH_ALG_SHARED_KEY;
1995 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1998 case IW_AUTH_WPA_ENABLED:
2009 static int atmel_get_name(struct net_device *dev,
2010 struct iw_request_info *info,
2014 strcpy(cwrq, "IEEE 802.11-DS");
2018 static int atmel_set_rate(struct net_device *dev,
2019 struct iw_request_info *info,
2020 struct iw_param *vwrq,
2023 struct atmel_private *priv = netdev_priv(dev);
2025 if (vwrq->fixed == 0) {
2027 priv->auto_tx_rate = 1;
2029 priv->auto_tx_rate = 0;
2031 /* Which type of value ? */
2032 if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2033 /* Setting by rate index */
2034 priv->tx_rate = vwrq->value;
2036 /* Setting by frequency value */
2037 switch (vwrq->value) {
2056 return -EINPROGRESS;
2059 static int atmel_set_mode(struct net_device *dev,
2060 struct iw_request_info *info,
2064 struct atmel_private *priv = netdev_priv(dev);
2066 if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2069 priv->operating_mode = *uwrq;
2070 return -EINPROGRESS;
2073 static int atmel_get_mode(struct net_device *dev,
2074 struct iw_request_info *info,
2078 struct atmel_private *priv = netdev_priv(dev);
2080 *uwrq = priv->operating_mode;
2084 static int atmel_get_rate(struct net_device *dev,
2085 struct iw_request_info *info,
2086 struct iw_param *vwrq,
2089 struct atmel_private *priv = netdev_priv(dev);
2091 if (priv->auto_tx_rate) {
2093 vwrq->value = 11000000;
2096 switch (priv->tx_rate) {
2098 vwrq->value = 1000000;
2101 vwrq->value = 2000000;
2104 vwrq->value = 5500000;
2107 vwrq->value = 11000000;
2114 static int atmel_set_power(struct net_device *dev,
2115 struct iw_request_info *info,
2116 struct iw_param *vwrq,
2119 struct atmel_private *priv = netdev_priv(dev);
2120 priv->power_mode = vwrq->disabled ? 0 : 1;
2121 return -EINPROGRESS;
2124 static int atmel_get_power(struct net_device *dev,
2125 struct iw_request_info *info,
2126 struct iw_param *vwrq,
2129 struct atmel_private *priv = netdev_priv(dev);
2130 vwrq->disabled = priv->power_mode ? 0 : 1;
2131 vwrq->flags = IW_POWER_ON;
2135 static int atmel_set_retry(struct net_device *dev,
2136 struct iw_request_info *info,
2137 struct iw_param *vwrq,
2140 struct atmel_private *priv = netdev_priv(dev);
2142 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2143 if (vwrq->flags & IW_RETRY_LONG)
2144 priv->long_retry = vwrq->value;
2145 else if (vwrq->flags & IW_RETRY_SHORT)
2146 priv->short_retry = vwrq->value;
2148 /* No modifier : set both */
2149 priv->long_retry = vwrq->value;
2150 priv->short_retry = vwrq->value;
2152 return -EINPROGRESS;
2158 static int atmel_get_retry(struct net_device *dev,
2159 struct iw_request_info *info,
2160 struct iw_param *vwrq,
2163 struct atmel_private *priv = netdev_priv(dev);
2165 vwrq->disabled = 0; /* Can't be disabled */
2167 /* Note : by default, display the short retry number */
2168 if (vwrq->flags & IW_RETRY_LONG) {
2169 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2170 vwrq->value = priv->long_retry;
2172 vwrq->flags = IW_RETRY_LIMIT;
2173 vwrq->value = priv->short_retry;
2174 if (priv->long_retry != priv->short_retry)
2175 vwrq->flags |= IW_RETRY_SHORT;
2181 static int atmel_set_rts(struct net_device *dev,
2182 struct iw_request_info *info,
2183 struct iw_param *vwrq,
2186 struct atmel_private *priv = netdev_priv(dev);
2187 int rthr = vwrq->value;
2191 if ((rthr < 0) || (rthr > 2347)) {
2194 priv->rts_threshold = rthr;
2196 return -EINPROGRESS; /* Call commit handler */
2199 static int atmel_get_rts(struct net_device *dev,
2200 struct iw_request_info *info,
2201 struct iw_param *vwrq,
2204 struct atmel_private *priv = netdev_priv(dev);
2206 vwrq->value = priv->rts_threshold;
2207 vwrq->disabled = (vwrq->value >= 2347);
2213 static int atmel_set_frag(struct net_device *dev,
2214 struct iw_request_info *info,
2215 struct iw_param *vwrq,
2218 struct atmel_private *priv = netdev_priv(dev);
2219 int fthr = vwrq->value;
2223 if ((fthr < 256) || (fthr > 2346)) {
2226 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
2227 priv->frag_threshold = fthr;
2229 return -EINPROGRESS; /* Call commit handler */
2232 static int atmel_get_frag(struct net_device *dev,
2233 struct iw_request_info *info,
2234 struct iw_param *vwrq,
2237 struct atmel_private *priv = netdev_priv(dev);
2239 vwrq->value = priv->frag_threshold;
2240 vwrq->disabled = (vwrq->value >= 2346);
2246 static int atmel_set_freq(struct net_device *dev,
2247 struct iw_request_info *info,
2248 struct iw_freq *fwrq,
2251 struct atmel_private *priv = netdev_priv(dev);
2252 int rc = -EINPROGRESS; /* Call commit handler */
2254 /* If setting by frequency, convert to a channel */
2256 int f = fwrq->m / 100000;
2258 /* Hack to fall through... */
2260 fwrq->m = ieee80211_frequency_to_channel(f);
2262 /* Setting by channel number */
2263 if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2266 int channel = fwrq->m;
2267 if (atmel_validate_channel(priv, channel) == 0) {
2268 priv->channel = channel;
2276 static int atmel_get_freq(struct net_device *dev,
2277 struct iw_request_info *info,
2278 struct iw_freq *fwrq,
2281 struct atmel_private *priv = netdev_priv(dev);
2283 fwrq->m = priv->channel;
2288 static int atmel_set_scan(struct net_device *dev,
2289 struct iw_request_info *info,
2290 struct iw_point *dwrq,
2293 struct atmel_private *priv = netdev_priv(dev);
2294 unsigned long flags;
2296 /* Note : you may have realised that, as this is a SET operation,
2297 * this is privileged and therefore a normal user can't
2299 * This is not an error, while the device perform scanning,
2300 * traffic doesn't flow, so it's a perfect DoS...
2303 if (priv->station_state == STATION_STATE_DOWN)
2306 /* Timeout old surveys. */
2307 if (time_after(jiffies, priv->last_survey + 20 * HZ))
2308 priv->site_survey_state = SITE_SURVEY_IDLE;
2309 priv->last_survey = jiffies;
2311 /* Initiate a scan command */
2312 if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2315 del_timer_sync(&priv->management_timer);
2316 spin_lock_irqsave(&priv->irqlock, flags);
2318 priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2319 priv->fast_scan = 0;
2320 atmel_scan(priv, 0);
2321 spin_unlock_irqrestore(&priv->irqlock, flags);
2326 static int atmel_get_scan(struct net_device *dev,
2327 struct iw_request_info *info,
2328 struct iw_point *dwrq,
2331 struct atmel_private *priv = netdev_priv(dev);
2333 char *current_ev = extra;
2334 struct iw_event iwe;
2336 if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2339 for (i = 0; i < priv->BSS_list_entries; i++) {
2340 iwe.cmd = SIOCGIWAP;
2341 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2342 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2343 current_ev = iwe_stream_add_event(info, current_ev,
2344 extra + IW_SCAN_MAX_DATA,
2345 &iwe, IW_EV_ADDR_LEN);
2347 iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
2348 if (iwe.u.data.length > 32)
2349 iwe.u.data.length = 32;
2350 iwe.cmd = SIOCGIWESSID;
2351 iwe.u.data.flags = 1;
2352 current_ev = iwe_stream_add_point(info, current_ev,
2353 extra + IW_SCAN_MAX_DATA,
2354 &iwe, priv->BSSinfo[i].SSID);
2356 iwe.cmd = SIOCGIWMODE;
2357 iwe.u.mode = priv->BSSinfo[i].BSStype;
2358 current_ev = iwe_stream_add_event(info, current_ev,
2359 extra + IW_SCAN_MAX_DATA,
2360 &iwe, IW_EV_UINT_LEN);
2362 iwe.cmd = SIOCGIWFREQ;
2363 iwe.u.freq.m = priv->BSSinfo[i].channel;
2365 current_ev = iwe_stream_add_event(info, current_ev,
2366 extra + IW_SCAN_MAX_DATA,
2367 &iwe, IW_EV_FREQ_LEN);
2369 /* Add quality statistics */
2371 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2372 iwe.u.qual.qual = iwe.u.qual.level;
2373 /* iwe.u.qual.noise = SOMETHING */
2374 current_ev = iwe_stream_add_event(info, current_ev,
2375 extra + IW_SCAN_MAX_DATA,
2376 &iwe, IW_EV_QUAL_LEN);
2379 iwe.cmd = SIOCGIWENCODE;
2380 if (priv->BSSinfo[i].UsingWEP)
2381 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2383 iwe.u.data.flags = IW_ENCODE_DISABLED;
2384 iwe.u.data.length = 0;
2385 current_ev = iwe_stream_add_point(info, current_ev,
2386 extra + IW_SCAN_MAX_DATA,
2390 /* Length of data */
2391 dwrq->length = (current_ev - extra);
2397 static int atmel_get_range(struct net_device *dev,
2398 struct iw_request_info *info,
2399 struct iw_point *dwrq,
2402 struct atmel_private *priv = netdev_priv(dev);
2403 struct iw_range *range = (struct iw_range *) extra;
2406 dwrq->length = sizeof(struct iw_range);
2407 memset(range, 0, sizeof(struct iw_range));
2408 range->min_nwid = 0x0000;
2409 range->max_nwid = 0x0000;
2410 range->num_channels = 0;
2411 for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2412 if (priv->reg_domain == channel_table[j].reg_domain) {
2413 range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2416 if (range->num_channels != 0) {
2417 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2418 range->freq[k].i = i; /* List index */
2420 /* Values in MHz -> * 10^5 * 10 */
2421 range->freq[k].m = 100000 *
2422 ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2423 range->freq[k++].e = 1;
2425 range->num_frequency = k;
2428 range->max_qual.qual = 100;
2429 range->max_qual.level = 100;
2430 range->max_qual.noise = 0;
2431 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2433 range->avg_qual.qual = 50;
2434 range->avg_qual.level = 50;
2435 range->avg_qual.noise = 0;
2436 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2438 range->sensitivity = 0;
2440 range->bitrate[0] = 1000000;
2441 range->bitrate[1] = 2000000;
2442 range->bitrate[2] = 5500000;
2443 range->bitrate[3] = 11000000;
2444 range->num_bitrates = 4;
2447 range->max_rts = 2347;
2448 range->min_frag = 256;
2449 range->max_frag = 2346;
2451 range->encoding_size[0] = 5;
2452 range->encoding_size[1] = 13;
2453 range->num_encoding_sizes = 2;
2454 range->max_encoding_tokens = 4;
2456 range->pmp_flags = IW_POWER_ON;
2457 range->pmt_flags = IW_POWER_ON;
2460 range->we_version_source = WIRELESS_EXT;
2461 range->we_version_compiled = WIRELESS_EXT;
2462 range->retry_capa = IW_RETRY_LIMIT ;
2463 range->retry_flags = IW_RETRY_LIMIT;
2464 range->r_time_flags = 0;
2465 range->min_retry = 1;
2466 range->max_retry = 65535;
2471 static int atmel_set_wap(struct net_device *dev,
2472 struct iw_request_info *info,
2473 struct sockaddr *awrq,
2476 struct atmel_private *priv = netdev_priv(dev);
2478 static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2479 static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2480 unsigned long flags;
2482 if (awrq->sa_family != ARPHRD_ETHER)
2485 if (!memcmp(any, awrq->sa_data, 6) ||
2486 !memcmp(off, awrq->sa_data, 6)) {
2487 del_timer_sync(&priv->management_timer);
2488 spin_lock_irqsave(&priv->irqlock, flags);
2489 atmel_scan(priv, 1);
2490 spin_unlock_irqrestore(&priv->irqlock, flags);
2494 for (i = 0; i < priv->BSS_list_entries; i++) {
2495 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2496 if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2498 } else if (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2501 del_timer_sync(&priv->management_timer);
2502 spin_lock_irqsave(&priv->irqlock, flags);
2503 atmel_join_bss(priv, i);
2504 spin_unlock_irqrestore(&priv->irqlock, flags);
2513 static int atmel_config_commit(struct net_device *dev,
2514 struct iw_request_info *info, /* NULL */
2515 void *zwrq, /* NULL */
2516 char *extra) /* NULL */
2518 return atmel_open(dev);
2521 static const iw_handler atmel_handler[] =
2523 (iw_handler) atmel_config_commit, /* SIOCSIWCOMMIT */
2524 (iw_handler) atmel_get_name, /* SIOCGIWNAME */
2525 (iw_handler) NULL, /* SIOCSIWNWID */
2526 (iw_handler) NULL, /* SIOCGIWNWID */
2527 (iw_handler) atmel_set_freq, /* SIOCSIWFREQ */
2528 (iw_handler) atmel_get_freq, /* SIOCGIWFREQ */
2529 (iw_handler) atmel_set_mode, /* SIOCSIWMODE */
2530 (iw_handler) atmel_get_mode, /* SIOCGIWMODE */
2531 (iw_handler) NULL, /* SIOCSIWSENS */
2532 (iw_handler) NULL, /* SIOCGIWSENS */
2533 (iw_handler) NULL, /* SIOCSIWRANGE */
2534 (iw_handler) atmel_get_range, /* SIOCGIWRANGE */
2535 (iw_handler) NULL, /* SIOCSIWPRIV */
2536 (iw_handler) NULL, /* SIOCGIWPRIV */
2537 (iw_handler) NULL, /* SIOCSIWSTATS */
2538 (iw_handler) NULL, /* SIOCGIWSTATS */
2539 (iw_handler) NULL, /* SIOCSIWSPY */
2540 (iw_handler) NULL, /* SIOCGIWSPY */
2541 (iw_handler) NULL, /* -- hole -- */
2542 (iw_handler) NULL, /* -- hole -- */
2543 (iw_handler) atmel_set_wap, /* SIOCSIWAP */
2544 (iw_handler) atmel_get_wap, /* SIOCGIWAP */
2545 (iw_handler) NULL, /* -- hole -- */
2546 (iw_handler) NULL, /* SIOCGIWAPLIST */
2547 (iw_handler) atmel_set_scan, /* SIOCSIWSCAN */
2548 (iw_handler) atmel_get_scan, /* SIOCGIWSCAN */
2549 (iw_handler) atmel_set_essid, /* SIOCSIWESSID */
2550 (iw_handler) atmel_get_essid, /* SIOCGIWESSID */
2551 (iw_handler) NULL, /* SIOCSIWNICKN */
2552 (iw_handler) NULL, /* SIOCGIWNICKN */
2553 (iw_handler) NULL, /* -- hole -- */
2554 (iw_handler) NULL, /* -- hole -- */
2555 (iw_handler) atmel_set_rate, /* SIOCSIWRATE */
2556 (iw_handler) atmel_get_rate, /* SIOCGIWRATE */
2557 (iw_handler) atmel_set_rts, /* SIOCSIWRTS */
2558 (iw_handler) atmel_get_rts, /* SIOCGIWRTS */
2559 (iw_handler) atmel_set_frag, /* SIOCSIWFRAG */
2560 (iw_handler) atmel_get_frag, /* SIOCGIWFRAG */
2561 (iw_handler) NULL, /* SIOCSIWTXPOW */
2562 (iw_handler) NULL, /* SIOCGIWTXPOW */
2563 (iw_handler) atmel_set_retry, /* SIOCSIWRETRY */
2564 (iw_handler) atmel_get_retry, /* SIOCGIWRETRY */
2565 (iw_handler) atmel_set_encode, /* SIOCSIWENCODE */
2566 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */
2567 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */
2568 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */
2569 (iw_handler) NULL, /* -- hole -- */
2570 (iw_handler) NULL, /* -- hole -- */
2571 (iw_handler) NULL, /* SIOCSIWGENIE */
2572 (iw_handler) NULL, /* SIOCGIWGENIE */
2573 (iw_handler) atmel_set_auth, /* SIOCSIWAUTH */
2574 (iw_handler) atmel_get_auth, /* SIOCGIWAUTH */
2575 (iw_handler) atmel_set_encodeext, /* SIOCSIWENCODEEXT */
2576 (iw_handler) atmel_get_encodeext, /* SIOCGIWENCODEEXT */
2577 (iw_handler) NULL, /* SIOCSIWPMKSA */
2580 static const iw_handler atmel_private_handler[] =
2582 NULL, /* SIOCIWFIRSTPRIV */
2585 struct atmel_priv_ioctl {
2587 unsigned char __user *data;
2591 #define ATMELFWL SIOCIWFIRSTPRIV
2592 #define ATMELIDIFC ATMELFWL + 1
2593 #define ATMELRD ATMELFWL + 2
2594 #define ATMELMAGIC 0x51807
2595 #define REGDOMAINSZ 20
2597 static const struct iw_priv_args atmel_private_args[] = {
2600 .set_args = IW_PRIV_TYPE_BYTE
2601 | IW_PRIV_SIZE_FIXED
2602 | sizeof(struct atmel_priv_ioctl),
2603 .get_args = IW_PRIV_TYPE_NONE,
2607 .set_args = IW_PRIV_TYPE_NONE,
2608 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2609 .name = "atmelidifc"
2612 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2613 .get_args = IW_PRIV_TYPE_NONE,
2618 static const struct iw_handler_def atmel_handler_def = {
2619 .num_standard = ARRAY_SIZE(atmel_handler),
2620 .num_private = ARRAY_SIZE(atmel_private_handler),
2621 .num_private_args = ARRAY_SIZE(atmel_private_args),
2622 .standard = (iw_handler *) atmel_handler,
2623 .private = (iw_handler *) atmel_private_handler,
2624 .private_args = (struct iw_priv_args *) atmel_private_args,
2625 .get_wireless_stats = atmel_get_wireless_stats
2628 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2631 struct atmel_private *priv = netdev_priv(dev);
2632 struct atmel_priv_ioctl com;
2633 struct iwreq *wrq = (struct iwreq *) rq;
2634 unsigned char *new_firmware;
2635 char domain[REGDOMAINSZ + 1];
2639 wrq->u.param.value = ATMELMAGIC;
2643 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2648 if (!capable(CAP_NET_ADMIN)) {
2653 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2658 if (copy_from_user(new_firmware, com.data, com.len)) {
2659 kfree(new_firmware);
2664 kfree(priv->firmware);
2666 priv->firmware = new_firmware;
2667 priv->firmware_length = com.len;
2668 strncpy(priv->firmware_id, com.id, 31);
2669 priv->firmware_id[31] = '\0';
2673 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2678 if (!capable(CAP_NET_ADMIN)) {
2683 domain[REGDOMAINSZ] = 0;
2685 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2686 if (!strcasecmp(channel_table[i].name, domain)) {
2687 priv->config_reg_domain = channel_table[i].reg_domain;
2692 if (rc == 0 && priv->station_state != STATION_STATE_DOWN)
2693 rc = atmel_open(dev);
2712 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2714 int old_state = priv->station_state;
2716 if (new_state == old_state)
2719 priv->station_state = new_state;
2721 if (new_state == STATION_STATE_READY) {
2722 netif_start_queue(priv->dev);
2723 netif_carrier_on(priv->dev);
2726 if (old_state == STATION_STATE_READY) {
2727 netif_carrier_off(priv->dev);
2728 if (netif_running(priv->dev))
2729 netif_stop_queue(priv->dev);
2730 priv->last_beacon_timestamp = 0;
2734 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2738 u8 SSID[MAX_SSID_LENGTH];
2742 __le16 min_channel_time;
2743 __le16 max_channel_time;
2748 eth_broadcast_addr(cmd.BSSID);
2750 if (priv->fast_scan) {
2751 cmd.SSID_size = priv->SSID_size;
2752 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2753 cmd.min_channel_time = cpu_to_le16(10);
2754 cmd.max_channel_time = cpu_to_le16(50);
2756 priv->BSS_list_entries = 0;
2758 cmd.min_channel_time = cpu_to_le16(10);
2759 cmd.max_channel_time = cpu_to_le16(120);
2765 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2767 cmd.channel = (priv->channel & 0x7f);
2768 cmd.scan_type = SCAN_TYPE_ACTIVE;
2769 cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2770 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2772 atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2774 /* This must come after all hardware access to avoid being messed up
2775 by stuff happening in interrupt context after we leave STATE_DOWN */
2776 atmel_enter_state(priv, STATION_STATE_SCANNING);
2779 static void join(struct atmel_private *priv, int type)
2783 u8 SSID[MAX_SSID_LENGTH];
2784 u8 BSS_type; /* this is a short in a scan command - weird */
2791 cmd.SSID_size = priv->SSID_size;
2792 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2793 memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2794 cmd.channel = (priv->channel & 0x7f);
2795 cmd.BSS_type = type;
2796 cmd.timeout = cpu_to_le16(2000);
2798 atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2801 static void start(struct atmel_private *priv, int type)
2805 u8 SSID[MAX_SSID_LENGTH];
2812 cmd.SSID_size = priv->SSID_size;
2813 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2814 memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2815 cmd.BSS_type = type;
2816 cmd.channel = (priv->channel & 0x7f);
2818 atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2821 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2825 int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2826 SHORT_PREAMBLE : LONG_PREAMBLE;
2828 if (priv->preamble != new) {
2829 priv->preamble = new;
2831 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2834 if (priv->channel != channel) {
2835 priv->channel = channel;
2837 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2841 priv->station_is_associated = 0;
2842 atmel_enter_state(priv, STATION_STATE_JOINNING);
2844 if (priv->operating_mode == IW_MODE_INFRA)
2845 join(priv, BSS_TYPE_INFRASTRUCTURE);
2847 join(priv, BSS_TYPE_AD_HOC);
2851 static void send_authentication_request(struct atmel_private *priv, u16 system,
2852 u8 *challenge, int challenge_len)
2854 struct ieee80211_hdr header;
2855 struct auth_body auth;
2857 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2858 header.duration_id = cpu_to_le16(0x8000);
2859 header.seq_ctrl = 0;
2860 memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2861 memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2862 memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2864 if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2865 /* no WEP for authentication frames with TrSeqNo 1 */
2866 header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2868 auth.alg = cpu_to_le16(system);
2871 auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2872 priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2873 priv->CurrentAuthentTransactionSeqNum += 2;
2875 if (challenge_len != 0) {
2876 auth.el_id = 16; /* challenge_text */
2877 auth.chall_text_len = challenge_len;
2878 memcpy(auth.chall_text, challenge, challenge_len);
2879 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2881 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2885 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2889 struct ieee80211_hdr header;
2890 struct ass_req_format {
2892 __le16 listen_interval;
2893 u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2896 u8 ssid[MAX_SSID_LENGTH];
2902 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2903 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2904 header.duration_id = cpu_to_le16(0x8000);
2905 header.seq_ctrl = 0;
2907 memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2908 memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2909 memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2911 body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2912 if (priv->wep_is_on)
2913 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2914 if (priv->preamble == SHORT_PREAMBLE)
2915 body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2917 body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2919 /* current AP address - only in reassoc frame */
2921 memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2922 ssid_el_p = &body.ssid_el_id;
2923 bodysize = 18 + priv->SSID_size;
2925 ssid_el_p = &body.ap[0];
2926 bodysize = 12 + priv->SSID_size;
2929 ssid_el_p[0] = WLAN_EID_SSID;
2930 ssid_el_p[1] = priv->SSID_size;
2931 memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2932 ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2933 ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2934 memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2936 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2939 static int is_frame_from_current_bss(struct atmel_private *priv,
2940 struct ieee80211_hdr *header)
2942 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2943 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2945 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2948 static int retrieve_bss(struct atmel_private *priv)
2951 int max_rssi = -128;
2954 if (priv->BSS_list_entries == 0)
2957 if (priv->connect_to_any_BSS) {
2958 /* Select a BSS with the max-RSSI but of the same type and of
2959 the same WEP mode and that it is not marked as 'bad' (i.e.
2960 we had previously failed to connect to this BSS with the
2961 settings that we currently use) */
2962 priv->current_BSS = 0;
2963 for (i = 0; i < priv->BSS_list_entries; i++) {
2964 if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2965 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2966 (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2967 !(priv->BSSinfo[i].channel & 0x80)) {
2968 max_rssi = priv->BSSinfo[i].RSSI;
2969 priv->current_BSS = max_index = i;
2975 for (i = 0; i < priv->BSS_list_entries; i++) {
2976 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2977 memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2978 priv->operating_mode == priv->BSSinfo[i].BSStype &&
2979 atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2980 if (priv->BSSinfo[i].RSSI >= max_rssi) {
2981 max_rssi = priv->BSSinfo[i].RSSI;
2989 static void store_bss_info(struct atmel_private *priv,
2990 struct ieee80211_hdr *header, u16 capability,
2991 u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2992 u8 *ssid, int is_beacon)
2994 u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2997 for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2998 if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
3001 /* If we process a probe and an entry from this BSS exists
3002 we will update the BSS entry with the info from this BSS.
3003 If we process a beacon we will only update RSSI */
3006 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
3008 index = priv->BSS_list_entries++;
3009 memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
3010 priv->BSSinfo[index].RSSI = rssi;
3012 if (rssi > priv->BSSinfo[index].RSSI)
3013 priv->BSSinfo[index].RSSI = rssi;
3018 priv->BSSinfo[index].channel = channel;
3019 priv->BSSinfo[index].beacon_period = beacon_period;
3020 priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3021 memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3022 priv->BSSinfo[index].SSIDsize = ssid_len;
3024 if (capability & WLAN_CAPABILITY_IBSS)
3025 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3026 else if (capability & WLAN_CAPABILITY_ESS)
3027 priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3029 priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3030 SHORT_PREAMBLE : LONG_PREAMBLE;
3033 static void authenticate(struct atmel_private *priv, u16 frame_len)
3035 struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3036 u16 status = le16_to_cpu(auth->status);
3037 u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3038 u16 system = le16_to_cpu(auth->alg);
3040 if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3042 if (priv->station_was_associated) {
3043 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3044 send_association_request(priv, 1);
3047 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3048 send_association_request(priv, 0);
3053 if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3054 int should_associate = 0;
3056 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3059 if (system == WLAN_AUTH_OPEN) {
3060 if (trans_seq_no == 0x0002) {
3061 should_associate = 1;
3063 } else if (system == WLAN_AUTH_SHARED_KEY) {
3064 if (trans_seq_no == 0x0002 &&
3065 auth->el_id == WLAN_EID_CHALLENGE) {
3066 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3068 } else if (trans_seq_no == 0x0004) {
3069 should_associate = 1;
3073 if (should_associate) {
3074 if (priv->station_was_associated) {
3075 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3076 send_association_request(priv, 1);
3079 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3080 send_association_request(priv, 0);
3086 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3087 /* Flip back and forth between WEP auth modes until the max
3088 * authentication tries has been exceeded.
3090 if (system == WLAN_AUTH_OPEN) {
3091 priv->CurrentAuthentTransactionSeqNum = 0x001;
3092 priv->exclude_unencrypted = 1;
3093 send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3095 } else if (system == WLAN_AUTH_SHARED_KEY
3096 && priv->wep_is_on) {
3097 priv->CurrentAuthentTransactionSeqNum = 0x001;
3098 priv->exclude_unencrypted = 0;
3099 send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3101 } else if (priv->connect_to_any_BSS) {
3104 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3106 if ((bss_index = retrieve_bss(priv)) != -1) {
3107 atmel_join_bss(priv, bss_index);
3113 priv->AuthenticationRequestRetryCnt = 0;
3114 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3115 priv->station_is_associated = 0;
3118 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3120 struct ass_resp_format {
3127 } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3129 u16 status = le16_to_cpu(ass_resp->status);
3130 u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3131 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3133 union iwreq_data wrqu;
3135 if (frame_len < 8 + rates_len)
3138 if (status == WLAN_STATUS_SUCCESS) {
3139 if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3140 priv->AssociationRequestRetryCnt = 0;
3142 priv->ReAssociationRequestRetryCnt = 0;
3144 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3145 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3146 atmel_set_mib(priv, Phy_Mib_Type,
3147 PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3148 if (priv->power_mode == 0) {
3149 priv->listen_interval = 1;
3150 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3151 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3152 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3153 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3155 priv->listen_interval = 2;
3156 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3157 MAC_MGMT_MIB_PS_MODE_POS, PS_MODE);
3158 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3159 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3162 priv->station_is_associated = 1;
3163 priv->station_was_associated = 1;
3164 atmel_enter_state(priv, STATION_STATE_READY);
3166 /* Send association event to userspace */
3167 wrqu.data.length = 0;
3168 wrqu.data.flags = 0;
3169 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3170 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3171 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3176 if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3177 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3178 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3179 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3180 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3181 priv->AssociationRequestRetryCnt++;
3182 send_association_request(priv, 0);
3186 if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3187 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3188 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3189 priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3190 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3191 priv->ReAssociationRequestRetryCnt++;
3192 send_association_request(priv, 1);
3196 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3197 priv->station_is_associated = 0;
3199 if (priv->connect_to_any_BSS) {
3201 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3203 if ((bss_index = retrieve_bss(priv)) != -1)
3204 atmel_join_bss(priv, bss_index);
3208 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3210 struct bss_info *bss = &priv->BSSinfo[bss_index];
3212 memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3213 memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3215 /* The WPA stuff cares about the current AP address */
3217 build_wpa_mib(priv);
3219 /* When switching to AdHoc turn OFF Power Save if needed */
3221 if (bss->BSStype == IW_MODE_ADHOC &&
3222 priv->operating_mode != IW_MODE_ADHOC &&
3224 priv->power_mode = 0;
3225 priv->listen_interval = 1;
3226 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3227 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3228 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3229 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3232 priv->operating_mode = bss->BSStype;
3233 priv->channel = bss->channel & 0x7f;
3234 priv->beacon_period = bss->beacon_period;
3236 if (priv->preamble != bss->preamble) {
3237 priv->preamble = bss->preamble;
3238 atmel_set_mib8(priv, Local_Mib_Type,
3239 LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3242 if (!priv->wep_is_on && bss->UsingWEP) {
3243 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3244 priv->station_is_associated = 0;
3248 if (priv->wep_is_on && !bss->UsingWEP) {
3249 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3250 priv->station_is_associated = 0;
3254 atmel_enter_state(priv, STATION_STATE_JOINNING);
3256 if (priv->operating_mode == IW_MODE_INFRA)
3257 join(priv, BSS_TYPE_INFRASTRUCTURE);
3259 join(priv, BSS_TYPE_AD_HOC);
3262 static void restart_search(struct atmel_private *priv)
3266 if (!priv->connect_to_any_BSS) {
3267 atmel_scan(priv, 1);
3269 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3271 if ((bss_index = retrieve_bss(priv)) != -1)
3272 atmel_join_bss(priv, bss_index);
3274 atmel_scan(priv, 0);
3278 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3280 u8 old = priv->wstats.qual.level;
3281 u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3283 switch (priv->firmware_type) {
3284 case ATMEL_FW_TYPE_502E:
3285 max_rssi = 63; /* 502-rmfd-reve max by experiment */
3291 rssi = rssi * 100 / max_rssi;
3292 if ((rssi + old) % 2)
3293 priv->wstats.qual.level = (rssi + old) / 2 + 1;
3295 priv->wstats.qual.level = (rssi + old) / 2;
3296 priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3297 priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3300 static void atmel_smooth_qual(struct atmel_private *priv)
3302 unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3303 while (time_diff--) {
3304 priv->last_qual += HZ;
3305 priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3306 priv->wstats.qual.qual +=
3307 priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3308 priv->beacons_this_sec = 0;
3310 priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3311 priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3314 /* deals with incoming management frames. */
3315 static void atmel_management_frame(struct atmel_private *priv,
3316 struct ieee80211_hdr *header,
3317 u16 frame_len, u8 rssi)
3321 subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3323 case IEEE80211_STYPE_BEACON:
3324 case IEEE80211_STYPE_PROBE_RESP:
3326 /* beacon frame has multiple variable-length fields -
3327 never let an engineer loose with a data structure design. */
3329 struct beacon_format {
3342 } *beacon = (struct beacon_format *)priv->rx_buf;
3344 u8 channel, rates_length, ssid_length;
3345 u64 timestamp = le64_to_cpu(beacon->timestamp);
3346 u16 beacon_interval = le16_to_cpu(beacon->interval);
3347 u16 capability = le16_to_cpu(beacon->capability);
3348 u8 *beaconp = priv->rx_buf;
3349 ssid_length = beacon->ssid_length;
3350 /* this blows chunks. */
3351 if (frame_len < 14 || frame_len < ssid_length + 15)
3353 rates_length = beaconp[beacon->ssid_length + 15];
3354 if (frame_len < ssid_length + rates_length + 18)
3356 if (ssid_length > MAX_SSID_LENGTH)
3358 channel = beaconp[ssid_length + rates_length + 18];
3360 if (priv->station_state == STATION_STATE_READY) {
3361 smooth_rssi(priv, rssi);
3362 if (is_frame_from_current_bss(priv, header)) {
3363 priv->beacons_this_sec++;
3364 atmel_smooth_qual(priv);
3365 if (priv->last_beacon_timestamp) {
3366 /* Note truncate this to 32 bits - kernel can't divide a long long */
3367 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3368 int beacons = beacon_delay / (beacon_interval * 1000);
3370 priv->wstats.miss.beacon += beacons - 1;
3372 priv->last_beacon_timestamp = timestamp;
3373 handle_beacon_probe(priv, capability, channel);
3377 if (priv->station_state == STATION_STATE_SCANNING)
3378 store_bss_info(priv, header, capability,
3379 beacon_interval, channel, rssi,
3381 &beacon->rates_el_id,
3382 subtype == IEEE80211_STYPE_BEACON);
3386 case IEEE80211_STYPE_AUTH:
3388 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3389 authenticate(priv, frame_len);
3393 case IEEE80211_STYPE_ASSOC_RESP:
3394 case IEEE80211_STYPE_REASSOC_RESP:
3396 if (priv->station_state == STATION_STATE_ASSOCIATING ||
3397 priv->station_state == STATION_STATE_REASSOCIATING)
3398 associate(priv, frame_len, subtype);
3402 case IEEE80211_STYPE_DISASSOC:
3403 if (priv->station_is_associated &&
3404 priv->operating_mode == IW_MODE_INFRA &&
3405 is_frame_from_current_bss(priv, header)) {
3406 priv->station_was_associated = 0;
3407 priv->station_is_associated = 0;
3409 atmel_enter_state(priv, STATION_STATE_JOINNING);
3410 join(priv, BSS_TYPE_INFRASTRUCTURE);
3415 case IEEE80211_STYPE_DEAUTH:
3416 if (priv->operating_mode == IW_MODE_INFRA &&
3417 is_frame_from_current_bss(priv, header)) {
3418 priv->station_was_associated = 0;
3420 atmel_enter_state(priv, STATION_STATE_JOINNING);
3421 join(priv, BSS_TYPE_INFRASTRUCTURE);
3428 /* run when timer expires */
3429 static void atmel_management_timer(u_long a)
3431 struct net_device *dev = (struct net_device *) a;
3432 struct atmel_private *priv = netdev_priv(dev);
3433 unsigned long flags;
3435 /* Check if the card has been yanked. */
3436 if (priv->card && priv->present_callback &&
3437 !(*priv->present_callback)(priv->card))
3440 spin_lock_irqsave(&priv->irqlock, flags);
3442 switch (priv->station_state) {
3444 case STATION_STATE_AUTHENTICATING:
3445 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3446 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3447 priv->station_is_associated = 0;
3448 priv->AuthenticationRequestRetryCnt = 0;
3449 restart_search(priv);
3451 int auth = WLAN_AUTH_OPEN;
3452 priv->AuthenticationRequestRetryCnt++;
3453 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3454 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3455 if (priv->wep_is_on && priv->exclude_unencrypted)
3456 auth = WLAN_AUTH_SHARED_KEY;
3457 send_authentication_request(priv, auth, NULL, 0);
3461 case STATION_STATE_ASSOCIATING:
3462 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3463 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3464 priv->station_is_associated = 0;
3465 priv->AssociationRequestRetryCnt = 0;
3466 restart_search(priv);
3468 priv->AssociationRequestRetryCnt++;
3469 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3470 send_association_request(priv, 0);
3474 case STATION_STATE_REASSOCIATING:
3475 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3476 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3477 priv->station_is_associated = 0;
3478 priv->ReAssociationRequestRetryCnt = 0;
3479 restart_search(priv);
3481 priv->ReAssociationRequestRetryCnt++;
3482 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3483 send_association_request(priv, 1);
3491 spin_unlock_irqrestore(&priv->irqlock, flags);
3494 static void atmel_command_irq(struct atmel_private *priv)
3496 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3497 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3499 union iwreq_data wrqu;
3501 if (status == CMD_STATUS_IDLE ||
3502 status == CMD_STATUS_IN_PROGRESS)
3507 if (status == CMD_STATUS_COMPLETE) {
3508 priv->station_was_associated = priv->station_is_associated;
3509 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3510 (u8 *)priv->CurrentBSSID, 6);
3511 atmel_enter_state(priv, STATION_STATE_READY);
3516 fast_scan = priv->fast_scan;
3517 priv->fast_scan = 0;
3519 if (status != CMD_STATUS_COMPLETE) {
3520 atmel_scan(priv, 1);
3522 int bss_index = retrieve_bss(priv);
3523 int notify_scan_complete = 1;
3524 if (bss_index != -1) {
3525 atmel_join_bss(priv, bss_index);
3526 } else if (priv->operating_mode == IW_MODE_ADHOC &&
3527 priv->SSID_size != 0) {
3528 start(priv, BSS_TYPE_AD_HOC);
3530 priv->fast_scan = !fast_scan;
3531 atmel_scan(priv, 1);
3532 notify_scan_complete = 0;
3534 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3535 if (notify_scan_complete) {
3536 wrqu.data.length = 0;
3537 wrqu.data.flags = 0;
3538 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3543 case CMD_SiteSurvey:
3544 priv->fast_scan = 0;
3546 if (status != CMD_STATUS_COMPLETE)
3549 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3550 if (priv->station_is_associated) {
3551 atmel_enter_state(priv, STATION_STATE_READY);
3552 wrqu.data.length = 0;
3553 wrqu.data.flags = 0;
3554 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3556 atmel_scan(priv, 1);
3561 if (status == CMD_STATUS_COMPLETE) {
3562 if (priv->operating_mode == IW_MODE_ADHOC) {
3563 priv->station_was_associated = priv->station_is_associated;
3564 atmel_enter_state(priv, STATION_STATE_READY);
3566 int auth = WLAN_AUTH_OPEN;
3567 priv->AuthenticationRequestRetryCnt = 0;
3568 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3570 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3571 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3572 if (priv->wep_is_on && priv->exclude_unencrypted)
3573 auth = WLAN_AUTH_SHARED_KEY;
3574 send_authentication_request(priv, auth, NULL, 0);
3579 atmel_scan(priv, 1);
3583 static int atmel_wakeup_firmware(struct atmel_private *priv)
3585 struct host_info_struct *iface = &priv->host_info;
3589 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3590 atmel_set_gcr(priv->dev, GCR_REMAP);
3592 /* wake up on-board processor */
3593 atmel_clear_gcr(priv->dev, 0x0040);
3594 atmel_write16(priv->dev, BSR, BSS_SRAM);
3596 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3599 /* and wait for it */
3600 for (i = LOOP_RETRY_LIMIT; i; i--) {
3601 mr1 = atmel_read16(priv->dev, MR1);
3602 mr3 = atmel_read16(priv->dev, MR3);
3604 if (mr3 & MAC_BOOT_COMPLETE)
3606 if (mr1 & MAC_BOOT_COMPLETE &&
3607 priv->bus_type == BUS_TYPE_PCCARD)
3612 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3616 if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3617 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3621 /* now check for completion of MAC initialization through
3622 the FunCtrl field of the IFACE, poll MR1 to detect completion of
3623 MAC initialization, check completion status, set interrupt mask,
3624 enables interrupts and calls Tx and Rx initialization functions */
3626 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3628 for (i = LOOP_RETRY_LIMIT; i; i--) {
3629 mr1 = atmel_read16(priv->dev, MR1);
3630 mr3 = atmel_read16(priv->dev, MR3);
3632 if (mr3 & MAC_INIT_COMPLETE)
3634 if (mr1 & MAC_INIT_COMPLETE &&
3635 priv->bus_type == BUS_TYPE_PCCARD)
3640 printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3645 /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3646 if ((mr3 & MAC_INIT_COMPLETE) &&
3647 !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3648 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3651 if ((mr1 & MAC_INIT_COMPLETE) &&
3652 !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3653 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3657 atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3658 priv->host_info_base, sizeof(*iface));
3660 iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3661 iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3662 iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3663 iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3664 iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3665 iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3666 iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3667 iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3668 iface->build_version = le16_to_cpu(iface->build_version);
3669 iface->command_pos = le16_to_cpu(iface->command_pos);
3670 iface->major_version = le16_to_cpu(iface->major_version);
3671 iface->minor_version = le16_to_cpu(iface->minor_version);
3672 iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3673 iface->mac_status = le16_to_cpu(iface->mac_status);
3678 /* determine type of memory and MAC address */
3679 static int probe_atmel_card(struct net_device *dev)
3682 struct atmel_private *priv = netdev_priv(dev);
3685 if (priv->bus_type == BUS_TYPE_PCCARD)
3686 atmel_write16(dev, GCR, 0x0060);
3688 atmel_write16(dev, GCR, 0x0040);
3691 if (atmel_read16(dev, MR2) == 0) {
3692 /* No stored firmware so load a small stub which just
3693 tells us the MAC address */
3695 priv->card_type = CARD_TYPE_EEPROM;
3696 atmel_write16(dev, BSR, BSS_IRAM);
3697 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3698 atmel_set_gcr(dev, GCR_REMAP);
3699 atmel_clear_gcr(priv->dev, 0x0040);
3700 atmel_write16(dev, BSR, BSS_SRAM);
3701 for (i = LOOP_RETRY_LIMIT; i; i--)
3702 if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3705 printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3707 atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3708 /* got address, now squash it again until the network
3709 interface is opened */
3710 if (priv->bus_type == BUS_TYPE_PCCARD)
3711 atmel_write16(dev, GCR, 0x0060);
3712 atmel_write16(dev, GCR, 0x0040);
3715 } else if (atmel_read16(dev, MR4) == 0) {
3716 /* Mac address easy in this case. */
3717 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3718 atmel_write16(dev, BSR, 1);
3719 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3720 atmel_write16(dev, BSR, 0x200);
3723 /* Standard firmware in flash, boot it up and ask
3724 for the Mac Address */
3725 priv->card_type = CARD_TYPE_SPI_FLASH;
3726 if (atmel_wakeup_firmware(priv) == 0) {
3727 atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3729 /* got address, now squash it again until the network
3730 interface is opened */
3731 if (priv->bus_type == BUS_TYPE_PCCARD)
3732 atmel_write16(dev, GCR, 0x0060);
3733 atmel_write16(dev, GCR, 0x0040);
3739 if (dev->dev_addr[0] == 0xFF) {
3740 static const u8 default_mac[] = {
3741 0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3743 printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3744 memcpy(dev->dev_addr, default_mac, ETH_ALEN);
3751 /* Move the encyption information on the MIB structure.
3752 This routine is for the pre-WPA firmware: later firmware has
3753 a different format MIB and a different routine. */
3754 static void build_wep_mib(struct atmel_private *priv)
3756 struct { /* NB this is matched to the hardware, don't change. */
3758 u8 default_key; /* 0..3 */
3760 u8 exclude_unencrypted;
3762 u32 WEPICV_error_count;
3763 u32 WEP_excluded_count;
3765 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3766 u8 encryption_level; /* 0, 1, 2 */
3771 mib.wep_is_on = priv->wep_is_on;
3772 if (priv->wep_is_on) {
3773 if (priv->wep_key_len[priv->default_key] > 5)
3774 mib.encryption_level = 2;
3776 mib.encryption_level = 1;
3778 mib.encryption_level = 0;
3781 mib.default_key = priv->default_key;
3782 mib.exclude_unencrypted = priv->exclude_unencrypted;
3784 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3785 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3787 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3790 static void build_wpa_mib(struct atmel_private *priv)
3792 /* This is for the later (WPA enabled) firmware. */
3794 struct { /* NB this is matched to the hardware, don't change. */
3795 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3796 u8 receiver_address[ETH_ALEN];
3798 u8 default_key; /* 0..3 */
3800 u8 exclude_unencrypted;
3804 u32 WEPICV_error_count;
3805 u32 WEP_excluded_count;
3812 mib.wep_is_on = priv->wep_is_on;
3813 mib.exclude_unencrypted = priv->exclude_unencrypted;
3814 memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3816 /* zero all the keys before adding in valid ones. */
3817 memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3819 if (priv->wep_is_on) {
3820 /* There's a comment in the Atmel code to the effect that this
3821 is only valid when still using WEP, it may need to be set to
3822 something to use WPA */
3823 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3825 mib.default_key = mib.group_key = 255;
3826 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3827 if (priv->wep_key_len[i] > 0) {
3828 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3829 if (i == priv->default_key) {
3830 mib.default_key = i;
3831 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3832 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3835 priv->group_cipher_suite = priv->pairwise_cipher_suite;
3836 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3837 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3841 if (mib.default_key == 255)
3842 mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3843 if (mib.group_key == 255)
3844 mib.group_key = mib.default_key;
3848 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3851 static int reset_atmel_card(struct net_device *dev)
3853 /* do everything necessary to wake up the hardware, including
3854 waiting for the lightning strike and throwing the knife switch....
3856 set all the Mib values which matter in the card to match
3857 their settings in the atmel_private structure. Some of these
3858 can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3859 can only be changed by tearing down the world and coming back through
3862 This routine is also responsible for initialising some
3863 hardware-specific fields in the atmel_private structure,
3864 including a copy of the firmware's hostinfo structure
3865 which is the route into the rest of the firmware datastructures. */
3867 struct atmel_private *priv = netdev_priv(dev);
3869 int old_state = priv->station_state;
3872 /* data to add to the firmware names, in priority order
3873 this implemenents firmware versioning */
3875 static char *firmware_modifier[] = {
3882 if (priv->bus_type == BUS_TYPE_PCCARD)
3883 atmel_write16(priv->dev, GCR, 0x0060);
3885 /* stop card , disable interrupts */
3886 atmel_write16(priv->dev, GCR, 0x0040);
3888 if (priv->card_type == CARD_TYPE_EEPROM) {
3889 /* copy in firmware if needed */
3890 const struct firmware *fw_entry = NULL;
3891 const unsigned char *fw;
3892 int len = priv->firmware_length;
3893 if (!(fw = priv->firmware)) {
3894 if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3895 if (strlen(priv->firmware_id) == 0) {
3897 "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3900 "%s: if not, use the firmware= module parameter.\n",
3902 strcpy(priv->firmware_id, "/*(DEBLOBBED)*/");
3904 err = reject_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3907 "%s: firmware %s is missing, cannot continue.\n",
3908 dev->name, priv->firmware_id);
3915 /* get firmware filename entry based on firmware type ID */
3916 while (fw_table[fw_index].fw_type != priv->firmware_type
3917 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3920 /* construct the actual firmware file name */
3921 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3923 for (i = 0; firmware_modifier[i]; i++) {
3924 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3925 firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3926 priv->firmware_id[31] = '\0';
3927 if (reject_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3935 "%s: firmware %s is missing, cannot start.\n",
3936 dev->name, priv->firmware_id);
3937 priv->firmware_id[0] = '\0';
3942 fw = fw_entry->data;
3943 len = fw_entry->size;
3946 if (len <= 0x6000) {
3947 atmel_write16(priv->dev, BSR, BSS_IRAM);
3948 atmel_copy_to_card(priv->dev, 0, fw, len);
3949 atmel_set_gcr(priv->dev, GCR_REMAP);
3952 atmel_set_gcr(priv->dev, GCR_REMAP);
3953 atmel_write16(priv->dev, BSR, BSS_IRAM);
3954 atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3955 atmel_write16(priv->dev, BSR, 0x2ff);
3956 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3959 release_firmware(fw_entry);
3962 err = atmel_wakeup_firmware(priv);
3966 /* Check the version and set the correct flag for wpa stuff,
3967 old and new firmware is incompatible.
3968 The pre-wpa 3com firmware reports major version 5,
3969 the wpa 3com firmware is major version 4 and doesn't need
3970 the 3com broken-ness filter. */
3971 priv->use_wpa = (priv->host_info.major_version == 4);
3972 priv->radio_on_broken = (priv->host_info.major_version == 5);
3974 /* unmask all irq sources */
3975 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3977 /* int Tx system and enable Tx */
3978 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3979 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3980 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3981 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3983 priv->tx_desc_free = priv->host_info.tx_desc_count;
3984 priv->tx_desc_head = 0;
3985 priv->tx_desc_tail = 0;
3986 priv->tx_desc_previous = 0;
3987 priv->tx_free_mem = priv->host_info.tx_buff_size;
3988 priv->tx_buff_head = 0;
3989 priv->tx_buff_tail = 0;
3991 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3992 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3993 configuration | FUNC_CTRL_TxENABLE);
3995 /* init Rx system and enable */
3996 priv->rx_desc_head = 0;
3998 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3999 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
4000 configuration | FUNC_CTRL_RxENABLE);
4002 if (!priv->radio_on_broken) {
4003 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
4004 CMD_STATUS_REJECTED_RADIO_OFF) {
4005 printk(KERN_INFO "%s: cannot turn the radio on.\n",
4011 /* set up enough MIB values to run. */
4012 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4013 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_TX_PROMISCUOUS_POS, PROM_MODE_OFF);
4014 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4015 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4016 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4017 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4018 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4019 atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4020 priv->dev->dev_addr, 6);
4021 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4022 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4023 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4024 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4025 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4027 build_wpa_mib(priv);
4029 build_wep_mib(priv);
4031 if (old_state == STATION_STATE_READY) {
4032 union iwreq_data wrqu;
4034 wrqu.data.length = 0;
4035 wrqu.data.flags = 0;
4036 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4037 eth_zero_addr(wrqu.ap_addr.sa_data);
4038 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4044 static void atmel_send_command(struct atmel_private *priv, int command,
4045 void *cmd, int cmd_size)
4048 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4051 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4052 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4055 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4056 void *cmd, int cmd_size)
4060 atmel_send_command(priv, command, cmd, cmd_size);
4062 for (i = 5000; i; i--) {
4063 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4064 if (status != CMD_STATUS_IDLE &&
4065 status != CMD_STATUS_IN_PROGRESS)
4071 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4072 status = CMD_STATUS_HOST_ERROR;
4074 if (command != CMD_EnableRadio)
4075 status = CMD_STATUS_COMPLETE;
4081 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4083 struct get_set_mib m;
4088 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4089 return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4092 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4094 struct get_set_mib m;
4100 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4103 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4106 struct get_set_mib m;
4111 m.data[1] = data >> 8;
4113 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4116 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4117 u8 *data, int data_len)
4119 struct get_set_mib m;
4124 if (data_len > MIB_MAX_DATA_BYTES)
4125 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4127 memcpy(m.data, data, data_len);
4128 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4131 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4132 u8 *data, int data_len)
4134 struct get_set_mib m;
4139 if (data_len > MIB_MAX_DATA_BYTES)
4140 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4142 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4143 atmel_copy_to_host(priv->dev, data,
4144 atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4147 static void atmel_writeAR(struct net_device *dev, u16 data)
4150 outw(data, dev->base_addr + AR);
4151 /* Address register appears to need some convincing..... */
4152 for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4153 outw(data, dev->base_addr + AR);
4156 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4157 const unsigned char *src, u16 len)
4160 atmel_writeAR(dev, dest);
4162 atmel_write8(dev, DR, *src);
4165 for (i = len; i > 1 ; i -= 2) {
4168 atmel_write16(dev, DR, lb | (hb << 8));
4171 atmel_write8(dev, DR, *src);
4174 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4178 atmel_writeAR(dev, src);
4180 *dest = atmel_read8(dev, DR);
4183 for (i = len; i > 1 ; i -= 2) {
4184 u16 hw = atmel_read16(dev, DR);
4189 *dest = atmel_read8(dev, DR);
4192 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4194 outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4197 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4199 outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4202 static int atmel_lock_mac(struct atmel_private *priv)
4206 for (i = 5000; i; i--) {
4207 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4213 return 0; /* timed out */
4215 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4216 if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4217 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4219 return 0; /* timed out */
4226 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4228 atmel_writeAR(priv->dev, pos);
4229 atmel_write16(priv->dev, DR, data); /* card is little-endian */
4230 atmel_write16(priv->dev, DR, data >> 16);
4233 /***************************************************************************/
4234 /* There follows the source form of the MAC address reading firmware */
4235 /***************************************************************************/
4238 /* Copyright 2003 Matthew T. Russotto */
4239 /* But derived from the Atmel 76C502 firmware written by Atmel and */
4240 /* included in "atmel wireless lan drivers" package */
4242 This file is part of net.russotto.AtmelMACFW, hereto referred to
4245 AtmelMACFW is free software; you can redistribute it and/or modify
4246 it under the terms of the GNU General Public License version 2
4247 as published by the Free Software Foundation.
4249 AtmelMACFW is distributed in the hope that it will be useful,
4250 but WITHOUT ANY WARRANTY; without even the implied warranty of
4251 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4252 GNU General Public License for more details.
4254 You should have received a copy of the GNU General Public License
4255 along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4257 ****************************************************************************/
4258 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */
4259 /* It will probably work on the 76C504 and 76C502 RFMD_3COM */
4260 /* It only works on SPI EEPROM versions of the card. */
4262 /* This firmware initializes the SPI controller and clock, reads the MAC */
4263 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC */
4264 /* address in MR2, and sets MR3 to 0x10 to indicate it is done */
4265 /* It also puts a complete copy of the EEPROM in SRAM with the offset in */
4266 /* MR4, for investigational purposes (maybe we can determine chip type */
4270 .set MRBASE, 0x8000000
4271 .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4272 .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4273 .set SRAM_BASE, 0x02000000
4274 .set SP_BASE, 0x0F300000
4275 .set UNK_BASE, 0x0F000000 /* Some internal device, but which one? */
4276 .set SPI_CGEN_BASE, 0x0E000000 /* Some internal device, but which one? */
4277 .set UNK3_BASE, 0x02014000 /* Some internal device, but which one? */
4278 .set STACK_BASE, 0x5600
4280 .set SP_TDRE, 2 /* status register bit -- TDR empty */
4281 .set SP_RDRF, 1 /* status register bit -- RDR full */
4284 .set SP_CR, 0 /* control register */
4285 .set SP_MR, 4 /* mode register */
4286 .set SP_RDR, 0x08 /* Read Data Register */
4287 .set SP_TDR, 0x0C /* Transmit Data Register */
4288 .set SP_CSR0, 0x30 /* chip select registers */
4292 .set NVRAM_CMD_RDSR, 5 /* read status register */
4293 .set NVRAM_CMD_READ, 3 /* read data */
4294 .set NVRAM_SR_RDY, 1 /* RDY bit. This bit is inverted */
4295 .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4296 serial output, since SO is normally high. But it
4297 does cause 8 clock cycles and thus 8 bits to be
4298 clocked in to the chip. See Atmel's SPI
4299 controller (e.g. AT91M55800) timing and 4K
4300 SPI EEPROM manuals */
4302 .set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */
4303 .set NVRAM_IMAGE, 0x02000200
4304 .set NVRAM_LENGTH, 0x0200
4305 .set MAC_ADDRESS_MIB, SRAM_BASE
4306 .set MAC_ADDRESS_LENGTH, 6
4307 .set MAC_BOOT_FLAG, 0x10
4329 mov r0, #CPSR_INITIAL
4330 msr CPSR_c, r0 /* This is probably unnecessary */
4332 /* I'm guessing this is initializing clock generator electronics for SPI */
4333 ldr r0, =SPI_CGEN_BASE
4358 ldr r1, =MAC_ADDRESS_MIB
4360 ldr r1, =NVRAM_IMAGE
4362 mov r1, #MAC_BOOT_FLAG
4365 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4368 mov r2, #0 /* 0th bytes of NVRAM */
4369 mov r3, #NVRAM_LENGTH
4370 mov r1, #0 /* not used in routine */
4371 ldr r0, =NVRAM_IMAGE
4377 .func Get_MAC_Addr, GET_MAC_ADDR
4380 mov r2, #0x120 /* address of MAC Address within NVRAM */
4381 mov r3, #MAC_ADDRESS_LENGTH
4382 mov r1, #0 /* not used in routine */
4383 ldr r0, =MAC_ADDRESS_MIB
4389 .func Delay9, DELAY9
4391 adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */
4400 .func SP_Init, SP_INIT
4404 str r1, [r0, #SP_CR] /* reset the SPI */
4406 str r1, [r0, #SP_CR] /* release SPI from reset state */
4408 str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4409 str r1, [r0, #SP_CR] /* enable the SPI */
4411 /* My guess would be this turns on the SPI clock */
4412 ldr r3, =SPI_CGEN_BASE
4418 str r1, [r0, #SP_CSR0]
4420 str r1, [r0, #SP_CSR1]
4421 str r1, [r0, #SP_CSR2]
4422 str r1, [r0, #SP_CSR3]
4423 ldr r1, [r0, #SP_SR]
4424 ldr r0, [r0, #SP_RDR]
4427 .func NVRAM_Init, NVRAM_INIT
4430 ldr r0, [r1, #SP_RDR]
4431 mov r0, #NVRAM_CMD_RDSR
4432 str r0, [r1, #SP_TDR]
4434 ldr r0, [r1, #SP_SR]
4438 mov r0, #SPI_8CLOCKS
4439 str r0, [r1, #SP_TDR]
4441 ldr r0, [r1, #SP_SR]
4445 ldr r0, [r1, #SP_RDR]
4447 ldr r0, [r1, #SP_SR]
4451 ldr r0, [r1, #SP_RDR]
4456 .func NVRAM_Xfer, NVRAM_XFER
4457 /* r0 = dest address */
4459 /* r2 = src address within NVRAM */
4462 stmdb sp!, {r4, r5, lr}
4463 mov r5, r0 /* save r0 (dest address) */
4464 mov r4, r3 /* save r3 (length) */
4465 mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */
4467 add r0, r0, #NVRAM_CMD_READ
4468 ldr r1, =NVRAM_SCRATCH
4469 strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */
4470 strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */
4473 tst r0, #NVRAM_SR_RDY
4477 mov r2, r4 /* length */
4478 mov r1, r5 /* dest address */
4479 mov r0, #2 /* bytes to transfer in command */
4481 ldmia sp!, {r4, r5, lr}
4485 .func NVRAM_Xfer2, NVRAM_XFER2
4487 stmdb sp!, {r4, r5, r6, lr}
4492 ldr r5, =NVRAM_SCRATCH
4495 str r6, [r4, #SP_TDR]
4497 ldr r6, [r4, #SP_SR]
4501 cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */
4504 mov r3, #SPI_8CLOCKS
4505 str r3, [r4, #SP_TDR]
4506 ldr r0, [r4, #SP_RDR]
4508 ldr r0, [r4, #SP_SR]
4511 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 */
4513 cmp r2, #0 /* r2 is # of bytes to copy in */
4516 ldr r5, [r4, #SP_SR]
4519 str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */
4521 ldr r5, [r4, #SP_SR]
4524 ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4525 strb r5, [r1], #1 /* postindexed */
4528 blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4532 ldmia sp!, {r4, r5, r6, lr}