Merge ../linus
[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                 /* Add quality statistics */
2347                 iwe.cmd = IWEVQUAL;
2348                 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2349                 iwe.u.qual.qual  = iwe.u.qual.level;
2350                 /* iwe.u.qual.noise  = SOMETHING */
2351                 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
2352
2353
2354                 iwe.cmd = SIOCGIWENCODE;
2355                 if (priv->BSSinfo[i].UsingWEP)
2356                         iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2357                 else
2358                         iwe.u.data.flags = IW_ENCODE_DISABLED;
2359                 iwe.u.data.length = 0;
2360                 current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
2361         }
2362
2363         /* Length of data */
2364         dwrq->length = (current_ev - extra);
2365         dwrq->flags = 0;
2366
2367         return 0;
2368 }
2369
2370 static int atmel_get_range(struct net_device *dev,
2371                            struct iw_request_info *info,
2372                            struct iw_point *dwrq,
2373                            char *extra)
2374 {
2375         struct atmel_private *priv = netdev_priv(dev);
2376         struct iw_range *range = (struct iw_range *) extra;
2377         int k, i, j;
2378
2379         dwrq->length = sizeof(struct iw_range);
2380         memset(range, 0, sizeof(struct iw_range));
2381         range->min_nwid = 0x0000;
2382         range->max_nwid = 0x0000;
2383         range->num_channels = 0;
2384         for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2385                 if (priv->reg_domain == channel_table[j].reg_domain) {
2386                         range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2387                         break;
2388                 }
2389         if (range->num_channels != 0) {
2390                 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2391                         range->freq[k].i = i; /* List index */
2392                         range->freq[k].m = frequency_list[i - 1] * 100000;
2393                         range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
2394                 }
2395                 range->num_frequency = k;
2396         }
2397
2398         range->max_qual.qual = 100;
2399         range->max_qual.level = 100;
2400         range->max_qual.noise = 0;
2401         range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2402
2403         range->avg_qual.qual = 50;
2404         range->avg_qual.level = 50;
2405         range->avg_qual.noise = 0;
2406         range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2407
2408         range->sensitivity = 0;
2409
2410         range->bitrate[0] =  1000000;
2411         range->bitrate[1] =  2000000;
2412         range->bitrate[2] =  5500000;
2413         range->bitrate[3] = 11000000;
2414         range->num_bitrates = 4;
2415
2416         range->min_rts = 0;
2417         range->max_rts = 2347;
2418         range->min_frag = 256;
2419         range->max_frag = 2346;
2420
2421         range->encoding_size[0] = 5;
2422         range->encoding_size[1] = 13;
2423         range->num_encoding_sizes = 2;
2424         range->max_encoding_tokens = 4;
2425
2426         range->pmp_flags = IW_POWER_ON;
2427         range->pmt_flags = IW_POWER_ON;
2428         range->pm_capa = 0;
2429
2430         range->we_version_source = WIRELESS_EXT;
2431         range->we_version_compiled = WIRELESS_EXT;
2432         range->retry_capa = IW_RETRY_LIMIT ;
2433         range->retry_flags = IW_RETRY_LIMIT;
2434         range->r_time_flags = 0;
2435         range->min_retry = 1;
2436         range->max_retry = 65535;
2437
2438         return 0;
2439 }
2440
2441 static int atmel_set_wap(struct net_device *dev,
2442                          struct iw_request_info *info,
2443                          struct sockaddr *awrq,
2444                          char *extra)
2445 {
2446         struct atmel_private *priv = netdev_priv(dev);
2447         int i;
2448         static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2449         static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2450         unsigned long flags;
2451
2452         if (awrq->sa_family != ARPHRD_ETHER)
2453                 return -EINVAL;
2454
2455         if (!memcmp(any, awrq->sa_data, 6) ||
2456             !memcmp(off, awrq->sa_data, 6)) {
2457                 del_timer_sync(&priv->management_timer);
2458                 spin_lock_irqsave(&priv->irqlock, flags);
2459                 atmel_scan(priv, 1);
2460                 spin_unlock_irqrestore(&priv->irqlock, flags);
2461                 return 0;
2462         }
2463
2464         for (i = 0; i < priv->BSS_list_entries; i++) {
2465                 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2466                         if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2467                                 return -EINVAL;
2468                         } else if  (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2469                                 return -EINVAL;
2470                         } else {
2471                                 del_timer_sync(&priv->management_timer);
2472                                 spin_lock_irqsave(&priv->irqlock, flags);
2473                                 atmel_join_bss(priv, i);
2474                                 spin_unlock_irqrestore(&priv->irqlock, flags);
2475                                 return 0;
2476                         }
2477                 }
2478         }
2479
2480         return -EINVAL;
2481 }
2482
2483 static int atmel_config_commit(struct net_device *dev,
2484                                struct iw_request_info *info,    /* NULL */
2485                                void *zwrq,                      /* NULL */
2486                                char *extra)                     /* NULL */
2487 {
2488         return atmel_open(dev);
2489 }
2490
2491 static const iw_handler atmel_handler[] =
2492 {
2493         (iw_handler) atmel_config_commit,       /* SIOCSIWCOMMIT */
2494         (iw_handler) atmel_get_name,            /* SIOCGIWNAME */
2495         (iw_handler) NULL,                      /* SIOCSIWNWID */
2496         (iw_handler) NULL,                      /* SIOCGIWNWID */
2497         (iw_handler) atmel_set_freq,            /* SIOCSIWFREQ */
2498         (iw_handler) atmel_get_freq,            /* SIOCGIWFREQ */
2499         (iw_handler) atmel_set_mode,            /* SIOCSIWMODE */
2500         (iw_handler) atmel_get_mode,            /* SIOCGIWMODE */
2501         (iw_handler) NULL,                      /* SIOCSIWSENS */
2502         (iw_handler) NULL,                      /* SIOCGIWSENS */
2503         (iw_handler) NULL,                      /* SIOCSIWRANGE */
2504         (iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
2505         (iw_handler) NULL,                      /* SIOCSIWPRIV */
2506         (iw_handler) NULL,                      /* SIOCGIWPRIV */
2507         (iw_handler) NULL,                      /* SIOCSIWSTATS */
2508         (iw_handler) NULL,                      /* SIOCGIWSTATS */
2509         (iw_handler) NULL,                      /* SIOCSIWSPY */
2510         (iw_handler) NULL,                      /* SIOCGIWSPY */
2511         (iw_handler) NULL,                      /* -- hole -- */
2512         (iw_handler) NULL,                      /* -- hole -- */
2513         (iw_handler) atmel_set_wap,             /* SIOCSIWAP */
2514         (iw_handler) atmel_get_wap,             /* SIOCGIWAP */
2515         (iw_handler) NULL,                      /* -- hole -- */
2516         (iw_handler) NULL,                      /* SIOCGIWAPLIST */
2517         (iw_handler) atmel_set_scan,            /* SIOCSIWSCAN */
2518         (iw_handler) atmel_get_scan,            /* SIOCGIWSCAN */
2519         (iw_handler) atmel_set_essid,           /* SIOCSIWESSID */
2520         (iw_handler) atmel_get_essid,           /* SIOCGIWESSID */
2521         (iw_handler) NULL,                      /* SIOCSIWNICKN */
2522         (iw_handler) NULL,                      /* SIOCGIWNICKN */
2523         (iw_handler) NULL,                      /* -- hole -- */
2524         (iw_handler) NULL,                      /* -- hole -- */
2525         (iw_handler) atmel_set_rate,            /* SIOCSIWRATE */
2526         (iw_handler) atmel_get_rate,            /* SIOCGIWRATE */
2527         (iw_handler) atmel_set_rts,             /* SIOCSIWRTS */
2528         (iw_handler) atmel_get_rts,             /* SIOCGIWRTS */
2529         (iw_handler) atmel_set_frag,            /* SIOCSIWFRAG */
2530         (iw_handler) atmel_get_frag,            /* SIOCGIWFRAG */
2531         (iw_handler) NULL,                      /* SIOCSIWTXPOW */
2532         (iw_handler) NULL,                      /* SIOCGIWTXPOW */
2533         (iw_handler) atmel_set_retry,           /* SIOCSIWRETRY */
2534         (iw_handler) atmel_get_retry,           /* SIOCGIWRETRY */
2535         (iw_handler) atmel_set_encode,          /* SIOCSIWENCODE */
2536         (iw_handler) atmel_get_encode,          /* SIOCGIWENCODE */
2537         (iw_handler) atmel_set_power,           /* SIOCSIWPOWER */
2538         (iw_handler) atmel_get_power,           /* SIOCGIWPOWER */
2539         (iw_handler) NULL,                      /* -- hole -- */
2540         (iw_handler) NULL,                      /* -- hole -- */
2541         (iw_handler) NULL,                      /* SIOCSIWGENIE */
2542         (iw_handler) NULL,                      /* SIOCGIWGENIE */
2543         (iw_handler) atmel_set_auth,            /* SIOCSIWAUTH */
2544         (iw_handler) atmel_get_auth,            /* SIOCGIWAUTH */
2545         (iw_handler) atmel_set_encodeext,       /* SIOCSIWENCODEEXT */
2546         (iw_handler) atmel_get_encodeext,       /* SIOCGIWENCODEEXT */
2547         (iw_handler) NULL,                      /* SIOCSIWPMKSA */
2548 };
2549
2550 static const iw_handler atmel_private_handler[] =
2551 {
2552         NULL,                           /* SIOCIWFIRSTPRIV */
2553 };
2554
2555 typedef struct atmel_priv_ioctl {
2556         char id[32];
2557         unsigned char __user *data;
2558         unsigned short len;
2559 } atmel_priv_ioctl;
2560
2561 #define ATMELFWL        SIOCIWFIRSTPRIV
2562 #define ATMELIDIFC      ATMELFWL + 1
2563 #define ATMELRD         ATMELFWL + 2
2564 #define ATMELMAGIC 0x51807
2565 #define REGDOMAINSZ 20
2566
2567 static const struct iw_priv_args atmel_private_args[] = {
2568         {
2569                 .cmd = ATMELFWL,
2570                 .set_args = IW_PRIV_TYPE_BYTE
2571                                 | IW_PRIV_SIZE_FIXED
2572                                 | sizeof (atmel_priv_ioctl),
2573                 .get_args = IW_PRIV_TYPE_NONE,
2574                 .name = "atmelfwl"
2575         }, {
2576                 .cmd = ATMELIDIFC,
2577                 .set_args = IW_PRIV_TYPE_NONE,
2578                 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2579                 .name = "atmelidifc"
2580         }, {
2581                 .cmd = ATMELRD,
2582                 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2583                 .get_args = IW_PRIV_TYPE_NONE,
2584                 .name = "regdomain"
2585         },
2586 };
2587
2588 static const struct iw_handler_def atmel_handler_def =
2589 {
2590         .num_standard   = ARRAY_SIZE(atmel_handler),
2591         .num_private    = ARRAY_SIZE(atmel_private_handler),
2592         .num_private_args = ARRAY_SIZE(atmel_private_args),
2593         .standard       = (iw_handler *) atmel_handler,
2594         .private        = (iw_handler *) atmel_private_handler,
2595         .private_args   = (struct iw_priv_args *) atmel_private_args,
2596         .get_wireless_stats = atmel_get_wireless_stats
2597 };
2598
2599 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2600 {
2601         int i, rc = 0;
2602         struct atmel_private *priv = netdev_priv(dev);
2603         atmel_priv_ioctl com;
2604         struct iwreq *wrq = (struct iwreq *) rq;
2605         unsigned char *new_firmware;
2606         char domain[REGDOMAINSZ + 1];
2607
2608         switch (cmd) {
2609         case ATMELIDIFC:
2610                 wrq->u.param.value = ATMELMAGIC;
2611                 break;
2612
2613         case ATMELFWL:
2614                 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2615                         rc = -EFAULT;
2616                         break;
2617                 }
2618
2619                 if (!capable(CAP_NET_ADMIN)) {
2620                         rc = -EPERM;
2621                         break;
2622                 }
2623
2624                 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2625                         rc = -ENOMEM;
2626                         break;
2627                 }
2628
2629                 if (copy_from_user(new_firmware, com.data, com.len)) {
2630                         kfree(new_firmware);
2631                         rc = -EFAULT;
2632                         break;
2633                 }
2634
2635                 kfree(priv->firmware);
2636
2637                 priv->firmware = new_firmware;
2638                 priv->firmware_length = com.len;
2639                 strncpy(priv->firmware_id, com.id, 31);
2640                 priv->firmware_id[31] = '\0';
2641                 break;
2642
2643         case ATMELRD:
2644                 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2645                         rc = -EFAULT;
2646                         break;
2647                 }
2648
2649                 if (!capable(CAP_NET_ADMIN)) {
2650                         rc = -EPERM;
2651                         break;
2652                 }
2653
2654                 domain[REGDOMAINSZ] = 0;
2655                 rc = -EINVAL;
2656                 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2657                         /* strcasecmp doesn't exist in the library */
2658                         char *a = channel_table[i].name;
2659                         char *b = domain;
2660                         while (*a) {
2661                                 char c1 = *a++;
2662                                 char c2 = *b++;
2663                                 if (tolower(c1) != tolower(c2))
2664                                         break;
2665                         }
2666                         if (!*a && !*b) {
2667                                 priv->config_reg_domain = channel_table[i].reg_domain;
2668                                 rc = 0;
2669                         }
2670                 }
2671
2672                 if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2673                         rc = atmel_open(dev);
2674                 break;
2675
2676         default:
2677                 rc = -EOPNOTSUPP;
2678         }
2679
2680         return rc;
2681 }
2682
2683 struct auth_body {
2684         u16 alg;
2685         u16 trans_seq;
2686         u16 status;
2687         u8 el_id;
2688         u8 chall_text_len;
2689         u8 chall_text[253];
2690 };
2691
2692 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2693 {
2694         int old_state = priv->station_state;
2695
2696         if (new_state == old_state)
2697                 return;
2698
2699         priv->station_state = new_state;
2700
2701         if (new_state == STATION_STATE_READY) {
2702                 netif_start_queue(priv->dev);
2703                 netif_carrier_on(priv->dev);
2704         }
2705
2706         if (old_state == STATION_STATE_READY) {
2707                 netif_carrier_off(priv->dev);
2708                 if (netif_running(priv->dev))
2709                         netif_stop_queue(priv->dev);
2710                 priv->last_beacon_timestamp = 0;
2711         }
2712 }
2713
2714 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2715 {
2716         struct {
2717                 u8 BSSID[6];
2718                 u8 SSID[MAX_SSID_LENGTH];
2719                 u8 scan_type;
2720                 u8 channel;
2721                 u16 BSS_type;
2722                 u16 min_channel_time;
2723                 u16 max_channel_time;
2724                 u8 options;
2725                 u8 SSID_size;
2726         } cmd;
2727
2728         memset(cmd.BSSID, 0xff, 6);
2729
2730         if (priv->fast_scan) {
2731                 cmd.SSID_size = priv->SSID_size;
2732                 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2733                 cmd.min_channel_time = cpu_to_le16(10);
2734                 cmd.max_channel_time = cpu_to_le16(50);
2735         } else {
2736                 priv->BSS_list_entries = 0;
2737                 cmd.SSID_size = 0;
2738                 cmd.min_channel_time = cpu_to_le16(10);
2739                 cmd.max_channel_time = cpu_to_le16(120);
2740         }
2741
2742         cmd.options = 0;
2743
2744         if (!specific_ssid)
2745                 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2746
2747         cmd.channel = (priv->channel & 0x7f);
2748         cmd.scan_type = SCAN_TYPE_ACTIVE;
2749         cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2750                 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2751
2752         atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2753
2754         /* This must come after all hardware access to avoid being messed up
2755            by stuff happening in interrupt context after we leave STATE_DOWN */
2756         atmel_enter_state(priv, STATION_STATE_SCANNING);
2757 }
2758
2759 static void join(struct atmel_private *priv, int type)
2760 {
2761         struct {
2762                 u8 BSSID[6];
2763                 u8 SSID[MAX_SSID_LENGTH];
2764                 u8 BSS_type; /* this is a short in a scan command - weird */
2765                 u8 channel;
2766                 u16 timeout;
2767                 u8 SSID_size;
2768                 u8 reserved;
2769         } cmd;
2770
2771         cmd.SSID_size = priv->SSID_size;
2772         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2773         memcpy(cmd.BSSID, priv->CurrentBSSID, 6);
2774         cmd.channel = (priv->channel & 0x7f);
2775         cmd.BSS_type = type;
2776         cmd.timeout = cpu_to_le16(2000);
2777
2778         atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2779 }
2780
2781 static void start(struct atmel_private *priv, int type)
2782 {
2783         struct {
2784                 u8 BSSID[6];
2785                 u8 SSID[MAX_SSID_LENGTH];
2786                 u8 BSS_type;
2787                 u8 channel;
2788                 u8 SSID_size;
2789                 u8 reserved[3];
2790         } cmd;
2791
2792         cmd.SSID_size = priv->SSID_size;
2793         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2794         memcpy(cmd.BSSID, priv->BSSID, 6);
2795         cmd.BSS_type = type;
2796         cmd.channel = (priv->channel & 0x7f);
2797
2798         atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2799 }
2800
2801 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2802                                 u8 channel)
2803 {
2804         int rejoin = 0;
2805         int new = capability & MFIE_TYPE_POWER_CONSTRAINT ?
2806                 SHORT_PREAMBLE : LONG_PREAMBLE;
2807
2808         if (priv->preamble != new) {
2809                 priv->preamble = new;
2810                 rejoin = 1;
2811                 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2812         }
2813
2814         if (priv->channel != channel) {
2815                 priv->channel = channel;
2816                 rejoin = 1;
2817                 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2818         }
2819
2820         if (rejoin) {
2821                 priv->station_is_associated = 0;
2822                 atmel_enter_state(priv, STATION_STATE_JOINNING);
2823
2824                 if (priv->operating_mode == IW_MODE_INFRA)
2825                         join(priv, BSS_TYPE_INFRASTRUCTURE);
2826                 else
2827                         join(priv, BSS_TYPE_AD_HOC);
2828         }
2829 }
2830
2831 static void send_authentication_request(struct atmel_private *priv, u16 system,
2832                                         u8 *challenge, int challenge_len)
2833 {
2834         struct ieee80211_hdr_4addr header;
2835         struct auth_body auth;
2836
2837         header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2838         header.duration_id = cpu_to_le16(0x8000);
2839         header.seq_ctl = 0;
2840         memcpy(header.addr1, priv->CurrentBSSID, 6);
2841         memcpy(header.addr2, priv->dev->dev_addr, 6);
2842         memcpy(header.addr3, priv->CurrentBSSID, 6);
2843
2844         if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2845                 /* no WEP for authentication frames with TrSeqNo 1 */
2846                 header.frame_ctl |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2847
2848         auth.alg = cpu_to_le16(system);
2849
2850         auth.status = 0;
2851         auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2852         priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2853         priv->CurrentAuthentTransactionSeqNum += 2;
2854
2855         if (challenge_len != 0) {
2856                 auth.el_id = 16; /* challenge_text */
2857                 auth.chall_text_len = challenge_len;
2858                 memcpy(auth.chall_text, challenge, challenge_len);
2859                 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2860         } else {
2861                 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2862         }
2863 }
2864
2865 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2866 {
2867         u8 *ssid_el_p;
2868         int bodysize;
2869         struct ieee80211_hdr_4addr header;
2870         struct ass_req_format {
2871                 u16 capability;
2872                 u16 listen_interval;
2873                 u8 ap[6]; /* nothing after here directly accessible */
2874                 u8 ssid_el_id;
2875                 u8 ssid_len;
2876                 u8 ssid[MAX_SSID_LENGTH];
2877                 u8 sup_rates_el_id;
2878                 u8 sup_rates_len;
2879                 u8 rates[4];
2880         } body;
2881
2882         header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2883                 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2884         header.duration_id = cpu_to_le16(0x8000);
2885         header.seq_ctl = 0;
2886
2887         memcpy(header.addr1, priv->CurrentBSSID, 6);
2888         memcpy(header.addr2, priv->dev->dev_addr, 6);
2889         memcpy(header.addr3, priv->CurrentBSSID, 6);
2890
2891         body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2892         if (priv->wep_is_on)
2893                 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2894         if (priv->preamble == SHORT_PREAMBLE)
2895                 body.capability |= cpu_to_le16(MFIE_TYPE_POWER_CONSTRAINT);
2896
2897         body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2898
2899         /* current AP address - only in reassoc frame */
2900         if (is_reassoc) {
2901                 memcpy(body.ap, priv->CurrentBSSID, 6);
2902                 ssid_el_p = (u8 *)&body.ssid_el_id;
2903                 bodysize = 18 + priv->SSID_size;
2904         } else {
2905                 ssid_el_p = (u8 *)&body.ap[0];
2906                 bodysize = 12 + priv->SSID_size;
2907         }
2908
2909         ssid_el_p[0] = MFIE_TYPE_SSID;
2910         ssid_el_p[1] = priv->SSID_size;
2911         memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2912         ssid_el_p[2 + priv->SSID_size] = MFIE_TYPE_RATES;
2913         ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
2914         memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2915
2916         atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2917 }
2918
2919 static int is_frame_from_current_bss(struct atmel_private *priv,
2920                                      struct ieee80211_hdr_4addr *header)
2921 {
2922         if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
2923                 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2924         else
2925                 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2926 }
2927
2928 static int retrieve_bss(struct atmel_private *priv)
2929 {
2930         int i;
2931         int max_rssi = -128;
2932         int max_index = -1;
2933
2934         if (priv->BSS_list_entries == 0)
2935                 return -1;
2936
2937         if (priv->connect_to_any_BSS) {
2938                 /* Select a BSS with the max-RSSI but of the same type and of
2939                    the same WEP mode and that it is not marked as 'bad' (i.e.
2940                    we had previously failed to connect to this BSS with the
2941                    settings that we currently use) */
2942                 priv->current_BSS = 0;
2943                 for (i = 0; i < priv->BSS_list_entries; i++) {
2944                         if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2945                             ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2946                              (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2947                             !(priv->BSSinfo[i].channel & 0x80)) {
2948                                 max_rssi = priv->BSSinfo[i].RSSI;
2949                                 priv->current_BSS = max_index = i;
2950                         }
2951                 }
2952                 return max_index;
2953         }
2954
2955         for (i = 0; i < priv->BSS_list_entries; i++) {
2956                 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2957                     memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2958                     priv->operating_mode == priv->BSSinfo[i].BSStype &&
2959                     atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2960                         if (priv->BSSinfo[i].RSSI >= max_rssi) {
2961                                 max_rssi = priv->BSSinfo[i].RSSI;
2962                                 max_index = i;
2963                         }
2964                 }
2965         }
2966         return max_index;
2967 }
2968
2969 static void store_bss_info(struct atmel_private *priv,
2970                            struct ieee80211_hdr_4addr *header, u16 capability,
2971                            u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2972                            u8 *ssid, int is_beacon)
2973 {
2974         u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2975         int i, index;
2976
2977         for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2978                 if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
2979                         index = i;
2980
2981         /* If we process a probe and an entry from this BSS exists
2982            we will update the BSS entry with the info from this BSS.
2983            If we process a beacon we will only update RSSI */
2984
2985         if (index == -1) {
2986                 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2987                         return;
2988                 index = priv->BSS_list_entries++;
2989                 memcpy(priv->BSSinfo[index].BSSID, bss, 6);
2990                 priv->BSSinfo[index].RSSI = rssi;
2991         } else {
2992                 if (rssi > priv->BSSinfo[index].RSSI)
2993                         priv->BSSinfo[index].RSSI = rssi;
2994                 if (is_beacon)
2995                         return;
2996         }
2997
2998         priv->BSSinfo[index].channel = channel;
2999         priv->BSSinfo[index].beacon_period = beacon_period;
3000         priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3001         memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3002         priv->BSSinfo[index].SSIDsize = ssid_len;
3003
3004         if (capability & WLAN_CAPABILITY_IBSS)
3005                 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3006         else if (capability & WLAN_CAPABILITY_ESS)
3007                 priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
3008
3009         priv->BSSinfo[index].preamble = capability & MFIE_TYPE_POWER_CONSTRAINT ?
3010                 SHORT_PREAMBLE : LONG_PREAMBLE;
3011 }
3012
3013 static void authenticate(struct atmel_private *priv, u16 frame_len)
3014 {
3015         struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3016         u16 status = le16_to_cpu(auth->status);
3017         u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3018         u16 system = le16_to_cpu(auth->alg);
3019
3020         if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3021                 /* no WEP */
3022                 if (priv->station_was_associated) {
3023                         atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3024                         send_association_request(priv, 1);
3025                         return;
3026                 } else {
3027                         atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3028                         send_association_request(priv, 0);
3029                         return;
3030                 }
3031         }
3032
3033         if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3034                 int should_associate = 0;
3035                 /* WEP */
3036                 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3037                         return;
3038
3039                 if (system == WLAN_AUTH_OPEN) {
3040                         if (trans_seq_no == 0x0002) {
3041                                 should_associate = 1;
3042                         }
3043                 } else if (system == WLAN_AUTH_SHARED_KEY) {
3044                         if (trans_seq_no == 0x0002 &&
3045                             auth->el_id == MFIE_TYPE_CHALLENGE) {
3046                                 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3047                                 return;
3048                         } else if (trans_seq_no == 0x0004) {
3049                                 should_associate = 1;
3050                         }
3051                 }
3052
3053                 if (should_associate) {
3054                         if(priv->station_was_associated) {
3055                                 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3056                                 send_association_request(priv, 1);
3057                                 return;
3058                         } else {
3059                                 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3060                                 send_association_request(priv, 0);
3061                                 return;
3062                         }
3063                 }
3064         }
3065
3066         if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3067                 /* Do opensystem first, then try sharedkey */
3068                 if (system == WLAN_AUTH_OPEN) {
3069                         priv->CurrentAuthentTransactionSeqNum = 0x001;
3070                         priv->exclude_unencrypted = 1;
3071                         send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3072                         return;
3073                 } else if (priv->connect_to_any_BSS) {
3074                         int bss_index;
3075
3076                         priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3077
3078                         if ((bss_index  = retrieve_bss(priv)) != -1) {
3079                                 atmel_join_bss(priv, bss_index);
3080                                 return;
3081                         }
3082                 }
3083         }
3084
3085         priv->AuthenticationRequestRetryCnt = 0;
3086         atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3087         priv->station_is_associated = 0;
3088 }
3089
3090 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3091 {
3092         struct ass_resp_format {
3093                 u16 capability;
3094                 u16 status;
3095                 u16 ass_id;
3096                 u8 el_id;
3097                 u8 length;
3098                 u8 rates[4];
3099         } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3100
3101         u16 status = le16_to_cpu(ass_resp->status);
3102         u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3103         u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3104
3105         union iwreq_data wrqu;
3106
3107         if (frame_len < 8 + rates_len)
3108                 return;
3109
3110         if (status == WLAN_STATUS_SUCCESS) {
3111                 if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3112                         priv->AssociationRequestRetryCnt = 0;
3113                 else
3114                         priv->ReAssociationRequestRetryCnt = 0;
3115
3116                 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3117                                 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3118                 atmel_set_mib(priv, Phy_Mib_Type,
3119                               PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3120                 if (priv->power_mode == 0) {
3121                         priv->listen_interval = 1;
3122                         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3123                                        MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3124                         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3125                                         MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3126                 } else {
3127                         priv->listen_interval = 2;
3128                         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3129                                        MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
3130                         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3131                                         MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3132                 }
3133
3134                 priv->station_is_associated = 1;
3135                 priv->station_was_associated = 1;
3136                 atmel_enter_state(priv, STATION_STATE_READY);
3137
3138                 /* Send association event to userspace */
3139                 wrqu.data.length = 0;
3140                 wrqu.data.flags = 0;
3141                 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3142                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3143                 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3144
3145                 return;
3146         }
3147
3148         if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3149             status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3150             status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3151             priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3152                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3153                 priv->AssociationRequestRetryCnt++;
3154                 send_association_request(priv, 0);
3155                 return;
3156         }
3157
3158         if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3159             status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3160             status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3161             priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3162                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3163                 priv->ReAssociationRequestRetryCnt++;
3164                 send_association_request(priv, 1);
3165                 return;
3166         }
3167
3168         atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3169         priv->station_is_associated = 0;
3170
3171         if (priv->connect_to_any_BSS) {
3172                 int bss_index;
3173                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3174
3175                 if ((bss_index = retrieve_bss(priv)) != -1)
3176                         atmel_join_bss(priv, bss_index);
3177         }
3178 }
3179
3180 void atmel_join_bss(struct atmel_private *priv, int bss_index)
3181 {
3182         struct bss_info *bss =  &priv->BSSinfo[bss_index];
3183
3184         memcpy(priv->CurrentBSSID, bss->BSSID, 6);
3185         memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3186
3187         /* The WPA stuff cares about the current AP address */
3188         if (priv->use_wpa)
3189                 build_wpa_mib(priv);
3190
3191         /* When switching to AdHoc turn OFF Power Save if needed */
3192
3193         if (bss->BSStype == IW_MODE_ADHOC &&
3194             priv->operating_mode != IW_MODE_ADHOC &&
3195             priv->power_mode) {
3196                 priv->power_mode = 0;
3197                 priv->listen_interval = 1;
3198                 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3199                                MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
3200                 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3201                                 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3202         }
3203
3204         priv->operating_mode = bss->BSStype;
3205         priv->channel = bss->channel & 0x7f;
3206         priv->beacon_period = bss->beacon_period;
3207
3208         if (priv->preamble != bss->preamble) {
3209                 priv->preamble = bss->preamble;
3210                 atmel_set_mib8(priv, Local_Mib_Type,
3211                                LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3212         }
3213
3214         if (!priv->wep_is_on && bss->UsingWEP) {
3215                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3216                 priv->station_is_associated = 0;
3217                 return;
3218         }
3219
3220         if (priv->wep_is_on && !bss->UsingWEP) {
3221                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3222                 priv->station_is_associated = 0;
3223                 return;
3224         }
3225
3226         atmel_enter_state(priv, STATION_STATE_JOINNING);
3227
3228         if (priv->operating_mode == IW_MODE_INFRA)
3229                 join(priv, BSS_TYPE_INFRASTRUCTURE);
3230         else
3231                 join(priv, BSS_TYPE_AD_HOC);
3232 }
3233
3234 static void restart_search(struct atmel_private *priv)
3235 {
3236         int bss_index;
3237
3238         if (!priv->connect_to_any_BSS) {
3239                 atmel_scan(priv, 1);
3240         } else {
3241                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3242
3243                 if ((bss_index = retrieve_bss(priv)) != -1)
3244                         atmel_join_bss(priv, bss_index);
3245                 else
3246                         atmel_scan(priv, 0);
3247         }
3248 }
3249
3250 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3251 {
3252         u8 old = priv->wstats.qual.level;
3253         u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3254
3255         switch (priv->firmware_type) {
3256                 case ATMEL_FW_TYPE_502E:
3257                         max_rssi = 63; /* 502-rmfd-reve max by experiment */
3258                         break;
3259                 default:
3260                         break;
3261         }
3262
3263         rssi = rssi * 100 / max_rssi;
3264         if ((rssi + old) % 2)
3265                 priv->wstats.qual.level = (rssi + old) / 2 + 1;
3266         else
3267                 priv->wstats.qual.level = (rssi + old) / 2;
3268         priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3269         priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3270 }
3271
3272 static void atmel_smooth_qual(struct atmel_private *priv)
3273 {
3274         unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3275         while (time_diff--) {
3276                 priv->last_qual += HZ;
3277                 priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3278                 priv->wstats.qual.qual +=
3279                         priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3280                 priv->beacons_this_sec = 0;
3281         }
3282         priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3283         priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3284 }
3285
3286 /* deals with incoming managment frames. */
3287 static void atmel_management_frame(struct atmel_private *priv,
3288                                    struct ieee80211_hdr_4addr *header,
3289                                    u16 frame_len, u8 rssi)
3290 {
3291         u16 subtype;
3292
3293         subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE;
3294         switch (subtype) {
3295         case IEEE80211_STYPE_BEACON:
3296         case IEEE80211_STYPE_PROBE_RESP:
3297
3298                 /* beacon frame has multiple variable-length fields -
3299                    never let an engineer loose with a data structure design. */
3300                 {
3301                         struct beacon_format {
3302                                 u64 timestamp;
3303                                 u16 interval;
3304                                 u16 capability;
3305                                 u8 ssid_el_id;
3306                                 u8 ssid_length;
3307                                 /* ssid here */
3308                                 u8 rates_el_id;
3309                                 u8 rates_length;
3310                                 /* rates here */
3311                                 u8 ds_el_id;
3312                                 u8 ds_length;
3313                                 /* ds here */
3314                         } *beacon = (struct beacon_format *)priv->rx_buf;
3315
3316                         u8 channel, rates_length, ssid_length;
3317                         u64 timestamp = le64_to_cpu(beacon->timestamp);
3318                         u16 beacon_interval = le16_to_cpu(beacon->interval);
3319                         u16 capability = le16_to_cpu(beacon->capability);
3320                         u8 *beaconp = priv->rx_buf;
3321                         ssid_length = beacon->ssid_length;
3322                         /* this blows chunks. */
3323                         if (frame_len < 14 || frame_len < ssid_length + 15)
3324                                 return;
3325                         rates_length = beaconp[beacon->ssid_length + 15];
3326                         if (frame_len < ssid_length + rates_length + 18)
3327                                 return;
3328                         if (ssid_length >  MAX_SSID_LENGTH)
3329                                 return;
3330                         channel = beaconp[ssid_length + rates_length + 18];
3331
3332                         if (priv->station_state == STATION_STATE_READY) {
3333                                 smooth_rssi(priv, rssi);
3334                                 if (is_frame_from_current_bss(priv, header)) {
3335                                         priv->beacons_this_sec++;
3336                                         atmel_smooth_qual(priv);
3337                                         if (priv->last_beacon_timestamp) {
3338                                                 /* Note truncate this to 32 bits - kernel can't divide a long long */
3339                                                 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3340                                                 int beacons = beacon_delay / (beacon_interval * 1000);
3341                                                 if (beacons > 1)
3342                                                         priv->wstats.miss.beacon += beacons - 1;
3343                                         }
3344                                         priv->last_beacon_timestamp = timestamp;
3345                                         handle_beacon_probe(priv, capability, channel);
3346                                 }
3347                         }
3348
3349                         if (priv->station_state == STATION_STATE_SCANNING)
3350                                 store_bss_info(priv, header, capability,
3351                                                beacon_interval, channel, rssi,
3352                                                ssid_length,
3353                                                &beacon->rates_el_id,
3354                                                subtype == IEEE80211_STYPE_BEACON);
3355                 }
3356                 break;
3357
3358         case IEEE80211_STYPE_AUTH:
3359
3360                 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3361                         authenticate(priv, frame_len);
3362
3363                 break;
3364
3365         case IEEE80211_STYPE_ASSOC_RESP:
3366         case IEEE80211_STYPE_REASSOC_RESP:
3367
3368                 if (priv->station_state == STATION_STATE_ASSOCIATING ||
3369                     priv->station_state == STATION_STATE_REASSOCIATING)
3370                         associate(priv, frame_len, subtype);
3371
3372                 break;
3373
3374         case IEEE80211_STYPE_DISASSOC:
3375                 if (priv->station_is_associated &&
3376                     priv->operating_mode == IW_MODE_INFRA &&
3377                     is_frame_from_current_bss(priv, header)) {
3378                         priv->station_was_associated = 0;
3379                         priv->station_is_associated = 0;
3380
3381                         atmel_enter_state(priv, STATION_STATE_JOINNING);
3382                         join(priv, BSS_TYPE_INFRASTRUCTURE);
3383                 }
3384
3385                 break;
3386
3387         case IEEE80211_STYPE_DEAUTH:
3388                 if (priv->operating_mode == IW_MODE_INFRA &&
3389                     is_frame_from_current_bss(priv, header)) {
3390                         priv->station_was_associated = 0;
3391
3392                         atmel_enter_state(priv, STATION_STATE_JOINNING);
3393                         join(priv, BSS_TYPE_INFRASTRUCTURE);
3394                 }
3395
3396                 break;
3397         }
3398 }
3399
3400 /* run when timer expires */
3401 static void atmel_management_timer(u_long a)
3402 {
3403         struct net_device *dev = (struct net_device *) a;
3404         struct atmel_private *priv = netdev_priv(dev);
3405         unsigned long flags;
3406
3407         /* Check if the card has been yanked. */
3408         if (priv->card && priv->present_callback &&
3409                 !(*priv->present_callback)(priv->card))
3410                 return;
3411
3412         spin_lock_irqsave(&priv->irqlock, flags);
3413
3414         switch (priv->station_state) {
3415
3416         case STATION_STATE_AUTHENTICATING:
3417                 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3418                         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3419                         priv->station_is_associated = 0;
3420                         priv->AuthenticationRequestRetryCnt = 0;
3421                         restart_search(priv);
3422                 } else {
3423                         int auth = WLAN_AUTH_OPEN;
3424                         priv->AuthenticationRequestRetryCnt++;
3425                         priv->CurrentAuthentTransactionSeqNum = 0x0001;
3426                         mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3427                         if (priv->wep_is_on && priv->exclude_unencrypted)
3428                                 auth = WLAN_AUTH_SHARED_KEY;
3429                         send_authentication_request(priv, auth, NULL, 0);
3430           }
3431           break;
3432
3433         case STATION_STATE_ASSOCIATING:
3434                 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3435                         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3436                         priv->station_is_associated = 0;
3437                         priv->AssociationRequestRetryCnt = 0;
3438                         restart_search(priv);
3439                 } else {
3440                         priv->AssociationRequestRetryCnt++;
3441                         mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3442                         send_association_request(priv, 0);
3443                 }
3444           break;
3445
3446         case STATION_STATE_REASSOCIATING:
3447                 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3448                         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3449                         priv->station_is_associated = 0;
3450                         priv->ReAssociationRequestRetryCnt = 0;
3451                         restart_search(priv);
3452                 } else {
3453                         priv->ReAssociationRequestRetryCnt++;
3454                         mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3455                         send_association_request(priv, 1);
3456                 }
3457                 break;
3458
3459         default:
3460                 break;
3461         }
3462
3463         spin_unlock_irqrestore(&priv->irqlock, flags);
3464 }
3465
3466 static void atmel_command_irq(struct atmel_private *priv)
3467 {
3468         u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3469         u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3470         int fast_scan;
3471         union iwreq_data wrqu;
3472
3473         if (status == CMD_STATUS_IDLE ||
3474             status == CMD_STATUS_IN_PROGRESS)
3475                 return;
3476
3477         switch (command){
3478
3479         case CMD_Start:
3480                 if (status == CMD_STATUS_COMPLETE) {
3481                         priv->station_was_associated = priv->station_is_associated;
3482                         atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3483                                       (u8 *)priv->CurrentBSSID, 6);
3484                         atmel_enter_state(priv, STATION_STATE_READY);
3485                 }
3486                 break;
3487
3488         case CMD_Scan:
3489                 fast_scan = priv->fast_scan;
3490                 priv->fast_scan = 0;
3491
3492                 if (status != CMD_STATUS_COMPLETE) {
3493                         atmel_scan(priv, 1);
3494                 } else {
3495                         int bss_index = retrieve_bss(priv);
3496                         int notify_scan_complete = 1;
3497                         if (bss_index != -1) {
3498                                 atmel_join_bss(priv, bss_index);
3499                         } else if (priv->operating_mode == IW_MODE_ADHOC &&
3500                                    priv->SSID_size != 0) {
3501                                 start(priv, BSS_TYPE_AD_HOC);
3502                         } else {
3503                                 priv->fast_scan = !fast_scan;
3504                                 atmel_scan(priv, 1);
3505                                 notify_scan_complete = 0;
3506                         }
3507                         priv->site_survey_state = SITE_SURVEY_COMPLETED;
3508                         if (notify_scan_complete) {
3509                                 wrqu.data.length = 0;
3510                                 wrqu.data.flags = 0;
3511                                 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3512                         }
3513                 }
3514                 break;
3515
3516         case CMD_SiteSurvey:
3517                 priv->fast_scan = 0;
3518
3519                 if (status != CMD_STATUS_COMPLETE)
3520                         return;
3521
3522                 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3523                 if (priv->station_is_associated) {
3524                         atmel_enter_state(priv, STATION_STATE_READY);
3525                         wrqu.data.length = 0;
3526                         wrqu.data.flags = 0;
3527                         wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3528                 } else {
3529                         atmel_scan(priv, 1);
3530                 }
3531                 break;
3532
3533         case CMD_Join:
3534                 if (status == CMD_STATUS_COMPLETE) {
3535                         if (priv->operating_mode == IW_MODE_ADHOC) {
3536                                 priv->station_was_associated = priv->station_is_associated;
3537                                 atmel_enter_state(priv, STATION_STATE_READY);
3538                         } else {
3539                                 int auth = WLAN_AUTH_OPEN;
3540                                 priv->AuthenticationRequestRetryCnt = 0;
3541                                 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3542
3543                                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3544                                 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3545                                 if (priv->wep_is_on && priv->exclude_unencrypted)
3546                                         auth = WLAN_AUTH_SHARED_KEY;
3547                                 send_authentication_request(priv, auth, NULL, 0);
3548                         }
3549                         return;
3550                 }
3551
3552                 atmel_scan(priv, 1);
3553         }
3554 }
3555
3556 static int atmel_wakeup_firmware(struct atmel_private *priv)
3557 {
3558         struct host_info_struct *iface = &priv->host_info;
3559         u16 mr1, mr3;
3560         int i;
3561
3562         if (priv->card_type == CARD_TYPE_SPI_FLASH)
3563                 atmel_set_gcr(priv->dev, GCR_REMAP);
3564
3565         /* wake up on-board processor */
3566         atmel_clear_gcr(priv->dev, 0x0040);
3567         atmel_write16(priv->dev, BSR, BSS_SRAM);
3568
3569         if (priv->card_type == CARD_TYPE_SPI_FLASH)
3570                 mdelay(100);
3571
3572         /* and wait for it */
3573         for (i = LOOP_RETRY_LIMIT; i; i--) {
3574                 mr1 = atmel_read16(priv->dev, MR1);
3575                 mr3 = atmel_read16(priv->dev, MR3);
3576
3577                 if (mr3 & MAC_BOOT_COMPLETE)
3578                         break;
3579                 if (mr1 & MAC_BOOT_COMPLETE &&
3580                     priv->bus_type == BUS_TYPE_PCCARD)
3581                         break;
3582         }
3583
3584         if (i == 0) {
3585                 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3586                 return 0;
3587         }
3588
3589         if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3590                 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3591                 return 0;
3592         }
3593
3594         /* now check for completion of MAC initialization through
3595            the FunCtrl field of the IFACE, poll MR1 to detect completion of
3596            MAC initialization, check completion status, set interrupt mask,
3597            enables interrupts and calls Tx and Rx initialization functions */
3598
3599         atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3600
3601         for (i = LOOP_RETRY_LIMIT; i; i--) {
3602                 mr1 = atmel_read16(priv->dev, MR1);
3603                 mr3 = atmel_read16(priv->dev, MR3);
3604
3605                 if (mr3 & MAC_INIT_COMPLETE)
3606                         break;
3607                 if (mr1 & MAC_INIT_COMPLETE &&
3608                     priv->bus_type == BUS_TYPE_PCCARD)
3609                         break;
3610         }
3611
3612         if (i == 0) {
3613                 printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3614                                 priv->dev->name);
3615                 return 0;
3616         }
3617
3618         /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3619         if ((mr3 & MAC_INIT_COMPLETE) &&
3620             !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3621                 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3622                 return 0;
3623         }
3624         if ((mr1 & MAC_INIT_COMPLETE) &&
3625             !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3626                 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3627                 return 0;
3628         }
3629
3630         atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3631                            priv->host_info_base, sizeof(*iface));
3632
3633         iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3634         iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3635         iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3636         iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3637         iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3638         iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3639         iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3640         iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3641         iface->build_version = le16_to_cpu(iface->build_version);
3642         iface->command_pos = le16_to_cpu(iface->command_pos);
3643         iface->major_version = le16_to_cpu(iface->major_version);
3644         iface->minor_version = le16_to_cpu(iface->minor_version);
3645         iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3646         iface->mac_status = le16_to_cpu(iface->mac_status);
3647
3648         return 1;
3649 }
3650
3651 /* determine type of memory and MAC address */
3652 static int probe_atmel_card(struct net_device *dev)
3653 {
3654         int rc = 0;
3655         struct atmel_private *priv = netdev_priv(dev);
3656
3657         /* reset pccard */
3658         if (priv->bus_type == BUS_TYPE_PCCARD)
3659                 atmel_write16(dev, GCR, 0x0060);
3660
3661         atmel_write16(dev, GCR, 0x0040);
3662         mdelay(500);
3663
3664         if (atmel_read16(dev, MR2) == 0) {
3665                 /* No stored firmware so load a small stub which just
3666                    tells us the MAC address */
3667                 int i;
3668                 priv->card_type = CARD_TYPE_EEPROM;
3669                 atmel_write16(dev, BSR, BSS_IRAM);
3670                 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3671                 atmel_set_gcr(dev, GCR_REMAP);
3672                 atmel_clear_gcr(priv->dev, 0x0040);
3673                 atmel_write16(dev, BSR, BSS_SRAM);
3674                 for (i = LOOP_RETRY_LIMIT; i; i--)
3675                         if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3676                                 break;
3677                 if (i == 0) {
3678                         printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3679                 } else {
3680                         atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3681                         /* got address, now squash it again until the network
3682                            interface is opened */
3683                         if (priv->bus_type == BUS_TYPE_PCCARD)
3684                                 atmel_write16(dev, GCR, 0x0060);
3685                         atmel_write16(dev, GCR, 0x0040);
3686                         rc = 1;
3687                 }
3688         } else if (atmel_read16(dev, MR4) == 0) {
3689                 /* Mac address easy in this case. */
3690                 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3691                 atmel_write16(dev,  BSR, 1);
3692                 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3693                 atmel_write16(dev,  BSR, 0x200);
3694                 rc = 1;
3695         } else {
3696                 /* Standard firmware in flash, boot it up and ask
3697                    for the Mac Address */
3698                 priv->card_type = CARD_TYPE_SPI_FLASH;
3699                 if (atmel_wakeup_firmware(priv)) {
3700                         atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3701
3702                         /* got address, now squash it again until the network
3703                            interface is opened */
3704                         if (priv->bus_type == BUS_TYPE_PCCARD)
3705                                 atmel_write16(dev, GCR, 0x0060);
3706                         atmel_write16(dev, GCR, 0x0040);
3707                         rc = 1;
3708                 }
3709         }
3710
3711         if (rc) {
3712                 if (dev->dev_addr[0] == 0xFF) {
3713                         u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
3714                         printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3715                         memcpy(dev->dev_addr, default_mac, 6);
3716                 }
3717         }
3718
3719         return rc;
3720 }
3721
3722 /* Move the encyption information on the MIB structure.
3723    This routine is for the pre-WPA firmware: later firmware has
3724    a different format MIB and a different routine. */
3725 static void build_wep_mib(struct atmel_private *priv)
3726 {
3727         struct { /* NB this is matched to the hardware, don't change. */
3728                 u8 wep_is_on;
3729                 u8 default_key; /* 0..3 */
3730                 u8 reserved;
3731                 u8 exclude_unencrypted;
3732
3733                 u32 WEPICV_error_count;
3734                 u32 WEP_excluded_count;
3735
3736                 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3737                 u8 encryption_level; /* 0, 1, 2 */
3738                 u8 reserved2[3];
3739         } mib;
3740         int i;
3741
3742         mib.wep_is_on = priv->wep_is_on;
3743         if (priv->wep_is_on) {
3744                 if (priv->wep_key_len[priv->default_key] > 5)
3745                         mib.encryption_level = 2;
3746                 else
3747                         mib.encryption_level = 1;
3748         } else {
3749                 mib.encryption_level = 0;
3750         }
3751
3752         mib.default_key = priv->default_key;
3753         mib.exclude_unencrypted = priv->exclude_unencrypted;
3754
3755         for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3756                 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3757
3758         atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3759 }
3760
3761 static void build_wpa_mib(struct atmel_private *priv)
3762 {
3763         /* This is for the later (WPA enabled) firmware. */
3764
3765         struct { /* NB this is matched to the hardware, don't change. */
3766                 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3767                 u8 receiver_address[6];
3768                 u8 wep_is_on;
3769                 u8 default_key; /* 0..3 */
3770                 u8 group_key;
3771                 u8 exclude_unencrypted;
3772                 u8 encryption_type;
3773                 u8 reserved;
3774
3775                 u32 WEPICV_error_count;
3776                 u32 WEP_excluded_count;
3777
3778                 u8 key_RSC[4][8];
3779         } mib;
3780
3781         int i;
3782
3783         mib.wep_is_on = priv->wep_is_on;
3784         mib.exclude_unencrypted = priv->exclude_unencrypted;
3785         memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
3786
3787         /* zero all the keys before adding in valid ones. */
3788         memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3789
3790         if (priv->wep_is_on) {
3791                 /* There's a comment in the Atmel code to the effect that this
3792                    is only valid when still using WEP, it may need to be set to
3793                    something to use WPA */
3794                 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3795
3796                 mib.default_key = mib.group_key = 255;
3797                 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3798                         if (priv->wep_key_len[i] > 0) {
3799                                 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3800                                 if (i == priv->default_key) {
3801                                         mib.default_key = i;
3802                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3803                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3804                                 } else {
3805                                         mib.group_key = i;
3806                                         priv->group_cipher_suite = priv->pairwise_cipher_suite;
3807                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3808                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3809                                 }
3810                         }
3811                 }
3812                 if (mib.default_key == 255)
3813                         mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3814                 if (mib.group_key == 255)
3815                         mib.group_key = mib.default_key;
3816
3817         }
3818
3819         atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3820 }
3821
3822 static int reset_atmel_card(struct net_device *dev)
3823 {
3824         /* do everything necessary to wake up the hardware, including
3825            waiting for the lightning strike and throwing the knife switch....
3826
3827            set all the Mib values which matter in the card to match
3828            their settings in the atmel_private structure. Some of these
3829            can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3830            can only be changed by tearing down the world and coming back through
3831            here.
3832
3833            This routine is also responsible for initialising some
3834            hardware-specific fields in the atmel_private structure,
3835            including a copy of the firmware's hostinfo stucture
3836            which is the route into the rest of the firmare datastructures. */
3837
3838         struct atmel_private *priv = netdev_priv(dev);
3839         u8 configuration;
3840         int old_state = priv->station_state;
3841
3842         /* data to add to the firmware names, in priority order
3843            this implemenents firmware versioning */
3844
3845         static char *firmware_modifier[] = {
3846                 "-wpa",
3847                 "",
3848                 NULL
3849         };
3850
3851         /* reset pccard */
3852         if (priv->bus_type == BUS_TYPE_PCCARD)
3853                 atmel_write16(priv->dev, GCR, 0x0060);
3854
3855         /* stop card , disable interrupts */
3856         atmel_write16(priv->dev, GCR, 0x0040);
3857
3858         if (priv->card_type == CARD_TYPE_EEPROM) {
3859                 /* copy in firmware if needed */
3860                 const struct firmware *fw_entry = NULL;
3861                 unsigned char *fw;
3862                 int len = priv->firmware_length;
3863                 if (!(fw = priv->firmware)) {
3864                         if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3865                                 if (strlen(priv->firmware_id) == 0) {
3866                                         printk(KERN_INFO
3867                                                "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3868                                                dev->name);
3869                                         printk(KERN_INFO
3870                                                "%s: if not, use the firmware= module parameter.\n",
3871                                                dev->name);
3872                                         strcpy(priv->firmware_id, "atmel_at76c502.bin");
3873                                 }
3874                                 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
3875                                         printk(KERN_ALERT
3876                                                "%s: firmware %s is missing, cannot continue.\n",
3877                                                dev->name, priv->firmware_id);
3878                                         return 0;
3879                                 }
3880                         } else {
3881                                 int fw_index = 0;
3882                                 int success = 0;
3883
3884                                 /* get firmware filename entry based on firmware type ID */
3885                                 while (fw_table[fw_index].fw_type != priv->firmware_type
3886                                                 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3887                                         fw_index++;
3888
3889                                 /* construct the actual firmware file name */
3890                                 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3891                                         int i;
3892                                         for (i = 0; firmware_modifier[i]; i++) {
3893                                                 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3894                                                         firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3895                                                 priv->firmware_id[31] = '\0';
3896                                                 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3897                                                         success = 1;
3898                                                         break;
3899                                                 }
3900                                         }
3901                                 }
3902                                 if (!success) {
3903                                         printk(KERN_ALERT
3904                                                "%s: firmware %s is missing, cannot start.\n",
3905                                                dev->name, priv->firmware_id);
3906                                         priv->firmware_id[0] = '\0';
3907                                         return 0;
3908                                 }
3909                         }
3910
3911                         fw = fw_entry->data;
3912                         len = fw_entry->size;
3913                 }
3914
3915                 if (len <= 0x6000) {
3916                         atmel_write16(priv->dev, BSR, BSS_IRAM);
3917                         atmel_copy_to_card(priv->dev, 0, fw, len);
3918                         atmel_set_gcr(priv->dev, GCR_REMAP);
3919                 } else {
3920                         /* Remap */
3921                         atmel_set_gcr(priv->dev, GCR_REMAP);
3922                         atmel_write16(priv->dev, BSR, BSS_IRAM);
3923                         atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3924                         atmel_write16(priv->dev, BSR, 0x2ff);
3925                         atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3926                 }
3927
3928                 if (fw_entry)
3929                         release_firmware(fw_entry);
3930         }
3931
3932         if (!atmel_wakeup_firmware(priv))
3933                 return 0;
3934
3935         /* Check the version and set the correct flag for wpa stuff,
3936            old and new firmware is incompatible.
3937            The pre-wpa 3com firmware reports major version 5,
3938            the wpa 3com firmware is major version 4 and doesn't need
3939            the 3com broken-ness filter. */
3940         priv->use_wpa = (priv->host_info.major_version == 4);
3941         priv->radio_on_broken = (priv->host_info.major_version == 5);
3942
3943         /* unmask all irq sources */
3944         atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3945
3946         /* int Tx system and enable Tx */
3947         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3948         atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3949         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3950         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3951
3952         priv->tx_desc_free = priv->host_info.tx_desc_count;
3953         priv->tx_desc_head = 0;
3954         priv->tx_desc_tail = 0;
3955         priv->tx_desc_previous = 0;
3956         priv->tx_free_mem = priv->host_info.tx_buff_size;
3957         priv->tx_buff_head = 0;
3958         priv->tx_buff_tail = 0;
3959
3960         configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3961         atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3962                                    configuration | FUNC_CTRL_TxENABLE);
3963
3964         /* init Rx system and enable */
3965         priv->rx_desc_head = 0;
3966
3967         configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3968         atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3969                                    configuration | FUNC_CTRL_RxENABLE);
3970
3971         if (!priv->radio_on_broken) {
3972                 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3973                     CMD_STATUS_REJECTED_RADIO_OFF) {
3974                         printk(KERN_INFO
3975                                "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
3976                                dev->name);
3977                         return 0;
3978                 }
3979         }
3980
3981         /* set up enough MIB values to run. */
3982         atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
3983         atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
3984         atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
3985         atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
3986         atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
3987         atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
3988         atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
3989         atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
3990                       priv->dev->dev_addr, 6);
3991         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3992         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3993         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
3994         atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
3995         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
3996         if (priv->use_wpa)
3997                 build_wpa_mib(priv);
3998         else
3999                 build_wep_mib(priv);
4000
4001         if (old_state == STATION_STATE_READY)
4002         {
4003                 union iwreq_data wrqu;
4004
4005                 wrqu.data.length = 0;
4006                 wrqu.data.flags = 0;
4007                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4008                 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
4009                 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4010         }
4011
4012         return 1;
4013 }
4014
4015 static void atmel_send_command(struct atmel_private *priv, int command,
4016                                void *cmd, int cmd_size)
4017 {
4018         if (cmd)
4019                 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4020                                    cmd, cmd_size);
4021
4022         atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4023         atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4024 }
4025
4026 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4027                                    void *cmd, int cmd_size)
4028 {
4029         int i, status;
4030
4031         atmel_send_command(priv, command, cmd, cmd_size);
4032
4033         for (i = 5000; i; i--) {
4034                 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4035                 if (status != CMD_STATUS_IDLE &&
4036                     status != CMD_STATUS_IN_PROGRESS)
4037                         break;
4038                 udelay(20);
4039         }
4040
4041         if (i == 0) {
4042                 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4043                 status =  CMD_STATUS_HOST_ERROR;
4044         } else {
4045                 if (command != CMD_EnableRadio)
4046                         status = CMD_STATUS_COMPLETE;
4047         }
4048
4049         return status;
4050 }
4051
4052 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4053 {
4054         struct get_set_mib m;
4055         m.type = type;
4056         m.size = 1;
4057         m.index = index;
4058
4059         atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4060         return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4061 }
4062
4063 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4064 {
4065         struct get_set_mib m;
4066         m.type = type;
4067         m.size = 1;
4068         m.index = index;
4069         m.data[0] = data;
4070
4071         atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4072 }
4073
4074 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4075                             u16 data)
4076 {
4077         struct get_set_mib m;
4078         m.type = type;
4079         m.size = 2;
4080         m.index = index;
4081         m.data[0] = data;
4082         m.data[1] = data >> 8;
4083
4084         atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4085 }
4086
4087 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4088                           u8 *data, int data_len)
4089 {
4090         struct get_set_mib m;
4091         m.type = type;
4092         m.size = data_len;
4093         m.index = index;
4094
4095         if (data_len > MIB_MAX_DATA_BYTES)
4096                 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4097
4098         memcpy(m.data, data, data_len);
4099         atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4100 }
4101
4102 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4103                           u8 *data, int data_len)
4104 {
4105         struct get_set_mib m;
4106         m.type = type;
4107         m.size = data_len;
4108         m.index = index;
4109
4110         if (data_len > MIB_MAX_DATA_BYTES)
4111                 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4112
4113         atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4114         atmel_copy_to_host(priv->dev, data,
4115                            atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4116 }
4117
4118 static void atmel_writeAR(struct net_device *dev, u16 data)
4119 {
4120         int i;
4121         outw(data, dev->base_addr + AR);
4122         /* Address register appears to need some convincing..... */
4123         for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4124                 outw(data, dev->base_addr + AR);
4125 }
4126
4127 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4128                                unsigned char *src, u16 len)
4129 {
4130         int i;
4131         atmel_writeAR(dev, dest);
4132         if (dest % 2) {
4133                 atmel_write8(dev, DR, *src);
4134                 src++; len--;
4135         }
4136         for (i = len; i > 1 ; i -= 2) {
4137                 u8 lb = *src++;
4138                 u8 hb = *src++;
4139                 atmel_write16(dev, DR, lb | (hb << 8));
4140         }
4141         if (i)
4142                 atmel_write8(dev, DR, *src);
4143 }
4144
4145 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4146                                u16 src, u16 len)
4147 {
4148         int i;
4149         atmel_writeAR(dev, src);
4150         if (src % 2) {
4151                 *dest = atmel_read8(dev, DR);
4152                 dest++; len--;
4153         }
4154         for (i = len; i > 1 ; i -= 2) {
4155                 u16 hw = atmel_read16(dev, DR);
4156                 *dest++ = hw;
4157                 *dest++ = hw >> 8;
4158         }
4159         if (i)
4160                 *dest = atmel_read8(dev, DR);
4161 }
4162
4163 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4164 {
4165         outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4166 }
4167
4168 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4169 {
4170         outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4171 }
4172
4173 static int atmel_lock_mac(struct atmel_private *priv)
4174 {
4175         int i, j = 20;
4176  retry:
4177         for (i = 5000; i; i--) {
4178                 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4179                         break;
4180                 udelay(20);
4181         }
4182
4183         if (!i)
4184                 return 0; /* timed out */
4185
4186         atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4187         if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4188                 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4189                 if (!j--)
4190                         return 0; /* timed out */
4191                 goto retry;
4192         }
4193
4194         return 1;
4195 }
4196
4197 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4198 {
4199         atmel_writeAR(priv->dev, pos);
4200         atmel_write16(priv->dev, DR, data); /* card is little-endian */
4201         atmel_write16(priv->dev, DR, data >> 16);
4202 }
4203
4204 /***************************************************************************/
4205 /* There follows the source form of the MAC address reading firmware       */
4206 /***************************************************************************/
4207 #if 0
4208
4209 /* Copyright 2003 Matthew T. Russotto                                      */
4210 /* But derived from the Atmel 76C502 firmware written by Atmel and         */
4211 /* included in "atmel wireless lan drivers" package                        */
4212 /**
4213     This file is part of net.russotto.AtmelMACFW, hereto referred to
4214     as AtmelMACFW
4215
4216     AtmelMACFW is free software; you can redistribute it and/or modify
4217     it under the terms of the GNU General Public License version 2
4218     as published by the Free Software Foundation.
4219
4220     AtmelMACFW is distributed in the hope that it will be useful,
4221     but WITHOUT ANY WARRANTY; without even the implied warranty of
4222     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4223     GNU General Public License for more details.
4224
4225     You should have received a copy of the GNU General Public License
4226     along with AtmelMACFW; if not, write to the Free Software
4227     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
4228
4229 ****************************************************************************/
4230 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
4231 /* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
4232 /* It only works on SPI EEPROM versions of the card.                       */
4233
4234 /* This firmware initializes the SPI controller and clock, reads the MAC   */
4235 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
4236 /* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
4237 /* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
4238 /* MR4, for investigational purposes (maybe we can determine chip type     */
4239 /* from that?)                                                             */
4240
4241         .org 0
4242     .set MRBASE, 0x8000000
4243         .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4244         .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4245         .set SRAM_BASE,  0x02000000
4246         .set SP_BASE,    0x0F300000
4247         .set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
4248         .set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
4249         .set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
4250         .set STACK_BASE, 0x5600
4251         .set SP_SR, 0x10
4252         .set SP_TDRE, 2 /* status register bit -- TDR empty */
4253         .set SP_RDRF, 1 /* status register bit -- RDR full */
4254         .set SP_SWRST, 0x80
4255         .set SP_SPIEN, 0x1
4256         .set SP_CR, 0   /* control register */
4257         .set SP_MR, 4   /* mode register */
4258         .set SP_RDR, 0x08 /* Read Data Register */
4259         .set SP_TDR, 0x0C /* Transmit Data Register */
4260         .set SP_CSR0, 0x30 /* chip select registers */
4261         .set SP_CSR1, 0x34
4262         .set SP_CSR2, 0x38
4263         .set SP_CSR3, 0x3C
4264         .set NVRAM_CMD_RDSR, 5 /* read status register */
4265         .set NVRAM_CMD_READ, 3 /* read data */
4266         .set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
4267         .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4268                                   serial output, since SO is normally high.  But it
4269                                   does cause 8 clock cycles and thus 8 bits to be
4270                                   clocked in to the chip.  See Atmel's SPI
4271                                   controller (e.g. AT91M55800) timing and 4K
4272                                   SPI EEPROM manuals */
4273
4274         .set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
4275         .set NVRAM_IMAGE, 0x02000200
4276         .set NVRAM_LENGTH, 0x0200
4277         .set MAC_ADDRESS_MIB, SRAM_BASE
4278         .set MAC_ADDRESS_LENGTH, 6
4279         .set MAC_BOOT_FLAG, 0x10
4280         .set MR1, 0
4281         .set MR2, 4
4282         .set MR3, 8
4283         .set MR4, 0xC
4284 RESET_VECTOR:
4285         b RESET_HANDLER
4286 UNDEF_VECTOR:
4287         b HALT1
4288 SWI_VECTOR:
4289         b HALT1
4290 IABORT_VECTOR:
4291         b HALT1
4292 DABORT_VECTOR:
4293 RESERVED_VECTOR:
4294         b HALT1
4295 IRQ_VECTOR:
4296         b HALT1
4297 FIQ_VECTOR:
4298         b HALT1
4299 HALT1:  b HALT1
4300 RESET_HANDLER:
4301         mov     r0, #CPSR_INITIAL
4302         msr     CPSR_c, r0      /* This is probably unnecessary */
4303
4304 /* I'm guessing this is initializing clock generator electronics for SPI */
4305         ldr     r0, =SPI_CGEN_BASE
4306         mov     r1, #0
4307         mov     r1, r1, lsl #3
4308         orr     r1,r1, #0
4309         str     r1, [r0]
4310         ldr     r1, [r0, #28]
4311         bic     r1, r1, #16
4312         str     r1, [r0, #28]
4313         mov     r1, #1
4314         str     r1, [r0, #8]
4315
4316         ldr     r0, =MRBASE
4317         mov     r1, #0
4318         strh    r1, [r0, #MR1]
4319         strh    r1, [r0, #MR2]
4320         strh    r1, [r0, #MR3]
4321         strh    r1, [r0, #MR4]
4322
4323         mov     sp, #STACK_BASE
4324         bl      SP_INIT
4325         mov     r0, #10
4326         bl      DELAY9
4327         bl      GET_MAC_ADDR
4328         bl      GET_WHOLE_NVRAM
4329         ldr     r0, =MRBASE
4330         ldr     r1, =MAC_ADDRESS_MIB
4331         strh    r1, [r0, #MR2]
4332         ldr     r1, =NVRAM_IMAGE
4333         strh    r1, [r0, #MR4]
4334         mov     r1, #MAC_BOOT_FLAG
4335         strh    r1, [r0, #MR3]
4336 HALT2:  b HALT2
4337 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4338 GET_WHOLE_NVRAM:
4339         stmdb   sp!, {lr}
4340         mov     r2, #0 /* 0th bytes of NVRAM */
4341         mov     r3, #NVRAM_LENGTH
4342         mov     r1, #0          /* not used in routine */
4343         ldr     r0, =NVRAM_IMAGE
4344         bl      NVRAM_XFER
4345         ldmia   sp!, {lr}
4346         bx      lr
4347 .endfunc
4348
4349 .func Get_MAC_Addr, GET_MAC_ADDR
4350 GET_MAC_ADDR:
4351         stmdb   sp!, {lr}
4352         mov     r2, #0x120      /* address of MAC Address within NVRAM */
4353         mov     r3, #MAC_ADDRESS_LENGTH
4354         mov     r1, #0          /* not used in routine */
4355         ldr     r0, =MAC_ADDRESS_MIB
4356         bl      NVRAM_XFER
4357         ldmia   sp!, {lr}
4358         bx      lr
4359 .endfunc
4360 .ltorg
4361 .func Delay9, DELAY9
4362 DELAY9:
4363         adds    r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
4364 DELAYLOOP:
4365         beq     DELAY9_done
4366         subs    r0, r0, #1
4367         b       DELAYLOOP
4368 DELAY9_done:
4369         bx      lr
4370 .endfunc
4371
4372 .func SP_Init, SP_INIT
4373 SP_INIT:
4374         mov     r1, #SP_SWRST
4375         ldr     r0, =SP_BASE
4376         str     r1, [r0, #SP_CR] /* reset the SPI */
4377         mov     r1, #0
4378         str     r1, [r0, #SP_CR] /* release SPI from reset state */
4379         mov     r1, #SP_SPIEN
4380         str     r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4381         str     r1, [r0, #SP_CR] /* enable the SPI */
4382
4383 /*  My guess would be this turns on the SPI clock */
4384         ldr     r3, =SPI_CGEN_BASE
4385         ldr     r1, [r3, #28]
4386         orr     r1, r1, #0x2000
4387         str     r1, [r3, #28]
4388
4389         ldr     r1, =0x2000c01
4390         str     r1, [r0, #SP_CSR0]
4391         ldr     r1, =0x2000201
4392         str     r1, [r0, #SP_CSR1]
4393         str     r1, [r0, #SP_CSR2]
4394         str     r1, [r0, #SP_CSR3]
4395         ldr     r1, [r0, #SP_SR]
4396         ldr     r0, [r0, #SP_RDR]
4397         bx      lr
4398 .endfunc
4399 .func NVRAM_Init, NVRAM_INIT
4400 NVRAM_INIT:
4401         ldr     r1, =SP_BASE
4402         ldr     r0, [r1, #SP_RDR]
4403         mov     r0, #NVRAM_CMD_RDSR
4404         str     r0, [r1, #SP_TDR]
4405 SP_loop1:
4406         ldr     r0, [r1, #SP_SR]
4407         tst     r0, #SP_TDRE
4408         beq     SP_loop1
4409
4410         mov     r0, #SPI_8CLOCKS
4411         str     r0, [r1, #SP_TDR]
4412 SP_loop2:
4413         ldr     r0, [r1, #SP_SR]
4414         tst     r0, #SP_TDRE
4415         beq     SP_loop2
4416
4417         ldr     r0, [r1, #SP_RDR]
4418 SP_loop3:
4419         ldr     r0, [r1, #SP_SR]
4420         tst     r0, #SP_RDRF
4421         beq     SP_loop3
4422
4423         ldr     r0, [r1, #SP_RDR]
4424         and     r0, r0, #255
4425         bx      lr
4426 .endfunc
4427
4428 .func NVRAM_Xfer, NVRAM_XFER
4429         /* r0 = dest address */
4430         /* r1 = not used */
4431         /* r2 = src address within NVRAM */
4432         /* r3 = length */
4433 NVRAM_XFER:
4434         stmdb   sp!, {r4, r5, lr}
4435         mov     r5, r0          /* save r0 (dest address) */
4436         mov     r4, r3          /* save r3 (length) */
4437         mov     r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
4438         and     r0, r0, #8
4439         add     r0, r0, #NVRAM_CMD_READ
4440         ldr     r1, =NVRAM_SCRATCH
4441         strb    r0, [r1, #0]    /* save command in NVRAM_SCRATCH[0] */
4442         strb    r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
4443 _local1:
4444         bl      NVRAM_INIT
4445         tst     r0, #NVRAM_SR_RDY
4446         bne     _local1
4447         mov     r0, #20
4448         bl      DELAY9
4449         mov     r2, r4          /* length */
4450         mov     r1, r5          /* dest address */
4451         mov     r0, #2          /* bytes to transfer in command */
4452         bl      NVRAM_XFER2
4453         ldmia   sp!, {r4, r5, lr}
4454         bx      lr
4455 .endfunc
4456
4457 .func NVRAM_Xfer2, NVRAM_XFER2
4458 NVRAM_XFER2:
4459         stmdb   sp!, {r4, r5, r6, lr}
4460         ldr     r4, =SP_BASE
4461         mov     r3, #0
4462         cmp     r0, #0
4463         bls     _local2
4464         ldr     r5, =NVRAM_SCRATCH
4465 _local4:
4466         ldrb    r6, [r5, r3]
4467         str     r6, [r4, #SP_TDR]
4468 _local3:
4469         ldr     r6, [r4, #SP_SR]
4470         tst     r6, #SP_TDRE
4471         beq     _local3
4472         add     r3, r3, #1
4473         cmp     r3, r0 /* r0 is # of bytes to send out (command+addr) */
4474         blo     _local4
4475 _local2:
4476         mov     r3, #SPI_8CLOCKS
4477         str     r3, [r4, #SP_TDR]
4478         ldr     r0, [r4, #SP_RDR]
4479 _local5:
4480         ldr     r0, [r4, #SP_SR]
4481         tst     r0, #SP_RDRF
4482         beq     _local5
4483         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 */
4484         mov     r0, #0
4485         cmp     r2, #0  /* r2 is # of bytes to copy in */
4486         bls     _local6
4487 _local7:
4488         ldr     r5, [r4, #SP_SR]
4489         tst     r5, #SP_TDRE
4490         beq     _local7
4491         str     r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
4492 _local8:
4493         ldr     r5, [r4, #SP_SR]
4494         tst     r5, #SP_RDRF
4495         beq     _local8
4496         ldr     r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4497         strb    r5, [r1], #1 /* postindexed */
4498         add     r0, r0, #1
4499         cmp     r0, r2
4500         blo     _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4501 _local6:
4502         mov     r0, #200
4503         bl      DELAY9
4504         ldmia   sp!, {r4, r5, r6, lr}
4505         bx      lr
4506 #endif