1 /*======================================================================
2 
3     Aironet driver for 4500 and 4800 series cards
4 
5     This code is released under both the GPL version 2 and BSD licenses.
6     Either license may be used.  The respective licenses are found at
7     the end of this file.
8 
9     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10     including portions of which come from the Aironet PC4500
11     Developer's Reference Manual and used with permission.  Copyright
12     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
13     code in the Developer's manual was granted for this driver by
14     Aironet.  Major code contributions were received from Javier Achirica
15     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
16     Code was also integrated from the Cisco Aironet driver for Linux.
17 
18 ======================================================================*/
19 
20 #include <linux/config.h>
21 #include <linux/init.h>
22 
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/proc_fs.h>
26 
27 #include <linux/sched.h>
28 #include <linux/ptrace.h>
29 #include <linux/slab.h>
30 #include <linux/string.h>
31 #include <linux/timer.h>
32 #include <linux/interrupt.h>
33 #include <linux/in.h>
34 #include <asm/io.h>
35 #include <asm/system.h>
36 #include <asm/bitops.h>
37 
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40 #include <linux/skbuff.h>
41 #include <linux/if_arp.h>
42 #include <linux/ioport.h>
43 #include <linux/pci.h>
44 #include <asm/uaccess.h>
45 
46 #include "airo.h"
47 
48 #ifdef CONFIG_PCI
49 static struct pci_device_id card_ids[] = {
50 	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
51 	{ 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
52 	{ 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
53 	{ 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
54 	{ 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
55 	{ 0, }
56 };
57 MODULE_DEVICE_TABLE(pci, card_ids);
58 
59 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
60 static void airo_pci_remove(struct pci_dev *);
61 
62 static struct pci_driver airo_driver = {
63 	.name     = "airo",
64 	.id_table = card_ids,
65 	.probe    = airo_pci_probe,
66 	.remove   = __devexit_p(airo_pci_remove),
67 };
68 #endif /* CONFIG_PCI */
69 
70 /* Include Wireless Extension definition and check version - Jean II */
71 #include <linux/wireless.h>
72 #define WIRELESS_SPY		// enable iwspy support
73 #if WIRELESS_EXT > 12
74 #include <net/iw_handler.h>	// New driver API
75 #endif	/* WIRELESS_EXT > 12 */
76 
77 #define CISCO_EXT		// enable Cisco extensions
78 #ifdef CISCO_EXT
79 #include <linux/delay.h>
80 #endif
81 
82 /* Support Cisco MIC feature */
83 #define MICSUPPORT
84 
85 #if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO)
86 #warning MIC support requires Crypto API
87 #undef MICSUPPORT
88 #endif
89 
90 /* Hack to do some power saving */
91 #define POWER_ON_DOWN
92 
93 /* As you can see this list is HUGH!
94    I really don't know what a lot of these counts are about, but they
95    are all here for completeness.  If the IGNLABEL macro is put in
96    infront of the label, that statistic will not be included in the list
97    of statistics in the /proc filesystem */
98 
99 #define IGNLABEL(comment) 0
100 static char *statsLabels[] = {
101 	"RxOverrun",
102 	IGNLABEL("RxPlcpCrcErr"),
103 	IGNLABEL("RxPlcpFormatErr"),
104 	IGNLABEL("RxPlcpLengthErr"),
105 	"RxMacCrcErr",
106 	"RxMacCrcOk",
107 	"RxWepErr",
108 	"RxWepOk",
109 	"RetryLong",
110 	"RetryShort",
111 	"MaxRetries",
112 	"NoAck",
113 	"NoCts",
114 	"RxAck",
115 	"RxCts",
116 	"TxAck",
117 	"TxRts",
118 	"TxCts",
119 	"TxMc",
120 	"TxBc",
121 	"TxUcFrags",
122 	"TxUcPackets",
123 	"TxBeacon",
124 	"RxBeacon",
125 	"TxSinColl",
126 	"TxMulColl",
127 	"DefersNo",
128 	"DefersProt",
129 	"DefersEngy",
130 	"DupFram",
131 	"RxFragDisc",
132 	"TxAged",
133 	"RxAged",
134 	"LostSync-MaxRetry",
135 	"LostSync-MissedBeacons",
136 	"LostSync-ArlExceeded",
137 	"LostSync-Deauth",
138 	"LostSync-Disassoced",
139 	"LostSync-TsfTiming",
140 	"HostTxMc",
141 	"HostTxBc",
142 	"HostTxUc",
143 	"HostTxFail",
144 	"HostRxMc",
145 	"HostRxBc",
146 	"HostRxUc",
147 	"HostRxDiscard",
148 	IGNLABEL("HmacTxMc"),
149 	IGNLABEL("HmacTxBc"),
150 	IGNLABEL("HmacTxUc"),
151 	IGNLABEL("HmacTxFail"),
152 	IGNLABEL("HmacRxMc"),
153 	IGNLABEL("HmacRxBc"),
154 	IGNLABEL("HmacRxUc"),
155 	IGNLABEL("HmacRxDiscard"),
156 	IGNLABEL("HmacRxAccepted"),
157 	"SsidMismatch",
158 	"ApMismatch",
159 	"RatesMismatch",
160 	"AuthReject",
161 	"AuthTimeout",
162 	"AssocReject",
163 	"AssocTimeout",
164 	IGNLABEL("ReasonOutsideTable"),
165 	IGNLABEL("ReasonStatus1"),
166 	IGNLABEL("ReasonStatus2"),
167 	IGNLABEL("ReasonStatus3"),
168 	IGNLABEL("ReasonStatus4"),
169 	IGNLABEL("ReasonStatus5"),
170 	IGNLABEL("ReasonStatus6"),
171 	IGNLABEL("ReasonStatus7"),
172 	IGNLABEL("ReasonStatus8"),
173 	IGNLABEL("ReasonStatus9"),
174 	IGNLABEL("ReasonStatus10"),
175 	IGNLABEL("ReasonStatus11"),
176 	IGNLABEL("ReasonStatus12"),
177 	IGNLABEL("ReasonStatus13"),
178 	IGNLABEL("ReasonStatus14"),
179 	IGNLABEL("ReasonStatus15"),
180 	IGNLABEL("ReasonStatus16"),
181 	IGNLABEL("ReasonStatus17"),
182 	IGNLABEL("ReasonStatus18"),
183 	IGNLABEL("ReasonStatus19"),
184 	"RxMan",
185 	"TxMan",
186 	"RxRefresh",
187 	"TxRefresh",
188 	"RxPoll",
189 	"TxPoll",
190 	"HostRetries",
191 	"LostSync-HostReq",
192 	"HostTxBytes",
193 	"HostRxBytes",
194 	"ElapsedUsec",
195 	"ElapsedSec",
196 	"LostSyncBetterAP",
197 	"PrivacyMismatch",
198 	"Jammed",
199 	"DiscRxNotWepped",
200 	"PhyEleMismatch",
201 	(char*)-1 };
202 #ifndef RUN_AT
203 #define RUN_AT(x) (jiffies+(x))
204 #endif
205 
206 
207 /* These variables are for insmod, since it seems that the rates
208    can only be set in setup_card.  Rates should be a comma separated
209    (no spaces) list of rates (up to 8). */
210 
211 static int rates[8];
212 static int basic_rate;
213 static char *ssids[3];
214 
215 static int io[4];
216 static int irq[4];
217 
218 static
219 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
220 		       0 means no limit.  For old cards this was 4 */
221 
222 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
223 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
224 		    the bap, needed on some older cards and buses. */
225 static int adhoc;
226 
227 static int probe = 1;
228 
229 static int proc_uid /* = 0 */;
230 
231 static int proc_gid /* = 0 */;
232 
233 static int airo_perm = 0555;
234 
235 static int proc_perm = 0644;
236 
237 MODULE_AUTHOR("Benjamin Reed");
238 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
239                    cards.  Direct support for ISA/PCI cards and support \
240 		   for PCMCIA when used with airo_cs.");
241 MODULE_LICENSE("Dual BSD/GPL");
242 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340");
243 MODULE_PARM(io,"1-4i");
244 MODULE_PARM(irq,"1-4i");
245 MODULE_PARM(basic_rate,"i");
246 MODULE_PARM(rates,"1-8i");
247 MODULE_PARM(ssids,"1-3s");
248 MODULE_PARM(auto_wep,"i");
249 MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
250 the authentication options until an association is made.  The value of \
251 auto_wep is number of the wep keys to check.  A value of 2 will try using \
252 the key at index 0 and index 1.");
253 MODULE_PARM(aux_bap,"i");
254 MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
255 than seems to work better for older cards with some older buses.  Before \
256 switching it checks that the switch is needed.");
257 MODULE_PARM(maxencrypt, "i");
258 MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
259 encryption.  Units are in 512kbs.  Zero (default) means there is no limit. \
260 Older cards used to be limited to 2mbs (4).");
261 MODULE_PARM(adhoc, "i");
262 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
263 MODULE_PARM(probe, "i");
264 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
265 
266 MODULE_PARM(proc_uid, "i");
267 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
268 MODULE_PARM(proc_gid, "i");
269 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
270 MODULE_PARM(airo_perm, "i");
271 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
272 MODULE_PARM(proc_perm, "i");
273 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
274 
275 /* This is a kind of sloppy hack to get this information to OUT4500 and
276    IN4500.  I would be extremely interested in the situation where this
277    doesn't work though!!! */
278 static int do8bitIO = 0;
279 
280 /* Return codes */
281 #define SUCCESS 0
282 #define ERROR -1
283 #define NO_PACKET -2
284 
285 /* Commands */
286 #define NOP2		0x0000
287 #define MAC_ENABLE	0x0001
288 #define MAC_DISABLE	0x0002
289 #define CMD_LOSE_SYNC	0x0003 /* Not sure what this does... */
290 #define CMD_SOFTRESET	0x0004
291 #define HOSTSLEEP	0x0005
292 #define CMD_MAGIC_PKT	0x0006
293 #define CMD_SETWAKEMASK	0x0007
294 #define CMD_READCFG	0x0008
295 #define CMD_SETMODE	0x0009
296 #define CMD_ALLOCATETX	0x000a
297 #define CMD_TRANSMIT	0x000b
298 #define CMD_DEALLOCATETX 0x000c
299 #define NOP		0x0010
300 #define CMD_WORKAROUND	0x0011
301 #define CMD_ALLOCATEAUX 0x0020
302 #define CMD_ACCESS	0x0021
303 #define CMD_PCIBAP	0x0022
304 #define CMD_PCIAUX	0x0023
305 #define CMD_ALLOCBUF	0x0028
306 #define CMD_GETTLV	0x0029
307 #define CMD_PUTTLV	0x002a
308 #define CMD_DELTLV	0x002b
309 #define CMD_FINDNEXTTLV	0x002c
310 #define CMD_PSPNODES	0x0030
311 #define CMD_SETCW	0x0031
312 #define CMD_SETPCF	0x0032
313 #define CMD_SETPHYREG	0x003e
314 #define CMD_TXTEST	0x003f
315 #define MAC_ENABLETX	0x0101
316 #define CMD_LISTBSS	0x0103
317 #define CMD_SAVECFG	0x0108
318 #define CMD_ENABLEAUX	0x0111
319 #define CMD_WRITERID	0x0121
320 #define CMD_USEPSPNODES	0x0130
321 #define MAC_ENABLERX	0x0201
322 
323 /* Command errors */
324 #define ERROR_QUALIF 0x00
325 #define ERROR_ILLCMD 0x01
326 #define ERROR_ILLFMT 0x02
327 #define ERROR_INVFID 0x03
328 #define ERROR_INVRID 0x04
329 #define ERROR_LARGE 0x05
330 #define ERROR_NDISABL 0x06
331 #define ERROR_ALLOCBSY 0x07
332 #define ERROR_NORD 0x0B
333 #define ERROR_NOWR 0x0C
334 #define ERROR_INVFIDTX 0x0D
335 #define ERROR_TESTACT 0x0E
336 #define ERROR_TAGNFND 0x12
337 #define ERROR_DECODE 0x20
338 #define ERROR_DESCUNAV 0x21
339 #define ERROR_BADLEN 0x22
340 #define ERROR_MODE 0x80
341 #define ERROR_HOP 0x81
342 #define ERROR_BINTER 0x82
343 #define ERROR_RXMODE 0x83
344 #define ERROR_MACADDR 0x84
345 #define ERROR_RATES 0x85
346 #define ERROR_ORDER 0x86
347 #define ERROR_SCAN 0x87
348 #define ERROR_AUTH 0x88
349 #define ERROR_PSMODE 0x89
350 #define ERROR_RTYPE 0x8A
351 #define ERROR_DIVER 0x8B
352 #define ERROR_SSID 0x8C
353 #define ERROR_APLIST 0x8D
354 #define ERROR_AUTOWAKE 0x8E
355 #define ERROR_LEAP 0x8F
356 
357 /* Registers */
358 #define COMMAND 0x00
359 #define PARAM0 0x02
360 #define PARAM1 0x04
361 #define PARAM2 0x06
362 #define STATUS 0x08
363 #define RESP0 0x0a
364 #define RESP1 0x0c
365 #define RESP2 0x0e
366 #define LINKSTAT 0x10
367 #define SELECT0 0x18
368 #define OFFSET0 0x1c
369 #define RXFID 0x20
370 #define TXALLOCFID 0x22
371 #define TXCOMPLFID 0x24
372 #define DATA0 0x36
373 #define EVSTAT 0x30
374 #define EVINTEN 0x32
375 #define EVACK 0x34
376 #define SWS0 0x28
377 #define SWS1 0x2a
378 #define SWS2 0x2c
379 #define SWS3 0x2e
380 #define AUXPAGE 0x3A
381 #define AUXOFF 0x3C
382 #define AUXDATA 0x3E
383 
384 /* BAP selectors */
385 #define BAP0 0 // Used for receiving packets
386 #define BAP1 2 // Used for xmiting packets and working with RIDS
387 
388 /* Flags */
389 #define COMMAND_BUSY 0x8000
390 
391 #define BAP_BUSY 0x8000
392 #define BAP_ERR 0x4000
393 #define BAP_DONE 0x2000
394 
395 #define PROMISC 0xffff
396 #define NOPROMISC 0x0000
397 
398 #define EV_CMD 0x10
399 #define EV_CLEARCOMMANDBUSY 0x4000
400 #define EV_RX 0x01
401 #define EV_TX 0x02
402 #define EV_TXEXC 0x04
403 #define EV_ALLOC 0x08
404 #define EV_LINK 0x80
405 #define EV_AWAKE 0x100
406 #define EV_TXCPY 0x400
407 #define EV_UNKNOWN 0x800
408 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
409 #define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX | EV_MIC )
410 
411 #ifdef CHECK_UNKNOWN_INTS
412 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
413 #else
414 #define IGNORE_INTS (~STATUS_INTS)
415 #endif
416 
417 /* The RIDs */
418 #define RID_CAPABILITIES 0xFF00
419 #define RID_APINFO     0xFF01
420 #define RID_RADIOINFO  0xFF02
421 #define RID_UNKNOWN3   0xFF03
422 #define RID_RSSI       0xFF04
423 #define RID_CONFIG     0xFF10
424 #define RID_SSID       0xFF11
425 #define RID_APLIST     0xFF12
426 #define RID_DRVNAME    0xFF13
427 #define RID_ETHERENCAP 0xFF14
428 #define RID_WEP_TEMP   0xFF15
429 #define RID_WEP_PERM   0xFF16
430 #define RID_MODULATION 0xFF17
431 #define RID_OPTIONS    0xFF18
432 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
433 #define RID_FACTORYCONFIG 0xFF21
434 #define RID_UNKNOWN22  0xFF22
435 #define RID_LEAPUSERNAME 0xFF23
436 #define RID_LEAPPASSWORD 0xFF24
437 #define RID_STATUS     0xFF50
438 #define RID_BEACON_HST 0xFF51
439 #define RID_BUSY_HST   0xFF52
440 #define RID_RETRIES_HST 0xFF53
441 #define RID_UNKNOWN54  0xFF54
442 #define RID_UNKNOWN55  0xFF55
443 #define RID_UNKNOWN56  0xFF56
444 #define RID_MIC        0xFF57
445 #define RID_STATS16    0xFF60
446 #define RID_STATS16DELTA 0xFF61
447 #define RID_STATS16DELTACLEAR 0xFF62
448 #define RID_STATS      0xFF68
449 #define RID_STATSDELTA 0xFF69
450 #define RID_STATSDELTACLEAR 0xFF6A
451 #define RID_ECHOTEST_RID 0xFF70
452 #define RID_ECHOTEST_RESULTS 0xFF71
453 #define RID_BSSLISTFIRST 0xFF72
454 #define RID_BSSLISTNEXT  0xFF73
455 
456 typedef struct {
457 	u16 cmd;
458 	u16 parm0;
459 	u16 parm1;
460 	u16 parm2;
461 } Cmd;
462 
463 typedef struct {
464 	u16 status;
465 	u16 rsp0;
466 	u16 rsp1;
467 	u16 rsp2;
468 } Resp;
469 
470 /*
471  * Rids and endian-ness:  The Rids will always be in cpu endian, since
472  * this all the patches from the big-endian guys end up doing that.
473  * so all rid access should use the read/writeXXXRid routines.
474  */
475 
476 /* This is redundant for x86 archs, but it seems necessary for ARM */
477 #pragma pack(1)
478 
479 /* This structure came from an email sent to me from an engineer at
480    aironet for inclusion into this driver */
481 typedef struct {
482 	u16 len;
483 	u16 kindex;
484 	u8 mac[ETH_ALEN];
485 	u16 klen;
486 	u8 key[16];
487 } WepKeyRid;
488 
489 /* These structures are from the Aironet's PC4500 Developers Manual */
490 typedef struct {
491 	u16 len;
492 	u8 ssid[32];
493 } Ssid;
494 
495 typedef struct {
496 	u16 len;
497 	Ssid ssids[3];
498 } SsidRid;
499 
500 typedef struct {
501         u16 len;
502         u16 modulation;
503 #define MOD_DEFAULT 0
504 #define MOD_CCK 1
505 #define MOD_MOK 2
506 } ModulationRid;
507 
508 typedef struct {
509 	u16 len; /* sizeof(ConfigRid) */
510 	u16 opmode; /* operating mode */
511 #define MODE_STA_IBSS 0
512 #define MODE_STA_ESS 1
513 #define MODE_AP 2
514 #define MODE_AP_RPTR 3
515 #define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
516 #define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
517 #define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
518 #define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
519 #define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
520 #define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
521 #define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
522 #define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
523 #define MODE_MIC (1<<15) /* enable MIC */
524 	u16 rmode; /* receive mode */
525 #define RXMODE_BC_MC_ADDR 0
526 #define RXMODE_BC_ADDR 1 /* ignore multicasts */
527 #define RXMODE_ADDR 2 /* ignore multicast and broadcast */
528 #define RXMODE_RFMON 3 /* wireless monitor mode */
529 #define RXMODE_RFMON_ANYBSS 4
530 #define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
531 #define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
532 #define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
533 	u16 fragThresh;
534 	u16 rtsThres;
535 	u8 macAddr[ETH_ALEN];
536 	u8 rates[8];
537 	u16 shortRetryLimit;
538 	u16 longRetryLimit;
539 	u16 txLifetime; /* in kusec */
540 	u16 rxLifetime; /* in kusec */
541 	u16 stationary;
542 	u16 ordering;
543 	u16 u16deviceType; /* for overriding device type */
544 	u16 cfpRate;
545 	u16 cfpDuration;
546 	u16 _reserved1[3];
547 	/*---------- Scanning/Associating ----------*/
548 	u16 scanMode;
549 #define SCANMODE_ACTIVE 0
550 #define SCANMODE_PASSIVE 1
551 #define SCANMODE_AIROSCAN 2
552 	u16 probeDelay; /* in kusec */
553 	u16 probeEnergyTimeout; /* in kusec */
554         u16 probeResponseTimeout;
555 	u16 beaconListenTimeout;
556 	u16 joinNetTimeout;
557 	u16 authTimeout;
558 	u16 authType;
559 #define AUTH_OPEN 0x1
560 #define AUTH_ENCRYPT 0x101
561 #define AUTH_SHAREDKEY 0x102
562 #define AUTH_ALLOW_UNENCRYPTED 0x200
563 	u16 associationTimeout;
564 	u16 specifiedApTimeout;
565 	u16 offlineScanInterval;
566 	u16 offlineScanDuration;
567 	u16 linkLossDelay;
568 	u16 maxBeaconLostTime;
569 	u16 refreshInterval;
570 #define DISABLE_REFRESH 0xFFFF
571 	u16 _reserved1a[1];
572 	/*---------- Power save operation ----------*/
573 	u16 powerSaveMode;
574 #define POWERSAVE_CAM 0
575 #define POWERSAVE_PSP 1
576 #define POWERSAVE_PSPCAM 2
577 	u16 sleepForDtims;
578 	u16 listenInterval;
579 	u16 fastListenInterval;
580 	u16 listenDecay;
581 	u16 fastListenDelay;
582 	u16 _reserved2[2];
583 	/*---------- Ap/Ibss config items ----------*/
584 	u16 beaconPeriod;
585 	u16 atimDuration;
586 	u16 hopPeriod;
587 	u16 channelSet;
588 	u16 channel;
589 	u16 dtimPeriod;
590 	u16 bridgeDistance;
591 	u16 radioID;
592 	/*---------- Radio configuration ----------*/
593 	u16 radioType;
594 #define RADIOTYPE_DEFAULT 0
595 #define RADIOTYPE_802_11 1
596 #define RADIOTYPE_LEGACY 2
597 	u8 rxDiversity;
598 	u8 txDiversity;
599 	u16 txPower;
600 #define TXPOWER_DEFAULT 0
601 	u16 rssiThreshold;
602 #define RSSI_DEFAULT 0
603         u16 modulation;
604 #define PREAMBLE_AUTO 0
605 #define PREAMBLE_LONG 1
606 #define PREAMBLE_SHORT 2
607 	u16 preamble;
608 	u16 homeProduct;
609 	u16 radioSpecific;
610 	/*---------- Aironet Extensions ----------*/
611 	u8 nodeName[16];
612 	u16 arlThreshold;
613 	u16 arlDecay;
614 	u16 arlDelay;
615 	u16 _reserved4[1];
616 	/*---------- Aironet Extensions ----------*/
617 	u8 magicAction;
618 #define MAGIC_ACTION_STSCHG 1
619 #define MACIC_ACTION_RESUME 2
620 #define MAGIC_IGNORE_MCAST (1<<8)
621 #define MAGIC_IGNORE_BCAST (1<<9)
622 #define MAGIC_SWITCH_TO_PSP (0<<10)
623 #define MAGIC_STAY_IN_CAM (1<<10)
624 	u8 magicControl;
625 	u16 autoWake;
626 } ConfigRid;
627 
628 typedef struct {
629 	u16 len;
630 	u8 mac[ETH_ALEN];
631 	u16 mode;
632 	u16 errorCode;
633 	u16 sigQuality;
634 	u16 SSIDlen;
635 	char SSID[32];
636 	char apName[16];
637 	u8 bssid[4][ETH_ALEN];
638 	u16 beaconPeriod;
639 	u16 dimPeriod;
640 	u16 atimDuration;
641 	u16 hopPeriod;
642 	u16 channelSet;
643 	u16 channel;
644 	u16 hopsToBackbone;
645 	u16 apTotalLoad;
646 	u16 generatedLoad;
647 	u16 accumulatedArl;
648 	u16 signalQuality;
649 	u16 currentXmitRate;
650 	u16 apDevExtensions;
651 	u16 normalizedSignalStrength;
652 	u16 shortPreamble;
653 	u8 apIP[4];
654 	u8 noisePercent; /* Noise percent in last second */
655 	u8 noisedBm; /* Noise dBm in last second */
656 	u8 noiseAvePercent; /* Noise percent in last minute */
657 	u8 noiseAvedBm; /* Noise dBm in last minute */
658 	u8 noiseMaxPercent; /* Highest noise percent in last minute */
659 	u8 noiseMaxdBm; /* Highest noise dbm in last minute */
660 	u16 load;
661 	u8 carrier[4];
662 	u16 assocStatus;
663 #define STAT_NOPACKETS 0
664 #define STAT_NOCARRIERSET 10
665 #define STAT_GOTCARRIERSET 11
666 #define STAT_WRONGSSID 20
667 #define STAT_BADCHANNEL 25
668 #define STAT_BADBITRATES 30
669 #define STAT_BADPRIVACY 35
670 #define STAT_APFOUND 40
671 #define STAT_APREJECTED 50
672 #define STAT_AUTHENTICATING 60
673 #define STAT_DEAUTHENTICATED 61
674 #define STAT_AUTHTIMEOUT 62
675 #define STAT_ASSOCIATING 70
676 #define STAT_DEASSOCIATED 71
677 #define STAT_ASSOCTIMEOUT 72
678 #define STAT_NOTAIROAP 73
679 #define STAT_ASSOCIATED 80
680 #define STAT_LEAPING 90
681 #define STAT_LEAPFAILED 91
682 #define STAT_LEAPTIMEDOUT 92
683 #define STAT_LEAPCOMPLETE 93
684 } StatusRid;
685 
686 typedef struct {
687 	u16 len;
688 	u16 spacer;
689 	u32 vals[100];
690 } StatsRid;
691 
692 
693 typedef struct {
694 	u16 len;
695 	u8 ap[4][ETH_ALEN];
696 } APListRid;
697 
698 typedef struct {
699 	u16 len;
700 	char oui[3];
701 	char zero;
702 	u16 prodNum;
703 	char manName[32];
704 	char prodName[16];
705 	char prodVer[8];
706 	char factoryAddr[ETH_ALEN];
707 	char aironetAddr[ETH_ALEN];
708 	u16 radioType;
709 	u16 country;
710 	char callid[ETH_ALEN];
711 	char supportedRates[8];
712 	char rxDiversity;
713 	char txDiversity;
714 	u16 txPowerLevels[8];
715 	u16 hardVer;
716 	u16 hardCap;
717 	u16 tempRange;
718 	u16 softVer;
719 	u16 softSubVer;
720 	u16 interfaceVer;
721 	u16 softCap;
722 	u16 bootBlockVer;
723 	u16 requiredHard;
724 	u16 extSoftCap;
725 } CapabilityRid;
726 
727 typedef struct {
728   u16 len;
729   u16 index; /* First is 0 and 0xffff means end of list */
730 #define RADIO_FH 1 /* Frequency hopping radio type */
731 #define RADIO_DS 2 /* Direct sequence radio type */
732 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
733   u16 radioType;
734   u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
735   u8 zero;
736   u8 ssidLen;
737   u8 ssid[32];
738   u16 rssi;
739 #define CAP_ESS (1<<0)
740 #define CAP_IBSS (1<<1)
741 #define CAP_PRIVACY (1<<4)
742 #define CAP_SHORTHDR (1<<5)
743   u16 cap;
744   u16 beaconInterval;
745   u8 rates[8]; /* Same as rates for config rid */
746   struct { /* For frequency hopping only */
747     u16 dwell;
748     u8 hopSet;
749     u8 hopPattern;
750     u8 hopIndex;
751     u8 fill;
752   } fh;
753   u16 dsChannel;
754   u16 atimWindow;
755 } BSSListRid;
756 
757 typedef struct {
758   u8 rssipct;
759   u8 rssidBm;
760 } tdsRssiEntry;
761 
762 typedef struct {
763   u16 len;
764   tdsRssiEntry x[256];
765 } tdsRssiRid;
766 
767 typedef struct {
768 	u16 len;
769 	u16 state;
770 	u16 multicastValid;
771 	u8  multicast[16];
772 	u16 unicastValid;
773 	u8  unicast[16];
774 } MICRid;
775 
776 typedef struct {
777 	u16 typelen;
778 
779 	union {
780 	    u8 snap[8];
781 	    struct {
782 		u8 dsap;
783 		u8 ssap;
784 		u8 control;
785 		u8 orgcode[3];
786 		u8 fieldtype[2];
787 	    } llc;
788 	} u;
789 	u32 mic;
790 	u32 seq;
791 } MICBuffer;
792 
793 typedef struct {
794 	u8 da[ETH_ALEN];
795 	u8 sa[ETH_ALEN];
796 } etherHead;
797 
798 #pragma pack()
799 
800 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
801 #define TXCTL_TXEX (1<<2) /* report if tx fails */
802 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
803 #define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
804 #define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
805 #define TXCTL_LLC (1<<4) /* payload is llc */
806 #define TXCTL_RELEASE (0<<5) /* release after completion */
807 #define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
808 
809 #define BUSY_FID 0x10000
810 
811 #ifdef CISCO_EXT
812 #define AIROMAGIC	0xa55a
813 /* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
814 #ifdef SIOCIWFIRSTPRIV
815 #ifdef SIOCDEVPRIVATE
816 #define AIROOLDIOCTL	SIOCDEVPRIVATE
817 #define AIROOLDIDIFC 	AIROOLDIOCTL + 1
818 #endif /* SIOCDEVPRIVATE */
819 #else /* SIOCIWFIRSTPRIV */
820 #define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
821 #endif /* SIOCIWFIRSTPRIV */
822 /* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
823  * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
824  * only and don't return the modified struct ifreq to the application which
825  * is usually a problem. - Jean II */
826 #define AIROIOCTL	SIOCIWFIRSTPRIV
827 #define AIROIDIFC 	AIROIOCTL + 1
828 
829 /* Ioctl constants to be used in airo_ioctl.command */
830 
831 #define	AIROGCAP  		0	// Capability rid
832 #define AIROGCFG		1       // USED A LOT
833 #define AIROGSLIST		2	// System ID list
834 #define AIROGVLIST		3       // List of specified AP's
835 #define AIROGDRVNAM		4	//  NOTUSED
836 #define AIROGEHTENC		5	// NOTUSED
837 #define AIROGWEPKTMP		6
838 #define AIROGWEPKNV		7
839 #define AIROGSTAT		8
840 #define AIROGSTATSC32		9
841 #define AIROGSTATSD32		10
842 #define AIROGMICRID		11
843 #define AIROGMICSTATS		12
844 #define AIROGFLAGS		13
845 #define AIRORRID		15
846 
847 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
848 
849 #define AIROPCAP               	AIROGSTATSD32 + 40
850 #define AIROPVLIST              AIROPCAP      + 1
851 #define AIROPSLIST		AIROPVLIST    + 1
852 #define AIROPCFG		AIROPSLIST    + 1
853 #define AIROPSIDS		AIROPCFG      + 1
854 #define AIROPAPLIST		AIROPSIDS     + 1
855 #define AIROPMACON		AIROPAPLIST   + 1	/* Enable mac  */
856 #define AIROPMACOFF		AIROPMACON    + 1 	/* Disable mac */
857 #define AIROPSTCLR		AIROPMACOFF   + 1
858 #define AIROPWEPKEY		AIROPSTCLR    + 1
859 #define AIROPWEPKEYNV		AIROPWEPKEY   + 1
860 #define AIROPLEAPPWD            AIROPWEPKEYNV + 1
861 #define AIROPLEAPUSR            AIROPLEAPPWD  + 1
862 
863 /* Flash codes */
864 
865 #define AIROFLSHRST	       AIROPWEPKEYNV  + 40
866 #define AIROFLSHGCHR           AIROFLSHRST    + 1
867 #define AIROFLSHSTFL           AIROFLSHGCHR   + 1
868 #define AIROFLSHPCHR           AIROFLSHSTFL   + 1
869 #define AIROFLPUTBUF           AIROFLSHPCHR   + 1
870 #define AIRORESTART            AIROFLPUTBUF   + 1
871 
872 #define FLASHSIZE	32768
873 
874 typedef struct aironet_ioctl {
875 	unsigned short command;	// What to do
876 	unsigned short len;		// Len of data
877 	unsigned char *data;		// d-data
878 } aironet_ioctl;
879 #endif /* CISCO_EXT */
880 
881 #define NUM_MODULES       2
882 #define MIC_MSGLEN_MAX    2400
883 #define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
884 
885 typedef struct {
886 	u32   size;            // size
887 	u8    enabled;         // MIC enabled or not
888 	u32   rxSuccess;       // successful packets received
889 	u32   rxIncorrectMIC;  // pkts dropped due to incorrect MIC comparison
890 	u32   rxNotMICed;      // pkts dropped due to not being MIC'd
891 	u32   rxMICPlummed;    // pkts dropped due to not having a MIC plummed
892 	u32   rxWrongSequence; // pkts dropped due to sequence number violation
893 	u32   reserve[32];
894 } mic_statistics;
895 
896 typedef struct {
897 	u32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
898 	u64 accum;	// accumulated mic, reduced to u32 in final()
899 	int position;	// current position (byte offset) in message
900 	union {
901 		u8  d8[4];
902 		u32 d32;
903 	} part;	// saves partial message word across update() calls
904 } emmh32_context;
905 
906 typedef struct {
907 	emmh32_context seed;	    // Context - the seed
908 	u32		 rx;	    // Received sequence number
909 	u32		 tx;	    // Tx sequence number
910 	u32		 window;    // Start of window
911 	u8		 valid;	    // Flag to say if context is valid or not
912 	u8		 key[16];
913 } miccntx;
914 
915 typedef struct {
916 	miccntx mCtx;		// Multicast context
917 	miccntx uCtx;		// Unicast context
918 } mic_module;
919 
920 #ifdef WIRELESS_EXT
921 // Frequency list (map channels to frequencies)
922 static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
923 				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
924 
925 // A few details needed for WEP (Wireless Equivalent Privacy)
926 #define MAX_KEY_SIZE 13			// 128 (?) bits
927 #define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
928 typedef struct wep_key_t {
929 	u16	len;
930 	u8	key[16];	/* 40-bit and 104-bit keys */
931 } wep_key_t;
932 
933 /* Backward compatibility */
934 #ifndef IW_ENCODE_NOKEY
935 #define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */
936 #define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
937 #endif /* IW_ENCODE_NOKEY */
938 
939 #if WIRELESS_EXT > 12
940 /* List of Wireless Handlers (new API) */
941 static const struct iw_handler_def	airo_handler_def;
942 #else	/* WIRELESS_EXT > 12 */
943 /* More Wireless Extensions backward compatibility */
944 /* Part of iw_handler prototype we need (apart that we don't need it) */
945 struct iw_request_info {};
946 #endif	/* WIRELESS_EXT > 12 */
947 #endif /* WIRELESS_EXT */
948 
949 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
950 
951 struct airo_info;
952 
953 static int get_dec_u16( char *buffer, int *start, int limit );
954 static void OUT4500( struct airo_info *, u16 register, u16 value );
955 static unsigned short IN4500( struct airo_info *, u16 register );
956 static u16 setup_card(struct airo_info*, u8 *mac);
957 static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock );
958 static void disable_MAC(struct airo_info *ai, int lock);
959 static void enable_interrupts(struct airo_info*);
960 static void disable_interrupts(struct airo_info*);
961 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
962 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
963 static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
964 			int whichbap);
965 static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
966 			 int whichbap);
967 static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
968 		     int whichbap);
969 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
970 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
971 static int PC4500_writerid(struct airo_info*, u16 rid, const void
972 			   *pBuf, int len, int lock);
973 static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
974 			int len, int dummy );
975 static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
976 static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
977 static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
978 
979 static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
980 			    *regs);
981 static int airo_thread(void *data);
982 static void timer_func( struct net_device *dev );
983 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
984 #ifdef WIRELESS_EXT
985 struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
986 static void airo_read_wireless_stats (struct airo_info *local);
987 #endif /* WIRELESS_EXT */
988 #ifdef CISCO_EXT
989 static int readrids(struct net_device *dev, aironet_ioctl *comp);
990 static int writerids(struct net_device *dev, aironet_ioctl *comp);
991 int flashcard(struct net_device *dev, aironet_ioctl *comp);
992 #endif /* CISCO_EXT */
993 #ifdef MICSUPPORT
994 static void micinit(struct airo_info *ai);
995 static int micsetup(struct airo_info *ai);
996 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
997 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
998 
999 #include <linux/crypto.h>
1000 #endif
1001 
1002 struct airo_info {
1003 	struct net_device_stats	stats;
1004 	int open;
1005 	struct net_device             *dev;
1006 	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
1007 	   use the high bit to mark whether it is in use. */
1008 #define MAX_FIDS 6
1009 	int                           fids[MAX_FIDS];
1010 	int registered;
1011 	ConfigRid config;
1012 	int need_commit;	// Need to set config
1013 	char keyindex; // Used with auto wep
1014 	char defindex; // Used with auto wep
1015 	struct proc_dir_entry *proc_entry;
1016 	struct airo_info *next;
1017         spinlock_t aux_lock;
1018         unsigned long flags;
1019 #define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
1020 #define FLAG_RADIO_OFF	0	/* User disabling of MAC */
1021 #define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */
1022 #define FLAG_RADIO_MASK 0x03
1023 #define FLAG_FLASHING	2
1024 #define FLAG_ADHOC	3	/* Needed by MIC */
1025 #define FLAG_MIC_CAPABLE 4
1026 #define FLAG_UPDATE_MULTI 5
1027 #define FLAG_UPDATE_UNI 6
1028 #define FLAG_802_11	7
1029 #define FLAG_PENDING_XMIT 9
1030 #define FLAG_PENDING_XMIT11 10
1031 #define FLAG_PCI	11
1032 #define JOB_MASK	0x1ff0000
1033 #define JOB_DIE		16
1034 #define JOB_XMIT	17
1035 #define JOB_XMIT11	18
1036 #define JOB_STATS	19
1037 #define JOB_PROMISC	20
1038 #define JOB_MIC		21
1039 #define JOB_EVENT	22
1040 #define JOB_AUTOWEP	23
1041 #define JOB_WSTATS	24
1042 	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
1043 			int whichbap);
1044 	unsigned short *flash;
1045 	tdsRssiEntry *rssi;
1046 	struct task_struct *task;
1047 	struct semaphore sem;
1048 	pid_t thr_pid;
1049 	wait_queue_head_t thr_wait;
1050 	struct completion thr_exited;
1051 	unsigned long expires;
1052 	struct {
1053 		struct sk_buff *skb;
1054 		int fid;
1055 	} xmit, xmit11;
1056 	struct net_device *wifidev;
1057 #ifdef WIRELESS_EXT
1058 	struct iw_statistics	wstats;		// wireless stats
1059 	unsigned long		scan_timestamp;	/* Time started to scan */
1060 #if WIRELESS_EXT > 15
1061 	struct iw_spy_data	spy_data;
1062 #else /* WIRELESS_EXT > 15 */
1063 #ifdef WIRELESS_SPY
1064 	int			spy_number;
1065 	u_char			spy_address[IW_MAX_SPY][ETH_ALEN];
1066 	struct iw_quality	spy_stat[IW_MAX_SPY];
1067 #endif /* WIRELESS_SPY */
1068 #endif /* WIRELESS_EXT > 15 */
1069 #endif /* WIRELESS_EXT */
1070 #ifdef MICSUPPORT
1071 	/* MIC stuff */
1072 	struct crypto_tfm	*tfm;
1073 	mic_module		mod[2];
1074 	mic_statistics		micstats;
1075 #endif
1076 };
1077 
bap_read(struct airo_info * ai,u16 * pu16Dst,int bytelen,int whichbap)1078 static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
1079 			   int whichbap) {
1080 	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
1081 }
1082 
1083 static int setup_proc_entry( struct net_device *dev,
1084 			     struct airo_info *apriv );
1085 static int takedown_proc_entry( struct net_device *dev,
1086 				struct airo_info *apriv );
1087 
1088 #ifdef MICSUPPORT
1089 /***********************************************************************
1090  *                              MIC ROUTINES                           *
1091  ***********************************************************************
1092  */
1093 
1094 static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
1095 static void MoveWindow(miccntx *context, u32 micSeq);
1096 void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *);
1097 void emmh32_init(emmh32_context *context);
1098 void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1099 void emmh32_final(emmh32_context *context, u8 digest[4]);
1100 
1101 /* micinit - Initialize mic seed */
1102 
micinit(struct airo_info * ai)1103 static void micinit(struct airo_info *ai)
1104 {
1105 	MICRid mic_rid;
1106 
1107 	clear_bit(JOB_MIC, &ai->flags);
1108 	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1109 	up(&ai->sem);
1110 
1111 	ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;
1112 
1113 	if (ai->micstats.enabled) {
1114 		/* Key must be valid and different */
1115 		if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||
1116 		    (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,
1117 			     sizeof(ai->mod[0].mCtx.key)) != 0))) {
1118 			/* Age current mic Context */
1119 			memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));
1120 			/* Initialize new context */
1121 			memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));
1122 			ai->mod[0].mCtx.window  = 33; //Window always points to the middle
1123 			ai->mod[0].mCtx.rx      = 0;  //Rx Sequence numbers
1124 			ai->mod[0].mCtx.tx      = 0;  //Tx sequence numbers
1125 			ai->mod[0].mCtx.valid   = 1;  //Key is now valid
1126 
1127 			/* Give key to mic seed */
1128 			emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);
1129 		}
1130 
1131 		/* Key must be valid and different */
1132 		if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid ||
1133 		    (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,
1134 			    sizeof(ai->mod[0].uCtx.key)) != 0))) {
1135 			/* Age current mic Context */
1136 			memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));
1137 			/* Initialize new context */
1138 			memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));
1139 
1140 			ai->mod[0].uCtx.window  = 33; //Window always points to the middle
1141 			ai->mod[0].uCtx.rx      = 0;  //Rx Sequence numbers
1142 			ai->mod[0].uCtx.tx      = 0;  //Tx sequence numbers
1143 			ai->mod[0].uCtx.valid   = 1;  //Key is now valid
1144 
1145 			//Give key to mic seed
1146 			emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);
1147 		}
1148 	} else {
1149       /* So next time we have a valid key and mic is enabled, we will update
1150        * the sequence number if the key is the same as before.
1151        */
1152 		ai->mod[0].uCtx.valid = 0;
1153 		ai->mod[0].mCtx.valid = 0;
1154 	}
1155 }
1156 
1157 /* micsetup - Get ready for business */
1158 
micsetup(struct airo_info * ai)1159 static int micsetup(struct airo_info *ai) {
1160 	int i;
1161 
1162 	if (ai->tfm == NULL)
1163 	        ai->tfm = crypto_alloc_tfm("aes", 0);
1164 
1165         if (ai->tfm == NULL) {
1166                 printk(KERN_ERR "airo: failed to load transform for AES\n");
1167                 return ERROR;
1168         }
1169 
1170 	for (i=0; i < NUM_MODULES; i++) {
1171 		memset(&ai->mod[i].mCtx,0,sizeof(miccntx));
1172 		memset(&ai->mod[i].uCtx,0,sizeof(miccntx));
1173 	}
1174 	return SUCCESS;
1175 }
1176 
1177 char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
1178 
1179 /*===========================================================================
1180  * Description: Mic a packet
1181  *
1182  *      Inputs: etherHead * pointer to an 802.3 frame
1183  *
1184  *     Returns: BOOLEAN if successful, otherwise false.
1185  *             PacketTxLen will be updated with the mic'd packets size.
1186  *
1187  *    Caveats: It is assumed that the frame buffer will already
1188  *             be big enough to hold the largets mic message possible.
1189  *            (No memory allocation is done here).
1190  *
1191  *    Author: sbraneky (10/15/01)
1192  *    Merciless hacks by rwilcher (1/14/02)
1193  */
1194 
encapsulate(struct airo_info * ai,etherHead * frame,MICBuffer * mic,int payLen)1195 static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen)
1196 {
1197 	miccntx   *context;
1198 
1199 	// Determine correct context
1200 	// If not adhoc, always use unicast key
1201 
1202 	if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
1203 		context = &ai->mod[0].mCtx;
1204 	else
1205 		context = &ai->mod[0].uCtx;
1206 
1207 	if (!context->valid)
1208 		return ERROR;
1209 
1210 	mic->typelen = htons(payLen + 16); //Length of Mic'd packet
1211 
1212 	memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
1213 
1214 	// Add Tx sequence
1215 	mic->seq = htonl(context->tx);
1216 	context->tx += 2;
1217 
1218 	emmh32_init(&context->seed); // Mic the packet
1219 	emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA
1220 	emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap
1221 	emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ
1222 	emmh32_update(&context->seed,frame->da + ETH_ALEN * 2,payLen); //payload
1223 	emmh32_final(&context->seed, (u8*)&mic->mic);
1224 
1225 	/*    New Type/length ?????????? */
1226 	mic->typelen = 0; //Let NIC know it could be an oversized packet
1227 	return SUCCESS;
1228 }
1229 
1230 typedef enum {
1231     NONE,
1232     NOMIC,
1233     NOMICPLUMMED,
1234     SEQUENCE,
1235     INCORRECTMIC,
1236 } mic_error;
1237 
1238 /*===========================================================================
1239  *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet
1240  *               (removes the MIC stuff) if packet is a valid packet.
1241  *
1242  *       Inputs: etherHead  pointer to the 802.3 packet
1243  *
1244  *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
1245  *
1246  *      Author: sbraneky (10/15/01)
1247  *    Merciless hacks by rwilcher (1/14/02)
1248  *---------------------------------------------------------------------------
1249  */
1250 
decapsulate(struct airo_info * ai,MICBuffer * mic,etherHead * eth,u16 payLen)1251 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
1252 {
1253 	int      i;
1254 	u32      micSEQ;
1255 	miccntx  *context;
1256 	u8       digest[4];
1257 	mic_error micError = NONE;
1258 
1259 	// Check if the packet is a Mic'd packet
1260 
1261 	if (!ai->micstats.enabled) {
1262 		//No Mic set or Mic OFF but we received a MIC'd packet.
1263 		if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
1264 			ai->micstats.rxMICPlummed++;
1265 			return ERROR;
1266 		}
1267 		return SUCCESS;
1268 	}
1269 
1270 	if (ntohs(mic->typelen) == 0x888E)
1271 		return SUCCESS;
1272 
1273 	if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
1274 	    // Mic enabled but packet isn't Mic'd
1275 		ai->micstats.rxMICPlummed++;
1276 	    	return ERROR;
1277 	}
1278 
1279 	micSEQ = ntohl(mic->seq);            //store SEQ as CPU order
1280 
1281 	//At this point we a have a mic'd packet and mic is enabled
1282 	//Now do the mic error checking.
1283 
1284 	//Receive seq must be odd
1285 	if ( (micSEQ & 1) == 0 ) {
1286 		ai->micstats.rxWrongSequence++;
1287 		return ERROR;
1288 	}
1289 
1290 	for (i = 0; i < NUM_MODULES; i++) {
1291 		int mcast = eth->da[0] & 1;
1292 		//Determine proper context
1293 		context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
1294 
1295 		//Make sure context is valid
1296 		if (!context->valid) {
1297 			if (i == 0)
1298 				micError = NOMICPLUMMED;
1299 			continue;
1300 		}
1301 	       	//DeMic it
1302 
1303 		if (!mic->typelen)
1304 			mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
1305 
1306 		emmh32_init(&context->seed);
1307 		emmh32_update(&context->seed, eth->da, ETH_ALEN*2);
1308 		emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap));
1309 		emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq));
1310 		emmh32_update(&context->seed, eth->da + ETH_ALEN*2,payLen);
1311 		//Calculate MIC
1312 		emmh32_final(&context->seed, digest);
1313 
1314 		if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
1315 		  //Invalid Mic
1316 			if (i == 0)
1317 				micError = INCORRECTMIC;
1318 			continue;
1319 		}
1320 
1321 		//Check Sequence number if mics pass
1322 		if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
1323 			ai->micstats.rxSuccess++;
1324 			return SUCCESS;
1325 		}
1326 		if (i == 0)
1327 			micError = SEQUENCE;
1328 	}
1329 
1330 	// Update statistics
1331 	switch (micError) {
1332 		case NOMICPLUMMED: ai->micstats.rxMICPlummed++;   break;
1333 		case SEQUENCE:    ai->micstats.rxWrongSequence++; break;
1334 		case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
1335 		case NONE:  break;
1336 		case NOMIC: break;
1337 	}
1338 	return ERROR;
1339 }
1340 
1341 /*===========================================================================
1342  * Description:  Checks the Rx Seq number to make sure it is valid
1343  *               and hasn't already been received
1344  *
1345  *     Inputs: miccntx - mic context to check seq against
1346  *             micSeq  - the Mic seq number
1347  *
1348  *    Returns: TRUE if valid otherwise FALSE.
1349  *
1350  *    Author: sbraneky (10/15/01)
1351  *    Merciless hacks by rwilcher (1/14/02)
1352  *---------------------------------------------------------------------------
1353  */
1354 
RxSeqValid(struct airo_info * ai,miccntx * context,int mcast,u32 micSeq)1355 static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq)
1356 {
1357 	u32 seq,index;
1358 
1359 	//Allow for the ap being rebooted - if it is then use the next
1360 	//sequence number of the current sequence number - might go backwards
1361 
1362 	if (mcast) {
1363 		if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
1364 			clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
1365 			context->window = (micSeq > 33) ? micSeq : 33;
1366 			context->rx     = 0;        // Reset rx
1367 		}
1368 	} else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
1369 		clear_bit (FLAG_UPDATE_UNI, &ai->flags);
1370 		context->window = (micSeq > 33) ? micSeq : 33; // Move window
1371 		context->rx     = 0;        // Reset rx
1372 	}
1373 
1374 	//Make sequence number relative to START of window
1375 	seq = micSeq - (context->window - 33);
1376 
1377 	//Too old of a SEQ number to check.
1378 	if ((u32)seq < 0)
1379 		return ERROR;
1380 
1381 	if ( seq > 64 ) {
1382 		//Window is infinite forward
1383 		MoveWindow(context,micSeq);
1384 		return SUCCESS;
1385 	}
1386 
1387 	// We are in the window. Now check the context rx bit to see if it was already sent
1388 	seq >>= 1;         //divide by 2 because we only have odd numbers
1389 	index = 1 << seq;  //Get an index number
1390 
1391 	if (!(context->rx & index)) {
1392 		//micSEQ falls inside the window.
1393 		//Add seqence number to the list of received numbers.
1394 		context->rx |= index;
1395 
1396 		MoveWindow(context,micSeq);
1397 
1398 		return SUCCESS;
1399 	}
1400 	return ERROR;
1401 }
1402 
MoveWindow(miccntx * context,u32 micSeq)1403 static void MoveWindow(miccntx *context, u32 micSeq)
1404 {
1405 	u32 shift;
1406 
1407 	//Move window if seq greater than the middle of the window
1408 	if (micSeq > context->window) {
1409 		shift = (micSeq - context->window) >> 1;
1410 
1411 		    //Shift out old
1412 		if (shift < 32)
1413 			context->rx >>= shift;
1414 		else
1415 			context->rx = 0;
1416 
1417 		context->window = micSeq;      //Move window
1418 	}
1419 }
1420 
1421 /*==============================================*/
1422 /*========== EMMH ROUTINES  ====================*/
1423 /*==============================================*/
1424 
1425 /* mic accumulate */
1426 #define MIC_ACCUM(val)	\
1427 	context->accum += (u64)(val) * context->coeff[coeff_position++];
1428 
1429 static unsigned char aes_counter[16];
1430 
1431 /* expand the key to fill the MMH coefficient array */
emmh32_setseed(emmh32_context * context,u8 * pkey,int keylen,struct crypto_tfm * tfm)1432 void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm)
1433 {
1434   /* take the keying material, expand if necessary, truncate at 16-bytes */
1435   /* run through AES counter mode to generate context->coeff[] */
1436 
1437 	int i,j;
1438 	u32 counter;
1439 	u8 *cipher, plain[16];
1440 	struct scatterlist sg[1];
1441 
1442 	crypto_cipher_setkey(tfm, pkey, 16);
1443 	counter = 0;
1444 	for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) {
1445 		aes_counter[15] = (u8)(counter >> 0);
1446 		aes_counter[14] = (u8)(counter >> 8);
1447 		aes_counter[13] = (u8)(counter >> 16);
1448 		aes_counter[12] = (u8)(counter >> 24);
1449 		counter++;
1450 		memcpy (plain, aes_counter, 16);
1451 		sg[0].page = virt_to_page(plain);
1452 		sg[0].offset = ((long) plain & ~PAGE_MASK);
1453 		sg[0].length = 16;
1454 		crypto_cipher_encrypt(tfm, sg, sg, 16);
1455 		cipher = kmap(sg[0].page) + sg[0].offset;
1456 		for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
1457 			context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
1458 			j += 4;
1459 		}
1460 	}
1461 }
1462 
1463 /* prepare for calculation of a new mic */
emmh32_init(emmh32_context * context)1464 void emmh32_init(emmh32_context *context)
1465 {
1466 	/* prepare for new mic calculation */
1467 	context->accum = 0;
1468 	context->position = 0;
1469 }
1470 
1471 /* add some bytes to the mic calculation */
emmh32_update(emmh32_context * context,u8 * pOctets,int len)1472 void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1473 {
1474 	int	coeff_position, byte_position;
1475 
1476 	if (len == 0) return;
1477 
1478 	coeff_position = context->position >> 2;
1479 
1480 	/* deal with partial 32-bit word left over from last update */
1481 	byte_position = context->position & 3;
1482 	if (byte_position) {
1483 		/* have a partial word in part to deal with */
1484 		do {
1485 			if (len == 0) return;
1486 			context->part.d8[byte_position++] = *pOctets++;
1487 			context->position++;
1488 			len--;
1489 		} while (byte_position < 4);
1490 		MIC_ACCUM(htonl(context->part.d32));
1491 	}
1492 
1493 	/* deal with full 32-bit words */
1494 	while (len >= 4) {
1495 		MIC_ACCUM(htonl(*(u32 *)pOctets));
1496 		context->position += 4;
1497 		pOctets += 4;
1498 		len -= 4;
1499 	}
1500 
1501 	/* deal with partial 32-bit word that will be left over from this update */
1502 	byte_position = 0;
1503 	while (len > 0) {
1504 		context->part.d8[byte_position++] = *pOctets++;
1505 		context->position++;
1506 		len--;
1507 	}
1508 }
1509 
1510 /* mask used to zero empty bytes for final partial word */
1511 static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1512 
1513 /* calculate the mic */
emmh32_final(emmh32_context * context,u8 digest[4])1514 void emmh32_final(emmh32_context *context, u8 digest[4])
1515 {
1516 	int	coeff_position, byte_position;
1517 	u32	val;
1518 
1519 	u64 sum, utmp;
1520 	s64 stmp;
1521 
1522 	coeff_position = context->position >> 2;
1523 
1524 	/* deal with partial 32-bit word left over from last update */
1525 	byte_position = context->position & 3;
1526 	if (byte_position) {
1527 		/* have a partial word in part to deal with */
1528 		val = htonl(context->part.d32);
1529 		MIC_ACCUM(val & mask32[byte_position]);	/* zero empty bytes */
1530 	}
1531 
1532 	/* reduce the accumulated u64 to a 32-bit MIC */
1533 	sum = context->accum;
1534 	stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);
1535 	utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
1536 	sum = utmp & 0xffffffffLL;
1537 	if (utmp > 0x10000000fLL)
1538 		sum -= 15;
1539 
1540 	val = (u32)sum;
1541 	digest[0] = (val>>24) & 0xFF;
1542 	digest[1] = (val>>16) & 0xFF;
1543 	digest[2] = (val>>8) & 0xFF;
1544 	digest[3] = val & 0xFF;
1545 }
1546 #endif
1547 
readBSSListRid(struct airo_info * ai,int first,BSSListRid * list)1548 static int readBSSListRid(struct airo_info *ai, int first,
1549 		      BSSListRid *list) {
1550 	int rc;
1551 			Cmd cmd;
1552 			Resp rsp;
1553 
1554 	if (first == 1) {
1555 			memset(&cmd, 0, sizeof(cmd));
1556 			cmd.cmd=CMD_LISTBSS;
1557 			if (down_interruptible(&ai->sem))
1558 				return -ERESTARTSYS;
1559 			issuecommand(ai, &cmd, &rsp);
1560 			up(&ai->sem);
1561 			/* Let the command take effect */
1562 			set_current_state (TASK_INTERRUPTIBLE);
1563 			ai->task = current;
1564 			schedule_timeout (3*HZ);
1565 			ai->task = NULL;
1566 		}
1567 	rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
1568 			    list, sizeof(*list), 1);
1569 
1570 	list->len = le16_to_cpu(list->len);
1571 	list->index = le16_to_cpu(list->index);
1572 	list->radioType = le16_to_cpu(list->radioType);
1573 	list->cap = le16_to_cpu(list->cap);
1574 	list->beaconInterval = le16_to_cpu(list->beaconInterval);
1575 	list->fh.dwell = le16_to_cpu(list->fh.dwell);
1576 	list->dsChannel = le16_to_cpu(list->dsChannel);
1577 	list->atimWindow = le16_to_cpu(list->atimWindow);
1578 	return rc;
1579 }
1580 
readWepKeyRid(struct airo_info * ai,WepKeyRid * wkr,int temp)1581 static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {
1582 	int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
1583 				wkr, sizeof(*wkr), 1);
1584 
1585 	wkr->len = le16_to_cpu(wkr->len);
1586 	wkr->kindex = le16_to_cpu(wkr->kindex);
1587 	wkr->klen = le16_to_cpu(wkr->klen);
1588 	return rc;
1589 }
1590 /* In the writeXXXRid routines we copy the rids so that we don't screwup
1591  * the originals when we endian them... */
writeWepKeyRid(struct airo_info * ai,WepKeyRid * pwkr,int perm,int lock)1592 static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lock) {
1593 	int rc;
1594 	WepKeyRid wkr = *pwkr;
1595 
1596 	wkr.len = cpu_to_le16(wkr.len);
1597 	wkr.kindex = cpu_to_le16(wkr.kindex);
1598 	wkr.klen = cpu_to_le16(wkr.klen);
1599 	rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);
1600 	if (rc!=SUCCESS) printk(KERN_ERR "airo:  WEP_TEMP set %x\n", rc);
1601 	if (perm) {
1602 		rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);
1603 		if (rc!=SUCCESS) {
1604 			printk(KERN_ERR "airo:  WEP_PERM set %x\n", rc);
1605 		}
1606 	}
1607 	return rc;
1608 }
1609 
readSsidRid(struct airo_info * ai,SsidRid * ssidr)1610 static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {
1611 	int i;
1612 	int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1613 
1614 	ssidr->len = le16_to_cpu(ssidr->len);
1615 	for(i = 0; i < 3; i++) {
1616 		ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
1617 	}
1618 	return rc;
1619 }
writeSsidRid(struct airo_info * ai,SsidRid * pssidr)1620 static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {
1621 	int rc;
1622 	int i;
1623 	SsidRid ssidr = *pssidr;
1624 
1625 	ssidr.len = cpu_to_le16(ssidr.len);
1626 	for(i = 0; i < 3; i++) {
1627 		ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
1628 	}
1629 	rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), 1);
1630 	return rc;
1631 }
readConfigRid(struct airo_info * ai,int lock)1632 static int readConfigRid(struct airo_info*ai, int lock) {
1633 	int rc;
1634 	u16 *s;
1635 	ConfigRid cfg;
1636 
1637 	if (ai->config.len)
1638 		return SUCCESS;
1639 
1640 	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
1641 	if (rc != SUCCESS)
1642 		return rc;
1643 
1644 	for(s = &cfg.len; s <= &cfg.rtsThres; s++) *s = le16_to_cpu(*s);
1645 
1646 	for(s = &cfg.shortRetryLimit; s <= &cfg.radioType; s++)
1647 		*s = le16_to_cpu(*s);
1648 
1649 	for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)
1650 		*s = le16_to_cpu(*s);
1651 
1652 	for(s = &cfg.arlThreshold; s <= &cfg.autoWake; s++)
1653 		*s = le16_to_cpu(*s);
1654 
1655 	ai->config = cfg;
1656 	return SUCCESS;
1657 }
checkThrottle(struct airo_info * ai)1658 static inline void checkThrottle(struct airo_info *ai) {
1659 	int i;
1660 /* Old hardware had a limit on encryption speed */
1661 	if (ai->config.authType != AUTH_OPEN && maxencrypt) {
1662 		for(i=0; i<8; i++) {
1663 			if (ai->config.rates[i] > maxencrypt) {
1664 				ai->config.rates[i] = 0;
1665 			}
1666 		}
1667 	}
1668 }
writeConfigRid(struct airo_info * ai,int lock)1669 static int writeConfigRid(struct airo_info*ai, int lock) {
1670 	u16 *s;
1671 	ConfigRid cfgr;
1672 
1673 	if (!ai->need_commit)
1674 		return SUCCESS;
1675 
1676 	ai->need_commit = 0;
1677 	checkThrottle(ai);
1678 	cfgr = ai->config;
1679 
1680 	if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)
1681 		set_bit(FLAG_ADHOC, &ai->flags);
1682 	else
1683 		clear_bit(FLAG_ADHOC, &ai->flags);
1684 
1685 	for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
1686 
1687 	for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
1688 		*s = cpu_to_le16(*s);
1689 
1690 	for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
1691 		*s = cpu_to_le16(*s);
1692 
1693 	for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)
1694 		*s = cpu_to_le16(*s);
1695 
1696 	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1697 }
readStatusRid(struct airo_info * ai,StatusRid * statr,int lock)1698 static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) {
1699 	int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1700 	u16 *s;
1701 
1702 	statr->len = le16_to_cpu(statr->len);
1703 	for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
1704 
1705 	for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++)
1706 		*s = le16_to_cpu(*s);
1707 	statr->load = le16_to_cpu(statr->load);
1708 	statr->assocStatus = le16_to_cpu(statr->assocStatus);
1709 	return rc;
1710 }
readAPListRid(struct airo_info * ai,APListRid * aplr)1711 static int readAPListRid(struct airo_info*ai, APListRid *aplr) {
1712 	int rc =  PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
1713 	aplr->len = le16_to_cpu(aplr->len);
1714 	return rc;
1715 }
writeAPListRid(struct airo_info * ai,APListRid * aplr)1716 static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {
1717 	int rc;
1718 	aplr->len = cpu_to_le16(aplr->len);
1719 	rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
1720 	return rc;
1721 }
readCapabilityRid(struct airo_info * ai,CapabilityRid * capr)1722 static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {
1723 	int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), 1);
1724 	u16 *s;
1725 
1726 	capr->len = le16_to_cpu(capr->len);
1727 	capr->prodNum = le16_to_cpu(capr->prodNum);
1728 	capr->radioType = le16_to_cpu(capr->radioType);
1729 	capr->country = le16_to_cpu(capr->country);
1730 	for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
1731 		*s = le16_to_cpu(*s);
1732 	return rc;
1733 }
readStatsRid(struct airo_info * ai,StatsRid * sr,int rid,int lock)1734 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
1735 	int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1736 	u32 *i;
1737 
1738 	sr->len = le16_to_cpu(sr->len);
1739 	for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);
1740 	return rc;
1741 }
1742 
airo_open(struct net_device * dev)1743 static int airo_open(struct net_device *dev) {
1744 	struct airo_info *info = dev->priv;
1745 	Resp rsp;
1746 
1747 	if (test_bit(FLAG_FLASHING, &info->flags))
1748 		return -EIO;
1749 
1750 	/* Make sure the card is configured.
1751 	 * Wireless Extensions may postpone config changes until the card
1752 	 * is open (to pipeline changes and speed-up card setup). If
1753 	 * those changes are not yet commited, do it now - Jean II */
1754 	if(info->need_commit) {
1755 		disable_MAC(info, 1);
1756 		writeConfigRid(info, 1);
1757 	}
1758 
1759 	if (info->wifidev != dev) {
1760 		/* Power on the MAC controller (which may have been disabled) */
1761 		clear_bit(FLAG_RADIO_DOWN, &info->flags);
1762 		enable_interrupts(info);
1763 	}
1764 	enable_MAC(info, &rsp, 1);
1765 
1766 	netif_start_queue(dev);
1767 	return 0;
1768 }
1769 
get_tx_error(struct airo_info * ai,u32 fid)1770 static void get_tx_error(struct airo_info *ai, u32 fid)
1771 {
1772 	u16 status;
1773 
1774 	if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) == SUCCESS) {
1775 		bap_read(ai, &status, 2, BAP0);
1776 		if (le16_to_cpu(status) & 2) /* Too many retries */
1777 			ai->stats.tx_aborted_errors++;
1778 		if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
1779 			ai->stats.tx_heartbeat_errors++;
1780 		if (le16_to_cpu(status) & 8) /* Aid fail */
1781 			{ }
1782 		if (le16_to_cpu(status) & 0x10) /* MAC disabled */
1783 			ai->stats.tx_carrier_errors++;
1784 		if (le16_to_cpu(status) & 0x20) /* Association lost */
1785 			{ }
1786 #if WIRELESS_EXT > 13
1787 		/* We produce a TXDROP event only for retry or lifetime
1788 		 * exceeded, because that's the only status that really mean
1789 		 * that this particular node went away.
1790 		 * Other errors means that *we* screwed up. - Jean II */
1791 		if ((le16_to_cpu(status) & 2) ||
1792 		     (le16_to_cpu(status) & 4)) {
1793 			union iwreq_data	wrqu;
1794 			char junk[0x18];
1795 
1796 			/* Faster to skip over useless data than to do
1797 			 * another bap_setup(). We are at offset 0x6 and
1798 			 * need to go to 0x18 and read 6 bytes - Jean II */
1799 			bap_read(ai, (u16 *) junk, 0x18, BAP0);
1800 
1801 			/* Copy 802.11 dest address.
1802 			 * We use the 802.11 header because the frame may
1803 			 * not be 802.3 or may be mangled...
1804 			 * In Ad-Hoc mode, it will be the node address.
1805 			 * In managed mode, it will be most likely the AP addr
1806 			 * User space will figure out how to convert it to
1807 			 * whatever it needs (IP address or else).
1808 			 * - Jean II */
1809 			memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
1810 			wrqu.addr.sa_family = ARPHRD_ETHER;
1811 
1812 			/* Send event to user space */
1813 			wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
1814 		}
1815 #endif /* WIRELESS_EXT > 13 */
1816 	}
1817 }
1818 
airo_end_xmit(struct net_device * dev)1819 static void airo_end_xmit(struct net_device *dev) {
1820 	u16 status;
1821 	int i;
1822 	struct airo_info *priv = dev->priv;
1823 	struct sk_buff *skb = priv->xmit.skb;
1824 	int fid = priv->xmit.fid;
1825 	u32 *fids = priv->fids;
1826 
1827 	clear_bit(JOB_XMIT, &priv->flags);
1828 	clear_bit(FLAG_PENDING_XMIT, &priv->flags);
1829 	status = transmit_802_3_packet (priv, fids[fid], skb->data);
1830 	up(&priv->sem);
1831 
1832 	i = 0;
1833 	if ( status == SUCCESS ) {
1834 		dev->trans_start = jiffies;
1835 		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
1836 	} else {
1837 		priv->fids[fid] &= 0xffff;
1838 		priv->stats.tx_window_errors++;
1839 	}
1840 	if (i < MAX_FIDS / 2)
1841 		netif_wake_queue(dev);
1842 	dev_kfree_skb(skb);
1843 }
1844 
airo_start_xmit(struct sk_buff * skb,struct net_device * dev)1845 static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1846 	s16 len;
1847 	int i, j;
1848 	struct airo_info *priv = dev->priv;
1849 	u32 *fids = priv->fids;
1850 
1851 	if ( skb == NULL ) {
1852 		printk( KERN_ERR "airo:  skb == NULL!!!\n" );
1853 		return 0;
1854 	}
1855 
1856 	/* Find a vacant FID */
1857 	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
1858 	for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
1859 
1860 	if ( j >= MAX_FIDS / 2 ) {
1861 		netif_stop_queue(dev);
1862 
1863 		if (i == MAX_FIDS / 2) {
1864 			priv->stats.tx_fifo_errors++;
1865 			return 1;
1866 		}
1867 	}
1868 	/* check min length*/
1869 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1870         /* Mark fid as used & save length for later */
1871 	fids[i] |= (len << 16);
1872 	priv->xmit.skb = skb;
1873 	priv->xmit.fid = i;
1874 	if (down_trylock(&priv->sem) != 0) {
1875 		set_bit(FLAG_PENDING_XMIT, &priv->flags);
1876 		netif_stop_queue(dev);
1877 		set_bit(JOB_XMIT, &priv->flags);
1878 		wake_up_interruptible(&priv->thr_wait);
1879 	} else
1880 		airo_end_xmit(dev);
1881 	return 0;
1882 }
1883 
airo_end_xmit11(struct net_device * dev)1884 static void airo_end_xmit11(struct net_device *dev) {
1885 	u16 status;
1886 	int i;
1887 	struct airo_info *priv = dev->priv;
1888 	struct sk_buff *skb = priv->xmit11.skb;
1889 	int fid = priv->xmit11.fid;
1890 	u32 *fids = priv->fids;
1891 
1892 	clear_bit(JOB_XMIT11, &priv->flags);
1893 	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
1894 	status = transmit_802_11_packet (priv, fids[fid], skb->data);
1895 	up(&priv->sem);
1896 
1897 	i = MAX_FIDS / 2;
1898 	if ( status == SUCCESS ) {
1899 		dev->trans_start = jiffies;
1900 		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
1901 	} else {
1902 		priv->fids[fid] &= 0xffff;
1903 		priv->stats.tx_window_errors++;
1904 	}
1905 	if (i < MAX_FIDS)
1906 		netif_wake_queue(dev);
1907 	dev_kfree_skb(skb);
1908 }
1909 
airo_start_xmit11(struct sk_buff * skb,struct net_device * dev)1910 static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
1911 	s16 len;
1912 	int i, j;
1913 	struct airo_info *priv = dev->priv;
1914 	u32 *fids = priv->fids;
1915 
1916 	if ( skb == NULL ) {
1917 		printk( KERN_ERR "airo:  skb == NULL!!!\n" );
1918 		return 0;
1919 	}
1920 
1921 	/* Find a vacant FID */
1922 	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
1923 	for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
1924 
1925 	if ( j >= MAX_FIDS ) {
1926 		netif_stop_queue(dev);
1927 
1928 		if (i == MAX_FIDS) {
1929 			priv->stats.tx_fifo_errors++;
1930 			return 1;
1931 		}
1932 	}
1933 	/* check min length*/
1934 	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1935         /* Mark fid as used & save length for later */
1936 	fids[i] |= (len << 16);
1937 	priv->xmit11.skb = skb;
1938 	priv->xmit11.fid = i;
1939 	if (down_trylock(&priv->sem) != 0) {
1940 		set_bit(FLAG_PENDING_XMIT11, &priv->flags);
1941 		netif_stop_queue(dev);
1942 		set_bit(JOB_XMIT11, &priv->flags);
1943 		wake_up_interruptible(&priv->thr_wait);
1944 	} else
1945 		airo_end_xmit11(dev);
1946 	return 0;
1947 }
1948 
airo_read_stats(struct airo_info * ai)1949 static void airo_read_stats(struct airo_info *ai) {
1950 	StatsRid stats_rid;
1951 	u32 *vals = stats_rid.vals;
1952 
1953 	clear_bit(JOB_STATS, &ai->flags);
1954 	readStatsRid(ai, &stats_rid, RID_STATS, 0);
1955 	up(&ai->sem);
1956 
1957 	ai->stats.rx_packets = vals[43] + vals[44] + vals[45];
1958 	ai->stats.tx_packets = vals[39] + vals[40] + vals[41];
1959 	ai->stats.rx_bytes = vals[92];
1960 	ai->stats.tx_bytes = vals[91];
1961 	ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4];
1962 	ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors;
1963 	ai->stats.multicast = vals[43];
1964 	ai->stats.collisions = vals[89];
1965 
1966 	/* detailed rx_errors: */
1967 	ai->stats.rx_length_errors = vals[3];
1968 	ai->stats.rx_crc_errors = vals[4];
1969 	ai->stats.rx_frame_errors = vals[2];
1970 	ai->stats.rx_fifo_errors = vals[0];
1971 }
1972 
airo_get_stats(struct net_device * dev)1973 struct net_device_stats *airo_get_stats(struct net_device *dev)
1974 {
1975 	struct airo_info *local =  dev->priv;
1976 
1977 	/* Get stats out of the card if available */
1978 	if (down_trylock(&local->sem) != 0) {
1979 		set_bit(JOB_STATS, &local->flags);
1980 		wake_up_interruptible(&local->thr_wait);
1981 	} else
1982 		airo_read_stats(local);
1983 
1984 	return &local->stats;
1985 }
1986 
airo_set_promisc(struct airo_info * ai)1987 static void airo_set_promisc(struct airo_info *ai) {
1988 	Cmd cmd;
1989 	Resp rsp;
1990 
1991 	memset(&cmd, 0, sizeof(cmd));
1992 	cmd.cmd=CMD_SETMODE;
1993 	clear_bit(JOB_PROMISC, &ai->flags);
1994 	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
1995 	issuecommand(ai, &cmd, &rsp);
1996 	up(&ai->sem);
1997 }
1998 
airo_set_multicast_list(struct net_device * dev)1999 static void airo_set_multicast_list(struct net_device *dev) {
2000 	struct airo_info *ai = dev->priv;
2001 
2002 	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
2003 		change_bit(FLAG_PROMISC, &ai->flags);
2004 		if (down_trylock(&ai->sem) != 0) {
2005 			set_bit(JOB_PROMISC, &ai->flags);
2006 			wake_up_interruptible(&ai->thr_wait);
2007 		} else
2008 			airo_set_promisc(ai);
2009 	}
2010 
2011 	if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
2012 		/* Turn on multicast.  (Should be already setup...) */
2013 	}
2014 }
2015 
airo_set_mac_address(struct net_device * dev,void * p)2016 static int airo_set_mac_address(struct net_device *dev, void *p)
2017 {
2018 	struct airo_info *ai = dev->priv;
2019 	struct sockaddr *addr = p;
2020 	Resp rsp;
2021 
2022 	readConfigRid(ai, 1);
2023 	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
2024 	ai->need_commit = 1;
2025 	disable_MAC(ai, 1);
2026 	writeConfigRid (ai, 1);
2027 	enable_MAC(ai, &rsp, 1);
2028 	memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
2029 	if (ai->wifidev)
2030 		memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
2031 	return 0;
2032 }
2033 
airo_change_mtu(struct net_device * dev,int new_mtu)2034 static int airo_change_mtu(struct net_device *dev, int new_mtu)
2035 {
2036 	if ((new_mtu < 68) || (new_mtu > 2400))
2037 		return -EINVAL;
2038 	dev->mtu = new_mtu;
2039 	return 0;
2040 }
2041 
2042 
airo_close(struct net_device * dev)2043 static int airo_close(struct net_device *dev) {
2044 	struct airo_info *ai = dev->priv;
2045 
2046 	netif_stop_queue(dev);
2047 
2048 	if (ai->wifidev != dev) {
2049 #ifdef POWER_ON_DOWN
2050 		/* Shut power to the card. The idea is that the user can save
2051 		 * power when he doesn't need the card with "ifconfig down".
2052 		 * That's the method that is most friendly towards the network
2053 		 * stack (i.e. the network stack won't try to broadcast
2054 		 * anything on the interface and routes are gone. Jean II */
2055 		set_bit(FLAG_RADIO_DOWN, &ai->flags);
2056 		disable_MAC(ai, 1);
2057 #endif
2058 		disable_interrupts( ai );
2059 	}
2060 	return 0;
2061 }
2062 
2063 static void del_airo_dev( struct net_device *dev );
2064 
stop_airo_card(struct net_device * dev,int freeres)2065 void stop_airo_card( struct net_device *dev, int freeres )
2066 {
2067 	struct airo_info *ai = dev->priv;
2068 	disable_interrupts(ai);
2069 	free_irq( dev->irq, dev );
2070 	takedown_proc_entry( dev, ai );
2071 	if (ai->registered) {
2072 		unregister_netdev( dev );
2073 		if (ai->wifidev) {
2074 			unregister_netdev(ai->wifidev);
2075 			free_netdev(ai->wifidev);
2076 			ai->wifidev = 0;
2077 		}
2078 		ai->registered = 0;
2079 	}
2080 	set_bit(JOB_DIE, &ai->flags);
2081 	kill_proc(ai->thr_pid, SIGTERM, 1);
2082 	wait_for_completion(&ai->thr_exited);
2083 	if (ai->flash)
2084 		kfree(ai->flash);
2085 	if (ai->rssi)
2086 		kfree(ai->rssi);
2087 	if (freeres) {
2088 		/* PCMCIA frees this stuff, so only for PCI and ISA */
2089 	        release_region( dev->base_addr, 64 );
2090         }
2091 #ifdef MICSUPPORT
2092 	if (ai->tfm)
2093 		crypto_free_tfm(ai->tfm);
2094 #endif
2095 	del_airo_dev( dev );
2096 	free_netdev( dev );
2097 }
2098 
2099 EXPORT_SYMBOL(stop_airo_card);
2100 
2101 static int add_airo_dev( struct net_device *dev );
2102 
wll_header_parse(struct sk_buff * skb,unsigned char * haddr)2103 int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
2104 {
2105 	memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
2106 	return ETH_ALEN;
2107 }
2108 
wifi_setup(struct net_device * dev,struct net_device * ethdev)2109 static void wifi_setup(struct net_device *dev, struct net_device *ethdev)
2110 {
2111 	struct airo_info *ai = ethdev->priv;
2112 	dev->priv = ai;
2113 	dev->hard_header        = 0;
2114 	dev->rebuild_header     = 0;
2115 	dev->hard_header_cache  = 0;
2116 	dev->header_cache_update= 0;
2117 
2118 	dev->hard_header_parse  = wll_header_parse;
2119 	dev->hard_start_xmit = &airo_start_xmit11;
2120 	dev->get_stats = &airo_get_stats;
2121 	dev->set_mac_address = &airo_set_mac_address;
2122 	dev->do_ioctl = &airo_ioctl;
2123 #ifdef WIRELESS_EXT
2124 	dev->get_wireless_stats = airo_get_wireless_stats;
2125 #if WIRELESS_EXT > 12
2126 	dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;
2127 #endif /* WIRELESS_EXT > 12 */
2128 #endif /* WIRELESS_EXT */
2129 	dev->change_mtu = &airo_change_mtu;
2130 	dev->open = &airo_open;
2131 	dev->stop = &airo_close;
2132 	dev->irq = ethdev->irq;
2133 	dev->base_addr = ethdev->base_addr;
2134 
2135 	dev->type               = ARPHRD_IEEE80211;
2136 	dev->hard_header_len    = ETH_HLEN;
2137 	dev->mtu                = 2312;
2138 	dev->addr_len           = ETH_ALEN;
2139 	memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
2140 	dev->tx_queue_len       = 100;
2141 
2142 	memset(dev->broadcast,0xFF, ETH_ALEN);
2143 
2144 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
2145 }
2146 
init_wifidev(struct airo_info * ai,struct net_device * ethdev)2147 static struct net_device *init_wifidev(struct airo_info *ai,
2148 					struct net_device *ethdev)
2149 {
2150 	int err;
2151 	struct net_device *dev = (struct net_device*)kmalloc(sizeof *dev,GFP_KERNEL);
2152 	if (!dev) return 0;
2153 	memset(dev, 0, sizeof(*dev));
2154 
2155 	strcpy(dev->name, "wifi%d");
2156 	dev->priv = ai;
2157 	wifi_setup(dev, ethdev);
2158 	err = register_netdev(dev);
2159 	if (err<0) {
2160 		kfree(dev);
2161 		return 0;
2162 	}
2163 	return dev;
2164 }
2165 
init_airo_card(unsigned short irq,int port,int is_pcmcia)2166 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
2167 {
2168 	struct net_device *dev;
2169 	struct airo_info *ai;
2170 	int i, rc;
2171 
2172 	/* Create the network device object. */
2173         dev = alloc_etherdev(sizeof(*ai));
2174         if (!dev) {
2175 		printk(KERN_ERR "airo:  Couldn't alloc_etherdev\n");
2176 		return NULL;
2177         }
2178 	if (dev_alloc_name(dev, dev->name) < 0) {
2179 		printk(KERN_ERR "airo:  Couldn't get name!\n");
2180 		goto err_out_free;
2181 	}
2182 
2183 	ai = dev->priv;
2184 	ai->wifidev = 0;
2185 	ai->registered = 0;
2186         ai->dev = dev;
2187 	ai->aux_lock = SPIN_LOCK_UNLOCKED;
2188 	sema_init(&ai->sem, 1);
2189 	ai->need_commit = 0;
2190 	ai->config.len = 0;
2191 	init_waitqueue_head (&ai->thr_wait);
2192 	init_completion (&ai->thr_exited);
2193 	ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
2194 	if (ai->thr_pid < 0)
2195 		goto err_out_free;
2196 #ifdef MICSUPPORT
2197 	ai->tfm = NULL;
2198 #endif
2199 	rc = add_airo_dev( dev );
2200 	if (rc)
2201 		goto err_out_thr;
2202 
2203 	/* The Airo-specific entries in the device structure. */
2204 	dev->hard_start_xmit = &airo_start_xmit;
2205 	dev->get_stats = &airo_get_stats;
2206 	dev->set_multicast_list = &airo_set_multicast_list;
2207 	dev->set_mac_address = &airo_set_mac_address;
2208 	dev->do_ioctl = &airo_ioctl;
2209 #ifdef WIRELESS_EXT
2210 	dev->get_wireless_stats = airo_get_wireless_stats;
2211 #if WIRELESS_EXT > 12
2212 	dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;
2213 #endif /* WIRELESS_EXT > 12 */
2214 #endif /* WIRELESS_EXT */
2215 	dev->change_mtu = &airo_change_mtu;
2216 	dev->open = &airo_open;
2217 	dev->stop = &airo_close;
2218 	dev->irq = irq;
2219 	dev->base_addr = port;
2220 
2221 	rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
2222 	if (rc) {
2223 		printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
2224 		goto err_out_unlink;
2225 	}
2226 	if (!is_pcmcia) {
2227 		if (!request_region( dev->base_addr, 64, dev->name )) {
2228 			rc = -EBUSY;
2229 			goto err_out_irq;
2230 		}
2231 	}
2232 
2233 	if (probe) {
2234 		if ( setup_card( ai, dev->dev_addr ) != SUCCESS ) {
2235 			printk( KERN_ERR "airo: MAC could not be enabled\n" );
2236 			rc = -EIO;
2237 			goto err_out_res;
2238 		}
2239 	} else {
2240 		ai->bap_read = fast_bap_read;
2241 		set_bit(FLAG_FLASHING, &ai->flags);
2242 	}
2243 
2244 	rc = register_netdev(dev);
2245 	if (rc)
2246 		goto err_out_res;
2247 	ai->wifidev = init_wifidev(ai, dev);
2248 
2249 	ai->registered = 1;
2250 	printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
2251 		dev->name,
2252 		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2253 		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
2254 
2255 	/* Allocate the transmit buffers */
2256 	if (probe)
2257 		for( i = 0; i < MAX_FIDS; i++ )
2258 			ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
2259 
2260 	setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
2261 	netif_start_queue(dev);
2262 	SET_MODULE_OWNER(dev);
2263 	return dev;
2264 
2265 err_out_res:
2266 	if (!is_pcmcia)
2267 	        release_region( dev->base_addr, 64 );
2268 err_out_irq:
2269 	free_irq(dev->irq, dev);
2270 err_out_unlink:
2271 	del_airo_dev(dev);
2272 err_out_thr:
2273 	set_bit(JOB_DIE, &ai->flags);
2274 	kill_proc(ai->thr_pid, SIGTERM, 1);
2275 	wait_for_completion(&ai->thr_exited);
2276 err_out_free:
2277 	kfree(dev);
2278 	return NULL;
2279 }
2280 
2281 EXPORT_SYMBOL(init_airo_card);
2282 
waitbusy(struct airo_info * ai)2283 static int waitbusy (struct airo_info *ai) {
2284 	int delay = 0;
2285 	while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) {
2286 		udelay (10);
2287 		if (++delay % 20)
2288 			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2289 	}
2290 	return delay < 10000;
2291 }
2292 
reset_airo_card(struct net_device * dev)2293 int reset_airo_card( struct net_device *dev ) {
2294 	int i;
2295 	struct airo_info *ai = dev->priv;
2296 
2297 
2298 	if (down_interruptible(&ai->sem))
2299 		return -1;
2300 	waitbusy (ai);
2301 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
2302 	set_current_state (TASK_UNINTERRUPTIBLE);
2303 	schedule_timeout (HZ/5);
2304 	waitbusy (ai);
2305 	set_current_state (TASK_UNINTERRUPTIBLE);
2306 	schedule_timeout (HZ/5);
2307 	if ( setup_card(ai, dev->dev_addr ) != SUCCESS ) {
2308 		printk( KERN_ERR "airo: MAC could not be enabled\n" );
2309 		up(&ai->sem);
2310 		return -1;
2311 	} else {
2312 		printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
2313 			dev->name,
2314 			dev->dev_addr[0],
2315 			dev->dev_addr[1],
2316 			dev->dev_addr[2],
2317 			dev->dev_addr[3],
2318 			dev->dev_addr[4],
2319 			dev->dev_addr[5]
2320 			);
2321 		/* Allocate the transmit buffers */
2322 		for( i = 0; i < MAX_FIDS; i++ )
2323 			ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
2324 	}
2325 	enable_interrupts( ai );
2326 	netif_wake_queue(dev);
2327 	up(&ai->sem);
2328 	return 0;
2329 }
2330 
2331 EXPORT_SYMBOL(reset_airo_card);
2332 
2333 #if WIRELESS_EXT > 13
airo_send_event(struct net_device * dev)2334 static void airo_send_event(struct net_device *dev) {
2335 	struct airo_info *ai = dev->priv;
2336 	union iwreq_data wrqu;
2337 	StatusRid status_rid;
2338 
2339 	clear_bit(JOB_EVENT, &ai->flags);
2340 	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
2341 	up(&ai->sem);
2342 	wrqu.data.length = 0;
2343 	wrqu.data.flags = 0;
2344 	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
2345 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2346 
2347 	/* Send event to user space */
2348 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
2349 }
2350 #endif
2351 
airo_thread(void * data)2352 static int airo_thread(void *data) {
2353 	struct net_device *dev = data;
2354 	struct airo_info *ai = dev->priv;
2355 	int locked;
2356 
2357 	daemonize();
2358 	reparent_to_init();
2359 	spin_lock_irq(&current->sigmask_lock);
2360 	sigemptyset(&current->blocked);
2361 	recalc_sigpending(current);
2362 	spin_unlock_irq(&current->sigmask_lock);
2363 
2364 	strncpy (current->comm, dev->name, sizeof(current->comm) - 1);
2365 	current->comm[sizeof(current->comm) - 1] = '\0';
2366 
2367 	while(1) {
2368 		if (signal_pending(current)) {
2369 			spin_lock_irq(&current->sigmask_lock);
2370 			flush_signals(current);
2371 			spin_unlock_irq(&current->sigmask_lock);
2372 		}
2373 
2374 		if (test_bit(JOB_DIE, &ai->flags))
2375 			break;
2376 
2377 		if (ai->flags & JOB_MASK) {
2378 			locked = down_interruptible(&ai->sem);
2379 		} else {
2380 			wait_queue_t wait;
2381 
2382 			init_waitqueue_entry(&wait, current);
2383 			add_wait_queue(&ai->thr_wait, &wait);
2384 			for (;;) {
2385 				set_current_state(TASK_INTERRUPTIBLE);
2386 				if (ai->flags & JOB_MASK)
2387 					break;
2388 				if (ai->expires) {
2389 					if (time_after_eq(jiffies,ai->expires)){
2390 						set_bit(JOB_AUTOWEP,&ai->flags);
2391 						break;
2392 					}
2393 					if (!signal_pending(current)) {
2394 						schedule_timeout(ai->expires - jiffies);
2395 						continue;
2396 					}
2397 				} else if (!signal_pending(current)) {
2398 					schedule();
2399 					continue;
2400 				}
2401 				break;
2402 			}
2403 			current->state = TASK_RUNNING;
2404 			remove_wait_queue(&ai->thr_wait, &wait);
2405 			locked = 1;
2406 		}
2407 
2408 		if (locked)
2409 			continue;
2410 
2411 		if (test_bit(JOB_DIE, &ai->flags)) {
2412 			up(&ai->sem);
2413 			break;
2414 		}
2415 
2416 		if (test_bit(FLAG_FLASHING, &ai->flags)) {
2417 			up(&ai->sem);
2418 			continue;
2419 		}
2420 
2421 		if (test_bit(JOB_XMIT, &ai->flags))
2422 			airo_end_xmit(dev);
2423 		else if (test_bit(JOB_XMIT11, &ai->flags))
2424 			airo_end_xmit11(dev);
2425 		else if (test_bit(JOB_STATS, &ai->flags))
2426 			airo_read_stats(ai);
2427 		else if (test_bit(JOB_WSTATS, &ai->flags))
2428 			airo_read_wireless_stats(ai);
2429 		else if (test_bit(JOB_PROMISC, &ai->flags))
2430 			airo_set_promisc(ai);
2431 #ifdef MICSUPPORT
2432 		else if (test_bit(JOB_MIC, &ai->flags))
2433 			micinit(ai);
2434 #endif
2435 #if WIRELESS_EXT > 13
2436 		else if (test_bit(JOB_EVENT, &ai->flags))
2437 			airo_send_event(dev);
2438 #endif
2439 		else if (test_bit(JOB_AUTOWEP, &ai->flags))
2440 			timer_func(dev);
2441 	}
2442 	complete_and_exit (&ai->thr_exited, 0);
2443 }
2444 
airo_interrupt(int irq,void * dev_id,struct pt_regs * regs)2445 static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
2446 	struct net_device *dev = (struct net_device *)dev_id;
2447 	u16 status;
2448 	u16 fid;
2449 	struct airo_info *apriv = dev->priv;
2450 	u16 savedInterrupts = 0;
2451 	int handled = 0;
2452 
2453 	if (!netif_device_present(dev))
2454 		return IRQ_NONE;
2455 
2456 	for (;;) {
2457 		status = IN4500( apriv, EVSTAT );
2458 		if ( !(status & STATUS_INTS) || status == 0xffff ) break;
2459 
2460 		handled = 1;
2461 
2462 		if ( status & EV_AWAKE ) {
2463 			OUT4500( apriv, EVACK, EV_AWAKE );
2464 			OUT4500( apriv, EVACK, EV_AWAKE );
2465 		}
2466 
2467 		if (!savedInterrupts) {
2468 			savedInterrupts = IN4500( apriv, EVINTEN );
2469 			OUT4500( apriv, EVINTEN, 0 );
2470 		}
2471 
2472 		if ( status & EV_MIC ) {
2473 			OUT4500( apriv, EVACK, EV_MIC );
2474 #ifdef MICSUPPORT
2475 			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
2476 				set_bit(JOB_MIC, &apriv->flags);
2477 				wake_up_interruptible(&apriv->thr_wait);
2478 			}
2479 #endif
2480 		}
2481 		if ( status & EV_LINK ) {
2482 #if WIRELESS_EXT > 13
2483 			union iwreq_data	wrqu;
2484 #endif /* WIRELESS_EXT > 13 */
2485 			/* The link status has changed, if you want to put a
2486 			   monitor hook in, do it here.  (Remember that
2487 			   interrupts are still disabled!)
2488 			*/
2489 			u16 newStatus = IN4500(apriv, LINKSTAT);
2490 			OUT4500( apriv, EVACK, EV_LINK);
2491 			/* Here is what newStatus means: */
2492 #define NOBEACON 0x8000 /* Loss of sync - missed beacons */
2493 #define MAXRETRIES 0x8001 /* Loss of sync - max retries */
2494 #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
2495 #define FORCELOSS 0x8003 /* Loss of sync - host request */
2496 #define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
2497 #define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
2498 #define DISASS 0x8200 /* Disassociation (low byte is reason code) */
2499 #define ASSFAIL 0x8400 /* Association failure (low byte is reason
2500 			  code) */
2501 #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
2502 			   code) */
2503 #define ASSOCIATED 0x0400 /* Assocatied */
2504 #define RC_RESERVED 0 /* Reserved return code */
2505 #define RC_NOREASON 1 /* Unspecified reason */
2506 #define RC_AUTHINV 2 /* Previous authentication invalid */
2507 #define RC_DEAUTH 3 /* Deauthenticated because sending station is
2508 		       leaving */
2509 #define RC_NOACT 4 /* Disassociated due to inactivity */
2510 #define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
2511 			all currently associated stations */
2512 #define RC_BADCLASS2 6 /* Class 2 frame received from
2513 			  non-Authenticated station */
2514 #define RC_BADCLASS3 7 /* Class 3 frame received from
2515 			  non-Associated station */
2516 #define RC_STATLEAVE 8 /* Disassociated because sending station is
2517 			  leaving BSS */
2518 #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
2519 		       Authenticated with the responding station */
2520 			if (newStatus != ASSOCIATED) {
2521 				if (auto_wep && !apriv->expires) {
2522 					apriv->expires = RUN_AT(3*HZ);
2523 					wake_up_interruptible(&apriv->thr_wait);
2524 				}
2525 			} else {
2526 				struct task_struct *task = apriv->task;
2527 				if (auto_wep)
2528 					apriv->expires = 0;
2529 				if (task)
2530 					wake_up_process (task);
2531 				set_bit(FLAG_UPDATE_UNI, &apriv->flags);
2532 				set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
2533 			}
2534 #if WIRELESS_EXT > 13
2535 			/* Question : is ASSOCIATED the only status
2536 			 * that is valid ? We want to catch handover
2537 			 * and reassociations as valid status
2538 			 * Jean II */
2539 			if(newStatus == ASSOCIATED) {
2540 				if (apriv->scan_timestamp) {
2541 					/* Send an empty event to user space.
2542 					 * We don't send the received data on
2543 					 * the event because it would require
2544 					 * us to do complex transcoding, and
2545 					 * we want to minimise the work done in
2546 					 * the irq handler. Use a request to
2547 					 * extract the data - Jean II */
2548 					wrqu.data.length = 0;
2549 					wrqu.data.flags = 0;
2550 					wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
2551 					apriv->scan_timestamp = 0;
2552 				}
2553 				if (down_trylock(&apriv->sem) != 0) {
2554 					set_bit(JOB_EVENT, &apriv->flags);
2555 					wake_up_interruptible(&apriv->thr_wait);
2556 				} else
2557 					airo_send_event(dev);
2558 			} else {
2559 				memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
2560 				wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2561 
2562 				/* Send event to user space */
2563 				wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
2564 			}
2565 #endif /* WIRELESS_EXT > 13 */
2566 		}
2567 
2568 		/* Check to see if there is something to receive */
2569 		if ( status & EV_RX  ) {
2570 			struct sk_buff *skb = NULL;
2571 			u16 fc, len, hdrlen = 0;
2572 #pragma pack(1)
2573 			struct {
2574 				u16 status, len;
2575 				u8 rssi[2];
2576 				u8 rate;
2577 				u8 freq;
2578 				u16 tmp[4];
2579 			} hdr;
2580 #pragma pack()
2581 			u16 gap;
2582 			u16 tmpbuf[4];
2583 			u16 *buffer;
2584 
2585 			fid = IN4500( apriv, RXFID );
2586 
2587 			/* Get the packet length */
2588 			if (test_bit(FLAG_802_11, &apriv->flags)) {
2589 				bap_setup (apriv, fid, 4, BAP0);
2590 				bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
2591 				/* Bad CRC. Ignore packet */
2592 				if (le16_to_cpu(hdr.status) & 2)
2593 					hdr.len = 0;
2594 				if (apriv->wifidev == NULL)
2595 					hdr.len = 0;
2596 			} else {
2597 				bap_setup (apriv, fid, 0x36, BAP0);
2598 				bap_read (apriv, (u16*)&hdr.len, 2, BAP0);
2599 			}
2600 			len = le16_to_cpu(hdr.len);
2601 
2602 			if (len > 2312) {
2603 				printk( KERN_ERR "airo: Bad size %d\n", len );
2604 				goto badrx;
2605 			}
2606 			if (len == 0)
2607 				goto badrx;
2608 
2609 			if (test_bit(FLAG_802_11, &apriv->flags)) {
2610 				bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
2611 				fc = le16_to_cpu(fc);
2612 				switch (fc & 0xc) {
2613 					case 4:
2614 						if ((fc & 0xe0) == 0xc0)
2615 							hdrlen = 10;
2616 						else
2617 							hdrlen = 16;
2618 						break;
2619 					case 8:
2620 						if ((fc&0x300)==0x300){
2621 							hdrlen = 30;
2622 							break;
2623 						}
2624 					default:
2625 						hdrlen = 24;
2626 				}
2627 			} else
2628 				hdrlen = ETH_ALEN * 2;
2629 
2630 			skb = dev_alloc_skb( len + hdrlen + 2 );
2631 			if ( !skb ) {
2632 				apriv->stats.rx_dropped++;
2633 				goto badrx;
2634 			}
2635 			buffer = (u16*)skb_put (skb, len + hdrlen);
2636 			if (test_bit(FLAG_802_11, &apriv->flags)) {
2637 				buffer[0] = fc;
2638 				bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
2639 				if (hdrlen == 24)
2640 					bap_read (apriv, tmpbuf, 6, BAP0);
2641 
2642 				bap_read (apriv, &gap, sizeof(gap), BAP0);
2643 				gap = le16_to_cpu(gap);
2644 				if (gap) {
2645 					if (gap <= 8)
2646 						bap_read (apriv, tmpbuf, gap, BAP0);
2647 					else
2648 						printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n");
2649 				}
2650 				bap_read (apriv, buffer + hdrlen/2, len, BAP0);
2651 			} else {
2652 #ifdef MICSUPPORT
2653 				MICBuffer micbuf;
2654 #endif
2655 				bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
2656 #ifdef MICSUPPORT
2657 				if (apriv->micstats.enabled) {
2658 					bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
2659 					if (ntohs(micbuf.typelen) > 0x05DC)
2660 						bap_setup (apriv, fid, 0x44, BAP0);
2661 					else {
2662 						if (len <= sizeof(micbuf))
2663 							goto badmic;
2664 
2665 						len -= sizeof(micbuf);
2666 						skb_trim (skb, len + hdrlen);
2667 					}
2668 				}
2669 #endif
2670 				bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
2671 #ifdef MICSUPPORT
2672 				if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
2673 badmic:
2674 					dev_kfree_skb_irq (skb);
2675 #else
2676 				if (0) {
2677 #endif
2678 badrx:
2679 					OUT4500( apriv, EVACK, EV_RX);
2680 					goto exitrx;
2681 				}
2682 			}
2683 #if WIRELESS_EXT > 15
2684 #ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
2685 			if (apriv->spy_data.spy_number > 0) {
2686 				char *sa;
2687 				struct iw_quality wstats;
2688 				/* Prepare spy data : addr + qual */
2689 				if (!test_bit(FLAG_802_11, &apriv->flags)) {
2690 					sa = (char*)buffer + 6;
2691 					bap_setup (apriv, fid, 8, BAP0);
2692 					bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
2693 				} else
2694 					sa = (char*)buffer + 10;
2695 				wstats.qual = hdr.rssi[0];
2696 				if (apriv->rssi)
2697 					wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
2698 				else
2699 					wstats.level = (hdr.rssi[1] + 321) / 2;
2700 				wstats.updated = 3;
2701 				/* Update spy records */
2702 				wireless_spy_update(dev, sa, &wstats);
2703 			}
2704 #endif /* IW_WIRELESS_SPY */
2705 #else /* WIRELESS_EXT > 15 */
2706 #ifdef WIRELESS_SPY
2707 			if (apriv->spy_number > 0) {
2708 				int i;
2709 				char *sa;
2710 
2711 				sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6);
2712 
2713 				for (i=0; i<apriv->spy_number; i++)
2714 					if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN))
2715 					{
2716 						if (!test_bit(FLAG_802_11, &apriv->flags)) {
2717 							bap_setup (apriv, fid, 8, BAP0);
2718 							bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
2719 						}
2720 						apriv->spy_stat[i].qual = hdr.rssi[0];
2721 						if (apriv->rssi)
2722 							apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
2723 						else
2724 							apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
2725 						apriv->spy_stat[i].noise = 0;
2726 						apriv->spy_stat[i].updated = 3;
2727 						break;
2728 					}
2729 			}
2730 #endif /* WIRELESS_SPY  */
2731 #endif /* WIRELESS_EXT > 15 */
2732 			OUT4500( apriv, EVACK, EV_RX);
2733 
2734 			if (test_bit(FLAG_802_11, &apriv->flags)) {
2735 				skb->mac.raw = skb->data;
2736 				skb->pkt_type = PACKET_OTHERHOST;
2737 				skb->dev = apriv->wifidev;
2738 				skb->protocol = htons(ETH_P_802_2);
2739 			} else {
2740 				skb->dev = dev;
2741 				skb->protocol = eth_type_trans(skb,dev);
2742 			}
2743 			skb->dev->last_rx = jiffies;
2744 			skb->ip_summed = CHECKSUM_NONE;
2745 
2746 			netif_rx( skb );
2747 		}
2748 exitrx:
2749 
2750 		/* Check to see if a packet has been transmitted */
2751 		if (  status & ( EV_TX|EV_TXEXC ) ) {
2752 			int i;
2753 			int len = 0;
2754 			int index = -1;
2755 
2756 			fid = IN4500(apriv, TXCOMPLFID);
2757 
2758 			for( i = 0; i < MAX_FIDS; i++ ) {
2759 				if ( ( apriv->fids[i] & 0xffff ) == fid ) {
2760 					len = apriv->fids[i] >> 16;
2761 					index = i;
2762 				}
2763 			}
2764 			if (index != -1) {
2765 				if (status & EV_TXEXC)
2766 					get_tx_error(apriv, index);
2767 				OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
2768 				/* Set up to be used again */
2769 				apriv->fids[index] &= 0xffff;
2770 				if (index < MAX_FIDS / 2) {
2771 					if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
2772 						netif_wake_queue(dev);
2773 				} else {
2774 					if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
2775 						netif_wake_queue(apriv->wifidev);
2776 				}
2777 			} else {
2778 				OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
2779 				printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
2780 			}
2781 		}
2782 		if ( status & ~STATUS_INTS & ~IGNORE_INTS )
2783 			printk( KERN_WARNING "airo: Got weird status %x\n",
2784 				status & ~STATUS_INTS & ~IGNORE_INTS );
2785 	}
2786 
2787 	if (savedInterrupts)
2788 		OUT4500( apriv, EVINTEN, savedInterrupts );
2789 
2790 	/* done.. */
2791 	return IRQ_RETVAL(handled);
2792 }
2793 
2794 /*
2795  *  Routines to talk to the card
2796  */
2797 
2798 /*
2799  *  This was originally written for the 4500, hence the name
2800  *  NOTE:  If use with 8bit mode and SMP bad things will happen!
2801  *         Why would some one do 8 bit IO in an SMP machine?!?
2802  */
2803 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
2804 	if ( !do8bitIO )
2805 		outw( val, ai->dev->base_addr + reg );
2806 	else {
2807 		outb( val & 0xff, ai->dev->base_addr + reg );
2808 		outb( val >> 8, ai->dev->base_addr + reg + 1 );
2809 	}
2810 }
2811 
2812 static u16 IN4500( struct airo_info *ai, u16 reg ) {
2813 	unsigned short rc;
2814 
2815 	if ( !do8bitIO )
2816 		rc = inw( ai->dev->base_addr + reg );
2817 	else {
2818 		rc = inb( ai->dev->base_addr + reg );
2819 		rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
2820 	}
2821 	return rc;
2822 }
2823 
2824 static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
2825 	int rc;
2826         Cmd cmd;
2827 
2828 	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
2829 	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
2830 	 * Note : we could try to use !netif_running(dev) in enable_MAC()
2831 	 * instead of this flag, but I don't trust it *within* the
2832 	 * open/close functions, and testing both flags together is
2833 	 * "cheaper" - Jean II */
2834 	if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
2835 	memset(&cmd, 0, sizeof(cmd));
2836 	cmd.cmd = MAC_ENABLE;
2837 	if (!lock)
2838 		return issuecommand(ai, &cmd, rsp);
2839 
2840 	if (down_interruptible(&ai->sem))
2841 		return -ERESTARTSYS;
2842 	rc = issuecommand(ai, &cmd, rsp);
2843 	up(&ai->sem);
2844 	return rc;
2845 }
2846 
2847 static void disable_MAC( struct airo_info *ai, int lock ) {
2848         Cmd cmd;
2849 	Resp rsp;
2850 
2851 	memset(&cmd, 0, sizeof(cmd));
2852 	cmd.cmd = MAC_DISABLE; // disable in case already enabled
2853 	if (!lock) {
2854 		issuecommand(ai, &cmd, &rsp);
2855 		return;
2856 	}
2857 
2858 	if (down_interruptible(&ai->sem))
2859 		return;
2860 	issuecommand(ai, &cmd, &rsp);
2861 	up(&ai->sem);
2862 }
2863 
2864 static void enable_interrupts( struct airo_info *ai ) {
2865 	/* Reset the status register */
2866 	u16 status = IN4500( ai, EVSTAT );
2867 	OUT4500( ai, EVACK, status );
2868 	/* Enable the interrupts */
2869 	OUT4500( ai, EVINTEN, STATUS_INTS );
2870 	/* Note there is a race condition between the last two lines that
2871 	   I don't know how to get rid of right now... */
2872 }
2873 
2874 static void disable_interrupts( struct airo_info *ai ) {
2875 	OUT4500( ai, EVINTEN, 0 );
2876 }
2877 
2878 static u16 setup_card(struct airo_info *ai, u8 *mac)
2879 {
2880 	Cmd cmd;
2881 	Resp rsp;
2882 	int status;
2883 	int i;
2884 	SsidRid mySsid;
2885 	u16 lastindex;
2886 	WepKeyRid wkr;
2887 	int rc;
2888 
2889 	memset( &mySsid, 0, sizeof( mySsid ) );
2890 	if (ai->flash) {
2891 		kfree (ai->flash);
2892 		ai->flash = NULL;
2893 	}
2894 
2895 	/* The NOP is the first step in getting the card going */
2896 	cmd.cmd = NOP;
2897 	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
2898 	if (down_interruptible(&ai->sem))
2899 		return ERROR;
2900 	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
2901 		up(&ai->sem);
2902 		return ERROR;
2903 	}
2904 	memset(&cmd, 0, sizeof(cmd));
2905 	cmd.cmd = MAC_DISABLE; // disable in case already enabled
2906 	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
2907 		up(&ai->sem);
2908 		return ERROR;
2909 	}
2910 
2911 	// Let's figure out if we need to use the AUX port
2912 	cmd.cmd = CMD_ENABLEAUX;
2913 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
2914 		up(&ai->sem);
2915 		printk(KERN_ERR "airo: Error checking for AUX port\n");
2916 		return ERROR;
2917 	}
2918 	if (!aux_bap || rsp.status & 0xff00) {
2919 		ai->bap_read = fast_bap_read;
2920 		printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
2921 	} else {
2922 		ai->bap_read = aux_bap_read;
2923 		printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
2924 	}
2925 	up(&ai->sem);
2926 	if (ai->config.len == 0) {
2927 		tdsRssiRid rssi_rid;
2928 		CapabilityRid cap_rid;
2929 
2930 		// general configuration (read/modify/write)
2931 		status = readConfigRid(ai, 1);
2932 		if ( status != SUCCESS ) return ERROR;
2933 
2934 		status = readCapabilityRid(ai, &cap_rid);
2935 		if ( status != SUCCESS ) return ERROR;
2936 
2937 		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),1);
2938 		if ( status == SUCCESS ) {
2939 			if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
2940 				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
2941 		}
2942 		else {
2943 			if (ai->rssi) {
2944 				kfree(ai->rssi);
2945 				ai->rssi = NULL;
2946 			}
2947 			if (cap_rid.softCap & 8)
2948 				ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
2949 			else
2950 				printk(KERN_WARNING "airo: unknown received signal level scale\n");
2951 		}
2952 		ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
2953 		ai->config.authType = AUTH_OPEN;
2954 		ai->config.modulation = MOD_CCK;
2955 
2956 #ifdef MICSUPPORT
2957 		if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
2958 		    (micsetup(ai) == SUCCESS)) {
2959 			ai->config.opmode |= MODE_MIC;
2960 			set_bit(FLAG_MIC_CAPABLE, &ai->flags);
2961 		}
2962 #endif
2963 
2964 		/* Save off the MAC */
2965 		for( i = 0; i < ETH_ALEN; i++ ) {
2966 			mac[i] = ai->config.macAddr[i];
2967 		}
2968 
2969 		/* Check to see if there are any insmod configured
2970 		   rates to add */
2971 		if ( rates ) {
2972 			int i = 0;
2973 			if ( rates[0] ) memset(ai->config.rates,0,sizeof(ai->config.rates));
2974 			for( i = 0; i < 8 && rates[i]; i++ ) {
2975 				ai->config.rates[i] = rates[i];
2976 			}
2977 		}
2978 		if ( basic_rate > 0 ) {
2979 			int i;
2980 			for( i = 0; i < 8; i++ ) {
2981 				if ( ai->config.rates[i] == basic_rate ||
2982 				     !ai->config.rates ) {
2983 					ai->config.rates[i] = basic_rate | 0x80;
2984 					break;
2985 				}
2986 			}
2987 		}
2988 		ai->need_commit = 1;
2989 	}
2990 
2991 	/* Setup the SSIDs if present */
2992 	if ( ssids[0] ) {
2993 		int i;
2994 		for( i = 0; i < 3 && ssids[i]; i++ ) {
2995 			mySsid.ssids[i].len = strlen(ssids[i]);
2996 			if ( mySsid.ssids[i].len > 32 )
2997 				mySsid.ssids[i].len = 32;
2998 			memcpy(mySsid.ssids[i].ssid, ssids[i],
2999 			       mySsid.ssids[i].len);
3000 		}
3001 		mySsid.len = sizeof(mySsid);
3002 	}
3003 
3004 	status = writeConfigRid(ai, 1);
3005 	if ( status != SUCCESS ) return ERROR;
3006 
3007 	/* Set up the SSID list */
3008 	status = writeSsidRid(ai, &mySsid);
3009 	if ( status != SUCCESS ) return ERROR;
3010 
3011 	status = enable_MAC(ai, &rsp, 1);
3012 	if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
3013 		printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
3014 		return ERROR;
3015 	}
3016 
3017 	/* Grab the initial wep key, we gotta save it for auto_wep */
3018 	rc = readWepKeyRid(ai, &wkr, 1);
3019 	if (rc == SUCCESS) do {
3020 		lastindex = wkr.kindex;
3021 		if (wkr.kindex == 0xffff) {
3022 			ai->defindex = wkr.mac[0];
3023 		}
3024 		rc = readWepKeyRid(ai, &wkr, 0);
3025 	} while(lastindex != wkr.kindex);
3026 
3027 	if (auto_wep) {
3028 		ai->expires = RUN_AT(3*HZ);
3029 		wake_up_interruptible(&ai->thr_wait);
3030 	}
3031 
3032 	return SUCCESS;
3033 }
3034 
3035 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3036         // Im really paranoid about letting it run forever!
3037 	int max_tries = 600000;
3038 	u16 cmd;
3039 
3040 	OUT4500(ai, PARAM0, pCmd->parm0);
3041 	OUT4500(ai, PARAM1, pCmd->parm1);
3042 	OUT4500(ai, PARAM2, pCmd->parm2);
3043 	OUT4500(ai, COMMAND, pCmd->cmd);
3044 	while ( max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0 &&
3045 		(cmd = IN4500(ai, COMMAND)) != 0 )
3046 			if (cmd == pCmd->cmd)
3047 				// PC4500 didn't notice command, try again
3048 				OUT4500(ai, COMMAND, pCmd->cmd);
3049 	if ( max_tries == -1 ) {
3050 		printk( KERN_ERR
3051 			"airo: Max tries exceeded when issueing command\n" );
3052                 return ERROR;
3053 	}
3054 
3055 	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3056 		if (!in_interrupt() && (max_tries & 255) == 0)
3057 			schedule();
3058 	}
3059 	if ( max_tries == -1 ) {
3060 		printk( KERN_ERR
3061 			"airo: Max tries exceeded waiting for command\n" );
3062                 return ERROR;
3063 	}
3064 	// command completed
3065 	pRsp->status = IN4500(ai, STATUS);
3066 	pRsp->rsp0 = IN4500(ai, RESP0);
3067 	pRsp->rsp1 = IN4500(ai, RESP1);
3068 	pRsp->rsp2 = IN4500(ai, RESP2);
3069 
3070 	// clear stuck command busy if necessary
3071 	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
3072 		OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3073 	}
3074 	// acknowledge processing the status/response
3075 	OUT4500(ai, EVACK, EV_CMD);
3076 
3077 	return SUCCESS;
3078 }
3079 
3080 /* Sets up the bap to start exchange data.  whichbap should
3081  * be one of the BAP0 or BAP1 defines.  Locks should be held before
3082  * calling! */
3083 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3084 {
3085 	int timeout = 50;
3086 	int max_tries = 3;
3087 
3088 	OUT4500(ai, SELECT0+whichbap, rid);
3089 	OUT4500(ai, OFFSET0+whichbap, offset);
3090 	while (1) {
3091 		int status = IN4500(ai, OFFSET0+whichbap);
3092 		if (status & BAP_BUSY) {
3093                         /* This isn't really a timeout, but its kinda
3094 			   close */
3095 			if (timeout--) {
3096 				continue;
3097 			}
3098 		} else if ( status & BAP_ERR ) {
3099 			/* invalid rid or offset */
3100 			printk( KERN_ERR "airo: BAP error %x %d\n",
3101 				status, whichbap );
3102 			return ERROR;
3103 		} else if (status & BAP_DONE) { // success
3104 			return SUCCESS;
3105 		}
3106 		if ( !(max_tries--) ) {
3107 			printk( KERN_ERR
3108 				"airo: BAP setup error too many retries\n" );
3109 			return ERROR;
3110 		}
3111 		// -- PC4500 missed it, try again
3112 		OUT4500(ai, SELECT0+whichbap, rid);
3113 		OUT4500(ai, OFFSET0+whichbap, offset);
3114 		timeout = 50;
3115 	}
3116 }
3117 
3118 /* should only be called by aux_bap_read.  This aux function and the
3119    following use concepts not documented in the developers guide.  I
3120    got them from a patch given to my by Aironet */
3121 static u16 aux_setup(struct airo_info *ai, u16 page,
3122 		     u16 offset, u16 *len)
3123 {
3124 	u16 next;
3125 
3126 	OUT4500(ai, AUXPAGE, page);
3127 	OUT4500(ai, AUXOFF, 0);
3128 	next = IN4500(ai, AUXDATA);
3129 	*len = IN4500(ai, AUXDATA)&0xff;
3130 	if (offset != 4) OUT4500(ai, AUXOFF, offset);
3131 	return next;
3132 }
3133 
3134 /* requires call to bap_setup() first */
3135 static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
3136 			int bytelen, int whichbap)
3137 {
3138 	u16 len;
3139 	u16 page;
3140 	u16 offset;
3141 	u16 next;
3142 	int words;
3143 	int i;
3144 	unsigned long flags;
3145 
3146 	spin_lock_irqsave(&ai->aux_lock, flags);
3147 	page = IN4500(ai, SWS0+whichbap);
3148 	offset = IN4500(ai, SWS2+whichbap);
3149 	next = aux_setup(ai, page, offset, &len);
3150 	words = (bytelen+1)>>1;
3151 
3152 	for (i=0; i<words;) {
3153 		int count;
3154 		count = (len>>1) < (words-i) ? (len>>1) : (words-i);
3155 		if ( !do8bitIO )
3156 			insw( ai->dev->base_addr+DATA0+whichbap,
3157 			      pu16Dst+i,count );
3158 		else
3159 			insb( ai->dev->base_addr+DATA0+whichbap,
3160 			      pu16Dst+i, count << 1 );
3161 		i += count;
3162 		if (i<words) {
3163 			next = aux_setup(ai, next, 4, &len);
3164 		}
3165 	}
3166 	spin_unlock_irqrestore(&ai->aux_lock, flags);
3167 	return SUCCESS;
3168 }
3169 
3170 
3171 /* requires call to bap_setup() first */
3172 static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
3173 			 int bytelen, int whichbap)
3174 {
3175 	bytelen = (bytelen + 1) & (~1); // round up to even value
3176 	if ( !do8bitIO )
3177 		insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
3178 	else
3179 		insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
3180 	return SUCCESS;
3181 }
3182 
3183 /* requires call to bap_setup() first */
3184 static int bap_write(struct airo_info *ai, const u16 *pu16Src,
3185 		     int bytelen, int whichbap)
3186 {
3187 	bytelen = (bytelen + 1) & (~1); // round up to even value
3188 	if ( !do8bitIO )
3189 		outsw( ai->dev->base_addr+DATA0+whichbap,
3190 		       pu16Src, bytelen>>1 );
3191 	else
3192 		outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
3193 	return SUCCESS;
3194 }
3195 
3196 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
3197 {
3198 	Cmd cmd; /* for issuing commands */
3199 	Resp rsp; /* response from commands */
3200 	u16 status;
3201 
3202 	memset(&cmd, 0, sizeof(cmd));
3203 	cmd.cmd = accmd;
3204 	cmd.parm0 = rid;
3205 	status = issuecommand(ai, &cmd, &rsp);
3206 	if (status != 0) return status;
3207 	if ( (rsp.status & 0x7F00) != 0) {
3208 		return (accmd << 8) + (rsp.rsp0 & 0xFF);
3209 	}
3210 	return 0;
3211 }
3212 
3213 /*  Note, that we are using BAP1 which is also used by transmit, so
3214  *  we must get a lock. */
3215 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
3216 {
3217 	u16 status;
3218         int rc = SUCCESS;
3219 
3220 	if (lock) {
3221 		if (down_interruptible(&ai->sem))
3222 			return ERROR;
3223 	}
3224 	if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
3225                 rc = status;
3226                 goto done;
3227         }
3228 	if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
3229 		rc = ERROR;
3230                 goto done;
3231         }
3232 	// read the rid length field
3233 	bap_read(ai, pBuf, 2, BAP1);
3234 	// length for remaining part of rid
3235 	len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
3236 
3237 	if ( len <= 2 ) {
3238 		printk( KERN_ERR
3239 			"airo: Rid %x has a length of %d which is too short\n",
3240 			(int)rid,
3241 			(int)len );
3242 		rc = ERROR;
3243                 goto done;
3244 	}
3245 	// read remainder of the rid
3246 	rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
3247 done:
3248 	if (lock)
3249 		up(&ai->sem);
3250 	return rc;
3251 }
3252 
3253 /*  Note, that we are using BAP1 which is also used by transmit, so
3254  *  make sure this isnt called when a transmit is happening */
3255 static int PC4500_writerid(struct airo_info *ai, u16 rid,
3256 			   const void *pBuf, int len, int lock)
3257 {
3258 	u16 status;
3259 	int rc = SUCCESS;
3260 
3261 	*(u16*)pBuf = cpu_to_le16((u16)len);
3262 
3263 	if (lock) {
3264 		if (down_interruptible(&ai->sem))
3265 			return ERROR;
3266 	}
3267 	// --- first access so that we can write the rid data
3268 	if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
3269                 rc = status;
3270                 goto done;
3271         }
3272 	// --- now write the rid data
3273 	if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
3274                 rc = ERROR;
3275                 goto done;
3276         }
3277 	bap_write(ai, pBuf, len, BAP1);
3278 	// ---now commit the rid data
3279 	rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
3280  done:
3281 	if (lock)
3282 		up(&ai->sem);
3283         return rc;
3284 }
3285 
3286 /* Allocates a FID to be used for transmitting packets.  We only use
3287    one for now. */
3288 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
3289 {
3290 	unsigned int loop = 3000;
3291 	Cmd cmd;
3292 	Resp rsp;
3293 	u16 txFid;
3294 	u16 txControl;
3295 
3296 	cmd.cmd = CMD_ALLOCATETX;
3297 	cmd.parm0 = lenPayload;
3298 	if (down_interruptible(&ai->sem))
3299 		return ERROR;
3300 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3301 		txFid = ERROR;
3302 		goto done;
3303 	}
3304 	if ( (rsp.status & 0xFF00) != 0) {
3305 		txFid = ERROR;
3306 		goto done;
3307 	}
3308 	/* wait for the allocate event/indication
3309 	 * It makes me kind of nervous that this can just sit here and spin,
3310 	 * but in practice it only loops like four times. */
3311 	while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
3312 	if (!loop) {
3313 		txFid = ERROR;
3314 		goto done;
3315 	}
3316 
3317 	// get the allocated fid and acknowledge
3318 	txFid = IN4500(ai, TXALLOCFID);
3319 	OUT4500(ai, EVACK, EV_ALLOC);
3320 
3321 	/*  The CARD is pretty cool since it converts the ethernet packet
3322 	 *  into 802.11.  Also note that we don't release the FID since we
3323 	 *  will be using the same one over and over again. */
3324 	/*  We only have to setup the control once since we are not
3325 	 *  releasing the fid. */
3326 	if (raw)
3327 		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
3328 			| TXCTL_ETHERNET | TXCTL_NORELEASE);
3329 	else
3330 		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
3331 			| TXCTL_ETHERNET | TXCTL_NORELEASE);
3332 	if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
3333 		txFid = ERROR;
3334 	else
3335 		bap_write(ai, &txControl, sizeof(txControl), BAP1);
3336 
3337 done:
3338 	up(&ai->sem);
3339 
3340 	return txFid;
3341 }
3342 
3343 /* In general BAP1 is dedicated to transmiting packets.  However,
3344    since we need a BAP when accessing RIDs, we also use BAP1 for that.
3345    Make sure the BAP1 spinlock is held when this is called. */
3346 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
3347 {
3348 	u16 payloadLen;
3349 	Cmd cmd;
3350 	Resp rsp;
3351 	int miclen = 0;
3352 	u16 txFid = len;
3353 	MICBuffer pMic;
3354 
3355 	len >>= 16;
3356 
3357 	if (len <= ETH_ALEN * 2) {
3358 		printk( KERN_WARNING "Short packet %d\n", len );
3359 		return ERROR;
3360 	}
3361 	len -= ETH_ALEN * 2;
3362 
3363 #ifdef MICSUPPORT
3364 	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
3365 	    (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
3366 		if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
3367 			return ERROR;
3368 		miclen = sizeof(pMic);
3369 	}
3370 #endif
3371 
3372 	// packet is destination[6], source[6], payload[len-12]
3373 	// write the payload length and dst/src/payload
3374 	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
3375 	/* The hardware addresses aren't counted as part of the payload, so
3376 	 * we have to subtract the 12 bytes for the addresses off */
3377 	payloadLen = cpu_to_le16(len + miclen);
3378 	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
3379 	bap_write(ai, (const u16*)pPacket, sizeof(etherHead), BAP1);
3380 	if (miclen)
3381 		bap_write(ai, (const u16*)&pMic, miclen, BAP1);
3382 	bap_write(ai, (const u16*)(pPacket + sizeof(etherHead)), len, BAP1);
3383 	// issue the transmit command
3384 	memset( &cmd, 0, sizeof( cmd ) );
3385 	cmd.cmd = CMD_TRANSMIT;
3386 	cmd.parm0 = txFid;
3387 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
3388 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
3389 	return SUCCESS;
3390 }
3391 
3392 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
3393 {
3394 	u16 fc, payloadLen;
3395 	Cmd cmd;
3396 	Resp rsp;
3397 	int hdrlen;
3398 	struct {
3399 		u8 addr4[ETH_ALEN];
3400 		u16 gaplen;
3401 		u8 gap[6];
3402 	} gap;
3403 	u16 txFid = len;
3404 	len >>= 16;
3405 	gap.gaplen = 6;
3406 
3407 	fc = le16_to_cpu(*(const u16*)pPacket);
3408 	switch (fc & 0xc) {
3409 		case 4:
3410 			if ((fc & 0xe0) == 0xc0)
3411 				hdrlen = 10;
3412 			else
3413 				hdrlen = 16;
3414 			break;
3415 		case 8:
3416 			if ((fc&0x300)==0x300){
3417 				hdrlen = 30;
3418 				break;
3419 			}
3420 		default:
3421 			hdrlen = 24;
3422 	}
3423 
3424 	if (len < hdrlen) {
3425 		printk( KERN_WARNING "Short packet %d\n", len );
3426 		return ERROR;
3427 	}
3428 
3429 	/* packet is 802.11 header +  payload
3430 	 * write the payload length and dst/src/payload */
3431 	if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
3432 	/* The 802.11 header aren't counted as part of the payload, so
3433 	 * we have to subtract the header bytes off */
3434 	payloadLen = cpu_to_le16(len-hdrlen);
3435 	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
3436 	if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
3437 	bap_write(ai, (const u16*)pPacket, hdrlen, BAP1);
3438 	bap_write(ai, hdrlen == 30 ?
3439 		(const u16*)&gap.gaplen : (const u16*)&gap, 38 - hdrlen, BAP1);
3440 
3441 	bap_write(ai, (const u16*)(pPacket + hdrlen), len - hdrlen, BAP1);
3442 	// issue the transmit command
3443 	memset( &cmd, 0, sizeof( cmd ) );
3444 	cmd.cmd = CMD_TRANSMIT;
3445 	cmd.parm0 = txFid;
3446 	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
3447 	if ( (rsp.status & 0xFF00) != 0) return ERROR;
3448 	return SUCCESS;
3449 }
3450 
3451 /*
3452  *  This is the proc_fs routines.  It is a bit messier than I would
3453  *  like!  Feel free to clean it up!
3454  */
3455 
3456 static ssize_t proc_read( struct file *file,
3457 			  char *buffer,
3458 			  size_t len,
3459 			  loff_t *offset);
3460 
3461 static ssize_t proc_write( struct file *file,
3462 			   const char *buffer,
3463 			   size_t len,
3464 			   loff_t *offset );
3465 static int proc_close( struct inode *inode, struct file *file );
3466 
3467 static int proc_stats_open( struct inode *inode, struct file *file );
3468 static int proc_statsdelta_open( struct inode *inode, struct file *file );
3469 static int proc_status_open( struct inode *inode, struct file *file );
3470 static int proc_SSID_open( struct inode *inode, struct file *file );
3471 static int proc_APList_open( struct inode *inode, struct file *file );
3472 static int proc_BSSList_open( struct inode *inode, struct file *file );
3473 static int proc_config_open( struct inode *inode, struct file *file );
3474 static int proc_wepkey_open( struct inode *inode, struct file *file );
3475 
3476 static struct file_operations proc_statsdelta_ops = {
3477 	.read		= proc_read,
3478 	.open		= proc_statsdelta_open,
3479 	.release	= proc_close
3480 };
3481 
3482 static struct file_operations proc_stats_ops = {
3483 	.read		= proc_read,
3484 	.open		= proc_stats_open,
3485 	.release	= proc_close
3486 };
3487 
3488 static struct file_operations proc_status_ops = {
3489 	.read		= proc_read,
3490 	.open		= proc_status_open,
3491 	.release	= proc_close
3492 };
3493 
3494 static struct file_operations proc_SSID_ops = {
3495 	.read		= proc_read,
3496 	.write		= proc_write,
3497 	.open		= proc_SSID_open,
3498 	.release	= proc_close
3499 };
3500 
3501 static struct file_operations proc_BSSList_ops = {
3502 	.read		= proc_read,
3503 	.write		= proc_write,
3504 	.open		= proc_BSSList_open,
3505 	.release	= proc_close
3506 };
3507 
3508 static struct file_operations proc_APList_ops = {
3509 	.read		= proc_read,
3510 	.write		= proc_write,
3511 	.open		= proc_APList_open,
3512 	.release	= proc_close
3513 };
3514 
3515 static struct file_operations proc_config_ops = {
3516 	.read		= proc_read,
3517 	.write		= proc_write,
3518 	.open		= proc_config_open,
3519 	.release	= proc_close
3520 };
3521 
3522 static struct file_operations proc_wepkey_ops = {
3523 	.read		= proc_read,
3524 	.write		= proc_write,
3525 	.open		= proc_wepkey_open,
3526 	.release	= proc_close
3527 };
3528 
3529 static struct proc_dir_entry *airo_entry = 0;
3530 
3531 struct proc_data {
3532 	int release_buffer;
3533 	int readlen;
3534 	char *rbuffer;
3535 	int writelen;
3536 	int maxwritelen;
3537 	char *wbuffer;
3538 	void (*on_close) (struct inode *, struct file *);
3539 };
3540 
3541 #ifndef SETPROC_OPS
3542 #define SETPROC_OPS(entry, ops) (entry)->proc_fops = &(ops)
3543 #endif
3544 
3545 static int setup_proc_entry( struct net_device *dev,
3546 			     struct airo_info *apriv ) {
3547 	struct proc_dir_entry *entry;
3548 	/* First setup the device directory */
3549 	apriv->proc_entry = create_proc_entry(dev->name,
3550 					      S_IFDIR|airo_perm,
3551 					      airo_entry);
3552         apriv->proc_entry->uid = proc_uid;
3553         apriv->proc_entry->gid = proc_gid;
3554 	apriv->proc_entry->owner = THIS_MODULE;
3555 
3556 	/* Setup the StatsDelta */
3557 	entry = create_proc_entry("StatsDelta",
3558 				  S_IFREG | (S_IRUGO&proc_perm),
3559 				  apriv->proc_entry);
3560         entry->uid = proc_uid;
3561         entry->gid = proc_gid;
3562 	entry->data = dev;
3563 	entry->owner = THIS_MODULE;
3564 	SETPROC_OPS(entry, proc_statsdelta_ops);
3565 
3566 	/* Setup the Stats */
3567 	entry = create_proc_entry("Stats",
3568 				  S_IFREG | (S_IRUGO&proc_perm),
3569 				  apriv->proc_entry);
3570         entry->uid = proc_uid;
3571         entry->gid = proc_gid;
3572 	entry->data = dev;
3573 	entry->owner = THIS_MODULE;
3574 	SETPROC_OPS(entry, proc_stats_ops);
3575 
3576 	/* Setup the Status */
3577 	entry = create_proc_entry("Status",
3578 				  S_IFREG | (S_IRUGO&proc_perm),
3579 				  apriv->proc_entry);
3580         entry->uid = proc_uid;
3581         entry->gid = proc_gid;
3582 	entry->data = dev;
3583 	entry->owner = THIS_MODULE;
3584 	SETPROC_OPS(entry, proc_status_ops);
3585 
3586 	/* Setup the Config */
3587 	entry = create_proc_entry("Config",
3588 				  S_IFREG | proc_perm,
3589 				  apriv->proc_entry);
3590         entry->uid = proc_uid;
3591         entry->gid = proc_gid;
3592 	entry->data = dev;
3593 	entry->owner = THIS_MODULE;
3594 	SETPROC_OPS(entry, proc_config_ops);
3595 
3596 	/* Setup the SSID */
3597 	entry = create_proc_entry("SSID",
3598 				  S_IFREG | proc_perm,
3599 				  apriv->proc_entry);
3600         entry->uid = proc_uid;
3601         entry->gid = proc_gid;
3602 	entry->data = dev;
3603 	entry->owner = THIS_MODULE;
3604 	SETPROC_OPS(entry, proc_SSID_ops);
3605 
3606 	/* Setup the APList */
3607 	entry = create_proc_entry("APList",
3608 				  S_IFREG | proc_perm,
3609 				  apriv->proc_entry);
3610         entry->uid = proc_uid;
3611         entry->gid = proc_gid;
3612 	entry->data = dev;
3613 	entry->owner = THIS_MODULE;
3614 	SETPROC_OPS(entry, proc_APList_ops);
3615 
3616 	/* Setup the BSSList */
3617 	entry = create_proc_entry("BSSList",
3618 				  S_IFREG | proc_perm,
3619 				  apriv->proc_entry);
3620 	entry->uid = proc_uid;
3621 	entry->gid = proc_gid;
3622 	entry->data = dev;
3623 	entry->owner = THIS_MODULE;
3624 	SETPROC_OPS(entry, proc_BSSList_ops);
3625 
3626 	/* Setup the WepKey */
3627 	entry = create_proc_entry("WepKey",
3628 				  S_IFREG | proc_perm,
3629 				  apriv->proc_entry);
3630         entry->uid = proc_uid;
3631         entry->gid = proc_gid;
3632 	entry->data = dev;
3633 	entry->owner = THIS_MODULE;
3634 	SETPROC_OPS(entry, proc_wepkey_ops);
3635 
3636 	return 0;
3637 }
3638 
3639 static int takedown_proc_entry( struct net_device *dev,
3640 				struct airo_info *apriv ) {
3641 	if ( !apriv->proc_entry->namelen ) return 0;
3642 	remove_proc_entry("Stats",apriv->proc_entry);
3643 	remove_proc_entry("StatsDelta",apriv->proc_entry);
3644 	remove_proc_entry("Status",apriv->proc_entry);
3645 	remove_proc_entry("Config",apriv->proc_entry);
3646 	remove_proc_entry("SSID",apriv->proc_entry);
3647 	remove_proc_entry("APList",apriv->proc_entry);
3648 	remove_proc_entry("BSSList",apriv->proc_entry);
3649 	remove_proc_entry("WepKey",apriv->proc_entry);
3650 	remove_proc_entry(dev->name,airo_entry);
3651 	return 0;
3652 }
3653 
3654 /*
3655  *  What we want from the proc_fs is to be able to efficiently read
3656  *  and write the configuration.  To do this, we want to read the
3657  *  configuration when the file is opened and write it when the file is
3658  *  closed.  So basically we allocate a read buffer at open and fill it
3659  *  with data, and allocate a write buffer and read it at close.
3660  */
3661 
3662 /*
3663  *  The read routine is generic, it relies on the preallocated rbuffer
3664  *  to supply the data.
3665  */
3666 static ssize_t proc_read( struct file *file,
3667 			  char *buffer,
3668 			  size_t len,
3669 			  loff_t *offset )
3670 {
3671 	loff_t pos = *offset;
3672 	struct proc_data *priv = (struct proc_data*)file->private_data;
3673 
3674 	if (!priv->rbuffer)
3675 		return -EINVAL;
3676 
3677 	if (pos < 0)
3678 		return -EINVAL;
3679 	if (pos >= priv->readlen)
3680 		return 0;
3681 	if (len > priv->readlen - pos)
3682 		len = priv->readlen - pos;
3683 	if (copy_to_user(buffer, priv->rbuffer + pos, len))
3684 		return -EFAULT;
3685 	*offset = pos + len;
3686 	return len;
3687 }
3688 
3689 /*
3690  *  The write routine is generic, it fills in a preallocated rbuffer
3691  *  to supply the data.
3692  */
3693 static ssize_t proc_write( struct file *file,
3694 			   const char *buffer,
3695 			   size_t len,
3696 			   loff_t *offset )
3697 {
3698 	loff_t pos = *offset;
3699 	struct proc_data *priv = (struct proc_data*)file->private_data;
3700 
3701 	if (!priv->wbuffer)
3702 		return -EINVAL;
3703 
3704 	if (pos < 0)
3705 		return -EINVAL;
3706 	if (pos >= priv->maxwritelen)
3707 		return 0;
3708 	if (len > priv->maxwritelen - pos)
3709 		len = priv->maxwritelen - pos;
3710 	if (copy_from_user(priv->wbuffer + pos, buffer, len))
3711 		return -EFAULT;
3712 	if (pos + len > priv->writelen)
3713 		priv->writelen = pos + len;
3714 	*offset = pos + len;
3715 	return len;
3716 }
3717 
3718 static int proc_status_open( struct inode *inode, struct file *file ) {
3719 	struct proc_data *data;
3720 	struct proc_dir_entry *dp = PDE(inode);
3721 	struct net_device *dev = dp->data;
3722 	struct airo_info *apriv = dev->priv;
3723 	CapabilityRid cap_rid;
3724 	StatusRid status_rid;
3725 	int i;
3726 
3727 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3728 		return -ENOMEM;
3729 	memset(file->private_data, 0, sizeof(struct proc_data));
3730 	data = (struct proc_data *)file->private_data;
3731 	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
3732 		kfree (file->private_data);
3733 		return -ENOMEM;
3734 	}
3735 
3736 	readStatusRid(apriv, &status_rid, 1);
3737 	readCapabilityRid(apriv, &cap_rid);
3738 
3739         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
3740                     status_rid.mode & 1 ? "CFG ": "",
3741                     status_rid.mode & 2 ? "ACT ": "",
3742                     status_rid.mode & 0x10 ? "SYN ": "",
3743                     status_rid.mode & 0x20 ? "LNK ": "",
3744                     status_rid.mode & 0x40 ? "LEAP ": "",
3745                     status_rid.mode & 0x80 ? "PRIV ": "",
3746                     status_rid.mode & 0x100 ? "KEY ": "",
3747                     status_rid.mode & 0x200 ? "WEP ": "",
3748                     status_rid.mode & 0x8000 ? "ERR ": "");
3749 	sprintf( data->rbuffer+i, "Mode: %x\n"
3750 		 "Signal Strength: %d\n"
3751 		 "Signal Quality: %d\n"
3752 		 "SSID: %-.*s\n"
3753 		 "AP: %-.16s\n"
3754 		 "Freq: %d\n"
3755 		 "BitRate: %dmbs\n"
3756 		 "Driver Version: %s\n"
3757 		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
3758 		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
3759 		 "Software Version: %x\nSoftware Subversion: %x\n"
3760 		 "Boot block version: %x\n",
3761 		 (int)status_rid.mode,
3762 		 (int)status_rid.normalizedSignalStrength,
3763 		 (int)status_rid.signalQuality,
3764 		 (int)status_rid.SSIDlen,
3765 		 status_rid.SSID,
3766 		 status_rid.apName,
3767 		 (int)status_rid.channel,
3768 		 (int)status_rid.currentXmitRate/2,
3769 		 version,
3770 		 cap_rid.prodName,
3771 		 cap_rid.manName,
3772 		 cap_rid.prodVer,
3773 		 cap_rid.radioType,
3774 		 cap_rid.country,
3775 		 cap_rid.hardVer,
3776 		 (int)cap_rid.softVer,
3777 		 (int)cap_rid.softSubVer,
3778 		 (int)cap_rid.bootBlockVer );
3779 	data->readlen = strlen( data->rbuffer );
3780 	return 0;
3781 }
3782 
3783 static int proc_stats_rid_open(struct inode*, struct file*, u16);
3784 static int proc_statsdelta_open( struct inode *inode,
3785 				 struct file *file ) {
3786 	if (file->f_mode&FMODE_WRITE) {
3787 		return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
3788 	}
3789 	return proc_stats_rid_open(inode, file, RID_STATSDELTA);
3790 }
3791 
3792 static int proc_stats_open( struct inode *inode, struct file *file ) {
3793 	return proc_stats_rid_open(inode, file, RID_STATS);
3794 }
3795 
3796 static int proc_stats_rid_open( struct inode *inode,
3797 				struct file *file,
3798 				u16 rid ) {
3799 	struct proc_data *data;
3800 	struct proc_dir_entry *dp = PDE(inode);
3801 	struct net_device *dev = dp->data;
3802 	struct airo_info *apriv = dev->priv;
3803 	StatsRid stats;
3804 	int i, j;
3805 	int *vals = stats.vals;
3806 
3807 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3808 		return -ENOMEM;
3809 	memset(file->private_data, 0, sizeof(struct proc_data));
3810 	data = (struct proc_data *)file->private_data;
3811 	if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
3812 		kfree (file->private_data);
3813 		return -ENOMEM;
3814 	}
3815 
3816 	readStatsRid(apriv, &stats, rid, 1);
3817 
3818         j = 0;
3819 	for(i=0; statsLabels[i]!=(char *)-1 &&
3820 		    i*4<stats.len; i++){
3821 		if (!statsLabels[i]) continue;
3822 		if (j+strlen(statsLabels[i])+16>4096) {
3823 			printk(KERN_WARNING
3824 			       "airo: Potentially disasterous buffer overflow averted!\n");
3825 			break;
3826 		}
3827 		j+=sprintf(data->rbuffer+j, "%s: %d\n", statsLabels[i], vals[i]);
3828 	}
3829 	if (i*4>=stats.len){
3830 		printk(KERN_WARNING
3831 		       "airo: Got a short rid\n");
3832 	}
3833 	data->readlen = j;
3834 	return 0;
3835 }
3836 
3837 static int get_dec_u16( char *buffer, int *start, int limit ) {
3838 	u16 value;
3839 	int valid = 0;
3840 	for( value = 0; buffer[*start] >= '0' &&
3841 		     buffer[*start] <= '9' &&
3842 		     *start < limit; (*start)++ ) {
3843 		valid = 1;
3844 		value *= 10;
3845 		value += buffer[*start] - '0';
3846 	}
3847 	if ( !valid ) return -1;
3848 	return value;
3849 }
3850 
3851 static int airo_config_commit(struct net_device *dev,
3852 			      struct iw_request_info *info, void *zwrq,
3853 			      char *extra);
3854 
3855 static void proc_config_on_close( struct inode *inode, struct file *file ) {
3856 	struct proc_data *data = file->private_data;
3857 	struct proc_dir_entry *dp = PDE(inode);
3858 	struct net_device *dev = dp->data;
3859 	struct airo_info *ai = dev->priv;
3860 	char *line;
3861 
3862 	if ( !data->writelen ) return;
3863 
3864 	readConfigRid(ai, 1);
3865 	ai->need_commit = 1;
3866 
3867 	line = data->wbuffer;
3868 	while( line[0] ) {
3869 /*** Mode processing */
3870 		if ( !strncmp( line, "Mode: ", 6 ) ) {
3871 			line += 6;
3872 			if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
3873 					ai->need_commit = 2;
3874 			ai->config.rmode &= 0xfe00;
3875 			clear_bit (FLAG_802_11, &ai->flags);
3876 			ai->config.opmode &= 0xFF00;
3877 			ai->config.scanMode = SCANMODE_ACTIVE;
3878 			if ( line[0] == 'a' ) {
3879 				ai->config.opmode |= 0;
3880 			} else {
3881 				ai->config.opmode |= 1;
3882 				if ( line[0] == 'r' ) {
3883 					ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
3884 					ai->config.scanMode = SCANMODE_PASSIVE;
3885 					set_bit (FLAG_802_11, &ai->flags);
3886 				} else if ( line[0] == 'y' ) {
3887 					ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
3888 					ai->config.scanMode = SCANMODE_PASSIVE;
3889 					set_bit (FLAG_802_11, &ai->flags);
3890 				} else if ( line[0] == 'l' )
3891 					ai->config.rmode |= RXMODE_LANMON;
3892 			}
3893 			ai->need_commit = 1;
3894 		}
3895 
3896 /*** Radio status */
3897 		else if (!strncmp(line,"Radio: ", 7)) {
3898 			line += 7;
3899 			if (!strncmp(line,"off",3)) {
3900 				set_bit (FLAG_RADIO_OFF, &ai->flags);
3901 			} else {
3902 				clear_bit (FLAG_RADIO_OFF, &ai->flags);
3903 			}
3904 		}
3905 /*** NodeName processing */
3906 		else if ( !strncmp( line, "NodeName: ", 10 ) ) {
3907 			int j;
3908 
3909 			line += 10;
3910 			memset( ai->config.nodeName, 0, 16 );
3911 /* Do the name, assume a space between the mode and node name */
3912 			for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
3913 				ai->config.nodeName[j] = line[j];
3914 			}
3915 			ai->need_commit = 1;
3916 		}
3917 
3918 /*** PowerMode processing */
3919 		else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
3920 			line += 11;
3921 			if ( !strncmp( line, "PSPCAM", 6 ) ) {
3922 				ai->config.powerSaveMode = POWERSAVE_PSPCAM;
3923 				ai->need_commit = 1;
3924 			} else if ( !strncmp( line, "PSP", 3 ) ) {
3925 				ai->config.powerSaveMode = POWERSAVE_PSP;
3926 				ai->need_commit = 1;
3927 			} else {
3928 				ai->config.powerSaveMode = POWERSAVE_CAM;
3929 				ai->need_commit = 1;
3930 			}
3931 		} else if ( !strncmp( line, "DataRates: ", 11 ) ) {
3932 			int v, i = 0, k = 0; /* i is index into line,
3933 						k is index to rates */
3934 
3935 			line += 11;
3936 			while((v = get_dec_u16(line, &i, 3))!=-1) {
3937 				ai->config.rates[k++] = (u8)v;
3938 				line += i + 1;
3939 				i = 0;
3940 			}
3941 			ai->need_commit = 1;
3942 		} else if ( !strncmp( line, "Channel: ", 9 ) ) {
3943 			int v, i = 0;
3944 			line += 9;
3945 			v = get_dec_u16(line, &i, i+3);
3946 			if ( v != -1 ) {
3947 				ai->config.channelSet = (u16)v;
3948 				ai->need_commit = 1;
3949 			}
3950 		} else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
3951 			int v, i = 0;
3952 			line += 11;
3953 			v = get_dec_u16(line, &i, i+3);
3954 			if ( v != -1 ) {
3955 				ai->config.txPower = (u16)v;
3956 				ai->need_commit = 1;
3957 			}
3958 		} else if ( !strncmp( line, "WEP: ", 5 ) ) {
3959 			line += 5;
3960 			switch( line[0] ) {
3961 			case 's':
3962 				ai->config.authType = (u16)AUTH_SHAREDKEY;
3963 				break;
3964 			case 'e':
3965 				ai->config.authType = (u16)AUTH_ENCRYPT;
3966 				break;
3967 			default:
3968 				ai->config.authType = (u16)AUTH_OPEN;
3969 				break;
3970 			}
3971 			ai->need_commit = 1;
3972 		} else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
3973 			int v, i = 0;
3974 
3975 			line += 16;
3976 			v = get_dec_u16(line, &i, 3);
3977 			v = (v<0) ? 0 : ((v>255) ? 255 : v);
3978 			ai->config.longRetryLimit = (u16)v;
3979 			ai->need_commit = 1;
3980 		} else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
3981 			int v, i = 0;
3982 
3983 			line += 17;
3984 			v = get_dec_u16(line, &i, 3);
3985 			v = (v<0) ? 0 : ((v>255) ? 255 : v);
3986 			ai->config.shortRetryLimit = (u16)v;
3987 			ai->need_commit = 1;
3988 		} else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
3989 			int v, i = 0;
3990 
3991 			line += 14;
3992 			v = get_dec_u16(line, &i, 4);
3993 			v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
3994 			ai->config.rtsThres = (u16)v;
3995 			ai->need_commit = 1;
3996 		} else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
3997 			int v, i = 0;
3998 
3999 			line += 16;
4000 			v = get_dec_u16(line, &i, 5);
4001 			v = (v<0) ? 0 : v;
4002 			ai->config.txLifetime = (u16)v;
4003 			ai->need_commit = 1;
4004 		} else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
4005 			int v, i = 0;
4006 
4007 			line += 16;
4008 			v = get_dec_u16(line, &i, 5);
4009 			v = (v<0) ? 0 : v;
4010 			ai->config.rxLifetime = (u16)v;
4011 			ai->need_commit = 1;
4012 		} else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4013 			ai->config.txDiversity =
4014 				(line[13]=='l') ? 1 :
4015 				((line[13]=='r')? 2: 3);
4016 			ai->need_commit = 1;
4017 		} else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4018 			ai->config.rxDiversity =
4019 				(line[13]=='l') ? 1 :
4020 				((line[13]=='r')? 2: 3);
4021 			ai->need_commit = 1;
4022 		} else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4023 			int v, i = 0;
4024 
4025 			line += 15;
4026 			v = get_dec_u16(line, &i, 4);
4027 			v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
4028 			v = v & 0xfffe; /* Make sure its even */
4029 			ai->config.fragThresh = (u16)v;
4030 			ai->need_commit = 1;
4031 		} else if (!strncmp(line, "Modulation: ", 12)) {
4032 			line += 12;
4033 			switch(*line) {
4034 			case 'd':  ai->config.modulation=MOD_DEFAULT; ai->need_commit=1; break;
4035 			case 'c':  ai->config.modulation=MOD_CCK; ai->need_commit=1; break;
4036 			case 'm':  ai->config.modulation=MOD_MOK; ai->need_commit=1; break;
4037 			default:
4038 				printk( KERN_WARNING "airo: Unknown modulation\n" );
4039 			}
4040 		} else if (!strncmp(line, "Preamble: ", 10)) {
4041 			line += 10;
4042 			switch(*line) {
4043 			case 'a': ai->config.preamble=PREAMBLE_AUTO; ai->need_commit=1; break;
4044 			case 'l': ai->config.preamble=PREAMBLE_LONG; ai->need_commit=1; break;
4045 			case 's': ai->config.preamble=PREAMBLE_SHORT; ai->need_commit=1; break;
4046 		        default: printk(KERN_WARNING "airo: Unknown preamble\n");
4047 			}
4048 		} else {
4049 			printk( KERN_WARNING "Couldn't figure out %s\n", line );
4050 		}
4051 		while( line[0] && line[0] != '\n' ) line++;
4052 		if ( line[0] ) line++;
4053 	}
4054 	airo_config_commit(dev, NULL, NULL, NULL);
4055 }
4056 
4057 static char *get_rmode(u16 mode) {
4058         switch(mode&0xff) {
4059         case RXMODE_RFMON:  return "rfmon";
4060         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
4061         case RXMODE_LANMON:  return "lanmon";
4062         }
4063         return "ESS";
4064 }
4065 
4066 static int proc_config_open( struct inode *inode, struct file *file ) {
4067 	struct proc_data *data;
4068 	struct proc_dir_entry *dp = PDE(inode);
4069 	struct net_device *dev = dp->data;
4070 	struct airo_info *ai = dev->priv;
4071 	int i;
4072 
4073 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4074 		return -ENOMEM;
4075 	memset(file->private_data, 0, sizeof(struct proc_data));
4076 	data = (struct proc_data *)file->private_data;
4077 	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4078 		kfree (file->private_data);
4079 		return -ENOMEM;
4080 	}
4081 	if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4082 		kfree (data->rbuffer);
4083 		kfree (file->private_data);
4084 		return -ENOMEM;
4085 	}
4086 	memset( data->wbuffer, 0, 2048 );
4087 	data->maxwritelen = 2048;
4088 	data->on_close = proc_config_on_close;
4089 
4090 	readConfigRid(ai, 1);
4091 
4092 	i = sprintf( data->rbuffer,
4093 		     "Mode: %s\n"
4094 		     "Radio: %s\n"
4095 		     "NodeName: %-16s\n"
4096 		     "PowerMode: %s\n"
4097 		     "DataRates: %d %d %d %d %d %d %d %d\n"
4098 		     "Channel: %d\n"
4099 		     "XmitPower: %d\n",
4100 		     (ai->config.opmode & 0xFF) == 0 ? "adhoc" :
4101 		     (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode):
4102 		     (ai->config.opmode & 0xFF) == 2 ? "AP" :
4103 		     (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error",
4104 		     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
4105 		     ai->config.nodeName,
4106 		     ai->config.powerSaveMode == 0 ? "CAM" :
4107 		     ai->config.powerSaveMode == 1 ? "PSP" :
4108 		     ai->config.powerSaveMode == 2 ? "PSPCAM" : "Error",
4109 		     (int)ai->config.rates[0],
4110 		     (int)ai->config.rates[1],
4111 		     (int)ai->config.rates[2],
4112 		     (int)ai->config.rates[3],
4113 		     (int)ai->config.rates[4],
4114 		     (int)ai->config.rates[5],
4115 		     (int)ai->config.rates[6],
4116 		     (int)ai->config.rates[7],
4117 		     (int)ai->config.channelSet,
4118 		     (int)ai->config.txPower
4119 		);
4120 	sprintf( data->rbuffer + i,
4121 		 "LongRetryLimit: %d\n"
4122 		 "ShortRetryLimit: %d\n"
4123 		 "RTSThreshold: %d\n"
4124 		 "TXMSDULifetime: %d\n"
4125 		 "RXMSDULifetime: %d\n"
4126 		 "TXDiversity: %s\n"
4127 		 "RXDiversity: %s\n"
4128 		 "FragThreshold: %d\n"
4129 		 "WEP: %s\n"
4130 		 "Modulation: %s\n"
4131 		 "Preamble: %s\n",
4132 		 (int)ai->config.longRetryLimit,
4133 		 (int)ai->config.shortRetryLimit,
4134 		 (int)ai->config.rtsThres,
4135 		 (int)ai->config.txLifetime,
4136 		 (int)ai->config.rxLifetime,
4137 		 ai->config.txDiversity == 1 ? "left" :
4138 		 ai->config.txDiversity == 2 ? "right" : "both",
4139 		 ai->config.rxDiversity == 1 ? "left" :
4140 		 ai->config.rxDiversity == 2 ? "right" : "both",
4141 		 (int)ai->config.fragThresh,
4142 		 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
4143 		 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
4144 		 ai->config.modulation == 0 ? "default" :
4145 		 ai->config.modulation == MOD_CCK ? "cck" :
4146 		 ai->config.modulation == MOD_MOK ? "mok" : "error",
4147 		 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
4148 		 ai->config.preamble == PREAMBLE_LONG ? "long" :
4149 		 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
4150 		);
4151 	data->readlen = strlen( data->rbuffer );
4152 	return 0;
4153 }
4154 
4155 static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
4156 	struct proc_data *data = (struct proc_data *)file->private_data;
4157 	struct proc_dir_entry *dp = PDE(inode);
4158 	struct net_device *dev = dp->data;
4159 	struct airo_info *ai = dev->priv;
4160 	SsidRid SSID_rid;
4161 	Resp rsp;
4162 	int i;
4163 	int offset = 0;
4164 
4165 	if ( !data->writelen ) return;
4166 
4167 	memset( &SSID_rid, 0, sizeof( SSID_rid ) );
4168 
4169 	for( i = 0; i < 3; i++ ) {
4170 		int j;
4171 		for( j = 0; j+offset < data->writelen && j < 32 &&
4172 			     data->wbuffer[offset+j] != '\n'; j++ ) {
4173 			SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
4174 		}
4175 		if ( j == 0 ) break;
4176 		SSID_rid.ssids[i].len = j;
4177 		offset += j;
4178 		while( data->wbuffer[offset] != '\n' &&
4179 		       offset < data->writelen ) offset++;
4180 		offset++;
4181 	}
4182 	if (i)
4183 		SSID_rid.len = sizeof(SSID_rid);
4184 	disable_MAC(ai, 1);
4185 	writeSsidRid(ai, &SSID_rid);
4186 	enable_MAC(ai, &rsp, 1);
4187 }
4188 
4189 inline static u8 hexVal(char c) {
4190 	if (c>='0' && c<='9') return c -= '0';
4191 	if (c>='a' && c<='f') return c -= 'a'-10;
4192 	if (c>='A' && c<='F') return c -= 'A'-10;
4193 	return 0;
4194 }
4195 
4196 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
4197 	struct proc_data *data = (struct proc_data *)file->private_data;
4198 	struct proc_dir_entry *dp = PDE(inode);
4199 	struct net_device *dev = dp->data;
4200 	struct airo_info *ai = dev->priv;
4201 	APListRid APList_rid;
4202 	Resp rsp;
4203 	int i;
4204 
4205 	if ( !data->writelen ) return;
4206 
4207 	memset( &APList_rid, 0, sizeof(APList_rid) );
4208 	APList_rid.len = sizeof(APList_rid);
4209 
4210 	for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
4211 		int j;
4212 		for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
4213 			switch(j%3) {
4214 			case 0:
4215 				APList_rid.ap[i][j/3]=
4216 					hexVal(data->wbuffer[j+i*6*3])<<4;
4217 				break;
4218 			case 1:
4219 				APList_rid.ap[i][j/3]|=
4220 					hexVal(data->wbuffer[j+i*6*3]);
4221 				break;
4222 			}
4223 		}
4224 	}
4225 	disable_MAC(ai, 1);
4226 	writeAPListRid(ai, &APList_rid);
4227 	enable_MAC(ai, &rsp, 1);
4228 }
4229 
4230 /* This function wraps PC4500_writerid with a MAC disable */
4231 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
4232 			int len, int dummy ) {
4233 	int rc;
4234 	Resp rsp;
4235 
4236 	disable_MAC(ai, 1);
4237 	rc = PC4500_writerid(ai, rid, rid_data, len, 1);
4238 	enable_MAC(ai, &rsp, 1);
4239 	return rc;
4240 }
4241 
4242 /* Returns the length of the key at the index.  If index == 0xffff
4243  * the index of the transmit key is returned.  If the key doesn't exist,
4244  * -1 will be returned.
4245  */
4246 static int get_wep_key(struct airo_info *ai, u16 index) {
4247 	WepKeyRid wkr;
4248 	int rc;
4249 	u16 lastindex;
4250 
4251 	rc = readWepKeyRid(ai, &wkr, 1);
4252 	if (rc == SUCCESS) do {
4253 		lastindex = wkr.kindex;
4254 		if (wkr.kindex == index) {
4255 			if (index == 0xffff) {
4256 				return wkr.mac[0];
4257 			}
4258 			return wkr.klen;
4259 		}
4260 		readWepKeyRid(ai, &wkr, 0);
4261 	} while(lastindex != wkr.kindex);
4262 	return -1;
4263 }
4264 
4265 static int set_wep_key(struct airo_info *ai, u16 index,
4266 		       const char *key, u16 keylen, int perm, int lock ) {
4267 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
4268 	WepKeyRid wkr;
4269 
4270 	memset(&wkr, 0, sizeof(wkr));
4271 	if (keylen == 0) {
4272 // We are selecting which key to use
4273 		wkr.len = sizeof(wkr);
4274 		wkr.kindex = 0xffff;
4275 		wkr.mac[0] = (char)index;
4276 		if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
4277 		if (perm) ai->defindex = (char)index;
4278 	} else {
4279 // We are actually setting the key
4280 		wkr.len = sizeof(wkr);
4281 		wkr.kindex = index;
4282 		wkr.klen = keylen;
4283 		memcpy( wkr.key, key, keylen );
4284 		memcpy( wkr.mac, macaddr, ETH_ALEN );
4285 		printk(KERN_INFO "Setting key %d\n", index);
4286 	}
4287 
4288 	writeWepKeyRid(ai, &wkr, perm, lock);
4289 	return 0;
4290 }
4291 
4292 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
4293 	struct proc_data *data;
4294 	struct proc_dir_entry *dp = PDE(inode);
4295 	struct net_device *dev = dp->data;
4296 	struct airo_info *ai = dev->priv;
4297 	int i;
4298 	char key[16];
4299 	u16 index = 0;
4300 	int j = 0;
4301 
4302 	memset(key, 0, sizeof(key));
4303 
4304 	data = (struct proc_data *)file->private_data;
4305 	if ( !data->writelen ) return;
4306 
4307 	if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
4308 	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
4309 		index = data->wbuffer[0] - '0';
4310 		if (data->wbuffer[1] == '\n') {
4311 			set_wep_key(ai, index, 0, 0, 1, 1);
4312 			return;
4313 		}
4314 		j = 2;
4315 	} else {
4316 		printk(KERN_ERR "airo:  WepKey passed invalid key index\n");
4317 		return;
4318 	}
4319 
4320 	for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
4321 		switch(i%3) {
4322 		case 0:
4323 			key[i/3] = hexVal(data->wbuffer[i+j])<<4;
4324 			break;
4325 		case 1:
4326 			key[i/3] |= hexVal(data->wbuffer[i+j]);
4327 			break;
4328 		}
4329 	}
4330 	set_wep_key(ai, index, key, i/3, 1, 1);
4331 }
4332 
4333 static int proc_wepkey_open( struct inode *inode, struct file *file ) {
4334 	struct proc_data *data;
4335 	struct proc_dir_entry *dp = PDE(inode);
4336 	struct net_device *dev = dp->data;
4337 	struct airo_info *ai = dev->priv;
4338 	char *ptr;
4339 	WepKeyRid wkr;
4340 	u16 lastindex;
4341 	int j=0;
4342 	int rc;
4343 
4344 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4345 		return -ENOMEM;
4346 	memset(file->private_data, 0, sizeof(struct proc_data));
4347 	memset(&wkr, 0, sizeof(wkr));
4348 	data = (struct proc_data *)file->private_data;
4349 	if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
4350 		kfree (file->private_data);
4351 		return -ENOMEM;
4352 	}
4353 	memset(data->rbuffer, 0, 180);
4354 	data->writelen = 0;
4355 	data->maxwritelen = 80;
4356 	if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
4357 		kfree (data->rbuffer);
4358 		kfree (file->private_data);
4359 		return -ENOMEM;
4360 	}
4361 	memset( data->wbuffer, 0, 80 );
4362 	data->on_close = proc_wepkey_on_close;
4363 
4364 	ptr = data->rbuffer;
4365 	strcpy(ptr, "No wep keys\n");
4366 	rc = readWepKeyRid(ai, &wkr, 1);
4367 	if (rc == SUCCESS) do {
4368 		lastindex = wkr.kindex;
4369 		if (wkr.kindex == 0xffff) {
4370 			j += sprintf(ptr+j, "Tx key = %d\n",
4371 				     (int)wkr.mac[0]);
4372 		} else {
4373 			j += sprintf(ptr+j, "Key %d set with length = %d\n",
4374 				     (int)wkr.kindex, (int)wkr.klen);
4375 		}
4376 		readWepKeyRid(ai, &wkr, 0);
4377 	} while((lastindex != wkr.kindex) && (j < 180-30));
4378 
4379 	data->readlen = strlen( data->rbuffer );
4380 	return 0;
4381 }
4382 
4383 static int proc_SSID_open( struct inode *inode, struct file *file ) {
4384 	struct proc_data *data;
4385 	struct proc_dir_entry *dp = PDE(inode);
4386 	struct net_device *dev = dp->data;
4387 	struct airo_info *ai = dev->priv;
4388 	int i;
4389 	char *ptr;
4390 	SsidRid SSID_rid;
4391 
4392 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4393 		return -ENOMEM;
4394 	memset(file->private_data, 0, sizeof(struct proc_data));
4395 	data = (struct proc_data *)file->private_data;
4396 	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
4397 		kfree (file->private_data);
4398 		return -ENOMEM;
4399 	}
4400 	data->writelen = 0;
4401 	data->maxwritelen = 33*3;
4402 	if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
4403 		kfree (data->rbuffer);
4404 		kfree (file->private_data);
4405 		return -ENOMEM;
4406 	}
4407 	memset( data->wbuffer, 0, 33*3 );
4408 	data->on_close = proc_SSID_on_close;
4409 
4410 	readSsidRid(ai, &SSID_rid);
4411 	ptr = data->rbuffer;
4412 	for( i = 0; i < 3; i++ ) {
4413 		int j;
4414 		if ( !SSID_rid.ssids[i].len ) break;
4415 		for( j = 0; j < 32 &&
4416 			     j < SSID_rid.ssids[i].len &&
4417 			     SSID_rid.ssids[i].ssid[j]; j++ ) {
4418 			*ptr++ = SSID_rid.ssids[i].ssid[j];
4419 		}
4420 		*ptr++ = '\n';
4421 	}
4422 	*ptr = '\0';
4423 	data->readlen = strlen( data->rbuffer );
4424 	return 0;
4425 }
4426 
4427 static int proc_APList_open( struct inode *inode, struct file *file ) {
4428 	struct proc_data *data;
4429 	struct proc_dir_entry *dp = PDE(inode);
4430 	struct net_device *dev = dp->data;
4431 	struct airo_info *ai = dev->priv;
4432 	int i;
4433 	char *ptr;
4434 	APListRid APList_rid;
4435 
4436 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4437 		return -ENOMEM;
4438 	memset(file->private_data, 0, sizeof(struct proc_data));
4439 	data = (struct proc_data *)file->private_data;
4440 	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
4441 		kfree (file->private_data);
4442 		return -ENOMEM;
4443 	}
4444 	data->writelen = 0;
4445 	data->maxwritelen = 4*6*3;
4446 	if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
4447 		kfree (data->rbuffer);
4448 		kfree (file->private_data);
4449 		return -ENOMEM;
4450 	}
4451 	memset( data->wbuffer, 0, data->maxwritelen );
4452 	data->on_close = proc_APList_on_close;
4453 
4454 	readAPListRid(ai, &APList_rid);
4455 	ptr = data->rbuffer;
4456 	for( i = 0; i < 4; i++ ) {
4457 // We end when we find a zero MAC
4458 		if ( !*(int*)APList_rid.ap[i] &&
4459 		     !*(int*)&APList_rid.ap[i][2]) break;
4460 		ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n",
4461 			       (int)APList_rid.ap[i][0],
4462 			       (int)APList_rid.ap[i][1],
4463 			       (int)APList_rid.ap[i][2],
4464 			       (int)APList_rid.ap[i][3],
4465 			       (int)APList_rid.ap[i][4],
4466 			       (int)APList_rid.ap[i][5]);
4467 	}
4468 	if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
4469 
4470 	*ptr = '\0';
4471 	data->readlen = strlen( data->rbuffer );
4472 	return 0;
4473 }
4474 
4475 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
4476 	struct proc_data *data;
4477 	struct proc_dir_entry *dp = PDE(inode);
4478 	struct net_device *dev = dp->data;
4479 	struct airo_info *ai = dev->priv;
4480 	char *ptr;
4481 	BSSListRid BSSList_rid;
4482 	int rc;
4483 	/* If doLoseSync is not 1, we won't do a Lose Sync */
4484 	int doLoseSync = -1;
4485 
4486 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4487 		return -ENOMEM;
4488 	memset(file->private_data, 0, sizeof(struct proc_data));
4489 	data = (struct proc_data *)file->private_data;
4490 	if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
4491 		kfree (file->private_data);
4492 		return -ENOMEM;
4493 	}
4494 	data->writelen = 0;
4495 	data->maxwritelen = 0;
4496 	data->wbuffer = 0;
4497 	data->on_close = 0;
4498 
4499 	if (file->f_mode & FMODE_WRITE) {
4500 		if (!(file->f_mode & FMODE_READ)) {
4501 			Cmd cmd;
4502 			Resp rsp;
4503 
4504 			memset(&cmd, 0, sizeof(cmd));
4505 			cmd.cmd=CMD_LISTBSS;
4506 			if (down_interruptible(&ai->sem))
4507 				return -ERESTARTSYS;
4508 			issuecommand(ai, &cmd, &rsp);
4509 			up(&ai->sem);
4510 			data->readlen = 0;
4511 			return 0;
4512 		}
4513 		doLoseSync = 1;
4514 	}
4515 	ptr = data->rbuffer;
4516 	/* There is a race condition here if there are concurrent opens.
4517            Since it is a rare condition, we'll just live with it, otherwise
4518            we have to add a spin lock... */
4519 	rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
4520 	while(rc == 0 && BSSList_rid.index != 0xffff) {
4521 		ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x %*s rssi = %d",
4522 				(int)BSSList_rid.bssid[0],
4523 				(int)BSSList_rid.bssid[1],
4524 				(int)BSSList_rid.bssid[2],
4525 				(int)BSSList_rid.bssid[3],
4526 				(int)BSSList_rid.bssid[4],
4527 				(int)BSSList_rid.bssid[5],
4528 				(int)BSSList_rid.ssidLen,
4529 				BSSList_rid.ssid,
4530 				(int)BSSList_rid.rssi);
4531 		ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
4532 				(int)BSSList_rid.dsChannel,
4533 				BSSList_rid.cap & CAP_ESS ? "ESS" : "",
4534 				BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
4535 				BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
4536 				BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
4537 		rc = readBSSListRid(ai, 0, &BSSList_rid);
4538 	}
4539 	*ptr = '\0';
4540 	data->readlen = strlen( data->rbuffer );
4541 	return 0;
4542 }
4543 
4544 static int proc_close( struct inode *inode, struct file *file )
4545 {
4546 	struct proc_data *data = (struct proc_data *)file->private_data;
4547 	if ( data->on_close != NULL ) data->on_close( inode, file );
4548 	if ( data->rbuffer ) kfree( data->rbuffer );
4549 	if ( data->wbuffer ) kfree( data->wbuffer );
4550 	kfree( data );
4551 	return 0;
4552 }
4553 
4554 static struct net_device_list {
4555 	struct net_device *dev;
4556 	struct net_device_list *next;
4557 } *airo_devices = 0;
4558 
4559 /* Since the card doesn't automatically switch to the right WEP mode,
4560    we will make it do it.  If the card isn't associated, every secs we
4561    will switch WEP modes to see if that will help.  If the card is
4562    associated we will check every minute to see if anything has
4563    changed. */
4564 static void timer_func( struct net_device *dev ) {
4565 	struct airo_info *apriv = dev->priv;
4566 	Resp rsp;
4567 
4568 /* We don't have a link so try changing the authtype */
4569 	readConfigRid(apriv, 0);
4570 	disable_MAC(apriv, 0);
4571 	switch(apriv->config.authType) {
4572 		case AUTH_ENCRYPT:
4573 /* So drop to OPEN */
4574 			apriv->config.authType = AUTH_OPEN;
4575 			break;
4576 		case AUTH_SHAREDKEY:
4577 			if (apriv->keyindex < auto_wep) {
4578 				set_wep_key(apriv, apriv->keyindex, 0, 0, 0, 0);
4579 				apriv->config.authType = AUTH_SHAREDKEY;
4580 				apriv->keyindex++;
4581 			} else {
4582 			        /* Drop to ENCRYPT */
4583 				apriv->keyindex = 0;
4584 				set_wep_key(apriv, apriv->defindex, 0, 0, 0, 0);
4585 				apriv->config.authType = AUTH_ENCRYPT;
4586 			}
4587 			break;
4588 		default:  /* We'll escalate to SHAREDKEY */
4589 			apriv->config.authType = AUTH_SHAREDKEY;
4590 	}
4591 	apriv->need_commit = 1;
4592 	writeConfigRid(apriv, 0);
4593 	enable_MAC(apriv, &rsp, 0);
4594 	up(&apriv->sem);
4595 
4596 /* Schedule check to see if the change worked */
4597 	clear_bit(JOB_AUTOWEP, &apriv->flags);
4598 	apriv->expires = RUN_AT(HZ*3);
4599 }
4600 
4601 static int add_airo_dev( struct net_device *dev ) {
4602 	struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
4603 	if ( !node )
4604 		return -ENOMEM;
4605 
4606 	node->dev = dev;
4607 	node->next = airo_devices;
4608 	airo_devices = node;
4609 
4610 	return 0;
4611 }
4612 
4613 static void del_airo_dev( struct net_device *dev ) {
4614 	struct net_device_list **p = &airo_devices;
4615 	while( *p && ( (*p)->dev != dev ) )
4616 		p = &(*p)->next;
4617 	if ( *p && (*p)->dev == dev )
4618 		*p = (*p)->next;
4619 }
4620 
4621 #ifdef CONFIG_PCI
4622 static int __devinit airo_pci_probe(struct pci_dev *pdev,
4623 				    const struct pci_device_id *pent)
4624 {
4625 	struct net_device *dev;
4626 
4627 	if (pci_enable_device(pdev))
4628 		return -ENODEV;
4629 	pci_set_master(pdev);
4630 
4631 	dev = init_airo_card(pdev->irq,	pdev->resource[2].start, 0);
4632 	if (!dev)
4633 		return -ENODEV;
4634 
4635 	pci_set_drvdata(pdev, dev);
4636 	set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
4637 	return 0;
4638 }
4639 
4640 static void __devexit airo_pci_remove(struct pci_dev *pdev)
4641 {
4642 	stop_airo_card(pci_get_drvdata(pdev), 1);
4643 }
4644 #endif
4645 
4646 static int __init airo_init_module( void )
4647 {
4648 	int i, have_isa_dev = 0;
4649 
4650 	airo_entry = create_proc_entry("aironet",
4651 				       S_IFDIR | airo_perm,
4652 				       proc_root_driver);
4653         airo_entry->uid = proc_uid;
4654         airo_entry->gid = proc_gid;
4655 
4656 	for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
4657 		printk( KERN_INFO
4658 			"airo:  Trying to configure ISA adapter at irq=%d io=0x%x\n",
4659 			irq[i], io[i] );
4660 		if (init_airo_card( irq[i], io[i], 0 ))
4661 			have_isa_dev = 1;
4662 	}
4663 
4664 #ifdef CONFIG_PCI
4665 	printk( KERN_INFO "airo:  Probing for PCI adapters\n" );
4666 	pci_module_init(&airo_driver);		/* FIXME: check return val */
4667 	printk( KERN_INFO "airo:  Finished probing for PCI adapters\n" );
4668 #endif
4669 
4670 	/* Always exit with success, as we are a library module
4671 	 * as well as a driver module
4672 	 */
4673 	return 0;
4674 }
4675 
4676 static void __exit airo_cleanup_module( void )
4677 {
4678 	int is_pci = 0;
4679 	while( airo_devices ) {
4680 		printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
4681 #ifdef CONFIG_PCI
4682 		if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags))
4683 			is_pci = 1;
4684 #endif
4685 		stop_airo_card( airo_devices->dev, 1 );
4686 	}
4687 	remove_proc_entry("aironet", proc_root_driver);
4688 
4689 	if (is_pci) {
4690 #ifdef CONFIG_PCI
4691 		pci_unregister_driver(&airo_driver);
4692 #endif
4693 	}
4694 }
4695 
4696 #ifdef WIRELESS_EXT
4697 /*
4698  * Initial Wireless Extension code for Aironet driver by :
4699  *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
4700  * Conversion to new driver API by :
4701  *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
4702  * Javier also did a good amount of work here, adding some new extensions
4703  * and fixing my code. Let's just say that without him this code just
4704  * would not work at all... - Jean II
4705  */
4706 
4707 /*------------------------------------------------------------------*/
4708 /*
4709  * Wireless Handler : get protocol name
4710  */
4711 static int airo_get_name(struct net_device *dev,
4712 			 struct iw_request_info *info,
4713 			 char *cwrq,
4714 			 char *extra)
4715 {
4716 	strcpy(cwrq, "IEEE 802.11-DS");
4717 	return 0;
4718 }
4719 
4720 /*------------------------------------------------------------------*/
4721 /*
4722  * Wireless Handler : set frequency
4723  */
4724 static int airo_set_freq(struct net_device *dev,
4725 			 struct iw_request_info *info,
4726 			 struct iw_freq *fwrq,
4727 			 char *extra)
4728 {
4729 	struct airo_info *local = dev->priv;
4730 	int rc = -EINPROGRESS;		/* Call commit handler */
4731 
4732 	/* If setting by frequency, convert to a channel */
4733 	if((fwrq->e == 1) &&
4734 	   (fwrq->m >= (int) 2.412e8) &&
4735 	   (fwrq->m <= (int) 2.487e8)) {
4736 		int f = fwrq->m / 100000;
4737 		int c = 0;
4738 		while((c < 14) && (f != frequency_list[c]))
4739 			c++;
4740 		/* Hack to fall through... */
4741 		fwrq->e = 0;
4742 		fwrq->m = c + 1;
4743 	}
4744 	/* Setting by channel number */
4745 	if((fwrq->m > 1000) || (fwrq->e > 0))
4746 		rc = -EOPNOTSUPP;
4747 	else {
4748 		int channel = fwrq->m;
4749 		/* We should do a better check than that,
4750 		 * based on the card capability !!! */
4751 		if((channel < 1) || (channel > 16)) {
4752 			printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m);
4753 			rc = -EINVAL;
4754 		} else {
4755 			readConfigRid(local, 1);
4756 			/* Yes ! We can set it !!! */
4757 			local->config.channelSet = (u16)(channel - 1);
4758 			local->need_commit = 1;
4759 		}
4760 	}
4761 	return rc;
4762 }
4763 
4764 /*------------------------------------------------------------------*/
4765 /*
4766  * Wireless Handler : get frequency
4767  */
4768 static int airo_get_freq(struct net_device *dev,
4769 			 struct iw_request_info *info,
4770 			 struct iw_freq *fwrq,
4771 			 char *extra)
4772 {
4773 	struct airo_info *local = dev->priv;
4774 	StatusRid status_rid;		/* Card status info */
4775 
4776 	readConfigRid(local, 1);
4777 	if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
4778 		status_rid.channel = local->config.channelSet;
4779 	else
4780 		readStatusRid(local, &status_rid, 1);
4781 
4782 #ifdef WEXT_USECHANNELS
4783 	fwrq->m = ((int)status_rid.channel) + 1;
4784 	fwrq->e = 0;
4785 #else
4786 	{
4787 		int f = (int)status_rid.channel;
4788 		fwrq->m = frequency_list[f] * 100000;
4789 		fwrq->e = 1;
4790 	}
4791 #endif
4792 
4793 	return 0;
4794 }
4795 
4796 /*------------------------------------------------------------------*/
4797 /*
4798  * Wireless Handler : set ESSID
4799  */
4800 static int airo_set_essid(struct net_device *dev,
4801 			  struct iw_request_info *info,
4802 			  struct iw_point *dwrq,
4803 			  char *extra)
4804 {
4805 	struct airo_info *local = dev->priv;
4806 	Resp rsp;
4807 	SsidRid SSID_rid;		/* SSIDs */
4808 
4809 	/* Reload the list of current SSID */
4810 	readSsidRid(local, &SSID_rid);
4811 
4812 	/* Check if we asked for `any' */
4813 	if(dwrq->flags == 0) {
4814 		/* Just send an empty SSID list */
4815 		memset(&SSID_rid, 0, sizeof(SSID_rid));
4816 	} else {
4817 		int	index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4818 
4819 		/* Check the size of the string */
4820 		if(dwrq->length > IW_ESSID_MAX_SIZE+1) {
4821 			return -E2BIG ;
4822 		}
4823 		/* Check if index is valid */
4824 		if((index < 0) || (index >= 4)) {
4825 			return -EINVAL;
4826 		}
4827 
4828 		/* Set the SSID */
4829 		memset(SSID_rid.ssids[index].ssid, 0,
4830 		       sizeof(SSID_rid.ssids[index].ssid));
4831 		memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
4832 		SSID_rid.ssids[index].len = dwrq->length - 1;
4833 		SSID_rid.len = sizeof(SSID_rid);
4834 	}
4835 	/* Write it to the card */
4836 	disable_MAC(local, 1);
4837 	writeSsidRid(local, &SSID_rid);
4838 	enable_MAC(local, &rsp, 1);
4839 
4840 	return 0;
4841 }
4842 
4843 /*------------------------------------------------------------------*/
4844 /*
4845  * Wireless Handler : get ESSID
4846  */
4847 static int airo_get_essid(struct net_device *dev,
4848 			  struct iw_request_info *info,
4849 			  struct iw_point *dwrq,
4850 			  char *extra)
4851 {
4852 	struct airo_info *local = dev->priv;
4853 	StatusRid status_rid;		/* Card status info */
4854 
4855 	readStatusRid(local, &status_rid, 1);
4856 
4857 	/* Note : if dwrq->flags != 0, we should
4858 	 * get the relevant SSID from the SSID list... */
4859 
4860 	/* Get the current SSID */
4861 	memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
4862 	extra[status_rid.SSIDlen] = '\0';
4863 	/* If none, we may want to get the one that was set */
4864 
4865 	/* Push it out ! */
4866 	dwrq->length = status_rid.SSIDlen + 1;
4867 	dwrq->flags = 1; /* active */
4868 
4869 	return 0;
4870 }
4871 
4872 /*------------------------------------------------------------------*/
4873 /*
4874  * Wireless Handler : set AP address
4875  */
4876 static int airo_set_wap(struct net_device *dev,
4877 			struct iw_request_info *info,
4878 			struct sockaddr *awrq,
4879 			char *extra)
4880 {
4881 	struct airo_info *local = dev->priv;
4882 	Cmd cmd;
4883 	Resp rsp;
4884 	APListRid APList_rid;
4885 	static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
4886 
4887 	if (awrq->sa_family != ARPHRD_ETHER)
4888 		return -EINVAL;
4889 	else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
4890 		memset(&cmd, 0, sizeof(cmd));
4891 		cmd.cmd=CMD_LOSE_SYNC;
4892 		if (down_interruptible(&local->sem))
4893 			return -ERESTARTSYS;
4894 		issuecommand(local, &cmd, &rsp);
4895 		up(&local->sem);
4896 	} else {
4897 		memset(&APList_rid, 0, sizeof(APList_rid));
4898 		APList_rid.len = sizeof(APList_rid);
4899 		memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
4900 		disable_MAC(local, 1);
4901 		writeAPListRid(local, &APList_rid);
4902 		enable_MAC(local, &rsp, 1);
4903 	}
4904 	return 0;
4905 }
4906 
4907 /*------------------------------------------------------------------*/
4908 /*
4909  * Wireless Handler : get AP address
4910  */
4911 static int airo_get_wap(struct net_device *dev,
4912 			struct iw_request_info *info,
4913 			struct sockaddr *awrq,
4914 			char *extra)
4915 {
4916 	struct airo_info *local = dev->priv;
4917 	StatusRid status_rid;		/* Card status info */
4918 
4919 	readStatusRid(local, &status_rid, 1);
4920 
4921 	/* Tentative. This seems to work, wow, I'm lucky !!! */
4922 	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
4923 	awrq->sa_family = ARPHRD_ETHER;
4924 
4925 	return 0;
4926 }
4927 
4928 /*------------------------------------------------------------------*/
4929 /*
4930  * Wireless Handler : set Nickname
4931  */
4932 static int airo_set_nick(struct net_device *dev,
4933 			 struct iw_request_info *info,
4934 			 struct iw_point *dwrq,
4935 			 char *extra)
4936 {
4937 	struct airo_info *local = dev->priv;
4938 
4939 	/* Check the size of the string */
4940 	if(dwrq->length > 16 + 1) {
4941 		return -E2BIG;
4942 	}
4943 	readConfigRid(local, 1);
4944 	memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
4945 	memcpy(local->config.nodeName, extra, dwrq->length);
4946 	local->need_commit = 1;
4947 
4948 	return -EINPROGRESS;		/* Call commit handler */
4949 }
4950 
4951 /*------------------------------------------------------------------*/
4952 /*
4953  * Wireless Handler : get Nickname
4954  */
4955 static int airo_get_nick(struct net_device *dev,
4956 			 struct iw_request_info *info,
4957 			 struct iw_point *dwrq,
4958 			 char *extra)
4959 {
4960 	struct airo_info *local = dev->priv;
4961 
4962 	readConfigRid(local, 1);
4963 	strncpy(extra, local->config.nodeName, 16);
4964 	extra[16] = '\0';
4965 	dwrq->length = strlen(extra) + 1;
4966 
4967 	return 0;
4968 }
4969 
4970 /*------------------------------------------------------------------*/
4971 /*
4972  * Wireless Handler : set Bit-Rate
4973  */
4974 static int airo_set_rate(struct net_device *dev,
4975 			 struct iw_request_info *info,
4976 			 struct iw_param *vwrq,
4977 			 char *extra)
4978 {
4979 	struct airo_info *local = dev->priv;
4980 	CapabilityRid cap_rid;		/* Card capability info */
4981 	u8	brate = 0;
4982 	int	i;
4983 
4984 	/* First : get a valid bit rate value */
4985 	readCapabilityRid(local, &cap_rid);
4986 
4987 	/* Which type of value ? */
4988 	if((vwrq->value < 8) && (vwrq->value >= 0)) {
4989 		/* Setting by rate index */
4990 		/* Find value in the magic rate table */
4991 		brate = cap_rid.supportedRates[vwrq->value];
4992 	} else {
4993 		/* Setting by frequency value */
4994 		u8	normvalue = (u8) (vwrq->value/500000);
4995 
4996 		/* Check if rate is valid */
4997 		for(i = 0 ; i < 8 ; i++) {
4998 			if(normvalue == cap_rid.supportedRates[i]) {
4999 				brate = normvalue;
5000 				break;
5001 			}
5002 		}
5003 	}
5004 	/* -1 designed the max rate (mostly auto mode) */
5005 	if(vwrq->value == -1) {
5006 		/* Get the highest available rate */
5007 		for(i = 0 ; i < 8 ; i++) {
5008 			if(cap_rid.supportedRates[i] == 0)
5009 				break;
5010 		}
5011 		if(i != 0)
5012 			brate = cap_rid.supportedRates[i - 1];
5013 	}
5014 	/* Check that it is valid */
5015 	if(brate == 0) {
5016 		return -EINVAL;
5017 	}
5018 
5019 	readConfigRid(local, 1);
5020 	/* Now, check if we want a fixed or auto value */
5021 	if(vwrq->fixed == 0) {
5022 		/* Fill all the rates up to this max rate */
5023 		memset(local->config.rates, 0, 8);
5024 		for(i = 0 ; i < 8 ; i++) {
5025 			local->config.rates[i] = cap_rid.supportedRates[i];
5026 			if(local->config.rates[i] == brate)
5027 				break;
5028 		}
5029 	} else {
5030 		/* Fixed mode */
5031 		/* One rate, fixed */
5032 		memset(local->config.rates, 0, 8);
5033 		local->config.rates[0] = brate;
5034 	}
5035 	local->need_commit = 1;
5036 
5037 	return -EINPROGRESS;		/* Call commit handler */
5038 }
5039 
5040 /*------------------------------------------------------------------*/
5041 /*
5042  * Wireless Handler : get Bit-Rate
5043  */
5044 static int airo_get_rate(struct net_device *dev,
5045 			 struct iw_request_info *info,
5046 			 struct iw_param *vwrq,
5047 			 char *extra)
5048 {
5049 	struct airo_info *local = dev->priv;
5050 	StatusRid status_rid;		/* Card status info */
5051 
5052 	readStatusRid(local, &status_rid, 1);
5053 
5054 	vwrq->value = status_rid.currentXmitRate * 500000;
5055 	/* If more than one rate, set auto */
5056 	readConfigRid(local, 1);
5057 	vwrq->fixed = (local->config.rates[1] == 0);
5058 
5059 	return 0;
5060 }
5061 
5062 /*------------------------------------------------------------------*/
5063 /*
5064  * Wireless Handler : set RTS threshold
5065  */
5066 static int airo_set_rts(struct net_device *dev,
5067 			struct iw_request_info *info,
5068 			struct iw_param *vwrq,
5069 			char *extra)
5070 {
5071 	struct airo_info *local = dev->priv;
5072 	int rthr = vwrq->value;
5073 
5074 	if(vwrq->disabled)
5075 		rthr = 2312;
5076 	if((rthr < 0) || (rthr > 2312)) {
5077 		return -EINVAL;
5078 	}
5079 	readConfigRid(local, 1);
5080 	local->config.rtsThres = rthr;
5081 	local->need_commit = 1;
5082 
5083 	return -EINPROGRESS;		/* Call commit handler */
5084 }
5085 
5086 /*------------------------------------------------------------------*/
5087 /*
5088  * Wireless Handler : get RTS threshold
5089  */
5090 static int airo_get_rts(struct net_device *dev,
5091 			struct iw_request_info *info,
5092 			struct iw_param *vwrq,
5093 			char *extra)
5094 {
5095 	struct airo_info *local = dev->priv;
5096 
5097 	readConfigRid(local, 1);
5098 	vwrq->value = local->config.rtsThres;
5099 	vwrq->disabled = (vwrq->value >= 2312);
5100 	vwrq->fixed = 1;
5101 
5102 	return 0;
5103 }
5104 
5105 /*------------------------------------------------------------------*/
5106 /*
5107  * Wireless Handler : set Fragmentation threshold
5108  */
5109 static int airo_set_frag(struct net_device *dev,
5110 			 struct iw_request_info *info,
5111 			 struct iw_param *vwrq,
5112 			 char *extra)
5113 {
5114 	struct airo_info *local = dev->priv;
5115 	int fthr = vwrq->value;
5116 
5117 	if(vwrq->disabled)
5118 		fthr = 2312;
5119 	if((fthr < 256) || (fthr > 2312)) {
5120 		return -EINVAL;
5121 	}
5122 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
5123 	readConfigRid(local, 1);
5124 	local->config.fragThresh = (u16)fthr;
5125 	local->need_commit = 1;
5126 
5127 	return -EINPROGRESS;		/* Call commit handler */
5128 }
5129 
5130 /*------------------------------------------------------------------*/
5131 /*
5132  * Wireless Handler : get Fragmentation threshold
5133  */
5134 static int airo_get_frag(struct net_device *dev,
5135 			 struct iw_request_info *info,
5136 			 struct iw_param *vwrq,
5137 			 char *extra)
5138 {
5139 	struct airo_info *local = dev->priv;
5140 
5141 	readConfigRid(local, 1);
5142 	vwrq->value = local->config.fragThresh;
5143 	vwrq->disabled = (vwrq->value >= 2312);
5144 	vwrq->fixed = 1;
5145 
5146 	return 0;
5147 }
5148 
5149 /*------------------------------------------------------------------*/
5150 /*
5151  * Wireless Handler : set Mode of Operation
5152  */
5153 static int airo_set_mode(struct net_device *dev,
5154 			 struct iw_request_info *info,
5155 			 __u32 *uwrq,
5156 			 char *extra)
5157 {
5158 	struct airo_info *local = dev->priv;
5159 	int commit = 1;
5160 
5161 	readConfigRid(local, 1);
5162 	if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
5163 		commit = 2;
5164 
5165 	switch(*uwrq) {
5166 		case IW_MODE_ADHOC:
5167 			local->config.opmode &= 0xFF00;
5168 			local->config.opmode |= MODE_STA_IBSS;
5169 			local->config.rmode &= 0xfe00;
5170 			local->config.scanMode = SCANMODE_ACTIVE;
5171 			clear_bit (FLAG_802_11, &local->flags);
5172 			break;
5173 		case IW_MODE_INFRA:
5174 			local->config.opmode &= 0xFF00;
5175 			local->config.opmode |= MODE_STA_ESS;
5176 			local->config.rmode &= 0xfe00;
5177 			local->config.scanMode = SCANMODE_ACTIVE;
5178 			clear_bit (FLAG_802_11, &local->flags);
5179 			break;
5180 		case IW_MODE_MASTER:
5181 			local->config.opmode &= 0xFF00;
5182 			local->config.opmode |= MODE_AP;
5183 			local->config.rmode &= 0xfe00;
5184 			local->config.scanMode = SCANMODE_ACTIVE;
5185 			clear_bit (FLAG_802_11, &local->flags);
5186 			break;
5187 		case IW_MODE_REPEAT:
5188 			local->config.opmode &= 0xFF00;
5189 			local->config.opmode |= MODE_AP_RPTR;
5190 			local->config.rmode &= 0xfe00;
5191 			local->config.scanMode = SCANMODE_ACTIVE;
5192 			clear_bit (FLAG_802_11, &local->flags);
5193 			break;
5194 		case IW_MODE_MONITOR:
5195 			local->config.opmode &= 0xFF00;
5196 			local->config.opmode |= MODE_STA_ESS;
5197 			local->config.rmode &= 0xfe00;
5198 			local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
5199 			local->config.scanMode = SCANMODE_PASSIVE;
5200 			set_bit (FLAG_802_11, &local->flags);
5201 			break;
5202 		default:
5203 			return -EINVAL;
5204 	}
5205 	local->need_commit = commit;
5206 
5207 	return -EINPROGRESS;		/* Call commit handler */
5208 }
5209 
5210 /*------------------------------------------------------------------*/
5211 /*
5212  * Wireless Handler : get Mode of Operation
5213  */
5214 static int airo_get_mode(struct net_device *dev,
5215 			 struct iw_request_info *info,
5216 			 __u32 *uwrq,
5217 			 char *extra)
5218 {
5219 	struct airo_info *local = dev->priv;
5220 
5221 	readConfigRid(local, 1);
5222 	/* If not managed, assume it's ad-hoc */
5223 	switch (local->config.opmode & 0xFF) {
5224 		case MODE_STA_ESS:
5225 			*uwrq = IW_MODE_INFRA;
5226 			break;
5227 		case MODE_AP:
5228 			*uwrq = IW_MODE_MASTER;
5229 			break;
5230 		case MODE_AP_RPTR:
5231 			*uwrq = IW_MODE_REPEAT;
5232 			break;
5233 		default:
5234 			*uwrq = IW_MODE_ADHOC;
5235 	}
5236 
5237 	return 0;
5238 }
5239 
5240 /*------------------------------------------------------------------*/
5241 /*
5242  * Wireless Handler : set Encryption Key
5243  */
5244 static int airo_set_encode(struct net_device *dev,
5245 			   struct iw_request_info *info,
5246 			   struct iw_point *dwrq,
5247 			   char *extra)
5248 {
5249 	struct airo_info *local = dev->priv;
5250 	CapabilityRid cap_rid;		/* Card capability info */
5251 
5252 	/* Is WEP supported ? */
5253 	readCapabilityRid(local, &cap_rid);
5254 	/* Older firmware doesn't support this...
5255 	if(!(cap_rid.softCap & 2)) {
5256 		return -EOPNOTSUPP;
5257 	} */
5258 	readConfigRid(local, 1);
5259 
5260 	/* Basic checking: do we have a key to set ?
5261 	 * Note : with the new API, it's impossible to get a NULL pointer.
5262 	 * Therefore, we need to check a key size == 0 instead.
5263 	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
5264 	 * when no key is present (only change flags), but older versions
5265 	 * don't do it. - Jean II */
5266 	if (dwrq->length > 0) {
5267 		wep_key_t key;
5268 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5269 		int current_index = get_wep_key(local, 0xffff);
5270 		/* Check the size of the key */
5271 		if (dwrq->length > MAX_KEY_SIZE) {
5272 			return -EINVAL;
5273 		}
5274 		/* Check the index (none -> use current) */
5275 		if ((index < 0) || (index>=(cap_rid.softCap&0x80)?4:1))
5276 			index = current_index;
5277 		/* Set the length */
5278 		if (dwrq->length > MIN_KEY_SIZE)
5279 			key.len = MAX_KEY_SIZE;
5280 		else
5281 			if (dwrq->length > 0)
5282 				key.len = MIN_KEY_SIZE;
5283 			else
5284 				/* Disable the key */
5285 				key.len = 0;
5286 		/* Check if the key is not marked as invalid */
5287 		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
5288 			/* Cleanup */
5289 			memset(key.key, 0, MAX_KEY_SIZE);
5290 			/* Copy the key in the driver */
5291 			memcpy(key.key, extra, dwrq->length);
5292 			/* Send the key to the card */
5293 			set_wep_key(local, index, key.key, key.len, 1, 1);
5294 		}
5295 		/* WE specify that if a valid key is set, encryption
5296 		 * should be enabled (user may turn it off later)
5297 		 * This is also how "iwconfig ethX key on" works */
5298 		if((index == current_index) && (key.len > 0) &&
5299 		   (local->config.authType == AUTH_OPEN)) {
5300 			local->config.authType = AUTH_ENCRYPT;
5301 			local->need_commit = 1;
5302 		}
5303 	} else {
5304 		/* Do we want to just set the transmit key index ? */
5305 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5306 		if ((index>=0) && (index<(cap_rid.softCap&0x80)?4:1)) {
5307 			set_wep_key(local, index, 0, 0, 1, 1);
5308 		} else
5309 			/* Don't complain if only change the mode */
5310 			if(!dwrq->flags & IW_ENCODE_MODE) {
5311 				return -EINVAL;
5312 			}
5313 	}
5314 	/* Read the flags */
5315 	if(dwrq->flags & IW_ENCODE_DISABLED)
5316 		local->config.authType = AUTH_OPEN;	// disable encryption
5317 	if(dwrq->flags & IW_ENCODE_RESTRICTED)
5318 		local->config.authType = AUTH_SHAREDKEY;	// Only Both
5319 	if(dwrq->flags & IW_ENCODE_OPEN)
5320 		local->config.authType = AUTH_ENCRYPT;	// Only Wep
5321 	/* Commit the changes to flags if needed */
5322 	if(dwrq->flags & IW_ENCODE_MODE)
5323 		local->need_commit = 1;
5324 	return -EINPROGRESS;		/* Call commit handler */
5325 }
5326 
5327 /*------------------------------------------------------------------*/
5328 /*
5329  * Wireless Handler : get Encryption Key
5330  */
5331 static int airo_get_encode(struct net_device *dev,
5332 			   struct iw_request_info *info,
5333 			   struct iw_point *dwrq,
5334 			   char *extra)
5335 {
5336 	struct airo_info *local = dev->priv;
5337 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5338 	CapabilityRid cap_rid;		/* Card capability info */
5339 
5340 	/* Is it supported ? */
5341 	readCapabilityRid(local, &cap_rid);
5342 	if(!(cap_rid.softCap & 2)) {
5343 		return -EOPNOTSUPP;
5344 	}
5345 	readConfigRid(local, 1);
5346 	/* Check encryption mode */
5347 	switch(local->config.authType)	{
5348 		case AUTH_ENCRYPT:
5349 			dwrq->flags = IW_ENCODE_OPEN;
5350 			break;
5351 		case AUTH_SHAREDKEY:
5352 			dwrq->flags = IW_ENCODE_RESTRICTED;
5353 			break;
5354 		default:
5355 		case AUTH_OPEN:
5356 			dwrq->flags = IW_ENCODE_DISABLED;
5357 			break;
5358 	}
5359 	/* We can't return the key, so set the proper flag and return zero */
5360 	dwrq->flags |= IW_ENCODE_NOKEY;
5361 	memset(extra, 0, 16);
5362 
5363 	/* Which key do we want ? -1 -> tx index */
5364 	if((index < 0) || (index >= (cap_rid.softCap & 0x80) ? 4 : 1))
5365 		index = get_wep_key(local, 0xffff);
5366 	dwrq->flags |= index + 1;
5367 	/* Copy the key to the user buffer */
5368 	dwrq->length = get_wep_key(local, index);
5369 	if (dwrq->length > 16) {
5370 		dwrq->length=0;
5371 	}
5372 	return 0;
5373 }
5374 
5375 /*------------------------------------------------------------------*/
5376 /*
5377  * Wireless Handler : set Tx-Power
5378  */
5379 static int airo_set_txpow(struct net_device *dev,
5380 			  struct iw_request_info *info,
5381 			  struct iw_param *vwrq,
5382 			  char *extra)
5383 {
5384 	struct airo_info *local = dev->priv;
5385 	CapabilityRid cap_rid;		/* Card capability info */
5386 	int i;
5387 	int rc = -EINVAL;
5388 
5389 	readCapabilityRid(local, &cap_rid);
5390 
5391 	if (vwrq->disabled) {
5392 		set_bit (FLAG_RADIO_OFF, &local->flags);
5393 		local->need_commit = 1;
5394 		return -EINPROGRESS;		/* Call commit handler */
5395 	}
5396 	if (vwrq->flags != IW_TXPOW_MWATT) {
5397 		return -EINVAL;
5398 	}
5399 	clear_bit (FLAG_RADIO_OFF, &local->flags);
5400 	for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
5401 		if ((vwrq->value==cap_rid.txPowerLevels[i])) {
5402 			readConfigRid(local, 1);
5403 			local->config.txPower = vwrq->value;
5404 			local->need_commit = 1;
5405 			rc = -EINPROGRESS;	/* Call commit handler */
5406 			break;
5407 		}
5408 	return rc;
5409 }
5410 
5411 /*------------------------------------------------------------------*/
5412 /*
5413  * Wireless Handler : get Tx-Power
5414  */
5415 static int airo_get_txpow(struct net_device *dev,
5416 			  struct iw_request_info *info,
5417 			  struct iw_param *vwrq,
5418 			  char *extra)
5419 {
5420 	struct airo_info *local = dev->priv;
5421 
5422 	readConfigRid(local, 1);
5423 	vwrq->value = local->config.txPower;
5424 	vwrq->fixed = 1;	/* No power control */
5425 	vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
5426 	vwrq->flags = IW_TXPOW_MWATT;
5427 
5428 	return 0;
5429 }
5430 
5431 /*------------------------------------------------------------------*/
5432 /*
5433  * Wireless Handler : set Retry limits
5434  */
5435 static int airo_set_retry(struct net_device *dev,
5436 			  struct iw_request_info *info,
5437 			  struct iw_param *vwrq,
5438 			  char *extra)
5439 {
5440 	struct airo_info *local = dev->priv;
5441 	int rc = -EINVAL;
5442 
5443 	if(vwrq->disabled) {
5444 		return -EINVAL;
5445 	}
5446 	readConfigRid(local, 1);
5447 	if(vwrq->flags & IW_RETRY_LIMIT) {
5448 		if(vwrq->flags & IW_RETRY_MAX)
5449 			local->config.longRetryLimit = vwrq->value;
5450 		else if (vwrq->flags & IW_RETRY_MIN)
5451 			local->config.shortRetryLimit = vwrq->value;
5452 		else {
5453 			/* No modifier : set both */
5454 			local->config.longRetryLimit = vwrq->value;
5455 			local->config.shortRetryLimit = vwrq->value;
5456 		}
5457 		local->need_commit = 1;
5458 		rc = -EINPROGRESS;		/* Call commit handler */
5459 	}
5460 	if(vwrq->flags & IW_RETRY_LIFETIME) {
5461 		local->config.txLifetime = vwrq->value / 1024;
5462 		local->need_commit = 1;
5463 		rc = -EINPROGRESS;		/* Call commit handler */
5464 	}
5465 	return rc;
5466 }
5467 
5468 /*------------------------------------------------------------------*/
5469 /*
5470  * Wireless Handler : get Retry limits
5471  */
5472 static int airo_get_retry(struct net_device *dev,
5473 			  struct iw_request_info *info,
5474 			  struct iw_param *vwrq,
5475 			  char *extra)
5476 {
5477 	struct airo_info *local = dev->priv;
5478 
5479 	vwrq->disabled = 0;      /* Can't be disabled */
5480 
5481 	readConfigRid(local, 1);
5482 	/* Note : by default, display the min retry number */
5483 	if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
5484 		vwrq->flags = IW_RETRY_LIFETIME;
5485 		vwrq->value = (int)local->config.txLifetime * 1024;
5486 	} else if((vwrq->flags & IW_RETRY_MAX)) {
5487 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
5488 		vwrq->value = (int)local->config.longRetryLimit;
5489 	} else {
5490 		vwrq->flags = IW_RETRY_LIMIT;
5491 		vwrq->value = (int)local->config.shortRetryLimit;
5492 		if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
5493 			vwrq->flags |= IW_RETRY_MIN;
5494 	}
5495 
5496 	return 0;
5497 }
5498 
5499 /*------------------------------------------------------------------*/
5500 /*
5501  * Wireless Handler : get range info
5502  */
5503 static int airo_get_range(struct net_device *dev,
5504 			  struct iw_request_info *info,
5505 			  struct iw_point *dwrq,
5506 			  char *extra)
5507 {
5508 	struct airo_info *local = dev->priv;
5509 	struct iw_range *range = (struct iw_range *) extra;
5510 	CapabilityRid cap_rid;		/* Card capability info */
5511 	int		i;
5512 	int		k;
5513 
5514 	readCapabilityRid(local, &cap_rid);
5515 
5516 	dwrq->length = sizeof(struct iw_range);
5517 	memset(range, 0, sizeof(*range));
5518 	range->min_nwid = 0x0000;
5519 	range->max_nwid = 0x0000;
5520 	range->num_channels = 14;
5521 	/* Should be based on cap_rid.country to give only
5522 	 * what the current card support */
5523 	k = 0;
5524 	for(i = 0; i < 14; i++) {
5525 		range->freq[k].i = i + 1; /* List index */
5526 		range->freq[k].m = frequency_list[i] * 100000;
5527 		range->freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
5528 	}
5529 	range->num_frequency = k;
5530 
5531 	/* Hum... Should put the right values there */
5532 	range->max_qual.qual = 10;
5533 	range->max_qual.level = 0x100 - 120;	/* -120 dBm */
5534 	range->max_qual.noise = 0;
5535 	range->sensitivity = 65535;
5536 
5537 	for(i = 0 ; i < 8 ; i++) {
5538 		range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
5539 		if(range->bitrate[i] == 0)
5540 			break;
5541 	}
5542 	range->num_bitrates = i;
5543 
5544 	/* Set an indication of the max TCP throughput
5545 	 * in bit/s that we can expect using this interface.
5546 	 * May be use for QoS stuff... Jean II */
5547 	if(i > 2)
5548 		range->throughput = 5000 * 1000;
5549 	else
5550 		range->throughput = 1500 * 1000;
5551 
5552 	range->min_rts = 0;
5553 	range->max_rts = 2312;
5554 	range->min_frag = 256;
5555 	range->max_frag = 2312;
5556 
5557 	if(cap_rid.softCap & 2) {
5558 		// WEP: RC4 40 bits
5559 		range->encoding_size[0] = 5;
5560 		// RC4 ~128 bits
5561 		if (cap_rid.softCap & 0x100) {
5562 			range->encoding_size[1] = 13;
5563 			range->num_encoding_sizes = 2;
5564 		} else
5565 			range->num_encoding_sizes = 1;
5566 		range->max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1;
5567 	} else {
5568 		range->num_encoding_sizes = 0;
5569 		range->max_encoding_tokens = 0;
5570 	}
5571 	range->min_pmp = 0;
5572 	range->max_pmp = 5000000;	/* 5 secs */
5573 	range->min_pmt = 0;
5574 	range->max_pmt = 65535 * 1024;	/* ??? */
5575 	range->pmp_flags = IW_POWER_PERIOD;
5576 	range->pmt_flags = IW_POWER_TIMEOUT;
5577 	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
5578 
5579 	/* Transmit Power - values are in mW */
5580 	for(i = 0 ; i < 8 ; i++) {
5581 		range->txpower[i] = cap_rid.txPowerLevels[i];
5582 		if(range->txpower[i] == 0)
5583 			break;
5584 	}
5585 	range->num_txpower = i;
5586 	range->txpower_capa = IW_TXPOW_MWATT;
5587 	range->we_version_source = 12;
5588 	range->we_version_compiled = WIRELESS_EXT;
5589 	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
5590 	range->retry_flags = IW_RETRY_LIMIT;
5591 	range->r_time_flags = IW_RETRY_LIFETIME;
5592 	range->min_retry = 1;
5593 	range->max_retry = 65535;
5594 	range->min_r_time = 1024;
5595 	range->max_r_time = 65535 * 1024;
5596 	/* Experimental measurements - boundary 11/5.5 Mb/s */
5597 	/* Note : with or without the (local->rssi), results
5598 	 * are somewhat different. - Jean II */
5599 	range->avg_qual.qual = 6;
5600 	if (local->rssi)
5601 		range->avg_qual.level = 186;	/* -70 dBm */
5602 	else
5603 		range->avg_qual.level = 176;	/* -80 dBm */
5604 	range->avg_qual.noise = 0;
5605 
5606 	return 0;
5607 }
5608 
5609 /*------------------------------------------------------------------*/
5610 /*
5611  * Wireless Handler : set Power Management
5612  */
5613 static int airo_set_power(struct net_device *dev,
5614 			  struct iw_request_info *info,
5615 			  struct iw_param *vwrq,
5616 			  char *extra)
5617 {
5618 	struct airo_info *local = dev->priv;
5619 
5620 	readConfigRid(local, 1);
5621 	if (vwrq->disabled) {
5622 		if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
5623 			return -EINVAL;
5624 		}
5625 		local->config.powerSaveMode = POWERSAVE_CAM;
5626 		local->config.rmode &= 0xFF00;
5627 		local->config.rmode |= RXMODE_BC_MC_ADDR;
5628 		local->need_commit = 1;
5629 		return -EINPROGRESS;		/* Call commit handler */
5630 	}
5631 	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
5632 		local->config.fastListenDelay = (vwrq->value + 500) / 1024;
5633 		local->config.powerSaveMode = POWERSAVE_PSPCAM;
5634 		local->need_commit = 1;
5635 	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
5636 		local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
5637 		local->config.powerSaveMode = POWERSAVE_PSPCAM;
5638 		local->need_commit = 1;
5639 	}
5640 	switch (vwrq->flags & IW_POWER_MODE) {
5641 		case IW_POWER_UNICAST_R:
5642 			if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
5643 				return -EINVAL;
5644 			}
5645 			local->config.rmode &= 0xFF00;
5646 			local->config.rmode |= RXMODE_ADDR;
5647 			local->need_commit = 1;
5648 			break;
5649 		case IW_POWER_ALL_R:
5650 			if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
5651 				return -EINVAL;
5652 			}
5653 			local->config.rmode &= 0xFF00;
5654 			local->config.rmode |= RXMODE_BC_MC_ADDR;
5655 			local->need_commit = 1;
5656 		case IW_POWER_ON:
5657 			break;
5658 		default:
5659 			return -EINVAL;
5660 	}
5661 	// Note : we may want to factor local->need_commit here
5662 	// Note2 : may also want to factor RXMODE_RFMON test
5663 	return -EINPROGRESS;		/* Call commit handler */
5664 }
5665 
5666 /*------------------------------------------------------------------*/
5667 /*
5668  * Wireless Handler : get Power Management
5669  */
5670 static int airo_get_power(struct net_device *dev,
5671 			  struct iw_request_info *info,
5672 			  struct iw_param *vwrq,
5673 			  char *extra)
5674 {
5675 	struct airo_info *local = dev->priv;
5676 	int mode;
5677 
5678 	readConfigRid(local, 1);
5679 	mode = local->config.powerSaveMode;
5680 	if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
5681 		return 0;
5682 	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
5683 		vwrq->value = (int)local->config.fastListenDelay * 1024;
5684 		vwrq->flags = IW_POWER_TIMEOUT;
5685 	} else {
5686 		vwrq->value = (int)local->config.fastListenInterval * 1024;
5687 		vwrq->flags = IW_POWER_PERIOD;
5688 	}
5689 	if ((local->config.rmode & 0xFF) == RXMODE_ADDR)
5690 		vwrq->flags |= IW_POWER_UNICAST_R;
5691 	else
5692 		vwrq->flags |= IW_POWER_ALL_R;
5693 
5694 	return 0;
5695 }
5696 
5697 /*------------------------------------------------------------------*/
5698 /*
5699  * Wireless Handler : set Sensitivity
5700  */
5701 static int airo_set_sens(struct net_device *dev,
5702 			 struct iw_request_info *info,
5703 			 struct iw_param *vwrq,
5704 			 char *extra)
5705 {
5706 	struct airo_info *local = dev->priv;
5707 
5708 	readConfigRid(local, 1);
5709 	local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
5710 	local->need_commit = 1;
5711 
5712 	return -EINPROGRESS;		/* Call commit handler */
5713 }
5714 
5715 /*------------------------------------------------------------------*/
5716 /*
5717  * Wireless Handler : get Sensitivity
5718  */
5719 static int airo_get_sens(struct net_device *dev,
5720 			 struct iw_request_info *info,
5721 			 struct iw_param *vwrq,
5722 			 char *extra)
5723 {
5724 	struct airo_info *local = dev->priv;
5725 
5726 	readConfigRid(local, 1);
5727 	vwrq->value = local->config.rssiThreshold;
5728 	vwrq->disabled = (vwrq->value == 0);
5729 	vwrq->fixed = 1;
5730 
5731 	return 0;
5732 }
5733 
5734 /*------------------------------------------------------------------*/
5735 /*
5736  * Wireless Handler : get AP List
5737  * Note : this is deprecated in favor of IWSCAN
5738  */
5739 static int airo_get_aplist(struct net_device *dev,
5740 			   struct iw_request_info *info,
5741 			   struct iw_point *dwrq,
5742 			   char *extra)
5743 {
5744 	struct airo_info *local = dev->priv;
5745 	struct sockaddr *address = (struct sockaddr *) extra;
5746 	struct iw_quality qual[IW_MAX_AP];
5747 	BSSListRid BSSList;
5748 	int i;
5749 	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
5750 
5751 	for (i = 0; i < IW_MAX_AP; i++) {
5752 		if (readBSSListRid(local, loseSync, &BSSList))
5753 			break;
5754 		loseSync = 0;
5755 		memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
5756 		address[i].sa_family = ARPHRD_ETHER;
5757 		if (local->rssi)
5758 			qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
5759 		else
5760 			qual[i].level = (BSSList.rssi + 321) / 2;
5761 		qual[i].qual = qual[i].noise = 0;
5762 		qual[i].updated = 2;
5763 		if (BSSList.index == 0xffff)
5764 			break;
5765 	}
5766 	if (!i) {
5767 		StatusRid status_rid;		/* Card status info */
5768 		readStatusRid(local, &status_rid, 1);
5769 		for (i = 0;
5770 		     i < min(IW_MAX_AP, 4) &&
5771 			     (status_rid.bssid[i][0]
5772 			      & status_rid.bssid[i][1]
5773 			      & status_rid.bssid[i][2]
5774 			      & status_rid.bssid[i][3]
5775 			      & status_rid.bssid[i][4]
5776 			      & status_rid.bssid[i][5])!=0xff &&
5777 			     (status_rid.bssid[i][0]
5778 			      | status_rid.bssid[i][1]
5779 			      | status_rid.bssid[i][2]
5780 			      | status_rid.bssid[i][3]
5781 			      | status_rid.bssid[i][4]
5782 			      | status_rid.bssid[i][5]);
5783 		     i++) {
5784 			memcpy(address[i].sa_data,
5785 			       status_rid.bssid[i], ETH_ALEN);
5786 			address[i].sa_family = ARPHRD_ETHER;
5787 		}
5788 	} else {
5789 		dwrq->flags = 1; /* Should be define'd */
5790 		memcpy(extra + sizeof(struct sockaddr)*i,
5791 		       &qual,  sizeof(struct iw_quality)*i);
5792 	}
5793 	dwrq->length = i;
5794 
5795 	return 0;
5796 }
5797 
5798 #if WIRELESS_EXT > 13
5799 /*------------------------------------------------------------------*/
5800 /*
5801  * Wireless Handler : Initiate Scan
5802  */
5803 static int airo_set_scan(struct net_device *dev,
5804 			 struct iw_request_info *info,
5805 			 struct iw_param *vwrq,
5806 			 char *extra)
5807 {
5808 	struct airo_info *ai = dev->priv;
5809 	Cmd cmd;
5810 	Resp rsp;
5811 
5812 	/* Note : you may have realised that, as this is a SET operation,
5813 	 * this is privileged and therefore a normal user can't
5814 	 * perform scanning.
5815 	 * This is not an error, while the device perform scanning,
5816 	 * traffic doesn't flow, so it's a perfect DoS...
5817 	 * Jean II */
5818 
5819 	/* Initiate a scan command */
5820 	memset(&cmd, 0, sizeof(cmd));
5821 	cmd.cmd=CMD_LISTBSS;
5822 	if (down_interruptible(&ai->sem))
5823 		return -ERESTARTSYS;
5824 	issuecommand(ai, &cmd, &rsp);
5825 	ai->scan_timestamp = jiffies;
5826 	up(&ai->sem);
5827 
5828 	/* At this point, just return to the user. */
5829 
5830 	return 0;
5831 }
5832 
5833 /*------------------------------------------------------------------*/
5834 /*
5835  * Translate scan data returned from the card to a card independent
5836  * format that the Wireless Tools will understand - Jean II
5837  */
5838 static inline char *airo_translate_scan(struct net_device *dev,
5839 					char *current_ev,
5840 					char *end_buf,
5841 					BSSListRid *list)
5842 {
5843 	struct airo_info *ai = dev->priv;
5844 	struct iw_event		iwe;		/* Temporary buffer */
5845 	u16			capabilities;
5846 	char *			current_val;	/* For rates */
5847 	int			i;
5848 
5849 	/* First entry *MUST* be the AP MAC address */
5850 	iwe.cmd = SIOCGIWAP;
5851 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
5852 	memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
5853 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
5854 
5855 	/* Other entries will be displayed in the order we give them */
5856 
5857 	/* Add the ESSID */
5858 	iwe.u.data.length = list->ssidLen;
5859 	if(iwe.u.data.length > 32)
5860 		iwe.u.data.length = 32;
5861 	iwe.cmd = SIOCGIWESSID;
5862 	iwe.u.data.flags = 1;
5863 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
5864 
5865 	/* Add mode */
5866 	iwe.cmd = SIOCGIWMODE;
5867 	capabilities = le16_to_cpu(list->cap);
5868 	if(capabilities & (CAP_ESS | CAP_IBSS)) {
5869 		if(capabilities & CAP_ESS)
5870 			iwe.u.mode = IW_MODE_MASTER;
5871 		else
5872 			iwe.u.mode = IW_MODE_ADHOC;
5873 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
5874 	}
5875 
5876 	/* Add frequency */
5877 	iwe.cmd = SIOCGIWFREQ;
5878 	iwe.u.freq.m = le16_to_cpu(list->dsChannel);
5879 	iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
5880 	iwe.u.freq.e = 1;
5881 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
5882 
5883 	/* Add quality statistics */
5884 	iwe.cmd = IWEVQUAL;
5885 	if (ai->rssi)
5886 		iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm;
5887 	else
5888 		iwe.u.qual.level = (list->rssi + 321) / 2;
5889 	iwe.u.qual.noise = 0;
5890 	iwe.u.qual.qual = 0;
5891 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
5892 
5893 	/* Add encryption capability */
5894 	iwe.cmd = SIOCGIWENCODE;
5895 	if(capabilities & CAP_PRIVACY)
5896 		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
5897 	else
5898 		iwe.u.data.flags = IW_ENCODE_DISABLED;
5899 	iwe.u.data.length = 0;
5900 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
5901 
5902 	/* Rate : stuffing multiple values in a single event require a bit
5903 	 * more of magic - Jean II */
5904 	current_val = current_ev + IW_EV_LCP_LEN;
5905 
5906 	iwe.cmd = SIOCGIWRATE;
5907 	/* Those two flags are ignored... */
5908 	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
5909 	/* Max 8 values */
5910 	for(i = 0 ; i < 8 ; i++) {
5911 		/* NULL terminated */
5912 		if(list->rates[i] == 0)
5913 			break;
5914 		/* Bit rate given in 500 kb/s units (+ 0x80) */
5915 		iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000);
5916 		/* Add new value to event */
5917 		current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
5918 	}
5919 	/* Check if we added any event */
5920 	if((current_val - current_ev) > IW_EV_LCP_LEN)
5921 		current_ev = current_val;
5922 
5923 	/* The other data in the scan result are not really
5924 	 * interesting, so for now drop it - Jean II */
5925 	return current_ev;
5926 }
5927 
5928 /*------------------------------------------------------------------*/
5929 /*
5930  * Wireless Handler : Read Scan Results
5931  */
5932 static int airo_get_scan(struct net_device *dev,
5933 			 struct iw_request_info *info,
5934 			 struct iw_point *dwrq,
5935 			 char *extra)
5936 {
5937 	struct airo_info *ai = dev->priv;
5938 	BSSListRid BSSList;
5939 	int rc;
5940 	char *current_ev = extra;
5941 
5942 	/* When we are associated again, the scan has surely finished.
5943 	 * Just in case, let's make sure enough time has elapsed since
5944 	 * we started the scan. - Javier */
5945 	if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) {
5946 		/* Important note : we don't want to block the caller
5947 		 * until results are ready for various reasons.
5948 		 * First, managing wait queues is complex and racy
5949 		 * (there may be multiple simultaneous callers).
5950 		 * Second, we grab some rtnetlink lock before comming
5951 		 * here (in dev_ioctl()).
5952 		 * Third, the caller can wait on the Wireless Event
5953 		 * - Jean II */
5954 		return -EAGAIN;
5955 	}
5956 	ai->scan_timestamp = 0;
5957 
5958 	/* There's only a race with proc_BSSList_open(), but its
5959 	 * consequences are begnign. So I don't bother fixing it - Javier */
5960 
5961 	/* Try to read the first entry of the scan result */
5962 	rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1);
5963 	if((rc) || (BSSList.index == 0xffff)) {
5964 		/* Client error, no scan results...
5965 		 * The caller need to restart the scan. */
5966 		return -ENODATA;
5967 	}
5968 
5969 	/* Read and parse all entries */
5970 	while((!rc) && (BSSList.index != 0xffff)) {
5971 		/* Translate to WE format this entry */
5972 		current_ev = airo_translate_scan(dev, current_ev,
5973 						 extra + IW_SCAN_MAX_DATA,
5974 						 &BSSList);
5975 
5976 		/* Read next entry */
5977 		rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
5978 				    &BSSList, sizeof(BSSList), 1);
5979 	}
5980 	/* Length of data */
5981 	dwrq->length = (current_ev - extra);
5982 	dwrq->flags = 0;	/* todo */
5983 
5984 	return 0;
5985 }
5986 #endif	/* WIRELESS_EXT > 13 */
5987 
5988 #if WIRELESS_EXT <= 15
5989 #ifdef WIRELESS_SPY
5990 /*------------------------------------------------------------------*/
5991 /*
5992  * Wireless Handler : set Spy List
5993  */
5994 static int airo_set_spy(struct net_device *dev,
5995 			struct iw_request_info *info,
5996 			struct iw_point *dwrq,
5997 			char *extra)
5998 {
5999 	struct airo_info *local = dev->priv;
6000 	struct sockaddr *address = (struct sockaddr *) extra;
6001 
6002 	/* Disable spy while we copy the addresses.
6003 	 * As we don't disable interrupts, we need to do this to avoid races */
6004 	local->spy_number = 0;
6005 
6006 	if (dwrq->length > 0) {
6007 		int i;
6008 
6009 		/* Copy addresses */
6010 		for (i = 0; i < dwrq->length; i++)
6011 			memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
6012 		/* Reset stats */
6013 		memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
6014 	}
6015 	/* Enable addresses */
6016 	local->spy_number = dwrq->length;
6017 
6018 	return 0;
6019 }
6020 
6021 /*------------------------------------------------------------------*/
6022 /*
6023  * Wireless Handler : get Spy List
6024  */
6025 static int airo_get_spy(struct net_device *dev,
6026 			struct iw_request_info *info,
6027 			struct iw_point *dwrq,
6028 			char *extra)
6029 {
6030 	struct airo_info *local = dev->priv;
6031 	struct sockaddr *address = (struct sockaddr *) extra;
6032 	int i;
6033 
6034 	dwrq->length = local->spy_number;
6035 
6036 	/* Copy addresses. */
6037 	for(i = 0; i < local->spy_number; i++) 	{
6038 		memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN);
6039 		address[i].sa_family = AF_UNIX;
6040 	}
6041 	/* Copy stats to the user buffer (just after). */
6042 	if(local->spy_number > 0)
6043 		memcpy(extra  + (sizeof(struct sockaddr) * local->spy_number),
6044 		       local->spy_stat, sizeof(struct iw_quality) * local->spy_number);
6045 	/* Reset updated flags. */
6046 	for (i=0; i<local->spy_number; i++)
6047 		local->spy_stat[i].updated = 0;
6048 	return 0;
6049 }
6050 #endif			/* WIRELESS_SPY */
6051 #endif /* WIRELESS_EXT <= 15 */
6052 
6053 /*------------------------------------------------------------------*/
6054 /*
6055  * Commit handler : called after a bunch of SET operations
6056  */
6057 static int airo_config_commit(struct net_device *dev,
6058 			      struct iw_request_info *info,	/* NULL */
6059 			      void *zwrq,			/* NULL */
6060 			      char *extra)			/* NULL */
6061 {
6062 	struct airo_info *local = dev->priv;
6063 	Resp rsp;
6064 
6065 	if (!local->need_commit)
6066 		return 0;
6067 
6068 	/* Some of the "SET" function may have modified some of the
6069 	 * parameters. It's now time to commit them in the card */
6070 	disable_MAC(local, 1);
6071 	if (local->need_commit > 1) {
6072 		APListRid APList_rid;
6073 		SsidRid SSID_rid;
6074 
6075 		readAPListRid(local, &APList_rid);
6076 		readSsidRid(local, &SSID_rid);
6077 		reset_airo_card(dev);
6078 		disable_MAC(local, 1);
6079 		writeSsidRid(local, &SSID_rid);
6080 		writeAPListRid(local, &APList_rid);
6081 	}
6082 	if (down_interruptible(&local->sem))
6083 		return -ERESTARTSYS;
6084 	writeConfigRid(local, 0);
6085 	enable_MAC(local, &rsp, 0);
6086 	if (local->need_commit > 1)
6087 		airo_set_promisc(local);
6088 	else
6089 		up(&local->sem);
6090 
6091 	return 0;
6092 }
6093 
6094 /*------------------------------------------------------------------*/
6095 /*
6096  * Structures to export the Wireless Handlers
6097  */
6098 
6099 static const struct iw_priv_args airo_private_args[] = {
6100 /*{ cmd,         set_args,                            get_args, name } */
6101   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
6102     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
6103   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
6104     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
6105 };
6106 
6107 #if WIRELESS_EXT > 12
6108 static const iw_handler		airo_handler[] =
6109 {
6110 	(iw_handler) airo_config_commit,	/* SIOCSIWCOMMIT */
6111 	(iw_handler) airo_get_name,		/* SIOCGIWNAME */
6112 	(iw_handler) NULL,			/* SIOCSIWNWID */
6113 	(iw_handler) NULL,			/* SIOCGIWNWID */
6114 	(iw_handler) airo_set_freq,		/* SIOCSIWFREQ */
6115 	(iw_handler) airo_get_freq,		/* SIOCGIWFREQ */
6116 	(iw_handler) airo_set_mode,		/* SIOCSIWMODE */
6117 	(iw_handler) airo_get_mode,		/* SIOCGIWMODE */
6118 	(iw_handler) airo_set_sens,		/* SIOCSIWSENS */
6119 	(iw_handler) airo_get_sens,		/* SIOCGIWSENS */
6120 	(iw_handler) NULL,			/* SIOCSIWRANGE */
6121 	(iw_handler) airo_get_range,		/* SIOCGIWRANGE */
6122 	(iw_handler) NULL,			/* SIOCSIWPRIV */
6123 	(iw_handler) NULL,			/* SIOCGIWPRIV */
6124 	(iw_handler) NULL,			/* SIOCSIWSTATS */
6125 	(iw_handler) NULL,			/* SIOCGIWSTATS */
6126 #if WIRELESS_EXT > 15
6127 	iw_handler_set_spy,			/* SIOCSIWSPY */
6128 	iw_handler_get_spy,			/* SIOCGIWSPY */
6129 	iw_handler_set_thrspy,			/* SIOCSIWTHRSPY */
6130 	iw_handler_get_thrspy,			/* SIOCGIWTHRSPY */
6131 #else /* WIRELESS_EXT > 15 */
6132 #ifdef WIRELESS_SPY
6133 	(iw_handler) airo_set_spy,		/* SIOCSIWSPY */
6134 	(iw_handler) airo_get_spy,		/* SIOCGIWSPY */
6135 #else	/* WIRELESS_SPY */
6136 	(iw_handler) NULL,			/* SIOCSIWSPY */
6137 	(iw_handler) NULL,			/* SIOCGIWSPY */
6138 #endif	/* WIRELESS_SPY */
6139 	(iw_handler) NULL,			/* -- hole -- */
6140 	(iw_handler) NULL,			/* -- hole -- */
6141 #endif /* WIRELESS_EXT > 15 */
6142 	(iw_handler) airo_set_wap,		/* SIOCSIWAP */
6143 	(iw_handler) airo_get_wap,		/* SIOCGIWAP */
6144 	(iw_handler) NULL,			/* -- hole -- */
6145 	(iw_handler) airo_get_aplist,		/* SIOCGIWAPLIST */
6146 #if WIRELESS_EXT > 13
6147 	(iw_handler) airo_set_scan,		/* SIOCSIWSCAN */
6148 	(iw_handler) airo_get_scan,		/* SIOCGIWSCAN */
6149 #else	/* WIRELESS_EXT > 13 */
6150 	(iw_handler) NULL,			/* SIOCSIWSCAN */
6151 	(iw_handler) NULL,			/* SIOCGIWSCAN */
6152 #endif	/* WIRELESS_EXT > 13 */
6153 	(iw_handler) airo_set_essid,		/* SIOCSIWESSID */
6154 	(iw_handler) airo_get_essid,		/* SIOCGIWESSID */
6155 	(iw_handler) airo_set_nick,		/* SIOCSIWNICKN */
6156 	(iw_handler) airo_get_nick,		/* SIOCGIWNICKN */
6157 	(iw_handler) NULL,			/* -- hole -- */
6158 	(iw_handler) NULL,			/* -- hole -- */
6159 	(iw_handler) airo_set_rate,		/* SIOCSIWRATE */
6160 	(iw_handler) airo_get_rate,		/* SIOCGIWRATE */
6161 	(iw_handler) airo_set_rts,		/* SIOCSIWRTS */
6162 	(iw_handler) airo_get_rts,		/* SIOCGIWRTS */
6163 	(iw_handler) airo_set_frag,		/* SIOCSIWFRAG */
6164 	(iw_handler) airo_get_frag,		/* SIOCGIWFRAG */
6165 	(iw_handler) airo_set_txpow,		/* SIOCSIWTXPOW */
6166 	(iw_handler) airo_get_txpow,		/* SIOCGIWTXPOW */
6167 	(iw_handler) airo_set_retry,		/* SIOCSIWRETRY */
6168 	(iw_handler) airo_get_retry,		/* SIOCGIWRETRY */
6169 	(iw_handler) airo_set_encode,		/* SIOCSIWENCODE */
6170 	(iw_handler) airo_get_encode,		/* SIOCGIWENCODE */
6171 	(iw_handler) airo_set_power,		/* SIOCSIWPOWER */
6172 	(iw_handler) airo_get_power,		/* SIOCGIWPOWER */
6173 };
6174 
6175 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
6176  * We want to force the use of the ioctl code, because those can't be
6177  * won't work the iw_handler code (because they simultaneously read
6178  * and write data and iw_handler can't do that).
6179  * Note that it's perfectly legal to read/write on a single ioctl command,
6180  * you just can't use iwpriv and need to force it via the ioctl handler.
6181  * Jean II */
6182 static const iw_handler		airo_private_handler[] =
6183 {
6184 	NULL,				/* SIOCIWFIRSTPRIV */
6185 };
6186 
6187 static const struct iw_handler_def	airo_handler_def =
6188 {
6189 	.num_standard	= sizeof(airo_handler)/sizeof(iw_handler),
6190 	.num_private	= sizeof(airo_private_handler)/sizeof(iw_handler),
6191 	.num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args),
6192 	.standard	= (iw_handler *) airo_handler,
6193 	.private	= (iw_handler *) airo_private_handler,
6194 	.private_args	= (struct iw_priv_args *) airo_private_args,
6195 #if WIRELESS_EXT > 15
6196 	.spy_offset	= ((void *) (&((struct airo_info *) NULL)->spy_data) -
6197 			   (void *) NULL),
6198 #endif /* WIRELESS_EXT > 15 */
6199 
6200 };
6201 
6202 #endif /* WIRELESS_EXT > 12 */
6203 #endif /* WIRELESS_EXT */
6204 
6205 /*
6206  * This defines the configuration part of the Wireless Extensions
6207  * Note : irq and spinlock protection will occur in the subroutines
6208  *
6209  * TODO :
6210  *	o Check input value more carefully and fill correct values in range
6211  *	o Test and shakeout the bugs (if any)
6212  *
6213  * Jean II
6214  *
6215  * Javier Achirica did a great job of merging code from the unnamed CISCO
6216  * developer that added support for flashing the card.
6217  */
6218 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6219 {
6220 	int rc = 0;
6221 #if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
6222 	struct iwreq *wrq = (struct iwreq *) rq;
6223 #endif /* WIRELESS_EXT < 13 */
6224 
6225 	switch (cmd) {
6226 /* WE 13 and higher will use airo_handler_def */
6227 #if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
6228 	case SIOCGIWNAME:	// Get name
6229 		airo_get_name(dev, NULL, (char *) &(wrq->u.name), NULL);
6230 		break;
6231 
6232 	case SIOCSIWFREQ:	// Set frequency/channel
6233 		rc = airo_set_freq(dev, NULL, &(wrq->u.freq), NULL);
6234 		break;
6235 
6236 	case SIOCGIWFREQ:	// Get frequency/channel
6237 		rc = airo_get_freq(dev, NULL, &(wrq->u.freq), NULL);
6238 		break;
6239 
6240 	case SIOCSIWESSID:	// Set desired network name (ESSID)
6241 		{
6242 			char essidbuf[IW_ESSID_MAX_SIZE+1];
6243 			if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
6244 				rc = -E2BIG;
6245 				break;
6246 			}
6247 			if (copy_from_user(essidbuf, wrq->u.essid.pointer,
6248 					   wrq->u.essid.length)) {
6249 				rc = -EFAULT;
6250 				break;
6251 			}
6252 			rc = airo_set_essid(dev, NULL,
6253 					    &(wrq->u.essid), essidbuf);
6254 		}
6255 		break;
6256 
6257 	case SIOCGIWESSID:	// Get current network name (ESSID)
6258 		{
6259 			char essidbuf[IW_ESSID_MAX_SIZE+1];
6260 			if (wrq->u.essid.pointer)
6261 				rc = airo_get_essid(dev, NULL,
6262 						    &(wrq->u.essid), essidbuf);
6263 				if ( copy_to_user(wrq->u.essid.pointer,
6264 						  essidbuf,
6265 						  wrq->u.essid.length) )
6266 					rc = -EFAULT;
6267 		}
6268 		break;
6269 
6270 	case SIOCSIWAP:
6271 		rc = airo_set_wap(dev, NULL, &(wrq->u.ap_addr), NULL);
6272 		break;
6273 
6274 	case SIOCGIWAP:		// Get current Access Point (BSSID)
6275 		rc = airo_get_wap(dev, NULL, &(wrq->u.ap_addr), NULL);
6276 		break;
6277 
6278 	case SIOCSIWNICKN:	// Set desired station name
6279 		{
6280 			char nickbuf[IW_ESSID_MAX_SIZE+1];
6281 			if (wrq->u.data.length > IW_ESSID_MAX_SIZE) {
6282 				rc = -E2BIG;
6283 				break;
6284 			}
6285 			if (copy_from_user(nickbuf, wrq->u.data.pointer,
6286 					   wrq->u.data.length)) {
6287 				rc = -EFAULT;
6288 				break;
6289 			}
6290 			rc = airo_set_nick(dev, NULL,
6291 					   &(wrq->u.data), nickbuf);
6292 		}
6293 		break;
6294 
6295 	case SIOCGIWNICKN:	// Get current station name
6296 		{
6297 			char nickbuf[IW_ESSID_MAX_SIZE+1];
6298 			if (wrq->u.data.pointer)
6299 				rc = airo_get_nick(dev, NULL,
6300 						   &(wrq->u.data), nickbuf);
6301 				if ( copy_to_user(wrq->u.data.pointer,
6302 						  nickbuf,
6303 						  wrq->u.data.length) )
6304 					rc = -EFAULT;
6305 		}
6306 		break;
6307 
6308 	case SIOCSIWRATE:	// Set the desired bit-rate
6309 		rc = airo_set_rate(dev, NULL, &(wrq->u.bitrate), NULL);
6310 		break;
6311 
6312 	case SIOCGIWRATE:	// Get the current bit-rate
6313 		rc = airo_get_rate(dev, NULL, &(wrq->u.bitrate), NULL);
6314 		break;
6315 
6316 	case SIOCSIWRTS:	// Set the desired RTS threshold
6317 		rc = airo_set_rts(dev, NULL, &(wrq->u.rts), NULL);
6318 		break;
6319 
6320 	case SIOCGIWRTS:	// Get the current RTS threshold
6321 		rc = airo_get_rts(dev, NULL, &(wrq->u.rts), NULL);
6322 		break;
6323 
6324 	case SIOCSIWFRAG:	// Set the desired fragmentation threshold
6325 		rc = airo_set_frag(dev, NULL, &(wrq->u.frag), NULL);
6326 		break;
6327 
6328 	case SIOCGIWFRAG:	// Get the current fragmentation threshold
6329 		rc = airo_get_frag(dev, NULL, &(wrq->u.frag), NULL);
6330 		break;
6331 
6332 	case SIOCSIWMODE:	// Set mode of operation
6333 		rc = airo_set_mode(dev, NULL, &(wrq->u.mode), NULL);
6334 		break;
6335 
6336 	case SIOCGIWMODE:	// Get mode of operation
6337 		rc = airo_get_mode(dev, NULL, &(wrq->u.mode), NULL);
6338 		break;
6339 
6340 	case SIOCSIWENCODE:	// Set WEP keys and mode
6341 		{
6342 			char keybuf[MAX_KEY_SIZE];
6343 			if (wrq->u.encoding.pointer) {
6344 				/* We actually have a key to set */
6345 				if (wrq->u.encoding.length > MAX_KEY_SIZE) {
6346 					rc = -E2BIG;
6347 					break;
6348 				}
6349 				if (copy_from_user(keybuf,
6350 						   wrq->u.encoding.pointer,
6351 						   wrq->u.encoding.length)) {
6352 					rc = -EFAULT;
6353 					break;
6354 				}
6355 			} else if (wrq->u.encoding.length != 0) {
6356 				rc = -EINVAL;
6357 				break;
6358 			}
6359 			rc = airo_set_encode(dev, NULL,
6360 					     &(wrq->u.encoding), keybuf);
6361 		}
6362 		break;
6363 
6364 	case SIOCGIWENCODE:	// Get the WEP keys and mode
6365 		// Only super-user can see WEP key
6366 		// Note : this is needed only for very old versions of WE
6367 		if (!capable(CAP_NET_ADMIN)) {
6368 			rc = -EPERM;
6369 			break;
6370 		}
6371 		{
6372 			char keybuf[MAX_KEY_SIZE];
6373 			rc = airo_get_encode(dev, NULL,
6374 					     &(wrq->u.encoding), keybuf);
6375 			if (wrq->u.encoding.pointer) {
6376 				if (copy_to_user(wrq->u.encoding.pointer,
6377 						 keybuf,
6378 						 wrq->u.encoding.length))
6379 					rc = -EFAULT;
6380 			}
6381 		}
6382 		break;
6383 
6384 	case SIOCGIWTXPOW:	// Get the current Tx-Power
6385 		rc=airo_get_txpow(dev, NULL, &(wrq->u.txpower), NULL);
6386 		break;
6387 	case SIOCSIWTXPOW:
6388 		rc=airo_set_txpow(dev, NULL, &(wrq->u.txpower), NULL);
6389 		break;
6390 
6391 	case SIOCSIWRETRY:
6392 		rc=airo_set_retry(dev, NULL, &(wrq->u.retry), NULL);
6393 		break;
6394 	case SIOCGIWRETRY:
6395 		rc=airo_get_retry(dev, NULL, &(wrq->u.retry), NULL);
6396 		break;
6397 
6398 	case SIOCGIWRANGE:	// Get range of parameters
6399 		{
6400 			struct iw_range range;
6401 			rc = airo_get_range(dev, NULL,
6402 					    &(wrq->u.data), (char *) &range);
6403 			if (copy_to_user(wrq->u.data.pointer, &range,
6404 					 sizeof(struct iw_range)))
6405 				rc = -EFAULT;
6406 		}
6407 		break;
6408 
6409 	case SIOCGIWPOWER:
6410 		rc=airo_get_power(dev, NULL, &(wrq->u.power), NULL);
6411 		break;
6412 
6413 	case SIOCSIWPOWER:
6414 		rc=airo_set_power(dev, NULL, &(wrq->u.power), NULL);
6415 		break;
6416 
6417 	case SIOCGIWSENS:
6418 		rc = airo_get_sens(dev, NULL, &(wrq->u.sens), NULL);
6419 		break;
6420 
6421 	case SIOCSIWSENS:
6422 		rc = airo_set_sens(dev, NULL, &(wrq->u.sens), NULL);
6423 		break;
6424 
6425 	case SIOCGIWAPLIST:
6426 		{
6427 			char buffer[IW_MAX_AP * (sizeof(struct sockaddr) +
6428 						  sizeof(struct iw_quality))];
6429 			if (wrq->u.data.pointer) {
6430 				rc = airo_get_aplist(dev, NULL,
6431 						     &(wrq->u.data), buffer);
6432 				if (copy_to_user(wrq->u.data.pointer,
6433 						 buffer,
6434 						 (wrq->u.data.length *
6435 						  (sizeof(struct sockaddr) +
6436 						   sizeof(struct iw_quality)))
6437 						 ))
6438 					rc = -EFAULT;
6439 			}
6440 		}
6441 		break;
6442 
6443 #ifdef WIRELESS_SPY
6444 	case SIOCSIWSPY:	// Set the spy list
6445 		{
6446 			struct sockaddr address[IW_MAX_SPY];
6447 			/* Check the number of addresses */
6448 			if (wrq->u.data.length > IW_MAX_SPY) {
6449 				rc = -E2BIG;
6450 				break;
6451 			}
6452 			/* Get the data in the driver */
6453 			if (wrq->u.data.pointer) {
6454 				if (copy_from_user((char *) address,
6455 						   wrq->u.data.pointer,
6456 						   sizeof(struct sockaddr) *
6457 						   wrq->u.data.length)) {
6458 				rc = -EFAULT;
6459 				break;
6460 				}
6461 			} else if (wrq->u.data.length != 0) {
6462 				rc = -EINVAL;
6463 				break;
6464 			}
6465 			rc=airo_set_spy(dev, NULL, &(wrq->u.data),
6466 					(char *) address);
6467 		}
6468 		break;
6469 
6470 	case SIOCGIWSPY:	// Get the spy list
6471 		{
6472 			char buffer[IW_MAX_SPY * (sizeof(struct sockaddr) +
6473 						  sizeof(struct iw_quality))];
6474 			if (wrq->u.data.pointer) {
6475 				rc = airo_get_spy(dev, NULL,
6476 						  &(wrq->u.data), buffer);
6477 				if (copy_to_user(wrq->u.data.pointer,
6478 						 buffer,
6479 						 (wrq->u.data.length *
6480 						  (sizeof(struct sockaddr) +
6481 						   sizeof(struct iw_quality)))
6482 						 ))
6483 					rc = -EFAULT;
6484 			}
6485 		}
6486 		break;
6487 #endif /* WIRELESS_SPY */
6488 
6489 #ifdef CISCO_EXT
6490 	case SIOCGIWPRIV:
6491 		if(wrq->u.data.pointer) {
6492 			/* Set the number of ioctl available */
6493 			wrq->u.data.length = sizeof(airo_private_args) / sizeof( airo_private_args[0]);
6494 
6495 			/* Copy structure to the user buffer */
6496 			if(copy_to_user(wrq->u.data.pointer,
6497 					(u_char *) airo_private_args,
6498 					sizeof(airo_private_args)))
6499 				rc = -EFAULT;
6500 		}
6501 		break;
6502 #endif /* CISCO_EXT */
6503 #endif /* WIRELESS_EXT < 13 */
6504 
6505 #ifdef CISCO_EXT
6506 	case AIROIDIFC:
6507 #ifdef AIROOLDIDIFC
6508 	case AIROOLDIDIFC:
6509 #endif
6510 	{
6511 		int val = AIROMAGIC;
6512 		aironet_ioctl com;
6513 		if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
6514 			rc = -EFAULT;
6515 		else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
6516 			rc = -EFAULT;
6517 	}
6518 	break;
6519 
6520 	case AIROIOCTL:
6521 #ifdef AIROOLDIOCTL
6522 	case AIROOLDIOCTL:
6523 #endif
6524 		/* Get the command struct and hand it off for evaluation by
6525 		 * the proper subfunction
6526 		 */
6527 	{
6528 		aironet_ioctl com;
6529 		if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
6530 			rc = -EFAULT;
6531 			break;
6532 		}
6533 
6534 		/* Separate R/W functions bracket legality here
6535 		 */
6536 		if ( com.command <= AIRORRID )
6537 			rc = readrids(dev,&com);
6538 		else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR )
6539 			rc = writerids(dev,&com);
6540 		else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
6541 			rc = flashcard(dev,&com);
6542 		else
6543 			rc = -EINVAL;      /* Bad command in ioctl */
6544 	}
6545 	break;
6546 #endif /* CISCO_EXT */
6547 
6548 	// All other calls are currently unsupported
6549 	default:
6550 		rc = -EOPNOTSUPP;
6551 	}
6552 
6553 #if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
6554 	/* WE 13 and higher will use airo_config_commit */
6555 	/* Some of the "SET" function may have modified some of the
6556 	 * parameters. It's now time to commit them in the card */
6557 	airo_config_commit(dev, NULL, NULL, NULL);
6558 	if (rc == -EINPROGRESS)
6559 		return 0;
6560 #endif /* WIRELESS_EXT < 13 */
6561 
6562 	return rc;
6563 }
6564 
6565 #ifdef WIRELESS_EXT
6566 /*
6567  * Get the Wireless stats out of the driver
6568  * Note : irq and spinlock protection will occur in the subroutines
6569  *
6570  * TODO :
6571  *	o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
6572  *
6573  * Jean
6574  */
6575 static void airo_read_wireless_stats(struct airo_info *local)
6576 {
6577 	StatusRid status_rid;
6578 	StatsRid stats_rid;
6579 	u32 *vals = stats_rid.vals;
6580 
6581 	/* Get stats out of the card */
6582 	clear_bit(JOB_WSTATS, &local->flags);
6583 	readStatusRid(local, &status_rid, 0);
6584 	readStatsRid(local, &stats_rid, RID_STATS, 0);
6585 	up(&local->sem);
6586 
6587 	/* The status */
6588 	local->wstats.status = status_rid.mode;
6589 
6590 	/* Signal quality and co. But where is the noise level ??? */
6591 	local->wstats.qual.qual = status_rid.signalQuality;
6592 	if (local->rssi)
6593 		local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
6594 	else
6595 		local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
6596 	if (status_rid.len >= 124) {
6597 		local->wstats.qual.noise = 256 - status_rid.noisedBm;
6598 		local->wstats.qual.updated = 7;
6599 	} else {
6600 		local->wstats.qual.noise = 0;
6601 		local->wstats.qual.updated = 3;
6602 	}
6603 
6604 	/* Packets discarded in the wireless adapter due to wireless
6605 	 * specific problems */
6606 	local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
6607 	local->wstats.discard.code = vals[6];/* RxWepErr */
6608 	local->wstats.discard.fragment = vals[30];
6609 	local->wstats.discard.retries = vals[10];
6610 	local->wstats.discard.misc = vals[1] + vals[32];
6611 	local->wstats.miss.beacon = vals[34];
6612 }
6613 
6614 struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
6615 {
6616 	struct airo_info *local =  dev->priv;
6617 
6618 	/* Get stats out of the card if available */
6619 	if (down_trylock(&local->sem) != 0) {
6620 		set_bit(JOB_WSTATS, &local->flags);
6621 		wake_up_interruptible(&local->thr_wait);
6622 	} else
6623 		airo_read_wireless_stats(local);
6624 
6625 	return &local->wstats;
6626 }
6627 #endif /* WIRELESS_EXT */
6628 
6629 #ifdef CISCO_EXT
6630 #define RIDS_SIZE	2048
6631 /*
6632  * This just translates from driver IOCTL codes to the command codes to
6633  * feed to the radio's host interface. Things can be added/deleted
6634  * as needed.  This represents the READ side of control I/O to
6635  * the card
6636  */
6637 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
6638 	unsigned short ridcode;
6639 	unsigned char *iobuf;
6640 	int len;
6641 	struct airo_info *ai = dev->priv;
6642 
6643 	if (test_bit(FLAG_FLASHING, &ai->flags))
6644 		return -EIO;
6645 
6646 	switch(comp->command)
6647 	{
6648 	case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
6649 	case AIROGCFG: writeConfigRid (ai, 1);
6650 			    ridcode = RID_CONFIG;       break;
6651 	case AIROGSLIST:    ridcode = RID_SSID;         break;
6652 	case AIROGVLIST:    ridcode = RID_APLIST;       break;
6653 	case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
6654 	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
6655 	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
6656 		/* Only super-user can read WEP keys */
6657 		if (!capable(CAP_NET_ADMIN))
6658 			return -EPERM;
6659 		break;
6660 	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
6661 		/* Only super-user can read WEP keys */
6662 		if (!capable(CAP_NET_ADMIN))
6663 			return -EPERM;
6664 		break;
6665 	case AIROGSTAT:     ridcode = RID_STATUS;       break;
6666 	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
6667 	case AIROGSTATSC32: ridcode = RID_STATS;        break;
6668 #ifdef MICSUPPORT
6669 	case AIROGMICSTATS:
6670 		if (copy_to_user(comp->data, &ai->micstats,
6671 				 min((int)comp->len,(int)sizeof(ai->micstats))))
6672 			return -EFAULT;
6673 		return 0;
6674 #endif
6675 	case AIRORRID:      ridcode = comp->len;        break;
6676 	default:
6677 		return -EINVAL;
6678 		break;
6679 	}
6680 
6681 	if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
6682 		return -ENOMEM;
6683 
6684 	PC4500_readrid(ai,ridcode,iobuf,RIDS_SIZE, 1);
6685 	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
6686 	 * then return it to the user
6687 	 * 9/22/2000 Honor user given length
6688 	 */
6689 	if (comp->command == AIRORRID)
6690 		len = le16_to_cpu(*(unsigned short *)iobuf); /* Yuck! */
6691 	else
6692 		len = comp->len;
6693 
6694 	if (copy_to_user(comp->data, iobuf, min(len, (int)RIDS_SIZE))) {
6695 		kfree (iobuf);
6696 		return -EFAULT;
6697 	}
6698 	kfree (iobuf);
6699 	return 0;
6700 }
6701 
6702 /*
6703  * Danger Will Robinson write the rids here
6704  */
6705 
6706 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
6707 	struct airo_info *ai = dev->priv;
6708 	int  ridcode, enabled;
6709 	Resp      rsp;
6710 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
6711 	unsigned char *iobuf;
6712 
6713 	/* Only super-user can write RIDs */
6714 	if (!capable(CAP_NET_ADMIN))
6715 		return -EPERM;
6716 
6717 	if (test_bit(FLAG_FLASHING, &ai->flags))
6718 		return -EIO;
6719 
6720 	ridcode = 0;
6721 	writer = do_writerid;
6722 
6723 	switch(comp->command)
6724 	{
6725 	case AIROPSIDS:     ridcode = RID_SSID;         break;
6726 	case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
6727 	case AIROPAPLIST:   ridcode = RID_APLIST;       break;
6728 	case AIROPCFG: ai->config.len = 0;
6729 			    ridcode = RID_CONFIG;       break;
6730 	case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
6731 	case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
6732 	case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
6733 	case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
6734 		break;
6735 
6736 		/* this is not really a rid but a command given to the card
6737 		 * same with MAC off
6738 		 */
6739 	case AIROPMACON:
6740 		if (enable_MAC(ai, &rsp, 1) != 0)
6741 			return -EIO;
6742 		return 0;
6743 
6744 		/*
6745 		 * Evidently this code in the airo driver does not get a symbol
6746 		 * as disable_MAC. it's probably so short the compiler does not gen one.
6747 		 */
6748 	case AIROPMACOFF:
6749 		disable_MAC(ai, 1);
6750 		return 0;
6751 
6752 		/* This command merely clears the counts does not actually store any data
6753 		 * only reads rid. But as it changes the cards state, I put it in the
6754 		 * writerid routines.
6755 		 */
6756 	case AIROPSTCLR:
6757 		if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
6758 			return -ENOMEM;
6759 
6760 		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDS_SIZE, 1);
6761 
6762 #ifdef MICSUPPORT
6763 		enabled = ai->micstats.enabled;
6764 		memset(&ai->micstats,0,sizeof(ai->micstats));
6765 		ai->micstats.enabled = enabled;
6766 #endif
6767 
6768 		if (copy_to_user(comp->data, iobuf,
6769 				 min((int)comp->len, (int)RIDS_SIZE))) {
6770 			kfree (iobuf);
6771 			return -EFAULT;
6772 		}
6773 		kfree (iobuf);
6774 		return 0;
6775 
6776 	default:
6777 		return -EOPNOTSUPP;	/* Blarg! */
6778 	}
6779 	if(comp->len > RIDS_SIZE)
6780 		return -EINVAL;
6781 
6782 	if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
6783 		return -ENOMEM;
6784 
6785 	if (copy_from_user(iobuf,comp->data,comp->len)) {
6786 		kfree (iobuf);
6787 		return -EFAULT;
6788 	}
6789 
6790 	if (comp->command == AIROPCFG) {
6791 		ConfigRid *cfg = (ConfigRid *)iobuf;
6792 
6793 		if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
6794 			cfg->opmode |= MODE_MIC;
6795 
6796 		if ((cfg->opmode & 0xFF) == MODE_STA_IBSS)
6797 			set_bit (FLAG_ADHOC, &ai->flags);
6798 		else
6799 			clear_bit (FLAG_ADHOC, &ai->flags);
6800 	}
6801 
6802 	if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
6803 		kfree (iobuf);
6804 		return -EIO;
6805 	}
6806 	kfree (iobuf);
6807 	return 0;
6808 }
6809 
6810 /*****************************************************************************
6811  * Ancillary flash / mod functions much black magic lurkes here              *
6812  *****************************************************************************
6813  */
6814 
6815 /*
6816  * Flash command switch table
6817  */
6818 
6819 int flashcard(struct net_device *dev, aironet_ioctl *comp) {
6820 	int z;
6821 	int cmdreset(struct airo_info *);
6822 	int setflashmode(struct airo_info *);
6823 	int flashgchar(struct airo_info *,int,int);
6824 	int flashpchar(struct airo_info *,int,int);
6825 	int flashputbuf(struct airo_info *);
6826 	int flashrestart(struct airo_info *,struct net_device *);
6827 
6828 	/* Only super-user can modify flash */
6829 	if (!capable(CAP_NET_ADMIN))
6830 		return -EPERM;
6831 
6832 	switch(comp->command)
6833 	{
6834 	case AIROFLSHRST:
6835 		return cmdreset((struct airo_info *)dev->priv);
6836 
6837 	case AIROFLSHSTFL:
6838 		if (!((struct airo_info *)dev->priv)->flash &&
6839 			(((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
6840 			return -ENOMEM;
6841 		return setflashmode((struct airo_info *)dev->priv);
6842 
6843 	case AIROFLSHGCHR: /* Get char from aux */
6844 		if(comp->len != sizeof(int))
6845 			return -EINVAL;
6846 		if (copy_from_user(&z,comp->data,comp->len))
6847 			return -EFAULT;
6848 		return flashgchar((struct airo_info *)dev->priv,z,8000);
6849 
6850 	case AIROFLSHPCHR: /* Send char to card. */
6851 		if(comp->len != sizeof(int))
6852 			return -EINVAL;
6853 		if (copy_from_user(&z,comp->data,comp->len))
6854 			return -EFAULT;
6855 		return flashpchar((struct airo_info *)dev->priv,z,8000);
6856 
6857 	case AIROFLPUTBUF: /* Send 32k to card */
6858 		if (!((struct airo_info *)dev->priv)->flash)
6859 			return -ENOMEM;
6860 		if(comp->len > FLASHSIZE)
6861 			return -EINVAL;
6862 		if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
6863 			return -EFAULT;
6864 
6865 		flashputbuf((struct airo_info *)dev->priv);
6866 		return 0;
6867 
6868 	case AIRORESTART:
6869 		if(flashrestart((struct airo_info *)dev->priv,dev))
6870 			return -EIO;
6871 		return 0;
6872 	}
6873 	return -EINVAL;
6874 }
6875 
6876 #define FLASH_COMMAND  0x7e7e
6877 
6878 /*
6879  * STEP 1)
6880  * Disable MAC and do soft reset on
6881  * card.
6882  */
6883 
6884 int cmdreset(struct airo_info *ai) {
6885 	disable_MAC(ai, 1);
6886 
6887 	if(!waitbusy (ai)){
6888 		printk(KERN_INFO "Waitbusy hang before RESET\n");
6889 		return -EBUSY;
6890 	}
6891 
6892 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
6893 
6894 	set_current_state (TASK_UNINTERRUPTIBLE);
6895 	schedule_timeout (HZ);          /* WAS 600 12/7/00 */
6896 
6897 	if(!waitbusy (ai)){
6898 		printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
6899 		return -EBUSY;
6900 	}
6901 	return 0;
6902 }
6903 
6904 /* STEP 2)
6905  * Put the card in legendary flash
6906  * mode
6907  */
6908 
6909 int setflashmode (struct airo_info *ai) {
6910 	set_bit (FLAG_FLASHING, &ai->flags);
6911 
6912 	OUT4500(ai, SWS0, FLASH_COMMAND);
6913 	OUT4500(ai, SWS1, FLASH_COMMAND);
6914 	if (probe) {
6915 		OUT4500(ai, SWS0, FLASH_COMMAND);
6916 		OUT4500(ai, COMMAND,0x10);
6917 	} else {
6918 		OUT4500(ai, SWS2, FLASH_COMMAND);
6919 		OUT4500(ai, SWS3, FLASH_COMMAND);
6920 		OUT4500(ai, COMMAND,0);
6921 	}
6922 	set_current_state (TASK_UNINTERRUPTIBLE);
6923 	schedule_timeout (HZ/2); /* 500ms delay */
6924 
6925 	if(!waitbusy(ai)) {
6926 		clear_bit (FLAG_FLASHING, &ai->flags);
6927 		printk(KERN_INFO "Waitbusy hang after setflash mode\n");
6928 		return -EIO;
6929 	}
6930 	return 0;
6931 }
6932 
6933 /* Put character to SWS0 wait for dwelltime
6934  * x 50us for  echo .
6935  */
6936 
6937 int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
6938 	int echo;
6939 	int waittime;
6940 
6941 	byte |= 0x8000;
6942 
6943 	if(dwelltime == 0 )
6944 		dwelltime = 200;
6945 
6946 	waittime=dwelltime;
6947 
6948 	/* Wait for busy bit d15 to go false indicating buffer empty */
6949 	while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
6950 		udelay (50);
6951 		waittime -= 50;
6952 	}
6953 
6954 	/* timeout for busy clear wait */
6955 	if(waittime <= 0 ){
6956 		printk(KERN_INFO "flash putchar busywait timeout! \n");
6957 		return -EBUSY;
6958 	}
6959 
6960 	/* Port is clear now write byte and wait for it to echo back */
6961 	do {
6962 		OUT4500(ai,SWS0,byte);
6963 		udelay(50);
6964 		dwelltime -= 50;
6965 		echo = IN4500(ai,SWS1);
6966 	} while (dwelltime >= 0 && echo != byte);
6967 
6968 	OUT4500(ai,SWS1,0);
6969 
6970 	return (echo == byte) ? 0 : -EIO;
6971 }
6972 
6973 /*
6974  * Get a character from the card matching matchbyte
6975  * Step 3)
6976  */
6977 int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
6978 	int           rchar;
6979 	unsigned char rbyte=0;
6980 
6981 	do {
6982 		rchar = IN4500(ai,SWS1);
6983 
6984 		if(dwelltime && !(0x8000 & rchar)){
6985 			dwelltime -= 10;
6986 			mdelay(10);
6987 			continue;
6988 		}
6989 		rbyte = 0xff & rchar;
6990 
6991 		if( (rbyte == matchbyte) && (0x8000 & rchar) ){
6992 			OUT4500(ai,SWS1,0);
6993 			return 0;
6994 		}
6995 		if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
6996 			break;
6997 		OUT4500(ai,SWS1,0);
6998 
6999 	}while(dwelltime > 0);
7000 	return -EIO;
7001 }
7002 
7003 /*
7004  * Transfer 32k of firmware data from user buffer to our buffer and
7005  * send to the card
7006  */
7007 
7008 int flashputbuf(struct airo_info *ai){
7009 	int            nwords;
7010 
7011 	/* Write stuff */
7012 	OUT4500(ai,AUXPAGE,0x100);
7013 	OUT4500(ai,AUXOFF,0);
7014 
7015 	for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
7016 		OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
7017 	}
7018 
7019 	OUT4500(ai,SWS0,0x8000);
7020 
7021 	return 0;
7022 }
7023 
7024 /*
7025  *
7026  */
7027 int flashrestart(struct airo_info *ai,struct net_device *dev){
7028 	int    i,status;
7029 
7030 	set_current_state (TASK_UNINTERRUPTIBLE);
7031 	schedule_timeout (HZ);          /* Added 12/7/00 */
7032 	clear_bit (FLAG_FLASHING, &ai->flags);
7033 	status = setup_card(ai, dev->dev_addr);
7034 
7035 	for( i = 0; i < MAX_FIDS; i++ ) {
7036 		ai->fids[i] = transmit_allocate( ai, 2312, i >= MAX_FIDS / 2 );
7037 	}
7038 
7039 	set_current_state (TASK_UNINTERRUPTIBLE);
7040 	schedule_timeout (HZ);          /* Added 12/7/00 */
7041 	return status;
7042 }
7043 #endif /* CISCO_EXT */
7044 
7045 /*
7046     This program is free software; you can redistribute it and/or
7047     modify it under the terms of the GNU General Public License
7048     as published by the Free Software Foundation; either version 2
7049     of the License, or (at your option) any later version.
7050 
7051     This program is distributed in the hope that it will be useful,
7052     but WITHOUT ANY WARRANTY; without even the implied warranty of
7053     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7054     GNU General Public License for more details.
7055 
7056     In addition:
7057 
7058     Redistribution and use in source and binary forms, with or without
7059     modification, are permitted provided that the following conditions
7060     are met:
7061 
7062     1. Redistributions of source code must retain the above copyright
7063        notice, this list of conditions and the following disclaimer.
7064     2. Redistributions in binary form must reproduce the above copyright
7065        notice, this list of conditions and the following disclaimer in the
7066        documentation and/or other materials provided with the distribution.
7067     3. The name of the author may not be used to endorse or promote
7068        products derived from this software without specific prior written
7069        permission.
7070 
7071     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
7072     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7073     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7074     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
7075     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7076     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7077     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7078     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
7079     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
7080     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
7081     POSSIBILITY OF SUCH DAMAGE.
7082 */
7083 
7084 module_init(airo_init_module);
7085 module_exit(airo_cleanup_module);
7086