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
1402#ifdef CONFIG_PROC_FS
1403static int atmel_proc_show(struct seq_file *m, void *v)
1404{
1405        struct atmel_private *priv = m->private;
1406        int i;
1407        char *s, *r, *c;
1408
1409        seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1410
1411        if (priv->station_state != STATION_STATE_DOWN) {
1412                seq_printf(m,
1413                           "Firmware version:\t%d.%d build %d\n"
1414                           "Firmware location:\t",
1415                           priv->host_info.major_version,
1416                           priv->host_info.minor_version,
1417                           priv->host_info.build_version);
1418
1419                if (priv->card_type != CARD_TYPE_EEPROM)
1420                        seq_puts(m, "on card\n");
1421                else if (priv->firmware)
1422                        seq_printf(m, "%s loaded by host\n", priv->firmware_id);
1423                else
1424                        seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
1425
1426                switch (priv->card_type) {
1427                case CARD_TYPE_PARALLEL_FLASH:
1428                        c = "Parallel flash";
1429                        break;
1430                case CARD_TYPE_SPI_FLASH:
1431                        c = "SPI flash\n";
1432                        break;
1433                case CARD_TYPE_EEPROM:
1434                        c = "EEPROM";
1435                        break;
1436                default:
1437                        c = "<unknown>";
1438                }
1439
1440                r = "<unknown>";
1441                for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1442                        if (priv->reg_domain == channel_table[i].reg_domain)
1443                                r = channel_table[i].name;
1444
1445                seq_printf(m, "MAC memory type:\t%s\n", c);
1446                seq_printf(m, "Regulatory domain:\t%s\n", r);
1447                seq_printf(m, "Host CRC checking:\t%s\n",
1448                         priv->do_rx_crc ? "On" : "Off");
1449                seq_printf(m, "WPA-capable firmware:\t%s\n",
1450                         priv->use_wpa ? "Yes" : "No");
1451        }
1452
1453        switch (priv->station_state) {
1454        case STATION_STATE_SCANNING:
1455                s = "Scanning";
1456                break;
1457        case STATION_STATE_JOINNING:
1458                s = "Joining";
1459                break;
1460        case STATION_STATE_AUTHENTICATING:
1461                s = "Authenticating";
1462                break;
1463        case STATION_STATE_ASSOCIATING:
1464                s = "Associating";
1465                break;
1466        case STATION_STATE_READY:
1467                s = "Ready";
1468                break;
1469        case STATION_STATE_REASSOCIATING:
1470                s = "Reassociating";
1471                break;
1472        case STATION_STATE_MGMT_ERROR:
1473                s = "Management error";
1474                break;
1475        case STATION_STATE_DOWN:
1476                s = "Down";
1477                break;
1478        default:
1479                s = "<unknown>";
1480        }
1481
1482        seq_printf(m, "Current state:\t\t%s\n", s);
1483        return 0;
1484}
1485#endif
1486
1487static const struct net_device_ops atmel_netdev_ops = {
1488        .ndo_open               = atmel_open,
1489        .ndo_stop               = atmel_close,
1490        .ndo_set_mac_address    = atmel_set_mac_address,
1491        .ndo_start_xmit         = start_tx,
1492        .ndo_do_ioctl           = atmel_ioctl,
1493        .ndo_validate_addr      = eth_validate_addr,
1494};
1495
1496struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1497                                   const AtmelFWType fw_type,
1498                                   struct device *sys_dev,
1499                                   int (*card_present)(void *), void *card)
1500{
1501        struct net_device *dev;
1502        struct atmel_private *priv;
1503        int rc;
1504
1505        /* Create the network device object. */
1506        dev = alloc_etherdev(sizeof(*priv));
1507        if (!dev)
1508                return NULL;
1509
1510        if (dev_alloc_name(dev, dev->name) < 0) {
1511                printk(KERN_ERR "atmel: Couldn't get name!\n");
1512                goto err_out_free;
1513        }
1514
1515        priv = netdev_priv(dev);
1516        priv->dev = dev;
1517        priv->sys_dev = sys_dev;
1518        priv->present_callback = card_present;
1519        priv->card = card;
1520        priv->firmware = NULL;
1521        priv->firmware_type = fw_type;
1522        if (firmware) /* module parameter */
1523                strlcpy(priv->firmware_id, firmware, sizeof(priv->firmware_id));
1524        priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1525        priv->station_state = STATION_STATE_DOWN;
1526        priv->do_rx_crc = 0;
1527        /* For PCMCIA cards, some chips need CRC, some don't
1528           so we have to probe. */
1529        if (priv->bus_type == BUS_TYPE_PCCARD) {
1530                priv->probe_crc = 1;
1531                priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1532        } else
1533                priv->probe_crc = 0;
1534        priv->last_qual = jiffies;
1535        priv->last_beacon_timestamp = 0;
1536        memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1537        eth_zero_addr(priv->BSSID);
1538        priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1539        priv->station_was_associated = 0;
1540
1541        priv->last_survey = jiffies;
1542        priv->preamble = LONG_PREAMBLE;
1543        priv->operating_mode = IW_MODE_INFRA;
1544        priv->connect_to_any_BSS = 0;
1545        priv->config_reg_domain = 0;
1546        priv->reg_domain = 0;
1547        priv->tx_rate = 3;
1548        priv->auto_tx_rate = 1;
1549        priv->channel = 4;
1550        priv->power_mode = 0;
1551        priv->SSID[0] = '\0';
1552        priv->SSID_size = 0;
1553        priv->new_SSID_size = 0;
1554        priv->frag_threshold = 2346;
1555        priv->rts_threshold = 2347;
1556        priv->short_retry = 7;
1557        priv->long_retry = 4;
1558
1559        priv->wep_is_on = 0;
1560        priv->default_key = 0;
1561        priv->encryption_level = 0;
1562        priv->exclude_unencrypted = 0;
1563        priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1564        priv->use_wpa = 0;
1565        memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1566        memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1567
1568        priv->default_beacon_period = priv->beacon_period = 100;
1569        priv->listen_interval = 1;
1570
1571        timer_setup(&priv->management_timer, atmel_management_timer, 0);
1572        spin_lock_init(&priv->irqlock);
1573        spin_lock_init(&priv->timerlock);
1574
1575        dev->netdev_ops = &atmel_netdev_ops;
1576        dev->wireless_handlers = &atmel_handler_def;
1577        dev->irq = irq;
1578        dev->base_addr = port;
1579
1580        /* MTU range: 68 - 2312 */
1581        dev->min_mtu = 68;
1582        dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
1583
1584        SET_NETDEV_DEV(dev, sys_dev);
1585
1586        if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1587                printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1588                goto err_out_free;
1589        }
1590
1591        if (!request_region(dev->base_addr, 32,
1592                            priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
1593                goto err_out_irq;
1594        }
1595
1596        if (register_netdev(dev))
1597                goto err_out_res;
1598
1599        if (!probe_atmel_card(dev)) {
1600                unregister_netdev(dev);
1601                goto err_out_res;
1602        }
1603
1604        netif_carrier_off(dev);
1605
1606        if (!proc_create_single_data("driver/atmel", 0, NULL, atmel_proc_show,
1607                        priv))
1608                printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1609
1610        printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1611               dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1612
1613        return dev;
1614
1615err_out_res:
1616        release_region(dev->base_addr, 32);
1617err_out_irq:
1618        free_irq(dev->irq, dev);
1619err_out_free:
1620        free_netdev(dev);
1621        return NULL;
1622}
1623
1624EXPORT_SYMBOL(init_atmel_card);
1625
1626void stop_atmel_card(struct net_device *dev)
1627{
1628        struct atmel_private *priv = netdev_priv(dev);
1629
1630        /* put a brick on it... */
1631        if (priv->bus_type == BUS_TYPE_PCCARD)
1632                atmel_write16(dev, GCR, 0x0060);
1633        atmel_write16(dev, GCR, 0x0040);
1634
1635        del_timer_sync(&priv->management_timer);
1636        unregister_netdev(dev);
1637        remove_proc_entry("driver/atmel", NULL);
1638        free_irq(dev->irq, dev);
1639        kfree(priv->firmware);
1640        release_region(dev->base_addr, 32);
1641        free_netdev(dev);
1642}
1643
1644EXPORT_SYMBOL(stop_atmel_card);
1645
1646static int atmel_set_essid(struct net_device *dev,
1647                           struct iw_request_info *info,
1648                           struct iw_point *dwrq,
1649                           char *extra)
1650{
1651        struct atmel_private *priv = netdev_priv(dev);
1652
1653        /* Check if we asked for `any' */
1654        if (dwrq->flags == 0) {
1655                priv->connect_to_any_BSS = 1;
1656        } else {
1657                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1658
1659                priv->connect_to_any_BSS = 0;
1660
1661                /* Check the size of the string */
1662                if (dwrq->length > MAX_SSID_LENGTH)
1663                         return -E2BIG;
1664                if (index != 0)
1665                        return -EINVAL;
1666
1667                memcpy(priv->new_SSID, extra, dwrq->length);
1668                priv->new_SSID_size = dwrq->length;
1669        }
1670
1671        return -EINPROGRESS;
1672}
1673
1674static int atmel_get_essid(struct net_device *dev,
1675                           struct iw_request_info *info,
1676                           struct iw_point *dwrq,
1677                           char *extra)
1678{
1679        struct atmel_private *priv = netdev_priv(dev);
1680
1681        /* Get the current SSID */
1682        if (priv->new_SSID_size != 0) {
1683                memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1684                dwrq->length = priv->new_SSID_size;
1685        } else {
1686                memcpy(extra, priv->SSID, priv->SSID_size);
1687                dwrq->length = priv->SSID_size;
1688        }
1689
1690        dwrq->flags = !priv->connect_to_any_BSS; /* active */
1691
1692        return 0;
1693}
1694
1695static int atmel_get_wap(struct net_device *dev,
1696                         struct iw_request_info *info,
1697                         struct sockaddr *awrq,
1698                         char *extra)
1699{
1700        struct atmel_private *priv = netdev_priv(dev);
1701        memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1702        awrq->sa_family = ARPHRD_ETHER;
1703
1704        return 0;
1705}
1706
1707static int atmel_set_encode(struct net_device *dev,
1708                            struct iw_request_info *info,
1709                            struct iw_point *dwrq,
1710                            char *extra)
1711{
1712        struct atmel_private *priv = netdev_priv(dev);
1713
1714        /* Basic checking: do we have a key to set ?
1715         * Note : with the new API, it's impossible to get a NULL pointer.
1716         * Therefore, we need to check a key size == 0 instead.
1717         * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1718         * when no key is present (only change flags), but older versions
1719         * don't do it. - Jean II */
1720        if (dwrq->length > 0) {
1721                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1722                int current_index = priv->default_key;
1723                /* Check the size of the key */
1724                if (dwrq->length > 13) {
1725                        return -EINVAL;
1726                }
1727                /* Check the index (none -> use current) */
1728                if (index < 0 || index >= 4)
1729                        index = current_index;
1730                else
1731                        priv->default_key = index;
1732                /* Set the length */
1733                if (dwrq->length > 5)
1734                        priv->wep_key_len[index] = 13;
1735                else
1736                        if (dwrq->length > 0)
1737                                priv->wep_key_len[index] = 5;
1738                        else
1739                                /* Disable the key */
1740                                priv->wep_key_len[index] = 0;
1741                /* Check if the key is not marked as invalid */
1742                if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1743                        /* Cleanup */
1744                        memset(priv->wep_keys[index], 0, 13);
1745                        /* Copy the key in the driver */
1746                        memcpy(priv->wep_keys[index], extra, dwrq->length);
1747                }
1748                /* WE specify that if a valid key is set, encryption
1749                 * should be enabled (user may turn it off later)
1750                 * This is also how "iwconfig ethX key on" works */
1751                if (index == current_index &&
1752                    priv->wep_key_len[index] > 0) {
1753                        priv->wep_is_on = 1;
1754                        priv->exclude_unencrypted = 1;
1755                        if (priv->wep_key_len[index] > 5) {
1756                                priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1757                                priv->encryption_level = 2;
1758                        } else {
1759                                priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1760                                priv->encryption_level = 1;
1761                        }
1762                }
1763        } else {
1764                /* Do we want to just set the transmit key index ? */
1765                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1766                if (index >= 0 && index < 4) {
1767                        priv->default_key = index;
1768                } else
1769                        /* Don't complain if only change the mode */
1770                        if (!(dwrq->flags & IW_ENCODE_MODE))
1771                                return -EINVAL;
1772        }
1773        /* Read the flags */
1774        if (dwrq->flags & IW_ENCODE_DISABLED) {
1775                priv->wep_is_on = 0;
1776                priv->encryption_level = 0;
1777                priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1778        } else {
1779                priv->wep_is_on = 1;
1780                if (priv->wep_key_len[priv->default_key] > 5) {
1781                        priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1782                        priv->encryption_level = 2;
1783                } else {
1784                        priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1785                        priv->encryption_level = 1;
1786                }
1787        }
1788        if (dwrq->flags & IW_ENCODE_RESTRICTED)
1789                priv->exclude_unencrypted = 1;
1790        if (dwrq->flags & IW_ENCODE_OPEN)
1791                priv->exclude_unencrypted = 0;
1792
1793        return -EINPROGRESS;            /* Call commit handler */
1794}
1795
1796static int atmel_get_encode(struct net_device *dev,
1797                            struct iw_request_info *info,
1798                            struct iw_point *dwrq,
1799                            char *extra)
1800{
1801        struct atmel_private *priv = netdev_priv(dev);
1802        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1803
1804        if (!priv->wep_is_on)
1805                dwrq->flags = IW_ENCODE_DISABLED;
1806        else {
1807                if (priv->exclude_unencrypted)
1808                        dwrq->flags = IW_ENCODE_RESTRICTED;
1809                else
1810                        dwrq->flags = IW_ENCODE_OPEN;
1811        }
1812                /* Which key do we want ? -1 -> tx index */
1813        if (index < 0 || index >= 4)
1814                index = priv->default_key;
1815        dwrq->flags |= index + 1;
1816        /* Copy the key to the user buffer */
1817        dwrq->length = priv->wep_key_len[index];
1818        if (dwrq->length > 16) {
1819                dwrq->length = 0;
1820        } else {
1821                memset(extra, 0, 16);
1822                memcpy(extra, priv->wep_keys[index], dwrq->length);
1823        }
1824
1825        return 0;
1826}
1827
1828static int atmel_set_encodeext(struct net_device *dev,
1829                            struct iw_request_info *info,
1830                            union iwreq_data *wrqu,
1831                            char *extra)
1832{
1833        struct atmel_private *priv = netdev_priv(dev);
1834        struct iw_point *encoding = &wrqu->encoding;
1835        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1836        int idx, key_len, alg = ext->alg, set_key = 1;
1837
1838        /* Determine and validate the key index */
1839        idx = encoding->flags & IW_ENCODE_INDEX;
1840        if (idx) {
1841                if (idx < 1 || idx > 4)
1842                        return -EINVAL;
1843                idx--;
1844        } else
1845                idx = priv->default_key;
1846
1847        if (encoding->flags & IW_ENCODE_DISABLED)
1848            alg = IW_ENCODE_ALG_NONE;
1849
1850        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1851                priv->default_key = idx;
1852                set_key = ext->key_len > 0 ? 1 : 0;
1853        }
1854
1855        if (set_key) {
1856                /* Set the requested key first */
1857                switch (alg) {
1858                case IW_ENCODE_ALG_NONE:
1859                        priv->wep_is_on = 0;
1860                        priv->encryption_level = 0;
1861                        priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1862                        break;
1863                case IW_ENCODE_ALG_WEP:
1864                        if (ext->key_len > 5) {
1865                                priv->wep_key_len[idx] = 13;
1866                                priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1867                                priv->encryption_level = 2;
1868                        } else if (ext->key_len > 0) {
1869                                priv->wep_key_len[idx] = 5;
1870                                priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1871                                priv->encryption_level = 1;
1872                        } else {
1873                                return -EINVAL;
1874                        }
1875                        priv->wep_is_on = 1;
1876                        memset(priv->wep_keys[idx], 0, 13);
1877                        key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1878                        memcpy(priv->wep_keys[idx], ext->key, key_len);
1879                        break;
1880                default:
1881                        return -EINVAL;
1882                }
1883        }
1884
1885        return -EINPROGRESS;
1886}
1887
1888static int atmel_get_encodeext(struct net_device *dev,
1889                            struct iw_request_info *info,
1890                            union iwreq_data *wrqu,
1891                            char *extra)
1892{
1893        struct atmel_private *priv = netdev_priv(dev);
1894        struct iw_point *encoding = &wrqu->encoding;
1895        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1896        int idx, max_key_len;
1897
1898        max_key_len = encoding->length - sizeof(*ext);
1899        if (max_key_len < 0)
1900                return -EINVAL;
1901
1902        idx = encoding->flags & IW_ENCODE_INDEX;
1903        if (idx) {
1904                if (idx < 1 || idx > 4)
1905                        return -EINVAL;
1906                idx--;
1907        } else
1908                idx = priv->default_key;
1909
1910        encoding->flags = idx + 1;
1911        memset(ext, 0, sizeof(*ext));
1912
1913        if (!priv->wep_is_on) {
1914                ext->alg = IW_ENCODE_ALG_NONE;
1915                ext->key_len = 0;
1916                encoding->flags |= IW_ENCODE_DISABLED;
1917        } else {
1918                if (priv->encryption_level > 0)
1919                        ext->alg = IW_ENCODE_ALG_WEP;
1920                else
1921                        return -EINVAL;
1922
1923                ext->key_len = priv->wep_key_len[idx];
1924                memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1925                encoding->flags |= IW_ENCODE_ENABLED;
1926        }
1927
1928        return 0;
1929}
1930
1931static int atmel_set_auth(struct net_device *dev,
1932                               struct iw_request_info *info,
1933                               union iwreq_data *wrqu, char *extra)
1934{
1935        struct atmel_private *priv = netdev_priv(dev);
1936        struct iw_param *param = &wrqu->param;
1937
1938        switch (param->flags & IW_AUTH_INDEX) {
1939        case IW_AUTH_WPA_VERSION:
1940        case IW_AUTH_CIPHER_PAIRWISE:
1941        case IW_AUTH_CIPHER_GROUP:
1942        case IW_AUTH_KEY_MGMT:
1943        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1944        case IW_AUTH_PRIVACY_INVOKED:
1945                /*
1946                 * atmel does not use these parameters
1947                 */
1948                break;
1949
1950        case IW_AUTH_DROP_UNENCRYPTED:
1951                priv->exclude_unencrypted = param->value ? 1 : 0;
1952                break;
1953
1954        case IW_AUTH_80211_AUTH_ALG: {
1955                        if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1956                                priv->exclude_unencrypted = 1;
1957                        } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1958                                priv->exclude_unencrypted = 0;
1959                        } else
1960                                return -EINVAL;
1961                        break;
1962                }
1963
1964        case IW_AUTH_WPA_ENABLED:
1965                /* Silently accept disable of WPA */
1966                if (param->value > 0)
1967                        return -EOPNOTSUPP;
1968                break;
1969
1970        default:
1971                return -EOPNOTSUPP;
1972        }
1973        return -EINPROGRESS;
1974}
1975
1976static int atmel_get_auth(struct net_device *dev,
1977                               struct iw_request_info *info,
1978                               union iwreq_data *wrqu, char *extra)
1979{
1980        struct atmel_private *priv = netdev_priv(dev);
1981        struct iw_param *param = &wrqu->param;
1982
1983        switch (param->flags & IW_AUTH_INDEX) {
1984        case IW_AUTH_DROP_UNENCRYPTED:
1985                param->value = priv->exclude_unencrypted;
1986                break;
1987
1988        case IW_AUTH_80211_AUTH_ALG:
1989                if (priv->exclude_unencrypted == 1)
1990                        param->value = IW_AUTH_ALG_SHARED_KEY;
1991                else
1992                        param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1993                break;
1994
1995        case IW_AUTH_WPA_ENABLED:
1996                param->value = 0;
1997                break;
1998
1999        default:
2000                return -EOPNOTSUPP;
2001        }
2002        return 0;
2003}
2004
2005
2006static int atmel_get_name(struct net_device *dev,
2007                          struct iw_request_info *info,
2008                          char *cwrq,
2009                          char *extra)
2010{
2011        strcpy(cwrq, "IEEE 802.11-DS");
2012        return 0;
2013}
2014
2015static int atmel_set_rate(struct net_device *dev,
2016                          struct iw_request_info *info,
2017                          struct iw_param *vwrq,
2018                          char *extra)
2019{
2020        struct atmel_private *priv = netdev_priv(dev);
2021
2022        if (vwrq->fixed == 0) {
2023                priv->tx_rate = 3;
2024                priv->auto_tx_rate = 1;
2025        } else {
2026                priv->auto_tx_rate = 0;
2027
2028                /* Which type of value ? */
2029                if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2030                        /* Setting by rate index */
2031                        priv->tx_rate = vwrq->value;
2032                } else {
2033                /* Setting by frequency value */
2034                        switch (vwrq->value) {
2035                        case  1000000:
2036                                priv->tx_rate = 0;
2037                                break;
2038                        case  2000000:
2039                                priv->tx_rate = 1;
2040                                break;
2041                        case  5500000:
2042                                priv->tx_rate = 2;
2043                                break;
2044                        case 11000000:
2045                                priv->tx_rate = 3;
2046                                break;
2047                        default:
2048                                return -EINVAL;
2049                        }
2050                }
2051        }
2052
2053        return -EINPROGRESS;
2054}
2055
2056static int atmel_set_mode(struct net_device *dev,
2057                          struct iw_request_info *info,
2058                          __u32 *uwrq,
2059                          char *extra)
2060{
2061        struct atmel_private *priv = netdev_priv(dev);
2062
2063        if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2064                return -EINVAL;
2065
2066        priv->operating_mode = *uwrq;
2067        return -EINPROGRESS;
2068}
2069
2070static int atmel_get_mode(struct net_device *dev,
2071                          struct iw_request_info *info,
2072                          __u32 *uwrq,
2073                          char *extra)
2074{
2075        struct atmel_private *priv = netdev_priv(dev);
2076
2077        *uwrq = priv->operating_mode;
2078        return 0;
2079}
2080
2081static int atmel_get_rate(struct net_device *dev,
2082                         struct iw_request_info *info,
2083                         struct iw_param *vwrq,
2084                         char *extra)
2085{
2086        struct atmel_private *priv = netdev_priv(dev);
2087
2088        if (priv->auto_tx_rate) {
2089                vwrq->fixed = 0;
2090                vwrq->value = 11000000;
2091        } else {
2092                vwrq->fixed = 1;
2093                switch (priv->tx_rate) {
2094                case 0:
2095                        vwrq->value =  1000000;
2096                        break;
2097                case 1:
2098                        vwrq->value =  2000000;
2099                        break;
2100                case 2:
2101                        vwrq->value =  5500000;
2102                        break;
2103                case 3:
2104                        vwrq->value = 11000000;
2105                        break;
2106                }
2107        }
2108        return 0;
2109}
2110
2111static int atmel_set_power(struct net_device *dev,
2112                           struct iw_request_info *info,
2113                           struct iw_param *vwrq,
2114                           char *extra)
2115{
2116        struct atmel_private *priv = netdev_priv(dev);
2117        priv->power_mode = vwrq->disabled ? 0 : 1;
2118        return -EINPROGRESS;
2119}
2120
2121static int atmel_get_power(struct net_device *dev,
2122                           struct iw_request_info *info,
2123                           struct iw_param *vwrq,
2124                           char *extra)
2125{
2126        struct atmel_private *priv = netdev_priv(dev);
2127        vwrq->disabled = priv->power_mode ? 0 : 1;
2128        vwrq->flags = IW_POWER_ON;
2129        return 0;
2130}
2131
2132static int atmel_set_retry(struct net_device *dev,
2133                           struct iw_request_info *info,
2134                           struct iw_param *vwrq,
2135                           char *extra)
2136{
2137        struct atmel_private *priv = netdev_priv(dev);
2138
2139        if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2140                if (vwrq->flags & IW_RETRY_LONG)
2141                        priv->long_retry = vwrq->value;
2142                else if (vwrq->flags & IW_RETRY_SHORT)
2143                        priv->short_retry = vwrq->value;
2144                else {
2145                        /* No modifier : set both */
2146                        priv->long_retry = vwrq->value;
2147                        priv->short_retry = vwrq->value;
2148                }
2149                return -EINPROGRESS;
2150        }
2151
2152        return -EINVAL;
2153}
2154
2155static int atmel_get_retry(struct net_device *dev,
2156                           struct iw_request_info *info,
2157                           struct iw_param *vwrq,
2158                           char *extra)
2159{
2160        struct atmel_private *priv = netdev_priv(dev);
2161
2162        vwrq->disabled = 0;      /* Can't be disabled */
2163
2164        /* Note : by default, display the short retry number */
2165        if (vwrq->flags & IW_RETRY_LONG) {
2166                vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2167                vwrq->value = priv->long_retry;
2168        } else {
2169                vwrq->flags = IW_RETRY_LIMIT;
2170                vwrq->value = priv->short_retry;
2171                if (priv->long_retry != priv->short_retry)
2172                        vwrq->flags |= IW_RETRY_SHORT;
2173        }
2174
2175        return 0;
2176}
2177
2178static int atmel_set_rts(struct net_device *dev,
2179                         struct iw_request_info *info,
2180                         struct iw_param *vwrq,
2181                         char *extra)
2182{
2183        struct atmel_private *priv = netdev_priv(dev);
2184        int rthr = vwrq->value;
2185
2186        if (vwrq->disabled)
2187                rthr = 2347;
2188        if ((rthr < 0) || (rthr > 2347)) {
2189                return -EINVAL;
2190        }
2191        priv->rts_threshold = rthr;
2192
2193        return -EINPROGRESS;            /* Call commit handler */
2194}
2195
2196static int atmel_get_rts(struct net_device *dev,
2197                         struct iw_request_info *info,
2198                         struct iw_param *vwrq,
2199                         char *extra)
2200{
2201        struct atmel_private *priv = netdev_priv(dev);
2202
2203        vwrq->value = priv->rts_threshold;
2204        vwrq->disabled = (vwrq->value >= 2347);
2205        vwrq->fixed = 1;
2206
2207        return 0;
2208}
2209
2210static int atmel_set_frag(struct net_device *dev,
2211                          struct iw_request_info *info,
2212                          struct iw_param *vwrq,
2213                          char *extra)
2214{
2215        struct atmel_private *priv = netdev_priv(dev);
2216        int fthr = vwrq->value;
2217
2218        if (vwrq->disabled)
2219                fthr = 2346;
2220        if ((fthr < 256) || (fthr > 2346)) {
2221                return -EINVAL;
2222        }
2223        fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
2224        priv->frag_threshold = fthr;
2225
2226        return -EINPROGRESS;            /* Call commit handler */
2227}
2228
2229static int atmel_get_frag(struct net_device *dev,
2230                          struct iw_request_info *info,
2231                          struct iw_param *vwrq,
2232                          char *extra)
2233{
2234        struct atmel_private *priv = netdev_priv(dev);
2235
2236        vwrq->value = priv->frag_threshold;
2237        vwrq->disabled = (vwrq->value >= 2346);
2238        vwrq->fixed = 1;
2239
2240        return 0;
2241}
2242
2243static int atmel_set_freq(struct net_device *dev,
2244                          struct iw_request_info *info,
2245                          struct iw_freq *fwrq,
2246                          char *extra)
2247{
2248        struct atmel_private *priv = netdev_priv(dev);
2249        int rc = -EINPROGRESS;          /* Call commit handler */
2250
2251        /* If setting by frequency, convert to a channel */
2252        if (fwrq->e == 1) {
2253                int f = fwrq->m / 100000;
2254
2255                /* Hack to fall through... */
2256                fwrq->e = 0;
2257                fwrq->m = ieee80211_frequency_to_channel(f);
2258        }
2259        /* Setting by channel number */
2260        if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2261                rc = -EOPNOTSUPP;
2262        else {
2263                int channel = fwrq->m;
2264                if (atmel_validate_channel(priv, channel) == 0) {
2265                        priv->channel = channel;
2266                } else {
2267                        rc = -EINVAL;
2268                }
2269        }
2270        return rc;
2271}
2272
2273static int atmel_get_freq(struct net_device *dev,
2274                          struct iw_request_info *info,
2275                          struct iw_freq *fwrq,
2276                          char *extra)
2277{
2278        struct atmel_private *priv = netdev_priv(dev);
2279
2280        fwrq->m = priv->channel;
2281        fwrq->e = 0;
2282        return 0;
2283}
2284
2285static int atmel_set_scan(struct net_device *dev,
2286                          struct iw_request_info *info,
2287                          struct iw_point *dwrq,
2288                          char *extra)
2289{
2290        struct atmel_private *priv = netdev_priv(dev);
2291        unsigned long flags;
2292
2293        /* Note : you may have realised that, as this is a SET operation,
2294         * this is privileged and therefore a normal user can't
2295         * perform scanning.
2296         * This is not an error, while the device perform scanning,
2297         * traffic doesn't flow, so it's a perfect DoS...
2298         * Jean II */
2299
2300        if (priv->station_state == STATION_STATE_DOWN)
2301                return -EAGAIN;
2302
2303        /* Timeout old surveys. */
2304        if (time_after(jiffies, priv->last_survey + 20 * HZ))
2305                priv->site_survey_state = SITE_SURVEY_IDLE;
2306        priv->last_survey = jiffies;
2307
2308        /* Initiate a scan command */
2309        if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2310                return -EBUSY;
2311
2312        del_timer_sync(&priv->management_timer);
2313        spin_lock_irqsave(&priv->irqlock, flags);
2314
2315        priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2316        priv->fast_scan = 0;
2317        atmel_scan(priv, 0);
2318        spin_unlock_irqrestore(&priv->irqlock, flags);
2319
2320        return 0;
2321}
2322
2323static int atmel_get_scan(struct net_device *dev,
2324                          struct iw_request_info *info,
2325                          struct iw_point *dwrq,
2326                          char *extra)
2327{
2328        struct atmel_private *priv = netdev_priv(dev);
2329        int i;
2330        char *current_ev = extra;
2331        struct iw_event iwe;
2332
2333        if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2334                return -EAGAIN;
2335
2336        for (i = 0; i < priv->BSS_list_entries; i++) {
2337                iwe.cmd = SIOCGIWAP;
2338                iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2339                memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2340                current_ev = iwe_stream_add_event(info, current_ev,
2341                                                  extra + IW_SCAN_MAX_DATA,
2342                                                  &iwe, IW_EV_ADDR_LEN);
2343
2344                iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
2345                if (iwe.u.data.length > 32)
2346                        iwe.u.data.length = 32;
2347                iwe.cmd = SIOCGIWESSID;
2348                iwe.u.data.flags = 1;
2349                current_ev = iwe_stream_add_point(info, current_ev,
2350                                                  extra + IW_SCAN_MAX_DATA,
2351                                                  &iwe, priv->BSSinfo[i].SSID);
2352
2353                iwe.cmd = SIOCGIWMODE;
2354                iwe.u.mode = priv->BSSinfo[i].BSStype;
2355                current_ev = iwe_stream_add_event(info, current_ev,
2356                                                  extra + IW_SCAN_MAX_DATA,
2357                                                  &iwe, IW_EV_UINT_LEN);
2358
2359                iwe.cmd = SIOCGIWFREQ;
2360                iwe.u.freq.m = priv->BSSinfo[i].channel;
2361                iwe.u.freq.e = 0;
2362                current_ev = iwe_stream_add_event(info, current_ev,
2363                                                  extra + IW_SCAN_MAX_DATA,
2364                                                  &iwe, IW_EV_FREQ_LEN);
2365
2366                /* Add quality statistics */
2367                iwe.cmd = IWEVQUAL;
2368                iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2369                iwe.u.qual.qual  = iwe.u.qual.level;
2370                /* iwe.u.qual.noise  = SOMETHING */
2371                current_ev = iwe_stream_add_event(info, current_ev,
2372                                                  extra + IW_SCAN_MAX_DATA,
2373                                                  &iwe, IW_EV_QUAL_LEN);
2374
2375
2376                iwe.cmd = SIOCGIWENCODE;
2377                if (priv->BSSinfo[i].UsingWEP)
2378                        iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2379                else
2380                        iwe.u.data.flags = IW_ENCODE_DISABLED;
2381                iwe.u.data.length = 0;
2382                current_ev = iwe_stream_add_point(info, current_ev,
2383                                                  extra + IW_SCAN_MAX_DATA,
2384                                                  &iwe, NULL);
2385        }
2386
2387        /* Length of data */
2388        dwrq->length = (current_ev - extra);
2389        dwrq->flags = 0;
2390
2391        return 0;
2392}
2393
2394static int atmel_get_range(struct net_device *dev,
2395                           struct iw_request_info *info,
2396                           struct iw_point *dwrq,
2397                           char *extra)
2398{
2399        struct atmel_private *priv = netdev_priv(dev);
2400        struct iw_range *range = (struct iw_range *) extra;
2401        int k, i, j;
2402
2403        dwrq->length = sizeof(struct iw_range);
2404        memset(range, 0, sizeof(struct iw_range));
2405        range->min_nwid = 0x0000;
2406        range->max_nwid = 0x0000;
2407        range->num_channels = 0;
2408        for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2409                if (priv->reg_domain == channel_table[j].reg_domain) {
2410                        range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2411                        break;
2412                }
2413        if (range->num_channels != 0) {
2414                for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2415                        range->freq[k].i = i; /* List index */
2416
2417                        /* Values in MHz -> * 10^5 * 10 */
2418                        range->freq[k].m = 100000 *
2419                         ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2420                        range->freq[k++].e = 1;
2421                }
2422                range->num_frequency = k;
2423        }
2424
2425        range->max_qual.qual = 100;
2426        range->max_qual.level = 100;
2427        range->max_qual.noise = 0;
2428        range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2429
2430        range->avg_qual.qual = 50;
2431        range->avg_qual.level = 50;
2432        range->avg_qual.noise = 0;
2433        range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2434
2435        range->sensitivity = 0;
2436
2437        range->bitrate[0] =  1000000;
2438        range->bitrate[1] =  2000000;
2439        range->bitrate[2] =  5500000;
2440        range->bitrate[3] = 11000000;
2441        range->num_bitrates = 4;
2442
2443        range->min_rts = 0;
2444        range->max_rts = 2347;
2445        range->min_frag = 256;
2446        range->max_frag = 2346;
2447
2448        range->encoding_size[0] = 5;
2449        range->encoding_size[1] = 13;
2450        range->num_encoding_sizes = 2;
2451        range->max_encoding_tokens = 4;
2452
2453        range->pmp_flags = IW_POWER_ON;
2454        range->pmt_flags = IW_POWER_ON;
2455        range->pm_capa = 0;
2456
2457        range->we_version_source = WIRELESS_EXT;
2458        range->we_version_compiled = WIRELESS_EXT;
2459        range->retry_capa = IW_RETRY_LIMIT ;
2460        range->retry_flags = IW_RETRY_LIMIT;
2461        range->r_time_flags = 0;
2462        range->min_retry = 1;
2463        range->max_retry = 65535;
2464
2465        return 0;
2466}
2467
2468static int atmel_set_wap(struct net_device *dev,
2469                         struct iw_request_info *info,
2470                         struct sockaddr *awrq,
2471                         char *extra)
2472{
2473        struct atmel_private *priv = netdev_priv(dev);
2474        int i;
2475        static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2476        static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2477        unsigned long flags;
2478
2479        if (awrq->sa_family != ARPHRD_ETHER)
2480                return -EINVAL;
2481
2482        if (!memcmp(any, awrq->sa_data, 6) ||
2483            !memcmp(off, awrq->sa_data, 6)) {
2484                del_timer_sync(&priv->management_timer);
2485                spin_lock_irqsave(&priv->irqlock, flags);
2486                atmel_scan(priv, 1);
2487                spin_unlock_irqrestore(&priv->irqlock, flags);
2488                return 0;
2489        }
2490
2491        for (i = 0; i < priv->BSS_list_entries; i++) {
2492                if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2493                        if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2494                                return -EINVAL;
2495                        } else if  (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2496                                return -EINVAL;
2497                        } else {
2498                                del_timer_sync(&priv->management_timer);
2499                                spin_lock_irqsave(&priv->irqlock, flags);
2500                                atmel_join_bss(priv, i);
2501                                spin_unlock_irqrestore(&priv->irqlock, flags);
2502                                return 0;
2503                        }
2504                }
2505        }
2506
2507        return -EINVAL;
2508}
2509
2510static int atmel_config_commit(struct net_device *dev,
2511                               struct iw_request_info *info,    /* NULL */
2512                               void *zwrq,                      /* NULL */
2513                               char *extra)                     /* NULL */
2514{
2515        return atmel_open(dev);
2516}
2517
2518static const iw_handler atmel_handler[] =
2519{
2520        (iw_handler) atmel_config_commit,       /* SIOCSIWCOMMIT */
2521        (iw_handler) atmel_get_name,            /* SIOCGIWNAME */
2522        (iw_handler) NULL,                      /* SIOCSIWNWID */
2523        (iw_handler) NULL,                      /* SIOCGIWNWID */
2524        (iw_handler) atmel_set_freq,            /* SIOCSIWFREQ */
2525        (iw_handler) atmel_get_freq,            /* SIOCGIWFREQ */
2526        (iw_handler) atmel_set_mode,            /* SIOCSIWMODE */
2527        (iw_handler) atmel_get_mode,            /* SIOCGIWMODE */
2528        (iw_handler) NULL,                      /* SIOCSIWSENS */
2529        (iw_handler) NULL,                      /* SIOCGIWSENS */
2530        (iw_handler) NULL,                      /* SIOCSIWRANGE */
2531        (iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
2532        (iw_handler) NULL,                      /* SIOCSIWPRIV */
2533        (iw_handler) NULL,                      /* SIOCGIWPRIV */
2534        (iw_handler) NULL,                      /* SIOCSIWSTATS */
2535        (iw_handler) NULL,                      /* SIOCGIWSTATS */
2536        (iw_handler) NULL,                      /* SIOCSIWSPY */
2537        (iw_handler) NULL,                      /* SIOCGIWSPY */
2538        (iw_handler) NULL,                      /* -- hole -- */
2539        (iw_handler) NULL,                      /* -- hole -- */
2540        (iw_handler) atmel_set_wap,             /* SIOCSIWAP */
2541        (iw_handler) atmel_get_wap,             /* SIOCGIWAP */
2542        (iw_handler) NULL,                      /* -- hole -- */
2543        (iw_handler) NULL,                      /* SIOCGIWAPLIST */
2544        (iw_handler) atmel_set_scan,            /* SIOCSIWSCAN */
2545        (iw_handler) atmel_get_scan,            /* SIOCGIWSCAN */
2546        (iw_handler) atmel_set_essid,           /* SIOCSIWESSID */
2547        (iw_handler) atmel_get_essid,           /* SIOCGIWESSID */
2548        (iw_handler) NULL,                      /* SIOCSIWNICKN */
2549        (iw_handler) NULL,                      /* SIOCGIWNICKN */
2550        (iw_handler) NULL,                      /* -- hole -- */
2551        (iw_handler) NULL,                      /* -- hole -- */
2552        (iw_handler) atmel_set_rate,            /* SIOCSIWRATE */
2553        (iw_handler) atmel_get_rate,            /* SIOCGIWRATE */
2554        (iw_handler) atmel_set_rts,             /* SIOCSIWRTS */
2555        (iw_handler) atmel_get_rts,             /* SIOCGIWRTS */
2556        (iw_handler) atmel_set_frag,            /* SIOCSIWFRAG */
2557        (iw_handler) atmel_get_frag,            /* SIOCGIWFRAG */
2558        (iw_handler) NULL,                      /* SIOCSIWTXPOW */
2559        (iw_handler) NULL,                      /* SIOCGIWTXPOW */
2560        (iw_handler) atmel_set_retry,           /* SIOCSIWRETRY */
2561        (iw_handler) atmel_get_retry,           /* SIOCGIWRETRY */
2562        (iw_handler) atmel_set_encode,          /* SIOCSIWENCODE */
2563        (iw_handler) atmel_get_encode,          /* SIOCGIWENCODE */
2564        (iw_handler) atmel_set_power,           /* SIOCSIWPOWER */
2565        (iw_handler) atmel_get_power,           /* SIOCGIWPOWER */
2566        (iw_handler) NULL,                      /* -- hole -- */
2567        (iw_handler) NULL,                      /* -- hole -- */
2568        (iw_handler) NULL,                      /* SIOCSIWGENIE */
2569        (iw_handler) NULL,                      /* SIOCGIWGENIE */
2570        (iw_handler) atmel_set_auth,            /* SIOCSIWAUTH */
2571        (iw_handler) atmel_get_auth,            /* SIOCGIWAUTH */
2572        (iw_handler) atmel_set_encodeext,       /* SIOCSIWENCODEEXT */
2573        (iw_handler) atmel_get_encodeext,       /* SIOCGIWENCODEEXT */
2574        (iw_handler) NULL,                      /* SIOCSIWPMKSA */
2575};
2576
2577static const iw_handler atmel_private_handler[] =
2578{
2579        NULL,                           /* SIOCIWFIRSTPRIV */
2580};
2581
2582struct atmel_priv_ioctl {
2583        char id[32];
2584        unsigned char __user *data;
2585        unsigned short len;
2586};
2587
2588#define ATMELFWL        SIOCIWFIRSTPRIV
2589#define ATMELIDIFC      ATMELFWL + 1
2590#define ATMELRD         ATMELFWL + 2
2591#define ATMELMAGIC 0x51807
2592#define REGDOMAINSZ 20
2593
2594static const struct iw_priv_args atmel_private_args[] = {
2595        {
2596                .cmd = ATMELFWL,
2597                .set_args = IW_PRIV_TYPE_BYTE
2598                                | IW_PRIV_SIZE_FIXED
2599                                | sizeof(struct atmel_priv_ioctl),
2600                .get_args = IW_PRIV_TYPE_NONE,
2601                .name = "atmelfwl"
2602        }, {
2603                .cmd = ATMELIDIFC,
2604                .set_args = IW_PRIV_TYPE_NONE,
2605                .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2606                .name = "atmelidifc"
2607        }, {
2608                .cmd = ATMELRD,
2609                .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2610                .get_args = IW_PRIV_TYPE_NONE,
2611                .name = "regdomain"
2612        },
2613};
2614
2615static const struct iw_handler_def atmel_handler_def = {
2616        .num_standard   = ARRAY_SIZE(atmel_handler),
2617        .num_private    = ARRAY_SIZE(atmel_private_handler),
2618        .num_private_args = ARRAY_SIZE(atmel_private_args),
2619        .standard       = (iw_handler *) atmel_handler,
2620        .private        = (iw_handler *) atmel_private_handler,
2621        .private_args   = (struct iw_priv_args *) atmel_private_args,
2622        .get_wireless_stats = atmel_get_wireless_stats
2623};
2624
2625static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2626{
2627        int i, rc = 0;
2628        struct atmel_private *priv = netdev_priv(dev);
2629        struct atmel_priv_ioctl com;
2630        struct iwreq *wrq = (struct iwreq *) rq;
2631        unsigned char *new_firmware;
2632        char domain[REGDOMAINSZ + 1];
2633
2634        switch (cmd) {
2635        case ATMELIDIFC:
2636                wrq->u.param.value = ATMELMAGIC;
2637                break;
2638
2639        case ATMELFWL:
2640                if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2641                        rc = -EFAULT;
2642                        break;
2643                }
2644
2645                if (!capable(CAP_NET_ADMIN)) {
2646                        rc = -EPERM;
2647                        break;
2648                }
2649
2650                new_firmware = memdup_user(com.data, com.len);
2651                if (IS_ERR(new_firmware)) {
2652                        rc = PTR_ERR(new_firmware);
2653                        break;
2654                }
2655
2656                kfree(priv->firmware);
2657
2658                priv->firmware = new_firmware;
2659                priv->firmware_length = com.len;
2660                strncpy(priv->firmware_id, com.id, 31);
2661                priv->firmware_id[31] = '\0';
2662                break;
2663
2664        case ATMELRD:
2665                if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2666                        rc = -EFAULT;
2667                        break;
2668                }
2669
2670                if (!capable(CAP_NET_ADMIN)) {
2671                        rc = -EPERM;
2672                        break;
2673                }
2674
2675                domain[REGDOMAINSZ] = 0;
2676                rc = -EINVAL;
2677                for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2678                        if (!strcasecmp(channel_table[i].name, domain)) {
2679                                priv->config_reg_domain = channel_table[i].reg_domain;
2680                                rc = 0;
2681                        }
2682                }
2683
2684                if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2685                        rc = atmel_open(dev);
2686                break;
2687
2688        default:
2689                rc = -EOPNOTSUPP;
2690        }
2691
2692        return rc;
2693}
2694
2695struct auth_body {
2696        __le16 alg;
2697        __le16 trans_seq;
2698        __le16 status;
2699        u8 el_id;
2700        u8 chall_text_len;
2701        u8 chall_text[253];
2702};
2703
2704static void atmel_enter_state(struct atmel_private *priv, int new_state)
2705{
2706        int old_state = priv->station_state;
2707
2708        if (new_state == old_state)
2709                return;
2710
2711        priv->station_state = new_state;
2712
2713        if (new_state == STATION_STATE_READY) {
2714                netif_start_queue(priv->dev);
2715                netif_carrier_on(priv->dev);
2716        }
2717
2718        if (old_state == STATION_STATE_READY) {
2719                netif_carrier_off(priv->dev);
2720                if (netif_running(priv->dev))
2721                        netif_stop_queue(priv->dev);
2722                priv->last_beacon_timestamp = 0;
2723        }
2724}
2725
2726static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2727{
2728        struct {
2729                u8 BSSID[ETH_ALEN];
2730                u8 SSID[MAX_SSID_LENGTH];
2731                u8 scan_type;
2732                u8 channel;
2733                __le16 BSS_type;
2734                __le16 min_channel_time;
2735                __le16 max_channel_time;
2736                u8 options;
2737                u8 SSID_size;
2738        } cmd;
2739
2740        eth_broadcast_addr(cmd.BSSID);
2741
2742        if (priv->fast_scan) {
2743                cmd.SSID_size = priv->SSID_size;
2744                memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2745                cmd.min_channel_time = cpu_to_le16(10);
2746                cmd.max_channel_time = cpu_to_le16(50);
2747        } else {
2748                priv->BSS_list_entries = 0;
2749                cmd.SSID_size = 0;
2750                cmd.min_channel_time = cpu_to_le16(10);
2751                cmd.max_channel_time = cpu_to_le16(120);
2752        }
2753
2754        cmd.options = 0;
2755
2756        if (!specific_ssid)
2757                cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2758
2759        cmd.channel = (priv->channel & 0x7f);
2760        cmd.scan_type = SCAN_TYPE_ACTIVE;
2761        cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2762                BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2763
2764        atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2765
2766        /* This must come after all hardware access to avoid being messed up
2767           by stuff happening in interrupt context after we leave STATE_DOWN */
2768        atmel_enter_state(priv, STATION_STATE_SCANNING);
2769}
2770
2771static void join(struct atmel_private *priv, int type)
2772{
2773        struct {
2774                u8 BSSID[6];
2775                u8 SSID[MAX_SSID_LENGTH];
2776                u8 BSS_type; /* this is a short in a scan command - weird */
2777                u8 channel;
2778                __le16 timeout;
2779                u8 SSID_size;
2780                u8 reserved;
2781        } cmd;
2782
2783        cmd.SSID_size = priv->SSID_size;
2784        memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2785        memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2786        cmd.channel = (priv->channel & 0x7f);
2787        cmd.BSS_type = type;
2788        cmd.timeout = cpu_to_le16(2000);
2789
2790        atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2791}
2792
2793static void start(struct atmel_private *priv, int type)
2794{
2795        struct {
2796                u8 BSSID[6];
2797                u8 SSID[MAX_SSID_LENGTH];
2798                u8 BSS_type;
2799                u8 channel;
2800                u8 SSID_size;
2801                u8 reserved[3];
2802        } cmd;
2803
2804        cmd.SSID_size = priv->SSID_size;
2805        memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2806        memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2807        cmd.BSS_type = type;
2808        cmd.channel = (priv->channel & 0x7f);
2809
2810        atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2811}
2812
2813static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2814                                u8 channel)
2815{
2816        int rejoin = 0;
2817        int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2818                SHORT_PREAMBLE : LONG_PREAMBLE;
2819
2820        if (priv->preamble != new) {
2821                priv->preamble = new;
2822                rejoin = 1;
2823                atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2824        }
2825
2826        if (priv->channel != channel) {
2827                priv->channel = channel;
2828                rejoin = 1;
2829                atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2830        }
2831
2832        if (rejoin) {
2833                priv->station_is_associated = 0;
2834                atmel_enter_state(priv, STATION_STATE_JOINNING);
2835
2836                if (priv->operating_mode == IW_MODE_INFRA)
2837                        join(priv, BSS_TYPE_INFRASTRUCTURE);
2838                else
2839                        join(priv, BSS_TYPE_AD_HOC);
2840        }
2841}
2842
2843static void send_authentication_request(struct atmel_private *priv, u16 system,
2844                                        u8 *challenge, int challenge_len)
2845{
2846        struct ieee80211_hdr header;
2847        struct auth_body auth;
2848
2849        header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2850        header.duration_id = cpu_to_le16(0x8000);
2851        header.seq_ctrl = 0;
2852        memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2853        memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2854        memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2855
2856        if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2857                /* no WEP for authentication frames with TrSeqNo 1 */
2858                header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2859
2860        auth.alg = cpu_to_le16(system);
2861
2862        auth.status = 0;
2863        auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2864        priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2865        priv->CurrentAuthentTransactionSeqNum += 2;
2866
2867        if (challenge_len != 0) {
2868                auth.el_id = 16; /* challenge_text */
2869                auth.chall_text_len = challenge_len;
2870                memcpy(auth.chall_text, challenge, challenge_len);
2871                atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2872        } else {
2873                atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2874        }
2875}
2876
2877static void send_association_request(struct atmel_private *priv, int is_reassoc)
2878{
2879        u8 *ssid_el_p;
2880        int bodysize;
2881        struct ieee80211_hdr header;
2882        struct ass_req_format {
2883                __le16 capability;
2884                __le16 listen_interval;
2885                u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2886                u8 ssid_el_id;
2887                u8 ssid_len;
2888                u8 ssid[MAX_SSID_LENGTH];
2889                u8 sup_rates_el_id;
2890                u8 sup_rates_len;
2891                u8 rates[4];
2892        } body;
2893
2894        header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2895                (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2896        header.duration_id = cpu_to_le16(0x8000);
2897        header.seq_ctrl = 0;
2898
2899        memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2900        memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2901        memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2902
2903        body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2904        if (priv->wep_is_on)
2905                body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2906        if (priv->preamble == SHORT_PREAMBLE)
2907                body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2908
2909        body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2910
2911        /* current AP address - only in reassoc frame */
2912        if (is_reassoc) {
2913                memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2914                ssid_el_p = &body.ssid_el_id;
2915                bodysize = 18 + priv->SSID_size;
2916        } else {
2917                ssid_el_p = &body.ap[0];
2918                bodysize = 12 + priv->SSID_size;
2919        }
2920
2921        ssid_el_p[0] = WLAN_EID_SSID;
2922        ssid_el_p[1] = priv->SSID_size;
2923        memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2924        ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2925        ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2926        memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2927
2928        atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2929}
2930
2931static int is_frame_from_current_bss(struct atmel_private *priv,
2932                                     struct ieee80211_hdr *header)
2933{
2934        if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2935                return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2936        else
2937                return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2938}
2939
2940static int retrieve_bss(struct atmel_private *priv)
2941{
2942        int i;
2943        int max_rssi = -128;
2944        int max_index = -1;
2945
2946        if (priv->BSS_list_entries == 0)
2947                return -1;
2948
2949        if (priv->connect_to_any_BSS) {
2950                /* Select a BSS with the max-RSSI but of the same type and of
2951                   the same WEP mode and that it is not marked as 'bad' (i.e.
2952                   we had previously failed to connect to this BSS with the
2953                   settings that we currently use) */
2954                priv->current_BSS = 0;
2955                for (i = 0; i < priv->BSS_list_entries; i++) {
2956                        if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2957                            ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2958                             (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2959                            !(priv->BSSinfo[i].channel & 0x80)) {
2960                                max_rssi = priv->BSSinfo[i].RSSI;
2961                                priv->current_BSS = max_index = i;
2962                        }
2963                }
2964                return max_index;
2965        }
2966
2967        for (i = 0; i < priv->BSS_list_entries; i++) {
2968                if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2969                    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2970                    priv->operating_mode == priv->BSSinfo[i].BSStype &&
2971                    atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2972                        if (priv->BSSinfo[i].RSSI >= max_rssi) {
2973                                max_rssi = priv->BSSinfo[i].RSSI;
2974                                max_index = i;
2975                        }
2976                }
2977        }
2978        return max_index;
2979}
2980
2981static void store_bss_info(struct atmel_private *priv,
2982                           struct ieee80211_hdr *header, u16 capability,
2983                           u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2984                           u8 *ssid, int is_beacon)
2985{
2986        u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2987        int i, index;
2988
2989        for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2990                if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
2991                        index = i;
2992
2993        /* If we process a probe and an entry from this BSS exists
2994           we will update the BSS entry with the info from this BSS.
2995           If we process a beacon we will only update RSSI */
2996
2997        if (index == -1) {
2998                if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2999                        return;
3000                index = priv->BSS_list_entries++;
3001                memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
3002                priv->BSSinfo[index].RSSI = rssi;
3003        } else {
3004                if (rssi > priv->BSSinfo[index].RSSI)
3005                        priv->BSSinfo[index].RSSI = rssi;
3006                if (is_beacon)
3007                        return;
3008        }
3009
3010        priv->BSSinfo[index].channel = channel;
3011        priv->BSSinfo[index].beacon_period = beacon_period;
3012        priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3013        memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3014        priv->BSSinfo[index].SSIDsize = ssid_len;
3015
3016        if (capability & WLAN_CAPABILITY_IBSS)
3017                priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3018        else if (capability & WLAN_CAPABILITY_ESS)
3019                priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3020
3021        priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3022                SHORT_PREAMBLE : LONG_PREAMBLE;
3023}
3024
3025static void authenticate(struct atmel_private *priv, u16 frame_len)
3026{
3027        struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3028        u16 status = le16_to_cpu(auth->status);
3029        u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3030        u16 system = le16_to_cpu(auth->alg);
3031
3032        if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3033                /* no WEP */
3034                if (priv->station_was_associated) {
3035                        atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3036                        send_association_request(priv, 1);
3037                        return;
3038                } else {
3039                        atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3040                        send_association_request(priv, 0);
3041                        return;
3042                }
3043        }
3044
3045        if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3046                int should_associate = 0;
3047                /* WEP */
3048                if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3049                        return;
3050
3051                if (system == WLAN_AUTH_OPEN) {
3052                        if (trans_seq_no == 0x0002) {
3053                                should_associate = 1;
3054                        }
3055                } else if (system == WLAN_AUTH_SHARED_KEY) {
3056                        if (trans_seq_no == 0x0002 &&
3057                            auth->el_id == WLAN_EID_CHALLENGE) {
3058                                send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3059                                return;
3060                        } else if (trans_seq_no == 0x0004) {
3061                                should_associate = 1;
3062                        }
3063                }
3064
3065                if (should_associate) {
3066                        if (priv->station_was_associated) {
3067                                atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3068                                send_association_request(priv, 1);
3069                                return;
3070                        } else {
3071                                atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3072                                send_association_request(priv, 0);
3073                                return;
3074                        }
3075                }
3076        }
3077
3078        if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3079                /* Flip back and forth between WEP auth modes until the max
3080                 * authentication tries has been exceeded.
3081                 */
3082                if (system == WLAN_AUTH_OPEN) {
3083                        priv->CurrentAuthentTransactionSeqNum = 0x001;
3084                        priv->exclude_unencrypted = 1;
3085                        send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3086                        return;
3087                } else if (system == WLAN_AUTH_SHARED_KEY
3088                           && priv->wep_is_on) {
3089                        priv->CurrentAuthentTransactionSeqNum = 0x001;
3090                        priv->exclude_unencrypted = 0;
3091                        send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3092                        return;
3093                } else if (priv->connect_to_any_BSS) {
3094                        int bss_index;
3095
3096                        priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3097
3098                        if ((bss_index  = retrieve_bss(priv)) != -1) {
3099                                atmel_join_bss(priv, bss_index);
3100                                return;
3101                        }
3102                }
3103        }
3104
3105        priv->AuthenticationRequestRetryCnt = 0;
3106        atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3107        priv->station_is_associated = 0;
3108}
3109
3110static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3111{
3112        struct ass_resp_format {
3113                __le16 capability;
3114                __le16 status;
3115                __le16 ass_id;
3116                u8 el_id;
3117                u8 length;
3118                u8 rates[4];
3119        } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3120
3121        u16 status = le16_to_cpu(ass_resp->status);
3122        u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3123        u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3124
3125        union iwreq_data wrqu;
3126
3127        if (frame_len < 8 + rates_len)
3128                return;
3129
3130        if (status == WLAN_STATUS_SUCCESS) {
3131                if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3132                        priv->AssociationRequestRetryCnt = 0;
3133                else
3134                        priv->ReAssociationRequestRetryCnt = 0;
3135
3136                atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3137                                MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3138                atmel_set_mib(priv, Phy_Mib_Type,
3139                              PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3140                if (priv->power_mode == 0) {
3141                        priv->listen_interval = 1;
3142                        atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3143                                       MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3144                        atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3145                                        MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3146                } else {
3147                        priv->listen_interval = 2;
3148                        atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3149                                       MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
3150                        atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3151                                        MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3152                }
3153
3154                priv->station_is_associated = 1;
3155                priv->station_was_associated = 1;
3156                atmel_enter_state(priv, STATION_STATE_READY);
3157
3158                /* Send association event to userspace */
3159                wrqu.data.length = 0;
3160                wrqu.data.flags = 0;
3161                memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3162                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3163                wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3164
3165                return;
3166        }
3167
3168        if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3169            status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3170            status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3171            priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3172                mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3173                priv->AssociationRequestRetryCnt++;
3174                send_association_request(priv, 0);
3175                return;
3176        }
3177
3178        if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3179            status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3180            status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3181            priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3182                mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3183                priv->ReAssociationRequestRetryCnt++;
3184                send_association_request(priv, 1);
3185                return;
3186        }
3187
3188        atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3189        priv->station_is_associated = 0;
3190
3191        if (priv->connect_to_any_BSS) {
3192                int bss_index;
3193                priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3194
3195                if ((bss_index = retrieve_bss(priv)) != -1)
3196                        atmel_join_bss(priv, bss_index);
3197        }
3198}
3199
3200static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3201{
3202        struct bss_info *bss =  &priv->BSSinfo[bss_index];
3203
3204        memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3205        memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3206
3207        /* The WPA stuff cares about the current AP address */
3208        if (priv->use_wpa)
3209                build_wpa_mib(priv);
3210
3211        /* When switching to AdHoc turn OFF Power Save if needed */
3212
3213        if (bss->BSStype == IW_MODE_ADHOC &&
3214            priv->operating_mode != IW_MODE_ADHOC &&
3215            priv->power_mode) {
3216                priv->power_mode = 0;
3217                priv->listen_interval = 1;
3218                atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3219                               MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
3220                atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3221                                MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3222        }
3223
3224        priv->operating_mode = bss->BSStype;
3225        priv->channel = bss->channel & 0x7f;
3226        priv->beacon_period = bss->beacon_period;
3227
3228        if (priv->preamble != bss->preamble) {
3229                priv->preamble = bss->preamble;
3230                atmel_set_mib8(priv, Local_Mib_Type,
3231                               LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3232        }
3233
3234        if (!priv->wep_is_on && bss->UsingWEP) {
3235                atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3236                priv->station_is_associated = 0;
3237                return;
3238        }
3239
3240        if (priv->wep_is_on && !bss->UsingWEP) {
3241                atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3242                priv->station_is_associated = 0;
3243                return;
3244        }
3245
3246        atmel_enter_state(priv, STATION_STATE_JOINNING);
3247
3248        if (priv->operating_mode == IW_MODE_INFRA)
3249                join(priv, BSS_TYPE_INFRASTRUCTURE);
3250        else
3251                join(priv, BSS_TYPE_AD_HOC);
3252}
3253
3254static void restart_search(struct atmel_private *priv)
3255{
3256        int bss_index;
3257
3258        if (!priv->connect_to_any_BSS) {
3259                atmel_scan(priv, 1);
3260        } else {
3261                priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3262
3263                if ((bss_index = retrieve_bss(priv)) != -1)
3264                        atmel_join_bss(priv, bss_index);
3265                else
3266                        atmel_scan(priv, 0);
3267        }
3268}
3269
3270static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3271{
3272        u8 old = priv->wstats.qual.level;
3273        u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3274
3275        switch (priv->firmware_type) {
3276        case ATMEL_FW_TYPE_502E:
3277                max_rssi = 63; /* 502-rmfd-reve max by experiment */
3278                break;
3279        default:
3280                break;
3281        }
3282
3283        rssi = rssi * 100 / max_rssi;
3284        if ((rssi + old) % 2)
3285                priv->wstats.qual.level = (rssi + old) / 2 + 1;
3286        else
3287                priv->wstats.qual.level = (rssi + old) / 2;
3288        priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3289        priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3290}
3291
3292static void atmel_smooth_qual(struct atmel_private *priv)
3293{
3294        unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3295        while (time_diff--) {
3296                priv->last_qual += HZ;
3297                priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3298                priv->wstats.qual.qual +=
3299                        priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3300                priv->beacons_this_sec = 0;
3301        }
3302        priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3303        priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3304}
3305
3306/* deals with incoming management frames. */
3307static void atmel_management_frame(struct atmel_private *priv,
3308                                   struct ieee80211_hdr *header,
3309                                   u16 frame_len, u8 rssi)
3310{
3311        u16 subtype;
3312
3313        subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3314        switch (subtype) {
3315        case IEEE80211_STYPE_BEACON:
3316        case IEEE80211_STYPE_PROBE_RESP:
3317
3318                /* beacon frame has multiple variable-length fields -
3319                   never let an engineer loose with a data structure design. */
3320                {
3321                        struct beacon_format {
3322                                __le64 timestamp;
3323                                __le16 interval;
3324                                __le16 capability;
3325                                u8 ssid_el_id;
3326                                u8 ssid_length;
3327                                /* ssid here */
3328                                u8 rates_el_id;
3329                                u8 rates_length;
3330                                /* rates here */
3331                                u8 ds_el_id;
3332                                u8 ds_length;
3333                                /* ds here */
3334                        } *beacon = (struct beacon_format *)priv->rx_buf;
3335
3336                        u8 channel, rates_length, ssid_length;
3337                        u64 timestamp = le64_to_cpu(beacon->timestamp);
3338                        u16 beacon_interval = le16_to_cpu(beacon->interval);
3339                        u16 capability = le16_to_cpu(beacon->capability);
3340                        u8 *beaconp = priv->rx_buf;
3341                        ssid_length = beacon->ssid_length;
3342                        /* this blows chunks. */
3343                        if (frame_len < 14 || frame_len < ssid_length + 15)
3344                                return;
3345                        rates_length = beaconp[beacon->ssid_length + 15];
3346                        if (frame_len < ssid_length + rates_length + 18)
3347                                return;
3348                        if (ssid_length >  MAX_SSID_LENGTH)
3349                                return;
3350                        channel = beaconp[ssid_length + rates_length + 18];
3351
3352                        if (priv->station_state == STATION_STATE_READY) {
3353                                smooth_rssi(priv, rssi);
3354                                if (is_frame_from_current_bss(priv, header)) {
3355                                        priv->beacons_this_sec++;
3356                                        atmel_smooth_qual(priv);
3357                                        if (priv->last_beacon_timestamp) {
3358                                                /* Note truncate this to 32 bits - kernel can't divide a long long */
3359                                                u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3360                                                int beacons = beacon_delay / (beacon_interval * 1000);
3361                                                if (beacons > 1)
3362                                                        priv->wstats.miss.beacon += beacons - 1;
3363                                        }
3364                                        priv->last_beacon_timestamp = timestamp;
3365                                        handle_beacon_probe(priv, capability, channel);
3366                                }
3367                        }
3368
3369                        if (priv->station_state == STATION_STATE_SCANNING)
3370                                store_bss_info(priv, header, capability,
3371                                               beacon_interval, channel, rssi,
3372                                               ssid_length,
3373                                               &beacon->rates_el_id,
3374                                               subtype == IEEE80211_STYPE_BEACON);
3375                }
3376                break;
3377
3378        case IEEE80211_STYPE_AUTH:
3379
3380                if (priv->station_state == STATION_STATE_AUTHENTICATING)
3381                        authenticate(priv, frame_len);
3382
3383                break;
3384
3385        case IEEE80211_STYPE_ASSOC_RESP:
3386        case IEEE80211_STYPE_REASSOC_RESP:
3387
3388                if (priv->station_state == STATION_STATE_ASSOCIATING ||
3389                    priv->station_state == STATION_STATE_REASSOCIATING)
3390                        associate(priv, frame_len, subtype);
3391
3392                break;
3393
3394        case IEEE80211_STYPE_DISASSOC:
3395                if (priv->station_is_associated &&
3396                    priv->operating_mode == IW_MODE_INFRA &&
3397                    is_frame_from_current_bss(priv, header)) {
3398                        priv->station_was_associated = 0;
3399                        priv->station_is_associated = 0;
3400
3401                        atmel_enter_state(priv, STATION_STATE_JOINNING);
3402                        join(priv, BSS_TYPE_INFRASTRUCTURE);
3403                }
3404
3405                break;
3406
3407        case IEEE80211_STYPE_DEAUTH:
3408                if (priv->operating_mode == IW_MODE_INFRA &&
3409                    is_frame_from_current_bss(priv, header)) {
3410                        priv->station_was_associated = 0;
3411
3412                        atmel_enter_state(priv, STATION_STATE_JOINNING);
3413                        join(priv, BSS_TYPE_INFRASTRUCTURE);
3414                }
3415
3416                break;
3417        }
3418}
3419
3420/* run when timer expires */
3421static void atmel_management_timer(struct timer_list *t)
3422{
3423        struct atmel_private *priv = from_timer(priv, t, management_timer);
3424        unsigned long flags;
3425
3426        /* Check if the card has been yanked. */
3427        if (priv->card && priv->present_callback &&
3428                !(*priv->present_callback)(priv->card))
3429                return;
3430
3431        spin_lock_irqsave(&priv->irqlock, flags);
3432
3433        switch (priv->station_state) {
3434
3435        case STATION_STATE_AUTHENTICATING:
3436                if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3437                        atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3438                        priv->station_is_associated = 0;
3439                        priv->AuthenticationRequestRetryCnt = 0;
3440                        restart_search(priv);
3441                } else {
3442                        int auth = WLAN_AUTH_OPEN;
3443                        priv->AuthenticationRequestRetryCnt++;
3444                        priv->CurrentAuthentTransactionSeqNum = 0x0001;
3445                        mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3446                        if (priv->wep_is_on && priv->exclude_unencrypted)
3447                                auth = WLAN_AUTH_SHARED_KEY;
3448                        send_authentication_request(priv, auth, NULL, 0);
3449          }
3450          break;
3451
3452        case STATION_STATE_ASSOCIATING:
3453                if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3454                        atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3455                        priv->station_is_associated = 0;
3456                        priv->AssociationRequestRetryCnt = 0;
3457                        restart_search(priv);
3458                } else {
3459                        priv->AssociationRequestRetryCnt++;
3460                        mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3461                        send_association_request(priv, 0);
3462                }
3463          break;
3464
3465        case STATION_STATE_REASSOCIATING:
3466                if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3467                        atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3468                        priv->station_is_associated = 0;
3469                        priv->ReAssociationRequestRetryCnt = 0;
3470                        restart_search(priv);
3471                } else {
3472                        priv->ReAssociationRequestRetryCnt++;
3473                        mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3474                        send_association_request(priv, 1);
3475                }
3476                break;
3477
3478        default:
3479                break;
3480        }
3481
3482        spin_unlock_irqrestore(&priv->irqlock, flags);
3483}
3484
3485static void atmel_command_irq(struct atmel_private *priv)
3486{
3487        u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3488        u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3489        int fast_scan;
3490        union iwreq_data wrqu;
3491
3492        if (status == CMD_STATUS_IDLE ||
3493            status == CMD_STATUS_IN_PROGRESS)
3494                return;
3495
3496        switch (command) {
3497        case CMD_Start:
3498                if (status == CMD_STATUS_COMPLETE) {
3499                        priv->station_was_associated = priv->station_is_associated;
3500                        atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3501                                      (u8 *)priv->CurrentBSSID, 6);
3502                        atmel_enter_state(priv, STATION_STATE_READY);
3503                }
3504                break;
3505
3506        case CMD_Scan:
3507                fast_scan = priv->fast_scan;
3508                priv->fast_scan = 0;
3509
3510                if (status != CMD_STATUS_COMPLETE) {
3511                        atmel_scan(priv, 1);
3512                } else {
3513                        int bss_index = retrieve_bss(priv);
3514                        int notify_scan_complete = 1;
3515                        if (bss_index != -1) {
3516                                atmel_join_bss(priv, bss_index);
3517                        } else if (priv->operating_mode == IW_MODE_ADHOC &&
3518                                   priv->SSID_size != 0) {
3519                                start(priv, BSS_TYPE_AD_HOC);
3520                        } else {
3521                                priv->fast_scan = !fast_scan;
3522                                atmel_scan(priv, 1);
3523                                notify_scan_complete = 0;
3524                        }
3525                        priv->site_survey_state = SITE_SURVEY_COMPLETED;
3526                        if (notify_scan_complete) {
3527                                wrqu.data.length = 0;
3528                                wrqu.data.flags = 0;
3529                                wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3530                        }
3531                }
3532                break;
3533
3534        case CMD_SiteSurvey:
3535                priv->fast_scan = 0;
3536
3537                if (status != CMD_STATUS_COMPLETE)
3538                        return;
3539
3540                priv->site_survey_state = SITE_SURVEY_COMPLETED;
3541                if (priv->station_is_associated) {
3542                        atmel_enter_state(priv, STATION_STATE_READY);
3543                        wrqu.data.length = 0;
3544                        wrqu.data.flags = 0;
3545                        wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3546                } else {
3547                        atmel_scan(priv, 1);
3548                }
3549                break;
3550
3551        case CMD_Join:
3552                if (status == CMD_STATUS_COMPLETE) {
3553                        if (priv->operating_mode == IW_MODE_ADHOC) {
3554                                priv->station_was_associated = priv->station_is_associated;
3555                                atmel_enter_state(priv, STATION_STATE_READY);
3556                        } else {
3557                                int auth = WLAN_AUTH_OPEN;
3558                                priv->AuthenticationRequestRetryCnt = 0;
3559                                atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3560
3561                                mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3562                                priv->CurrentAuthentTransactionSeqNum = 0x0001;
3563                                if (priv->wep_is_on && priv->exclude_unencrypted)
3564                                        auth = WLAN_AUTH_SHARED_KEY;
3565                                send_authentication_request(priv, auth, NULL, 0);
3566                        }
3567                        return;
3568                }
3569
3570                atmel_scan(priv, 1);
3571        }
3572}
3573
3574static int atmel_wakeup_firmware(struct atmel_private *priv)
3575{
3576        struct host_info_struct *iface = &priv->host_info;
3577        u16 mr1, mr3;
3578        int i;
3579
3580        if (priv->card_type == CARD_TYPE_SPI_FLASH)
3581                atmel_set_gcr(priv->dev, GCR_REMAP);
3582
3583        /* wake up on-board processor */
3584        atmel_clear_gcr(priv->dev, 0x0040);
3585        atmel_write16(priv->dev, BSR, BSS_SRAM);
3586
3587        if (priv->card_type == CARD_TYPE_SPI_FLASH)
3588                mdelay(100);
3589
3590        /* and wait for it */
3591        for (i = LOOP_RETRY_LIMIT; i; i--) {
3592                mr1 = atmel_read16(priv->dev, MR1);
3593                mr3 = atmel_read16(priv->dev, MR3);
3594
3595                if (mr3 & MAC_BOOT_COMPLETE)
3596                        break;
3597                if (mr1 & MAC_BOOT_COMPLETE &&
3598                    priv->bus_type == BUS_TYPE_PCCARD)
3599                        break;
3600        }
3601
3602        if (i == 0) {
3603                printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3604                return -EIO;
3605        }
3606
3607        if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3608                printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3609                return -ENODEV;
3610        }
3611
3612        /* now check for completion of MAC initialization through
3613           the FunCtrl field of the IFACE, poll MR1 to detect completion of
3614           MAC initialization, check completion status, set interrupt mask,
3615           enables interrupts and calls Tx and Rx initialization functions */
3616
3617        atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3618
3619        for (i = LOOP_RETRY_LIMIT; i; i--) {
3620                mr1 = atmel_read16(priv->dev, MR1);
3621                mr3 = atmel_read16(priv->dev, MR3);
3622
3623                if (mr3 & MAC_INIT_COMPLETE)
3624                        break;
3625                if (mr1 & MAC_INIT_COMPLETE &&
3626                    priv->bus_type == BUS_TYPE_PCCARD)
3627                        break;
3628        }
3629
3630        if (i == 0) {
3631                printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3632                                priv->dev->name);
3633                return -EIO;
3634        }
3635
3636        /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3637        if ((mr3 & MAC_INIT_COMPLETE) &&
3638            !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3639                printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3640                return -EIO;
3641        }
3642        if ((mr1 & MAC_INIT_COMPLETE) &&
3643            !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3644                printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3645                return -EIO;
3646        }
3647
3648        atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3649                           priv->host_info_base, sizeof(*iface));
3650
3651        iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3652        iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3653        iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3654        iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3655        iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3656        iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3657        iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3658        iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3659        iface->build_version = le16_to_cpu(iface->build_version);
3660        iface->command_pos = le16_to_cpu(iface->command_pos);
3661        iface->major_version = le16_to_cpu(iface->major_version);
3662        iface->minor_version = le16_to_cpu(iface->minor_version);
3663        iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3664        iface->mac_status = le16_to_cpu(iface->mac_status);
3665
3666        return 0;
3667}
3668
3669/* determine type of memory and MAC address */
3670static int probe_atmel_card(struct net_device *dev)
3671{
3672        int rc = 0;
3673        struct atmel_private *priv = netdev_priv(dev);
3674
3675        /* reset pccard */
3676        if (priv->bus_type == BUS_TYPE_PCCARD)
3677                atmel_write16(dev, GCR, 0x0060);
3678
3679        atmel_write16(dev, GCR, 0x0040);
3680        msleep(500);
3681
3682        if (atmel_read16(dev, MR2) == 0) {
3683                /* No stored firmware so load a small stub which just
3684                   tells us the MAC address */
3685                int i;
3686                priv->card_type = CARD_TYPE_EEPROM;
3687                atmel_write16(dev, BSR, BSS_IRAM);
3688                atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3689                atmel_set_gcr(dev, GCR_REMAP);
3690                atmel_clear_gcr(priv->dev, 0x0040);
3691                atmel_write16(dev, BSR, BSS_SRAM);
3692                for (i = LOOP_RETRY_LIMIT; i; i--)
3693                        if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3694                                break;
3695                if (i == 0) {
3696                        printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3697                } else {
3698                        atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3699                        /* got address, now squash it again until the network
3700                           interface is opened */
3701                        if (priv->bus_type == BUS_TYPE_PCCARD)
3702                                atmel_write16(dev, GCR, 0x0060);
3703                        atmel_write16(dev, GCR, 0x0040);
3704                        rc = 1;
3705                }
3706        } else if (atmel_read16(dev, MR4) == 0) {
3707                /* Mac address easy in this case. */
3708                priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3709                atmel_write16(dev,  BSR, 1);
3710                atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3711                atmel_write16(dev,  BSR, 0x200);
3712                rc = 1;
3713        } else {
3714                /* Standard firmware in flash, boot it up and ask
3715                   for the Mac Address */
3716                priv->card_type = CARD_TYPE_SPI_FLASH;
3717                if (atmel_wakeup_firmware(priv) == 0) {
3718                        atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3719
3720                        /* got address, now squash it again until the network
3721                           interface is opened */
3722                        if (priv->bus_type == BUS_TYPE_PCCARD)
3723                                atmel_write16(dev, GCR, 0x0060);
3724                        atmel_write16(dev, GCR, 0x0040);
3725                        rc = 1;
3726                }
3727        }
3728
3729        if (rc) {
3730                if (dev->dev_addr[0] == 0xFF) {
3731                        static const u8 default_mac[] = {
3732                                0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3733                        };
3734                        printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3735                        memcpy(dev->dev_addr, default_mac, ETH_ALEN);
3736                }
3737        }
3738
3739        return rc;
3740}
3741
3742/* Move the encyption information on the MIB structure.
3743   This routine is for the pre-WPA firmware: later firmware has
3744   a different format MIB and a different routine. */
3745static void build_wep_mib(struct atmel_private *priv)
3746{
3747        struct { /* NB this is matched to the hardware, don't change. */
3748                u8 wep_is_on;
3749                u8 default_key; /* 0..3 */
3750                u8 reserved;
3751                u8 exclude_unencrypted;
3752
3753                u32 WEPICV_error_count;
3754                u32 WEP_excluded_count;
3755
3756                u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3757                u8 encryption_level; /* 0, 1, 2 */
3758                u8 reserved2[3];
3759        } mib;
3760        int i;
3761
3762        mib.wep_is_on = priv->wep_is_on;
3763        if (priv->wep_is_on) {
3764                if (priv->wep_key_len[priv->default_key] > 5)
3765                        mib.encryption_level = 2;
3766                else
3767                        mib.encryption_level = 1;
3768        } else {
3769                mib.encryption_level = 0;
3770        }
3771
3772        mib.default_key = priv->default_key;
3773        mib.exclude_unencrypted = priv->exclude_unencrypted;
3774
3775        for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3776                memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3777
3778        atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3779}
3780
3781static void build_wpa_mib(struct atmel_private *priv)
3782{
3783        /* This is for the later (WPA enabled) firmware. */
3784
3785        struct { /* NB this is matched to the hardware, don't change. */
3786                u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3787                u8 receiver_address[ETH_ALEN];
3788                u8 wep_is_on;
3789                u8 default_key; /* 0..3 */
3790                u8 group_key;
3791                u8 exclude_unencrypted;
3792                u8 encryption_type;
3793                u8 reserved;
3794
3795                u32 WEPICV_error_count;
3796                u32 WEP_excluded_count;
3797
3798                u8 key_RSC[4][8];
3799        } mib;
3800
3801        int i;
3802
3803        mib.wep_is_on = priv->wep_is_on;
3804        mib.exclude_unencrypted = priv->exclude_unencrypted;
3805        memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3806
3807        /* zero all the keys before adding in valid ones. */
3808        memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3809
3810        if (priv->wep_is_on) {
3811                /* There's a comment in the Atmel code to the effect that this
3812                   is only valid when still using WEP, it may need to be set to
3813                   something to use WPA */
3814                memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3815
3816                mib.default_key = mib.group_key = 255;
3817                for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3818                        if (priv->wep_key_len[i] > 0) {
3819                                memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3820                                if (i == priv->default_key) {
3821                                        mib.default_key = i;
3822                                        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3823                                        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3824                                } else {
3825                                        mib.group_key = i;
3826                                        priv->group_cipher_suite = priv->pairwise_cipher_suite;
3827                                        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3828                                        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3829                                }
3830                        }
3831                }
3832                if (mib.default_key == 255)
3833                        mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3834                if (mib.group_key == 255)
3835                        mib.group_key = mib.default_key;
3836
3837        }
3838
3839        atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3840}
3841
3842static int reset_atmel_card(struct net_device *dev)
3843{
3844        /* do everything necessary to wake up the hardware, including
3845           waiting for the lightning strike and throwing the knife switch....
3846
3847           set all the Mib values which matter in the card to match
3848           their settings in the atmel_private structure. Some of these
3849           can be altered on the fly, but many (WEP, infrastructure or ad-hoc)
3850           can only be changed by tearing down the world and coming back through
3851           here.
3852
3853           This routine is also responsible for initialising some
3854           hardware-specific fields in the atmel_private structure,
3855           including a copy of the firmware's hostinfo structure
3856           which is the route into the rest of the firmware datastructures. */
3857
3858        struct atmel_private *priv = netdev_priv(dev);
3859        u8 configuration;
3860        int old_state = priv->station_state;
3861        int err = 0;
3862
3863        /* data to add to the firmware names, in priority order
3864           this implemenents firmware versioning */
3865
3866        static char *firmware_modifier[] = {
3867                "-wpa",
3868                "",
3869                NULL
3870        };
3871
3872        /* reset pccard */
3873        if (priv->bus_type == BUS_TYPE_PCCARD)
3874                atmel_write16(priv->dev, GCR, 0x0060);
3875
3876        /* stop card , disable interrupts */
3877        atmel_write16(priv->dev, GCR, 0x0040);
3878
3879        if (priv->card_type == CARD_TYPE_EEPROM) {
3880                /* copy in firmware if needed */
3881                const struct firmware *fw_entry = NULL;
3882                const unsigned char *fw;
3883                int len = priv->firmware_length;
3884                if (!(fw = priv->firmware)) {
3885                        if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3886                                if (strlen(priv->firmware_id) == 0) {
3887                                        printk(KERN_INFO
3888                                               "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3889                                               dev->name);
3890                                        printk(KERN_INFO
3891                                               "%s: if not, use the firmware= module parameter.\n",
3892                                               dev->name);
3893                                        strcpy(priv->firmware_id, "atmel_at76c502.bin");
3894                                }
3895                                err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3896                                if (err != 0) {
3897                                        printk(KERN_ALERT
3898                                               "%s: firmware %s is missing, cannot continue.\n",
3899                                               dev->name, priv->firmware_id);
3900                                        return err;
3901                                }
3902                        } else {
3903                                int fw_index = 0;
3904                                int success = 0;
3905
3906                                /* get firmware filename entry based on firmware type ID */
3907                                while (fw_table[fw_index].fw_type != priv->firmware_type
3908                                                && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3909                                        fw_index++;
3910
3911                                /* construct the actual firmware file name */
3912                                if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3913                                        int i;
3914                                        for (i = 0; firmware_modifier[i]; i++) {
3915                                                snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3916                                                        firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3917                                                priv->firmware_id[31] = '\0';
3918                                                if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3919                                                        success = 1;
3920                                                        break;
3921                                                }
3922                                        }
3923                                }
3924                                if (!success) {
3925                                        printk(KERN_ALERT
3926                                               "%s: firmware %s is missing, cannot start.\n",
3927                                               dev->name, priv->firmware_id);
3928                                        priv->firmware_id[0] = '\0';
3929                                        return -ENOENT;
3930                                }
3931                        }
3932
3933                        fw = fw_entry->data;
3934                        len = fw_entry->size;
3935                }
3936
3937                if (len <= 0x6000) {
3938                        atmel_write16(priv->dev, BSR, BSS_IRAM);
3939                        atmel_copy_to_card(priv->dev, 0, fw, len);
3940                        atmel_set_gcr(priv->dev, GCR_REMAP);
3941                } else {
3942                        /* Remap */
3943                        atmel_set_gcr(priv->dev, GCR_REMAP);
3944                        atmel_write16(priv->dev, BSR, BSS_IRAM);
3945                        atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3946                        atmel_write16(priv->dev, BSR, 0x2ff);
3947                        atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3948                }
3949
3950                release_firmware(fw_entry);
3951        }
3952
3953        err = atmel_wakeup_firmware(priv);
3954        if (err != 0)
3955                return err;
3956
3957        /* Check the version and set the correct flag for wpa stuff,
3958           old and new firmware is incompatible.
3959           The pre-wpa 3com firmware reports major version 5,
3960           the wpa 3com firmware is major version 4 and doesn't need
3961           the 3com broken-ness filter. */
3962        priv->use_wpa = (priv->host_info.major_version == 4);
3963        priv->radio_on_broken = (priv->host_info.major_version == 5);
3964
3965        /* unmask all irq sources */
3966        atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3967
3968        /* int Tx system and enable Tx */
3969        atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3970        atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3971        atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3972        atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3973
3974        priv->tx_desc_free = priv->host_info.tx_desc_count;
3975        priv->tx_desc_head = 0;
3976        priv->tx_desc_tail = 0;
3977        priv->tx_desc_previous = 0;
3978        priv->tx_free_mem = priv->host_info.tx_buff_size;
3979        priv->tx_buff_head = 0;
3980        priv->tx_buff_tail = 0;
3981
3982        configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3983        atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3984                                   configuration | FUNC_CTRL_TxENABLE);
3985
3986        /* init Rx system and enable */
3987        priv->rx_desc_head = 0;
3988
3989        configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3990        atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3991                                   configuration | FUNC_CTRL_RxENABLE);
3992
3993        if (!priv->radio_on_broken) {
3994                if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3995                    CMD_STATUS_REJECTED_RADIO_OFF) {
3996                        printk(KERN_INFO "%s: cannot turn the radio on.\n",
3997                               dev->name);
3998                        return -EIO;
3999                }
4000        }
4001
4002        /* set up enough MIB values to run. */
4003        atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4004        atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
4005        atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4006        atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4007        atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4008        atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4009        atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4010        atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4011                      priv->dev->dev_addr, 6);
4012        atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4013        atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4014        atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4015        atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4016        atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4017        if (priv->use_wpa)
4018                build_wpa_mib(priv);
4019        else
4020                build_wep_mib(priv);
4021
4022        if (old_state == STATION_STATE_READY) {
4023                union iwreq_data wrqu;
4024
4025                wrqu.data.length = 0;
4026                wrqu.data.flags = 0;
4027                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4028                eth_zero_addr(wrqu.ap_addr.sa_data);
4029                wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4030        }
4031
4032        return 0;
4033}
4034
4035static void atmel_send_command(struct atmel_private *priv, int command,
4036                               void *cmd, int cmd_size)
4037{
4038        if (cmd)
4039                atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4040                                   cmd, cmd_size);
4041
4042        atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4043        atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4044}
4045
4046static int atmel_send_command_wait(struct atmel_private *priv, int command,
4047                                   void *cmd, int cmd_size)
4048{
4049        int i, status;
4050
4051        atmel_send_command(priv, command, cmd, cmd_size);
4052
4053        for (i = 5000; i; i--) {
4054                status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4055                if (status != CMD_STATUS_IDLE &&
4056                    status != CMD_STATUS_IN_PROGRESS)
4057                        break;
4058                udelay(20);
4059        }
4060
4061        if (i == 0) {
4062                printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4063                status =  CMD_STATUS_HOST_ERROR;
4064        } else {
4065                if (command != CMD_EnableRadio)
4066                        status = CMD_STATUS_COMPLETE;
4067        }
4068
4069        return status;
4070}
4071
4072static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4073{
4074        struct get_set_mib m;
4075        m.type = type;
4076        m.size = 1;
4077        m.index = index;
4078
4079        atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4080        return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4081}
4082
4083static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4084{
4085        struct get_set_mib m;
4086        m.type = type;
4087        m.size = 1;
4088        m.index = index;
4089        m.data[0] = data;
4090
4091        atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4092}
4093
4094static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4095                            u16 data)
4096{
4097        struct get_set_mib m;
4098        m.type = type;
4099        m.size = 2;
4100        m.index = index;
4101        m.data[0] = data;
4102        m.data[1] = data >> 8;
4103
4104        atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4105}
4106
4107static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4108                          u8 *data, int data_len)
4109{
4110        struct get_set_mib m;
4111        m.type = type;
4112        m.size = data_len;
4113        m.index = index;
4114
4115        if (data_len > MIB_MAX_DATA_BYTES)
4116                printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4117
4118        memcpy(m.data, data, data_len);
4119        atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4120}
4121
4122static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4123                          u8 *data, int data_len)
4124{
4125        struct get_set_mib m;
4126        m.type = type;
4127        m.size = data_len;
4128        m.index = index;
4129
4130        if (data_len > MIB_MAX_DATA_BYTES)
4131                printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4132
4133        atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4134        atmel_copy_to_host(priv->dev, data,
4135                           atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4136}
4137
4138static void atmel_writeAR(struct net_device *dev, u16 data)
4139{
4140        int i;
4141        outw(data, dev->base_addr + AR);
4142        /* Address register appears to need some convincing..... */
4143        for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4144                outw(data, dev->base_addr + AR);
4145}
4146
4147static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4148                               const unsigned char *src, u16 len)
4149{
4150        int i;
4151        atmel_writeAR(dev, dest);
4152        if (dest % 2) {
4153                atmel_write8(dev, DR, *src);
4154                src++; len--;
4155        }
4156        for (i = len; i > 1 ; i -= 2) {
4157                u8 lb = *src++;
4158                u8 hb = *src++;
4159                atmel_write16(dev, DR, lb | (hb << 8));
4160        }
4161        if (i)
4162                atmel_write8(dev, DR, *src);
4163}
4164
4165static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4166                               u16 src, u16 len)
4167{
4168        int i;
4169        atmel_writeAR(dev, src);
4170        if (src % 2) {
4171                *dest = atmel_read8(dev, DR);
4172                dest++; len--;
4173        }
4174        for (i = len; i > 1 ; i -= 2) {
4175                u16 hw = atmel_read16(dev, DR);
4176                *dest++ = hw;
4177                *dest++ = hw >> 8;
4178        }
4179        if (i)
4180                *dest = atmel_read8(dev, DR);
4181}
4182
4183static void atmel_set_gcr(struct net_device *dev, u16 mask)
4184{
4185        outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4186}
4187
4188static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4189{
4190        outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4191}
4192
4193static int atmel_lock_mac(struct atmel_private *priv)
4194{
4195        int i, j = 20;
4196 retry:
4197        for (i = 5000; i; i--) {
4198                if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4199                        break;
4200                udelay(20);
4201        }
4202
4203        if (!i)
4204                return 0; /* timed out */
4205
4206        atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4207        if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4208                atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4209                if (!j--)
4210                        return 0; /* timed out */
4211                goto retry;
4212        }
4213
4214        return 1;
4215}
4216
4217static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4218{
4219        atmel_writeAR(priv->dev, pos);
4220        atmel_write16(priv->dev, DR, data); /* card is little-endian */
4221        atmel_write16(priv->dev, DR, data >> 16);
4222}
4223
4224/***************************************************************************/
4225/* There follows the source form of the MAC address reading firmware       */
4226/***************************************************************************/
4227#if 0
4228
4229/* Copyright 2003 Matthew T. Russotto                                      */
4230/* But derived from the Atmel 76C502 firmware written by Atmel and         */
4231/* included in "atmel wireless lan drivers" package                        */
4232/**
4233    This file is part of net.russotto.AtmelMACFW, hereto referred to
4234    as AtmelMACFW
4235
4236    AtmelMACFW is free software; you can redistribute it and/or modify
4237    it under the terms of the GNU General Public License version 2
4238    as published by the Free Software Foundation.
4239
4240    AtmelMACFW is distributed in the hope that it will be useful,
4241    but WITHOUT ANY WARRANTY; without even the implied warranty of
4242    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4243    GNU General Public License for more details.
4244
4245    You should have received a copy of the GNU General Public License
4246    along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4247
4248****************************************************************************/
4249/* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
4250/* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
4251/* It only works on SPI EEPROM versions of the card.                       */
4252
4253/* This firmware initializes the SPI controller and clock, reads the MAC   */
4254/* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
4255/* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
4256/* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
4257/* MR4, for investigational purposes (maybe we can determine chip type     */
4258/* from that?)                                                             */
4259
4260        .org 0
4261    .set MRBASE, 0x8000000
4262        .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4263        .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4264        .set SRAM_BASE,  0x02000000
4265        .set SP_BASE,    0x0F300000
4266        .set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
4267        .set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
4268        .set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
4269        .set STACK_BASE, 0x5600
4270        .set SP_SR, 0x10
4271        .set SP_TDRE, 2 /* status register bit -- TDR empty */
4272        .set SP_RDRF, 1 /* status register bit -- RDR full */
4273        .set SP_SWRST, 0x80
4274        .set SP_SPIEN, 0x1
4275        .set SP_CR, 0   /* control register */
4276        .set SP_MR, 4   /* mode register */
4277        .set SP_RDR, 0x08 /* Read Data Register */
4278        .set SP_TDR, 0x0C /* Transmit Data Register */
4279        .set SP_CSR0, 0x30 /* chip select registers */
4280        .set SP_CSR1, 0x34
4281        .set SP_CSR2, 0x38
4282        .set SP_CSR3, 0x3C
4283        .set NVRAM_CMD_RDSR, 5 /* read status register */
4284        .set NVRAM_CMD_READ, 3 /* read data */
4285        .set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
4286        .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4287                                  serial output, since SO is normally high.  But it
4288                                  does cause 8 clock cycles and thus 8 bits to be
4289                                  clocked in to the chip.  See Atmel's SPI
4290                                  controller (e.g. AT91M55800) timing and 4K
4291                                  SPI EEPROM manuals */
4292
4293        .set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
4294        .set NVRAM_IMAGE, 0x02000200
4295        .set NVRAM_LENGTH, 0x0200
4296        .set MAC_ADDRESS_MIB, SRAM_BASE
4297        .set MAC_ADDRESS_LENGTH, 6
4298        .set MAC_BOOT_FLAG, 0x10
4299        .set MR1, 0
4300        .set MR2, 4
4301        .set MR3, 8
4302        .set MR4, 0xC
4303RESET_VECTOR:
4304        b RESET_HANDLER
4305UNDEF_VECTOR:
4306        b HALT1
4307SWI_VECTOR:
4308        b HALT1
4309IABORT_VECTOR:
4310        b HALT1
4311DABORT_VECTOR:
4312RESERVED_VECTOR:
4313        b HALT1
4314IRQ_VECTOR:
4315        b HALT1
4316FIQ_VECTOR:
4317        b HALT1
4318HALT1:  b HALT1
4319RESET_HANDLER:
4320        mov     r0, #CPSR_INITIAL
4321        msr     CPSR_c, r0      /* This is probably unnecessary */
4322
4323/* I'm guessing this is initializing clock generator electronics for SPI */
4324        ldr     r0, =SPI_CGEN_BASE
4325        mov     r1, #0
4326        mov     r1, r1, lsl #3
4327        orr     r1, r1, #0
4328        str     r1, [r0]
4329        ldr     r1, [r0, #28]
4330        bic     r1, r1, #16
4331        str     r1, [r0, #28]
4332        mov     r1, #1
4333        str     r1, [r0, #8]
4334
4335        ldr     r0, =MRBASE
4336        mov     r1, #0
4337        strh    r1, [r0, #MR1]
4338        strh    r1, [r0, #MR2]
4339        strh    r1, [r0, #MR3]
4340        strh    r1, [r0, #MR4]
4341
4342        mov     sp, #STACK_BASE
4343        bl      SP_INIT
4344        mov     r0, #10
4345        bl      DELAY9
4346        bl      GET_MAC_ADDR
4347        bl      GET_WHOLE_NVRAM
4348        ldr     r0, =MRBASE
4349        ldr     r1, =MAC_ADDRESS_MIB
4350        strh    r1, [r0, #MR2]
4351        ldr     r1, =NVRAM_IMAGE
4352        strh    r1, [r0, #MR4]
4353        mov     r1, #MAC_BOOT_FLAG
4354        strh    r1, [r0, #MR3]
4355HALT2:  b HALT2
4356.func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4357GET_WHOLE_NVRAM:
4358        stmdb   sp!, {lr}
4359        mov     r2, #0 /* 0th bytes of NVRAM */
4360        mov     r3, #NVRAM_LENGTH
4361        mov     r1, #0          /* not used in routine */
4362        ldr     r0, =NVRAM_IMAGE
4363        bl      NVRAM_XFER
4364        ldmia   sp!, {lr}
4365        bx      lr
4366.endfunc
4367
4368.func Get_MAC_Addr, GET_MAC_ADDR
4369GET_MAC_ADDR:
4370        stmdb   sp!, {lr}
4371        mov     r2, #0x120      /* address of MAC Address within NVRAM */
4372        mov     r3, #MAC_ADDRESS_LENGTH
4373        mov     r1, #0          /* not used in routine */
4374        ldr     r0, =MAC_ADDRESS_MIB
4375        bl      NVRAM_XFER
4376        ldmia   sp!, {lr}
4377        bx      lr
4378.endfunc
4379.ltorg
4380.func Delay9, DELAY9
4381DELAY9:
4382        adds    r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
4383DELAYLOOP:
4384        beq     DELAY9_done
4385        subs    r0, r0, #1
4386        b       DELAYLOOP
4387DELAY9_done:
4388        bx      lr
4389.endfunc
4390
4391.func SP_Init, SP_INIT
4392SP_INIT:
4393        mov     r1, #SP_SWRST
4394        ldr     r0, =SP_BASE
4395        str     r1, [r0, #SP_CR] /* reset the SPI */
4396        mov     r1, #0
4397        str     r1, [r0, #SP_CR] /* release SPI from reset state */
4398        mov     r1, #SP_SPIEN
4399        str     r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4400        str     r1, [r0, #SP_CR] /* enable the SPI */
4401
4402/*  My guess would be this turns on the SPI clock */
4403        ldr     r3, =SPI_CGEN_BASE
4404        ldr     r1, [r3, #28]
4405        orr     r1, r1, #0x2000
4406        str     r1, [r3, #28]
4407
4408        ldr     r1, =0x2000c01
4409        str     r1, [r0, #SP_CSR0]
4410        ldr     r1, =0x2000201
4411        str     r1, [r0, #SP_CSR1]
4412        str     r1, [r0, #SP_CSR2]
4413        str     r1, [r0, #SP_CSR3]
4414        ldr     r1, [r0, #SP_SR]
4415        ldr     r0, [r0, #SP_RDR]
4416        bx      lr
4417.endfunc
4418.func NVRAM_Init, NVRAM_INIT
4419NVRAM_INIT:
4420        ldr     r1, =SP_BASE
4421        ldr     r0, [r1, #SP_RDR]
4422        mov     r0, #NVRAM_CMD_RDSR
4423        str     r0, [r1, #SP_TDR]
4424SP_loop1:
4425        ldr     r0, [r1, #SP_SR]
4426        tst     r0, #SP_TDRE
4427        beq     SP_loop1
4428
4429        mov     r0, #SPI_8CLOCKS
4430        str     r0, [r1, #SP_TDR]
4431SP_loop2:
4432        ldr     r0, [r1, #SP_SR]
4433        tst     r0, #SP_TDRE
4434        beq     SP_loop2
4435
4436        ldr     r0, [r1, #SP_RDR]
4437SP_loop3:
4438        ldr     r0, [r1, #SP_SR]
4439        tst     r0, #SP_RDRF
4440        beq     SP_loop3
4441
4442        ldr     r0, [r1, #SP_RDR]
4443        and     r0, r0, #255
4444        bx      lr
4445.endfunc
4446
4447.func NVRAM_Xfer, NVRAM_XFER
4448        /* r0 = dest address */
4449        /* r1 = not used */
4450        /* r2 = src address within NVRAM */
4451        /* r3 = length */
4452NVRAM_XFER:
4453        stmdb   sp!, {r4, r5, lr}
4454        mov     r5, r0          /* save r0 (dest address) */
4455        mov     r4, r3          /* save r3 (length) */
4456        mov     r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
4457        and     r0, r0, #8
4458        add     r0, r0, #NVRAM_CMD_READ
4459        ldr     r1, =NVRAM_SCRATCH
4460        strb    r0, [r1, #0]    /* save command in NVRAM_SCRATCH[0] */
4461        strb    r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
4462_local1:
4463        bl      NVRAM_INIT
4464        tst     r0, #NVRAM_SR_RDY
4465        bne     _local1
4466        mov     r0, #20
4467        bl      DELAY9
4468        mov     r2, r4          /* length */
4469        mov     r1, r5          /* dest address */
4470        mov     r0, #2          /* bytes to transfer in command */
4471        bl      NVRAM_XFER2
4472        ldmia   sp!, {r4, r5, lr}
4473        bx      lr
4474.endfunc
4475
4476.func NVRAM_Xfer2, NVRAM_XFER2
4477NVRAM_XFER2:
4478        stmdb   sp!, {r4, r5, r6, lr}
4479        ldr     r4, =SP_BASE
4480        mov     r3, #0
4481        cmp     r0, #0
4482        bls     _local2
4483        ldr     r5, =NVRAM_SCRATCH
4484_local4:
4485        ldrb    r6, [r5, r3]
4486        str     r6, [r4, #SP_TDR]
4487_local3:
4488        ldr     r6, [r4, #SP_SR]
4489        tst     r6, #SP_TDRE
4490        beq     _local3
4491        add     r3, r3, #1
4492        cmp     r3, r0 /* r0 is # of bytes to send out (command+addr) */
4493        blo     _local4
4494_local2:
4495        mov     r3, #SPI_8CLOCKS
4496        str     r3, [r4, #SP_TDR]
4497        ldr     r0, [r4, #SP_RDR]
4498_local5:
4499        ldr     r0, [r4, #SP_SR]
4500        tst     r0, #SP_RDRF
4501        beq     _local5
4502        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 */
4503        mov     r0, #0
4504        cmp     r2, #0  /* r2 is # of bytes to copy in */
4505        bls     _local6
4506_local7:
4507        ldr     r5, [r4, #SP_SR]
4508        tst     r5, #SP_TDRE
4509        beq     _local7
4510        str     r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
4511_local8:
4512        ldr     r5, [r4, #SP_SR]
4513        tst     r5, #SP_RDRF
4514        beq     _local8
4515        ldr     r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4516        strb    r5, [r1], #1 /* postindexed */
4517        add     r0, r0, #1
4518        cmp     r0, r2
4519        blo     _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4520_local6:
4521        mov     r0, #200
4522        bl      DELAY9
4523        ldmia   sp!, {r4, r5, r6, lr}
4524        bx      lr
4525#endif
4526