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