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