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