Linux Audio

Check our new training course

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