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