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