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