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