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