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