This commit was manufactured by cvs2svn to create tag
[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 <linux/bitops.h>
39 #include <asm/io.h>
40 #include <asm/system.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         struct iw_public_data   wireless_data;
1193 #endif /* WIRELESS_EXT */
1194 #ifdef MICSUPPORT
1195         /* MIC stuff */
1196         struct crypto_tfm       *tfm;
1197         mic_module              mod[2];
1198         mic_statistics          micstats;
1199 #endif
1200         HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
1201         HostTxDesc txfids[MPI_MAX_FIDS];
1202         HostRidDesc config_desc;
1203         unsigned long ridbus; // phys addr of config_desc
1204         struct sk_buff_head txq;// tx queue used by mpi350 code
1205         struct pci_dev          *pci;
1206         unsigned char           *pcimem;
1207         unsigned char           *pciaux;
1208         unsigned char           *shared;
1209         dma_addr_t              shared_dma;
1210         int                     power;
1211         SsidRid                 *SSID;
1212         APListRid               *APList;
1213 #define PCI_SHARED_LEN          2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
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                 ai->flash = NULL;
2384         }
2385         if (ai->rssi) {
2386                 kfree(ai->rssi);
2387                 ai->rssi = NULL;
2388         }
2389         if (ai->APList) {
2390                 kfree(ai->APList);
2391                 ai->APList = NULL;
2392         }
2393         if (ai->SSID) {
2394                 kfree(ai->SSID);
2395                 ai->SSID = NULL;
2396         }
2397         if (freeres) {
2398                 /* PCMCIA frees this stuff, so only for PCI and ISA */
2399                 release_region( dev->base_addr, 64 );
2400                 if (test_bit(FLAG_MPI, &ai->flags)) {
2401                         if (ai->pci)
2402                                 mpi_unmap_card(ai->pci);
2403                         if (ai->pcimem)
2404                                 iounmap(ai->pcimem);
2405                         if (ai->pciaux)
2406                                 iounmap(ai->pciaux);
2407                         pci_free_consistent(ai->pci, PCI_SHARED_LEN,
2408                                 ai->shared, ai->shared_dma);
2409                 }
2410         }
2411 #ifdef MICSUPPORT
2412         if (ai->tfm)
2413                 crypto_free_tfm(ai->tfm);
2414 #endif
2415         del_airo_dev( dev );
2416         free_netdev( dev );
2417 }
2418
2419 EXPORT_SYMBOL(stop_airo_card);
2420
2421 static int add_airo_dev( struct net_device *dev );
2422
2423 int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
2424 {
2425         memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
2426         return ETH_ALEN;
2427 }
2428
2429 static void mpi_unmap_card(struct pci_dev *pci)
2430 {
2431         unsigned long mem_start = pci_resource_start(pci, 1);
2432         unsigned long mem_len = pci_resource_len(pci, 1);
2433         unsigned long aux_start = pci_resource_start(pci, 2);
2434         unsigned long aux_len = AUXMEMSIZE;
2435
2436         release_mem_region(aux_start, aux_len);
2437         release_mem_region(mem_start, mem_len);
2438 }
2439
2440 /*************************************************************
2441  *  This routine assumes that descriptors have been setup .
2442  *  Run at insmod time or after reset  when the decriptors
2443  *  have been initialized . Returns 0 if all is well nz
2444  *  otherwise . Does not allocate memory but sets up card
2445  *  using previously allocated descriptors.
2446  */
2447 static int mpi_init_descriptors (struct airo_info *ai)
2448 {
2449         Cmd cmd;
2450         Resp rsp;
2451         int i;
2452         int rc = SUCCESS;
2453
2454         /* Alloc  card RX descriptors */
2455         netif_stop_queue(ai->dev);
2456
2457         memset(&rsp,0,sizeof(rsp));
2458         memset(&cmd,0,sizeof(cmd));
2459
2460         cmd.cmd = CMD_ALLOCATEAUX;
2461         cmd.parm0 = FID_RX;
2462         cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
2463         cmd.parm2 = MPI_MAX_FIDS;
2464         rc=issuecommand(ai, &cmd, &rsp);
2465         if (rc != SUCCESS) {
2466                 printk(KERN_ERR "airo:  Couldn't allocate RX FID\n");
2467                 return rc;
2468         }
2469
2470         for (i=0; i<MPI_MAX_FIDS; i++) {
2471                 memcpy(ai->rxfids[i].card_ram_off,
2472                         &ai->rxfids[i].rx_desc, sizeof(RxFid));
2473         }
2474
2475         /* Alloc card TX descriptors */
2476
2477         memset(&rsp,0,sizeof(rsp));
2478         memset(&cmd,0,sizeof(cmd));
2479
2480         cmd.cmd = CMD_ALLOCATEAUX;
2481         cmd.parm0 = FID_TX;
2482         cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
2483         cmd.parm2 = MPI_MAX_FIDS;
2484
2485         for (i=0; i<MPI_MAX_FIDS; i++) {
2486                 ai->txfids[i].tx_desc.valid = 1;
2487                 memcpy((char *)ai->txfids[i].card_ram_off,
2488                         &ai->txfids[i].tx_desc, sizeof(TxFid));
2489         }
2490         ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2491
2492         rc=issuecommand(ai, &cmd, &rsp);
2493         if (rc != SUCCESS) {
2494                 printk(KERN_ERR "airo:  Couldn't allocate TX FID\n");
2495                 return rc;
2496         }
2497
2498         /* Alloc card Rid descriptor */
2499         memset(&rsp,0,sizeof(rsp));
2500         memset(&cmd,0,sizeof(cmd));
2501
2502         cmd.cmd = CMD_ALLOCATEAUX;
2503         cmd.parm0 = RID_RW;
2504         cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
2505         cmd.parm2 = 1; /* Magic number... */
2506         rc=issuecommand(ai, &cmd, &rsp);
2507         if (rc != SUCCESS) {
2508                 printk(KERN_ERR "airo:  Couldn't allocate RID\n");
2509                 return rc;
2510         }
2511
2512         memcpy((char *)ai->config_desc.card_ram_off,
2513                 (char *)&ai->config_desc.rid_desc, sizeof(Rid));
2514
2515         return rc;
2516 }
2517
2518 /*
2519  * We are setting up three things here:
2520  * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
2521  * 2) Map PCI memory for issueing commands.
2522  * 3) Allocate memory (shared) to send and receive ethernet frames.
2523  */
2524 static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
2525                     const char *name)
2526 {
2527         unsigned long mem_start, mem_len, aux_start, aux_len;
2528         int rc = -1;
2529         int i;
2530         unsigned char *busaddroff,*vpackoff;
2531         unsigned char *pciaddroff;
2532
2533         mem_start = pci_resource_start(pci, 1);
2534         mem_len = pci_resource_len(pci, 1);
2535         aux_start = pci_resource_start(pci, 2);
2536         aux_len = AUXMEMSIZE;
2537
2538         if (!request_mem_region(mem_start, mem_len, name)) {
2539                 printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
2540                        (int)mem_start, (int)mem_len, name);
2541                 goto out;
2542         }
2543         if (!request_mem_region(aux_start, aux_len, name)) {
2544                 printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
2545                        (int)aux_start, (int)aux_len, name);
2546                 goto free_region1;
2547         }
2548
2549         ai->pcimem = ioremap(mem_start, mem_len);
2550         if (!ai->pcimem) {
2551                 printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
2552                        (int)mem_start, (int)mem_len, name);
2553                 goto free_region2;
2554         }
2555         ai->pciaux = ioremap(aux_start, aux_len);
2556         if (!ai->pciaux) {
2557                 printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
2558                        (int)aux_start, (int)aux_len, name);
2559                 goto free_memmap;
2560         }
2561
2562         /* Reserve PKTSIZE for each fid and 2K for the Rids */
2563         ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
2564         if (!ai->shared) {
2565                 printk(KERN_ERR "airo: Couldn't alloc_consistent %d\n",
2566                        PCI_SHARED_LEN);
2567                 goto free_auxmap;
2568         }
2569
2570         /*
2571          * Setup descriptor RX, TX, CONFIG
2572          */
2573         busaddroff = (unsigned char *)ai->shared_dma;
2574         pciaddroff = ai->pciaux + AUX_OFFSET;
2575         vpackoff   = ai->shared;
2576
2577         /* RX descriptor setup */
2578         for(i = 0; i < MPI_MAX_FIDS; i++) {
2579                 ai->rxfids[i].pending = 0;
2580                 ai->rxfids[i].card_ram_off = pciaddroff;
2581                 ai->rxfids[i].virtual_host_addr = vpackoff;
2582                 ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
2583                 ai->rxfids[i].rx_desc.valid = 1;
2584                 ai->rxfids[i].rx_desc.len = PKTSIZE;
2585                 ai->rxfids[i].rx_desc.rdy = 0;
2586
2587                 pciaddroff += sizeof(RxFid);
2588                 busaddroff += PKTSIZE;
2589                 vpackoff   += PKTSIZE;
2590         }
2591
2592         /* TX descriptor setup */
2593         for(i = 0; i < MPI_MAX_FIDS; i++) {
2594                 ai->txfids[i].card_ram_off = pciaddroff;
2595                 ai->txfids[i].virtual_host_addr = vpackoff;
2596                 ai->txfids[i].tx_desc.valid = 1;
2597                 ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
2598                 memcpy(ai->txfids[i].virtual_host_addr,
2599                         &wifictlhdr8023, sizeof(wifictlhdr8023));
2600
2601                 pciaddroff += sizeof(TxFid);
2602                 busaddroff += PKTSIZE;
2603                 vpackoff   += PKTSIZE;
2604         }
2605         ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2606
2607         /* Rid descriptor setup */
2608         ai->config_desc.card_ram_off = pciaddroff;
2609         ai->config_desc.virtual_host_addr = vpackoff;
2610         ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
2611         ai->ridbus = (dma_addr_t)busaddroff;
2612         ai->config_desc.rid_desc.rid = 0;
2613         ai->config_desc.rid_desc.len = RIDSIZE;
2614         ai->config_desc.rid_desc.valid = 1;
2615         pciaddroff += sizeof(Rid);
2616         busaddroff += RIDSIZE;
2617         vpackoff   += RIDSIZE;
2618
2619         /* Tell card about descriptors */
2620         if (mpi_init_descriptors (ai) != SUCCESS)
2621                 goto free_shared;
2622
2623         return 0;
2624  free_shared:
2625         pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
2626  free_auxmap:
2627         iounmap(ai->pciaux);
2628  free_memmap:
2629         iounmap(ai->pcimem);
2630  free_region2:
2631         release_mem_region(aux_start, aux_len);
2632  free_region1:
2633         release_mem_region(mem_start, mem_len);
2634  out:
2635         return rc;
2636 }
2637
2638 static void wifi_setup(struct net_device *dev)
2639 {
2640         dev->hard_header        = NULL;
2641         dev->rebuild_header     = NULL;
2642         dev->hard_header_cache  = NULL;
2643         dev->header_cache_update= NULL;
2644
2645         dev->hard_header_parse  = wll_header_parse;
2646         dev->hard_start_xmit = &airo_start_xmit11;
2647         dev->get_stats = &airo_get_stats;
2648         dev->set_mac_address = &airo_set_mac_address;
2649         dev->do_ioctl = &airo_ioctl;
2650 #ifdef WIRELESS_EXT
2651         dev->wireless_handlers = &airo_handler_def;
2652 #endif /* WIRELESS_EXT */
2653         dev->change_mtu = &airo_change_mtu;
2654         dev->open = &airo_open;
2655         dev->stop = &airo_close;
2656
2657         dev->type               = ARPHRD_IEEE80211;
2658         dev->hard_header_len    = ETH_HLEN;
2659         dev->mtu                = 2312;
2660         dev->addr_len           = ETH_ALEN;
2661         dev->tx_queue_len       = 100; 
2662
2663         memset(dev->broadcast,0xFF, ETH_ALEN);
2664
2665         dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
2666 }
2667
2668 static struct net_device *init_wifidev(struct airo_info *ai,
2669                                         struct net_device *ethdev)
2670 {
2671         int err;
2672         struct net_device *dev = alloc_netdev(0, "wifi%d", wifi_setup);
2673         if (!dev)
2674                 return NULL;
2675         dev->priv = ethdev->priv;
2676         dev->irq = ethdev->irq;
2677         dev->base_addr = ethdev->base_addr;
2678 #ifdef WIRELESS_EXT
2679         dev->wireless_data = ethdev->wireless_data;
2680 #endif /* WIRELESS_EXT */
2681         memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
2682         err = register_netdev(dev);
2683         if (err<0) {
2684                 free_netdev(dev);
2685                 return NULL;
2686         }
2687         return dev;
2688 }
2689
2690 int reset_card( struct net_device *dev , int lock) {
2691         struct airo_info *ai = dev->priv;
2692
2693         if (lock && down_interruptible(&ai->sem))
2694                 return -1;
2695         waitbusy (ai);
2696         OUT4500(ai,COMMAND,CMD_SOFTRESET);
2697         set_current_state (TASK_UNINTERRUPTIBLE);
2698         schedule_timeout (HZ/5);
2699         waitbusy (ai);
2700         set_current_state (TASK_UNINTERRUPTIBLE);
2701         schedule_timeout (HZ/5);
2702         if (lock)
2703                 up(&ai->sem);
2704         return 0;
2705 }
2706
2707 struct net_device *_init_airo_card( unsigned short irq, int port,
2708                                     int is_pcmcia, struct pci_dev *pci )
2709 {
2710         struct net_device *dev;
2711         struct airo_info *ai;
2712         int i, rc;
2713
2714         /* Create the network device object. */
2715         dev = alloc_etherdev(sizeof(*ai));
2716         if (!dev) {
2717                 printk(KERN_ERR "airo:  Couldn't alloc_etherdev\n");
2718                 return NULL;
2719         }
2720         if (dev_alloc_name(dev, dev->name) < 0) {
2721                 printk(KERN_ERR "airo:  Couldn't get name!\n");
2722                 goto err_out_free;
2723         }
2724
2725         ai = dev->priv;
2726         ai->wifidev = NULL;
2727         ai->flags = 0;
2728         if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2729                 printk(KERN_DEBUG "airo: Found an MPI350 card\n");
2730                 set_bit(FLAG_MPI, &ai->flags);
2731         }
2732         ai->dev = dev;
2733         spin_lock_init(&ai->aux_lock);
2734         sema_init(&ai->sem, 1);
2735         ai->config.len = 0;
2736         ai->pci = pci;
2737         init_waitqueue_head (&ai->thr_wait);
2738         init_completion (&ai->thr_exited);
2739         ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
2740         if (ai->thr_pid < 0)
2741                 goto err_out_free;
2742 #ifdef MICSUPPORT
2743         ai->tfm = NULL;
2744 #endif
2745         rc = add_airo_dev( dev );
2746         if (rc)
2747                 goto err_out_thr;
2748
2749         /* The Airo-specific entries in the device structure. */
2750         if (test_bit(FLAG_MPI,&ai->flags)) {
2751                 skb_queue_head_init (&ai->txq);
2752                 dev->hard_start_xmit = &mpi_start_xmit;
2753         } else
2754                 dev->hard_start_xmit = &airo_start_xmit;
2755         dev->get_stats = &airo_get_stats;
2756         dev->set_multicast_list = &airo_set_multicast_list;
2757         dev->set_mac_address = &airo_set_mac_address;
2758         dev->do_ioctl = &airo_ioctl;
2759 #ifdef WIRELESS_EXT
2760         dev->wireless_handlers = &airo_handler_def;
2761         ai->wireless_data.spy_data = &ai->spy_data;
2762         dev->wireless_data = &ai->wireless_data;
2763 #endif /* WIRELESS_EXT */
2764         dev->change_mtu = &airo_change_mtu;
2765         dev->open = &airo_open;
2766         dev->stop = &airo_close;
2767         dev->irq = irq;
2768         dev->base_addr = port;
2769
2770         /* what is with PCMCIA ??? */
2771         if (pci) {
2772                 SET_NETDEV_DEV(dev, &pci->dev);
2773         }
2774
2775         if (test_bit(FLAG_MPI,&ai->flags))
2776                 reset_card (dev, 1);
2777
2778         rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
2779         if (rc) {
2780                 printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
2781                 goto err_out_unlink;
2782         }
2783         if (!is_pcmcia) {
2784                 if (!request_region( dev->base_addr, 64, dev->name )) {
2785                         rc = -EBUSY;
2786                         printk(KERN_ERR "airo: Couldn't request region\n");
2787                         goto err_out_irq;
2788                 }
2789         }
2790
2791         if (test_bit(FLAG_MPI,&ai->flags)) {
2792                 if (mpi_map_card(ai, pci, dev->name)) {
2793                         printk(KERN_ERR "airo: Could not map memory\n");
2794                         goto err_out_res;
2795                 }
2796         }
2797
2798         if (probe) {
2799                 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
2800                         printk( KERN_ERR "airo: MAC could not be enabled\n" );
2801                         rc = -EIO;
2802                         goto err_out_map;
2803                 }
2804         } else if (!test_bit(FLAG_MPI,&ai->flags)) {
2805                 ai->bap_read = fast_bap_read;
2806                 set_bit(FLAG_FLASHING, &ai->flags);
2807         }
2808
2809         rc = register_netdev(dev);
2810         if (rc) {
2811                 printk(KERN_ERR "airo: Couldn't register_netdev\n");
2812                 goto err_out_map;
2813         }
2814         ai->wifidev = init_wifidev(ai, dev);
2815
2816         set_bit(FLAG_REGISTERED,&ai->flags);
2817         printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
2818                 dev->name,
2819                 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2820                 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
2821
2822         /* Allocate the transmit buffers */
2823         if (probe && !test_bit(FLAG_MPI,&ai->flags))
2824                 for( i = 0; i < MAX_FIDS; i++ )
2825                         ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
2826
2827         setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
2828         netif_start_queue(dev);
2829         SET_MODULE_OWNER(dev);
2830         return dev;
2831
2832 err_out_map:
2833         if (test_bit(FLAG_MPI,&ai->flags) && pci) {
2834                 pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
2835                 iounmap(ai->pciaux);
2836                 iounmap(ai->pcimem);
2837                 mpi_unmap_card(ai->pci);
2838         }
2839 err_out_res:
2840         if (!is_pcmcia)
2841                 release_region( dev->base_addr, 64 );
2842 err_out_irq:
2843         free_irq(dev->irq, dev);
2844 err_out_unlink:
2845         del_airo_dev(dev);
2846 err_out_thr:
2847         set_bit(JOB_DIE, &ai->flags);
2848         kill_proc(ai->thr_pid, SIGTERM, 1);
2849         wait_for_completion(&ai->thr_exited);
2850 err_out_free:
2851         free_netdev(dev);
2852         return NULL;
2853 }
2854
2855 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
2856 {
2857         return _init_airo_card ( irq, port, is_pcmcia, NULL);
2858 }
2859
2860 EXPORT_SYMBOL(init_airo_card);
2861
2862 static int waitbusy (struct airo_info *ai) {
2863         int delay = 0;
2864         while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
2865                 udelay (10);
2866                 if ((++delay % 20) == 0)
2867                         OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2868         }
2869         return delay < 10000;
2870 }
2871
2872 int reset_airo_card( struct net_device *dev )
2873 {
2874         int i;
2875         struct airo_info *ai = dev->priv;
2876
2877         if (reset_card (dev, 1))
2878                 return -1;
2879
2880         if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
2881                 printk( KERN_ERR "airo: MAC could not be enabled\n" );
2882                 return -1;
2883         }
2884         printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", dev->name,
2885                         dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2886                         dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
2887         /* Allocate the transmit buffers if needed */
2888         if (!test_bit(FLAG_MPI,&ai->flags))
2889                 for( i = 0; i < MAX_FIDS; i++ )
2890                         ai->fids[i] = transmit_allocate (ai,2312,i>=MAX_FIDS/2);
2891
2892         enable_interrupts( ai );
2893         netif_wake_queue(dev);
2894         return 0;
2895 }
2896
2897 EXPORT_SYMBOL(reset_airo_card);
2898
2899 static void airo_send_event(struct net_device *dev) {
2900         struct airo_info *ai = dev->priv;
2901         union iwreq_data wrqu;
2902         StatusRid status_rid;
2903
2904         clear_bit(JOB_EVENT, &ai->flags);
2905         PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
2906         up(&ai->sem);
2907         wrqu.data.length = 0;
2908         wrqu.data.flags = 0;
2909         memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
2910         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2911
2912         /* Send event to user space */
2913         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
2914 }
2915
2916 static int airo_thread(void *data) {
2917         struct net_device *dev = data;
2918         struct airo_info *ai = dev->priv;
2919         int locked;
2920         
2921         daemonize("%s", dev->name);
2922         allow_signal(SIGTERM);
2923
2924         while(1) {
2925                 if (signal_pending(current))
2926                         flush_signals(current);
2927
2928                 /* make swsusp happy with our thread */
2929                 if (current->flags & PF_FREEZE)
2930                         refrigerator(PF_FREEZE);
2931
2932                 if (test_bit(JOB_DIE, &ai->flags))
2933                         break;
2934
2935                 if (ai->flags & JOB_MASK) {
2936                         locked = down_interruptible(&ai->sem);
2937                 } else {
2938                         wait_queue_t wait;
2939
2940                         init_waitqueue_entry(&wait, current);
2941                         add_wait_queue(&ai->thr_wait, &wait);
2942                         for (;;) {
2943                                 set_current_state(TASK_INTERRUPTIBLE);
2944                                 if (ai->flags & JOB_MASK)
2945                                         break;
2946                                 if (ai->expires) {
2947                                         if (time_after_eq(jiffies,ai->expires)){
2948                                                 set_bit(JOB_AUTOWEP,&ai->flags);
2949                                                 break;
2950                                         }
2951                                         if (!signal_pending(current)) {
2952                                                 schedule_timeout(ai->expires - jiffies);
2953                                                 continue;
2954                                         }
2955                                 } else if (!signal_pending(current)) {
2956                                         schedule();
2957                                         continue;
2958                                 }
2959                                 break;
2960                         }
2961                         current->state = TASK_RUNNING;
2962                         remove_wait_queue(&ai->thr_wait, &wait);
2963                         locked = 1;
2964                 }
2965
2966                 if (locked)
2967                         continue;
2968
2969                 if (test_bit(JOB_DIE, &ai->flags)) {
2970                         up(&ai->sem);
2971                         break;
2972                 }
2973
2974                 if (ai->power || test_bit(FLAG_FLASHING, &ai->flags)) {
2975                         up(&ai->sem);
2976                         continue;
2977                 }
2978
2979                 if (test_bit(JOB_XMIT, &ai->flags))
2980                         airo_end_xmit(dev);
2981                 else if (test_bit(JOB_XMIT11, &ai->flags))
2982                         airo_end_xmit11(dev);
2983                 else if (test_bit(JOB_STATS, &ai->flags))
2984                         airo_read_stats(ai);
2985                 else if (test_bit(JOB_WSTATS, &ai->flags))
2986                         airo_read_wireless_stats(ai);
2987                 else if (test_bit(JOB_PROMISC, &ai->flags))
2988                         airo_set_promisc(ai);
2989 #ifdef MICSUPPORT
2990                 else if (test_bit(JOB_MIC, &ai->flags))
2991                         micinit(ai);
2992 #endif
2993                 else if (test_bit(JOB_EVENT, &ai->flags))
2994                         airo_send_event(dev);
2995                 else if (test_bit(JOB_AUTOWEP, &ai->flags))
2996                         timer_func(dev);
2997         }
2998         complete_and_exit (&ai->thr_exited, 0);
2999 }
3000
3001 static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
3002         struct net_device *dev = (struct net_device *)dev_id;
3003         u16 status;
3004         u16 fid;
3005         struct airo_info *apriv = dev->priv;
3006         u16 savedInterrupts = 0;
3007         int handled = 0;
3008
3009         if (!netif_device_present(dev))
3010                 return IRQ_NONE;
3011
3012         for (;;) {
3013                 status = IN4500( apriv, EVSTAT );
3014                 if ( !(status & STATUS_INTS) || status == 0xffff ) break;
3015
3016                 handled = 1;
3017
3018                 if ( status & EV_AWAKE ) {
3019                         OUT4500( apriv, EVACK, EV_AWAKE );
3020                         OUT4500( apriv, EVACK, EV_AWAKE );
3021                 }
3022
3023                 if (!savedInterrupts) {
3024                         savedInterrupts = IN4500( apriv, EVINTEN );
3025                         OUT4500( apriv, EVINTEN, 0 );
3026                 }
3027
3028                 if ( status & EV_MIC ) {
3029                         OUT4500( apriv, EVACK, EV_MIC );
3030 #ifdef MICSUPPORT
3031                         if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
3032                                 set_bit(JOB_MIC, &apriv->flags);
3033                                 wake_up_interruptible(&apriv->thr_wait);
3034                         }
3035 #endif
3036                 }
3037                 if ( status & EV_LINK ) {
3038                         union iwreq_data        wrqu;
3039                         /* The link status has changed, if you want to put a
3040                            monitor hook in, do it here.  (Remember that
3041                            interrupts are still disabled!)
3042                         */
3043                         u16 newStatus = IN4500(apriv, LINKSTAT);
3044                         OUT4500( apriv, EVACK, EV_LINK);
3045                         /* Here is what newStatus means: */
3046 #define NOBEACON 0x8000 /* Loss of sync - missed beacons */
3047 #define MAXRETRIES 0x8001 /* Loss of sync - max retries */
3048 #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3049 #define FORCELOSS 0x8003 /* Loss of sync - host request */
3050 #define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
3051 #define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
3052 #define DISASS 0x8200 /* Disassociation (low byte is reason code) */
3053 #define ASSFAIL 0x8400 /* Association failure (low byte is reason
3054                           code) */
3055 #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
3056                            code) */
3057 #define ASSOCIATED 0x0400 /* Assocatied */
3058 #define RC_RESERVED 0 /* Reserved return code */
3059 #define RC_NOREASON 1 /* Unspecified reason */
3060 #define RC_AUTHINV 2 /* Previous authentication invalid */
3061 #define RC_DEAUTH 3 /* Deauthenticated because sending station is
3062                        leaving */
3063 #define RC_NOACT 4 /* Disassociated due to inactivity */
3064 #define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
3065                         all currently associated stations */
3066 #define RC_BADCLASS2 6 /* Class 2 frame received from
3067                           non-Authenticated station */
3068 #define RC_BADCLASS3 7 /* Class 3 frame received from
3069                           non-Associated station */
3070 #define RC_STATLEAVE 8 /* Disassociated because sending station is
3071                           leaving BSS */
3072 #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
3073                        Authenticated with the responding station */
3074                         if (newStatus != ASSOCIATED) {
3075                                 if (auto_wep && !apriv->expires) {
3076                                         apriv->expires = RUN_AT(3*HZ);
3077                                         wake_up_interruptible(&apriv->thr_wait);
3078                                 }
3079                         } else {
3080                                 struct task_struct *task = apriv->task;
3081                                 if (auto_wep)
3082                                         apriv->expires = 0;
3083                                 if (task)
3084                                         wake_up_process (task);
3085                                 set_bit(FLAG_UPDATE_UNI, &apriv->flags);
3086                                 set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
3087                         }
3088                         /* Question : is ASSOCIATED the only status
3089                          * that is valid ? We want to catch handover
3090                          * and reassociations as valid status
3091                          * Jean II */
3092                         if(newStatus == ASSOCIATED) {
3093                                 if (apriv->scan_timestamp) {
3094                                         /* Send an empty event to user space.
3095                                          * We don't send the received data on
3096                                          * the event because it would require
3097                                          * us to do complex transcoding, and
3098                                          * we want to minimise the work done in
3099                                          * the irq handler. Use a request to
3100                                          * extract the data - Jean II */
3101                                         wrqu.data.length = 0;
3102                                         wrqu.data.flags = 0;
3103                                         wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
3104                                         apriv->scan_timestamp = 0;
3105                                 }
3106                                 if (down_trylock(&apriv->sem) != 0) {
3107                                         set_bit(JOB_EVENT, &apriv->flags);
3108                                         wake_up_interruptible(&apriv->thr_wait);
3109                                 } else
3110                                         airo_send_event(dev);
3111                         } else {
3112                                 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3113                                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3114
3115                                 /* Send event to user space */
3116                                 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
3117                         }
3118                 }
3119
3120                 /* Check to see if there is something to receive */
3121                 if ( status & EV_RX  ) {
3122                         struct sk_buff *skb = NULL;
3123                         u16 fc, len, hdrlen = 0;
3124 #pragma pack(1)
3125                         struct {
3126                                 u16 status, len;
3127                                 u8 rssi[2];
3128                                 u8 rate;
3129                                 u8 freq;
3130                                 u16 tmp[4];
3131                         } hdr;
3132 #pragma pack()
3133                         u16 gap;
3134                         u16 tmpbuf[4];
3135                         u16 *buffer;
3136
3137                         if (test_bit(FLAG_MPI,&apriv->flags)) {
3138                                 if (test_bit(FLAG_802_11, &apriv->flags))
3139                                         mpi_receive_802_11(apriv);
3140                                 else
3141                                         mpi_receive_802_3(apriv);
3142                                 OUT4500(apriv, EVACK, EV_RX);
3143                                 goto exitrx;
3144                         }
3145
3146                         fid = IN4500( apriv, RXFID );
3147
3148                         /* Get the packet length */
3149                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3150                                 bap_setup (apriv, fid, 4, BAP0);
3151                                 bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
3152                                 /* Bad CRC. Ignore packet */
3153                                 if (le16_to_cpu(hdr.status) & 2)
3154                                         hdr.len = 0;
3155                                 if (apriv->wifidev == NULL)
3156                                         hdr.len = 0;
3157                         } else {
3158                                 bap_setup (apriv, fid, 0x36, BAP0);
3159                                 bap_read (apriv, (u16*)&hdr.len, 2, BAP0);
3160                         }
3161                         len = le16_to_cpu(hdr.len);
3162
3163                         if (len > 2312) {
3164                                 printk( KERN_ERR "airo: Bad size %d\n", len );
3165                                 goto badrx;
3166                         }
3167                         if (len == 0)
3168                                 goto badrx;
3169
3170                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3171                                 bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
3172                                 fc = le16_to_cpu(fc);
3173                                 switch (fc & 0xc) {
3174                                         case 4:
3175                                                 if ((fc & 0xe0) == 0xc0)
3176                                                         hdrlen = 10;
3177                                                 else
3178                                                         hdrlen = 16;
3179                                                 break;
3180                                         case 8:
3181                                                 if ((fc&0x300)==0x300){
3182                                                         hdrlen = 30;
3183                                                         break;
3184                                                 }
3185                                         default:
3186                                                 hdrlen = 24;
3187                                 }
3188                         } else
3189                                 hdrlen = ETH_ALEN * 2;
3190
3191                         skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
3192                         if ( !skb ) {
3193                                 apriv->stats.rx_dropped++;
3194                                 goto badrx;
3195                         }
3196                         skb_reserve(skb, 2); /* This way the IP header is aligned */
3197                         buffer = (u16*)skb_put (skb, len + hdrlen);
3198                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3199                                 buffer[0] = fc;
3200                                 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
3201                                 if (hdrlen == 24)
3202                                         bap_read (apriv, tmpbuf, 6, BAP0);
3203
3204                                 bap_read (apriv, &gap, sizeof(gap), BAP0);
3205                                 gap = le16_to_cpu(gap);
3206                                 if (gap) {
3207                                         if (gap <= 8)
3208                                                 bap_read (apriv, tmpbuf, gap, BAP0);
3209                                         else
3210                                                 printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n");
3211                                 }
3212                                 bap_read (apriv, buffer + hdrlen/2, len, BAP0);
3213                         } else {
3214 #ifdef MICSUPPORT
3215                                 MICBuffer micbuf;
3216 #endif
3217                                 bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
3218 #ifdef MICSUPPORT
3219                                 if (apriv->micstats.enabled) {
3220                                         bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
3221                                         if (ntohs(micbuf.typelen) > 0x05DC)
3222                                                 bap_setup (apriv, fid, 0x44, BAP0);
3223                                         else {
3224                                                 if (len <= sizeof(micbuf))
3225                                                         goto badmic;
3226
3227                                                 len -= sizeof(micbuf);
3228                                                 skb_trim (skb, len + hdrlen);
3229                                         }
3230                                 }
3231 #endif
3232                                 bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
3233 #ifdef MICSUPPORT
3234                                 if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
3235 badmic:
3236                                         dev_kfree_skb_irq (skb);
3237 #else
3238                                 if (0) {
3239 #endif
3240 badrx:
3241                                         OUT4500( apriv, EVACK, EV_RX);
3242                                         goto exitrx;
3243                                 }
3244                         }
3245 #ifdef WIRELESS_SPY
3246                         if (apriv->spy_data.spy_number > 0) {
3247                                 char *sa;
3248                                 struct iw_quality wstats;
3249                                 /* Prepare spy data : addr + qual */
3250                                 if (!test_bit(FLAG_802_11, &apriv->flags)) {
3251                                         sa = (char*)buffer + 6;
3252                                         bap_setup (apriv, fid, 8, BAP0);
3253                                         bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
3254                                 } else
3255                                         sa = (char*)buffer + 10;
3256                                 wstats.qual = hdr.rssi[0];
3257                                 if (apriv->rssi)
3258                                         wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
3259                                 else
3260                                         wstats.level = (hdr.rssi[1] + 321) / 2;
3261                                 wstats.updated = 3;     
3262                                 /* Update spy records */
3263                                 wireless_spy_update(dev, sa, &wstats);
3264                         }
3265 #endif /* WIRELESS_SPY */
3266                         OUT4500( apriv, EVACK, EV_RX);
3267
3268                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3269                                 skb->mac.raw = skb->data;
3270                                 skb->pkt_type = PACKET_OTHERHOST;
3271                                 skb->dev = apriv->wifidev;
3272                                 skb->protocol = htons(ETH_P_802_2);
3273                         } else {
3274                                 skb->dev = dev;
3275                                 skb->protocol = eth_type_trans(skb,dev);
3276                         }
3277                         skb->dev->last_rx = jiffies;
3278                         skb->ip_summed = CHECKSUM_NONE;
3279
3280                         netif_rx( skb );
3281                 }
3282 exitrx:
3283
3284                 /* Check to see if a packet has been transmitted */
3285                 if (  status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
3286                         int i;
3287                         int len = 0;
3288                         int index = -1;
3289
3290                         if (test_bit(FLAG_MPI,&apriv->flags)) {
3291                                 unsigned long flags;
3292
3293                                 if (status & EV_TXEXC)
3294                                         get_tx_error(apriv, -1);
3295                                 spin_lock_irqsave(&apriv->aux_lock, flags);
3296                                 if (skb_queue_len (&apriv->txq)) {
3297                                         spin_unlock_irqrestore(&apriv->aux_lock,flags);
3298                                         mpi_send_packet (dev);
3299                                 } else {
3300                                         clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
3301                                         spin_unlock_irqrestore(&apriv->aux_lock,flags);
3302                                         netif_wake_queue (dev);
3303                                 }
3304                                 OUT4500( apriv, EVACK,
3305                                         status & (EV_TX|EV_TXCPY|EV_TXEXC));
3306                                 goto exittx;
3307                         }
3308
3309                         fid = IN4500(apriv, TXCOMPLFID);
3310
3311                         for( i = 0; i < MAX_FIDS; i++ ) {
3312                                 if ( ( apriv->fids[i] & 0xffff ) == fid ) {
3313                                         len = apriv->fids[i] >> 16;
3314                                         index = i;
3315                                 }
3316                         }
3317                         if (index != -1) {
3318                                 if (status & EV_TXEXC)
3319                                         get_tx_error(apriv, index);
3320                                 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
3321                                 /* Set up to be used again */
3322                                 apriv->fids[index] &= 0xffff;
3323                                 if (index < MAX_FIDS / 2) {
3324                                         if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
3325                                                 netif_wake_queue(dev);
3326                                 } else {
3327                                         if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
3328                                                 netif_wake_queue(apriv->wifidev);
3329                                 }
3330                         } else {
3331                                 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3332                                 printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
3333                         }
3334                 }
3335 exittx:
3336                 if ( status & ~STATUS_INTS & ~IGNORE_INTS )
3337                         printk( KERN_WARNING "airo: Got weird status %x\n",
3338                                 status & ~STATUS_INTS & ~IGNORE_INTS );
3339         }
3340
3341         if (savedInterrupts)
3342                 OUT4500( apriv, EVINTEN, savedInterrupts );
3343
3344         /* done.. */
3345         return IRQ_RETVAL(handled);
3346 }
3347
3348 /*
3349  *  Routines to talk to the card
3350  */
3351
3352 /*
3353  *  This was originally written for the 4500, hence the name
3354  *  NOTE:  If use with 8bit mode and SMP bad things will happen!
3355  *         Why would some one do 8 bit IO in an SMP machine?!?
3356  */
3357 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
3358         if (test_bit(FLAG_MPI,&ai->flags))
3359                 reg <<= 1;
3360         if ( !do8bitIO )
3361                 outw( val, ai->dev->base_addr + reg );
3362         else {
3363                 outb( val & 0xff, ai->dev->base_addr + reg );
3364                 outb( val >> 8, ai->dev->base_addr + reg + 1 );
3365         }
3366 }
3367
3368 static u16 IN4500( struct airo_info *ai, u16 reg ) {
3369         unsigned short rc;
3370
3371         if (test_bit(FLAG_MPI,&ai->flags))
3372                 reg <<= 1;
3373         if ( !do8bitIO )
3374                 rc = inw( ai->dev->base_addr + reg );
3375         else {
3376                 rc = inb( ai->dev->base_addr + reg );
3377                 rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
3378         }
3379         return rc;
3380 }
3381
3382 static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
3383         int rc;
3384         Cmd cmd;
3385
3386         /* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3387          * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3388          * Note : we could try to use !netif_running(dev) in enable_MAC()
3389          * instead of this flag, but I don't trust it *within* the
3390          * open/close functions, and testing both flags together is
3391          * "cheaper" - Jean II */
3392         if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3393
3394         if (lock && down_interruptible(&ai->sem))
3395                 return -ERESTARTSYS;
3396
3397         if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3398                 memset(&cmd, 0, sizeof(cmd));
3399                 cmd.cmd = MAC_ENABLE;
3400                 rc = issuecommand(ai, &cmd, rsp);
3401                 if (rc == SUCCESS)
3402                         set_bit(FLAG_ENABLED, &ai->flags);
3403         } else
3404                 rc = SUCCESS;
3405
3406         if (lock)
3407             up(&ai->sem);
3408
3409         if (rc)
3410                 printk(KERN_ERR "%s: Cannot enable MAC, err=%d\n",
3411                         __FUNCTION__,rc);
3412         return rc;
3413 }
3414
3415 static void disable_MAC( struct airo_info *ai, int lock ) {
3416         Cmd cmd;
3417         Resp rsp;
3418
3419         if (lock && down_interruptible(&ai->sem))
3420                 return;
3421
3422         if (test_bit(FLAG_ENABLED, &ai->flags)) {
3423                 memset(&cmd, 0, sizeof(cmd));
3424                 cmd.cmd = MAC_DISABLE; // disable in case already enabled
3425                 issuecommand(ai, &cmd, &rsp);
3426                 clear_bit(FLAG_ENABLED, &ai->flags);
3427         }
3428         if (lock)
3429                 up(&ai->sem);
3430 }
3431
3432 static void enable_interrupts( struct airo_info *ai ) {
3433         /* Enable the interrupts */
3434         OUT4500( ai, EVINTEN, STATUS_INTS );
3435 }
3436
3437 static void disable_interrupts( struct airo_info *ai ) {
3438         OUT4500( ai, EVINTEN, 0 );
3439 }
3440
3441 static void mpi_receive_802_3(struct airo_info *ai)
3442 {
3443         RxFid rxd;
3444         int len = 0;
3445         struct sk_buff *skb;
3446         char *buffer;
3447 #ifdef MICSUPPORT
3448         int off = 0;
3449         MICBuffer micbuf;
3450 #endif
3451
3452         memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3453         /* Make sure we got something */
3454         if (rxd.rdy && rxd.valid == 0) {
3455                 len = rxd.len + 12;
3456                 if (len < 12 && len > 2048)
3457                         goto badrx;
3458
3459                 skb = dev_alloc_skb(len);
3460                 if (!skb) {
3461                         ai->stats.rx_dropped++;
3462                         goto badrx;
3463                 }
3464                 buffer = skb_put(skb,len);
3465 #ifdef MICSUPPORT
3466                 memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3467                 if (ai->micstats.enabled) {
3468                         memcpy(&micbuf,
3469                                 ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3470                                 sizeof(micbuf));
3471                         if (ntohs(micbuf.typelen) <= 0x05DC) {
3472                                 if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3473                                         goto badmic;
3474
3475                                 off = sizeof(micbuf);
3476                                 skb_trim (skb, len - off);
3477                         }
3478                 }
3479                 memcpy(buffer + ETH_ALEN * 2,
3480                         ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3481                         len - ETH_ALEN * 2 - off);
3482                 if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3483 badmic:
3484                         dev_kfree_skb_irq (skb);
3485                         goto badrx;
3486                 }
3487 #else
3488                 memcpy(buffer, ai->rxfids[0].virtual_host_addr, len);
3489 #endif
3490 #ifdef WIRELESS_SPY
3491                 if (ai->spy_data.spy_number > 0) {
3492                         char *sa;
3493                         struct iw_quality wstats;
3494                         /* Prepare spy data : addr + qual */
3495                         sa = buffer + ETH_ALEN;
3496                         wstats.qual = 0; /* XXX Where do I get that info from ??? */
3497                         wstats.level = 0;
3498                         wstats.updated = 0;
3499                         /* Update spy records */
3500                         wireless_spy_update(ai->dev, sa, &wstats);
3501                 }
3502 #endif /* WIRELESS_SPY */
3503
3504                 skb->dev = ai->dev;
3505                 skb->ip_summed = CHECKSUM_NONE;
3506                 skb->protocol = eth_type_trans(skb, ai->dev);
3507                 skb->dev->last_rx = jiffies;
3508                 netif_rx(skb);
3509         }
3510 badrx:
3511         if (rxd.valid == 0) {
3512                 rxd.valid = 1;
3513                 rxd.rdy = 0;
3514                 rxd.len = PKTSIZE;
3515                 memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
3516         }
3517 }
3518
3519 void mpi_receive_802_11 (struct airo_info *ai)
3520 {
3521         RxFid rxd;
3522         struct sk_buff *skb = NULL;
3523         u16 fc, len, hdrlen = 0;
3524 #pragma pack(1)
3525         struct {
3526                 u16 status, len;
3527                 u8 rssi[2];
3528                 u8 rate;
3529                 u8 freq;
3530                 u16 tmp[4];
3531         } hdr;
3532 #pragma pack()
3533         u16 gap;
3534         u16 *buffer;
3535         char *ptr = ai->rxfids[0].virtual_host_addr+4;
3536
3537         memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3538         memcpy ((char *)&hdr, ptr, sizeof(hdr));
3539         ptr += sizeof(hdr);
3540         /* Bad CRC. Ignore packet */
3541         if (le16_to_cpu(hdr.status) & 2)
3542                 hdr.len = 0;
3543         if (ai->wifidev == NULL)
3544                 hdr.len = 0;
3545         len = le16_to_cpu(hdr.len);
3546         if (len > 2312) {
3547                 printk( KERN_ERR "airo: Bad size %d\n", len );
3548                 goto badrx;
3549         }
3550         if (len == 0)
3551                 goto badrx;
3552
3553         memcpy ((char *)&fc, ptr, sizeof(fc));
3554         fc = le16_to_cpu(fc);
3555         switch (fc & 0xc) {
3556                 case 4:
3557                         if ((fc & 0xe0) == 0xc0)
3558                                 hdrlen = 10;
3559                         else
3560                                 hdrlen = 16;
3561                         break;
3562                 case 8:
3563                         if ((fc&0x300)==0x300){
3564                                 hdrlen = 30;
3565                                 break;
3566                         }
3567                 default:
3568                         hdrlen = 24;
3569         }
3570
3571         skb = dev_alloc_skb( len + hdrlen + 2 );
3572         if ( !skb ) {
3573                 ai->stats.rx_dropped++;
3574                 goto badrx;
3575         }
3576         buffer = (u16*)skb_put (skb, len + hdrlen);
3577         memcpy ((char *)buffer, ptr, hdrlen);
3578         ptr += hdrlen;
3579         if (hdrlen == 24)
3580                 ptr += 6;
3581         memcpy ((char *)&gap, ptr, sizeof(gap));
3582         ptr += sizeof(gap);
3583         gap = le16_to_cpu(gap);
3584         if (gap) {
3585                 if (gap <= 8)
3586                         ptr += gap;
3587                 else
3588                         printk(KERN_ERR
3589                             "airo: gaplen too big. Problems will follow...\n");
3590         }
3591         memcpy ((char *)buffer + hdrlen, ptr, len);
3592         ptr += len;
3593 #ifdef IW_WIRELESS_SPY    /* defined in iw_handler.h */
3594         if (ai->spy_data.spy_number > 0) {
3595                 char *sa;
3596                 struct iw_quality wstats;
3597                 /* Prepare spy data : addr + qual */
3598                 sa = (char*)buffer + 10;
3599                 wstats.qual = hdr.rssi[0];
3600                 if (ai->rssi)
3601                         wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3602                 else
3603                         wstats.level = (hdr.rssi[1] + 321) / 2;
3604                 wstats.updated = 3;
3605                 /* Update spy records */
3606                 wireless_spy_update(ai->dev, sa, &wstats);
3607         }
3608 #endif /* IW_WIRELESS_SPY */
3609         skb->mac.raw = skb->data;
3610         skb->pkt_type = PACKET_OTHERHOST;
3611         skb->dev = ai->wifidev;
3612         skb->protocol = htons(ETH_P_802_2);
3613         skb->dev->last_rx = jiffies;
3614         skb->ip_summed = CHECKSUM_NONE;
3615         netif_rx( skb );
3616 badrx:
3617         if (rxd.valid == 0) {
3618                 rxd.valid = 1;
3619                 rxd.rdy = 0;
3620                 rxd.len = PKTSIZE;
3621                 memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
3622         }
3623 }
3624
3625 static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3626 {
3627         Cmd cmd;
3628         Resp rsp;
3629         int status;
3630         int i;
3631         SsidRid mySsid;
3632         u16 lastindex;
3633         WepKeyRid wkr;
3634         int rc;
3635
3636         memset( &mySsid, 0, sizeof( mySsid ) );
3637         if (ai->flash) {
3638                 kfree (ai->flash);
3639                 ai->flash = NULL;
3640         }
3641
3642         /* The NOP is the first step in getting the card going */
3643         cmd.cmd = NOP;
3644         cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3645         if (lock && down_interruptible(&ai->sem))
3646                 return ERROR;
3647         if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
3648                 if (lock)
3649                         up(&ai->sem);
3650                 return ERROR;
3651         }
3652         disable_MAC( ai, 0);
3653
3654         // Let's figure out if we need to use the AUX port
3655         if (!test_bit(FLAG_MPI,&ai->flags)) {
3656                 cmd.cmd = CMD_ENABLEAUX;
3657                 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3658                         if (lock)
3659                                 up(&ai->sem);
3660                         printk(KERN_ERR "airo: Error checking for AUX port\n");
3661                         return ERROR;
3662                 }
3663                 if (!aux_bap || rsp.status & 0xff00) {
3664                         ai->bap_read = fast_bap_read;
3665                         printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
3666                 } else {
3667                         ai->bap_read = aux_bap_read;
3668                         printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
3669                 }
3670         }
3671         if (lock)
3672                 up(&ai->sem);
3673         if (ai->config.len == 0) {
3674                 tdsRssiRid rssi_rid;
3675                 CapabilityRid cap_rid;
3676
3677                 if (ai->APList) {
3678                         kfree(ai->APList);
3679                         ai->APList = NULL;
3680                 }
3681                 if (ai->SSID) {
3682                         kfree(ai->SSID);
3683                         ai->SSID = NULL;
3684                 }
3685                 // general configuration (read/modify/write)
3686                 status = readConfigRid(ai, lock);
3687                 if ( status != SUCCESS ) return ERROR;
3688
3689                 status = readCapabilityRid(ai, &cap_rid, lock);
3690                 if ( status != SUCCESS ) return ERROR;
3691
3692                 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3693                 if ( status == SUCCESS ) {
3694                         if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3695                                 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
3696                 }
3697                 else {
3698                         if (ai->rssi) {
3699                                 kfree(ai->rssi);
3700                                 ai->rssi = NULL;
3701                         }
3702                         if (cap_rid.softCap & 8)
3703                                 ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3704                         else
3705                                 printk(KERN_WARNING "airo: unknown received signal level scale\n");
3706                 }
3707                 ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3708                 ai->config.authType = AUTH_OPEN;
3709                 ai->config.modulation = MOD_CCK;
3710
3711 #ifdef MICSUPPORT
3712                 if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
3713                     (micsetup(ai) == SUCCESS)) {
3714                         ai->config.opmode |= MODE_MIC;
3715                         set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3716                 }
3717 #endif
3718
3719                 /* Save off the MAC */
3720                 for( i = 0; i < ETH_ALEN; i++ ) {
3721                         mac[i] = ai->config.macAddr[i];
3722                 }
3723
3724                 /* Check to see if there are any insmod configured
3725                    rates to add */
3726                 if ( rates[0] ) {
3727                         int i = 0;
3728                         memset(ai->config.rates,0,sizeof(ai->config.rates));
3729                         for( i = 0; i < 8 && rates[i]; i++ ) {
3730                                 ai->config.rates[i] = rates[i];
3731                         }
3732                 }
3733                 if ( basic_rate > 0 ) {
3734                         int i;
3735                         for( i = 0; i < 8; i++ ) {
3736                                 if ( ai->config.rates[i] == basic_rate ||
3737                                      !ai->config.rates ) {
3738                                         ai->config.rates[i] = basic_rate | 0x80;
3739                                         break;
3740                                 }
3741                         }
3742                 }
3743                 set_bit (FLAG_COMMIT, &ai->flags);
3744         }
3745
3746         /* Setup the SSIDs if present */
3747         if ( ssids[0] ) {
3748                 int i;
3749                 for( i = 0; i < 3 && ssids[i]; i++ ) {
3750                         mySsid.ssids[i].len = strlen(ssids[i]);
3751                         if ( mySsid.ssids[i].len > 32 )
3752                                 mySsid.ssids[i].len = 32;
3753                         memcpy(mySsid.ssids[i].ssid, ssids[i],
3754                                mySsid.ssids[i].len);
3755                 }
3756                 mySsid.len = sizeof(mySsid);
3757         }
3758
3759         status = writeConfigRid(ai, lock);
3760         if ( status != SUCCESS ) return ERROR;
3761
3762         /* Set up the SSID list */
3763         if ( ssids[0] ) {
3764                 status = writeSsidRid(ai, &mySsid, lock);
3765                 if ( status != SUCCESS ) return ERROR;
3766         }
3767
3768         status = enable_MAC(ai, &rsp, lock);
3769         if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
3770                 printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
3771                 return ERROR;
3772         }
3773
3774         /* Grab the initial wep key, we gotta save it for auto_wep */
3775         rc = readWepKeyRid(ai, &wkr, 1, lock);
3776         if (rc == SUCCESS) do {
3777                 lastindex = wkr.kindex;
3778                 if (wkr.kindex == 0xffff) {
3779                         ai->defindex = wkr.mac[0];
3780                 }
3781                 rc = readWepKeyRid(ai, &wkr, 0, lock);
3782         } while(lastindex != wkr.kindex);
3783
3784         if (auto_wep) {
3785                 ai->expires = RUN_AT(3*HZ);
3786                 wake_up_interruptible(&ai->thr_wait);
3787         }
3788
3789         return SUCCESS;
3790 }
3791
3792 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3793         // Im really paranoid about letting it run forever!
3794         int max_tries = 600000;
3795
3796         if (IN4500(ai, EVSTAT) & EV_CMD)
3797                 OUT4500(ai, EVACK, EV_CMD);
3798
3799         OUT4500(ai, PARAM0, pCmd->parm0);
3800         OUT4500(ai, PARAM1, pCmd->parm1);
3801         OUT4500(ai, PARAM2, pCmd->parm2);
3802         OUT4500(ai, COMMAND, pCmd->cmd);
3803
3804         while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3805                 if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3806                         // PC4500 didn't notice command, try again
3807                         OUT4500(ai, COMMAND, pCmd->cmd);
3808                 if (!in_atomic() && (max_tries & 255) == 0)
3809                         schedule();
3810         }
3811
3812         if ( max_tries == -1 ) {
3813                 printk( KERN_ERR
3814                         "airo: Max tries exceeded when issueing command\n" );
3815                 if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3816                         OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3817                 return ERROR;
3818         }
3819
3820         // command completed
3821         pRsp->status = IN4500(ai, STATUS);
3822         pRsp->rsp0 = IN4500(ai, RESP0);
3823         pRsp->rsp1 = IN4500(ai, RESP1);
3824         pRsp->rsp2 = IN4500(ai, RESP2);
3825         if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) {
3826                 printk (KERN_ERR "airo: cmd= %x\n", pCmd->cmd);
3827                 printk (KERN_ERR "airo: status= %x\n", pRsp->status);
3828                 printk (KERN_ERR "airo: Rsp0= %x\n", pRsp->rsp0);
3829                 printk (KERN_ERR "airo: Rsp1= %x\n", pRsp->rsp1);
3830                 printk (KERN_ERR "airo: Rsp2= %x\n", pRsp->rsp2);
3831         }
3832
3833         // clear stuck command busy if necessary
3834         if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
3835                 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3836         }
3837         // acknowledge processing the status/response
3838         OUT4500(ai, EVACK, EV_CMD);
3839
3840         return SUCCESS;
3841 }
3842
3843 /* Sets up the bap to start exchange data.  whichbap should
3844  * be one of the BAP0 or BAP1 defines.  Locks should be held before
3845  * calling! */
3846 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3847 {
3848         int timeout = 50;
3849         int max_tries = 3;
3850
3851         OUT4500(ai, SELECT0+whichbap, rid);
3852         OUT4500(ai, OFFSET0+whichbap, offset);
3853         while (1) {
3854                 int status = IN4500(ai, OFFSET0+whichbap);
3855                 if (status & BAP_BUSY) {
3856                         /* This isn't really a timeout, but its kinda
3857                            close */
3858                         if (timeout--) {
3859                                 continue;
3860                         }
3861                 } else if ( status & BAP_ERR ) {
3862                         /* invalid rid or offset */
3863                         printk( KERN_ERR "airo: BAP error %x %d\n",
3864                                 status, whichbap );
3865                         return ERROR;
3866                 } else if (status & BAP_DONE) { // success
3867                         return SUCCESS;
3868                 }
3869                 if ( !(max_tries--) ) {
3870                         printk( KERN_ERR
3871                                 "airo: BAP setup error too many retries\n" );
3872                         return ERROR;
3873                 }
3874                 // -- PC4500 missed it, try again
3875                 OUT4500(ai, SELECT0+whichbap, rid);
3876                 OUT4500(ai, OFFSET0+whichbap, offset);
3877                 timeout = 50;
3878         }
3879 }
3880
3881 /* should only be called by aux_bap_read.  This aux function and the
3882    following use concepts not documented in the developers guide.  I
3883    got them from a patch given to my by Aironet */
3884 static u16 aux_setup(struct airo_info *ai, u16 page,
3885                      u16 offset, u16 *len)
3886 {
3887         u16 next;
3888
3889         OUT4500(ai, AUXPAGE, page);
3890         OUT4500(ai, AUXOFF, 0);
3891         next = IN4500(ai, AUXDATA);
3892         *len = IN4500(ai, AUXDATA)&0xff;
3893         if (offset != 4) OUT4500(ai, AUXOFF, offset);
3894         return next;
3895 }
3896
3897 /* requires call to bap_setup() first */
3898 static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
3899                         int bytelen, int whichbap)
3900 {
3901         u16 len;
3902         u16 page;
3903         u16 offset;
3904         u16 next;
3905         int words;
3906         int i;
3907         unsigned long flags;
3908
3909         spin_lock_irqsave(&ai->aux_lock, flags);
3910         page = IN4500(ai, SWS0+whichbap);
3911         offset = IN4500(ai, SWS2+whichbap);
3912         next = aux_setup(ai, page, offset, &len);
3913         words = (bytelen+1)>>1;
3914
3915         for (i=0; i<words;) {
3916                 int count;
3917                 count = (len>>1) < (words-i) ? (len>>1) : (words-i);
3918                 if ( !do8bitIO )
3919                         insw( ai->dev->base_addr+DATA0+whichbap,
3920                               pu16Dst+i,count );
3921                 else
3922                         insb( ai->dev->base_addr+DATA0+whichbap,
3923                               pu16Dst+i, count << 1 );
3924                 i += count;
3925                 if (i<words) {
3926                         next = aux_setup(ai, next, 4, &len);
3927                 }
3928         }
3929         spin_unlock_irqrestore(&ai->aux_lock, flags);
3930         return SUCCESS;
3931 }
3932
3933
3934 /* requires call to bap_setup() first */
3935 static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
3936                          int bytelen, int whichbap)
3937 {
3938         bytelen = (bytelen + 1) & (~1); // round up to even value
3939         if ( !do8bitIO )
3940                 insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
3941         else
3942                 insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
3943         return SUCCESS;
3944 }
3945
3946 /* requires call to bap_setup() first */
3947 static int bap_write(struct airo_info *ai, const u16 *pu16Src,
3948                      int bytelen, int whichbap)
3949 {
3950         bytelen = (bytelen + 1) & (~1); // round up to even value
3951         if ( !do8bitIO )
3952                 outsw( ai->dev->base_addr+DATA0+whichbap,
3953                        pu16Src, bytelen>>1 );
3954         else
3955                 outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
3956         return SUCCESS;
3957 }
3958
3959 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
3960 {
3961         Cmd cmd; /* for issuing commands */
3962         Resp rsp; /* response from commands */
3963         u16 status;
3964
3965         memset(&cmd, 0, sizeof(cmd));
3966         cmd.cmd = accmd;
3967         cmd.parm0 = rid;
3968         status = issuecommand(ai, &cmd, &rsp);
3969         if (status != 0) return status;
3970         if ( (rsp.status & 0x7F00) != 0) {
3971                 return (accmd << 8) + (rsp.rsp0 & 0xFF);
3972         }
3973         return 0;
3974 }
3975
3976 /*  Note, that we are using BAP1 which is also used by transmit, so
3977  *  we must get a lock. */
3978 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
3979 {
3980         u16 status;
3981         int rc = SUCCESS;
3982
3983         if (lock) {
3984                 if (down_interruptible(&ai->sem))
3985                         return ERROR;
3986         }
3987         if (test_bit(FLAG_MPI,&ai->flags)) {
3988                 Cmd cmd;
3989                 Resp rsp;
3990
3991                 memset(&cmd, 0, sizeof(cmd));
3992                 memset(&rsp, 0, sizeof(rsp));
3993                 ai->config_desc.rid_desc.valid = 1;
3994                 ai->config_desc.rid_desc.len = RIDSIZE;
3995                 ai->config_desc.rid_desc.rid = 0;
3996                 ai->config_desc.rid_desc.host_addr = ai->ridbus;
3997
3998                 cmd.cmd = CMD_ACCESS;
3999                 cmd.parm0 = rid;
4000
4001                 memcpy((char *)ai->config_desc.card_ram_off,
4002                         (char *)&ai->config_desc.rid_desc, sizeof(Rid));
4003
4004                 rc = issuecommand(ai, &cmd, &rsp);
4005
4006                 if (rsp.status & 0x7f00)
4007                         rc = rsp.rsp0;
4008                 if (!rc)
4009                         memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
4010                 goto done;
4011         } else {
4012                 if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4013                         rc = status;
4014                         goto done;
4015                 }
4016                 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4017                         rc = ERROR;
4018                         goto done;
4019                 }
4020                 // read the rid length field
4021                 bap_read(ai, pBuf, 2, BAP1);
4022                 // length for remaining part of rid
4023                 len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
4024
4025                 if ( len <= 2 ) {
4026                         printk( KERN_ERR
4027                         "airo: Rid %x has a length of %d which is too short\n",
4028                                 (int)rid, (int)len );
4029                         rc = ERROR;
4030                         goto done;
4031                 }
4032                 // read remainder of the rid
4033                 rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
4034         }
4035 done:
4036         if (lock)
4037                 up(&ai->sem);
4038         return rc;
4039 }
4040
4041 /*  Note, that we are using BAP1 which is also used by transmit, so
4042  *  make sure this isnt called when a transmit is happening */
4043 static int PC4500_writerid(struct airo_info *ai, u16 rid,
4044                            const void *pBuf, int len, int lock)
4045 {
4046         u16 status;
4047         int rc = SUCCESS;
4048
4049         *(u16*)pBuf = cpu_to_le16((u16)len);
4050
4051         if (lock) {
4052                 if (down_interruptible(&ai->sem))
4053                         return ERROR;
4054         }
4055         if (test_bit(FLAG_MPI,&ai->flags)) {
4056                 Cmd cmd;
4057                 Resp rsp;
4058
4059                 if (test_bit(FLAG_ENABLED, &ai->flags))
4060                         printk(KERN_ERR
4061                                 "%s: MAC should be disabled (rid=%04x)\n",
4062                                 __FUNCTION__, rid);
4063                 memset(&cmd, 0, sizeof(cmd));
4064                 memset(&rsp, 0, sizeof(rsp));
4065
4066                 ai->config_desc.rid_desc.valid = 1;
4067                 ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4068                 ai->config_desc.rid_desc.rid = 0;
4069
4070                 cmd.cmd = CMD_WRITERID;
4071                 cmd.parm0 = rid;
4072
4073                 memcpy((char *)ai->config_desc.card_ram_off,
4074                         (char *)&ai->config_desc.rid_desc, sizeof(Rid));
4075
4076                 if (len < 4 || len > 2047) {
4077                         printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len);
4078                         rc = -1;
4079                 } else {
4080                         memcpy((char *)ai->config_desc.virtual_host_addr,
4081                                 pBuf, len);
4082
4083                         rc = issuecommand(ai, &cmd, &rsp);
4084                         if ((rc & 0xff00) != 0) {
4085                                 printk(KERN_ERR "%s: Write rid Error %d\n",
4086                                         __FUNCTION__,rc);
4087                                 printk(KERN_ERR "%s: Cmd=%04x\n",
4088                                                 __FUNCTION__,cmd.cmd);
4089                         }
4090
4091                         if ((rsp.status & 0x7f00))
4092                                 rc = rsp.rsp0;
4093                 }
4094         } else {
4095                 // --- first access so that we can write the rid data
4096                 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4097                         rc = status;
4098                         goto done;
4099                 }
4100                 // --- now write the rid data
4101                 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4102                         rc = ERROR;
4103                         goto done;
4104                 }
4105                 bap_write(ai, pBuf, len, BAP1);
4106                 // ---now commit the rid data
4107                 rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4108         }
4109 done:
4110         if (lock)
4111                 up(&ai->sem);
4112         return rc;
4113 }
4114
4115 /* Allocates a FID to be used for transmitting packets.  We only use
4116    one for now. */
4117 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4118 {
4119         unsigned int loop = 3000;
4120         Cmd cmd;
4121         Resp rsp;
4122         u16 txFid;
4123         u16 txControl;
4124
4125         cmd.cmd = CMD_ALLOCATETX;
4126         cmd.parm0 = lenPayload;
4127         if (down_interruptible(&ai->sem))
4128                 return ERROR;
4129         if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
4130                 txFid = ERROR;
4131                 goto done;
4132         }
4133         if ( (rsp.status & 0xFF00) != 0) {
4134                 txFid = ERROR;
4135                 goto done;
4136         }
4137         /* wait for the allocate event/indication
4138          * It makes me kind of nervous that this can just sit here and spin,
4139          * but in practice it only loops like four times. */
4140         while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4141         if (!loop) {
4142                 txFid = ERROR;
4143                 goto done;
4144         }
4145
4146         // get the allocated fid and acknowledge
4147         txFid = IN4500(ai, TXALLOCFID);
4148         OUT4500(ai, EVACK, EV_ALLOC);
4149
4150         /*  The CARD is pretty cool since it converts the ethernet packet
4151          *  into 802.11.  Also note that we don't release the FID since we
4152          *  will be using the same one over and over again. */
4153         /*  We only have to setup the control once since we are not
4154          *  releasing the fid. */
4155         if (raw)
4156                 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4157                         | TXCTL_ETHERNET | TXCTL_NORELEASE);
4158         else
4159                 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4160                         | TXCTL_ETHERNET | TXCTL_NORELEASE);
4161         if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4162                 txFid = ERROR;
4163         else
4164                 bap_write(ai, &txControl, sizeof(txControl), BAP1);
4165
4166 done:
4167         up(&ai->sem);
4168
4169         return txFid;
4170 }
4171
4172 /* In general BAP1 is dedicated to transmiting packets.  However,
4173    since we need a BAP when accessing RIDs, we also use BAP1 for that.
4174    Make sure the BAP1 spinlock is held when this is called. */
4175 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
4176 {
4177         u16 payloadLen;
4178         Cmd cmd;
4179         Resp rsp;
4180         int miclen = 0;
4181         u16 txFid = len;
4182         MICBuffer pMic;
4183
4184         len >>= 16;
4185
4186         if (len <= ETH_ALEN * 2) {
4187                 printk( KERN_WARNING "Short packet %d\n", len );
4188                 return ERROR;
4189         }
4190         len -= ETH_ALEN * 2;
4191
4192 #ifdef MICSUPPORT
4193         if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
4194             (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
4195                 if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
4196                         return ERROR;
4197                 miclen = sizeof(pMic);
4198         }
4199 #endif
4200
4201         // packet is destination[6], source[6], payload[len-12]
4202         // write the payload length and dst/src/payload
4203         if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4204         /* The hardware addresses aren't counted as part of the payload, so
4205          * we have to subtract the 12 bytes for the addresses off */
4206         payloadLen = cpu_to_le16(len + miclen);
4207         bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4208         bap_write(ai, (const u16*)pPacket, sizeof(etherHead), BAP1);
4209         if (miclen)
4210                 bap_write(ai, (const u16*)&pMic, miclen, BAP1);
4211         bap_write(ai, (const u16*)(pPacket + sizeof(etherHead)), len, BAP1);
4212         // issue the transmit command
4213         memset( &cmd, 0, sizeof( cmd ) );
4214         cmd.cmd = CMD_TRANSMIT;
4215         cmd.parm0 = txFid;
4216         if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4217         if ( (rsp.status & 0xFF00) != 0) return ERROR;
4218         return SUCCESS;
4219 }
4220
4221 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
4222 {
4223         u16 fc, payloadLen;
4224         Cmd cmd;
4225         Resp rsp;
4226         int hdrlen;
4227         struct {
4228                 u8 addr4[ETH_ALEN];
4229                 u16 gaplen;
4230                 u8 gap[6];
4231         } gap;
4232         u16 txFid = len;
4233         len >>= 16;
4234         gap.gaplen = 6;
4235
4236         fc = le16_to_cpu(*(const u16*)pPacket);
4237         switch (fc & 0xc) {
4238                 case 4:
4239                         if ((fc & 0xe0) == 0xc0)
4240                                 hdrlen = 10;
4241                         else
4242                                 hdrlen = 16;
4243                         break;
4244                 case 8:
4245                         if ((fc&0x300)==0x300){
4246                                 hdrlen = 30;
4247                                 break;
4248                         }
4249                 default:
4250                         hdrlen = 24;
4251         }
4252
4253         if (len < hdrlen) {
4254                 printk( KERN_WARNING "Short packet %d\n", len );
4255                 return ERROR;
4256         }
4257
4258         /* packet is 802.11 header +  payload
4259          * write the payload length and dst/src/payload */
4260         if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4261         /* The 802.11 header aren't counted as part of the payload, so
4262          * we have to subtract the header bytes off */
4263         payloadLen = cpu_to_le16(len-hdrlen);
4264         bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4265         if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4266         bap_write(ai, (const u16*)pPacket, hdrlen, BAP1);
4267         bap_write(ai, hdrlen == 30 ?
4268                 (const u16*)&gap.gaplen : (const u16*)&gap, 38 - hdrlen, BAP1);
4269
4270         bap_write(ai, (const u16*)(pPacket + hdrlen), len - hdrlen, BAP1);
4271         // issue the transmit command
4272         memset( &cmd, 0, sizeof( cmd ) );
4273         cmd.cmd = CMD_TRANSMIT;
4274         cmd.parm0 = txFid;
4275         if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4276         if ( (rsp.status & 0xFF00) != 0) return ERROR;
4277         return SUCCESS;
4278 }
4279
4280 /*
4281  *  This is the proc_fs routines.  It is a bit messier than I would
4282  *  like!  Feel free to clean it up!
4283  */
4284
4285 static ssize_t proc_read( struct file *file,
4286                           char __user *buffer,
4287                           size_t len,
4288                           loff_t *offset);
4289
4290 static ssize_t proc_write( struct file *file,
4291                            const char __user *buffer,
4292                            size_t len,
4293                            loff_t *offset );
4294 static int proc_close( struct inode *inode, struct file *file );
4295
4296 static int proc_stats_open( struct inode *inode, struct file *file );
4297 static int proc_statsdelta_open( struct inode *inode, struct file *file );
4298 static int proc_status_open( struct inode *inode, struct file *file );
4299 static int proc_SSID_open( struct inode *inode, struct file *file );
4300 static int proc_APList_open( struct inode *inode, struct file *file );
4301 static int proc_BSSList_open( struct inode *inode, struct file *file );
4302 static int proc_config_open( struct inode *inode, struct file *file );
4303 static int proc_wepkey_open( struct inode *inode, struct file *file );
4304
4305 static struct file_operations proc_statsdelta_ops = {
4306         .read           = proc_read,
4307         .open           = proc_statsdelta_open,
4308         .release        = proc_close
4309 };
4310
4311 static struct file_operations proc_stats_ops = {
4312         .read           = proc_read,
4313         .open           = proc_stats_open,
4314         .release        = proc_close
4315 };
4316
4317 static struct file_operations proc_status_ops = {
4318         .read           = proc_read,
4319         .open           = proc_status_open,
4320         .release        = proc_close
4321 };
4322
4323 static struct file_operations proc_SSID_ops = {
4324         .read           = proc_read,
4325         .write          = proc_write,
4326         .open           = proc_SSID_open,
4327         .release        = proc_close
4328 };
4329
4330 static struct file_operations proc_BSSList_ops = {
4331         .read           = proc_read,
4332         .write          = proc_write,
4333         .open           = proc_BSSList_open,
4334         .release        = proc_close
4335 };
4336
4337 static struct file_operations proc_APList_ops = {
4338         .read           = proc_read,
4339         .write          = proc_write,
4340         .open           = proc_APList_open,
4341         .release        = proc_close
4342 };
4343
4344 static struct file_operations proc_config_ops = {
4345         .read           = proc_read,
4346         .write          = proc_write,
4347         .open           = proc_config_open,
4348         .release        = proc_close
4349 };
4350
4351 static struct file_operations proc_wepkey_ops = {
4352         .read           = proc_read,
4353         .write          = proc_write,
4354         .open           = proc_wepkey_open,
4355         .release        = proc_close
4356 };
4357
4358 static struct proc_dir_entry *airo_entry;
4359
4360 struct proc_data {
4361         int release_buffer;
4362         int readlen;
4363         char *rbuffer;
4364         int writelen;
4365         int maxwritelen;
4366         char *wbuffer;
4367         void (*on_close) (struct inode *, struct file *);
4368 };
4369
4370 #ifndef SETPROC_OPS
4371 #define SETPROC_OPS(entry, ops) (entry)->proc_fops = &(ops)
4372 #endif
4373
4374 static int setup_proc_entry( struct net_device *dev,
4375                              struct airo_info *apriv ) {
4376         struct proc_dir_entry *entry;
4377         /* First setup the device directory */
4378         strcpy(apriv->proc_name,dev->name);
4379         apriv->proc_entry = create_proc_entry(apriv->proc_name,
4380                                               S_IFDIR|airo_perm,
4381                                               airo_entry);
4382         apriv->proc_entry->uid = proc_uid;
4383         apriv->proc_entry->gid = proc_gid;
4384         apriv->proc_entry->owner = THIS_MODULE;
4385
4386         /* Setup the StatsDelta */
4387         entry = create_proc_entry("StatsDelta",
4388                                   S_IFREG | (S_IRUGO&proc_perm),
4389                                   apriv->proc_entry);
4390         entry->uid = proc_uid;
4391         entry->gid = proc_gid;
4392         entry->data = dev;
4393         entry->owner = THIS_MODULE;
4394         SETPROC_OPS(entry, proc_statsdelta_ops);
4395
4396         /* Setup the Stats */
4397         entry = create_proc_entry("Stats",
4398                                   S_IFREG | (S_IRUGO&proc_perm),
4399                                   apriv->proc_entry);
4400         entry->uid = proc_uid;
4401         entry->gid = proc_gid;
4402         entry->data = dev;
4403         entry->owner = THIS_MODULE;
4404         SETPROC_OPS(entry, proc_stats_ops);
4405
4406         /* Setup the Status */
4407         entry = create_proc_entry("Status",
4408                                   S_IFREG | (S_IRUGO&proc_perm),
4409                                   apriv->proc_entry);
4410         entry->uid = proc_uid;
4411         entry->gid = proc_gid;
4412         entry->data = dev;
4413         entry->owner = THIS_MODULE;
4414         SETPROC_OPS(entry, proc_status_ops);
4415
4416         /* Setup the Config */
4417         entry = create_proc_entry("Config",
4418                                   S_IFREG | proc_perm,
4419                                   apriv->proc_entry);
4420         entry->uid = proc_uid;
4421         entry->gid = proc_gid;
4422         entry->data = dev;
4423         entry->owner = THIS_MODULE;
4424         SETPROC_OPS(entry, proc_config_ops);
4425
4426         /* Setup the SSID */
4427         entry = create_proc_entry("SSID",
4428                                   S_IFREG | proc_perm,
4429                                   apriv->proc_entry);
4430         entry->uid = proc_uid;
4431         entry->gid = proc_gid;
4432         entry->data = dev;
4433         entry->owner = THIS_MODULE;
4434         SETPROC_OPS(entry, proc_SSID_ops);
4435
4436         /* Setup the APList */
4437         entry = create_proc_entry("APList",
4438                                   S_IFREG | proc_perm,
4439                                   apriv->proc_entry);
4440         entry->uid = proc_uid;
4441         entry->gid = proc_gid;
4442         entry->data = dev;
4443         entry->owner = THIS_MODULE;
4444         SETPROC_OPS(entry, proc_APList_ops);
4445
4446         /* Setup the BSSList */
4447         entry = create_proc_entry("BSSList",
4448                                   S_IFREG | proc_perm,
4449                                   apriv->proc_entry);
4450         entry->uid = proc_uid;
4451         entry->gid = proc_gid;
4452         entry->data = dev;
4453         entry->owner = THIS_MODULE;
4454         SETPROC_OPS(entry, proc_BSSList_ops);
4455
4456         /* Setup the WepKey */
4457         entry = create_proc_entry("WepKey",
4458                                   S_IFREG | proc_perm,
4459                                   apriv->proc_entry);
4460         entry->uid = proc_uid;
4461         entry->gid = proc_gid;
4462         entry->data = dev;
4463         entry->owner = THIS_MODULE;
4464         SETPROC_OPS(entry, proc_wepkey_ops);
4465
4466         return 0;
4467 }
4468
4469 static int takedown_proc_entry( struct net_device *dev,
4470                                 struct airo_info *apriv ) {
4471         if ( !apriv->proc_entry->namelen ) return 0;
4472         remove_proc_entry("Stats",apriv->proc_entry);
4473         remove_proc_entry("StatsDelta",apriv->proc_entry);
4474         remove_proc_entry("Status",apriv->proc_entry);
4475         remove_proc_entry("Config",apriv->proc_entry);
4476         remove_proc_entry("SSID",apriv->proc_entry);
4477         remove_proc_entry("APList",apriv->proc_entry);
4478         remove_proc_entry("BSSList",apriv->proc_entry);
4479         remove_proc_entry("WepKey",apriv->proc_entry);
4480         remove_proc_entry(apriv->proc_name,airo_entry);
4481         return 0;
4482 }
4483
4484 /*
4485  *  What we want from the proc_fs is to be able to efficiently read
4486  *  and write the configuration.  To do this, we want to read the
4487  *  configuration when the file is opened and write it when the file is
4488  *  closed.  So basically we allocate a read buffer at open and fill it
4489  *  with data, and allocate a write buffer and read it at close.
4490  */
4491
4492 /*
4493  *  The read routine is generic, it relies on the preallocated rbuffer
4494  *  to supply the data.
4495  */
4496 static ssize_t proc_read( struct file *file,
4497                           char __user *buffer,
4498                           size_t len,
4499                           loff_t *offset )
4500 {
4501         loff_t pos = *offset;
4502         struct proc_data *priv = (struct proc_data*)file->private_data;
4503
4504         if (!priv->rbuffer)
4505                 return -EINVAL;
4506
4507         if (pos < 0)
4508                 return -EINVAL;
4509         if (pos >= priv->readlen)
4510                 return 0;
4511         if (len > priv->readlen - pos)
4512                 len = priv->readlen - pos;
4513         if (copy_to_user(buffer, priv->rbuffer + pos, len))
4514                 return -EFAULT;
4515         *offset = pos + len;
4516         return len;
4517 }
4518
4519 /*
4520  *  The write routine is generic, it fills in a preallocated rbuffer
4521  *  to supply the data.
4522  */
4523 static ssize_t proc_write( struct file *file,
4524                            const char __user *buffer,
4525                            size_t len,
4526                            loff_t *offset )
4527 {
4528         loff_t pos = *offset;
4529         struct proc_data *priv = (struct proc_data*)file->private_data;
4530
4531         if (!priv->wbuffer)
4532                 return -EINVAL;
4533
4534         if (pos < 0)
4535                 return -EINVAL;
4536         if (pos >= priv->maxwritelen)
4537                 return 0;
4538         if (len > priv->maxwritelen - pos)
4539                 len = priv->maxwritelen - pos;
4540         if (copy_from_user(priv->wbuffer + pos, buffer, len))
4541                 return -EFAULT;
4542         if ( pos + len > priv->writelen )
4543                 priv->writelen = len + file->f_pos;
4544         *offset = pos + len;
4545         return len;
4546 }
4547
4548 static int proc_status_open( struct inode *inode, struct file *file ) {
4549         struct proc_data *data;
4550         struct proc_dir_entry *dp = PDE(inode);
4551         struct net_device *dev = dp->data;
4552         struct airo_info *apriv = dev->priv;
4553         CapabilityRid cap_rid;
4554         StatusRid status_rid;
4555         int i;
4556
4557         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4558                 return -ENOMEM;
4559         memset(file->private_data, 0, sizeof(struct proc_data));
4560         data = (struct proc_data *)file->private_data;
4561         if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4562                 kfree (file->private_data);
4563                 file->private_data = NULL;
4564                 return -ENOMEM;
4565         }
4566
4567         readStatusRid(apriv, &status_rid, 1);
4568         readCapabilityRid(apriv, &cap_rid, 1);
4569
4570         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4571                     status_rid.mode & 1 ? "CFG ": "",
4572                     status_rid.mode & 2 ? "ACT ": "",
4573                     status_rid.mode & 0x10 ? "SYN ": "",
4574                     status_rid.mode & 0x20 ? "LNK ": "",
4575                     status_rid.mode & 0x40 ? "LEAP ": "",
4576                     status_rid.mode & 0x80 ? "PRIV ": "",
4577                     status_rid.mode & 0x100 ? "KEY ": "",
4578                     status_rid.mode & 0x200 ? "WEP ": "",
4579                     status_rid.mode & 0x8000 ? "ERR ": "");
4580         sprintf( data->rbuffer+i, "Mode: %x\n"
4581                  "Signal Strength: %d\n"
4582                  "Signal Quality: %d\n"
4583                  "SSID: %-.*s\n"
4584                  "AP: %-.16s\n"
4585                  "Freq: %d\n"
4586                  "BitRate: %dmbs\n"
4587                  "Driver Version: %s\n"
4588                  "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4589                  "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4590                  "Software Version: %x\nSoftware Subversion: %x\n"
4591                  "Boot block version: %x\n",
4592                  (int)status_rid.mode,
4593                  (int)status_rid.normalizedSignalStrength,
4594                  (int)status_rid.signalQuality,
4595                  (int)status_rid.SSIDlen,
4596                  status_rid.SSID,
4597                  status_rid.apName,
4598                  (int)status_rid.channel,
4599                  (int)status_rid.currentXmitRate/2,
4600                  version,
4601                  cap_rid.prodName,
4602                  cap_rid.manName,
4603                  cap_rid.prodVer,
4604                  cap_rid.radioType,
4605                  cap_rid.country,
4606                  cap_rid.hardVer,
4607                  (int)cap_rid.softVer,
4608                  (int)cap_rid.softSubVer,
4609                  (int)cap_rid.bootBlockVer );
4610         data->readlen = strlen( data->rbuffer );
4611         return 0;
4612 }
4613
4614 static int proc_stats_rid_open(struct inode*, struct file*, u16);
4615 static int proc_statsdelta_open( struct inode *inode,
4616                                  struct file *file ) {
4617         if (file->f_mode&FMODE_WRITE) {
4618                 return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4619         }
4620         return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4621 }
4622
4623 static int proc_stats_open( struct inode *inode, struct file *file ) {
4624         return proc_stats_rid_open(inode, file, RID_STATS);
4625 }
4626
4627 static int proc_stats_rid_open( struct inode *inode,
4628                                 struct file *file,
4629                                 u16 rid ) {
4630         struct proc_data *data;
4631         struct proc_dir_entry *dp = PDE(inode);
4632         struct net_device *dev = dp->data;
4633         struct airo_info *apriv = dev->priv;
4634         StatsRid stats;
4635         int i, j;
4636         u32 *vals = stats.vals;
4637
4638         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4639                 return -ENOMEM;
4640         memset(file->private_data, 0, sizeof(struct proc_data));
4641         data = (struct proc_data *)file->private_data;
4642         if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4643                 kfree (file->private_data);
4644                 file->private_data = NULL;
4645                 return -ENOMEM;
4646         }
4647
4648         readStatsRid(apriv, &stats, rid, 1);
4649
4650         j = 0;
4651         for(i=0; statsLabels[i]!=(char *)-1 &&
4652                     i*4<stats.len; i++){
4653                 if (!statsLabels[i]) continue;
4654                 if (j+strlen(statsLabels[i])+16>4096) {
4655                         printk(KERN_WARNING
4656                                "airo: Potentially disasterous buffer overflow averted!\n");
4657                         break;
4658                 }
4659                 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]);
4660         }
4661         if (i*4>=stats.len){
4662                 printk(KERN_WARNING
4663                        "airo: Got a short rid\n");
4664         }
4665         data->readlen = j;
4666         return 0;
4667 }
4668
4669 static int get_dec_u16( char *buffer, int *start, int limit ) {
4670         u16 value;
4671         int valid = 0;
4672         for( value = 0; buffer[*start] >= '0' &&
4673                      buffer[*start] <= '9' &&
4674                      *start < limit; (*start)++ ) {
4675                 valid = 1;
4676                 value *= 10;
4677                 value += buffer[*start] - '0';
4678         }
4679         if ( !valid ) return -1;
4680         return value;
4681 }
4682
4683 static int airo_config_commit(struct net_device *dev,
4684                               struct iw_request_info *info, void *zwrq,
4685                               char *extra);
4686
4687 static void proc_config_on_close( struct inode *inode, struct file *file ) {
4688         struct proc_data *data = file->private_data;
4689         struct proc_dir_entry *dp = PDE(inode);
4690         struct net_device *dev = dp->data;
4691         struct airo_info *ai = dev->priv;
4692         char *line;
4693
4694         if ( !data->writelen ) return;
4695
4696         readConfigRid(ai, 1);
4697         set_bit (FLAG_COMMIT, &ai->flags);
4698
4699         line = data->wbuffer;
4700         while( line[0] ) {
4701 /*** Mode processing */
4702                 if ( !strncmp( line, "Mode: ", 6 ) ) {
4703                         line += 6;
4704                         if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
4705                                         set_bit (FLAG_RESET, &ai->flags);
4706                         ai->config.rmode &= 0xfe00;
4707                         clear_bit (FLAG_802_11, &ai->flags);
4708                         ai->config.opmode &= 0xFF00;
4709                         ai->config.scanMode = SCANMODE_ACTIVE;
4710                         if ( line[0] == 'a' ) {
4711                                 ai->config.opmode |= 0;
4712                         } else {
4713                                 ai->config.opmode |= 1;
4714                                 if ( line[0] == 'r' ) {
4715                                         ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4716                                         ai->config.scanMode = SCANMODE_PASSIVE;
4717                                         set_bit (FLAG_802_11, &ai->flags);
4718                                 } else if ( line[0] == 'y' ) {
4719                                         ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4720                                         ai->config.scanMode = SCANMODE_PASSIVE;
4721                                         set_bit (FLAG_802_11, &ai->flags);
4722                                 } else if ( line[0] == 'l' )
4723                                         ai->config.rmode |= RXMODE_LANMON;
4724                         }
4725                         set_bit (FLAG_COMMIT, &ai->flags);
4726                 }
4727
4728 /*** Radio status */
4729                 else if (!strncmp(line,"Radio: ", 7)) {
4730                         line += 7;
4731                         if (!strncmp(line,"off",3)) {
4732                                 set_bit (FLAG_RADIO_OFF, &ai->flags);
4733                         } else {
4734                                 clear_bit (FLAG_RADIO_OFF, &ai->flags);
4735                         }
4736                 }
4737 /*** NodeName processing */
4738                 else if ( !strncmp( line, "NodeName: ", 10 ) ) {
4739                         int j;
4740
4741                         line += 10;
4742                         memset( ai->config.nodeName, 0, 16 );
4743 /* Do the name, assume a space between the mode and node name */
4744                         for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
4745                                 ai->config.nodeName[j] = line[j];
4746                         }
4747                         set_bit (FLAG_COMMIT, &ai->flags);
4748                 }
4749
4750 /*** PowerMode processing */
4751                 else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
4752                         line += 11;
4753                         if ( !strncmp( line, "PSPCAM", 6 ) ) {
4754                                 ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4755                                 set_bit (FLAG_COMMIT, &ai->flags);
4756                         } else if ( !strncmp( line, "PSP", 3 ) ) {
4757                                 ai->config.powerSaveMode = POWERSAVE_PSP;
4758                                 set_bit (FLAG_COMMIT, &ai->flags);
4759                         } else {
4760                                 ai->config.powerSaveMode = POWERSAVE_CAM;
4761                                 set_bit (FLAG_COMMIT, &ai->flags);
4762                         }
4763                 } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
4764                         int v, i = 0, k = 0; /* i is index into line,
4765                                                 k is index to rates */
4766
4767                         line += 11;
4768                         while((v = get_dec_u16(line, &i, 3))!=-1) {
4769                                 ai->config.rates[k++] = (u8)v;
4770                                 line += i + 1;
4771                                 i = 0;
4772                         }
4773                         set_bit (FLAG_COMMIT, &ai->flags);
4774                 } else if ( !strncmp( line, "Channel: ", 9 ) ) {
4775                         int v, i = 0;
4776                         line += 9;
4777                         v = get_dec_u16(line, &i, i+3);
4778                         if ( v != -1 ) {
4779                                 ai->config.channelSet = (u16)v;
4780                                 set_bit (FLAG_COMMIT, &ai->flags);
4781                         }
4782                 } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
4783                         int v, i = 0;
4784                         line += 11;
4785                         v = get_dec_u16(line, &i, i+3);
4786                         if ( v != -1 ) {
4787                                 ai->config.txPower = (u16)v;
4788                                 set_bit (FLAG_COMMIT, &ai->flags);
4789                         }
4790                 } else if ( !strncmp( line, "WEP: ", 5 ) ) {
4791                         line += 5;
4792                         switch( line[0] ) {
4793                         case 's':
4794                                 ai->config.authType = (u16)AUTH_SHAREDKEY;
4795                                 break;
4796                         case 'e':
4797                                 ai->config.authType = (u16)AUTH_ENCRYPT;
4798                                 break;
4799                         default:
4800                                 ai->config.authType = (u16)AUTH_OPEN;
4801                                 break;
4802                         }
4803                         set_bit (FLAG_COMMIT, &ai->flags);
4804                 } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
4805                         int v, i = 0;
4806
4807                         line += 16;
4808                         v = get_dec_u16(line, &i, 3);
4809                         v = (v<0) ? 0 : ((v>255) ? 255 : v);
4810                         ai->config.longRetryLimit = (u16)v;
4811                         set_bit (FLAG_COMMIT, &ai->flags);
4812                 } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
4813                         int v, i = 0;
4814
4815                         line += 17;
4816                         v = get_dec_u16(line, &i, 3);
4817                         v = (v<0) ? 0 : ((v>255) ? 255 : v);
4818                         ai->config.shortRetryLimit = (u16)v;
4819                         set_bit (FLAG_COMMIT, &ai->flags);
4820                 } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
4821                         int v, i = 0;
4822
4823                         line += 14;
4824                         v = get_dec_u16(line, &i, 4);
4825                         v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
4826                         ai->config.rtsThres = (u16)v;
4827                         set_bit (FLAG_COMMIT, &ai->flags);
4828                 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
4829                         int v, i = 0;
4830
4831                         line += 16;
4832                         v = get_dec_u16(line, &i, 5);
4833                         v = (v<0) ? 0 : v;
4834                         ai->config.txLifetime = (u16)v;
4835                         set_bit (FLAG_COMMIT, &ai->flags);
4836                 } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
4837                         int v, i = 0;
4838
4839                         line += 16;
4840                         v = get_dec_u16(line, &i, 5);
4841                         v = (v<0) ? 0 : v;
4842                         ai->config.rxLifetime = (u16)v;
4843                         set_bit (FLAG_COMMIT, &ai->flags);
4844                 } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4845                         ai->config.txDiversity =
4846                                 (line[13]=='l') ? 1 :
4847                                 ((line[13]=='r')? 2: 3);
4848                         set_bit (FLAG_COMMIT, &ai->flags);
4849                 } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4850                         ai->config.rxDiversity =
4851                                 (line[13]=='l') ? 1 :
4852                                 ((line[13]=='r')? 2: 3);
4853                         set_bit (FLAG_COMMIT, &ai->flags);
4854                 } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4855                         int v, i = 0;
4856
4857                         line += 15;
4858                         v = get_dec_u16(line, &i, 4);
4859                         v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
4860                         v = v & 0xfffe; /* Make sure its even */
4861                         ai->config.fragThresh = (u16)v;
4862                         set_bit (FLAG_COMMIT, &ai->flags);
4863                 } else if (!strncmp(line, "Modulation: ", 12)) {
4864                         line += 12;
4865                         switch(*line) {
4866                         case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4867                         case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4868                         case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4869                         default:
4870                                 printk( KERN_WARNING "airo: Unknown modulation\n" );
4871                         }
4872                 } else if (!strncmp(line, "Preamble: ", 10)) {
4873                         line += 10;
4874                         switch(*line) {
4875                         case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4876                         case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4877                         case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4878                         default: printk(KERN_WARNING "airo: Unknown preamble\n");
4879                         }
4880                 } else {
4881                         printk( KERN_WARNING "Couldn't figure out %s\n", line );
4882                 }
4883                 while( line[0] && line[0] != '\n' ) line++;
4884                 if ( line[0] ) line++;
4885         }
4886         airo_config_commit(dev, NULL, NULL, NULL);
4887 }
4888
4889 static char *get_rmode(u16 mode) {
4890         switch(mode&0xff) {
4891         case RXMODE_RFMON:  return "rfmon";
4892         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
4893         case RXMODE_LANMON:  return "lanmon";
4894         }
4895         return "ESS";
4896 }
4897
4898 static int proc_config_open( struct inode *inode, struct file *file ) {
4899         struct proc_data *data;
4900         struct proc_dir_entry *dp = PDE(inode);
4901         struct net_device *dev = dp->data;
4902         struct airo_info *ai = dev->priv;
4903         int i;
4904
4905         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4906                 return -ENOMEM;
4907         memset(file->private_data, 0, sizeof(struct proc_data));
4908         data = (struct proc_data *)file->private_data;
4909         if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4910                 kfree (file->private_data);
4911                 file->private_data = NULL;
4912                 return -ENOMEM;
4913         }
4914         if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4915                 kfree (data->rbuffer);
4916                 data->rbuffer = NULL;
4917                 kfree (file->private_data);
4918                 file->private_data = NULL;
4919                 return -ENOMEM;
4920         }
4921         memset( data->wbuffer, 0, 2048 );
4922         data->maxwritelen = 2048;
4923         data->on_close = proc_config_on_close;
4924
4925         readConfigRid(ai, 1);
4926
4927         i = sprintf( data->rbuffer,
4928                      "Mode: %s\n"
4929                      "Radio: %s\n"
4930                      "NodeName: %-16s\n"
4931                      "PowerMode: %s\n"
4932                      "DataRates: %d %d %d %d %d %d %d %d\n"
4933                      "Channel: %d\n"
4934                      "XmitPower: %d\n",
4935                      (ai->config.opmode & 0xFF) == 0 ? "adhoc" :
4936                      (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode):
4937                      (ai->config.opmode & 0xFF) == 2 ? "AP" :
4938                      (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error",
4939                      test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
4940                      ai->config.nodeName,
4941                      ai->config.powerSaveMode == 0 ? "CAM" :
4942                      ai->config.powerSaveMode == 1 ? "PSP" :
4943                      ai->config.powerSaveMode == 2 ? "PSPCAM" : "Error",
4944                      (int)ai->config.rates[0],
4945                      (int)ai->config.rates[1],
4946                      (int)ai->config.rates[2],
4947                      (int)ai->config.rates[3],
4948                      (int)ai->config.rates[4],
4949                      (int)ai->config.rates[5],
4950                      (int)ai->config.rates[6],
4951                      (int)ai->config.rates[7],
4952                      (int)ai->config.channelSet,
4953                      (int)ai->config.txPower
4954                 );
4955         sprintf( data->rbuffer + i,
4956                  "LongRetryLimit: %d\n"
4957                  "ShortRetryLimit: %d\n"
4958                  "RTSThreshold: %d\n"
4959                  "TXMSDULifetime: %d\n"
4960                  "RXMSDULifetime: %d\n"
4961                  "TXDiversity: %s\n"
4962                  "RXDiversity: %s\n"
4963                  "FragThreshold: %d\n"
4964                  "WEP: %s\n"
4965                  "Modulation: %s\n"
4966                  "Preamble: %s\n",
4967                  (int)ai->config.longRetryLimit,
4968                  (int)ai->config.shortRetryLimit,
4969                  (int)ai->config.rtsThres,
4970                  (int)ai->config.txLifetime,
4971                  (int)ai->config.rxLifetime,
4972                  ai->config.txDiversity == 1 ? "left" :
4973                  ai->config.txDiversity == 2 ? "right" : "both",
4974                  ai->config.rxDiversity == 1 ? "left" :
4975                  ai->config.rxDiversity == 2 ? "right" : "both",
4976                  (int)ai->config.fragThresh,
4977                  ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
4978                  ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
4979                  ai->config.modulation == 0 ? "default" :
4980                  ai->config.modulation == MOD_CCK ? "cck" :
4981                  ai->config.modulation == MOD_MOK ? "mok" : "error",
4982                  ai->config.preamble == PREAMBLE_AUTO ? "auto" :
4983                  ai->config.preamble == PREAMBLE_LONG ? "long" :
4984                  ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
4985                 );
4986         data->readlen = strlen( data->rbuffer );
4987         return 0;
4988 }
4989
4990 static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
4991         struct proc_data *data = (struct proc_data *)file->private_data;
4992         struct proc_dir_entry *dp = PDE(inode);
4993         struct net_device *dev = dp->data;
4994         struct airo_info *ai = dev->priv;
4995         SsidRid SSID_rid;
4996         Resp rsp;
4997         int i;
4998         int offset = 0;
4999
5000         if ( !data->writelen ) return;
5001
5002         memset( &SSID_rid, 0, sizeof( SSID_rid ) );
5003
5004         for( i = 0; i < 3; i++ ) {
5005                 int j;
5006                 for( j = 0; j+offset < data->writelen && j < 32 &&
5007                              data->wbuffer[offset+j] != '\n'; j++ ) {
5008                         SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
5009                 }
5010                 if ( j == 0 ) break;
5011                 SSID_rid.ssids[i].len = j;
5012                 offset += j;
5013                 while( data->wbuffer[offset] != '\n' &&
5014                        offset < data->writelen ) offset++;
5015                 offset++;
5016         }
5017         if (i)
5018                 SSID_rid.len = sizeof(SSID_rid);
5019         disable_MAC(ai, 1);
5020         writeSsidRid(ai, &SSID_rid, 1);
5021         enable_MAC(ai, &rsp, 1);
5022 }
5023
5024 inline static u8 hexVal(char c) {
5025         if (c>='0' && c<='9') return c -= '0';
5026         if (c>='a' && c<='f') return c -= 'a'-10;
5027         if (c>='A' && c<='F') return c -= 'A'-10;
5028         return 0;
5029 }
5030
5031 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
5032         struct proc_data *data = (struct proc_data *)file->private_data;
5033         struct proc_dir_entry *dp = PDE(inode);
5034         struct net_device *dev = dp->data;
5035         struct airo_info *ai = dev->priv;
5036         APListRid APList_rid;
5037         Resp rsp;
5038         int i;
5039
5040         if ( !data->writelen ) return;
5041
5042         memset( &APList_rid, 0, sizeof(APList_rid) );
5043         APList_rid.len = sizeof(APList_rid);
5044
5045         for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
5046                 int j;
5047                 for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
5048                         switch(j%3) {
5049                         case 0:
5050                                 APList_rid.ap[i][j/3]=
5051                                         hexVal(data->wbuffer[j+i*6*3])<<4;
5052                                 break;
5053                         case 1:
5054                                 APList_rid.ap[i][j/3]|=
5055                                         hexVal(data->wbuffer[j+i*6*3]);
5056                                 break;
5057                         }
5058                 }
5059         }
5060         disable_MAC(ai, 1);
5061         writeAPListRid(ai, &APList_rid, 1);
5062         enable_MAC(ai, &rsp, 1);
5063 }
5064
5065 /* This function wraps PC4500_writerid with a MAC disable */
5066 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5067                         int len, int dummy ) {
5068         int rc;
5069         Resp rsp;
5070
5071         disable_MAC(ai, 1);
5072         rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5073         enable_MAC(ai, &rsp, 1);
5074         return rc;
5075 }
5076
5077 /* Returns the length of the key at the index.  If index == 0xffff
5078  * the index of the transmit key is returned.  If the key doesn't exist,
5079  * -1 will be returned.
5080  */
5081 static int get_wep_key(struct airo_info *ai, u16 index) {
5082         WepKeyRid wkr;
5083         int rc;
5084         u16 lastindex;
5085
5086         rc = readWepKeyRid(ai, &wkr, 1, 1);
5087         if (rc == SUCCESS) do {
5088                 lastindex = wkr.kindex;
5089                 if (wkr.kindex == index) {
5090                         if (index == 0xffff) {
5091                                 return wkr.mac[0];
5092                         }
5093                         return wkr.klen;
5094                 }
5095                 readWepKeyRid(ai, &wkr, 0, 1);
5096         } while(lastindex != wkr.kindex);
5097         return -1;
5098 }
5099
5100 static int set_wep_key(struct airo_info *ai, u16 index,
5101                        const char *key, u16 keylen, int perm, int lock ) {
5102         static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5103         WepKeyRid wkr;
5104         Resp rsp;
5105
5106         memset(&wkr, 0, sizeof(wkr));
5107         if (keylen == 0) {
5108 // We are selecting which key to use
5109                 wkr.len = sizeof(wkr);
5110                 wkr.kindex = 0xffff;
5111                 wkr.mac[0] = (char)index;
5112                 if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
5113                 if (perm) ai->defindex = (char)index;
5114         } else {
5115 // We are actually setting the key
5116                 wkr.len = sizeof(wkr);
5117                 wkr.kindex = index;
5118                 wkr.klen = keylen;
5119                 memcpy( wkr.key, key, keylen );
5120                 memcpy( wkr.mac, macaddr, ETH_ALEN );
5121                 printk(KERN_INFO "Setting key %d\n", index);
5122         }
5123
5124         disable_MAC(ai, lock);
5125         writeWepKeyRid(ai, &wkr, perm, lock);
5126         enable_MAC(ai, &rsp, lock);
5127         return 0;
5128 }
5129
5130 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5131         struct proc_data *data;
5132         struct proc_dir_entry *dp = PDE(inode);
5133         struct net_device *dev = dp->data;
5134         struct airo_info *ai = dev->priv;
5135         int i;
5136         char key[16];
5137         u16 index = 0;
5138         int j = 0;
5139
5140         memset(key, 0, sizeof(key));
5141
5142         data = (struct proc_data *)file->private_data;
5143         if ( !data->writelen ) return;
5144
5145         if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5146             (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5147                 index = data->wbuffer[0] - '0';
5148                 if (data->wbuffer[1] == '\n') {
5149                         set_wep_key(ai, index, NULL, 0, 1, 1);
5150                         return;
5151                 }
5152                 j = 2;
5153         } else {
5154                 printk(KERN_ERR "airo:  WepKey passed invalid key index\n");
5155                 return;
5156         }
5157
5158         for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
5159                 switch(i%3) {
5160                 case 0:
5161                         key[i/3] = hexVal(data->wbuffer[i+j])<<4;
5162                         break;
5163                 case 1:
5164                         key[i/3] |= hexVal(data->wbuffer[i+j]);
5165                         break;
5166                 }
5167         }
5168         set_wep_key(ai, index, key, i/3, 1, 1);
5169 }
5170
5171 static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5172         struct proc_data *data;
5173         struct proc_dir_entry *dp = PDE(inode);
5174         struct net_device *dev = dp->data;
5175         struct airo_info *ai = dev->priv;
5176         char *ptr;
5177         WepKeyRid wkr;
5178         u16 lastindex;
5179         int j=0;
5180         int rc;
5181
5182         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5183                 return -ENOMEM;
5184         memset(file->private_data, 0, sizeof(struct proc_data));
5185         memset(&wkr, 0, sizeof(wkr));
5186         data = (struct proc_data *)file->private_data;
5187         if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
5188                 kfree (file->private_data);
5189                 file->private_data = NULL;
5190                 return -ENOMEM;
5191         }
5192         memset(data->rbuffer, 0, 180);
5193         data->writelen = 0;
5194         data->maxwritelen = 80;
5195         if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
5196                 kfree (data->rbuffer);
5197                 data->rbuffer = NULL;
5198                 kfree (file->private_data);
5199                 file->private_data = NULL;
5200                 return -ENOMEM;
5201         }
5202         memset( data->wbuffer, 0, 80 );
5203         data->on_close = proc_wepkey_on_close;
5204
5205         ptr = data->rbuffer;
5206         strcpy(ptr, "No wep keys\n");
5207         rc = readWepKeyRid(ai, &wkr, 1, 1);
5208         if (rc == SUCCESS) do {
5209                 lastindex = wkr.kindex;
5210                 if (wkr.kindex == 0xffff) {
5211                         j += sprintf(ptr+j, "Tx key = %d\n",
5212                                      (int)wkr.mac[0]);
5213                 } else {
5214                         j += sprintf(ptr+j, "Key %d set with length = %d\n",
5215                                      (int)wkr.kindex, (int)wkr.klen);
5216                 }
5217                 readWepKeyRid(ai, &wkr, 0, 1);
5218         } while((lastindex != wkr.kindex) && (j < 180-30));
5219
5220         data->readlen = strlen( data->rbuffer );
5221         return 0;
5222 }
5223
5224 static int proc_SSID_open( struct inode *inode, struct file *file ) {
5225         struct proc_data *data;
5226         struct proc_dir_entry *dp = PDE(inode);
5227         struct net_device *dev = dp->data;
5228         struct airo_info *ai = dev->priv;
5229         int i;
5230         char *ptr;
5231         SsidRid SSID_rid;
5232
5233         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5234                 return -ENOMEM;
5235         memset(file->private_data, 0, sizeof(struct proc_data));
5236         data = (struct proc_data *)file->private_data;
5237         if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5238                 kfree (file->private_data);
5239                 file->private_data = NULL;
5240                 return -ENOMEM;
5241         }
5242         data->writelen = 0;
5243         data->maxwritelen = 33*3;
5244         if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
5245                 kfree (data->rbuffer);
5246                 data->rbuffer = NULL;
5247                 kfree (file->private_data);
5248                 file->private_data = NULL;
5249                 return -ENOMEM;
5250         }
5251         memset( data->wbuffer, 0, 33*3 );
5252         data->on_close = proc_SSID_on_close;
5253
5254         readSsidRid(ai, &SSID_rid);
5255         ptr = data->rbuffer;
5256         for( i = 0; i < 3; i++ ) {
5257                 int j;
5258                 if ( !SSID_rid.ssids[i].len ) break;
5259                 for( j = 0; j < 32 &&
5260                              j < SSID_rid.ssids[i].len &&
5261                              SSID_rid.ssids[i].ssid[j]; j++ ) {
5262                         *ptr++ = SSID_rid.ssids[i].ssid[j];
5263                 }
5264                 *ptr++ = '\n';
5265         }
5266         *ptr = '\0';
5267         data->readlen = strlen( data->rbuffer );
5268         return 0;
5269 }
5270
5271 static int proc_APList_open( struct inode *inode, struct file *file ) {
5272         struct proc_data *data;
5273         struct proc_dir_entry *dp = PDE(inode);
5274         struct net_device *dev = dp->data;
5275         struct airo_info *ai = dev->priv;
5276         int i;
5277         char *ptr;
5278         APListRid APList_rid;
5279
5280         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5281                 return -ENOMEM;
5282         memset(file->private_data, 0, sizeof(struct proc_data));
5283         data = (struct proc_data *)file->private_data;
5284         if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5285                 kfree (file->private_data);
5286                 file->private_data = NULL;
5287                 return -ENOMEM;
5288         }
5289         data->writelen = 0;
5290         data->maxwritelen = 4*6*3;
5291         if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5292                 kfree (data->rbuffer);
5293                 data->rbuffer=NULL;
5294                 kfree (file->private_data);
5295                 file->private_data = NULL;
5296                 return -ENOMEM;
5297         }
5298         memset( data->wbuffer, 0, data->maxwritelen );
5299         data->on_close = proc_APList_on_close;
5300
5301         readAPListRid(ai, &APList_rid);
5302         ptr = data->rbuffer;
5303         for( i = 0; i < 4; i++ ) {
5304 // We end when we find a zero MAC
5305                 if ( !*(int*)APList_rid.ap[i] &&
5306                      !*(int*)&APList_rid.ap[i][2]) break;
5307                 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n",
5308                                (int)APList_rid.ap[i][0],
5309                                (int)APList_rid.ap[i][1],
5310                                (int)APList_rid.ap[i][2],
5311                                (int)APList_rid.ap[i][3],
5312                                (int)APList_rid.ap[i][4],
5313                                (int)APList_rid.ap[i][5]);
5314         }
5315         if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5316
5317         *ptr = '\0';
5318         data->readlen = strlen( data->rbuffer );
5319         return 0;
5320 }
5321
5322 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5323         struct proc_data *data;
5324         struct proc_dir_entry *dp = PDE(inode);
5325         struct net_device *dev = dp->data;
5326         struct airo_info *ai = dev->priv;
5327         char *ptr;
5328         BSSListRid BSSList_rid;
5329         int rc;
5330         /* If doLoseSync is not 1, we won't do a Lose Sync */
5331         int doLoseSync = -1;
5332
5333         if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5334                 return -ENOMEM;
5335         memset(file->private_data, 0, sizeof(struct proc_data));
5336         data = (struct proc_data *)file->private_data;
5337         if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5338                 kfree (file->private_data);
5339                 file->private_data = NULL;
5340                 return -ENOMEM;
5341         }
5342         data->writelen = 0;
5343         data->maxwritelen = 0;
5344         data->wbuffer = NULL;
5345         data->on_close = NULL;
5346
5347         if (file->f_mode & FMODE_WRITE) {
5348                 if (!(file->f_mode & FMODE_READ)) {
5349                         Cmd cmd;
5350                         Resp rsp;
5351
5352                         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
5353                         memset(&cmd, 0, sizeof(cmd));
5354                         cmd.cmd=CMD_LISTBSS;
5355                         if (down_interruptible(&ai->sem))
5356                                 return -ERESTARTSYS;
5357                         issuecommand(ai, &cmd, &rsp);
5358                         up(&ai->sem);
5359                         data->readlen = 0;
5360                         return 0;
5361                 }
5362                 doLoseSync = 1;
5363         }
5364         ptr = data->rbuffer;
5365         /* There is a race condition here if there are concurrent opens.
5366            Since it is a rare condition, we'll just live with it, otherwise
5367            we have to add a spin lock... */
5368         rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5369         while(rc == 0 && BSSList_rid.index != 0xffff) {
5370                 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x %*s rssi = %d",
5371                                 (int)BSSList_rid.bssid[0],
5372                                 (int)BSSList_rid.bssid[1],
5373                                 (int)BSSList_rid.bssid[2],
5374                                 (int)BSSList_rid.bssid[3],
5375                                 (int)BSSList_rid.bssid[4],
5376                                 (int)BSSList_rid.bssid[5],
5377                                 (int)BSSList_rid.ssidLen,
5378                                 BSSList_rid.ssid,
5379                                 (int)BSSList_rid.rssi);
5380                 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5381                                 (int)BSSList_rid.dsChannel,
5382                                 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5383                                 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5384                                 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5385                                 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5386                 rc = readBSSListRid(ai, 0, &BSSList_rid);
5387         }
5388         *ptr = '\0';
5389         data->readlen = strlen( data->rbuffer );
5390         return 0;
5391 }
5392
5393 static int proc_close( struct inode *inode, struct file *file )
5394 {
5395         struct proc_data *data = (struct proc_data *)file->private_data;
5396         if ( data->on_close != NULL ) data->on_close( inode, file );
5397         if ( data->rbuffer ) {
5398                 kfree( data->rbuffer );
5399                 data->rbuffer = NULL;
5400         }
5401         if ( data->wbuffer ) {
5402                 kfree( data->wbuffer );
5403                 data->wbuffer = NULL;
5404         }
5405         kfree( data );
5406         file->private_data = NULL;
5407         return 0;
5408 }
5409
5410 static struct net_device_list {
5411         struct net_device *dev;
5412         struct net_device_list *next;
5413 } *airo_devices;
5414
5415 /* Since the card doesn't automatically switch to the right WEP mode,
5416    we will make it do it.  If the card isn't associated, every secs we
5417    will switch WEP modes to see if that will help.  If the card is
5418    associated we will check every minute to see if anything has
5419    changed. */
5420 static void timer_func( struct net_device *dev ) {
5421         struct airo_info *apriv = dev->priv;
5422         Resp rsp;
5423
5424 /* We don't have a link so try changing the authtype */
5425         readConfigRid(apriv, 0);
5426         disable_MAC(apriv, 0);
5427         switch(apriv->config.authType) {
5428                 case AUTH_ENCRYPT:
5429 /* So drop to OPEN */
5430                         apriv->config.authType = AUTH_OPEN;
5431                         break;
5432                 case AUTH_SHAREDKEY:
5433                         if (apriv->keyindex < auto_wep) {
5434                                 set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
5435                                 apriv->config.authType = AUTH_SHAREDKEY;
5436                                 apriv->keyindex++;
5437                         } else {
5438                                 /* Drop to ENCRYPT */
5439                                 apriv->keyindex = 0;
5440                                 set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
5441                                 apriv->config.authType = AUTH_ENCRYPT;
5442                         }
5443                         break;
5444                 default:  /* We'll escalate to SHAREDKEY */
5445                         apriv->config.authType = AUTH_SHAREDKEY;
5446         }
5447         set_bit (FLAG_COMMIT, &apriv->flags);
5448         writeConfigRid(apriv, 0);
5449         enable_MAC(apriv, &rsp, 0);
5450         up(&apriv->sem);
5451
5452 /* Schedule check to see if the change worked */
5453         clear_bit(JOB_AUTOWEP, &apriv->flags);
5454         apriv->expires = RUN_AT(HZ*3);
5455 }
5456
5457 static int add_airo_dev( struct net_device *dev ) {
5458         struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
5459         if ( !node )
5460                 return -ENOMEM;
5461
5462         node->dev = dev;
5463         node->next = airo_devices;
5464         airo_devices = node;
5465
5466         return 0;
5467 }
5468
5469 static void del_airo_dev( struct net_device *dev ) {
5470         struct net_device_list **p = &airo_devices;
5471         while( *p && ( (*p)->dev != dev ) )
5472                 p = &(*p)->next;
5473         if ( *p && (*p)->dev == dev )
5474                 *p = (*p)->next;
5475 }
5476
5477 #ifdef CONFIG_PCI
5478 static int __devinit airo_pci_probe(struct pci_dev *pdev,
5479                                     const struct pci_device_id *pent)
5480 {
5481         struct net_device *dev;
5482
5483         if (pci_enable_device(pdev))
5484                 return -ENODEV;
5485         pci_set_master(pdev);
5486
5487         if (pdev->device == 0x5000 || pdev->device == 0xa504)
5488                         dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev);
5489         else
5490                         dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev);
5491         if (!dev)
5492                 return -ENODEV;
5493
5494         pci_set_drvdata(pdev, dev);
5495         return 0;
5496 }
5497
5498 static void __devexit airo_pci_remove(struct pci_dev *pdev)
5499 {
5500 }
5501
5502 static int airo_pci_suspend(struct pci_dev *pdev, u32 state)
5503 {
5504         struct net_device *dev = pci_get_drvdata(pdev);
5505         struct airo_info *ai = dev->priv;
5506         Cmd cmd;
5507         Resp rsp;
5508
5509         if ((ai->APList == NULL) &&
5510                 (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
5511                 return -ENOMEM;
5512         if ((ai->SSID == NULL) &&
5513                 (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
5514                 return -ENOMEM;
5515         readAPListRid(ai, ai->APList);
5516         readSsidRid(ai, ai->SSID);
5517         memset(&cmd, 0, sizeof(cmd));
5518         /* the lock will be released at the end of the resume callback */
5519         if (down_interruptible(&ai->sem))
5520                 return -EAGAIN;
5521         disable_MAC(ai, 0);
5522         netif_device_detach(dev);
5523         ai->power = state;
5524         cmd.cmd=HOSTSLEEP;
5525         issuecommand(ai, &cmd, &rsp);
5526
5527         pci_enable_wake(pdev, state, 1);
5528         pci_save_state(pdev);
5529         return pci_set_power_state(pdev, state);
5530 }
5531
5532 static int airo_pci_resume(struct pci_dev *pdev)
5533 {
5534         struct net_device *dev = pci_get_drvdata(pdev);
5535         struct airo_info *ai = dev->priv;
5536         Resp rsp;
5537
5538         pci_set_power_state(pdev, 0);
5539         pci_restore_state(pdev);
5540         pci_enable_wake(pdev, ai->power, 0);
5541
5542         if (ai->power > 1) {
5543                 reset_card(dev, 0);
5544                 mpi_init_descriptors(ai);
5545                 setup_card(ai, dev->dev_addr, 0);
5546                 clear_bit(FLAG_RADIO_OFF, &ai->flags);
5547                 clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5548         } else {
5549                 OUT4500(ai, EVACK, EV_AWAKEN);
5550                 OUT4500(ai, EVACK, EV_AWAKEN);
5551                 schedule_timeout(HZ/10);
5552         }
5553
5554         set_bit (FLAG_COMMIT, &ai->flags);
5555         disable_MAC(ai, 0);
5556         schedule_timeout (HZ/5);
5557         if (ai->SSID) {
5558                 writeSsidRid(ai, ai->SSID, 0);
5559                 kfree(ai->SSID);
5560                 ai->SSID = NULL;
5561         }
5562         if (ai->APList) {
5563                 writeAPListRid(ai, ai->APList, 0);
5564                 kfree(ai->APList);
5565                 ai->APList = NULL;
5566         }
5567         writeConfigRid(ai, 0);
5568         enable_MAC(ai, &rsp, 0);
5569         ai->power = 0;
5570         netif_device_attach(dev);
5571         netif_wake_queue(dev);
5572         enable_interrupts(ai);
5573         up(&ai->sem);
5574         return 0;
5575 }
5576 #endif
5577
5578 static int __init airo_init_module( void )
5579 {
5580         int i, have_isa_dev = 0;
5581
5582         airo_entry = create_proc_entry("aironet",
5583                                        S_IFDIR | airo_perm,
5584                                        proc_root_driver);
5585         airo_entry->uid = proc_uid;
5586         airo_entry->gid = proc_gid;
5587
5588         for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
5589                 printk( KERN_INFO
5590                         "airo:  Trying to configure ISA adapter at irq=%d io=0x%x\n",
5591                         irq[i], io[i] );
5592                 if (init_airo_card( irq[i], io[i], 0 ))
5593                         have_isa_dev = 1;
5594         }
5595
5596 #ifdef CONFIG_PCI
5597         printk( KERN_INFO "airo:  Probing for PCI adapters\n" );
5598         pci_register_driver(&airo_driver);
5599         printk( KERN_INFO "airo:  Finished probing for PCI adapters\n" );
5600 #endif
5601
5602         /* Always exit with success, as we are a library module
5603          * as well as a driver module
5604          */
5605         return 0;
5606 }
5607
5608 static void __exit airo_cleanup_module( void )
5609 {
5610         while( airo_devices ) {
5611                 printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
5612                 stop_airo_card( airo_devices->dev, 1 );
5613         }
5614 #ifdef CONFIG_PCI
5615         pci_unregister_driver(&airo_driver);
5616 #endif
5617         remove_proc_entry("aironet", proc_root_driver);
5618 }
5619
5620 #ifdef WIRELESS_EXT
5621 /*
5622  * Initial Wireless Extension code for Aironet driver by :
5623  *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5624  * Conversion to new driver API by :
5625  *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5626  * Javier also did a good amount of work here, adding some new extensions
5627  * and fixing my code. Let's just say that without him this code just
5628  * would not work at all... - Jean II
5629  */
5630
5631 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5632 {
5633         int quality = 0;
5634
5635         if ((status_rid->mode & 0x3f) == 0x3f && (cap_rid->hardCap & 8)) {
5636                 if (memcmp(cap_rid->prodName, "350", 3))
5637                         if (status_rid->signalQuality > 0x20)
5638                                 quality = 0;
5639                         else
5640                                 quality = 0x20 - status_rid->signalQuality;
5641                 else
5642                         if (status_rid->signalQuality > 0xb0)
5643                                 quality = 0;
5644                         else if (status_rid->signalQuality < 0x10)
5645                                 quality = 0xa0;
5646                         else
5647                                 quality = 0xb0 - status_rid->signalQuality;
5648         }
5649         return quality;
5650 }
5651
5652 #define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5653 #define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
5654
5655 /*------------------------------------------------------------------*/
5656 /*
5657  * Wireless Handler : get protocol name
5658  */
5659 static int airo_get_name(struct net_device *dev,
5660                          struct iw_request_info *info,
5661                          char *cwrq,
5662                          char *extra)
5663 {
5664         strcpy(cwrq, "IEEE 802.11-DS");
5665         return 0;
5666 }
5667
5668 /*------------------------------------------------------------------*/
5669 /*
5670  * Wireless Handler : set frequency
5671  */
5672 static int airo_set_freq(struct net_device *dev,
5673                          struct iw_request_info *info,
5674                          struct iw_freq *fwrq,
5675                          char *extra)
5676 {
5677         struct airo_info *local = dev->priv;
5678         int rc = -EINPROGRESS;          /* Call commit handler */
5679
5680         /* If setting by frequency, convert to a channel */
5681         if((fwrq->e == 1) &&
5682            (fwrq->m >= (int) 2.412e8) &&
5683            (fwrq->m <= (int) 2.487e8)) {
5684                 int f = fwrq->m / 100000;
5685                 int c = 0;
5686                 while((c < 14) && (f != frequency_list[c]))
5687                         c++;
5688                 /* Hack to fall through... */
5689                 fwrq->e = 0;
5690                 fwrq->m = c + 1;
5691         }
5692         /* Setting by channel number */
5693         if((fwrq->m > 1000) || (fwrq->e > 0))
5694                 rc = -EOPNOTSUPP;
5695         else {
5696                 int channel = fwrq->m;
5697                 /* We should do a better check than that,
5698                  * based on the card capability !!! */
5699                 if((channel < 1) || (channel > 16)) {
5700                         printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m);
5701                         rc = -EINVAL;
5702                 } else {
5703                         readConfigRid(local, 1);
5704                         /* Yes ! We can set it !!! */
5705                         local->config.channelSet = (u16)(channel - 1);
5706                         set_bit (FLAG_COMMIT, &local->flags);
5707                 }
5708         }
5709         return rc;
5710 }
5711
5712 /*------------------------------------------------------------------*/
5713 /*
5714  * Wireless Handler : get frequency
5715  */
5716 static int airo_get_freq(struct net_device *dev,
5717                          struct iw_request_info *info,
5718                          struct iw_freq *fwrq,
5719                          char *extra)
5720 {
5721         struct airo_info *local = dev->priv;
5722         StatusRid status_rid;           /* Card status info */
5723
5724         readConfigRid(local, 1);
5725         if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
5726                 status_rid.channel = local->config.channelSet;
5727         else
5728                 readStatusRid(local, &status_rid, 1);
5729
5730 #ifdef WEXT_USECHANNELS
5731         fwrq->m = ((int)status_rid.channel) + 1;
5732         fwrq->e = 0;
5733 #else
5734         {
5735                 int f = (int)status_rid.channel;
5736                 fwrq->m = frequency_list[f] * 100000;
5737                 fwrq->e = 1;
5738         }
5739 #endif
5740
5741         return 0;
5742 }
5743
5744 /*------------------------------------------------------------------*/
5745 /*
5746  * Wireless Handler : set ESSID
5747  */
5748 static int airo_set_essid(struct net_device *dev,
5749                           struct iw_request_info *info,
5750                           struct iw_point *dwrq,
5751                           char *extra)
5752 {
5753         struct airo_info *local = dev->priv;
5754         Resp rsp;
5755         SsidRid SSID_rid;               /* SSIDs */
5756
5757         /* Reload the list of current SSID */
5758         readSsidRid(local, &SSID_rid);
5759
5760         /* Check if we asked for `any' */
5761         if(dwrq->flags == 0) {
5762                 /* Just send an empty SSID list */
5763                 memset(&SSID_rid, 0, sizeof(SSID_rid));
5764         } else {
5765                 int     index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5766
5767                 /* Check the size of the string */
5768                 if(dwrq->length > IW_ESSID_MAX_SIZE+1) {
5769                         return -E2BIG ;
5770                 }
5771                 /* Check if index is valid */
5772                 if((index < 0) || (index >= 4)) {
5773                         return -EINVAL;
5774                 }
5775
5776                 /* Set the SSID */
5777                 memset(SSID_rid.ssids[index].ssid, 0,
5778                        sizeof(SSID_rid.ssids[index].ssid));
5779                 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5780                 SSID_rid.ssids[index].len = dwrq->length - 1;
5781         }
5782         SSID_rid.len = sizeof(SSID_rid);
5783         /* Write it to the card */
5784         disable_MAC(local, 1);
5785         writeSsidRid(local, &SSID_rid, 1);
5786         enable_MAC(local, &rsp, 1);
5787
5788         return 0;
5789 }
5790
5791 /*------------------------------------------------------------------*/
5792 /*
5793  * Wireless Handler : get ESSID
5794  */
5795 static int airo_get_essid(struct net_device *dev,
5796                           struct iw_request_info *info,
5797                           struct iw_point *dwrq,
5798                           char *extra)
5799 {
5800         struct airo_info *local = dev->priv;
5801         StatusRid status_rid;           /* Card status info */
5802
5803         readStatusRid(local, &status_rid, 1);
5804
5805         /* Note : if dwrq->flags != 0, we should
5806          * get the relevant SSID from the SSID list... */
5807
5808         /* Get the current SSID */
5809         memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
5810         extra[status_rid.SSIDlen] = '\0';
5811         /* If none, we may want to get the one that was set */
5812
5813         /* Push it out ! */
5814         dwrq->length = status_rid.SSIDlen + 1;
5815         dwrq->flags = 1; /* active */
5816
5817         return 0;
5818 }
5819
5820 /*------------------------------------------------------------------*/
5821 /*
5822  * Wireless Handler : set AP address
5823  */
5824 static int airo_set_wap(struct net_device *dev,
5825                         struct iw_request_info *info,
5826                         struct sockaddr *awrq,
5827                         char *extra)
5828 {
5829         struct airo_info *local = dev->priv;
5830         Cmd cmd;
5831         Resp rsp;
5832         APListRid APList_rid;
5833         static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
5834
5835         if (awrq->sa_family != ARPHRD_ETHER)
5836                 return -EINVAL;
5837         else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
5838                 memset(&cmd, 0, sizeof(cmd));
5839                 cmd.cmd=CMD_LOSE_SYNC;
5840                 if (down_interruptible(&local->sem))
5841                         return -ERESTARTSYS;
5842                 issuecommand(local, &cmd, &rsp);
5843                 up(&local->sem);
5844         } else {
5845                 memset(&APList_rid, 0, sizeof(APList_rid));
5846                 APList_rid.len = sizeof(APList_rid);
5847                 memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
5848                 disable_MAC(local, 1);
5849                 writeAPListRid(local, &APList_rid, 1);
5850                 enable_MAC(local, &rsp, 1);
5851         }
5852         return 0;
5853 }
5854
5855 /*------------------------------------------------------------------*/
5856 /*
5857  * Wireless Handler : get AP address
5858  */
5859 static int airo_get_wap(struct net_device *dev,
5860                         struct iw_request_info *info,
5861                         struct sockaddr *awrq,
5862                         char *extra)
5863 {
5864         struct airo_info *local = dev->priv;
5865         StatusRid status_rid;           /* Card status info */
5866
5867         readStatusRid(local, &status_rid, 1);
5868
5869         /* Tentative. This seems to work, wow, I'm lucky !!! */
5870         memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
5871         awrq->sa_family = ARPHRD_ETHER;
5872
5873         return 0;
5874 }
5875
5876 /*------------------------------------------------------------------*/
5877 /*
5878  * Wireless Handler : set Nickname
5879  */
5880 static int airo_set_nick(struct net_device *dev,
5881                          struct iw_request_info *info,
5882                          struct iw_point *dwrq,
5883                          char *extra)
5884 {
5885         struct airo_info *local = dev->priv;
5886
5887         /* Check the size of the string */
5888         if(dwrq->length > 16 + 1) {
5889                 return -E2BIG;
5890         }
5891         readConfigRid(local, 1);
5892         memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
5893         memcpy(local->config.nodeName, extra, dwrq->length);
5894         set_bit (FLAG_COMMIT, &local->flags);
5895
5896         return -EINPROGRESS;            /* Call commit handler */
5897 }
5898
5899 /*------------------------------------------------------------------*/
5900 /*
5901  * Wireless Handler : get Nickname
5902  */
5903 static int airo_get_nick(struct net_device *dev,
5904                          struct iw_request_info *info,
5905                          struct iw_point *dwrq,
5906                          char *extra)
5907 {
5908         struct airo_info *local = dev->priv;
5909
5910         readConfigRid(local, 1);
5911         strncpy(extra, local->config.nodeName, 16);
5912         extra[16] = '\0';
5913         dwrq->length = strlen(extra) + 1;
5914
5915         return 0;
5916 }
5917
5918 /*------------------------------------------------------------------*/
5919 /*
5920  * Wireless Handler : set Bit-Rate
5921  */
5922 static int airo_set_rate(struct net_device *dev,
5923                          struct iw_request_info *info,
5924                          struct iw_param *vwrq,
5925                          char *extra)
5926 {
5927         struct airo_info *local = dev->priv;
5928         CapabilityRid cap_rid;          /* Card capability info */
5929         u8      brate = 0;
5930         int     i;
5931
5932         /* First : get a valid bit rate value */
5933         readCapabilityRid(local, &cap_rid, 1);
5934
5935         /* Which type of value ? */
5936         if((vwrq->value < 8) && (vwrq->value >= 0)) {
5937                 /* Setting by rate index */
5938                 /* Find value in the magic rate table */
5939                 brate = cap_rid.supportedRates[vwrq->value];
5940         } else {
5941                 /* Setting by frequency value */
5942                 u8      normvalue = (u8) (vwrq->value/500000);
5943
5944                 /* Check if rate is valid */
5945                 for(i = 0 ; i < 8 ; i++) {
5946                         if(normvalue == cap_rid.supportedRates[i]) {
5947                                 brate = normvalue;
5948                                 break;
5949                         }
5950                 }
5951         }
5952         /* -1 designed the max rate (mostly auto mode) */
5953         if(vwrq->value == -1) {
5954                 /* Get the highest available rate */
5955                 for(i = 0 ; i < 8 ; i++) {
5956                         if(cap_rid.supportedRates[i] == 0)
5957                                 break;
5958                 }
5959                 if(i != 0)
5960                         brate = cap_rid.supportedRates[i - 1];
5961         }
5962         /* Check that it is valid */
5963         if(brate == 0) {
5964                 return -EINVAL;
5965         }
5966
5967         readConfigRid(local, 1);
5968         /* Now, check if we want a fixed or auto value */
5969         if(vwrq->fixed == 0) {
5970                 /* Fill all the rates up to this max rate */
5971                 memset(local->config.rates, 0, 8);
5972                 for(i = 0 ; i < 8 ; i++) {
5973                         local->config.rates[i] = cap_rid.supportedRates[i];
5974                         if(local->config.rates[i] == brate)
5975                                 break;
5976                 }
5977         } else {
5978                 /* Fixed mode */
5979                 /* One rate, fixed */
5980                 memset(local->config.rates, 0, 8);
5981                 local->config.rates[0] = brate;
5982         }
5983         set_bit (FLAG_COMMIT, &local->flags);
5984
5985         return -EINPROGRESS;            /* Call commit handler */
5986 }
5987
5988 /*------------------------------------------------------------------*/
5989 /*
5990  * Wireless Handler : get Bit-Rate
5991  */
5992 static int airo_get_rate(struct net_device *dev,
5993                          struct iw_request_info *info,
5994                          struct iw_param *vwrq,
5995                          char *extra)
5996 {
5997         struct airo_info *local = dev->priv;
5998         StatusRid status_rid;           /* Card status info */
5999
6000         readStatusRid(local, &status_rid, 1);
6001
6002         vwrq->value = status_rid.currentXmitRate * 500000;
6003         /* If more than one rate, set auto */
6004         readConfigRid(local, 1);
6005         vwrq->fixed = (local->config.rates[1] == 0);
6006
6007         return 0;
6008 }
6009
6010 /*------------------------------------------------------------------*/
6011 /*
6012  * Wireless Handler : set RTS threshold
6013  */
6014 static int airo_set_rts(struct net_device *dev,
6015                         struct iw_request_info *info,
6016                         struct iw_param *vwrq,
6017                         char *extra)
6018 {
6019         struct airo_info *local = dev->priv;
6020         int rthr = vwrq->value;
6021
6022         if(vwrq->disabled)
6023                 rthr = 2312;
6024         if((rthr < 0) || (rthr > 2312)) {
6025                 return -EINVAL;
6026         }
6027         readConfigRid(local, 1);
6028         local->config.rtsThres = rthr;
6029         set_bit (FLAG_COMMIT, &local->flags);
6030
6031         return -EINPROGRESS;            /* Call commit handler */
6032 }
6033
6034 /*------------------------------------------------------------------*/
6035 /*
6036  * Wireless Handler : get RTS threshold
6037  */
6038 static int airo_get_rts(struct net_device *dev,
6039                         struct iw_request_info *info,
6040                         struct iw_param *vwrq,
6041                         char *extra)
6042 {
6043         struct airo_info *local = dev->priv;
6044
6045         readConfigRid(local, 1);
6046         vwrq->value = local->config.rtsThres;
6047         vwrq->disabled = (vwrq->value >= 2312);
6048         vwrq->fixed = 1;
6049
6050         return 0;
6051 }
6052
6053 /*------------------------------------------------------------------*/
6054 /*
6055  * Wireless Handler : set Fragmentation threshold
6056  */
6057 static int airo_set_frag(struct net_device *dev,
6058                          struct iw_request_info *info,
6059                          struct iw_param *vwrq,
6060                          char *extra)
6061 {
6062         struct airo_info *local = dev->priv;
6063         int fthr = vwrq->value;
6064
6065         if(vwrq->disabled)
6066                 fthr = 2312;
6067         if((fthr < 256) || (fthr > 2312)) {
6068                 return -EINVAL;
6069         }
6070         fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
6071         readConfigRid(local, 1);
6072         local->config.fragThresh = (u16)fthr;
6073         set_bit (FLAG_COMMIT, &local->flags);
6074
6075         return -EINPROGRESS;            /* Call commit handler */
6076 }
6077
6078 /*------------------------------------------------------------------*/
6079 /*
6080  * Wireless Handler : get Fragmentation threshold
6081  */
6082 static int airo_get_frag(struct net_device *dev,
6083                          struct iw_request_info *info,
6084                          struct iw_param *vwrq,
6085                          char *extra)
6086 {
6087         struct airo_info *local = dev->priv;
6088
6089         readConfigRid(local, 1);
6090         vwrq->value = local->config.fragThresh;
6091         vwrq->disabled = (vwrq->value >= 2312);
6092         vwrq->fixed = 1;
6093
6094         return 0;
6095 }
6096
6097 /*------------------------------------------------------------------*/
6098 /*
6099  * Wireless Handler : set Mode of Operation
6100  */
6101 static int airo_set_mode(struct net_device *dev,
6102                          struct iw_request_info *info,
6103                          __u32 *uwrq,
6104                          char *extra)
6105 {
6106         struct airo_info *local = dev->priv;
6107         int reset = 0;
6108
6109         readConfigRid(local, 1);
6110         if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
6111                 reset = 1;
6112
6113         switch(*uwrq) {
6114                 case IW_MODE_ADHOC:
6115                         local->config.opmode &= 0xFF00;
6116                         local->config.opmode |= MODE_STA_IBSS;
6117                         local->config.rmode &= 0xfe00;
6118                         local->config.scanMode = SCANMODE_ACTIVE;
6119                         clear_bit (FLAG_802_11, &local->flags);
6120                         break;
6121                 case IW_MODE_INFRA:
6122                         local->config.opmode &= 0xFF00;
6123                         local->config.opmode |= MODE_STA_ESS;
6124                         local->config.rmode &= 0xfe00;
6125                         local->config.scanMode = SCANMODE_ACTIVE;
6126                         clear_bit (FLAG_802_11, &local->flags);
6127                         break;
6128                 case IW_MODE_MASTER:
6129                         local->config.opmode &= 0xFF00;
6130                         local->config.opmode |= MODE_AP;
6131                         local->config.rmode &= 0xfe00;
6132                         local->config.scanMode = SCANMODE_ACTIVE;
6133                         clear_bit (FLAG_802_11, &local->flags);
6134                         break;
6135                 case IW_MODE_REPEAT:
6136                         local->config.opmode &= 0xFF00;
6137                         local->config.opmode |= MODE_AP_RPTR;
6138                         local->config.rmode &= 0xfe00;
6139                         local->config.scanMode = SCANMODE_ACTIVE;
6140                         clear_bit (FLAG_802_11, &local->flags);
6141                         break;
6142                 case IW_MODE_MONITOR:
6143                         local->config.opmode &= 0xFF00;
6144                         local->config.opmode |= MODE_STA_ESS;
6145                         local->config.rmode &= 0xfe00;
6146                         local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6147                         local->config.scanMode = SCANMODE_PASSIVE;
6148                         set_bit (FLAG_802_11, &local->flags);
6149                         break;
6150                 default:
6151                         return -EINVAL;
6152         }
6153         if (reset)
6154                 set_bit (FLAG_RESET, &local->flags);
6155         set_bit (FLAG_COMMIT, &local->flags);
6156
6157         return -EINPROGRESS;            /* Call commit handler */
6158 }
6159
6160 /*------------------------------------------------------------------*/
6161 /*
6162  * Wireless Handler : get Mode of Operation
6163  */
6164 static int airo_get_mode(struct net_device *dev,
6165                          struct iw_request_info *info,
6166                          __u32 *uwrq,
6167                          char *extra)
6168 {
6169         struct airo_info *local = dev->priv;
6170
6171         readConfigRid(local, 1);
6172         /* If not managed, assume it's ad-hoc */
6173         switch (local->config.opmode & 0xFF) {
6174                 case MODE_STA_ESS:
6175                         *uwrq = IW_MODE_INFRA;
6176                         break;
6177                 case MODE_AP:
6178                         *uwrq = IW_MODE_MASTER;
6179                         break;
6180                 case MODE_AP_RPTR:
6181                         *uwrq = IW_MODE_REPEAT;
6182                         break;
6183                 default:
6184                         *uwrq = IW_MODE_ADHOC;
6185         }
6186
6187         return 0;
6188 }
6189
6190 /*------------------------------------------------------------------*/
6191 /*
6192  * Wireless Handler : set Encryption Key
6193  */
6194 static int airo_set_encode(struct net_device *dev,
6195                            struct iw_request_info *info,
6196                            struct iw_point *dwrq,
6197                            char *extra)
6198 {
6199         struct airo_info *local = dev->priv;
6200         CapabilityRid cap_rid;          /* Card capability info */
6201
6202         /* Is WEP supported ? */
6203         readCapabilityRid(local, &cap_rid, 1);
6204         /* Older firmware doesn't support this...
6205         if(!(cap_rid.softCap & 2)) {
6206                 return -EOPNOTSUPP;
6207         } */
6208         readConfigRid(local, 1);
6209
6210         /* Basic checking: do we have a key to set ?
6211          * Note : with the new API, it's impossible to get a NULL pointer.
6212          * Therefore, we need to check a key size == 0 instead.
6213          * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6214          * when no key is present (only change flags), but older versions
6215          * don't do it. - Jean II */
6216         if (dwrq->length > 0) {
6217                 wep_key_t key;
6218                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6219                 int current_index = get_wep_key(local, 0xffff);
6220                 /* Check the size of the key */
6221                 if (dwrq->length > MAX_KEY_SIZE) {
6222                         return -EINVAL;
6223                 }
6224                 /* Check the index (none -> use current) */
6225                 if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4:1)))
6226                         index = current_index;
6227                 /* Set the length */
6228                 if (dwrq->length > MIN_KEY_SIZE)
6229                         key.len = MAX_KEY_SIZE;
6230                 else
6231                         if (dwrq->length > 0)
6232                                 key.len = MIN_KEY_SIZE;
6233                         else
6234                                 /* Disable the key */
6235                                 key.len = 0;
6236                 /* Check if the key is not marked as invalid */
6237                 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6238                         /* Cleanup */
6239                         memset(key.key, 0, MAX_KEY_SIZE);
6240                         /* Copy the key in the driver */
6241                         memcpy(key.key, extra, dwrq->length);
6242                         /* Send the key to the card */
6243                         set_wep_key(local, index, key.key, key.len, 1, 1);
6244                 }
6245                 /* WE specify that if a valid key is set, encryption
6246                  * should be enabled (user may turn it off later)
6247                  * This is also how "iwconfig ethX key on" works */
6248                 if((index == current_index) && (key.len > 0) &&
6249                    (local->config.authType == AUTH_OPEN)) {
6250                         local->config.authType = AUTH_ENCRYPT;
6251                         set_bit (FLAG_COMMIT, &local->flags);
6252                 }
6253         } else {
6254                 /* Do we want to just set the transmit key index ? */
6255                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6256                 if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
6257                         set_wep_key(local, index, NULL, 0, 1, 1);
6258                 } else
6259                         /* Don't complain if only change the mode */
6260                         if(!dwrq->flags & IW_ENCODE_MODE) {
6261                                 return -EINVAL;
6262                         }
6263         }
6264         /* Read the flags */
6265         if(dwrq->flags & IW_ENCODE_DISABLED)
6266                 local->config.authType = AUTH_OPEN;     // disable encryption
6267         if(dwrq->flags & IW_ENCODE_RESTRICTED)
6268                 local->config.authType = AUTH_SHAREDKEY;        // Only Both
6269         if(dwrq->flags & IW_ENCODE_OPEN)
6270                 local->config.authType = AUTH_ENCRYPT;  // Only Wep
6271         /* Commit the changes to flags if needed */
6272         if(dwrq->flags & IW_ENCODE_MODE)
6273                 set_bit (FLAG_COMMIT, &local->flags);
6274         return -EINPROGRESS;            /* Call commit handler */
6275 }
6276
6277 /*------------------------------------------------------------------*/
6278 /*
6279  * Wireless Handler : get Encryption Key
6280  */
6281 static int airo_get_encode(struct net_device *dev,
6282                            struct iw_request_info *info,
6283                            struct iw_point *dwrq,
6284                            char *extra)
6285 {
6286         struct airo_info *local = dev->priv;
6287         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6288         CapabilityRid cap_rid;          /* Card capability info */
6289
6290         /* Is it supported ? */
6291         readCapabilityRid(local, &cap_rid, 1);
6292         if(!(cap_rid.softCap & 2)) {
6293                 return -EOPNOTSUPP;
6294         }
6295         readConfigRid(local, 1);
6296         /* Check encryption mode */
6297         switch(local->config.authType)  {
6298                 case AUTH_ENCRYPT:
6299                         dwrq->flags = IW_ENCODE_OPEN;
6300                         break;
6301                 case AUTH_SHAREDKEY:
6302                         dwrq->flags = IW_ENCODE_RESTRICTED;
6303                         break;
6304                 default:
6305                 case AUTH_OPEN:
6306                         dwrq->flags = IW_ENCODE_DISABLED;
6307                         break;
6308         }
6309         /* We can't return the key, so set the proper flag and return zero */
6310         dwrq->flags |= IW_ENCODE_NOKEY;
6311         memset(extra, 0, 16);
6312
6313         /* Which key do we want ? -1 -> tx index */
6314         if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4 : 1)))
6315                 index = get_wep_key(local, 0xffff);
6316         dwrq->flags |= index + 1;
6317         /* Copy the key to the user buffer */
6318         dwrq->length = get_wep_key(local, index);
6319         if (dwrq->length > 16) {
6320                 dwrq->length=0;
6321         }
6322         return 0;
6323 }
6324
6325 /*------------------------------------------------------------------*/
6326 /*
6327  * Wireless Handler : set Tx-Power
6328  */
6329 static int airo_set_txpow(struct net_device *dev,
6330                           struct iw_request_info *info,
6331                           struct iw_param *vwrq,
6332                           char *extra)
6333 {
6334         struct airo_info *local = dev->priv;
6335         CapabilityRid cap_rid;          /* Card capability info */
6336         int i;
6337         int rc = -EINVAL;
6338
6339         readCapabilityRid(local, &cap_rid, 1);
6340
6341         if (vwrq->disabled) {
6342                 set_bit (FLAG_RADIO_OFF, &local->flags);
6343                 set_bit (FLAG_COMMIT, &local->flags);
6344                 return -EINPROGRESS;            /* Call commit handler */
6345         }
6346         if (vwrq->flags != IW_TXPOW_MWATT) {
6347                 return -EINVAL;
6348         }
6349         clear_bit (FLAG_RADIO_OFF, &local->flags);
6350         for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
6351                 if ((vwrq->value==cap_rid.txPowerLevels[i])) {
6352                         readConfigRid(local, 1);
6353                         local->config.txPower = vwrq->value;
6354                         set_bit (FLAG_COMMIT, &local->flags);
6355                         rc = -EINPROGRESS;      /* Call commit handler */
6356                         break;
6357                 }
6358         return rc;
6359 }
6360
6361 /*------------------------------------------------------------------*/
6362 /*
6363  * Wireless Handler : get Tx-Power
6364  */
6365 static int airo_get_txpow(struct net_device *dev,
6366                           struct iw_request_info *info,
6367                           struct iw_param *vwrq,
6368                           char *extra)
6369 {
6370         struct airo_info *local = dev->priv;
6371
6372         readConfigRid(local, 1);
6373         vwrq->value = local->config.txPower;
6374         vwrq->fixed = 1;        /* No power control */
6375         vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6376         vwrq->flags = IW_TXPOW_MWATT;
6377
6378         return 0;
6379 }
6380
6381 /*------------------------------------------------------------------*/
6382 /*
6383  * Wireless Handler : set Retry limits
6384  */
6385 static int airo_set_retry(struct net_device *dev,
6386                           struct iw_request_info *info,
6387                           struct iw_param *vwrq,
6388                           char *extra)
6389 {
6390         struct airo_info *local = dev->priv;
6391         int rc = -EINVAL;
6392
6393         if(vwrq->disabled) {
6394                 return -EINVAL;
6395         }
6396         readConfigRid(local, 1);
6397         if(vwrq->flags & IW_RETRY_LIMIT) {
6398                 if(vwrq->flags & IW_RETRY_MAX)
6399                         local->config.longRetryLimit = vwrq->value;
6400                 else if (vwrq->flags & IW_RETRY_MIN)
6401                         local->config.shortRetryLimit = vwrq->value;
6402                 else {
6403                         /* No modifier : set both */
6404                         local->config.longRetryLimit = vwrq->value;
6405                         local->config.shortRetryLimit = vwrq->value;
6406                 }
6407                 set_bit (FLAG_COMMIT, &local->flags);
6408                 rc = -EINPROGRESS;              /* Call commit handler */
6409         }
6410         if(vwrq->flags & IW_RETRY_LIFETIME) {
6411                 local->config.txLifetime = vwrq->value / 1024;
6412                 set_bit (FLAG_COMMIT, &local->flags);
6413                 rc = -EINPROGRESS;              /* Call commit handler */
6414         }
6415         return rc;
6416 }
6417
6418 /*------------------------------------------------------------------*/
6419 /*
6420  * Wireless Handler : get Retry limits
6421  */
6422 static int airo_get_retry(struct net_device *dev,
6423                           struct iw_request_info *info,
6424                           struct iw_param *vwrq,
6425                           char *extra)
6426 {
6427         struct airo_info *local = dev->priv;
6428
6429         vwrq->disabled = 0;      /* Can't be disabled */
6430
6431         readConfigRid(local, 1);
6432         /* Note : by default, display the min retry number */
6433         if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6434                 vwrq->flags = IW_RETRY_LIFETIME;
6435                 vwrq->value = (int)local->config.txLifetime * 1024;
6436         } else if((vwrq->flags & IW_RETRY_MAX)) {
6437                 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
6438                 vwrq->value = (int)local->config.longRetryLimit;
6439         } else {
6440                 vwrq->flags = IW_RETRY_LIMIT;
6441                 vwrq->value = (int)local->config.shortRetryLimit;
6442                 if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
6443                         vwrq->flags |= IW_RETRY_MIN;
6444         }
6445
6446         return 0;
6447 }
6448
6449 /*------------------------------------------------------------------*/
6450 /*
6451  * Wireless Handler : get range info
6452  */
6453 static int airo_get_range(struct net_device *dev,
6454                           struct iw_request_info *info,
6455                           struct iw_point *dwrq,
6456                           char *extra)
6457 {
6458         struct airo_info *local = dev->priv;
6459         struct iw_range *range = (struct iw_range *) extra;
6460         CapabilityRid cap_rid;          /* Card capability info */
6461         int             i;
6462         int             k;
6463
6464         readCapabilityRid(local, &cap_rid, 1);
6465
6466         dwrq->length = sizeof(struct iw_range);
6467         memset(range, 0, sizeof(*range));
6468         range->min_nwid = 0x0000;
6469         range->max_nwid = 0x0000;
6470         range->num_channels = 14;
6471         /* Should be based on cap_rid.country to give only
6472          * what the current card support */
6473         k = 0;
6474         for(i = 0; i < 14; i++) {
6475                 range->freq[k].i = i + 1; /* List index */
6476                 range->freq[k].m = frequency_list[i] * 100000;
6477                 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
6478         }
6479         range->num_frequency = k;
6480
6481         /* Hum... Should put the right values there */
6482         range->max_qual.qual = airo_get_max_quality(&cap_rid);
6483         range->max_qual.level = 0x100 - 120;    /* -120 dBm */
6484         range->max_qual.noise = 0;
6485         range->sensitivity = 65535;
6486
6487         for(i = 0 ; i < 8 ; i++) {
6488                 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6489                 if(range->bitrate[i] == 0)
6490                         break;
6491         }
6492         range->num_bitrates = i;
6493
6494         /* Set an indication of the max TCP throughput
6495          * in bit/s that we can expect using this interface.
6496          * May be use for QoS stuff... Jean II */
6497         if(i > 2)
6498                 range->throughput = 5000 * 1000;
6499         else
6500                 range->throughput = 1500 * 1000;
6501
6502         range->min_rts = 0;
6503         range->max_rts = 2312;
6504         range->min_frag = 256;
6505         range->max_frag = 2312;
6506
6507         if(cap_rid.softCap & 2) {
6508                 // WEP: RC4 40 bits
6509                 range->encoding_size[0] = 5;
6510                 // RC4 ~128 bits
6511                 if (cap_rid.softCap & 0x100) {
6512                         range->encoding_size[1] = 13;
6513                         range->num_encoding_sizes = 2;
6514                 } else
6515                         range->num_encoding_sizes = 1;
6516                 range->max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1;
6517         } else {
6518                 range->num_encoding_sizes = 0;
6519                 range->max_encoding_tokens = 0;
6520         }
6521         range->min_pmp = 0;
6522         range->max_pmp = 5000000;       /* 5 secs */
6523         range->min_pmt = 0;
6524         range->max_pmt = 65535 * 1024;  /* ??? */
6525         range->pmp_flags = IW_POWER_PERIOD;
6526         range->pmt_flags = IW_POWER_TIMEOUT;
6527         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
6528
6529         /* Transmit Power - values are in mW */
6530         for(i = 0 ; i < 8 ; i++) {
6531                 range->txpower[i] = cap_rid.txPowerLevels[i];
6532                 if(range->txpower[i] == 0)
6533                         break;
6534         }
6535         range->num_txpower = i;
6536         range->txpower_capa = IW_TXPOW_MWATT;
6537         range->we_version_source = 12;
6538         range->we_version_compiled = WIRELESS_EXT;
6539         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
6540         range->retry_flags = IW_RETRY_LIMIT;
6541         range->r_time_flags = IW_RETRY_LIFETIME;
6542         range->min_retry = 1;
6543         range->max_retry = 65535;
6544         range->min_r_time = 1024;
6545         range->max_r_time = 65535 * 1024;
6546         /* Experimental measurements - boundary 11/5.5 Mb/s */
6547         /* Note : with or without the (local->rssi), results
6548          * are somewhat different. - Jean II */
6549         range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6550         if (local->rssi)
6551                 range->avg_qual.level = 186;    /* -70 dBm */
6552         else
6553                 range->avg_qual.level = 176;    /* -80 dBm */
6554         range->avg_qual.noise = 0;
6555
6556         /* Event capability (kernel + driver) */
6557         range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
6558                                 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
6559                                 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
6560                                 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
6561         range->event_capa[1] = IW_EVENT_CAPA_K_1;
6562         range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
6563         return 0;
6564 }
6565
6566 /*------------------------------------------------------------------*/
6567 /*
6568  * Wireless Handler : set Power Management
6569  */
6570 static int airo_set_power(struct net_device *dev,
6571                           struct iw_request_info *info,
6572                           struct iw_param *vwrq,
6573                           char *extra)
6574 {
6575         struct airo_info *local = dev->priv;
6576
6577         readConfigRid(local, 1);
6578         if (vwrq->disabled) {
6579                 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6580                         return -EINVAL;
6581                 }
6582                 local->config.powerSaveMode = POWERSAVE_CAM;
6583                 local->config.rmode &= 0xFF00;
6584                 local->config.rmode |= RXMODE_BC_MC_ADDR;
6585                 set_bit (FLAG_COMMIT, &local->flags);
6586                 return -EINPROGRESS;            /* Call commit handler */
6587         }
6588         if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6589                 local->config.fastListenDelay = (vwrq->value + 500) / 1024;
6590                 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6591                 set_bit (FLAG_COMMIT, &local->flags);
6592         } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
6593                 local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
6594                 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6595                 set_bit (FLAG_COMMIT, &local->flags);
6596         }
6597         switch (vwrq->flags & IW_POWER_MODE) {
6598                 case IW_POWER_UNICAST_R:
6599                         if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6600                                 return -EINVAL;
6601                         }
6602                         local->config.rmode &= 0xFF00;
6603                         local->config.rmode |= RXMODE_ADDR;
6604                         set_bit (FLAG_COMMIT, &local->flags);
6605                         break;
6606                 case IW_POWER_ALL_R:
6607                         if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6608                                 return -EINVAL;
6609                         }
6610                         local->config.rmode &= 0xFF00;
6611                         local->config.rmode |= RXMODE_BC_MC_ADDR;
6612                         set_bit (FLAG_COMMIT, &local->flags);
6613                 case IW_POWER_ON:
6614                         break;
6615                 default:
6616                         return -EINVAL;
6617         }
6618         // Note : we may want to factor local->need_commit here
6619         // Note2 : may also want to factor RXMODE_RFMON test
6620         return -EINPROGRESS;            /* Call commit handler */
6621 }
6622
6623 /*------------------------------------------------------------------*/
6624 /*
6625  * Wireless Handler : get Power Management
6626  */
6627 static int airo_get_power(struct net_device *dev,
6628                           struct iw_request_info *info,
6629                           struct iw_param *vwrq,
6630                           char *extra)
6631 {
6632         struct airo_info *local = dev->priv;
6633         int mode;
6634
6635         readConfigRid(local, 1);
6636         mode = local->config.powerSaveMode;
6637         if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
6638                 return 0;
6639         if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6640                 vwrq->value = (int)local->config.fastListenDelay * 1024;
6641                 vwrq->flags = IW_POWER_TIMEOUT;
6642         } else {
6643                 vwrq->value = (int)local->config.fastListenInterval * 1024;
6644                 vwrq->flags = IW_POWER_PERIOD;
6645         }
6646         if ((local->config.rmode & 0xFF) == RXMODE_ADDR)
6647                 vwrq->flags |= IW_POWER_UNICAST_R;
6648         else
6649                 vwrq->flags |= IW_POWER_ALL_R;
6650
6651         return 0;
6652 }
6653
6654 /*------------------------------------------------------------------*/
6655 /*
6656  * Wireless Handler : set Sensitivity
6657  */
6658 static int airo_set_sens(struct net_device *dev,
6659                          struct iw_request_info *info,
6660                          struct iw_param *vwrq,
6661                          char *extra)
6662 {
6663         struct airo_info *local = dev->priv;
6664
6665         readConfigRid(local, 1);
6666         local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
6667         set_bit (FLAG_COMMIT, &local->flags);
6668
6669         return -EINPROGRESS;            /* Call commit handler */
6670 }
6671
6672 /*------------------------------------------------------------------*/
6673 /*
6674  * Wireless Handler : get Sensitivity
6675  */
6676 static int airo_get_sens(struct net_device *dev,
6677                          struct iw_request_info *info,
6678                          struct iw_param *vwrq,
6679                          char *extra)
6680 {
6681         struct airo_info *local = dev->priv;
6682
6683         readConfigRid(local, 1);
6684         vwrq->value = local->config.rssiThreshold;
6685         vwrq->disabled = (vwrq->value == 0);
6686         vwrq->fixed = 1;
6687
6688         return 0;
6689 }
6690
6691 /*------------------------------------------------------------------*/
6692 /*
6693  * Wireless Handler : get AP List
6694  * Note : this is deprecated in favor of IWSCAN
6695  */
6696 static int airo_get_aplist(struct net_device *dev,
6697                            struct iw_request_info *info,
6698                            struct iw_point *dwrq,
6699                            char *extra)
6700 {
6701         struct airo_info *local = dev->priv;
6702         struct sockaddr *address = (struct sockaddr *) extra;
6703         struct iw_quality qual[IW_MAX_AP];
6704         BSSListRid BSSList;
6705         int i;
6706         int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
6707
6708         for (i = 0; i < IW_MAX_AP; i++) {
6709                 if (readBSSListRid(local, loseSync, &BSSList))
6710                         break;
6711                 loseSync = 0;
6712                 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
6713                 address[i].sa_family = ARPHRD_ETHER;
6714                 if (local->rssi)
6715                         qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
6716                 else
6717                         qual[i].level = (BSSList.rssi + 321) / 2;
6718                 qual[i].qual = qual[i].noise = 0;
6719                 qual[i].updated = 2;
6720                 if (BSSList.index == 0xffff)
6721                         break;
6722         }
6723         if (!i) {
6724                 StatusRid status_rid;           /* Card status info */
6725                 readStatusRid(local, &status_rid, 1);
6726                 for (i = 0;
6727                      i < min(IW_MAX_AP, 4) &&
6728                              (status_rid.bssid[i][0]
6729                               & status_rid.bssid[i][1]
6730                               & status_rid.bssid[i][2]
6731                               & status_rid.bssid[i][3]
6732                               & status_rid.bssid[i][4]
6733                               & status_rid.bssid[i][5])!=0xff &&
6734                              (status_rid.bssid[i][0]
6735                               | status_rid.bssid[i][1]
6736                               | status_rid.bssid[i][2]
6737                               | status_rid.bssid[i][3]
6738                               | status_rid.bssid[i][4]
6739                               | status_rid.bssid[i][5]);
6740                      i++) {
6741                         memcpy(address[i].sa_data,
6742                                status_rid.bssid[i], ETH_ALEN);
6743                         address[i].sa_family = ARPHRD_ETHER;
6744                 }
6745         } else {
6746                 dwrq->flags = 1; /* Should be define'd */
6747                 memcpy(extra + sizeof(struct sockaddr)*i,
6748                        &qual,  sizeof(struct iw_quality)*i);
6749         }
6750         dwrq->length = i;
6751
6752         return 0;
6753 }
6754
6755 /*------------------------------------------------------------------*/
6756 /*
6757  * Wireless Handler : Initiate Scan
6758  */
6759 static int airo_set_scan(struct net_device *dev,
6760                          struct iw_request_info *info,
6761                          struct iw_param *vwrq,
6762                          char *extra)
6763 {
6764         struct airo_info *ai = dev->priv;
6765         Cmd cmd;
6766         Resp rsp;
6767
6768         /* Note : you may have realised that, as this is a SET operation,
6769          * this is privileged and therefore a normal user can't
6770          * perform scanning.
6771          * This is not an error, while the device perform scanning,
6772          * traffic doesn't flow, so it's a perfect DoS...
6773          * Jean II */
6774         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
6775
6776         /* Initiate a scan command */
6777         memset(&cmd, 0, sizeof(cmd));
6778         cmd.cmd=CMD_LISTBSS;
6779         if (down_interruptible(&ai->sem))
6780                 return -ERESTARTSYS;
6781         issuecommand(ai, &cmd, &rsp);
6782         ai->scan_timestamp = jiffies;
6783         up(&ai->sem);
6784
6785         /* At this point, just return to the user. */
6786
6787         return 0;
6788 }
6789
6790 /*------------------------------------------------------------------*/
6791 /*
6792  * Translate scan data returned from the card to a card independent
6793  * format that the Wireless Tools will understand - Jean II
6794  */
6795 static inline char *airo_translate_scan(struct net_device *dev,
6796                                         char *current_ev,
6797                                         char *end_buf,
6798                                         BSSListRid *list)
6799 {
6800         struct airo_info *ai = dev->priv;
6801         struct iw_event         iwe;            /* Temporary buffer */
6802         u16                     capabilities;
6803         char *                  current_val;    /* For rates */
6804         int                     i;
6805
6806         /* First entry *MUST* be the AP MAC address */
6807         iwe.cmd = SIOCGIWAP;
6808         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
6809         memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
6810         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
6811
6812         /* Other entries will be displayed in the order we give them */
6813
6814         /* Add the ESSID */
6815         iwe.u.data.length = list->ssidLen;
6816         if(iwe.u.data.length > 32)
6817                 iwe.u.data.length = 32;
6818         iwe.cmd = SIOCGIWESSID;
6819         iwe.u.data.flags = 1;
6820         current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
6821
6822         /* Add mode */
6823         iwe.cmd = SIOCGIWMODE;
6824         capabilities = le16_to_cpu(list->cap);
6825         if(capabilities & (CAP_ESS | CAP_IBSS)) {
6826                 if(capabilities & CAP_ESS)
6827                         iwe.u.mode = IW_MODE_MASTER;
6828                 else
6829                         iwe.u.mode = IW_MODE_ADHOC;
6830                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
6831         }
6832
6833         /* Add frequency */
6834         iwe.cmd = SIOCGIWFREQ;
6835         iwe.u.freq.m = le16_to_cpu(list->dsChannel);
6836         iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
6837         iwe.u.freq.e = 1;
6838         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
6839
6840         /* Add quality statistics */
6841         iwe.cmd = IWEVQUAL;
6842         if (ai->rssi)
6843                 iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm;
6844         else
6845                 iwe.u.qual.level = (list->rssi + 321) / 2;
6846         iwe.u.qual.noise = 0;
6847         iwe.u.qual.qual = 0;
6848         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
6849
6850         /* Add encryption capability */
6851         iwe.cmd = SIOCGIWENCODE;
6852         if(capabilities & CAP_PRIVACY)
6853                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
6854         else
6855                 iwe.u.data.flags = IW_ENCODE_DISABLED;
6856         iwe.u.data.length = 0;
6857         current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
6858
6859         /* Rate : stuffing multiple values in a single event require a bit
6860          * more of magic - Jean II */
6861         current_val = current_ev + IW_EV_LCP_LEN;
6862
6863         iwe.cmd = SIOCGIWRATE;
6864         /* Those two flags are ignored... */
6865         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
6866         /* Max 8 values */
6867         for(i = 0 ; i < 8 ; i++) {
6868                 /* NULL terminated */
6869                 if(list->rates[i] == 0)
6870                         break;
6871                 /* Bit rate given in 500 kb/s units (+ 0x80) */
6872                 iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000);
6873                 /* Add new value to event */
6874                 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
6875         }
6876         /* Check if we added any event */
6877         if((current_val - current_ev) > IW_EV_LCP_LEN)
6878                 current_ev = current_val;
6879
6880         /* The other data in the scan result are not really
6881          * interesting, so for now drop it - Jean II */
6882         return current_ev;
6883 }
6884
6885 /*------------------------------------------------------------------*/
6886 /*
6887  * Wireless Handler : Read Scan Results
6888  */
6889 static int airo_get_scan(struct net_device *dev,
6890                          struct iw_request_info *info,
6891                          struct iw_point *dwrq,
6892                          char *extra)
6893 {
6894         struct airo_info *ai = dev->priv;
6895         BSSListRid BSSList;
6896         int rc;
6897         char *current_ev = extra;
6898
6899         /* When we are associated again, the scan has surely finished.
6900          * Just in case, let's make sure enough time has elapsed since
6901          * we started the scan. - Javier */
6902         if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) {
6903                 /* Important note : we don't want to block the caller
6904                  * until results are ready for various reasons.
6905                  * First, managing wait queues is complex and racy
6906                  * (there may be multiple simultaneous callers).
6907                  * Second, we grab some rtnetlink lock before comming
6908                  * here (in dev_ioctl()).
6909                  * Third, the caller can wait on the Wireless Event
6910                  * - Jean II */
6911                 return -EAGAIN;
6912         }
6913         ai->scan_timestamp = 0;
6914
6915         /* There's only a race with proc_BSSList_open(), but its
6916          * consequences are begnign. So I don't bother fixing it - Javier */
6917
6918         /* Try to read the first entry of the scan result */
6919         rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1);
6920         if((rc) || (BSSList.index == 0xffff)) {
6921                 /* Client error, no scan results...
6922                  * The caller need to restart the scan. */
6923                 return -ENODATA;
6924         }
6925
6926         /* Read and parse all entries */
6927         while((!rc) && (BSSList.index != 0xffff)) {
6928                 /* Translate to WE format this entry */
6929                 current_ev = airo_translate_scan(dev, current_ev,
6930                                                  extra + dwrq->length,
6931                                                  &BSSList);
6932
6933                 /* Check if there is space for one more entry */
6934                 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
6935                         /* Ask user space to try again with a bigger buffer */
6936                         return -E2BIG;
6937                 }
6938
6939                 /* Read next entry */
6940                 rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
6941                                     &BSSList, sizeof(BSSList), 1);
6942         }
6943         /* Length of data */
6944         dwrq->length = (current_ev - extra);
6945         dwrq->flags = 0;        /* todo */
6946
6947         return 0;
6948 }
6949
6950 /*------------------------------------------------------------------*/
6951 /*
6952  * Commit handler : called after a bunch of SET operations
6953  */
6954 static int airo_config_commit(struct net_device *dev,
6955                               struct iw_request_info *info,     /* NULL */
6956                               void *zwrq,                       /* NULL */
6957                               char *extra)                      /* NULL */
6958 {
6959         struct airo_info *local = dev->priv;
6960         Resp rsp;
6961
6962         if (!test_bit (FLAG_COMMIT, &local->flags))
6963                 return 0;
6964
6965         /* Some of the "SET" function may have modified some of the
6966          * parameters. It's now time to commit them in the card */
6967         disable_MAC(local, 1);
6968         if (test_bit (FLAG_RESET, &local->flags)) {
6969                 APListRid APList_rid;
6970                 SsidRid SSID_rid;
6971
6972                 readAPListRid(local, &APList_rid);
6973                 readSsidRid(local, &SSID_rid);
6974                 if (test_bit(FLAG_MPI,&local->flags))
6975                         setup_card(local, dev->dev_addr, 1 );
6976                 else
6977                         reset_airo_card(dev);
6978                 disable_MAC(local, 1);
6979                 writeSsidRid(local, &SSID_rid, 1);
6980                 writeAPListRid(local, &APList_rid, 1);
6981         }
6982         if (down_interruptible(&local->sem))
6983                 return -ERESTARTSYS;
6984         writeConfigRid(local, 0);
6985         enable_MAC(local, &rsp, 0);
6986         if (test_bit (FLAG_RESET, &local->flags))
6987                 airo_set_promisc(local);
6988         else
6989                 up(&local->sem);
6990
6991         return 0;
6992 }
6993
6994 /*------------------------------------------------------------------*/
6995 /*
6996  * Structures to export the Wireless Handlers
6997  */
6998
6999 static const struct iw_priv_args airo_private_args[] = {
7000 /*{ cmd,         set_args,                            get_args, name } */
7001   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7002     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7003   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7004     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7005 };
7006
7007 static const iw_handler         airo_handler[] =
7008 {
7009         (iw_handler) airo_config_commit,        /* SIOCSIWCOMMIT */
7010         (iw_handler) airo_get_name,             /* SIOCGIWNAME */
7011         (iw_handler) NULL,                      /* SIOCSIWNWID */
7012         (iw_handler) NULL,                      /* SIOCGIWNWID */
7013         (iw_handler) airo_set_freq,             /* SIOCSIWFREQ */
7014         (iw_handler) airo_get_freq,             /* SIOCGIWFREQ */
7015         (iw_handler) airo_set_mode,             /* SIOCSIWMODE */
7016         (iw_handler) airo_get_mode,             /* SIOCGIWMODE */
7017         (iw_handler) airo_set_sens,             /* SIOCSIWSENS */
7018         (iw_handler) airo_get_sens,             /* SIOCGIWSENS */
7019         (iw_handler) NULL,                      /* SIOCSIWRANGE */
7020         (iw_handler) airo_get_range,            /* SIOCGIWRANGE */
7021         (iw_handler) NULL,                      /* SIOCSIWPRIV */
7022         (iw_handler) NULL,                      /* SIOCGIWPRIV */
7023         (iw_handler) NULL,                      /* SIOCSIWSTATS */
7024         (iw_handler) NULL,                      /* SIOCGIWSTATS */
7025         iw_handler_set_spy,                     /* SIOCSIWSPY */
7026         iw_handler_get_spy,                     /* SIOCGIWSPY */
7027         iw_handler_set_thrspy,                  /* SIOCSIWTHRSPY */
7028         iw_handler_get_thrspy,                  /* SIOCGIWTHRSPY */
7029         (iw_handler) airo_set_wap,              /* SIOCSIWAP */
7030         (iw_handler) airo_get_wap,              /* SIOCGIWAP */
7031         (iw_handler) NULL,                      /* -- hole -- */
7032         (iw_handler) airo_get_aplist,           /* SIOCGIWAPLIST */
7033         (iw_handler) airo_set_scan,             /* SIOCSIWSCAN */
7034         (iw_handler) airo_get_scan,             /* SIOCGIWSCAN */
7035         (iw_handler) airo_set_essid,            /* SIOCSIWESSID */
7036         (iw_handler) airo_get_essid,            /* SIOCGIWESSID */
7037         (iw_handler) airo_set_nick,             /* SIOCSIWNICKN */
7038         (iw_handler) airo_get_nick,             /* SIOCGIWNICKN */
7039         (iw_handler) NULL,                      /* -- hole -- */
7040         (iw_handler) NULL,                      /* -- hole -- */
7041         (iw_handler) airo_set_rate,             /* SIOCSIWRATE */
7042         (iw_handler) airo_get_rate,             /* SIOCGIWRATE */
7043         (iw_handler) airo_set_rts,              /* SIOCSIWRTS */
7044         (iw_handler) airo_get_rts,              /* SIOCGIWRTS */
7045         (iw_handler) airo_set_frag,             /* SIOCSIWFRAG */
7046         (iw_handler) airo_get_frag,             /* SIOCGIWFRAG */
7047         (iw_handler) airo_set_txpow,            /* SIOCSIWTXPOW */
7048         (iw_handler) airo_get_txpow,            /* SIOCGIWTXPOW */
7049         (iw_handler) airo_set_retry,            /* SIOCSIWRETRY */
7050         (iw_handler) airo_get_retry,            /* SIOCGIWRETRY */
7051         (iw_handler) airo_set_encode,           /* SIOCSIWENCODE */
7052         (iw_handler) airo_get_encode,           /* SIOCGIWENCODE */
7053         (iw_handler) airo_set_power,            /* SIOCSIWPOWER */
7054         (iw_handler) airo_get_power,            /* SIOCGIWPOWER */
7055 };
7056
7057 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7058  * We want to force the use of the ioctl code, because those can't be
7059  * won't work the iw_handler code (because they simultaneously read
7060  * and write data and iw_handler can't do that).
7061  * Note that it's perfectly legal to read/write on a single ioctl command,
7062  * you just can't use iwpriv and need to force it via the ioctl handler.
7063  * Jean II */
7064 static const iw_handler         airo_private_handler[] =
7065 {
7066         NULL,                           /* SIOCIWFIRSTPRIV */
7067 };
7068
7069 static const struct iw_handler_def      airo_handler_def =
7070 {
7071         .num_standard   = sizeof(airo_handler)/sizeof(iw_handler),
7072         .num_private    = sizeof(airo_private_handler)/sizeof(iw_handler),
7073         .num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args),
7074         .standard       = airo_handler,
7075         .private        = airo_private_handler,
7076         .private_args   = airo_private_args,
7077         .get_wireless_stats = airo_get_wireless_stats,
7078 };
7079
7080 #endif /* WIRELESS_EXT */
7081
7082 /*
7083  * This defines the configuration part of the Wireless Extensions
7084  * Note : irq and spinlock protection will occur in the subroutines
7085  *
7086  * TODO :
7087  *      o Check input value more carefully and fill correct values in range
7088  *      o Test and shakeout the bugs (if any)
7089  *
7090  * Jean II
7091  *
7092  * Javier Achirica did a great job of merging code from the unnamed CISCO
7093  * developer that added support for flashing the card.
7094  */
7095 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7096 {
7097         int rc = 0;
7098         struct airo_info *ai = (struct airo_info *)dev->priv;
7099
7100         if (ai->power)
7101                 return 0;
7102
7103         switch (cmd) {
7104 #ifdef CISCO_EXT
7105         case AIROIDIFC:
7106 #ifdef AIROOLDIDIFC
7107         case AIROOLDIDIFC:
7108 #endif
7109         {
7110                 int val = AIROMAGIC;
7111                 aironet_ioctl com;
7112                 if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
7113                         rc = -EFAULT;
7114                 else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
7115                         rc = -EFAULT;
7116         }
7117         break;
7118
7119         case AIROIOCTL:
7120 #ifdef AIROOLDIOCTL
7121         case AIROOLDIOCTL:
7122 #endif
7123                 /* Get the command struct and hand it off for evaluation by
7124                  * the proper subfunction
7125                  */
7126         {
7127                 aironet_ioctl com;
7128                 if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
7129                         rc = -EFAULT;
7130                         break;
7131                 }
7132
7133                 /* Separate R/W functions bracket legality here
7134                  */
7135                 if ( com.command == AIRORSWVERSION ) {
7136                         if (copy_to_user(com.data, swversion, sizeof(swversion)))
7137                                 rc = -EFAULT;
7138                         else
7139                                 rc = 0;
7140                 }
7141                 else if ( com.command <= AIRORRID)
7142                         rc = readrids(dev,&com);
7143                 else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
7144                         rc = writerids(dev,&com);
7145                 else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
7146                         rc = flashcard(dev,&com);
7147                 else
7148                         rc = -EINVAL;      /* Bad command in ioctl */
7149         }
7150         break;
7151 #endif /* CISCO_EXT */
7152
7153         // All other calls are currently unsupported
7154         default:
7155                 rc = -EOPNOTSUPP;
7156         }
7157         return rc;
7158 }
7159
7160 #ifdef WIRELESS_EXT
7161 /*
7162  * Get the Wireless stats out of the driver
7163  * Note : irq and spinlock protection will occur in the subroutines
7164  *
7165  * TODO :
7166  *      o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7167  *
7168  * Jean
7169  */
7170 static void airo_read_wireless_stats(struct airo_info *local)
7171 {
7172         StatusRid status_rid;
7173         StatsRid stats_rid;
7174         CapabilityRid cap_rid;
7175         u32 *vals = stats_rid.vals;
7176
7177         /* Get stats out of the card */
7178         clear_bit(JOB_WSTATS, &local->flags);
7179         if (local->power) {
7180                 up(&local->sem);
7181                 return;
7182         }
7183         readCapabilityRid(local, &cap_rid, 0);
7184         readStatusRid(local, &status_rid, 0);
7185         readStatsRid(local, &stats_rid, RID_STATS, 0);
7186         up(&local->sem);
7187
7188         /* The status */
7189         local->wstats.status = status_rid.mode;
7190
7191         /* Signal quality and co. But where is the noise level ??? */
7192         local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7193         if (local->rssi)
7194                 local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
7195         else
7196                 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
7197         if (status_rid.len >= 124) {
7198                 local->wstats.qual.noise = 256 - status_rid.noisedBm;
7199                 local->wstats.qual.updated = 7;
7200         } else {
7201                 local->wstats.qual.noise = 0;
7202                 local->wstats.qual.updated = 3;
7203         }
7204
7205         /* Packets discarded in the wireless adapter due to wireless
7206          * specific problems */
7207         local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
7208         local->wstats.discard.code = vals[6];/* RxWepErr */
7209         local->wstats.discard.fragment = vals[30];
7210         local->wstats.discard.retries = vals[10];
7211         local->wstats.discard.misc = vals[1] + vals[32];
7212         local->wstats.miss.beacon = vals[34];
7213 }
7214
7215 struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7216 {
7217         struct airo_info *local =  dev->priv;
7218
7219         if (!test_bit(JOB_WSTATS, &local->flags)) {
7220                 /* Get stats out of the card if available */
7221                 if (down_trylock(&local->sem) != 0) {
7222                         set_bit(JOB_WSTATS, &local->flags);
7223                         wake_up_interruptible(&local->thr_wait);
7224                 } else
7225                         airo_read_wireless_stats(local);
7226         }
7227
7228         return &local->wstats;
7229 }
7230 #endif /* WIRELESS_EXT */
7231
7232 #ifdef CISCO_EXT
7233 /*
7234  * This just translates from driver IOCTL codes to the command codes to
7235  * feed to the radio's host interface. Things can be added/deleted
7236  * as needed.  This represents the READ side of control I/O to
7237  * the card
7238  */
7239 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
7240         unsigned short ridcode;
7241         unsigned char *iobuf;
7242         int len;
7243         struct airo_info *ai = dev->priv;
7244         Resp rsp;
7245
7246         if (test_bit(FLAG_FLASHING, &ai->flags))
7247                 return -EIO;
7248
7249         switch(comp->command)
7250         {
7251         case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7252         case AIROGCFG:      ridcode = RID_CONFIG;
7253                 if (test_bit(FLAG_COMMIT, &ai->flags)) {
7254                         disable_MAC (ai, 1);
7255                         writeConfigRid (ai, 1);
7256                         enable_MAC (ai, &rsp, 1);
7257                 }
7258                 break;
7259         case AIROGSLIST:    ridcode = RID_SSID;         break;
7260         case AIROGVLIST:    ridcode = RID_APLIST;       break;
7261         case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7262         case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7263         case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
7264                 /* Only super-user can read WEP keys */
7265                 if (!capable(CAP_NET_ADMIN))
7266                         return -EPERM;
7267                 break;
7268         case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
7269                 /* Only super-user can read WEP keys */
7270                 if (!capable(CAP_NET_ADMIN))
7271                         return -EPERM;
7272                 break;
7273         case AIROGSTAT:     ridcode = RID_STATUS;       break;
7274         case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7275         case AIROGSTATSC32: ridcode = RID_STATS;        break;
7276 #ifdef MICSUPPORT
7277         case AIROGMICSTATS:
7278                 if (copy_to_user(comp->data, &ai->micstats,
7279                                  min((int)comp->len,(int)sizeof(ai->micstats))))
7280                         return -EFAULT;
7281                 return 0;
7282 #endif
7283         case AIRORRID:      ridcode = comp->ridnum;     break;
7284         default:
7285                 return -EINVAL;
7286                 break;
7287         }
7288
7289         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7290                 return -ENOMEM;
7291
7292         PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
7293         /* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7294          * then return it to the user
7295          * 9/22/2000 Honor user given length
7296          */
7297         len = comp->len;
7298
7299         if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7300                 kfree (iobuf);
7301                 return -EFAULT;
7302         }
7303         kfree (iobuf);
7304         return 0;
7305 }
7306
7307 /*
7308  * Danger Will Robinson write the rids here
7309  */
7310
7311 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7312         struct airo_info *ai = dev->priv;
7313         int  ridcode;
7314 #ifdef MICSUPPORT
7315         int  enabled;
7316 #endif
7317         Resp      rsp;
7318         static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
7319         unsigned char *iobuf;
7320
7321         /* Only super-user can write RIDs */
7322         if (!capable(CAP_NET_ADMIN))
7323                 return -EPERM;
7324
7325         if (test_bit(FLAG_FLASHING, &ai->flags))
7326                 return -EIO;
7327
7328         ridcode = 0;
7329         writer = do_writerid;
7330
7331         switch(comp->command)
7332         {
7333         case AIROPSIDS:     ridcode = RID_SSID;         break;
7334         case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7335         case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7336         case AIROPCFG: ai->config.len = 0;
7337                             clear_bit(FLAG_COMMIT, &ai->flags);
7338                             ridcode = RID_CONFIG;       break;
7339         case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7340         case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7341         case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7342         case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7343                 break;
7344         case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7345         case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7346
7347                 /* this is not really a rid but a command given to the card
7348                  * same with MAC off
7349                  */
7350         case AIROPMACON:
7351                 if (enable_MAC(ai, &rsp, 1) != 0)
7352                         return -EIO;
7353                 return 0;
7354
7355                 /*
7356                  * Evidently this code in the airo driver does not get a symbol
7357                  * as disable_MAC. it's probably so short the compiler does not gen one.
7358                  */
7359         case AIROPMACOFF:
7360                 disable_MAC(ai, 1);
7361                 return 0;
7362
7363                 /* This command merely clears the counts does not actually store any data
7364                  * only reads rid. But as it changes the cards state, I put it in the
7365                  * writerid routines.
7366                  */
7367         case AIROPSTCLR:
7368                 if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7369                         return -ENOMEM;
7370
7371                 PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
7372
7373 #ifdef MICSUPPORT
7374                 enabled = ai->micstats.enabled;
7375                 memset(&ai->micstats,0,sizeof(ai->micstats));
7376                 ai->micstats.enabled = enabled;
7377 #endif
7378
7379                 if (copy_to_user(comp->data, iobuf,
7380                                  min((int)comp->len, (int)RIDSIZE))) {
7381                         kfree (iobuf);
7382                         return -EFAULT;
7383                 }
7384                 kfree (iobuf);
7385                 return 0;
7386
7387         default:
7388                 return -EOPNOTSUPP;     /* Blarg! */
7389         }
7390         if(comp->len > RIDSIZE)
7391                 return -EINVAL;
7392
7393         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7394                 return -ENOMEM;
7395
7396         if (copy_from_user(iobuf,comp->data,comp->len)) {
7397                 kfree (iobuf);
7398                 return -EFAULT;
7399         }
7400
7401         if (comp->command == AIROPCFG) {
7402                 ConfigRid *cfg = (ConfigRid *)iobuf;
7403
7404                 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7405                         cfg->opmode |= MODE_MIC;
7406
7407                 if ((cfg->opmode & 0xFF) == MODE_STA_IBSS)
7408                         set_bit (FLAG_ADHOC, &ai->flags);
7409                 else
7410                         clear_bit (FLAG_ADHOC, &ai->flags);
7411         }
7412
7413         if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
7414                 kfree (iobuf);
7415                 return -EIO;
7416         }
7417         kfree (iobuf);
7418         return 0;
7419 }
7420
7421 /*****************************************************************************
7422  * Ancillary flash / mod functions much black magic lurkes here              *
7423  *****************************************************************************
7424  */
7425
7426 /*
7427  * Flash command switch table
7428  */
7429
7430 int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7431         int z;
7432         int cmdreset(struct airo_info *);
7433         int setflashmode(struct airo_info *);
7434         int flashgchar(struct airo_info *,int,int);
7435         int flashpchar(struct airo_info *,int,int);
7436         int flashputbuf(struct airo_info *);
7437         int flashrestart(struct airo_info *,struct net_device *);
7438
7439         /* Only super-user can modify flash */
7440         if (!capable(CAP_NET_ADMIN))
7441                 return -EPERM;
7442
7443         switch(comp->command)
7444         {
7445         case AIROFLSHRST:
7446                 return cmdreset((struct airo_info *)dev->priv);
7447
7448         case AIROFLSHSTFL:
7449                 if (!((struct airo_info *)dev->priv)->flash &&
7450                         (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
7451                         return -ENOMEM;
7452                 return setflashmode((struct airo_info *)dev->priv);
7453
7454         case AIROFLSHGCHR: /* Get char from aux */
7455                 if(comp->len != sizeof(int))
7456                         return -EINVAL;
7457                 if (copy_from_user(&z,comp->data,comp->len))
7458                         return -EFAULT;
7459                 return flashgchar((struct airo_info *)dev->priv,z,8000);
7460
7461         case AIROFLSHPCHR: /* Send char to card. */
7462                 if(comp->len != sizeof(int))
7463                         return -EINVAL;
7464                 if (copy_from_user(&z,comp->data,comp->len))
7465                         return -EFAULT;
7466                 return flashpchar((struct airo_info *)dev->priv,z,8000);
7467
7468         case AIROFLPUTBUF: /* Send 32k to card */
7469                 if (!((struct airo_info *)dev->priv)->flash)
7470                         return -ENOMEM;
7471                 if(comp->len > FLASHSIZE)
7472                         return -EINVAL;
7473                 if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
7474                         return -EFAULT;
7475
7476                 flashputbuf((struct airo_info *)dev->priv);
7477                 return 0;
7478
7479         case AIRORESTART:
7480                 if(flashrestart((struct airo_info *)dev->priv,dev))
7481                         return -EIO;
7482                 return 0;
7483         }
7484         return -EINVAL;
7485 }
7486
7487 #define FLASH_COMMAND  0x7e7e
7488
7489 /*
7490  * STEP 1)
7491  * Disable MAC and do soft reset on
7492  * card.
7493  */
7494
7495 int cmdreset(struct airo_info *ai) {
7496         disable_MAC(ai, 1);
7497
7498         if(!waitbusy (ai)){
7499                 printk(KERN_INFO "Waitbusy hang before RESET\n");
7500                 return -EBUSY;
7501         }
7502
7503         OUT4500(ai,COMMAND,CMD_SOFTRESET);
7504
7505         set_current_state (TASK_UNINTERRUPTIBLE);
7506         schedule_timeout (HZ);          /* WAS 600 12/7/00 */
7507
7508         if(!waitbusy (ai)){
7509                 printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
7510                 return -EBUSY;
7511         }
7512         return 0;
7513 }
7514
7515 /* STEP 2)
7516  * Put the card in legendary flash
7517  * mode
7518  */
7519
7520 int setflashmode (struct airo_info *ai) {
7521         set_bit (FLAG_FLASHING, &ai->flags);
7522
7523         OUT4500(ai, SWS0, FLASH_COMMAND);
7524         OUT4500(ai, SWS1, FLASH_COMMAND);
7525         if (probe) {
7526                 OUT4500(ai, SWS0, FLASH_COMMAND);
7527                 OUT4500(ai, COMMAND,0x10);
7528         } else {
7529                 OUT4500(ai, SWS2, FLASH_COMMAND);
7530                 OUT4500(ai, SWS3, FLASH_COMMAND);
7531                 OUT4500(ai, COMMAND,0);
7532         }
7533         set_current_state (TASK_UNINTERRUPTIBLE);
7534         schedule_timeout (HZ/2); /* 500ms delay */
7535
7536         if(!waitbusy(ai)) {
7537                 clear_bit (FLAG_FLASHING, &ai->flags);
7538                 printk(KERN_INFO "Waitbusy hang after setflash mode\n");
7539                 return -EIO;
7540         }
7541         return 0;
7542 }
7543
7544 /* Put character to SWS0 wait for dwelltime
7545  * x 50us for  echo .
7546  */
7547
7548 int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7549         int echo;
7550         int waittime;
7551
7552         byte |= 0x8000;
7553
7554         if(dwelltime == 0 )
7555                 dwelltime = 200;
7556
7557         waittime=dwelltime;
7558
7559         /* Wait for busy bit d15 to go false indicating buffer empty */
7560         while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
7561                 udelay (50);
7562                 waittime -= 50;
7563         }
7564
7565         /* timeout for busy clear wait */
7566         if(waittime <= 0 ){
7567                 printk(KERN_INFO "flash putchar busywait timeout! \n");
7568                 return -EBUSY;
7569         }
7570
7571         /* Port is clear now write byte and wait for it to echo back */
7572         do {
7573                 OUT4500(ai,SWS0,byte);
7574                 udelay(50);
7575                 dwelltime -= 50;
7576                 echo = IN4500(ai,SWS1);
7577         } while (dwelltime >= 0 && echo != byte);
7578
7579         OUT4500(ai,SWS1,0);
7580
7581         return (echo == byte) ? 0 : -EIO;
7582 }
7583
7584 /*
7585  * Get a character from the card matching matchbyte
7586  * Step 3)
7587  */
7588 int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
7589         int           rchar;
7590         unsigned char rbyte=0;
7591
7592         do {
7593                 rchar = IN4500(ai,SWS1);
7594
7595                 if(dwelltime && !(0x8000 & rchar)){
7596                         dwelltime -= 10;
7597                         mdelay(10);
7598                         continue;
7599                 }
7600                 rbyte = 0xff & rchar;
7601
7602                 if( (rbyte == matchbyte) && (0x8000 & rchar) ){
7603                         OUT4500(ai,SWS1,0);
7604                         return 0;
7605                 }
7606                 if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
7607                         break;
7608                 OUT4500(ai,SWS1,0);
7609
7610         }while(dwelltime > 0);
7611         return -EIO;
7612 }
7613
7614 /*
7615  * Transfer 32k of firmware data from user buffer to our buffer and
7616  * send to the card
7617  */
7618
7619 int flashputbuf(struct airo_info *ai){
7620         int            nwords;
7621
7622         /* Write stuff */
7623         if (test_bit(FLAG_MPI,&ai->flags))
7624                 memcpy(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
7625         else {
7626                 OUT4500(ai,AUXPAGE,0x100);
7627                 OUT4500(ai,AUXOFF,0);
7628
7629                 for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
7630                         OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
7631                 }
7632         }
7633         OUT4500(ai,SWS0,0x8000);
7634
7635         return 0;
7636 }
7637
7638 /*
7639  *
7640  */
7641 int flashrestart(struct airo_info *ai,struct net_device *dev){
7642         int    i,status;
7643
7644         set_current_state (TASK_UNINTERRUPTIBLE);
7645         schedule_timeout (HZ);          /* Added 12/7/00 */
7646         clear_bit (FLAG_FLASHING, &ai->flags);
7647         if (test_bit(FLAG_MPI, &ai->flags)) {
7648                 status = mpi_init_descriptors(ai);
7649                 if (status != SUCCESS)
7650                         return status;
7651         }
7652         status = setup_card(ai, dev->dev_addr, 1);
7653
7654         if (!test_bit(FLAG_MPI,&ai->flags))
7655                 for( i = 0; i < MAX_FIDS; i++ ) {
7656                         ai->fids[i] = transmit_allocate
7657                                 ( ai, 2312, i >= MAX_FIDS / 2 );
7658                 }
7659
7660         set_current_state (TASK_UNINTERRUPTIBLE);
7661         schedule_timeout (HZ);          /* Added 12/7/00 */
7662         return status;
7663 }
7664 #endif /* CISCO_EXT */
7665
7666 /*
7667     This program is free software; you can redistribute it and/or
7668     modify it under the terms of the GNU General Public License
7669     as published by the Free Software Foundation; either version 2
7670     of the License, or (at your option) any later version.
7671
7672     This program is distributed in the hope that it will be useful,
7673     but WITHOUT ANY WARRANTY; without even the implied warranty of
7674     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7675     GNU General Public License for more details.
7676
7677     In addition:
7678
7679     Redistribution and use in source and binary forms, with or without
7680     modification, are permitted provided that the following conditions
7681     are met:
7682
7683     1. Redistributions of source code must retain the above copyright
7684        notice, this list of conditions and the following disclaimer.
7685     2. Redistributions in binary form must reproduce the above copyright
7686        notice, this list of conditions and the following disclaimer in the
7687        documentation and/or other materials provided with the distribution.
7688     3. The name of the author may not be used to endorse or promote
7689        products derived from this software without specific prior written
7690        permission.
7691
7692     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
7693     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7694     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7695     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
7696     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7697     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7698     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7699     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
7700     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
7701     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
7702     POSSIBILITY OF SUCH DAMAGE.
7703 */
7704
7705 module_init(airo_init_module);
7706 module_exit(airo_cleanup_module);