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