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