ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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, 0, 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 *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                         rc = -EFAULT;
2436                         break;
2437                 }
2438                 
2439                 if (priv->firmware)
2440                         kfree(priv->firmware);
2441                 
2442                 priv->firmware = new_firmware;
2443                 priv->firmware_length = com.len;
2444                 strncpy(priv->firmware_id, com.id, 31);
2445                 priv->firmware_id[31] = '\0';
2446                 break;
2447
2448         case ATMELRD:
2449                 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2450                         rc = -EFAULT;
2451                         break;
2452                 }
2453                 
2454                 if (!capable(CAP_NET_ADMIN)) {
2455                         rc = -EPERM;
2456                         break;
2457                 }
2458
2459                 domain[REGDOMAINSZ] = 0;
2460                 rc = -EINVAL;
2461                 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) {
2462                         /* strcasecmp doesn't exist in the library */
2463                         char *a = channel_table[i].name;
2464                         char *b = domain;
2465                         while (*a) {
2466                                 char c1 = *a++;
2467                                 char c2 = *b++;
2468                                 if (tolower(c1) != tolower(c2))
2469                                         break;
2470                         }
2471                         if (!*a && !*b) {
2472                                 priv->config_reg_domain = channel_table[i].reg_domain;
2473                                 rc = 0;
2474                         }
2475                 }
2476                 
2477                 if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2478                         rc = atmel_open(dev);
2479                 break;
2480                 
2481         default:
2482                 rc = -EOPNOTSUPP;
2483         }
2484         
2485         return rc;
2486 }
2487
2488 struct auth_body {
2489         u16 alg;
2490         u16 trans_seq;
2491         u16 status;
2492         u8 el_id;
2493         u8 chall_text_len;
2494         u8 chall_text[253];
2495 }; 
2496
2497 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2498 {
2499         int old_state = priv->station_state;
2500                 
2501         if (new_state == old_state)
2502                 return;
2503         
2504         priv->station_state = new_state;
2505                 
2506         if (new_state == STATION_STATE_READY) {
2507                 netif_start_queue(priv->dev);
2508                 netif_carrier_on(priv->dev);
2509         }
2510
2511         if (old_state == STATION_STATE_READY) {
2512                 netif_carrier_off(priv->dev);
2513                 if (netif_running(priv->dev))
2514                         netif_stop_queue(priv->dev);
2515                 priv->last_beacon_timestamp = 0;
2516         }
2517 }
2518
2519 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2520 {
2521         struct {
2522                 u8 BSSID[6];
2523                 u8 SSID[MAX_SSID_LENGTH];
2524                 u8 scan_type;
2525                 u8 channel;
2526                 u16 BSS_type;
2527                 u16 min_channel_time;
2528                 u16 max_channel_time;
2529                 u8 options;
2530                 u8 SSID_size;
2531         } cmd;
2532         
2533         memset(cmd.BSSID, 0xff, 6);
2534
2535         if (priv->fast_scan) {
2536                 cmd.SSID_size = priv->SSID_size;
2537                 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2538                 cmd.min_channel_time = cpu_to_le16(10);
2539                 cmd.max_channel_time = cpu_to_le16(50);
2540         } else {
2541                 priv->BSS_list_entries = 0;
2542                 cmd.SSID_size = 0;
2543                 cmd.min_channel_time = cpu_to_le16(10);
2544                 cmd.max_channel_time = cpu_to_le16(120);
2545         }
2546         
2547         cmd.options = 0;
2548         
2549         if (!specific_ssid)
2550                 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2551         
2552         cmd.channel = (priv->channel & 0x7f); 
2553         cmd.scan_type = SCAN_TYPE_ACTIVE;
2554         cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ? 
2555                 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2556         
2557         atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2558
2559         /* This must come after all hardware access to avoid being messed up
2560            by stuff happening in interrupt context after we leave STATE_DOWN */
2561         atmel_enter_state(priv, STATION_STATE_SCANNING);
2562 }
2563
2564 static void join(struct atmel_private *priv, int type)
2565 {
2566         struct {
2567                 u8 BSSID[6];
2568                 u8 SSID[MAX_SSID_LENGTH];
2569                 u8 BSS_type; /* this is a short in a scan command - wierd */                                
2570                 u8 channel;
2571                 u16 timeout;
2572                 u8 SSID_size;
2573                 u8 reserved;
2574         } cmd;
2575
2576         cmd.SSID_size = priv->SSID_size;
2577         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2578         memcpy(cmd.BSSID, priv->CurrentBSSID, 6);
2579         cmd.channel = (priv->channel & 0x7f);
2580         cmd.BSS_type = type;
2581         cmd.timeout = cpu_to_le16(2000);
2582
2583         atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2584 }
2585
2586
2587 static void start(struct atmel_private *priv, int type)
2588 {
2589         struct {
2590                 u8 BSSID[6];
2591                 u8 SSID[MAX_SSID_LENGTH];
2592                 u8 BSS_type;                                
2593                 u8 channel;
2594                 u8 SSID_size;
2595                 u8 reserved[3];
2596         } cmd;
2597
2598         cmd.SSID_size = priv->SSID_size;
2599         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2600         memcpy(cmd.BSSID, priv->BSSID, 6);
2601         cmd.BSS_type = type;
2602         cmd.channel = (priv->channel & 0x7f);
2603
2604         atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd)); 
2605 }
2606
2607 static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel)
2608 {
2609         int rejoin = 0;
2610         int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
2611                 SHORT_PREAMBLE : LONG_PREAMBLE;
2612
2613         if (priv->preamble != new) {
2614                 priv->preamble = new;
2615                 rejoin = 1;
2616                 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2617         }
2618                 
2619         if (priv->channel != channel) {
2620                 priv->channel = channel;
2621                 rejoin = 1;
2622                 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2623         }
2624         
2625         if (rejoin) {
2626                 priv->station_is_associated = 0;
2627                 atmel_enter_state(priv, STATION_STATE_JOINNING);
2628                 
2629                 if (priv->operating_mode == IW_MODE_INFRA)
2630                         join(priv, BSS_TYPE_INFRASTRUCTURE);
2631                 else 
2632                         join(priv, BSS_TYPE_AD_HOC);
2633         } 
2634 }
2635
2636  
2637 static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
2638 {
2639         struct ieee802_11_hdr header;
2640         struct auth_body auth;
2641         
2642         header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | IEEE802_11_STYPE_AUTH); 
2643         header.duration_id      = cpu_to_le16(0x8000);  
2644         header.seq_ctl = 0;
2645         memcpy(header.addr1, priv->CurrentBSSID, 6);
2646         memcpy(header.addr2, priv->dev->dev_addr, 6);
2647         memcpy(header.addr3, priv->CurrentBSSID, 6);
2648         
2649         if (priv->wep_is_on) {
2650                 auth.alg = C80211_MGMT_AAN_SHAREDKEY; 
2651                 /* no WEP for authentication frames with TrSeqNo 1 */
2652                 if (priv->CurrentAuthentTransactionSeqNum != 1)
2653                         header.frame_ctl |=  cpu_to_le16(IEEE802_11_FCTL_WEP); 
2654         } else {
2655                 auth.alg = C80211_MGMT_AAN_OPENSYSTEM;
2656         }
2657
2658         auth.status = 0;
2659         auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2660         priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1; 
2661         priv->CurrentAuthentTransactionSeqNum += 2;
2662         
2663         if (challenge_len != 0) {
2664                 auth.el_id = 16; /* challenge_text */
2665                 auth.chall_text_len = challenge_len;
2666                 memcpy(auth.chall_text, challenge, challenge_len);
2667                 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2668         } else {
2669                 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2670         }
2671 }
2672
2673 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2674 {
2675         u8 *ssid_el_p;
2676         int bodysize;
2677         struct ieee802_11_hdr header;
2678         struct ass_req_format {
2679                 u16 capability;
2680                 u16 listen_interval; 
2681                 u8 ap[6]; /* nothing after here directly accessible */
2682                 u8 ssid_el_id;
2683                 u8 ssid_len;
2684                 u8 ssid[MAX_SSID_LENGTH];
2685                 u8 sup_rates_el_id;
2686                 u8 sup_rates_len;
2687                 u8 rates[4];
2688         } body;
2689                 
2690         header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | 
2691                 (is_reassoc ? IEEE802_11_STYPE_REASSOC_REQ : IEEE802_11_STYPE_ASSOC_REQ));
2692         header.duration_id = cpu_to_le16(0x8000);
2693         header.seq_ctl = 0;
2694
2695         memcpy(header.addr1, priv->CurrentBSSID, 6); 
2696         memcpy(header.addr2, priv->dev->dev_addr, 6);
2697         memcpy(header.addr3, priv->CurrentBSSID, 6); 
2698
2699         body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS);
2700         if (priv->wep_is_on)
2701                 body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_Privacy);
2702         if (priv->preamble == SHORT_PREAMBLE)
2703                 body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble);
2704
2705         body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2706         
2707         /* current AP address - only in reassoc frame */
2708         if (is_reassoc) {
2709                 memcpy(body.ap,  priv->CurrentBSSID, 6);
2710                 ssid_el_p = (u8 *)&body.ssid_el_id;
2711                 bodysize = 18 + priv->SSID_size;
2712         } else {
2713                 ssid_el_p = (u8 *)&body.ap[0];
2714                 bodysize = 12 + priv->SSID_size;
2715         }
2716                 
2717         ssid_el_p[0]= C80211_MGMT_ElementID_SSID;
2718         ssid_el_p[1] = priv->SSID_size;
2719         memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2720         ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates;
2721         ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
2722         memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2723
2724         atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2725 }
2726
2727 static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee802_11_hdr *header)
2728 {
2729         if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS)
2730                 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2731         else
2732                 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2733 }
2734
2735 static int retrieve_bss(struct atmel_private *priv)
2736 {
2737         int i;
2738         int max_rssi = -128;
2739         int max_index = -1;
2740         
2741         if (priv->BSS_list_entries == 0)
2742                 return -1;
2743                         
2744         if (priv->connect_to_any_BSS) {
2745                 /* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
2746                    and that it is not marked as 'bad' (i.e. we had previously failed to connect to
2747                    this BSS with the settings that we currently use) */
2748                 priv->current_BSS = 0;
2749                 for(i=0; i<priv->BSS_list_entries; i++) { 
2750                         if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2751                             ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) || 
2752                              (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2753                             !(priv->BSSinfo[i].channel & 0x80)) {
2754                                 max_rssi = priv->BSSinfo[i].RSSI;
2755                                 priv->current_BSS = max_index = i;
2756                         }
2757                         
2758                 }
2759                 return max_index;
2760         }
2761                 
2762         for(i=0; i<priv->BSS_list_entries; i++) {
2763                 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2764                     memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2765                     priv->operating_mode == priv->BSSinfo[i].BSStype &&
2766                     atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2767                         if (priv->BSSinfo[i].RSSI >= max_rssi) {
2768                                 max_rssi = priv->BSSinfo[i].RSSI;
2769                                 max_index = i;
2770                         }
2771                 }
2772         }
2773         return max_index;
2774 }
2775
2776
2777 static void store_bss_info(struct atmel_private *priv, struct ieee802_11_hdr *header,
2778                            u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
2779                            u8 ssid_len, u8 *ssid, int is_beacon)
2780 {
2781         u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3;
2782         int i, index;
2783                 
2784         for (index = -1, i = 0; i < priv->BSS_list_entries; i++) 
2785                 if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) 
2786                         index = i;
2787
2788         /* If we process a probe and an entry from this BSS exists 
2789            we will update the BSS entry with the info from this BSS.
2790            If we process a beacon we will only update RSSI */
2791
2792         if (index == -1) {
2793                 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2794                         return;
2795                 index = priv->BSS_list_entries++;
2796                 memcpy(priv->BSSinfo[index].BSSID, bss, 6);
2797                 priv->BSSinfo[index].RSSI = rssi;
2798         } else {
2799                 if (rssi > priv->BSSinfo[index].RSSI)
2800                         priv->BSSinfo[index].RSSI = rssi;
2801                 if (is_beacon)
2802                         return;
2803         }
2804
2805         priv->BSSinfo[index].channel = channel;
2806         priv->BSSinfo[index].beacon_period = beacon_period;
2807         priv->BSSinfo[index].UsingWEP = capability & C80211_MGMT_CAPABILITY_Privacy;
2808         memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
2809         priv->BSSinfo[index].SSIDsize = ssid_len;
2810
2811         if (capability & C80211_MGMT_CAPABILITY_IBSS)
2812                 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
2813         else if (capability & C80211_MGMT_CAPABILITY_ESS)
2814                 priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
2815         
2816         priv->BSSinfo[index].preamble = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
2817                 SHORT_PREAMBLE : LONG_PREAMBLE;
2818 }
2819
2820 static void authenticate(struct atmel_private *priv, u16 frame_len)
2821 {
2822         struct auth_body *auth = (struct auth_body *)priv->rx_buf;
2823         u16 status = le16_to_cpu(auth->status);
2824         u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
2825         
2826         if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) { 
2827                 /* no WEP */
2828                 if (priv->station_was_associated) {
2829                         atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
2830                         send_association_request(priv, 1);
2831                         return;
2832                 } else {
2833                         atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
2834                         send_association_request(priv, 0);
2835                         return;
2836                 } 
2837         }
2838                 
2839         if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { 
2840                 /* WEP */
2841                 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
2842                         return;
2843                                 
2844                 if (trans_seq_no == 0x0002 &&
2845                     auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
2846                         send_authentication_request(priv, auth->chall_text, auth->chall_text_len);
2847                         return;
2848                 }
2849                 
2850                 if (trans_seq_no == 0x0004) {
2851                         if(priv->station_was_associated) {
2852                                 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
2853                                 send_association_request(priv, 1);
2854                                 return;
2855                         } else {
2856                                 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
2857                                 send_association_request(priv, 0);
2858                                 return;
2859                         } 
2860                 }
2861         }                       
2862         
2863         if (status == C80211_MGMT_SC_AuthAlgNotSupported && priv->connect_to_any_BSS) {
2864                 int bss_index;
2865                 
2866                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
2867                 
2868                 if ((bss_index  = retrieve_bss(priv)) != -1) {
2869                         atmel_join_bss(priv, bss_index);
2870                         return;
2871                 }
2872         }
2873         
2874         
2875         priv->AuthenticationRequestRetryCnt = 0;
2876         atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
2877         priv->station_is_associated = 0;
2878 }
2879
2880 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
2881 {
2882         struct ass_resp_format {
2883                 u16 capability;
2884                 u16 status;
2885                 u16 ass_id;
2886                 u8 el_id;
2887                 u8 length;
2888                 u8 rates[4];
2889         } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
2890         
2891         u16 status = le16_to_cpu(ass_resp->status);
2892         u16 ass_id = le16_to_cpu(ass_resp->ass_id);
2893         u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
2894         
2895         if (frame_len < 8 + rates_len)
2896                 return;
2897         
2898         if (status == C80211_MGMT_SC_Success) {
2899                 if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE)
2900                         priv->AssociationRequestRetryCnt = 0;
2901                 else
2902                         priv->ReAssociationRequestRetryCnt = 0;
2903                 
2904                 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
2905                 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
2906                 if (priv->power_mode == 0) {
2907                         priv->listen_interval = 1;
2908                         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
2909                         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
2910                 } else {
2911                         priv->listen_interval = 2;
2912                         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
2913                         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
2914                 }
2915                 
2916                 priv->station_is_associated = 1;
2917                 priv->station_was_associated = 1;
2918                 atmel_enter_state(priv, STATION_STATE_READY);
2919                 return;
2920         }
2921         
2922         if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE &&
2923             status != C80211_MGMT_SC_AssDeniedBSSRate &&
2924             status != C80211_MGMT_SC_SupportCapabilities &&
2925             priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
2926                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
2927                 priv->AssociationRequestRetryCnt++;
2928                 send_association_request(priv, 0);
2929                 return;
2930         }
2931                 
2932         if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE &&
2933             status != C80211_MGMT_SC_AssDeniedBSSRate &&
2934             status != C80211_MGMT_SC_SupportCapabilities &&
2935             priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
2936                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
2937                 priv->ReAssociationRequestRetryCnt++;
2938                 send_association_request(priv, 1);
2939                 return;
2940         }
2941         
2942         atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
2943         priv->station_is_associated = 0;
2944         
2945         if(priv->connect_to_any_BSS) {
2946                 int bss_index;
2947                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
2948                 
2949                 if ((bss_index = retrieve_bss(priv)) != -1) 
2950                         atmel_join_bss(priv, bss_index);
2951                 
2952         }
2953 }
2954
2955 void atmel_join_bss(struct atmel_private *priv, int bss_index)
2956 {
2957         struct bss_info *bss =  &priv->BSSinfo[bss_index];
2958
2959         memcpy(priv->CurrentBSSID, bss->BSSID, 6);
2960         memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
2961
2962         /* The WPA stuff cares about the current AP address */
2963         if (priv->use_wpa)
2964                 build_wpa_mib(priv);
2965         
2966         /* When switching to AdHoc turn OFF Power Save if needed */
2967
2968         if (bss->BSStype == IW_MODE_ADHOC &&
2969             priv->operating_mode != IW_MODE_ADHOC &&
2970             priv->power_mode) {
2971                 priv->power_mode = 0;
2972                 priv->listen_interval = 1;
2973                 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
2974                 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
2975         }
2976                 
2977         priv->operating_mode = bss->BSStype;
2978         priv->channel = bss->channel & 0x7f;    
2979         priv->beacon_period = bss->beacon_period;
2980         
2981         if (priv->preamble != bss->preamble) {
2982                 priv->preamble = bss->preamble;
2983                 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
2984         }
2985         
2986         if (!priv->wep_is_on && bss->UsingWEP) {
2987                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
2988                 priv->station_is_associated = 0;
2989                 return;
2990         }
2991                 
2992         if (priv->wep_is_on && !bss->UsingWEP) {
2993                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
2994                 priv->station_is_associated = 0;
2995                 return;
2996         }
2997
2998         atmel_enter_state(priv, STATION_STATE_JOINNING);
2999         
3000         if (priv->operating_mode == IW_MODE_INFRA)
3001                 join(priv, BSS_TYPE_INFRASTRUCTURE);
3002         else 
3003                 join(priv, BSS_TYPE_AD_HOC);
3004 }
3005
3006
3007 static void restart_search(struct atmel_private *priv)
3008 {
3009         int bss_index;
3010         
3011         if (!priv->connect_to_any_BSS) {
3012                 atmel_scan(priv, 1);
3013         } else {
3014                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3015                 
3016                 if ((bss_index = retrieve_bss(priv)) != -1) 
3017                         atmel_join_bss(priv, bss_index);
3018                 else
3019                         atmel_scan(priv, 0);
3020                 
3021         } 
3022 }       
3023
3024 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3025 {
3026         u8 old = priv->wstats.qual.level;
3027
3028         /* 502-rmfd-revd gives max signal level as 42, by experiment.
3029            This is going to break for other hardware variants. */
3030
3031         rssi = rssi * 100 / 42;
3032         if((rssi + old) % 2)
3033                 priv->wstats.qual.level =  ((rssi + old)/2) + 1;
3034         else
3035                 priv->wstats.qual.level =  ((rssi + old)/2);            
3036         
3037 }
3038
3039 static void atmel_smooth_qual(struct atmel_private *priv)
3040 {
3041         unsigned long time_diff = (jiffies - priv->last_qual)/HZ;
3042         while (time_diff--) {
3043                 priv->last_qual += HZ;
3044                 priv->wstats.qual.qual = priv->wstats.qual.qual/2;
3045                 priv->wstats.qual.qual += 
3046                         priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3047                 priv->beacons_this_sec = 0;
3048         }
3049 }
3050         
3051 /* deals with incoming managment frames. */
3052 static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 
3053                       u16 frame_len, u8 rssi)
3054 {
3055         u16 subtype;
3056         
3057         switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_STYPE) {
3058         case C80211_SUBTYPE_MGMT_BEACON :
3059         case C80211_SUBTYPE_MGMT_ProbeResponse:
3060                 
3061                 /* beacon frame has multiple variable-length fields -
3062                    never let an engineer loose with a data structure design. */
3063                 {
3064                         struct beacon_format {
3065                                 u64 timestamp;
3066                                 u16 interval;
3067                                 u16 capability;
3068                                 u8 ssid_el_id;
3069                                 u8 ssid_length;
3070                                 /* ssid here */
3071                                 u8 rates_el_id;
3072                                 u8 rates_length;
3073                                 /* rates here */
3074                                 u8 ds_el_id;
3075                                 u8 ds_length;
3076                                 /* ds here */
3077                         } *beacon = (struct beacon_format *)priv->rx_buf;
3078                         
3079                         u8 channel, rates_length, ssid_length;
3080                         u64 timestamp = le64_to_cpu(beacon->timestamp);
3081                         u16 beacon_interval = le16_to_cpu(beacon->interval);
3082                         u16 capability = le16_to_cpu(beacon->capability);
3083                         u8 *beaconp = priv->rx_buf;
3084                         ssid_length = beacon->ssid_length;
3085                         /* this blows chunks. */
3086                         if (frame_len < 14 || frame_len < ssid_length + 15) 
3087                                 return;
3088                         rates_length = beaconp[beacon->ssid_length + 15];
3089                         if (frame_len < ssid_length + rates_length + 18)
3090                                 return;
3091                         if (ssid_length >  MAX_SSID_LENGTH)
3092                                 return;
3093                         channel = beaconp[ssid_length + rates_length + 18];
3094                        
3095                         if (priv->station_state == STATION_STATE_READY) {
3096                                 smooth_rssi(priv, rssi);
3097                                 if (is_frame_from_current_bss(priv, header)) { 
3098                                         priv->beacons_this_sec++;
3099                                         atmel_smooth_qual(priv);
3100                                         if (priv->last_beacon_timestamp) {
3101                                                 /* Note truncate this to 32 bits - kernel can't divide a long long */
3102                                                 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3103                                                 int beacons = beacon_delay / (beacon_interval * 1000);
3104                                                 if (beacons > 1)
3105                                                         priv->wstats.miss.beacon += beacons - 1;
3106                                         }
3107                                         priv->last_beacon_timestamp = timestamp;
3108                                         handle_beacon_probe(priv, capability, channel);
3109                                 }
3110                         }
3111                         
3112                         if (priv->station_state == STATION_STATE_SCANNING ) 
3113                                 store_bss_info(priv, header, capability, beacon_interval, channel,
3114                                                rssi, ssid_length, &beacon->rates_el_id,
3115                                                subtype == C80211_SUBTYPE_MGMT_BEACON) ;
3116                 }
3117                 break;
3118                 
3119         case C80211_SUBTYPE_MGMT_Authentication:
3120
3121                 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3122                         authenticate(priv, frame_len);
3123         
3124                 break;
3125                 
3126         case C80211_SUBTYPE_MGMT_ASS_RESPONSE:
3127         case C80211_SUBTYPE_MGMT_REASS_RESPONSE:
3128                 
3129                 if (priv->station_state == STATION_STATE_ASSOCIATING || 
3130                     priv->station_state == STATION_STATE_REASSOCIATING)
3131                         associate(priv, frame_len, subtype);
3132                 
3133                 break;
3134
3135         case C80211_SUBTYPE_MGMT_DISASSOSIATION:
3136                 if (priv->station_is_associated && 
3137                     priv->operating_mode == IW_MODE_INFRA && 
3138                     is_frame_from_current_bss(priv, header)) {
3139                         priv->station_was_associated = 0;
3140                         priv->station_is_associated = 0;
3141                         
3142                         atmel_enter_state(priv, STATION_STATE_JOINNING);
3143                         join(priv, BSS_TYPE_INFRASTRUCTURE);
3144                 }
3145                 
3146                 break;
3147
3148         case C80211_SUBTYPE_MGMT_Deauthentication:
3149                 if (priv->operating_mode == IW_MODE_INFRA &&
3150                     is_frame_from_current_bss(priv, header)) {
3151                         priv->station_was_associated = 0;
3152
3153                         atmel_enter_state(priv, STATION_STATE_JOINNING);
3154                         join(priv, BSS_TYPE_INFRASTRUCTURE);
3155                 }
3156                 
3157                 break;
3158         }
3159 }
3160
3161 /* run when timer expires */
3162 static void atmel_management_timer(u_long a)
3163 {
3164   struct net_device *dev = (struct net_device *) a;
3165   struct atmel_private *priv = netdev_priv(dev);
3166   unsigned long flags;
3167   
3168   /* Check if the card has been yanked. */
3169   if (priv->card && priv->present_callback && 
3170       !(*priv->present_callback)(priv->card))
3171           return;
3172   
3173   spin_lock_irqsave(&priv->irqlock, flags);
3174
3175   switch (priv->station_state) {
3176           
3177   case STATION_STATE_AUTHENTICATING:
3178           if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3179                   atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3180                   priv->station_is_associated = 0;
3181                   priv->AuthenticationRequestRetryCnt = 0;
3182                   restart_search(priv);
3183           } else {
3184                   priv->AuthenticationRequestRetryCnt++;
3185                   priv->CurrentAuthentTransactionSeqNum = 0x0001;
3186                   mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3187                   send_authentication_request(priv, NULL, 0);
3188           }
3189           
3190           break;
3191
3192   case STATION_STATE_ASSOCIATING:
3193           if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3194                   atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3195                   priv->station_is_associated = 0;
3196                   priv->AssociationRequestRetryCnt = 0;
3197                   restart_search(priv);
3198           } else {
3199                   priv->AssociationRequestRetryCnt++;
3200                   mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3201                   send_association_request(priv, 0);
3202           }
3203
3204           break;
3205                   
3206   case STATION_STATE_REASSOCIATING:     
3207           if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3208                   atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3209                   priv->station_is_associated = 0;
3210                   priv->ReAssociationRequestRetryCnt = 0;
3211                   restart_search(priv);
3212           } else {
3213                   priv->ReAssociationRequestRetryCnt++;
3214                   mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3215                   send_association_request(priv, 1);
3216           }
3217
3218           break;
3219   
3220   default:
3221           break;
3222   }
3223   
3224   spin_unlock_irqrestore(&priv->irqlock, flags);
3225 }
3226   
3227 static void atmel_command_irq(struct atmel_private *priv)
3228 {
3229         u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3230         u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3231         int fast_scan;
3232         
3233         if (status == CMD_STATUS_IDLE || 
3234             status == CMD_STATUS_IN_PROGRESS)
3235                 return;
3236
3237         switch (command){
3238
3239         case CMD_Start:
3240                 if (status == CMD_STATUS_COMPLETE) {
3241                         priv->station_was_associated = priv->station_is_associated;
3242                         atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3243                                       (u8 *)priv->CurrentBSSID, 6);
3244                         atmel_enter_state(priv, STATION_STATE_READY);
3245                 }                       
3246                 break;
3247                 
3248         case CMD_Scan:
3249                 fast_scan = priv->fast_scan;
3250                 priv->fast_scan = 0;
3251                 
3252                 if (status != CMD_STATUS_COMPLETE) {
3253                         atmel_scan(priv, 1);
3254                 } else {
3255                         int bss_index = retrieve_bss(priv);
3256                         if (bss_index != -1) {
3257                                 atmel_join_bss(priv, bss_index);
3258                         } else if (priv->operating_mode == IW_MODE_ADHOC && 
3259                                    priv->SSID_size != 0) {
3260                                 start(priv, BSS_TYPE_AD_HOC);
3261                         } else {
3262                                 priv->fast_scan = !fast_scan;
3263                                 atmel_scan(priv, 1);
3264                         }
3265                         priv->site_survey_state = SITE_SURVEY_COMPLETED;
3266                 }
3267                 break;
3268                 
3269         case CMD_SiteSurvey:
3270                 priv->fast_scan = 0;
3271                 
3272                 if (status != CMD_STATUS_COMPLETE)
3273                         return;
3274                 
3275                 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3276                 if (priv->station_is_associated) {
3277                         atmel_enter_state(priv, STATION_STATE_READY);                           
3278                 } else {
3279                         atmel_scan(priv, 1);
3280                 }
3281                 break;
3282
3283         case CMD_Join:
3284                 if (status == CMD_STATUS_COMPLETE) {
3285                         if (priv->operating_mode == IW_MODE_ADHOC) {
3286                                 priv->station_was_associated = priv->station_is_associated;
3287                                 atmel_enter_state(priv, STATION_STATE_READY);
3288                         } else {
3289                                 priv->AuthenticationRequestRetryCnt = 0;
3290                                 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3291                                 
3292                                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3293                                 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3294                                 send_authentication_request(priv, NULL, 0);
3295                         }
3296                         return;
3297                 }
3298                 
3299                 atmel_scan(priv, 1);
3300                 
3301         }
3302 }
3303
3304 static int atmel_wakeup_firmware(struct atmel_private *priv)
3305 {
3306         struct host_info_struct *iface = &priv->host_info;
3307         u16 mr1, mr3;
3308         int i;
3309
3310         if (priv->card_type == CARD_TYPE_SPI_FLASH)
3311                 atmel_set_gcr(priv->dev, GCR_REMAP);
3312         
3313         /* wake up on-board processor */
3314         atmel_clear_gcr(priv->dev, 0x0040);
3315         atmel_write16(priv->dev, BSR, BSS_SRAM);
3316         
3317         if (priv->card_type == CARD_TYPE_SPI_FLASH)
3318                 mdelay(100);
3319
3320         /* and wait for it */
3321         for (i =  LOOP_RETRY_LIMIT; i; i--) {
3322                 mr1 = atmel_read16(priv->dev, MR1);
3323                 mr3 = atmel_read16(priv->dev, MR3);
3324                 
3325                 if (mr3 & MAC_BOOT_COMPLETE) 
3326                         break;
3327                 if (mr1 & MAC_BOOT_COMPLETE &&
3328                     priv->bus_type == BUS_TYPE_PCCARD)
3329                         break;
3330         }
3331
3332         if (i == 0) {
3333                 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3334                 return 0;
3335         }
3336                 
3337         if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3338                 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3339                 return 0;
3340         }
3341         
3342         /* now check for completion of MAC initialization through  
3343            the FunCtrl field of the IFACE, poll MR1 to detect completion of       
3344            MAC initialization, check completion status, set interrupt mask,  
3345            enables interrupts and calls Tx and Rx initialization functions */  
3346         
3347         atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3348         
3349         for (i =  LOOP_RETRY_LIMIT; i; i--) {
3350                 mr1 = atmel_read16(priv->dev, MR1);
3351                 mr3 = atmel_read16(priv->dev, MR3);
3352                 
3353                 if (mr3 & MAC_INIT_COMPLETE) 
3354                         break;
3355                 if (mr1 & MAC_INIT_COMPLETE &&
3356                     priv->bus_type == BUS_TYPE_PCCARD)
3357                         break;
3358         }
3359         
3360         if (i == 0) {
3361                 printk(KERN_ALERT "%s: MAC failed to initialise.\n", priv->dev->name);
3362                 return 0;
3363         }
3364         
3365         /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3366         if ((mr3 & MAC_INIT_COMPLETE) &&
3367             !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3368                 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3369                 return 0;
3370         }
3371         if ((mr1 & MAC_INIT_COMPLETE) &&
3372             !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3373                 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3374                 return 0;
3375         }
3376
3377         atmel_copy_to_host(priv->dev, (unsigned char *)iface, 
3378                            priv->host_info_base, sizeof(*iface));
3379         
3380         iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3381         iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3382         iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3383         iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3384         iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3385         iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3386         iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3387         iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3388         iface->build_version = le16_to_cpu(iface->build_version);
3389         iface->command_pos = le16_to_cpu(iface->command_pos);
3390         iface->major_version = le16_to_cpu(iface->major_version);
3391         iface->minor_version = le16_to_cpu(iface->minor_version);
3392         iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3393         iface->mac_status = le16_to_cpu(iface->mac_status);
3394
3395         return 1;
3396 }
3397
3398 /* determine type of memory and MAC address */
3399 static int probe_atmel_card(struct net_device *dev)
3400 {
3401         int rc = 0;
3402         struct atmel_private *priv = netdev_priv(dev);
3403          
3404         /* reset pccard */
3405         if (priv->bus_type == BUS_TYPE_PCCARD) 
3406                 atmel_write16(dev, GCR, 0x0060);
3407         
3408         atmel_write16(dev, GCR, 0x0040);
3409         mdelay(500);
3410         
3411         if (atmel_read16(dev, MR2) == 0) {
3412                 /* No stored firmware so load a small stub which just 
3413                    tells us the MAC address */
3414                 int i;
3415                 priv->card_type = CARD_TYPE_EEPROM;
3416                 atmel_write16(dev, BSR, BSS_IRAM);
3417                 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3418                 atmel_set_gcr(dev, GCR_REMAP);
3419                 atmel_clear_gcr(priv->dev, 0x0040);
3420                 atmel_write16(dev, BSR, BSS_SRAM);
3421                 for (i =  LOOP_RETRY_LIMIT; i; i--) 
3422                         if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3423                                 break;
3424                 if (i == 0) {
3425                         printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3426                 } else {
3427                         atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3428                         /* got address, now squash it again until the network
3429                            interface is opened */
3430                         if (priv->bus_type == BUS_TYPE_PCCARD) 
3431                                 atmel_write16(dev, GCR, 0x0060);
3432                         atmel_write16(dev, GCR, 0x0040);
3433                         rc = 1;
3434                 }
3435         } else if (atmel_read16(dev, MR4) == 0) {
3436                 /* Mac address easy in this case. */
3437                 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3438                 atmel_write16(dev,  BSR, 1);    
3439                 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3440                 atmel_write16(dev,  BSR, 0x200);
3441                 rc = 1;
3442         } else {
3443                 /* Standard firmware in flash, boot it up and ask
3444                    for the Mac Address */
3445                 priv->card_type = CARD_TYPE_SPI_FLASH;
3446                 if (atmel_wakeup_firmware(priv)) {
3447                         atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3448                         
3449                         /* got address, now squash it again until the network
3450                            interface is opened */
3451                         if (priv->bus_type == BUS_TYPE_PCCARD) 
3452                                 atmel_write16(dev, GCR, 0x0060);
3453                         atmel_write16(dev, GCR, 0x0040);
3454                         rc = 1;
3455                 }
3456         }
3457         
3458         if (rc) {
3459                 if (dev->dev_addr[0] == 0xFF) {
3460                         u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
3461                         printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3462                         memcpy(dev->dev_addr, default_mac, 6);
3463                 }
3464                 printk(KERN_INFO "%s: MAC address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
3465                        dev->name,
3466                        dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
3467                        dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
3468                 
3469         }
3470         
3471         return rc;
3472 }
3473
3474 static void build_wep_mib(struct atmel_private *priv)
3475 /* Move the encyption information on the MIB structure.
3476    This routine is for the pre-WPA firmware: later firmware has
3477    a different format MIB and a different routine. */
3478 {
3479         struct { /* NB this is matched to the hardware, don't change. */
3480                 u8 wep_is_on;                 
3481                 u8 default_key; /* 0..3 */
3482                 u8 reserved;
3483                 u8 exclude_unencrypted;
3484                 
3485                 u32 WEPICV_error_count;
3486                 u32 WEP_excluded_count;
3487                 
3488                 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3489                 u8 encryption_level; /* 0, 1, 2 */
3490                 u8 reserved2[3]; 
3491         } mib;
3492         int i;
3493
3494         mib.wep_is_on = priv->wep_is_on;
3495         if (priv->wep_is_on) {
3496                 if (priv->wep_key_len[priv->default_key] > 5)
3497                         mib.encryption_level = 2;
3498                 else
3499                         mib.encryption_level = 1;       
3500         } else {
3501                 mib.encryption_level = 0;
3502         }
3503
3504         mib.default_key = priv->default_key;
3505         mib.exclude_unencrypted = priv->exclude_unencrypted;
3506         
3507         for(i = 0; i < MAX_ENCRYPTION_KEYS;  i++)
3508                 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3509                 
3510         atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3511 }
3512
3513 static void build_wpa_mib(struct atmel_private *priv)
3514 {
3515         /* This is for the later (WPA enabled) firmware. */        
3516
3517         struct { /* NB this is matched to the hardware, don't change. */
3518                 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3519                 u8 receiver_address[6];
3520                 u8 wep_is_on;                 
3521                 u8 default_key; /* 0..3 */
3522                 u8 group_key;
3523                 u8 exclude_unencrypted;
3524                 u8 encryption_type;
3525                 u8 reserved;
3526                 
3527                 u32 WEPICV_error_count;
3528                 u32 WEP_excluded_count;
3529                 
3530                 u8 key_RSC[4][8];
3531         } mib;
3532         
3533         int i;
3534
3535         mib.wep_is_on = priv->wep_is_on;
3536         mib.exclude_unencrypted = priv->exclude_unencrypted;
3537         memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
3538         
3539         /* zero all the keys before adding in valid ones. */
3540         memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3541         
3542         if (priv->wep_is_on) {
3543                 /* There's a comment in the Atmel code to the effect that this is only valid
3544                    when still using WEP, it may need to be set to something to use WPA */
3545                 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3546                 
3547                 mib.default_key = mib.group_key = 255;
3548                 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3549                         if (priv->wep_key_len[i] > 0) {
3550                                 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3551                                 if (i == priv->default_key) {
3552                                         mib.default_key = i;
3553                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3554                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite; 
3555                                 } else {
3556                                         mib.group_key = i;
3557                                         priv->group_cipher_suite = priv->pairwise_cipher_suite;
3558                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3559                                         mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;  
3560                                 }
3561                         }
3562                 }
3563                 if (mib.default_key == 255)
3564                         mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3565                 if (mib.group_key == 255)
3566                         mib.group_key = mib.default_key;
3567                 
3568         }
3569         
3570         atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3571 }
3572                                         
3573 static int reset_atmel_card(struct net_device *dev) 
3574 {
3575         /* do everything necessary to wake up the hardware, including
3576            waiting for the lightning strike and throwing the knife switch....
3577
3578            set all the Mib values which matter in the card to match 
3579            their settings in the atmel_private structure. Some of these
3580            can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3581            can only be changed by tearing down the world and coming back through
3582            here.
3583
3584            This routine is also responsible for initialising some 
3585            hardware-specific fields in the atmel_private structure, 
3586            including a copy of the firmware's hostinfo stucture
3587            which is the route into the rest of the firmare datastructures. */
3588
3589         struct atmel_private *priv = netdev_priv(dev);
3590         u8 configuration;
3591         
3592         /* data to add to the firmware names, in priority order
3593            this implemenents firmware versioning */
3594         
3595         static char *firmware_modifier[] = {
3596                 "-wpa",
3597                 "",
3598                 NULL
3599         };
3600                 
3601         /* reset pccard */
3602         if (priv->bus_type == BUS_TYPE_PCCARD) 
3603                 atmel_write16(priv->dev, GCR, 0x0060);
3604                 
3605         /* stop card , disable interrupts */
3606         atmel_write16(priv->dev, GCR, 0x0040);
3607                 
3608         if (priv->card_type == CARD_TYPE_EEPROM) {
3609                 /* copy in firmware if needed */
3610                 const struct firmware *fw_entry = NULL;
3611                 unsigned char *fw;
3612                 int len = priv->firmware_length;
3613                 if (!(fw = priv->firmware)) { 
3614                         if (strlen(priv->firmware_template) == 0) {     
3615                                 if (strlen(priv->firmware_id) == 0) {
3616                                         printk(KERN_INFO
3617                                                "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3618                                                dev->name);
3619                                         printk(KERN_INFO
3620                                                "%s: if not, use the firmware= module parameter.\n", 
3621                                                dev->name);
3622                                         strcpy(priv->firmware_id, "atmel_at76c502.bin");
3623                                 }
3624                                 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
3625                                         printk(KERN_ALERT 
3626                                                "%s: firmware %s is missing, cannot continue.\n", 
3627                                                dev->name, priv->firmware_id);
3628                                         return 0;
3629                                         
3630                                 } 
3631                         } else {
3632                                 int i;
3633                                 
3634                                 for (i = 0; firmware_modifier[i]; i++) {
3635                                         sprintf(priv->firmware_id, priv->firmware_template, firmware_modifier[i]);
3636                                         if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) 
3637                                                 break;
3638                                 }
3639                                 if (!firmware_modifier[i]) {
3640                                         printk(KERN_ALERT 
3641                                                "%s: firmware %s is missing, cannot start.\n", 
3642                                                dev->name, priv->firmware_id);
3643                                         priv->firmware_id[0] = '\0';
3644                                         return 0;       
3645                                 }
3646                                 priv->firmware_template[0] = '\0';      
3647                         }
3648                         
3649                         fw = fw_entry->data;
3650                         len = fw_entry->size;
3651                 }
3652                 
3653                 if (len <= 0x6000) {
3654                         atmel_write16(priv->dev, BSR, BSS_IRAM);
3655                         atmel_copy_to_card(priv->dev, 0, fw, len);
3656                         atmel_set_gcr(priv->dev, GCR_REMAP);
3657                 } else {
3658                         /* Remap */ 
3659                         atmel_set_gcr(priv->dev, GCR_REMAP);
3660                         atmel_write16(priv->dev, BSR, BSS_IRAM);
3661                         atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3662                         atmel_write16(priv->dev, BSR, 0x2ff);
3663                         atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3664                 }
3665
3666                 if (fw_entry)
3667                         release_firmware(fw_entry);
3668         }
3669
3670         if (!atmel_wakeup_firmware(priv))
3671                 return 0;
3672
3673         /* Check the version and set the correct flag for wpa stuff,
3674            old and new firmware is incompatible.
3675            The pre-wpa 3com firmware reports major version 5,
3676            the wpa 3com firmware is major version 4 and doesn't need
3677            the 3com broken-ness filter. */
3678         priv->use_wpa = (priv->host_info.major_version == 4);
3679         priv->radio_on_broken = (priv->host_info.major_version == 5);
3680         
3681         /* unmask all irq sources */
3682         atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3683         
3684         /* int Tx system and enable Tx */
3685         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3686         atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3687         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3688         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3689
3690         priv->tx_desc_free = priv->host_info.tx_desc_count;             
3691         priv->tx_desc_head = 0;                                                                 
3692         priv->tx_desc_tail = 0;                                                                 
3693         priv->tx_desc_previous = 0;
3694         priv->tx_free_mem = priv->host_info.tx_buff_size;
3695         priv->tx_buff_head = 0; 
3696         priv->tx_buff_tail = 0; 
3697                 
3698         configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
3699         atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
3700                                    configuration | FUNC_CTRL_TxENABLE);
3701
3702         /* init Rx system and enable */
3703         priv->rx_desc_head = 0;
3704         
3705         configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
3706         atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
3707                                    configuration | FUNC_CTRL_RxENABLE);
3708                         
3709         if (!priv->radio_on_broken) {
3710                 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 
3711                     CMD_STATUS_REJECTED_RADIO_OFF) {
3712                         printk(KERN_INFO 
3713                                "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
3714                                dev->name);
3715                         return 0;
3716                 }
3717         }
3718         
3719         /* set up enough MIB values to run. */
3720         atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
3721         atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
3722         atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
3723         atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
3724         atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
3725         atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
3726         atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
3727         atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS, 
3728                       priv->dev->dev_addr, 6);
3729         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3730         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3731         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
3732         atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
3733         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
3734         if (priv->use_wpa)
3735                 build_wpa_mib(priv);
3736         else
3737                 build_wep_mib(priv);
3738         
3739         return 1;
3740 }
3741
3742 static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size)
3743 {
3744         if (cmd)
3745                 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET), 
3746                                    cmd, cmd_size);
3747         
3748         atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
3749         atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
3750 }
3751         
3752 static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size)
3753 {
3754         int i, status;
3755         
3756         atmel_send_command(priv, command, cmd, cmd_size);
3757         
3758         for (i = 5000; i; i--) {
3759                 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3760                 if (status != CMD_STATUS_IDLE && 
3761                     status != CMD_STATUS_IN_PROGRESS)
3762                         break;
3763                 udelay(20);
3764         }
3765         
3766         if (i == 0) {
3767                 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
3768                 status =  CMD_STATUS_HOST_ERROR;
3769         } else { 
3770                 if (command != CMD_EnableRadio)
3771                         status = CMD_STATUS_COMPLETE;
3772         }
3773         
3774         return status;
3775 }
3776
3777 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
3778 {
3779         struct get_set_mib m;
3780         m.type = type;
3781         m.size = 1;
3782         m.index = index;
3783
3784         atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
3785         return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
3786 }
3787
3788 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
3789 {
3790         struct get_set_mib m;
3791         m.type = type;
3792         m.size = 1;
3793         m.index = index;
3794         m.data[0] = data;
3795
3796         atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
3797 }
3798
3799 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data)
3800 {
3801         struct get_set_mib m;
3802         m.type = type;
3803         m.size = 2;
3804         m.index = index;
3805         m.data[0] = data;
3806         m.data[1] = data >> 8;
3807
3808         atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
3809 }
3810
3811 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
3812 {
3813         struct get_set_mib m;
3814         m.type = type;
3815         m.size = data_len;
3816         m.index = index;
3817
3818         if (data_len > MIB_MAX_DATA_BYTES)
3819                 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
3820         
3821         memcpy(m.data, data, data_len);
3822         atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
3823 }
3824
3825 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
3826 {
3827         struct get_set_mib m;
3828         m.type = type;
3829         m.size = data_len;
3830         m.index = index;
3831         
3832         if (data_len > MIB_MAX_DATA_BYTES)
3833                 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
3834         
3835         atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
3836         atmel_copy_to_host(priv->dev, data, 
3837                            atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
3838 }
3839
3840 static void atmel_writeAR(struct net_device *dev, u16 data)
3841 {
3842         int i;
3843         outw(data, dev->base_addr + AR);
3844         /* Address register appears to need some convincing..... */
3845         for (i = 0; data != inw(dev->base_addr + AR) && i<10; i++)
3846                 outw(data, dev->base_addr + AR);
3847 }
3848
3849 static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len)
3850 {
3851         int i;
3852         atmel_writeAR(dev, dest);
3853         if (dest % 2) {
3854                 atmel_write8(dev, DR, *src);
3855                 src++; len--;
3856         }
3857         for (i = len; i > 1 ; i -= 2) {
3858                 u8 lb = *src++;
3859                 u8 hb = *src++;
3860                 atmel_write16(dev, DR, lb | (hb << 8));
3861         }
3862         if (i)
3863                 atmel_write8(dev, DR, *src);
3864 }
3865
3866 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len)
3867 {
3868         int i;
3869         atmel_writeAR(dev, src);
3870         if (src % 2) {
3871                 *dest = atmel_read8(dev, DR);
3872                 dest++; len--;
3873         }
3874         for (i = len; i > 1 ; i -= 2) {
3875                 u16 hw = atmel_read16(dev, DR);
3876                 *dest++ = hw;
3877                 *dest++ = hw >> 8;
3878         }
3879         if (i)
3880                 *dest = atmel_read8(dev, DR);
3881 }
3882
3883 static void atmel_set_gcr(struct net_device *dev, u16 mask)
3884 {
3885         outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
3886 }
3887
3888 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
3889 {
3890         outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
3891 }
3892
3893 static int atmel_lock_mac(struct atmel_private *priv)
3894 {
3895         int i, j = 20;
3896  retry:
3897         for (i = 5000; i; i--) {
3898                 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
3899                         break;
3900                 udelay(20);
3901         }
3902         
3903         if (!i) return 0; /* timed out */
3904         
3905         atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
3906         if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
3907                 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
3908                 if (!j--) return 0; /* timed out */
3909                 goto retry;
3910         }
3911         
3912         return 1;
3913 }
3914
3915 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
3916 {
3917         atmel_writeAR(priv->dev, pos);  
3918         atmel_write16(priv->dev, DR, data); /* card is little-endian */
3919         atmel_write16(priv->dev, DR, data >> 16);
3920 }
3921
3922 /***************************************************************************/
3923 /* There follows the source form of the MAC address reading firmware       */
3924 /***************************************************************************/
3925 #if 0
3926
3927 /* Copyright 2003 Matthew T. Russotto                                      */
3928 /* But derived from the Atmel 76C502 firmware written by Atmel and         */
3929 /* included in "atmel wireless lan drivers" package                        */
3930 /**
3931     This file is part of net.russotto.AtmelMACFW, hereto referred to
3932     as AtmelMACFW
3933
3934     AtmelMACFW is free software; you can redistribute it and/or modify
3935     it under the terms of the GNU General Public License version 2
3936     as published by the Free Software Foundation.
3937
3938     AtmelMACFW is distributed in the hope that it will be useful,
3939     but WITHOUT ANY WARRANTY; without even the implied warranty of
3940     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3941     GNU General Public License for more details.
3942
3943     You should have received a copy of the GNU General Public License
3944     along with AtmelMACFW; if not, write to the Free Software
3945     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
3946
3947 ****************************************************************************/
3948 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
3949 /* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
3950 /* It only works on SPI EEPROM versions of the card.                       */
3951
3952 /* This firmware initializes the SPI controller and clock, reads the MAC   */
3953 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
3954 /* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
3955 /* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
3956 /* MR4, for investigational purposes (maybe we can determine chip type     */
3957 /* from that?)                                                             */
3958
3959         .org 0
3960     .set MRBASE, 0x8000000
3961         .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
3962         .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
3963         .set SRAM_BASE,  0x02000000
3964         .set SP_BASE,    0x0F300000
3965         .set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
3966         .set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
3967         .set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
3968         .set STACK_BASE, 0x5600
3969         .set SP_SR, 0x10
3970         .set SP_TDRE, 2 /* status register bit -- TDR empty */
3971         .set SP_RDRF, 1 /* status register bit -- RDR full */
3972         .set SP_SWRST, 0x80
3973         .set SP_SPIEN, 0x1
3974         .set SP_CR, 0   /* control register */
3975         .set SP_MR, 4   /* mode register */
3976         .set SP_RDR, 0x08 /* Read Data Register */
3977         .set SP_TDR, 0x0C /* Transmit Data Register */
3978         .set SP_CSR0, 0x30 /* chip select registers */
3979         .set SP_CSR1, 0x34
3980         .set SP_CSR2, 0x38
3981         .set SP_CSR3, 0x3C
3982         .set NVRAM_CMD_RDSR, 5 /* read status register */
3983         .set NVRAM_CMD_READ, 3 /* read data */
3984         .set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
3985         .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
3986                                   serial output, since SO is normally high.  But it
3987                                   does cause 8 clock cycles and thus 8 bits to be
3988                                   clocked in to the chip.  See Atmel's SPI
3989                                   controller (e.g. AT91M55800) timing and 4K 
3990                                   SPI EEPROM manuals */
3991                                  
3992         .set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
3993         .set NVRAM_IMAGE, 0x02000200
3994         .set NVRAM_LENGTH, 0x0200
3995         .set MAC_ADDRESS_MIB, SRAM_BASE
3996         .set MAC_ADDRESS_LENGTH, 6
3997         .set MAC_BOOT_FLAG, 0x10
3998         .set MR1, 0
3999         .set MR2, 4
4000         .set MR3, 8
4001         .set MR4, 0xC
4002 RESET_VECTOR:
4003         b RESET_HANDLER
4004 UNDEF_VECTOR:  
4005         b HALT1
4006 SWI_VECTOR:            
4007         b HALT1
4008 IABORT_VECTOR: 
4009         b HALT1
4010 DABORT_VECTOR:         
4011 RESERVED_VECTOR:    
4012         b HALT1
4013 IRQ_VECTOR:    
4014         b HALT1
4015 FIQ_VECTOR:    
4016         b HALT1
4017 HALT1:  b HALT1
4018 RESET_HANDLER:
4019         mov     r0, #CPSR_INITIAL
4020         msr     CPSR_c, r0      /* This is probably unnecessary */
4021                         
4022 /* I'm guessing this is initializing clock generator electronics for SPI */
4023         ldr     r0, =SPI_CGEN_BASE
4024         mov     r1, #0
4025         mov     r1, r1, lsl #3
4026         orr     r1,r1, #0
4027         str     r1, [r0]
4028         ldr     r1, [r0, #28]
4029         bic     r1, r1, #16
4030         str     r1, [r0, #28]
4031         mov     r1, #1
4032         str     r1, [r0, #8]
4033         
4034         ldr     r0, =MRBASE
4035         mov     r1, #0
4036         strh    r1, [r0, #MR1]
4037         strh    r1, [r0, #MR2]
4038         strh    r1, [r0, #MR3]
4039         strh    r1, [r0, #MR4]
4040
4041         mov     sp, #STACK_BASE
4042         bl      SP_INIT
4043         mov     r0, #10
4044         bl      DELAY9
4045         bl      GET_MAC_ADDR
4046         bl      GET_WHOLE_NVRAM
4047         ldr     r0, =MRBASE
4048         ldr     r1, =MAC_ADDRESS_MIB
4049         strh    r1, [r0, #MR2]
4050         ldr     r1, =NVRAM_IMAGE
4051         strh    r1, [r0, #MR4]
4052         mov     r1, #MAC_BOOT_FLAG
4053         strh    r1, [r0, #MR3]
4054 HALT2:  b HALT2
4055 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4056 GET_WHOLE_NVRAM:
4057         stmdb   sp!, {lr}
4058         mov     r2, #0 /* 0th bytes of NVRAM */
4059         mov     r3, #NVRAM_LENGTH
4060         mov     r1, #0          /* not used in routine */
4061         ldr     r0, =NVRAM_IMAGE
4062         bl      NVRAM_XFER
4063         ldmia   sp!, {lr}
4064         bx      lr
4065 .endfunc
4066         
4067 .func Get_MAC_Addr, GET_MAC_ADDR
4068 GET_MAC_ADDR:
4069         stmdb   sp!, {lr}
4070         mov     r2, #0x120      /* address of MAC Address within NVRAM */
4071         mov     r3, #MAC_ADDRESS_LENGTH
4072         mov     r1, #0          /* not used in routine */
4073         ldr     r0, =MAC_ADDRESS_MIB
4074         bl      NVRAM_XFER
4075         ldmia   sp!, {lr}
4076         bx      lr
4077 .endfunc
4078 .ltorg
4079 .func Delay9, DELAY9
4080 DELAY9:
4081         adds    r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
4082 DELAYLOOP:      
4083         beq     DELAY9_done
4084         subs    r0, r0, #1
4085         b       DELAYLOOP
4086 DELAY9_done:    
4087         bx      lr
4088 .endfunc        
4089
4090 .func SP_Init, SP_INIT
4091 SP_INIT:
4092         mov     r1, #SP_SWRST
4093         ldr     r0, =SP_BASE
4094         str     r1, [r0, #SP_CR] /* reset the SPI */
4095         mov     r1, #0
4096         str     r1, [r0, #SP_CR] /* release SPI from reset state */
4097         mov     r1, #SP_SPIEN
4098         str     r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4099         str     r1, [r0, #SP_CR] /* enable the SPI */
4100
4101 /*  My guess would be this turns on the SPI clock */
4102         ldr     r3, =SPI_CGEN_BASE
4103         ldr     r1, [r3, #28]
4104         orr     r1, r1, #0x2000
4105         str     r1, [r3, #28]
4106
4107         ldr     r1, =0x2000c01
4108         str     r1, [r0, #SP_CSR0]
4109         ldr     r1, =0x2000201
4110         str     r1, [r0, #SP_CSR1]
4111         str     r1, [r0, #SP_CSR2]
4112         str     r1, [r0, #SP_CSR3]
4113         ldr     r1, [r0, #SP_SR]
4114         ldr     r0, [r0, #SP_RDR]
4115         bx      lr
4116 .endfunc
4117 .func NVRAM_Init, NVRAM_INIT    
4118 NVRAM_INIT:
4119         ldr     r1, =SP_BASE
4120         ldr     r0, [r1, #SP_RDR]
4121         mov     r0, #NVRAM_CMD_RDSR
4122         str     r0, [r1, #SP_TDR]
4123 SP_loop1:       
4124         ldr     r0, [r1, #SP_SR]
4125         tst     r0, #SP_TDRE
4126         beq     SP_loop1
4127
4128         mov     r0, #SPI_8CLOCKS
4129         str     r0, [r1, #SP_TDR] 
4130 SP_loop2:       
4131         ldr     r0, [r1, #SP_SR]
4132         tst     r0, #SP_TDRE
4133         beq     SP_loop2
4134
4135         ldr     r0, [r1, #SP_RDR]
4136 SP_loop3:       
4137         ldr     r0, [r1, #SP_SR]
4138         tst     r0, #SP_RDRF
4139         beq     SP_loop3
4140
4141         ldr     r0, [r1, #SP_RDR]
4142         and     r0, r0, #255
4143         bx      lr
4144 .endfunc
4145         
4146 .func NVRAM_Xfer, NVRAM_XFER
4147         /* r0 = dest address */
4148         /* r1 = not used */
4149         /* r2 = src address within NVRAM */
4150         /* r3 = length */
4151 NVRAM_XFER:
4152         stmdb   sp!, {r4, r5, lr}
4153         mov     r5, r0          /* save r0 (dest address) */
4154         mov     r4, r3          /* save r3 (length) */
4155         mov     r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
4156         and     r0, r0, #8
4157         add     r0, r0, #NVRAM_CMD_READ 
4158         ldr     r1, =NVRAM_SCRATCH
4159         strb    r0, [r1, #0]    /* save command in NVRAM_SCRATCH[0] */
4160         strb    r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
4161 _local1:        
4162         bl      NVRAM_INIT
4163         tst     r0, #NVRAM_SR_RDY
4164         bne     _local1
4165         mov     r0, #20
4166         bl      DELAY9
4167         mov     r2, r4          /* length */
4168         mov     r1, r5          /* dest address */
4169         mov     r0, #2          /* bytes to transfer in command */
4170         bl      NVRAM_XFER2
4171         ldmia   sp!, {r4, r5, lr}
4172         bx      lr
4173 .endfunc
4174
4175 .func NVRAM_Xfer2, NVRAM_XFER2
4176 NVRAM_XFER2:
4177         stmdb   sp!, {r4, r5, r6, lr}
4178         ldr     r4, =SP_BASE
4179         mov     r3, #0
4180         cmp     r0, #0
4181         bls     _local2
4182         ldr     r5, =NVRAM_SCRATCH
4183 _local4:        
4184         ldrb    r6, [r5, r3]
4185         str     r6, [r4, #SP_TDR]
4186 _local3:
4187         ldr     r6, [r4, #SP_SR]
4188         tst     r6, #SP_TDRE
4189         beq     _local3
4190         add     r3, r3, #1
4191         cmp     r3, r0 /* r0 is # of bytes to send out (command+addr) */
4192         blo     _local4
4193 _local2:
4194         mov     r3, #SPI_8CLOCKS
4195         str     r3, [r4, #SP_TDR]
4196         ldr     r0, [r4, #SP_RDR]
4197 _local5:        
4198         ldr     r0, [r4, #SP_SR]
4199         tst     r0, #SP_RDRF
4200         beq     _local5
4201         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 */
4202         mov     r0, #0
4203         cmp     r2, #0  /* r2 is # of bytes to copy in */
4204         bls     _local6
4205 _local7:        
4206         ldr     r5, [r4, #SP_SR]
4207         tst     r5, #SP_TDRE
4208         beq     _local7
4209         str     r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
4210 _local8:        
4211         ldr     r5, [r4, #SP_SR]
4212         tst     r5, #SP_RDRF
4213         beq     _local8
4214         ldr     r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4215         strb    r5, [r1], #1 /* postindexed */
4216         add     r0, r0, #1
4217         cmp     r0, r2
4218         blo     _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4219 _local6:
4220         mov     r0, #200
4221         bl      DELAY9
4222         ldmia   sp!, {r4, r5, r6, lr}
4223         bx      lr
4224 #endif