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