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