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