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