Linux Audio

Check our new training course

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