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