Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/init.h>
 43 
 44 #include <linux/kernel.h>
 45 #include <linux/ptrace.h>
 46 #include <linux/slab.h>
 47 #include <linux/string.h>
 48 #include <linux/ctype.h>
 49 #include <linux/timer.h>
 50 #include <asm/byteorder.h>
 51 #include <asm/io.h>
 52 #include <asm/system.h>
 53 #include <asm/uaccess.h>
 54 #include <linux/module.h>
 55 #include <linux/netdevice.h>
 56 #include <linux/etherdevice.h>
 57 #include <linux/skbuff.h>
 58 #include <linux/if_arp.h>
 59 #include <linux/ioport.h>
 60 #include <linux/fcntl.h>
 61 #include <linux/delay.h>
 62 #include <linux/wireless.h>
 63 #include <net/iw_handler.h>
 64 #include <linux/crc32.h>
 65 #include <linux/proc_fs.h>
 66 #include <linux/device.h>
 67 #include <linux/moduleparam.h>
 68 #include <linux/firmware.h>
 69 #include <linux/jiffies.h>
 70 #include <linux/ieee80211.h>
 71 #include "atmel.h"
 72 
 73 #define DRIVER_MAJOR 0
 74 #define DRIVER_MINOR 98
 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 /* table of firmware file names */
 87 static struct {
 88         AtmelFWType fw_type;
 89         const char *fw_file;
 90         const char *fw_file_ext;
 91 } fw_table[] = {
 92         { ATMEL_FW_TYPE_502,            "atmel_at76c502",       "bin" },
 93         { ATMEL_FW_TYPE_502D,           "atmel_at76c502d",      "bin" },
 94         { ATMEL_FW_TYPE_502E,           "atmel_at76c502e",      "bin" },
 95         { ATMEL_FW_TYPE_502_3COM,       "atmel_at76c502_3com",  "bin" },
 96         { ATMEL_FW_TYPE_504,            "atmel_at76c504",       "bin" },
 97         { ATMEL_FW_TYPE_504_2958,       "atmel_at76c504_2958",  "bin" },
 98         { ATMEL_FW_TYPE_504A_2958,      "atmel_at76c504a_2958", "bin" },
 99         { ATMEL_FW_TYPE_506,            "atmel_at76c506",       "bin" },
100         { ATMEL_FW_TYPE_NONE,           NULL,                   NULL }
101 };
102 
103 #define MAX_SSID_LENGTH 32
104 #define MGMT_JIFFIES (256 * HZ / 100)
105 
106 #define MAX_BSS_ENTRIES 64
107 
108 /* registers */
109 #define GCR  0x00    /* (SIR0)  General Configuration Register */
110 #define BSR  0x02    /* (SIR1)  Bank Switching Select Register */
111 #define AR   0x04
112 #define DR   0x08
113 #define MR1  0x12    /* Mirror Register 1 */
114 #define MR2  0x14    /* Mirror Register 2 */
115 #define MR3  0x16    /* Mirror Register 3 */
116 #define MR4  0x18    /* Mirror Register 4 */
117 
118 #define GPR1                            0x0c
119 #define GPR2                            0x0e
120 #define GPR3                            0x10
121 /*
122  * Constants for the GCR register.
123  */
124 #define GCR_REMAP     0x0400          /* Remap internal SRAM to 0 */
125 #define GCR_SWRES     0x0080          /* BIU reset (ARM and PAI are NOT reset) */
126 #define GCR_CORES     0x0060          /* Core Reset (ARM and PAI are reset) */
127 #define GCR_ENINT     0x0002          /* Enable Interrupts */
128 #define GCR_ACKINT    0x0008          /* Acknowledge Interrupts */
129 
130 #define BSS_SRAM      0x0200          /* AMBA module selection --> SRAM */
131 #define BSS_IRAM      0x0100          /* AMBA module selection --> IRAM */
132 /*
133  *Constants for the MR registers.
134  */
135 #define MAC_INIT_COMPLETE       0x0001        /* MAC init has been completed */
136 #define MAC_BOOT_COMPLETE       0x0010        /* MAC boot has been completed */
137 #define MAC_INIT_OK             0x0002        /* MAC boot has been completed */
138 
139 #define MIB_MAX_DATA_BYTES    212
140 #define MIB_HEADER_SIZE       4    /* first four fields */
141 
142 struct get_set_mib {
143         u8 type;
144         u8 size;
145         u8 index;
146         u8 reserved;
147         u8 data[MIB_MAX_DATA_BYTES];
148 };
149 
150 struct rx_desc {
151         u32          Next;
152         u16          MsduPos;
153         u16          MsduSize;
154 
155         u8           State;
156         u8           Status;
157         u8           Rate;
158         u8           Rssi;
159         u8           LinkQuality;
160         u8           PreambleType;
161         u16          Duration;
162         u32          RxTime;
163 };
164 
165 #define RX_DESC_FLAG_VALID       0x80
166 #define RX_DESC_FLAG_CONSUMED    0x40
167 #define RX_DESC_FLAG_IDLE        0x00
168 
169 #define RX_STATUS_SUCCESS        0x00
170 
171 #define RX_DESC_MSDU_POS_OFFSET      4
172 #define RX_DESC_MSDU_SIZE_OFFSET     6
173 #define RX_DESC_FLAGS_OFFSET         8
174 #define RX_DESC_STATUS_OFFSET        9
175 #define RX_DESC_RSSI_OFFSET          11
176 #define RX_DESC_LINK_QUALITY_OFFSET  12
177 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
178 #define RX_DESC_DURATION_OFFSET      14
179 #define RX_DESC_RX_TIME_OFFSET       16
180 
181 struct tx_desc {
182         u32       NextDescriptor;
183         u16       TxStartOfFrame;
184         u16       TxLength;
185 
186         u8        TxState;
187         u8        TxStatus;
188         u8        RetryCount;
189 
190         u8        TxRate;
191 
192         u8        KeyIndex;
193         u8        ChiperType;
194         u8        ChipreLength;
195         u8        Reserved1;
196 
197         u8        Reserved;
198         u8        PacketType;
199         u16       HostTxLength;
200 };
201 
202 #define TX_DESC_NEXT_OFFSET          0
203 #define TX_DESC_POS_OFFSET           4
204 #define TX_DESC_SIZE_OFFSET          6
205 #define TX_DESC_FLAGS_OFFSET         8
206 #define TX_DESC_STATUS_OFFSET        9
207 #define TX_DESC_RETRY_OFFSET         10
208 #define TX_DESC_RATE_OFFSET          11
209 #define TX_DESC_KEY_INDEX_OFFSET     12
210 #define TX_DESC_CIPHER_TYPE_OFFSET   13
211 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
212 #define TX_DESC_PACKET_TYPE_OFFSET   17
213 #define TX_DESC_HOST_LENGTH_OFFSET   18
214 
215 /*
216  * Host-MAC interface
217  */
218 
219 #define TX_STATUS_SUCCESS       0x00
220 
221 #define TX_FIRM_OWN             0x80
222 #define TX_DONE                 0x40
223 
224 #define TX_ERROR                0x01
225 
226 #define TX_PACKET_TYPE_DATA     0x01
227 #define TX_PACKET_TYPE_MGMT     0x02
228 
229 #define ISR_EMPTY               0x00        /* no bits set in ISR */
230 #define ISR_TxCOMPLETE          0x01        /* packet transmitted */
231 #define ISR_RxCOMPLETE          0x02        /* packet received */
232 #define ISR_RxFRAMELOST         0x04        /* Rx Frame lost */
233 #define ISR_FATAL_ERROR         0x08        /* Fatal error */
234 #define ISR_COMMAND_COMPLETE    0x10        /* command completed */
235 #define ISR_OUT_OF_RANGE        0x20        /* command completed */
236 #define ISR_IBSS_MERGE          0x40        /* (4.1.2.30): IBSS merge */
237 #define ISR_GENERIC_IRQ         0x80
238 
239 #define Local_Mib_Type          0x01
240 #define Mac_Address_Mib_Type    0x02
241 #define Mac_Mib_Type            0x03
242 #define Statistics_Mib_Type     0x04
243 #define Mac_Mgmt_Mib_Type       0x05
244 #define Mac_Wep_Mib_Type        0x06
245 #define Phy_Mib_Type            0x07
246 #define Multi_Domain_MIB        0x08
247 
248 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
249 #define MAC_MIB_FRAG_THRESHOLD_POS            8
250 #define MAC_MIB_RTS_THRESHOLD_POS             10
251 #define MAC_MIB_SHORT_RETRY_POS               16
252 #define MAC_MIB_LONG_RETRY_POS                17
253 #define MAC_MIB_SHORT_RETRY_LIMIT_POS         16
254 #define MAC_MGMT_MIB_BEACON_PER_POS           0
255 #define MAC_MGMT_MIB_STATION_ID_POS           6
256 #define MAC_MGMT_MIB_CUR_PRIVACY_POS          11
257 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
258 #define MAC_MGMT_MIB_PS_MODE_POS              53
259 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS      54
260 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
261 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED     57
262 #define PHY_MIB_CHANNEL_POS                   14
263 #define PHY_MIB_RATE_SET_POS                  20
264 #define PHY_MIB_REG_DOMAIN_POS                26
265 #define LOCAL_MIB_AUTO_TX_RATE_POS            3
266 #define LOCAL_MIB_SSID_SIZE                   5
267 #define LOCAL_MIB_TX_PROMISCUOUS_POS          6
268 #define LOCAL_MIB_TX_MGMT_RATE_POS            7
269 #define LOCAL_MIB_TX_CONTROL_RATE_POS         8
270 #define LOCAL_MIB_PREAMBLE_TYPE               9
271 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
272 
273 #define         CMD_Set_MIB_Vars              0x01
274 #define         CMD_Get_MIB_Vars              0x02
275 #define         CMD_Scan                      0x03
276 #define         CMD_Join                      0x04
277 #define         CMD_Start                     0x05
278 #define         CMD_EnableRadio               0x06
279 #define         CMD_DisableRadio              0x07
280 #define         CMD_SiteSurvey                0x0B
281 
282 #define         CMD_STATUS_IDLE                   0x00
283 #define         CMD_STATUS_COMPLETE               0x01
284 #define         CMD_STATUS_UNKNOWN                0x02
285 #define         CMD_STATUS_INVALID_PARAMETER      0x03
286 #define         CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
287 #define         CMD_STATUS_TIME_OUT               0x07
288 #define         CMD_STATUS_IN_PROGRESS            0x08
289 #define         CMD_STATUS_REJECTED_RADIO_OFF     0x09
290 #define         CMD_STATUS_HOST_ERROR             0xFF
291 #define         CMD_STATUS_BUSY                   0xFE
292 
293 #define CMD_BLOCK_COMMAND_OFFSET        0
294 #define CMD_BLOCK_STATUS_OFFSET         1
295 #define CMD_BLOCK_PARAMETERS_OFFSET     4
296 
297 #define SCAN_OPTIONS_SITE_SURVEY        0x80
298 
299 #define MGMT_FRAME_BODY_OFFSET          24
300 #define MAX_AUTHENTICATION_RETRIES      3
301 #define MAX_ASSOCIATION_RETRIES         3
302 
303 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
304 
305 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
306 #define LOOP_RETRY_LIMIT   500000
307 
308 #define ACTIVE_MODE     1
309 #define PS_MODE         2
310 
311 #define MAX_ENCRYPTION_KEYS 4
312 #define MAX_ENCRYPTION_KEY_SIZE 40
313 
314 /*
315  * 802.11 related definitions
316  */
317 
318 /*
319  * Regulatory Domains
320  */
321 
322 #define REG_DOMAIN_FCC          0x10    /* Channels     1-11    USA                             */
323 #define REG_DOMAIN_DOC          0x20    /* Channel      1-11    Canada                          */
324 #define REG_DOMAIN_ETSI         0x30    /* Channel      1-13    Europe (ex Spain/France)        */
325 #define REG_DOMAIN_SPAIN        0x31    /* Channel      10-11   Spain                           */
326 #define REG_DOMAIN_FRANCE       0x32    /* Channel      10-13   France                          */
327 #define REG_DOMAIN_MKK          0x40    /* Channel      14      Japan                           */
328 #define REG_DOMAIN_MKK1         0x41    /* Channel      1-14    Japan(MKK1)                     */
329 #define REG_DOMAIN_ISRAEL       0x50    /* Channel      3-9     ISRAEL                          */
330 
331 #define BSS_TYPE_AD_HOC         1
332 #define BSS_TYPE_INFRASTRUCTURE 2
333 
334 #define SCAN_TYPE_ACTIVE        0
335 #define SCAN_TYPE_PASSIVE       1
336 
337 #define LONG_PREAMBLE           0
338 #define SHORT_PREAMBLE          1
339 #define AUTO_PREAMBLE           2
340 
341 #define DATA_FRAME_WS_HEADER_SIZE   30
342 
343 /* promiscuous mode control */
344 #define PROM_MODE_OFF                   0x0
345 #define PROM_MODE_UNKNOWN               0x1
346 #define PROM_MODE_CRC_FAILED            0x2
347 #define PROM_MODE_DUPLICATED            0x4
348 #define PROM_MODE_MGMT                  0x8
349 #define PROM_MODE_CTRL                  0x10
350 #define PROM_MODE_BAD_PROTOCOL          0x20
351 
352 #define IFACE_INT_STATUS_OFFSET         0
353 #define IFACE_INT_MASK_OFFSET           1
354 #define IFACE_LOCKOUT_HOST_OFFSET       2
355 #define IFACE_LOCKOUT_MAC_OFFSET        3
356 #define IFACE_FUNC_CTRL_OFFSET          28
357 #define IFACE_MAC_STAT_OFFSET           30
358 #define IFACE_GENERIC_INT_TYPE_OFFSET   32
359 
360 #define CIPHER_SUITE_NONE     0
361 #define CIPHER_SUITE_WEP_64   1
362 #define CIPHER_SUITE_TKIP     2
363 #define CIPHER_SUITE_AES      3
364 #define CIPHER_SUITE_CCX      4
365 #define CIPHER_SUITE_WEP_128  5
366 
367 /*
368  * IFACE MACROS & definitions
369  */
370 
371 /*
372  * FuncCtrl field:
373  */
374 #define FUNC_CTRL_TxENABLE              0x10
375 #define FUNC_CTRL_RxENABLE              0x20
376 #define FUNC_CTRL_INIT_COMPLETE         0x01
377 
378 /* A stub firmware image which reads the MAC address from NVRAM on the card.
379    For copyright information and source see the end of this file. */
380 static u8 mac_reader[] = {
381         0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
382         0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
383         0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
384         0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
385         0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
386         0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
387         0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
388         0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
389         0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
390         0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
391         0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
392         0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
393         0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
394         0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
395         0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
396         0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
397         0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
398         0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
399         0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
400         0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
401         0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
402         0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
403         0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
404         0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
405         0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
406         0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
407         0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
408         0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
409         0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
410         0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
411         0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
412         0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
413         0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
414         0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
415         0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
416         0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
417         0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
418         0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
419         0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
420         0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
421         0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
422         0x00, 0x01, 0x00, 0x02
423 };
424 
425 struct atmel_private {
426         void *card; /* Bus dependent stucture varies for PCcard */
427         int (*present_callback)(void *); /* And callback which uses it */
428         char firmware_id[32];
429         AtmelFWType firmware_type;
430         u8 *firmware;
431         int firmware_length;
432         struct timer_list management_timer;
433         struct net_device *dev;
434         struct device *sys_dev;
435         struct iw_statistics wstats;
436         spinlock_t irqlock, timerlock;  /* spinlocks */
437         enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
438         enum {
439                 CARD_TYPE_PARALLEL_FLASH,
440                 CARD_TYPE_SPI_FLASH,
441                 CARD_TYPE_EEPROM
442         } card_type;
443         int do_rx_crc; /* If we need to CRC incoming packets */
444         int probe_crc; /* set if we don't yet know */
445         int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
446         u16 rx_desc_head;
447         u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
448         u16 tx_free_mem, tx_buff_head, tx_buff_tail;
449 
450         u16 frag_seq, frag_len, frag_no;
451         u8 frag_source[6];
452 
453         u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
454         u8 group_cipher_suite, pairwise_cipher_suite;
455         u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
456         int wep_key_len[MAX_ENCRYPTION_KEYS];
457         int use_wpa, radio_on_broken; /* firmware dependent stuff. */
458 
459         u16 host_info_base;
460         struct host_info_struct {
461                 /* NB this is matched to the hardware, don't change. */
462                 u8 volatile int_status;
463                 u8 volatile int_mask;
464                 u8 volatile lockout_host;
465                 u8 volatile lockout_mac;
466 
467                 u16 tx_buff_pos;
468                 u16 tx_buff_size;
469                 u16 tx_desc_pos;
470                 u16 tx_desc_count;
471 
472                 u16 rx_buff_pos;
473                 u16 rx_buff_size;
474                 u16 rx_desc_pos;
475                 u16 rx_desc_count;
476 
477                 u16 build_version;
478                 u16 command_pos;
479 
480                 u16 major_version;
481                 u16 minor_version;
482 
483                 u16 func_ctrl;
484                 u16 mac_status;
485                 u16 generic_IRQ_type;
486                 u8  reserved[2];
487         } host_info;
488 
489         enum {
490                 STATION_STATE_SCANNING,
491                 STATION_STATE_JOINNING,
492                 STATION_STATE_AUTHENTICATING,
493                 STATION_STATE_ASSOCIATING,
494                 STATION_STATE_READY,
495                 STATION_STATE_REASSOCIATING,
496                 STATION_STATE_DOWN,
497                 STATION_STATE_MGMT_ERROR
498         } station_state;
499 
500         int operating_mode, power_mode;
501         time_t last_qual;
502         int beacons_this_sec;
503         int channel;
504         int reg_domain, config_reg_domain;
505         int tx_rate;
506         int auto_tx_rate;
507         int rts_threshold;
508         int frag_threshold;
509         int long_retry, short_retry;
510         int preamble;
511         int default_beacon_period, beacon_period, listen_interval;
512         int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
513         int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
514         enum {
515                 SITE_SURVEY_IDLE,
516                 SITE_SURVEY_IN_PROGRESS,
517                 SITE_SURVEY_COMPLETED
518         } site_survey_state;
519         unsigned long last_survey;
520 
521         int station_was_associated, station_is_associated;
522         int fast_scan;
523 
524         struct bss_info {
525                 int channel;
526                 int SSIDsize;
527                 int RSSI;
528                 int UsingWEP;
529                 int preamble;
530                 int beacon_period;
531                 int BSStype;
532                 u8 BSSID[6];
533                 u8 SSID[MAX_SSID_LENGTH];
534         } BSSinfo[MAX_BSS_ENTRIES];
535         int BSS_list_entries, current_BSS;
536         int connect_to_any_BSS;
537         int SSID_size, new_SSID_size;
538         u8 CurrentBSSID[6], BSSID[6];
539         u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
540         u64 last_beacon_timestamp;
541         u8 rx_buf[MAX_WIRELESS_BODY];
542 };
543 
544 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
545 
546 static const struct {
547         int reg_domain;
548         int min, max;
549         char *name;
550 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
551                       { REG_DOMAIN_DOC, 1, 11, "Canada" },
552                       { REG_DOMAIN_ETSI, 1, 13, "Europe" },
553                       { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
554                       { REG_DOMAIN_FRANCE, 10, 13, "France" },
555                       { REG_DOMAIN_MKK, 14, 14, "MKK" },
556                       { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
557                       { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
558 
559 static void build_wpa_mib(struct atmel_private *priv);
560 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
561 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
562                                const unsigned char *src, u16 len);
563 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
564                                u16 src, u16 len);
565 static void atmel_set_gcr(struct net_device *dev, u16 mask);
566 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
567 static int atmel_lock_mac(struct atmel_private *priv);
568 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
569 static void atmel_command_irq(struct atmel_private *priv);
570 static int atmel_validate_channel(struct atmel_private *priv, int channel);
571 static void atmel_management_frame(struct atmel_private *priv,
572                                    struct ieee80211_hdr *header,
573                                    u16 frame_len, u8 rssi);
574 static void atmel_management_timer(u_long a);
575 static void atmel_send_command(struct atmel_private *priv, int command,
576                                void *cmd, int cmd_size);
577 static int atmel_send_command_wait(struct atmel_private *priv, int command,
578                                    void *cmd, int cmd_size);
579 static void atmel_transmit_management_frame(struct atmel_private *priv,
580                                             struct ieee80211_hdr *header,
581                                             u8 *body, int body_len);
582 
583 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
584 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
585                            u8 data);
586 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
587                             u16 data);
588 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
589                           u8 *data, int data_len);
590 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
591                           u8 *data, int data_len);
592 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
593 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
594 static void atmel_smooth_qual(struct atmel_private *priv);
595 static void atmel_writeAR(struct net_device *dev, u16 data);
596 static int probe_atmel_card(struct net_device *dev);
597 static int reset_atmel_card(struct net_device *dev);
598 static void atmel_enter_state(struct atmel_private *priv, int new_state);
599 int atmel_open (struct net_device *dev);
600 
601 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
602 {
603         return priv->host_info_base + offset;
604 }
605 
606 static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
607 {
608         return priv->host_info.command_pos + offset;
609 }
610 
611 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
612 {
613         return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
614 }
615 
616 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
617 {
618         return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
619 }
620 
621 static inline u8 atmel_read8(struct net_device *dev, u16 offset)
622 {
623         return inb(dev->base_addr + offset);
624 }
625 
626 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
627 {
628         outb(data, dev->base_addr + offset);
629 }
630 
631 static inline u16 atmel_read16(struct net_device *dev, u16 offset)
632 {
633         return inw(dev->base_addr + offset);
634 }
635 
636 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
637 {
638         outw(data, dev->base_addr + offset);
639 }
640 
641 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
642 {
643         atmel_writeAR(priv->dev, pos);
644         return atmel_read8(priv->dev, DR);
645 }
646 
647 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
648 {
649         atmel_writeAR(priv->dev, pos);
650         atmel_write8(priv->dev, DR, data);
651 }
652 
653 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
654 {
655         atmel_writeAR(priv->dev, pos);
656         return atmel_read16(priv->dev, DR);
657 }
658 
659 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
660 {
661         atmel_writeAR(priv->dev, pos);
662         atmel_write16(priv->dev, DR, data);
663 }
664 
665 static const struct iw_handler_def atmel_handler_def;
666 
667 static void tx_done_irq(struct atmel_private *priv)
668 {
669         int i;
670 
671         for (i = 0;
672              atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
673                      i < priv->host_info.tx_desc_count;
674              i++) {
675                 u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
676                 u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
677                 u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
678 
679                 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
680 
681                 priv->tx_free_mem += msdu_size;
682                 priv->tx_desc_free++;
683 
684                 if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
685                         priv->tx_buff_head = 0;
686                 else
687                         priv->tx_buff_head += msdu_size;
688 
689                 if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
690                         priv->tx_desc_head++ ;
691                 else
692                         priv->tx_desc_head = 0;
693 
694                 if (type == TX_PACKET_TYPE_DATA) {
695                         if (status == TX_STATUS_SUCCESS)
696                                 priv->dev->stats.tx_packets++;
697                         else
698                                 priv->dev->stats.tx_errors++;
699                         netif_wake_queue(priv->dev);
700                 }
701         }
702 }
703 
704 static u16 find_tx_buff(struct atmel_private *priv, u16 len)
705 {
706         u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
707 
708         if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
709                 return 0;
710 
711         if (bottom_free >= len)
712                 return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
713 
714         if (priv->tx_free_mem - bottom_free >= len) {
715                 priv->tx_buff_tail = 0;
716                 return priv->host_info.tx_buff_pos;
717         }
718 
719         return 0;
720 }
721 
722 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
723                                  u16 len, u16 buff, u8 type)
724 {
725         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
726         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
727         if (!priv->use_wpa)
728                 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
729         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
730         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
731         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
732         if (priv->use_wpa) {
733                 int cipher_type, cipher_length;
734                 if (is_bcast) {
735                         cipher_type = priv->group_cipher_suite;
736                         if (cipher_type == CIPHER_SUITE_WEP_64 ||
737                             cipher_type == CIPHER_SUITE_WEP_128)
738                                 cipher_length = 8;
739                         else if (cipher_type == CIPHER_SUITE_TKIP)
740                                 cipher_length = 12;
741                         else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
742                                  priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
743                                 cipher_type = priv->pairwise_cipher_suite;
744                                 cipher_length = 8;
745                         } else {
746                                 cipher_type = CIPHER_SUITE_NONE;
747                                 cipher_length = 0;
748                         }
749                 } else {
750                         cipher_type = priv->pairwise_cipher_suite;
751                         if (cipher_type == CIPHER_SUITE_WEP_64 ||
752                             cipher_type == CIPHER_SUITE_WEP_128)
753                                 cipher_length = 8;
754                         else if (cipher_type == CIPHER_SUITE_TKIP)
755                                 cipher_length = 12;
756                         else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
757                                  priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
758                                 cipher_type = priv->group_cipher_suite;
759                                 cipher_length = 8;
760                         } else {
761                                 cipher_type = CIPHER_SUITE_NONE;
762                                 cipher_length = 0;
763                         }
764                 }
765 
766                 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
767                             cipher_type);
768                 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
769                             cipher_length);
770         }
771         atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
772         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
773         if (priv->tx_desc_previous != priv->tx_desc_tail)
774                 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
775         priv->tx_desc_previous = priv->tx_desc_tail;
776         if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
777                 priv->tx_desc_tail++;
778         else
779                 priv->tx_desc_tail = 0;
780         priv->tx_desc_free--;
781         priv->tx_free_mem -= len;
782 }
783 
784 static int start_tx(struct sk_buff *skb, struct net_device *dev)
785 {
786         static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
787         struct atmel_private *priv = netdev_priv(dev);
788         struct ieee80211_hdr header;
789         unsigned long flags;
790         u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
791 
792         if (priv->card && priv->present_callback &&
793             !(*priv->present_callback)(priv->card)) {
794                 dev->stats.tx_errors++;
795                 dev_kfree_skb(skb);
796                 return 0;
797         }
798 
799         if (priv->station_state != STATION_STATE_READY) {
800                 dev->stats.tx_errors++;
801                 dev_kfree_skb(skb);
802                 return 0;
803         }
804 
805         /* first ensure the timer func cannot run */
806         spin_lock_bh(&priv->timerlock);
807         /* then stop the hardware ISR */
808         spin_lock_irqsave(&priv->irqlock, flags);
809         /* nb doing the above in the opposite order will deadlock */
810 
811         /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
812            12 first bytes (containing DA/SA) and put them in the appropriate
813            fields of the Wireless Header. Thus the packet length is then the
814            initial + 18 (+30-12) */
815 
816         if (!(buff = find_tx_buff(priv, len + 18))) {
817                 dev->stats.tx_dropped++;
818                 spin_unlock_irqrestore(&priv->irqlock, flags);
819                 spin_unlock_bh(&priv->timerlock);
820                 netif_stop_queue(dev);
821                 return NETDEV_TX_BUSY;
822         }
823 
824         frame_ctl = IEEE80211_FTYPE_DATA;
825         header.duration_id = 0;
826         header.seq_ctrl = 0;
827         if (priv->wep_is_on)
828                 frame_ctl |= IEEE80211_FCTL_PROTECTED;
829         if (priv->operating_mode == IW_MODE_ADHOC) {
830                 skb_copy_from_linear_data(skb, &header.addr1, 6);
831                 memcpy(&header.addr2, dev->dev_addr, 6);
832                 memcpy(&header.addr3, priv->BSSID, 6);
833         } else {
834                 frame_ctl |= IEEE80211_FCTL_TODS;
835                 memcpy(&header.addr1, priv->CurrentBSSID, 6);
836                 memcpy(&header.addr2, dev->dev_addr, 6);
837                 skb_copy_from_linear_data(skb, &header.addr3, 6);
838         }
839 
840         if (priv->use_wpa)
841                 memcpy(&header.addr4, SNAP_RFC1024, 6);
842 
843         header.frame_control = cpu_to_le16(frame_ctl);
844         /* Copy the wireless header into the card */
845         atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
846         /* Copy the packet sans its 802.3 header addresses which have been replaced */
847         atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
848         priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
849 
850         /* low bit of first byte of destination tells us if broadcast */
851         tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
852         dev->trans_start = jiffies;
853         dev->stats.tx_bytes += len;
854 
855         spin_unlock_irqrestore(&priv->irqlock, flags);
856         spin_unlock_bh(&priv->timerlock);
857         dev_kfree_skb(skb);
858 
859         return 0;
860 }
861 
862 static void atmel_transmit_management_frame(struct atmel_private *priv,
863                                             struct ieee80211_hdr *header,
864                                             u8 *body, int body_len)
865 {
866         u16 buff;
867         int len = MGMT_FRAME_BODY_OFFSET + body_len;
868 
869         if (!(buff = find_tx_buff(priv, len)))
870                 return;
871 
872         atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
873         atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
874         priv->tx_buff_tail += len;
875         tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
876 }
877 
878 static void fast_rx_path(struct atmel_private *priv,
879                          struct ieee80211_hdr *header,
880                          u16 msdu_size, u16 rx_packet_loc, u32 crc)
881 {
882         /* fast path: unfragmented packet copy directly into skbuf */
883         u8 mac4[6];
884         struct sk_buff  *skb;
885         unsigned char *skbp;
886 
887         /* get the final, mac 4 header field, this tells us encapsulation */
888         atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
889         msdu_size -= 6;
890 
891         if (priv->do_rx_crc) {
892                 crc = crc32_le(crc, mac4, 6);
893                 msdu_size -= 4;
894         }
895 
896         if (!(skb = dev_alloc_skb(msdu_size + 14))) {
897                 priv->dev->stats.rx_dropped++;
898                 return;
899         }
900 
901         skb_reserve(skb, 2);
902         skbp = skb_put(skb, msdu_size + 12);
903         atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
904 
905         if (priv->do_rx_crc) {
906                 u32 netcrc;
907                 crc = crc32_le(crc, skbp + 12, msdu_size);
908                 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
909                 if ((crc ^ 0xffffffff) != netcrc) {
910                         priv->dev->stats.rx_crc_errors++;
911                         dev_kfree_skb(skb);
912                         return;
913                 }
914         }
915 
916         memcpy(skbp, header->addr1, 6); /* destination address */
917         if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
918                 memcpy(&skbp[6], header->addr3, 6);
919         else
920                 memcpy(&skbp[6], header->addr2, 6); /* source address */
921 
922         skb->protocol = eth_type_trans(skb, priv->dev);
923         skb->ip_summed = CHECKSUM_NONE;
924         netif_rx(skb);
925         priv->dev->stats.rx_bytes += 12 + msdu_size;
926         priv->dev->stats.rx_packets++;
927 }
928 
929 /* Test to see if the packet in card memory at packet_loc has a valid CRC
930    It doesn't matter that this is slow: it is only used to proble the first few
931    packets. */
932 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
933 {
934         int i = msdu_size - 4;
935         u32 netcrc, crc = 0xffffffff;
936 
937         if (msdu_size < 4)
938                 return 0;
939 
940         atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
941 
942         atmel_writeAR(priv->dev, packet_loc);
943         while (i--) {
944                 u8 octet = atmel_read8(priv->dev, DR);
945                 crc = crc32_le(crc, &octet, 1);
946         }
947 
948         return (crc ^ 0xffffffff) == netcrc;
949 }
950 
951 static void frag_rx_path(struct atmel_private *priv,
952                          struct ieee80211_hdr *header,
953                          u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
954                          u8 frag_no, int more_frags)
955 {
956         u8 mac4[6];
957         u8 source[6];
958         struct sk_buff *skb;
959 
960         if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
961                 memcpy(source, header->addr3, 6);
962         else
963                 memcpy(source, header->addr2, 6);
964 
965         rx_packet_loc += 24; /* skip header */
966 
967         if (priv->do_rx_crc)
968                 msdu_size -= 4;
969 
970         if (frag_no == 0) { /* first fragment */
971                 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6);
972                 msdu_size -= 6;
973                 rx_packet_loc += 6;
974 
975                 if (priv->do_rx_crc)
976                         crc = crc32_le(crc, mac4, 6);
977 
978                 priv->frag_seq = seq_no;
979                 priv->frag_no = 1;
980                 priv->frag_len = msdu_size;
981                 memcpy(priv->frag_source, source, 6);
982                 memcpy(&priv->rx_buf[6], source, 6);
983                 memcpy(priv->rx_buf, header->addr1, 6);
984 
985                 atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
986 
987                 if (priv->do_rx_crc) {
988                         u32 netcrc;
989                         crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
990                         atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
991                         if ((crc ^ 0xffffffff) != netcrc) {
992                                 priv->dev->stats.rx_crc_errors++;
993                                 memset(priv->frag_source, 0xff, 6);
994                         }
995                 }
996 
997         } else if (priv->frag_no == frag_no &&
998                    priv->frag_seq == seq_no &&
999                    memcmp(priv->frag_source, source, 6) == 0) {
1000 
1001                 atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1002                                    rx_packet_loc, msdu_size);
1003                 if (priv->do_rx_crc) {
1004                         u32 netcrc;
1005                         crc = crc32_le(crc,
1006                                        &priv->rx_buf[12 + priv->frag_len],
1007                                        msdu_size);
1008                         atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1009                         if ((crc ^ 0xffffffff) != netcrc) {
1010                                 priv->dev->stats.rx_crc_errors++;
1011                                 memset(priv->frag_source, 0xff, 6);
1012                                 more_frags = 1; /* don't send broken assembly */
1013                         }
1014                 }
1015 
1016                 priv->frag_len += msdu_size;
1017                 priv->frag_no++;
1018 
1019                 if (!more_frags) { /* last one */
1020                         memset(priv->frag_source, 0xff, 6);
1021                         if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1022                                 priv->dev->stats.rx_dropped++;
1023                         } else {
1024                                 skb_reserve(skb, 2);
1025                                 memcpy(skb_put(skb, priv->frag_len + 12),
1026                                        priv->rx_buf,
1027                                        priv->frag_len + 12);
1028                                 skb->protocol = eth_type_trans(skb, priv->dev);
1029                                 skb->ip_summed = CHECKSUM_NONE;
1030                                 netif_rx(skb);
1031                                 priv->dev->stats.rx_bytes += priv->frag_len + 12;
1032                                 priv->dev->stats.rx_packets++;
1033                         }
1034                 }
1035         } else
1036                 priv->wstats.discard.fragment++;
1037 }
1038 
1039 static void rx_done_irq(struct atmel_private *priv)
1040 {
1041         int i;
1042         struct ieee80211_hdr header;
1043 
1044         for (i = 0;
1045              atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1046                      i < priv->host_info.rx_desc_count;
1047              i++) {
1048 
1049                 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1050                 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1051                 u32 crc = 0xffffffff;
1052 
1053                 if (status != RX_STATUS_SUCCESS) {
1054                         if (status == 0xc1) /* determined by experiment */
1055                                 priv->wstats.discard.nwid++;
1056                         else
1057                                 priv->dev->stats.rx_errors++;
1058                         goto next;
1059                 }
1060 
1061                 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1062                 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1063 
1064                 if (msdu_size < 30) {
1065                         priv->dev->stats.rx_errors++;
1066                         goto next;
1067                 }
1068 
1069                 /* Get header as far as end of seq_ctrl */
1070                 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1071                 frame_ctl = le16_to_cpu(header.frame_control);
1072                 seq_control = le16_to_cpu(header.seq_ctrl);
1073 
1074                 /* probe for CRC use here if needed  once five packets have
1075                    arrived with the same crc status, we assume we know what's
1076                    happening and stop probing */
1077                 if (priv->probe_crc) {
1078                         if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1079                                 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1080                         } else {
1081                                 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1082                         }
1083                         if (priv->do_rx_crc) {
1084                                 if (priv->crc_ok_cnt++ > 5)
1085                                         priv->probe_crc = 0;
1086                         } else {
1087                                 if (priv->crc_ko_cnt++ > 5)
1088                                         priv->probe_crc = 0;
1089                         }
1090                 }
1091 
1092                 /* don't CRC header when WEP in use */
1093                 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1094                         crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1095                 }
1096                 msdu_size -= 24; /* header */
1097 
1098                 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1099                         int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1100                         u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1101                         u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1102 
1103                         if (!more_fragments && packet_fragment_no == 0) {
1104                                 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1105                         } else {
1106                                 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1107                                              packet_sequence_no, packet_fragment_no, more_fragments);
1108                         }
1109                 }
1110 
1111                 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1112                         /* copy rest of packet into buffer */
1113                         atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1114 
1115                         /* we use the same buffer for frag reassembly and control packets */
1116                         memset(priv->frag_source, 0xff, 6);
1117 
1118                         if (priv->do_rx_crc) {
1119                                 /* last 4 octets is crc */
1120                                 msdu_size -= 4;
1121                                 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1122                                 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1123                                         priv->dev->stats.rx_crc_errors++;
1124                                         goto next;
1125                                 }
1126                         }
1127 
1128                         atmel_management_frame(priv, &header, msdu_size,
1129                                                atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1130                 }
1131 
1132 next:
1133                 /* release descriptor */
1134                 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1135 
1136                 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1137                         priv->rx_desc_head++;
1138                 else
1139                         priv->rx_desc_head = 0;
1140         }
1141 }
1142 
1143 static irqreturn_t service_interrupt(int irq, void *dev_id)
1144 {
1145         struct net_device *dev = (struct net_device *) dev_id;
1146         struct atmel_private *priv = netdev_priv(dev);
1147         u8 isr;
1148         int i = -1;
1149         static u8 irq_order[] = {
1150                 ISR_OUT_OF_RANGE,
1151                 ISR_RxCOMPLETE,
1152                 ISR_TxCOMPLETE,
1153                 ISR_RxFRAMELOST,
1154                 ISR_FATAL_ERROR,
1155                 ISR_COMMAND_COMPLETE,
1156                 ISR_IBSS_MERGE,
1157                 ISR_GENERIC_IRQ
1158         };
1159 
1160         if (priv->card && priv->present_callback &&
1161             !(*priv->present_callback)(priv->card))
1162                 return IRQ_HANDLED;
1163 
1164         /* In this state upper-level code assumes it can mess with
1165            the card unhampered by interrupts which may change register state.
1166            Note that even though the card shouldn't generate interrupts
1167            the inturrupt line may be shared. This allows card setup
1168            to go on without disabling interrupts for a long time. */
1169         if (priv->station_state == STATION_STATE_DOWN)
1170                 return IRQ_NONE;
1171 
1172         atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1173 
1174         while (1) {
1175                 if (!atmel_lock_mac(priv)) {
1176                         /* failed to contact card */
1177                         printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1178                         return IRQ_HANDLED;
1179                 }
1180 
1181                 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1182                 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1183 
1184                 if (!isr) {
1185                         atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1186                         return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1187                 }
1188 
1189                 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1190 
1191                 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1192                         if (isr & irq_order[i])
1193                                 break;
1194 
1195                 if (!atmel_lock_mac(priv)) {
1196                         /* failed to contact card */
1197                         printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1198                         return IRQ_HANDLED;
1199                 }
1200 
1201                 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1202                 isr ^= irq_order[i];
1203                 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1204                 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1205 
1206                 switch (irq_order[i]) {
1207 
1208                 case ISR_OUT_OF_RANGE:
1209                         if (priv->operating_mode == IW_MODE_INFRA &&
1210                             priv->station_state == STATION_STATE_READY) {
1211                                 priv->station_is_associated = 0;
1212                                 atmel_scan(priv, 1);
1213                         }
1214                         break;
1215 
1216                 case ISR_RxFRAMELOST:
1217                         priv->wstats.discard.misc++;
1218                         /* fall through */
1219                 case ISR_RxCOMPLETE:
1220                         rx_done_irq(priv);
1221                         break;
1222 
1223                 case ISR_TxCOMPLETE:
1224                         tx_done_irq(priv);
1225                         break;
1226 
1227                 case ISR_FATAL_ERROR:
1228                         printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1229                         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1230                         break;
1231 
1232                 case ISR_COMMAND_COMPLETE:
1233                         atmel_command_irq(priv);
1234                         break;
1235 
1236                 case ISR_IBSS_MERGE:
1237                         atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1238                                       priv->CurrentBSSID, 6);
1239                         /* The WPA stuff cares about the current AP address */
1240                         if (priv->use_wpa)
1241                                 build_wpa_mib(priv);
1242                         break;
1243                 case ISR_GENERIC_IRQ:
1244                         printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1245                         break;
1246                 }
1247         }
1248 }
1249 
1250 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1251 {
1252         struct atmel_private *priv = netdev_priv(dev);
1253 
1254         /* update the link quality here in case we are seeing no beacons
1255            at all to drive the process */
1256         atmel_smooth_qual(priv);
1257 
1258         priv->wstats.status = priv->station_state;
1259 
1260         if (priv->operating_mode == IW_MODE_INFRA) {
1261                 if (priv->station_state != STATION_STATE_READY) {
1262                         priv->wstats.qual.qual = 0;
1263                         priv->wstats.qual.level = 0;
1264                         priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1265                                         | IW_QUAL_LEVEL_INVALID);
1266                 }
1267                 priv->wstats.qual.noise = 0;
1268                 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1269         } else {
1270                 /* Quality levels cannot be determined in ad-hoc mode,
1271                    because we can 'hear' more that one remote station. */
1272                 priv->wstats.qual.qual = 0;
1273                 priv->wstats.qual.level = 0;
1274                 priv->wstats.qual.noise = 0;
1275                 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1276                                         | IW_QUAL_LEVEL_INVALID
1277                                         | IW_QUAL_NOISE_INVALID;
1278                 priv->wstats.miss.beacon = 0;
1279         }
1280 
1281         return &priv->wstats;
1282 }
1283 
1284 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
1285 {
1286         if ((new_mtu < 68) || (new_mtu > 2312))
1287                 return -EINVAL;
1288         dev->mtu = new_mtu;
1289         return 0;
1290 }
1291 
1292 static int atmel_set_mac_address(struct net_device *dev, void *p)
1293 {
1294         struct sockaddr *addr = p;
1295 
1296         memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1297         return atmel_open(dev);
1298 }
1299 
1300 EXPORT_SYMBOL(atmel_open);
1301 
1302 int atmel_open(struct net_device *dev)
1303 {
1304         struct atmel_private *priv = netdev_priv(dev);
1305         int i, channel, err;
1306 
1307         /* any scheduled timer is no longer needed and might screw things up.. */
1308         del_timer_sync(&priv->management_timer);
1309 
1310         /* Interrupts will not touch the card once in this state... */
1311         priv->station_state = STATION_STATE_DOWN;
1312 
1313         if (priv->new_SSID_size) {
1314                 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1315                 priv->SSID_size = priv->new_SSID_size;
1316                 priv->new_SSID_size = 0;
1317         }
1318         priv->BSS_list_entries = 0;
1319 
1320         priv->AuthenticationRequestRetryCnt = 0;
1321         priv->AssociationRequestRetryCnt = 0;
1322         priv->ReAssociationRequestRetryCnt = 0;
1323         priv->CurrentAuthentTransactionSeqNum = 0x0001;
1324         priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1325 
1326         priv->site_survey_state = SITE_SURVEY_IDLE;
1327         priv->station_is_associated = 0;
1328 
1329         err = reset_atmel_card(dev);
1330         if (err)
1331                 return err;
1332 
1333         if (priv->config_reg_domain) {
1334                 priv->reg_domain = priv->config_reg_domain;
1335                 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1336         } else {
1337                 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1338                 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1339                         if (priv->reg_domain == channel_table[i].reg_domain)
1340                                 break;
1341                 if (i == ARRAY_SIZE(channel_table)) {
1342                         priv->reg_domain = REG_DOMAIN_MKK1;
1343                         printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1344                 }
1345         }
1346 
1347         if ((channel = atmel_validate_channel(priv, priv->channel)))
1348                 priv->channel = channel;
1349 
1350         /* this moves station_state on.... */
1351         atmel_scan(priv, 1);
1352 
1353         atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1354         return 0;
1355 }
1356 
1357 static int atmel_close(struct net_device *dev)
1358 {
1359         struct atmel_private *priv = netdev_priv(dev);
1360 
1361         /* Send event to userspace that we are disassociating */
1362         if (priv->station_state == STATION_STATE_READY) {
1363                 union iwreq_data wrqu;
1364 
1365                 wrqu.data.length = 0;
1366                 wrqu.data.flags = 0;
1367                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1368                 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1369                 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1370         }
1371 
1372         atmel_enter_state(priv, STATION_STATE_DOWN);
1373 
1374         if (priv->bus_type == BUS_TYPE_PCCARD)
1375                 atmel_write16(dev, GCR, 0x0060);
1376         atmel_write16(dev, GCR, 0x0040);
1377         return 0;
1378 }
1379 
1380 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1381 {
1382         /* check that channel is OK, if so return zero,
1383            else return suitable default channel */
1384         int i;
1385 
1386         for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1387                 if (priv->reg_domain == channel_table[i].reg_domain) {
1388                         if (channel >= channel_table[i].min &&
1389                             channel <= channel_table[i].max)
1390                                 return 0;
1391                         else
1392                                 return channel_table[i].min;
1393                 }
1394         return 0;
1395 }
1396 
1397 static int atmel_proc_output (char *buf, struct atmel_private *priv)
1398 {
1399         int i;
1400         char *p = buf;
1401         char *s, *r, *c;
1402 
1403         p += sprintf(p, "Driver version:\t\t%d.%d\n",
1404                      DRIVER_MAJOR, DRIVER_MINOR);
1405 
1406         if (priv->station_state != STATION_STATE_DOWN) {
1407                 p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
1408                                 "Firmware location:\t",
1409                              priv->host_info.major_version,
1410                              priv->host_info.minor_version,
1411                              priv->host_info.build_version);
1412 
1413                 if (priv->card_type != CARD_TYPE_EEPROM)
1414                         p += sprintf(p, "on card\n");
1415                 else if (priv->firmware)
1416                         p += sprintf(p, "%s loaded by host\n",
1417                                      priv->firmware_id);
1418                 else
1419                         p += sprintf(p, "%s loaded by hotplug\n",
1420                                      priv->firmware_id);
1421 
1422                 switch (priv->card_type) {
1423                 case CARD_TYPE_PARALLEL_FLASH:
1424                         c = "Parallel flash";
1425                         break;
1426                 case CARD_TYPE_SPI_FLASH:
1427                         c = "SPI flash\n";
1428                         break;
1429                 case CARD_TYPE_EEPROM:
1430                         c = "EEPROM";
1431                         break;
1432                 default:
1433                         c = "<unknown>";
1434                 }
1435 
1436                 r = "<unknown>";
1437                 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1438                         if (priv->reg_domain == channel_table[i].reg_domain)
1439                                 r = channel_table[i].name;
1440 
1441                 p += sprintf(p, "MAC memory type:\t%s\n", c);
1442                 p += sprintf(p, "Regulatory domain:\t%s\n", r);
1443                 p += sprintf(p, "Host CRC checking:\t%s\n",
1444                              priv->do_rx_crc ? "On" : "Off");
1445                 p += sprintf(p, "WPA-capable firmware:\t%s\n",
1446                              priv->use_wpa ? "Yes" : "No");
1447         }
1448 
1449         switch (priv->station_state) {
1450         case STATION_STATE_SCANNING:
1451                 s = "Scanning";
1452                 break;
1453         case STATION_STATE_JOINNING:
1454                 s = "Joining";
1455                 break;
1456         case STATION_STATE_AUTHENTICATING:
1457                 s = "Authenticating";
1458                 break;
1459         case STATION_STATE_ASSOCIATING:
1460                 s = "Associating";
1461                 break;
1462         case STATION_STATE_READY:
1463                 s = "Ready";
1464                 break;
1465         case STATION_STATE_REASSOCIATING:
1466                 s = "Reassociating";
1467                 break;
1468         case STATION_STATE_MGMT_ERROR:
1469                 s = "Management error";
1470                 break;
1471         case STATION_STATE_DOWN:
1472                 s = "Down";
1473                 break;
1474         default:
1475                 s = "<unknown>";
1476         }
1477 
1478         p += sprintf(p, "Current state:\t\t%s\n", s);
1479         return p - buf;
1480 }
1481 
1482 static int atmel_read_proc(char *page, char **start, off_t off,
1483                            int count, int *eof, void *data)
1484 {
1485         struct atmel_private *priv = data;
1486         int len = atmel_proc_output (page, priv);
1487         if (len <= off+count)
1488                 *eof = 1;
1489         *start = page + off;
1490         len -= off;
1491         if (len > count)
1492                 len = count;
1493         if (len < 0)
1494                 len = 0;
1495         return len;
1496 }
1497 
1498 static const struct net_device_ops atmel_netdev_ops = {
1499         .ndo_open               = atmel_open,
1500         .ndo_stop               = atmel_close,
1501         .ndo_change_mtu         = atmel_change_mtu,
1502         .ndo_set_mac_address    = atmel_set_mac_address,
1503         .ndo_start_xmit         = start_tx,
1504         .ndo_do_ioctl           = atmel_ioctl,
1505         .ndo_validate_addr      = eth_validate_addr,
1506 };
1507 
1508 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1509                                    const AtmelFWType fw_type,
1510                                    struct device *sys_dev,
1511                                    int (*card_present)(void *), void *card)
1512 {
1513         struct proc_dir_entry *ent;
1514         struct net_device *dev;
1515         struct atmel_private *priv;
1516         int rc;
1517 
1518         /* Create the network device object. */
1519         dev = alloc_etherdev(sizeof(*priv));
1520         if (!dev) {
1521                 printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
1522                 return NULL;
1523         }
1524         if (dev_alloc_name(dev, dev->name) < 0) {
1525                 printk(KERN_ERR "atmel: Couldn't get name!\n");
1526                 goto err_out_free;
1527         }
1528 
1529         priv = netdev_priv(dev);
1530         priv->dev = dev;
1531         priv->sys_dev = sys_dev;
1532         priv->present_callback = card_present;
1533         priv->card = card;
1534         priv->firmware = NULL;
1535         priv->firmware_id[0] = '\0';
1536         priv->firmware_type = fw_type;
1537         if (firmware) /* module parameter */
1538                 strcpy(priv->firmware_id, firmware);
1539         priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1540         priv->station_state = STATION_STATE_DOWN;
1541         priv->do_rx_crc = 0;
1542         /* For PCMCIA cards, some chips need CRC, some don't
1543            so we have to probe. */
1544         if (priv->bus_type == BUS_TYPE_PCCARD) {
1545                 priv->probe_crc = 1;
1546                 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1547         } else
1548                 priv->probe_crc = 0;
1549         priv->last_qual = jiffies;
1550         priv->last_beacon_timestamp = 0;
1551         memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1552         memset(priv->BSSID, 0, 6);
1553         priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1554         priv->station_was_associated = 0;
1555 
1556         priv->last_survey = jiffies;
1557         priv->preamble = LONG_PREAMBLE;
1558         priv->operating_mode = IW_MODE_INFRA;
1559         priv->connect_to_any_BSS = 0;
1560         priv->config_reg_domain = 0;
1561         priv->reg_domain = 0;
1562         priv->tx_rate = 3;
1563         priv->auto_tx_rate = 1;
1564         priv->channel = 4;
1565         priv->power_mode = 0;
1566         priv->SSID[0] = '\0';
1567         priv->SSID_size = 0;
1568         priv->new_SSID_size = 0;
1569         priv->frag_threshold = 2346;
1570         priv->rts_threshold = 2347;
1571         priv->short_retry = 7;
1572         priv->long_retry = 4;
1573 
1574         priv->wep_is_on = 0;
1575         priv->default_key = 0;
1576         priv->encryption_level = 0;
1577         priv->exclude_unencrypted = 0;
1578         priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1579         priv->use_wpa = 0;
1580         memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1581         memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1582 
1583         priv->default_beacon_period = priv->beacon_period = 100;
1584         priv->listen_interval = 1;
1585 
1586         init_timer(&priv->management_timer);
1587         spin_lock_init(&priv->irqlock);
1588         spin_lock_init(&priv->timerlock);
1589         priv->management_timer.function = atmel_management_timer;
1590         priv->management_timer.data = (unsigned long) dev;
1591 
1592         dev->netdev_ops = &atmel_netdev_ops;
1593         dev->wireless_handlers = &atmel_handler_def;
1594         dev->irq = irq;
1595         dev->base_addr = port;
1596 
1597         SET_NETDEV_DEV(dev, sys_dev);
1598 
1599         if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1600                 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1601                 goto err_out_free;
1602         }
1603 
1604         if (!request_region(dev->base_addr, 32,
1605                             priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
1606                 goto err_out_irq;
1607         }
1608 
1609         if (register_netdev(dev))
1610                 goto err_out_res;
1611 
1612         if (!probe_atmel_card(dev)) {
1613                 unregister_netdev(dev);
1614                 goto err_out_res;
1615         }
1616 
1617         netif_carrier_off(dev);
1618 
1619         ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
1620         if (!ent)
1621                 printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1622 
1623         printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1624                dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1625 
1626         return dev;
1627 
1628 err_out_res:
1629         release_region(dev->base_addr, 32);
1630 err_out_irq:
1631         free_irq(dev->irq, dev);
1632 err_out_free:
1633         free_netdev(dev);
1634         return NULL;
1635 }
1636 
1637 EXPORT_SYMBOL(init_atmel_card);
1638 
1639 void stop_atmel_card(struct net_device *dev)
1640 {
1641         struct atmel_private *priv = netdev_priv(dev);
1642 
1643         /* put a brick on it... */
1644         if (priv->bus_type == BUS_TYPE_PCCARD)
1645                 atmel_write16(dev, GCR, 0x0060);
1646         atmel_write16(dev, GCR, 0x0040);
1647 
1648         del_timer_sync(&priv->management_timer);
1649         unregister_netdev(dev);
1650         remove_proc_entry("driver/atmel", NULL);
1651         free_irq(dev->irq, dev);
1652         kfree(priv->firmware);
1653         release_region(dev->base_addr, 32);
1654         free_netdev(dev);
1655 }
1656 
1657 EXPORT_SYMBOL(stop_atmel_card);
1658 
1659 static int atmel_set_essid(struct net_device *dev,
1660                            struct iw_request_info *info,
1661                            struct iw_point *dwrq,
1662                            char *extra)
1663 {
1664         struct atmel_private *priv = netdev_priv(dev);
1665 
1666         /* Check if we asked for `any' */
1667         if (dwrq->flags == 0) {
1668                 priv->connect_to_any_BSS = 1;
1669         } else {
1670                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1671 
1672                 priv->connect_to_any_BSS = 0;
1673 
1674                 /* Check the size of the string */
1675                 if (dwrq->length > MAX_SSID_LENGTH)
1676                          return -E2BIG;
1677                 if (index != 0)
1678                         return -EINVAL;
1679 
1680                 memcpy(priv->new_SSID, extra, dwrq->length);
1681                 priv->new_SSID_size = dwrq->length;
1682         }
1683 
1684         return -EINPROGRESS;
1685 }
1686 
1687 static int atmel_get_essid(struct net_device *dev,
1688                            struct iw_request_info *info,
1689                            struct iw_point *dwrq,
1690                            char *extra)
1691 {
1692         struct atmel_private *priv = netdev_priv(dev);
1693 
1694         /* Get the current SSID */
1695         if (priv->new_SSID_size != 0) {
1696                 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1697                 dwrq->length = priv->new_SSID_size;
1698         } else {
1699                 memcpy(extra, priv->SSID, priv->SSID_size);
1700                 dwrq->length = priv->SSID_size;
1701         }
1702 
1703         dwrq->flags = !priv->connect_to_any_BSS; /* active */
1704 
1705         return 0;
1706 }
1707 
1708 static int atmel_get_wap(struct net_device *dev,
1709                          struct iw_request_info *info,
1710                          struct sockaddr *awrq,
1711                          char *extra)
1712 {
1713         struct atmel_private *priv = netdev_priv(dev);
1714         memcpy(awrq->sa_data, priv->CurrentBSSID, 6);
1715         awrq->sa_family = ARPHRD_ETHER;
1716 
1717         return 0;
1718 }
1719 
1720 static int atmel_set_encode(struct net_device *dev,
1721                             struct iw_request_info *info,
1722                             struct iw_point *dwrq,
1723                             char *extra)
1724 {
1725         struct atmel_private *priv = netdev_priv(dev);
1726 
1727         /* Basic checking: do we have a key to set ?
1728          * Note : with the new API, it's impossible to get a NULL pointer.
1729          * Therefore, we need to check a key size == 0 instead.
1730          * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1731          * when no key is present (only change flags), but older versions
1732          * don't do it. - Jean II */
1733         if (dwrq->length > 0) {
1734                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1735                 int current_index = priv->default_key;
1736                 /* Check the size of the key */
1737                 if (dwrq->length > 13) {
1738                         return -EINVAL;
1739                 }
1740                 /* Check the index (none -> use current) */
1741                 if (index < 0 || index >= 4)
1742                         index = current_index;
1743                 else
1744                         priv->default_key = index;
1745                 /* Set the length */
1746                 if (dwrq->length > 5)
1747                         priv->wep_key_len[index] = 13;
1748                 else
1749                         if (dwrq->length > 0)
1750                                 priv->wep_key_len[index] = 5;
1751                         else
1752                                 /* Disable the key */
1753                                 priv->wep_key_len[index] = 0;
1754                 /* Check if the key is not marked as invalid */
1755                 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1756                         /* Cleanup */
1757                         memset(priv->wep_keys[index], 0, 13);
1758                         /* Copy the key in the driver */
1759                         memcpy(priv->wep_keys[index], extra, dwrq->length);
1760                 }
1761                 /* WE specify that if a valid key is set, encryption
1762                  * should be enabled (user may turn it off later)
1763                  * This is also how "iwconfig ethX key on" works */
1764                 if (index == current_index &&
1765                     priv->wep_key_len[index] > 0) {
1766                         priv->wep_is_on = 1;
1767                         priv->exclude_unencrypted = 1;
1768                         if (priv->wep_key_len[index] > 5) {
1769                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1770                                 priv->encryption_level = 2;
1771                         } else {
1772                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1773                                 priv->encryption_level = 1;
1774                         }
1775                 }
1776         } else {
1777                 /* Do we want to just set the transmit key index ? */
1778                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1779                 if (index >= 0 && index < 4) {
1780                         priv->default_key = index;
1781                 } else
1782                         /* Don't complain if only change the mode */
1783                         if (!(dwrq->flags & IW_ENCODE_MODE))
1784                                 return -EINVAL;
1785         }
1786         /* Read the flags */
1787         if (dwrq->flags & IW_ENCODE_DISABLED) {
1788                 priv->wep_is_on = 0;
1789                 priv->encryption_level = 0;
1790                 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1791         } else {
1792                 priv->wep_is_on = 1;
1793                 if (priv->wep_key_len[priv->default_key] > 5) {
1794                         priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1795                         priv->encryption_level = 2;
1796                 } else {
1797                         priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1798                         priv->encryption_level = 1;
1799                 }
1800         }
1801         if (dwrq->flags & IW_ENCODE_RESTRICTED)
1802                 priv->exclude_unencrypted = 1;
1803         if (dwrq->flags & IW_ENCODE_OPEN)
1804                 priv->exclude_unencrypted = 0;
1805 
1806         return -EINPROGRESS;            /* Call commit handler */
1807 }
1808 
1809 static int atmel_get_encode(struct net_device *dev,
1810                             struct iw_request_info *info,
1811                             struct iw_point *dwrq,
1812                             char *extra)
1813 {
1814         struct atmel_private *priv = netdev_priv(dev);
1815         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1816 
1817         if (!priv->wep_is_on)
1818                 dwrq->flags = IW_ENCODE_DISABLED;
1819         else {
1820                 if (priv->exclude_unencrypted)
1821                         dwrq->flags = IW_ENCODE_RESTRICTED;
1822                 else
1823                         dwrq->flags = IW_ENCODE_OPEN;
1824         }
1825                 /* Which key do we want ? -1 -> tx index */
1826         if (index < 0 || index >= 4)
1827                 index = priv->default_key;
1828         dwrq->flags |= index + 1;
1829         /* Copy the key to the user buffer */
1830         dwrq->length = priv->wep_key_len[index];
1831         if (dwrq->length > 16) {
1832                 dwrq->length = 0;
1833         } else {
1834                 memset(extra, 0, 16);
1835                 memcpy(extra, priv->wep_keys[index], dwrq->length);
1836         }
1837 
1838         return 0;
1839 }
1840 
1841 static int atmel_set_encodeext(struct net_device *dev,
1842                             struct iw_request_info *info,
1843                             union iwreq_data *wrqu,
1844                             char *extra)
1845 {
1846         struct atmel_private *priv = netdev_priv(dev);
1847         struct iw_point *encoding = &wrqu->encoding;
1848         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1849         int idx, key_len, alg = ext->alg, set_key = 1;
1850 
1851         /* Determine and validate the key index */
1852         idx = encoding->flags & IW_ENCODE_INDEX;
1853         if (idx) {
1854                 if (idx < 1 || idx > 4)
1855                         return -EINVAL;
1856                 idx--;
1857         } else
1858                 idx = priv->default_key;
1859 
1860         if (encoding->flags & IW_ENCODE_DISABLED)
1861             alg = IW_ENCODE_ALG_NONE;
1862 
1863         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1864                 priv->default_key = idx;
1865                 set_key = ext->key_len > 0 ? 1 : 0;
1866         }
1867 
1868         if (set_key) {
1869                 /* Set the requested key first */
1870                 switch (alg) {
1871                 case IW_ENCODE_ALG_NONE:
1872                         priv->wep_is_on = 0;
1873                         priv->encryption_level = 0;
1874                         priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1875                         break;
1876                 case IW_ENCODE_ALG_WEP:
1877                         if (ext->key_len > 5) {
1878                                 priv->wep_key_len[idx] = 13;
1879                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1880                                 priv->encryption_level = 2;
1881                         } else if (ext->key_len > 0) {
1882                                 priv->wep_key_len[idx] = 5;
1883                                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1884                                 priv->encryption_level = 1;
1885                         } else {
1886                                 return -EINVAL;
1887                         }
1888                         priv->wep_is_on = 1;
1889                         memset(priv->wep_keys[idx], 0, 13);
1890                         key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1891                         memcpy(priv->wep_keys[idx], ext->key, key_len);
1892                         break;
1893                 default:
1894                         return -EINVAL;
1895                 }
1896         }
1897 
1898         return -EINPROGRESS;
1899 }
1900 
1901 static int atmel_get_encodeext(struct net_device *dev,
1902                             struct iw_request_info *info,
1903                             union iwreq_data *wrqu,
1904                             char *extra)
1905 {
1906         struct atmel_private *priv = netdev_priv(dev);
1907         struct iw_point *encoding = &wrqu->encoding;
1908         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1909         int idx, max_key_len;
1910 
1911         max_key_len = encoding->length - sizeof(*ext);
1912         if (max_key_len < 0)
1913                 return -EINVAL;
1914 
1915         idx = encoding->flags & IW_ENCODE_INDEX;
1916         if (idx) {
1917                 if (idx < 1 || idx > 4)
1918                         return -EINVAL;
1919                 idx--;
1920         } else
1921                 idx = priv->default_key;
1922 
1923         encoding->flags = idx + 1;
1924         memset(ext, 0, sizeof(*ext));
1925 
1926         if (!priv->wep_is_on) {
1927                 ext->alg = IW_ENCODE_ALG_NONE;
1928                 ext->key_len = 0;
1929                 encoding->flags |= IW_ENCODE_DISABLED;
1930         } else {
1931                 if (priv->encryption_level > 0)
1932                         ext->alg = IW_ENCODE_ALG_WEP;
1933                 else
1934                         return -EINVAL;
1935 
1936                 ext->key_len = priv->wep_key_len[idx];
1937                 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1938                 encoding->flags |= IW_ENCODE_ENABLED;
1939         }
1940 
1941         return 0;
1942 }
1943 
1944 static int atmel_set_auth(struct net_device *dev,
1945                                struct iw_request_info *info,
1946                                union iwreq_data *wrqu, char *extra)
1947 {
1948         struct atmel_private *priv = netdev_priv(dev);
1949         struct iw_param *param = &wrqu->param;
1950 
1951         switch (param->flags & IW_AUTH_INDEX) {
1952         case IW_AUTH_WPA_VERSION:
1953         case IW_AUTH_CIPHER_PAIRWISE:
1954         case IW_AUTH_CIPHER_GROUP:
1955         case IW_AUTH_KEY_MGMT:
1956         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1957         case IW_AUTH_PRIVACY_INVOKED:
1958                 /*
1959                  * atmel does not use these parameters
1960                  */
1961                 break;
1962 
1963         case IW_AUTH_DROP_UNENCRYPTED:
1964                 priv->exclude_unencrypted = param->value ? 1 : 0;
1965                 break;
1966 
1967         case IW_AUTH_80211_AUTH_ALG: {
1968                         if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1969                                 priv->exclude_unencrypted = 1;
1970                         } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1971                                 priv->exclude_unencrypted = 0;
1972                         } else
1973                                 return -EINVAL;
1974                         break;
1975                 }
1976 
1977         case IW_AUTH_WPA_ENABLED:
1978                 /* Silently accept disable of WPA */
1979                 if (param->value > 0)
1980                         return -EOPNOTSUPP;
1981                 break;
1982 
1983         default:
1984                 return -EOPNOTSUPP;
1985         }
1986         return -EINPROGRESS;
1987 }
1988 
1989 static int atmel_get_auth(struct net_device *dev,
1990                                struct iw_request_info *info,
1991                                union iwreq_data *wrqu, char *extra)
1992 {
1993         struct atmel_private *priv = netdev_priv(dev);
1994         struct iw_param *param = &wrqu->param;
1995 
1996         switch (param->flags & IW_AUTH_INDEX) {
1997         case IW_AUTH_DROP_UNENCRYPTED:
1998                 param->value = priv->exclude_unencrypted;
1999                 break;
2000 
2001         case IW_AUTH_80211_AUTH_ALG:
2002                 if (priv->exclude_unencrypted == 1)
2003                         param->value = IW_AUTH_ALG_SHARED_KEY;
2004                 else
2005                         param->value = IW_AUTH_ALG_OPEN_SYSTEM;
2006                 break;
2007 
2008         case IW_AUTH_WPA_ENABLED:
2009                 param->value = 0;
2010                 break;
2011 
2012         default:
2013                 return -EOPNOTSUPP;
2014         }
2015         return 0;
2016 }
2017 
2018 
2019 static int atmel_get_name(struct net_device *dev,
2020                           struct iw_request_info *info,
2021                           char *cwrq,
2022                           char *extra)
2023 {
2024         strcpy(cwrq, "IEEE 802.11-DS");
2025         return 0;
2026 }
2027 
2028 static int atmel_set_rate(struct net_device *dev,
2029                           struct iw_request_info *info,
2030                           struct iw_param *vwrq,
2031                           char *extra)
2032 {
2033         struct atmel_private *priv = netdev_priv(dev);
2034 
2035         if (vwrq->fixed == 0) {
2036                 priv->tx_rate = 3;
2037                 priv->auto_tx_rate = 1;
2038         } else {
2039                 priv->auto_tx_rate = 0;
2040 
2041                 /* Which type of value ? */
2042                 if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2043                         /* Setting by rate index */
2044                         priv->tx_rate = vwrq->value;
2045                 } else {
2046                 /* Setting by frequency value */
2047                         switch (vwrq->value) {
2048                         case  1000000:
2049                                 priv->tx_rate = 0;
2050                                 break;
2051                         case  2000000:
2052                                 priv->tx_rate = 1;
2053                                 break;
2054                         case  5500000:
2055                                 priv->tx_rate = 2;
2056                                 break;
2057                         case 11000000:
2058                                 priv->tx_rate = 3;
2059                                 break;
2060                         default:
2061                                 return -EINVAL;
2062                         }
2063                 }
2064         }
2065 
2066         return -EINPROGRESS;
2067 }
2068 
2069 static int atmel_set_mode(struct net_device *dev,
2070                           struct iw_request_info *info,
2071                           __u32 *uwrq,
2072                           char *extra)
2073 {
2074         struct atmel_private *priv = netdev_priv(dev);
2075 
2076         if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2077                 return -EINVAL;
2078 
2079         priv->operating_mode = *uwrq;
2080         return -EINPROGRESS;
2081 }
2082 
2083 static int atmel_get_mode(struct net_device *dev,
2084                           struct iw_request_info *info,
2085                           __u32 *uwrq,
2086                           char *extra)
2087 {
2088         struct atmel_private *priv = netdev_priv(dev);
2089 
2090         *uwrq = priv->operating_mode;
2091         return 0;
2092 }
2093 
2094 static int atmel_get_rate(struct net_device *dev,
2095                          struct iw_request_info *info,
2096                          struct iw_param *vwrq,
2097                          char *extra)
2098 {
2099         struct atmel_private *priv = netdev_priv(dev);
2100 
2101         if (priv->auto_tx_rate) {
2102                 vwrq->fixed = 0;
2103                 vwrq->value = 11000000;
2104         } else {
2105                 vwrq->fixed = 1;
2106                 switch (priv->tx_rate) {
2107                 case 0:
2108                         vwrq->value =  1000000;
2109                         break;
2110                 case 1:
2111                         vwrq->value =  2000000;
2112                         break;
2113                 case 2:
2114                         vwrq->value =  5500000;
2115                         break;
2116                 case 3:
2117                         vwrq->value = 11000000;
2118                         break;
2119                 }
2120         }
2121         return 0;
2122 }
2123 
2124 static int atmel_set_power(struct net_device *dev,
2125                            struct iw_request_info *info,
2126                            struct iw_param *vwrq,
2127                            char *extra)
2128 {
2129         struct atmel_private *priv = netdev_priv(dev);
2130         priv->power_mode = vwrq->disabled ? 0 : 1;
2131         return -EINPROGRESS;
2132 }
2133 
2134 static int atmel_get_power(struct net_device *dev,
2135                            struct iw_request_info *info,
2136                            struct iw_param *vwrq,
2137                            char *extra)
2138 {
2139         struct atmel_private *priv = netdev_priv(dev);
2140         vwrq->disabled = priv->power_mode ? 0 : 1;
2141         vwrq->flags = IW_POWER_ON;
2142         return 0;
2143 }
2144 
2145 static int atmel_set_retry(struct net_device *dev,
2146                            struct iw_request_info *info,
2147                            struct iw_param *vwrq,
2148                            char *extra)
2149 {
2150         struct atmel_private *priv = netdev_priv(dev);
2151 
2152         if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2153                 if (vwrq->flags & IW_RETRY_LONG)
2154                         priv->long_retry = vwrq->value;
2155                 else if (vwrq->flags & IW_RETRY_SHORT)
2156                         priv->short_retry = vwrq->value;
2157                 else {
2158                         /* No modifier : set both */
2159                         priv->long_retry = vwrq->value;
2160                         priv->short_retry = vwrq->value;
2161                 }
2162                 return -EINPROGRESS;
2163         }
2164 
2165         return -EINVAL;
2166 }
2167 
2168 static int atmel_get_retry(struct net_device *dev,
2169                            struct iw_request_info *info,
2170                            struct iw_param *vwrq,
2171                            char *extra)
2172 {
2173         struct atmel_private *priv = netdev_priv(dev);
2174 
2175         vwrq->disabled = 0;      /* Can't be disabled */
2176 
2177         /* Note : by default, display the short retry number */
2178         if (vwrq->flags & IW_RETRY_LONG) {
2179                 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2180                 vwrq->value = priv->long_retry;
2181         } else {
2182                 vwrq->flags = IW_RETRY_LIMIT;
2183                 vwrq->value = priv->short_retry;
2184                 if (priv->long_retry != priv->short_retry)
2185                         vwrq->flags |= IW_RETRY_SHORT;
2186         }
2187 
2188         return 0;
2189 }
2190 
2191 static int atmel_set_rts(struct net_device *dev,
2192                          struct iw_request_info *info,
2193                          struct iw_param *vwrq,
2194                          char *extra)
2195 {
2196         struct atmel_private *priv = netdev_priv(dev);
2197         int rthr = vwrq->value;
2198 
2199         if (vwrq->disabled)
2200                 rthr = 2347;
2201         if ((rthr < 0) || (rthr > 2347)) {
2202                 return -EINVAL;
2203         }
2204         priv->rts_threshold = rthr;
2205 
2206         return -EINPROGRESS;            /* Call commit handler */
2207 }
2208 
2209 static int atmel_get_rts(struct net_device *dev,
2210                          struct iw_request_info *info,
2211                          struct iw_param *vwrq,
2212                          char *extra)
2213 {
2214         struct atmel_private *priv = netdev_priv(dev);
2215 
2216         vwrq->value = priv->rts_threshold;
2217         vwrq->disabled = (vwrq->value >= 2347);
2218         vwrq->fixed = 1;
2219 
2220         return 0;
2221 }
2222 
2223 static int atmel_set_frag(struct net_device *dev,
2224                           struct iw_request_info *info,
2225                           struct iw_param *vwrq,
2226                           char *extra)
2227 {
2228         struct atmel_private *priv = netdev_priv(dev);
2229         int fthr = vwrq->value;
2230 
2231         if (vwrq->disabled)
2232                 fthr = 2346;
2233         if ((fthr < 256) || (fthr > 2346)) {
2234                 return -EINVAL;
2235         }
2236         fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
2237         priv->frag_threshold = fthr;
2238 
2239         return -EINPROGRESS;            /* Call commit handler */
2240 }
2241 
2242 static int atmel_get_frag(struct net_device *dev,
2243                           struct iw_request_info *info,
2244                           struct iw_param *vwrq,
2245                           char *extra)
2246 {
2247         struct atmel_private *priv = netdev_priv(dev);
2248 
2249         vwrq->value = priv->frag_threshold;
2250         vwrq->disabled = (vwrq->value >= 2346);
2251         vwrq->fixed = 1;
2252 
2253         return 0;
2254 }
2255 
2256 static int atmel_set_freq(struct net_device *dev,
2257                           struct iw_request_info *info,
2258                           struct iw_freq *fwrq,
2259                           char *extra)
2260 {
2261         struct atmel_private *priv = netdev_priv(dev);
2262         int rc = -EINPROGRESS;          /* Call commit handler */
2263 
2264         /* If setting by frequency, convert to a channel */
2265         if (fwrq->e == 1) {
2266                 int f = fwrq->m / 100000;
2267 
2268                 /* Hack to fall through... */
2269                 fwrq->e = 0;
2270                 fwrq->m = ieee80211_freq_to_dsss_chan(f);
2271         }
2272         /* Setting by channel number */
2273         if ((fwrq->m > 1000) || (fwrq->e > 0))
2274                 rc = -EOPNOTSUPP;
2275         else {
2276                 int channel = fwrq->m;
2277                 if (atmel_validate_channel(priv, channel) == 0) {
2278                         priv->channel = channel;
2279                 } else {
2280                         rc = -EINVAL;
2281                 }
2282         }
2283         return rc;
2284 }
2285 
2286 static int atmel_get_freq(struct net_device *dev,
2287                           struct iw_request_info *info,
2288                           struct iw_freq *fwrq,
2289                           char *extra)
2290 {
2291         struct atmel_private *priv = netdev_priv(dev);
2292 
2293         fwrq->m = priv->channel;
2294         fwrq->e = 0;
2295         return 0;
2296 }
2297 
2298 static int atmel_set_scan(struct net_device *dev,
2299                           struct iw_request_info *info,
2300                           struct iw_point *dwrq,
2301                           char *extra)
2302 {
2303         struct atmel_private *priv = netdev_priv(dev);
2304         unsigned long flags;
2305 
2306         /* Note : you may have realised that, as this is a SET operation,
2307          * this is privileged and therefore a normal user can't
2308          * perform scanning.
2309          * This is not an error, while the device perform scanning,
2310          * traffic doesn't flow, so it's a perfect DoS...
2311          * Jean II */
2312 
2313         if (priv->station_state == STATION_STATE_DOWN)
2314                 return -EAGAIN;
2315 
2316         /* Timeout old surveys. */
2317         if (time_after(jiffies, priv->last_survey + 20 * HZ))
2318                 priv->site_survey_state = SITE_SURVEY_IDLE;
2319         priv->last_survey = jiffies;
2320 
2321         /* Initiate a scan command */
2322         if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2323                 return -EBUSY;
2324 
2325         del_timer_sync(&priv->management_timer);
2326         spin_lock_irqsave(&priv->irqlock, flags);
2327 
2328         priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2329         priv->fast_scan = 0;
2330         atmel_scan(priv, 0);
2331         spin_unlock_irqrestore(&priv->irqlock, flags);
2332 
2333         return 0;
2334 }
2335 
2336 static int atmel_get_scan(struct net_device *dev,
2337                           struct iw_request_info *info,
2338                           struct iw_point *dwrq,
2339                           char *extra)
2340 {
2341         struct atmel_private *priv = netdev_priv(dev);
2342         int i;
2343         char *current_ev = extra;
2344         struct iw_event iwe;
2345 
2346         if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2347                 return -EAGAIN;
2348 
2349         for (i = 0; i < priv->BSS_list_entries; i++) {
2350                 iwe.cmd = SIOCGIWAP;
2351                 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2352                 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
2353                 current_ev = iwe_stream_add_event(info, current_ev,
2354                                                   extra + IW_SCAN_MAX_DATA,
2355                                                   &iwe, IW_EV_ADDR_LEN);
2356 
2357                 iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
2358                 if (iwe.u.data.length > 32)
2359                         iwe.u.data.length = 32;
2360                 iwe.cmd = SIOCGIWESSID;
2361                 iwe.u.data.flags = 1;
2362                 current_ev = iwe_stream_add_point(info, current_ev,
2363                                                   extra + IW_SCAN_MAX_DATA,
2364                                                   &iwe, priv->BSSinfo[i].SSID);
2365 
2366                 iwe.cmd = SIOCGIWMODE;
2367                 iwe.u.mode = priv->BSSinfo[i].BSStype;
2368                 current_ev = iwe_stream_add_event(info, current_ev,
2369                                                   extra + IW_SCAN_MAX_DATA,
2370                                                   &iwe, IW_EV_UINT_LEN);
2371 
2372                 iwe.cmd = SIOCGIWFREQ;
2373                 iwe.u.freq.m = priv->BSSinfo[i].channel;
2374                 iwe.u.freq.e = 0;
2375                 current_ev = iwe_stream_add_event(info, current_ev,
2376                                                   extra + IW_SCAN_MAX_DATA,
2377                                                   &iwe, IW_EV_FREQ_LEN);
2378 
2379                 /* Add quality statistics */
2380                 iwe.cmd = IWEVQUAL;
2381                 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2382                 iwe.u.qual.qual  = iwe.u.qual.level;
2383                 /* iwe.u.qual.noise  = SOMETHING */
2384                 current_ev = iwe_stream_add_event(info, current_ev,
2385                                                   extra + IW_SCAN_MAX_DATA,
2386                                                   &iwe, IW_EV_QUAL_LEN);
2387 
2388 
2389                 iwe.cmd = SIOCGIWENCODE;
2390                 if (priv->BSSinfo[i].UsingWEP)
2391                         iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2392                 else
2393                         iwe.u.data.flags = IW_ENCODE_DISABLED;
2394                 iwe.u.data.length = 0;
2395                 current_ev = iwe_stream_add_point(info, current_ev,
2396                                                   extra + IW_SCAN_MAX_DATA,
2397                                                   &iwe, NULL);
2398         }
2399 
2400         /* Length of data */
2401         dwrq->length = (current_ev - extra);
2402         dwrq->flags = 0;
2403 
2404         return 0;
2405 }
2406 
2407 static int atmel_get_range(struct net_device *dev,
2408                            struct iw_request_info *info,
2409                            struct iw_point *dwrq,
2410                            char *extra)
2411 {
2412         struct atmel_private *priv = netdev_priv(dev);
2413         struct iw_range *range = (struct iw_range *) extra;
2414         int k, i, j;
2415 
2416         dwrq->length = sizeof(struct iw_range);
2417         memset(range, 0, sizeof(struct iw_range));
2418         range->min_nwid = 0x0000;
2419         range->max_nwid = 0x0000;
2420         range->num_channels = 0;
2421         for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2422                 if (priv->reg_domain == channel_table[j].reg_domain) {
2423                         range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2424                         break;
2425                 }
2426         if (range->num_channels != 0) {
2427                 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2428                         range->freq[k].i = i; /* List index */
2429 
2430                         /* Values in MHz -> * 10^5 * 10 */
2431                         range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) *
2432                                             100000);
2433                         range->freq[k++].e = 1;
2434                 }
2435                 range->num_frequency = k;
2436         }
2437 
2438         range->max_qual.qual = 100;
2439         range->max_qual.level = 100;
2440         range->max_qual.noise = 0;
2441         range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2442 
2443         range->avg_qual.qual = 50;
2444         range->avg_qual.level = 50;
2445         range->avg_qual.noise = 0;
2446         range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2447 
2448         range->sensitivity = 0;
2449 
2450         range->bitrate[0] =  1000000;
2451         range->bitrate[1] =  2000000;
2452         range->bitrate[2] =  5500000;
2453         range->bitrate[3] = 11000000;
2454         range->num_bitrates = 4;
2455 
2456         range->min_rts = 0;
2457         range->max_rts = 2347;
2458         range->min_frag = 256;
2459         range->max_frag = 2346;
2460 
2461         range->encoding_size[0] = 5;
2462         range->encoding_size[1] = 13;
2463         range->num_encoding_sizes = 2;
2464         range->max_encoding_tokens = 4;
2465 
2466         range->pmp_flags = IW_POWER_ON;
2467         range->pmt_flags = IW_POWER_ON;
2468         range->pm_capa = 0;
2469 
2470         range->we_version_source = WIRELESS_EXT;
2471         range->we_version_compiled = WIRELESS_EXT;
2472         range->retry_capa = IW_RETRY_LIMIT ;
2473         range->retry_flags = IW_RETRY_LIMIT;
2474         range->r_time_flags = 0;
2475         range->min_retry = 1;
2476         range->max_retry = 65535;
2477 
2478         return 0;
2479 }
2480 
2481 static int atmel_set_wap(struct net_device *dev,
2482                          struct iw_request_info *info,
2483                          struct sockaddr *awrq,
2484                          char *extra)
2485 {
2486         struct atmel_private *priv = netdev_priv(dev);
2487         int i;
2488         static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2489         static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2490         unsigned long flags;
2491 
2492         if (awrq->sa_family != ARPHRD_ETHER)
2493                 return -EINVAL;
2494 
2495         if (!memcmp(any, awrq->sa_data, 6) ||
2496             !memcmp(off, awrq->sa_data, 6)) {
2497                 del_timer_sync(&priv->management_timer);
2498                 spin_lock_irqsave(&priv->irqlock, flags);
2499                 atmel_scan(priv, 1);
2500                 spin_unlock_irqrestore(&priv->irqlock, flags);
2501                 return 0;
2502         }
2503 
2504         for (i = 0; i < priv->BSS_list_entries; i++) {
2505                 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2506                         if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2507                                 return -EINVAL;
2508                         } else if  (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2509                                 return -EINVAL;
2510                         } else {
2511                                 del_timer_sync(&priv->management_timer);
2512                                 spin_lock_irqsave(&priv->irqlock, flags);
2513                                 atmel_join_bss(priv, i);
2514                                 spin_unlock_irqrestore(&priv->irqlock, flags);
2515                                 return 0;
2516                         }
2517                 }
2518         }
2519 
2520         return -EINVAL;
2521 }
2522 
2523 static int atmel_config_commit(struct net_device *dev,
2524                                struct iw_request_info *info,    /* NULL */
2525                                void *zwrq,                      /* NULL */
2526                                char *extra)                     /* NULL */
2527 {
2528         return atmel_open(dev);
2529 }
2530 
2531 static const iw_handler atmel_handler[] =
2532 {
2533         (iw_handler) atmel_config_commit,       /* SIOCSIWCOMMIT */
2534         (iw_handler) atmel_get_name,            /* SIOCGIWNAME */
2535         (iw_handler) NULL,                      /* SIOCSIWNWID */
2536         (iw_handler) NULL,                      /* SIOCGIWNWID */
2537         (iw_handler) atmel_set_freq,            /* SIOCSIWFREQ */
2538         (iw_handler) atmel_get_freq,            /* SIOCGIWFREQ */
2539         (iw_handler) atmel_set_mode,            /* SIOCSIWMODE */
2540         (iw_handler) atmel_get_mode,            /* SIOCGIWMODE */
2541         (iw_handler) NULL,                      /* SIOCSIWSENS */
2542         (iw_handler) NULL,                      /* SIOCGIWSENS */
2543         (iw_handler) NULL,                      /* SIOCSIWRANGE */
2544         (iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
2545         (iw_handler) NULL,                      /* SIOCSIWPRIV */
2546         (iw_handler) NULL,                      /* SIOCGIWPRIV */
2547         (iw_handler) NULL,                      /* SIOCSIWSTATS */
2548         (iw_handler) NULL,                      /* SIOCGIWSTATS */
2549         (iw_handler) NULL,                      /* SIOCSIWSPY */
2550         (iw_handler) NULL,                      /* SIOCGIWSPY */
2551         (iw_handler) NULL,                      /* -- hole -- */
2552         (iw_handler) NULL,                      /* -- hole -- */
2553         (iw_handler) atmel_set_wap,             /* SIOCSIWAP */
2554         (iw_handler) atmel_get_wap,             /* SIOCGIWAP */
2555         (iw_handler) NULL,                      /* -- hole -- */
2556         (iw_handler) NULL,                      /* SIOCGIWAPLIST */
2557         (iw_handler) atmel_set_scan,            /* SIOCSIWSCAN */
2558         (iw_handler) atmel_get_scan,            /* SIOCGIWSCAN */
2559         (iw_handler) atmel_set_essid,           /* SIOCSIWESSID */
2560         (iw_handler) atmel_get_essid,           /* SIOCGIWESSID */
2561         (iw_handler) NULL,                      /* SIOCSIWNICKN */
2562         (iw_handler) NULL,                      /* SIOCGIWNICKN */
2563         (iw_handler) NULL,                      /* -- hole -- */
2564         (iw_handler) NULL,                      /* -- hole -- */
2565         (iw_handler) atmel_set_rate,            /* SIOCSIWRATE */
2566         (iw_handler) atmel_get_rate,            /* SIOCGIWRATE */
2567         (iw_handler) atmel_set_rts,             /* SIOCSIWRTS */
2568         (iw_handler) atmel_get_rts,             /* SIOCGIWRTS */
2569         (iw_handler) atmel_set_frag,            /* SIOCSIWFRAG */
2570         (iw_handler) atmel_get_frag,            /* SIOCGIWFRAG */
2571         (iw_handler) NULL,                      /* SIOCSIWTXPOW */
2572         (iw_handler) NULL,                      /* SIOCGIWTXPOW */
2573         (iw_handler) atmel_set_retry,           /* SIOCSIWRETRY */
2574         (iw_handler) atmel_get_retry,           /* SIOCGIWRETRY */
2575         (iw_handler) atmel_set_encode,          /* SIOCSIWENCODE */
2576         (iw_handler) atmel_get_encode,          /* SIOCGIWENCODE */
2577         (iw_handler) atmel_set_power,           /* SIOCSIWPOWER */
2578         (iw_handler) atmel_get_power,           /* SIOCGIWPOWER */
2579         (iw_handler) NULL,                      /* -- hole -- */
2580         (iw_handler) NULL,                      /* -- hole -- */
2581         (iw_handler) NULL,                      /* SIOCSIWGENIE */
2582         (iw_handler) NULL,                      /* SIOCGIWGENIE */
2583         (iw_handler) atmel_set_auth,            /* SIOCSIWAUTH */
2584         (iw_handler) atmel_get_auth,            /* SIOCGIWAUTH */
2585         (iw_handler) atmel_set_encodeext,       /* SIOCSIWENCODEEXT */
2586         (iw_handler) atmel_get_encodeext,       /* SIOCGIWENCODEEXT */
2587         (iw_handler) NULL,                      /* SIOCSIWPMKSA */
2588 };
2589 
2590 static const iw_handler atmel_private_handler[] =
2591 {
2592         NULL,                           /* SIOCIWFIRSTPRIV */
2593 };
2594 
2595 typedef struct atmel_priv_ioctl {
2596         char id[32];
2597         unsigned char __user *data;
2598         unsigned short len;
2599 } atmel_priv_ioctl;
2600 
2601 #define ATMELFWL        SIOCIWFIRSTPRIV
2602 #define ATMELIDIFC      ATMELFWL + 1
2603 #define ATMELRD         ATMELFWL + 2
2604 #define ATMELMAGIC 0x51807
2605 #define REGDOMAINSZ 20
2606 
2607 static const struct iw_priv_args atmel_private_args[] = {
2608         {
2609                 .cmd = ATMELFWL,
2610                 .set_args = IW_PRIV_TYPE_BYTE
2611                                 | IW_PRIV_SIZE_FIXED
2612                                 | sizeof (atmel_priv_ioctl),
2613                 .get_args = IW_PRIV_TYPE_NONE,
2614                 .name = "atmelfwl"
2615         }, {
2616                 .cmd = ATMELIDIFC,
2617                 .set_args = IW_PRIV_TYPE_NONE,
2618                 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2619                 .name = "atmelidifc"
2620         }, {
2621                 .cmd = ATMELRD,
2622                 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2623                 .get_args = IW_PRIV_TYPE_NONE,
2624                 .name = "regdomain"
2625         },
2626 };
2627 
2628 static const struct iw_handler_def atmel_handler_def = {
2629         .num_standard   = ARRAY_SIZE(atmel_handler),
2630         .num_private    = ARRAY_SIZE(atmel_private_handler),
2631         .num_private_args = ARRAY_SIZE(atmel_private_args),
2632         .standard       = (iw_handler *) atmel_handler,
2633         .private        = (iw_handler *) atmel_private_handler,
2634         .private_args   = (struct iw_priv_args *) atmel_private_args,
2635         .get_wireless_stats = atmel_get_wireless_stats
2636 };
2637 
2638 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2639 {
2640         int i, rc = 0;
2641         struct atmel_private *priv = netdev_priv(dev);
2642         atmel_priv_ioctl com;
2643         struct iwreq *wrq = (struct iwreq *) rq;
2644         unsigned char *new_firmware;
2645         char domain[REGDOMAINSZ + 1];
2646 
2647         switch (cmd) {
2648         case ATMELIDIFC:
2649                 wrq->u.param.value = ATMELMAGIC;
2650                 break;
2651 
2652         case ATMELFWL:
2653                 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2654                         rc = -EFAULT;
2655                         break;
2656                 }
2657 
2658                 if (!capable(CAP_NET_ADMIN)) {
2659                         rc = -EPERM;
2660                         break;
2661                 }
2662 
2663                 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2664                         rc = -ENOMEM;
2665                         break;
2666                 }
2667 
2668                 if (copy_from_user(new_firmware, com.data, com.len)) {
2669                         kfree(new_firmware);
2670                         rc = -EFAULT;
2671                         break;
2672                 }
2673 
2674                 kfree(priv->firmware);
2675 
2676                 priv->firmware = new_firmware;
2677                 priv->firmware_length = com.len;
2678                 strncpy(priv->firmware_id, com.id, 31);
2679                 priv->firmware_id[31] = '\0';
2680                 break;
2681 
2682         case ATMELRD:
2683                 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2684                         rc = -EFAULT;
2685                         break;
2686                 }
2687 
2688                 if (!capable(CAP_NET_ADMIN)) {
2689                         rc = -EPERM;
2690                         break;
2691                 }
2692 
2693                 domain[REGDOMAINSZ] = 0;
2694                 rc = -EINVAL;
2695                 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2696                         /* strcasecmp doesn't exist in the library */
2697                         char *a = channel_table[i].name;
2698                         char *b = domain;
2699                         while (*a) {
2700                                 char c1 = *a++;
2701                                 char c2 = *b++;
2702                                 if (tolower(c1) != tolower(c2))
2703                                         break;
2704                         }
2705                         if (!*a && !*b) {
2706                                 priv->config_reg_domain = channel_table[i].reg_domain;
2707                                 rc = 0;
2708                         }
2709                 }
2710 
2711                 if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2712                         rc = atmel_open(dev);
2713                 break;
2714 
2715         default:
2716                 rc = -EOPNOTSUPP;
2717         }
2718 
2719         return rc;
2720 }
2721 
2722 struct auth_body {
2723         __le16 alg;
2724         __le16 trans_seq;
2725         __le16 status;
2726         u8 el_id;
2727         u8 chall_text_len;
2728         u8 chall_text[253];
2729 };
2730 
2731 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2732 {
2733         int old_state = priv->station_state;
2734 
2735         if (new_state == old_state)
2736                 return;
2737 
2738         priv->station_state = new_state;
2739 
2740         if (new_state == STATION_STATE_READY) {
2741                 netif_start_queue(priv->dev);
2742                 netif_carrier_on(priv->dev);
2743         }
2744 
2745         if (old_state == STATION_STATE_READY) {
2746                 netif_carrier_off(priv->dev);
2747                 if (netif_running(priv->dev))
2748                         netif_stop_queue(priv->dev);
2749                 priv->last_beacon_timestamp = 0;
2750         }
2751 }
2752 
2753 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2754 {
2755         struct {
2756                 u8 BSSID[6];
2757                 u8 SSID[MAX_SSID_LENGTH];
2758                 u8 scan_type;
2759                 u8 channel;
2760                 __le16 BSS_type;
2761                 __le16 min_channel_time;
2762                 __le16 max_channel_time;
2763                 u8 options;
2764                 u8 SSID_size;
2765         } cmd;
2766 
2767         memset(cmd.BSSID, 0xff, 6);
2768 
2769         if (priv->fast_scan) {
2770                 cmd.SSID_size = priv->SSID_size;
2771                 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2772                 cmd.min_channel_time = cpu_to_le16(10);
2773                 cmd.max_channel_time = cpu_to_le16(50);
2774         } else {
2775                 priv->BSS_list_entries = 0;
2776                 cmd.SSID_size = 0;
2777                 cmd.min_channel_time = cpu_to_le16(10);
2778                 cmd.max_channel_time = cpu_to_le16(120);
2779         }
2780 
2781         cmd.options = 0;
2782 
2783         if (!specific_ssid)
2784                 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2785 
2786         cmd.channel = (priv->channel & 0x7f);
2787         cmd.scan_type = SCAN_TYPE_ACTIVE;
2788         cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2789                 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2790 
2791         atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2792 
2793         /* This must come after all hardware access to avoid being messed up
2794            by stuff happening in interrupt context after we leave STATE_DOWN */
2795         atmel_enter_state(priv, STATION_STATE_SCANNING);
2796 }
2797 
2798 static void join(struct atmel_private *priv, int type)
2799 {
2800         struct {
2801                 u8 BSSID[6];
2802                 u8 SSID[MAX_SSID_LENGTH];
2803                 u8 BSS_type; /* this is a short in a scan command - weird */
2804                 u8 channel;
2805                 __le16 timeout;
2806                 u8 SSID_size;
2807                 u8 reserved;
2808         } cmd;
2809 
2810         cmd.SSID_size = priv->SSID_size;
2811         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2812         memcpy(cmd.BSSID, priv->CurrentBSSID, 6);
2813         cmd.channel = (priv->channel & 0x7f);
2814         cmd.BSS_type = type;
2815         cmd.timeout = cpu_to_le16(2000);
2816 
2817         atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2818 }
2819 
2820 static void start(struct atmel_private *priv, int type)
2821 {
2822         struct {
2823                 u8 BSSID[6];
2824                 u8 SSID[MAX_SSID_LENGTH];
2825                 u8 BSS_type;
2826                 u8 channel;
2827                 u8 SSID_size;
2828                 u8 reserved[3];
2829         } cmd;
2830 
2831         cmd.SSID_size = priv->SSID_size;
2832         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2833         memcpy(cmd.BSSID, priv->BSSID, 6);
2834         cmd.BSS_type = type;
2835         cmd.channel = (priv->channel & 0x7f);
2836 
2837         atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2838 }
2839 
2840 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2841                                 u8 channel)
2842 {
2843         int rejoin = 0;
2844         int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2845                 SHORT_PREAMBLE : LONG_PREAMBLE;
2846 
2847         if (priv->preamble != new) {
2848                 priv->preamble = new;
2849                 rejoin = 1;
2850                 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2851         }
2852 
2853         if (priv->channel != channel) {
2854                 priv->channel = channel;
2855                 rejoin = 1;
2856                 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2857         }
2858 
2859         if (rejoin) {
2860                 priv->station_is_associated = 0;
2861                 atmel_enter_state(priv, STATION_STATE_JOINNING);
2862 
2863                 if (priv->operating_mode == IW_MODE_INFRA)
2864                         join(priv, BSS_TYPE_INFRASTRUCTURE);
2865                 else
2866                         join(priv, BSS_TYPE_AD_HOC);
2867         }
2868 }
2869 
2870 static void send_authentication_request(struct atmel_private *priv, u16 system,
2871                                         u8 *challenge, int challenge_len)
2872 {
2873         struct ieee80211_hdr header;
2874         struct auth_body auth;
2875 
2876         header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2877         header.duration_id = cpu_to_le16(0x8000);
2878         header.seq_ctrl = 0;
2879         memcpy(header.addr1, priv->CurrentBSSID, 6);
2880         memcpy(header.addr2, priv->dev->dev_addr, 6);
2881         memcpy(header.addr3, priv->CurrentBSSID, 6);
2882 
2883         if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2884                 /* no WEP for authentication frames with TrSeqNo 1 */
2885                 header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2886 
2887         auth.alg = cpu_to_le16(system);
2888 
2889         auth.status = 0;
2890         auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2891         priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2892         priv->CurrentAuthentTransactionSeqNum += 2;
2893 
2894         if (challenge_len != 0) {
2895                 auth.el_id = 16; /* challenge_text */
2896                 auth.chall_text_len = challenge_len;
2897                 memcpy(auth.chall_text, challenge, challenge_len);
2898                 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2899         } else {
2900                 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2901         }
2902 }
2903 
2904 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2905 {
2906         u8 *ssid_el_p;
2907         int bodysize;
2908         struct ieee80211_hdr header;
2909         struct ass_req_format {
2910                 __le16 capability;
2911                 __le16 listen_interval;
2912                 u8 ap[6]; /* nothing after here directly accessible */
2913                 u8 ssid_el_id;
2914                 u8 ssid_len;
2915                 u8 ssid[MAX_SSID_LENGTH];
2916                 u8 sup_rates_el_id;
2917                 u8 sup_rates_len;
2918                 u8 rates[4];
2919         } body;
2920 
2921         header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2922                 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2923         header.duration_id = cpu_to_le16(0x8000);
2924         header.seq_ctrl = 0;
2925 
2926         memcpy(header.addr1, priv->CurrentBSSID, 6);
2927         memcpy(header.addr2, priv->dev->dev_addr, 6);
2928         memcpy(header.addr3, priv->CurrentBSSID, 6);
2929 
2930         body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2931         if (priv->wep_is_on)
2932                 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2933         if (priv->preamble == SHORT_PREAMBLE)
2934                 body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2935 
2936         body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2937 
2938         /* current AP address - only in reassoc frame */
2939         if (is_reassoc) {
2940                 memcpy(body.ap, priv->CurrentBSSID, 6);
2941                 ssid_el_p = (u8 *)&body.ssid_el_id;
2942                 bodysize = 18 + priv->SSID_size;
2943         } else {
2944                 ssid_el_p = (u8 *)&body.ap[0];
2945                 bodysize = 12 + priv->SSID_size;
2946         }
2947 
2948         ssid_el_p[0] = WLAN_EID_SSID;
2949         ssid_el_p[1] = priv->SSID_size;
2950         memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2951         ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2952         ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
2953         memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2954 
2955         atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2956 }
2957 
2958 static int is_frame_from_current_bss(struct atmel_private *priv,
2959                                      struct ieee80211_hdr *header)
2960 {
2961         if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2962                 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2963         else
2964                 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2965 }
2966 
2967 static int retrieve_bss(struct atmel_private *priv)
2968 {
2969         int i;
2970         int max_rssi = -128;
2971         int max_index = -1;
2972 
2973         if (priv->BSS_list_entries == 0)
2974                 return -1;
2975 
2976         if (priv->connect_to_any_BSS) {
2977                 /* Select a BSS with the max-RSSI but of the same type and of
2978                    the same WEP mode and that it is not marked as 'bad' (i.e.
2979                    we had previously failed to connect to this BSS with the
2980                    settings that we currently use) */
2981                 priv->current_BSS = 0;
2982                 for (i = 0; i < priv->BSS_list_entries; i++) {
2983                         if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2984                             ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2985                              (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2986                             !(priv->BSSinfo[i].channel & 0x80)) {
2987                                 max_rssi = priv->BSSinfo[i].RSSI;
2988                                 priv->current_BSS = max_index = i;
2989                         }
2990                 }
2991                 return max_index;
2992         }
2993 
2994         for (i = 0; i < priv->BSS_list_entries; i++) {
2995                 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2996                     memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2997                     priv->operating_mode == priv->BSSinfo[i].BSStype &&
2998                     atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2999                         if (priv->BSSinfo[i].RSSI >= max_rssi) {
3000                                 max_rssi = priv->BSSinfo[i].RSSI;
3001                                 max_index = i;
3002                         }
3003                 }
3004         }
3005         return max_index;
3006 }
3007 
3008 static void store_bss_info(struct atmel_private *priv,
3009                            struct ieee80211_hdr *header, u16 capability,
3010                            u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
3011                            u8 *ssid, int is_beacon)
3012 {
3013         u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
3014         int i, index;
3015 
3016         for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
3017                 if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
3018                         index = i;
3019 
3020         /* If we process a probe and an entry from this BSS exists
3021            we will update the BSS entry with the info from this BSS.
3022            If we process a beacon we will only update RSSI */
3023 
3024         if (index == -1) {
3025                 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
3026                         return;
3027                 index = priv->BSS_list_entries++;
3028                 memcpy(priv->BSSinfo[index].BSSID, bss, 6);
3029                 priv->BSSinfo[index].RSSI = rssi;
3030         } else {
3031                 if (rssi > priv->BSSinfo[index].RSSI)
3032                         priv->BSSinfo[index].RSSI = rssi;
3033                 if (is_beacon)
3034                         return;
3035         }
3036 
3037         priv->BSSinfo[index].channel = channel;
3038         priv->BSSinfo[index].beacon_period = beacon_period;
3039         priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3040         memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3041         priv->BSSinfo[index].SSIDsize = ssid_len;
3042 
3043         if (capability & WLAN_CAPABILITY_IBSS)
3044                 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3045         else if (capability & WLAN_CAPABILITY_ESS)
3046                 priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3047 
3048         priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3049                 SHORT_PREAMBLE : LONG_PREAMBLE;
3050 }
3051 
3052 static void authenticate(struct atmel_private *priv, u16 frame_len)
3053 {
3054         struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3055         u16 status = le16_to_cpu(auth->status);
3056         u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3057         u16 system = le16_to_cpu(auth->alg);
3058 
3059         if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3060                 /* no WEP */
3061                 if (priv->station_was_associated) {
3062                         atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3063                         send_association_request(priv, 1);
3064                         return;
3065                 } else {
3066                         atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3067                         send_association_request(priv, 0);
3068                         return;
3069                 }
3070         }
3071 
3072         if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3073                 int should_associate = 0;
3074                 /* WEP */
3075                 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3076                         return;
3077 
3078                 if (system == WLAN_AUTH_OPEN) {
3079                         if (trans_seq_no == 0x0002) {
3080                                 should_associate = 1;
3081                         }
3082                 } else if (system == WLAN_AUTH_SHARED_KEY) {
3083                         if (trans_seq_no == 0x0002 &&
3084                             auth->el_id == WLAN_EID_CHALLENGE) {
3085                                 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3086                                 return;
3087                         } else if (trans_seq_no == 0x0004) {
3088                                 should_associate = 1;
3089                         }
3090                 }
3091 
3092                 if (should_associate) {
3093                         if (priv->station_was_associated) {
3094                                 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3095                                 send_association_request(priv, 1);
3096                                 return;
3097                         } else {
3098                                 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3099                                 send_association_request(priv, 0);
3100                                 return;
3101                         }
3102                 }
3103         }
3104 
3105         if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3106                 /* Flip back and forth between WEP auth modes until the max
3107                  * authentication tries has been exceeded.
3108                  */
3109                 if (system == WLAN_AUTH_OPEN) {
3110                         priv->CurrentAuthentTransactionSeqNum = 0x001;
3111                         priv->exclude_unencrypted = 1;
3112                         send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3113                         return;
3114                 } else if (system == WLAN_AUTH_SHARED_KEY
3115                            && priv->wep_is_on) {
3116                         priv->CurrentAuthentTransactionSeqNum = 0x001;
3117                         priv->exclude_unencrypted = 0;
3118                         send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3119                         return;
3120                 } else if (priv->connect_to_any_BSS) {
3121                         int bss_index;
3122 
3123                         priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3124 
3125                         if ((bss_index  = retrieve_bss(priv)) != -1) {
3126                                 atmel_join_bss(priv, bss_index);
3127                                 return;
3128                         }
3129                 }
3130         }
3131 
3132         priv->AuthenticationRequestRetryCnt = 0;
3133         atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3134         priv->station_is_associated = 0;
3135 }
3136 
3137 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3138 {
3139         struct ass_resp_format {
3140                 __le16 capability;
3141                 __le16 status;
3142                 __le16 ass_id;
3143                 u8 el_id;
3144                 u8 length;
3145                 u8 rates[4];
3146         } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3147 
3148         u16 status = le16_to_cpu(ass_resp->status);
3149         u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3150         u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3151 
3152         union iwreq_data wrqu;
3153 
3154         if (frame_len < 8 + rates_len)
3155                 return;
3156 
3157         if (status == WLAN_STATUS_SUCCESS) {
3158                 if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3159                         priv->AssociationRequestRetryCnt = 0;
3160                 else
3161                         priv->ReAssociationRequestRetryCnt = 0;
3162 
3163                 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3164                                 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3165                 atmel_set_mib(priv, Phy_Mib_Type,
3166                               PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3167                 if (priv->power_mode == 0) {
3168                         priv->listen_interval = 1;
3169                         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3170                                        MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3171                         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3172                                         MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3173                 } else {
3174                         priv->listen_interval = 2;
3175                         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3176                                        MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
3177                         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3178                                         MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3179                 }
3180 
3181                 priv->station_is_associated = 1;
3182                 priv->station_was_associated = 1;
3183                 atmel_enter_state(priv, STATION_STATE_READY);
3184 
3185                 /* Send association event to userspace */
3186                 wrqu.data.length = 0;
3187                 wrqu.data.flags = 0;
3188                 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3189                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3190                 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3191 
3192                 return;
3193         }
3194 
3195         if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3196             status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3197             status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3198             priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3199                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3200                 priv->AssociationRequestRetryCnt++;
3201                 send_association_request(priv, 0);
3202                 return;
3203         }
3204 
3205         if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3206             status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3207             status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3208             priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3209                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3210                 priv->ReAssociationRequestRetryCnt++;
3211                 send_association_request(priv, 1);
3212                 return;
3213         }
3214 
3215         atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3216         priv->station_is_associated = 0;
3217 
3218         if (priv->connect_to_any_BSS) {
3219                 int bss_index;
3220                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3221 
3222                 if ((bss_index = retrieve_bss(priv)) != -1)
3223                         atmel_join_bss(priv, bss_index);
3224         }
3225 }
3226 
3227 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3228 {
3229         struct bss_info *bss =  &priv->BSSinfo[bss_index];
3230 
3231         memcpy(priv->CurrentBSSID, bss->BSSID, 6);
3232         memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3233 
3234         /* The WPA stuff cares about the current AP address */
3235         if (priv->use_wpa)
3236                 build_wpa_mib(priv);
3237 
3238         /* When switching to AdHoc turn OFF Power Save if needed */
3239 
3240         if (bss->BSStype == IW_MODE_ADHOC &&
3241             priv->operating_mode != IW_MODE_ADHOC &&
3242             priv->power_mode) {
3243                 priv->power_mode = 0;
3244                 priv->listen_interval = 1;
3245                 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3246                                MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
3247                 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3248                                 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3249         }
3250 
3251         priv->operating_mode = bss->BSStype;
3252         priv->channel = bss->channel & 0x7f;
3253         priv->beacon_period = bss->beacon_period;
3254 
3255         if (priv->preamble != bss->preamble) {
3256                 priv->preamble = bss->preamble;
3257                 atmel_set_mib8(priv, Local_Mib_Type,
3258                                LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3259         }
3260 
3261         if (!priv->wep_is_on && bss->UsingWEP) {
3262                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3263                 priv->station_is_associated = 0;
3264                 return;
3265         }
3266 
3267         if (priv->wep_is_on && !bss->UsingWEP) {
3268                 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3269                 priv->station_is_associated = 0;
3270                 return;
3271         }
3272 
3273         atmel_enter_state(priv, STATION_STATE_JOINNING);
3274 
3275         if (priv->operating_mode == IW_MODE_INFRA)
3276                 join(priv, BSS_TYPE_INFRASTRUCTURE);
3277         else
3278                 join(priv, BSS_TYPE_AD_HOC);
3279 }
3280 
3281 static void restart_search(struct atmel_private *priv)
3282 {
3283         int bss_index;
3284 
3285         if (!priv->connect_to_any_BSS) {
3286                 atmel_scan(priv, 1);
3287         } else {
3288                 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3289 
3290                 if ((bss_index = retrieve_bss(priv)) != -1)
3291                         atmel_join_bss(priv, bss_index);
3292                 else
3293                         atmel_scan(priv, 0);
3294         }
3295 }
3296 
3297 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3298 {
3299         u8 old = priv->wstats.qual.level;
3300         u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3301 
3302         switch (priv->firmware_type) {
3303         case ATMEL_FW_TYPE_502E:
3304                 max_rssi = 63; /* 502-rmfd-reve max by experiment */
3305                 break;
3306         default:
3307                 break;
3308         }
3309 
3310         rssi = rssi * 100 / max_rssi;
3311         if ((rssi + old) % 2)
3312                 priv->wstats.qual.level = (rssi + old) / 2 + 1;
3313         else
3314                 priv->wstats.qual.level = (rssi + old) / 2;
3315         priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3316         priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3317 }
3318 
3319 static void atmel_smooth_qual(struct atmel_private *priv)
3320 {
3321         unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3322         while (time_diff--) {
3323                 priv->last_qual += HZ;
3324                 priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3325                 priv->wstats.qual.qual +=
3326                         priv->beacons_this_sec * priv->beacon_period * (priv<