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