Back to home page

OSCL-LXR

 
 

    


0001 /*** -*- linux-c -*- **********************************************************
0002 
0003      Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
0004 
0005     Copyright 2000-2001 ATMEL Corporation.
0006     Copyright 2003-2004 Simon Kelley.
0007 
0008     This code was developed from version 2.1.1 of the Atmel drivers,
0009     released by Atmel corp. under the GPL in December 2002. It also
0010     includes code from the Linux aironet drivers (C) Benjamin Reed,
0011     and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
0012     extensions, (C) Jean Tourrilhes.
0013 
0014     The firmware module for reading the MAC address of the card comes from
0015     net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright
0016     by him. net.russotto.AtmelMACFW is used under the GPL license version 2.
0017     This file contains the module in binary form and, under the terms
0018     of the GPL, in source form. The source is located at the end of the file.
0019 
0020     This program is free software; you can redistribute it and/or modify
0021     it under the terms of the GNU General Public License as published by
0022     the Free Software Foundation; either version 2 of the License, or
0023     (at your option) any later version.
0024 
0025     This software is distributed in the hope that it will be useful,
0026     but WITHOUT ANY WARRANTY; without even the implied warranty of
0027     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0028     GNU General Public License for more details.
0029 
0030     You should have received a copy of the GNU General Public License
0031     along with Atmel wireless lan drivers; if not, see
0032     <http://www.gnu.org/licenses/>.
0033 
0034     For all queries about this code, please contact the current author,
0035     Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
0036 
0037     Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
0038     hardware used during development of this driver.
0039 
0040 ******************************************************************************/
0041 
0042 #include <linux/interrupt.h>
0043 
0044 #include <linux/kernel.h>
0045 #include <linux/ptrace.h>
0046 #include <linux/slab.h>
0047 #include <linux/string.h>
0048 #include <linux/timer.h>
0049 #include <asm/byteorder.h>
0050 #include <asm/io.h>
0051 #include <linux/uaccess.h>
0052 #include <linux/module.h>
0053 #include <linux/netdevice.h>
0054 #include <linux/etherdevice.h>
0055 #include <linux/skbuff.h>
0056 #include <linux/if_arp.h>
0057 #include <linux/ioport.h>
0058 #include <linux/fcntl.h>
0059 #include <linux/delay.h>
0060 #include <linux/wireless.h>
0061 #include <net/iw_handler.h>
0062 #include <linux/crc32.h>
0063 #include <linux/proc_fs.h>
0064 #include <linux/seq_file.h>
0065 #include <linux/device.h>
0066 #include <linux/moduleparam.h>
0067 #include <linux/firmware.h>
0068 #include <linux/jiffies.h>
0069 #include <net/cfg80211.h>
0070 #include "atmel.h"
0071 
0072 #define DRIVER_MAJOR 0
0073 #define DRIVER_MINOR 98
0074 
0075 MODULE_AUTHOR("Simon Kelley");
0076 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
0077 MODULE_LICENSE("GPL");
0078 
0079 /* The name of the firmware file to be loaded
0080    over-rides any automatic selection */
0081 static char *firmware = NULL;
0082 module_param(firmware, charp, 0);
0083 
0084 /* table of firmware file names */
0085 static struct {
0086     AtmelFWType fw_type;
0087     const char *fw_file;
0088     const char *fw_file_ext;
0089 } fw_table[] = {
0090     { ATMEL_FW_TYPE_502,        "atmel_at76c502",   "bin" },
0091     { ATMEL_FW_TYPE_502D,       "atmel_at76c502d",  "bin" },
0092     { ATMEL_FW_TYPE_502E,       "atmel_at76c502e",  "bin" },
0093     { ATMEL_FW_TYPE_502_3COM,   "atmel_at76c502_3com",  "bin" },
0094     { ATMEL_FW_TYPE_504,        "atmel_at76c504",   "bin" },
0095     { ATMEL_FW_TYPE_504_2958,   "atmel_at76c504_2958",  "bin" },
0096     { ATMEL_FW_TYPE_504A_2958,  "atmel_at76c504a_2958", "bin" },
0097     { ATMEL_FW_TYPE_506,        "atmel_at76c506",   "bin" },
0098     { ATMEL_FW_TYPE_NONE,       NULL,           NULL }
0099 };
0100 MODULE_FIRMWARE("atmel_at76c502-wpa.bin");
0101 MODULE_FIRMWARE("atmel_at76c502.bin");
0102 MODULE_FIRMWARE("atmel_at76c502d-wpa.bin");
0103 MODULE_FIRMWARE("atmel_at76c502d.bin");
0104 MODULE_FIRMWARE("atmel_at76c502e-wpa.bin");
0105 MODULE_FIRMWARE("atmel_at76c502e.bin");
0106 MODULE_FIRMWARE("atmel_at76c502_3com-wpa.bin");
0107 MODULE_FIRMWARE("atmel_at76c502_3com.bin");
0108 MODULE_FIRMWARE("atmel_at76c504-wpa.bin");
0109 MODULE_FIRMWARE("atmel_at76c504.bin");
0110 MODULE_FIRMWARE("atmel_at76c504_2958-wpa.bin");
0111 MODULE_FIRMWARE("atmel_at76c504_2958.bin");
0112 MODULE_FIRMWARE("atmel_at76c504a_2958-wpa.bin");
0113 MODULE_FIRMWARE("atmel_at76c504a_2958.bin");
0114 MODULE_FIRMWARE("atmel_at76c506-wpa.bin");
0115 MODULE_FIRMWARE("atmel_at76c506.bin");
0116 
0117 #define MAX_SSID_LENGTH 32
0118 #define MGMT_JIFFIES (256 * HZ / 100)
0119 
0120 #define MAX_BSS_ENTRIES 64
0121 
0122 /* registers */
0123 #define GCR  0x00    /* (SIR0)  General Configuration Register */
0124 #define BSR  0x02    /* (SIR1)  Bank Switching Select Register */
0125 #define AR   0x04
0126 #define DR   0x08
0127 #define MR1  0x12    /* Mirror Register 1 */
0128 #define MR2  0x14    /* Mirror Register 2 */
0129 #define MR3  0x16    /* Mirror Register 3 */
0130 #define MR4  0x18    /* Mirror Register 4 */
0131 
0132 #define GPR1                            0x0c
0133 #define GPR2                            0x0e
0134 #define GPR3                            0x10
0135 /*
0136  * Constants for the GCR register.
0137  */
0138 #define GCR_REMAP     0x0400          /* Remap internal SRAM to 0 */
0139 #define GCR_SWRES     0x0080          /* BIU reset (ARM and PAI are NOT reset) */
0140 #define GCR_CORES     0x0060          /* Core Reset (ARM and PAI are reset) */
0141 #define GCR_ENINT     0x0002          /* Enable Interrupts */
0142 #define GCR_ACKINT    0x0008          /* Acknowledge Interrupts */
0143 
0144 #define BSS_SRAM      0x0200          /* AMBA module selection --> SRAM */
0145 #define BSS_IRAM      0x0100          /* AMBA module selection --> IRAM */
0146 /*
0147  *Constants for the MR registers.
0148  */
0149 #define MAC_INIT_COMPLETE       0x0001        /* MAC init has been completed */
0150 #define MAC_BOOT_COMPLETE       0x0010        /* MAC boot has been completed */
0151 #define MAC_INIT_OK             0x0002        /* MAC boot has been completed */
0152 
0153 #define MIB_MAX_DATA_BYTES    212
0154 #define MIB_HEADER_SIZE       4    /* first four fields */
0155 
0156 struct get_set_mib {
0157     u8 type;
0158     u8 size;
0159     u8 index;
0160     u8 reserved;
0161     u8 data[MIB_MAX_DATA_BYTES];
0162 };
0163 
0164 struct rx_desc {
0165     u32          Next;
0166     u16          MsduPos;
0167     u16          MsduSize;
0168 
0169     u8           State;
0170     u8           Status;
0171     u8           Rate;
0172     u8           Rssi;
0173     u8           LinkQuality;
0174     u8           PreambleType;
0175     u16          Duration;
0176     u32          RxTime;
0177 };
0178 
0179 #define RX_DESC_FLAG_VALID       0x80
0180 #define RX_DESC_FLAG_CONSUMED    0x40
0181 #define RX_DESC_FLAG_IDLE        0x00
0182 
0183 #define RX_STATUS_SUCCESS        0x00
0184 
0185 #define RX_DESC_MSDU_POS_OFFSET      4
0186 #define RX_DESC_MSDU_SIZE_OFFSET     6
0187 #define RX_DESC_FLAGS_OFFSET         8
0188 #define RX_DESC_STATUS_OFFSET        9
0189 #define RX_DESC_RSSI_OFFSET          11
0190 #define RX_DESC_LINK_QUALITY_OFFSET  12
0191 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
0192 #define RX_DESC_DURATION_OFFSET      14
0193 #define RX_DESC_RX_TIME_OFFSET       16
0194 
0195 struct tx_desc {
0196     u32       NextDescriptor;
0197     u16       TxStartOfFrame;
0198     u16       TxLength;
0199 
0200     u8        TxState;
0201     u8        TxStatus;
0202     u8        RetryCount;
0203 
0204     u8        TxRate;
0205 
0206     u8        KeyIndex;
0207     u8        ChiperType;
0208     u8        ChipreLength;
0209     u8        Reserved1;
0210 
0211     u8        Reserved;
0212     u8        PacketType;
0213     u16       HostTxLength;
0214 };
0215 
0216 #define TX_DESC_NEXT_OFFSET          0
0217 #define TX_DESC_POS_OFFSET           4
0218 #define TX_DESC_SIZE_OFFSET          6
0219 #define TX_DESC_FLAGS_OFFSET         8
0220 #define TX_DESC_STATUS_OFFSET        9
0221 #define TX_DESC_RETRY_OFFSET         10
0222 #define TX_DESC_RATE_OFFSET          11
0223 #define TX_DESC_KEY_INDEX_OFFSET     12
0224 #define TX_DESC_CIPHER_TYPE_OFFSET   13
0225 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
0226 #define TX_DESC_PACKET_TYPE_OFFSET   17
0227 #define TX_DESC_HOST_LENGTH_OFFSET   18
0228 
0229 /*
0230  * Host-MAC interface
0231  */
0232 
0233 #define TX_STATUS_SUCCESS       0x00
0234 
0235 #define TX_FIRM_OWN             0x80
0236 #define TX_DONE                 0x40
0237 
0238 #define TX_ERROR                0x01
0239 
0240 #define TX_PACKET_TYPE_DATA     0x01
0241 #define TX_PACKET_TYPE_MGMT     0x02
0242 
0243 #define ISR_EMPTY               0x00        /* no bits set in ISR */
0244 #define ISR_TxCOMPLETE          0x01        /* packet transmitted */
0245 #define ISR_RxCOMPLETE          0x02        /* packet received */
0246 #define ISR_RxFRAMELOST         0x04        /* Rx Frame lost */
0247 #define ISR_FATAL_ERROR         0x08        /* Fatal error */
0248 #define ISR_COMMAND_COMPLETE    0x10        /* command completed */
0249 #define ISR_OUT_OF_RANGE        0x20        /* command completed */
0250 #define ISR_IBSS_MERGE          0x40        /* (4.1.2.30): IBSS merge */
0251 #define ISR_GENERIC_IRQ         0x80
0252 
0253 #define Local_Mib_Type          0x01
0254 #define Mac_Address_Mib_Type    0x02
0255 #define Mac_Mib_Type            0x03
0256 #define Statistics_Mib_Type     0x04
0257 #define Mac_Mgmt_Mib_Type       0x05
0258 #define Mac_Wep_Mib_Type        0x06
0259 #define Phy_Mib_Type            0x07
0260 #define Multi_Domain_MIB        0x08
0261 
0262 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
0263 #define MAC_MIB_FRAG_THRESHOLD_POS            8
0264 #define MAC_MIB_RTS_THRESHOLD_POS             10
0265 #define MAC_MIB_SHORT_RETRY_POS               16
0266 #define MAC_MIB_LONG_RETRY_POS                17
0267 #define MAC_MIB_SHORT_RETRY_LIMIT_POS         16
0268 #define MAC_MGMT_MIB_BEACON_PER_POS           0
0269 #define MAC_MGMT_MIB_STATION_ID_POS           6
0270 #define MAC_MGMT_MIB_CUR_PRIVACY_POS          11
0271 #define MAC_MGMT_MIB_CUR_BSSID_POS            14
0272 #define MAC_MGMT_MIB_PS_MODE_POS              53
0273 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS      54
0274 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
0275 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED     57
0276 #define PHY_MIB_CHANNEL_POS                   14
0277 #define PHY_MIB_RATE_SET_POS                  20
0278 #define PHY_MIB_REG_DOMAIN_POS                26
0279 #define LOCAL_MIB_AUTO_TX_RATE_POS            3
0280 #define LOCAL_MIB_SSID_SIZE                   5
0281 #define LOCAL_MIB_TX_PROMISCUOUS_POS          6
0282 #define LOCAL_MIB_TX_MGMT_RATE_POS            7
0283 #define LOCAL_MIB_TX_CONTROL_RATE_POS         8
0284 #define LOCAL_MIB_PREAMBLE_TYPE               9
0285 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
0286 
0287 #define         CMD_Set_MIB_Vars              0x01
0288 #define         CMD_Get_MIB_Vars              0x02
0289 #define         CMD_Scan                      0x03
0290 #define         CMD_Join                      0x04
0291 #define         CMD_Start                     0x05
0292 #define         CMD_EnableRadio               0x06
0293 #define         CMD_DisableRadio              0x07
0294 #define         CMD_SiteSurvey                0x0B
0295 
0296 #define         CMD_STATUS_IDLE                   0x00
0297 #define         CMD_STATUS_COMPLETE               0x01
0298 #define         CMD_STATUS_UNKNOWN                0x02
0299 #define         CMD_STATUS_INVALID_PARAMETER      0x03
0300 #define         CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
0301 #define         CMD_STATUS_TIME_OUT               0x07
0302 #define         CMD_STATUS_IN_PROGRESS            0x08
0303 #define         CMD_STATUS_REJECTED_RADIO_OFF     0x09
0304 #define         CMD_STATUS_HOST_ERROR             0xFF
0305 #define         CMD_STATUS_BUSY                   0xFE
0306 
0307 #define CMD_BLOCK_COMMAND_OFFSET        0
0308 #define CMD_BLOCK_STATUS_OFFSET         1
0309 #define CMD_BLOCK_PARAMETERS_OFFSET     4
0310 
0311 #define SCAN_OPTIONS_SITE_SURVEY        0x80
0312 
0313 #define MGMT_FRAME_BODY_OFFSET      24
0314 #define MAX_AUTHENTICATION_RETRIES  3
0315 #define MAX_ASSOCIATION_RETRIES     3
0316 
0317 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
0318 
0319 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
0320 #define LOOP_RETRY_LIMIT   500000
0321 
0322 #define ACTIVE_MODE 1
0323 #define PS_MODE     2
0324 
0325 #define MAX_ENCRYPTION_KEYS 4
0326 #define MAX_ENCRYPTION_KEY_SIZE 40
0327 
0328 /*
0329  * 802.11 related definitions
0330  */
0331 
0332 /*
0333  * Regulatory Domains
0334  */
0335 
0336 #define REG_DOMAIN_FCC      0x10    /* Channels 1-11    USA             */
0337 #define REG_DOMAIN_DOC      0x20    /* Channel  1-11    Canada              */
0338 #define REG_DOMAIN_ETSI     0x30    /* Channel  1-13    Europe (ex Spain/France)    */
0339 #define REG_DOMAIN_SPAIN    0x31    /* Channel  10-11   Spain               */
0340 #define REG_DOMAIN_FRANCE   0x32    /* Channel  10-13   France              */
0341 #define REG_DOMAIN_MKK      0x40    /* Channel  14  Japan               */
0342 #define REG_DOMAIN_MKK1     0x41    /* Channel  1-14    Japan(MKK1)         */
0343 #define REG_DOMAIN_ISRAEL   0x50    /* Channel  3-9 ISRAEL              */
0344 
0345 #define BSS_TYPE_AD_HOC     1
0346 #define BSS_TYPE_INFRASTRUCTURE 2
0347 
0348 #define SCAN_TYPE_ACTIVE    0
0349 #define SCAN_TYPE_PASSIVE   1
0350 
0351 #define LONG_PREAMBLE       0
0352 #define SHORT_PREAMBLE      1
0353 #define AUTO_PREAMBLE       2
0354 
0355 #define DATA_FRAME_WS_HEADER_SIZE   30
0356 
0357 /* promiscuous mode control */
0358 #define PROM_MODE_OFF           0x0
0359 #define PROM_MODE_UNKNOWN       0x1
0360 #define PROM_MODE_CRC_FAILED        0x2
0361 #define PROM_MODE_DUPLICATED        0x4
0362 #define PROM_MODE_MGMT          0x8
0363 #define PROM_MODE_CTRL          0x10
0364 #define PROM_MODE_BAD_PROTOCOL      0x20
0365 
0366 #define IFACE_INT_STATUS_OFFSET     0
0367 #define IFACE_INT_MASK_OFFSET       1
0368 #define IFACE_LOCKOUT_HOST_OFFSET   2
0369 #define IFACE_LOCKOUT_MAC_OFFSET    3
0370 #define IFACE_FUNC_CTRL_OFFSET      28
0371 #define IFACE_MAC_STAT_OFFSET       30
0372 #define IFACE_GENERIC_INT_TYPE_OFFSET   32
0373 
0374 #define CIPHER_SUITE_NONE     0
0375 #define CIPHER_SUITE_WEP_64   1
0376 #define CIPHER_SUITE_TKIP     2
0377 #define CIPHER_SUITE_AES      3
0378 #define CIPHER_SUITE_CCX      4
0379 #define CIPHER_SUITE_WEP_128  5
0380 
0381 /*
0382  * IFACE MACROS & definitions
0383  */
0384 
0385 /*
0386  * FuncCtrl field:
0387  */
0388 #define FUNC_CTRL_TxENABLE      0x10
0389 #define FUNC_CTRL_RxENABLE      0x20
0390 #define FUNC_CTRL_INIT_COMPLETE     0x01
0391 
0392 /* A stub firmware image which reads the MAC address from NVRAM on the card.
0393    For copyright information and source see the end of this file. */
0394 static u8 mac_reader[] = {
0395     0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
0396     0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
0397     0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0398     0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
0399     0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
0400     0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
0401     0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
0402     0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
0403     0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
0404     0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
0405     0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0406     0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
0407     0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
0408     0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
0409     0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
0410     0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
0411     0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
0412     0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
0413     0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
0414     0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
0415     0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
0416     0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
0417     0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
0418     0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
0419     0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
0420     0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
0421     0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
0422     0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
0423     0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
0424     0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
0425     0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
0426     0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
0427     0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
0428     0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
0429     0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
0430     0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
0431     0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
0432     0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
0433     0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
0434     0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
0435     0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
0436     0x00, 0x01, 0x00, 0x02
0437 };
0438 
0439 struct atmel_private {
0440     void *card; /* Bus dependent structure varies for PCcard */
0441     int (*present_callback)(void *); /* And callback which uses it */
0442     char firmware_id[32];
0443     AtmelFWType firmware_type;
0444     u8 *firmware;
0445     int firmware_length;
0446     struct timer_list management_timer;
0447     struct net_device *dev;
0448     struct device *sys_dev;
0449     struct iw_statistics wstats;
0450     spinlock_t irqlock, timerlock;  /* spinlocks */
0451     enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
0452     enum {
0453         CARD_TYPE_PARALLEL_FLASH,
0454         CARD_TYPE_SPI_FLASH,
0455         CARD_TYPE_EEPROM
0456     } card_type;
0457     int do_rx_crc; /* If we need to CRC incoming packets */
0458     int probe_crc; /* set if we don't yet know */
0459     int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
0460     u16 rx_desc_head;
0461     u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
0462     u16 tx_free_mem, tx_buff_head, tx_buff_tail;
0463 
0464     u16 frag_seq, frag_len, frag_no;
0465     u8 frag_source[6];
0466 
0467     u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
0468     u8 group_cipher_suite, pairwise_cipher_suite;
0469     u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
0470     int wep_key_len[MAX_ENCRYPTION_KEYS];
0471     int use_wpa, radio_on_broken; /* firmware dependent stuff. */
0472 
0473     u16 host_info_base;
0474     struct host_info_struct {
0475         /* NB this is matched to the hardware, don't change. */
0476         u8 volatile int_status;
0477         u8 volatile int_mask;
0478         u8 volatile lockout_host;
0479         u8 volatile lockout_mac;
0480 
0481         u16 tx_buff_pos;
0482         u16 tx_buff_size;
0483         u16 tx_desc_pos;
0484         u16 tx_desc_count;
0485 
0486         u16 rx_buff_pos;
0487         u16 rx_buff_size;
0488         u16 rx_desc_pos;
0489         u16 rx_desc_count;
0490 
0491         u16 build_version;
0492         u16 command_pos;
0493 
0494         u16 major_version;
0495         u16 minor_version;
0496 
0497         u16 func_ctrl;
0498         u16 mac_status;
0499         u16 generic_IRQ_type;
0500         u8  reserved[2];
0501     } host_info;
0502 
0503     enum {
0504         STATION_STATE_SCANNING,
0505         STATION_STATE_JOINNING,
0506         STATION_STATE_AUTHENTICATING,
0507         STATION_STATE_ASSOCIATING,
0508         STATION_STATE_READY,
0509         STATION_STATE_REASSOCIATING,
0510         STATION_STATE_DOWN,
0511         STATION_STATE_MGMT_ERROR
0512     } station_state;
0513 
0514     int operating_mode, power_mode;
0515     unsigned long last_qual;
0516     int beacons_this_sec;
0517     int channel;
0518     int reg_domain, config_reg_domain;
0519     int tx_rate;
0520     int auto_tx_rate;
0521     int rts_threshold;
0522     int frag_threshold;
0523     int long_retry, short_retry;
0524     int preamble;
0525     int default_beacon_period, beacon_period, listen_interval;
0526     int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
0527     int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
0528     enum {
0529         SITE_SURVEY_IDLE,
0530         SITE_SURVEY_IN_PROGRESS,
0531         SITE_SURVEY_COMPLETED
0532     } site_survey_state;
0533     unsigned long last_survey;
0534 
0535     int station_was_associated, station_is_associated;
0536     int fast_scan;
0537 
0538     struct bss_info {
0539         int channel;
0540         int SSIDsize;
0541         int RSSI;
0542         int UsingWEP;
0543         int preamble;
0544         int beacon_period;
0545         int BSStype;
0546         u8 BSSID[6];
0547         u8 SSID[MAX_SSID_LENGTH];
0548     } BSSinfo[MAX_BSS_ENTRIES];
0549     int BSS_list_entries, current_BSS;
0550     int connect_to_any_BSS;
0551     int SSID_size, new_SSID_size;
0552     u8 CurrentBSSID[6], BSSID[6];
0553     u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
0554     u64 last_beacon_timestamp;
0555     u8 rx_buf[MAX_WIRELESS_BODY];
0556 };
0557 
0558 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
0559 
0560 static const struct {
0561     int reg_domain;
0562     int min, max;
0563     char *name;
0564 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
0565               { REG_DOMAIN_DOC, 1, 11, "Canada" },
0566               { REG_DOMAIN_ETSI, 1, 13, "Europe" },
0567               { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
0568               { REG_DOMAIN_FRANCE, 10, 13, "France" },
0569               { REG_DOMAIN_MKK, 14, 14, "MKK" },
0570               { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
0571               { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
0572 
0573 static void build_wpa_mib(struct atmel_private *priv);
0574 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
0575 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
0576                    const unsigned char *src, u16 len);
0577 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
0578                    u16 src, u16 len);
0579 static void atmel_set_gcr(struct net_device *dev, u16 mask);
0580 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
0581 static int atmel_lock_mac(struct atmel_private *priv);
0582 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
0583 static void atmel_command_irq(struct atmel_private *priv);
0584 static int atmel_validate_channel(struct atmel_private *priv, int channel);
0585 static void atmel_management_frame(struct atmel_private *priv,
0586                    struct ieee80211_hdr *header,
0587                    u16 frame_len, u8 rssi);
0588 static void atmel_management_timer(struct timer_list *t);
0589 static void atmel_send_command(struct atmel_private *priv, int command,
0590                    void *cmd, int cmd_size);
0591 static int atmel_send_command_wait(struct atmel_private *priv, int command,
0592                    void *cmd, int cmd_size);
0593 static void atmel_transmit_management_frame(struct atmel_private *priv,
0594                         struct ieee80211_hdr *header,
0595                         u8 *body, int body_len);
0596 
0597 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
0598 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
0599                u8 data);
0600 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
0601                 u16 data);
0602 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
0603               const u8 *data, int data_len);
0604 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
0605               u8 *data, int data_len);
0606 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
0607 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
0608 static void atmel_smooth_qual(struct atmel_private *priv);
0609 static void atmel_writeAR(struct net_device *dev, u16 data);
0610 static int probe_atmel_card(struct net_device *dev);
0611 static int reset_atmel_card(struct net_device *dev);
0612 static void atmel_enter_state(struct atmel_private *priv, int new_state);
0613 int atmel_open (struct net_device *dev);
0614 
0615 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
0616 {
0617     return priv->host_info_base + offset;
0618 }
0619 
0620 static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
0621 {
0622     return priv->host_info.command_pos + offset;
0623 }
0624 
0625 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
0626 {
0627     return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
0628 }
0629 
0630 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
0631 {
0632     return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
0633 }
0634 
0635 static inline u8 atmel_read8(struct net_device *dev, u16 offset)
0636 {
0637     return inb(dev->base_addr + offset);
0638 }
0639 
0640 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
0641 {
0642     outb(data, dev->base_addr + offset);
0643 }
0644 
0645 static inline u16 atmel_read16(struct net_device *dev, u16 offset)
0646 {
0647     return inw(dev->base_addr + offset);
0648 }
0649 
0650 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
0651 {
0652     outw(data, dev->base_addr + offset);
0653 }
0654 
0655 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
0656 {
0657     atmel_writeAR(priv->dev, pos);
0658     return atmel_read8(priv->dev, DR);
0659 }
0660 
0661 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
0662 {
0663     atmel_writeAR(priv->dev, pos);
0664     atmel_write8(priv->dev, DR, data);
0665 }
0666 
0667 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
0668 {
0669     atmel_writeAR(priv->dev, pos);
0670     return atmel_read16(priv->dev, DR);
0671 }
0672 
0673 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
0674 {
0675     atmel_writeAR(priv->dev, pos);
0676     atmel_write16(priv->dev, DR, data);
0677 }
0678 
0679 static const struct iw_handler_def atmel_handler_def;
0680 
0681 static void tx_done_irq(struct atmel_private *priv)
0682 {
0683     int i;
0684 
0685     for (i = 0;
0686          atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
0687              i < priv->host_info.tx_desc_count;
0688          i++) {
0689         u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
0690         u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
0691         u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
0692 
0693         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
0694 
0695         priv->tx_free_mem += msdu_size;
0696         priv->tx_desc_free++;
0697 
0698         if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
0699             priv->tx_buff_head = 0;
0700         else
0701             priv->tx_buff_head += msdu_size;
0702 
0703         if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
0704             priv->tx_desc_head++ ;
0705         else
0706             priv->tx_desc_head = 0;
0707 
0708         if (type == TX_PACKET_TYPE_DATA) {
0709             if (status == TX_STATUS_SUCCESS)
0710                 priv->dev->stats.tx_packets++;
0711             else
0712                 priv->dev->stats.tx_errors++;
0713             netif_wake_queue(priv->dev);
0714         }
0715     }
0716 }
0717 
0718 static u16 find_tx_buff(struct atmel_private *priv, u16 len)
0719 {
0720     u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
0721 
0722     if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
0723         return 0;
0724 
0725     if (bottom_free >= len)
0726         return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
0727 
0728     if (priv->tx_free_mem - bottom_free >= len) {
0729         priv->tx_buff_tail = 0;
0730         return priv->host_info.tx_buff_pos;
0731     }
0732 
0733     return 0;
0734 }
0735 
0736 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
0737                  u16 len, u16 buff, u8 type)
0738 {
0739     atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
0740     atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
0741     if (!priv->use_wpa)
0742         atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
0743     atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
0744     atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
0745     atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
0746     if (priv->use_wpa) {
0747         int cipher_type, cipher_length;
0748         if (is_bcast) {
0749             cipher_type = priv->group_cipher_suite;
0750             if (cipher_type == CIPHER_SUITE_WEP_64 ||
0751                 cipher_type == CIPHER_SUITE_WEP_128)
0752                 cipher_length = 8;
0753             else if (cipher_type == CIPHER_SUITE_TKIP)
0754                 cipher_length = 12;
0755             else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
0756                  priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
0757                 cipher_type = priv->pairwise_cipher_suite;
0758                 cipher_length = 8;
0759             } else {
0760                 cipher_type = CIPHER_SUITE_NONE;
0761                 cipher_length = 0;
0762             }
0763         } else {
0764             cipher_type = priv->pairwise_cipher_suite;
0765             if (cipher_type == CIPHER_SUITE_WEP_64 ||
0766                 cipher_type == CIPHER_SUITE_WEP_128)
0767                 cipher_length = 8;
0768             else if (cipher_type == CIPHER_SUITE_TKIP)
0769                 cipher_length = 12;
0770             else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
0771                  priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
0772                 cipher_type = priv->group_cipher_suite;
0773                 cipher_length = 8;
0774             } else {
0775                 cipher_type = CIPHER_SUITE_NONE;
0776                 cipher_length = 0;
0777             }
0778         }
0779 
0780         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
0781                 cipher_type);
0782         atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
0783                 cipher_length);
0784     }
0785     atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
0786     atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
0787     if (priv->tx_desc_previous != priv->tx_desc_tail)
0788         atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
0789     priv->tx_desc_previous = priv->tx_desc_tail;
0790     if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
0791         priv->tx_desc_tail++;
0792     else
0793         priv->tx_desc_tail = 0;
0794     priv->tx_desc_free--;
0795     priv->tx_free_mem -= len;
0796 }
0797 
0798 static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
0799 {
0800     struct atmel_private *priv = netdev_priv(dev);
0801     struct ieee80211_hdr header;
0802     unsigned long flags;
0803     u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
0804 
0805     if (priv->card && priv->present_callback &&
0806         !(*priv->present_callback)(priv->card)) {
0807         dev->stats.tx_errors++;
0808         dev_kfree_skb(skb);
0809         return NETDEV_TX_OK;
0810     }
0811 
0812     if (priv->station_state != STATION_STATE_READY) {
0813         dev->stats.tx_errors++;
0814         dev_kfree_skb(skb);
0815         return NETDEV_TX_OK;
0816     }
0817 
0818     /* first ensure the timer func cannot run */
0819     spin_lock_bh(&priv->timerlock);
0820     /* then stop the hardware ISR */
0821     spin_lock_irqsave(&priv->irqlock, flags);
0822     /* nb doing the above in the opposite order will deadlock */
0823 
0824     /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
0825        12 first bytes (containing DA/SA) and put them in the appropriate
0826        fields of the Wireless Header. Thus the packet length is then the
0827        initial + 18 (+30-12) */
0828 
0829     if (!(buff = find_tx_buff(priv, len + 18))) {
0830         dev->stats.tx_dropped++;
0831         spin_unlock_irqrestore(&priv->irqlock, flags);
0832         spin_unlock_bh(&priv->timerlock);
0833         netif_stop_queue(dev);
0834         return NETDEV_TX_BUSY;
0835     }
0836 
0837     frame_ctl = IEEE80211_FTYPE_DATA;
0838     header.duration_id = 0;
0839     header.seq_ctrl = 0;
0840     if (priv->wep_is_on)
0841         frame_ctl |= IEEE80211_FCTL_PROTECTED;
0842     if (priv->operating_mode == IW_MODE_ADHOC) {
0843         skb_copy_from_linear_data(skb, &header.addr1, ETH_ALEN);
0844         memcpy(&header.addr2, dev->dev_addr, ETH_ALEN);
0845         memcpy(&header.addr3, priv->BSSID, ETH_ALEN);
0846     } else {
0847         frame_ctl |= IEEE80211_FCTL_TODS;
0848         memcpy(&header.addr1, priv->CurrentBSSID, ETH_ALEN);
0849         memcpy(&header.addr2, dev->dev_addr, ETH_ALEN);
0850         skb_copy_from_linear_data(skb, &header.addr3, ETH_ALEN);
0851     }
0852 
0853     if (priv->use_wpa)
0854         memcpy(&header.addr4, rfc1042_header, ETH_ALEN);
0855 
0856     header.frame_control = cpu_to_le16(frame_ctl);
0857     /* Copy the wireless header into the card */
0858     atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
0859     /* Copy the packet sans its 802.3 header addresses which have been replaced */
0860     atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
0861     priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
0862 
0863     /* low bit of first byte of destination tells us if broadcast */
0864     tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
0865     dev->stats.tx_bytes += len;
0866 
0867     spin_unlock_irqrestore(&priv->irqlock, flags);
0868     spin_unlock_bh(&priv->timerlock);
0869     dev_kfree_skb(skb);
0870 
0871     return NETDEV_TX_OK;
0872 }
0873 
0874 static void atmel_transmit_management_frame(struct atmel_private *priv,
0875                         struct ieee80211_hdr *header,
0876                         u8 *body, int body_len)
0877 {
0878     u16 buff;
0879     int len = MGMT_FRAME_BODY_OFFSET + body_len;
0880 
0881     if (!(buff = find_tx_buff(priv, len)))
0882         return;
0883 
0884     atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
0885     atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
0886     priv->tx_buff_tail += len;
0887     tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
0888 }
0889 
0890 static void fast_rx_path(struct atmel_private *priv,
0891              struct ieee80211_hdr *header,
0892              u16 msdu_size, u16 rx_packet_loc, u32 crc)
0893 {
0894     /* fast path: unfragmented packet copy directly into skbuf */
0895     u8 mac4[6];
0896     struct sk_buff  *skb;
0897     unsigned char *skbp;
0898 
0899     /* get the final, mac 4 header field, this tells us encapsulation */
0900     atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
0901     msdu_size -= 6;
0902 
0903     if (priv->do_rx_crc) {
0904         crc = crc32_le(crc, mac4, 6);
0905         msdu_size -= 4;
0906     }
0907 
0908     if (!(skb = dev_alloc_skb(msdu_size + 14))) {
0909         priv->dev->stats.rx_dropped++;
0910         return;
0911     }
0912 
0913     skb_reserve(skb, 2);
0914     skbp = skb_put(skb, msdu_size + 12);
0915     atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
0916 
0917     if (priv->do_rx_crc) {
0918         u32 netcrc;
0919         crc = crc32_le(crc, skbp + 12, msdu_size);
0920         atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
0921         if ((crc ^ 0xffffffff) != netcrc) {
0922             priv->dev->stats.rx_crc_errors++;
0923             dev_kfree_skb(skb);
0924             return;
0925         }
0926     }
0927 
0928     memcpy(skbp, header->addr1, ETH_ALEN); /* destination address */
0929     if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
0930         memcpy(&skbp[ETH_ALEN], header->addr3, ETH_ALEN);
0931     else
0932         memcpy(&skbp[ETH_ALEN], header->addr2, ETH_ALEN); /* source address */
0933 
0934     skb->protocol = eth_type_trans(skb, priv->dev);
0935     skb->ip_summed = CHECKSUM_NONE;
0936     netif_rx(skb);
0937     priv->dev->stats.rx_bytes += 12 + msdu_size;
0938     priv->dev->stats.rx_packets++;
0939 }
0940 
0941 /* Test to see if the packet in card memory at packet_loc has a valid CRC
0942    It doesn't matter that this is slow: it is only used to proble the first few
0943    packets. */
0944 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
0945 {
0946     int i = msdu_size - 4;
0947     u32 netcrc, crc = 0xffffffff;
0948 
0949     if (msdu_size < 4)
0950         return 0;
0951 
0952     atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
0953 
0954     atmel_writeAR(priv->dev, packet_loc);
0955     while (i--) {
0956         u8 octet = atmel_read8(priv->dev, DR);
0957         crc = crc32_le(crc, &octet, 1);
0958     }
0959 
0960     return (crc ^ 0xffffffff) == netcrc;
0961 }
0962 
0963 static void frag_rx_path(struct atmel_private *priv,
0964              struct ieee80211_hdr *header,
0965              u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
0966              u8 frag_no, int more_frags)
0967 {
0968     u8 mac4[ETH_ALEN];
0969     u8 source[ETH_ALEN];
0970     struct sk_buff *skb;
0971 
0972     if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
0973         memcpy(source, header->addr3, ETH_ALEN);
0974     else
0975         memcpy(source, header->addr2, ETH_ALEN);
0976 
0977     rx_packet_loc += 24; /* skip header */
0978 
0979     if (priv->do_rx_crc)
0980         msdu_size -= 4;
0981 
0982     if (frag_no == 0) { /* first fragment */
0983         atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, ETH_ALEN);
0984         msdu_size -= ETH_ALEN;
0985         rx_packet_loc += ETH_ALEN;
0986 
0987         if (priv->do_rx_crc)
0988             crc = crc32_le(crc, mac4, 6);
0989 
0990         priv->frag_seq = seq_no;
0991         priv->frag_no = 1;
0992         priv->frag_len = msdu_size;
0993         memcpy(priv->frag_source, source, ETH_ALEN);
0994         memcpy(&priv->rx_buf[ETH_ALEN], source, ETH_ALEN);
0995         memcpy(priv->rx_buf, header->addr1, ETH_ALEN);
0996 
0997         atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
0998 
0999         if (priv->do_rx_crc) {
1000             u32 netcrc;
1001             crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
1002             atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1003             if ((crc ^ 0xffffffff) != netcrc) {
1004                 priv->dev->stats.rx_crc_errors++;
1005                 eth_broadcast_addr(priv->frag_source);
1006             }
1007         }
1008 
1009     } else if (priv->frag_no == frag_no &&
1010            priv->frag_seq == seq_no &&
1011            memcmp(priv->frag_source, source, ETH_ALEN) == 0) {
1012 
1013         atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1014                    rx_packet_loc, msdu_size);
1015         if (priv->do_rx_crc) {
1016             u32 netcrc;
1017             crc = crc32_le(crc,
1018                        &priv->rx_buf[12 + priv->frag_len],
1019                        msdu_size);
1020             atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1021             if ((crc ^ 0xffffffff) != netcrc) {
1022                 priv->dev->stats.rx_crc_errors++;
1023                 eth_broadcast_addr(priv->frag_source);
1024                 more_frags = 1; /* don't send broken assembly */
1025             }
1026         }
1027 
1028         priv->frag_len += msdu_size;
1029         priv->frag_no++;
1030 
1031         if (!more_frags) { /* last one */
1032             eth_broadcast_addr(priv->frag_source);
1033             if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1034                 priv->dev->stats.rx_dropped++;
1035             } else {
1036                 skb_reserve(skb, 2);
1037                 skb_put_data(skb, priv->rx_buf,
1038                              priv->frag_len + 12);
1039                 skb->protocol = eth_type_trans(skb, priv->dev);
1040                 skb->ip_summed = CHECKSUM_NONE;
1041                 netif_rx(skb);
1042                 priv->dev->stats.rx_bytes += priv->frag_len + 12;
1043                 priv->dev->stats.rx_packets++;
1044             }
1045         }
1046     } else
1047         priv->wstats.discard.fragment++;
1048 }
1049 
1050 static void rx_done_irq(struct atmel_private *priv)
1051 {
1052     int i;
1053     struct ieee80211_hdr header;
1054 
1055     for (i = 0;
1056          atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1057              i < priv->host_info.rx_desc_count;
1058          i++) {
1059 
1060         u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1061         u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1062         u32 crc = 0xffffffff;
1063 
1064         if (status != RX_STATUS_SUCCESS) {
1065             if (status == 0xc1) /* determined by experiment */
1066                 priv->wstats.discard.nwid++;
1067             else
1068                 priv->dev->stats.rx_errors++;
1069             goto next;
1070         }
1071 
1072         msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1073         rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1074 
1075         if (msdu_size < 30) {
1076             priv->dev->stats.rx_errors++;
1077             goto next;
1078         }
1079 
1080         /* Get header as far as end of seq_ctrl */
1081         atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1082         frame_ctl = le16_to_cpu(header.frame_control);
1083         seq_control = le16_to_cpu(header.seq_ctrl);
1084 
1085         /* probe for CRC use here if needed  once five packets have
1086            arrived with the same crc status, we assume we know what's
1087            happening and stop probing */
1088         if (priv->probe_crc) {
1089             if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1090                 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1091             } else {
1092                 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1093             }
1094             if (priv->do_rx_crc) {
1095                 if (priv->crc_ok_cnt++ > 5)
1096                     priv->probe_crc = 0;
1097             } else {
1098                 if (priv->crc_ko_cnt++ > 5)
1099                     priv->probe_crc = 0;
1100             }
1101         }
1102 
1103         /* don't CRC header when WEP in use */
1104         if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1105             crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1106         }
1107         msdu_size -= 24; /* header */
1108 
1109         if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1110             int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1111             u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1112             u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1113 
1114             if (!more_fragments && packet_fragment_no == 0) {
1115                 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1116             } else {
1117                 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1118                          packet_sequence_no, packet_fragment_no, more_fragments);
1119             }
1120         }
1121 
1122         if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1123             /* copy rest of packet into buffer */
1124             atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1125 
1126             /* we use the same buffer for frag reassembly and control packets */
1127             eth_broadcast_addr(priv->frag_source);
1128 
1129             if (priv->do_rx_crc) {
1130                 /* last 4 octets is crc */
1131                 msdu_size -= 4;
1132                 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1133                 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1134                     priv->dev->stats.rx_crc_errors++;
1135                     goto next;
1136                 }
1137             }
1138 
1139             atmel_management_frame(priv, &header, msdu_size,
1140                            atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1141         }
1142 
1143 next:
1144         /* release descriptor */
1145         atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1146 
1147         if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1148             priv->rx_desc_head++;
1149         else
1150             priv->rx_desc_head = 0;
1151     }
1152 }
1153 
1154 static irqreturn_t service_interrupt(int irq, void *dev_id)
1155 {
1156     struct net_device *dev = (struct net_device *) dev_id;
1157     struct atmel_private *priv = netdev_priv(dev);
1158     u8 isr;
1159     int i = -1;
1160     static const u8 irq_order[] = {
1161         ISR_OUT_OF_RANGE,
1162         ISR_RxCOMPLETE,
1163         ISR_TxCOMPLETE,
1164         ISR_RxFRAMELOST,
1165         ISR_FATAL_ERROR,
1166         ISR_COMMAND_COMPLETE,
1167         ISR_IBSS_MERGE,
1168         ISR_GENERIC_IRQ
1169     };
1170 
1171     if (priv->card && priv->present_callback &&
1172         !(*priv->present_callback)(priv->card))
1173         return IRQ_HANDLED;
1174 
1175     /* In this state upper-level code assumes it can mess with
1176        the card unhampered by interrupts which may change register state.
1177        Note that even though the card shouldn't generate interrupts
1178        the inturrupt line may be shared. This allows card setup
1179        to go on without disabling interrupts for a long time. */
1180     if (priv->station_state == STATION_STATE_DOWN)
1181         return IRQ_NONE;
1182 
1183     atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1184 
1185     while (1) {
1186         if (!atmel_lock_mac(priv)) {
1187             /* failed to contact card */
1188             printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1189             return IRQ_HANDLED;
1190         }
1191 
1192         isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1193         atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1194 
1195         if (!isr) {
1196             atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1197             return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1198         }
1199 
1200         atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1201 
1202         for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1203             if (isr & irq_order[i])
1204                 break;
1205 
1206         if (!atmel_lock_mac(priv)) {
1207             /* failed to contact card */
1208             printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1209             return IRQ_HANDLED;
1210         }
1211 
1212         isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1213         isr ^= irq_order[i];
1214         atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1215         atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1216 
1217         switch (irq_order[i]) {
1218 
1219         case ISR_OUT_OF_RANGE:
1220             if (priv->operating_mode == IW_MODE_INFRA &&
1221                 priv->station_state == STATION_STATE_READY) {
1222                 priv->station_is_associated = 0;
1223                 atmel_scan(priv, 1);
1224             }
1225             break;
1226 
1227         case ISR_RxFRAMELOST:
1228             priv->wstats.discard.misc++;
1229             fallthrough;
1230         case ISR_RxCOMPLETE:
1231             rx_done_irq(priv);
1232             break;
1233 
1234         case ISR_TxCOMPLETE:
1235             tx_done_irq(priv);
1236             break;
1237 
1238         case ISR_FATAL_ERROR:
1239             printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1240             atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1241             break;
1242 
1243         case ISR_COMMAND_COMPLETE:
1244             atmel_command_irq(priv);
1245             break;
1246 
1247         case ISR_IBSS_MERGE:
1248             atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1249                       priv->CurrentBSSID, 6);
1250             /* The WPA stuff cares about the current AP address */
1251             if (priv->use_wpa)
1252                 build_wpa_mib(priv);
1253             break;
1254         case ISR_GENERIC_IRQ:
1255             printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1256             break;
1257         }
1258     }
1259 }
1260 
1261 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1262 {
1263     struct atmel_private *priv = netdev_priv(dev);
1264 
1265     /* update the link quality here in case we are seeing no beacons
1266        at all to drive the process */
1267     atmel_smooth_qual(priv);
1268 
1269     priv->wstats.status = priv->station_state;
1270 
1271     if (priv->operating_mode == IW_MODE_INFRA) {
1272         if (priv->station_state != STATION_STATE_READY) {
1273             priv->wstats.qual.qual = 0;
1274             priv->wstats.qual.level = 0;
1275             priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1276                     | IW_QUAL_LEVEL_INVALID);
1277         }
1278         priv->wstats.qual.noise = 0;
1279         priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1280     } else {
1281         /* Quality levels cannot be determined in ad-hoc mode,
1282            because we can 'hear' more that one remote station. */
1283         priv->wstats.qual.qual = 0;
1284         priv->wstats.qual.level = 0;
1285         priv->wstats.qual.noise = 0;
1286         priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1287                     | IW_QUAL_LEVEL_INVALID
1288                     | IW_QUAL_NOISE_INVALID;
1289         priv->wstats.miss.beacon = 0;
1290     }
1291 
1292     return &priv->wstats;
1293 }
1294 
1295 static int atmel_set_mac_address(struct net_device *dev, void *p)
1296 {
1297     struct sockaddr *addr = p;
1298 
1299     eth_hw_addr_set(dev, addr->sa_data);
1300     return atmel_open(dev);
1301 }
1302 
1303 EXPORT_SYMBOL(atmel_open);
1304 
1305 int atmel_open(struct net_device *dev)
1306 {
1307     struct atmel_private *priv = netdev_priv(dev);
1308     int i, channel, err;
1309 
1310     /* any scheduled timer is no longer needed and might screw things up.. */
1311     del_timer_sync(&priv->management_timer);
1312 
1313     /* Interrupts will not touch the card once in this state... */
1314     priv->station_state = STATION_STATE_DOWN;
1315 
1316     if (priv->new_SSID_size) {
1317         memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1318         priv->SSID_size = priv->new_SSID_size;
1319         priv->new_SSID_size = 0;
1320     }
1321     priv->BSS_list_entries = 0;
1322 
1323     priv->AuthenticationRequestRetryCnt = 0;
1324     priv->AssociationRequestRetryCnt = 0;
1325     priv->ReAssociationRequestRetryCnt = 0;
1326     priv->CurrentAuthentTransactionSeqNum = 0x0001;
1327     priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1328 
1329     priv->site_survey_state = SITE_SURVEY_IDLE;
1330     priv->station_is_associated = 0;
1331 
1332     err = reset_atmel_card(dev);
1333     if (err)
1334         return err;
1335 
1336     if (priv->config_reg_domain) {
1337         priv->reg_domain = priv->config_reg_domain;
1338         atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1339     } else {
1340         priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1341         for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1342             if (priv->reg_domain == channel_table[i].reg_domain)
1343                 break;
1344         if (i == ARRAY_SIZE(channel_table)) {
1345             priv->reg_domain = REG_DOMAIN_MKK1;
1346             printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1347         }
1348     }
1349 
1350     if ((channel = atmel_validate_channel(priv, priv->channel)))
1351         priv->channel = channel;
1352 
1353     /* this moves station_state on.... */
1354     atmel_scan(priv, 1);
1355 
1356     atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1357     return 0;
1358 }
1359 
1360 static int atmel_close(struct net_device *dev)
1361 {
1362     struct atmel_private *priv = netdev_priv(dev);
1363 
1364     /* Send event to userspace that we are disassociating */
1365     if (priv->station_state == STATION_STATE_READY) {
1366         union iwreq_data wrqu;
1367 
1368         wrqu.data.length = 0;
1369         wrqu.data.flags = 0;
1370         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1371         eth_zero_addr(wrqu.ap_addr.sa_data);
1372         wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1373     }
1374 
1375     atmel_enter_state(priv, STATION_STATE_DOWN);
1376 
1377     if (priv->bus_type == BUS_TYPE_PCCARD)
1378         atmel_write16(dev, GCR, 0x0060);
1379     atmel_write16(dev, GCR, 0x0040);
1380     return 0;
1381 }
1382 
1383 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1384 {
1385     /* check that channel is OK, if so return zero,
1386        else return suitable default channel */
1387     int i;
1388 
1389     for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1390         if (priv->reg_domain == channel_table[i].reg_domain) {
1391             if (channel >= channel_table[i].min &&
1392                 channel <= channel_table[i].max)
1393                 return 0;
1394             else
1395                 return channel_table[i].min;
1396         }
1397     return 0;
1398 }
1399 
1400 #ifdef CONFIG_PROC_FS
1401 static int atmel_proc_show(struct seq_file *m, void *v)
1402 {
1403     struct atmel_private *priv = m->private;
1404     int i;
1405     char *s, *r, *c;
1406 
1407     seq_printf(m, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1408 
1409     if (priv->station_state != STATION_STATE_DOWN) {
1410         seq_printf(m,
1411                "Firmware version:\t%d.%d build %d\n"
1412                "Firmware location:\t",
1413                priv->host_info.major_version,
1414                priv->host_info.minor_version,
1415                priv->host_info.build_version);
1416 
1417         if (priv->card_type != CARD_TYPE_EEPROM)
1418             seq_puts(m, "on card\n");
1419         else if (priv->firmware)
1420             seq_printf(m, "%s loaded by host\n", priv->firmware_id);
1421         else
1422             seq_printf(m, "%s loaded by hotplug\n", priv->firmware_id);
1423 
1424         switch (priv->card_type) {
1425         case CARD_TYPE_PARALLEL_FLASH:
1426             c = "Parallel flash";
1427             break;
1428         case CARD_TYPE_SPI_FLASH:
1429             c = "SPI flash\n";
1430             break;
1431         case CARD_TYPE_EEPROM:
1432             c = "EEPROM";
1433             break;
1434         default:
1435             c = "<unknown>";
1436         }
1437 
1438         r = "<unknown>";
1439         for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1440             if (priv->reg_domain == channel_table[i].reg_domain)
1441                 r = channel_table[i].name;
1442 
1443         seq_printf(m, "MAC memory type:\t%s\n", c);
1444         seq_printf(m, "Regulatory domain:\t%s\n", r);
1445         seq_printf(m, "Host CRC checking:\t%s\n",
1446              priv->do_rx_crc ? "On" : "Off");
1447         seq_printf(m, "WPA-capable firmware:\t%s\n",
1448              priv->use_wpa ? "Yes" : "No");
1449     }
1450 
1451     switch (priv->station_state) {
1452     case STATION_STATE_SCANNING:
1453         s = "Scanning";
1454         break;
1455     case STATION_STATE_JOINNING:
1456         s = "Joining";
1457         break;
1458     case STATION_STATE_AUTHENTICATING:
1459         s = "Authenticating";
1460         break;
1461     case STATION_STATE_ASSOCIATING:
1462         s = "Associating";
1463         break;
1464     case STATION_STATE_READY:
1465         s = "Ready";
1466         break;
1467     case STATION_STATE_REASSOCIATING:
1468         s = "Reassociating";
1469         break;
1470     case STATION_STATE_MGMT_ERROR:
1471         s = "Management error";
1472         break;
1473     case STATION_STATE_DOWN:
1474         s = "Down";
1475         break;
1476     default:
1477         s = "<unknown>";
1478     }
1479 
1480     seq_printf(m, "Current state:\t\t%s\n", s);
1481     return 0;
1482 }
1483 #endif
1484 
1485 static const struct net_device_ops atmel_netdev_ops = {
1486     .ndo_open       = atmel_open,
1487     .ndo_stop       = atmel_close,
1488     .ndo_set_mac_address    = atmel_set_mac_address,
1489     .ndo_start_xmit     = start_tx,
1490     .ndo_do_ioctl       = atmel_ioctl,
1491     .ndo_validate_addr  = eth_validate_addr,
1492 };
1493 
1494 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1495                    const AtmelFWType fw_type,
1496                    struct device *sys_dev,
1497                    int (*card_present)(void *), void *card)
1498 {
1499     struct net_device *dev;
1500     struct atmel_private *priv;
1501     int rc;
1502 
1503     /* Create the network device object. */
1504     dev = alloc_etherdev(sizeof(*priv));
1505     if (!dev)
1506         return NULL;
1507 
1508     if (dev_alloc_name(dev, dev->name) < 0) {
1509         printk(KERN_ERR "atmel: Couldn't get name!\n");
1510         goto err_out_free;
1511     }
1512 
1513     priv = netdev_priv(dev);
1514     priv->dev = dev;
1515     priv->sys_dev = sys_dev;
1516     priv->present_callback = card_present;
1517     priv->card = card;
1518     priv->firmware = NULL;
1519     priv->firmware_type = fw_type;
1520     if (firmware) /* module parameter */
1521         strlcpy(priv->firmware_id, firmware, sizeof(priv->firmware_id));
1522     priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1523     priv->station_state = STATION_STATE_DOWN;
1524     priv->do_rx_crc = 0;
1525     /* For PCMCIA cards, some chips need CRC, some don't
1526        so we have to probe. */
1527     if (priv->bus_type == BUS_TYPE_PCCARD) {
1528         priv->probe_crc = 1;
1529         priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1530     } else
1531         priv->probe_crc = 0;
1532     priv->last_qual = jiffies;
1533     priv->last_beacon_timestamp = 0;
1534     memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1535     eth_zero_addr(priv->BSSID);
1536     priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1537     priv->station_was_associated = 0;
1538 
1539     priv->last_survey = jiffies;
1540     priv->preamble = LONG_PREAMBLE;
1541     priv->operating_mode = IW_MODE_INFRA;
1542     priv->connect_to_any_BSS = 0;
1543     priv->config_reg_domain = 0;
1544     priv->reg_domain = 0;
1545     priv->tx_rate = 3;
1546     priv->auto_tx_rate = 1;
1547     priv->channel = 4;
1548     priv->power_mode = 0;
1549     priv->SSID[0] = '\0';
1550     priv->SSID_size = 0;
1551     priv->new_SSID_size = 0;
1552     priv->frag_threshold = 2346;
1553     priv->rts_threshold = 2347;
1554     priv->short_retry = 7;
1555     priv->long_retry = 4;
1556 
1557     priv->wep_is_on = 0;
1558     priv->default_key = 0;
1559     priv->encryption_level = 0;
1560     priv->exclude_unencrypted = 0;
1561     priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1562     priv->use_wpa = 0;
1563     memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1564     memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1565 
1566     priv->default_beacon_period = priv->beacon_period = 100;
1567     priv->listen_interval = 1;
1568 
1569     timer_setup(&priv->management_timer, atmel_management_timer, 0);
1570     spin_lock_init(&priv->irqlock);
1571     spin_lock_init(&priv->timerlock);
1572 
1573     dev->netdev_ops = &atmel_netdev_ops;
1574     dev->wireless_handlers = &atmel_handler_def;
1575     dev->irq = irq;
1576     dev->base_addr = port;
1577 
1578     /* MTU range: 68 - 2312 */
1579     dev->min_mtu = 68;
1580     dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
1581 
1582     SET_NETDEV_DEV(dev, sys_dev);
1583 
1584     if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1585         printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1586         goto err_out_free;
1587     }
1588 
1589     if (!request_region(dev->base_addr, 32,
1590                 priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
1591         goto err_out_irq;
1592     }
1593 
1594     if (register_netdev(dev))
1595         goto err_out_res;
1596 
1597     if (!probe_atmel_card(dev)) {
1598         unregister_netdev(dev);
1599         goto err_out_res;
1600     }
1601 
1602     netif_carrier_off(dev);
1603 
1604     if (!proc_create_single_data("driver/atmel", 0, NULL, atmel_proc_show,
1605             priv))
1606         printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1607 
1608     printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1609            dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1610 
1611     return dev;
1612 
1613 err_out_res:
1614     release_region(dev->base_addr, 32);
1615 err_out_irq:
1616     free_irq(dev->irq, dev);
1617 err_out_free:
1618     free_netdev(dev);
1619     return NULL;
1620 }
1621 
1622 EXPORT_SYMBOL(init_atmel_card);
1623 
1624 void stop_atmel_card(struct net_device *dev)
1625 {
1626     struct atmel_private *priv = netdev_priv(dev);
1627 
1628     /* put a brick on it... */
1629     if (priv->bus_type == BUS_TYPE_PCCARD)
1630         atmel_write16(dev, GCR, 0x0060);
1631     atmel_write16(dev, GCR, 0x0040);
1632 
1633     del_timer_sync(&priv->management_timer);
1634     unregister_netdev(dev);
1635     remove_proc_entry("driver/atmel", NULL);
1636     free_irq(dev->irq, dev);
1637     kfree(priv->firmware);
1638     release_region(dev->base_addr, 32);
1639     free_netdev(dev);
1640 }
1641 
1642 EXPORT_SYMBOL(stop_atmel_card);
1643 
1644 static int atmel_set_essid(struct net_device *dev,
1645                struct iw_request_info *info,
1646                struct iw_point *dwrq,
1647                char *extra)
1648 {
1649     struct atmel_private *priv = netdev_priv(dev);
1650 
1651     /* Check if we asked for `any' */
1652     if (dwrq->flags == 0) {
1653         priv->connect_to_any_BSS = 1;
1654     } else {
1655         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1656 
1657         priv->connect_to_any_BSS = 0;
1658 
1659         /* Check the size of the string */
1660         if (dwrq->length > MAX_SSID_LENGTH)
1661              return -E2BIG;
1662         if (index != 0)
1663             return -EINVAL;
1664 
1665         memcpy(priv->new_SSID, extra, dwrq->length);
1666         priv->new_SSID_size = dwrq->length;
1667     }
1668 
1669     return -EINPROGRESS;
1670 }
1671 
1672 static int atmel_get_essid(struct net_device *dev,
1673                struct iw_request_info *info,
1674                struct iw_point *dwrq,
1675                char *extra)
1676 {
1677     struct atmel_private *priv = netdev_priv(dev);
1678 
1679     /* Get the current SSID */
1680     if (priv->new_SSID_size != 0) {
1681         memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1682         dwrq->length = priv->new_SSID_size;
1683     } else {
1684         memcpy(extra, priv->SSID, priv->SSID_size);
1685         dwrq->length = priv->SSID_size;
1686     }
1687 
1688     dwrq->flags = !priv->connect_to_any_BSS; /* active */
1689 
1690     return 0;
1691 }
1692 
1693 static int atmel_get_wap(struct net_device *dev,
1694              struct iw_request_info *info,
1695              struct sockaddr *awrq,
1696              char *extra)
1697 {
1698     struct atmel_private *priv = netdev_priv(dev);
1699     memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN);
1700     awrq->sa_family = ARPHRD_ETHER;
1701 
1702     return 0;
1703 }
1704 
1705 static int atmel_set_encode(struct net_device *dev,
1706                 struct iw_request_info *info,
1707                 struct iw_point *dwrq,
1708                 char *extra)
1709 {
1710     struct atmel_private *priv = netdev_priv(dev);
1711 
1712     /* Basic checking: do we have a key to set ?
1713      * Note : with the new API, it's impossible to get a NULL pointer.
1714      * Therefore, we need to check a key size == 0 instead.
1715      * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1716      * when no key is present (only change flags), but older versions
1717      * don't do it. - Jean II */
1718     if (dwrq->length > 0) {
1719         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1720         int current_index = priv->default_key;
1721         /* Check the size of the key */
1722         if (dwrq->length > 13) {
1723             return -EINVAL;
1724         }
1725         /* Check the index (none -> use current) */
1726         if (index < 0 || index >= 4)
1727             index = current_index;
1728         else
1729             priv->default_key = index;
1730         /* Set the length */
1731         if (dwrq->length > 5)
1732             priv->wep_key_len[index] = 13;
1733         else
1734             if (dwrq->length > 0)
1735                 priv->wep_key_len[index] = 5;
1736             else
1737                 /* Disable the key */
1738                 priv->wep_key_len[index] = 0;
1739         /* Check if the key is not marked as invalid */
1740         if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1741             /* Cleanup */
1742             memset(priv->wep_keys[index], 0, 13);
1743             /* Copy the key in the driver */
1744             memcpy(priv->wep_keys[index], extra, dwrq->length);
1745         }
1746         /* WE specify that if a valid key is set, encryption
1747          * should be enabled (user may turn it off later)
1748          * This is also how "iwconfig ethX key on" works */
1749         if (index == current_index &&
1750             priv->wep_key_len[index] > 0) {
1751             priv->wep_is_on = 1;
1752             priv->exclude_unencrypted = 1;
1753             if (priv->wep_key_len[index] > 5) {
1754                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1755                 priv->encryption_level = 2;
1756             } else {
1757                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1758                 priv->encryption_level = 1;
1759             }
1760         }
1761     } else {
1762         /* Do we want to just set the transmit key index ? */
1763         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1764         if (index >= 0 && index < 4) {
1765             priv->default_key = index;
1766         } else
1767             /* Don't complain if only change the mode */
1768             if (!(dwrq->flags & IW_ENCODE_MODE))
1769                 return -EINVAL;
1770     }
1771     /* Read the flags */
1772     if (dwrq->flags & IW_ENCODE_DISABLED) {
1773         priv->wep_is_on = 0;
1774         priv->encryption_level = 0;
1775         priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1776     } else {
1777         priv->wep_is_on = 1;
1778         if (priv->wep_key_len[priv->default_key] > 5) {
1779             priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1780             priv->encryption_level = 2;
1781         } else {
1782             priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1783             priv->encryption_level = 1;
1784         }
1785     }
1786     if (dwrq->flags & IW_ENCODE_RESTRICTED)
1787         priv->exclude_unencrypted = 1;
1788     if (dwrq->flags & IW_ENCODE_OPEN)
1789         priv->exclude_unencrypted = 0;
1790 
1791     return -EINPROGRESS;        /* Call commit handler */
1792 }
1793 
1794 static int atmel_get_encode(struct net_device *dev,
1795                 struct iw_request_info *info,
1796                 struct iw_point *dwrq,
1797                 char *extra)
1798 {
1799     struct atmel_private *priv = netdev_priv(dev);
1800     int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1801 
1802     if (!priv->wep_is_on)
1803         dwrq->flags = IW_ENCODE_DISABLED;
1804     else {
1805         if (priv->exclude_unencrypted)
1806             dwrq->flags = IW_ENCODE_RESTRICTED;
1807         else
1808             dwrq->flags = IW_ENCODE_OPEN;
1809     }
1810         /* Which key do we want ? -1 -> tx index */
1811     if (index < 0 || index >= 4)
1812         index = priv->default_key;
1813     dwrq->flags |= index + 1;
1814     /* Copy the key to the user buffer */
1815     dwrq->length = priv->wep_key_len[index];
1816     if (dwrq->length > 16) {
1817         dwrq->length = 0;
1818     } else {
1819         memset(extra, 0, 16);
1820         memcpy(extra, priv->wep_keys[index], dwrq->length);
1821     }
1822 
1823     return 0;
1824 }
1825 
1826 static int atmel_set_encodeext(struct net_device *dev,
1827                 struct iw_request_info *info,
1828                 union iwreq_data *wrqu,
1829                 char *extra)
1830 {
1831     struct atmel_private *priv = netdev_priv(dev);
1832     struct iw_point *encoding = &wrqu->encoding;
1833     struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1834     int idx, key_len, alg = ext->alg, set_key = 1;
1835 
1836     /* Determine and validate the key index */
1837     idx = encoding->flags & IW_ENCODE_INDEX;
1838     if (idx) {
1839         if (idx < 1 || idx > 4)
1840             return -EINVAL;
1841         idx--;
1842     } else
1843         idx = priv->default_key;
1844 
1845     if (encoding->flags & IW_ENCODE_DISABLED)
1846         alg = IW_ENCODE_ALG_NONE;
1847 
1848     if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1849         priv->default_key = idx;
1850         set_key = ext->key_len > 0 ? 1 : 0;
1851     }
1852 
1853     if (set_key) {
1854         /* Set the requested key first */
1855         switch (alg) {
1856         case IW_ENCODE_ALG_NONE:
1857             priv->wep_is_on = 0;
1858             priv->encryption_level = 0;
1859             priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1860             break;
1861         case IW_ENCODE_ALG_WEP:
1862             if (ext->key_len > 5) {
1863                 priv->wep_key_len[idx] = 13;
1864                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1865                 priv->encryption_level = 2;
1866             } else if (ext->key_len > 0) {
1867                 priv->wep_key_len[idx] = 5;
1868                 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1869                 priv->encryption_level = 1;
1870             } else {
1871                 return -EINVAL;
1872             }
1873             priv->wep_is_on = 1;
1874             memset(priv->wep_keys[idx], 0, 13);
1875             key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1876             memcpy(priv->wep_keys[idx], ext->key, key_len);
1877             break;
1878         default:
1879             return -EINVAL;
1880         }
1881     }
1882 
1883     return -EINPROGRESS;
1884 }
1885 
1886 static int atmel_get_encodeext(struct net_device *dev,
1887                 struct iw_request_info *info,
1888                 union iwreq_data *wrqu,
1889                 char *extra)
1890 {
1891     struct atmel_private *priv = netdev_priv(dev);
1892     struct iw_point *encoding = &wrqu->encoding;
1893     struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1894     int idx, max_key_len;
1895 
1896     max_key_len = encoding->length - sizeof(*ext);
1897     if (max_key_len < 0)
1898         return -EINVAL;
1899 
1900     idx = encoding->flags & IW_ENCODE_INDEX;
1901     if (idx) {
1902         if (idx < 1 || idx > 4)
1903             return -EINVAL;
1904         idx--;
1905     } else
1906         idx = priv->default_key;
1907 
1908     encoding->flags = idx + 1;
1909     memset(ext, 0, sizeof(*ext));
1910 
1911     if (!priv->wep_is_on) {
1912         ext->alg = IW_ENCODE_ALG_NONE;
1913         ext->key_len = 0;
1914         encoding->flags |= IW_ENCODE_DISABLED;
1915     } else {
1916         if (priv->encryption_level > 0)
1917             ext->alg = IW_ENCODE_ALG_WEP;
1918         else
1919             return -EINVAL;
1920 
1921         ext->key_len = priv->wep_key_len[idx];
1922         memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1923         encoding->flags |= IW_ENCODE_ENABLED;
1924     }
1925 
1926     return 0;
1927 }
1928 
1929 static int atmel_set_auth(struct net_device *dev,
1930                    struct iw_request_info *info,
1931                    union iwreq_data *wrqu, char *extra)
1932 {
1933     struct atmel_private *priv = netdev_priv(dev);
1934     struct iw_param *param = &wrqu->param;
1935 
1936     switch (param->flags & IW_AUTH_INDEX) {
1937     case IW_AUTH_WPA_VERSION:
1938     case IW_AUTH_CIPHER_PAIRWISE:
1939     case IW_AUTH_CIPHER_GROUP:
1940     case IW_AUTH_KEY_MGMT:
1941     case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1942     case IW_AUTH_PRIVACY_INVOKED:
1943         /*
1944          * atmel does not use these parameters
1945          */
1946         break;
1947 
1948     case IW_AUTH_DROP_UNENCRYPTED:
1949         priv->exclude_unencrypted = param->value ? 1 : 0;
1950         break;
1951 
1952     case IW_AUTH_80211_AUTH_ALG: {
1953             if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1954                 priv->exclude_unencrypted = 1;
1955             } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1956                 priv->exclude_unencrypted = 0;
1957             } else
1958                 return -EINVAL;
1959             break;
1960         }
1961 
1962     case IW_AUTH_WPA_ENABLED:
1963         /* Silently accept disable of WPA */
1964         if (param->value > 0)
1965             return -EOPNOTSUPP;
1966         break;
1967 
1968     default:
1969         return -EOPNOTSUPP;
1970     }
1971     return -EINPROGRESS;
1972 }
1973 
1974 static int atmel_get_auth(struct net_device *dev,
1975                    struct iw_request_info *info,
1976                    union iwreq_data *wrqu, char *extra)
1977 {
1978     struct atmel_private *priv = netdev_priv(dev);
1979     struct iw_param *param = &wrqu->param;
1980 
1981     switch (param->flags & IW_AUTH_INDEX) {
1982     case IW_AUTH_DROP_UNENCRYPTED:
1983         param->value = priv->exclude_unencrypted;
1984         break;
1985 
1986     case IW_AUTH_80211_AUTH_ALG:
1987         if (priv->exclude_unencrypted == 1)
1988             param->value = IW_AUTH_ALG_SHARED_KEY;
1989         else
1990             param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1991         break;
1992 
1993     case IW_AUTH_WPA_ENABLED:
1994         param->value = 0;
1995         break;
1996 
1997     default:
1998         return -EOPNOTSUPP;
1999     }
2000     return 0;
2001 }
2002 
2003 
2004 static int atmel_get_name(struct net_device *dev,
2005               struct iw_request_info *info,
2006               char *cwrq,
2007               char *extra)
2008 {
2009     strcpy(cwrq, "IEEE 802.11-DS");
2010     return 0;
2011 }
2012 
2013 static int atmel_set_rate(struct net_device *dev,
2014               struct iw_request_info *info,
2015               struct iw_param *vwrq,
2016               char *extra)
2017 {
2018     struct atmel_private *priv = netdev_priv(dev);
2019 
2020     if (vwrq->fixed == 0) {
2021         priv->tx_rate = 3;
2022         priv->auto_tx_rate = 1;
2023     } else {
2024         priv->auto_tx_rate = 0;
2025 
2026         /* Which type of value ? */
2027         if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2028             /* Setting by rate index */
2029             priv->tx_rate = vwrq->value;
2030         } else {
2031         /* Setting by frequency value */
2032             switch (vwrq->value) {
2033             case  1000000:
2034                 priv->tx_rate = 0;
2035                 break;
2036             case  2000000:
2037                 priv->tx_rate = 1;
2038                 break;
2039             case  5500000:
2040                 priv->tx_rate = 2;
2041                 break;
2042             case 11000000:
2043                 priv->tx_rate = 3;
2044                 break;
2045             default:
2046                 return -EINVAL;
2047             }
2048         }
2049     }
2050 
2051     return -EINPROGRESS;
2052 }
2053 
2054 static int atmel_set_mode(struct net_device *dev,
2055               struct iw_request_info *info,
2056               __u32 *uwrq,
2057               char *extra)
2058 {
2059     struct atmel_private *priv = netdev_priv(dev);
2060 
2061     if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2062         return -EINVAL;
2063 
2064     priv->operating_mode = *uwrq;
2065     return -EINPROGRESS;
2066 }
2067 
2068 static int atmel_get_mode(struct net_device *dev,
2069               struct iw_request_info *info,
2070               __u32 *uwrq,
2071               char *extra)
2072 {
2073     struct atmel_private *priv = netdev_priv(dev);
2074 
2075     *uwrq = priv->operating_mode;
2076     return 0;
2077 }
2078 
2079 static int atmel_get_rate(struct net_device *dev,
2080              struct iw_request_info *info,
2081              struct iw_param *vwrq,
2082              char *extra)
2083 {
2084     struct atmel_private *priv = netdev_priv(dev);
2085 
2086     if (priv->auto_tx_rate) {
2087         vwrq->fixed = 0;
2088         vwrq->value = 11000000;
2089     } else {
2090         vwrq->fixed = 1;
2091         switch (priv->tx_rate) {
2092         case 0:
2093             vwrq->value =  1000000;
2094             break;
2095         case 1:
2096             vwrq->value =  2000000;
2097             break;
2098         case 2:
2099             vwrq->value =  5500000;
2100             break;
2101         case 3:
2102             vwrq->value = 11000000;
2103             break;
2104         }
2105     }
2106     return 0;
2107 }
2108 
2109 static int atmel_set_power(struct net_device *dev,
2110                struct iw_request_info *info,
2111                struct iw_param *vwrq,
2112                char *extra)
2113 {
2114     struct atmel_private *priv = netdev_priv(dev);
2115     priv->power_mode = vwrq->disabled ? 0 : 1;
2116     return -EINPROGRESS;
2117 }
2118 
2119 static int atmel_get_power(struct net_device *dev,
2120                struct iw_request_info *info,
2121                struct iw_param *vwrq,
2122                char *extra)
2123 {
2124     struct atmel_private *priv = netdev_priv(dev);
2125     vwrq->disabled = priv->power_mode ? 0 : 1;
2126     vwrq->flags = IW_POWER_ON;
2127     return 0;
2128 }
2129 
2130 static int atmel_set_retry(struct net_device *dev,
2131                struct iw_request_info *info,
2132                struct iw_param *vwrq,
2133                char *extra)
2134 {
2135     struct atmel_private *priv = netdev_priv(dev);
2136 
2137     if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2138         if (vwrq->flags & IW_RETRY_LONG)
2139             priv->long_retry = vwrq->value;
2140         else if (vwrq->flags & IW_RETRY_SHORT)
2141             priv->short_retry = vwrq->value;
2142         else {
2143             /* No modifier : set both */
2144             priv->long_retry = vwrq->value;
2145             priv->short_retry = vwrq->value;
2146         }
2147         return -EINPROGRESS;
2148     }
2149 
2150     return -EINVAL;
2151 }
2152 
2153 static int atmel_get_retry(struct net_device *dev,
2154                struct iw_request_info *info,
2155                struct iw_param *vwrq,
2156                char *extra)
2157 {
2158     struct atmel_private *priv = netdev_priv(dev);
2159 
2160     vwrq->disabled = 0;      /* Can't be disabled */
2161 
2162     /* Note : by default, display the short retry number */
2163     if (vwrq->flags & IW_RETRY_LONG) {
2164         vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2165         vwrq->value = priv->long_retry;
2166     } else {
2167         vwrq->flags = IW_RETRY_LIMIT;
2168         vwrq->value = priv->short_retry;
2169         if (priv->long_retry != priv->short_retry)
2170             vwrq->flags |= IW_RETRY_SHORT;
2171     }
2172 
2173     return 0;
2174 }
2175 
2176 static int atmel_set_rts(struct net_device *dev,
2177              struct iw_request_info *info,
2178              struct iw_param *vwrq,
2179              char *extra)
2180 {
2181     struct atmel_private *priv = netdev_priv(dev);
2182     int rthr = vwrq->value;
2183 
2184     if (vwrq->disabled)
2185         rthr = 2347;
2186     if ((rthr < 0) || (rthr > 2347)) {
2187         return -EINVAL;
2188     }
2189     priv->rts_threshold = rthr;
2190 
2191     return -EINPROGRESS;        /* Call commit handler */
2192 }
2193 
2194 static int atmel_get_rts(struct net_device *dev,
2195              struct iw_request_info *info,
2196              struct iw_param *vwrq,
2197              char *extra)
2198 {
2199     struct atmel_private *priv = netdev_priv(dev);
2200 
2201     vwrq->value = priv->rts_threshold;
2202     vwrq->disabled = (vwrq->value >= 2347);
2203     vwrq->fixed = 1;
2204 
2205     return 0;
2206 }
2207 
2208 static int atmel_set_frag(struct net_device *dev,
2209               struct iw_request_info *info,
2210               struct iw_param *vwrq,
2211               char *extra)
2212 {
2213     struct atmel_private *priv = netdev_priv(dev);
2214     int fthr = vwrq->value;
2215 
2216     if (vwrq->disabled)
2217         fthr = 2346;
2218     if ((fthr < 256) || (fthr > 2346)) {
2219         return -EINVAL;
2220     }
2221     fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
2222     priv->frag_threshold = fthr;
2223 
2224     return -EINPROGRESS;        /* Call commit handler */
2225 }
2226 
2227 static int atmel_get_frag(struct net_device *dev,
2228               struct iw_request_info *info,
2229               struct iw_param *vwrq,
2230               char *extra)
2231 {
2232     struct atmel_private *priv = netdev_priv(dev);
2233 
2234     vwrq->value = priv->frag_threshold;
2235     vwrq->disabled = (vwrq->value >= 2346);
2236     vwrq->fixed = 1;
2237 
2238     return 0;
2239 }
2240 
2241 static int atmel_set_freq(struct net_device *dev,
2242               struct iw_request_info *info,
2243               struct iw_freq *fwrq,
2244               char *extra)
2245 {
2246     struct atmel_private *priv = netdev_priv(dev);
2247     int rc = -EINPROGRESS;      /* Call commit handler */
2248 
2249     /* If setting by frequency, convert to a channel */
2250     if (fwrq->e == 1) {
2251         int f = fwrq->m / 100000;
2252 
2253         /* Hack to fall through... */
2254         fwrq->e = 0;
2255         fwrq->m = ieee80211_frequency_to_channel(f);
2256     }
2257     /* Setting by channel number */
2258     if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
2259         rc = -EOPNOTSUPP;
2260     else {
2261         int channel = fwrq->m;
2262         if (atmel_validate_channel(priv, channel) == 0) {
2263             priv->channel = channel;
2264         } else {
2265             rc = -EINVAL;
2266         }
2267     }
2268     return rc;
2269 }
2270 
2271 static int atmel_get_freq(struct net_device *dev,
2272               struct iw_request_info *info,
2273               struct iw_freq *fwrq,
2274               char *extra)
2275 {
2276     struct atmel_private *priv = netdev_priv(dev);
2277 
2278     fwrq->m = priv->channel;
2279     fwrq->e = 0;
2280     return 0;
2281 }
2282 
2283 static int atmel_set_scan(struct net_device *dev,
2284               struct iw_request_info *info,
2285               struct iw_point *dwrq,
2286               char *extra)
2287 {
2288     struct atmel_private *priv = netdev_priv(dev);
2289     unsigned long flags;
2290 
2291     /* Note : you may have realised that, as this is a SET operation,
2292      * this is privileged and therefore a normal user can't
2293      * perform scanning.
2294      * This is not an error, while the device perform scanning,
2295      * traffic doesn't flow, so it's a perfect DoS...
2296      * Jean II */
2297 
2298     if (priv->station_state == STATION_STATE_DOWN)
2299         return -EAGAIN;
2300 
2301     /* Timeout old surveys. */
2302     if (time_after(jiffies, priv->last_survey + 20 * HZ))
2303         priv->site_survey_state = SITE_SURVEY_IDLE;
2304     priv->last_survey = jiffies;
2305 
2306     /* Initiate a scan command */
2307     if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2308         return -EBUSY;
2309 
2310     del_timer_sync(&priv->management_timer);
2311     spin_lock_irqsave(&priv->irqlock, flags);
2312 
2313     priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2314     priv->fast_scan = 0;
2315     atmel_scan(priv, 0);
2316     spin_unlock_irqrestore(&priv->irqlock, flags);
2317 
2318     return 0;
2319 }
2320 
2321 static int atmel_get_scan(struct net_device *dev,
2322               struct iw_request_info *info,
2323               struct iw_point *dwrq,
2324               char *extra)
2325 {
2326     struct atmel_private *priv = netdev_priv(dev);
2327     int i;
2328     char *current_ev = extra;
2329     struct iw_event iwe;
2330 
2331     if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2332         return -EAGAIN;
2333 
2334     for (i = 0; i < priv->BSS_list_entries; i++) {
2335         iwe.cmd = SIOCGIWAP;
2336         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2337         memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN);
2338         current_ev = iwe_stream_add_event(info, current_ev,
2339                           extra + IW_SCAN_MAX_DATA,
2340                           &iwe, IW_EV_ADDR_LEN);
2341 
2342         iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
2343         if (iwe.u.data.length > 32)
2344             iwe.u.data.length = 32;
2345         iwe.cmd = SIOCGIWESSID;
2346         iwe.u.data.flags = 1;
2347         current_ev = iwe_stream_add_point(info, current_ev,
2348                           extra + IW_SCAN_MAX_DATA,
2349                           &iwe, priv->BSSinfo[i].SSID);
2350 
2351         iwe.cmd = SIOCGIWMODE;
2352         iwe.u.mode = priv->BSSinfo[i].BSStype;
2353         current_ev = iwe_stream_add_event(info, current_ev,
2354                           extra + IW_SCAN_MAX_DATA,
2355                           &iwe, IW_EV_UINT_LEN);
2356 
2357         iwe.cmd = SIOCGIWFREQ;
2358         iwe.u.freq.m = priv->BSSinfo[i].channel;
2359         iwe.u.freq.e = 0;
2360         current_ev = iwe_stream_add_event(info, current_ev,
2361                           extra + IW_SCAN_MAX_DATA,
2362                           &iwe, IW_EV_FREQ_LEN);
2363 
2364         /* Add quality statistics */
2365         iwe.cmd = IWEVQUAL;
2366         iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2367         iwe.u.qual.qual  = iwe.u.qual.level;
2368         /* iwe.u.qual.noise  = SOMETHING */
2369         current_ev = iwe_stream_add_event(info, current_ev,
2370                           extra + IW_SCAN_MAX_DATA,
2371                           &iwe, IW_EV_QUAL_LEN);
2372 
2373 
2374         iwe.cmd = SIOCGIWENCODE;
2375         if (priv->BSSinfo[i].UsingWEP)
2376             iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2377         else
2378             iwe.u.data.flags = IW_ENCODE_DISABLED;
2379         iwe.u.data.length = 0;
2380         current_ev = iwe_stream_add_point(info, current_ev,
2381                           extra + IW_SCAN_MAX_DATA,
2382                           &iwe, NULL);
2383     }
2384 
2385     /* Length of data */
2386     dwrq->length = (current_ev - extra);
2387     dwrq->flags = 0;
2388 
2389     return 0;
2390 }
2391 
2392 static int atmel_get_range(struct net_device *dev,
2393                struct iw_request_info *info,
2394                struct iw_point *dwrq,
2395                char *extra)
2396 {
2397     struct atmel_private *priv = netdev_priv(dev);
2398     struct iw_range *range = (struct iw_range *) extra;
2399     int k, i, j;
2400 
2401     dwrq->length = sizeof(struct iw_range);
2402     memset(range, 0, sizeof(struct iw_range));
2403     range->min_nwid = 0x0000;
2404     range->max_nwid = 0x0000;
2405     range->num_channels = 0;
2406     for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2407         if (priv->reg_domain == channel_table[j].reg_domain) {
2408             range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2409             break;
2410         }
2411     if (range->num_channels != 0) {
2412         for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2413             range->freq[k].i = i; /* List index */
2414 
2415             /* Values in MHz -> * 10^5 * 10 */
2416             range->freq[k].m = 100000 *
2417              ieee80211_channel_to_frequency(i, NL80211_BAND_2GHZ);
2418             range->freq[k++].e = 1;
2419         }
2420         range->num_frequency = k;
2421     }
2422 
2423     range->max_qual.qual = 100;
2424     range->max_qual.level = 100;
2425     range->max_qual.noise = 0;
2426     range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2427 
2428     range->avg_qual.qual = 50;
2429     range->avg_qual.level = 50;
2430     range->avg_qual.noise = 0;
2431     range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2432 
2433     range->sensitivity = 0;
2434 
2435     range->bitrate[0] =  1000000;
2436     range->bitrate[1] =  2000000;
2437     range->bitrate[2] =  5500000;
2438     range->bitrate[3] = 11000000;
2439     range->num_bitrates = 4;
2440 
2441     range->min_rts = 0;
2442     range->max_rts = 2347;
2443     range->min_frag = 256;
2444     range->max_frag = 2346;
2445 
2446     range->encoding_size[0] = 5;
2447     range->encoding_size[1] = 13;
2448     range->num_encoding_sizes = 2;
2449     range->max_encoding_tokens = 4;
2450 
2451     range->pmp_flags = IW_POWER_ON;
2452     range->pmt_flags = IW_POWER_ON;
2453     range->pm_capa = 0;
2454 
2455     range->we_version_source = WIRELESS_EXT;
2456     range->we_version_compiled = WIRELESS_EXT;
2457     range->retry_capa = IW_RETRY_LIMIT ;
2458     range->retry_flags = IW_RETRY_LIMIT;
2459     range->r_time_flags = 0;
2460     range->min_retry = 1;
2461     range->max_retry = 65535;
2462 
2463     return 0;
2464 }
2465 
2466 static int atmel_set_wap(struct net_device *dev,
2467              struct iw_request_info *info,
2468              struct sockaddr *awrq,
2469              char *extra)
2470 {
2471     struct atmel_private *priv = netdev_priv(dev);
2472     int i;
2473     static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2474     static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2475     unsigned long flags;
2476 
2477     if (awrq->sa_family != ARPHRD_ETHER)
2478         return -EINVAL;
2479 
2480     if (!memcmp(any, awrq->sa_data, 6) ||
2481         !memcmp(off, awrq->sa_data, 6)) {
2482         del_timer_sync(&priv->management_timer);
2483         spin_lock_irqsave(&priv->irqlock, flags);
2484         atmel_scan(priv, 1);
2485         spin_unlock_irqrestore(&priv->irqlock, flags);
2486         return 0;
2487     }
2488 
2489     for (i = 0; i < priv->BSS_list_entries; i++) {
2490         if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2491             if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2492                 return -EINVAL;
2493             } else if  (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2494                 return -EINVAL;
2495             } else {
2496                 del_timer_sync(&priv->management_timer);
2497                 spin_lock_irqsave(&priv->irqlock, flags);
2498                 atmel_join_bss(priv, i);
2499                 spin_unlock_irqrestore(&priv->irqlock, flags);
2500                 return 0;
2501             }
2502         }
2503     }
2504 
2505     return -EINVAL;
2506 }
2507 
2508 static int atmel_config_commit(struct net_device *dev,
2509                    struct iw_request_info *info,    /* NULL */
2510                    void *zwrq,          /* NULL */
2511                    char *extra)         /* NULL */
2512 {
2513     return atmel_open(dev);
2514 }
2515 
2516 static const iw_handler atmel_handler[] =
2517 {
2518     (iw_handler) atmel_config_commit,   /* SIOCSIWCOMMIT */
2519     (iw_handler) atmel_get_name,        /* SIOCGIWNAME */
2520     (iw_handler) NULL,          /* SIOCSIWNWID */
2521     (iw_handler) NULL,          /* SIOCGIWNWID */
2522     (iw_handler) atmel_set_freq,        /* SIOCSIWFREQ */
2523     (iw_handler) atmel_get_freq,        /* SIOCGIWFREQ */
2524     (iw_handler) atmel_set_mode,        /* SIOCSIWMODE */
2525     (iw_handler) atmel_get_mode,        /* SIOCGIWMODE */
2526     (iw_handler) NULL,          /* SIOCSIWSENS */
2527     (iw_handler) NULL,          /* SIOCGIWSENS */
2528     (iw_handler) NULL,          /* SIOCSIWRANGE */
2529     (iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
2530     (iw_handler) NULL,          /* SIOCSIWPRIV */
2531     (iw_handler) NULL,          /* SIOCGIWPRIV */
2532     (iw_handler) NULL,          /* SIOCSIWSTATS */
2533     (iw_handler) NULL,          /* SIOCGIWSTATS */
2534     (iw_handler) NULL,          /* SIOCSIWSPY */
2535     (iw_handler) NULL,          /* SIOCGIWSPY */
2536     (iw_handler) NULL,          /* -- hole -- */
2537     (iw_handler) NULL,          /* -- hole -- */
2538     (iw_handler) atmel_set_wap,     /* SIOCSIWAP */
2539     (iw_handler) atmel_get_wap,     /* SIOCGIWAP */
2540     (iw_handler) NULL,          /* -- hole -- */
2541     (iw_handler) NULL,          /* SIOCGIWAPLIST */
2542     (iw_handler) atmel_set_scan,        /* SIOCSIWSCAN */
2543     (iw_handler) atmel_get_scan,        /* SIOCGIWSCAN */
2544     (iw_handler) atmel_set_essid,       /* SIOCSIWESSID */
2545     (iw_handler) atmel_get_essid,       /* SIOCGIWESSID */
2546     (iw_handler) NULL,          /* SIOCSIWNICKN */
2547     (iw_handler) NULL,          /* SIOCGIWNICKN */
2548     (iw_handler) NULL,          /* -- hole -- */
2549     (iw_handler) NULL,          /* -- hole -- */
2550     (iw_handler) atmel_set_rate,        /* SIOCSIWRATE */
2551     (iw_handler) atmel_get_rate,        /* SIOCGIWRATE */
2552     (iw_handler) atmel_set_rts,     /* SIOCSIWRTS */
2553     (iw_handler) atmel_get_rts,     /* SIOCGIWRTS */
2554     (iw_handler) atmel_set_frag,        /* SIOCSIWFRAG */
2555     (iw_handler) atmel_get_frag,        /* SIOCGIWFRAG */
2556     (iw_handler) NULL,          /* SIOCSIWTXPOW */
2557     (iw_handler) NULL,          /* SIOCGIWTXPOW */
2558     (iw_handler) atmel_set_retry,       /* SIOCSIWRETRY */
2559     (iw_handler) atmel_get_retry,       /* SIOCGIWRETRY */
2560     (iw_handler) atmel_set_encode,      /* SIOCSIWENCODE */
2561     (iw_handler) atmel_get_encode,      /* SIOCGIWENCODE */
2562     (iw_handler) atmel_set_power,       /* SIOCSIWPOWER */
2563     (iw_handler) atmel_get_power,       /* SIOCGIWPOWER */
2564     (iw_handler) NULL,          /* -- hole -- */
2565     (iw_handler) NULL,          /* -- hole -- */
2566     (iw_handler) NULL,          /* SIOCSIWGENIE */
2567     (iw_handler) NULL,          /* SIOCGIWGENIE */
2568     (iw_handler) atmel_set_auth,        /* SIOCSIWAUTH */
2569     (iw_handler) atmel_get_auth,        /* SIOCGIWAUTH */
2570     (iw_handler) atmel_set_encodeext,   /* SIOCSIWENCODEEXT */
2571     (iw_handler) atmel_get_encodeext,   /* SIOCGIWENCODEEXT */
2572     (iw_handler) NULL,          /* SIOCSIWPMKSA */
2573 };
2574 
2575 static const iw_handler atmel_private_handler[] =
2576 {
2577     NULL,               /* SIOCIWFIRSTPRIV */
2578 };
2579 
2580 struct atmel_priv_ioctl {
2581     char id[32];
2582     unsigned char __user *data;
2583     unsigned short len;
2584 };
2585 
2586 #define ATMELFWL    SIOCIWFIRSTPRIV
2587 #define ATMELIDIFC  ATMELFWL + 1
2588 #define ATMELRD     ATMELFWL + 2
2589 #define ATMELMAGIC 0x51807
2590 #define REGDOMAINSZ 20
2591 
2592 static const struct iw_priv_args atmel_private_args[] = {
2593     {
2594         .cmd = ATMELFWL,
2595         .set_args = IW_PRIV_TYPE_BYTE
2596                 | IW_PRIV_SIZE_FIXED
2597                 | sizeof(struct atmel_priv_ioctl),
2598         .get_args = IW_PRIV_TYPE_NONE,
2599         .name = "atmelfwl"
2600     }, {
2601         .cmd = ATMELIDIFC,
2602         .set_args = IW_PRIV_TYPE_NONE,
2603         .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2604         .name = "atmelidifc"
2605     }, {
2606         .cmd = ATMELRD,
2607         .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2608         .get_args = IW_PRIV_TYPE_NONE,
2609         .name = "regdomain"
2610     },
2611 };
2612 
2613 static const struct iw_handler_def atmel_handler_def = {
2614     .num_standard   = ARRAY_SIZE(atmel_handler),
2615     .num_private    = ARRAY_SIZE(atmel_private_handler),
2616     .num_private_args = ARRAY_SIZE(atmel_private_args),
2617     .standard   = (iw_handler *) atmel_handler,
2618     .private    = (iw_handler *) atmel_private_handler,
2619     .private_args   = (struct iw_priv_args *) atmel_private_args,
2620     .get_wireless_stats = atmel_get_wireless_stats
2621 };
2622 
2623 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2624 {
2625     int i, rc = 0;
2626     struct atmel_private *priv = netdev_priv(dev);
2627     struct atmel_priv_ioctl com;
2628     struct iwreq *wrq = (struct iwreq *) rq;
2629     unsigned char *new_firmware;
2630     char domain[REGDOMAINSZ + 1];
2631 
2632     switch (cmd) {
2633     case ATMELIDIFC:
2634         wrq->u.param.value = ATMELMAGIC;
2635         break;
2636 
2637     case ATMELFWL:
2638         if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2639             rc = -EFAULT;
2640             break;
2641         }
2642 
2643         if (!capable(CAP_NET_ADMIN)) {
2644             rc = -EPERM;
2645             break;
2646         }
2647 
2648         new_firmware = memdup_user(com.data, com.len);
2649         if (IS_ERR(new_firmware)) {
2650             rc = PTR_ERR(new_firmware);
2651             break;
2652         }
2653 
2654         kfree(priv->firmware);
2655 
2656         priv->firmware = new_firmware;
2657         priv->firmware_length = com.len;
2658         strncpy(priv->firmware_id, com.id, 31);
2659         priv->firmware_id[31] = '\0';
2660         break;
2661 
2662     case ATMELRD:
2663         if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2664             rc = -EFAULT;
2665             break;
2666         }
2667 
2668         if (!capable(CAP_NET_ADMIN)) {
2669             rc = -EPERM;
2670             break;
2671         }
2672 
2673         domain[REGDOMAINSZ] = 0;
2674         rc = -EINVAL;
2675         for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2676             if (!strcasecmp(channel_table[i].name, domain)) {
2677                 priv->config_reg_domain = channel_table[i].reg_domain;
2678                 rc = 0;
2679             }
2680         }
2681 
2682         if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
2683             rc = atmel_open(dev);
2684         break;
2685 
2686     default:
2687         rc = -EOPNOTSUPP;
2688     }
2689 
2690     return rc;
2691 }
2692 
2693 struct auth_body {
2694     __le16 alg;
2695     __le16 trans_seq;
2696     __le16 status;
2697     u8 el_id;
2698     u8 chall_text_len;
2699     u8 chall_text[253];
2700 };
2701 
2702 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2703 {
2704     int old_state = priv->station_state;
2705 
2706     if (new_state == old_state)
2707         return;
2708 
2709     priv->station_state = new_state;
2710 
2711     if (new_state == STATION_STATE_READY) {
2712         netif_start_queue(priv->dev);
2713         netif_carrier_on(priv->dev);
2714     }
2715 
2716     if (old_state == STATION_STATE_READY) {
2717         netif_carrier_off(priv->dev);
2718         if (netif_running(priv->dev))
2719             netif_stop_queue(priv->dev);
2720         priv->last_beacon_timestamp = 0;
2721     }
2722 }
2723 
2724 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2725 {
2726     struct {
2727         u8 BSSID[ETH_ALEN];
2728         u8 SSID[MAX_SSID_LENGTH];
2729         u8 scan_type;
2730         u8 channel;
2731         __le16 BSS_type;
2732         __le16 min_channel_time;
2733         __le16 max_channel_time;
2734         u8 options;
2735         u8 SSID_size;
2736     } cmd;
2737 
2738     eth_broadcast_addr(cmd.BSSID);
2739 
2740     if (priv->fast_scan) {
2741         cmd.SSID_size = priv->SSID_size;
2742         memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2743         cmd.min_channel_time = cpu_to_le16(10);
2744         cmd.max_channel_time = cpu_to_le16(50);
2745     } else {
2746         priv->BSS_list_entries = 0;
2747         cmd.SSID_size = 0;
2748         cmd.min_channel_time = cpu_to_le16(10);
2749         cmd.max_channel_time = cpu_to_le16(120);
2750     }
2751 
2752     cmd.options = 0;
2753 
2754     if (!specific_ssid)
2755         cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2756 
2757     cmd.channel = (priv->channel & 0x7f);
2758     cmd.scan_type = SCAN_TYPE_ACTIVE;
2759     cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2760         BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2761 
2762     atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2763 
2764     /* This must come after all hardware access to avoid being messed up
2765        by stuff happening in interrupt context after we leave STATE_DOWN */
2766     atmel_enter_state(priv, STATION_STATE_SCANNING);
2767 }
2768 
2769 static void join(struct atmel_private *priv, int type)
2770 {
2771     struct {
2772         u8 BSSID[6];
2773         u8 SSID[MAX_SSID_LENGTH];
2774         u8 BSS_type; /* this is a short in a scan command - weird */
2775         u8 channel;
2776         __le16 timeout;
2777         u8 SSID_size;
2778         u8 reserved;
2779     } cmd;
2780 
2781     cmd.SSID_size = priv->SSID_size;
2782     memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2783     memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN);
2784     cmd.channel = (priv->channel & 0x7f);
2785     cmd.BSS_type = type;
2786     cmd.timeout = cpu_to_le16(2000);
2787 
2788     atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2789 }
2790 
2791 static void start(struct atmel_private *priv, int type)
2792 {
2793     struct {
2794         u8 BSSID[6];
2795         u8 SSID[MAX_SSID_LENGTH];
2796         u8 BSS_type;
2797         u8 channel;
2798         u8 SSID_size;
2799         u8 reserved[3];
2800     } cmd;
2801 
2802     cmd.SSID_size = priv->SSID_size;
2803     memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2804     memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN);
2805     cmd.BSS_type = type;
2806     cmd.channel = (priv->channel & 0x7f);
2807 
2808     atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2809 }
2810 
2811 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2812                 u8 channel)
2813 {
2814     int rejoin = 0;
2815     int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2816         SHORT_PREAMBLE : LONG_PREAMBLE;
2817 
2818     if (priv->preamble != new) {
2819         priv->preamble = new;
2820         rejoin = 1;
2821         atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2822     }
2823 
2824     if (priv->channel != channel) {
2825         priv->channel = channel;
2826         rejoin = 1;
2827         atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2828     }
2829 
2830     if (rejoin) {
2831         priv->station_is_associated = 0;
2832         atmel_enter_state(priv, STATION_STATE_JOINNING);
2833 
2834         if (priv->operating_mode == IW_MODE_INFRA)
2835             join(priv, BSS_TYPE_INFRASTRUCTURE);
2836         else
2837             join(priv, BSS_TYPE_AD_HOC);
2838     }
2839 }
2840 
2841 static void send_authentication_request(struct atmel_private *priv, u16 system,
2842                     u8 *challenge, int challenge_len)
2843 {
2844     struct ieee80211_hdr header;
2845     struct auth_body auth;
2846 
2847     header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2848     header.duration_id = cpu_to_le16(0x8000);
2849     header.seq_ctrl = 0;
2850     memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2851     memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2852     memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2853 
2854     if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2855         /* no WEP for authentication frames with TrSeqNo 1 */
2856         header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2857 
2858     auth.alg = cpu_to_le16(system);
2859 
2860     auth.status = 0;
2861     auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2862     priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2863     priv->CurrentAuthentTransactionSeqNum += 2;
2864 
2865     if (challenge_len != 0) {
2866         auth.el_id = 16; /* challenge_text */
2867         auth.chall_text_len = challenge_len;
2868         memcpy(auth.chall_text, challenge, challenge_len);
2869         atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2870     } else {
2871         atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2872     }
2873 }
2874 
2875 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2876 {
2877     u8 *ssid_el_p;
2878     int bodysize;
2879     struct ieee80211_hdr header;
2880     struct ass_req_format {
2881         __le16 capability;
2882         __le16 listen_interval;
2883         u8 ap[ETH_ALEN]; /* nothing after here directly accessible */
2884         u8 ssid_el_id;
2885         u8 ssid_len;
2886         u8 ssid[MAX_SSID_LENGTH];
2887         u8 sup_rates_el_id;
2888         u8 sup_rates_len;
2889         u8 rates[4];
2890     } body;
2891 
2892     header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2893         (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2894     header.duration_id = cpu_to_le16(0x8000);
2895     header.seq_ctrl = 0;
2896 
2897     memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN);
2898     memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN);
2899     memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN);
2900 
2901     body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2902     if (priv->wep_is_on)
2903         body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2904     if (priv->preamble == SHORT_PREAMBLE)
2905         body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2906 
2907     body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2908 
2909     /* current AP address - only in reassoc frame */
2910     if (is_reassoc) {
2911         memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN);
2912         ssid_el_p = &body.ssid_el_id;
2913         bodysize = 18 + priv->SSID_size;
2914     } else {
2915         ssid_el_p = &body.ap[0];
2916         bodysize = 12 + priv->SSID_size;
2917     }
2918 
2919     ssid_el_p[0] = WLAN_EID_SSID;
2920     ssid_el_p[1] = priv->SSID_size;
2921     memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2922     ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2923     ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
2924     memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2925 
2926     atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2927 }
2928 
2929 static int is_frame_from_current_bss(struct atmel_private *priv,
2930                      struct ieee80211_hdr *header)
2931 {
2932     if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2933         return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2934     else
2935         return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2936 }
2937 
2938 static int retrieve_bss(struct atmel_private *priv)
2939 {
2940     int i;
2941     int max_rssi = -128;
2942     int max_index = -1;
2943 
2944     if (priv->BSS_list_entries == 0)
2945         return -1;
2946 
2947     if (priv->connect_to_any_BSS) {
2948         /* Select a BSS with the max-RSSI but of the same type and of
2949            the same WEP mode and that it is not marked as 'bad' (i.e.
2950            we had previously failed to connect to this BSS with the
2951            settings that we currently use) */
2952         priv->current_BSS = 0;
2953         for (i = 0; i < priv->BSS_list_entries; i++) {
2954             if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2955                 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2956                  (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2957                 !(priv->BSSinfo[i].channel & 0x80)) {
2958                 max_rssi = priv->BSSinfo[i].RSSI;
2959                 priv->current_BSS = max_index = i;
2960             }
2961         }
2962         return max_index;
2963     }
2964 
2965     for (i = 0; i < priv->BSS_list_entries; i++) {
2966         if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2967             memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2968             priv->operating_mode == priv->BSSinfo[i].BSStype &&
2969             atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2970             if (priv->BSSinfo[i].RSSI >= max_rssi) {
2971                 max_rssi = priv->BSSinfo[i].RSSI;
2972                 max_index = i;
2973             }
2974         }
2975     }
2976     return max_index;
2977 }
2978 
2979 static void store_bss_info(struct atmel_private *priv,
2980                struct ieee80211_hdr *header, u16 capability,
2981                u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
2982                u8 *ssid, int is_beacon)
2983 {
2984     u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
2985     int i, index;
2986 
2987     for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2988         if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0)
2989             index = i;
2990 
2991     /* If we process a probe and an entry from this BSS exists
2992        we will update the BSS entry with the info from this BSS.
2993        If we process a beacon we will only update RSSI */
2994 
2995     if (index == -1) {
2996         if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2997             return;
2998         index = priv->BSS_list_entries++;
2999         memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN);
3000         priv->BSSinfo[index].RSSI = rssi;
3001     } else {
3002         if (rssi > priv->BSSinfo[index].RSSI)
3003             priv->BSSinfo[index].RSSI = rssi;
3004         if (is_beacon)
3005             return;
3006     }
3007 
3008     priv->BSSinfo[index].channel = channel;
3009     priv->BSSinfo[index].beacon_period = beacon_period;
3010     priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3011     memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3012     priv->BSSinfo[index].SSIDsize = ssid_len;
3013 
3014     if (capability & WLAN_CAPABILITY_IBSS)
3015         priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3016     else if (capability & WLAN_CAPABILITY_ESS)
3017         priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3018 
3019     priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3020         SHORT_PREAMBLE : LONG_PREAMBLE;
3021 }
3022 
3023 static void authenticate(struct atmel_private *priv, u16 frame_len)
3024 {
3025     struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3026     u16 status = le16_to_cpu(auth->status);
3027     u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3028     u16 system = le16_to_cpu(auth->alg);
3029 
3030     if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3031         /* no WEP */
3032         if (priv->station_was_associated) {
3033             atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3034             send_association_request(priv, 1);
3035             return;
3036         } else {
3037             atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3038             send_association_request(priv, 0);
3039             return;
3040         }
3041     }
3042 
3043     if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3044         int should_associate = 0;
3045         /* WEP */
3046         if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3047             return;
3048 
3049         if (system == WLAN_AUTH_OPEN) {
3050             if (trans_seq_no == 0x0002) {
3051                 should_associate = 1;
3052             }
3053         } else if (system == WLAN_AUTH_SHARED_KEY) {
3054             if (trans_seq_no == 0x0002 &&
3055                 auth->el_id == WLAN_EID_CHALLENGE) {
3056                 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3057                 return;
3058             } else if (trans_seq_no == 0x0004) {
3059                 should_associate = 1;
3060             }
3061         }
3062 
3063         if (should_associate) {
3064             if (priv->station_was_associated) {
3065                 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3066                 send_association_request(priv, 1);
3067                 return;
3068             } else {
3069                 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3070                 send_association_request(priv, 0);
3071                 return;
3072             }
3073         }
3074     }
3075 
3076     if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3077         /* Flip back and forth between WEP auth modes until the max
3078          * authentication tries has been exceeded.
3079          */
3080         if (system == WLAN_AUTH_OPEN) {
3081             priv->CurrentAuthentTransactionSeqNum = 0x001;
3082             priv->exclude_unencrypted = 1;
3083             send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3084             return;
3085         } else if (system == WLAN_AUTH_SHARED_KEY
3086                && priv->wep_is_on) {
3087             priv->CurrentAuthentTransactionSeqNum = 0x001;
3088             priv->exclude_unencrypted = 0;
3089             send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3090             return;
3091         } else if (priv->connect_to_any_BSS) {
3092             int bss_index;
3093 
3094             priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3095 
3096             if ((bss_index  = retrieve_bss(priv)) != -1) {
3097                 atmel_join_bss(priv, bss_index);
3098                 return;
3099             }
3100         }
3101     }
3102 
3103     priv->AuthenticationRequestRetryCnt = 0;
3104     atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3105     priv->station_is_associated = 0;
3106 }
3107 
3108 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3109 {
3110     struct ass_resp_format {
3111         __le16 capability;
3112         __le16 status;
3113         __le16 ass_id;
3114         u8 el_id;
3115         u8 length;
3116         u8 rates[4];
3117     } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3118 
3119     u16 status = le16_to_cpu(ass_resp->status);
3120     u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3121     u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3122 
3123     union iwreq_data wrqu;
3124 
3125     if (frame_len < 8 + rates_len)
3126         return;
3127 
3128     if (status == WLAN_STATUS_SUCCESS) {
3129         if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3130             priv->AssociationRequestRetryCnt = 0;
3131         else
3132             priv->ReAssociationRequestRetryCnt = 0;
3133 
3134         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3135                 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3136         atmel_set_mib(priv, Phy_Mib_Type,
3137                   PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3138         if (priv->power_mode == 0) {
3139             priv->listen_interval = 1;
3140             atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3141                        MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3142             atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3143                     MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3144         } else {
3145             priv->listen_interval = 2;
3146             atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3147                        MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
3148             atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3149                     MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3150         }
3151 
3152         priv->station_is_associated = 1;
3153         priv->station_was_associated = 1;
3154         atmel_enter_state(priv, STATION_STATE_READY);
3155 
3156         /* Send association event to userspace */
3157         wrqu.data.length = 0;
3158         wrqu.data.flags = 0;
3159         memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3160         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3161         wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3162 
3163         return;
3164     }
3165 
3166     if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3167         status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3168         status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3169         priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3170         mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3171         priv->AssociationRequestRetryCnt++;
3172         send_association_request(priv, 0);
3173         return;
3174     }
3175 
3176     if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3177         status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3178         status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3179         priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3180         mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3181         priv->ReAssociationRequestRetryCnt++;
3182         send_association_request(priv, 1);
3183         return;
3184     }
3185 
3186     atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
3187     priv->station_is_associated = 0;
3188 
3189     if (priv->connect_to_any_BSS) {
3190         int bss_index;
3191         priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3192 
3193         if ((bss_index = retrieve_bss(priv)) != -1)
3194             atmel_join_bss(priv, bss_index);
3195     }
3196 }
3197 
3198 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3199 {
3200     struct bss_info *bss =  &priv->BSSinfo[bss_index];
3201 
3202     memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN);
3203     memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3204 
3205     /* The WPA stuff cares about the current AP address */
3206     if (priv->use_wpa)
3207         build_wpa_mib(priv);
3208 
3209     /* When switching to AdHoc turn OFF Power Save if needed */
3210 
3211     if (bss->BSStype == IW_MODE_ADHOC &&
3212         priv->operating_mode != IW_MODE_ADHOC &&
3213         priv->power_mode) {
3214         priv->power_mode = 0;
3215         priv->listen_interval = 1;
3216         atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3217                    MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
3218         atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3219                 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3220     }
3221 
3222     priv->operating_mode = bss->BSStype;
3223     priv->channel = bss->channel & 0x7f;
3224     priv->beacon_period = bss->beacon_period;
3225 
3226     if (priv->preamble != bss->preamble) {
3227         priv->preamble = bss->preamble;
3228         atmel_set_mib8(priv, Local_Mib_Type,
3229                    LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3230     }
3231 
3232     if (!priv->wep_is_on && bss->UsingWEP) {
3233         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3234         priv->station_is_associated = 0;
3235         return;
3236     }
3237 
3238     if (priv->wep_is_on && !bss->UsingWEP) {
3239         atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3240         priv->station_is_associated = 0;
3241         return;
3242     }
3243 
3244     atmel_enter_state(priv, STATION_STATE_JOINNING);
3245 
3246     if (priv->operating_mode == IW_MODE_INFRA)
3247         join(priv, BSS_TYPE_INFRASTRUCTURE);
3248     else
3249         join(priv, BSS_TYPE_AD_HOC);
3250 }
3251 
3252 static void restart_search(struct atmel_private *priv)
3253 {
3254     int bss_index;
3255 
3256     if (!priv->connect_to_any_BSS) {
3257         atmel_scan(priv, 1);
3258     } else {
3259         priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3260 
3261         if ((bss_index = retrieve_bss(priv)) != -1)
3262             atmel_join_bss(priv, bss_index);
3263         else
3264             atmel_scan(priv, 0);
3265     }
3266 }
3267 
3268 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3269 {
3270     u8 old = priv->wstats.qual.level;
3271     u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3272 
3273     switch (priv->firmware_type) {
3274     case ATMEL_FW_TYPE_502E:
3275         max_rssi = 63; /* 502-rmfd-reve max by experiment */
3276         break;
3277     default:
3278         break;
3279     }
3280 
3281     rssi = rssi * 100 / max_rssi;
3282     if ((rssi + old) % 2)
3283         priv->wstats.qual.level = (rssi + old) / 2 + 1;
3284     else
3285         priv->wstats.qual.level = (rssi + old) / 2;
3286     priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3287     priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3288 }
3289 
3290 static void atmel_smooth_qual(struct atmel_private *priv)
3291 {
3292     unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3293     while (time_diff--) {
3294         priv->last_qual += HZ;
3295         priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3296         priv->wstats.qual.qual +=
3297             priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3298         priv->beacons_this_sec = 0;
3299     }
3300     priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3301     priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3302 }
3303 
3304 /* deals with incoming management frames. */
3305 static void atmel_management_frame(struct atmel_private *priv,
3306                    struct ieee80211_hdr *header,
3307                    u16 frame_len, u8 rssi)
3308 {
3309     u16 subtype;
3310 
3311     subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3312     switch (subtype) {
3313     case IEEE80211_STYPE_BEACON:
3314     case IEEE80211_STYPE_PROBE_RESP:
3315 
3316         /* beacon frame has multiple variable-length fields -
3317            never let an engineer loose with a data structure design. */
3318         {
3319             struct beacon_format {
3320                 __le64 timestamp;
3321                 __le16 interval;
3322                 __le16 capability;
3323                 u8 ssid_el_id;
3324                 u8 ssid_length;
3325                 /* ssid here */
3326                 u8 rates_el_id;
3327                 u8 rates_length;
3328                 /* rates here */
3329                 u8 ds_el_id;
3330                 u8 ds_length;
3331                 /* ds here */
3332             } *beacon = (struct beacon_format *)priv->rx_buf;
3333 
3334             u8 channel, rates_length, ssid_length;
3335             u64 timestamp = le64_to_cpu(beacon->timestamp);
3336             u16 beacon_interval = le16_to_cpu(beacon->interval);
3337             u16 capability = le16_to_cpu(beacon->capability);
3338             u8 *beaconp = priv->rx_buf;
3339             ssid_length = beacon->ssid_length;
3340             /* this blows chunks. */
3341             if (frame_len < 14 || frame_len < ssid_length + 15)
3342                 return;
3343             rates_length = beaconp[beacon->ssid_length + 15];
3344             if (frame_len < ssid_length + rates_length + 18)
3345                 return;
3346             if (ssid_length >  MAX_SSID_LENGTH)
3347                 return;
3348             channel = beaconp[ssid_length + rates_length + 18];
3349 
3350             if (priv->station_state == STATION_STATE_READY) {
3351                 smooth_rssi(priv, rssi);
3352                 if (is_frame_from_current_bss(priv, header)) {
3353                     priv->beacons_this_sec++;
3354                     atmel_smooth_qual(priv);
3355                     if (priv->last_beacon_timestamp) {
3356                         /* Note truncate this to 32 bits - kernel can't divide a long */
3357                         u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3358                         int beacons = beacon_delay / (beacon_interval * 1000);
3359                         if (beacons > 1)
3360                             priv->wstats.miss.beacon += beacons - 1;
3361                     }
3362                     priv->last_beacon_timestamp = timestamp;
3363                     handle_beacon_probe(priv, capability, channel);
3364                 }
3365             }
3366 
3367             if (priv->station_state == STATION_STATE_SCANNING)
3368                 store_bss_info(priv, header, capability,
3369                            beacon_interval, channel, rssi,
3370                            ssid_length,
3371                            &beacon->rates_el_id,
3372                            subtype == IEEE80211_STYPE_BEACON);
3373         }
3374         break;
3375 
3376     case IEEE80211_STYPE_AUTH:
3377 
3378         if (priv->station_state == STATION_STATE_AUTHENTICATING)
3379             authenticate(priv, frame_len);
3380 
3381         break;
3382 
3383     case IEEE80211_STYPE_ASSOC_RESP:
3384     case IEEE80211_STYPE_REASSOC_RESP:
3385 
3386         if (priv->station_state == STATION_STATE_ASSOCIATING ||
3387             priv->station_state == STATION_STATE_REASSOCIATING)
3388             associate(priv, frame_len, subtype);
3389 
3390         break;
3391 
3392     case IEEE80211_STYPE_DISASSOC:
3393         if (priv->station_is_associated &&
3394             priv->operating_mode == IW_MODE_INFRA &&
3395             is_frame_from_current_bss(priv, header)) {
3396             priv->station_was_associated = 0;
3397             priv->station_is_associated = 0;
3398 
3399             atmel_enter_state(priv, STATION_STATE_JOINNING);
3400             join(priv, BSS_TYPE_INFRASTRUCTURE);
3401         }
3402 
3403         break;
3404 
3405     case IEEE80211_STYPE_DEAUTH:
3406         if (priv->operating_mode == IW_MODE_INFRA &&
3407             is_frame_from_current_bss(priv, header)) {
3408             priv->station_was_associated = 0;
3409 
3410             atmel_enter_state(priv, STATION_STATE_JOINNING);
3411             join(priv, BSS_TYPE_INFRASTRUCTURE);
3412         }
3413 
3414         break;
3415     }
3416 }
3417 
3418 /* run when timer expires */
3419 static void atmel_management_timer(struct timer_list *t)
3420 {
3421     struct atmel_private *priv = from_timer(priv, t, management_timer);
3422     unsigned long flags;
3423 
3424     /* Check if the card has been yanked. */
3425     if (priv->card && priv->present_callback &&
3426         !(*priv->present_callback)(priv->card))
3427         return;
3428 
3429     spin_lock_irqsave(&priv->irqlock, flags);
3430 
3431     switch (priv->station_state) {
3432 
3433     case STATION_STATE_AUTHENTICATING:
3434         if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3435             atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3436             priv->station_is_associated = 0;
3437             priv->AuthenticationRequestRetryCnt = 0;
3438             restart_search(priv);
3439         } else {
3440             int auth = WLAN_AUTH_OPEN;
3441             priv->AuthenticationRequestRetryCnt++;
3442             priv->CurrentAuthentTransactionSeqNum = 0x0001;
3443             mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3444             if (priv->wep_is_on && priv->exclude_unencrypted)
3445                 auth = WLAN_AUTH_SHARED_KEY;
3446             send_authentication_request(priv, auth, NULL, 0);
3447       }
3448       break;
3449 
3450     case STATION_STATE_ASSOCIATING:
3451         if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3452             atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3453             priv->station_is_associated = 0;
3454             priv->AssociationRequestRetryCnt = 0;
3455             restart_search(priv);
3456         } else {
3457             priv->AssociationRequestRetryCnt++;
3458             mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3459             send_association_request(priv, 0);
3460         }
3461       break;
3462 
3463     case STATION_STATE_REASSOCIATING:
3464         if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3465             atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3466             priv->station_is_associated = 0;
3467             priv->ReAssociationRequestRetryCnt = 0;
3468             restart_search(priv);
3469         } else {
3470             priv->ReAssociationRequestRetryCnt++;
3471             mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3472             send_association_request(priv, 1);
3473         }
3474         break;
3475 
3476     default:
3477         break;
3478     }
3479 
3480     spin_unlock_irqrestore(&priv->irqlock, flags);
3481 }
3482 
3483 static void atmel_command_irq(struct atmel_private *priv)
3484 {
3485     u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3486     u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3487     int fast_scan;
3488     union iwreq_data wrqu;
3489 
3490     if (status == CMD_STATUS_IDLE ||
3491         status == CMD_STATUS_IN_PROGRESS)
3492         return;
3493 
3494     switch (command) {
3495     case CMD_Start:
3496         if (status == CMD_STATUS_COMPLETE) {
3497             priv->station_was_associated = priv->station_is_associated;
3498             atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3499                       (u8 *)priv->CurrentBSSID, 6);
3500             atmel_enter_state(priv, STATION_STATE_READY);
3501         }
3502         break;
3503 
3504     case CMD_Scan:
3505         fast_scan = priv->fast_scan;
3506         priv->fast_scan = 0;
3507 
3508         if (status != CMD_STATUS_COMPLETE) {
3509             atmel_scan(priv, 1);
3510         } else {
3511             int bss_index = retrieve_bss(priv);
3512             int notify_scan_complete = 1;
3513             if (bss_index != -1) {
3514                 atmel_join_bss(priv, bss_index);
3515             } else if (priv->operating_mode == IW_MODE_ADHOC &&
3516                    priv->SSID_size != 0) {
3517                 start(priv, BSS_TYPE_AD_HOC);
3518             } else {
3519                 priv->fast_scan = !fast_scan;
3520                 atmel_scan(priv, 1);
3521                 notify_scan_complete = 0;
3522             }
3523             priv->site_survey_state = SITE_SURVEY_COMPLETED;
3524             if (notify_scan_complete) {
3525                 wrqu.data.length = 0;
3526                 wrqu.data.flags = 0;
3527                 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3528             }
3529         }
3530         break;
3531 
3532     case CMD_SiteSurvey:
3533         priv->fast_scan = 0;
3534 
3535         if (status != CMD_STATUS_COMPLETE)
3536             return;
3537 
3538         priv->site_survey_state = SITE_SURVEY_COMPLETED;
3539         if (priv->station_is_associated) {
3540             atmel_enter_state(priv, STATION_STATE_READY);
3541             wrqu.data.length = 0;
3542             wrqu.data.flags = 0;
3543             wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3544         } else {
3545             atmel_scan(priv, 1);
3546         }
3547         break;
3548 
3549     case CMD_Join:
3550         if (status == CMD_STATUS_COMPLETE) {
3551             if (priv->operating_mode == IW_MODE_ADHOC) {
3552                 priv->station_was_associated = priv->station_is_associated;
3553                 atmel_enter_state(priv, STATION_STATE_READY);
3554             } else {
3555                 int auth = WLAN_AUTH_OPEN;
3556                 priv->AuthenticationRequestRetryCnt = 0;
3557                 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3558 
3559                 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3560                 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3561                 if (priv->wep_is_on && priv->exclude_unencrypted)
3562                     auth = WLAN_AUTH_SHARED_KEY;
3563                 send_authentication_request(priv, auth, NULL, 0);
3564             }
3565             return;
3566         }
3567 
3568         atmel_scan(priv, 1);
3569     }
3570 }
3571 
3572 static int atmel_wakeup_firmware(struct atmel_private *priv)
3573 {
3574     struct host_info_struct *iface = &priv->host_info;
3575     u16 mr1, mr3;
3576     int i;
3577 
3578     if (priv->card_type == CARD_TYPE_SPI_FLASH)
3579         atmel_set_gcr(priv->dev, GCR_REMAP);
3580 
3581     /* wake up on-board processor */
3582     atmel_clear_gcr(priv->dev, 0x0040);
3583     atmel_write16(priv->dev, BSR, BSS_SRAM);
3584 
3585     if (priv->card_type == CARD_TYPE_SPI_FLASH)
3586         mdelay(100);
3587 
3588     /* and wait for it */
3589     for (i = LOOP_RETRY_LIMIT; i; i--) {
3590         mr1 = atmel_read16(priv->dev, MR1);
3591         mr3 = atmel_read16(priv->dev, MR3);
3592 
3593         if (mr3 & MAC_BOOT_COMPLETE)
3594             break;
3595         if (mr1 & MAC_BOOT_COMPLETE &&
3596             priv->bus_type == BUS_TYPE_PCCARD)
3597             break;
3598     }
3599 
3600     if (i == 0) {
3601         printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3602         return -EIO;
3603     }
3604 
3605     if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3606         printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3607         return -ENODEV;
3608     }
3609 
3610     /* now check for completion of MAC initialization through
3611        the FunCtrl field of the IFACE, poll MR1 to detect completion of
3612        MAC initialization, check completion status, set interrupt mask,
3613        enables interrupts and calls Tx and Rx initialization functions */
3614 
3615     atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3616 
3617     for (i = LOOP_RETRY_LIMIT; i; i--) {
3618         mr1 = atmel_read16(priv->dev, MR1);
3619         mr3 = atmel_read16(priv->dev, MR3);
3620 
3621         if (mr3 & MAC_INIT_COMPLETE)
3622             break;
3623         if (mr1 & MAC_INIT_COMPLETE &&
3624             priv->bus_type == BUS_TYPE_PCCARD)
3625             break;
3626     }
3627 
3628     if (i == 0) {
3629         printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3630                 priv->dev->name);
3631         return -EIO;
3632     }
3633 
3634     /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3635     if ((mr3 & MAC_INIT_COMPLETE) &&
3636         !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3637         printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3638         return -EIO;
3639     }
3640     if ((mr1 & MAC_INIT_COMPLETE) &&
3641         !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3642         printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3643         return -EIO;
3644     }
3645 
3646     atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3647                priv->host_info_base, sizeof(*iface));
3648 
3649     iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3650     iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3651     iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3652     iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3653     iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3654     iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3655     iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3656     iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3657     iface->build_version = le16_to_cpu(iface->build_version);
3658     iface->command_pos = le16_to_cpu(iface->command_pos);
3659     iface->major_version = le16_to_cpu(iface->major_version);
3660     iface->minor_version = le16_to_cpu(iface->minor_version);
3661     iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3662     iface->mac_status = le16_to_cpu(iface->mac_status);
3663 
3664     return 0;
3665 }
3666 
3667 /* determine type of memory and MAC address */
3668 static int probe_atmel_card(struct net_device *dev)
3669 {
3670     int rc = 0;
3671     struct atmel_private *priv = netdev_priv(dev);
3672     u8 addr[ETH_ALEN] = {};
3673 
3674     /* reset pccard */
3675     if (priv->bus_type == BUS_TYPE_PCCARD)
3676         atmel_write16(dev, GCR, 0x0060);
3677 
3678     atmel_write16(dev, GCR, 0x0040);
3679     msleep(500);
3680 
3681     if (atmel_read16(dev, MR2) == 0) {
3682         /* No stored firmware so load a small stub which just
3683            tells us the MAC address */
3684         int i;
3685         priv->card_type = CARD_TYPE_EEPROM;
3686         atmel_write16(dev, BSR, BSS_IRAM);
3687         atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3688         atmel_set_gcr(dev, GCR_REMAP);
3689         atmel_clear_gcr(priv->dev, 0x0040);
3690         atmel_write16(dev, BSR, BSS_SRAM);
3691         for (i = LOOP_RETRY_LIMIT; i; i--)
3692             if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3693                 break;
3694         if (i == 0) {
3695             printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3696         } else {
3697 
3698             atmel_copy_to_host(dev, addr, atmel_read16(dev, MR2), 6);
3699             eth_hw_addr_set(dev, addr);
3700             /* got address, now squash it again until the network
3701                interface is opened */
3702             if (priv->bus_type == BUS_TYPE_PCCARD)
3703                 atmel_write16(dev, GCR, 0x0060);
3704             atmel_write16(dev, GCR, 0x0040);
3705             rc = 1;
3706         }
3707     } else if (atmel_read16(dev, MR4) == 0) {
3708         /* Mac address easy in this case. */
3709         priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3710         atmel_write16(dev,  BSR, 1);
3711         atmel_copy_to_host(dev, addr, 0xc000, 6);
3712         eth_hw_addr_set(dev, addr);
3713         atmel_write16(dev,  BSR, 0x200);
3714         rc = 1;
3715     } else {
3716         /* Standard firmware in flash, boot it up and ask
3717            for the Mac Address */
3718         priv->card_type = CARD_TYPE_SPI_FLASH;
3719         if (atmel_wakeup_firmware(priv) == 0) {
3720             atmel_get_mib(priv, Mac_Address_Mib_Type, 0, addr, 6);
3721             eth_hw_addr_set(dev, addr);
3722 
3723             /* got address, now squash it again until the network
3724                interface is opened */
3725             if (priv->bus_type == BUS_TYPE_PCCARD)
3726                 atmel_write16(dev, GCR, 0x0060);
3727             atmel_write16(dev, GCR, 0x0040);
3728             rc = 1;
3729         }
3730     }
3731 
3732     if (rc) {
3733         if (dev->dev_addr[0] == 0xFF) {
3734             static const u8 default_mac[] = {
3735                 0x00, 0x04, 0x25, 0x00, 0x00, 0x00
3736             };
3737             printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3738             eth_hw_addr_set(dev, default_mac);
3739         }
3740     }
3741 
3742     return rc;
3743 }
3744 
3745 /* Move the encyption information on the MIB structure.
3746    This routine is for the pre-WPA firmware: later firmware has
3747    a different format MIB and a different routine. */
3748 static void build_wep_mib(struct atmel_private *priv)
3749 {
3750     struct { /* NB this is matched to the hardware, don't change. */
3751         u8 wep_is_on;
3752         u8 default_key; /* 0..3 */
3753         u8 reserved;
3754         u8 exclude_unencrypted;
3755 
3756         u32 WEPICV_error_count;
3757         u32 WEP_excluded_count;
3758 
3759         u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3760         u8 encryption_level; /* 0, 1, 2 */
3761         u8 reserved2[3];
3762     } mib;
3763     int i;
3764 
3765     mib.wep_is_on = priv->wep_is_on;
3766     if (priv->wep_is_on) {
3767         if (priv->wep_key_len[priv->default_key] > 5)
3768             mib.encryption_level = 2;
3769         else
3770             mib.encryption_level = 1;
3771     } else {
3772         mib.encryption_level = 0;
3773     }
3774 
3775     mib.default_key = priv->default_key;
3776     mib.exclude_unencrypted = priv->exclude_unencrypted;
3777 
3778     for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3779         memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3780 
3781     atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3782 }
3783 
3784 static void build_wpa_mib(struct atmel_private *priv)
3785 {
3786     /* This is for the later (WPA enabled) firmware. */
3787 
3788     struct { /* NB this is matched to the hardware, don't change. */
3789         u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3790         u8 receiver_address[ETH_ALEN];
3791         u8 wep_is_on;
3792         u8 default_key; /* 0..3 */
3793         u8 group_key;
3794         u8 exclude_unencrypted;
3795         u8 encryption_type;
3796         u8 reserved;
3797 
3798         u32 WEPICV_error_count;
3799         u32 WEP_excluded_count;
3800 
3801         u8 key_RSC[4][8];
3802     } mib;
3803 
3804     int i;
3805 
3806     mib.wep_is_on = priv->wep_is_on;
3807     mib.exclude_unencrypted = priv->exclude_unencrypted;
3808     memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN);
3809 
3810     /* zero all the keys before adding in valid ones. */
3811     memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3812 
3813     if (priv->wep_is_on) {
3814         /* There's a comment in the Atmel code to the effect that this
3815            is only valid when still using WEP, it may need to be set to
3816            something to use WPA */
3817         memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3818 
3819         mib.default_key = mib.group_key = 255;
3820         for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3821             if (priv->wep_key_len[i] > 0) {
3822                 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3823                 if (i == priv->default_key) {
3824                     mib.default_key = i;
3825                     mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3826                     mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3827                 } else {
3828                     mib.group_key = i;
3829                     priv->group_cipher_suite = priv->pairwise_cipher_suite;
3830                     mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3831                     mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3832                 }
3833             }
3834         }
3835         if (mib.default_key == 255)
3836             mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3837         if (mib.group_key == 255)
3838             mib.group_key = mib.default_key;
3839 
3840     }
3841 
3842     atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3843 }
3844 
3845 static int reset_atmel_card(struct net_device *dev)
3846 {
3847     /* do everything necessary to wake up the hardware, including
3848        waiting for the lightning strike and throwing the knife switch....
3849 
3850        set all the Mib values which matter in the card to match
3851        their settings in the atmel_private structure. Some of these
3852        can be altered on the fly, but many (WEP, infrastructure or ad-hoc)
3853        can only be changed by tearing down the world and coming back through
3854        here.
3855 
3856        This routine is also responsible for initialising some
3857        hardware-specific fields in the atmel_private structure,
3858        including a copy of the firmware's hostinfo structure
3859        which is the route into the rest of the firmware datastructures. */
3860 
3861     struct atmel_private *priv = netdev_priv(dev);
3862     u8 configuration;
3863     int old_state = priv->station_state;
3864     int err = 0;
3865 
3866     /* data to add to the firmware names, in priority order
3867        this implemenents firmware versioning */
3868 
3869     static char *firmware_modifier[] = {
3870         "-wpa",
3871         "",
3872         NULL
3873     };
3874 
3875     /* reset pccard */
3876     if (priv->bus_type == BUS_TYPE_PCCARD)
3877         atmel_write16(priv->dev, GCR, 0x0060);
3878 
3879     /* stop card , disable interrupts */
3880     atmel_write16(priv->dev, GCR, 0x0040);
3881 
3882     if (priv->card_type == CARD_TYPE_EEPROM) {
3883         /* copy in firmware if needed */
3884         const struct firmware *fw_entry = NULL;
3885         const unsigned char *fw;
3886         int len = priv->firmware_length;
3887         if (!(fw = priv->firmware)) {
3888             if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3889                 if (strlen(priv->firmware_id) == 0) {
3890                     printk(KERN_INFO
3891                            "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3892                            dev->name);
3893                     printk(KERN_INFO
3894                            "%s: if not, use the firmware= module parameter.\n",
3895                            dev->name);
3896                     strcpy(priv->firmware_id, "atmel_at76c502.bin");
3897                 }
3898                 err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3899                 if (err != 0) {
3900                     printk(KERN_ALERT
3901                            "%s: firmware %s is missing, cannot continue.\n",
3902                            dev->name, priv->firmware_id);
3903                     return err;
3904                 }
3905             } else {
3906                 int fw_index = 0;
3907                 int success = 0;
3908 
3909                 /* get firmware filename entry based on firmware type ID */
3910                 while (fw_table[fw_index].fw_type != priv->firmware_type
3911                         && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3912                     fw_index++;
3913 
3914                 /* construct the actual firmware file name */
3915                 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3916                     int i;
3917                     for (i = 0; firmware_modifier[i]; i++) {
3918                         snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3919                             firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3920                         priv->firmware_id[31] = '\0';
3921                         if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3922                             success = 1;
3923                             break;
3924                         }
3925                     }
3926                 }
3927                 if (!success) {
3928                     printk(KERN_ALERT
3929                            "%s: firmware %s is missing, cannot start.\n",
3930                            dev->name, priv->firmware_id);
3931                     priv->firmware_id[0] = '\0';
3932                     return -ENOENT;
3933                 }
3934             }
3935 
3936             fw = fw_entry->data;
3937             len = fw_entry->size;
3938         }
3939 
3940         if (len <= 0x6000) {
3941             atmel_write16(priv->dev, BSR, BSS_IRAM);
3942             atmel_copy_to_card(priv->dev, 0, fw, len);
3943             atmel_set_gcr(priv->dev, GCR_REMAP);
3944         } else {
3945             /* Remap */
3946             atmel_set_gcr(priv->dev, GCR_REMAP);
3947             atmel_write16(priv->dev, BSR, BSS_IRAM);
3948             atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3949             atmel_write16(priv->dev, BSR, 0x2ff);
3950             atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3951         }
3952 
3953         release_firmware(fw_entry);
3954     }
3955 
3956     err = atmel_wakeup_firmware(priv);
3957     if (err != 0)
3958         return err;
3959 
3960     /* Check the version and set the correct flag for wpa stuff,
3961        old and new firmware is incompatible.
3962        The pre-wpa 3com firmware reports major version 5,
3963        the wpa 3com firmware is major version 4 and doesn't need
3964        the 3com broken-ness filter. */
3965     priv->use_wpa = (priv->host_info.major_version == 4);
3966     priv->radio_on_broken = (priv->host_info.major_version == 5);
3967 
3968     /* unmask all irq sources */
3969     atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3970 
3971     /* int Tx system and enable Tx */
3972     atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3973     atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3974     atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3975     atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3976 
3977     priv->tx_desc_free = priv->host_info.tx_desc_count;
3978     priv->tx_desc_head = 0;
3979     priv->tx_desc_tail = 0;
3980     priv->tx_desc_previous = 0;
3981     priv->tx_free_mem = priv->host_info.tx_buff_size;
3982     priv->tx_buff_head = 0;
3983     priv->tx_buff_tail = 0;
3984 
3985     configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3986     atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3987                    configuration | FUNC_CTRL_TxENABLE);
3988 
3989     /* init Rx system and enable */
3990     priv->rx_desc_head = 0;
3991 
3992     configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3993     atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3994                    configuration | FUNC_CTRL_RxENABLE);
3995 
3996     if (!priv->radio_on_broken) {
3997         if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3998             CMD_STATUS_REJECTED_RADIO_OFF) {
3999             printk(KERN_INFO "%s: cannot turn the radio on.\n",
4000                    dev->name);
4001             return -EIO;
4002         }
4003     }
4004 
4005     /* set up enough MIB values to run. */
4006     atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4007     atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
4008     atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4009     atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4010     atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4011     atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4012     atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4013     atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4014               priv->dev->dev_addr, 6);
4015     atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4016     atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4017     atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4018     atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4019     atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4020     if (priv->use_wpa)
4021         build_wpa_mib(priv);
4022     else
4023         build_wep_mib(priv);
4024 
4025     if (old_state == STATION_STATE_READY) {
4026         union iwreq_data wrqu;
4027 
4028         wrqu.data.length = 0;
4029         wrqu.data.flags = 0;
4030         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4031         eth_zero_addr(wrqu.ap_addr.sa_data);
4032         wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4033     }
4034 
4035     return 0;
4036 }
4037 
4038 static void atmel_send_command(struct atmel_private *priv, int command,
4039                    void *cmd, int cmd_size)
4040 {
4041     if (cmd)
4042         atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4043                    cmd, cmd_size);
4044 
4045     atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4046     atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4047 }
4048 
4049 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4050                    void *cmd, int cmd_size)
4051 {
4052     int i, status;
4053 
4054     atmel_send_command(priv, command, cmd, cmd_size);
4055 
4056     for (i = 5000; i; i--) {
4057         status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4058         if (status != CMD_STATUS_IDLE &&
4059             status != CMD_STATUS_IN_PROGRESS)
4060             break;
4061         udelay(20);
4062     }
4063 
4064     if (i == 0) {
4065         printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4066         status =  CMD_STATUS_HOST_ERROR;
4067     } else {
4068         if (command != CMD_EnableRadio)
4069             status = CMD_STATUS_COMPLETE;
4070     }
4071 
4072     return status;
4073 }
4074 
4075 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4076 {
4077     struct get_set_mib m;
4078     m.type = type;
4079     m.size = 1;
4080     m.index = index;
4081 
4082     atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4083     return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4084 }
4085 
4086 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4087 {
4088     struct get_set_mib m;
4089     m.type = type;
4090     m.size = 1;
4091     m.index = index;
4092     m.data[0] = data;
4093 
4094     atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4095 }
4096 
4097 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4098                 u16 data)
4099 {
4100     struct get_set_mib m;
4101     m.type = type;
4102     m.size = 2;
4103     m.index = index;
4104     m.data[0] = data;
4105     m.data[1] = data >> 8;
4106 
4107     atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4108 }
4109 
4110 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4111               const u8 *data, int data_len)
4112 {
4113     struct get_set_mib m;
4114     m.type = type;
4115     m.size = data_len;
4116     m.index = index;
4117 
4118     if (data_len > MIB_MAX_DATA_BYTES)
4119         printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4120 
4121     memcpy(m.data, data, data_len);
4122     atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4123 }
4124 
4125 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4126               u8 *data, int data_len)
4127 {
4128     struct get_set_mib m;
4129     m.type = type;
4130     m.size = data_len;
4131     m.index = index;
4132 
4133     if (data_len > MIB_MAX_DATA_BYTES)
4134         printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4135 
4136     atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4137     atmel_copy_to_host(priv->dev, data,
4138                atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4139 }
4140 
4141 static void atmel_writeAR(struct net_device *dev, u16 data)
4142 {
4143     int i;
4144     outw(data, dev->base_addr + AR);
4145     /* Address register appears to need some convincing..... */
4146     for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4147         outw(data, dev->base_addr + AR);
4148 }
4149 
4150 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4151                    const unsigned char *src, u16 len)
4152 {
4153     int i;
4154     atmel_writeAR(dev, dest);
4155     if (dest % 2) {
4156         atmel_write8(dev, DR, *src);
4157         src++; len--;
4158     }
4159     for (i = len; i > 1 ; i -= 2) {
4160         u8 lb = *src++;
4161         u8 hb = *src++;
4162         atmel_write16(dev, DR, lb | (hb << 8));
4163     }
4164     if (i)
4165         atmel_write8(dev, DR, *src);
4166 }
4167 
4168 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4169                    u16 src, u16 len)
4170 {
4171     int i;
4172     atmel_writeAR(dev, src);
4173     if (src % 2) {
4174         *dest = atmel_read8(dev, DR);
4175         dest++; len--;
4176     }
4177     for (i = len; i > 1 ; i -= 2) {
4178         u16 hw = atmel_read16(dev, DR);
4179         *dest++ = hw;
4180         *dest++ = hw >> 8;
4181     }
4182     if (i)
4183         *dest = atmel_read8(dev, DR);
4184 }
4185 
4186 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4187 {
4188     outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4189 }
4190 
4191 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4192 {
4193     outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4194 }
4195 
4196 static int atmel_lock_mac(struct atmel_private *priv)
4197 {
4198     int i, j = 20;
4199  retry:
4200     for (i = 5000; i; i--) {
4201         if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4202             break;
4203         udelay(20);
4204     }
4205 
4206     if (!i)
4207         return 0; /* timed out */
4208 
4209     atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4210     if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4211         atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4212         if (!j--)
4213             return 0; /* timed out */
4214         goto retry;
4215     }
4216 
4217     return 1;
4218 }
4219 
4220 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4221 {
4222     atmel_writeAR(priv->dev, pos);
4223     atmel_write16(priv->dev, DR, data); /* card is little-endian */
4224     atmel_write16(priv->dev, DR, data >> 16);
4225 }
4226 
4227 /***************************************************************************/
4228 /* There follows the source form of the MAC address reading firmware       */
4229 /***************************************************************************/
4230 #if 0
4231 
4232 /* Copyright 2003 Matthew T. Russotto                                      */
4233 /* But derived from the Atmel 76C502 firmware written by Atmel and         */
4234 /* included in "atmel wireless lan drivers" package                        */
4235 /*
4236     This file is part of net.russotto.AtmelMACFW, hereto referred to
4237     as AtmelMACFW
4238 
4239     AtmelMACFW is free software; you can redistribute it and/or modify
4240     it under the terms of the GNU General Public License version 2
4241     as published by the Free Software Foundation.
4242 
4243     AtmelMACFW is distributed in the hope that it will be useful,
4244     but WITHOUT ANY WARRANTY; without even the implied warranty of
4245     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4246     GNU General Public License for more details.
4247 
4248     You should have received a copy of the GNU General Public License
4249     along with AtmelMACFW; if not, see <http://www.gnu.org/licenses/>.
4250 
4251 ****************************************************************************/
4252 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
4253 /* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
4254 /* It only works on SPI EEPROM versions of the card.                       */
4255 
4256 /* This firmware initializes the SPI controller and clock, reads the MAC   */
4257 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
4258 /* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
4259 /* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
4260 /* MR4, for investigational purposes (maybe we can determine chip type     */
4261 /* from that?)                                                             */
4262 
4263     .org 0
4264     .set MRBASE, 0x8000000
4265     .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4266     .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4267     .set SRAM_BASE,  0x02000000
4268     .set SP_BASE,    0x0F300000
4269     .set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
4270     .set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
4271     .set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
4272     .set STACK_BASE, 0x5600
4273     .set SP_SR, 0x10
4274     .set SP_TDRE, 2 /* status register bit -- TDR empty */
4275     .set SP_RDRF, 1 /* status register bit -- RDR full */
4276     .set SP_SWRST, 0x80
4277     .set SP_SPIEN, 0x1
4278     .set SP_CR, 0   /* control register */
4279     .set SP_MR, 4   /* mode register */
4280     .set SP_RDR, 0x08 /* Read Data Register */
4281     .set SP_TDR, 0x0C /* Transmit Data Register */
4282     .set SP_CSR0, 0x30 /* chip select registers */
4283     .set SP_CSR1, 0x34
4284     .set SP_CSR2, 0x38
4285     .set SP_CSR3, 0x3C
4286     .set NVRAM_CMD_RDSR, 5 /* read status register */
4287     .set NVRAM_CMD_READ, 3 /* read data */
4288     .set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
4289     .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4290                   serial output, since SO is normally high.  But it
4291                   does cause 8 clock cycles and thus 8 bits to be
4292                   clocked in to the chip.  See Atmel's SPI
4293                   controller (e.g. AT91M55800) timing and 4K
4294                   SPI EEPROM manuals */
4295 
4296     .set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
4297     .set NVRAM_IMAGE, 0x02000200
4298     .set NVRAM_LENGTH, 0x0200
4299     .set MAC_ADDRESS_MIB, SRAM_BASE
4300     .set MAC_ADDRESS_LENGTH, 6
4301     .set MAC_BOOT_FLAG, 0x10
4302     .set MR1, 0
4303     .set MR2, 4
4304     .set MR3, 8
4305     .set MR4, 0xC
4306 RESET_VECTOR:
4307     b RESET_HANDLER
4308 UNDEF_VECTOR:
4309     b HALT1
4310 SWI_VECTOR:
4311     b HALT1
4312 IABORT_VECTOR:
4313     b HALT1
4314 DABORT_VECTOR:
4315 RESERVED_VECTOR:
4316     b HALT1
4317 IRQ_VECTOR:
4318     b HALT1
4319 FIQ_VECTOR:
4320     b HALT1
4321 HALT1:  b HALT1
4322 RESET_HANDLER:
4323     mov     r0, #CPSR_INITIAL
4324     msr CPSR_c, r0  /* This is probably unnecessary */
4325 
4326 /* I'm guessing this is initializing clock generator electronics for SPI */
4327     ldr r0, =SPI_CGEN_BASE
4328     mov r1, #0
4329     mov r1, r1, lsl #3
4330     orr r1, r1, #0
4331     str r1, [r0]
4332     ldr r1, [r0, #28]
4333     bic r1, r1, #16
4334     str r1, [r0, #28]
4335     mov r1, #1
4336     str r1, [r0, #8]
4337 
4338     ldr r0, =MRBASE
4339     mov r1, #0
4340     strh    r1, [r0, #MR1]
4341     strh    r1, [r0, #MR2]
4342     strh    r1, [r0, #MR3]
4343     strh    r1, [r0, #MR4]
4344 
4345     mov sp, #STACK_BASE
4346     bl  SP_INIT
4347     mov r0, #10
4348     bl  DELAY9
4349     bl  GET_MAC_ADDR
4350     bl  GET_WHOLE_NVRAM
4351     ldr r0, =MRBASE
4352     ldr r1, =MAC_ADDRESS_MIB
4353     strh    r1, [r0, #MR2]
4354     ldr r1, =NVRAM_IMAGE
4355     strh    r1, [r0, #MR4]
4356     mov r1, #MAC_BOOT_FLAG
4357     strh    r1, [r0, #MR3]
4358 HALT2:  b HALT2
4359 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4360 GET_WHOLE_NVRAM:
4361     stmdb   sp!, {lr}
4362     mov r2, #0 /* 0th bytes of NVRAM */
4363     mov r3, #NVRAM_LENGTH
4364     mov r1, #0      /* not used in routine */
4365     ldr r0, =NVRAM_IMAGE
4366     bl  NVRAM_XFER
4367     ldmia   sp!, {lr}
4368     bx  lr
4369 .endfunc
4370 
4371 .func Get_MAC_Addr, GET_MAC_ADDR
4372 GET_MAC_ADDR:
4373     stmdb   sp!, {lr}
4374     mov r2, #0x120  /* address of MAC Address within NVRAM */
4375     mov r3, #MAC_ADDRESS_LENGTH
4376     mov r1, #0      /* not used in routine */
4377     ldr r0, =MAC_ADDRESS_MIB
4378     bl  NVRAM_XFER
4379     ldmia   sp!, {lr}
4380     bx  lr
4381 .endfunc
4382 .ltorg
4383 .func Delay9, DELAY9
4384 DELAY9:
4385     adds    r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
4386 DELAYLOOP:
4387     beq DELAY9_done
4388     subs    r0, r0, #1
4389     b   DELAYLOOP
4390 DELAY9_done:
4391     bx  lr
4392 .endfunc
4393 
4394 .func SP_Init, SP_INIT
4395 SP_INIT:
4396     mov r1, #SP_SWRST
4397     ldr r0, =SP_BASE
4398     str r1, [r0, #SP_CR] /* reset the SPI */
4399     mov r1, #0
4400     str r1, [r0, #SP_CR] /* release SPI from reset state */
4401     mov r1, #SP_SPIEN
4402     str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4403     str r1, [r0, #SP_CR] /* enable the SPI */
4404 
4405 /*  My guess would be this turns on the SPI clock */
4406     ldr r3, =SPI_CGEN_BASE
4407     ldr r1, [r3, #28]
4408     orr r1, r1, #0x2000
4409     str r1, [r3, #28]
4410 
4411     ldr r1, =0x2000c01
4412     str r1, [r0, #SP_CSR0]
4413     ldr r1, =0x2000201
4414     str r1, [r0, #SP_CSR1]
4415     str r1, [r0, #SP_CSR2]
4416     str r1, [r0, #SP_CSR3]
4417     ldr r1, [r0, #SP_SR]
4418     ldr r0, [r0, #SP_RDR]
4419     bx  lr
4420 .endfunc
4421 .func NVRAM_Init, NVRAM_INIT
4422 NVRAM_INIT:
4423     ldr r1, =SP_BASE
4424     ldr r0, [r1, #SP_RDR]
4425     mov r0, #NVRAM_CMD_RDSR
4426     str r0, [r1, #SP_TDR]
4427 SP_loop1:
4428     ldr r0, [r1, #SP_SR]
4429     tst r0, #SP_TDRE
4430     beq SP_loop1
4431 
4432     mov r0, #SPI_8CLOCKS
4433     str r0, [r1, #SP_TDR]
4434 SP_loop2:
4435     ldr r0, [r1, #SP_SR]
4436     tst r0, #SP_TDRE
4437     beq SP_loop2
4438 
4439     ldr r0, [r1, #SP_RDR]
4440 SP_loop3:
4441     ldr r0, [r1, #SP_SR]
4442     tst r0, #SP_RDRF
4443     beq SP_loop3
4444 
4445     ldr r0, [r1, #SP_RDR]
4446     and r0, r0, #255
4447     bx  lr
4448 .endfunc
4449 
4450 .func NVRAM_Xfer, NVRAM_XFER
4451     /* r0 = dest address */
4452     /* r1 = not used */
4453     /* r2 = src address within NVRAM */
4454     /* r3 = length */
4455 NVRAM_XFER:
4456     stmdb   sp!, {r4, r5, lr}
4457     mov r5, r0      /* save r0 (dest address) */
4458     mov r4, r3      /* save r3 (length) */
4459     mov r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
4460     and r0, r0, #8
4461     add r0, r0, #NVRAM_CMD_READ
4462     ldr r1, =NVRAM_SCRATCH
4463     strb    r0, [r1, #0]    /* save command in NVRAM_SCRATCH[0] */
4464     strb    r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
4465 _local1:
4466     bl  NVRAM_INIT
4467     tst r0, #NVRAM_SR_RDY
4468     bne _local1
4469     mov r0, #20
4470     bl  DELAY9
4471     mov r2, r4      /* length */
4472     mov r1, r5      /* dest address */
4473     mov r0, #2      /* bytes to transfer in command */
4474     bl  NVRAM_XFER2
4475     ldmia   sp!, {r4, r5, lr}
4476     bx  lr
4477 .endfunc
4478 
4479 .func NVRAM_Xfer2, NVRAM_XFER2
4480 NVRAM_XFER2:
4481     stmdb   sp!, {r4, r5, r6, lr}
4482     ldr r4, =SP_BASE
4483     mov r3, #0
4484     cmp r0, #0
4485     bls _local2
4486     ldr r5, =NVRAM_SCRATCH
4487 _local4:
4488     ldrb    r6, [r5, r3]
4489     str r6, [r4, #SP_TDR]
4490 _local3:
4491     ldr r6, [r4, #SP_SR]
4492     tst r6, #SP_TDRE
4493     beq _local3
4494     add r3, r3, #1
4495     cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */
4496     blo _local4
4497 _local2:
4498     mov r3, #SPI_8CLOCKS
4499     str r3, [r4, #SP_TDR]
4500     ldr r0, [r4, #SP_RDR]
4501 _local5:
4502     ldr r0, [r4, #SP_SR]
4503     tst r0, #SP_RDRF
4504     beq _local5
4505     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 */
4506     mov r0, #0
4507     cmp r2, #0  /* r2 is # of bytes to copy in */
4508     bls _local6
4509 _local7:
4510     ldr r5, [r4, #SP_SR]
4511     tst r5, #SP_TDRE
4512     beq _local7
4513     str r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
4514 _local8:
4515     ldr r5, [r4, #SP_SR]
4516     tst r5, #SP_RDRF
4517     beq _local8
4518     ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4519     strb    r5, [r1], #1 /* postindexed */
4520     add r0, r0, #1
4521     cmp r0, r2
4522     blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4523 _local6:
4524     mov r0, #200
4525     bl  DELAY9
4526     ldmia   sp!, {r4, r5, r6, lr}
4527     bx  lr
4528 #endif