1 /*** -*- linux-c -*- **********************************************************
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
5 Copyright 2000-2001 ATMEL Corporation.
6 Copyright 2003-2004 Simon Kelley.
8 This code was developed from version 2.1.1 of the Atmel drivers,
9 released by Atmel corp. under the GPL in December 2002. It also
10 includes code from the Linux aironet drivers (C) Benjamin Reed,
11 and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
12 extensions, (C) Jean Tourrilhes.
14 The firmware module for reading the MAC address of the card comes from
15 net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright
16 by him. net.russotto.AtmelMACFW is used under the GPL license version 2.
17 This file contains the module in binary form and, under the terms
18 of the GPL, in source form. The source is located at the end of the file.
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
25 This software is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with Atmel wireless lan drivers; if not, see
32 <http://www.gnu.org/licenses/>.
34 For all queries about this code, please contact the current author,
35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
37 Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
38 hardware used during development of this driver.
40 ******************************************************************************/
42 #include <linux/interrupt.h>
44 #include <linux/kernel.h>
45 #include <linux/ptrace.h>
46 #include <linux/slab.h>
47 #include <linux/string.h>
48 #include <linux/timer.h>
49 #include <asm/byteorder.h>
51 #include <linux/uaccess.h>
52 #include <linux/module.h>
53 #include <linux/netdevice.h>
54 #include <linux/etherdevice.h>
55 #include <linux/skbuff.h>
56 #include <linux/if_arp.h>
57 #include <linux/ioport.h>
58 #include <linux/fcntl.h>
59 #include <linux/delay.h>
60 #include <linux/wireless.h>
61 #include <net/iw_handler.h>
62 #include <linux/crc32.h>
63 #include <linux/proc_fs.h>
64 #include <linux/seq_file.h>
65 #include <linux/device.h>
66 #include <linux/moduleparam.h>
67 #include <linux/firmware.h>
68 #include <linux/jiffies.h>
69 #include <net/cfg80211.h>
72 #define DRIVER_MAJOR 0
73 #define DRIVER_MINOR 98
75 MODULE_AUTHOR("Simon Kelley");
76 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
77 MODULE_LICENSE("GPL");
78 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
80 /* The name of the firmware file to be loaded
81 over-rides any automatic selection */
82 static char *firmware = NULL;
83 module_param(firmware, charp, 0);
85 /* table of firmware file names */
89 const char *fw_file_ext;
91 { ATMEL_FW_TYPE_502, "/*(DEBLOBBED)*/", "bin" },
92 { ATMEL_FW_TYPE_502D, "/*(DEBLOBBED)*/", "bin" },
93 { ATMEL_FW_TYPE_502E, "/*(DEBLOBBED)*/", "bin" },
94 { ATMEL_FW_TYPE_502_3COM, "/*(DEBLOBBED)*/", "bin" },
95 { ATMEL_FW_TYPE_504, "/*(DEBLOBBED)*/", "bin" },
96 { ATMEL_FW_TYPE_504_2958, "/*(DEBLOBBED)*/", "bin" },
97 { ATMEL_FW_TYPE_504A_2958, "/*(DEBLOBBED)*/", "bin" },
98 { ATMEL_FW_TYPE_506, "/*(DEBLOBBED)*/", "bin" },
99 { ATMEL_FW_TYPE_NONE, NULL, NULL }
103 #define MAX_SSID_LENGTH 32
104 #define MGMT_JIFFIES (256 * HZ / 100)
106 #define MAX_BSS_ENTRIES 64
109 #define GCR 0x00 /* (SIR0) General Configuration Register */
110 #define BSR 0x02 /* (SIR1) Bank Switching Select Register */
113 #define MR1 0x12 /* Mirror Register 1 */
114 #define MR2 0x14 /* Mirror Register 2 */
115 #define MR3 0x16 /* Mirror Register 3 */
116 #define MR4 0x18 /* Mirror Register 4 */
122 * Constants for the GCR register.
124 #define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */
125 #define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */
126 #define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */
127 #define GCR_ENINT 0x0002 /* Enable Interrupts */
128 #define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */
130 #define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */
131 #define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */
133 *Constants for the MR registers.
135 #define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */
136 #define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */
137 #define MAC_INIT_OK 0x0002 /* MAC boot has been completed */
139 #define MIB_MAX_DATA_BYTES 212
140 #define MIB_HEADER_SIZE 4 /* first four fields */
147 u8 data[MIB_MAX_DATA_BYTES];
165 #define RX_DESC_FLAG_VALID 0x80
166 #define RX_DESC_FLAG_CONSUMED 0x40
167 #define RX_DESC_FLAG_IDLE 0x00
169 #define RX_STATUS_SUCCESS 0x00
171 #define RX_DESC_MSDU_POS_OFFSET 4
172 #define RX_DESC_MSDU_SIZE_OFFSET 6
173 #define RX_DESC_FLAGS_OFFSET 8
174 #define RX_DESC_STATUS_OFFSET 9
175 #define RX_DESC_RSSI_OFFSET 11
176 #define RX_DESC_LINK_QUALITY_OFFSET 12
177 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
178 #define RX_DESC_DURATION_OFFSET 14
179 #define RX_DESC_RX_TIME_OFFSET 16
202 #define TX_DESC_NEXT_OFFSET 0
203 #define TX_DESC_POS_OFFSET 4
204 #define TX_DESC_SIZE_OFFSET 6
205 #define TX_DESC_FLAGS_OFFSET 8
206 #define TX_DESC_STATUS_OFFSET 9
207 #define TX_DESC_RETRY_OFFSET 10
208 #define TX_DESC_RATE_OFFSET 11
209 #define TX_DESC_KEY_INDEX_OFFSET 12
210 #define TX_DESC_CIPHER_TYPE_OFFSET 13
211 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
212 #define TX_DESC_PACKET_TYPE_OFFSET 17
213 #define TX_DESC_HOST_LENGTH_OFFSET 18
219 #define TX_STATUS_SUCCESS 0x00
221 #define TX_FIRM_OWN 0x80
224 #define TX_ERROR 0x01
226 #define TX_PACKET_TYPE_DATA 0x01
227 #define TX_PACKET_TYPE_MGMT 0x02
229 #define ISR_EMPTY 0x00 /* no bits set in ISR */
230 #define ISR_TxCOMPLETE 0x01 /* packet transmitted */
231 #define ISR_RxCOMPLETE 0x02 /* packet received */
232 #define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */
233 #define ISR_FATAL_ERROR 0x08 /* Fatal error */
234 #define ISR_COMMAND_COMPLETE 0x10 /* command completed */
235 #define ISR_OUT_OF_RANGE 0x20 /* command completed */
236 #define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */
237 #define ISR_GENERIC_IRQ 0x80
239 #define Local_Mib_Type 0x01
240 #define Mac_Address_Mib_Type 0x02
241 #define Mac_Mib_Type 0x03
242 #define Statistics_Mib_Type 0x04
243 #define Mac_Mgmt_Mib_Type 0x05
244 #define Mac_Wep_Mib_Type 0x06
245 #define Phy_Mib_Type 0x07
246 #define Multi_Domain_MIB 0x08
248 #define MAC_MGMT_MIB_CUR_BSSID_POS 14
249 #define MAC_MIB_FRAG_THRESHOLD_POS 8
250 #define MAC_MIB_RTS_THRESHOLD_POS 10
251 #define MAC_MIB_SHORT_RETRY_POS 16
252 #define MAC_MIB_LONG_RETRY_POS 17
253 #define MAC_MIB_SHORT_RETRY_LIMIT_POS 16
254 #define MAC_MGMT_MIB_BEACON_PER_POS 0
255 #define MAC_MGMT_MIB_STATION_ID_POS 6
256 #define MAC_MGMT_MIB_CUR_PRIVACY_POS 11
257 #define MAC_MGMT_MIB_CUR_BSSID_POS 14
258 #define MAC_MGMT_MIB_PS_MODE_POS 53
259 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS 54
260 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
261 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED 57
262 #define PHY_MIB_CHANNEL_POS 14
263 #define PHY_MIB_RATE_SET_POS 20
264 #define PHY_MIB_REG_DOMAIN_POS 26
265 #define LOCAL_MIB_AUTO_TX_RATE_POS 3
266 #define LOCAL_MIB_SSID_SIZE 5
267 #define LOCAL_MIB_TX_PROMISCUOUS_POS 6
268 #define LOCAL_MIB_TX_MGMT_RATE_POS 7
269 #define LOCAL_MIB_TX_CONTROL_RATE_POS 8
270 #define LOCAL_MIB_PREAMBLE_TYPE 9
271 #define MAC_ADDR_MIB_MAC_ADDR_POS 0
273 #define CMD_Set_MIB_Vars 0x01
274 #define CMD_Get_MIB_Vars 0x02
275 #define CMD_Scan 0x03
276 #define CMD_Join 0x04
277 #define CMD_Start 0x05
278 #define CMD_EnableRadio 0x06
279 #define CMD_DisableRadio 0x07
280 #define CMD_SiteSurvey 0x0B
282 #define CMD_STATUS_IDLE 0x00
283 #define CMD_STATUS_COMPLETE 0x01
284 #define CMD_STATUS_UNKNOWN 0x02
285 #define CMD_STATUS_INVALID_PARAMETER 0x03
286 #define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
287 #define CMD_STATUS_TIME_OUT 0x07
288 #define CMD_STATUS_IN_PROGRESS 0x08
289 #define CMD_STATUS_REJECTED_RADIO_OFF 0x09
290 #define CMD_STATUS_HOST_ERROR 0xFF
291 #define CMD_STATUS_BUSY 0xFE
293 #define CMD_BLOCK_COMMAND_OFFSET 0
294 #define CMD_BLOCK_STATUS_OFFSET 1
295 #define CMD_BLOCK_PARAMETERS_OFFSET 4
297 #define SCAN_OPTIONS_SITE_SURVEY 0x80
299 #define MGMT_FRAME_BODY_OFFSET 24
300 #define MAX_AUTHENTICATION_RETRIES 3
301 #define MAX_ASSOCIATION_RETRIES 3
303 #define AUTHENTICATION_RESPONSE_TIME_OUT 1000
305 #define MAX_WIRELESS_BODY 2316 /* mtu is 2312, CRC is 4 */
306 #define LOOP_RETRY_LIMIT 500000
308 #define ACTIVE_MODE 1
311 #define MAX_ENCRYPTION_KEYS 4
312 #define MAX_ENCRYPTION_KEY_SIZE 40
315 * 802.11 related definitions
322 #define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */
323 #define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */
324 #define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */
325 #define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */
326 #define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */
327 #define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
328 #define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */
329 #define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */
331 #define BSS_TYPE_AD_HOC 1
332 #define BSS_TYPE_INFRASTRUCTURE 2
334 #define SCAN_TYPE_ACTIVE 0
335 #define SCAN_TYPE_PASSIVE 1
337 #define LONG_PREAMBLE 0
338 #define SHORT_PREAMBLE 1
339 #define AUTO_PREAMBLE 2
341 #define DATA_FRAME_WS_HEADER_SIZE 30
343 /* promiscuous mode control */
344 #define PROM_MODE_OFF 0x0
345 #define PROM_MODE_UNKNOWN 0x1
346 #define PROM_MODE_CRC_FAILED 0x2
347 #define PROM_MODE_DUPLICATED 0x4
348 #define PROM_MODE_MGMT 0x8
349 #define PROM_MODE_CTRL 0x10
350 #define PROM_MODE_BAD_PROTOCOL 0x20
352 #define IFACE_INT_STATUS_OFFSET 0
353 #define IFACE_INT_MASK_OFFSET 1
354 #define IFACE_LOCKOUT_HOST_OFFSET 2
355 #define IFACE_LOCKOUT_MAC_OFFSET 3
356 #define IFACE_FUNC_CTRL_OFFSET 28
357 #define IFACE_MAC_STAT_OFFSET 30
358 #define IFACE_GENERIC_INT_TYPE_OFFSET 32
360 #define CIPHER_SUITE_NONE 0
361 #define CIPHER_SUITE_WEP_64 1
362 #define CIPHER_SUITE_TKIP 2
363 #define CIPHER_SUITE_AES 3
364 #define CIPHER_SUITE_CCX 4
365 #define CIPHER_SUITE_WEP_128 5
368 * IFACE MACROS & definitions
374 #define FUNC_CTRL_TxENABLE 0x10
375 #define FUNC_CTRL_RxENABLE 0x20
376 #define FUNC_CTRL_INIT_COMPLETE 0x01
378 /* A stub firmware image which reads the MAC address from NVRAM on the card.
379 For copyright information and source see the end of this file. */
380 static u8 mac_reader[] = {
381 0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
382 0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
383 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
384 0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
385 0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
386 0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
387 0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
388 0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
389 0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
390 0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
391 0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
392 0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
393 0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
394 0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
395 0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
396 0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
397 0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
398 0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
399 0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
400 0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
401 0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
402 0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
403 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
404 0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
405 0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
406 0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
407 0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
408 0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
409 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
410 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
411 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
412 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
413 0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
414 0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
415 0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
416 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
417 0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
418 0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
419 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
420 0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
421 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
422 0x00, 0x01, 0x00, 0x02
425 struct atmel_private {
426 void *card; /* Bus dependent structure varies for PCcard */
427 int (*present_callback)(void *); /* And callback which uses it */
428 char firmware_id[32];
429 AtmelFWType firmware_type;
432 struct timer_list management_timer;
433 struct net_device *dev;
434 struct device *sys_dev;
435 struct iw_statistics wstats;
436 spinlock_t irqlock, timerlock; /* spinlocks */
437 enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
439 CARD_TYPE_PARALLEL_FLASH,
443 int do_rx_crc; /* If we need to CRC incoming packets */
444 int probe_crc; /* set if we don't yet know */
445 int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
447 u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
448 u16 tx_free_mem, tx_buff_head, tx_buff_tail;
450 u16 frag_seq, frag_len, frag_no;
453 u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
454 u8 group_cipher_suite, pairwise_cipher_suite;
455 u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
456 int wep_key_len[MAX_ENCRYPTION_KEYS];
457 int use_wpa, radio_on_broken; /* firmware dependent stuff. */
460 struct host_info_struct {
461 /* NB this is matched to the hardware, don't change. */
462 u8 volatile int_status;
463 u8 volatile int_mask;
464 u8 volatile lockout_host;
465 u8 volatile lockout_mac;
485 u16 generic_IRQ_type;
490 STATION_STATE_SCANNING,
491 STATION_STATE_JOINNING,
492 STATION_STATE_AUTHENTICATING,
493 STATION_STATE_ASSOCIATING,
495 STATION_STATE_REASSOCIATING,
497 STATION_STATE_MGMT_ERROR
500 int operating_mode, power_mode;
501 unsigned long last_qual;
502 int beacons_this_sec;
504 int reg_domain, config_reg_domain;
509 int long_retry, short_retry;
511 int default_beacon_period, beacon_period, listen_interval;
512 int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
513 int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
516 SITE_SURVEY_IN_PROGRESS,
517 SITE_SURVEY_COMPLETED
519 unsigned long last_survey;
521 int station_was_associated, station_is_associated;
533 u8 SSID[MAX_SSID_LENGTH];
534 } BSSinfo[MAX_BSS_ENTRIES];
535 int BSS_list_entries, current_BSS;
536 int connect_to_any_BSS;
537 int SSID_size, new_SSID_size;
538 u8 CurrentBSSID[6], BSSID[6];
539 u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
540 u64 last_beacon_timestamp;
541 u8 rx_buf[MAX_WIRELESS_BODY];
544 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
546 static const struct {
550 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
551 { REG_DOMAIN_DOC, 1, 11, "Canada" },
552 { REG_DOMAIN_ETSI, 1, 13, "Europe" },
553 { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
554 { REG_DOMAIN_FRANCE, 10, 13, "France" },
555 { REG_DOMAIN_MKK, 14, 14, "MKK" },
556 { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
557 { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
559 static void build_wpa_mib(struct atmel_private *priv);
560 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
561 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
562 const unsigned char *src, u16 len);
563 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
565 static void atmel_set_gcr(struct net_device *dev, u16 mask);
566 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
567 static int atmel_lock_mac(struct atmel_private *priv);
568 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
569 static void atmel_command_irq(struct atmel_private *priv);
570 static int atmel_validate_channel(struct atmel_private *priv, int channel);
571 static void atmel_management_frame(struct atmel_private *priv,
572 struct ieee80211_hdr *header,
573 u16 frame_len, u8 rssi);
574 static void atmel_management_timer(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 skb_put_data(skb, priv->rx_buf,
1025 priv->frag_len + 12);
1026 skb->protocol = eth_type_trans(skb, priv->dev);
1027 skb->ip_summed = CHECKSUM_NONE;
1029 priv->dev->stats.rx_bytes += priv->frag_len + 12;
1030 priv->dev->stats.rx_packets++;
1034 priv->wstats.discard.fragment++;
1037 static void rx_done_irq(struct atmel_private *priv)
1040 struct ieee80211_hdr header;
1043 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1044 i < priv->host_info.rx_desc_count;
1047 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1048 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1049 u32 crc = 0xffffffff;
1051 if (status != RX_STATUS_SUCCESS) {
1052 if (status == 0xc1) /* determined by experiment */
1053 priv->wstats.discard.nwid++;
1055 priv->dev->stats.rx_errors++;
1059 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1060 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1062 if (msdu_size < 30) {
1063 priv->dev->stats.rx_errors++;
1067 /* Get header as far as end of seq_ctrl */
1068 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1069 frame_ctl = le16_to_cpu(header.frame_control);
1070 seq_control = le16_to_cpu(header.seq_ctrl);
1072 /* probe for CRC use here if needed once five packets have
1073 arrived with the same crc status, we assume we know what's
1074 happening and stop probing */
1075 if (priv->probe_crc) {
1076 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1077 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1079 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1081 if (priv->do_rx_crc) {
1082 if (priv->crc_ok_cnt++ > 5)
1083 priv->probe_crc = 0;
1085 if (priv->crc_ko_cnt++ > 5)
1086 priv->probe_crc = 0;
1090 /* don't CRC header when WEP in use */
1091 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1092 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1094 msdu_size -= 24; /* header */
1096 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1097 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1098 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1099 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1101 if (!more_fragments && packet_fragment_no == 0) {
1102 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1104 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1105 packet_sequence_no, packet_fragment_no, more_fragments);
1109 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1110 /* copy rest of packet into buffer */
1111 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1113 /* we use the same buffer for frag reassembly and control packets */
1114 eth_broadcast_addr(priv->frag_source);
1116 if (priv->do_rx_crc) {
1117 /* last 4 octets is crc */
1119 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1120 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1121 priv->dev->stats.rx_crc_errors++;
1126 atmel_management_frame(priv, &header, msdu_size,
1127 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1131 /* release descriptor */
1132 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1134 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1135 priv->rx_desc_head++;
1137 priv->rx_desc_head = 0;
1141 static irqreturn_t service_interrupt(int irq, void *dev_id)
1143 struct net_device *dev = (struct net_device *) dev_id;
1144 struct atmel_private *priv = netdev_priv(dev);
1147 static const u8 irq_order[] = {
1153 ISR_COMMAND_COMPLETE,
1158 if (priv->card && priv->present_callback &&
1159 !(*priv->present_callback)(priv->card))
1162 /* In this state upper-level code assumes it can mess with
1163 the card unhampered by interrupts which may change register state.
1164 Note that even though the card shouldn't generate interrupts
1165 the inturrupt line may be shared. This allows card setup
1166 to go on without disabling interrupts for a long time. */
1167 if (priv->station_state == STATION_STATE_DOWN)
1170 atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1173 if (!atmel_lock_mac(priv)) {
1174 /* failed to contact card */
1175 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1179 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1180 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1183 atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1184 return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1187 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1189 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1190 if (isr & irq_order[i])
1193 if (!atmel_lock_mac(priv)) {
1194 /* failed to contact card */
1195 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1199 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1200 isr ^= irq_order[i];
1201 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1202 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1204 switch (irq_order[i]) {
1206 case ISR_OUT_OF_RANGE:
1207 if (priv->operating_mode == IW_MODE_INFRA &&
1208 priv->station_state == STATION_STATE_READY) {
1209 priv->station_is_associated = 0;
1210 atmel_scan(priv, 1);
1214 case ISR_RxFRAMELOST:
1215 priv->wstats.discard.misc++;
1217 case ISR_RxCOMPLETE:
1221 case ISR_TxCOMPLETE:
1225 case ISR_FATAL_ERROR:
1226 printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1227 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1230 case ISR_COMMAND_COMPLETE:
1231 atmel_command_irq(priv);
1234 case ISR_IBSS_MERGE:
1235 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1236 priv->CurrentBSSID, 6);
1237 /* The WPA stuff cares about the current AP address */
1239 build_wpa_mib(priv);
1241 case ISR_GENERIC_IRQ:
1242 printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1248 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1250 struct atmel_private *priv = netdev_priv(dev);
1252 /* update the link quality here in case we are seeing no beacons
1253 at all to drive the process */
1254 atmel_smooth_qual(priv);
1256 priv->wstats.status = priv->station_state;
1258 if (priv->operating_mode == IW_MODE_INFRA) {
1259 if (priv->station_state != STATION_STATE_READY) {
1260 priv->wstats.qual.qual = 0;
1261 priv->wstats.qual.level = 0;
1262 priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1263 | IW_QUAL_LEVEL_INVALID);
1265 priv->wstats.qual.noise = 0;
1266 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1268 /* Quality levels cannot be determined in ad-hoc mode,
1269 because we can 'hear' more that one remote station. */
1270 priv->wstats.qual.qual = 0;
1271 priv->wstats.qual.level = 0;
1272 priv->wstats.qual.noise = 0;
1273 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1274 | IW_QUAL_LEVEL_INVALID
1275 | IW_QUAL_NOISE_INVALID;
1276 priv->wstats.miss.beacon = 0;
1279 return &priv->wstats;
1282 static int atmel_set_mac_address(struct net_device *dev, void *p)
1284 struct sockaddr *addr = p;
1286 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1287 return atmel_open(dev);
1290 EXPORT_SYMBOL(atmel_open);
1292 int atmel_open(struct net_device *dev)
1294 struct atmel_private *priv = netdev_priv(dev);
1295 int i, channel, err;
1297 /* any scheduled timer is no longer needed and might screw things up.. */
1298 del_timer_sync(&priv->management_timer);
1300 /* Interrupts will not touch the card once in this state... */
1301 priv->station_state = STATION_STATE_DOWN;
1303 if (priv->new_SSID_size) {
1304 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1305 priv->SSID_size = priv->new_SSID_size;
1306 priv->new_SSID_size = 0;
1308 priv->BSS_list_entries = 0;
1310 priv->AuthenticationRequestRetryCnt = 0;
1311 priv->AssociationRequestRetryCnt = 0;
1312 priv->ReAssociationRequestRetryCnt = 0;
1313 priv->CurrentAuthentTransactionSeqNum = 0x0001;
1314 priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1316 priv->site_survey_state = SITE_SURVEY_IDLE;
1317 priv->station_is_associated = 0;
1319 err = reset_atmel_card(dev);
1323 if (priv->config_reg_domain) {
1324 priv->reg_domain = priv->config_reg_domain;
1325 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1327 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1328 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1329 if (priv->reg_domain == channel_table[i].reg_domain)
1331 if (i == ARRAY_SIZE(channel_table)) {
1332 priv->reg_domain = REG_DOMAIN_MKK1;
1333 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1337 if ((channel = atmel_validate_channel(priv, priv->channel)))
1338 priv->channel = channel;
1340 /* this moves station_state on.... */
1341 atmel_scan(priv, 1);
1343 atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1347 static int atmel_close(struct net_device *dev)
1349 struct atmel_private *priv = netdev_priv(dev);
1351 /* Send event to userspace that we are disassociating */
1352 if (priv->station_state == STATION_STATE_READY) {
1353 union iwreq_data wrqu;
1355 wrqu.data.length = 0;
1356 wrqu.data.flags = 0;
1357 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1358 eth_zero_addr(wrqu.ap_addr.sa_data);
1359 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1362 atmel_enter_state(priv, STATION_STATE_DOWN);
1364 if (priv->bus_type == BUS_TYPE_PCCARD)
1365 atmel_write16(dev, GCR, 0x0060);
1366 atmel_write16(dev, GCR, 0x0040);
1370 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1372 /* check that channel is OK, if so return zero,
1373 else return suitable default channel */
1376 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1377 if (priv->reg_domain == channel_table[i].reg_domain) {
1378 if (channel >= channel_table[i].min &&
1379 channel <= channel_table[i].max)
1382 return channel_table[i].min;
1387 static int atmel_proc_show(struct seq_file *m, void *v)
1389 struct atmel_private *priv = m->private;
1393 seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1395 if (priv->station_state != STATION_STATE_DOWN) {
1397 "Firmware version:\t%d.%d build %d\n"
1398 "Firmware location:\t",
1399 priv->host_info.major_version,
1400 priv->host_info.minor_version,
1401 priv->host_info.build_version);
1403 if (priv->card_type != CARD_TYPE_EEPROM)
1404 seq_puts(m, "on card\n");
1405 else if (priv->firmware)
1406 seq_printf(m, "%s loaded by host\n", priv->firmware_id);
1408 seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
1410 switch (priv->card_type) {
1411 case CARD_TYPE_PARALLEL_FLASH:
1412 c = "Parallel flash";
1414 case CARD_TYPE_SPI_FLASH:
1417 case CARD_TYPE_EEPROM:
1425 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1426 if (priv->reg_domain == channel_table[i].reg_domain)
1427 r = channel_table[i].name;
1429 seq_printf(m, "MAC memory type:\t%s\n", c);
1430 seq_printf(m, "Regulatory domain:\t%s\n", r);
1431 seq_printf(m, "Host CRC checking:\t%s\n",
1432 priv->do_rx_crc ? "On" : "Off");
1433 seq_printf(m, "WPA-capable firmware:\t%s\n",
1434 priv->use_wpa ? "Yes" : "No");
1437 switch (priv->station_state) {
1438 case STATION_STATE_SCANNING:
1441 case STATION_STATE_JOINNING:
1444 case STATION_STATE_AUTHENTICATING:
1445 s = "Authenticating";
1447 case STATION_STATE_ASSOCIATING:
1450 case STATION_STATE_READY:
1453 case STATION_STATE_REASSOCIATING:
1454 s = "Reassociating";
1456 case STATION_STATE_MGMT_ERROR:
1457 s = "Management error";
1459 case STATION_STATE_DOWN:
1466 seq_printf(m, "Current state:\t\t%s\n", s);
1470 static int atmel_proc_open(struct inode *inode, struct file *file)
1472 return single_open(file, atmel_proc_show, PDE_DATA(inode));
1475 static const struct file_operations atmel_proc_fops = {
1476 .open = atmel_proc_open,
1478 .llseek = seq_lseek,
1479 .release = single_release,
1482 static const struct net_device_ops atmel_netdev_ops = {
1483 .ndo_open = atmel_open,
1484 .ndo_stop = atmel_close,
1485 .ndo_set_mac_address = atmel_set_mac_address,
1486 .ndo_start_xmit = start_tx,
1487 .ndo_do_ioctl = atmel_ioctl,
1488 .ndo_validate_addr = eth_validate_addr,
1491 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1492 const AtmelFWType fw_type,
1493 struct device *sys_dev,
1494 int (*card_present)(void *), void *card)
1496 struct net_device *dev;
1497 struct atmel_private *priv;
1500 /* Create the network device object. */
1501 dev = alloc_etherdev(sizeof(*priv));
1505 if (dev_alloc_name(dev, dev->name) < 0) {
1506 printk(KERN_ERR "atmel: Couldn't get name!\n");
1510 priv = netdev_priv(dev);
1512 priv->sys_dev = sys_dev;
1513 priv->present_callback = card_present;
1515 priv->firmware = NULL;
1516 priv->firmware_id[0] = '\0';
1517 priv->firmware_type = fw_type;
1518 if (firmware) /* module parameter */
1519 strcpy(priv->firmware_id, firmware);
1520 priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1521 priv->station_state = STATION_STATE_DOWN;
1522 priv->do_rx_crc = 0;
1523 /* For PCMCIA cards, some chips need CRC, some don't
1524 so we have to probe. */
1525 if (priv->bus_type == BUS_TYPE_PCCARD) {
1526 priv->probe_crc = 1;
1527 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1529 priv->probe_crc = 0;
1530 priv->last_qual = jiffies;
1531 priv->last_beacon_timestamp = 0;
1532 memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1533 eth_zero_addr(priv->BSSID);
1534 priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1535 priv->station_was_associated = 0;
1537 priv->last_survey = jiffies;
1538 priv->preamble = LONG_PREAMBLE;
1539 priv->operating_mode = IW_MODE_INFRA;
1540 priv->connect_to_any_BSS = 0;
1541 priv->config_reg_domain = 0;
1542 priv->reg_domain = 0;
1544 priv->auto_tx_rate = 1;
1546 priv->power_mode = 0;
1547 priv->SSID[0] = '\0';
1548 priv->SSID_size = 0;
1549 priv->new_SSID_size = 0;
1550 priv->frag_threshold = 2346;
1551 priv->rts_threshold = 2347;
1552 priv->short_retry = 7;
1553 priv->long_retry = 4;
1555 priv->wep_is_on = 0;
1556 priv->default_key = 0;
1557 priv->encryption_level = 0;
1558 priv->exclude_unencrypted = 0;
1559 priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1561 memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1562 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1564 priv->default_beacon_period = priv->beacon_period = 100;
1565 priv->listen_interval = 1;
1567 init_timer(&priv->management_timer);
1568 spin_lock_init(&priv->irqlock);
1569 spin_lock_init(&priv->timerlock);
1570 priv->management_timer.function = atmel_management_timer;
1571 priv->management_timer.data = (unsigned long) dev;
1573 dev->netdev_ops = &atmel_netdev_ops;
1574 dev->wireless_handlers = &atmel_handler_def;
1576 dev->base_addr = port;
1578 /* MTU range: 68 - 2312 */
1580 dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
1582 SET_NETDEV_DEV(dev, sys_dev);
1584 if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1585 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1589 if (!request_region(dev->base_addr, 32,
1590 priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) {
1594 if (register_netdev(dev))
1597 if (!probe_atmel_card(dev)) {
1598 unregister_netdev(dev);
1602 netif_carrier_off(dev);
1604 if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv))
1605 printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1607 printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1608 dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1613 release_region(dev->base_addr, 32);
1615 free_irq(dev->irq, dev);
1621 EXPORT_SYMBOL(init_atmel_card);
1623 void stop_atmel_card(struct net_device *dev)
1625 struct atmel_private *priv = netdev_priv(dev);
1627 /* put a brick on it... */
1628 if (priv->bus_type == BUS_TYPE_PCCARD)
1629 atmel_write16(dev, GCR, 0x0060);
1630 atmel_write16(dev, GCR, 0x0040);
1632 del_timer_sync(&priv->management_timer);
1633 unregister_netdev(dev);
1634 remove_proc_entry("driver/atmel", NULL);
1635 free_irq(dev->irq, dev);
1636 kfree(priv->firmware);
1637 release_region(dev->base_addr, 32);
1641 EXPORT_SYMBOL(stop_atmel_card);
1643 static int atmel_set_essid(struct net_device *dev,
1644 struct iw_request_info *info,
1645 struct iw_point *dwrq,
1648 struct atmel_private *priv = netdev_priv(dev);
1650 /* Check if we asked for `any' */
1651 if (dwrq->flags == 0) {
1652 priv->connect_to_any_BSS = 1;
1654 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1656 priv->connect_to_any_BSS = 0;
1658 /* Check the size of the string */
1659 if (dwrq->length > MAX_SSID_LENGTH)
1664 memcpy(priv->new_SSID, extra, dwrq->length);
1665 priv->new_SSID_size = dwrq->length;
1668 return -EINPROGRESS;
1671 static int atmel_get_essid(struct net_device *dev,
1672 struct iw_request_info *info,
1673 struct iw_point *dwrq,
1676 struct atmel_private *priv = netdev_priv(dev);
1678 /* Get the current SSID */
1679 if (priv->new_SSID_size != 0) {
1680 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1681 dwrq->length = priv->new_SSID_size;
1683 memcpy(extra, priv->SSID, priv->SSID_size);
1684 dwrq->length = priv->SSID_size;
1687 dwrq->flags = !priv->connect_to_any_BSS; /* active */
1692 static int atmel_get_wap(struct net_device *dev,
1693 struct iw_request_info *info,
1694 struct sockaddr *awrq,
1697 struct atmel_private *priv = netdev_priv(dev);
1698 memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1699 awrq->sa_family = ARPHRD_ETHER;
1704 static int atmel_set_encode(struct net_device *dev,
1705 struct iw_request_info *info,
1706 struct iw_point *dwrq,
1709 struct atmel_private *priv = netdev_priv(dev);
1711 /* Basic checking: do we have a key to set ?
1712 * Note : with the new API, it's impossible to get a NULL pointer.
1713 * Therefore, we need to check a key size == 0 instead.
1714 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1715 * when no key is present (only change flags), but older versions
1716 * don't do it. - Jean II */
1717 if (dwrq->length > 0) {
1718 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1719 int current_index = priv->default_key;
1720 /* Check the size of the key */
1721 if (dwrq->length > 13) {
1724 /* Check the index (none -> use current) */
1725 if (index < 0 || index >= 4)
1726 index = current_index;
1728 priv->default_key = index;
1729 /* Set the length */
1730 if (dwrq->length > 5)
1731 priv->wep_key_len[index] = 13;
1733 if (dwrq->length > 0)
1734 priv->wep_key_len[index] = 5;
1736 /* Disable the key */
1737 priv->wep_key_len[index] = 0;
1738 /* Check if the key is not marked as invalid */
1739 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1741 memset(priv->wep_keys[index], 0, 13);
1742 /* Copy the key in the driver */
1743 memcpy(priv->wep_keys[index], extra, dwrq->length);
1745 /* WE specify that if a valid key is set, encryption
1746 * should be enabled (user may turn it off later)
1747 * This is also how "iwconfig ethX key on" works */
1748 if (index == current_index &&
1749 priv->wep_key_len[index] > 0) {
1750 priv->wep_is_on = 1;
1751 priv->exclude_unencrypted = 1;
1752 if (priv->wep_key_len[index] > 5) {
1753 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1754 priv->encryption_level = 2;
1756 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1757 priv->encryption_level = 1;
1761 /* Do we want to just set the transmit key index ? */
1762 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1763 if (index >= 0 && index < 4) {
1764 priv->default_key = index;
1766 /* Don't complain if only change the mode */
1767 if (!(dwrq->flags & IW_ENCODE_MODE))
1770 /* Read the flags */
1771 if (dwrq->flags & IW_ENCODE_DISABLED) {
1772 priv->wep_is_on = 0;
1773 priv->encryption_level = 0;
1774 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1776 priv->wep_is_on = 1;
1777 if (priv->wep_key_len[priv->default_key] > 5) {
1778 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1779 priv->encryption_level = 2;
1781 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1782 priv->encryption_level = 1;
1785 if (dwrq->flags & IW_ENCODE_RESTRICTED)
1786 priv->exclude_unencrypted = 1;
1787 if (dwrq->flags & IW_ENCODE_OPEN)
1788 priv->exclude_unencrypted = 0;
1790 return -EINPROGRESS; /* Call commit handler */
1793 static int atmel_get_encode(struct net_device *dev,
1794 struct iw_request_info *info,
1795 struct iw_point *dwrq,
1798 struct atmel_private *priv = netdev_priv(dev);
1799 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1801 if (!priv->wep_is_on)
1802 dwrq->flags = IW_ENCODE_DISABLED;
1804 if (priv->exclude_unencrypted)
1805 dwrq->flags = IW_ENCODE_RESTRICTED;
1807 dwrq->flags = IW_ENCODE_OPEN;
1809 /* Which key do we want ? -1 -> tx index */
1810 if (index < 0 || index >= 4)
1811 index = priv->default_key;
1812 dwrq->flags |= index + 1;
1813 /* Copy the key to the user buffer */
1814 dwrq->length = priv->wep_key_len[index];
1815 if (dwrq->length > 16) {
1818 memset(extra, 0, 16);
1819 memcpy(extra, priv->wep_keys[index], dwrq->length);
1825 static int atmel_set_encodeext(struct net_device *dev,
1826 struct iw_request_info *info,
1827 union iwreq_data *wrqu,
1830 struct atmel_private *priv = netdev_priv(dev);
1831 struct iw_point *encoding = &wrqu->encoding;
1832 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1833 int idx, key_len, alg = ext->alg, set_key = 1;
1835 /* Determine and validate the key index */
1836 idx = encoding->flags & IW_ENCODE_INDEX;
1838 if (idx < 1 || idx > 4)
1842 idx = priv->default_key;
1844 if (encoding->flags & IW_ENCODE_DISABLED)
1845 alg = IW_ENCODE_ALG_NONE;
1847 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1848 priv->default_key = idx;
1849 set_key = ext->key_len > 0 ? 1 : 0;
1853 /* Set the requested key first */
1855 case IW_ENCODE_ALG_NONE:
1856 priv->wep_is_on = 0;
1857 priv->encryption_level = 0;
1858 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1860 case IW_ENCODE_ALG_WEP:
1861 if (ext->key_len > 5) {
1862 priv->wep_key_len[idx] = 13;
1863 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1864 priv->encryption_level = 2;
1865 } else if (ext->key_len > 0) {
1866 priv->wep_key_len[idx] = 5;
1867 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1868 priv->encryption_level = 1;
1872 priv->wep_is_on = 1;
1873 memset(priv->wep_keys[idx], 0, 13);
1874 key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1875 memcpy(priv->wep_keys[idx], ext->key, key_len);
1882 return -EINPROGRESS;
1885 static int atmel_get_encodeext(struct net_device *dev,
1886 struct iw_request_info *info,
1887 union iwreq_data *wrqu,
1890 struct atmel_private *priv = netdev_priv(dev);
1891 struct iw_point *encoding = &wrqu->encoding;
1892 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1893 int idx, max_key_len;
1895 max_key_len = encoding->length - sizeof(*ext);
1896 if (max_key_len < 0)
1899 idx = encoding->flags & IW_ENCODE_INDEX;
1901 if (idx < 1 || idx > 4)
1905 idx = priv->default_key;
1907 encoding->flags = idx + 1;
1908 memset(ext, 0, sizeof(*ext));
1910 if (!priv->wep_is_on) {
1911 ext->alg = IW_ENCODE_ALG_NONE;
1913 encoding->flags |= IW_ENCODE_DISABLED;
1915 if (priv->encryption_level > 0)
1916 ext->alg = IW_ENCODE_ALG_WEP;
1920 ext->key_len = priv->wep_key_len[idx];
1921 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1922 encoding->flags |= IW_ENCODE_ENABLED;
1928 static int atmel_set_auth(struct net_device *dev,
1929 struct iw_request_info *info,
1930 union iwreq_data *wrqu, char *extra)
1932 struct atmel_private *priv = netdev_priv(dev);
1933 struct iw_param *param = &wrqu->param;
1935 switch (param->flags & IW_AUTH_INDEX) {
1936 case IW_AUTH_WPA_VERSION:
1937 case IW_AUTH_CIPHER_PAIRWISE:
1938 case IW_AUTH_CIPHER_GROUP:
1939 case IW_AUTH_KEY_MGMT:
1940 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1941 case IW_AUTH_PRIVACY_INVOKED:
1943 * atmel does not use these parameters
1947 case IW_AUTH_DROP_UNENCRYPTED:
1948 priv->exclude_unencrypted = param->value ? 1 : 0;
1951 case IW_AUTH_80211_AUTH_ALG: {
1952 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1953 priv->exclude_unencrypted = 1;
1954 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1955 priv->exclude_unencrypted = 0;
1961 case IW_AUTH_WPA_ENABLED:
1962 /* Silently accept disable of WPA */
1963 if (param->value > 0)
1970 return -EINPROGRESS;
1973 static int atmel_get_auth(struct net_device *dev,
1974 struct iw_request_info *info,
1975 union iwreq_data *wrqu, char *extra)
1977 struct atmel_private *priv = netdev_priv(dev);
1978 struct iw_param *param = &wrqu->param;
1980 switch (param->flags & IW_AUTH_INDEX) {
1981 case IW_AUTH_DROP_UNENCRYPTED:
1982 param->value = priv->exclude_unencrypted;
1985 case IW_AUTH_80211_AUTH_ALG:
1986 if (priv->exclude_unencrypted == 1)
1987 param->value = IW_AUTH_ALG_SHARED_KEY;
1989 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1992 case IW_AUTH_WPA_ENABLED:
2003 static int atmel_get_name(struct net_device *dev,
2004 struct iw_request_info *info,
2008 strcpy(cwrq, "IEEE 802.11-DS");
2012 static int atmel_set_rate(struct net_device *dev,
2013 struct iw_request_info *info,
2014 struct iw_param *vwrq,
2017 struct atmel_private *priv = netdev_priv(dev);
2019 if (vwrq->fixed == 0) {
2021 priv->auto_tx_rate = 1;
2023 priv->auto_tx_rate = 0;
2025 /* Which type of value ? */
2026 if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2027 /* Setting by rate index */
2028 priv->tx_rate = vwrq->value;
2030 /* Setting by frequency value */
2031 switch (vwrq->value) {
2050 return -EINPROGRESS;
2053 static int atmel_set_mode(struct net_device *dev,
2054 struct iw_request_info *info,
2058 struct atmel_private *priv = netdev_priv(dev);
2060 if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2063 priv->operating_mode = *uwrq;
2064 return -EINPROGRESS;
2067 static int atmel_get_mode(struct net_device *dev,
2068 struct iw_request_info *info,
2072 struct atmel_private *priv = netdev_priv(dev);
2074 *uwrq = priv->operating_mode;
2078 static int atmel_get_rate(struct net_device *dev,
2079 struct iw_request_info *info,
2080 struct iw_param *vwrq,
2083 struct atmel_private *priv = netdev_priv(dev);
2085 if (priv->auto_tx_rate) {
2087 vwrq->value = 11000000;
2090 switch (priv->tx_rate) {
2092 vwrq->value = 1000000;
2095 vwrq->value = 2000000;
2098 vwrq->value = 5500000;
2101 vwrq->value = 11000000;
2108 static int atmel_set_power(struct net_device *dev,
2109 struct iw_request_info *info,
2110 struct iw_param *vwrq,
2113 struct atmel_private *priv = netdev_priv(dev);
2114 priv->power_mode = vwrq->disabled ? 0 : 1;
2115 return -EINPROGRESS;
2118 static int atmel_get_power(struct net_device *dev,
2119 struct iw_request_info *info,
2120 struct iw_param *vwrq,
2123 struct atmel_private *priv = netdev_priv(dev);
2124 vwrq->disabled = priv->power_mode ? 0 : 1;
2125 vwrq->flags = IW_POWER_ON;
2129 static int atmel_set_retry(struct net_device *dev,
2130 struct iw_request_info *info,
2131 struct iw_param *vwrq,
2134 struct atmel_private *priv = netdev_priv(dev);
2136 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2137 if (vwrq->flags & IW_RETRY_LONG)
2138 priv->long_retry = vwrq->value;
2139 else if (vwrq->flags & IW_RETRY_SHORT)
2140 priv->short_retry = vwrq->value;
2142 /* No modifier : set both */
2143 priv->long_retry = vwrq->value;
2144 priv->short_retry = vwrq->value;
2146 return -EINPROGRESS;
2152 static int atmel_get_retry(struct net_device *dev,
2153 struct iw_request_info *info,
2154 struct iw_param *vwrq,
2157 struct atmel_private *priv = netdev_priv(dev);
2159 vwrq->disabled = 0; /* Can't be disabled */
2161 /* Note : by default, display the short retry number */
2162 if (vwrq->flags & IW_RETRY_LONG) {
2163 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2164 vwrq->value = priv->long_retry;
2166 vwrq->flags = IW_RETRY_LIMIT;
2167 vwrq->value = priv->short_retry;
2168 if (priv->long_retry != priv->short_retry)
2169 vwrq->flags |= IW_RETRY_SHORT;
2175 static int atmel_set_rts(struct net_device *dev,
2176 struct iw_request_info *info,
2177 struct iw_param *vwrq,
2180 struct atmel_private *priv = netdev_priv(dev);
2181 int rthr = vwrq->value;
2185 if ((rthr < 0) || (rthr > 2347)) {
2188 priv->rts_threshold = rthr;
2190 return -EINPROGRESS; /* Call commit handler */
2193 static int atmel_get_rts(struct net_device *dev,
2194 struct iw_request_info *info,
2195 struct iw_param *vwrq,
2198 struct atmel_private *priv = netdev_priv(dev);
2200 vwrq->value = priv->rts_threshold;
2201 vwrq->disabled = (vwrq->value >= 2347);
2207 static int atmel_set_frag(struct net_device *dev,
2208 struct iw_request_info *info,
2209 struct iw_param *vwrq,
2212 struct atmel_private *priv = netdev_priv(dev);
2213 int fthr = vwrq->value;
2217 if ((fthr < 256) || (fthr > 2346)) {
2220 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
2221 priv->frag_threshold = fthr;
2223 return -EINPROGRESS; /* Call commit handler */
2226 static int atmel_get_frag(struct net_device *dev,
2227 struct iw_request_info *info,
2228 struct iw_param *vwrq,
2231 struct atmel_private *priv = netdev_priv(dev);
2233 vwrq->value = priv->frag_threshold;
2234 vwrq->disabled = (vwrq->value >= 2346);
2240 static int atmel_set_freq(struct net_device *dev,
2241 struct iw_request_info *info,
2242 struct iw_freq *fwrq,
2245 struct atmel_private *priv = netdev_priv(dev);
2246 int rc = -EINPROGRESS; /* Call commit handler */
2248 /* If setting by frequency, convert to a channel */
2250 int f = fwrq->m / 100000;
2252 /* Hack to fall through... */
2254 fwrq->m = ieee80211_frequency_to_channel(f);
2256 /* Setting by channel number */
2257 if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2260 int channel = fwrq->m;
2261 if (atmel_validate_channel(priv, channel) == 0) {
2262 priv->channel = channel;
2270 static int atmel_get_freq(struct net_device *dev,
2271 struct iw_request_info *info,
2272 struct iw_freq *fwrq,
2275 struct atmel_private *priv = netdev_priv(dev);
2277 fwrq->m = priv->channel;
2282 static int atmel_set_scan(struct net_device *dev,
2283 struct iw_request_info *info,
2284 struct iw_point *dwrq,
2287 struct atmel_private *priv = netdev_priv(dev);
2288 unsigned long flags;
2290 /* Note : you may have realised that, as this is a SET operation,
2291 * this is privileged and therefore a normal user can't
2293 * This is not an error, while the device perform scanning,
2294 * traffic doesn't flow, so it's a perfect DoS...
2297 if (priv->station_state == STATION_STATE_DOWN)
2300 /* Timeout old surveys. */
2301 if (time_after(jiffies, priv->last_survey + 20 * HZ))
2302 priv->site_survey_state = SITE_SURVEY_IDLE;
2303 priv->last_survey = jiffies;
2305 /* Initiate a scan command */
2306 if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2309 del_timer_sync(&priv->management_timer);
2310 spin_lock_irqsave(&priv->irqlock, flags);
2312 priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2313 priv->fast_scan = 0;
2314 atmel_scan(priv, 0);
2315 spin_unlock_irqrestore(&priv->irqlock, flags);
2320 static int atmel_get_scan(struct net_device *dev,
2321 struct iw_request_info *info,
2322 struct iw_point *dwrq,
2325 struct atmel_private *priv = netdev_priv(dev);
2327 char *current_ev = extra;
2328 struct iw_event iwe;
2330 if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2333 for (i = 0; i < priv->BSS_list_entries; i++) {
2334 iwe.cmd = SIOCGIWAP;
2335 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2336 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2337 current_ev = iwe_stream_add_event(info, current_ev,
2338 extra + IW_SCAN_MAX_DATA,
2339 &iwe, IW_EV_ADDR_LEN);
2341 iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
2342 if (iwe.u.data.length > 32)
2343 iwe.u.data.length = 32;
2344 iwe.cmd = SIOCGIWESSID;
2345 iwe.u.data.flags = 1;
2346 current_ev = iwe_stream_add_point(info, current_ev,
2347 extra + IW_SCAN_MAX_DATA,
2348 &iwe, priv->BSSinfo[i].SSID);
2350 iwe.cmd = SIOCGIWMODE;
2351 iwe.u.mode = priv->BSSinfo[i].BSStype;
2352 current_ev = iwe_stream_add_event(info, current_ev,
2353 extra + IW_SCAN_MAX_DATA,
2354 &iwe, IW_EV_UINT_LEN);
2356 iwe.cmd = SIOCGIWFREQ;
2357 iwe.u.freq.m = priv->BSSinfo[i].channel;
2359 current_ev = iwe_stream_add_event(info, current_ev,
2360 extra + IW_SCAN_MAX_DATA,
2361 &iwe, IW_EV_FREQ_LEN);
2363 /* Add quality statistics */
2365 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2366 iwe.u.qual.qual = iwe.u.qual.level;
2367 /* iwe.u.qual.noise = SOMETHING */
2368 current_ev = iwe_stream_add_event(info, current_ev,
2369 extra + IW_SCAN_MAX_DATA,
2370 &iwe, IW_EV_QUAL_LEN);
2373 iwe.cmd = SIOCGIWENCODE;
2374 if (priv->BSSinfo[i].UsingWEP)
2375 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2377 iwe.u.data.flags = IW_ENCODE_DISABLED;
2378 iwe.u.data.length = 0;
2379 current_ev = iwe_stream_add_point(info, current_ev,
2380 extra + IW_SCAN_MAX_DATA,
2384 /* Length of data */
2385 dwrq->length = (current_ev - extra);
2391 static int atmel_get_range(struct net_device *dev,
2392 struct iw_request_info *info,
2393 struct iw_point *dwrq,
2396 struct atmel_private *priv = netdev_priv(dev);
2397 struct iw_range *range = (struct iw_range *) extra;
2400 dwrq->length = sizeof(struct iw_range);
2401 memset(range, 0, sizeof(struct iw_range));
2402 range->min_nwid = 0x0000;
2403 range->max_nwid = 0x0000;
2404 range->num_channels = 0;
2405 for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2406 if (priv->reg_domain == channel_table[j].reg_domain) {
2407 range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2410 if (range->num_channels != 0) {
2411 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2412 range->freq[k].i = i; /* List index */
2414 /* Values in MHz -> * 10^5 * 10 */
2415 range->freq[k].m = 100000 *
2416 ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2417 range->freq[k++].e = 1;
2419 range->num_frequency = k;
2422 range->max_qual.qual = 100;
2423 range->max_qual.level = 100;
2424 range->max_qual.noise = 0;
2425 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2427 range->avg_qual.qual = 50;
2428 range->avg_qual.level = 50;
2429 range->avg_qual.noise = 0;
2430 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2432 range->sensitivity = 0;
2434 range->bitrate[0] = 1000000;
2435 range->bitrate[1] = 2000000;
2436 range->bitrate[2] = 5500000;
2437 range->bitrate[3] = 11000000;
2438 range->num_bitrates = 4;
2441 range->max_rts = 2347;
2442 range->min_frag = 256;
2443 range->max_frag = 2346;
2445 range->encoding_size[0] = 5;
2446 range->encoding_size[1] = 13;
2447 range->num_encoding_sizes = 2;
2448 range->max_encoding_tokens = 4;
2450 range->pmp_flags = IW_POWER_ON;
2451 range->pmt_flags = IW_POWER_ON;
2454 range->we_version_source = WIRELESS_EXT;
2455 range->we_version_compiled = WIRELESS_EXT;
2456 range->retry_capa = IW_RETRY_LIMIT ;
2457 range->retry_flags = IW_RETRY_LIMIT;
2458 range->r_time_flags = 0;
2459 range->min_retry = 1;
2460 range->max_retry = 65535;
2465 static int atmel_set_wap(struct net_device *dev,
2466 struct iw_request_info *info,
2467 struct sockaddr *awrq,
2470 struct atmel_private *priv = netdev_priv(dev);
2472 static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2473 static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2474 unsigned long flags;
2476 if (awrq->sa_family != ARPHRD_ETHER)
2479 if (!memcmp(any, awrq->sa_data, 6) ||
2480 !memcmp(off, awrq->sa_data, 6)) {
2481 del_timer_sync(&priv->management_timer);
2482 spin_lock_irqsave(&priv->irqlock, flags);
2483 atmel_scan(priv, 1);
2484 spin_unlock_irqrestore(&priv->irqlock, flags);
2488 for (i = 0; i < priv->BSS_list_entries; i++) {
2489 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2490 if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2492 } else if (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2495 del_timer_sync(&priv->management_timer);
2496 spin_lock_irqsave(&priv->irqlock, flags);
2497 atmel_join_bss(priv, i);
2498 spin_unlock_irqrestore(&priv->irqlock, flags);
2507 static int atmel_config_commit(struct net_device *dev,
2508 struct iw_request_info *info, /* NULL */
2509 void *zwrq, /* NULL */
2510 char *extra) /* NULL */
2512 return atmel_open(dev);
2515 static const iw_handler atmel_handler[] =
2517 (iw_handler) atmel_config_commit, /* SIOCSIWCOMMIT */
2518 (iw_handler) atmel_get_name, /* SIOCGIWNAME */
2519 (iw_handler) NULL, /* SIOCSIWNWID */
2520 (iw_handler) NULL, /* SIOCGIWNWID */
2521 (iw_handler) atmel_set_freq, /* SIOCSIWFREQ */
2522 (iw_handler) atmel_get_freq, /* SIOCGIWFREQ */
2523 (iw_handler) atmel_set_mode, /* SIOCSIWMODE */
2524 (iw_handler) atmel_get_mode, /* SIOCGIWMODE */
2525 (iw_handler) NULL, /* SIOCSIWSENS */
2526 (iw_handler) NULL, /* SIOCGIWSENS */
2527 (iw_handler) NULL, /* SIOCSIWRANGE */
2528 (iw_handler) atmel_get_range, /* SIOCGIWRANGE */
2529 (iw_handler) NULL, /* SIOCSIWPRIV */
2530 (iw_handler) NULL, /* SIOCGIWPRIV */
2531 (iw_handler) NULL, /* SIOCSIWSTATS */
2532 (iw_handler) NULL, /* SIOCGIWSTATS */
2533 (iw_handler) NULL, /* SIOCSIWSPY */
2534 (iw_handler) NULL, /* SIOCGIWSPY */
2535 (iw_handler) NULL, /* -- hole -- */
2536 (iw_handler) NULL, /* -- hole -- */
2537 (iw_handler) atmel_set_wap, /* SIOCSIWAP */
2538 (iw_handler) atmel_get_wap, /* SIOCGIWAP */
2539 (iw_handler) NULL, /* -- hole -- */
2540 (iw_handler) NULL, /* SIOCGIWAPLIST */
2541 (iw_handler) atmel_set_scan, /* SIOCSIWSCAN */
2542 (iw_handler) atmel_get_scan, /* SIOCGIWSCAN */
2543 (iw_handler) atmel_set_essid, /* SIOCSIWESSID */
2544 (iw_handler) atmel_get_essid, /* SIOCGIWESSID */
2545 (iw_handler) NULL, /* SIOCSIWNICKN */
2546 (iw_handler) NULL, /* SIOCGIWNICKN */
2547 (iw_handler) NULL, /* -- hole -- */
2548 (iw_handler) NULL, /* -- hole -- */
2549 (iw_handler) atmel_set_rate, /* SIOCSIWRATE */
2550 (iw_handler) atmel_get_rate, /* SIOCGIWRATE */
2551 (iw_handler) atmel_set_rts, /* SIOCSIWRTS */
2552 (iw_handler) atmel_get_rts, /* SIOCGIWRTS */
2553 (iw_handler) atmel_set_frag, /* SIOCSIWFRAG */
2554 (iw_handler) atmel_get_frag, /* SIOCGIWFRAG */
2555 (iw_handler) NULL, /* SIOCSIWTXPOW */
2556 (iw_handler) NULL, /* SIOCGIWTXPOW */
2557 (iw_handler) atmel_set_retry, /* SIOCSIWRETRY */
2558 (iw_handler) atmel_get_retry, /* SIOCGIWRETRY */
2559 (iw_handler) atmel_set_encode, /* SIOCSIWENCODE */
2560 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */
2561 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */
2562 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */
2563 (iw_handler) NULL, /* -- hole -- */
2564 (iw_handler) NULL, /* -- hole -- */
2565 (iw_handler) NULL, /* SIOCSIWGENIE */
2566 (iw_handler) NULL, /* SIOCGIWGENIE */
2567 (iw_handler) atmel_set_auth, /* SIOCSIWAUTH */
2568 (iw_handler) atmel_get_auth, /* SIOCGIWAUTH */
2569 (iw_handler) atmel_set_encodeext, /* SIOCSIWENCODEEXT */
2570 (iw_handler) atmel_get_encodeext, /* SIOCGIWENCODEEXT */
2571 (iw_handler) NULL, /* SIOCSIWPMKSA */
2574 static const iw_handler atmel_private_handler[] =
2576 NULL, /* SIOCIWFIRSTPRIV */
2579 struct atmel_priv_ioctl {
2581 unsigned char __user *data;
2585 #define ATMELFWL SIOCIWFIRSTPRIV
2586 #define ATMELIDIFC ATMELFWL + 1
2587 #define ATMELRD ATMELFWL + 2
2588 #define ATMELMAGIC 0x51807
2589 #define REGDOMAINSZ 20
2591 static const struct iw_priv_args atmel_private_args[] = {
2594 .set_args = IW_PRIV_TYPE_BYTE
2595 | IW_PRIV_SIZE_FIXED
2596 | sizeof(struct atmel_priv_ioctl),
2597 .get_args = IW_PRIV_TYPE_NONE,
2601 .set_args = IW_PRIV_TYPE_NONE,
2602 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2603 .name = "atmelidifc"
2606 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2607 .get_args = IW_PRIV_TYPE_NONE,
2612 static const struct iw_handler_def atmel_handler_def = {
2613 .num_standard = ARRAY_SIZE(atmel_handler),
2614 .num_private = ARRAY_SIZE(atmel_private_handler),
2615 .num_private_args = ARRAY_SIZE(atmel_private_args),
2616 .standard = (iw_handler *) atmel_handler,
2617 .private = (iw_handler *) atmel_private_handler,
2618 .private_args = (struct iw_priv_args *) atmel_private_args,
2619 .get_wireless_stats = atmel_get_wireless_stats
2622 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2625 struct atmel_private *priv = netdev_priv(dev);
2626 struct atmel_priv_ioctl com;
2627 struct iwreq *wrq = (struct iwreq *) rq;
2628 unsigned char *new_firmware;
2629 char domain[REGDOMAINSZ + 1];
2633 wrq->u.param.value = ATMELMAGIC;
2637 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2642 if (!capable(CAP_NET_ADMIN)) {
2647 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2652 if (copy_from_user(new_firmware, com.data, com.len)) {
2653 kfree(new_firmware);
2658 kfree(priv->firmware);
2660 priv->firmware = new_firmware;
2661 priv->firmware_length = com.len;
2662 strncpy(priv->firmware_id, com.id, 31);
2663 priv->firmware_id[31] = '\0';
2667 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2672 if (!capable(CAP_NET_ADMIN)) {
2677 domain[REGDOMAINSZ] = 0;
2679 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2680 if (!strcasecmp(channel_table[i].name, domain)) {
2681 priv->config_reg_domain = channel_table[i].reg_domain;
2686 if (rc == 0 && priv->station_state != STATION_STATE_DOWN)
2687 rc = atmel_open(dev);
2706 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2708 int old_state = priv->station_state;
2710 if (new_state == old_state)
2713 priv->station_state = new_state;
2715 if (new_state == STATION_STATE_READY) {
2716 netif_start_queue(priv->dev);
2717 netif_carrier_on(priv->dev);
2720 if (old_state == STATION_STATE_READY) {
2721 netif_carrier_off(priv->dev);
2722 if (netif_running(priv->dev))
2723 netif_stop_queue(priv->dev);
2724 priv->last_beacon_timestamp = 0;
2728 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2732 u8 SSID[MAX_SSID_LENGTH];
2736 __le16 min_channel_time;
2737 __le16 max_channel_time;
2742 eth_broadcast_addr(cmd.BSSID);
2744 if (priv->fast_scan) {
2745 cmd.SSID_size = priv->SSID_size;
2746 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2747 cmd.min_channel_time = cpu_to_le16(10);
2748 cmd.max_channel_time = cpu_to_le16(50);
2750 priv->BSS_list_entries = 0;
2752 cmd.min_channel_time = cpu_to_le16(10);
2753 cmd.max_channel_time = cpu_to_le16(120);
2759 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2761 cmd.channel = (priv->channel & 0x7f);
2762 cmd.scan_type = SCAN_TYPE_ACTIVE;
2763 cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2764 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2766 atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2768 /* This must come after all hardware access to avoid being messed up
2769 by stuff happening in interrupt context after we leave STATE_DOWN */
2770 atmel_enter_state(priv, STATION_STATE_SCANNING);
2773 static void join(struct atmel_private *priv, int type)
2777 u8 SSID[MAX_SSID_LENGTH];
2778 u8 BSS_type; /* this is a short in a scan command - weird */
2785 cmd.SSID_size = priv->SSID_size;
2786 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2787 memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2788 cmd.channel = (priv->channel & 0x7f);
2789 cmd.BSS_type = type;
2790 cmd.timeout = cpu_to_le16(2000);
2792 atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2795 static void start(struct atmel_private *priv, int type)
2799 u8 SSID[MAX_SSID_LENGTH];
2806 cmd.SSID_size = priv->SSID_size;
2807 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2808 memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2809 cmd.BSS_type = type;
2810 cmd.channel = (priv->channel & 0x7f);
2812 atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2815 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2819 int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2820 SHORT_PREAMBLE : LONG_PREAMBLE;
2822 if (priv->preamble != new) {
2823 priv->preamble = new;
2825 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2828 if (priv->channel != channel) {
2829 priv->channel = channel;
2831 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2835 priv->station_is_associated = 0;
2836 atmel_enter_state(priv, STATION_STATE_JOINNING);
2838 if (priv->operating_mode == IW_MODE_INFRA)
2839 join(priv, BSS_TYPE_INFRASTRUCTURE);
2841 join(priv, BSS_TYPE_AD_HOC);
2845 static void send_authentication_request(struct atmel_private *priv, u16 system,
2846 u8 *challenge, int challenge_len)
2848 struct ieee80211_hdr header;
2849 struct auth_body auth;
2851 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2852 header.duration_id = cpu_to_le16(0x8000);
2853 header.seq_ctrl = 0;
2854 memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2855 memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2856 memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2858 if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2859 /* no WEP for authentication frames with TrSeqNo 1 */
2860 header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2862 auth.alg = cpu_to_le16(system);
2865 auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2866 priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2867 priv->CurrentAuthentTransactionSeqNum += 2;
2869 if (challenge_len != 0) {
2870 auth.el_id = 16; /* challenge_text */
2871 auth.chall_text_len = challenge_len;
2872 memcpy(auth.chall_text, challenge, challenge_len);
2873 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2875 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2879 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2883 struct ieee80211_hdr header;
2884 struct ass_req_format {
2886 __le16 listen_interval;
2887 u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2890 u8 ssid[MAX_SSID_LENGTH];
2896 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2897 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2898 header.duration_id = cpu_to_le16(0x8000);
2899 header.seq_ctrl = 0;
2901 memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2902 memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2903 memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2905 body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2906 if (priv->wep_is_on)
2907 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2908 if (priv->preamble == SHORT_PREAMBLE)
2909 body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2911 body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2913 /* current AP address - only in reassoc frame */
2915 memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2916 ssid_el_p = &body.ssid_el_id;
2917 bodysize = 18 + priv->SSID_size;
2919 ssid_el_p = &body.ap[0];
2920 bodysize = 12 + priv->SSID_size;
2923 ssid_el_p[0] = WLAN_EID_SSID;
2924 ssid_el_p[1] = priv->SSID_size;
2925 memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2926 ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2927 ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2928 memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2930 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2933 static int is_frame_from_current_bss(struct atmel_private *priv,
2934 struct ieee80211_hdr *header)
2936 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2937 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2939 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2942 static int retrieve_bss(struct atmel_private *priv)
2945 int max_rssi = -128;
2948 if (priv->BSS_list_entries == 0)
2951 if (priv->connect_to_any_BSS) {
2952 /* Select a BSS with the max-RSSI but of the same type and of
2953 the same WEP mode and that it is not marked as 'bad' (i.e.
2954 we had previously failed to connect to this BSS with the
2955 settings that we currently use) */
2956 priv->current_BSS = 0;
2957 for (i = 0; i < priv->BSS_list_entries; i++) {
2958 if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2959 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2960 (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2961 !(priv->BSSinfo[i].channel & 0x80)) {
2962 max_rssi = priv->BSSinfo[i].RSSI;
2963 priv->current_BSS = max_index = i;
2969 for (i = 0; i < priv->BSS_list_entries; i++) {
2970 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2971 memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2972 priv->operating_mode == priv->BSSinfo[i].BSStype &&
2973 atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2974 if (priv->BSSinfo[i].RSSI >= max_rssi) {
2975 max_rssi = priv->BSSinfo[i].RSSI;
2983 static void store_bss_info(struct atmel_private *priv,
2984 struct ieee80211_hdr *header, u16 capability,
2985 u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2986 u8 *ssid, int is_beacon)
2988 u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2991 for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2992 if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
2995 /* If we process a probe and an entry from this BSS exists
2996 we will update the BSS entry with the info from this BSS.
2997 If we process a beacon we will only update RSSI */
3000 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
3002 index = priv->BSS_list_entries++;
3003 memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
3004 priv->BSSinfo[index].RSSI = rssi;
3006 if (rssi > priv->BSSinfo[index].RSSI)
3007 priv->BSSinfo[index].RSSI = rssi;
3012 priv->BSSinfo[index].channel = channel;
3013 priv->BSSinfo[index].beacon_period = beacon_period;
3014 priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3015 memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3016 priv->BSSinfo[index].SSIDsize = ssid_len;
3018 if (capability & WLAN_CAPABILITY_IBSS)
3019 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3020 else if (capability & WLAN_CAPABILITY_ESS)
3021 priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3023 priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3024 SHORT_PREAMBLE : LONG_PREAMBLE;
3027 static void authenticate(struct atmel_private *priv, u16 frame_len)
3029 struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3030 u16 status = le16_to_cpu(auth->status);
3031 u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3032 u16 system = le16_to_cpu(auth->alg);
3034 if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3036 if (priv->station_was_associated) {
3037 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3038 send_association_request(priv, 1);
3041 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3042 send_association_request(priv, 0);
3047 if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3048 int should_associate = 0;
3050 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3053 if (system == WLAN_AUTH_OPEN) {
3054 if (trans_seq_no == 0x0002) {
3055 should_associate = 1;
3057 } else if (system == WLAN_AUTH_SHARED_KEY) {
3058 if (trans_seq_no == 0x0002 &&
3059 auth->el_id == WLAN_EID_CHALLENGE) {
3060 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3062 } else if (trans_seq_no == 0x0004) {
3063 should_associate = 1;
3067 if (should_associate) {
3068 if (priv->station_was_associated) {
3069 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3070 send_association_request(priv, 1);
3073 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3074 send_association_request(priv, 0);
3080 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3081 /* Flip back and forth between WEP auth modes until the max
3082 * authentication tries has been exceeded.
3084 if (system == WLAN_AUTH_OPEN) {
3085 priv->CurrentAuthentTransactionSeqNum = 0x001;
3086 priv->exclude_unencrypted = 1;
3087 send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3089 } else if (system == WLAN_AUTH_SHARED_KEY
3090 && priv->wep_is_on) {
3091 priv->CurrentAuthentTransactionSeqNum = 0x001;
3092 priv->exclude_unencrypted = 0;
3093 send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3095 } else if (priv->connect_to_any_BSS) {
3098 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3100 if ((bss_index = retrieve_bss(priv)) != -1) {
3101 atmel_join_bss(priv, bss_index);
3107 priv->AuthenticationRequestRetryCnt = 0;
3108 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3109 priv->station_is_associated = 0;
3112 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3114 struct ass_resp_format {
3121 } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3123 u16 status = le16_to_cpu(ass_resp->status);
3124 u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3125 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3127 union iwreq_data wrqu;
3129 if (frame_len < 8 + rates_len)
3132 if (status == WLAN_STATUS_SUCCESS) {
3133 if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3134 priv->AssociationRequestRetryCnt = 0;
3136 priv->ReAssociationRequestRetryCnt = 0;
3138 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3139 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3140 atmel_set_mib(priv, Phy_Mib_Type,
3141 PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3142 if (priv->power_mode == 0) {
3143 priv->listen_interval = 1;
3144 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3145 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3146 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3147 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3149 priv->listen_interval = 2;
3150 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3151 MAC_MGMT_MIB_PS_MODE_POS, PS_MODE);
3152 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3153 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3156 priv->station_is_associated = 1;
3157 priv->station_was_associated = 1;
3158 atmel_enter_state(priv, STATION_STATE_READY);
3160 /* Send association event to userspace */
3161 wrqu.data.length = 0;
3162 wrqu.data.flags = 0;
3163 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3164 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3165 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3170 if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3171 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3172 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3173 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3174 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3175 priv->AssociationRequestRetryCnt++;
3176 send_association_request(priv, 0);
3180 if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3181 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3182 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3183 priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3184 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3185 priv->ReAssociationRequestRetryCnt++;
3186 send_association_request(priv, 1);
3190 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3191 priv->station_is_associated = 0;
3193 if (priv->connect_to_any_BSS) {
3195 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3197 if ((bss_index = retrieve_bss(priv)) != -1)
3198 atmel_join_bss(priv, bss_index);
3202 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3204 struct bss_info *bss = &priv->BSSinfo[bss_index];
3206 memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3207 memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3209 /* The WPA stuff cares about the current AP address */
3211 build_wpa_mib(priv);
3213 /* When switching to AdHoc turn OFF Power Save if needed */
3215 if (bss->BSStype == IW_MODE_ADHOC &&
3216 priv->operating_mode != IW_MODE_ADHOC &&
3218 priv->power_mode = 0;
3219 priv->listen_interval = 1;
3220 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3221 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3222 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3223 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3226 priv->operating_mode = bss->BSStype;
3227 priv->channel = bss->channel & 0x7f;
3228 priv->beacon_period = bss->beacon_period;
3230 if (priv->preamble != bss->preamble) {
3231 priv->preamble = bss->preamble;
3232 atmel_set_mib8(priv, Local_Mib_Type,
3233 LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3236 if (!priv->wep_is_on && bss->UsingWEP) {
3237 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3238 priv->station_is_associated = 0;
3242 if (priv->wep_is_on && !bss->UsingWEP) {
3243 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3244 priv->station_is_associated = 0;
3248 atmel_enter_state(priv, STATION_STATE_JOINNING);
3250 if (priv->operating_mode == IW_MODE_INFRA)
3251 join(priv, BSS_TYPE_INFRASTRUCTURE);
3253 join(priv, BSS_TYPE_AD_HOC);
3256 static void restart_search(struct atmel_private *priv)
3260 if (!priv->connect_to_any_BSS) {
3261 atmel_scan(priv, 1);
3263 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3265 if ((bss_index = retrieve_bss(priv)) != -1)
3266 atmel_join_bss(priv, bss_index);
3268 atmel_scan(priv, 0);
3272 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3274 u8 old = priv->wstats.qual.level;
3275 u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3277 switch (priv->firmware_type) {
3278 case ATMEL_FW_TYPE_502E:
3279 max_rssi = 63; /* 502-rmfd-reve max by experiment */
3285 rssi = rssi * 100 / max_rssi;
3286 if ((rssi + old) % 2)
3287 priv->wstats.qual.level = (rssi + old) / 2 + 1;
3289 priv->wstats.qual.level = (rssi + old) / 2;
3290 priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3291 priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3294 static void atmel_smooth_qual(struct atmel_private *priv)
3296 unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3297 while (time_diff--) {
3298 priv->last_qual += HZ;
3299 priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3300 priv->wstats.qual.qual +=
3301 priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3302 priv->beacons_this_sec = 0;
3304 priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3305 priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3308 /* deals with incoming management frames. */
3309 static void atmel_management_frame(struct atmel_private *priv,
3310 struct ieee80211_hdr *header,
3311 u16 frame_len, u8 rssi)
3315 subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3317 case IEEE80211_STYPE_BEACON:
3318 case IEEE80211_STYPE_PROBE_RESP:
3320 /* beacon frame has multiple variable-length fields -
3321 never let an engineer loose with a data structure design. */
3323 struct beacon_format {
3336 } *beacon = (struct beacon_format *)priv->rx_buf;
3338 u8 channel, rates_length, ssid_length;
3339 u64 timestamp = le64_to_cpu(beacon->timestamp);
3340 u16 beacon_interval = le16_to_cpu(beacon->interval);
3341 u16 capability = le16_to_cpu(beacon->capability);
3342 u8 *beaconp = priv->rx_buf;
3343 ssid_length = beacon->ssid_length;
3344 /* this blows chunks. */
3345 if (frame_len < 14 || frame_len < ssid_length + 15)
3347 rates_length = beaconp[beacon->ssid_length + 15];
3348 if (frame_len < ssid_length + rates_length + 18)
3350 if (ssid_length > MAX_SSID_LENGTH)
3352 channel = beaconp[ssid_length + rates_length + 18];
3354 if (priv->station_state == STATION_STATE_READY) {
3355 smooth_rssi(priv, rssi);
3356 if (is_frame_from_current_bss(priv, header)) {
3357 priv->beacons_this_sec++;
3358 atmel_smooth_qual(priv);
3359 if (priv->last_beacon_timestamp) {
3360 /* Note truncate this to 32 bits - kernel can't divide a long long */
3361 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3362 int beacons = beacon_delay / (beacon_interval * 1000);
3364 priv->wstats.miss.beacon += beacons - 1;
3366 priv->last_beacon_timestamp = timestamp;
3367 handle_beacon_probe(priv, capability, channel);
3371 if (priv->station_state == STATION_STATE_SCANNING)
3372 store_bss_info(priv, header, capability,
3373 beacon_interval, channel, rssi,
3375 &beacon->rates_el_id,
3376 subtype == IEEE80211_STYPE_BEACON);
3380 case IEEE80211_STYPE_AUTH:
3382 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3383 authenticate(priv, frame_len);
3387 case IEEE80211_STYPE_ASSOC_RESP:
3388 case IEEE80211_STYPE_REASSOC_RESP:
3390 if (priv->station_state == STATION_STATE_ASSOCIATING ||
3391 priv->station_state == STATION_STATE_REASSOCIATING)
3392 associate(priv, frame_len, subtype);
3396 case IEEE80211_STYPE_DISASSOC:
3397 if (priv->station_is_associated &&
3398 priv->operating_mode == IW_MODE_INFRA &&
3399 is_frame_from_current_bss(priv, header)) {
3400 priv->station_was_associated = 0;
3401 priv->station_is_associated = 0;
3403 atmel_enter_state(priv, STATION_STATE_JOINNING);
3404 join(priv, BSS_TYPE_INFRASTRUCTURE);
3409 case IEEE80211_STYPE_DEAUTH:
3410 if (priv->operating_mode == IW_MODE_INFRA &&
3411 is_frame_from_current_bss(priv, header)) {
3412 priv->station_was_associated = 0;
3414 atmel_enter_state(priv, STATION_STATE_JOINNING);
3415 join(priv, BSS_TYPE_INFRASTRUCTURE);
3422 /* run when timer expires */
3423 static void atmel_management_timer(u_long a)
3425 struct net_device *dev = (struct net_device *) a;
3426 struct atmel_private *priv = netdev_priv(dev);
3427 unsigned long flags;
3429 /* Check if the card has been yanked. */
3430 if (priv->card && priv->present_callback &&
3431 !(*priv->present_callback)(priv->card))
3434 spin_lock_irqsave(&priv->irqlock, flags);
3436 switch (priv->station_state) {
3438 case STATION_STATE_AUTHENTICATING:
3439 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3440 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3441 priv->station_is_associated = 0;
3442 priv->AuthenticationRequestRetryCnt = 0;
3443 restart_search(priv);
3445 int auth = WLAN_AUTH_OPEN;
3446 priv->AuthenticationRequestRetryCnt++;
3447 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3448 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3449 if (priv->wep_is_on && priv->exclude_unencrypted)
3450 auth = WLAN_AUTH_SHARED_KEY;
3451 send_authentication_request(priv, auth, NULL, 0);
3455 case STATION_STATE_ASSOCIATING:
3456 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3457 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3458 priv->station_is_associated = 0;
3459 priv->AssociationRequestRetryCnt = 0;
3460 restart_search(priv);
3462 priv->AssociationRequestRetryCnt++;
3463 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3464 send_association_request(priv, 0);
3468 case STATION_STATE_REASSOCIATING:
3469 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3470 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3471 priv->station_is_associated = 0;
3472 priv->ReAssociationRequestRetryCnt = 0;
3473 restart_search(priv);
3475 priv->ReAssociationRequestRetryCnt++;
3476 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3477 send_association_request(priv, 1);
3485 spin_unlock_irqrestore(&priv->irqlock, flags);
3488 static void atmel_command_irq(struct atmel_private *priv)
3490 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3491 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3493 union iwreq_data wrqu;
3495 if (status == CMD_STATUS_IDLE ||
3496 status == CMD_STATUS_IN_PROGRESS)
3501 if (status == CMD_STATUS_COMPLETE) {
3502 priv->station_was_associated = priv->station_is_associated;
3503 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3504 (u8 *)priv->CurrentBSSID, 6);
3505 atmel_enter_state(priv, STATION_STATE_READY);
3510 fast_scan = priv->fast_scan;
3511 priv->fast_scan = 0;
3513 if (status != CMD_STATUS_COMPLETE) {
3514 atmel_scan(priv, 1);
3516 int bss_index = retrieve_bss(priv);
3517 int notify_scan_complete = 1;
3518 if (bss_index != -1) {
3519 atmel_join_bss(priv, bss_index);
3520 } else if (priv->operating_mode == IW_MODE_ADHOC &&
3521 priv->SSID_size != 0) {
3522 start(priv, BSS_TYPE_AD_HOC);
3524 priv->fast_scan = !fast_scan;
3525 atmel_scan(priv, 1);
3526 notify_scan_complete = 0;
3528 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3529 if (notify_scan_complete) {
3530 wrqu.data.length = 0;
3531 wrqu.data.flags = 0;
3532 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3537 case CMD_SiteSurvey:
3538 priv->fast_scan = 0;
3540 if (status != CMD_STATUS_COMPLETE)
3543 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3544 if (priv->station_is_associated) {
3545 atmel_enter_state(priv, STATION_STATE_READY);
3546 wrqu.data.length = 0;
3547 wrqu.data.flags = 0;
3548 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3550 atmel_scan(priv, 1);
3555 if (status == CMD_STATUS_COMPLETE) {
3556 if (priv->operating_mode == IW_MODE_ADHOC) {
3557 priv->station_was_associated = priv->station_is_associated;
3558 atmel_enter_state(priv, STATION_STATE_READY);
3560 int auth = WLAN_AUTH_OPEN;
3561 priv->AuthenticationRequestRetryCnt = 0;
3562 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3564 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3565 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3566 if (priv->wep_is_on && priv->exclude_unencrypted)
3567 auth = WLAN_AUTH_SHARED_KEY;
3568 send_authentication_request(priv, auth, NULL, 0);
3573 atmel_scan(priv, 1);
3577 static int atmel_wakeup_firmware(struct atmel_private *priv)
3579 struct host_info_struct *iface = &priv->host_info;
3583 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3584 atmel_set_gcr(priv->dev, GCR_REMAP);
3586 /* wake up on-board processor */
3587 atmel_clear_gcr(priv->dev, 0x0040);
3588 atmel_write16(priv->dev, BSR, BSS_SRAM);
3590 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3593 /* and wait for it */
3594 for (i = LOOP_RETRY_LIMIT; i; i--) {
3595 mr1 = atmel_read16(priv->dev, MR1);
3596 mr3 = atmel_read16(priv->dev, MR3);
3598 if (mr3 & MAC_BOOT_COMPLETE)
3600 if (mr1 & MAC_BOOT_COMPLETE &&
3601 priv->bus_type == BUS_TYPE_PCCARD)
3606 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3610 if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3611 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3615 /* now check for completion of MAC initialization through
3616 the FunCtrl field of the IFACE, poll MR1 to detect completion of
3617 MAC initialization, check completion status, set interrupt mask,
3618 enables interrupts and calls Tx and Rx initialization functions */
3620 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3622 for (i = LOOP_RETRY_LIMIT; i; i--) {
3623 mr1 = atmel_read16(priv->dev, MR1);
3624 mr3 = atmel_read16(priv->dev, MR3);
3626 if (mr3 & MAC_INIT_COMPLETE)
3628 if (mr1 & MAC_INIT_COMPLETE &&
3629 priv->bus_type == BUS_TYPE_PCCARD)
3634 printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3639 /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3640 if ((mr3 & MAC_INIT_COMPLETE) &&
3641 !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3642 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3645 if ((mr1 & MAC_INIT_COMPLETE) &&
3646 !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3647 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3651 atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3652 priv->host_info_base, sizeof(*iface));
3654 iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3655 iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3656 iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3657 iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3658 iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3659 iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3660 iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3661 iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3662 iface->build_version = le16_to_cpu(iface->build_version);
3663 iface->command_pos = le16_to_cpu(iface->command_pos);
3664 iface->major_version = le16_to_cpu(iface->major_version);
3665 iface->minor_version = le16_to_cpu(iface->minor_version);
3666 iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3667 iface->mac_status = le16_to_cpu(iface->mac_status);
3672 /* determine type of memory and MAC address */
3673 static int probe_atmel_card(struct net_device *dev)
3676 struct atmel_private *priv = netdev_priv(dev);
3679 if (priv->bus_type == BUS_TYPE_PCCARD)
3680 atmel_write16(dev, GCR, 0x0060);
3682 atmel_write16(dev, GCR, 0x0040);
3685 if (atmel_read16(dev, MR2) == 0) {
3686 /* No stored firmware so load a small stub which just
3687 tells us the MAC address */
3689 priv->card_type = CARD_TYPE_EEPROM;
3690 atmel_write16(dev, BSR, BSS_IRAM);
3691 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3692 atmel_set_gcr(dev, GCR_REMAP);
3693 atmel_clear_gcr(priv->dev, 0x0040);
3694 atmel_write16(dev, BSR, BSS_SRAM);
3695 for (i = LOOP_RETRY_LIMIT; i; i--)
3696 if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3699 printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3701 atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3702 /* got address, now squash it again until the network
3703 interface is opened */
3704 if (priv->bus_type == BUS_TYPE_PCCARD)
3705 atmel_write16(dev, GCR, 0x0060);
3706 atmel_write16(dev, GCR, 0x0040);
3709 } else if (atmel_read16(dev, MR4) == 0) {
3710 /* Mac address easy in this case. */
3711 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3712 atmel_write16(dev, BSR, 1);
3713 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3714 atmel_write16(dev, BSR, 0x200);
3717 /* Standard firmware in flash, boot it up and ask
3718 for the Mac Address */
3719 priv->card_type = CARD_TYPE_SPI_FLASH;
3720 if (atmel_wakeup_firmware(priv) == 0) {
3721 atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3723 /* got address, now squash it again until the network
3724 interface is opened */
3725 if (priv->bus_type == BUS_TYPE_PCCARD)
3726 atmel_write16(dev, GCR, 0x0060);
3727 atmel_write16(dev, GCR, 0x0040);
3733 if (dev->dev_addr[0] == 0xFF) {
3734 static const u8 default_mac[] = {
3735 0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3737 printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3738 memcpy(dev->dev_addr, default_mac, ETH_ALEN);
3745 /* Move the encyption information on the MIB structure.
3746 This routine is for the pre-WPA firmware: later firmware has
3747 a different format MIB and a different routine. */
3748 static void build_wep_mib(struct atmel_private *priv)
3750 struct { /* NB this is matched to the hardware, don't change. */
3752 u8 default_key; /* 0..3 */
3754 u8 exclude_unencrypted;
3756 u32 WEPICV_error_count;
3757 u32 WEP_excluded_count;
3759 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3760 u8 encryption_level; /* 0, 1, 2 */
3765 mib.wep_is_on = priv->wep_is_on;
3766 if (priv->wep_is_on) {
3767 if (priv->wep_key_len[priv->default_key] > 5)
3768 mib.encryption_level = 2;
3770 mib.encryption_level = 1;
3772 mib.encryption_level = 0;
3775 mib.default_key = priv->default_key;
3776 mib.exclude_unencrypted = priv->exclude_unencrypted;
3778 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3779 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3781 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3784 static void build_wpa_mib(struct atmel_private *priv)
3786 /* This is for the later (WPA enabled) firmware. */
3788 struct { /* NB this is matched to the hardware, don't change. */
3789 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3790 u8 receiver_address[ETH_ALEN];
3792 u8 default_key; /* 0..3 */
3794 u8 exclude_unencrypted;
3798 u32 WEPICV_error_count;
3799 u32 WEP_excluded_count;
3806 mib.wep_is_on = priv->wep_is_on;
3807 mib.exclude_unencrypted = priv->exclude_unencrypted;
3808 memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3810 /* zero all the keys before adding in valid ones. */
3811 memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3813 if (priv->wep_is_on) {
3814 /* There's a comment in the Atmel code to the effect that this
3815 is only valid when still using WEP, it may need to be set to
3816 something to use WPA */
3817 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3819 mib.default_key = mib.group_key = 255;
3820 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3821 if (priv->wep_key_len[i] > 0) {
3822 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3823 if (i == priv->default_key) {
3824 mib.default_key = i;
3825 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3826 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3829 priv->group_cipher_suite = priv->pairwise_cipher_suite;
3830 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3831 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3835 if (mib.default_key == 255)
3836 mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3837 if (mib.group_key == 255)
3838 mib.group_key = mib.default_key;
3842 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3845 static int reset_atmel_card(struct net_device *dev)
3847 /* do everything necessary to wake up the hardware, including
3848 waiting for the lightning strike and throwing the knife switch....
3850 set all the Mib values which matter in the card to match
3851 their settings in the atmel_private structure. Some of these
3852 can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3853 can only be changed by tearing down the world and coming back through
3856 This routine is also responsible for initialising some
3857 hardware-specific fields in the atmel_private structure,
3858 including a copy of the firmware's hostinfo structure
3859 which is the route into the rest of the firmware datastructures. */
3861 struct atmel_private *priv = netdev_priv(dev);
3863 int old_state = priv->station_state;
3866 /* data to add to the firmware names, in priority order
3867 this implemenents firmware versioning */
3869 static char *firmware_modifier[] = {
3876 if (priv->bus_type == BUS_TYPE_PCCARD)
3877 atmel_write16(priv->dev, GCR, 0x0060);
3879 /* stop card , disable interrupts */
3880 atmel_write16(priv->dev, GCR, 0x0040);
3882 if (priv->card_type == CARD_TYPE_EEPROM) {
3883 /* copy in firmware if needed */
3884 const struct firmware *fw_entry = NULL;
3885 const unsigned char *fw;
3886 int len = priv->firmware_length;
3887 if (!(fw = priv->firmware)) {
3888 if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3889 if (strlen(priv->firmware_id) == 0) {
3891 "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3894 "%s: if not, use the firmware= module parameter.\n",
3896 strcpy(priv->firmware_id, "/*(DEBLOBBED)*/");
3898 err = reject_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3901 "%s: firmware %s is missing, cannot continue.\n",
3902 dev->name, priv->firmware_id);
3909 /* get firmware filename entry based on firmware type ID */
3910 while (fw_table[fw_index].fw_type != priv->firmware_type
3911 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3914 /* construct the actual firmware file name */
3915 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3917 for (i = 0; firmware_modifier[i]; i++) {
3918 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3919 firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3920 priv->firmware_id[31] = '\0';
3921 if (reject_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3929 "%s: firmware %s is missing, cannot start.\n",
3930 dev->name, priv->firmware_id);
3931 priv->firmware_id[0] = '\0';
3936 fw = fw_entry->data;
3937 len = fw_entry->size;
3940 if (len <= 0x6000) {
3941 atmel_write16(priv->dev, BSR, BSS_IRAM);
3942 atmel_copy_to_card(priv->dev, 0, fw, len);
3943 atmel_set_gcr(priv->dev, GCR_REMAP);
3946 atmel_set_gcr(priv->dev, GCR_REMAP);
3947 atmel_write16(priv->dev, BSR, BSS_IRAM);
3948 atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3949 atmel_write16(priv->dev, BSR, 0x2ff);
3950 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3953 release_firmware(fw_entry);
3956 err = atmel_wakeup_firmware(priv);
3960 /* Check the version and set the correct flag for wpa stuff,
3961 old and new firmware is incompatible.
3962 The pre-wpa 3com firmware reports major version 5,
3963 the wpa 3com firmware is major version 4 and doesn't need
3964 the 3com broken-ness filter. */
3965 priv->use_wpa = (priv->host_info.major_version == 4);
3966 priv->radio_on_broken = (priv->host_info.major_version == 5);
3968 /* unmask all irq sources */
3969 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3971 /* int Tx system and enable Tx */
3972 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3973 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3974 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3975 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3977 priv->tx_desc_free = priv->host_info.tx_desc_count;
3978 priv->tx_desc_head = 0;
3979 priv->tx_desc_tail = 0;
3980 priv->tx_desc_previous = 0;
3981 priv->tx_free_mem = priv->host_info.tx_buff_size;
3982 priv->tx_buff_head = 0;
3983 priv->tx_buff_tail = 0;
3985 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3986 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3987 configuration | FUNC_CTRL_TxENABLE);
3989 /* init Rx system and enable */
3990 priv->rx_desc_head = 0;
3992 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3993 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3994 configuration | FUNC_CTRL_RxENABLE);
3996 if (!priv->radio_on_broken) {
3997 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3998 CMD_STATUS_REJECTED_RADIO_OFF) {
3999 printk(KERN_INFO "%s: cannot turn the radio on.\n",
4005 /* set up enough MIB values to run. */
4006 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4007 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_TX_PROMISCUOUS_POS, PROM_MODE_OFF);
4008 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4009 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4010 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4011 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4012 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4013 atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4014 priv->dev->dev_addr, 6);
4015 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4016 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4017 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4018 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4019 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4021 build_wpa_mib(priv);
4023 build_wep_mib(priv);
4025 if (old_state == STATION_STATE_READY) {
4026 union iwreq_data wrqu;
4028 wrqu.data.length = 0;
4029 wrqu.data.flags = 0;
4030 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4031 eth_zero_addr(wrqu.ap_addr.sa_data);
4032 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4038 static void atmel_send_command(struct atmel_private *priv, int command,
4039 void *cmd, int cmd_size)
4042 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4045 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4046 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4049 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4050 void *cmd, int cmd_size)
4054 atmel_send_command(priv, command, cmd, cmd_size);
4056 for (i = 5000; i; i--) {
4057 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4058 if (status != CMD_STATUS_IDLE &&
4059 status != CMD_STATUS_IN_PROGRESS)
4065 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4066 status = CMD_STATUS_HOST_ERROR;
4068 if (command != CMD_EnableRadio)
4069 status = CMD_STATUS_COMPLETE;
4075 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4077 struct get_set_mib m;
4082 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4083 return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4086 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4088 struct get_set_mib m;
4094 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4097 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4100 struct get_set_mib m;
4105 m.data[1] = data >> 8;
4107 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4110 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4111 u8 *data, int data_len)
4113 struct get_set_mib m;
4118 if (data_len > MIB_MAX_DATA_BYTES)
4119 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4121 memcpy(m.data, data, data_len);
4122 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4125 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4126 u8 *data, int data_len)
4128 struct get_set_mib m;
4133 if (data_len > MIB_MAX_DATA_BYTES)
4134 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4136 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4137 atmel_copy_to_host(priv->dev, data,
4138 atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4141 static void atmel_writeAR(struct net_device *dev, u16 data)
4144 outw(data, dev->base_addr + AR);
4145 /* Address register appears to need some convincing..... */
4146 for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4147 outw(data, dev->base_addr + AR);
4150 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4151 const unsigned char *src, u16 len)
4154 atmel_writeAR(dev, dest);
4156 atmel_write8(dev, DR, *src);
4159 for (i = len; i > 1 ; i -= 2) {
4162 atmel_write16(dev, DR, lb | (hb << 8));
4165 atmel_write8(dev, DR, *src);
4168 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4172 atmel_writeAR(dev, src);
4174 *dest = atmel_read8(dev, DR);
4177 for (i = len; i > 1 ; i -= 2) {
4178 u16 hw = atmel_read16(dev, DR);
4183 *dest = atmel_read8(dev, DR);
4186 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4188 outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4191 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4193 outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4196 static int atmel_lock_mac(struct atmel_private *priv)
4200 for (i = 5000; i; i--) {
4201 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4207 return 0; /* timed out */
4209 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4210 if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4211 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4213 return 0; /* timed out */
4220 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4222 atmel_writeAR(priv->dev, pos);
4223 atmel_write16(priv->dev, DR, data); /* card is little-endian */
4224 atmel_write16(priv->dev, DR, data >> 16);
4227 /***************************************************************************/
4228 /* There follows the source form of the MAC address reading firmware */
4229 /***************************************************************************/
4232 /* Copyright 2003 Matthew T. Russotto */
4233 /* But derived from the Atmel 76C502 firmware written by Atmel and */
4234 /* included in "atmel wireless lan drivers" package */
4236 This file is part of net.russotto.AtmelMACFW, hereto referred to
4239 AtmelMACFW is free software; you can redistribute it and/or modify
4240 it under the terms of the GNU General Public License version 2
4241 as published by the Free Software Foundation.
4243 AtmelMACFW is distributed in the hope that it will be useful,
4244 but WITHOUT ANY WARRANTY; without even the implied warranty of
4245 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4246 GNU General Public License for more details.
4248 You should have received a copy of the GNU General Public License
4249 along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4251 ****************************************************************************/
4252 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */
4253 /* It will probably work on the 76C504 and 76C502 RFMD_3COM */
4254 /* It only works on SPI EEPROM versions of the card. */
4256 /* This firmware initializes the SPI controller and clock, reads the MAC */
4257 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC */
4258 /* address in MR2, and sets MR3 to 0x10 to indicate it is done */
4259 /* It also puts a complete copy of the EEPROM in SRAM with the offset in */
4260 /* MR4, for investigational purposes (maybe we can determine chip type */
4264 .set MRBASE, 0x8000000
4265 .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4266 .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4267 .set SRAM_BASE, 0x02000000
4268 .set SP_BASE, 0x0F300000
4269 .set UNK_BASE, 0x0F000000 /* Some internal device, but which one? */
4270 .set SPI_CGEN_BASE, 0x0E000000 /* Some internal device, but which one? */
4271 .set UNK3_BASE, 0x02014000 /* Some internal device, but which one? */
4272 .set STACK_BASE, 0x5600
4274 .set SP_TDRE, 2 /* status register bit -- TDR empty */
4275 .set SP_RDRF, 1 /* status register bit -- RDR full */
4278 .set SP_CR, 0 /* control register */
4279 .set SP_MR, 4 /* mode register */
4280 .set SP_RDR, 0x08 /* Read Data Register */
4281 .set SP_TDR, 0x0C /* Transmit Data Register */
4282 .set SP_CSR0, 0x30 /* chip select registers */
4286 .set NVRAM_CMD_RDSR, 5 /* read status register */
4287 .set NVRAM_CMD_READ, 3 /* read data */
4288 .set NVRAM_SR_RDY, 1 /* RDY bit. This bit is inverted */
4289 .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4290 serial output, since SO is normally high. But it
4291 does cause 8 clock cycles and thus 8 bits to be
4292 clocked in to the chip. See Atmel's SPI
4293 controller (e.g. AT91M55800) timing and 4K
4294 SPI EEPROM manuals */
4296 .set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */
4297 .set NVRAM_IMAGE, 0x02000200
4298 .set NVRAM_LENGTH, 0x0200
4299 .set MAC_ADDRESS_MIB, SRAM_BASE
4300 .set MAC_ADDRESS_LENGTH, 6
4301 .set MAC_BOOT_FLAG, 0x10
4323 mov r0, #CPSR_INITIAL
4324 msr CPSR_c, r0 /* This is probably unnecessary */
4326 /* I'm guessing this is initializing clock generator electronics for SPI */
4327 ldr r0, =SPI_CGEN_BASE
4352 ldr r1, =MAC_ADDRESS_MIB
4354 ldr r1, =NVRAM_IMAGE
4356 mov r1, #MAC_BOOT_FLAG
4359 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4362 mov r2, #0 /* 0th bytes of NVRAM */
4363 mov r3, #NVRAM_LENGTH
4364 mov r1, #0 /* not used in routine */
4365 ldr r0, =NVRAM_IMAGE
4371 .func Get_MAC_Addr, GET_MAC_ADDR
4374 mov r2, #0x120 /* address of MAC Address within NVRAM */
4375 mov r3, #MAC_ADDRESS_LENGTH
4376 mov r1, #0 /* not used in routine */
4377 ldr r0, =MAC_ADDRESS_MIB
4383 .func Delay9, DELAY9
4385 adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */
4394 .func SP_Init, SP_INIT
4398 str r1, [r0, #SP_CR] /* reset the SPI */
4400 str r1, [r0, #SP_CR] /* release SPI from reset state */
4402 str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4403 str r1, [r0, #SP_CR] /* enable the SPI */
4405 /* My guess would be this turns on the SPI clock */
4406 ldr r3, =SPI_CGEN_BASE
4412 str r1, [r0, #SP_CSR0]
4414 str r1, [r0, #SP_CSR1]
4415 str r1, [r0, #SP_CSR2]
4416 str r1, [r0, #SP_CSR3]
4417 ldr r1, [r0, #SP_SR]
4418 ldr r0, [r0, #SP_RDR]
4421 .func NVRAM_Init, NVRAM_INIT
4424 ldr r0, [r1, #SP_RDR]
4425 mov r0, #NVRAM_CMD_RDSR
4426 str r0, [r1, #SP_TDR]
4428 ldr r0, [r1, #SP_SR]
4432 mov r0, #SPI_8CLOCKS
4433 str r0, [r1, #SP_TDR]
4435 ldr r0, [r1, #SP_SR]
4439 ldr r0, [r1, #SP_RDR]
4441 ldr r0, [r1, #SP_SR]
4445 ldr r0, [r1, #SP_RDR]
4450 .func NVRAM_Xfer, NVRAM_XFER
4451 /* r0 = dest address */
4453 /* r2 = src address within NVRAM */
4456 stmdb sp!, {r4, r5, lr}
4457 mov r5, r0 /* save r0 (dest address) */
4458 mov r4, r3 /* save r3 (length) */
4459 mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */
4461 add r0, r0, #NVRAM_CMD_READ
4462 ldr r1, =NVRAM_SCRATCH
4463 strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */
4464 strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */
4467 tst r0, #NVRAM_SR_RDY
4471 mov r2, r4 /* length */
4472 mov r1, r5 /* dest address */
4473 mov r0, #2 /* bytes to transfer in command */
4475 ldmia sp!, {r4, r5, lr}
4479 .func NVRAM_Xfer2, NVRAM_XFER2
4481 stmdb sp!, {r4, r5, r6, lr}
4486 ldr r5, =NVRAM_SCRATCH
4489 str r6, [r4, #SP_TDR]
4491 ldr r6, [r4, #SP_SR]
4495 cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */
4498 mov r3, #SPI_8CLOCKS
4499 str r3, [r4, #SP_TDR]
4500 ldr r0, [r4, #SP_RDR]
4502 ldr r0, [r4, #SP_SR]
4505 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 */
4507 cmp r2, #0 /* r2 is # of bytes to copy in */
4510 ldr r5, [r4, #SP_SR]
4513 str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */
4515 ldr r5, [r4, #SP_SR]
4518 ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4519 strb r5, [r1], #1 /* postindexed */
4522 blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4526 ldmia sp!, {r4, r5, r6, lr}