xref: /openbmc/linux/drivers/net/wireless/atmel/atmel.c (revision 8730046c)
1 /*** -*- linux-c -*- **********************************************************
2 
3      Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4 
5 	Copyright 2000-2001 ATMEL Corporation.
6 	Copyright 2003-2004 Simon Kelley.
7 
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.
13 
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.
19 
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.
24 
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.
29 
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/>.
33 
34     For all queries about this code, please contact the current author,
35     Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
36 
37     Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
38     hardware used during development of this driver.
39 
40 ******************************************************************************/
41 
42 #include <linux/interrupt.h>
43 
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>
50 #include <asm/io.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>
70 #include "atmel.h"
71 
72 #define DRIVER_MAJOR 0
73 #define DRIVER_MINOR 98
74 
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");
79 
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);
84 
85 /* table of firmware file names */
86 static struct {
87 	AtmelFWType fw_type;
88 	const char *fw_file;
89 	const char *fw_file_ext;
90 } fw_table[] = {
91 	{ ATMEL_FW_TYPE_502,		"atmel_at76c502",	"bin" },
92 	{ ATMEL_FW_TYPE_502D,		"atmel_at76c502d",	"bin" },
93 	{ ATMEL_FW_TYPE_502E,		"atmel_at76c502e",	"bin" },
94 	{ ATMEL_FW_TYPE_502_3COM,	"atmel_at76c502_3com",	"bin" },
95 	{ ATMEL_FW_TYPE_504,		"atmel_at76c504",	"bin" },
96 	{ ATMEL_FW_TYPE_504_2958,	"atmel_at76c504_2958",	"bin" },
97 	{ ATMEL_FW_TYPE_504A_2958,	"atmel_at76c504a_2958",	"bin" },
98 	{ ATMEL_FW_TYPE_506,		"atmel_at76c506",	"bin" },
99 	{ ATMEL_FW_TYPE_NONE,		NULL,			NULL }
100 };
101 MODULE_FIRMWARE("atmel_at76c502-wpa.bin");
102 MODULE_FIRMWARE("atmel_at76c502.bin");
103 MODULE_FIRMWARE("atmel_at76c502d-wpa.bin");
104 MODULE_FIRMWARE("atmel_at76c502d.bin");
105 MODULE_FIRMWARE("atmel_at76c502e-wpa.bin");
106 MODULE_FIRMWARE("atmel_at76c502e.bin");
107 MODULE_FIRMWARE("atmel_at76c502_3com-wpa.bin");
108 MODULE_FIRMWARE("atmel_at76c502_3com.bin");
109 MODULE_FIRMWARE("atmel_at76c504-wpa.bin");
110 MODULE_FIRMWARE("atmel_at76c504.bin");
111 MODULE_FIRMWARE("atmel_at76c504_2958-wpa.bin");
112 MODULE_FIRMWARE("atmel_at76c504_2958.bin");
113 MODULE_FIRMWARE("atmel_at76c504a_2958-wpa.bin");
114 MODULE_FIRMWARE("atmel_at76c504a_2958.bin");
115 MODULE_FIRMWARE("atmel_at76c506-wpa.bin");
116 MODULE_FIRMWARE("atmel_at76c506.bin");
117 
118 #define MAX_SSID_LENGTH 32
119 #define MGMT_JIFFIES (256 * HZ / 100)
120 
121 #define MAX_BSS_ENTRIES	64
122 
123 /* registers */
124 #define GCR  0x00    /* (SIR0)  General Configuration Register */
125 #define BSR  0x02    /* (SIR1)  Bank Switching Select Register */
126 #define AR   0x04
127 #define DR   0x08
128 #define MR1  0x12    /* Mirror Register 1 */
129 #define MR2  0x14    /* Mirror Register 2 */
130 #define MR3  0x16    /* Mirror Register 3 */
131 #define MR4  0x18    /* Mirror Register 4 */
132 
133 #define GPR1                            0x0c
134 #define GPR2                            0x0e
135 #define GPR3                            0x10
136 /*
137  * Constants for the GCR register.
138  */
139 #define GCR_REMAP     0x0400          /* Remap internal SRAM to 0 */
140 #define GCR_SWRES     0x0080          /* BIU reset (ARM and PAI are NOT reset) */
141 #define GCR_CORES     0x0060          /* Core Reset (ARM and PAI are reset) */
142 #define GCR_ENINT     0x0002          /* Enable Interrupts */
143 #define GCR_ACKINT    0x0008          /* Acknowledge Interrupts */
144 
145 #define BSS_SRAM      0x0200          /* AMBA module selection --> SRAM */
146 #define BSS_IRAM      0x0100          /* AMBA module selection --> IRAM */
147 /*
148  *Constants for the MR registers.
149  */
150 #define MAC_INIT_COMPLETE       0x0001        /* MAC init has been completed */
151 #define MAC_BOOT_COMPLETE       0x0010        /* MAC boot has been completed */
152 #define MAC_INIT_OK             0x0002        /* MAC boot has been completed */
153 
154 #define MIB_MAX_DATA_BYTES    212
155 #define MIB_HEADER_SIZE       4    /* first four fields */
156 
157 struct get_set_mib {
158 	u8 type;
159 	u8 size;
160 	u8 index;
161 	u8 reserved;
162 	u8 data[MIB_MAX_DATA_BYTES];
163 };
164 
165 struct rx_desc {
166 	u32          Next;
167 	u16          MsduPos;
168 	u16          MsduSize;
169 
170 	u8           State;
171 	u8           Status;
172 	u8           Rate;
173 	u8           Rssi;
174 	u8           LinkQuality;
175 	u8           PreambleType;
176 	u16          Duration;
177 	u32          RxTime;
178 };
179 
180 #define RX_DESC_FLAG_VALID       0x80
181 #define RX_DESC_FLAG_CONSUMED    0x40
182 #define RX_DESC_FLAG_IDLE        0x00
183 
184 #define RX_STATUS_SUCCESS        0x00
185 
186 #define RX_DESC_MSDU_POS_OFFSET      4
187 #define RX_DESC_MSDU_SIZE_OFFSET     6
188 #define RX_DESC_FLAGS_OFFSET         8
189 #define RX_DESC_STATUS_OFFSET        9
190 #define RX_DESC_RSSI_OFFSET          11
191 #define RX_DESC_LINK_QUALITY_OFFSET  12
192 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
193 #define RX_DESC_DURATION_OFFSET      14
194 #define RX_DESC_RX_TIME_OFFSET       16
195 
196 struct tx_desc {
197 	u32       NextDescriptor;
198 	u16       TxStartOfFrame;
199 	u16       TxLength;
200 
201 	u8        TxState;
202 	u8        TxStatus;
203 	u8        RetryCount;
204 
205 	u8        TxRate;
206 
207 	u8        KeyIndex;
208 	u8        ChiperType;
209 	u8        ChipreLength;
210 	u8        Reserved1;
211 
212 	u8        Reserved;
213 	u8        PacketType;
214 	u16       HostTxLength;
215 };
216 
217 #define TX_DESC_NEXT_OFFSET          0
218 #define TX_DESC_POS_OFFSET           4
219 #define TX_DESC_SIZE_OFFSET          6
220 #define TX_DESC_FLAGS_OFFSET         8
221 #define TX_DESC_STATUS_OFFSET        9
222 #define TX_DESC_RETRY_OFFSET         10
223 #define TX_DESC_RATE_OFFSET          11
224 #define TX_DESC_KEY_INDEX_OFFSET     12
225 #define TX_DESC_CIPHER_TYPE_OFFSET   13
226 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
227 #define TX_DESC_PACKET_TYPE_OFFSET   17
228 #define TX_DESC_HOST_LENGTH_OFFSET   18
229 
230 /*
231  * Host-MAC interface
232  */
233 
234 #define TX_STATUS_SUCCESS       0x00
235 
236 #define TX_FIRM_OWN             0x80
237 #define TX_DONE                 0x40
238 
239 #define TX_ERROR                0x01
240 
241 #define TX_PACKET_TYPE_DATA     0x01
242 #define TX_PACKET_TYPE_MGMT     0x02
243 
244 #define ISR_EMPTY               0x00        /* no bits set in ISR */
245 #define ISR_TxCOMPLETE          0x01        /* packet transmitted */
246 #define ISR_RxCOMPLETE          0x02        /* packet received */
247 #define ISR_RxFRAMELOST         0x04        /* Rx Frame lost */
248 #define ISR_FATAL_ERROR         0x08        /* Fatal error */
249 #define ISR_COMMAND_COMPLETE    0x10        /* command completed */
250 #define ISR_OUT_OF_RANGE        0x20        /* command completed */
251 #define ISR_IBSS_MERGE          0x40        /* (4.1.2.30): IBSS merge */
252 #define ISR_GENERIC_IRQ         0x80
253 
254 #define Local_Mib_Type          0x01
255 #define Mac_Address_Mib_Type    0x02
256 #define Mac_Mib_Type            0x03
257 #define Statistics_Mib_Type     0x04
258 #define Mac_Mgmt_Mib_Type       0x05
259 #define Mac_Wep_Mib_Type        0x06
260 #define Phy_Mib_Type            0x07
261 #define Multi_Domain_MIB        0x08
262 
263 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
264 #define MAC_MIB_FRAG_THRESHOLD_POS            8
265 #define MAC_MIB_RTS_THRESHOLD_POS             10
266 #define MAC_MIB_SHORT_RETRY_POS               16
267 #define MAC_MIB_LONG_RETRY_POS                17
268 #define MAC_MIB_SHORT_RETRY_LIMIT_POS         16
269 #define MAC_MGMT_MIB_BEACON_PER_POS           0
270 #define MAC_MGMT_MIB_STATION_ID_POS           6
271 #define MAC_MGMT_MIB_CUR_PRIVACY_POS          11
272 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
273 #define MAC_MGMT_MIB_PS_MODE_POS              53
274 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS      54
275 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
276 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED     57
277 #define PHY_MIB_CHANNEL_POS                   14
278 #define PHY_MIB_RATE_SET_POS                  20
279 #define PHY_MIB_REG_DOMAIN_POS                26
280 #define LOCAL_MIB_AUTO_TX_RATE_POS            3
281 #define LOCAL_MIB_SSID_SIZE                   5
282 #define LOCAL_MIB_TX_PROMISCUOUS_POS          6
283 #define LOCAL_MIB_TX_MGMT_RATE_POS            7
284 #define LOCAL_MIB_TX_CONTROL_RATE_POS         8
285 #define LOCAL_MIB_PREAMBLE_TYPE               9
286 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
287 
288 #define         CMD_Set_MIB_Vars              0x01
289 #define         CMD_Get_MIB_Vars              0x02
290 #define         CMD_Scan                      0x03
291 #define         CMD_Join                      0x04
292 #define         CMD_Start                     0x05
293 #define         CMD_EnableRadio               0x06
294 #define         CMD_DisableRadio              0x07
295 #define         CMD_SiteSurvey                0x0B
296 
297 #define         CMD_STATUS_IDLE                   0x00
298 #define         CMD_STATUS_COMPLETE               0x01
299 #define         CMD_STATUS_UNKNOWN                0x02
300 #define         CMD_STATUS_INVALID_PARAMETER      0x03
301 #define         CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
302 #define         CMD_STATUS_TIME_OUT               0x07
303 #define         CMD_STATUS_IN_PROGRESS            0x08
304 #define         CMD_STATUS_REJECTED_RADIO_OFF     0x09
305 #define         CMD_STATUS_HOST_ERROR             0xFF
306 #define         CMD_STATUS_BUSY                   0xFE
307 
308 #define CMD_BLOCK_COMMAND_OFFSET        0
309 #define CMD_BLOCK_STATUS_OFFSET         1
310 #define CMD_BLOCK_PARAMETERS_OFFSET     4
311 
312 #define SCAN_OPTIONS_SITE_SURVEY        0x80
313 
314 #define MGMT_FRAME_BODY_OFFSET		24
315 #define MAX_AUTHENTICATION_RETRIES	3
316 #define MAX_ASSOCIATION_RETRIES		3
317 
318 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
319 
320 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
321 #define LOOP_RETRY_LIMIT   500000
322 
323 #define ACTIVE_MODE	1
324 #define PS_MODE		2
325 
326 #define MAX_ENCRYPTION_KEYS 4
327 #define MAX_ENCRYPTION_KEY_SIZE 40
328 
329 /*
330  * 802.11 related definitions
331  */
332 
333 /*
334  * Regulatory Domains
335  */
336 
337 #define REG_DOMAIN_FCC		0x10	/* Channels	1-11	USA				*/
338 #define REG_DOMAIN_DOC		0x20	/* Channel	1-11	Canada				*/
339 #define REG_DOMAIN_ETSI		0x30	/* Channel	1-13	Europe (ex Spain/France)	*/
340 #define REG_DOMAIN_SPAIN	0x31	/* Channel	10-11	Spain				*/
341 #define REG_DOMAIN_FRANCE	0x32	/* Channel	10-13	France				*/
342 #define REG_DOMAIN_MKK		0x40	/* Channel	14	Japan				*/
343 #define REG_DOMAIN_MKK1		0x41	/* Channel	1-14	Japan(MKK1)			*/
344 #define REG_DOMAIN_ISRAEL	0x50	/* Channel	3-9	ISRAEL				*/
345 
346 #define BSS_TYPE_AD_HOC		1
347 #define BSS_TYPE_INFRASTRUCTURE 2
348 
349 #define SCAN_TYPE_ACTIVE	0
350 #define SCAN_TYPE_PASSIVE	1
351 
352 #define LONG_PREAMBLE		0
353 #define SHORT_PREAMBLE		1
354 #define AUTO_PREAMBLE		2
355 
356 #define DATA_FRAME_WS_HEADER_SIZE   30
357 
358 /* promiscuous mode control */
359 #define PROM_MODE_OFF			0x0
360 #define PROM_MODE_UNKNOWN		0x1
361 #define PROM_MODE_CRC_FAILED		0x2
362 #define PROM_MODE_DUPLICATED		0x4
363 #define PROM_MODE_MGMT			0x8
364 #define PROM_MODE_CTRL			0x10
365 #define PROM_MODE_BAD_PROTOCOL		0x20
366 
367 #define IFACE_INT_STATUS_OFFSET		0
368 #define IFACE_INT_MASK_OFFSET		1
369 #define IFACE_LOCKOUT_HOST_OFFSET	2
370 #define IFACE_LOCKOUT_MAC_OFFSET	3
371 #define IFACE_FUNC_CTRL_OFFSET		28
372 #define IFACE_MAC_STAT_OFFSET		30
373 #define IFACE_GENERIC_INT_TYPE_OFFSET	32
374 
375 #define CIPHER_SUITE_NONE     0
376 #define CIPHER_SUITE_WEP_64   1
377 #define CIPHER_SUITE_TKIP     2
378 #define CIPHER_SUITE_AES      3
379 #define CIPHER_SUITE_CCX      4
380 #define CIPHER_SUITE_WEP_128  5
381 
382 /*
383  * IFACE MACROS & definitions
384  */
385 
386 /*
387  * FuncCtrl field:
388  */
389 #define FUNC_CTRL_TxENABLE		0x10
390 #define FUNC_CTRL_RxENABLE		0x20
391 #define FUNC_CTRL_INIT_COMPLETE		0x01
392 
393 /* A stub firmware image which reads the MAC address from NVRAM on the card.
394    For copyright information and source see the end of this file. */
395 static u8 mac_reader[] = {
396 	0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
397 	0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
398 	0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
399 	0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
400 	0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
401 	0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
402 	0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
403 	0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
404 	0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
405 	0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
406 	0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
407 	0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
408 	0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
409 	0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
410 	0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
411 	0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
412 	0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
413 	0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
414 	0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
415 	0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
416 	0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
417 	0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
418 	0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
419 	0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
420 	0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
421 	0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
422 	0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
423 	0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
424 	0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
425 	0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
426 	0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
427 	0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
428 	0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
429 	0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
430 	0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
431 	0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
432 	0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
433 	0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
434 	0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
435 	0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
436 	0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
437 	0x00, 0x01, 0x00, 0x02
438 };
439 
440 struct atmel_private {
441 	void *card; /* Bus dependent structure varies for PCcard */
442 	int (*present_callback)(void *); /* And callback which uses it */
443 	char firmware_id[32];
444 	AtmelFWType firmware_type;
445 	u8 *firmware;
446 	int firmware_length;
447 	struct timer_list management_timer;
448 	struct net_device *dev;
449 	struct device *sys_dev;
450 	struct iw_statistics wstats;
451 	spinlock_t irqlock, timerlock;	/* spinlocks */
452 	enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
453 	enum {
454 		CARD_TYPE_PARALLEL_FLASH,
455 		CARD_TYPE_SPI_FLASH,
456 		CARD_TYPE_EEPROM
457 	} card_type;
458 	int do_rx_crc; /* If we need to CRC incoming packets */
459 	int probe_crc; /* set if we don't yet know */
460 	int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
461 	u16 rx_desc_head;
462 	u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
463 	u16 tx_free_mem, tx_buff_head, tx_buff_tail;
464 
465 	u16 frag_seq, frag_len, frag_no;
466 	u8 frag_source[6];
467 
468 	u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
469 	u8 group_cipher_suite, pairwise_cipher_suite;
470 	u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
471 	int wep_key_len[MAX_ENCRYPTION_KEYS];
472 	int use_wpa, radio_on_broken; /* firmware dependent stuff. */
473 
474 	u16 host_info_base;
475 	struct host_info_struct {
476 		/* NB this is matched to the hardware, don't change. */
477 		u8 volatile int_status;
478 		u8 volatile int_mask;
479 		u8 volatile lockout_host;
480 		u8 volatile lockout_mac;
481 
482 		u16 tx_buff_pos;
483 		u16 tx_buff_size;
484 		u16 tx_desc_pos;
485 		u16 tx_desc_count;
486 
487 		u16 rx_buff_pos;
488 		u16 rx_buff_size;
489 		u16 rx_desc_pos;
490 		u16 rx_desc_count;
491 
492 		u16 build_version;
493 		u16 command_pos;
494 
495 		u16 major_version;
496 		u16 minor_version;
497 
498 		u16 func_ctrl;
499 		u16 mac_status;
500 		u16 generic_IRQ_type;
501 		u8  reserved[2];
502 	} host_info;
503 
504 	enum {
505 		STATION_STATE_SCANNING,
506 		STATION_STATE_JOINNING,
507 		STATION_STATE_AUTHENTICATING,
508 		STATION_STATE_ASSOCIATING,
509 		STATION_STATE_READY,
510 		STATION_STATE_REASSOCIATING,
511 		STATION_STATE_DOWN,
512 		STATION_STATE_MGMT_ERROR
513 	} station_state;
514 
515 	int operating_mode, power_mode;
516 	time_t last_qual;
517 	int beacons_this_sec;
518 	int channel;
519 	int reg_domain, config_reg_domain;
520 	int tx_rate;
521 	int auto_tx_rate;
522 	int rts_threshold;
523 	int frag_threshold;
524 	int long_retry, short_retry;
525 	int preamble;
526 	int default_beacon_period, beacon_period, listen_interval;
527 	int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
528 	int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
529 	enum {
530 		SITE_SURVEY_IDLE,
531 		SITE_SURVEY_IN_PROGRESS,
532 		SITE_SURVEY_COMPLETED
533 	} site_survey_state;
534 	unsigned long last_survey;
535 
536 	int station_was_associated, station_is_associated;
537 	int fast_scan;
538 
539 	struct bss_info {
540 		int channel;
541 		int SSIDsize;
542 		int RSSI;
543 		int UsingWEP;
544 		int preamble;
545 		int beacon_period;
546 		int BSStype;
547 		u8 BSSID[6];
548 		u8 SSID[MAX_SSID_LENGTH];
549 	} BSSinfo[MAX_BSS_ENTRIES];
550 	int BSS_list_entries, current_BSS;
551 	int connect_to_any_BSS;
552 	int SSID_size, new_SSID_size;
553 	u8 CurrentBSSID[6], BSSID[6];
554 	u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
555 	u64 last_beacon_timestamp;
556 	u8 rx_buf[MAX_WIRELESS_BODY];
557 };
558 
559 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
560 
561 static const struct {
562 	int reg_domain;
563 	int min, max;
564 	char *name;
565 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
566 		      { REG_DOMAIN_DOC, 1, 11, "Canada" },
567 		      { REG_DOMAIN_ETSI, 1, 13, "Europe" },
568 		      { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
569 		      { REG_DOMAIN_FRANCE, 10, 13, "France" },
570 		      { REG_DOMAIN_MKK, 14, 14, "MKK" },
571 		      { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
572 		      { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
573 
574 static void build_wpa_mib(struct atmel_private *priv);
575 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
576 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
577 			       const unsigned char *src, u16 len);
578 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
579 			       u16 src, u16 len);
580 static void atmel_set_gcr(struct net_device *dev, u16 mask);
581 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
582 static int atmel_lock_mac(struct atmel_private *priv);
583 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
584 static void atmel_command_irq(struct atmel_private *priv);
585 static int atmel_validate_channel(struct atmel_private *priv, int channel);
586 static void atmel_management_frame(struct atmel_private *priv,
587 				   struct ieee80211_hdr *header,
588 				   u16 frame_len, u8 rssi);
589 static void atmel_management_timer(u_long a);
590 static void atmel_send_command(struct atmel_private *priv, int command,
591 			       void *cmd, int cmd_size);
592 static int atmel_send_command_wait(struct atmel_private *priv, int command,
593 				   void *cmd, int cmd_size);
594 static void atmel_transmit_management_frame(struct atmel_private *priv,
595 					    struct ieee80211_hdr *header,
596 					    u8 *body, int body_len);
597 
598 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
599 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
600 			   u8 data);
601 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
602 			    u16 data);
603 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
604 			  u8 *data, int data_len);
605 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
606 			  u8 *data, int data_len);
607 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
608 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
609 static void atmel_smooth_qual(struct atmel_private *priv);
610 static void atmel_writeAR(struct net_device *dev, u16 data);
611 static int probe_atmel_card(struct net_device *dev);
612 static int reset_atmel_card(struct net_device *dev);
613 static void atmel_enter_state(struct atmel_private *priv, int new_state);
614 int atmel_open (struct net_device *dev);
615 
616 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
617 {
618 	return priv->host_info_base + offset;
619 }
620 
621 static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
622 {
623 	return priv->host_info.command_pos + offset;
624 }
625 
626 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
627 {
628 	return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
629 }
630 
631 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
632 {
633 	return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
634 }
635 
636 static inline u8 atmel_read8(struct net_device *dev, u16 offset)
637 {
638 	return inb(dev->base_addr + offset);
639 }
640 
641 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
642 {
643 	outb(data, dev->base_addr + offset);
644 }
645 
646 static inline u16 atmel_read16(struct net_device *dev, u16 offset)
647 {
648 	return inw(dev->base_addr + offset);
649 }
650 
651 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
652 {
653 	outw(data, dev->base_addr + offset);
654 }
655 
656 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
657 {
658 	atmel_writeAR(priv->dev, pos);
659 	return atmel_read8(priv->dev, DR);
660 }
661 
662 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
663 {
664 	atmel_writeAR(priv->dev, pos);
665 	atmel_write8(priv->dev, DR, data);
666 }
667 
668 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
669 {
670 	atmel_writeAR(priv->dev, pos);
671 	return atmel_read16(priv->dev, DR);
672 }
673 
674 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
675 {
676 	atmel_writeAR(priv->dev, pos);
677 	atmel_write16(priv->dev, DR, data);
678 }
679 
680 static const struct iw_handler_def atmel_handler_def;
681 
682 static void tx_done_irq(struct atmel_private *priv)
683 {
684 	int i;
685 
686 	for (i = 0;
687 	     atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
688 		     i < priv->host_info.tx_desc_count;
689 	     i++) {
690 		u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
691 		u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
692 		u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
693 
694 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
695 
696 		priv->tx_free_mem += msdu_size;
697 		priv->tx_desc_free++;
698 
699 		if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
700 			priv->tx_buff_head = 0;
701 		else
702 			priv->tx_buff_head += msdu_size;
703 
704 		if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
705 			priv->tx_desc_head++ ;
706 		else
707 			priv->tx_desc_head = 0;
708 
709 		if (type == TX_PACKET_TYPE_DATA) {
710 			if (status == TX_STATUS_SUCCESS)
711 				priv->dev->stats.tx_packets++;
712 			else
713 				priv->dev->stats.tx_errors++;
714 			netif_wake_queue(priv->dev);
715 		}
716 	}
717 }
718 
719 static u16 find_tx_buff(struct atmel_private *priv, u16 len)
720 {
721 	u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
722 
723 	if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
724 		return 0;
725 
726 	if (bottom_free >= len)
727 		return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
728 
729 	if (priv->tx_free_mem - bottom_free >= len) {
730 		priv->tx_buff_tail = 0;
731 		return priv->host_info.tx_buff_pos;
732 	}
733 
734 	return 0;
735 }
736 
737 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
738 				 u16 len, u16 buff, u8 type)
739 {
740 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
741 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
742 	if (!priv->use_wpa)
743 		atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
744 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
745 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
746 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
747 	if (priv->use_wpa) {
748 		int cipher_type, cipher_length;
749 		if (is_bcast) {
750 			cipher_type = priv->group_cipher_suite;
751 			if (cipher_type == CIPHER_SUITE_WEP_64 ||
752 			    cipher_type == CIPHER_SUITE_WEP_128)
753 				cipher_length = 8;
754 			else if (cipher_type == CIPHER_SUITE_TKIP)
755 				cipher_length = 12;
756 			else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
757 				 priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
758 				cipher_type = priv->pairwise_cipher_suite;
759 				cipher_length = 8;
760 			} else {
761 				cipher_type = CIPHER_SUITE_NONE;
762 				cipher_length = 0;
763 			}
764 		} else {
765 			cipher_type = priv->pairwise_cipher_suite;
766 			if (cipher_type == CIPHER_SUITE_WEP_64 ||
767 			    cipher_type == CIPHER_SUITE_WEP_128)
768 				cipher_length = 8;
769 			else if (cipher_type == CIPHER_SUITE_TKIP)
770 				cipher_length = 12;
771 			else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
772 				 priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
773 				cipher_type = priv->group_cipher_suite;
774 				cipher_length = 8;
775 			} else {
776 				cipher_type = CIPHER_SUITE_NONE;
777 				cipher_length = 0;
778 			}
779 		}
780 
781 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
782 			    cipher_type);
783 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
784 			    cipher_length);
785 	}
786 	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
787 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
788 	if (priv->tx_desc_previous != priv->tx_desc_tail)
789 		atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
790 	priv->tx_desc_previous = priv->tx_desc_tail;
791 	if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
792 		priv->tx_desc_tail++;
793 	else
794 		priv->tx_desc_tail = 0;
795 	priv->tx_desc_free--;
796 	priv->tx_free_mem -= len;
797 }
798 
799 static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
800 {
801 	static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
802 	struct atmel_private *priv = netdev_priv(dev);
803 	struct ieee80211_hdr header;
804 	unsigned long flags;
805 	u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
806 
807 	if (priv->card && priv->present_callback &&
808 	    !(*priv->present_callback)(priv->card)) {
809 		dev->stats.tx_errors++;
810 		dev_kfree_skb(skb);
811 		return NETDEV_TX_OK;
812 	}
813 
814 	if (priv->station_state != STATION_STATE_READY) {
815 		dev->stats.tx_errors++;
816 		dev_kfree_skb(skb);
817 		return NETDEV_TX_OK;
818 	}
819 
820 	/* first ensure the timer func cannot run */
821 	spin_lock_bh(&priv->timerlock);
822 	/* then stop the hardware ISR */
823 	spin_lock_irqsave(&priv->irqlock, flags);
824 	/* nb doing the above in the opposite order will deadlock */
825 
826 	/* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
827 	   12 first bytes (containing DA/SA) and put them in the appropriate
828 	   fields of the Wireless Header. Thus the packet length is then the
829 	   initial + 18 (+30-12) */
830 
831 	if (!(buff = find_tx_buff(priv, len + 18))) {
832 		dev->stats.tx_dropped++;
833 		spin_unlock_irqrestore(&priv->irqlock, flags);
834 		spin_unlock_bh(&priv->timerlock);
835 		netif_stop_queue(dev);
836 		return NETDEV_TX_BUSY;
837 	}
838 
839 	frame_ctl = IEEE80211_FTYPE_DATA;
840 	header.duration_id = 0;
841 	header.seq_ctrl = 0;
842 	if (priv->wep_is_on)
843 		frame_ctl |= IEEE80211_FCTL_PROTECTED;
844 	if (priv->operating_mode == IW_MODE_ADHOC) {
845 		skb_copy_from_linear_data(skb, &header.addr1, ETH_ALEN);
846 		memcpy(&header.addr2, dev->dev_addr, ETH_ALEN);
847 		memcpy(&header.addr3, priv->BSSID, ETH_ALEN);
848 	} else {
849 		frame_ctl |= IEEE80211_FCTL_TODS;
850 		memcpy(&header.addr1, priv->CurrentBSSID, ETH_ALEN);
851 		memcpy(&header.addr2, dev->dev_addr, ETH_ALEN);
852 		skb_copy_from_linear_data(skb, &header.addr3, ETH_ALEN);
853 	}
854 
855 	if (priv->use_wpa)
856 		memcpy(&header.addr4, SNAP_RFC1024, ETH_ALEN);
857 
858 	header.frame_control = cpu_to_le16(frame_ctl);
859 	/* Copy the wireless header into the card */
860 	atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
861 	/* Copy the packet sans its 802.3 header addresses which have been replaced */
862 	atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
863 	priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
864 
865 	/* low bit of first byte of destination tells us if broadcast */
866 	tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
867 	dev->stats.tx_bytes += len;
868 
869 	spin_unlock_irqrestore(&priv->irqlock, flags);
870 	spin_unlock_bh(&priv->timerlock);
871 	dev_kfree_skb(skb);
872 
873 	return NETDEV_TX_OK;
874 }
875 
876 static void atmel_transmit_management_frame(struct atmel_private *priv,
877 					    struct ieee80211_hdr *header,
878 					    u8 *body, int body_len)
879 {
880 	u16 buff;
881 	int len = MGMT_FRAME_BODY_OFFSET + body_len;
882 
883 	if (!(buff = find_tx_buff(priv, len)))
884 		return;
885 
886 	atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
887 	atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
888 	priv->tx_buff_tail += len;
889 	tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
890 }
891 
892 static void fast_rx_path(struct atmel_private *priv,
893 			 struct ieee80211_hdr *header,
894 			 u16 msdu_size, u16 rx_packet_loc, u32 crc)
895 {
896 	/* fast path: unfragmented packet copy directly into skbuf */
897 	u8 mac4[6];
898 	struct sk_buff	*skb;
899 	unsigned char *skbp;
900 
901 	/* get the final, mac 4 header field, this tells us encapsulation */
902 	atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
903 	msdu_size -= 6;
904 
905 	if (priv->do_rx_crc) {
906 		crc = crc32_le(crc, mac4, 6);
907 		msdu_size -= 4;
908 	}
909 
910 	if (!(skb = dev_alloc_skb(msdu_size + 14))) {
911 		priv->dev->stats.rx_dropped++;
912 		return;
913 	}
914 
915 	skb_reserve(skb, 2);
916 	skbp = skb_put(skb, msdu_size + 12);
917 	atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
918 
919 	if (priv->do_rx_crc) {
920 		u32 netcrc;
921 		crc = crc32_le(crc, skbp + 12, msdu_size);
922 		atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
923 		if ((crc ^ 0xffffffff) != netcrc) {
924 			priv->dev->stats.rx_crc_errors++;
925 			dev_kfree_skb(skb);
926 			return;
927 		}
928 	}
929 
930 	memcpy(skbp, header->addr1, ETH_ALEN); /* destination address */
931 	if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
932 		memcpy(&skbp[ETH_ALEN], header->addr3, ETH_ALEN);
933 	else
934 		memcpy(&skbp[ETH_ALEN], header->addr2, ETH_ALEN); /* source address */
935 
936 	skb->protocol = eth_type_trans(skb, priv->dev);
937 	skb->ip_summed = CHECKSUM_NONE;
938 	netif_rx(skb);
939 	priv->dev->stats.rx_bytes += 12 + msdu_size;
940 	priv->dev->stats.rx_packets++;
941 }
942 
943 /* Test to see if the packet in card memory at packet_loc has a valid CRC
944    It doesn't matter that this is slow: it is only used to proble the first few
945    packets. */
946 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
947 {
948 	int i = msdu_size - 4;
949 	u32 netcrc, crc = 0xffffffff;
950 
951 	if (msdu_size < 4)
952 		return 0;
953 
954 	atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
955 
956 	atmel_writeAR(priv->dev, packet_loc);
957 	while (i--) {
958 		u8 octet = atmel_read8(priv->dev, DR);
959 		crc = crc32_le(crc, &octet, 1);
960 	}
961 
962 	return (crc ^ 0xffffffff) == netcrc;
963 }
964 
965 static void frag_rx_path(struct atmel_private *priv,
966 			 struct ieee80211_hdr *header,
967 			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
968 			 u8 frag_no, int more_frags)
969 {
970 	u8 mac4[ETH_ALEN];
971 	u8 source[ETH_ALEN];
972 	struct sk_buff *skb;
973 
974 	if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
975 		memcpy(source, header->addr3, ETH_ALEN);
976 	else
977 		memcpy(source, header->addr2, ETH_ALEN);
978 
979 	rx_packet_loc += 24; /* skip header */
980 
981 	if (priv->do_rx_crc)
982 		msdu_size -= 4;
983 
984 	if (frag_no == 0) { /* first fragment */
985 		atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, ETH_ALEN);
986 		msdu_size -= ETH_ALEN;
987 		rx_packet_loc += ETH_ALEN;
988 
989 		if (priv->do_rx_crc)
990 			crc = crc32_le(crc, mac4, 6);
991 
992 		priv->frag_seq = seq_no;
993 		priv->frag_no = 1;
994 		priv->frag_len = msdu_size;
995 		memcpy(priv->frag_source, source, ETH_ALEN);
996 		memcpy(&priv->rx_buf[ETH_ALEN], source, ETH_ALEN);
997 		memcpy(priv->rx_buf, header->addr1, ETH_ALEN);
998 
999 		atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
1000 
1001 		if (priv->do_rx_crc) {
1002 			u32 netcrc;
1003 			crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
1004 			atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1005 			if ((crc ^ 0xffffffff) != netcrc) {
1006 				priv->dev->stats.rx_crc_errors++;
1007 				eth_broadcast_addr(priv->frag_source);
1008 			}
1009 		}
1010 
1011 	} else if (priv->frag_no == frag_no &&
1012 		   priv->frag_seq == seq_no &&
1013 		   memcmp(priv->frag_source, source, ETH_ALEN) == 0) {
1014 
1015 		atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1016 				   rx_packet_loc, msdu_size);
1017 		if (priv->do_rx_crc) {
1018 			u32 netcrc;
1019 			crc = crc32_le(crc,
1020 				       &priv->rx_buf[12 + priv->frag_len],
1021 				       msdu_size);
1022 			atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1023 			if ((crc ^ 0xffffffff) != netcrc) {
1024 				priv->dev->stats.rx_crc_errors++;
1025 				eth_broadcast_addr(priv->frag_source);
1026 				more_frags = 1; /* don't send broken assembly */
1027 			}
1028 		}
1029 
1030 		priv->frag_len += msdu_size;
1031 		priv->frag_no++;
1032 
1033 		if (!more_frags) { /* last one */
1034 			eth_broadcast_addr(priv->frag_source);
1035 			if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1036 				priv->dev->stats.rx_dropped++;
1037 			} else {
1038 				skb_reserve(skb, 2);
1039 				memcpy(skb_put(skb, priv->frag_len + 12),
1040 				       priv->rx_buf,
1041 				       priv->frag_len + 12);
1042 				skb->protocol = eth_type_trans(skb, priv->dev);
1043 				skb->ip_summed = CHECKSUM_NONE;
1044 				netif_rx(skb);
1045 				priv->dev->stats.rx_bytes += priv->frag_len + 12;
1046 				priv->dev->stats.rx_packets++;
1047 			}
1048 		}
1049 	} else
1050 		priv->wstats.discard.fragment++;
1051 }
1052 
1053 static void rx_done_irq(struct atmel_private *priv)
1054 {
1055 	int i;
1056 	struct ieee80211_hdr header;
1057 
1058 	for (i = 0;
1059 	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1060 		     i < priv->host_info.rx_desc_count;
1061 	     i++) {
1062 
1063 		u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1064 		u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1065 		u32 crc = 0xffffffff;
1066 
1067 		if (status != RX_STATUS_SUCCESS) {
1068 			if (status == 0xc1) /* determined by experiment */
1069 				priv->wstats.discard.nwid++;
1070 			else
1071 				priv->dev->stats.rx_errors++;
1072 			goto next;
1073 		}
1074 
1075 		msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1076 		rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1077 
1078 		if (msdu_size < 30) {
1079 			priv->dev->stats.rx_errors++;
1080 			goto next;
1081 		}
1082 
1083 		/* Get header as far as end of seq_ctrl */
1084 		atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1085 		frame_ctl = le16_to_cpu(header.frame_control);
1086 		seq_control = le16_to_cpu(header.seq_ctrl);
1087 
1088 		/* probe for CRC use here if needed  once five packets have
1089 		   arrived with the same crc status, we assume we know what's
1090 		   happening and stop probing */
1091 		if (priv->probe_crc) {
1092 			if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1093 				priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1094 			} else {
1095 				priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1096 			}
1097 			if (priv->do_rx_crc) {
1098 				if (priv->crc_ok_cnt++ > 5)
1099 					priv->probe_crc = 0;
1100 			} else {
1101 				if (priv->crc_ko_cnt++ > 5)
1102 					priv->probe_crc = 0;
1103 			}
1104 		}
1105 
1106 		/* don't CRC header when WEP in use */
1107 		if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1108 			crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1109 		}
1110 		msdu_size -= 24; /* header */
1111 
1112 		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1113 			int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1114 			u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1115 			u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1116 
1117 			if (!more_fragments && packet_fragment_no == 0) {
1118 				fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1119 			} else {
1120 				frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1121 					     packet_sequence_no, packet_fragment_no, more_fragments);
1122 			}
1123 		}
1124 
1125 		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1126 			/* copy rest of packet into buffer */
1127 			atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1128 
1129 			/* we use the same buffer for frag reassembly and control packets */
1130 			eth_broadcast_addr(priv->frag_source);
1131 
1132 			if (priv->do_rx_crc) {
1133 				/* last 4 octets is crc */
1134 				msdu_size -= 4;
1135 				crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1136 				if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1137 					priv->dev->stats.rx_crc_errors++;
1138 					goto next;
1139 				}
1140 			}
1141 
1142 			atmel_management_frame(priv, &header, msdu_size,
1143 					       atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1144 		}
1145 
1146 next:
1147 		/* release descriptor */
1148 		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1149 
1150 		if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1151 			priv->rx_desc_head++;
1152 		else
1153 			priv->rx_desc_head = 0;
1154 	}
1155 }
1156 
1157 static irqreturn_t service_interrupt(int irq, void *dev_id)
1158 {
1159 	struct net_device *dev = (struct net_device *) dev_id;
1160 	struct atmel_private *priv = netdev_priv(dev);
1161 	u8 isr;
1162 	int i = -1;
1163 	static const u8 irq_order[] = {
1164 		ISR_OUT_OF_RANGE,
1165 		ISR_RxCOMPLETE,
1166 		ISR_TxCOMPLETE,
1167 		ISR_RxFRAMELOST,
1168 		ISR_FATAL_ERROR,
1169 		ISR_COMMAND_COMPLETE,
1170 		ISR_IBSS_MERGE,
1171 		ISR_GENERIC_IRQ
1172 	};
1173 
1174 	if (priv->card && priv->present_callback &&
1175 	    !(*priv->present_callback)(priv->card))
1176 		return IRQ_HANDLED;
1177 
1178 	/* In this state upper-level code assumes it can mess with
1179 	   the card unhampered by interrupts which may change register state.
1180 	   Note that even though the card shouldn't generate interrupts
1181 	   the inturrupt line may be shared. This allows card setup
1182 	   to go on without disabling interrupts for a long time. */
1183 	if (priv->station_state == STATION_STATE_DOWN)
1184 		return IRQ_NONE;
1185 
1186 	atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1187 
1188 	while (1) {
1189 		if (!atmel_lock_mac(priv)) {
1190 			/* failed to contact card */
1191 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1192 			return IRQ_HANDLED;
1193 		}
1194 
1195 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1196 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1197 
1198 		if (!isr) {
1199 			atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1200 			return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1201 		}
1202 
1203 		atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1204 
1205 		for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1206 			if (isr & irq_order[i])
1207 				break;
1208 
1209 		if (!atmel_lock_mac(priv)) {
1210 			/* failed to contact card */
1211 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1212 			return IRQ_HANDLED;
1213 		}
1214 
1215 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1216 		isr ^= irq_order[i];
1217 		atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1218 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1219 
1220 		switch (irq_order[i]) {
1221 
1222 		case ISR_OUT_OF_RANGE:
1223 			if (priv->operating_mode == IW_MODE_INFRA &&
1224 			    priv->station_state == STATION_STATE_READY) {
1225 				priv->station_is_associated = 0;
1226 				atmel_scan(priv, 1);
1227 			}
1228 			break;
1229 
1230 		case ISR_RxFRAMELOST:
1231 			priv->wstats.discard.misc++;
1232 			/* fall through */
1233 		case ISR_RxCOMPLETE:
1234 			rx_done_irq(priv);
1235 			break;
1236 
1237 		case ISR_TxCOMPLETE:
1238 			tx_done_irq(priv);
1239 			break;
1240 
1241 		case ISR_FATAL_ERROR:
1242 			printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1243 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1244 			break;
1245 
1246 		case ISR_COMMAND_COMPLETE:
1247 			atmel_command_irq(priv);
1248 			break;
1249 
1250 		case ISR_IBSS_MERGE:
1251 			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1252 				      priv->CurrentBSSID, 6);
1253 			/* The WPA stuff cares about the current AP address */
1254 			if (priv->use_wpa)
1255 				build_wpa_mib(priv);
1256 			break;
1257 		case ISR_GENERIC_IRQ:
1258 			printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1259 			break;
1260 		}
1261 	}
1262 }
1263 
1264 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1265 {
1266 	struct atmel_private *priv = netdev_priv(dev);
1267 
1268 	/* update the link quality here in case we are seeing no beacons
1269 	   at all to drive the process */
1270 	atmel_smooth_qual(priv);
1271 
1272 	priv->wstats.status = priv->station_state;
1273 
1274 	if (priv->operating_mode == IW_MODE_INFRA) {
1275 		if (priv->station_state != STATION_STATE_READY) {
1276 			priv->wstats.qual.qual = 0;
1277 			priv->wstats.qual.level = 0;
1278 			priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1279 					| IW_QUAL_LEVEL_INVALID);
1280 		}
1281 		priv->wstats.qual.noise = 0;
1282 		priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1283 	} else {
1284 		/* Quality levels cannot be determined in ad-hoc mode,
1285 		   because we can 'hear' more that one remote station. */
1286 		priv->wstats.qual.qual = 0;
1287 		priv->wstats.qual.level	= 0;
1288 		priv->wstats.qual.noise	= 0;
1289 		priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1290 					| IW_QUAL_LEVEL_INVALID
1291 					| IW_QUAL_NOISE_INVALID;
1292 		priv->wstats.miss.beacon = 0;
1293 	}
1294 
1295 	return &priv->wstats;
1296 }
1297 
1298 static int atmel_set_mac_address(struct net_device *dev, void *p)
1299 {
1300 	struct sockaddr *addr = p;
1301 
1302 	memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1303 	return atmel_open(dev);
1304 }
1305 
1306 EXPORT_SYMBOL(atmel_open);
1307 
1308 int atmel_open(struct net_device *dev)
1309 {
1310 	struct atmel_private *priv = netdev_priv(dev);
1311 	int i, channel, err;
1312 
1313 	/* any scheduled timer is no longer needed and might screw things up.. */
1314 	del_timer_sync(&priv->management_timer);
1315 
1316 	/* Interrupts will not touch the card once in this state... */
1317 	priv->station_state = STATION_STATE_DOWN;
1318 
1319 	if (priv->new_SSID_size) {
1320 		memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1321 		priv->SSID_size = priv->new_SSID_size;
1322 		priv->new_SSID_size = 0;
1323 	}
1324 	priv->BSS_list_entries = 0;
1325 
1326 	priv->AuthenticationRequestRetryCnt = 0;
1327 	priv->AssociationRequestRetryCnt = 0;
1328 	priv->ReAssociationRequestRetryCnt = 0;
1329 	priv->CurrentAuthentTransactionSeqNum = 0x0001;
1330 	priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1331 
1332 	priv->site_survey_state = SITE_SURVEY_IDLE;
1333 	priv->station_is_associated = 0;
1334 
1335 	err = reset_atmel_card(dev);
1336 	if (err)
1337 		return err;
1338 
1339 	if (priv->config_reg_domain) {
1340 		priv->reg_domain = priv->config_reg_domain;
1341 		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1342 	} else {
1343 		priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1344 		for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1345 			if (priv->reg_domain == channel_table[i].reg_domain)
1346 				break;
1347 		if (i == ARRAY_SIZE(channel_table)) {
1348 			priv->reg_domain = REG_DOMAIN_MKK1;
1349 			printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1350 		}
1351 	}
1352 
1353 	if ((channel = atmel_validate_channel(priv, priv->channel)))
1354 		priv->channel = channel;
1355 
1356 	/* this moves station_state on.... */
1357 	atmel_scan(priv, 1);
1358 
1359 	atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1360 	return 0;
1361 }
1362 
1363 static int atmel_close(struct net_device *dev)
1364 {
1365 	struct atmel_private *priv = netdev_priv(dev);
1366 
1367 	/* Send event to userspace that we are disassociating */
1368 	if (priv->station_state == STATION_STATE_READY) {
1369 		union iwreq_data wrqu;
1370 
1371 		wrqu.data.length = 0;
1372 		wrqu.data.flags = 0;
1373 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1374 		eth_zero_addr(wrqu.ap_addr.sa_data);
1375 		wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1376 	}
1377 
1378 	atmel_enter_state(priv, STATION_STATE_DOWN);
1379 
1380 	if (priv->bus_type == BUS_TYPE_PCCARD)
1381 		atmel_write16(dev, GCR, 0x0060);
1382 	atmel_write16(dev, GCR, 0x0040);
1383 	return 0;
1384 }
1385 
1386 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1387 {
1388 	/* check that channel is OK, if so return zero,
1389 	   else return suitable default channel */
1390 	int i;
1391 
1392 	for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1393 		if (priv->reg_domain == channel_table[i].reg_domain) {
1394 			if (channel >= channel_table[i].min &&
1395 			    channel <= channel_table[i].max)
1396 				return 0;
1397 			else
1398 				return channel_table[i].min;
1399 		}
1400 	return 0;
1401 }
1402 
1403 static int atmel_proc_show(struct seq_file *m, void *v)
1404 {
1405 	struct atmel_private *priv = m->private;
1406 	int i;
1407 	char *s, *r, *c;
1408 
1409 	seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1410 
1411 	if (priv->station_state != STATION_STATE_DOWN) {
1412 		seq_printf(m,
1413 			   "Firmware version:\t%d.%d build %d\n"
1414 			   "Firmware location:\t",
1415 			   priv->host_info.major_version,
1416 			   priv->host_info.minor_version,
1417 			   priv->host_info.build_version);
1418 
1419 		if (priv->card_type != CARD_TYPE_EEPROM)
1420 			seq_puts(m, "on card\n");
1421 		else if (priv->firmware)
1422 			seq_printf(m, "%s loaded by host\n", priv->firmware_id);
1423 		else
1424 			seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
1425 
1426 		switch (priv->card_type) {
1427 		case CARD_TYPE_PARALLEL_FLASH:
1428 			c = "Parallel flash";
1429 			break;
1430 		case CARD_TYPE_SPI_FLASH:
1431 			c = "SPI flash\n";
1432 			break;
1433 		case CARD_TYPE_EEPROM:
1434 			c = "EEPROM";
1435 			break;
1436 		default:
1437 			c = "<unknown>";
1438 		}
1439 
1440 		r = "<unknown>";
1441 		for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1442 			if (priv->reg_domain == channel_table[i].reg_domain)
1443 				r = channel_table[i].name;
1444 
1445 		seq_printf(m, "MAC memory type:\t%s\n", c);
1446 		seq_printf(m, "Regulatory domain:\t%s\n", r);
1447 		seq_printf(m, "Host CRC checking:\t%s\n",
1448 			 priv->do_rx_crc ? "On" : "Off");
1449 		seq_printf(m, "WPA-capable firmware:\t%s\n",
1450 			 priv->use_wpa ? "Yes" : "No");
1451 	}
1452 
1453 	switch (priv->station_state) {
1454 	case STATION_STATE_SCANNING:
1455 		s = "Scanning";
1456 		break;
1457 	case STATION_STATE_JOINNING:
1458 		s = "Joining";
1459 		break;
1460 	case STATION_STATE_AUTHENTICATING:
1461 		s = "Authenticating";
1462 		break;
1463 	case STATION_STATE_ASSOCIATING:
1464 		s = "Associating";
1465 		break;
1466 	case STATION_STATE_READY:
1467 		s = "Ready";
1468 		break;
1469 	case STATION_STATE_REASSOCIATING:
1470 		s = "Reassociating";
1471 		break;
1472 	case STATION_STATE_MGMT_ERROR:
1473 		s = "Management error";
1474 		break;
1475 	case STATION_STATE_DOWN:
1476 		s = "Down";
1477 		break;
1478 	default:
1479 		s = "<unknown>";
1480 	}
1481 
1482 	seq_printf(m, "Current state:\t\t%s\n", s);
1483 	return 0;
1484 }
1485 
1486 static int atmel_proc_open(struct inode *inode, struct file *file)
1487 {
1488 	return single_open(file, atmel_proc_show, PDE_DATA(inode));
1489 }
1490 
1491 static const struct file_operations atmel_proc_fops = {
1492 	.open		= atmel_proc_open,
1493 	.read		= seq_read,
1494 	.llseek		= seq_lseek,
1495 	.release	= single_release,
1496 };
1497 
1498 static const struct net_device_ops atmel_netdev_ops = {
1499 	.ndo_open 		= atmel_open,
1500 	.ndo_stop		= atmel_close,
1501 	.ndo_set_mac_address 	= atmel_set_mac_address,
1502 	.ndo_start_xmit 	= start_tx,
1503 	.ndo_do_ioctl 		= atmel_ioctl,
1504 	.ndo_validate_addr	= eth_validate_addr,
1505 };
1506 
1507 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1508 				   const AtmelFWType fw_type,
1509 				   struct device *sys_dev,
1510 				   int (*card_present)(void *), void *card)
1511 {
1512 	struct net_device *dev;
1513 	struct atmel_private *priv;
1514 	int rc;
1515 
1516 	/* Create the network device object. */
1517 	dev = alloc_etherdev(sizeof(*priv));
1518 	if (!dev)
1519 		return NULL;
1520 
1521 	if (dev_alloc_name(dev, dev->name) < 0) {
1522 		printk(KERN_ERR "atmel: Couldn't get name!\n");
1523 		goto err_out_free;
1524 	}
1525 
1526 	priv = netdev_priv(dev);
1527 	priv->dev = dev;
1528 	priv->sys_dev = sys_dev;
1529 	priv->present_callback = card_present;
1530 	priv->card = card;
1531 	priv->firmware = NULL;
1532 	priv->firmware_id[0] = '\0';
1533 	priv->firmware_type = fw_type;
1534 	if (firmware) /* module parameter */
1535 		strcpy(priv->firmware_id, firmware);
1536 	priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1537 	priv->station_state = STATION_STATE_DOWN;
1538 	priv->do_rx_crc = 0;
1539 	/* For PCMCIA cards, some chips need CRC, some don't
1540 	   so we have to probe. */
1541 	if (priv->bus_type == BUS_TYPE_PCCARD) {
1542 		priv->probe_crc = 1;
1543 		priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1544 	} else
1545 		priv->probe_crc = 0;
1546 	priv->last_qual = jiffies;
1547 	priv->last_beacon_timestamp = 0;
1548 	memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1549 	eth_zero_addr(priv->BSSID);
1550 	priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1551 	priv->station_was_associated = 0;
1552 
1553 	priv->last_survey = jiffies;
1554 	priv->preamble = LONG_PREAMBLE;
1555 	priv->operating_mode = IW_MODE_INFRA;
1556 	priv->connect_to_any_BSS = 0;
1557 	priv->config_reg_domain = 0;
1558 	priv->reg_domain = 0;
1559 	priv->tx_rate = 3;
1560 	priv->auto_tx_rate = 1;
1561 	priv->channel = 4;
1562 	priv->power_mode = 0;
1563 	priv->SSID[0] = '\0';
1564 	priv->SSID_size = 0;
1565 	priv->new_SSID_size = 0;
1566 	priv->frag_threshold = 2346;
1567 	priv->rts_threshold = 2347;
1568 	priv->short_retry = 7;
1569 	priv->long_retry = 4;
1570 
1571 	priv->wep_is_on = 0;
1572 	priv->default_key = 0;
1573 	priv->encryption_level = 0;
1574 	priv->exclude_unencrypted = 0;
1575 	priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1576 	priv->use_wpa = 0;
1577 	memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1578 	memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1579 
1580 	priv->default_beacon_period = priv->beacon_period = 100;
1581 	priv->listen_interval = 1;
1582 
1583 	init_timer(&priv->management_timer);
1584 	spin_lock_init(&priv->irqlock);
1585 	spin_lock_init(&priv->timerlock);
1586 	priv->management_timer.function = atmel_management_timer;
1587 	priv->management_timer.data = (unsigned long) dev;
1588 
1589 	dev->netdev_ops = &atmel_netdev_ops;
1590 	dev->wireless_handlers = &atmel_handler_def;
1591 	dev->irq = irq;
1592 	dev->base_addr = port;
1593 
1594 	/* MTU range: 68 - 2312 */
1595 	dev->min_mtu = 68;
1596 	dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
1597 
1598 	SET_NETDEV_DEV(dev, sys_dev);
1599 
1600 	if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1601 		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1602 		goto err_out_free;
1603 	}
1604 
1605 	if (!request_region(dev->base_addr, 32,
1606 			    priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
1607 		goto err_out_irq;
1608 	}
1609 
1610 	if (register_netdev(dev))
1611 		goto err_out_res;
1612 
1613 	if (!probe_atmel_card(dev)) {
1614 		unregister_netdev(dev);
1615 		goto err_out_res;
1616 	}
1617 
1618 	netif_carrier_off(dev);
1619 
1620 	if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv))
1621 		printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1622 
1623 	printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1624 	       dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1625 
1626 	return dev;
1627 
1628 err_out_res:
1629 	release_region(dev->base_addr, 32);
1630 err_out_irq:
1631 	free_irq(dev->irq, dev);
1632 err_out_free:
1633 	free_netdev(dev);
1634 	return NULL;
1635 }
1636 
1637 EXPORT_SYMBOL(init_atmel_card);
1638 
1639 void stop_atmel_card(struct net_device *dev)
1640 {
1641 	struct atmel_private *priv = netdev_priv(dev);
1642 
1643 	/* put a brick on it... */
1644 	if (priv->bus_type == BUS_TYPE_PCCARD)
1645 		atmel_write16(dev, GCR, 0x0060);
1646 	atmel_write16(dev, GCR, 0x0040);
1647 
1648 	del_timer_sync(&priv->management_timer);
1649 	unregister_netdev(dev);
1650 	remove_proc_entry("driver/atmel", NULL);
1651 	free_irq(dev->irq, dev);
1652 	kfree(priv->firmware);
1653 	release_region(dev->base_addr, 32);
1654 	free_netdev(dev);
1655 }
1656 
1657 EXPORT_SYMBOL(stop_atmel_card);
1658 
1659 static int atmel_set_essid(struct net_device *dev,
1660 			   struct iw_request_info *info,
1661 			   struct iw_point *dwrq,
1662 			   char *extra)
1663 {
1664 	struct atmel_private *priv = netdev_priv(dev);
1665 
1666 	/* Check if we asked for `any' */
1667 	if (dwrq->flags == 0) {
1668 		priv->connect_to_any_BSS = 1;
1669 	} else {
1670 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1671 
1672 		priv->connect_to_any_BSS = 0;
1673 
1674 		/* Check the size of the string */
1675 		if (dwrq->length > MAX_SSID_LENGTH)
1676 			 return -E2BIG;
1677 		if (index != 0)
1678 			return -EINVAL;
1679 
1680 		memcpy(priv->new_SSID, extra, dwrq->length);
1681 		priv->new_SSID_size = dwrq->length;
1682 	}
1683 
1684 	return -EINPROGRESS;
1685 }
1686 
1687 static int atmel_get_essid(struct net_device *dev,
1688 			   struct iw_request_info *info,
1689 			   struct iw_point *dwrq,
1690 			   char *extra)
1691 {
1692 	struct atmel_private *priv = netdev_priv(dev);
1693 
1694 	/* Get the current SSID */
1695 	if (priv->new_SSID_size != 0) {
1696 		memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1697 		dwrq->length = priv->new_SSID_size;
1698 	} else {
1699 		memcpy(extra, priv->SSID, priv->SSID_size);
1700 		dwrq->length = priv->SSID_size;
1701 	}
1702 
1703 	dwrq->flags = !priv->connect_to_any_BSS; /* active */
1704 
1705 	return 0;
1706 }
1707 
1708 static int atmel_get_wap(struct net_device *dev,
1709 			 struct iw_request_info *info,
1710 			 struct sockaddr *awrq,
1711 			 char *extra)
1712 {
1713 	struct atmel_private *priv = netdev_priv(dev);
1714 	memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1715 	awrq->sa_family = ARPHRD_ETHER;
1716 
1717 	return 0;
1718 }
1719 
1720 static int atmel_set_encode(struct net_device *dev,
1721 			    struct iw_request_info *info,
1722 			    struct iw_point *dwrq,
1723 			    char *extra)
1724 {
1725 	struct atmel_private *priv = netdev_priv(dev);
1726 
1727 	/* Basic checking: do we have a key to set ?
1728 	 * Note : with the new API, it's impossible to get a NULL pointer.
1729 	 * Therefore, we need to check a key size == 0 instead.
1730 	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1731 	 * when no key is present (only change flags), but older versions
1732 	 * don't do it. - Jean II */
1733 	if (dwrq->length > 0) {
1734 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1735 		int current_index = priv->default_key;
1736 		/* Check the size of the key */
1737 		if (dwrq->length > 13) {
1738 			return -EINVAL;
1739 		}
1740 		/* Check the index (none -> use current) */
1741 		if (index < 0 || index >= 4)
1742 			index = current_index;
1743 		else
1744 			priv->default_key = index;
1745 		/* Set the length */
1746 		if (dwrq->length > 5)
1747 			priv->wep_key_len[index] = 13;
1748 		else
1749 			if (dwrq->length > 0)
1750 				priv->wep_key_len[index] = 5;
1751 			else
1752 				/* Disable the key */
1753 				priv->wep_key_len[index] = 0;
1754 		/* Check if the key is not marked as invalid */
1755 		if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1756 			/* Cleanup */
1757 			memset(priv->wep_keys[index], 0, 13);
1758 			/* Copy the key in the driver */
1759 			memcpy(priv->wep_keys[index], extra, dwrq->length);
1760 		}
1761 		/* WE specify that if a valid key is set, encryption
1762 		 * should be enabled (user may turn it off later)
1763 		 * This is also how "iwconfig ethX key on" works */
1764 		if (index == current_index &&
1765 		    priv->wep_key_len[index] > 0) {
1766 			priv->wep_is_on = 1;
1767 			priv->exclude_unencrypted = 1;
1768 			if (priv->wep_key_len[index] > 5) {
1769 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1770 				priv->encryption_level = 2;
1771 			} else {
1772 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1773 				priv->encryption_level = 1;
1774 			}
1775 		}
1776 	} else {
1777 		/* Do we want to just set the transmit key index ? */
1778 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1779 		if (index >= 0 && index < 4) {
1780 			priv->default_key = index;
1781 		} else
1782 			/* Don't complain if only change the mode */
1783 			if (!(dwrq->flags & IW_ENCODE_MODE))
1784 				return -EINVAL;
1785 	}
1786 	/* Read the flags */
1787 	if (dwrq->flags & IW_ENCODE_DISABLED) {
1788 		priv->wep_is_on = 0;
1789 		priv->encryption_level = 0;
1790 		priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1791 	} else {
1792 		priv->wep_is_on = 1;
1793 		if (priv->wep_key_len[priv->default_key] > 5) {
1794 			priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1795 			priv->encryption_level = 2;
1796 		} else {
1797 			priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1798 			priv->encryption_level = 1;
1799 		}
1800 	}
1801 	if (dwrq->flags & IW_ENCODE_RESTRICTED)
1802 		priv->exclude_unencrypted = 1;
1803 	if (dwrq->flags & IW_ENCODE_OPEN)
1804 		priv->exclude_unencrypted = 0;
1805 
1806 	return -EINPROGRESS;		/* Call commit handler */
1807 }
1808 
1809 static int atmel_get_encode(struct net_device *dev,
1810 			    struct iw_request_info *info,
1811 			    struct iw_point *dwrq,
1812 			    char *extra)
1813 {
1814 	struct atmel_private *priv = netdev_priv(dev);
1815 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1816 
1817 	if (!priv->wep_is_on)
1818 		dwrq->flags = IW_ENCODE_DISABLED;
1819 	else {
1820 		if (priv->exclude_unencrypted)
1821 			dwrq->flags = IW_ENCODE_RESTRICTED;
1822 		else
1823 			dwrq->flags = IW_ENCODE_OPEN;
1824 	}
1825 		/* Which key do we want ? -1 -> tx index */
1826 	if (index < 0 || index >= 4)
1827 		index = priv->default_key;
1828 	dwrq->flags |= index + 1;
1829 	/* Copy the key to the user buffer */
1830 	dwrq->length = priv->wep_key_len[index];
1831 	if (dwrq->length > 16) {
1832 		dwrq->length = 0;
1833 	} else {
1834 		memset(extra, 0, 16);
1835 		memcpy(extra, priv->wep_keys[index], dwrq->length);
1836 	}
1837 
1838 	return 0;
1839 }
1840 
1841 static int atmel_set_encodeext(struct net_device *dev,
1842 			    struct iw_request_info *info,
1843 			    union iwreq_data *wrqu,
1844 			    char *extra)
1845 {
1846 	struct atmel_private *priv = netdev_priv(dev);
1847 	struct iw_point *encoding = &wrqu->encoding;
1848 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1849 	int idx, key_len, alg = ext->alg, set_key = 1;
1850 
1851 	/* Determine and validate the key index */
1852 	idx = encoding->flags & IW_ENCODE_INDEX;
1853 	if (idx) {
1854 		if (idx < 1 || idx > 4)
1855 			return -EINVAL;
1856 		idx--;
1857 	} else
1858 		idx = priv->default_key;
1859 
1860 	if (encoding->flags & IW_ENCODE_DISABLED)
1861 	    alg = IW_ENCODE_ALG_NONE;
1862 
1863 	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1864 		priv->default_key = idx;
1865 		set_key = ext->key_len > 0 ? 1 : 0;
1866 	}
1867 
1868 	if (set_key) {
1869 		/* Set the requested key first */
1870 		switch (alg) {
1871 		case IW_ENCODE_ALG_NONE:
1872 			priv->wep_is_on = 0;
1873 			priv->encryption_level = 0;
1874 			priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1875 			break;
1876 		case IW_ENCODE_ALG_WEP:
1877 			if (ext->key_len > 5) {
1878 				priv->wep_key_len[idx] = 13;
1879 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1880 				priv->encryption_level = 2;
1881 			} else if (ext->key_len > 0) {
1882 				priv->wep_key_len[idx] = 5;
1883 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1884 				priv->encryption_level = 1;
1885 			} else {
1886 				return -EINVAL;
1887 			}
1888 			priv->wep_is_on = 1;
1889 			memset(priv->wep_keys[idx], 0, 13);
1890 			key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1891 			memcpy(priv->wep_keys[idx], ext->key, key_len);
1892 			break;
1893 		default:
1894 			return -EINVAL;
1895 		}
1896 	}
1897 
1898 	return -EINPROGRESS;
1899 }
1900 
1901 static int atmel_get_encodeext(struct net_device *dev,
1902 			    struct iw_request_info *info,
1903 			    union iwreq_data *wrqu,
1904 			    char *extra)
1905 {
1906 	struct atmel_private *priv = netdev_priv(dev);
1907 	struct iw_point *encoding = &wrqu->encoding;
1908 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1909 	int idx, max_key_len;
1910 
1911 	max_key_len = encoding->length - sizeof(*ext);
1912 	if (max_key_len < 0)
1913 		return -EINVAL;
1914 
1915 	idx = encoding->flags & IW_ENCODE_INDEX;
1916 	if (idx) {
1917 		if (idx < 1 || idx > 4)
1918 			return -EINVAL;
1919 		idx--;
1920 	} else
1921 		idx = priv->default_key;
1922 
1923 	encoding->flags = idx + 1;
1924 	memset(ext, 0, sizeof(*ext));
1925 
1926 	if (!priv->wep_is_on) {
1927 		ext->alg = IW_ENCODE_ALG_NONE;
1928 		ext->key_len = 0;
1929 		encoding->flags |= IW_ENCODE_DISABLED;
1930 	} else {
1931 		if (priv->encryption_level > 0)
1932 			ext->alg = IW_ENCODE_ALG_WEP;
1933 		else
1934 			return -EINVAL;
1935 
1936 		ext->key_len = priv->wep_key_len[idx];
1937 		memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1938 		encoding->flags |= IW_ENCODE_ENABLED;
1939 	}
1940 
1941 	return 0;
1942 }
1943 
1944 static int atmel_set_auth(struct net_device *dev,
1945 			       struct iw_request_info *info,
1946 			       union iwreq_data *wrqu, char *extra)
1947 {
1948 	struct atmel_private *priv = netdev_priv(dev);
1949 	struct iw_param *param = &wrqu->param;
1950 
1951 	switch (param->flags & IW_AUTH_INDEX) {
1952 	case IW_AUTH_WPA_VERSION:
1953 	case IW_AUTH_CIPHER_PAIRWISE:
1954 	case IW_AUTH_CIPHER_GROUP:
1955 	case IW_AUTH_KEY_MGMT:
1956 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1957 	case IW_AUTH_PRIVACY_INVOKED:
1958 		/*
1959 		 * atmel does not use these parameters
1960 		 */
1961 		break;
1962 
1963 	case IW_AUTH_DROP_UNENCRYPTED:
1964 		priv->exclude_unencrypted = param->value ? 1 : 0;
1965 		break;
1966 
1967 	case IW_AUTH_80211_AUTH_ALG: {
1968 			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1969 				priv->exclude_unencrypted = 1;
1970 			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1971 				priv->exclude_unencrypted = 0;
1972 			} else
1973 				return -EINVAL;
1974 			break;
1975 		}
1976 
1977 	case IW_AUTH_WPA_ENABLED:
1978 		/* Silently accept disable of WPA */
1979 		if (param->value > 0)
1980 			return -EOPNOTSUPP;
1981 		break;
1982 
1983 	default:
1984 		return -EOPNOTSUPP;
1985 	}
1986 	return -EINPROGRESS;
1987 }
1988 
1989 static int atmel_get_auth(struct net_device *dev,
1990 			       struct iw_request_info *info,
1991 			       union iwreq_data *wrqu, char *extra)
1992 {
1993 	struct atmel_private *priv = netdev_priv(dev);
1994 	struct iw_param *param = &wrqu->param;
1995 
1996 	switch (param->flags & IW_AUTH_INDEX) {
1997 	case IW_AUTH_DROP_UNENCRYPTED:
1998 		param->value = priv->exclude_unencrypted;
1999 		break;
2000 
2001 	case IW_AUTH_80211_AUTH_ALG:
2002 		if (priv->exclude_unencrypted == 1)
2003 			param->value = IW_AUTH_ALG_SHARED_KEY;
2004 		else
2005 			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
2006 		break;
2007 
2008 	case IW_AUTH_WPA_ENABLED:
2009 		param->value = 0;
2010 		break;
2011 
2012 	default:
2013 		return -EOPNOTSUPP;
2014 	}
2015 	return 0;
2016 }
2017 
2018 
2019 static int atmel_get_name(struct net_device *dev,
2020 			  struct iw_request_info *info,
2021 			  char *cwrq,
2022 			  char *extra)
2023 {
2024 	strcpy(cwrq, "IEEE 802.11-DS");
2025 	return 0;
2026 }
2027 
2028 static int atmel_set_rate(struct net_device *dev,
2029 			  struct iw_request_info *info,
2030 			  struct iw_param *vwrq,
2031 			  char *extra)
2032 {
2033 	struct atmel_private *priv = netdev_priv(dev);
2034 
2035 	if (vwrq->fixed == 0) {
2036 		priv->tx_rate = 3;
2037 		priv->auto_tx_rate = 1;
2038 	} else {
2039 		priv->auto_tx_rate = 0;
2040 
2041 		/* Which type of value ? */
2042 		if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2043 			/* Setting by rate index */
2044 			priv->tx_rate = vwrq->value;
2045 		} else {
2046 		/* Setting by frequency value */
2047 			switch (vwrq->value) {
2048 			case  1000000:
2049 				priv->tx_rate = 0;
2050 				break;
2051 			case  2000000:
2052 				priv->tx_rate = 1;
2053 				break;
2054 			case  5500000:
2055 				priv->tx_rate = 2;
2056 				break;
2057 			case 11000000:
2058 				priv->tx_rate = 3;
2059 				break;
2060 			default:
2061 				return -EINVAL;
2062 			}
2063 		}
2064 	}
2065 
2066 	return -EINPROGRESS;
2067 }
2068 
2069 static int atmel_set_mode(struct net_device *dev,
2070 			  struct iw_request_info *info,
2071 			  __u32 *uwrq,
2072 			  char *extra)
2073 {
2074 	struct atmel_private *priv = netdev_priv(dev);
2075 
2076 	if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2077 		return -EINVAL;
2078 
2079 	priv->operating_mode = *uwrq;
2080 	return -EINPROGRESS;
2081 }
2082 
2083 static int atmel_get_mode(struct net_device *dev,
2084 			  struct iw_request_info *info,
2085 			  __u32 *uwrq,
2086 			  char *extra)
2087 {
2088 	struct atmel_private *priv = netdev_priv(dev);
2089 
2090 	*uwrq = priv->operating_mode;
2091 	return 0;
2092 }
2093 
2094 static int atmel_get_rate(struct net_device *dev,
2095 			 struct iw_request_info *info,
2096 			 struct iw_param *vwrq,
2097 			 char *extra)
2098 {
2099 	struct atmel_private *priv = netdev_priv(dev);
2100 
2101 	if (priv->auto_tx_rate) {
2102 		vwrq->fixed = 0;
2103 		vwrq->value = 11000000;
2104 	} else {
2105 		vwrq->fixed = 1;
2106 		switch (priv->tx_rate) {
2107 		case 0:
2108 			vwrq->value =  1000000;
2109 			break;
2110 		case 1:
2111 			vwrq->value =  2000000;
2112 			break;
2113 		case 2:
2114 			vwrq->value =  5500000;
2115 			break;
2116 		case 3:
2117 			vwrq->value = 11000000;
2118 			break;
2119 		}
2120 	}
2121 	return 0;
2122 }
2123 
2124 static int atmel_set_power(struct net_device *dev,
2125 			   struct iw_request_info *info,
2126 			   struct iw_param *vwrq,
2127 			   char *extra)
2128 {
2129 	struct atmel_private *priv = netdev_priv(dev);
2130 	priv->power_mode = vwrq->disabled ? 0 : 1;
2131 	return -EINPROGRESS;
2132 }
2133 
2134 static int atmel_get_power(struct net_device *dev,
2135 			   struct iw_request_info *info,
2136 			   struct iw_param *vwrq,
2137 			   char *extra)
2138 {
2139 	struct atmel_private *priv = netdev_priv(dev);
2140 	vwrq->disabled = priv->power_mode ? 0 : 1;
2141 	vwrq->flags = IW_POWER_ON;
2142 	return 0;
2143 }
2144 
2145 static int atmel_set_retry(struct net_device *dev,
2146 			   struct iw_request_info *info,
2147 			   struct iw_param *vwrq,
2148 			   char *extra)
2149 {
2150 	struct atmel_private *priv = netdev_priv(dev);
2151 
2152 	if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2153 		if (vwrq->flags & IW_RETRY_LONG)
2154 			priv->long_retry = vwrq->value;
2155 		else if (vwrq->flags & IW_RETRY_SHORT)
2156 			priv->short_retry = vwrq->value;
2157 		else {
2158 			/* No modifier : set both */
2159 			priv->long_retry = vwrq->value;
2160 			priv->short_retry = vwrq->value;
2161 		}
2162 		return -EINPROGRESS;
2163 	}
2164 
2165 	return -EINVAL;
2166 }
2167 
2168 static int atmel_get_retry(struct net_device *dev,
2169 			   struct iw_request_info *info,
2170 			   struct iw_param *vwrq,
2171 			   char *extra)
2172 {
2173 	struct atmel_private *priv = netdev_priv(dev);
2174 
2175 	vwrq->disabled = 0;      /* Can't be disabled */
2176 
2177 	/* Note : by default, display the short retry number */
2178 	if (vwrq->flags & IW_RETRY_LONG) {
2179 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2180 		vwrq->value = priv->long_retry;
2181 	} else {
2182 		vwrq->flags = IW_RETRY_LIMIT;
2183 		vwrq->value = priv->short_retry;
2184 		if (priv->long_retry != priv->short_retry)
2185 			vwrq->flags |= IW_RETRY_SHORT;
2186 	}
2187 
2188 	return 0;
2189 }
2190 
2191 static int atmel_set_rts(struct net_device *dev,
2192 			 struct iw_request_info *info,
2193 			 struct iw_param *vwrq,
2194 			 char *extra)
2195 {
2196 	struct atmel_private *priv = netdev_priv(dev);
2197 	int rthr = vwrq->value;
2198 
2199 	if (vwrq->disabled)
2200 		rthr = 2347;
2201 	if ((rthr < 0) || (rthr > 2347)) {
2202 		return -EINVAL;
2203 	}
2204 	priv->rts_threshold = rthr;
2205 
2206 	return -EINPROGRESS;		/* Call commit handler */
2207 }
2208 
2209 static int atmel_get_rts(struct net_device *dev,
2210 			 struct iw_request_info *info,
2211 			 struct iw_param *vwrq,
2212 			 char *extra)
2213 {
2214 	struct atmel_private *priv = netdev_priv(dev);
2215 
2216 	vwrq->value = priv->rts_threshold;
2217 	vwrq->disabled = (vwrq->value >= 2347);
2218 	vwrq->fixed = 1;
2219 
2220 	return 0;
2221 }
2222 
2223 static int atmel_set_frag(struct net_device *dev,
2224 			  struct iw_request_info *info,
2225 			  struct iw_param *vwrq,
2226 			  char *extra)
2227 {
2228 	struct atmel_private *priv = netdev_priv(dev);
2229 	int fthr = vwrq->value;
2230 
2231 	if (vwrq->disabled)
2232 		fthr = 2346;
2233 	if ((fthr < 256) || (fthr > 2346)) {
2234 		return -EINVAL;
2235 	}
2236 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
2237 	priv->frag_threshold = fthr;
2238 
2239 	return -EINPROGRESS;		/* Call commit handler */
2240 }
2241 
2242 static int atmel_get_frag(struct net_device *dev,
2243 			  struct iw_request_info *info,
2244 			  struct iw_param *vwrq,
2245 			  char *extra)
2246 {
2247 	struct atmel_private *priv = netdev_priv(dev);
2248 
2249 	vwrq->value = priv->frag_threshold;
2250 	vwrq->disabled = (vwrq->value >= 2346);
2251 	vwrq->fixed = 1;
2252 
2253 	return 0;
2254 }
2255 
2256 static int atmel_set_freq(struct net_device *dev,
2257 			  struct iw_request_info *info,
2258 			  struct iw_freq *fwrq,
2259 			  char *extra)
2260 {
2261 	struct atmel_private *priv = netdev_priv(dev);
2262 	int rc = -EINPROGRESS;		/* Call commit handler */
2263 
2264 	/* If setting by frequency, convert to a channel */
2265 	if (fwrq->e == 1) {
2266 		int f = fwrq->m / 100000;
2267 
2268 		/* Hack to fall through... */
2269 		fwrq->e = 0;
2270 		fwrq->m = ieee80211_frequency_to_channel(f);
2271 	}
2272 	/* Setting by channel number */
2273 	if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2274 		rc = -EOPNOTSUPP;
2275 	else {
2276 		int channel = fwrq->m;
2277 		if (atmel_validate_channel(priv, channel) == 0) {
2278 			priv->channel = channel;
2279 		} else {
2280 			rc = -EINVAL;
2281 		}
2282 	}
2283 	return rc;
2284 }
2285 
2286 static int atmel_get_freq(struct net_device *dev,
2287 			  struct iw_request_info *info,
2288 			  struct iw_freq *fwrq,
2289 			  char *extra)
2290 {
2291 	struct atmel_private *priv = netdev_priv(dev);
2292 
2293 	fwrq->m = priv->channel;
2294 	fwrq->e = 0;
2295 	return 0;
2296 }
2297 
2298 static int atmel_set_scan(struct net_device *dev,
2299 			  struct iw_request_info *info,
2300 			  struct iw_point *dwrq,
2301 			  char *extra)
2302 {
2303 	struct atmel_private *priv = netdev_priv(dev);
2304 	unsigned long flags;
2305 
2306 	/* Note : you may have realised that, as this is a SET operation,
2307 	 * this is privileged and therefore a normal user can't
2308 	 * perform scanning.
2309 	 * This is not an error, while the device perform scanning,
2310 	 * traffic doesn't flow, so it's a perfect DoS...
2311 	 * Jean II */
2312 
2313 	if (priv->station_state == STATION_STATE_DOWN)
2314 		return -EAGAIN;
2315 
2316 	/* Timeout old surveys. */
2317 	if (time_after(jiffies, priv->last_survey + 20 * HZ))
2318 		priv->site_survey_state = SITE_SURVEY_IDLE;
2319 	priv->last_survey = jiffies;
2320 
2321 	/* Initiate a scan command */
2322 	if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2323 		return -EBUSY;
2324 
2325 	del_timer_sync(&priv->management_timer);
2326 	spin_lock_irqsave(&priv->irqlock, flags);
2327 
2328 	priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2329 	priv->fast_scan = 0;
2330 	atmel_scan(priv, 0);
2331 	spin_unlock_irqrestore(&priv->irqlock, flags);
2332 
2333 	return 0;
2334 }
2335 
2336 static int atmel_get_scan(struct net_device *dev,
2337 			  struct iw_request_info *info,
2338 			  struct iw_point *dwrq,
2339 			  char *extra)
2340 {
2341 	struct atmel_private *priv = netdev_priv(dev);
2342 	int i;
2343 	char *current_ev = extra;
2344 	struct iw_event	iwe;
2345 
2346 	if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2347 		return -EAGAIN;
2348 
2349 	for (i = 0; i < priv->BSS_list_entries; i++) {
2350 		iwe.cmd = SIOCGIWAP;
2351 		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2352 		memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2353 		current_ev = iwe_stream_add_event(info, current_ev,
2354 						  extra + IW_SCAN_MAX_DATA,
2355 						  &iwe, IW_EV_ADDR_LEN);
2356 
2357 		iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
2358 		if (iwe.u.data.length > 32)
2359 			iwe.u.data.length = 32;
2360 		iwe.cmd = SIOCGIWESSID;
2361 		iwe.u.data.flags = 1;
2362 		current_ev = iwe_stream_add_point(info, current_ev,
2363 						  extra + IW_SCAN_MAX_DATA,
2364 						  &iwe, priv->BSSinfo[i].SSID);
2365 
2366 		iwe.cmd = SIOCGIWMODE;
2367 		iwe.u.mode = priv->BSSinfo[i].BSStype;
2368 		current_ev = iwe_stream_add_event(info, current_ev,
2369 						  extra + IW_SCAN_MAX_DATA,
2370 						  &iwe, IW_EV_UINT_LEN);
2371 
2372 		iwe.cmd = SIOCGIWFREQ;
2373 		iwe.u.freq.m = priv->BSSinfo[i].channel;
2374 		iwe.u.freq.e = 0;
2375 		current_ev = iwe_stream_add_event(info, current_ev,
2376 						  extra + IW_SCAN_MAX_DATA,
2377 						  &iwe, IW_EV_FREQ_LEN);
2378 
2379 		/* Add quality statistics */
2380 		iwe.cmd = IWEVQUAL;
2381 		iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2382 		iwe.u.qual.qual  = iwe.u.qual.level;
2383 		/* iwe.u.qual.noise  = SOMETHING */
2384 		current_ev = iwe_stream_add_event(info, current_ev,
2385 						  extra + IW_SCAN_MAX_DATA,
2386 						  &iwe, IW_EV_QUAL_LEN);
2387 
2388 
2389 		iwe.cmd = SIOCGIWENCODE;
2390 		if (priv->BSSinfo[i].UsingWEP)
2391 			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2392 		else
2393 			iwe.u.data.flags = IW_ENCODE_DISABLED;
2394 		iwe.u.data.length = 0;
2395 		current_ev = iwe_stream_add_point(info, current_ev,
2396 						  extra + IW_SCAN_MAX_DATA,
2397 						  &iwe, NULL);
2398 	}
2399 
2400 	/* Length of data */
2401 	dwrq->length = (current_ev - extra);
2402 	dwrq->flags = 0;
2403 
2404 	return 0;
2405 }
2406 
2407 static int atmel_get_range(struct net_device *dev,
2408 			   struct iw_request_info *info,
2409 			   struct iw_point *dwrq,
2410 			   char *extra)
2411 {
2412 	struct atmel_private *priv = netdev_priv(dev);
2413 	struct iw_range *range = (struct iw_range *) extra;
2414 	int k, i, j;
2415 
2416 	dwrq->length = sizeof(struct iw_range);
2417 	memset(range, 0, sizeof(struct iw_range));
2418 	range->min_nwid = 0x0000;
2419 	range->max_nwid = 0x0000;
2420 	range->num_channels = 0;
2421 	for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2422 		if (priv->reg_domain == channel_table[j].reg_domain) {
2423 			range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2424 			break;
2425 		}
2426 	if (range->num_channels != 0) {
2427 		for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2428 			range->freq[k].i = i; /* List index */
2429 
2430 			/* Values in MHz -> * 10^5 * 10 */
2431 			range->freq[k].m = 100000 *
2432 			 ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2433 			range->freq[k++].e = 1;
2434 		}
2435 		range->num_frequency = k;
2436 	}
2437 
2438 	range->max_qual.qual = 100;
2439 	range->max_qual.level = 100;
2440 	range->max_qual.noise = 0;
2441 	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2442 
2443 	range->avg_qual.qual = 50;
2444 	range->avg_qual.level = 50;
2445 	range->avg_qual.noise = 0;
2446 	range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2447 
2448 	range->sensitivity = 0;
2449 
2450 	range->bitrate[0] =  1000000;
2451 	range->bitrate[1] =  2000000;
2452 	range->bitrate[2] =  5500000;
2453 	range->bitrate[3] = 11000000;
2454 	range->num_bitrates = 4;
2455 
2456 	range->min_rts = 0;
2457 	range->max_rts = 2347;
2458 	range->min_frag = 256;
2459 	range->max_frag = 2346;
2460 
2461 	range->encoding_size[0] = 5;
2462 	range->encoding_size[1] = 13;
2463 	range->num_encoding_sizes = 2;
2464 	range->max_encoding_tokens = 4;
2465 
2466 	range->pmp_flags = IW_POWER_ON;
2467 	range->pmt_flags = IW_POWER_ON;
2468 	range->pm_capa = 0;
2469 
2470 	range->we_version_source = WIRELESS_EXT;
2471 	range->we_version_compiled = WIRELESS_EXT;
2472 	range->retry_capa = IW_RETRY_LIMIT ;
2473 	range->retry_flags = IW_RETRY_LIMIT;
2474 	range->r_time_flags = 0;
2475 	range->min_retry = 1;
2476 	range->max_retry = 65535;
2477 
2478 	return 0;
2479 }
2480 
2481 static int atmel_set_wap(struct net_device *dev,
2482 			 struct iw_request_info *info,
2483 			 struct sockaddr *awrq,
2484 			 char *extra)
2485 {
2486 	struct atmel_private *priv = netdev_priv(dev);
2487 	int i;
2488 	static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2489 	static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2490 	unsigned long flags;
2491 
2492 	if (awrq->sa_family != ARPHRD_ETHER)
2493 		return -EINVAL;
2494 
2495 	if (!memcmp(any, awrq->sa_data, 6) ||
2496 	    !memcmp(off, awrq->sa_data, 6)) {
2497 		del_timer_sync(&priv->management_timer);
2498 		spin_lock_irqsave(&priv->irqlock, flags);
2499 		atmel_scan(priv, 1);
2500 		spin_unlock_irqrestore(&priv->irqlock, flags);
2501 		return 0;
2502 	}
2503 
2504 	for (i = 0; i < priv->BSS_list_entries; i++) {
2505 		if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2506 			if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2507 				return -EINVAL;
2508 			} else if  (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2509 				return -EINVAL;
2510 			} else {
2511 				del_timer_sync(&priv->management_timer);
2512 				spin_lock_irqsave(&priv->irqlock, flags);
2513 				atmel_join_bss(priv, i);
2514 				spin_unlock_irqrestore(&priv->irqlock, flags);
2515 				return 0;
2516 			}
2517 		}
2518 	}
2519 
2520 	return -EINVAL;
2521 }
2522 
2523 static int atmel_config_commit(struct net_device *dev,
2524 			       struct iw_request_info *info,	/* NULL */
2525 			       void *zwrq,			/* NULL */
2526 			       char *extra)			/* NULL */
2527 {
2528 	return atmel_open(dev);
2529 }
2530 
2531 static const iw_handler atmel_handler[] =
2532 {
2533 	(iw_handler) atmel_config_commit,	/* SIOCSIWCOMMIT */
2534 	(iw_handler) atmel_get_name,		/* SIOCGIWNAME */
2535 	(iw_handler) NULL,			/* SIOCSIWNWID */
2536 	(iw_handler) NULL,			/* SIOCGIWNWID */
2537 	(iw_handler) atmel_set_freq,		/* SIOCSIWFREQ */
2538 	(iw_handler) atmel_get_freq,		/* SIOCGIWFREQ */
2539 	(iw_handler) atmel_set_mode,		/* SIOCSIWMODE */
2540 	(iw_handler) atmel_get_mode,		/* SIOCGIWMODE */
2541 	(iw_handler) NULL,			/* SIOCSIWSENS */
2542 	(iw_handler) NULL,			/* SIOCGIWSENS */
2543 	(iw_handler) NULL,			/* SIOCSIWRANGE */
2544 	(iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
2545 	(iw_handler) NULL,			/* SIOCSIWPRIV */
2546 	(iw_handler) NULL,			/* SIOCGIWPRIV */
2547 	(iw_handler) NULL,			/* SIOCSIWSTATS */
2548 	(iw_handler) NULL,			/* SIOCGIWSTATS */
2549 	(iw_handler) NULL,			/* SIOCSIWSPY */
2550 	(iw_handler) NULL,			/* SIOCGIWSPY */
2551 	(iw_handler) NULL,			/* -- hole -- */
2552 	(iw_handler) NULL,			/* -- hole -- */
2553 	(iw_handler) atmel_set_wap,		/* SIOCSIWAP */
2554 	(iw_handler) atmel_get_wap,		/* SIOCGIWAP */
2555 	(iw_handler) NULL,			/* -- hole -- */
2556 	(iw_handler) NULL,			/* SIOCGIWAPLIST */
2557 	(iw_handler) atmel_set_scan,		/* SIOCSIWSCAN */
2558 	(iw_handler) atmel_get_scan,		/* SIOCGIWSCAN */
2559 	(iw_handler) atmel_set_essid,		/* SIOCSIWESSID */
2560 	(iw_handler) atmel_get_essid,		/* SIOCGIWESSID */
2561 	(iw_handler) NULL,			/* SIOCSIWNICKN */
2562 	(iw_handler) NULL,			/* SIOCGIWNICKN */
2563 	(iw_handler) NULL,			/* -- hole -- */
2564 	(iw_handler) NULL,			/* -- hole -- */
2565 	(iw_handler) atmel_set_rate,		/* SIOCSIWRATE */
2566 	(iw_handler) atmel_get_rate,		/* SIOCGIWRATE */
2567 	(iw_handler) atmel_set_rts,		/* SIOCSIWRTS */
2568 	(iw_handler) atmel_get_rts,		/* SIOCGIWRTS */
2569 	(iw_handler) atmel_set_frag,		/* SIOCSIWFRAG */
2570 	(iw_handler) atmel_get_frag,		/* SIOCGIWFRAG */
2571 	(iw_handler) NULL,			/* SIOCSIWTXPOW */
2572 	(iw_handler) NULL,			/* SIOCGIWTXPOW */
2573 	(iw_handler) atmel_set_retry,		/* SIOCSIWRETRY */
2574 	(iw_handler) atmel_get_retry,		/* SIOCGIWRETRY */
2575 	(iw_handler) atmel_set_encode,		/* SIOCSIWENCODE */
2576 	(iw_handler) atmel_get_encode,		/* SIOCGIWENCODE */
2577 	(iw_handler) atmel_set_power,		/* SIOCSIWPOWER */
2578 	(iw_handler) atmel_get_power,		/* SIOCGIWPOWER */
2579 	(iw_handler) NULL,			/* -- hole -- */
2580 	(iw_handler) NULL,			/* -- hole -- */
2581 	(iw_handler) NULL,			/* SIOCSIWGENIE */
2582 	(iw_handler) NULL,			/* SIOCGIWGENIE */
2583 	(iw_handler) atmel_set_auth,		/* SIOCSIWAUTH */
2584 	(iw_handler) atmel_get_auth,		/* SIOCGIWAUTH */
2585 	(iw_handler) atmel_set_encodeext,	/* SIOCSIWENCODEEXT */
2586 	(iw_handler) atmel_get_encodeext,	/* SIOCGIWENCODEEXT */
2587 	(iw_handler) NULL,			/* SIOCSIWPMKSA */
2588 };
2589 
2590 static const iw_handler atmel_private_handler[] =
2591 {
2592 	NULL,				/* SIOCIWFIRSTPRIV */
2593 };
2594 
2595 struct atmel_priv_ioctl {
2596 	char id[32];
2597 	unsigned char __user *data;
2598 	unsigned short len;
2599 };
2600 
2601 #define ATMELFWL	SIOCIWFIRSTPRIV
2602 #define ATMELIDIFC	ATMELFWL + 1
2603 #define ATMELRD		ATMELFWL + 2
2604 #define ATMELMAGIC 0x51807
2605 #define REGDOMAINSZ 20
2606 
2607 static const struct iw_priv_args atmel_private_args[] = {
2608 	{
2609 		.cmd = ATMELFWL,
2610 		.set_args = IW_PRIV_TYPE_BYTE
2611 				| IW_PRIV_SIZE_FIXED
2612 				| sizeof(struct atmel_priv_ioctl),
2613 		.get_args = IW_PRIV_TYPE_NONE,
2614 		.name = "atmelfwl"
2615 	}, {
2616 		.cmd = ATMELIDIFC,
2617 		.set_args = IW_PRIV_TYPE_NONE,
2618 		.get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2619 		.name = "atmelidifc"
2620 	}, {
2621 		.cmd = ATMELRD,
2622 		.set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2623 		.get_args = IW_PRIV_TYPE_NONE,
2624 		.name = "regdomain"
2625 	},
2626 };
2627 
2628 static const struct iw_handler_def atmel_handler_def = {
2629 	.num_standard	= ARRAY_SIZE(atmel_handler),
2630 	.num_private	= ARRAY_SIZE(atmel_private_handler),
2631 	.num_private_args = ARRAY_SIZE(atmel_private_args),
2632 	.standard	= (iw_handler *) atmel_handler,
2633 	.private	= (iw_handler *) atmel_private_handler,
2634 	.private_args	= (struct iw_priv_args *) atmel_private_args,
2635 	.get_wireless_stats = atmel_get_wireless_stats
2636 };
2637 
2638 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2639 {
2640 	int i, rc = 0;
2641 	struct atmel_private *priv = netdev_priv(dev);
2642 	struct atmel_priv_ioctl com;
2643 	struct iwreq *wrq = (struct iwreq *) rq;
2644 	unsigned char *new_firmware;
2645 	char domain[REGDOMAINSZ + 1];
2646 
2647 	switch (cmd) {
2648 	case ATMELIDIFC:
2649 		wrq->u.param.value = ATMELMAGIC;
2650 		break;
2651 
2652 	case ATMELFWL:
2653 		if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2654 			rc = -EFAULT;
2655 			break;
2656 		}
2657 
2658 		if (!capable(CAP_NET_ADMIN)) {
2659 			rc = -EPERM;
2660 			break;
2661 		}
2662 
2663 		if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2664 			rc = -ENOMEM;
2665 			break;
2666 		}
2667 
2668 		if (copy_from_user(new_firmware, com.data, com.len)) {
2669 			kfree(new_firmware);
2670 			rc = -EFAULT;
2671 			break;
2672 		}
2673 
2674 		kfree(priv->firmware);
2675 
2676 		priv->firmware = new_firmware;
2677 		priv->firmware_length = com.len;
2678 		strncpy(priv->firmware_id, com.id, 31);
2679 		priv->firmware_id[31] = '\0';
2680 		break;
2681 
2682 	case ATMELRD:
2683 		if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2684 			rc = -EFAULT;
2685 			break;
2686 		}
2687 
2688 		if (!capable(CAP_NET_ADMIN)) {
2689 			rc = -EPERM;
2690 			break;
2691 		}
2692 
2693 		domain[REGDOMAINSZ] = 0;
2694 		rc = -EINVAL;
2695 		for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2696 			if (!strcasecmp(channel_table[i].name, domain)) {
2697 				priv->config_reg_domain = channel_table[i].reg_domain;
2698 				rc = 0;
2699 			}
2700 		}
2701 
2702 		if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2703 			rc = atmel_open(dev);
2704 		break;
2705 
2706 	default:
2707 		rc = -EOPNOTSUPP;
2708 	}
2709 
2710 	return rc;
2711 }
2712 
2713 struct auth_body {
2714 	__le16 alg;
2715 	__le16 trans_seq;
2716 	__le16 status;
2717 	u8 el_id;
2718 	u8 chall_text_len;
2719 	u8 chall_text[253];
2720 };
2721 
2722 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2723 {
2724 	int old_state = priv->station_state;
2725 
2726 	if (new_state == old_state)
2727 		return;
2728 
2729 	priv->station_state = new_state;
2730 
2731 	if (new_state == STATION_STATE_READY) {
2732 		netif_start_queue(priv->dev);
2733 		netif_carrier_on(priv->dev);
2734 	}
2735 
2736 	if (old_state == STATION_STATE_READY) {
2737 		netif_carrier_off(priv->dev);
2738 		if (netif_running(priv->dev))
2739 			netif_stop_queue(priv->dev);
2740 		priv->last_beacon_timestamp = 0;
2741 	}
2742 }
2743 
2744 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2745 {
2746 	struct {
2747 		u8 BSSID[ETH_ALEN];
2748 		u8 SSID[MAX_SSID_LENGTH];
2749 		u8 scan_type;
2750 		u8 channel;
2751 		__le16 BSS_type;
2752 		__le16 min_channel_time;
2753 		__le16 max_channel_time;
2754 		u8 options;
2755 		u8 SSID_size;
2756 	} cmd;
2757 
2758 	eth_broadcast_addr(cmd.BSSID);
2759 
2760 	if (priv->fast_scan) {
2761 		cmd.SSID_size = priv->SSID_size;
2762 		memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2763 		cmd.min_channel_time = cpu_to_le16(10);
2764 		cmd.max_channel_time = cpu_to_le16(50);
2765 	} else {
2766 		priv->BSS_list_entries = 0;
2767 		cmd.SSID_size = 0;
2768 		cmd.min_channel_time = cpu_to_le16(10);
2769 		cmd.max_channel_time = cpu_to_le16(120);
2770 	}
2771 
2772 	cmd.options = 0;
2773 
2774 	if (!specific_ssid)
2775 		cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2776 
2777 	cmd.channel = (priv->channel & 0x7f);
2778 	cmd.scan_type = SCAN_TYPE_ACTIVE;
2779 	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2780 		BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2781 
2782 	atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2783 
2784 	/* This must come after all hardware access to avoid being messed up
2785 	   by stuff happening in interrupt context after we leave STATE_DOWN */
2786 	atmel_enter_state(priv, STATION_STATE_SCANNING);
2787 }
2788 
2789 static void join(struct atmel_private *priv, int type)
2790 {
2791 	struct {
2792 		u8 BSSID[6];
2793 		u8 SSID[MAX_SSID_LENGTH];
2794 		u8 BSS_type; /* this is a short in a scan command - weird */
2795 		u8 channel;
2796 		__le16 timeout;
2797 		u8 SSID_size;
2798 		u8 reserved;
2799 	} cmd;
2800 
2801 	cmd.SSID_size = priv->SSID_size;
2802 	memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2803 	memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2804 	cmd.channel = (priv->channel & 0x7f);
2805 	cmd.BSS_type = type;
2806 	cmd.timeout = cpu_to_le16(2000);
2807 
2808 	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2809 }
2810 
2811 static void start(struct atmel_private *priv, int type)
2812 {
2813 	struct {
2814 		u8 BSSID[6];
2815 		u8 SSID[MAX_SSID_LENGTH];
2816 		u8 BSS_type;
2817 		u8 channel;
2818 		u8 SSID_size;
2819 		u8 reserved[3];
2820 	} cmd;
2821 
2822 	cmd.SSID_size = priv->SSID_size;
2823 	memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2824 	memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2825 	cmd.BSS_type = type;
2826 	cmd.channel = (priv->channel & 0x7f);
2827 
2828 	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2829 }
2830 
2831 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2832 				u8 channel)
2833 {
2834 	int rejoin = 0;
2835 	int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2836 		SHORT_PREAMBLE : LONG_PREAMBLE;
2837 
2838 	if (priv->preamble != new) {
2839 		priv->preamble = new;
2840 		rejoin = 1;
2841 		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2842 	}
2843 
2844 	if (priv->channel != channel) {
2845 		priv->channel = channel;
2846 		rejoin = 1;
2847 		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2848 	}
2849 
2850 	if (rejoin) {
2851 		priv->station_is_associated = 0;
2852 		atmel_enter_state(priv, STATION_STATE_JOINNING);
2853 
2854 		if (priv->operating_mode == IW_MODE_INFRA)
2855 			join(priv, BSS_TYPE_INFRASTRUCTURE);
2856 		else
2857 			join(priv, BSS_TYPE_AD_HOC);
2858 	}
2859 }
2860 
2861 static void send_authentication_request(struct atmel_private *priv, u16 system,
2862 					u8 *challenge, int challenge_len)
2863 {
2864 	struct ieee80211_hdr header;
2865 	struct auth_body auth;
2866 
2867 	header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2868 	header.duration_id = cpu_to_le16(0x8000);
2869 	header.seq_ctrl = 0;
2870 	memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2871 	memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2872 	memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2873 
2874 	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2875 		/* no WEP for authentication frames with TrSeqNo 1 */
2876 		header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2877 
2878 	auth.alg = cpu_to_le16(system);
2879 
2880 	auth.status = 0;
2881 	auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2882 	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2883 	priv->CurrentAuthentTransactionSeqNum += 2;
2884 
2885 	if (challenge_len != 0)	{
2886 		auth.el_id = 16; /* challenge_text */
2887 		auth.chall_text_len = challenge_len;
2888 		memcpy(auth.chall_text, challenge, challenge_len);
2889 		atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2890 	} else {
2891 		atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2892 	}
2893 }
2894 
2895 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2896 {
2897 	u8 *ssid_el_p;
2898 	int bodysize;
2899 	struct ieee80211_hdr header;
2900 	struct ass_req_format {
2901 		__le16 capability;
2902 		__le16 listen_interval;
2903 		u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2904 		u8 ssid_el_id;
2905 		u8 ssid_len;
2906 		u8 ssid[MAX_SSID_LENGTH];
2907 		u8 sup_rates_el_id;
2908 		u8 sup_rates_len;
2909 		u8 rates[4];
2910 	} body;
2911 
2912 	header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2913 		(is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2914 	header.duration_id = cpu_to_le16(0x8000);
2915 	header.seq_ctrl = 0;
2916 
2917 	memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2918 	memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2919 	memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2920 
2921 	body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2922 	if (priv->wep_is_on)
2923 		body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2924 	if (priv->preamble == SHORT_PREAMBLE)
2925 		body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2926 
2927 	body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2928 
2929 	/* current AP address - only in reassoc frame */
2930 	if (is_reassoc) {
2931 		memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2932 		ssid_el_p = &body.ssid_el_id;
2933 		bodysize = 18 + priv->SSID_size;
2934 	} else {
2935 		ssid_el_p = &body.ap[0];
2936 		bodysize = 12 + priv->SSID_size;
2937 	}
2938 
2939 	ssid_el_p[0] = WLAN_EID_SSID;
2940 	ssid_el_p[1] = priv->SSID_size;
2941 	memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2942 	ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2943 	ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2944 	memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2945 
2946 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2947 }
2948 
2949 static int is_frame_from_current_bss(struct atmel_private *priv,
2950 				     struct ieee80211_hdr *header)
2951 {
2952 	if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2953 		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2954 	else
2955 		return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2956 }
2957 
2958 static int retrieve_bss(struct atmel_private *priv)
2959 {
2960 	int i;
2961 	int max_rssi = -128;
2962 	int max_index = -1;
2963 
2964 	if (priv->BSS_list_entries == 0)
2965 		return -1;
2966 
2967 	if (priv->connect_to_any_BSS) {
2968 		/* Select a BSS with the max-RSSI but of the same type and of
2969 		   the same WEP mode and that it is not marked as 'bad' (i.e.
2970 		   we had previously failed to connect to this BSS with the
2971 		   settings that we currently use) */
2972 		priv->current_BSS = 0;
2973 		for (i = 0; i < priv->BSS_list_entries; i++) {
2974 			if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2975 			    ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2976 			     (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2977 			    !(priv->BSSinfo[i].channel & 0x80)) {
2978 				max_rssi = priv->BSSinfo[i].RSSI;
2979 				priv->current_BSS = max_index = i;
2980 			}
2981 		}
2982 		return max_index;
2983 	}
2984 
2985 	for (i = 0; i < priv->BSS_list_entries; i++) {
2986 		if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2987 		    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2988 		    priv->operating_mode == priv->BSSinfo[i].BSStype &&
2989 		    atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2990 			if (priv->BSSinfo[i].RSSI >= max_rssi) {
2991 				max_rssi = priv->BSSinfo[i].RSSI;
2992 				max_index = i;
2993 			}
2994 		}
2995 	}
2996 	return max_index;
2997 }
2998 
2999 static void store_bss_info(struct atmel_private *priv,
3000 			   struct ieee80211_hdr *header, u16 capability,
3001 			   u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
3002 			   u8 *ssid, int is_beacon)
3003 {
3004 	u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
3005 	int i, index;
3006 
3007 	for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
3008 		if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
3009 			index = i;
3010 
3011 	/* If we process a probe and an entry from this BSS exists
3012 	   we will update the BSS entry with the info from this BSS.
3013 	   If we process a beacon we will only update RSSI */
3014 
3015 	if (index == -1) {
3016 		if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
3017 			return;
3018 		index = priv->BSS_list_entries++;
3019 		memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
3020 		priv->BSSinfo[index].RSSI = rssi;
3021 	} else {
3022 		if (rssi > priv->BSSinfo[index].RSSI)
3023 			priv->BSSinfo[index].RSSI = rssi;
3024 		if (is_beacon)
3025 			return;
3026 	}
3027 
3028 	priv->BSSinfo[index].channel = channel;
3029 	priv->BSSinfo[index].beacon_period = beacon_period;
3030 	priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3031 	memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3032 	priv->BSSinfo[index].SSIDsize = ssid_len;
3033 
3034 	if (capability & WLAN_CAPABILITY_IBSS)
3035 		priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3036 	else if (capability & WLAN_CAPABILITY_ESS)
3037 		priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3038 
3039 	priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3040 		SHORT_PREAMBLE : LONG_PREAMBLE;
3041 }
3042 
3043 static void authenticate(struct atmel_private *priv, u16 frame_len)
3044 {
3045 	struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3046 	u16 status = le16_to_cpu(auth->status);
3047 	u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3048 	u16 system = le16_to_cpu(auth->alg);
3049 
3050 	if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3051 		/* no WEP */
3052 		if (priv->station_was_associated) {
3053 			atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3054 			send_association_request(priv, 1);
3055 			return;
3056 		} else {
3057 			atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3058 			send_association_request(priv, 0);
3059 			return;
3060 		}
3061 	}
3062 
3063 	if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3064 		int should_associate = 0;
3065 		/* WEP */
3066 		if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3067 			return;
3068 
3069 		if (system == WLAN_AUTH_OPEN) {
3070 			if (trans_seq_no == 0x0002) {
3071 				should_associate = 1;
3072 			}
3073 		} else if (system == WLAN_AUTH_SHARED_KEY) {
3074 			if (trans_seq_no == 0x0002 &&
3075 			    auth->el_id == WLAN_EID_CHALLENGE) {
3076 				send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3077 				return;
3078 			} else if (trans_seq_no == 0x0004) {
3079 				should_associate = 1;
3080 			}
3081 		}
3082 
3083 		if (should_associate) {
3084 			if (priv->station_was_associated) {
3085 				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3086 				send_association_request(priv, 1);
3087 				return;
3088 			} else {
3089 				atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3090 				send_association_request(priv, 0);
3091 				return;
3092 			}
3093 		}
3094 	}
3095 
3096 	if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3097 		/* Flip back and forth between WEP auth modes until the max
3098 		 * authentication tries has been exceeded.
3099 		 */
3100 		if (system == WLAN_AUTH_OPEN) {
3101 			priv->CurrentAuthentTransactionSeqNum = 0x001;
3102 			priv->exclude_unencrypted = 1;
3103 			send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3104 			return;
3105 		} else if (system == WLAN_AUTH_SHARED_KEY
3106 			   && priv->wep_is_on) {
3107 			priv->CurrentAuthentTransactionSeqNum = 0x001;
3108 			priv->exclude_unencrypted = 0;
3109 			send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3110 			return;
3111 		} else if (priv->connect_to_any_BSS) {
3112 			int bss_index;
3113 
3114 			priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3115 
3116 			if ((bss_index  = retrieve_bss(priv)) != -1) {
3117 				atmel_join_bss(priv, bss_index);
3118 				return;
3119 			}
3120 		}
3121 	}
3122 
3123 	priv->AuthenticationRequestRetryCnt = 0;
3124 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3125 	priv->station_is_associated = 0;
3126 }
3127 
3128 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3129 {
3130 	struct ass_resp_format {
3131 		__le16 capability;
3132 		__le16 status;
3133 		__le16 ass_id;
3134 		u8 el_id;
3135 		u8 length;
3136 		u8 rates[4];
3137 	} *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3138 
3139 	u16 status = le16_to_cpu(ass_resp->status);
3140 	u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3141 	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3142 
3143 	union iwreq_data wrqu;
3144 
3145 	if (frame_len < 8 + rates_len)
3146 		return;
3147 
3148 	if (status == WLAN_STATUS_SUCCESS) {
3149 		if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3150 			priv->AssociationRequestRetryCnt = 0;
3151 		else
3152 			priv->ReAssociationRequestRetryCnt = 0;
3153 
3154 		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3155 				MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3156 		atmel_set_mib(priv, Phy_Mib_Type,
3157 			      PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3158 		if (priv->power_mode == 0) {
3159 			priv->listen_interval = 1;
3160 			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3161 				       MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3162 			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3163 					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3164 		} else {
3165 			priv->listen_interval = 2;
3166 			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3167 				       MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
3168 			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3169 					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3170 		}
3171 
3172 		priv->station_is_associated = 1;
3173 		priv->station_was_associated = 1;
3174 		atmel_enter_state(priv, STATION_STATE_READY);
3175 
3176 		/* Send association event to userspace */
3177 		wrqu.data.length = 0;
3178 		wrqu.data.flags = 0;
3179 		memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3180 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3181 		wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3182 
3183 		return;
3184 	}
3185 
3186 	if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3187 	    status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3188 	    status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3189 	    priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3190 		mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3191 		priv->AssociationRequestRetryCnt++;
3192 		send_association_request(priv, 0);
3193 		return;
3194 	}
3195 
3196 	if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3197 	    status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3198 	    status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3199 	    priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3200 		mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3201 		priv->ReAssociationRequestRetryCnt++;
3202 		send_association_request(priv, 1);
3203 		return;
3204 	}
3205 
3206 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3207 	priv->station_is_associated = 0;
3208 
3209 	if (priv->connect_to_any_BSS) {
3210 		int bss_index;
3211 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3212 
3213 		if ((bss_index = retrieve_bss(priv)) != -1)
3214 			atmel_join_bss(priv, bss_index);
3215 	}
3216 }
3217 
3218 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3219 {
3220 	struct bss_info *bss =  &priv->BSSinfo[bss_index];
3221 
3222 	memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3223 	memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3224 
3225 	/* The WPA stuff cares about the current AP address */
3226 	if (priv->use_wpa)
3227 		build_wpa_mib(priv);
3228 
3229 	/* When switching to AdHoc turn OFF Power Save if needed */
3230 
3231 	if (bss->BSStype == IW_MODE_ADHOC &&
3232 	    priv->operating_mode != IW_MODE_ADHOC &&
3233 	    priv->power_mode) {
3234 		priv->power_mode = 0;
3235 		priv->listen_interval = 1;
3236 		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3237 			       MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
3238 		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3239 				MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3240 	}
3241 
3242 	priv->operating_mode = bss->BSStype;
3243 	priv->channel = bss->channel & 0x7f;
3244 	priv->beacon_period = bss->beacon_period;
3245 
3246 	if (priv->preamble != bss->preamble) {
3247 		priv->preamble = bss->preamble;
3248 		atmel_set_mib8(priv, Local_Mib_Type,
3249 			       LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3250 	}
3251 
3252 	if (!priv->wep_is_on && bss->UsingWEP) {
3253 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3254 		priv->station_is_associated = 0;
3255 		return;
3256 	}
3257 
3258 	if (priv->wep_is_on && !bss->UsingWEP) {
3259 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3260 		priv->station_is_associated = 0;
3261 		return;
3262 	}
3263 
3264 	atmel_enter_state(priv, STATION_STATE_JOINNING);
3265 
3266 	if (priv->operating_mode == IW_MODE_INFRA)
3267 		join(priv, BSS_TYPE_INFRASTRUCTURE);
3268 	else
3269 		join(priv, BSS_TYPE_AD_HOC);
3270 }
3271 
3272 static void restart_search(struct atmel_private *priv)
3273 {
3274 	int bss_index;
3275 
3276 	if (!priv->connect_to_any_BSS) {
3277 		atmel_scan(priv, 1);
3278 	} else {
3279 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3280 
3281 		if ((bss_index = retrieve_bss(priv)) != -1)
3282 			atmel_join_bss(priv, bss_index);
3283 		else
3284 			atmel_scan(priv, 0);
3285 	}
3286 }
3287 
3288 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3289 {
3290 	u8 old = priv->wstats.qual.level;
3291 	u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3292 
3293 	switch (priv->firmware_type) {
3294 	case ATMEL_FW_TYPE_502E:
3295 		max_rssi = 63; /* 502-rmfd-reve max by experiment */
3296 		break;
3297 	default:
3298 		break;
3299 	}
3300 
3301 	rssi = rssi * 100 / max_rssi;
3302 	if ((rssi + old) % 2)
3303 		priv->wstats.qual.level = (rssi + old) / 2 + 1;
3304 	else
3305 		priv->wstats.qual.level = (rssi + old) / 2;
3306 	priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3307 	priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3308 }
3309 
3310 static void atmel_smooth_qual(struct atmel_private *priv)
3311 {
3312 	unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3313 	while (time_diff--) {
3314 		priv->last_qual += HZ;
3315 		priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3316 		priv->wstats.qual.qual +=
3317 			priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3318 		priv->beacons_this_sec = 0;
3319 	}
3320 	priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3321 	priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3322 }
3323 
3324 /* deals with incoming management frames. */
3325 static void atmel_management_frame(struct atmel_private *priv,
3326 				   struct ieee80211_hdr *header,
3327 				   u16 frame_len, u8 rssi)
3328 {
3329 	u16 subtype;
3330 
3331 	subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3332 	switch (subtype) {
3333 	case IEEE80211_STYPE_BEACON:
3334 	case IEEE80211_STYPE_PROBE_RESP:
3335 
3336 		/* beacon frame has multiple variable-length fields -
3337 		   never let an engineer loose with a data structure design. */
3338 		{
3339 			struct beacon_format {
3340 				__le64 timestamp;
3341 				__le16 interval;
3342 				__le16 capability;
3343 				u8 ssid_el_id;
3344 				u8 ssid_length;
3345 				/* ssid here */
3346 				u8 rates_el_id;
3347 				u8 rates_length;
3348 				/* rates here */
3349 				u8 ds_el_id;
3350 				u8 ds_length;
3351 				/* ds here */
3352 			} *beacon = (struct beacon_format *)priv->rx_buf;
3353 
3354 			u8 channel, rates_length, ssid_length;
3355 			u64 timestamp = le64_to_cpu(beacon->timestamp);
3356 			u16 beacon_interval = le16_to_cpu(beacon->interval);
3357 			u16 capability = le16_to_cpu(beacon->capability);
3358 			u8 *beaconp = priv->rx_buf;
3359 			ssid_length = beacon->ssid_length;
3360 			/* this blows chunks. */
3361 			if (frame_len < 14 || frame_len < ssid_length + 15)
3362 				return;
3363 			rates_length = beaconp[beacon->ssid_length + 15];
3364 			if (frame_len < ssid_length + rates_length + 18)
3365 				return;
3366 			if (ssid_length >  MAX_SSID_LENGTH)
3367 				return;
3368 			channel = beaconp[ssid_length + rates_length + 18];
3369 
3370 			if (priv->station_state == STATION_STATE_READY) {
3371 				smooth_rssi(priv, rssi);
3372 				if (is_frame_from_current_bss(priv, header)) {
3373 					priv->beacons_this_sec++;
3374 					atmel_smooth_qual(priv);
3375 					if (priv->last_beacon_timestamp) {
3376 						/* Note truncate this to 32 bits - kernel can't divide a long long */
3377 						u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3378 						int beacons = beacon_delay / (beacon_interval * 1000);
3379 						if (beacons > 1)
3380 							priv->wstats.miss.beacon += beacons - 1;
3381 					}
3382 					priv->last_beacon_timestamp = timestamp;
3383 					handle_beacon_probe(priv, capability, channel);
3384 				}
3385 			}
3386 
3387 			if (priv->station_state == STATION_STATE_SCANNING)
3388 				store_bss_info(priv, header, capability,
3389 					       beacon_interval, channel, rssi,
3390 					       ssid_length,
3391 					       &beacon->rates_el_id,
3392 					       subtype == IEEE80211_STYPE_BEACON);
3393 		}
3394 		break;
3395 
3396 	case IEEE80211_STYPE_AUTH:
3397 
3398 		if (priv->station_state == STATION_STATE_AUTHENTICATING)
3399 			authenticate(priv, frame_len);
3400 
3401 		break;
3402 
3403 	case IEEE80211_STYPE_ASSOC_RESP:
3404 	case IEEE80211_STYPE_REASSOC_RESP:
3405 
3406 		if (priv->station_state == STATION_STATE_ASSOCIATING ||
3407 		    priv->station_state == STATION_STATE_REASSOCIATING)
3408 			associate(priv, frame_len, subtype);
3409 
3410 		break;
3411 
3412 	case IEEE80211_STYPE_DISASSOC:
3413 		if (priv->station_is_associated &&
3414 		    priv->operating_mode == IW_MODE_INFRA &&
3415 		    is_frame_from_current_bss(priv, header)) {
3416 			priv->station_was_associated = 0;
3417 			priv->station_is_associated = 0;
3418 
3419 			atmel_enter_state(priv, STATION_STATE_JOINNING);
3420 			join(priv, BSS_TYPE_INFRASTRUCTURE);
3421 		}
3422 
3423 		break;
3424 
3425 	case IEEE80211_STYPE_DEAUTH:
3426 		if (priv->operating_mode == IW_MODE_INFRA &&
3427 		    is_frame_from_current_bss(priv, header)) {
3428 			priv->station_was_associated = 0;
3429 
3430 			atmel_enter_state(priv, STATION_STATE_JOINNING);
3431 			join(priv, BSS_TYPE_INFRASTRUCTURE);
3432 		}
3433 
3434 		break;
3435 	}
3436 }
3437 
3438 /* run when timer expires */
3439 static void atmel_management_timer(u_long a)
3440 {
3441 	struct net_device *dev = (struct net_device *) a;
3442 	struct atmel_private *priv = netdev_priv(dev);
3443 	unsigned long flags;
3444 
3445 	/* Check if the card has been yanked. */
3446 	if (priv->card && priv->present_callback &&
3447 		!(*priv->present_callback)(priv->card))
3448 		return;
3449 
3450 	spin_lock_irqsave(&priv->irqlock, flags);
3451 
3452 	switch (priv->station_state) {
3453 
3454 	case STATION_STATE_AUTHENTICATING:
3455 		if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3456 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3457 			priv->station_is_associated = 0;
3458 			priv->AuthenticationRequestRetryCnt = 0;
3459 			restart_search(priv);
3460 		} else {
3461 			int auth = WLAN_AUTH_OPEN;
3462 			priv->AuthenticationRequestRetryCnt++;
3463 			priv->CurrentAuthentTransactionSeqNum = 0x0001;
3464 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3465 			if (priv->wep_is_on && priv->exclude_unencrypted)
3466 				auth = WLAN_AUTH_SHARED_KEY;
3467 			send_authentication_request(priv, auth, NULL, 0);
3468 	  }
3469 	  break;
3470 
3471 	case STATION_STATE_ASSOCIATING:
3472 		if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3473 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3474 			priv->station_is_associated = 0;
3475 			priv->AssociationRequestRetryCnt = 0;
3476 			restart_search(priv);
3477 		} else {
3478 			priv->AssociationRequestRetryCnt++;
3479 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3480 			send_association_request(priv, 0);
3481 		}
3482 	  break;
3483 
3484 	case STATION_STATE_REASSOCIATING:
3485 		if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3486 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3487 			priv->station_is_associated = 0;
3488 			priv->ReAssociationRequestRetryCnt = 0;
3489 			restart_search(priv);
3490 		} else {
3491 			priv->ReAssociationRequestRetryCnt++;
3492 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3493 			send_association_request(priv, 1);
3494 		}
3495 		break;
3496 
3497 	default:
3498 		break;
3499 	}
3500 
3501 	spin_unlock_irqrestore(&priv->irqlock, flags);
3502 }
3503 
3504 static void atmel_command_irq(struct atmel_private *priv)
3505 {
3506 	u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3507 	u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3508 	int fast_scan;
3509 	union iwreq_data wrqu;
3510 
3511 	if (status == CMD_STATUS_IDLE ||
3512 	    status == CMD_STATUS_IN_PROGRESS)
3513 		return;
3514 
3515 	switch (command) {
3516 	case CMD_Start:
3517 		if (status == CMD_STATUS_COMPLETE) {
3518 			priv->station_was_associated = priv->station_is_associated;
3519 			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3520 				      (u8 *)priv->CurrentBSSID, 6);
3521 			atmel_enter_state(priv, STATION_STATE_READY);
3522 		}
3523 		break;
3524 
3525 	case CMD_Scan:
3526 		fast_scan = priv->fast_scan;
3527 		priv->fast_scan = 0;
3528 
3529 		if (status != CMD_STATUS_COMPLETE) {
3530 			atmel_scan(priv, 1);
3531 		} else {
3532 			int bss_index = retrieve_bss(priv);
3533 			int notify_scan_complete = 1;
3534 			if (bss_index != -1) {
3535 				atmel_join_bss(priv, bss_index);
3536 			} else if (priv->operating_mode == IW_MODE_ADHOC &&
3537 				   priv->SSID_size != 0) {
3538 				start(priv, BSS_TYPE_AD_HOC);
3539 			} else {
3540 				priv->fast_scan = !fast_scan;
3541 				atmel_scan(priv, 1);
3542 				notify_scan_complete = 0;
3543 			}
3544 			priv->site_survey_state = SITE_SURVEY_COMPLETED;
3545 			if (notify_scan_complete) {
3546 				wrqu.data.length = 0;
3547 				wrqu.data.flags = 0;
3548 				wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3549 			}
3550 		}
3551 		break;
3552 
3553 	case CMD_SiteSurvey:
3554 		priv->fast_scan = 0;
3555 
3556 		if (status != CMD_STATUS_COMPLETE)
3557 			return;
3558 
3559 		priv->site_survey_state = SITE_SURVEY_COMPLETED;
3560 		if (priv->station_is_associated) {
3561 			atmel_enter_state(priv, STATION_STATE_READY);
3562 			wrqu.data.length = 0;
3563 			wrqu.data.flags = 0;
3564 			wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3565 		} else {
3566 			atmel_scan(priv, 1);
3567 		}
3568 		break;
3569 
3570 	case CMD_Join:
3571 		if (status == CMD_STATUS_COMPLETE) {
3572 			if (priv->operating_mode == IW_MODE_ADHOC) {
3573 				priv->station_was_associated = priv->station_is_associated;
3574 				atmel_enter_state(priv, STATION_STATE_READY);
3575 			} else {
3576 				int auth = WLAN_AUTH_OPEN;
3577 				priv->AuthenticationRequestRetryCnt = 0;
3578 				atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3579 
3580 				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3581 				priv->CurrentAuthentTransactionSeqNum = 0x0001;
3582 				if (priv->wep_is_on && priv->exclude_unencrypted)
3583 					auth = WLAN_AUTH_SHARED_KEY;
3584 				send_authentication_request(priv, auth, NULL, 0);
3585 			}
3586 			return;
3587 		}
3588 
3589 		atmel_scan(priv, 1);
3590 	}
3591 }
3592 
3593 static int atmel_wakeup_firmware(struct atmel_private *priv)
3594 {
3595 	struct host_info_struct *iface = &priv->host_info;
3596 	u16 mr1, mr3;
3597 	int i;
3598 
3599 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
3600 		atmel_set_gcr(priv->dev, GCR_REMAP);
3601 
3602 	/* wake up on-board processor */
3603 	atmel_clear_gcr(priv->dev, 0x0040);
3604 	atmel_write16(priv->dev, BSR, BSS_SRAM);
3605 
3606 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
3607 		mdelay(100);
3608 
3609 	/* and wait for it */
3610 	for (i = LOOP_RETRY_LIMIT; i; i--) {
3611 		mr1 = atmel_read16(priv->dev, MR1);
3612 		mr3 = atmel_read16(priv->dev, MR3);
3613 
3614 		if (mr3 & MAC_BOOT_COMPLETE)
3615 			break;
3616 		if (mr1 & MAC_BOOT_COMPLETE &&
3617 		    priv->bus_type == BUS_TYPE_PCCARD)
3618 			break;
3619 	}
3620 
3621 	if (i == 0) {
3622 		printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3623 		return -EIO;
3624 	}
3625 
3626 	if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3627 		printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3628 		return -ENODEV;
3629 	}
3630 
3631 	/* now check for completion of MAC initialization through
3632 	   the FunCtrl field of the IFACE, poll MR1 to detect completion of
3633 	   MAC initialization, check completion status, set interrupt mask,
3634 	   enables interrupts and calls Tx and Rx initialization functions */
3635 
3636 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3637 
3638 	for (i = LOOP_RETRY_LIMIT; i; i--) {
3639 		mr1 = atmel_read16(priv->dev, MR1);
3640 		mr3 = atmel_read16(priv->dev, MR3);
3641 
3642 		if (mr3 & MAC_INIT_COMPLETE)
3643 			break;
3644 		if (mr1 & MAC_INIT_COMPLETE &&
3645 		    priv->bus_type == BUS_TYPE_PCCARD)
3646 			break;
3647 	}
3648 
3649 	if (i == 0) {
3650 		printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3651 				priv->dev->name);
3652 		return -EIO;
3653 	}
3654 
3655 	/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3656 	if ((mr3 & MAC_INIT_COMPLETE) &&
3657 	    !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3658 		printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3659 		return -EIO;
3660 	}
3661 	if ((mr1 & MAC_INIT_COMPLETE) &&
3662 	    !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3663 		printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3664 		return -EIO;
3665 	}
3666 
3667 	atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3668 			   priv->host_info_base, sizeof(*iface));
3669 
3670 	iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3671 	iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3672 	iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3673 	iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3674 	iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3675 	iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3676 	iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3677 	iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3678 	iface->build_version = le16_to_cpu(iface->build_version);
3679 	iface->command_pos = le16_to_cpu(iface->command_pos);
3680 	iface->major_version = le16_to_cpu(iface->major_version);
3681 	iface->minor_version = le16_to_cpu(iface->minor_version);
3682 	iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3683 	iface->mac_status = le16_to_cpu(iface->mac_status);
3684 
3685 	return 0;
3686 }
3687 
3688 /* determine type of memory and MAC address */
3689 static int probe_atmel_card(struct net_device *dev)
3690 {
3691 	int rc = 0;
3692 	struct atmel_private *priv = netdev_priv(dev);
3693 
3694 	/* reset pccard */
3695 	if (priv->bus_type == BUS_TYPE_PCCARD)
3696 		atmel_write16(dev, GCR, 0x0060);
3697 
3698 	atmel_write16(dev, GCR, 0x0040);
3699 	mdelay(500);
3700 
3701 	if (atmel_read16(dev, MR2) == 0) {
3702 		/* No stored firmware so load a small stub which just
3703 		   tells us the MAC address */
3704 		int i;
3705 		priv->card_type = CARD_TYPE_EEPROM;
3706 		atmel_write16(dev, BSR, BSS_IRAM);
3707 		atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3708 		atmel_set_gcr(dev, GCR_REMAP);
3709 		atmel_clear_gcr(priv->dev, 0x0040);
3710 		atmel_write16(dev, BSR, BSS_SRAM);
3711 		for (i = LOOP_RETRY_LIMIT; i; i--)
3712 			if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3713 				break;
3714 		if (i == 0) {
3715 			printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3716 		} else {
3717 			atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3718 			/* got address, now squash it again until the network
3719 			   interface is opened */
3720 			if (priv->bus_type == BUS_TYPE_PCCARD)
3721 				atmel_write16(dev, GCR, 0x0060);
3722 			atmel_write16(dev, GCR, 0x0040);
3723 			rc = 1;
3724 		}
3725 	} else if (atmel_read16(dev, MR4) == 0) {
3726 		/* Mac address easy in this case. */
3727 		priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3728 		atmel_write16(dev,  BSR, 1);
3729 		atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3730 		atmel_write16(dev,  BSR, 0x200);
3731 		rc = 1;
3732 	} else {
3733 		/* Standard firmware in flash, boot it up and ask
3734 		   for the Mac Address */
3735 		priv->card_type = CARD_TYPE_SPI_FLASH;
3736 		if (atmel_wakeup_firmware(priv) == 0) {
3737 			atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3738 
3739 			/* got address, now squash it again until the network
3740 			   interface is opened */
3741 			if (priv->bus_type == BUS_TYPE_PCCARD)
3742 				atmel_write16(dev, GCR, 0x0060);
3743 			atmel_write16(dev, GCR, 0x0040);
3744 			rc = 1;
3745 		}
3746 	}
3747 
3748 	if (rc) {
3749 		if (dev->dev_addr[0] == 0xFF) {
3750 			static const u8 default_mac[] = {
3751 				0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3752 			};
3753 			printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3754 			memcpy(dev->dev_addr, default_mac, ETH_ALEN);
3755 		}
3756 	}
3757 
3758 	return rc;
3759 }
3760 
3761 /* Move the encyption information on the MIB structure.
3762    This routine is for the pre-WPA firmware: later firmware has
3763    a different format MIB and a different routine. */
3764 static void build_wep_mib(struct atmel_private *priv)
3765 {
3766 	struct { /* NB this is matched to the hardware, don't change. */
3767 		u8 wep_is_on;
3768 		u8 default_key; /* 0..3 */
3769 		u8 reserved;
3770 		u8 exclude_unencrypted;
3771 
3772 		u32 WEPICV_error_count;
3773 		u32 WEP_excluded_count;
3774 
3775 		u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3776 		u8 encryption_level; /* 0, 1, 2 */
3777 		u8 reserved2[3];
3778 	} mib;
3779 	int i;
3780 
3781 	mib.wep_is_on = priv->wep_is_on;
3782 	if (priv->wep_is_on) {
3783 		if (priv->wep_key_len[priv->default_key] > 5)
3784 			mib.encryption_level = 2;
3785 		else
3786 			mib.encryption_level = 1;
3787 	} else {
3788 		mib.encryption_level = 0;
3789 	}
3790 
3791 	mib.default_key = priv->default_key;
3792 	mib.exclude_unencrypted = priv->exclude_unencrypted;
3793 
3794 	for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3795 		memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3796 
3797 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3798 }
3799 
3800 static void build_wpa_mib(struct atmel_private *priv)
3801 {
3802 	/* This is for the later (WPA enabled) firmware. */
3803 
3804 	struct { /* NB this is matched to the hardware, don't change. */
3805 		u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3806 		u8 receiver_address[ETH_ALEN];
3807 		u8 wep_is_on;
3808 		u8 default_key; /* 0..3 */
3809 		u8 group_key;
3810 		u8 exclude_unencrypted;
3811 		u8 encryption_type;
3812 		u8 reserved;
3813 
3814 		u32 WEPICV_error_count;
3815 		u32 WEP_excluded_count;
3816 
3817 		u8 key_RSC[4][8];
3818 	} mib;
3819 
3820 	int i;
3821 
3822 	mib.wep_is_on = priv->wep_is_on;
3823 	mib.exclude_unencrypted = priv->exclude_unencrypted;
3824 	memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3825 
3826 	/* zero all the keys before adding in valid ones. */
3827 	memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3828 
3829 	if (priv->wep_is_on) {
3830 		/* There's a comment in the Atmel code to the effect that this
3831 		   is only valid when still using WEP, it may need to be set to
3832 		   something to use WPA */
3833 		memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3834 
3835 		mib.default_key = mib.group_key = 255;
3836 		for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3837 			if (priv->wep_key_len[i] > 0) {
3838 				memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3839 				if (i == priv->default_key) {
3840 					mib.default_key = i;
3841 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3842 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3843 				} else {
3844 					mib.group_key = i;
3845 					priv->group_cipher_suite = priv->pairwise_cipher_suite;
3846 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3847 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3848 				}
3849 			}
3850 		}
3851 		if (mib.default_key == 255)
3852 			mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3853 		if (mib.group_key == 255)
3854 			mib.group_key = mib.default_key;
3855 
3856 	}
3857 
3858 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3859 }
3860 
3861 static int reset_atmel_card(struct net_device *dev)
3862 {
3863 	/* do everything necessary to wake up the hardware, including
3864 	   waiting for the lightning strike and throwing the knife switch....
3865 
3866 	   set all the Mib values which matter in the card to match
3867 	   their settings in the atmel_private structure. Some of these
3868 	   can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3869 	   can only be changed by tearing down the world and coming back through
3870 	   here.
3871 
3872 	   This routine is also responsible for initialising some
3873 	   hardware-specific fields in the atmel_private structure,
3874 	   including a copy of the firmware's hostinfo structure
3875 	   which is the route into the rest of the firmware datastructures. */
3876 
3877 	struct atmel_private *priv = netdev_priv(dev);
3878 	u8 configuration;
3879 	int old_state = priv->station_state;
3880 	int err = 0;
3881 
3882 	/* data to add to the firmware names, in priority order
3883 	   this implemenents firmware versioning */
3884 
3885 	static char *firmware_modifier[] = {
3886 		"-wpa",
3887 		"",
3888 		NULL
3889 	};
3890 
3891 	/* reset pccard */
3892 	if (priv->bus_type == BUS_TYPE_PCCARD)
3893 		atmel_write16(priv->dev, GCR, 0x0060);
3894 
3895 	/* stop card , disable interrupts */
3896 	atmel_write16(priv->dev, GCR, 0x0040);
3897 
3898 	if (priv->card_type == CARD_TYPE_EEPROM) {
3899 		/* copy in firmware if needed */
3900 		const struct firmware *fw_entry = NULL;
3901 		const unsigned char *fw;
3902 		int len = priv->firmware_length;
3903 		if (!(fw = priv->firmware)) {
3904 			if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3905 				if (strlen(priv->firmware_id) == 0) {
3906 					printk(KERN_INFO
3907 					       "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3908 					       dev->name);
3909 					printk(KERN_INFO
3910 					       "%s: if not, use the firmware= module parameter.\n",
3911 					       dev->name);
3912 					strcpy(priv->firmware_id, "atmel_at76c502.bin");
3913 				}
3914 				err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3915 				if (err != 0) {
3916 					printk(KERN_ALERT
3917 					       "%s: firmware %s is missing, cannot continue.\n",
3918 					       dev->name, priv->firmware_id);
3919 					return err;
3920 				}
3921 			} else {
3922 				int fw_index = 0;
3923 				int success = 0;
3924 
3925 				/* get firmware filename entry based on firmware type ID */
3926 				while (fw_table[fw_index].fw_type != priv->firmware_type
3927 						&& fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3928 					fw_index++;
3929 
3930 				/* construct the actual firmware file name */
3931 				if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3932 					int i;
3933 					for (i = 0; firmware_modifier[i]; i++) {
3934 						snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3935 							firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3936 						priv->firmware_id[31] = '\0';
3937 						if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3938 							success = 1;
3939 							break;
3940 						}
3941 					}
3942 				}
3943 				if (!success) {
3944 					printk(KERN_ALERT
3945 					       "%s: firmware %s is missing, cannot start.\n",
3946 					       dev->name, priv->firmware_id);
3947 					priv->firmware_id[0] = '\0';
3948 					return -ENOENT;
3949 				}
3950 			}
3951 
3952 			fw = fw_entry->data;
3953 			len = fw_entry->size;
3954 		}
3955 
3956 		if (len <= 0x6000) {
3957 			atmel_write16(priv->dev, BSR, BSS_IRAM);
3958 			atmel_copy_to_card(priv->dev, 0, fw, len);
3959 			atmel_set_gcr(priv->dev, GCR_REMAP);
3960 		} else {
3961 			/* Remap */
3962 			atmel_set_gcr(priv->dev, GCR_REMAP);
3963 			atmel_write16(priv->dev, BSR, BSS_IRAM);
3964 			atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3965 			atmel_write16(priv->dev, BSR, 0x2ff);
3966 			atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3967 		}
3968 
3969 		release_firmware(fw_entry);
3970 	}
3971 
3972 	err = atmel_wakeup_firmware(priv);
3973 	if (err != 0)
3974 		return err;
3975 
3976 	/* Check the version and set the correct flag for wpa stuff,
3977 	   old and new firmware is incompatible.
3978 	   The pre-wpa 3com firmware reports major version 5,
3979 	   the wpa 3com firmware is major version 4 and doesn't need
3980 	   the 3com broken-ness filter. */
3981 	priv->use_wpa = (priv->host_info.major_version == 4);
3982 	priv->radio_on_broken = (priv->host_info.major_version == 5);
3983 
3984 	/* unmask all irq sources */
3985 	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3986 
3987 	/* int Tx system and enable Tx */
3988 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3989 	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3990 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3991 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3992 
3993 	priv->tx_desc_free = priv->host_info.tx_desc_count;
3994 	priv->tx_desc_head = 0;
3995 	priv->tx_desc_tail = 0;
3996 	priv->tx_desc_previous = 0;
3997 	priv->tx_free_mem = priv->host_info.tx_buff_size;
3998 	priv->tx_buff_head = 0;
3999 	priv->tx_buff_tail = 0;
4000 
4001 	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
4002 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
4003 				   configuration | FUNC_CTRL_TxENABLE);
4004 
4005 	/* init Rx system and enable */
4006 	priv->rx_desc_head = 0;
4007 
4008 	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
4009 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
4010 				   configuration | FUNC_CTRL_RxENABLE);
4011 
4012 	if (!priv->radio_on_broken) {
4013 		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
4014 		    CMD_STATUS_REJECTED_RADIO_OFF) {
4015 			printk(KERN_INFO "%s: cannot turn the radio on.\n",
4016 			       dev->name);
4017 			return -EIO;
4018 		}
4019 	}
4020 
4021 	/* set up enough MIB values to run. */
4022 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4023 	atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
4024 	atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4025 	atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4026 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4027 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4028 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4029 	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4030 		      priv->dev->dev_addr, 6);
4031 	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4032 	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4033 	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4034 	atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4035 	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4036 	if (priv->use_wpa)
4037 		build_wpa_mib(priv);
4038 	else
4039 		build_wep_mib(priv);
4040 
4041 	if (old_state == STATION_STATE_READY) {
4042 		union iwreq_data wrqu;
4043 
4044 		wrqu.data.length = 0;
4045 		wrqu.data.flags = 0;
4046 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4047 		eth_zero_addr(wrqu.ap_addr.sa_data);
4048 		wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4049 	}
4050 
4051 	return 0;
4052 }
4053 
4054 static void atmel_send_command(struct atmel_private *priv, int command,
4055 			       void *cmd, int cmd_size)
4056 {
4057 	if (cmd)
4058 		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4059 				   cmd, cmd_size);
4060 
4061 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4062 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4063 }
4064 
4065 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4066 				   void *cmd, int cmd_size)
4067 {
4068 	int i, status;
4069 
4070 	atmel_send_command(priv, command, cmd, cmd_size);
4071 
4072 	for (i = 5000; i; i--) {
4073 		status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4074 		if (status != CMD_STATUS_IDLE &&
4075 		    status != CMD_STATUS_IN_PROGRESS)
4076 			break;
4077 		udelay(20);
4078 	}
4079 
4080 	if (i == 0) {
4081 		printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4082 		status =  CMD_STATUS_HOST_ERROR;
4083 	} else {
4084 		if (command != CMD_EnableRadio)
4085 			status = CMD_STATUS_COMPLETE;
4086 	}
4087 
4088 	return status;
4089 }
4090 
4091 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4092 {
4093 	struct get_set_mib m;
4094 	m.type = type;
4095 	m.size = 1;
4096 	m.index = index;
4097 
4098 	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4099 	return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4100 }
4101 
4102 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4103 {
4104 	struct get_set_mib m;
4105 	m.type = type;
4106 	m.size = 1;
4107 	m.index = index;
4108 	m.data[0] = data;
4109 
4110 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4111 }
4112 
4113 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4114 			    u16 data)
4115 {
4116 	struct get_set_mib m;
4117 	m.type = type;
4118 	m.size = 2;
4119 	m.index = index;
4120 	m.data[0] = data;
4121 	m.data[1] = data >> 8;
4122 
4123 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4124 }
4125 
4126 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4127 			  u8 *data, int data_len)
4128 {
4129 	struct get_set_mib m;
4130 	m.type = type;
4131 	m.size = data_len;
4132 	m.index = index;
4133 
4134 	if (data_len > MIB_MAX_DATA_BYTES)
4135 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4136 
4137 	memcpy(m.data, data, data_len);
4138 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4139 }
4140 
4141 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4142 			  u8 *data, int data_len)
4143 {
4144 	struct get_set_mib m;
4145 	m.type = type;
4146 	m.size = data_len;
4147 	m.index = index;
4148 
4149 	if (data_len > MIB_MAX_DATA_BYTES)
4150 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4151 
4152 	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4153 	atmel_copy_to_host(priv->dev, data,
4154 			   atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4155 }
4156 
4157 static void atmel_writeAR(struct net_device *dev, u16 data)
4158 {
4159 	int i;
4160 	outw(data, dev->base_addr + AR);
4161 	/* Address register appears to need some convincing..... */
4162 	for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4163 		outw(data, dev->base_addr + AR);
4164 }
4165 
4166 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4167 			       const unsigned char *src, u16 len)
4168 {
4169 	int i;
4170 	atmel_writeAR(dev, dest);
4171 	if (dest % 2) {
4172 		atmel_write8(dev, DR, *src);
4173 		src++; len--;
4174 	}
4175 	for (i = len; i > 1 ; i -= 2) {
4176 		u8 lb = *src++;
4177 		u8 hb = *src++;
4178 		atmel_write16(dev, DR, lb | (hb << 8));
4179 	}
4180 	if (i)
4181 		atmel_write8(dev, DR, *src);
4182 }
4183 
4184 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4185 			       u16 src, u16 len)
4186 {
4187 	int i;
4188 	atmel_writeAR(dev, src);
4189 	if (src % 2) {
4190 		*dest = atmel_read8(dev, DR);
4191 		dest++; len--;
4192 	}
4193 	for (i = len; i > 1 ; i -= 2) {
4194 		u16 hw = atmel_read16(dev, DR);
4195 		*dest++ = hw;
4196 		*dest++ = hw >> 8;
4197 	}
4198 	if (i)
4199 		*dest = atmel_read8(dev, DR);
4200 }
4201 
4202 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4203 {
4204 	outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4205 }
4206 
4207 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4208 {
4209 	outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4210 }
4211 
4212 static int atmel_lock_mac(struct atmel_private *priv)
4213 {
4214 	int i, j = 20;
4215  retry:
4216 	for (i = 5000; i; i--) {
4217 		if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4218 			break;
4219 		udelay(20);
4220 	}
4221 
4222 	if (!i)
4223 		return 0; /* timed out */
4224 
4225 	atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4226 	if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4227 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4228 		if (!j--)
4229 			return 0; /* timed out */
4230 		goto retry;
4231 	}
4232 
4233 	return 1;
4234 }
4235 
4236 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4237 {
4238 	atmel_writeAR(priv->dev, pos);
4239 	atmel_write16(priv->dev, DR, data); /* card is little-endian */
4240 	atmel_write16(priv->dev, DR, data >> 16);
4241 }
4242 
4243 /***************************************************************************/
4244 /* There follows the source form of the MAC address reading firmware       */
4245 /***************************************************************************/
4246 #if 0
4247 
4248 /* Copyright 2003 Matthew T. Russotto                                      */
4249 /* But derived from the Atmel 76C502 firmware written by Atmel and         */
4250 /* included in "atmel wireless lan drivers" package                        */
4251 /**
4252     This file is part of net.russotto.AtmelMACFW, hereto referred to
4253     as AtmelMACFW
4254 
4255     AtmelMACFW is free software; you can redistribute it and/or modify
4256     it under the terms of the GNU General Public License version 2
4257     as published by the Free Software Foundation.
4258 
4259     AtmelMACFW is distributed in the hope that it will be useful,
4260     but WITHOUT ANY WARRANTY; without even the implied warranty of
4261     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4262     GNU General Public License for more details.
4263 
4264     You should have received a copy of the GNU General Public License
4265     along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4266 
4267 ****************************************************************************/
4268 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
4269 /* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
4270 /* It only works on SPI EEPROM versions of the card.                       */
4271 
4272 /* This firmware initializes the SPI controller and clock, reads the MAC   */
4273 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
4274 /* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
4275 /* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
4276 /* MR4, for investigational purposes (maybe we can determine chip type     */
4277 /* from that?)                                                             */
4278 
4279 	.org 0
4280     .set MRBASE, 0x8000000
4281 	.set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4282 	.set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4283 	.set SRAM_BASE,  0x02000000
4284 	.set SP_BASE,    0x0F300000
4285 	.set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
4286 	.set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
4287 	.set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
4288 	.set STACK_BASE, 0x5600
4289 	.set SP_SR, 0x10
4290 	.set SP_TDRE, 2 /* status register bit -- TDR empty */
4291 	.set SP_RDRF, 1 /* status register bit -- RDR full */
4292 	.set SP_SWRST, 0x80
4293 	.set SP_SPIEN, 0x1
4294 	.set SP_CR, 0   /* control register */
4295 	.set SP_MR, 4   /* mode register */
4296 	.set SP_RDR, 0x08 /* Read Data Register */
4297 	.set SP_TDR, 0x0C /* Transmit Data Register */
4298 	.set SP_CSR0, 0x30 /* chip select registers */
4299 	.set SP_CSR1, 0x34
4300 	.set SP_CSR2, 0x38
4301 	.set SP_CSR3, 0x3C
4302 	.set NVRAM_CMD_RDSR, 5 /* read status register */
4303 	.set NVRAM_CMD_READ, 3 /* read data */
4304 	.set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
4305 	.set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4306 				  serial output, since SO is normally high.  But it
4307 				  does cause 8 clock cycles and thus 8 bits to be
4308 				  clocked in to the chip.  See Atmel's SPI
4309 				  controller (e.g. AT91M55800) timing and 4K
4310 				  SPI EEPROM manuals */
4311 
4312 	.set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
4313 	.set NVRAM_IMAGE, 0x02000200
4314 	.set NVRAM_LENGTH, 0x0200
4315 	.set MAC_ADDRESS_MIB, SRAM_BASE
4316 	.set MAC_ADDRESS_LENGTH, 6
4317 	.set MAC_BOOT_FLAG, 0x10
4318 	.set MR1, 0
4319 	.set MR2, 4
4320 	.set MR3, 8
4321 	.set MR4, 0xC
4322 RESET_VECTOR:
4323 	b RESET_HANDLER
4324 UNDEF_VECTOR:
4325 	b HALT1
4326 SWI_VECTOR:
4327 	b HALT1
4328 IABORT_VECTOR:
4329 	b HALT1
4330 DABORT_VECTOR:
4331 RESERVED_VECTOR:
4332 	b HALT1
4333 IRQ_VECTOR:
4334 	b HALT1
4335 FIQ_VECTOR:
4336 	b HALT1
4337 HALT1:	b HALT1
4338 RESET_HANDLER:
4339 	mov     r0, #CPSR_INITIAL
4340 	msr	CPSR_c, r0	/* This is probably unnecessary */
4341 
4342 /* I'm guessing this is initializing clock generator electronics for SPI */
4343 	ldr	r0, =SPI_CGEN_BASE
4344 	mov	r1, #0
4345 	mov	r1, r1, lsl #3
4346 	orr	r1, r1, #0
4347 	str	r1, [r0]
4348 	ldr	r1, [r0, #28]
4349 	bic	r1, r1, #16
4350 	str	r1, [r0, #28]
4351 	mov	r1, #1
4352 	str	r1, [r0, #8]
4353 
4354 	ldr	r0, =MRBASE
4355 	mov	r1, #0
4356 	strh	r1, [r0, #MR1]
4357 	strh	r1, [r0, #MR2]
4358 	strh	r1, [r0, #MR3]
4359 	strh	r1, [r0, #MR4]
4360 
4361 	mov	sp, #STACK_BASE
4362 	bl	SP_INIT
4363 	mov	r0, #10
4364 	bl	DELAY9
4365 	bl	GET_MAC_ADDR
4366 	bl	GET_WHOLE_NVRAM
4367 	ldr	r0, =MRBASE
4368 	ldr	r1, =MAC_ADDRESS_MIB
4369 	strh	r1, [r0, #MR2]
4370 	ldr	r1, =NVRAM_IMAGE
4371 	strh	r1, [r0, #MR4]
4372 	mov	r1, #MAC_BOOT_FLAG
4373 	strh	r1, [r0, #MR3]
4374 HALT2:	b HALT2
4375 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4376 GET_WHOLE_NVRAM:
4377 	stmdb	sp!, {lr}
4378 	mov	r2, #0 /* 0th bytes of NVRAM */
4379 	mov	r3, #NVRAM_LENGTH
4380 	mov	r1, #0		/* not used in routine */
4381 	ldr	r0, =NVRAM_IMAGE
4382 	bl	NVRAM_XFER
4383 	ldmia	sp!, {lr}
4384 	bx	lr
4385 .endfunc
4386 
4387 .func Get_MAC_Addr, GET_MAC_ADDR
4388 GET_MAC_ADDR:
4389 	stmdb	sp!, {lr}
4390 	mov	r2, #0x120	/* address of MAC Address within NVRAM */
4391 	mov	r3, #MAC_ADDRESS_LENGTH
4392 	mov	r1, #0		/* not used in routine */
4393 	ldr	r0, =MAC_ADDRESS_MIB
4394 	bl	NVRAM_XFER
4395 	ldmia	sp!, {lr}
4396 	bx	lr
4397 .endfunc
4398 .ltorg
4399 .func Delay9, DELAY9
4400 DELAY9:
4401 	adds	r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
4402 DELAYLOOP:
4403 	beq	DELAY9_done
4404 	subs	r0, r0, #1
4405 	b	DELAYLOOP
4406 DELAY9_done:
4407 	bx	lr
4408 .endfunc
4409 
4410 .func SP_Init, SP_INIT
4411 SP_INIT:
4412 	mov	r1, #SP_SWRST
4413 	ldr	r0, =SP_BASE
4414 	str	r1, [r0, #SP_CR] /* reset the SPI */
4415 	mov	r1, #0
4416 	str	r1, [r0, #SP_CR] /* release SPI from reset state */
4417 	mov	r1, #SP_SPIEN
4418 	str	r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4419 	str	r1, [r0, #SP_CR] /* enable the SPI */
4420 
4421 /*  My guess would be this turns on the SPI clock */
4422 	ldr	r3, =SPI_CGEN_BASE
4423 	ldr	r1, [r3, #28]
4424 	orr	r1, r1, #0x2000
4425 	str	r1, [r3, #28]
4426 
4427 	ldr	r1, =0x2000c01
4428 	str	r1, [r0, #SP_CSR0]
4429 	ldr	r1, =0x2000201
4430 	str	r1, [r0, #SP_CSR1]
4431 	str	r1, [r0, #SP_CSR2]
4432 	str	r1, [r0, #SP_CSR3]
4433 	ldr	r1, [r0, #SP_SR]
4434 	ldr	r0, [r0, #SP_RDR]
4435 	bx	lr
4436 .endfunc
4437 .func NVRAM_Init, NVRAM_INIT
4438 NVRAM_INIT:
4439 	ldr	r1, =SP_BASE
4440 	ldr	r0, [r1, #SP_RDR]
4441 	mov	r0, #NVRAM_CMD_RDSR
4442 	str	r0, [r1, #SP_TDR]
4443 SP_loop1:
4444 	ldr	r0, [r1, #SP_SR]
4445 	tst	r0, #SP_TDRE
4446 	beq	SP_loop1
4447 
4448 	mov	r0, #SPI_8CLOCKS
4449 	str	r0, [r1, #SP_TDR]
4450 SP_loop2:
4451 	ldr	r0, [r1, #SP_SR]
4452 	tst	r0, #SP_TDRE
4453 	beq	SP_loop2
4454 
4455 	ldr	r0, [r1, #SP_RDR]
4456 SP_loop3:
4457 	ldr	r0, [r1, #SP_SR]
4458 	tst	r0, #SP_RDRF
4459 	beq	SP_loop3
4460 
4461 	ldr	r0, [r1, #SP_RDR]
4462 	and	r0, r0, #255
4463 	bx	lr
4464 .endfunc
4465 
4466 .func NVRAM_Xfer, NVRAM_XFER
4467 	/* r0 = dest address */
4468 	/* r1 = not used */
4469 	/* r2 = src address within NVRAM */
4470 	/* r3 = length */
4471 NVRAM_XFER:
4472 	stmdb	sp!, {r4, r5, lr}
4473 	mov	r5, r0		/* save r0 (dest address) */
4474 	mov	r4, r3		/* save r3 (length) */
4475 	mov	r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
4476 	and	r0, r0, #8
4477 	add	r0, r0, #NVRAM_CMD_READ
4478 	ldr	r1, =NVRAM_SCRATCH
4479 	strb	r0, [r1, #0]	/* save command in NVRAM_SCRATCH[0] */
4480 	strb	r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
4481 _local1:
4482 	bl	NVRAM_INIT
4483 	tst	r0, #NVRAM_SR_RDY
4484 	bne	_local1
4485 	mov	r0, #20
4486 	bl	DELAY9
4487 	mov	r2, r4		/* length */
4488 	mov	r1, r5		/* dest address */
4489 	mov	r0, #2		/* bytes to transfer in command */
4490 	bl	NVRAM_XFER2
4491 	ldmia	sp!, {r4, r5, lr}
4492 	bx	lr
4493 .endfunc
4494 
4495 .func NVRAM_Xfer2, NVRAM_XFER2
4496 NVRAM_XFER2:
4497 	stmdb	sp!, {r4, r5, r6, lr}
4498 	ldr	r4, =SP_BASE
4499 	mov	r3, #0
4500 	cmp	r0, #0
4501 	bls	_local2
4502 	ldr	r5, =NVRAM_SCRATCH
4503 _local4:
4504 	ldrb	r6, [r5, r3]
4505 	str	r6, [r4, #SP_TDR]
4506 _local3:
4507 	ldr	r6, [r4, #SP_SR]
4508 	tst	r6, #SP_TDRE
4509 	beq	_local3
4510 	add	r3, r3, #1
4511 	cmp	r3, r0 /* r0 is # of bytes to send out (command+addr) */
4512 	blo	_local4
4513 _local2:
4514 	mov	r3, #SPI_8CLOCKS
4515 	str	r3, [r4, #SP_TDR]
4516 	ldr	r0, [r4, #SP_RDR]
4517 _local5:
4518 	ldr	r0, [r4, #SP_SR]
4519 	tst	r0, #SP_RDRF
4520 	beq	_local5
4521 	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 */
4522 	mov	r0, #0
4523 	cmp	r2, #0  /* r2 is # of bytes to copy in */
4524 	bls	_local6
4525 _local7:
4526 	ldr	r5, [r4, #SP_SR]
4527 	tst	r5, #SP_TDRE
4528 	beq	_local7
4529 	str	r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
4530 _local8:
4531 	ldr	r5, [r4, #SP_SR]
4532 	tst	r5, #SP_RDRF
4533 	beq	_local8
4534 	ldr	r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4535 	strb	r5, [r1], #1 /* postindexed */
4536 	add	r0, r0, #1
4537 	cmp	r0, r2
4538 	blo	_local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4539 _local6:
4540 	mov	r0, #200
4541 	bl	DELAY9
4542 	ldmia	sp!, {r4, r5, r6, lr}
4543 	bx	lr
4544 #endif
4545