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