misc wireless annotations
[safe/jmp/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/ptrace.h>
46 #include <linux/slab.h>
47 #include <linux/string.h>
48 #include <linux/ctype.h>
49 #include <linux/timer.h>
50 #include <asm/io.h>
51 #include <asm/system.h>
52 #include <asm/uaccess.h>
53 #include <linux/module.h>
54 #include <linux/netdevice.h>
55 #include <linux/etherdevice.h>
56 #include <linux/skbuff.h>
57 #include <linux/if_arp.h>
58 #include <linux/ioport.h>
59 #include <linux/fcntl.h>
60 #include <linux/delay.h>
61 #include <linux/wireless.h>
62 #include <net/iw_handler.h>
63 #include <linux/byteorder/generic.h>
64 #include <linux/crc32.h>
65 #include <linux/proc_fs.h>
66 #include <linux/device.h>
67 #include <linux/moduleparam.h>
68 #include <linux/firmware.h>
69 #include <net/ieee80211.h>
70 #include "atmel.h"
71
72 #define DRIVER_MAJOR 0
73 #define DRIVER_MINOR 98
74
75 MODULE_AUTHOR("Simon Kelley");
76 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
77 MODULE_LICENSE("GPL");
78 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
79
80 /* The name of the firmware file to be loaded
81    over-rides any automatic selection */
82 static char *firmware = NULL;
83 module_param(firmware, charp, 0);
84
85 /* table of firmware file names */
86 static struct {
87         AtmelFWType fw_type;
88         const char *fw_file;
89         const char *fw_file_ext;
90 } fw_table[] = {
91         { ATMEL_FW_TYPE_502,      "atmel_at76c502",      "bin" },
92         { ATMEL_FW_TYPE_502D,     "atmel_at76c502d",     "bin" },
93         { ATMEL_FW_TYPE_502E,     "atmel_at76c502e",     "bin" },
94         { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
95         { ATMEL_FW_TYPE_504,      "atmel_at76c504",      "bin" },
96         { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
97         { ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
98         { ATMEL_FW_TYPE_506,      "atmel_at76c506",      "bin" },
99         { ATMEL_FW_TYPE_NONE,      NULL,                  NULL }
100 };
101
102 #define MAX_SSID_LENGTH 32
103 #define MGMT_JIFFIES (256 * HZ / 100)
104
105 #define MAX_BSS_ENTRIES 64
106
107 /* registers */
108 #define GCR  0x00    //      (SIR0)  General Configuration Register
109 #define BSR  0x02    //      (SIR1)  Bank Switching Select Register
110 #define AR   0x04
111 #define DR   0x08
112 #define MR1  0x12    //      Mirror Register 1
113 #define MR2  0x14    //      Mirror Register 2
114 #define MR3  0x16    //      Mirror Register 3
115 #define MR4  0x18    //      Mirror Register 4
116
117 #define GPR1                            0x0c
118 #define GPR2                            0x0e
119 #define GPR3                            0x10
120 //
121 // Constants for the GCR register.
122 //
123 #define GCR_REMAP     0x0400          // Remap internal SRAM to 0
124 #define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset)
125 #define GCR_CORES     0x0060          // Core Reset (ARM and PAI are reset)
126 #define GCR_ENINT     0x0002          // Enable Interrupts
127 #define GCR_ACKINT    0x0008          // Acknowledge Interrupts
128
129 #define BSS_SRAM      0x0200          // AMBA module selection --> SRAM
130 #define BSS_IRAM      0x0100          // AMBA module selection --> IRAM
131 //
132 // Constants for the MR registers.
133 //
134 #define MAC_INIT_COMPLETE       0x0001        // MAC init has been completed
135 #define MAC_BOOT_COMPLETE       0x0010        // MAC boot has been completed
136 #define MAC_INIT_OK             0x0002        // MAC boot has been completed
137
138 #define MIB_MAX_DATA_BYTES    212
139 #define MIB_HEADER_SIZE       4    /* first four fields */
140
141 struct get_set_mib {
142         u8 type;
143         u8 size;
144         u8 index;
145         u8 reserved;
146         u8 data[MIB_MAX_DATA_BYTES];
147 };
148
149 struct rx_desc {
150         u32          Next;
151         u16          MsduPos;
152         u16          MsduSize;
153
154         u8           State;
155         u8           Status;
156         u8           Rate;
157         u8           Rssi;
158         u8           LinkQuality;
159         u8           PreambleType;
160         u16          Duration;
161         u32          RxTime;
162 };
163
164 #define RX_DESC_FLAG_VALID       0x80
165 #define RX_DESC_FLAG_CONSUMED    0x40
166 #define RX_DESC_FLAG_IDLE        0x00
167
168 #define RX_STATUS_SUCCESS        0x00
169
170 #define RX_DESC_MSDU_POS_OFFSET      4
171 #define RX_DESC_MSDU_SIZE_OFFSET     6
172 #define RX_DESC_FLAGS_OFFSET         8
173 #define RX_DESC_STATUS_OFFSET        9
174 #define RX_DESC_RSSI_OFFSET          11
175 #define RX_DESC_LINK_QUALITY_OFFSET  12
176 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
177 #define RX_DESC_DURATION_OFFSET      14
178 #define RX_DESC_RX_TIME_OFFSET       16
179
180 struct tx_desc {
181         u32       NextDescriptor;
182         u16       TxStartOfFrame;
183         u16       TxLength;
184
185         u8        TxState;
186         u8        TxStatus;
187         u8        RetryCount;
188
189         u8        TxRate;
190
191         u8        KeyIndex;
192         u8        ChiperType;
193         u8        ChipreLength;
194         u8        Reserved1;
195
196         u8        Reserved;
197         u8        PacketType;
198         u16       HostTxLength;
199 };
200
201 #define TX_DESC_NEXT_OFFSET          0
202 #define TX_DESC_POS_OFFSET           4
203 #define TX_DESC_SIZE_OFFSET          6
204 #define TX_DESC_FLAGS_OFFSET         8
205 #define TX_DESC_STATUS_OFFSET        9
206 #define TX_DESC_RETRY_OFFSET         10
207 #define TX_DESC_RATE_OFFSET          11
208 #define TX_DESC_KEY_INDEX_OFFSET     12
209 #define TX_DESC_CIPHER_TYPE_OFFSET   13
210 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
211 #define TX_DESC_PACKET_TYPE_OFFSET   17
212 #define TX_DESC_HOST_LENGTH_OFFSET   18
213
214 ///////////////////////////////////////////////////////
215 // Host-MAC interface
216 ///////////////////////////////////////////////////////
217
218 #define TX_STATUS_SUCCESS       0x00
219
220 #define TX_FIRM_OWN             0x80
221 #define TX_DONE                 0x40
222
223 #define TX_ERROR                0x01
224
225 #define TX_PACKET_TYPE_DATA     0x01
226 #define TX_PACKET_TYPE_MGMT     0x02
227
228 #define ISR_EMPTY               0x00        // no bits set in ISR
229 #define ISR_TxCOMPLETE          0x01        // packet transmitted
230 #define ISR_RxCOMPLETE          0x02        // packet received
231 #define ISR_RxFRAMELOST         0x04        // Rx Frame lost
232 #define ISR_FATAL_ERROR         0x08        // Fatal error
233 #define ISR_COMMAND_COMPLETE    0x10        // command completed
234 #define ISR_OUT_OF_RANGE        0x20        // command completed
235 #define ISR_IBSS_MERGE          0x40        // (4.1.2.30): IBSS merge
236 #define ISR_GENERIC_IRQ         0x80
237
238 #define Local_Mib_Type          0x01
239 #define Mac_Address_Mib_Type    0x02
240 #define Mac_Mib_Type            0x03
241 #define Statistics_Mib_Type     0x04
242 #define Mac_Mgmt_Mib_Type       0x05
243 #define Mac_Wep_Mib_Type        0x06
244 #define Phy_Mib_Type            0x07
245 #define Multi_Domain_MIB        0x08
246
247 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
248 #define MAC_MIB_FRAG_THRESHOLD_POS            8
249 #define MAC_MIB_RTS_THRESHOLD_POS             10
250 #define MAC_MIB_SHORT_RETRY_POS               16
251 #define MAC_MIB_LONG_RETRY_POS                17
252 #define MAC_MIB_SHORT_RETRY_LIMIT_POS         16
253 #define MAC_MGMT_MIB_BEACON_PER_POS           0
254 #define MAC_MGMT_MIB_STATION_ID_POS           6
255 #define MAC_MGMT_MIB_CUR_PRIVACY_POS          11
256 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
257 #define MAC_MGMT_MIB_PS_MODE_POS              53
258 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS      54
259 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
260 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED     57
261 #define PHY_MIB_CHANNEL_POS                   14
262 #define PHY_MIB_RATE_SET_POS                  20
263 #define PHY_MIB_REG_DOMAIN_POS                26
264 #define LOCAL_MIB_AUTO_TX_RATE_POS            3
265 #define LOCAL_MIB_SSID_SIZE                   5
266 #define LOCAL_MIB_TX_PROMISCUOUS_POS          6
267 #define LOCAL_MIB_TX_MGMT_RATE_POS            7
268 #define LOCAL_MIB_TX_CONTROL_RATE_POS         8
269 #define LOCAL_MIB_PREAMBLE_TYPE               9
270 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
271
272 #define         CMD_Set_MIB_Vars              0x01
273 #define         CMD_Get_MIB_Vars              0x02
274 #define         CMD_Scan                      0x03
275 #define         CMD_Join                      0x04
276 #define         CMD_Start                     0x05
277 #define         CMD_EnableRadio               0x06
278 #define         CMD_DisableRadio              0x07
279 #define         CMD_SiteSurvey                0x0B
280
281 #define         CMD_STATUS_IDLE                   0x00
282 #define         CMD_STATUS_COMPLETE               0x01
283 #define         CMD_STATUS_UNKNOWN                0x02
284 #define         CMD_STATUS_INVALID_PARAMETER      0x03
285 #define         CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
286 #define         CMD_STATUS_TIME_OUT               0x07
287 #define         CMD_STATUS_IN_PROGRESS            0x08
288 #define         CMD_STATUS_REJECTED_RADIO_OFF     0x09
289 #define         CMD_STATUS_HOST_ERROR             0xFF
290 #define         CMD_STATUS_BUSY                   0xFE
291
292 #define CMD_BLOCK_COMMAND_OFFSET        0
293 #define CMD_BLOCK_STATUS_OFFSET         1
294 #define CMD_BLOCK_PARAMETERS_OFFSET     4
295
296 #define SCAN_OPTIONS_SITE_SURVEY        0x80
297
298 #define MGMT_FRAME_BODY_OFFSET          24
299 #define MAX_AUTHENTICATION_RETRIES      3
300 #define MAX_ASSOCIATION_RETRIES         3
301
302 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
303
304 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
305 #define LOOP_RETRY_LIMIT   500000
306
307 #define ACTIVE_MODE     1
308 #define PS_MODE         2
309
310 #define MAX_ENCRYPTION_KEYS 4
311 #define MAX_ENCRYPTION_KEY_SIZE 40
312
313 ///////////////////////////////////////////////////////////////////////////
314 // 802.11 related definitions
315 ///////////////////////////////////////////////////////////////////////////
316
317 //
318 // Regulatory Domains
319 //
320
321 #define REG_DOMAIN_FCC          0x10    //Channels      1-11    USA
322 #define REG_DOMAIN_DOC          0x20    //Channel       1-11    Canada
323 #define REG_DOMAIN_ETSI         0x30    //Channel       1-13    Europe (ex Spain/France)
324 #define REG_DOMAIN_SPAIN        0x31    //Channel       10-11   Spain
325 #define REG_DOMAIN_FRANCE       0x32    //Channel       10-13   France
326 #define REG_DOMAIN_MKK          0x40    //Channel       14      Japan
327 #define REG_DOMAIN_MKK1         0x41    //Channel       1-14    Japan(MKK1)
328 #define REG_DOMAIN_ISRAEL       0x50    //Channel       3-9     ISRAEL
329
330 #define BSS_TYPE_AD_HOC         1
331 #define BSS_TYPE_INFRASTRUCTURE 2
332
333 #define SCAN_TYPE_ACTIVE        0
334 #define SCAN_TYPE_PASSIVE       1
335
336 #define LONG_PREAMBLE           0
337 #define SHORT_PREAMBLE          1
338 #define AUTO_PREAMBLE           2
339
340 #define DATA_FRAME_WS_HEADER_SIZE   30
341
342 /* promiscuous mode control */
343 #define PROM_MODE_OFF                   0x0
344 #define PROM_MODE_UNKNOWN               0x1
345 #define PROM_MODE_CRC_FAILED            0x2
346 #define PROM_MODE_DUPLICATED            0x4
347 #define PROM_MODE_MGMT                  0x8
348 #define PROM_MODE_CTRL                  0x10
349 #define PROM_MODE_BAD_PROTOCOL          0x20
350
351 #define IFACE_INT_STATUS_OFFSET         0
352 #define IFACE_INT_MASK_OFFSET           1
353 #define IFACE_LOCKOUT_HOST_OFFSET       2
354 #define IFACE_LOCKOUT_MAC_OFFSET        3
355 #define IFACE_FUNC_CTRL_OFFSET          28
356 #define IFACE_MAC_STAT_OFFSET           30
357 #define IFACE_GENERIC_INT_TYPE_OFFSET   32
358
359 #define CIPHER_SUITE_NONE     0
360 #define CIPHER_SUITE_WEP_64   1
361 #define CIPHER_SUITE_TKIP     2
362 #define CIPHER_SUITE_AES      3
363 #define CIPHER_SUITE_CCX      4
364 #define CIPHER_SUITE_WEP_128  5
365
366 //
367 // IFACE MACROS & definitions
368 //
369 //
370
371 // FuncCtrl field:
372 //
373 #define FUNC_CTRL_TxENABLE              0x10
374 #define FUNC_CTRL_RxENABLE              0x20
375 #define FUNC_CTRL_INIT_COMPLETE         0x01
376
377 /* A stub firmware image which reads the MAC address from NVRAM on the card.
378    For copyright information and source see the end of this file. */
379 static u8 mac_reader[] = {
380         0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
381         0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
382         0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
383         0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
384         0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
385         0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
386         0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
387         0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
388         0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
389         0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
390         0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
391         0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
392         0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
393         0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
394         0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
395         0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
396         0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
397         0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
398         0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
399         0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
400         0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
401         0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
402         0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
403         0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
404         0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
405         0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
406         0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
407         0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
408         0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
409         0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
410         0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
411         0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
412         0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
413         0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
414         0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
415         0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
416         0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
417         0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
418         0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
419         0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
420         0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
421         0x00,0x01,0x00,0x02
422 };
423
424 struct atmel_private {
425         void *card; /* Bus dependent stucture varies for PCcard */
426         int (*present_callback)(void *); /* And callback which uses it */
427         char firmware_id[32];
428         AtmelFWType firmware_type;
429         u8 *firmware;
430         int firmware_length;
431         struct timer_list management_timer;
432         struct net_device *dev;
433         struct device *sys_dev;
434         struct iw_statistics wstats;
435         struct net_device_stats stats;  // device stats
436         spinlock_t irqlock, timerlock;  // spinlocks
437         enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
438         enum {
439                 CARD_TYPE_PARALLEL_FLASH,
440                 CARD_TYPE_SPI_FLASH,
441                 CARD_TYPE_EEPROM
442         } card_type;
443         int do_rx_crc; /* If we need to CRC incoming packets */
444         int probe_crc; /* set if we don't yet know */
445         int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
446         u16 rx_desc_head;
447         u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
448         u16 tx_free_mem, tx_buff_head, tx_buff_tail;
449
450         u16 frag_seq, frag_len, frag_no;
451         u8 frag_source[6];
452
453         u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
454         u8 group_cipher_suite, pairwise_cipher_suite;
455         u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
456         int wep_key_len[MAX_ENCRYPTION_KEYS];
457         int use_wpa, radio_on_broken; /* firmware dependent stuff. */
458
459         u16 host_info_base;
460         struct host_info_struct {
461                 /* NB this is matched to the hardware, don't change. */
462                 u8 volatile int_status;
463                 u8 volatile int_mask;
464                 u8 volatile lockout_host;
465                 u8 volatile lockout_mac;
466
467                 u16 tx_buff_pos;
468                 u16 tx_buff_size;
469                 u16 tx_desc_pos;
470                 u16 tx_desc_count;
471
472                 u16 rx_buff_pos;
473                 u16 rx_buff_size;
474                 u16 rx_desc_pos;
475                 u16 rx_desc_count;
476
477                 u16 build_version;
478                 u16 command_pos;
479
480                 u16 major_version;
481                 u16 minor_version;
482
483                 u16 func_ctrl;
484                 u16 mac_status;
485                 u16 generic_IRQ_type;
486                 u8  reserved[2];
487         } host_info;
488
489         enum {
490                 STATION_STATE_SCANNING,
491                 STATION_STATE_JOINNING,
492                 STATION_STATE_AUTHENTICATING,
493                 STATION_STATE_ASSOCIATING,
494                 STATION_STATE_READY,
495                 STATION_STATE_REASSOCIATING,
496                 STATION_STATE_DOWN,
497                 STATION_STATE_MGMT_ERROR
498         } station_state;
499
500         int operating_mode, power_mode;
501         time_t last_qual;
502         int beacons_this_sec;
503         int channel;
504         int reg_domain, config_reg_domain;
505         int tx_rate;
506         int auto_tx_rate;
507         int rts_threshold;
508         int frag_threshold;
509         int long_retry, short_retry;
510         int preamble;
511         int default_beacon_period, beacon_period, listen_interval;
512         int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
513         int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
514         enum {
515                 SITE_SURVEY_IDLE,
516                 SITE_SURVEY_IN_PROGRESS,
517                 SITE_SURVEY_COMPLETED
518         } site_survey_state;
519         time_t last_survey;
520
521         int station_was_associated, station_is_associated;
522         int fast_scan;
523
524         struct bss_info {
525                 int channel;
526                 int SSIDsize;
527                 int RSSI;
528                 int UsingWEP;
529                 int preamble;
530                 int beacon_period;
531                 int BSStype;
532                 u8 BSSID[6];
533                 u8 SSID[MAX_SSID_LENGTH];
534         } BSSinfo[MAX_BSS_ENTRIES];
535         int BSS_list_entries, current_BSS;
536         int connect_to_any_BSS;
537         int SSID_size, new_SSID_size;
538         u8 CurrentBSSID[6], BSSID[6];
539         u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
540         u64 last_beacon_timestamp;
541         u8 rx_buf[MAX_WIRELESS_BODY];
542 };
543
544 static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
545
546 static const struct {
547         int reg_domain;
548         int min, max;
549         char *name;
550 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
551                       { REG_DOMAIN_DOC, 1, 11, "Canada" },
552                       { REG_DOMAIN_ETSI, 1, 13, "Europe" },
553                       { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
554                       { REG_DOMAIN_FRANCE, 10, 13, "France" },
555                       { REG_DOMAIN_MKK, 14, 14, "MKK" },
556                       { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
557                       { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
558
559 static void build_wpa_mib(struct atmel_private *priv);
560 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
561 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
562                                unsigned char *src, u16 len);
563 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
564                                u16 src, u16 len);
565 static void atmel_set_gcr(struct net_device *dev, u16 mask);
566 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
567 static int atmel_lock_mac(struct atmel_private *priv);
568 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
569 static void atmel_command_irq(struct atmel_private *priv);
570 static int atmel_validate_channel(struct atmel_private *priv, int channel);
571 static void atmel_management_frame(struct atmel_private *priv,
572                                    struct ieee80211_hdr_4addr *header,
573                                    u16 frame_len, u8 rssi);
574 static void atmel_management_timer(u_long a);
575 static void atmel_send_command(struct atmel_private *priv, int command,
576                                void *cmd, int cmd_size);
577 static int atmel_send_command_wait(struct atmel_private *priv, int command,
578                                    void *cmd, int cmd_size);
579 static void atmel_transmit_management_frame(struct atmel_private *priv,
580                                             struct ieee80211_hdr_4addr *header,
581                                             u8 *body, int body_len);
582
583 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
584 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
585                            u8 data);
586 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
587                             u16 data);
588 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
589                           u8 *data, int data_len);
590 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
591                           u8 *data, int data_len);
592 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
593 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
594 static void atmel_smooth_qual(struct atmel_private *priv);
595 static void atmel_writeAR(struct net_device *dev, u16 data);
596 static int probe_atmel_card(struct net_device *dev);
597 static int reset_atmel_card(struct net_device *dev);
598 static void atmel_enter_state(struct atmel_private *priv, int new_state);
599 int atmel_open (struct net_device *dev);
600
601 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
602 {
603         return priv->host_info_base + offset;
604 }
605
606 static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
607 {
608         return priv->host_info.command_pos + offset;
609 }
610
611 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
612 {
613         return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
614 }
615
616 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
617 {
618         return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
619 }
620
621 static inline u8 atmel_read8(struct net_device *dev, u16 offset)
622 {
623         return inb(dev->base_addr + offset);
624 }
625
626 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
627 {
628         outb(data, dev->base_addr + offset);
629 }
630
631 static inline u16 atmel_read16(struct net_device *dev, u16 offset)
632 {
633         return inw(dev->base_addr + offset);
634 }
635
636 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
637 {
638         outw(data, dev->base_addr + offset);
639 }
640
641 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
642 {
643         atmel_writeAR(priv->dev, pos);
644         return atmel_read8(priv->dev, DR);
645 }
646
647 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
648 {
649         atmel_writeAR(priv->dev, pos);
650         atmel_write8(priv->dev, DR, data);
651 }
652
653 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
654 {
655         atmel_writeAR(priv->dev, pos);
656         return atmel_read16(priv->dev, DR);
657 }
658
659 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
660 {
661         atmel_writeAR(priv->dev, pos);
662         atmel_write16(priv->dev, DR, data);
663 }
664
665 static const struct iw_handler_def atmel_handler_def;
666
667 static void tx_done_irq(struct atmel_private *priv)
668 {
669         int i;
670
671         for (i = 0;
672              atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
673                      i < priv->host_info.tx_desc_count;
674              i++) {
675                 u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
676                 u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
677                 u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
678
679                 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
680
681                 priv->tx_free_mem += msdu_size;
682                 priv->tx_desc_free++;
683
684                 if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
685                         priv->tx_buff_head = 0;
686                 else
687                         priv->tx_buff_head += msdu_size;
688
689                 if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
690                         priv->tx_desc_head++ ;
691                 else
692                         priv->tx_desc_head = 0;
693
694                 if (type == TX_PACKET_TYPE_DATA) {
695                         if (status == TX_STATUS_SUCCESS)
696                                 priv->stats.tx_packets++;
697                         else
698                                 priv->stats.tx_errors++;
699                         netif_wake_queue(priv->dev);
700                 }
701         }
702 }
703
704 static u16 find_tx_buff(struct atmel_private *priv, u16 len)
705 {
706         u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
707
708         if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
709                 return 0;
710
711         if (bottom_free >= len)
712                 return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
713
714         if (priv->tx_free_mem - bottom_free >= len) {
715                 priv->tx_buff_tail = 0;
716                 return priv->host_info.tx_buff_pos;
717         }
718
719         return 0;
720 }
721
722 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
723                                  u16 len, u16 buff, u8 type)
724 {
725         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
726         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
727         if (!priv->use_wpa)
728                 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
729         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
730         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
731         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
732         if (priv->use_wpa) {
733                 int cipher_type, cipher_length;
734                 if (is_bcast) {
735                         cipher_type = priv->group_cipher_suite;
736                         if (cipher_type == CIPHER_SUITE_WEP_64 ||
737                             cipher_type == CIPHER_SUITE_WEP_128)
738                                 cipher_length = 8;
739                         else if (cipher_type == CIPHER_SUITE_TKIP)
740                                 cipher_length = 12;
741                         else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
742                                  priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
743                                 cipher_type = priv->pairwise_cipher_suite;
744                                 cipher_length = 8;
745                         } else {
746                                 cipher_type = CIPHER_SUITE_NONE;
747                                 cipher_length = 0;
748                         }
749                 } else {
750                         cipher_type = priv->pairwise_cipher_suite;
751                         if (cipher_type == CIPHER_SUITE_WEP_64 ||
752                             cipher_type == CIPHER_SUITE_WEP_128)
753                                 cipher_length = 8;
754                         else if (cipher_type == CIPHER_SUITE_TKIP)
755                                 cipher_length = 12;
756                         else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
757                                  priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
758                                 cipher_type = priv->group_cipher_suite;
759                                 cipher_length = 8;
760                         } else {
761                                 cipher_type = CIPHER_SUITE_NONE;
762                                 cipher_length = 0;
763                         }
764                 }
765
766                 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
767                             cipher_type);
768                 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
769                             cipher_length);
770         }
771         atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
772         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
773         if (priv->tx_desc_previous != priv->tx_desc_tail)
774                 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
775         priv->tx_desc_previous = priv->tx_desc_tail;
776         if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
777                 priv->tx_desc_tail++;
778         else
779                 priv->tx_desc_tail = 0;
780         priv->tx_desc_free--;
781         priv->tx_free_mem -= len;
782 }
783
784 static int start_tx(struct sk_buff *skb, struct net_device *dev)
785 {
786         static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
787         struct atmel_private *priv = netdev_priv(dev);
788         struct ieee80211_hdr_4addr header;
789         unsigned long flags;
790         u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
791
792         if (priv->card && priv->present_callback &&
793             !(*priv->present_callback)(priv->card)) {
794                 priv->stats.tx_errors++;
795                 dev_kfree_skb(skb);
796                 return 0;
797         }
798
799         if (priv->station_state != STATION_STATE_READY) {
800                 priv->stats.tx_errors++;
801                 dev_kfree_skb(skb);
802                 return 0;
803         }
804
805         /* first ensure the timer func cannot run */
806         spin_lock_bh(&priv->timerlock);
807         /* then stop the hardware ISR */
808         spin_lock_irqsave(&priv->irqlock, flags);
809         /* nb doing the above in the opposite order will deadlock */
810
811         /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
812            12 first bytes (containing DA/SA) and put them in the appropriate
813            fields of the Wireless Header. Thus the packet length is then the
814            initial + 18 (+30-12) */
815
816         if (!(buff = find_tx_buff(priv, len + 18))) {
817                 priv->stats.tx_dropped++;
818                 spin_unlock_irqrestore(&priv->irqlock, flags);
819                 spin_unlock_bh(&priv->timerlock);
820                 netif_stop_queue(dev);
821                 return 1;
822         }
823
824         frame_ctl = IEEE80211_FTYPE_DATA;
825         header.duration_id = 0;
826         header.seq_ctl = 0;
827         if (priv->wep_is_on)
828                 frame_ctl |= IEEE80211_FCTL_PROTECTED;
829         if (priv->operating_mode == IW_MODE_ADHOC) {
830                 skb_copy_from_linear_data(skb, &header.addr1, 6);
831                 memcpy(&header.addr2, dev->dev_addr, 6);
832                 memcpy(&header.addr3, priv->BSSID, 6);
833         } else {
834                 frame_ctl |= IEEE80211_FCTL_TODS;
835                 memcpy(&header.addr1, priv->CurrentBSSID, 6);
836                 memcpy(&header.addr2, dev->dev_addr, 6);
837                 skb_copy_from_linear_data(skb, &header.addr3, 6);
838         }
839
840         if (priv->use_wpa)
841                 memcpy(&header.addr4, SNAP_RFC1024, 6);
842
843         header.frame_ctl = cpu_to_le16(frame_ctl);
844         /* Copy the wireless header into the card */
845         atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
846         /* Copy the packet sans its 802.3 header addresses which have been replaced */
847         atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
848         priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
849
850         /* low bit of first byte of destination tells us if broadcast */
851         tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
852         dev->trans_start = jiffies;
853         priv->stats.tx_bytes += len;
854
855         spin_unlock_irqrestore(&priv->irqlock, flags);
856         spin_unlock_bh(&priv->timerlock);
857         dev_kfree_skb(skb);
858
859         return 0;
860 }
861
862 static void atmel_transmit_management_frame(struct atmel_private *priv,
863                                             struct ieee80211_hdr_4addr *header,
864                                             u8 *body, int body_len)
865 {
866         u16 buff;
867         int len = MGMT_FRAME_BODY_OFFSET + body_len;
868
869         if (!(buff = find_tx_buff(priv, len)))
870                 return;
871
872         atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
873         atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
874         priv->tx_buff_tail += len;
875         tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
876 }
877
878 static void fast_rx_path(struct atmel_private *priv,
879                          struct ieee80211_hdr_4addr *header,
880                          u16 msdu_size, u16 rx_packet_loc, u32 crc)
881 {
882         /* fast path: unfragmented packet copy directly into skbuf */
883         u8 mac4[6];
884         struct sk_buff  *skb;
885         unsigned char *skbp;
886
887         /* get the final, mac 4 header field, this tells us encapsulation */
888         atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
889         msdu_size -= 6;
890
891         if (priv->do_rx_crc) {
892                 crc = crc32_le(crc, mac4, 6);
893                 msdu_size -= 4;
894         }
895
896         if (!(skb = dev_alloc_skb(msdu_size + 14))) {
897                 priv->stats.rx_dropped++;
898                 return;
899         }
900
901         skb_reserve(skb, 2);
902         skbp = skb_put(skb, msdu_size + 12);
903         atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
904
905         if (priv->do_rx_crc) {
906                 u32 netcrc;
907                 crc = crc32_le(crc, skbp + 12, msdu_size);
908                 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
909                 if ((crc ^ 0xffffffff) != netcrc) {
910                         priv->stats.rx_crc_errors++;
911                         dev_kfree_skb(skb);
912                         return;
913                 }
914         }
915
916         memcpy(skbp, header->addr1, 6); /* destination address */
917         if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
918                 memcpy(&skbp[6], header->addr3, 6);
919         else
920                 memcpy(&skbp[6], header->addr2, 6); /* source address */
921
922         priv->dev->last_rx = jiffies;
923         skb->protocol = eth_type_trans(skb, priv->dev);
924         skb->ip_summed = CHECKSUM_NONE;
925         netif_rx(skb);
926         priv->stats.rx_bytes += 12 + msdu_size;
927         priv->stats.rx_packets++;
928 }
929
930 /* Test to see if the packet in card memory at packet_loc has a valid CRC
931    It doesn't matter that this is slow: it is only used to proble the first few
932    packets. */
933 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
934 {
935         int i = msdu_size - 4;
936         u32 netcrc, crc = 0xffffffff;
937
938         if (msdu_size < 4)
939                 return 0;
940
941         atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
942
943         atmel_writeAR(priv->dev, packet_loc);
944         while (i--) {
945                 u8 octet = atmel_read8(priv->dev, DR);
946                 crc = crc32_le(crc, &octet, 1);
947         }
948
949         return (crc ^ 0xffffffff) == netcrc;
950 }
951
952 static void frag_rx_path(struct atmel_private *priv,
953                          struct ieee80211_hdr_4addr *header,
954                          u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
955                          u8 frag_no, int more_frags)
956 {
957         u8 mac4[6];
958         u8 source[6];
959         struct sk_buff *skb;
960
961         if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
962                 memcpy(source, header->addr3, 6);
963         else
964                 memcpy(source, header->addr2, 6);
965
966         rx_packet_loc += 24; /* skip header */
967
968         if (priv->do_rx_crc)
969                 msdu_size -= 4;
970
971         if (frag_no == 0) { /* first fragment */
972                 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6);
973                 msdu_size -= 6;
974                 rx_packet_loc += 6;
975
976                 if (priv->do_rx_crc)
977                         crc = crc32_le(crc, mac4, 6);
978
979                 priv->frag_seq = seq_no;
980                 priv->frag_no = 1;
981                 priv->frag_len = msdu_size;
982                 memcpy(priv->frag_source, source, 6);
983                 memcpy(&priv->rx_buf[6], source, 6);
984                 memcpy(priv->rx_buf, header->addr1, 6);
985
986                 atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
987
988                 if (priv->do_rx_crc) {
989                         u32 netcrc;
990                         crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
991                         atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
992                         if ((crc ^ 0xffffffff) != netcrc) {
993                                 priv->stats.rx_crc_errors++;
994                                 memset(priv->frag_source, 0xff, 6);
995                         }
996                 }
997
998         } else if (priv->frag_no == frag_no &&
999                    priv->frag_seq == seq_no &&
1000                    memcmp(priv->frag_source, source, 6) == 0) {
1001
1002                 atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1003                                    rx_packet_loc, msdu_size);
1004                 if (priv->do_rx_crc) {
1005                         u32 netcrc;
1006                         crc = crc32_le(crc,
1007                                        &priv->rx_buf[12 + priv->frag_len],
1008                                        msdu_size);
1009                         atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1010                         if ((crc ^ 0xffffffff) != netcrc) {
1011                                 priv->stats.rx_crc_errors++;
1012                                 memset(priv->frag_source, 0xff, 6);
1013                                 more_frags = 1; /* don't send broken assembly */
1014                         }
1015                 }
1016
1017                 priv->frag_len += msdu_size;
1018                 priv->frag_no++;
1019
1020                 if (!more_frags) { /* last one */
1021                         memset(priv->frag_source, 0xff, 6);
1022                         if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1023                                 priv->stats.rx_dropped++;
1024                         } else {
1025                                 skb_reserve(skb, 2);
1026                                 memcpy(skb_put(skb, priv->frag_len + 12),
1027                                        priv->rx_buf,
1028                                        priv->frag_len + 12);
1029                                 priv->dev->last_rx = jiffies;
1030                                 skb->protocol = eth_type_trans(skb, priv->dev);
1031                                 skb->ip_summed = CHECKSUM_NONE;
1032                                 netif_rx(skb);
1033                                 priv->stats.rx_bytes += priv->frag_len + 12;
1034                                 priv->stats.rx_packets++;
1035                         }
1036                 }
1037         } else
1038                 priv->wstats.discard.fragment++;
1039 }
1040
1041 static void rx_done_irq(struct atmel_private *priv)
1042 {
1043         int i;
1044         struct ieee80211_hdr_4addr header;
1045
1046         for (i = 0;
1047              atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1048                      i < priv->host_info.rx_desc_count;
1049              i++) {
1050
1051                 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1052                 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1053                 u32 crc = 0xffffffff;
1054
1055                 if (status != RX_STATUS_SUCCESS) {
1056                         if (status == 0xc1) /* determined by experiment */
1057                                 priv->wstats.discard.nwid++;
1058                         else
1059                                 priv->stats.rx_errors++;
1060                         goto next;
1061                 }
1062
1063                 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1064                 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1065
1066                 if (msdu_size < 30) {
1067                         priv->stats.rx_errors++;
1068                         goto next;
1069                 }
1070
1071                 /* Get header as far as end of seq_ctl */
1072                 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1073                 frame_ctl = le16_to_cpu(header.frame_ctl);
1074                 seq_control = le16_to_cpu(header.seq_ctl);
1075
1076                 /* probe for CRC use here if needed  once five packets have
1077                    arrived with the same crc status, we assume we know what's
1078                    happening and stop probing */
1079                 if (priv->probe_crc) {
1080                         if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1081                                 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1082                         } else {
1083                                 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1084                         }
1085                         if (priv->do_rx_crc) {
1086                                 if (priv->crc_ok_cnt++ > 5)
1087                                         priv->probe_crc = 0;
1088                         } else {
1089                                 if (priv->crc_ko_cnt++ > 5)
1090                                         priv->probe_crc = 0;
1091                         }
1092                 }
1093
1094                 /* don't CRC header when WEP in use */
1095                 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1096                         crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1097                 }
1098                 msdu_size -= 24; /* header */
1099
1100                 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1101                         int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1102                         u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1103                         u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1104
1105                         if (!more_fragments && packet_fragment_no == 0) {
1106                                 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1107                         } else {
1108                                 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1109                                              packet_sequence_no, packet_fragment_no, more_fragments);
1110                         }
1111                 }
1112
1113                 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1114                         /* copy rest of packet into buffer */
1115                         atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1116
1117                         /* we use the same buffer for frag reassembly and control packets */
1118                         memset(priv->frag_source, 0xff, 6);
1119
1120                         if (priv->do_rx_crc) {
1121                                 /* last 4 octets is crc */
1122                                 msdu_size -= 4;
1123                                 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1124                                 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1125                                         priv->stats.rx_crc_errors++;
1126                                         goto next;
1127                                 }
1128                         }
1129
1130                         atmel_management_frame(priv, &header, msdu_size,
1131                                                atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1132                 }
1133
1134 next:
1135                 /* release descriptor */
1136                 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1137
1138                 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1139                         priv->rx_desc_head++;
1140                 else
1141                         priv->rx_desc_head = 0;
1142         }
1143 }
1144
1145 static irqreturn_t service_interrupt(int irq, void *dev_id)
1146 {
1147         struct net_device *dev = (struct net_device *) dev_id;
1148         struct atmel_private *priv = netdev_priv(dev);
1149         u8 isr;
1150         int i = -1;
1151         static u8 irq_order[] = {
1152                 ISR_OUT_OF_RANGE,
1153                 ISR_RxCOMPLETE,
1154                 ISR_TxCOMPLETE,
1155                 ISR_RxFRAMELOST,
1156                 ISR_FATAL_ERROR,
1157                 ISR_COMMAND_COMPLETE,
1158                 ISR_IBSS_MERGE,
1159                 ISR_GENERIC_IRQ
1160         };
1161
1162         if (priv->card && priv->present_callback &&
1163             !(*priv->present_callback)(priv->card))
1164                 return IRQ_HANDLED;
1165
1166         /* In this state upper-level code assumes it can mess with
1167            the card unhampered by interrupts which may change register state.
1168            Note that even though the card shouldn't generate interrupts
1169            the inturrupt line may be shared. This allows card setup
1170            to go on without disabling interrupts for a long time. */
1171         if (priv->station_state == STATION_STATE_DOWN)
1172                 return IRQ_NONE;
1173
1174         atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1175
1176         while (1) {
1177                 if (!atmel_lock_mac(priv)) {
1178                         /* failed to contact card */
1179                         printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1180                         return IRQ_HANDLED;
1181                 }
1182
1183                 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1184                 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1185
1186                 if (!isr) {
1187                         atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1188                         return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1189                 }
1190
1191                 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1192
1193                 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1194                         if (isr & irq_order[i])
1195                                 break;
1196
1197                 if (!atmel_lock_mac(priv)) {
1198                         /* failed to contact card */
1199                         printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1200                         return IRQ_HANDLED;
1201                 }
1202
1203                 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1204                 isr ^= irq_order[i];
1205                 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1206                 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1207
1208                 switch (irq_order[i]) {
1209
1210                 case ISR_OUT_OF_RANGE:
1211                         if (priv->operating_mode == IW_MODE_INFRA &&
1212                             priv->station_state == STATION_STATE_READY) {
1213                                 priv->station_is_associated = 0;
1214                                 atmel_scan(priv, 1);
1215                         }
1216                         break;
1217
1218                 case ISR_RxFRAMELOST:
1219                         priv->wstats.discard.misc++;
1220                         /* fall through */
1221                 case ISR_RxCOMPLETE:
1222                         rx_done_irq(priv);
1223                         break;
1224
1225                 case ISR_TxCOMPLETE:
1226                         tx_done_irq(priv);
1227                         break;
1228
1229                 case ISR_FATAL_ERROR:
1230                         printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1231                         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1232                         break;
1233
1234                 case ISR_COMMAND_COMPLETE:
1235                         atmel_command_irq(priv);
1236                         break;
1237
1238                 case ISR_IBSS_MERGE:
1239                         atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1240                                       priv->CurrentBSSID, 6);
1241                         /* The WPA stuff cares about the current AP address */
1242                         if (priv->use_wpa)
1243                                 build_wpa_mib(priv);
1244                         break;
1245                 case ISR_GENERIC_IRQ:
1246                         printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1247                         break;
1248                 }
1249         }
1250 }
1251
1252 static struct net_device_stats *atmel_get_stats(struct net_device *dev)
1253 {
1254         struct atmel_private *priv = netdev_priv(dev);
1255         return &priv->stats;
1256 }
1257
1258 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1259 {
1260         struct atmel_private *priv = netdev_priv(dev);
1261
1262         /* update the link quality here in case we are seeing no beacons
1263            at all to drive the process */
1264         atmel_smooth_qual(priv);
1265
1266         priv->wstats.status = priv->station_state;
1267
1268         if (priv->operating_mode == IW_MODE_INFRA) {
1269                 if (priv->station_state != STATION_STATE_READY) {
1270                         priv->wstats.qual.qual = 0;
1271                         priv->wstats.qual.level = 0;
1272                         priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1273                                         | IW_QUAL_LEVEL_INVALID);
1274                 }
1275                 priv->wstats.qual.noise = 0;
1276                 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1277         } else {
1278                 /* Quality levels cannot be determined in ad-hoc mode,
1279                    because we can 'hear' more that one remote station. */
1280                 priv->wstats.qual.qual = 0;
1281                 priv->wstats.qual.level = 0;
1282                 priv->wstats.qual.noise = 0;
1283                 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1284                                         | IW_QUAL_LEVEL_INVALID
1285                                         | IW_QUAL_NOISE_INVALID;
1286                 priv->wstats.miss.beacon = 0;
1287         }
1288
1289         return &priv->wstats;
1290 }
1291
1292 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
1293 {
1294         if ((new_mtu < 68) || (new_mtu > 2312))
1295                 return -EINVAL;
1296         dev->mtu = new_mtu;
1297         return 0;
1298 }
1299
1300 static int atmel_set_mac_address(struct net_device *dev, void *p)
1301 {
1302         struct sockaddr *addr = p;
1303
1304         memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1305         return atmel_open(dev);
1306 }
1307
1308 EXPORT_SYMBOL(atmel_open);
1309
1310 int atmel_open(struct net_device *dev)
1311 {
1312         struct atmel_private *priv = netdev_priv(dev);
1313         int i, channel;
1314
1315         /* any scheduled timer is no longer needed and might screw things up.. */
1316         del_timer_sync(&priv->management_timer);
1317
1318         /* Interrupts will not touch the card once in this state... */
1319         priv->station_state = STATION_STATE_DOWN;
1320
1321         if (priv->new_SSID_size) {
1322                 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1323                 priv->SSID_size = priv->new_SSID_size;
1324                 priv->new_SSID_size = 0;
1325         }
1326         priv->BSS_list_entries = 0;
1327
1328         priv->AuthenticationRequestRetryCnt = 0;
1329         priv->AssociationRequestRetryCnt = 0;
1330         priv->ReAssociationRequestRetryCnt = 0;
1331         priv->CurrentAuthentTransactionSeqNum = 0x0001;
1332         priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1333
1334         priv->site_survey_state = SITE_SURVEY_IDLE;
1335         priv->station_is_associated = 0;
1336
1337         if (!reset_atmel_card(dev))
1338                 return -EAGAIN;
1339
1340         if (priv->config_reg_domain) {
1341                 priv->reg_domain = priv->config_reg_domain;
1342                 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1343         } else {
1344                 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1345                 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1346                         if (priv->reg_domain == channel_table[i].reg_domain)
1347                                 break;
1348                 if (i == ARRAY_SIZE(channel_table)) {
1349                         priv->reg_domain = REG_DOMAIN_MKK1;
1350                         printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1351                 }
1352         }
1353
1354         if ((channel = atmel_validate_channel(priv, priv->channel)))
1355                 priv->channel = channel;
1356
1357         /* this moves station_state on.... */
1358         atmel_scan(priv, 1);
1359
1360         atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1361         return 0;
1362 }
1363
1364 static int atmel_close(struct net_device *dev)
1365 {
1366         struct atmel_private *priv = netdev_priv(dev);
1367
1368         /* Send event to userspace that we are disassociating */
1369         if (priv->station_state == STATION_STATE_READY) {
1370                 union iwreq_data wrqu;
1371
1372                 wrqu.data.length = 0;
1373                 wrqu.data.flags = 0;
1374                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1375                 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1376                 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1377         }
1378
1379         atmel_enter_state(priv, STATION_STATE_DOWN);
1380
1381         if (priv->bus_type == BUS_TYPE_PCCARD)
1382                 atmel_write16(dev, GCR, 0x0060);
1383         atmel_write16(dev, GCR, 0x0040);
1384         return 0;
1385 }
1386
1387 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1388 {
1389         /* check that channel is OK, if so return zero,
1390            else return suitable default channel */
1391         int i;
1392
1393         for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1394                 if (priv->reg_domain == channel_table[i].reg_domain) {
1395                         if (channel >= channel_table[i].min &&
1396                             channel <= channel_table[i].max)
1397                                 return 0;
1398                         else
1399                                 return channel_table[i].min;
1400                 }
1401         return 0;
1402 }
1403
1404 static int atmel_proc_output (char *buf, struct atmel_private *priv)
1405 {
1406         int i;
1407         char *p = buf;
1408         char *s, *r, *c;
1409
1410         p += sprintf(p, "Driver version:\t\t%d.%d\n",
1411                      DRIVER_MAJOR, DRIVER_MINOR);
1412
1413         if (priv->station_state != STATION_STATE_DOWN) {
1414                 p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
1415                                 "Firmware location:\t",
1416                              priv->host_info.major_version,
1417                              priv->host_info.minor_version,
1418                              priv->host_info.build_version);
1419
1420                 if (priv->card_type != CARD_TYPE_EEPROM)
1421                         p += sprintf(p, "on card\n");
1422                 else if (priv->firmware)
1423                         p += sprintf(p, "%s loaded by host\n",
1424                                      priv->firmware_id);
1425                 else
1426                         p += sprintf(p, "%s loaded by hotplug\n",
1427                                      priv->firmware_id);
1428
1429                 switch (priv->card_type) {
1430                 case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
1431                 case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
1432                 case CARD_TYPE_EEPROM: c = "EEPROM"; break;
1433                 default: c = "<unknown>";
1434                 }
1435
1436                 r = "<unknown>";
1437                 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1438                         if (priv->reg_domain == channel_table[i].reg_domain)
1439                                 r = channel_table[i].name;
1440
1441                 p += sprintf(p, "MAC memory type:\t%s\n", c);
1442                 p += sprintf(p, "Regulatory domain:\t%s\n", r);
1443                 p += sprintf(p, "Host CRC checking:\t%s\n",
1444                              priv->do_rx_crc ? "On" : "Off");
1445                 p += sprintf(p, "WPA-capable firmware:\t%s\n",
1446                              priv->use_wpa ? "Yes" : "No");
1447         }
1448
1449         switch(priv->station_state) {
1450         case STATION_STATE_SCANNING: s = "Scanning"; break;
1451         case STATION_STATE_JOINNING: s = "Joining"; break;
1452         case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
1453         case STATION_STATE_ASSOCIATING: s = "Associating"; break;
1454         case STATION_STATE_READY: s = "Ready"; break;
1455         case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
1456         case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
1457         case STATION_STATE_DOWN: s = "Down"; break;
1458         default: s = "<unknown>";
1459         }
1460
1461         p += sprintf(p, "Current state:\t\t%s\n", s);
1462         return p - buf;
1463 }
1464
1465 static int atmel_read_proc(char *page, char **start, off_t off,
1466                            int count, int *eof, void *data)
1467 {
1468         struct atmel_private *priv = data;
1469         int len = atmel_proc_output (page, priv);
1470         if (len <= off+count) *eof = 1;
1471         *start = page + off;
1472         len -= off;
1473         if (len>count) len = count;
1474         if (len<0) len = 0;
1475         return len;
1476 }
1477
1478 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1479                                    const AtmelFWType fw_type,
1480                                    struct device *sys_dev,
1481                                    int (*card_present)(void *), void *card)
1482 {
1483         struct proc_dir_entry *ent;
1484         struct net_device *dev;
1485         struct atmel_private *priv;
1486         int rc;
1487         DECLARE_MAC_BUF(mac);
1488
1489         /* Create the network device object. */
1490         dev = alloc_etherdev(sizeof(*priv));
1491         if (!dev) {
1492                 printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
1493                 return NULL;
1494         }
1495         if (dev_alloc_name(dev, dev->name) < 0) {
1496                 printk(KERN_ERR "atmel: Couldn't get name!\n");
1497                 goto err_out_free;
1498         }
1499
1500         priv = netdev_priv(dev);
1501         priv->dev = dev;
1502         priv->sys_dev = sys_dev;
1503         priv->present_callback = card_present;
1504         priv->card = card;
1505         priv->firmware = NULL;
1506         priv->firmware_id[0] = '\0';
1507         priv->firmware_type = fw_type;
1508         if (firmware) /* module parameter */
1509                 strcpy(priv->firmware_id, firmware);
1510         priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1511         priv->station_state = STATION_STATE_DOWN;
1512         priv->do_rx_crc = 0;
1513         /* For PCMCIA cards, some chips need CRC, some don't
1514            so we have to probe. */
1515         if (priv->bus_type == BUS_TYPE_PCCARD) {
1516                 priv->probe_crc = 1;
1517                 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1518         } else
1519                 priv->probe_crc = 0;
1520         memset(&priv->stats, 0, sizeof(priv->stats));
1521         memset(&priv->wstats, 0, sizeof(priv->wstats));
1522         priv->last_qual = jiffies;
1523         priv->last_beacon_timestamp = 0;
1524         memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1525         memset(priv->BSSID, 0, 6);
1526         priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1527         priv->station_was_associated = 0;
1528
1529         priv->last_survey = jiffies;
1530         priv->preamble = LONG_PREAMBLE;
1531         priv->operating_mode = IW_MODE_INFRA;
1532         priv->connect_to_any_BSS = 0;
1533         priv->config_reg_domain = 0;
1534         priv->reg_domain = 0;
1535         priv->tx_rate = 3;
1536         priv->auto_tx_rate = 1;
1537         priv->channel = 4;
1538         priv->power_mode = 0;
1539         priv->SSID[0] = '\0';
1540         priv->SSID_size = 0;
1541         priv->new_SSID_size = 0;
1542         priv->frag_threshold = 2346;
1543         priv->rts_threshold = 2347;
1544         priv->short_retry = 7;
1545         priv->long_retry = 4;
1546
1547         priv->wep_is_on = 0;
1548         priv->default_key = 0;
1549         priv->encryption_level = 0;
1550         priv->exclude_unencrypted = 0;
1551         priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1552         priv->use_wpa = 0;
1553         memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1554         memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1555
1556         priv->default_beacon_period = priv->beacon_period = 100;
1557         priv->listen_interval = 1;
1558
1559         init_timer(&priv->management_timer);
1560         spin_lock_init(&priv->irqlock);
1561         spin_lock_init(&priv->timerlock);
1562         priv->management_timer.function = atmel_management_timer;
1563         priv->management_timer.data = (unsigned long) dev;
1564
1565         dev->open = atmel_open;
1566         dev->stop = atmel_close;
1567         dev->change_mtu = atmel_change_mtu;
1568         dev->set_mac_address = atmel_set_mac_address;
1569         dev->hard_start_xmit = start_tx;
1570         dev->get_stats = atmel_get_stats;
1571         dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
1572         dev->do_ioctl = atmel_ioctl;
1573         dev->irq = irq;
1574         dev->base_addr = port;
1575
1576         SET_NETDEV_DEV(dev, sys_dev);
1577
1578         if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1579                 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1580                 goto err_out_free;
1581         }
1582
1583         if (!request_region(dev->base_addr, 32,
1584                             priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
1585                 goto err_out_irq;
1586         }
1587
1588         if (register_netdev(dev))
1589                 goto err_out_res;
1590
1591         if (!probe_atmel_card(dev)){
1592                 unregister_netdev(dev);
1593                 goto err_out_res;
1594         }
1595
1596         netif_carrier_off(dev);
1597
1598         ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
1599         if (!ent)
1600                 printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1601
1602         printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %s\n",
1603                dev->name, DRIVER_MAJOR, DRIVER_MINOR, print_mac(mac, dev->dev_addr));
1604
1605         return dev;
1606
1607 err_out_res:
1608         release_region( dev->base_addr, 32);
1609 err_out_irq:
1610         free_irq(dev->irq, dev);
1611 err_out_free:
1612         free_netdev(dev);
1613         return NULL;
1614 }
1615
1616 EXPORT_SYMBOL(init_atmel_card);
1617
1618 void stop_atmel_card(struct net_device *dev)
1619 {
1620         struct atmel_private *priv = netdev_priv(dev);
1621
1622         /* put a brick on it... */
1623         if (priv->bus_type == BUS_TYPE_PCCARD)
1624                 atmel_write16(dev, GCR, 0x0060);
1625         atmel_write16(dev, GCR, 0x0040);
1626
1627         del_timer_sync(&priv->management_timer);
1628         unregister_netdev(dev);
1629         remove_proc_entry("driver/atmel", NULL);
1630         free_irq(dev->irq, dev);
1631         kfree(priv->firmware);
1632         release_region(dev->base_addr, 32);
1633         free_netdev(dev);
1634 }
1635
1636 EXPORT_SYMBOL(stop_atmel_card);
1637
1638 static int atmel_set_essid(struct net_device *dev,
1639                            struct iw_request_info *info,
1640                            struct iw_point *dwrq,
1641                            char *extra)
1642 {
1643         struct atmel_private *priv = netdev_priv(dev);
1644
1645         /* Check if we asked for `any' */
1646         if(dwrq->flags == 0) {
1647                 priv->connect_to_any_BSS = 1;
1648         } else {
1649                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1650
1651                 priv->connect_to_any_BSS = 0;
1652
1653                 /* Check the size of the string */
1654                 if (dwrq->length > MAX_SSID_LENGTH)
1655                          return -E2BIG;
1656                 if (index != 0)
1657                         return -EINVAL;
1658
1659                 memcpy(priv->new_SSID, extra, dwrq->length);
1660                 priv->new_SSID_size = dwrq->length;
1661         }
1662
1663         return -EINPROGRESS;
1664 }
1665
1666 static int atmel_get_essid(struct net_device *dev,
1667                            struct iw_request_info *info,
1668                            struct iw_point *dwrq,
1669                            char *extra)
1670 {
1671         struct atmel_private *priv = netdev_priv(dev);
1672
1673         /* Get the current SSID */
1674         if (priv->new_SSID_size != 0) {
1675                 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1676                 dwrq->length = priv->new_SSID_size;
1677         } else {
1678                 memcpy(extra, priv->SSID, priv->SSID_size);
1679                 dwrq->length = priv->SSID_size;
1680         }
1681
1682         dwrq->flags = !priv->connect_to_any_BSS; /* active */
1683
1684         return 0;
1685 }
1686
1687 static int atmel_get_wap(struct net_device *dev,
1688                          struct iw_request_info *info,
1689                          struct sockaddr *awrq,
1690                          char *extra)
1691 {
1692         struct atmel_private *priv = netdev_priv(dev);
1693         memcpy(awrq->sa_data, priv->CurrentBSSID, 6);
1694         awrq->sa_family = ARPHRD_ETHER;
1695
1696         return 0;
1697 }
1698
1699 static int atmel_set_encode(struct net_device *dev,
1700                             struct iw_request_info *info,
1701                             struct iw_point *dwrq,
1702                             char *extra)
1703 {
1704         struct atmel_private *priv = netdev_priv(dev);
1705
1706         /* Basic checking: do we have a key to set ?
1707          * Note : with the new API, it's impossible to get a NULL pointer.
1708          * Therefore, we need to check a key size == 0 instead.
1709          * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1710          * when no key is present (only change flags), but older versions
1711          * don't do it. - Jean II */
1712         if (dwrq->length > 0) {
1713                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1714                 int current_index = priv->default_key;
1715                 /* Check the size of the key */
1716                 if (dwrq->length > 13) {
1717                         return -EINVAL;
1718                 }
1719                 /* Check the index (none -> use current) */
1720                 if (index < 0 || index >= 4)
1721                         index = current_index;
1722                 else
1723                         priv->default_key = index;
1724                 /* Set the length */
1725                 if (dwrq->length > 5)
1726                         priv->wep_key_len[index] = 13;
1727                 else
1728                         if (dwrq->length > 0)
1729                                 priv->wep_key_len[index] = 5;
1730                         else
1731                                 /* Disable the key */
1732                                 priv->wep_key_len[index] = 0;
1733                 /* Check if the key is not marked as invalid */
1734                 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1735                         /* Cleanup */
1736                         memset(priv->wep_keys[index], 0, 13);
1737                         /* Copy the key in the driver */
1738                         memcpy(priv->wep_keys[index], extra, dwrq->length);
1739                 }
1740                 /* WE specify that if a valid key is set, encryption
1741                  * should be enabled (user may turn it off later)
1742                  * This is also how "iwconfig ethX key on" works */
1743                 if (index == current_index &&
1744                     priv->wep_key_len[index] > 0) {
1745                         priv->wep_is_on = 1;
1746                         priv->exclude_unencrypted = 1;
1747                         if (priv->wep_key_len[index] > 5) {
1748                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1749                                 priv->encryption_level = 2;
1750                         } else {
1751                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1752                                 priv->encryption_level = 1;
1753                         }
1754                 }
1755         } else {
1756                 /* Do we want to just set the transmit key index ? */
1757                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1758                 if (index >= 0 && index < 4) {
1759                         priv->default_key = index;
1760                 } else
1761                         /* Don't complain if only change the mode */
1762                         if (!(dwrq->flags & IW_ENCODE_MODE))
1763                                 return -EINVAL;
1764         }
1765         /* Read the flags */
1766         if (dwrq->flags & IW_ENCODE_DISABLED) {
1767                 priv->wep_is_on = 0;
1768                 priv->encryption_level = 0;
1769                 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1770         } else {
1771                 priv->wep_is_on = 1;
1772                 if (priv->wep_key_len[priv->default_key] > 5) {
1773                         priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1774                         priv->encryption_level = 2;
1775                 } else {
1776                         priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1777                         priv->encryption_level = 1;
1778                 }
1779         }
1780         if (dwrq->flags & IW_ENCODE_RESTRICTED)
1781                 priv->exclude_unencrypted = 1;
1782         if(dwrq->flags & IW_ENCODE_OPEN)
1783                 priv->exclude_unencrypted = 0;
1784
1785         return -EINPROGRESS;            /* Call commit handler */
1786 }
1787
1788 static int atmel_get_encode(struct net_device *dev,
1789                             struct iw_request_info *info,
1790                             struct iw_point *dwrq,
1791                             char *extra)
1792 {
1793         struct atmel_private *priv = netdev_priv(dev);
1794         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1795
1796         if (!priv->wep_is_on)
1797                 dwrq->flags = IW_ENCODE_DISABLED;
1798         else {
1799                 if (priv->exclude_unencrypted)
1800                         dwrq->flags = IW_ENCODE_RESTRICTED;
1801                 else
1802                         dwrq->flags = IW_ENCODE_OPEN;
1803         }
1804                 /* Which key do we want ? -1 -> tx index */
1805         if (index < 0 || index >= 4)
1806                 index = priv->default_key;
1807         dwrq->flags |= index + 1;
1808         /* Copy the key to the user buffer */
1809         dwrq->length = priv->wep_key_len[index];
1810         if (dwrq->length > 16) {
1811                 dwrq->length=0;
1812         } else {
1813                 memset(extra, 0, 16);
1814                 memcpy(extra, priv->wep_keys[index], dwrq->length);
1815         }
1816
1817         return 0;
1818 }
1819
1820 static int atmel_set_encodeext(struct net_device *dev,
1821                             struct iw_request_info *info,
1822                             union iwreq_data *wrqu,
1823                             char *extra)
1824 {
1825         struct atmel_private *priv = netdev_priv(dev);
1826         struct iw_point *encoding = &wrqu->encoding;
1827         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1828         int idx, key_len, alg = ext->alg, set_key = 1;
1829
1830         /* Determine and validate the key index */
1831         idx = encoding->flags & IW_ENCODE_INDEX;
1832         if (idx) {
1833                 if (idx < 1 || idx > WEP_KEYS)
1834                         return -EINVAL;
1835                 idx--;
1836         } else
1837                 idx = priv->default_key;
1838
1839         if (encoding->flags & IW_ENCODE_DISABLED)
1840             alg = IW_ENCODE_ALG_NONE;
1841
1842         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1843                 priv->default_key = idx;
1844                 set_key = ext->key_len > 0 ? 1 : 0;
1845         }
1846
1847         if (set_key) {
1848                 /* Set the requested key first */
1849                 switch (alg) {
1850                 case IW_ENCODE_ALG_NONE:
1851                         priv->wep_is_on = 0;
1852                         priv->encryption_level = 0;
1853                         priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1854                         break;
1855                 case IW_ENCODE_ALG_WEP:
1856                         if (ext->key_len > 5) {
1857                                 priv->wep_key_len[idx] = 13;
1858                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1859                                 priv->encryption_level = 2;
1860                         } else if (ext->key_len > 0) {
1861                                 priv->wep_key_len[idx] = 5;
1862                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1863                                 priv->encryption_level = 1;
1864                         } else {
1865                                 return -EINVAL;
1866                         }
1867                         priv->wep_is_on = 1;
1868                         memset(priv->wep_keys[idx], 0, 13);
1869                         key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1870                         memcpy(priv->wep_keys[idx], ext->key, key_len);
1871                         break;
1872                 default:
1873                         return -EINVAL;
1874                 }
1875         }
1876
1877         return -EINPROGRESS;
1878 }
1879
1880 static int atmel_get_encodeext(struct net_device *dev,
1881                             struct iw_request_info *info,
1882                             union iwreq_data *wrqu,
1883                             char *extra)
1884 {
1885         struct atmel_private *priv = netdev_priv(dev);
1886         struct iw_point *encoding = &wrqu->encoding;
1887         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1888         int idx, max_key_len;
1889
1890         max_key_len = encoding->length - sizeof(*ext);
1891         if (max_key_len < 0)
1892                 return -EINVAL;
1893
1894         idx = encoding->flags & IW_ENCODE_INDEX;
1895         if (idx) {
1896                 if (idx < 1 || idx > WEP_KEYS)
1897                         return -EINVAL;
1898                 idx--;
1899         } else
1900                 idx = priv->default_key;
1901
1902         encoding->flags = idx + 1;
1903         memset(ext, 0, sizeof(*ext));
1904
1905         if (!priv->wep_is_on) {
1906                 ext->alg = IW_ENCODE_ALG_NONE;
1907                 ext->key_len = 0;
1908                 encoding->flags |= IW_ENCODE_DISABLED;
1909         } else {
1910                 if (priv->encryption_level > 0)
1911                         ext->alg = IW_ENCODE_ALG_WEP;
1912                 else
1913                         return -EINVAL;
1914
1915                 ext->key_len = priv->wep_key_len[idx];
1916                 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1917                 encoding->flags |= IW_ENCODE_ENABLED;
1918         }
1919
1920         return 0;
1921 }
1922
1923 static int atmel_set_auth(struct net_device *dev,
1924                                struct iw_request_info *info,
1925                                union iwreq_data *wrqu, char *extra)
1926 {
1927         struct atmel_private *priv = netdev_priv(dev);
1928         struct iw_param *param = &wrqu->param;
1929
1930         switch (param->flags & IW_AUTH_INDEX) {
1931         case IW_AUTH_WPA_VERSION:
1932         case IW_AUTH_CIPHER_PAIRWISE:
1933         case IW_AUTH_CIPHER_GROUP:
1934         case IW_AUTH_KEY_MGMT:
1935         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1936         case IW_AUTH_PRIVACY_INVOKED:
1937                 /*
1938                  * atmel does not use these parameters
1939                  */
1940                 break;
1941
1942         case IW_AUTH_DROP_UNENCRYPTED:
1943                 priv->exclude_unencrypted = param->value ? 1 : 0;
1944                 break;
1945
1946         case IW_AUTH_80211_AUTH_ALG: {
1947                         if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1948                                 priv->exclude_unencrypted = 1;
1949                         } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1950                                 priv->exclude_unencrypted = 0;
1951                         } else
1952                                 return -EINVAL;
1953                         break;
1954                 }
1955
1956         case IW_AUTH_WPA_ENABLED:
1957                 /* Silently accept disable of WPA */
1958                 if (param->value > 0)
1959                         return -EOPNOTSUPP;
1960                 break;
1961
1962         default:
1963                 return -EOPNOTSUPP;
1964         }
1965         return -EINPROGRESS;
1966 }
1967
1968 static int atmel_get_auth(struct net_device *dev,
1969                                struct iw_request_info *info,
1970                                union iwreq_data *wrqu, char *extra)
1971 {
1972         struct atmel_private *priv = netdev_priv(dev);
1973         struct iw_param *param = &wrqu->param;
1974
1975         switch (param->flags & IW_AUTH_INDEX) {
1976         case IW_AUTH_DROP_UNENCRYPTED:
1977                 param->value = priv->exclude_unencrypted;
1978                 break;
1979
1980         case IW_AUTH_80211_AUTH_ALG:
1981                 if (priv->exclude_unencrypted == 1)
1982                         param->value = IW_AUTH_ALG_SHARED_KEY;
1983                 else
1984                         param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1985                 break;
1986
1987         case IW_AUTH_WPA_ENABLED:
1988                 param->value = 0;
1989                 break;
1990
1991         default:
1992                 return -EOPNOTSUPP;
1993         }
1994         return 0;
1995 }
1996
1997
1998 static int atmel_get_name(struct net_device *dev,
1999                           struct iw_request_info *info,
2000                           char *cwrq,
2001                           char *extra)
2002 {
2003         strcpy(cwrq, "IEEE 802.11-DS");
2004         return 0;
2005 }
2006
2007 static int atmel_set_rate(struct net_device *dev,
2008                           struct iw_request_info *info,
2009                           struct iw_param *vwrq,
2010                           char *extra)
2011 {
2012         struct atmel_private *priv = netdev_priv(dev);
2013
2014         if (vwrq->fixed == 0) {
2015                 priv->tx_rate = 3;
2016                 priv->auto_tx_rate = 1;
2017         } else {
2018                 priv->auto_tx_rate = 0;
2019
2020                 /* Which type of value ? */
2021                 if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2022                         /* Setting by rate index */
2023                         priv->tx_rate = vwrq->value;
2024                 } else {
2025                 /* Setting by frequency value */
2026                         switch (vwrq->value) {
2027                         case  1000000: priv->tx_rate = 0; break;
2028                         case  2000000: priv->tx_rate = 1; break;
2029                         case  5500000: priv->tx_rate = 2; break;
2030                         case 11000000: priv->tx_rate = 3; break;
2031                         default: return -EINVAL;
2032                         }
2033                 }
2034         }
2035
2036         return -EINPROGRESS;
2037 }
2038
2039 static int atmel_set_mode(struct net_device *dev,
2040                           struct iw_request_info *info,
2041                           __u32 *uwrq,
2042                           char *extra)
2043 {
2044         struct atmel_private *priv = netdev_priv(dev);
2045
2046         if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2047                 return -EINVAL;
2048
2049         priv->operating_mode = *uwrq;
2050         return -EINPROGRESS;
2051 }
2052
2053 static int atmel_get_mode(struct net_device *dev,
2054                           struct iw_request_info *info,
2055                           __u32 *uwrq,
2056                           char *extra)
2057 {
2058         struct atmel_private *priv = netdev_priv(dev);
2059
2060         *uwrq = priv->operating_mode;
2061         return 0;
2062 }
2063
2064 static int atmel_get_rate(struct net_device *dev,
2065                          struct iw_request_info *info,
2066                          struct iw_param *vwrq,
2067                          char *extra)
2068 {
2069         struct atmel_private *priv = netdev_priv(dev);
2070
2071         if (priv->auto_tx_rate) {
2072                 vwrq->fixed = 0;
2073                 vwrq->value = 11000000;
2074         } else {
2075                 vwrq->fixed = 1;
2076                 switch(priv->tx_rate) {
2077                 case 0: vwrq->value =  1000000; break;
2078                 case 1: vwrq->value =  2000000; break;
2079                 case 2: vwrq->value =  5500000; break;
2080                 case 3: vwrq->value = 11000000; break;
2081                 }
2082         }
2083         return 0;
2084 }
2085
2086 static int atmel_set_power(struct net_device *dev,
2087                            struct iw_request_info *info,
2088                            struct iw_param *vwrq,
2089                            char *extra)
2090 {
2091         struct atmel_private *priv = netdev_priv(dev);
2092         priv->power_mode = vwrq->disabled ? 0 : 1;
2093         return -EINPROGRESS;
2094 }
2095
2096 static int atmel_get_power(struct net_device *dev,
2097                            struct iw_request_info *info,
2098                            struct iw_param *vwrq,
2099                            char *extra)
2100 {
2101         struct atmel_private *priv = netdev_priv(dev);
2102         vwrq->disabled = priv->power_mode ? 0 : 1;
2103         vwrq->flags = IW_POWER_ON;
2104         return 0;
2105 }
2106
2107 static int atmel_set_retry(struct net_device *dev,
2108                            struct iw_request_info *info,
2109                            struct iw_param *vwrq,
2110                            char *extra)
2111 {
2112         struct atmel_private *priv = netdev_priv(dev);
2113
2114         if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2115                 if (vwrq->flags & IW_RETRY_LONG)
2116                         priv->long_retry = vwrq->value;
2117                 else if (vwrq->flags & IW_RETRY_SHORT)
2118                         priv->short_retry = vwrq->value;
2119                 else {
2120                         /* No modifier : set both */
2121                         priv->long_retry = vwrq->value;
2122                         priv->short_retry = vwrq->value;
2123                 }
2124                 return -EINPROGRESS;
2125         }
2126
2127         return -EINVAL;
2128 }
2129
2130 static int atmel_get_retry(struct net_device *dev,
2131                            struct iw_request_info *info,
2132                            struct iw_param *vwrq,
2133                            char *extra)
2134 {
2135         struct atmel_private *priv = netdev_priv(dev);
2136
2137         vwrq->disabled = 0;      /* Can't be disabled */
2138
2139         /* Note : by default, display the short retry number */
2140         if (vwrq->flags & IW_RETRY_LONG) {
2141                 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2142                 vwrq->value = priv->long_retry;
2143         } else {
2144                 vwrq->flags = IW_RETRY_LIMIT;
2145                 vwrq->value = priv->short_retry;
2146                 if (priv->long_retry != priv->short_retry)
2147                         vwrq->flags |= IW_RETRY_SHORT;
2148         }
2149
2150         return 0;
2151 }
2152
2153 static int atmel_set_rts(struct net_device *dev,
2154                          struct iw_request_info *info,
2155                          struct iw_param *vwrq,
2156                          char *extra)
2157 {
2158         struct atmel_private *priv = netdev_priv(dev);
2159         int rthr = vwrq->value;
2160
2161         if (vwrq->disabled)
2162                 rthr = 2347;
2163         if ((rthr < 0) || (rthr > 2347)) {
2164                 return -EINVAL;
2165         }
2166         priv->rts_threshold = rthr;
2167
2168         return -EINPROGRESS;            /* Call commit handler */
2169 }
2170
2171 static int atmel_get_rts(struct net_device *dev,
2172                          struct iw_request_info *info,
2173                          struct iw_param *vwrq,
2174                          char *extra)
2175 {
2176         struct atmel_private *priv = netdev_priv(dev);
2177
2178         vwrq->value = priv->rts_threshold;
2179         vwrq->disabled = (vwrq->value >= 2347);
2180         vwrq->fixed = 1;
2181
2182         return 0;
2183 }
2184
2185 static int atmel_set_frag(struct net_device *dev,
2186                           struct iw_request_info *info,
2187                           struct iw_param *vwrq,
2188                           char *extra)
2189 {
2190         struct atmel_private *priv = netdev_priv(dev);
2191         int fthr = vwrq->value;
2192
2193         if (vwrq->disabled)
2194                 fthr = 2346;
2195         if ((fthr < 256) || (fthr > 2346)) {
2196                 return -EINVAL;
2197         }
2198         fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
2199         priv->frag_threshold = fthr;
2200
2201         return -EINPROGRESS;            /* Call commit handler */
2202 }
2203
2204 static int atmel_get_frag(struct net_device *dev,
2205                           struct iw_request_info *info,
2206                           struct iw_param *vwrq,
2207                           char *extra)
2208 {
2209         struct atmel_private *priv = netdev_priv(dev);
2210
2211         vwrq->value = priv->frag_threshold;
2212         vwrq->disabled = (vwrq->value >= 2346);
2213         vwrq->fixed = 1;
2214
2215         return 0;
2216 }
2217
2218 static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2219                                 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
2220
2221 static int atmel_set_freq(struct net_device *dev,
2222                           struct iw_request_info *info,
2223                           struct iw_freq *fwrq,
2224                           char *extra)
2225 {
2226         struct atmel_private *priv = netdev_priv(dev);
2227         int rc = -EINPROGRESS;          /* Call commit handler */
2228
2229         /* If setting by frequency, convert to a channel */
2230         if ((fwrq->e == 1) &&
2231             (fwrq->m >= (int) 241200000) &&
2232             (fwrq->m <= (int) 248700000)) {
2233                 int f = fwrq->m / 100000;
2234                 int c = 0;
2235                 while ((c < 14) && (f != frequency_list[c]))
2236                         c++;
2237                 /* Hack to fall through... */
2238                 fwrq->e = 0;
2239                 fwrq->m = c + 1;
2240         }
2241         /* Setting by channel number */
2242         if ((fwrq->m > 1000) || (fwrq->e > 0))
2243                 rc = -EOPNOTSUPP;
2244         else {
2245                 int channel = fwrq->m;
2246                 if (atmel_validate_channel(priv, channel) == 0) {
2247                         priv->channel = channel;
2248                 } else {
2249                         rc = -EINVAL;
2250                 }
2251         }
2252         return rc;
2253 }
2254
2255 static int atmel_get_freq(struct net_device *dev,
2256                           struct iw_request_info *info,
2257                           struct iw_freq *fwrq,
2258                           char *extra)
2259 {
2260         struct atmel_private *priv = netdev_priv(dev);
2261
2262         fwrq->m = priv->channel;
2263         fwrq->e = 0;
2264         return 0;
2265 }
2266
2267 static int atmel_set_scan(struct net_device *dev,
2268                           struct iw_request_info *info,
2269                           struct iw_param *vwrq,
2270                           char *extra)
2271 {
2272         struct atmel_private *priv = netdev_priv(dev);
2273         unsigned long flags;
2274
2275         /* Note : you may have realised that, as this is a SET operation,
2276          * this is privileged and therefore a normal user can't
2277          * perform scanning.
2278          * This is not an error, while the device perform scanning,
2279          * traffic doesn't flow, so it's a perfect DoS...
2280          * Jean II */
2281
2282         if (priv->station_state == STATION_STATE_DOWN)
2283                 return -EAGAIN;
2284
2285         /* Timeout old surveys. */
2286         if ((jiffies - priv->last_survey) > (20 * HZ))
2287                 priv->site_survey_state = SITE_SURVEY_IDLE;
2288         priv->last_survey = jiffies;
2289
2290         /* Initiate a scan command */
2291         if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2292                 return -EBUSY;
2293
2294         del_timer_sync(&priv->management_timer);
2295         spin_lock_irqsave(&priv->irqlock, flags);
2296
2297         priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2298         priv->fast_scan = 0;
2299         atmel_scan(priv, 0);
2300         spin_unlock_irqrestore(&priv->irqlock, flags);
2301
2302         return 0;
2303 }
2304
2305 static int atmel_get_scan(struct net_device *dev,
2306                           struct iw_request_info *info,
2307                           struct iw_point *dwrq,
2308                           char *extra)
2309 {
2310         struct atmel_private *priv = netdev_priv(dev);
2311         int i;
2312         char *current_ev = extra;
2313         struct iw_event iwe;
2314
2315         if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2316                 return -EAGAIN;
2317
2318         for (i = 0; i < priv->BSS_list_entries; i++) {
2319                 iwe.cmd = SIOCGIWAP;
2320                 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2321                 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
2322                 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
2323
2324                 iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
2325                 if (iwe.u.data.length > 32)
2326                         iwe.u.data.length = 32;
2327                 iwe.cmd = SIOCGIWESSID;
2328                 iwe.u.data.flags = 1;
2329                 current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
2330
2331                 iwe.cmd = SIOCGIWMODE;
2332                 iwe.u.mode = priv->BSSinfo[i].BSStype;
2333                 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
2334
2335                 iwe.cmd = SIOCGIWFREQ;
2336                 iwe.u.freq.m = priv->BSSinfo[i].channel;
2337                 iwe.u.freq.e = 0;
2338                 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
2339
2340                 /* Add quality statistics */
2341                 iwe.cmd = IWEVQUAL;
2342                 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2343                 iwe.u.qual.qual  = iwe.u.qual.level;
2344                 /* iwe.u.qual.noise  = SOMETHING */
2345                 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
2346
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 < ARRAY_SIZE(channel_table); 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   = ARRAY_SIZE(atmel_handler),
2585         .num_private    = ARRAY_SIZE(atmel_private_handler),
2586         .num_private_args = ARRAY_SIZE(atmel_private_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 < ARRAY_SIZE(channel_table); 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         __le16 alg;
2679         __le16 trans_seq;
2680         __le16 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                 __le16 BSS_type;
2716                 __le16 min_channel_time;
2717                 __le16 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                 __le16 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                 __le16 capability;
2866                 __le16 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                 __le16 capability;
3088                 __le16 status;
3089                 __le16 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                                 __le64 timestamp;
3297                                 __le16 interval;
3298                                 __le16 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