Linux Audio

Check our new training course

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