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