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