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

source code of linux/drivers/net/wireless/atmel/atmel.c