OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [wireless/] [atmel.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.