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