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