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