xref: /openbmc/linux/drivers/net/wireless/atmel/atmel.c (revision 7ff836f0)
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 	unsigned long 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(struct timer_list *t);
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 				skb_put_data(skb, priv->rx_buf,
1040 				             priv->frag_len + 12);
1041 				skb->protocol = eth_type_trans(skb, priv->dev);
1042 				skb->ip_summed = CHECKSUM_NONE;
1043 				netif_rx(skb);
1044 				priv->dev->stats.rx_bytes += priv->frag_len + 12;
1045 				priv->dev->stats.rx_packets++;
1046 			}
1047 		}
1048 	} else
1049 		priv->wstats.discard.fragment++;
1050 }
1051 
1052 static void rx_done_irq(struct atmel_private *priv)
1053 {
1054 	int i;
1055 	struct ieee80211_hdr header;
1056 
1057 	for (i = 0;
1058 	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1059 		     i < priv->host_info.rx_desc_count;
1060 	     i++) {
1061 
1062 		u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1063 		u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1064 		u32 crc = 0xffffffff;
1065 
1066 		if (status != RX_STATUS_SUCCESS) {
1067 			if (status == 0xc1) /* determined by experiment */
1068 				priv->wstats.discard.nwid++;
1069 			else
1070 				priv->dev->stats.rx_errors++;
1071 			goto next;
1072 		}
1073 
1074 		msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1075 		rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1076 
1077 		if (msdu_size < 30) {
1078 			priv->dev->stats.rx_errors++;
1079 			goto next;
1080 		}
1081 
1082 		/* Get header as far as end of seq_ctrl */
1083 		atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1084 		frame_ctl = le16_to_cpu(header.frame_control);
1085 		seq_control = le16_to_cpu(header.seq_ctrl);
1086 
1087 		/* probe for CRC use here if needed  once five packets have
1088 		   arrived with the same crc status, we assume we know what's
1089 		   happening and stop probing */
1090 		if (priv->probe_crc) {
1091 			if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1092 				priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1093 			} else {
1094 				priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1095 			}
1096 			if (priv->do_rx_crc) {
1097 				if (priv->crc_ok_cnt++ > 5)
1098 					priv->probe_crc = 0;
1099 			} else {
1100 				if (priv->crc_ko_cnt++ > 5)
1101 					priv->probe_crc = 0;
1102 			}
1103 		}
1104 
1105 		/* don't CRC header when WEP in use */
1106 		if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1107 			crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1108 		}
1109 		msdu_size -= 24; /* header */
1110 
1111 		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1112 			int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1113 			u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1114 			u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1115 
1116 			if (!more_fragments && packet_fragment_no == 0) {
1117 				fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1118 			} else {
1119 				frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1120 					     packet_sequence_no, packet_fragment_no, more_fragments);
1121 			}
1122 		}
1123 
1124 		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1125 			/* copy rest of packet into buffer */
1126 			atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1127 
1128 			/* we use the same buffer for frag reassembly and control packets */
1129 			eth_broadcast_addr(priv->frag_source);
1130 
1131 			if (priv->do_rx_crc) {
1132 				/* last 4 octets is crc */
1133 				msdu_size -= 4;
1134 				crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1135 				if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1136 					priv->dev->stats.rx_crc_errors++;
1137 					goto next;
1138 				}
1139 			}
1140 
1141 			atmel_management_frame(priv, &header, msdu_size,
1142 					       atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1143 		}
1144 
1145 next:
1146 		/* release descriptor */
1147 		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1148 
1149 		if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1150 			priv->rx_desc_head++;
1151 		else
1152 			priv->rx_desc_head = 0;
1153 	}
1154 }
1155 
1156 static irqreturn_t service_interrupt(int irq, void *dev_id)
1157 {
1158 	struct net_device *dev = (struct net_device *) dev_id;
1159 	struct atmel_private *priv = netdev_priv(dev);
1160 	u8 isr;
1161 	int i = -1;
1162 	static const u8 irq_order[] = {
1163 		ISR_OUT_OF_RANGE,
1164 		ISR_RxCOMPLETE,
1165 		ISR_TxCOMPLETE,
1166 		ISR_RxFRAMELOST,
1167 		ISR_FATAL_ERROR,
1168 		ISR_COMMAND_COMPLETE,
1169 		ISR_IBSS_MERGE,
1170 		ISR_GENERIC_IRQ
1171 	};
1172 
1173 	if (priv->card && priv->present_callback &&
1174 	    !(*priv->present_callback)(priv->card))
1175 		return IRQ_HANDLED;
1176 
1177 	/* In this state upper-level code assumes it can mess with
1178 	   the card unhampered by interrupts which may change register state.
1179 	   Note that even though the card shouldn't generate interrupts
1180 	   the inturrupt line may be shared. This allows card setup
1181 	   to go on without disabling interrupts for a long time. */
1182 	if (priv->station_state == STATION_STATE_DOWN)
1183 		return IRQ_NONE;
1184 
1185 	atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1186 
1187 	while (1) {
1188 		if (!atmel_lock_mac(priv)) {
1189 			/* failed to contact card */
1190 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1191 			return IRQ_HANDLED;
1192 		}
1193 
1194 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1195 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1196 
1197 		if (!isr) {
1198 			atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1199 			return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1200 		}
1201 
1202 		atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1203 
1204 		for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1205 			if (isr & irq_order[i])
1206 				break;
1207 
1208 		if (!atmel_lock_mac(priv)) {
1209 			/* failed to contact card */
1210 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1211 			return IRQ_HANDLED;
1212 		}
1213 
1214 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1215 		isr ^= irq_order[i];
1216 		atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1217 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1218 
1219 		switch (irq_order[i]) {
1220 
1221 		case ISR_OUT_OF_RANGE:
1222 			if (priv->operating_mode == IW_MODE_INFRA &&
1223 			    priv->station_state == STATION_STATE_READY) {
1224 				priv->station_is_associated = 0;
1225 				atmel_scan(priv, 1);
1226 			}
1227 			break;
1228 
1229 		case ISR_RxFRAMELOST:
1230 			priv->wstats.discard.misc++;
1231 			/* fall through */
1232 		case ISR_RxCOMPLETE:
1233 			rx_done_irq(priv);
1234 			break;
1235 
1236 		case ISR_TxCOMPLETE:
1237 			tx_done_irq(priv);
1238 			break;
1239 
1240 		case ISR_FATAL_ERROR:
1241 			printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1242 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1243 			break;
1244 
1245 		case ISR_COMMAND_COMPLETE:
1246 			atmel_command_irq(priv);
1247 			break;
1248 
1249 		case ISR_IBSS_MERGE:
1250 			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1251 				      priv->CurrentBSSID, 6);
1252 			/* The WPA stuff cares about the current AP address */
1253 			if (priv->use_wpa)
1254 				build_wpa_mib(priv);
1255 			break;
1256 		case ISR_GENERIC_IRQ:
1257 			printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1258 			break;
1259 		}
1260 	}
1261 }
1262 
1263 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1264 {
1265 	struct atmel_private *priv = netdev_priv(dev);
1266 
1267 	/* update the link quality here in case we are seeing no beacons
1268 	   at all to drive the process */
1269 	atmel_smooth_qual(priv);
1270 
1271 	priv->wstats.status = priv->station_state;
1272 
1273 	if (priv->operating_mode == IW_MODE_INFRA) {
1274 		if (priv->station_state != STATION_STATE_READY) {
1275 			priv->wstats.qual.qual = 0;
1276 			priv->wstats.qual.level = 0;
1277 			priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1278 					| IW_QUAL_LEVEL_INVALID);
1279 		}
1280 		priv->wstats.qual.noise = 0;
1281 		priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1282 	} else {
1283 		/* Quality levels cannot be determined in ad-hoc mode,
1284 		   because we can 'hear' more that one remote station. */
1285 		priv->wstats.qual.qual = 0;
1286 		priv->wstats.qual.level	= 0;
1287 		priv->wstats.qual.noise	= 0;
1288 		priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1289 					| IW_QUAL_LEVEL_INVALID
1290 					| IW_QUAL_NOISE_INVALID;
1291 		priv->wstats.miss.beacon = 0;
1292 	}
1293 
1294 	return &priv->wstats;
1295 }
1296 
1297 static int atmel_set_mac_address(struct net_device *dev, void *p)
1298 {
1299 	struct sockaddr *addr = p;
1300 
1301 	memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1302 	return atmel_open(dev);
1303 }
1304 
1305 EXPORT_SYMBOL(atmel_open);
1306 
1307 int atmel_open(struct net_device *dev)
1308 {
1309 	struct atmel_private *priv = netdev_priv(dev);
1310 	int i, channel, err;
1311 
1312 	/* any scheduled timer is no longer needed and might screw things up.. */
1313 	del_timer_sync(&priv->management_timer);
1314 
1315 	/* Interrupts will not touch the card once in this state... */
1316 	priv->station_state = STATION_STATE_DOWN;
1317 
1318 	if (priv->new_SSID_size) {
1319 		memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1320 		priv->SSID_size = priv->new_SSID_size;
1321 		priv->new_SSID_size = 0;
1322 	}
1323 	priv->BSS_list_entries = 0;
1324 
1325 	priv->AuthenticationRequestRetryCnt = 0;
1326 	priv->AssociationRequestRetryCnt = 0;
1327 	priv->ReAssociationRequestRetryCnt = 0;
1328 	priv->CurrentAuthentTransactionSeqNum = 0x0001;
1329 	priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1330 
1331 	priv->site_survey_state = SITE_SURVEY_IDLE;
1332 	priv->station_is_associated = 0;
1333 
1334 	err = reset_atmel_card(dev);
1335 	if (err)
1336 		return err;
1337 
1338 	if (priv->config_reg_domain) {
1339 		priv->reg_domain = priv->config_reg_domain;
1340 		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1341 	} else {
1342 		priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1343 		for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1344 			if (priv->reg_domain == channel_table[i].reg_domain)
1345 				break;
1346 		if (i == ARRAY_SIZE(channel_table)) {
1347 			priv->reg_domain = REG_DOMAIN_MKK1;
1348 			printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1349 		}
1350 	}
1351 
1352 	if ((channel = atmel_validate_channel(priv, priv->channel)))
1353 		priv->channel = channel;
1354 
1355 	/* this moves station_state on.... */
1356 	atmel_scan(priv, 1);
1357 
1358 	atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1359 	return 0;
1360 }
1361 
1362 static int atmel_close(struct net_device *dev)
1363 {
1364 	struct atmel_private *priv = netdev_priv(dev);
1365 
1366 	/* Send event to userspace that we are disassociating */
1367 	if (priv->station_state == STATION_STATE_READY) {
1368 		union iwreq_data wrqu;
1369 
1370 		wrqu.data.length = 0;
1371 		wrqu.data.flags = 0;
1372 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1373 		eth_zero_addr(wrqu.ap_addr.sa_data);
1374 		wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1375 	}
1376 
1377 	atmel_enter_state(priv, STATION_STATE_DOWN);
1378 
1379 	if (priv->bus_type == BUS_TYPE_PCCARD)
1380 		atmel_write16(dev, GCR, 0x0060);
1381 	atmel_write16(dev, GCR, 0x0040);
1382 	return 0;
1383 }
1384 
1385 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1386 {
1387 	/* check that channel is OK, if so return zero,
1388 	   else return suitable default channel */
1389 	int i;
1390 
1391 	for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1392 		if (priv->reg_domain == channel_table[i].reg_domain) {
1393 			if (channel >= channel_table[i].min &&
1394 			    channel <= channel_table[i].max)
1395 				return 0;
1396 			else
1397 				return channel_table[i].min;
1398 		}
1399 	return 0;
1400 }
1401 
1402 #ifdef CONFIG_PROC_FS
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 #endif
1486 
1487 static const struct net_device_ops atmel_netdev_ops = {
1488 	.ndo_open 		= atmel_open,
1489 	.ndo_stop		= atmel_close,
1490 	.ndo_set_mac_address 	= atmel_set_mac_address,
1491 	.ndo_start_xmit 	= start_tx,
1492 	.ndo_do_ioctl 		= atmel_ioctl,
1493 	.ndo_validate_addr	= eth_validate_addr,
1494 };
1495 
1496 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1497 				   const AtmelFWType fw_type,
1498 				   struct device *sys_dev,
1499 				   int (*card_present)(void *), void *card)
1500 {
1501 	struct net_device *dev;
1502 	struct atmel_private *priv;
1503 	int rc;
1504 
1505 	/* Create the network device object. */
1506 	dev = alloc_etherdev(sizeof(*priv));
1507 	if (!dev)
1508 		return NULL;
1509 
1510 	if (dev_alloc_name(dev, dev->name) < 0) {
1511 		printk(KERN_ERR "atmel: Couldn't get name!\n");
1512 		goto err_out_free;
1513 	}
1514 
1515 	priv = netdev_priv(dev);
1516 	priv->dev = dev;
1517 	priv->sys_dev = sys_dev;
1518 	priv->present_callback = card_present;
1519 	priv->card = card;
1520 	priv->firmware = NULL;
1521 	priv->firmware_type = fw_type;
1522 	if (firmware) /* module parameter */
1523 		strlcpy(priv->firmware_id, firmware, sizeof(priv->firmware_id));
1524 	priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1525 	priv->station_state = STATION_STATE_DOWN;
1526 	priv->do_rx_crc = 0;
1527 	/* For PCMCIA cards, some chips need CRC, some don't
1528 	   so we have to probe. */
1529 	if (priv->bus_type == BUS_TYPE_PCCARD) {
1530 		priv->probe_crc = 1;
1531 		priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1532 	} else
1533 		priv->probe_crc = 0;
1534 	priv->last_qual = jiffies;
1535 	priv->last_beacon_timestamp = 0;
1536 	memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1537 	eth_zero_addr(priv->BSSID);
1538 	priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1539 	priv->station_was_associated = 0;
1540 
1541 	priv->last_survey = jiffies;
1542 	priv->preamble = LONG_PREAMBLE;
1543 	priv->operating_mode = IW_MODE_INFRA;
1544 	priv->connect_to_any_BSS = 0;
1545 	priv->config_reg_domain = 0;
1546 	priv->reg_domain = 0;
1547 	priv->tx_rate = 3;
1548 	priv->auto_tx_rate = 1;
1549 	priv->channel = 4;
1550 	priv->power_mode = 0;
1551 	priv->SSID[0] = '\0';
1552 	priv->SSID_size = 0;
1553 	priv->new_SSID_size = 0;
1554 	priv->frag_threshold = 2346;
1555 	priv->rts_threshold = 2347;
1556 	priv->short_retry = 7;
1557 	priv->long_retry = 4;
1558 
1559 	priv->wep_is_on = 0;
1560 	priv->default_key = 0;
1561 	priv->encryption_level = 0;
1562 	priv->exclude_unencrypted = 0;
1563 	priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1564 	priv->use_wpa = 0;
1565 	memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1566 	memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1567 
1568 	priv->default_beacon_period = priv->beacon_period = 100;
1569 	priv->listen_interval = 1;
1570 
1571 	timer_setup(&priv->management_timer, atmel_management_timer, 0);
1572 	spin_lock_init(&priv->irqlock);
1573 	spin_lock_init(&priv->timerlock);
1574 
1575 	dev->netdev_ops = &atmel_netdev_ops;
1576 	dev->wireless_handlers = &atmel_handler_def;
1577 	dev->irq = irq;
1578 	dev->base_addr = port;
1579 
1580 	/* MTU range: 68 - 2312 */
1581 	dev->min_mtu = 68;
1582 	dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
1583 
1584 	SET_NETDEV_DEV(dev, sys_dev);
1585 
1586 	if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1587 		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1588 		goto err_out_free;
1589 	}
1590 
1591 	if (!request_region(dev->base_addr, 32,
1592 			    priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
1593 		goto err_out_irq;
1594 	}
1595 
1596 	if (register_netdev(dev))
1597 		goto err_out_res;
1598 
1599 	if (!probe_atmel_card(dev)) {
1600 		unregister_netdev(dev);
1601 		goto err_out_res;
1602 	}
1603 
1604 	netif_carrier_off(dev);
1605 
1606 	if (!proc_create_single_data("driver/atmel", 0, NULL, atmel_proc_show,
1607 			priv))
1608 		printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1609 
1610 	printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1611 	       dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1612 
1613 	return dev;
1614 
1615 err_out_res:
1616 	release_region(dev->base_addr, 32);
1617 err_out_irq:
1618 	free_irq(dev->irq, dev);
1619 err_out_free:
1620 	free_netdev(dev);
1621 	return NULL;
1622 }
1623 
1624 EXPORT_SYMBOL(init_atmel_card);
1625 
1626 void stop_atmel_card(struct net_device *dev)
1627 {
1628 	struct atmel_private *priv = netdev_priv(dev);
1629 
1630 	/* put a brick on it... */
1631 	if (priv->bus_type == BUS_TYPE_PCCARD)
1632 		atmel_write16(dev, GCR, 0x0060);
1633 	atmel_write16(dev, GCR, 0x0040);
1634 
1635 	del_timer_sync(&priv->management_timer);
1636 	unregister_netdev(dev);
1637 	remove_proc_entry("driver/atmel", NULL);
1638 	free_irq(dev->irq, dev);
1639 	kfree(priv->firmware);
1640 	release_region(dev->base_addr, 32);
1641 	free_netdev(dev);
1642 }
1643 
1644 EXPORT_SYMBOL(stop_atmel_card);
1645 
1646 static int atmel_set_essid(struct net_device *dev,
1647 			   struct iw_request_info *info,
1648 			   struct iw_point *dwrq,
1649 			   char *extra)
1650 {
1651 	struct atmel_private *priv = netdev_priv(dev);
1652 
1653 	/* Check if we asked for `any' */
1654 	if (dwrq->flags == 0) {
1655 		priv->connect_to_any_BSS = 1;
1656 	} else {
1657 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1658 
1659 		priv->connect_to_any_BSS = 0;
1660 
1661 		/* Check the size of the string */
1662 		if (dwrq->length > MAX_SSID_LENGTH)
1663 			 return -E2BIG;
1664 		if (index != 0)
1665 			return -EINVAL;
1666 
1667 		memcpy(priv->new_SSID, extra, dwrq->length);
1668 		priv->new_SSID_size = dwrq->length;
1669 	}
1670 
1671 	return -EINPROGRESS;
1672 }
1673 
1674 static int atmel_get_essid(struct net_device *dev,
1675 			   struct iw_request_info *info,
1676 			   struct iw_point *dwrq,
1677 			   char *extra)
1678 {
1679 	struct atmel_private *priv = netdev_priv(dev);
1680 
1681 	/* Get the current SSID */
1682 	if (priv->new_SSID_size != 0) {
1683 		memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1684 		dwrq->length = priv->new_SSID_size;
1685 	} else {
1686 		memcpy(extra, priv->SSID, priv->SSID_size);
1687 		dwrq->length = priv->SSID_size;
1688 	}
1689 
1690 	dwrq->flags = !priv->connect_to_any_BSS; /* active */
1691 
1692 	return 0;
1693 }
1694 
1695 static int atmel_get_wap(struct net_device *dev,
1696 			 struct iw_request_info *info,
1697 			 struct sockaddr *awrq,
1698 			 char *extra)
1699 {
1700 	struct atmel_private *priv = netdev_priv(dev);
1701 	memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1702 	awrq->sa_family = ARPHRD_ETHER;
1703 
1704 	return 0;
1705 }
1706 
1707 static int atmel_set_encode(struct net_device *dev,
1708 			    struct iw_request_info *info,
1709 			    struct iw_point *dwrq,
1710 			    char *extra)
1711 {
1712 	struct atmel_private *priv = netdev_priv(dev);
1713 
1714 	/* Basic checking: do we have a key to set ?
1715 	 * Note : with the new API, it's impossible to get a NULL pointer.
1716 	 * Therefore, we need to check a key size == 0 instead.
1717 	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1718 	 * when no key is present (only change flags), but older versions
1719 	 * don't do it. - Jean II */
1720 	if (dwrq->length > 0) {
1721 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1722 		int current_index = priv->default_key;
1723 		/* Check the size of the key */
1724 		if (dwrq->length > 13) {
1725 			return -EINVAL;
1726 		}
1727 		/* Check the index (none -> use current) */
1728 		if (index < 0 || index >= 4)
1729 			index = current_index;
1730 		else
1731 			priv->default_key = index;
1732 		/* Set the length */
1733 		if (dwrq->length > 5)
1734 			priv->wep_key_len[index] = 13;
1735 		else
1736 			if (dwrq->length > 0)
1737 				priv->wep_key_len[index] = 5;
1738 			else
1739 				/* Disable the key */
1740 				priv->wep_key_len[index] = 0;
1741 		/* Check if the key is not marked as invalid */
1742 		if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1743 			/* Cleanup */
1744 			memset(priv->wep_keys[index], 0, 13);
1745 			/* Copy the key in the driver */
1746 			memcpy(priv->wep_keys[index], extra, dwrq->length);
1747 		}
1748 		/* WE specify that if a valid key is set, encryption
1749 		 * should be enabled (user may turn it off later)
1750 		 * This is also how "iwconfig ethX key on" works */
1751 		if (index == current_index &&
1752 		    priv->wep_key_len[index] > 0) {
1753 			priv->wep_is_on = 1;
1754 			priv->exclude_unencrypted = 1;
1755 			if (priv->wep_key_len[index] > 5) {
1756 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1757 				priv->encryption_level = 2;
1758 			} else {
1759 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1760 				priv->encryption_level = 1;
1761 			}
1762 		}
1763 	} else {
1764 		/* Do we want to just set the transmit key index ? */
1765 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1766 		if (index >= 0 && index < 4) {
1767 			priv->default_key = index;
1768 		} else
1769 			/* Don't complain if only change the mode */
1770 			if (!(dwrq->flags & IW_ENCODE_MODE))
1771 				return -EINVAL;
1772 	}
1773 	/* Read the flags */
1774 	if (dwrq->flags & IW_ENCODE_DISABLED) {
1775 		priv->wep_is_on = 0;
1776 		priv->encryption_level = 0;
1777 		priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1778 	} else {
1779 		priv->wep_is_on = 1;
1780 		if (priv->wep_key_len[priv->default_key] > 5) {
1781 			priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1782 			priv->encryption_level = 2;
1783 		} else {
1784 			priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1785 			priv->encryption_level = 1;
1786 		}
1787 	}
1788 	if (dwrq->flags & IW_ENCODE_RESTRICTED)
1789 		priv->exclude_unencrypted = 1;
1790 	if (dwrq->flags & IW_ENCODE_OPEN)
1791 		priv->exclude_unencrypted = 0;
1792 
1793 	return -EINPROGRESS;		/* Call commit handler */
1794 }
1795 
1796 static int atmel_get_encode(struct net_device *dev,
1797 			    struct iw_request_info *info,
1798 			    struct iw_point *dwrq,
1799 			    char *extra)
1800 {
1801 	struct atmel_private *priv = netdev_priv(dev);
1802 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1803 
1804 	if (!priv->wep_is_on)
1805 		dwrq->flags = IW_ENCODE_DISABLED;
1806 	else {
1807 		if (priv->exclude_unencrypted)
1808 			dwrq->flags = IW_ENCODE_RESTRICTED;
1809 		else
1810 			dwrq->flags = IW_ENCODE_OPEN;
1811 	}
1812 		/* Which key do we want ? -1 -> tx index */
1813 	if (index < 0 || index >= 4)
1814 		index = priv->default_key;
1815 	dwrq->flags |= index + 1;
1816 	/* Copy the key to the user buffer */
1817 	dwrq->length = priv->wep_key_len[index];
1818 	if (dwrq->length > 16) {
1819 		dwrq->length = 0;
1820 	} else {
1821 		memset(extra, 0, 16);
1822 		memcpy(extra, priv->wep_keys[index], dwrq->length);
1823 	}
1824 
1825 	return 0;
1826 }
1827 
1828 static int atmel_set_encodeext(struct net_device *dev,
1829 			    struct iw_request_info *info,
1830 			    union iwreq_data *wrqu,
1831 			    char *extra)
1832 {
1833 	struct atmel_private *priv = netdev_priv(dev);
1834 	struct iw_point *encoding = &wrqu->encoding;
1835 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1836 	int idx, key_len, alg = ext->alg, set_key = 1;
1837 
1838 	/* Determine and validate the key index */
1839 	idx = encoding->flags & IW_ENCODE_INDEX;
1840 	if (idx) {
1841 		if (idx < 1 || idx > 4)
1842 			return -EINVAL;
1843 		idx--;
1844 	} else
1845 		idx = priv->default_key;
1846 
1847 	if (encoding->flags & IW_ENCODE_DISABLED)
1848 	    alg = IW_ENCODE_ALG_NONE;
1849 
1850 	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1851 		priv->default_key = idx;
1852 		set_key = ext->key_len > 0 ? 1 : 0;
1853 	}
1854 
1855 	if (set_key) {
1856 		/* Set the requested key first */
1857 		switch (alg) {
1858 		case IW_ENCODE_ALG_NONE:
1859 			priv->wep_is_on = 0;
1860 			priv->encryption_level = 0;
1861 			priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1862 			break;
1863 		case IW_ENCODE_ALG_WEP:
1864 			if (ext->key_len > 5) {
1865 				priv->wep_key_len[idx] = 13;
1866 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1867 				priv->encryption_level = 2;
1868 			} else if (ext->key_len > 0) {
1869 				priv->wep_key_len[idx] = 5;
1870 				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1871 				priv->encryption_level = 1;
1872 			} else {
1873 				return -EINVAL;
1874 			}
1875 			priv->wep_is_on = 1;
1876 			memset(priv->wep_keys[idx], 0, 13);
1877 			key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1878 			memcpy(priv->wep_keys[idx], ext->key, key_len);
1879 			break;
1880 		default:
1881 			return -EINVAL;
1882 		}
1883 	}
1884 
1885 	return -EINPROGRESS;
1886 }
1887 
1888 static int atmel_get_encodeext(struct net_device *dev,
1889 			    struct iw_request_info *info,
1890 			    union iwreq_data *wrqu,
1891 			    char *extra)
1892 {
1893 	struct atmel_private *priv = netdev_priv(dev);
1894 	struct iw_point *encoding = &wrqu->encoding;
1895 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1896 	int idx, max_key_len;
1897 
1898 	max_key_len = encoding->length - sizeof(*ext);
1899 	if (max_key_len < 0)
1900 		return -EINVAL;
1901 
1902 	idx = encoding->flags & IW_ENCODE_INDEX;
1903 	if (idx) {
1904 		if (idx < 1 || idx > 4)
1905 			return -EINVAL;
1906 		idx--;
1907 	} else
1908 		idx = priv->default_key;
1909 
1910 	encoding->flags = idx + 1;
1911 	memset(ext, 0, sizeof(*ext));
1912 
1913 	if (!priv->wep_is_on) {
1914 		ext->alg = IW_ENCODE_ALG_NONE;
1915 		ext->key_len = 0;
1916 		encoding->flags |= IW_ENCODE_DISABLED;
1917 	} else {
1918 		if (priv->encryption_level > 0)
1919 			ext->alg = IW_ENCODE_ALG_WEP;
1920 		else
1921 			return -EINVAL;
1922 
1923 		ext->key_len = priv->wep_key_len[idx];
1924 		memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1925 		encoding->flags |= IW_ENCODE_ENABLED;
1926 	}
1927 
1928 	return 0;
1929 }
1930 
1931 static int atmel_set_auth(struct net_device *dev,
1932 			       struct iw_request_info *info,
1933 			       union iwreq_data *wrqu, char *extra)
1934 {
1935 	struct atmel_private *priv = netdev_priv(dev);
1936 	struct iw_param *param = &wrqu->param;
1937 
1938 	switch (param->flags & IW_AUTH_INDEX) {
1939 	case IW_AUTH_WPA_VERSION:
1940 	case IW_AUTH_CIPHER_PAIRWISE:
1941 	case IW_AUTH_CIPHER_GROUP:
1942 	case IW_AUTH_KEY_MGMT:
1943 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1944 	case IW_AUTH_PRIVACY_INVOKED:
1945 		/*
1946 		 * atmel does not use these parameters
1947 		 */
1948 		break;
1949 
1950 	case IW_AUTH_DROP_UNENCRYPTED:
1951 		priv->exclude_unencrypted = param->value ? 1 : 0;
1952 		break;
1953 
1954 	case IW_AUTH_80211_AUTH_ALG: {
1955 			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1956 				priv->exclude_unencrypted = 1;
1957 			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1958 				priv->exclude_unencrypted = 0;
1959 			} else
1960 				return -EINVAL;
1961 			break;
1962 		}
1963 
1964 	case IW_AUTH_WPA_ENABLED:
1965 		/* Silently accept disable of WPA */
1966 		if (param->value > 0)
1967 			return -EOPNOTSUPP;
1968 		break;
1969 
1970 	default:
1971 		return -EOPNOTSUPP;
1972 	}
1973 	return -EINPROGRESS;
1974 }
1975 
1976 static int atmel_get_auth(struct net_device *dev,
1977 			       struct iw_request_info *info,
1978 			       union iwreq_data *wrqu, char *extra)
1979 {
1980 	struct atmel_private *priv = netdev_priv(dev);
1981 	struct iw_param *param = &wrqu->param;
1982 
1983 	switch (param->flags & IW_AUTH_INDEX) {
1984 	case IW_AUTH_DROP_UNENCRYPTED:
1985 		param->value = priv->exclude_unencrypted;
1986 		break;
1987 
1988 	case IW_AUTH_80211_AUTH_ALG:
1989 		if (priv->exclude_unencrypted == 1)
1990 			param->value = IW_AUTH_ALG_SHARED_KEY;
1991 		else
1992 			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1993 		break;
1994 
1995 	case IW_AUTH_WPA_ENABLED:
1996 		param->value = 0;
1997 		break;
1998 
1999 	default:
2000 		return -EOPNOTSUPP;
2001 	}
2002 	return 0;
2003 }
2004 
2005 
2006 static int atmel_get_name(struct net_device *dev,
2007 			  struct iw_request_info *info,
2008 			  char *cwrq,
2009 			  char *extra)
2010 {
2011 	strcpy(cwrq, "IEEE 802.11-DS");
2012 	return 0;
2013 }
2014 
2015 static int atmel_set_rate(struct net_device *dev,
2016 			  struct iw_request_info *info,
2017 			  struct iw_param *vwrq,
2018 			  char *extra)
2019 {
2020 	struct atmel_private *priv = netdev_priv(dev);
2021 
2022 	if (vwrq->fixed == 0) {
2023 		priv->tx_rate = 3;
2024 		priv->auto_tx_rate = 1;
2025 	} else {
2026 		priv->auto_tx_rate = 0;
2027 
2028 		/* Which type of value ? */
2029 		if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2030 			/* Setting by rate index */
2031 			priv->tx_rate = vwrq->value;
2032 		} else {
2033 		/* Setting by frequency value */
2034 			switch (vwrq->value) {
2035 			case  1000000:
2036 				priv->tx_rate = 0;
2037 				break;
2038 			case  2000000:
2039 				priv->tx_rate = 1;
2040 				break;
2041 			case  5500000:
2042 				priv->tx_rate = 2;
2043 				break;
2044 			case 11000000:
2045 				priv->tx_rate = 3;
2046 				break;
2047 			default:
2048 				return -EINVAL;
2049 			}
2050 		}
2051 	}
2052 
2053 	return -EINPROGRESS;
2054 }
2055 
2056 static int atmel_set_mode(struct net_device *dev,
2057 			  struct iw_request_info *info,
2058 			  __u32 *uwrq,
2059 			  char *extra)
2060 {
2061 	struct atmel_private *priv = netdev_priv(dev);
2062 
2063 	if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2064 		return -EINVAL;
2065 
2066 	priv->operating_mode = *uwrq;
2067 	return -EINPROGRESS;
2068 }
2069 
2070 static int atmel_get_mode(struct net_device *dev,
2071 			  struct iw_request_info *info,
2072 			  __u32 *uwrq,
2073 			  char *extra)
2074 {
2075 	struct atmel_private *priv = netdev_priv(dev);
2076 
2077 	*uwrq = priv->operating_mode;
2078 	return 0;
2079 }
2080 
2081 static int atmel_get_rate(struct net_device *dev,
2082 			 struct iw_request_info *info,
2083 			 struct iw_param *vwrq,
2084 			 char *extra)
2085 {
2086 	struct atmel_private *priv = netdev_priv(dev);
2087 
2088 	if (priv->auto_tx_rate) {
2089 		vwrq->fixed = 0;
2090 		vwrq->value = 11000000;
2091 	} else {
2092 		vwrq->fixed = 1;
2093 		switch (priv->tx_rate) {
2094 		case 0:
2095 			vwrq->value =  1000000;
2096 			break;
2097 		case 1:
2098 			vwrq->value =  2000000;
2099 			break;
2100 		case 2:
2101 			vwrq->value =  5500000;
2102 			break;
2103 		case 3:
2104 			vwrq->value = 11000000;
2105 			break;
2106 		}
2107 	}
2108 	return 0;
2109 }
2110 
2111 static int atmel_set_power(struct net_device *dev,
2112 			   struct iw_request_info *info,
2113 			   struct iw_param *vwrq,
2114 			   char *extra)
2115 {
2116 	struct atmel_private *priv = netdev_priv(dev);
2117 	priv->power_mode = vwrq->disabled ? 0 : 1;
2118 	return -EINPROGRESS;
2119 }
2120 
2121 static int atmel_get_power(struct net_device *dev,
2122 			   struct iw_request_info *info,
2123 			   struct iw_param *vwrq,
2124 			   char *extra)
2125 {
2126 	struct atmel_private *priv = netdev_priv(dev);
2127 	vwrq->disabled = priv->power_mode ? 0 : 1;
2128 	vwrq->flags = IW_POWER_ON;
2129 	return 0;
2130 }
2131 
2132 static int atmel_set_retry(struct net_device *dev,
2133 			   struct iw_request_info *info,
2134 			   struct iw_param *vwrq,
2135 			   char *extra)
2136 {
2137 	struct atmel_private *priv = netdev_priv(dev);
2138 
2139 	if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2140 		if (vwrq->flags & IW_RETRY_LONG)
2141 			priv->long_retry = vwrq->value;
2142 		else if (vwrq->flags & IW_RETRY_SHORT)
2143 			priv->short_retry = vwrq->value;
2144 		else {
2145 			/* No modifier : set both */
2146 			priv->long_retry = vwrq->value;
2147 			priv->short_retry = vwrq->value;
2148 		}
2149 		return -EINPROGRESS;
2150 	}
2151 
2152 	return -EINVAL;
2153 }
2154 
2155 static int atmel_get_retry(struct net_device *dev,
2156 			   struct iw_request_info *info,
2157 			   struct iw_param *vwrq,
2158 			   char *extra)
2159 {
2160 	struct atmel_private *priv = netdev_priv(dev);
2161 
2162 	vwrq->disabled = 0;      /* Can't be disabled */
2163 
2164 	/* Note : by default, display the short retry number */
2165 	if (vwrq->flags & IW_RETRY_LONG) {
2166 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2167 		vwrq->value = priv->long_retry;
2168 	} else {
2169 		vwrq->flags = IW_RETRY_LIMIT;
2170 		vwrq->value = priv->short_retry;
2171 		if (priv->long_retry != priv->short_retry)
2172 			vwrq->flags |= IW_RETRY_SHORT;
2173 	}
2174 
2175 	return 0;
2176 }
2177 
2178 static int atmel_set_rts(struct net_device *dev,
2179 			 struct iw_request_info *info,
2180 			 struct iw_param *vwrq,
2181 			 char *extra)
2182 {
2183 	struct atmel_private *priv = netdev_priv(dev);
2184 	int rthr = vwrq->value;
2185 
2186 	if (vwrq->disabled)
2187 		rthr = 2347;
2188 	if ((rthr < 0) || (rthr > 2347)) {
2189 		return -EINVAL;
2190 	}
2191 	priv->rts_threshold = rthr;
2192 
2193 	return -EINPROGRESS;		/* Call commit handler */
2194 }
2195 
2196 static int atmel_get_rts(struct net_device *dev,
2197 			 struct iw_request_info *info,
2198 			 struct iw_param *vwrq,
2199 			 char *extra)
2200 {
2201 	struct atmel_private *priv = netdev_priv(dev);
2202 
2203 	vwrq->value = priv->rts_threshold;
2204 	vwrq->disabled = (vwrq->value >= 2347);
2205 	vwrq->fixed = 1;
2206 
2207 	return 0;
2208 }
2209 
2210 static int atmel_set_frag(struct net_device *dev,
2211 			  struct iw_request_info *info,
2212 			  struct iw_param *vwrq,
2213 			  char *extra)
2214 {
2215 	struct atmel_private *priv = netdev_priv(dev);
2216 	int fthr = vwrq->value;
2217 
2218 	if (vwrq->disabled)
2219 		fthr = 2346;
2220 	if ((fthr < 256) || (fthr > 2346)) {
2221 		return -EINVAL;
2222 	}
2223 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
2224 	priv->frag_threshold = fthr;
2225 
2226 	return -EINPROGRESS;		/* Call commit handler */
2227 }
2228 
2229 static int atmel_get_frag(struct net_device *dev,
2230 			  struct iw_request_info *info,
2231 			  struct iw_param *vwrq,
2232 			  char *extra)
2233 {
2234 	struct atmel_private *priv = netdev_priv(dev);
2235 
2236 	vwrq->value = priv->frag_threshold;
2237 	vwrq->disabled = (vwrq->value >= 2346);
2238 	vwrq->fixed = 1;
2239 
2240 	return 0;
2241 }
2242 
2243 static int atmel_set_freq(struct net_device *dev,
2244 			  struct iw_request_info *info,
2245 			  struct iw_freq *fwrq,
2246 			  char *extra)
2247 {
2248 	struct atmel_private *priv = netdev_priv(dev);
2249 	int rc = -EINPROGRESS;		/* Call commit handler */
2250 
2251 	/* If setting by frequency, convert to a channel */
2252 	if (fwrq->e == 1) {
2253 		int f = fwrq->m / 100000;
2254 
2255 		/* Hack to fall through... */
2256 		fwrq->e = 0;
2257 		fwrq->m = ieee80211_frequency_to_channel(f);
2258 	}
2259 	/* Setting by channel number */
2260 	if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2261 		rc = -EOPNOTSUPP;
2262 	else {
2263 		int channel = fwrq->m;
2264 		if (atmel_validate_channel(priv, channel) == 0) {
2265 			priv->channel = channel;
2266 		} else {
2267 			rc = -EINVAL;
2268 		}
2269 	}
2270 	return rc;
2271 }
2272 
2273 static int atmel_get_freq(struct net_device *dev,
2274 			  struct iw_request_info *info,
2275 			  struct iw_freq *fwrq,
2276 			  char *extra)
2277 {
2278 	struct atmel_private *priv = netdev_priv(dev);
2279 
2280 	fwrq->m = priv->channel;
2281 	fwrq->e = 0;
2282 	return 0;
2283 }
2284 
2285 static int atmel_set_scan(struct net_device *dev,
2286 			  struct iw_request_info *info,
2287 			  struct iw_point *dwrq,
2288 			  char *extra)
2289 {
2290 	struct atmel_private *priv = netdev_priv(dev);
2291 	unsigned long flags;
2292 
2293 	/* Note : you may have realised that, as this is a SET operation,
2294 	 * this is privileged and therefore a normal user can't
2295 	 * perform scanning.
2296 	 * This is not an error, while the device perform scanning,
2297 	 * traffic doesn't flow, so it's a perfect DoS...
2298 	 * Jean II */
2299 
2300 	if (priv->station_state == STATION_STATE_DOWN)
2301 		return -EAGAIN;
2302 
2303 	/* Timeout old surveys. */
2304 	if (time_after(jiffies, priv->last_survey + 20 * HZ))
2305 		priv->site_survey_state = SITE_SURVEY_IDLE;
2306 	priv->last_survey = jiffies;
2307 
2308 	/* Initiate a scan command */
2309 	if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2310 		return -EBUSY;
2311 
2312 	del_timer_sync(&priv->management_timer);
2313 	spin_lock_irqsave(&priv->irqlock, flags);
2314 
2315 	priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2316 	priv->fast_scan = 0;
2317 	atmel_scan(priv, 0);
2318 	spin_unlock_irqrestore(&priv->irqlock, flags);
2319 
2320 	return 0;
2321 }
2322 
2323 static int atmel_get_scan(struct net_device *dev,
2324 			  struct iw_request_info *info,
2325 			  struct iw_point *dwrq,
2326 			  char *extra)
2327 {
2328 	struct atmel_private *priv = netdev_priv(dev);
2329 	int i;
2330 	char *current_ev = extra;
2331 	struct iw_event	iwe;
2332 
2333 	if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2334 		return -EAGAIN;
2335 
2336 	for (i = 0; i < priv->BSS_list_entries; i++) {
2337 		iwe.cmd = SIOCGIWAP;
2338 		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2339 		memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2340 		current_ev = iwe_stream_add_event(info, current_ev,
2341 						  extra + IW_SCAN_MAX_DATA,
2342 						  &iwe, IW_EV_ADDR_LEN);
2343 
2344 		iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
2345 		if (iwe.u.data.length > 32)
2346 			iwe.u.data.length = 32;
2347 		iwe.cmd = SIOCGIWESSID;
2348 		iwe.u.data.flags = 1;
2349 		current_ev = iwe_stream_add_point(info, current_ev,
2350 						  extra + IW_SCAN_MAX_DATA,
2351 						  &iwe, priv->BSSinfo[i].SSID);
2352 
2353 		iwe.cmd = SIOCGIWMODE;
2354 		iwe.u.mode = priv->BSSinfo[i].BSStype;
2355 		current_ev = iwe_stream_add_event(info, current_ev,
2356 						  extra + IW_SCAN_MAX_DATA,
2357 						  &iwe, IW_EV_UINT_LEN);
2358 
2359 		iwe.cmd = SIOCGIWFREQ;
2360 		iwe.u.freq.m = priv->BSSinfo[i].channel;
2361 		iwe.u.freq.e = 0;
2362 		current_ev = iwe_stream_add_event(info, current_ev,
2363 						  extra + IW_SCAN_MAX_DATA,
2364 						  &iwe, IW_EV_FREQ_LEN);
2365 
2366 		/* Add quality statistics */
2367 		iwe.cmd = IWEVQUAL;
2368 		iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2369 		iwe.u.qual.qual  = iwe.u.qual.level;
2370 		/* iwe.u.qual.noise  = SOMETHING */
2371 		current_ev = iwe_stream_add_event(info, current_ev,
2372 						  extra + IW_SCAN_MAX_DATA,
2373 						  &iwe, IW_EV_QUAL_LEN);
2374 
2375 
2376 		iwe.cmd = SIOCGIWENCODE;
2377 		if (priv->BSSinfo[i].UsingWEP)
2378 			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2379 		else
2380 			iwe.u.data.flags = IW_ENCODE_DISABLED;
2381 		iwe.u.data.length = 0;
2382 		current_ev = iwe_stream_add_point(info, current_ev,
2383 						  extra + IW_SCAN_MAX_DATA,
2384 						  &iwe, NULL);
2385 	}
2386 
2387 	/* Length of data */
2388 	dwrq->length = (current_ev - extra);
2389 	dwrq->flags = 0;
2390 
2391 	return 0;
2392 }
2393 
2394 static int atmel_get_range(struct net_device *dev,
2395 			   struct iw_request_info *info,
2396 			   struct iw_point *dwrq,
2397 			   char *extra)
2398 {
2399 	struct atmel_private *priv = netdev_priv(dev);
2400 	struct iw_range *range = (struct iw_range *) extra;
2401 	int k, i, j;
2402 
2403 	dwrq->length = sizeof(struct iw_range);
2404 	memset(range, 0, sizeof(struct iw_range));
2405 	range->min_nwid = 0x0000;
2406 	range->max_nwid = 0x0000;
2407 	range->num_channels = 0;
2408 	for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2409 		if (priv->reg_domain == channel_table[j].reg_domain) {
2410 			range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2411 			break;
2412 		}
2413 	if (range->num_channels != 0) {
2414 		for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2415 			range->freq[k].i = i; /* List index */
2416 
2417 			/* Values in MHz -> * 10^5 * 10 */
2418 			range->freq[k].m = 100000 *
2419 			 ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2420 			range->freq[k++].e = 1;
2421 		}
2422 		range->num_frequency = k;
2423 	}
2424 
2425 	range->max_qual.qual = 100;
2426 	range->max_qual.level = 100;
2427 	range->max_qual.noise = 0;
2428 	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2429 
2430 	range->avg_qual.qual = 50;
2431 	range->avg_qual.level = 50;
2432 	range->avg_qual.noise = 0;
2433 	range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2434 
2435 	range->sensitivity = 0;
2436 
2437 	range->bitrate[0] =  1000000;
2438 	range->bitrate[1] =  2000000;
2439 	range->bitrate[2] =  5500000;
2440 	range->bitrate[3] = 11000000;
2441 	range->num_bitrates = 4;
2442 
2443 	range->min_rts = 0;
2444 	range->max_rts = 2347;
2445 	range->min_frag = 256;
2446 	range->max_frag = 2346;
2447 
2448 	range->encoding_size[0] = 5;
2449 	range->encoding_size[1] = 13;
2450 	range->num_encoding_sizes = 2;
2451 	range->max_encoding_tokens = 4;
2452 
2453 	range->pmp_flags = IW_POWER_ON;
2454 	range->pmt_flags = IW_POWER_ON;
2455 	range->pm_capa = 0;
2456 
2457 	range->we_version_source = WIRELESS_EXT;
2458 	range->we_version_compiled = WIRELESS_EXT;
2459 	range->retry_capa = IW_RETRY_LIMIT ;
2460 	range->retry_flags = IW_RETRY_LIMIT;
2461 	range->r_time_flags = 0;
2462 	range->min_retry = 1;
2463 	range->max_retry = 65535;
2464 
2465 	return 0;
2466 }
2467 
2468 static int atmel_set_wap(struct net_device *dev,
2469 			 struct iw_request_info *info,
2470 			 struct sockaddr *awrq,
2471 			 char *extra)
2472 {
2473 	struct atmel_private *priv = netdev_priv(dev);
2474 	int i;
2475 	static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2476 	static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2477 	unsigned long flags;
2478 
2479 	if (awrq->sa_family != ARPHRD_ETHER)
2480 		return -EINVAL;
2481 
2482 	if (!memcmp(any, awrq->sa_data, 6) ||
2483 	    !memcmp(off, awrq->sa_data, 6)) {
2484 		del_timer_sync(&priv->management_timer);
2485 		spin_lock_irqsave(&priv->irqlock, flags);
2486 		atmel_scan(priv, 1);
2487 		spin_unlock_irqrestore(&priv->irqlock, flags);
2488 		return 0;
2489 	}
2490 
2491 	for (i = 0; i < priv->BSS_list_entries; i++) {
2492 		if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2493 			if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2494 				return -EINVAL;
2495 			} else if  (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2496 				return -EINVAL;
2497 			} else {
2498 				del_timer_sync(&priv->management_timer);
2499 				spin_lock_irqsave(&priv->irqlock, flags);
2500 				atmel_join_bss(priv, i);
2501 				spin_unlock_irqrestore(&priv->irqlock, flags);
2502 				return 0;
2503 			}
2504 		}
2505 	}
2506 
2507 	return -EINVAL;
2508 }
2509 
2510 static int atmel_config_commit(struct net_device *dev,
2511 			       struct iw_request_info *info,	/* NULL */
2512 			       void *zwrq,			/* NULL */
2513 			       char *extra)			/* NULL */
2514 {
2515 	return atmel_open(dev);
2516 }
2517 
2518 static const iw_handler atmel_handler[] =
2519 {
2520 	(iw_handler) atmel_config_commit,	/* SIOCSIWCOMMIT */
2521 	(iw_handler) atmel_get_name,		/* SIOCGIWNAME */
2522 	(iw_handler) NULL,			/* SIOCSIWNWID */
2523 	(iw_handler) NULL,			/* SIOCGIWNWID */
2524 	(iw_handler) atmel_set_freq,		/* SIOCSIWFREQ */
2525 	(iw_handler) atmel_get_freq,		/* SIOCGIWFREQ */
2526 	(iw_handler) atmel_set_mode,		/* SIOCSIWMODE */
2527 	(iw_handler) atmel_get_mode,		/* SIOCGIWMODE */
2528 	(iw_handler) NULL,			/* SIOCSIWSENS */
2529 	(iw_handler) NULL,			/* SIOCGIWSENS */
2530 	(iw_handler) NULL,			/* SIOCSIWRANGE */
2531 	(iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
2532 	(iw_handler) NULL,			/* SIOCSIWPRIV */
2533 	(iw_handler) NULL,			/* SIOCGIWPRIV */
2534 	(iw_handler) NULL,			/* SIOCSIWSTATS */
2535 	(iw_handler) NULL,			/* SIOCGIWSTATS */
2536 	(iw_handler) NULL,			/* SIOCSIWSPY */
2537 	(iw_handler) NULL,			/* SIOCGIWSPY */
2538 	(iw_handler) NULL,			/* -- hole -- */
2539 	(iw_handler) NULL,			/* -- hole -- */
2540 	(iw_handler) atmel_set_wap,		/* SIOCSIWAP */
2541 	(iw_handler) atmel_get_wap,		/* SIOCGIWAP */
2542 	(iw_handler) NULL,			/* -- hole -- */
2543 	(iw_handler) NULL,			/* SIOCGIWAPLIST */
2544 	(iw_handler) atmel_set_scan,		/* SIOCSIWSCAN */
2545 	(iw_handler) atmel_get_scan,		/* SIOCGIWSCAN */
2546 	(iw_handler) atmel_set_essid,		/* SIOCSIWESSID */
2547 	(iw_handler) atmel_get_essid,		/* SIOCGIWESSID */
2548 	(iw_handler) NULL,			/* SIOCSIWNICKN */
2549 	(iw_handler) NULL,			/* SIOCGIWNICKN */
2550 	(iw_handler) NULL,			/* -- hole -- */
2551 	(iw_handler) NULL,			/* -- hole -- */
2552 	(iw_handler) atmel_set_rate,		/* SIOCSIWRATE */
2553 	(iw_handler) atmel_get_rate,		/* SIOCGIWRATE */
2554 	(iw_handler) atmel_set_rts,		/* SIOCSIWRTS */
2555 	(iw_handler) atmel_get_rts,		/* SIOCGIWRTS */
2556 	(iw_handler) atmel_set_frag,		/* SIOCSIWFRAG */
2557 	(iw_handler) atmel_get_frag,		/* SIOCGIWFRAG */
2558 	(iw_handler) NULL,			/* SIOCSIWTXPOW */
2559 	(iw_handler) NULL,			/* SIOCGIWTXPOW */
2560 	(iw_handler) atmel_set_retry,		/* SIOCSIWRETRY */
2561 	(iw_handler) atmel_get_retry,		/* SIOCGIWRETRY */
2562 	(iw_handler) atmel_set_encode,		/* SIOCSIWENCODE */
2563 	(iw_handler) atmel_get_encode,		/* SIOCGIWENCODE */
2564 	(iw_handler) atmel_set_power,		/* SIOCSIWPOWER */
2565 	(iw_handler) atmel_get_power,		/* SIOCGIWPOWER */
2566 	(iw_handler) NULL,			/* -- hole -- */
2567 	(iw_handler) NULL,			/* -- hole -- */
2568 	(iw_handler) NULL,			/* SIOCSIWGENIE */
2569 	(iw_handler) NULL,			/* SIOCGIWGENIE */
2570 	(iw_handler) atmel_set_auth,		/* SIOCSIWAUTH */
2571 	(iw_handler) atmel_get_auth,		/* SIOCGIWAUTH */
2572 	(iw_handler) atmel_set_encodeext,	/* SIOCSIWENCODEEXT */
2573 	(iw_handler) atmel_get_encodeext,	/* SIOCGIWENCODEEXT */
2574 	(iw_handler) NULL,			/* SIOCSIWPMKSA */
2575 };
2576 
2577 static const iw_handler atmel_private_handler[] =
2578 {
2579 	NULL,				/* SIOCIWFIRSTPRIV */
2580 };
2581 
2582 struct atmel_priv_ioctl {
2583 	char id[32];
2584 	unsigned char __user *data;
2585 	unsigned short len;
2586 };
2587 
2588 #define ATMELFWL	SIOCIWFIRSTPRIV
2589 #define ATMELIDIFC	ATMELFWL + 1
2590 #define ATMELRD		ATMELFWL + 2
2591 #define ATMELMAGIC 0x51807
2592 #define REGDOMAINSZ 20
2593 
2594 static const struct iw_priv_args atmel_private_args[] = {
2595 	{
2596 		.cmd = ATMELFWL,
2597 		.set_args = IW_PRIV_TYPE_BYTE
2598 				| IW_PRIV_SIZE_FIXED
2599 				| sizeof(struct atmel_priv_ioctl),
2600 		.get_args = IW_PRIV_TYPE_NONE,
2601 		.name = "atmelfwl"
2602 	}, {
2603 		.cmd = ATMELIDIFC,
2604 		.set_args = IW_PRIV_TYPE_NONE,
2605 		.get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2606 		.name = "atmelidifc"
2607 	}, {
2608 		.cmd = ATMELRD,
2609 		.set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2610 		.get_args = IW_PRIV_TYPE_NONE,
2611 		.name = "regdomain"
2612 	},
2613 };
2614 
2615 static const struct iw_handler_def atmel_handler_def = {
2616 	.num_standard	= ARRAY_SIZE(atmel_handler),
2617 	.num_private	= ARRAY_SIZE(atmel_private_handler),
2618 	.num_private_args = ARRAY_SIZE(atmel_private_args),
2619 	.standard	= (iw_handler *) atmel_handler,
2620 	.private	= (iw_handler *) atmel_private_handler,
2621 	.private_args	= (struct iw_priv_args *) atmel_private_args,
2622 	.get_wireless_stats = atmel_get_wireless_stats
2623 };
2624 
2625 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2626 {
2627 	int i, rc = 0;
2628 	struct atmel_private *priv = netdev_priv(dev);
2629 	struct atmel_priv_ioctl com;
2630 	struct iwreq *wrq = (struct iwreq *) rq;
2631 	unsigned char *new_firmware;
2632 	char domain[REGDOMAINSZ + 1];
2633 
2634 	switch (cmd) {
2635 	case ATMELIDIFC:
2636 		wrq->u.param.value = ATMELMAGIC;
2637 		break;
2638 
2639 	case ATMELFWL:
2640 		if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2641 			rc = -EFAULT;
2642 			break;
2643 		}
2644 
2645 		if (!capable(CAP_NET_ADMIN)) {
2646 			rc = -EPERM;
2647 			break;
2648 		}
2649 
2650 		new_firmware = memdup_user(com.data, com.len);
2651 		if (IS_ERR(new_firmware)) {
2652 			rc = PTR_ERR(new_firmware);
2653 			break;
2654 		}
2655 
2656 		kfree(priv->firmware);
2657 
2658 		priv->firmware = new_firmware;
2659 		priv->firmware_length = com.len;
2660 		strncpy(priv->firmware_id, com.id, 31);
2661 		priv->firmware_id[31] = '\0';
2662 		break;
2663 
2664 	case ATMELRD:
2665 		if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2666 			rc = -EFAULT;
2667 			break;
2668 		}
2669 
2670 		if (!capable(CAP_NET_ADMIN)) {
2671 			rc = -EPERM;
2672 			break;
2673 		}
2674 
2675 		domain[REGDOMAINSZ] = 0;
2676 		rc = -EINVAL;
2677 		for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2678 			if (!strcasecmp(channel_table[i].name, domain)) {
2679 				priv->config_reg_domain = channel_table[i].reg_domain;
2680 				rc = 0;
2681 			}
2682 		}
2683 
2684 		if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2685 			rc = atmel_open(dev);
2686 		break;
2687 
2688 	default:
2689 		rc = -EOPNOTSUPP;
2690 	}
2691 
2692 	return rc;
2693 }
2694 
2695 struct auth_body {
2696 	__le16 alg;
2697 	__le16 trans_seq;
2698 	__le16 status;
2699 	u8 el_id;
2700 	u8 chall_text_len;
2701 	u8 chall_text[253];
2702 };
2703 
2704 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2705 {
2706 	int old_state = priv->station_state;
2707 
2708 	if (new_state == old_state)
2709 		return;
2710 
2711 	priv->station_state = new_state;
2712 
2713 	if (new_state == STATION_STATE_READY) {
2714 		netif_start_queue(priv->dev);
2715 		netif_carrier_on(priv->dev);
2716 	}
2717 
2718 	if (old_state == STATION_STATE_READY) {
2719 		netif_carrier_off(priv->dev);
2720 		if (netif_running(priv->dev))
2721 			netif_stop_queue(priv->dev);
2722 		priv->last_beacon_timestamp = 0;
2723 	}
2724 }
2725 
2726 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2727 {
2728 	struct {
2729 		u8 BSSID[ETH_ALEN];
2730 		u8 SSID[MAX_SSID_LENGTH];
2731 		u8 scan_type;
2732 		u8 channel;
2733 		__le16 BSS_type;
2734 		__le16 min_channel_time;
2735 		__le16 max_channel_time;
2736 		u8 options;
2737 		u8 SSID_size;
2738 	} cmd;
2739 
2740 	eth_broadcast_addr(cmd.BSSID);
2741 
2742 	if (priv->fast_scan) {
2743 		cmd.SSID_size = priv->SSID_size;
2744 		memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2745 		cmd.min_channel_time = cpu_to_le16(10);
2746 		cmd.max_channel_time = cpu_to_le16(50);
2747 	} else {
2748 		priv->BSS_list_entries = 0;
2749 		cmd.SSID_size = 0;
2750 		cmd.min_channel_time = cpu_to_le16(10);
2751 		cmd.max_channel_time = cpu_to_le16(120);
2752 	}
2753 
2754 	cmd.options = 0;
2755 
2756 	if (!specific_ssid)
2757 		cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2758 
2759 	cmd.channel = (priv->channel & 0x7f);
2760 	cmd.scan_type = SCAN_TYPE_ACTIVE;
2761 	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2762 		BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2763 
2764 	atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2765 
2766 	/* This must come after all hardware access to avoid being messed up
2767 	   by stuff happening in interrupt context after we leave STATE_DOWN */
2768 	atmel_enter_state(priv, STATION_STATE_SCANNING);
2769 }
2770 
2771 static void join(struct atmel_private *priv, int type)
2772 {
2773 	struct {
2774 		u8 BSSID[6];
2775 		u8 SSID[MAX_SSID_LENGTH];
2776 		u8 BSS_type; /* this is a short in a scan command - weird */
2777 		u8 channel;
2778 		__le16 timeout;
2779 		u8 SSID_size;
2780 		u8 reserved;
2781 	} cmd;
2782 
2783 	cmd.SSID_size = priv->SSID_size;
2784 	memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2785 	memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2786 	cmd.channel = (priv->channel & 0x7f);
2787 	cmd.BSS_type = type;
2788 	cmd.timeout = cpu_to_le16(2000);
2789 
2790 	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2791 }
2792 
2793 static void start(struct atmel_private *priv, int type)
2794 {
2795 	struct {
2796 		u8 BSSID[6];
2797 		u8 SSID[MAX_SSID_LENGTH];
2798 		u8 BSS_type;
2799 		u8 channel;
2800 		u8 SSID_size;
2801 		u8 reserved[3];
2802 	} cmd;
2803 
2804 	cmd.SSID_size = priv->SSID_size;
2805 	memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2806 	memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2807 	cmd.BSS_type = type;
2808 	cmd.channel = (priv->channel & 0x7f);
2809 
2810 	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2811 }
2812 
2813 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2814 				u8 channel)
2815 {
2816 	int rejoin = 0;
2817 	int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2818 		SHORT_PREAMBLE : LONG_PREAMBLE;
2819 
2820 	if (priv->preamble != new) {
2821 		priv->preamble = new;
2822 		rejoin = 1;
2823 		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2824 	}
2825 
2826 	if (priv->channel != channel) {
2827 		priv->channel = channel;
2828 		rejoin = 1;
2829 		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2830 	}
2831 
2832 	if (rejoin) {
2833 		priv->station_is_associated = 0;
2834 		atmel_enter_state(priv, STATION_STATE_JOINNING);
2835 
2836 		if (priv->operating_mode == IW_MODE_INFRA)
2837 			join(priv, BSS_TYPE_INFRASTRUCTURE);
2838 		else
2839 			join(priv, BSS_TYPE_AD_HOC);
2840 	}
2841 }
2842 
2843 static void send_authentication_request(struct atmel_private *priv, u16 system,
2844 					u8 *challenge, int challenge_len)
2845 {
2846 	struct ieee80211_hdr header;
2847 	struct auth_body auth;
2848 
2849 	header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2850 	header.duration_id = cpu_to_le16(0x8000);
2851 	header.seq_ctrl = 0;
2852 	memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2853 	memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2854 	memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2855 
2856 	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2857 		/* no WEP for authentication frames with TrSeqNo 1 */
2858 		header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2859 
2860 	auth.alg = cpu_to_le16(system);
2861 
2862 	auth.status = 0;
2863 	auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2864 	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2865 	priv->CurrentAuthentTransactionSeqNum += 2;
2866 
2867 	if (challenge_len != 0)	{
2868 		auth.el_id = 16; /* challenge_text */
2869 		auth.chall_text_len = challenge_len;
2870 		memcpy(auth.chall_text, challenge, challenge_len);
2871 		atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2872 	} else {
2873 		atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2874 	}
2875 }
2876 
2877 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2878 {
2879 	u8 *ssid_el_p;
2880 	int bodysize;
2881 	struct ieee80211_hdr header;
2882 	struct ass_req_format {
2883 		__le16 capability;
2884 		__le16 listen_interval;
2885 		u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2886 		u8 ssid_el_id;
2887 		u8 ssid_len;
2888 		u8 ssid[MAX_SSID_LENGTH];
2889 		u8 sup_rates_el_id;
2890 		u8 sup_rates_len;
2891 		u8 rates[4];
2892 	} body;
2893 
2894 	header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2895 		(is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2896 	header.duration_id = cpu_to_le16(0x8000);
2897 	header.seq_ctrl = 0;
2898 
2899 	memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2900 	memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2901 	memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2902 
2903 	body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2904 	if (priv->wep_is_on)
2905 		body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2906 	if (priv->preamble == SHORT_PREAMBLE)
2907 		body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2908 
2909 	body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2910 
2911 	/* current AP address - only in reassoc frame */
2912 	if (is_reassoc) {
2913 		memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2914 		ssid_el_p = &body.ssid_el_id;
2915 		bodysize = 18 + priv->SSID_size;
2916 	} else {
2917 		ssid_el_p = &body.ap[0];
2918 		bodysize = 12 + priv->SSID_size;
2919 	}
2920 
2921 	ssid_el_p[0] = WLAN_EID_SSID;
2922 	ssid_el_p[1] = priv->SSID_size;
2923 	memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2924 	ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2925 	ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2926 	memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2927 
2928 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2929 }
2930 
2931 static int is_frame_from_current_bss(struct atmel_private *priv,
2932 				     struct ieee80211_hdr *header)
2933 {
2934 	if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2935 		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2936 	else
2937 		return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2938 }
2939 
2940 static int retrieve_bss(struct atmel_private *priv)
2941 {
2942 	int i;
2943 	int max_rssi = -128;
2944 	int max_index = -1;
2945 
2946 	if (priv->BSS_list_entries == 0)
2947 		return -1;
2948 
2949 	if (priv->connect_to_any_BSS) {
2950 		/* Select a BSS with the max-RSSI but of the same type and of
2951 		   the same WEP mode and that it is not marked as 'bad' (i.e.
2952 		   we had previously failed to connect to this BSS with the
2953 		   settings that we currently use) */
2954 		priv->current_BSS = 0;
2955 		for (i = 0; i < priv->BSS_list_entries; i++) {
2956 			if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2957 			    ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2958 			     (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2959 			    !(priv->BSSinfo[i].channel & 0x80)) {
2960 				max_rssi = priv->BSSinfo[i].RSSI;
2961 				priv->current_BSS = max_index = i;
2962 			}
2963 		}
2964 		return max_index;
2965 	}
2966 
2967 	for (i = 0; i < priv->BSS_list_entries; i++) {
2968 		if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2969 		    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2970 		    priv->operating_mode == priv->BSSinfo[i].BSStype &&
2971 		    atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2972 			if (priv->BSSinfo[i].RSSI >= max_rssi) {
2973 				max_rssi = priv->BSSinfo[i].RSSI;
2974 				max_index = i;
2975 			}
2976 		}
2977 	}
2978 	return max_index;
2979 }
2980 
2981 static void store_bss_info(struct atmel_private *priv,
2982 			   struct ieee80211_hdr *header, u16 capability,
2983 			   u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2984 			   u8 *ssid, int is_beacon)
2985 {
2986 	u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2987 	int i, index;
2988 
2989 	for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2990 		if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
2991 			index = i;
2992 
2993 	/* If we process a probe and an entry from this BSS exists
2994 	   we will update the BSS entry with the info from this BSS.
2995 	   If we process a beacon we will only update RSSI */
2996 
2997 	if (index == -1) {
2998 		if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2999 			return;
3000 		index = priv->BSS_list_entries++;
3001 		memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
3002 		priv->BSSinfo[index].RSSI = rssi;
3003 	} else {
3004 		if (rssi > priv->BSSinfo[index].RSSI)
3005 			priv->BSSinfo[index].RSSI = rssi;
3006 		if (is_beacon)
3007 			return;
3008 	}
3009 
3010 	priv->BSSinfo[index].channel = channel;
3011 	priv->BSSinfo[index].beacon_period = beacon_period;
3012 	priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3013 	memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3014 	priv->BSSinfo[index].SSIDsize = ssid_len;
3015 
3016 	if (capability & WLAN_CAPABILITY_IBSS)
3017 		priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3018 	else if (capability & WLAN_CAPABILITY_ESS)
3019 		priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3020 
3021 	priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3022 		SHORT_PREAMBLE : LONG_PREAMBLE;
3023 }
3024 
3025 static void authenticate(struct atmel_private *priv, u16 frame_len)
3026 {
3027 	struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3028 	u16 status = le16_to_cpu(auth->status);
3029 	u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3030 	u16 system = le16_to_cpu(auth->alg);
3031 
3032 	if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3033 		/* no WEP */
3034 		if (priv->station_was_associated) {
3035 			atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3036 			send_association_request(priv, 1);
3037 			return;
3038 		} else {
3039 			atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3040 			send_association_request(priv, 0);
3041 			return;
3042 		}
3043 	}
3044 
3045 	if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3046 		int should_associate = 0;
3047 		/* WEP */
3048 		if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3049 			return;
3050 
3051 		if (system == WLAN_AUTH_OPEN) {
3052 			if (trans_seq_no == 0x0002) {
3053 				should_associate = 1;
3054 			}
3055 		} else if (system == WLAN_AUTH_SHARED_KEY) {
3056 			if (trans_seq_no == 0x0002 &&
3057 			    auth->el_id == WLAN_EID_CHALLENGE) {
3058 				send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3059 				return;
3060 			} else if (trans_seq_no == 0x0004) {
3061 				should_associate = 1;
3062 			}
3063 		}
3064 
3065 		if (should_associate) {
3066 			if (priv->station_was_associated) {
3067 				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3068 				send_association_request(priv, 1);
3069 				return;
3070 			} else {
3071 				atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3072 				send_association_request(priv, 0);
3073 				return;
3074 			}
3075 		}
3076 	}
3077 
3078 	if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3079 		/* Flip back and forth between WEP auth modes until the max
3080 		 * authentication tries has been exceeded.
3081 		 */
3082 		if (system == WLAN_AUTH_OPEN) {
3083 			priv->CurrentAuthentTransactionSeqNum = 0x001;
3084 			priv->exclude_unencrypted = 1;
3085 			send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3086 			return;
3087 		} else if (system == WLAN_AUTH_SHARED_KEY
3088 			   && priv->wep_is_on) {
3089 			priv->CurrentAuthentTransactionSeqNum = 0x001;
3090 			priv->exclude_unencrypted = 0;
3091 			send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3092 			return;
3093 		} else if (priv->connect_to_any_BSS) {
3094 			int bss_index;
3095 
3096 			priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3097 
3098 			if ((bss_index  = retrieve_bss(priv)) != -1) {
3099 				atmel_join_bss(priv, bss_index);
3100 				return;
3101 			}
3102 		}
3103 	}
3104 
3105 	priv->AuthenticationRequestRetryCnt = 0;
3106 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3107 	priv->station_is_associated = 0;
3108 }
3109 
3110 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3111 {
3112 	struct ass_resp_format {
3113 		__le16 capability;
3114 		__le16 status;
3115 		__le16 ass_id;
3116 		u8 el_id;
3117 		u8 length;
3118 		u8 rates[4];
3119 	} *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3120 
3121 	u16 status = le16_to_cpu(ass_resp->status);
3122 	u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3123 	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3124 
3125 	union iwreq_data wrqu;
3126 
3127 	if (frame_len < 8 + rates_len)
3128 		return;
3129 
3130 	if (status == WLAN_STATUS_SUCCESS) {
3131 		if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3132 			priv->AssociationRequestRetryCnt = 0;
3133 		else
3134 			priv->ReAssociationRequestRetryCnt = 0;
3135 
3136 		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3137 				MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3138 		atmel_set_mib(priv, Phy_Mib_Type,
3139 			      PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3140 		if (priv->power_mode == 0) {
3141 			priv->listen_interval = 1;
3142 			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3143 				       MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3144 			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3145 					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3146 		} else {
3147 			priv->listen_interval = 2;
3148 			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3149 				       MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
3150 			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3151 					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3152 		}
3153 
3154 		priv->station_is_associated = 1;
3155 		priv->station_was_associated = 1;
3156 		atmel_enter_state(priv, STATION_STATE_READY);
3157 
3158 		/* Send association event to userspace */
3159 		wrqu.data.length = 0;
3160 		wrqu.data.flags = 0;
3161 		memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3162 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3163 		wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3164 
3165 		return;
3166 	}
3167 
3168 	if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3169 	    status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3170 	    status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3171 	    priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3172 		mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3173 		priv->AssociationRequestRetryCnt++;
3174 		send_association_request(priv, 0);
3175 		return;
3176 	}
3177 
3178 	if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3179 	    status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3180 	    status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3181 	    priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3182 		mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3183 		priv->ReAssociationRequestRetryCnt++;
3184 		send_association_request(priv, 1);
3185 		return;
3186 	}
3187 
3188 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3189 	priv->station_is_associated = 0;
3190 
3191 	if (priv->connect_to_any_BSS) {
3192 		int bss_index;
3193 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3194 
3195 		if ((bss_index = retrieve_bss(priv)) != -1)
3196 			atmel_join_bss(priv, bss_index);
3197 	}
3198 }
3199 
3200 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3201 {
3202 	struct bss_info *bss =  &priv->BSSinfo[bss_index];
3203 
3204 	memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3205 	memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3206 
3207 	/* The WPA stuff cares about the current AP address */
3208 	if (priv->use_wpa)
3209 		build_wpa_mib(priv);
3210 
3211 	/* When switching to AdHoc turn OFF Power Save if needed */
3212 
3213 	if (bss->BSStype == IW_MODE_ADHOC &&
3214 	    priv->operating_mode != IW_MODE_ADHOC &&
3215 	    priv->power_mode) {
3216 		priv->power_mode = 0;
3217 		priv->listen_interval = 1;
3218 		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3219 			       MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
3220 		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3221 				MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3222 	}
3223 
3224 	priv->operating_mode = bss->BSStype;
3225 	priv->channel = bss->channel & 0x7f;
3226 	priv->beacon_period = bss->beacon_period;
3227 
3228 	if (priv->preamble != bss->preamble) {
3229 		priv->preamble = bss->preamble;
3230 		atmel_set_mib8(priv, Local_Mib_Type,
3231 			       LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3232 	}
3233 
3234 	if (!priv->wep_is_on && bss->UsingWEP) {
3235 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3236 		priv->station_is_associated = 0;
3237 		return;
3238 	}
3239 
3240 	if (priv->wep_is_on && !bss->UsingWEP) {
3241 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3242 		priv->station_is_associated = 0;
3243 		return;
3244 	}
3245 
3246 	atmel_enter_state(priv, STATION_STATE_JOINNING);
3247 
3248 	if (priv->operating_mode == IW_MODE_INFRA)
3249 		join(priv, BSS_TYPE_INFRASTRUCTURE);
3250 	else
3251 		join(priv, BSS_TYPE_AD_HOC);
3252 }
3253 
3254 static void restart_search(struct atmel_private *priv)
3255 {
3256 	int bss_index;
3257 
3258 	if (!priv->connect_to_any_BSS) {
3259 		atmel_scan(priv, 1);
3260 	} else {
3261 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3262 
3263 		if ((bss_index = retrieve_bss(priv)) != -1)
3264 			atmel_join_bss(priv, bss_index);
3265 		else
3266 			atmel_scan(priv, 0);
3267 	}
3268 }
3269 
3270 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3271 {
3272 	u8 old = priv->wstats.qual.level;
3273 	u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3274 
3275 	switch (priv->firmware_type) {
3276 	case ATMEL_FW_TYPE_502E:
3277 		max_rssi = 63; /* 502-rmfd-reve max by experiment */
3278 		break;
3279 	default:
3280 		break;
3281 	}
3282 
3283 	rssi = rssi * 100 / max_rssi;
3284 	if ((rssi + old) % 2)
3285 		priv->wstats.qual.level = (rssi + old) / 2 + 1;
3286 	else
3287 		priv->wstats.qual.level = (rssi + old) / 2;
3288 	priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3289 	priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3290 }
3291 
3292 static void atmel_smooth_qual(struct atmel_private *priv)
3293 {
3294 	unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3295 	while (time_diff--) {
3296 		priv->last_qual += HZ;
3297 		priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3298 		priv->wstats.qual.qual +=
3299 			priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3300 		priv->beacons_this_sec = 0;
3301 	}
3302 	priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3303 	priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3304 }
3305 
3306 /* deals with incoming management frames. */
3307 static void atmel_management_frame(struct atmel_private *priv,
3308 				   struct ieee80211_hdr *header,
3309 				   u16 frame_len, u8 rssi)
3310 {
3311 	u16 subtype;
3312 
3313 	subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3314 	switch (subtype) {
3315 	case IEEE80211_STYPE_BEACON:
3316 	case IEEE80211_STYPE_PROBE_RESP:
3317 
3318 		/* beacon frame has multiple variable-length fields -
3319 		   never let an engineer loose with a data structure design. */
3320 		{
3321 			struct beacon_format {
3322 				__le64 timestamp;
3323 				__le16 interval;
3324 				__le16 capability;
3325 				u8 ssid_el_id;
3326 				u8 ssid_length;
3327 				/* ssid here */
3328 				u8 rates_el_id;
3329 				u8 rates_length;
3330 				/* rates here */
3331 				u8 ds_el_id;
3332 				u8 ds_length;
3333 				/* ds here */
3334 			} *beacon = (struct beacon_format *)priv->rx_buf;
3335 
3336 			u8 channel, rates_length, ssid_length;
3337 			u64 timestamp = le64_to_cpu(beacon->timestamp);
3338 			u16 beacon_interval = le16_to_cpu(beacon->interval);
3339 			u16 capability = le16_to_cpu(beacon->capability);
3340 			u8 *beaconp = priv->rx_buf;
3341 			ssid_length = beacon->ssid_length;
3342 			/* this blows chunks. */
3343 			if (frame_len < 14 || frame_len < ssid_length + 15)
3344 				return;
3345 			rates_length = beaconp[beacon->ssid_length + 15];
3346 			if (frame_len < ssid_length + rates_length + 18)
3347 				return;
3348 			if (ssid_length >  MAX_SSID_LENGTH)
3349 				return;
3350 			channel = beaconp[ssid_length + rates_length + 18];
3351 
3352 			if (priv->station_state == STATION_STATE_READY) {
3353 				smooth_rssi(priv, rssi);
3354 				if (is_frame_from_current_bss(priv, header)) {
3355 					priv->beacons_this_sec++;
3356 					atmel_smooth_qual(priv);
3357 					if (priv->last_beacon_timestamp) {
3358 						/* Note truncate this to 32 bits - kernel can't divide a long long */
3359 						u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3360 						int beacons = beacon_delay / (beacon_interval * 1000);
3361 						if (beacons > 1)
3362 							priv->wstats.miss.beacon += beacons - 1;
3363 					}
3364 					priv->last_beacon_timestamp = timestamp;
3365 					handle_beacon_probe(priv, capability, channel);
3366 				}
3367 			}
3368 
3369 			if (priv->station_state == STATION_STATE_SCANNING)
3370 				store_bss_info(priv, header, capability,
3371 					       beacon_interval, channel, rssi,
3372 					       ssid_length,
3373 					       &beacon->rates_el_id,
3374 					       subtype == IEEE80211_STYPE_BEACON);
3375 		}
3376 		break;
3377 
3378 	case IEEE80211_STYPE_AUTH:
3379 
3380 		if (priv->station_state == STATION_STATE_AUTHENTICATING)
3381 			authenticate(priv, frame_len);
3382 
3383 		break;
3384 
3385 	case IEEE80211_STYPE_ASSOC_RESP:
3386 	case IEEE80211_STYPE_REASSOC_RESP:
3387 
3388 		if (priv->station_state == STATION_STATE_ASSOCIATING ||
3389 		    priv->station_state == STATION_STATE_REASSOCIATING)
3390 			associate(priv, frame_len, subtype);
3391 
3392 		break;
3393 
3394 	case IEEE80211_STYPE_DISASSOC:
3395 		if (priv->station_is_associated &&
3396 		    priv->operating_mode == IW_MODE_INFRA &&
3397 		    is_frame_from_current_bss(priv, header)) {
3398 			priv->station_was_associated = 0;
3399 			priv->station_is_associated = 0;
3400 
3401 			atmel_enter_state(priv, STATION_STATE_JOINNING);
3402 			join(priv, BSS_TYPE_INFRASTRUCTURE);
3403 		}
3404 
3405 		break;
3406 
3407 	case IEEE80211_STYPE_DEAUTH:
3408 		if (priv->operating_mode == IW_MODE_INFRA &&
3409 		    is_frame_from_current_bss(priv, header)) {
3410 			priv->station_was_associated = 0;
3411 
3412 			atmel_enter_state(priv, STATION_STATE_JOINNING);
3413 			join(priv, BSS_TYPE_INFRASTRUCTURE);
3414 		}
3415 
3416 		break;
3417 	}
3418 }
3419 
3420 /* run when timer expires */
3421 static void atmel_management_timer(struct timer_list *t)
3422 {
3423 	struct atmel_private *priv = from_timer(priv, t, management_timer);
3424 	unsigned long flags;
3425 
3426 	/* Check if the card has been yanked. */
3427 	if (priv->card && priv->present_callback &&
3428 		!(*priv->present_callback)(priv->card))
3429 		return;
3430 
3431 	spin_lock_irqsave(&priv->irqlock, flags);
3432 
3433 	switch (priv->station_state) {
3434 
3435 	case STATION_STATE_AUTHENTICATING:
3436 		if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3437 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3438 			priv->station_is_associated = 0;
3439 			priv->AuthenticationRequestRetryCnt = 0;
3440 			restart_search(priv);
3441 		} else {
3442 			int auth = WLAN_AUTH_OPEN;
3443 			priv->AuthenticationRequestRetryCnt++;
3444 			priv->CurrentAuthentTransactionSeqNum = 0x0001;
3445 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3446 			if (priv->wep_is_on && priv->exclude_unencrypted)
3447 				auth = WLAN_AUTH_SHARED_KEY;
3448 			send_authentication_request(priv, auth, NULL, 0);
3449 	  }
3450 	  break;
3451 
3452 	case STATION_STATE_ASSOCIATING:
3453 		if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3454 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3455 			priv->station_is_associated = 0;
3456 			priv->AssociationRequestRetryCnt = 0;
3457 			restart_search(priv);
3458 		} else {
3459 			priv->AssociationRequestRetryCnt++;
3460 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3461 			send_association_request(priv, 0);
3462 		}
3463 	  break;
3464 
3465 	case STATION_STATE_REASSOCIATING:
3466 		if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3467 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3468 			priv->station_is_associated = 0;
3469 			priv->ReAssociationRequestRetryCnt = 0;
3470 			restart_search(priv);
3471 		} else {
3472 			priv->ReAssociationRequestRetryCnt++;
3473 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3474 			send_association_request(priv, 1);
3475 		}
3476 		break;
3477 
3478 	default:
3479 		break;
3480 	}
3481 
3482 	spin_unlock_irqrestore(&priv->irqlock, flags);
3483 }
3484 
3485 static void atmel_command_irq(struct atmel_private *priv)
3486 {
3487 	u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3488 	u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3489 	int fast_scan;
3490 	union iwreq_data wrqu;
3491 
3492 	if (status == CMD_STATUS_IDLE ||
3493 	    status == CMD_STATUS_IN_PROGRESS)
3494 		return;
3495 
3496 	switch (command) {
3497 	case CMD_Start:
3498 		if (status == CMD_STATUS_COMPLETE) {
3499 			priv->station_was_associated = priv->station_is_associated;
3500 			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3501 				      (u8 *)priv->CurrentBSSID, 6);
3502 			atmel_enter_state(priv, STATION_STATE_READY);
3503 		}
3504 		break;
3505 
3506 	case CMD_Scan:
3507 		fast_scan = priv->fast_scan;
3508 		priv->fast_scan = 0;
3509 
3510 		if (status != CMD_STATUS_COMPLETE) {
3511 			atmel_scan(priv, 1);
3512 		} else {
3513 			int bss_index = retrieve_bss(priv);
3514 			int notify_scan_complete = 1;
3515 			if (bss_index != -1) {
3516 				atmel_join_bss(priv, bss_index);
3517 			} else if (priv->operating_mode == IW_MODE_ADHOC &&
3518 				   priv->SSID_size != 0) {
3519 				start(priv, BSS_TYPE_AD_HOC);
3520 			} else {
3521 				priv->fast_scan = !fast_scan;
3522 				atmel_scan(priv, 1);
3523 				notify_scan_complete = 0;
3524 			}
3525 			priv->site_survey_state = SITE_SURVEY_COMPLETED;
3526 			if (notify_scan_complete) {
3527 				wrqu.data.length = 0;
3528 				wrqu.data.flags = 0;
3529 				wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3530 			}
3531 		}
3532 		break;
3533 
3534 	case CMD_SiteSurvey:
3535 		priv->fast_scan = 0;
3536 
3537 		if (status != CMD_STATUS_COMPLETE)
3538 			return;
3539 
3540 		priv->site_survey_state = SITE_SURVEY_COMPLETED;
3541 		if (priv->station_is_associated) {
3542 			atmel_enter_state(priv, STATION_STATE_READY);
3543 			wrqu.data.length = 0;
3544 			wrqu.data.flags = 0;
3545 			wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3546 		} else {
3547 			atmel_scan(priv, 1);
3548 		}
3549 		break;
3550 
3551 	case CMD_Join:
3552 		if (status == CMD_STATUS_COMPLETE) {
3553 			if (priv->operating_mode == IW_MODE_ADHOC) {
3554 				priv->station_was_associated = priv->station_is_associated;
3555 				atmel_enter_state(priv, STATION_STATE_READY);
3556 			} else {
3557 				int auth = WLAN_AUTH_OPEN;
3558 				priv->AuthenticationRequestRetryCnt = 0;
3559 				atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3560 
3561 				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3562 				priv->CurrentAuthentTransactionSeqNum = 0x0001;
3563 				if (priv->wep_is_on && priv->exclude_unencrypted)
3564 					auth = WLAN_AUTH_SHARED_KEY;
3565 				send_authentication_request(priv, auth, NULL, 0);
3566 			}
3567 			return;
3568 		}
3569 
3570 		atmel_scan(priv, 1);
3571 	}
3572 }
3573 
3574 static int atmel_wakeup_firmware(struct atmel_private *priv)
3575 {
3576 	struct host_info_struct *iface = &priv->host_info;
3577 	u16 mr1, mr3;
3578 	int i;
3579 
3580 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
3581 		atmel_set_gcr(priv->dev, GCR_REMAP);
3582 
3583 	/* wake up on-board processor */
3584 	atmel_clear_gcr(priv->dev, 0x0040);
3585 	atmel_write16(priv->dev, BSR, BSS_SRAM);
3586 
3587 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
3588 		mdelay(100);
3589 
3590 	/* and wait for it */
3591 	for (i = LOOP_RETRY_LIMIT; i; i--) {
3592 		mr1 = atmel_read16(priv->dev, MR1);
3593 		mr3 = atmel_read16(priv->dev, MR3);
3594 
3595 		if (mr3 & MAC_BOOT_COMPLETE)
3596 			break;
3597 		if (mr1 & MAC_BOOT_COMPLETE &&
3598 		    priv->bus_type == BUS_TYPE_PCCARD)
3599 			break;
3600 	}
3601 
3602 	if (i == 0) {
3603 		printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3604 		return -EIO;
3605 	}
3606 
3607 	if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3608 		printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3609 		return -ENODEV;
3610 	}
3611 
3612 	/* now check for completion of MAC initialization through
3613 	   the FunCtrl field of the IFACE, poll MR1 to detect completion of
3614 	   MAC initialization, check completion status, set interrupt mask,
3615 	   enables interrupts and calls Tx and Rx initialization functions */
3616 
3617 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3618 
3619 	for (i = LOOP_RETRY_LIMIT; i; i--) {
3620 		mr1 = atmel_read16(priv->dev, MR1);
3621 		mr3 = atmel_read16(priv->dev, MR3);
3622 
3623 		if (mr3 & MAC_INIT_COMPLETE)
3624 			break;
3625 		if (mr1 & MAC_INIT_COMPLETE &&
3626 		    priv->bus_type == BUS_TYPE_PCCARD)
3627 			break;
3628 	}
3629 
3630 	if (i == 0) {
3631 		printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3632 				priv->dev->name);
3633 		return -EIO;
3634 	}
3635 
3636 	/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3637 	if ((mr3 & MAC_INIT_COMPLETE) &&
3638 	    !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3639 		printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3640 		return -EIO;
3641 	}
3642 	if ((mr1 & MAC_INIT_COMPLETE) &&
3643 	    !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3644 		printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3645 		return -EIO;
3646 	}
3647 
3648 	atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3649 			   priv->host_info_base, sizeof(*iface));
3650 
3651 	iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3652 	iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3653 	iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3654 	iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3655 	iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3656 	iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3657 	iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3658 	iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3659 	iface->build_version = le16_to_cpu(iface->build_version);
3660 	iface->command_pos = le16_to_cpu(iface->command_pos);
3661 	iface->major_version = le16_to_cpu(iface->major_version);
3662 	iface->minor_version = le16_to_cpu(iface->minor_version);
3663 	iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3664 	iface->mac_status = le16_to_cpu(iface->mac_status);
3665 
3666 	return 0;
3667 }
3668 
3669 /* determine type of memory and MAC address */
3670 static int probe_atmel_card(struct net_device *dev)
3671 {
3672 	int rc = 0;
3673 	struct atmel_private *priv = netdev_priv(dev);
3674 
3675 	/* reset pccard */
3676 	if (priv->bus_type == BUS_TYPE_PCCARD)
3677 		atmel_write16(dev, GCR, 0x0060);
3678 
3679 	atmel_write16(dev, GCR, 0x0040);
3680 	msleep(500);
3681 
3682 	if (atmel_read16(dev, MR2) == 0) {
3683 		/* No stored firmware so load a small stub which just
3684 		   tells us the MAC address */
3685 		int i;
3686 		priv->card_type = CARD_TYPE_EEPROM;
3687 		atmel_write16(dev, BSR, BSS_IRAM);
3688 		atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3689 		atmel_set_gcr(dev, GCR_REMAP);
3690 		atmel_clear_gcr(priv->dev, 0x0040);
3691 		atmel_write16(dev, BSR, BSS_SRAM);
3692 		for (i = LOOP_RETRY_LIMIT; i; i--)
3693 			if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3694 				break;
3695 		if (i == 0) {
3696 			printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3697 		} else {
3698 			atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3699 			/* got address, now squash it again until the network
3700 			   interface is opened */
3701 			if (priv->bus_type == BUS_TYPE_PCCARD)
3702 				atmel_write16(dev, GCR, 0x0060);
3703 			atmel_write16(dev, GCR, 0x0040);
3704 			rc = 1;
3705 		}
3706 	} else if (atmel_read16(dev, MR4) == 0) {
3707 		/* Mac address easy in this case. */
3708 		priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3709 		atmel_write16(dev,  BSR, 1);
3710 		atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3711 		atmel_write16(dev,  BSR, 0x200);
3712 		rc = 1;
3713 	} else {
3714 		/* Standard firmware in flash, boot it up and ask
3715 		   for the Mac Address */
3716 		priv->card_type = CARD_TYPE_SPI_FLASH;
3717 		if (atmel_wakeup_firmware(priv) == 0) {
3718 			atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3719 
3720 			/* got address, now squash it again until the network
3721 			   interface is opened */
3722 			if (priv->bus_type == BUS_TYPE_PCCARD)
3723 				atmel_write16(dev, GCR, 0x0060);
3724 			atmel_write16(dev, GCR, 0x0040);
3725 			rc = 1;
3726 		}
3727 	}
3728 
3729 	if (rc) {
3730 		if (dev->dev_addr[0] == 0xFF) {
3731 			static const u8 default_mac[] = {
3732 				0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3733 			};
3734 			printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3735 			memcpy(dev->dev_addr, default_mac, ETH_ALEN);
3736 		}
3737 	}
3738 
3739 	return rc;
3740 }
3741 
3742 /* Move the encyption information on the MIB structure.
3743    This routine is for the pre-WPA firmware: later firmware has
3744    a different format MIB and a different routine. */
3745 static void build_wep_mib(struct atmel_private *priv)
3746 {
3747 	struct { /* NB this is matched to the hardware, don't change. */
3748 		u8 wep_is_on;
3749 		u8 default_key; /* 0..3 */
3750 		u8 reserved;
3751 		u8 exclude_unencrypted;
3752 
3753 		u32 WEPICV_error_count;
3754 		u32 WEP_excluded_count;
3755 
3756 		u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3757 		u8 encryption_level; /* 0, 1, 2 */
3758 		u8 reserved2[3];
3759 	} mib;
3760 	int i;
3761 
3762 	mib.wep_is_on = priv->wep_is_on;
3763 	if (priv->wep_is_on) {
3764 		if (priv->wep_key_len[priv->default_key] > 5)
3765 			mib.encryption_level = 2;
3766 		else
3767 			mib.encryption_level = 1;
3768 	} else {
3769 		mib.encryption_level = 0;
3770 	}
3771 
3772 	mib.default_key = priv->default_key;
3773 	mib.exclude_unencrypted = priv->exclude_unencrypted;
3774 
3775 	for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3776 		memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3777 
3778 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3779 }
3780 
3781 static void build_wpa_mib(struct atmel_private *priv)
3782 {
3783 	/* This is for the later (WPA enabled) firmware. */
3784 
3785 	struct { /* NB this is matched to the hardware, don't change. */
3786 		u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3787 		u8 receiver_address[ETH_ALEN];
3788 		u8 wep_is_on;
3789 		u8 default_key; /* 0..3 */
3790 		u8 group_key;
3791 		u8 exclude_unencrypted;
3792 		u8 encryption_type;
3793 		u8 reserved;
3794 
3795 		u32 WEPICV_error_count;
3796 		u32 WEP_excluded_count;
3797 
3798 		u8 key_RSC[4][8];
3799 	} mib;
3800 
3801 	int i;
3802 
3803 	mib.wep_is_on = priv->wep_is_on;
3804 	mib.exclude_unencrypted = priv->exclude_unencrypted;
3805 	memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3806 
3807 	/* zero all the keys before adding in valid ones. */
3808 	memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3809 
3810 	if (priv->wep_is_on) {
3811 		/* There's a comment in the Atmel code to the effect that this
3812 		   is only valid when still using WEP, it may need to be set to
3813 		   something to use WPA */
3814 		memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3815 
3816 		mib.default_key = mib.group_key = 255;
3817 		for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3818 			if (priv->wep_key_len[i] > 0) {
3819 				memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3820 				if (i == priv->default_key) {
3821 					mib.default_key = i;
3822 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3823 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3824 				} else {
3825 					mib.group_key = i;
3826 					priv->group_cipher_suite = priv->pairwise_cipher_suite;
3827 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3828 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3829 				}
3830 			}
3831 		}
3832 		if (mib.default_key == 255)
3833 			mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3834 		if (mib.group_key == 255)
3835 			mib.group_key = mib.default_key;
3836 
3837 	}
3838 
3839 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3840 }
3841 
3842 static int reset_atmel_card(struct net_device *dev)
3843 {
3844 	/* do everything necessary to wake up the hardware, including
3845 	   waiting for the lightning strike and throwing the knife switch....
3846 
3847 	   set all the Mib values which matter in the card to match
3848 	   their settings in the atmel_private structure. Some of these
3849 	   can be altered on the fly, but many (WEP, infrastructure or ad-hoc)
3850 	   can only be changed by tearing down the world and coming back through
3851 	   here.
3852 
3853 	   This routine is also responsible for initialising some
3854 	   hardware-specific fields in the atmel_private structure,
3855 	   including a copy of the firmware's hostinfo structure
3856 	   which is the route into the rest of the firmware datastructures. */
3857 
3858 	struct atmel_private *priv = netdev_priv(dev);
3859 	u8 configuration;
3860 	int old_state = priv->station_state;
3861 	int err = 0;
3862 
3863 	/* data to add to the firmware names, in priority order
3864 	   this implemenents firmware versioning */
3865 
3866 	static char *firmware_modifier[] = {
3867 		"-wpa",
3868 		"",
3869 		NULL
3870 	};
3871 
3872 	/* reset pccard */
3873 	if (priv->bus_type == BUS_TYPE_PCCARD)
3874 		atmel_write16(priv->dev, GCR, 0x0060);
3875 
3876 	/* stop card , disable interrupts */
3877 	atmel_write16(priv->dev, GCR, 0x0040);
3878 
3879 	if (priv->card_type == CARD_TYPE_EEPROM) {
3880 		/* copy in firmware if needed */
3881 		const struct firmware *fw_entry = NULL;
3882 		const unsigned char *fw;
3883 		int len = priv->firmware_length;
3884 		if (!(fw = priv->firmware)) {
3885 			if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3886 				if (strlen(priv->firmware_id) == 0) {
3887 					printk(KERN_INFO
3888 					       "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3889 					       dev->name);
3890 					printk(KERN_INFO
3891 					       "%s: if not, use the firmware= module parameter.\n",
3892 					       dev->name);
3893 					strcpy(priv->firmware_id, "atmel_at76c502.bin");
3894 				}
3895 				err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3896 				if (err != 0) {
3897 					printk(KERN_ALERT
3898 					       "%s: firmware %s is missing, cannot continue.\n",
3899 					       dev->name, priv->firmware_id);
3900 					return err;
3901 				}
3902 			} else {
3903 				int fw_index = 0;
3904 				int success = 0;
3905 
3906 				/* get firmware filename entry based on firmware type ID */
3907 				while (fw_table[fw_index].fw_type != priv->firmware_type
3908 						&& fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3909 					fw_index++;
3910 
3911 				/* construct the actual firmware file name */
3912 				if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3913 					int i;
3914 					for (i = 0; firmware_modifier[i]; i++) {
3915 						snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3916 							firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3917 						priv->firmware_id[31] = '\0';
3918 						if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3919 							success = 1;
3920 							break;
3921 						}
3922 					}
3923 				}
3924 				if (!success) {
3925 					printk(KERN_ALERT
3926 					       "%s: firmware %s is missing, cannot start.\n",
3927 					       dev->name, priv->firmware_id);
3928 					priv->firmware_id[0] = '\0';
3929 					return -ENOENT;
3930 				}
3931 			}
3932 
3933 			fw = fw_entry->data;
3934 			len = fw_entry->size;
3935 		}
3936 
3937 		if (len <= 0x6000) {
3938 			atmel_write16(priv->dev, BSR, BSS_IRAM);
3939 			atmel_copy_to_card(priv->dev, 0, fw, len);
3940 			atmel_set_gcr(priv->dev, GCR_REMAP);
3941 		} else {
3942 			/* Remap */
3943 			atmel_set_gcr(priv->dev, GCR_REMAP);
3944 			atmel_write16(priv->dev, BSR, BSS_IRAM);
3945 			atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3946 			atmel_write16(priv->dev, BSR, 0x2ff);
3947 			atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3948 		}
3949 
3950 		release_firmware(fw_entry);
3951 	}
3952 
3953 	err = atmel_wakeup_firmware(priv);
3954 	if (err != 0)
3955 		return err;
3956 
3957 	/* Check the version and set the correct flag for wpa stuff,
3958 	   old and new firmware is incompatible.
3959 	   The pre-wpa 3com firmware reports major version 5,
3960 	   the wpa 3com firmware is major version 4 and doesn't need
3961 	   the 3com broken-ness filter. */
3962 	priv->use_wpa = (priv->host_info.major_version == 4);
3963 	priv->radio_on_broken = (priv->host_info.major_version == 5);
3964 
3965 	/* unmask all irq sources */
3966 	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3967 
3968 	/* int Tx system and enable Tx */
3969 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3970 	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3971 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3972 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3973 
3974 	priv->tx_desc_free = priv->host_info.tx_desc_count;
3975 	priv->tx_desc_head = 0;
3976 	priv->tx_desc_tail = 0;
3977 	priv->tx_desc_previous = 0;
3978 	priv->tx_free_mem = priv->host_info.tx_buff_size;
3979 	priv->tx_buff_head = 0;
3980 	priv->tx_buff_tail = 0;
3981 
3982 	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3983 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3984 				   configuration | FUNC_CTRL_TxENABLE);
3985 
3986 	/* init Rx system and enable */
3987 	priv->rx_desc_head = 0;
3988 
3989 	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3990 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3991 				   configuration | FUNC_CTRL_RxENABLE);
3992 
3993 	if (!priv->radio_on_broken) {
3994 		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3995 		    CMD_STATUS_REJECTED_RADIO_OFF) {
3996 			printk(KERN_INFO "%s: cannot turn the radio on.\n",
3997 			       dev->name);
3998 			return -EIO;
3999 		}
4000 	}
4001 
4002 	/* set up enough MIB values to run. */
4003 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4004 	atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
4005 	atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4006 	atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4007 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4008 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4009 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4010 	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4011 		      priv->dev->dev_addr, 6);
4012 	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4013 	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4014 	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4015 	atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4016 	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4017 	if (priv->use_wpa)
4018 		build_wpa_mib(priv);
4019 	else
4020 		build_wep_mib(priv);
4021 
4022 	if (old_state == STATION_STATE_READY) {
4023 		union iwreq_data wrqu;
4024 
4025 		wrqu.data.length = 0;
4026 		wrqu.data.flags = 0;
4027 		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4028 		eth_zero_addr(wrqu.ap_addr.sa_data);
4029 		wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4030 	}
4031 
4032 	return 0;
4033 }
4034 
4035 static void atmel_send_command(struct atmel_private *priv, int command,
4036 			       void *cmd, int cmd_size)
4037 {
4038 	if (cmd)
4039 		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4040 				   cmd, cmd_size);
4041 
4042 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4043 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4044 }
4045 
4046 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4047 				   void *cmd, int cmd_size)
4048 {
4049 	int i, status;
4050 
4051 	atmel_send_command(priv, command, cmd, cmd_size);
4052 
4053 	for (i = 5000; i; i--) {
4054 		status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4055 		if (status != CMD_STATUS_IDLE &&
4056 		    status != CMD_STATUS_IN_PROGRESS)
4057 			break;
4058 		udelay(20);
4059 	}
4060 
4061 	if (i == 0) {
4062 		printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4063 		status =  CMD_STATUS_HOST_ERROR;
4064 	} else {
4065 		if (command != CMD_EnableRadio)
4066 			status = CMD_STATUS_COMPLETE;
4067 	}
4068 
4069 	return status;
4070 }
4071 
4072 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4073 {
4074 	struct get_set_mib m;
4075 	m.type = type;
4076 	m.size = 1;
4077 	m.index = index;
4078 
4079 	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4080 	return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4081 }
4082 
4083 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4084 {
4085 	struct get_set_mib m;
4086 	m.type = type;
4087 	m.size = 1;
4088 	m.index = index;
4089 	m.data[0] = data;
4090 
4091 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4092 }
4093 
4094 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4095 			    u16 data)
4096 {
4097 	struct get_set_mib m;
4098 	m.type = type;
4099 	m.size = 2;
4100 	m.index = index;
4101 	m.data[0] = data;
4102 	m.data[1] = data >> 8;
4103 
4104 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4105 }
4106 
4107 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4108 			  u8 *data, int data_len)
4109 {
4110 	struct get_set_mib m;
4111 	m.type = type;
4112 	m.size = data_len;
4113 	m.index = index;
4114 
4115 	if (data_len > MIB_MAX_DATA_BYTES)
4116 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4117 
4118 	memcpy(m.data, data, data_len);
4119 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4120 }
4121 
4122 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4123 			  u8 *data, int data_len)
4124 {
4125 	struct get_set_mib m;
4126 	m.type = type;
4127 	m.size = data_len;
4128 	m.index = index;
4129 
4130 	if (data_len > MIB_MAX_DATA_BYTES)
4131 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4132 
4133 	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4134 	atmel_copy_to_host(priv->dev, data,
4135 			   atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4136 }
4137 
4138 static void atmel_writeAR(struct net_device *dev, u16 data)
4139 {
4140 	int i;
4141 	outw(data, dev->base_addr + AR);
4142 	/* Address register appears to need some convincing..... */
4143 	for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4144 		outw(data, dev->base_addr + AR);
4145 }
4146 
4147 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4148 			       const unsigned char *src, u16 len)
4149 {
4150 	int i;
4151 	atmel_writeAR(dev, dest);
4152 	if (dest % 2) {
4153 		atmel_write8(dev, DR, *src);
4154 		src++; len--;
4155 	}
4156 	for (i = len; i > 1 ; i -= 2) {
4157 		u8 lb = *src++;
4158 		u8 hb = *src++;
4159 		atmel_write16(dev, DR, lb | (hb << 8));
4160 	}
4161 	if (i)
4162 		atmel_write8(dev, DR, *src);
4163 }
4164 
4165 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4166 			       u16 src, u16 len)
4167 {
4168 	int i;
4169 	atmel_writeAR(dev, src);
4170 	if (src % 2) {
4171 		*dest = atmel_read8(dev, DR);
4172 		dest++; len--;
4173 	}
4174 	for (i = len; i > 1 ; i -= 2) {
4175 		u16 hw = atmel_read16(dev, DR);
4176 		*dest++ = hw;
4177 		*dest++ = hw >> 8;
4178 	}
4179 	if (i)
4180 		*dest = atmel_read8(dev, DR);
4181 }
4182 
4183 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4184 {
4185 	outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4186 }
4187 
4188 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4189 {
4190 	outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4191 }
4192 
4193 static int atmel_lock_mac(struct atmel_private *priv)
4194 {
4195 	int i, j = 20;
4196  retry:
4197 	for (i = 5000; i; i--) {
4198 		if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4199 			break;
4200 		udelay(20);
4201 	}
4202 
4203 	if (!i)
4204 		return 0; /* timed out */
4205 
4206 	atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4207 	if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4208 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4209 		if (!j--)
4210 			return 0; /* timed out */
4211 		goto retry;
4212 	}
4213 
4214 	return 1;
4215 }
4216 
4217 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4218 {
4219 	atmel_writeAR(priv->dev, pos);
4220 	atmel_write16(priv->dev, DR, data); /* card is little-endian */
4221 	atmel_write16(priv->dev, DR, data >> 16);
4222 }
4223 
4224 /***************************************************************************/
4225 /* There follows the source form of the MAC address reading firmware       */
4226 /***************************************************************************/
4227 #if 0
4228 
4229 /* Copyright 2003 Matthew T. Russotto                                      */
4230 /* But derived from the Atmel 76C502 firmware written by Atmel and         */
4231 /* included in "atmel wireless lan drivers" package                        */
4232 /**
4233     This file is part of net.russotto.AtmelMACFW, hereto referred to
4234     as AtmelMACFW
4235 
4236     AtmelMACFW is free software; you can redistribute it and/or modify
4237     it under the terms of the GNU General Public License version 2
4238     as published by the Free Software Foundation.
4239 
4240     AtmelMACFW is distributed in the hope that it will be useful,
4241     but WITHOUT ANY WARRANTY; without even the implied warranty of
4242     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4243     GNU General Public License for more details.
4244 
4245     You should have received a copy of the GNU General Public License
4246     along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4247 
4248 ****************************************************************************/
4249 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
4250 /* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
4251 /* It only works on SPI EEPROM versions of the card.                       */
4252 
4253 /* This firmware initializes the SPI controller and clock, reads the MAC   */
4254 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
4255 /* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
4256 /* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
4257 /* MR4, for investigational purposes (maybe we can determine chip type     */
4258 /* from that?)                                                             */
4259 
4260 	.org 0
4261     .set MRBASE, 0x8000000
4262 	.set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4263 	.set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4264 	.set SRAM_BASE,  0x02000000
4265 	.set SP_BASE,    0x0F300000
4266 	.set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
4267 	.set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
4268 	.set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
4269 	.set STACK_BASE, 0x5600
4270 	.set SP_SR, 0x10
4271 	.set SP_TDRE, 2 /* status register bit -- TDR empty */
4272 	.set SP_RDRF, 1 /* status register bit -- RDR full */
4273 	.set SP_SWRST, 0x80
4274 	.set SP_SPIEN, 0x1
4275 	.set SP_CR, 0   /* control register */
4276 	.set SP_MR, 4   /* mode register */
4277 	.set SP_RDR, 0x08 /* Read Data Register */
4278 	.set SP_TDR, 0x0C /* Transmit Data Register */
4279 	.set SP_CSR0, 0x30 /* chip select registers */
4280 	.set SP_CSR1, 0x34
4281 	.set SP_CSR2, 0x38
4282 	.set SP_CSR3, 0x3C
4283 	.set NVRAM_CMD_RDSR, 5 /* read status register */
4284 	.set NVRAM_CMD_READ, 3 /* read data */
4285 	.set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
4286 	.set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4287 				  serial output, since SO is normally high.  But it
4288 				  does cause 8 clock cycles and thus 8 bits to be
4289 				  clocked in to the chip.  See Atmel's SPI
4290 				  controller (e.g. AT91M55800) timing and 4K
4291 				  SPI EEPROM manuals */
4292 
4293 	.set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
4294 	.set NVRAM_IMAGE, 0x02000200
4295 	.set NVRAM_LENGTH, 0x0200
4296 	.set MAC_ADDRESS_MIB, SRAM_BASE
4297 	.set MAC_ADDRESS_LENGTH, 6
4298 	.set MAC_BOOT_FLAG, 0x10
4299 	.set MR1, 0
4300 	.set MR2, 4
4301 	.set MR3, 8
4302 	.set MR4, 0xC
4303 RESET_VECTOR:
4304 	b RESET_HANDLER
4305 UNDEF_VECTOR:
4306 	b HALT1
4307 SWI_VECTOR:
4308 	b HALT1
4309 IABORT_VECTOR:
4310 	b HALT1
4311 DABORT_VECTOR:
4312 RESERVED_VECTOR:
4313 	b HALT1
4314 IRQ_VECTOR:
4315 	b HALT1
4316 FIQ_VECTOR:
4317 	b HALT1
4318 HALT1:	b HALT1
4319 RESET_HANDLER:
4320 	mov     r0, #CPSR_INITIAL
4321 	msr	CPSR_c, r0	/* This is probably unnecessary */
4322 
4323 /* I'm guessing this is initializing clock generator electronics for SPI */
4324 	ldr	r0, =SPI_CGEN_BASE
4325 	mov	r1, #0
4326 	mov	r1, r1, lsl #3
4327 	orr	r1, r1, #0
4328 	str	r1, [r0]
4329 	ldr	r1, [r0, #28]
4330 	bic	r1, r1, #16
4331 	str	r1, [r0, #28]
4332 	mov	r1, #1
4333 	str	r1, [r0, #8]
4334 
4335 	ldr	r0, =MRBASE
4336 	mov	r1, #0
4337 	strh	r1, [r0, #MR1]
4338 	strh	r1, [r0, #MR2]
4339 	strh	r1, [r0, #MR3]
4340 	strh	r1, [r0, #MR4]
4341 
4342 	mov	sp, #STACK_BASE
4343 	bl	SP_INIT
4344 	mov	r0, #10
4345 	bl	DELAY9
4346 	bl	GET_MAC_ADDR
4347 	bl	GET_WHOLE_NVRAM
4348 	ldr	r0, =MRBASE
4349 	ldr	r1, =MAC_ADDRESS_MIB
4350 	strh	r1, [r0, #MR2]
4351 	ldr	r1, =NVRAM_IMAGE
4352 	strh	r1, [r0, #MR4]
4353 	mov	r1, #MAC_BOOT_FLAG
4354 	strh	r1, [r0, #MR3]
4355 HALT2:	b HALT2
4356 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4357 GET_WHOLE_NVRAM:
4358 	stmdb	sp!, {lr}
4359 	mov	r2, #0 /* 0th bytes of NVRAM */
4360 	mov	r3, #NVRAM_LENGTH
4361 	mov	r1, #0		/* not used in routine */
4362 	ldr	r0, =NVRAM_IMAGE
4363 	bl	NVRAM_XFER
4364 	ldmia	sp!, {lr}
4365 	bx	lr
4366 .endfunc
4367 
4368 .func Get_MAC_Addr, GET_MAC_ADDR
4369 GET_MAC_ADDR:
4370 	stmdb	sp!, {lr}
4371 	mov	r2, #0x120	/* address of MAC Address within NVRAM */
4372 	mov	r3, #MAC_ADDRESS_LENGTH
4373 	mov	r1, #0		/* not used in routine */
4374 	ldr	r0, =MAC_ADDRESS_MIB
4375 	bl	NVRAM_XFER
4376 	ldmia	sp!, {lr}
4377 	bx	lr
4378 .endfunc
4379 .ltorg
4380 .func Delay9, DELAY9
4381 DELAY9:
4382 	adds	r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
4383 DELAYLOOP:
4384 	beq	DELAY9_done
4385 	subs	r0, r0, #1
4386 	b	DELAYLOOP
4387 DELAY9_done:
4388 	bx	lr
4389 .endfunc
4390 
4391 .func SP_Init, SP_INIT
4392 SP_INIT:
4393 	mov	r1, #SP_SWRST
4394 	ldr	r0, =SP_BASE
4395 	str	r1, [r0, #SP_CR] /* reset the SPI */
4396 	mov	r1, #0
4397 	str	r1, [r0, #SP_CR] /* release SPI from reset state */
4398 	mov	r1, #SP_SPIEN
4399 	str	r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4400 	str	r1, [r0, #SP_CR] /* enable the SPI */
4401 
4402 /*  My guess would be this turns on the SPI clock */
4403 	ldr	r3, =SPI_CGEN_BASE
4404 	ldr	r1, [r3, #28]
4405 	orr	r1, r1, #0x2000
4406 	str	r1, [r3, #28]
4407 
4408 	ldr	r1, =0x2000c01
4409 	str	r1, [r0, #SP_CSR0]
4410 	ldr	r1, =0x2000201
4411 	str	r1, [r0, #SP_CSR1]
4412 	str	r1, [r0, #SP_CSR2]
4413 	str	r1, [r0, #SP_CSR3]
4414 	ldr	r1, [r0, #SP_SR]
4415 	ldr	r0, [r0, #SP_RDR]
4416 	bx	lr
4417 .endfunc
4418 .func NVRAM_Init, NVRAM_INIT
4419 NVRAM_INIT:
4420 	ldr	r1, =SP_BASE
4421 	ldr	r0, [r1, #SP_RDR]
4422 	mov	r0, #NVRAM_CMD_RDSR
4423 	str	r0, [r1, #SP_TDR]
4424 SP_loop1:
4425 	ldr	r0, [r1, #SP_SR]
4426 	tst	r0, #SP_TDRE
4427 	beq	SP_loop1
4428 
4429 	mov	r0, #SPI_8CLOCKS
4430 	str	r0, [r1, #SP_TDR]
4431 SP_loop2:
4432 	ldr	r0, [r1, #SP_SR]
4433 	tst	r0, #SP_TDRE
4434 	beq	SP_loop2
4435 
4436 	ldr	r0, [r1, #SP_RDR]
4437 SP_loop3:
4438 	ldr	r0, [r1, #SP_SR]
4439 	tst	r0, #SP_RDRF
4440 	beq	SP_loop3
4441 
4442 	ldr	r0, [r1, #SP_RDR]
4443 	and	r0, r0, #255
4444 	bx	lr
4445 .endfunc
4446 
4447 .func NVRAM_Xfer, NVRAM_XFER
4448 	/* r0 = dest address */
4449 	/* r1 = not used */
4450 	/* r2 = src address within NVRAM */
4451 	/* r3 = length */
4452 NVRAM_XFER:
4453 	stmdb	sp!, {r4, r5, lr}
4454 	mov	r5, r0		/* save r0 (dest address) */
4455 	mov	r4, r3		/* save r3 (length) */
4456 	mov	r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
4457 	and	r0, r0, #8
4458 	add	r0, r0, #NVRAM_CMD_READ
4459 	ldr	r1, =NVRAM_SCRATCH
4460 	strb	r0, [r1, #0]	/* save command in NVRAM_SCRATCH[0] */
4461 	strb	r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
4462 _local1:
4463 	bl	NVRAM_INIT
4464 	tst	r0, #NVRAM_SR_RDY
4465 	bne	_local1
4466 	mov	r0, #20
4467 	bl	DELAY9
4468 	mov	r2, r4		/* length */
4469 	mov	r1, r5		/* dest address */
4470 	mov	r0, #2		/* bytes to transfer in command */
4471 	bl	NVRAM_XFER2
4472 	ldmia	sp!, {r4, r5, lr}
4473 	bx	lr
4474 .endfunc
4475 
4476 .func NVRAM_Xfer2, NVRAM_XFER2
4477 NVRAM_XFER2:
4478 	stmdb	sp!, {r4, r5, r6, lr}
4479 	ldr	r4, =SP_BASE
4480 	mov	r3, #0
4481 	cmp	r0, #0
4482 	bls	_local2
4483 	ldr	r5, =NVRAM_SCRATCH
4484 _local4:
4485 	ldrb	r6, [r5, r3]
4486 	str	r6, [r4, #SP_TDR]
4487 _local3:
4488 	ldr	r6, [r4, #SP_SR]
4489 	tst	r6, #SP_TDRE
4490 	beq	_local3
4491 	add	r3, r3, #1
4492 	cmp	r3, r0 /* r0 is # of bytes to send out (command+addr) */
4493 	blo	_local4
4494 _local2:
4495 	mov	r3, #SPI_8CLOCKS
4496 	str	r3, [r4, #SP_TDR]
4497 	ldr	r0, [r4, #SP_RDR]
4498 _local5:
4499 	ldr	r0, [r4, #SP_SR]
4500 	tst	r0, #SP_RDRF
4501 	beq	_local5
4502 	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 */
4503 	mov	r0, #0
4504 	cmp	r2, #0  /* r2 is # of bytes to copy in */
4505 	bls	_local6
4506 _local7:
4507 	ldr	r5, [r4, #SP_SR]
4508 	tst	r5, #SP_TDRE
4509 	beq	_local7
4510 	str	r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
4511 _local8:
4512 	ldr	r5, [r4, #SP_SR]
4513 	tst	r5, #SP_RDRF
4514 	beq	_local8
4515 	ldr	r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4516 	strb	r5, [r1], #1 /* postindexed */
4517 	add	r0, r0, #1
4518 	cmp	r0, r2
4519 	blo	_local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4520 _local6:
4521 	mov	r0, #200
4522 	bl	DELAY9
4523 	ldmia	sp!, {r4, r5, r6, lr}
4524 	bx	lr
4525 #endif
4526