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