airo: sanitize handling of StatusRid
[linux-2.6.git] / drivers / net / wireless / airo.c
1 /*======================================================================
2
3     Aironet driver for 4500 and 4800 series cards
4
5     This code is released under both the GPL version 2 and BSD licenses.
6     Either license may be used.  The respective licenses are found at
7     the end of this file.
8
9     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10     including portions of which come from the Aironet PC4500
11     Developer's Reference Manual and used with permission.  Copyright
12     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
13     code in the Developer's manual was granted for this driver by
14     Aironet.  Major code contributions were received from Javier Achirica
15     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
16     Code was also integrated from the Cisco Aironet driver for Linux.
17     Support for MPI350 cards was added by Fabrice Bellet
18     <fabrice@bellet.info>.
19
20 ======================================================================*/
21
22 #include <linux/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         __le16 len;
652         u8 mac[ETH_ALEN];
653         __le16 mode;
654         __le16 errorCode;
655         __le16 sigQuality;
656         __le16 SSIDlen;
657         char SSID[32];
658         char apName[16];
659         u8 bssid[4][ETH_ALEN];
660         __le16 beaconPeriod;
661         __le16 dimPeriod;
662         __le16 atimDuration;
663         __le16 hopPeriod;
664         __le16 channelSet;
665         __le16 channel;
666         __le16 hopsToBackbone;
667         __le16 apTotalLoad;
668         __le16 generatedLoad;
669         __le16 accumulatedArl;
670         __le16 signalQuality;
671         __le16 currentXmitRate;
672         __le16 apDevExtensions;
673         __le16 normalizedSignalStrength;
674         __le16 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         __le16 load;
683         u8 carrier[4];
684         __le16 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         __le16 len;
710         __le16 spacer;
711         __le32 vals[100];
712 } StatsRid;
713
714
715 typedef struct {
716         __le16 len;
717         u8 ap[4][ETH_ALEN];
718 } APListRid;
719
720 typedef struct {
721         __le16 len;
722         char oui[3];
723         char zero;
724         __le16 prodNum;
725         char manName[32];
726         char prodName[16];
727         char prodVer[8];
728         char factoryAddr[ETH_ALEN];
729         char aironetAddr[ETH_ALEN];
730         __le16 radioType;
731         __le16 country;
732         char callid[ETH_ALEN];
733         char supportedRates[8];
734         char rxDiversity;
735         char txDiversity;
736         __le16 txPowerLevels[8];
737         __le16 hardVer;
738         __le16 hardCap;
739         __le16 tempRange;
740         __le16 softVer;
741         __le16 softSubVer;
742         __le16 interfaceVer;
743         __le16 softCap;
744         __le16 bootBlockVer;
745         __le16 requiredHard;
746         __le16 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
1857 static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
1858 {
1859         return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1860 }
1861
1862 static int readAPListRid(struct airo_info *ai, APListRid *aplr)
1863 {
1864         return PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
1865 }
1866
1867 static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
1868 {
1869         return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
1870 }
1871
1872 static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
1873 {
1874         return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1875 }
1876
1877 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
1878 {
1879         return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1880 }
1881
1882 static void try_auto_wep(struct airo_info *ai)
1883 {
1884         if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) {
1885                 ai->expires = RUN_AT(3*HZ);
1886                 wake_up_interruptible(&ai->thr_wait);
1887         }
1888 }
1889
1890 static int airo_open(struct net_device *dev) {
1891         struct airo_info *ai = dev->priv;
1892         int rc = 0;
1893
1894         if (test_bit(FLAG_FLASHING, &ai->flags))
1895                 return -EIO;
1896
1897         /* Make sure the card is configured.
1898          * Wireless Extensions may postpone config changes until the card
1899          * is open (to pipeline changes and speed-up card setup). If
1900          * those changes are not yet commited, do it now - Jean II */
1901         if (test_bit(FLAG_COMMIT, &ai->flags)) {
1902                 disable_MAC(ai, 1);
1903                 writeConfigRid(ai, 1);
1904         }
1905
1906         if (ai->wifidev != dev) {
1907                 clear_bit(JOB_DIE, &ai->jobs);
1908                 ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
1909                 if (IS_ERR(ai->airo_thread_task))
1910                         return (int)PTR_ERR(ai->airo_thread_task);
1911
1912                 rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
1913                         dev->name, dev);
1914                 if (rc) {
1915                         airo_print_err(dev->name,
1916                                 "register interrupt %d failed, rc %d",
1917                                 dev->irq, rc);
1918                         set_bit(JOB_DIE, &ai->jobs);
1919                         kthread_stop(ai->airo_thread_task);
1920                         return rc;
1921                 }
1922
1923                 /* Power on the MAC controller (which may have been disabled) */
1924                 clear_bit(FLAG_RADIO_DOWN, &ai->flags);
1925                 enable_interrupts(ai);
1926
1927                 try_auto_wep(ai);
1928         }
1929         enable_MAC(ai, 1);
1930
1931         netif_start_queue(dev);
1932         return 0;
1933 }
1934
1935 static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1936         int npacks, pending;
1937         unsigned long flags;
1938         struct airo_info *ai = dev->priv;
1939
1940         if (!skb) {
1941                 airo_print_err(dev->name, "%s: skb == NULL!",__FUNCTION__);
1942                 return 0;
1943         }
1944         npacks = skb_queue_len (&ai->txq);
1945
1946         if (npacks >= MAXTXQ - 1) {
1947                 netif_stop_queue (dev);
1948                 if (npacks > MAXTXQ) {
1949                         ai->stats.tx_fifo_errors++;
1950                         return 1;
1951                 }
1952                 skb_queue_tail (&ai->txq, skb);
1953                 return 0;
1954         }
1955
1956         spin_lock_irqsave(&ai->aux_lock, flags);
1957         skb_queue_tail (&ai->txq, skb);
1958         pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
1959         spin_unlock_irqrestore(&ai->aux_lock,flags);
1960         netif_wake_queue (dev);
1961
1962         if (pending == 0) {
1963                 set_bit(FLAG_PENDING_XMIT, &ai->flags);
1964                 mpi_send_packet (dev);
1965         }
1966         return 0;
1967 }
1968
1969 /*
1970  * @mpi_send_packet
1971  *
1972  * Attempt to transmit a packet. Can be called from interrupt
1973  * or transmit . return number of packets we tried to send
1974  */
1975
1976 static int mpi_send_packet (struct net_device *dev)
1977 {
1978         struct sk_buff *skb;
1979         unsigned char *buffer;
1980         s16 len;
1981         __le16 *payloadLen;
1982         struct airo_info *ai = dev->priv;
1983         u8 *sendbuf;
1984
1985         /* get a packet to send */
1986
1987         if ((skb = skb_dequeue(&ai->txq)) == NULL) {
1988                 airo_print_err(dev->name,
1989                         "%s: Dequeue'd zero in send_packet()",
1990                         __FUNCTION__);
1991                 return 0;
1992         }
1993
1994         /* check min length*/
1995         len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1996         buffer = skb->data;
1997
1998         ai->txfids[0].tx_desc.offset = 0;
1999         ai->txfids[0].tx_desc.valid = 1;
2000         ai->txfids[0].tx_desc.eoc = 1;
2001         ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
2002
2003 /*
2004  * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
2005  * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
2006  * is immediatly after it. ------------------------------------------------
2007  *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
2008  *                         ------------------------------------------------
2009  */
2010
2011         memcpy((char *)ai->txfids[0].virtual_host_addr,
2012                 (char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
2013
2014         payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
2015                 sizeof(wifictlhdr8023));
2016         sendbuf = ai->txfids[0].virtual_host_addr +
2017                 sizeof(wifictlhdr8023) + 2 ;
2018
2019         /*
2020          * Firmware automaticly puts 802 header on so
2021          * we don't need to account for it in the length
2022          */
2023         if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
2024                 (ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
2025                 MICBuffer pMic;
2026
2027                 if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
2028                         return ERROR;
2029
2030                 *payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
2031                 ai->txfids[0].tx_desc.len += sizeof(pMic);
2032                 /* copy data into airo dma buffer */
2033                 memcpy (sendbuf, buffer, sizeof(etherHead));
2034                 buffer += sizeof(etherHead);
2035                 sendbuf += sizeof(etherHead);
2036                 memcpy (sendbuf, &pMic, sizeof(pMic));
2037                 sendbuf += sizeof(pMic);
2038                 memcpy (sendbuf, buffer, len - sizeof(etherHead));
2039         } else {
2040                 *payloadLen = cpu_to_le16(len - sizeof(etherHead));
2041
2042                 dev->trans_start = jiffies;
2043
2044                 /* copy data into airo dma buffer */
2045                 memcpy(sendbuf, buffer, len);
2046         }
2047
2048         memcpy_toio(ai->txfids[0].card_ram_off,
2049                 &ai->txfids[0].tx_desc, sizeof(TxFid));
2050
2051         OUT4500(ai, EVACK, 8);
2052
2053         dev_kfree_skb_any(skb);
2054         return 1;
2055 }
2056
2057 static void get_tx_error(struct airo_info *ai, s32 fid)
2058 {
2059         __le16 status;
2060
2061         if (fid < 0)
2062                 status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
2063         else {
2064                 if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
2065                         return;
2066                 bap_read(ai, &status, 2, BAP0);
2067         }
2068         if (le16_to_cpu(status) & 2) /* Too many retries */
2069                 ai->stats.tx_aborted_errors++;
2070         if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
2071                 ai->stats.tx_heartbeat_errors++;
2072         if (le16_to_cpu(status) & 8) /* Aid fail */
2073                 { }
2074         if (le16_to_cpu(status) & 0x10) /* MAC disabled */
2075                 ai->stats.tx_carrier_errors++;
2076         if (le16_to_cpu(status) & 0x20) /* Association lost */
2077                 { }
2078         /* We produce a TXDROP event only for retry or lifetime
2079          * exceeded, because that's the only status that really mean
2080          * that this particular node went away.
2081          * Other errors means that *we* screwed up. - Jean II */
2082         if ((le16_to_cpu(status) & 2) ||
2083              (le16_to_cpu(status) & 4)) {
2084                 union iwreq_data        wrqu;
2085                 char junk[0x18];
2086
2087                 /* Faster to skip over useless data than to do
2088                  * another bap_setup(). We are at offset 0x6 and
2089                  * need to go to 0x18 and read 6 bytes - Jean II */
2090                 bap_read(ai, (__le16 *) junk, 0x18, BAP0);
2091
2092                 /* Copy 802.11 dest address.
2093                  * We use the 802.11 header because the frame may
2094                  * not be 802.3 or may be mangled...
2095                  * In Ad-Hoc mode, it will be the node address.
2096                  * In managed mode, it will be most likely the AP addr
2097                  * User space will figure out how to convert it to
2098                  * whatever it needs (IP address or else).
2099                  * - Jean II */
2100                 memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
2101                 wrqu.addr.sa_family = ARPHRD_ETHER;
2102
2103                 /* Send event to user space */
2104                 wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
2105         }
2106 }
2107
2108 static void airo_end_xmit(struct net_device *dev) {
2109         u16 status;
2110         int i;
2111         struct airo_info *priv = dev->priv;
2112         struct sk_buff *skb = priv->xmit.skb;
2113         int fid = priv->xmit.fid;
2114         u32 *fids = priv->fids;
2115
2116         clear_bit(JOB_XMIT, &priv->jobs);
2117         clear_bit(FLAG_PENDING_XMIT, &priv->flags);
2118         status = transmit_802_3_packet (priv, fids[fid], skb->data);
2119         up(&priv->sem);
2120
2121         i = 0;
2122         if ( status == SUCCESS ) {
2123                 dev->trans_start = jiffies;
2124                 for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
2125         } else {
2126                 priv->fids[fid] &= 0xffff;
2127                 priv->stats.tx_window_errors++;
2128         }
2129         if (i < MAX_FIDS / 2)
2130                 netif_wake_queue(dev);
2131         dev_kfree_skb(skb);
2132 }
2133
2134 static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
2135         s16 len;
2136         int i, j;
2137         struct airo_info *priv = dev->priv;
2138         u32 *fids = priv->fids;
2139
2140         if ( skb == NULL ) {
2141                 airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__);
2142                 return 0;
2143         }
2144
2145         /* Find a vacant FID */
2146         for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
2147         for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
2148
2149         if ( j >= MAX_FIDS / 2 ) {
2150                 netif_stop_queue(dev);
2151
2152                 if (i == MAX_FIDS / 2) {
2153                         priv->stats.tx_fifo_errors++;
2154                         return 1;
2155                 }
2156         }
2157         /* check min length*/
2158         len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2159         /* Mark fid as used & save length for later */
2160         fids[i] |= (len << 16);
2161         priv->xmit.skb = skb;
2162         priv->xmit.fid = i;
2163         if (down_trylock(&priv->sem) != 0) {
2164                 set_bit(FLAG_PENDING_XMIT, &priv->flags);
2165                 netif_stop_queue(dev);
2166                 set_bit(JOB_XMIT, &priv->jobs);
2167                 wake_up_interruptible(&priv->thr_wait);
2168         } else
2169                 airo_end_xmit(dev);
2170         return 0;
2171 }
2172
2173 static void airo_end_xmit11(struct net_device *dev) {
2174         u16 status;
2175         int i;
2176         struct airo_info *priv = dev->priv;
2177         struct sk_buff *skb = priv->xmit11.skb;
2178         int fid = priv->xmit11.fid;
2179         u32 *fids = priv->fids;
2180
2181         clear_bit(JOB_XMIT11, &priv->jobs);
2182         clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
2183         status = transmit_802_11_packet (priv, fids[fid], skb->data);
2184         up(&priv->sem);
2185
2186         i = MAX_FIDS / 2;
2187         if ( status == SUCCESS ) {
2188                 dev->trans_start = jiffies;
2189                 for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
2190         } else {
2191                 priv->fids[fid] &= 0xffff;
2192                 priv->stats.tx_window_errors++;
2193         }
2194         if (i < MAX_FIDS)
2195                 netif_wake_queue(dev);
2196         dev_kfree_skb(skb);
2197 }
2198
2199 static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
2200         s16 len;
2201         int i, j;
2202         struct airo_info *priv = dev->priv;
2203         u32 *fids = priv->fids;
2204
2205         if (test_bit(FLAG_MPI, &priv->flags)) {
2206                 /* Not implemented yet for MPI350 */
2207                 netif_stop_queue(dev);
2208                 return -ENETDOWN;
2209         }
2210
2211         if ( skb == NULL ) {
2212                 airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__);
2213                 return 0;
2214         }
2215
2216         /* Find a vacant FID */
2217         for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
2218         for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
2219
2220         if ( j >= MAX_FIDS ) {
2221                 netif_stop_queue(dev);
2222
2223                 if (i == MAX_FIDS) {
2224                         priv->stats.tx_fifo_errors++;
2225                         return 1;
2226                 }
2227         }
2228         /* check min length*/
2229         len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2230         /* Mark fid as used & save length for later */
2231         fids[i] |= (len << 16);
2232         priv->xmit11.skb = skb;
2233         priv->xmit11.fid = i;
2234         if (down_trylock(&priv->sem) != 0) {
2235                 set_bit(FLAG_PENDING_XMIT11, &priv->flags);
2236                 netif_stop_queue(dev);
2237                 set_bit(JOB_XMIT11, &priv->jobs);
2238                 wake_up_interruptible(&priv->thr_wait);
2239         } else
2240                 airo_end_xmit11(dev);
2241         return 0;
2242 }
2243
2244 static void airo_read_stats(struct airo_info *ai)
2245 {
2246         StatsRid stats_rid;
2247         __le32 *vals = stats_rid.vals;
2248
2249         clear_bit(JOB_STATS, &ai->jobs);
2250         if (ai->power.event) {
2251                 up(&ai->sem);
2252                 return;
2253         }
2254         readStatsRid(ai, &stats_rid, RID_STATS, 0);
2255         up(&ai->sem);
2256
2257         ai->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
2258                                le32_to_cpu(vals[45]);
2259         ai->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
2260                                le32_to_cpu(vals[41]);
2261         ai->stats.rx_bytes = le32_to_cpu(vals[92]);
2262         ai->stats.tx_bytes = le32_to_cpu(vals[91]);
2263         ai->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
2264                               le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
2265         ai->stats.tx_errors = le32_to_cpu(vals[42]) + ai->stats.tx_fifo_errors;
2266         ai->stats.multicast = le32_to_cpu(vals[43]);
2267         ai->stats.collisions = le32_to_cpu(vals[89]);
2268
2269         /* detailed rx_errors: */
2270         ai->stats.rx_length_errors = le32_to_cpu(vals[3]);
2271         ai->stats.rx_crc_errors = le32_to_cpu(vals[4]);
2272         ai->stats.rx_frame_errors = le32_to_cpu(vals[2]);
2273         ai->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
2274 }
2275
2276 static struct net_device_stats *airo_get_stats(struct net_device *dev)
2277 {
2278         struct airo_info *local =  dev->priv;
2279
2280         if (!test_bit(JOB_STATS, &local->jobs)) {
2281                 /* Get stats out of the card if available */
2282                 if (down_trylock(&local->sem) != 0) {
2283                         set_bit(JOB_STATS, &local->jobs);
2284                         wake_up_interruptible(&local->thr_wait);
2285                 } else
2286                         airo_read_stats(local);
2287         }
2288
2289         return &local->stats;
2290 }
2291
2292 static void airo_set_promisc(struct airo_info *ai) {
2293         Cmd cmd;
2294         Resp rsp;
2295
2296         memset(&cmd, 0, sizeof(cmd));
2297         cmd.cmd=CMD_SETMODE;
2298         clear_bit(JOB_PROMISC, &ai->jobs);
2299         cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
2300         issuecommand(ai, &cmd, &rsp);
2301         up(&ai->sem);
2302 }
2303
2304 static void airo_set_multicast_list(struct net_device *dev) {
2305         struct airo_info *ai = dev->priv;
2306
2307         if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
2308                 change_bit(FLAG_PROMISC, &ai->flags);
2309                 if (down_trylock(&ai->sem) != 0) {
2310                         set_bit(JOB_PROMISC, &ai->jobs);
2311                         wake_up_interruptible(&ai->thr_wait);
2312                 } else
2313                         airo_set_promisc(ai);
2314         }
2315
2316         if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
2317                 /* Turn on multicast.  (Should be already setup...) */
2318         }
2319 }
2320
2321 static int airo_set_mac_address(struct net_device *dev, void *p)
2322 {
2323         struct airo_info *ai = dev->priv;
2324         struct sockaddr *addr = p;
2325
2326         readConfigRid(ai, 1);
2327         memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
2328         set_bit (FLAG_COMMIT, &ai->flags);
2329         disable_MAC(ai, 1);
2330         writeConfigRid (ai, 1);
2331         enable_MAC(ai, 1);
2332         memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
2333         if (ai->wifidev)
2334                 memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
2335         return 0;
2336 }
2337
2338 static int airo_change_mtu(struct net_device *dev, int new_mtu)
2339 {
2340         if ((new_mtu < 68) || (new_mtu > 2400))
2341                 return -EINVAL;
2342         dev->mtu = new_mtu;
2343         return 0;
2344 }
2345
2346 static LIST_HEAD(airo_devices);
2347
2348 static void add_airo_dev(struct airo_info *ai)
2349 {
2350         /* Upper layers already keep track of PCI devices,
2351          * so we only need to remember our non-PCI cards. */
2352         if (!ai->pci)
2353                 list_add_tail(&ai->dev_list, &airo_devices);
2354 }
2355
2356 static void del_airo_dev(struct airo_info *ai)
2357 {
2358         if (!ai->pci)
2359                 list_del(&ai->dev_list);
2360 }
2361
2362 static int airo_close(struct net_device *dev) {
2363         struct airo_info *ai = dev->priv;
2364
2365         netif_stop_queue(dev);
2366
2367         if (ai->wifidev != dev) {
2368 #ifdef POWER_ON_DOWN
2369                 /* Shut power to the card. The idea is that the user can save
2370                  * power when he doesn't need the card with "ifconfig down".
2371                  * That's the method that is most friendly towards the network
2372                  * stack (i.e. the network stack won't try to broadcast
2373                  * anything on the interface and routes are gone. Jean II */
2374                 set_bit(FLAG_RADIO_DOWN, &ai->flags);
2375                 disable_MAC(ai, 1);
2376 #endif
2377                 disable_interrupts( ai );
2378
2379                 free_irq(dev->irq, dev);
2380
2381                 set_bit(JOB_DIE, &ai->jobs);
2382                 kthread_stop(ai->airo_thread_task);
2383         }
2384         return 0;
2385 }
2386
2387 void stop_airo_card( struct net_device *dev, int freeres )
2388 {
2389         struct airo_info *ai = dev->priv;
2390
2391         set_bit(FLAG_RADIO_DOWN, &ai->flags);
2392         disable_MAC(ai, 1);
2393         disable_interrupts(ai);
2394         takedown_proc_entry( dev, ai );
2395         if (test_bit(FLAG_REGISTERED, &ai->flags)) {
2396                 unregister_netdev( dev );
2397                 if (ai->wifidev) {
2398                         unregister_netdev(ai->wifidev);
2399                         free_netdev(ai->wifidev);
2400                         ai->wifidev = NULL;
2401                 }
2402                 clear_bit(FLAG_REGISTERED, &ai->flags);
2403         }
2404         /*
2405          * Clean out tx queue
2406          */
2407         if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
2408                 struct sk_buff *skb = NULL;
2409                 for (;(skb = skb_dequeue(&ai->txq));)
2410                         dev_kfree_skb(skb);
2411         }
2412
2413         airo_networks_free (ai);
2414
2415         kfree(ai->flash);
2416         kfree(ai->rssi);
2417         kfree(ai->APList);
2418         kfree(ai->SSID);
2419         if (freeres) {
2420                 /* PCMCIA frees this stuff, so only for PCI and ISA */
2421                 release_region( dev->base_addr, 64 );
2422                 if (test_bit(FLAG_MPI, &ai->flags)) {
2423                         if (ai->pci)
2424                                 mpi_unmap_card(ai->pci);
2425                         if (ai->pcimem)
2426                                 iounmap(ai->pcimem);
2427                         if (ai->pciaux)
2428                                 iounmap(ai->pciaux);
2429                         pci_free_consistent(ai->pci, PCI_SHARED_LEN,
2430                                 ai->shared, ai->shared_dma);
2431                 }
2432         }
2433         crypto_free_cipher(ai->tfm);
2434         del_airo_dev(ai);
2435         free_netdev( dev );
2436 }
2437
2438 EXPORT_SYMBOL(stop_airo_card);
2439
2440 static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr)
2441 {
2442         memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
2443         return ETH_ALEN;
2444 }
2445
2446 static void mpi_unmap_card(struct pci_dev *pci)
2447 {
2448         unsigned long mem_start = pci_resource_start(pci, 1);
2449         unsigned long mem_len = pci_resource_len(pci, 1);
2450         unsigned long aux_start = pci_resource_start(pci, 2);
2451         unsigned long aux_len = AUXMEMSIZE;
2452
2453         release_mem_region(aux_start, aux_len);
2454         release_mem_region(mem_start, mem_len);
2455 }
2456
2457 /*************************************************************
2458  *  This routine assumes that descriptors have been setup .
2459  *  Run at insmod time or after reset  when the decriptors
2460  *  have been initialized . Returns 0 if all is well nz
2461  *  otherwise . Does not allocate memory but sets up card
2462  *  using previously allocated descriptors.
2463  */
2464 static int mpi_init_descriptors (struct airo_info *ai)
2465 {
2466         Cmd cmd;
2467         Resp rsp;
2468         int i;
2469         int rc = SUCCESS;
2470
2471         /* Alloc  card RX descriptors */
2472         netif_stop_queue(ai->dev);
2473
2474         memset(&rsp,0,sizeof(rsp));
2475         memset(&cmd,0,sizeof(cmd));
2476
2477         cmd.cmd = CMD_ALLOCATEAUX;
2478         cmd.parm0 = FID_RX;
2479         cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
2480         cmd.parm2 = MPI_MAX_FIDS;
2481         rc=issuecommand(ai, &cmd, &rsp);
2482         if (rc != SUCCESS) {
2483                 airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
2484                 return rc;
2485         }
2486
2487         for (i=0; i<MPI_MAX_FIDS; i++) {
2488                 memcpy_toio(ai->rxfids[i].card_ram_off,
2489                         &ai->rxfids[i].rx_desc, sizeof(RxFid));
2490         }
2491
2492         /* Alloc card TX descriptors */
2493
2494         memset(&rsp,0,sizeof(rsp));
2495         memset(&cmd,0,sizeof(cmd));
2496
2497         cmd.cmd = CMD_ALLOCATEAUX;
2498         cmd.parm0 = FID_TX;
2499         cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
2500         cmd.parm2 = MPI_MAX_FIDS;
2501
2502         for (i=0; i<MPI_MAX_FIDS; i++) {
2503                 ai->txfids[i].tx_desc.valid = 1;
2504                 memcpy_toio(ai->txfids[i].card_ram_off,
2505                         &ai->txfids[i].tx_desc, sizeof(TxFid));
2506         }
2507         ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2508
2509         rc=issuecommand(ai, &cmd, &rsp);
2510         if (rc != SUCCESS) {
2511                 airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
2512                 return rc;
2513         }
2514
2515         /* Alloc card Rid descriptor */
2516         memset(&rsp,0,sizeof(rsp));
2517         memset(&cmd,0,sizeof(cmd));
2518
2519         cmd.cmd = CMD_ALLOCATEAUX;
2520         cmd.parm0 = RID_RW;
2521         cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
2522         cmd.parm2 = 1; /* Magic number... */
2523         rc=issuecommand(ai, &cmd, &rsp);
2524         if (rc != SUCCESS) {
2525                 airo_print_err(ai->dev->name, "Couldn't allocate RID");
2526                 return rc;
2527         }
2528
2529         memcpy_toio(ai->config_desc.card_ram_off,
2530                 &ai->config_desc.rid_desc, sizeof(Rid));
2531
2532         return rc;
2533 }
2534
2535 /*
2536  * We are setting up three things here:
2537  * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
2538  * 2) Map PCI memory for issueing commands.
2539  * 3) Allocate memory (shared) to send and receive ethernet frames.
2540  */
2541 static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
2542 {
2543         unsigned long mem_start, mem_len, aux_start, aux_len;
2544         int rc = -1;
2545         int i;
2546         dma_addr_t busaddroff;
2547         unsigned char *vpackoff;
2548         unsigned char __iomem *pciaddroff;
2549
2550         mem_start = pci_resource_start(pci, 1);
2551         mem_len = pci_resource_len(pci, 1);
2552         aux_start = pci_resource_start(pci, 2);
2553         aux_len = AUXMEMSIZE;
2554
2555         if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
2556                 airo_print_err("", "Couldn't get region %x[%x]",
2557                         (int)mem_start, (int)mem_len);
2558                 goto out;
2559         }
2560         if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
2561                 airo_print_err("", "Couldn't get region %x[%x]",
2562                         (int)aux_start, (int)aux_len);
2563                 goto free_region1;
2564         }
2565
2566         ai->pcimem = ioremap(mem_start, mem_len);
2567         if (!ai->pcimem) {
2568                 airo_print_err("", "Couldn't map region %x[%x]",
2569                         (int)mem_start, (int)mem_len);
2570                 goto free_region2;
2571         }
2572         ai->pciaux = ioremap(aux_start, aux_len);
2573         if (!ai->pciaux) {
2574                 airo_print_err("", "Couldn't map region %x[%x]",
2575                         (int)aux_start, (int)aux_len);
2576                 goto free_memmap;
2577         }
2578
2579         /* Reserve PKTSIZE for each fid and 2K for the Rids */
2580         ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
2581         if (!ai->shared) {
2582                 airo_print_err("", "Couldn't alloc_consistent %d",
2583                         PCI_SHARED_LEN);
2584                 goto free_auxmap;
2585         }
2586
2587         /*
2588          * Setup descriptor RX, TX, CONFIG
2589          */
2590         busaddroff = ai->shared_dma;
2591         pciaddroff = ai->pciaux + AUX_OFFSET;
2592         vpackoff   = ai->shared;
2593
2594         /* RX descriptor setup */
2595         for(i = 0; i < MPI_MAX_FIDS; i++) {
2596                 ai->rxfids[i].pending = 0;
2597                 ai->rxfids[i].card_ram_off = pciaddroff;
2598                 ai->rxfids[i].virtual_host_addr = vpackoff;
2599                 ai->rxfids[i].rx_desc.host_addr = busaddroff;
2600                 ai->rxfids[i].rx_desc.valid = 1;
2601                 ai->rxfids[i].rx_desc.len = PKTSIZE;
2602                 ai->rxfids[i].rx_desc.rdy = 0;
2603
2604                 pciaddroff += sizeof(RxFid);
2605                 busaddroff += PKTSIZE;
2606                 vpackoff   += PKTSIZE;
2607         }
2608
2609         /* TX descriptor setup */
2610         for(i = 0; i < MPI_MAX_FIDS; i++) {
2611                 ai->txfids[i].card_ram_off = pciaddroff;
2612                 ai->txfids[i].virtual_host_addr = vpackoff;
2613                 ai->txfids[i].tx_desc.valid = 1;
2614                 ai->txfids[i].tx_desc.host_addr = busaddroff;
2615                 memcpy(ai->txfids[i].virtual_host_addr,
2616                         &wifictlhdr8023, sizeof(wifictlhdr8023));
2617
2618                 pciaddroff += sizeof(TxFid);
2619                 busaddroff += PKTSIZE;
2620                 vpackoff   += PKTSIZE;
2621         }
2622         ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2623
2624         /* Rid descriptor setup */
2625         ai->config_desc.card_ram_off = pciaddroff;
2626         ai->config_desc.virtual_host_addr = vpackoff;
2627         ai->config_desc.rid_desc.host_addr = busaddroff;
2628         ai->ridbus = busaddroff;
2629         ai->config_desc.rid_desc.rid = 0;
2630         ai->config_desc.rid_desc.len = RIDSIZE;
2631         ai->config_desc.rid_desc.valid = 1;
2632         pciaddroff += sizeof(Rid);
2633         busaddroff += RIDSIZE;
2634         vpackoff   += RIDSIZE;
2635
2636         /* Tell card about descriptors */
2637         if (mpi_init_descriptors (ai) != SUCCESS)
2638                 goto free_shared;
2639
2640         return 0;
2641  free_shared:
2642         pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
2643  free_auxmap:
2644         iounmap(ai->pciaux);
2645  free_memmap:
2646         iounmap(ai->pcimem);
2647  free_region2:
2648         release_mem_region(aux_start, aux_len);
2649  free_region1:
2650         release_mem_region(mem_start, mem_len);
2651  out:
2652         return rc;
2653 }
2654
2655 static const struct header_ops airo_header_ops = {
2656         .parse = wll_header_parse,
2657 };
2658
2659 static void wifi_setup(struct net_device *dev)
2660 {
2661         dev->header_ops = &airo_header_ops;
2662         dev->hard_start_xmit = &airo_start_xmit11;
2663         dev->get_stats = &airo_get_stats;
2664         dev->set_mac_address = &airo_set_mac_address;
2665         dev->do_ioctl = &airo_ioctl;
2666         dev->wireless_handlers = &airo_handler_def;
2667         dev->change_mtu = &airo_change_mtu;
2668         dev->open = &airo_open;
2669         dev->stop = &airo_close;
2670
2671         dev->type               = ARPHRD_IEEE80211;
2672         dev->hard_header_len    = ETH_HLEN;
2673         dev->mtu                = AIRO_DEF_MTU;
2674         dev->addr_len           = ETH_ALEN;
2675         dev->tx_queue_len       = 100; 
2676
2677         memset(dev->broadcast,0xFF, ETH_ALEN);
2678
2679         dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
2680 }
2681
2682 static struct net_device *init_wifidev(struct airo_info *ai,
2683                                         struct net_device *ethdev)
2684 {
2685         int err;
2686         struct net_device *dev = alloc_netdev(0, "wifi%d", wifi_setup);
2687         if (!dev)
2688                 return NULL;
2689         dev->priv = ethdev->priv;
2690         dev->irq = ethdev->irq;
2691         dev->base_addr = ethdev->base_addr;
2692         dev->wireless_data = ethdev->wireless_data;
2693         memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
2694         err = register_netdev(dev);
2695         if (err<0) {
2696                 free_netdev(dev);
2697                 return NULL;
2698         }
2699         return dev;
2700 }
2701
2702 static int reset_card( struct net_device *dev , int lock) {
2703         struct airo_info *ai = dev->priv;
2704
2705         if (lock && down_interruptible(&ai->sem))
2706                 return -1;
2707         waitbusy (ai);
2708         OUT4500(ai,COMMAND,CMD_SOFTRESET);
2709         msleep(200);
2710         waitbusy (ai);
2711         msleep(200);
2712         if (lock)
2713                 up(&ai->sem);
2714         return 0;
2715 }
2716
2717 #define AIRO_MAX_NETWORK_COUNT  64
2718 static int airo_networks_allocate(struct airo_info *ai)
2719 {
2720         if (ai->networks)
2721                 return 0;
2722
2723         ai->networks =
2724             kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement),
2725                     GFP_KERNEL);
2726         if (!ai->networks) {
2727                 airo_print_warn("", "Out of memory allocating beacons");
2728                 return -ENOMEM;
2729         }
2730
2731         return 0;
2732 }
2733
2734 static void airo_networks_free(struct airo_info *ai)
2735 {
2736         kfree(ai->networks);
2737         ai->networks = NULL;
2738 }
2739
2740 static void airo_networks_initialize(struct airo_info *ai)
2741 {
2742         int i;
2743
2744         INIT_LIST_HEAD(&ai->network_free_list);
2745         INIT_LIST_HEAD(&ai->network_list);
2746         for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
2747                 list_add_tail(&ai->networks[i].list,
2748                               &ai->network_free_list);
2749 }
2750
2751 static int airo_test_wpa_capable(struct airo_info *ai)
2752 {
2753         int status;
2754         CapabilityRid cap_rid;
2755
2756         status = readCapabilityRid(ai, &cap_rid, 1);
2757         if (status != SUCCESS) return 0;
2758
2759         /* Only firmware versions 5.30.17 or better can do WPA */
2760         if (le16_to_cpu(cap_rid.softVer) > 0x530
2761           || (le16_to_cpu(cap_rid.softVer) == 0x530
2762               && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2763                 airo_print_info("", "WPA is supported.");
2764                 return 1;
2765         }
2766
2767         /* No WPA support */
2768         airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
2769                 " and greater support WPA.  Detected %s)", cap_rid.prodVer);
2770         return 0;
2771 }
2772
2773 static struct net_device *_init_airo_card( unsigned short irq, int port,
2774                                            int is_pcmcia, struct pci_dev *pci,
2775                                            struct device *dmdev )
2776 {
2777         struct net_device *dev;
2778         struct airo_info *ai;
2779         int i, rc;
2780         DECLARE_MAC_BUF(mac);
2781
2782         /* Create the network device object. */
2783         dev = alloc_netdev(sizeof(*ai), "", ether_setup);
2784         if (!dev) {
2785                 airo_print_err("", "Couldn't alloc_etherdev");
2786                 return NULL;
2787         }
2788
2789         ai = dev->priv;
2790         ai->wifidev = NULL;
2791         ai->flags = 1 << FLAG_RADIO_DOWN;
2792         ai->jobs = 0;
2793         ai->dev = dev;
2794         if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2795                 airo_print_dbg("", "Found an MPI350 card");
2796                 set_bit(FLAG_MPI, &ai->flags);
2797         }
2798         spin_lock_init(&ai->aux_lock);
2799         sema_init(&ai->sem, 1);
2800         ai->config.len = 0;
2801         ai->pci = pci;
2802         init_waitqueue_head (&ai->thr_wait);
2803         ai->tfm = NULL;
2804         add_airo_dev(ai);
2805
2806         if (airo_networks_allocate (ai))
2807                 goto err_out_free;
2808         airo_networks_initialize (ai);
2809
2810         /* The Airo-specific entries in the device structure. */
2811         if (test_bit(FLAG_MPI,&ai->flags)) {
2812                 skb_queue_head_init (&ai->txq);
2813                 dev->hard_start_xmit = &mpi_start_xmit;
2814         } else
2815                 dev->hard_start_xmit = &airo_start_xmit;
2816         dev->get_stats = &airo_get_stats;
2817         dev->set_multicast_list = &airo_set_multicast_list;
2818         dev->set_mac_address = &airo_set_mac_address;
2819         dev->do_ioctl = &airo_ioctl;
2820         dev->wireless_handlers = &airo_handler_def;
2821         ai->wireless_data.spy_data = &ai->spy_data;
2822         dev->wireless_data = &ai->wireless_data;
2823         dev->change_mtu = &airo_change_mtu;
2824         dev->open = &airo_open;
2825         dev->stop = &airo_close;
2826         dev->irq = irq;
2827         dev->base_addr = port;
2828
2829         SET_NETDEV_DEV(dev, dmdev);
2830
2831         reset_card (dev, 1);
2832         msleep(400);
2833
2834         if (!is_pcmcia) {
2835                 if (!request_region(dev->base_addr, 64, DRV_NAME)) {
2836                         rc = -EBUSY;
2837                         airo_print_err(dev->name, "Couldn't request region");
2838                         goto err_out_nets;
2839                 }
2840         }
2841
2842         if (test_bit(FLAG_MPI,&ai->flags)) {
2843                 if (mpi_map_card(ai, pci)) {
2844                         airo_print_err("", "Could not map memory");
2845                         goto err_out_res;
2846                 }
2847         }
2848
2849         if (probe) {
2850                 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
2851                         airo_print_err(dev->name, "MAC could not be enabled" );
2852                         rc = -EIO;
2853                         goto err_out_map;
2854                 }
2855         } else if (!test_bit(FLAG_MPI,&ai->flags)) {
2856                 ai->bap_read = fast_bap_read;
2857                 set_bit(FLAG_FLASHING, &ai->flags);
2858         }
2859
2860         /* Test for WPA support */
2861         if (airo_test_wpa_capable(ai)) {
2862                 set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2863                 ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2864                 ai->bssListNext = RID_WPA_BSSLISTNEXT;
2865                 ai->bssListRidLen = sizeof(BSSListRid);
2866         } else {
2867                 ai->bssListFirst = RID_BSSLISTFIRST;
2868                 ai->bssListNext = RID_BSSLISTNEXT;
2869                 ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2870         }
2871
2872         strcpy(dev->name, "eth%d");
2873         rc = register_netdev(dev);
2874         if (rc) {
2875                 airo_print_err(dev->name, "Couldn't register_netdev");
2876                 goto err_out_map;
2877         }
2878         ai->wifidev = init_wifidev(ai, dev);
2879         if (!ai->wifidev)
2880                 goto err_out_reg;
2881
2882         set_bit(FLAG_REGISTERED,&ai->flags);
2883         airo_print_info(dev->name, "MAC enabled %s",
2884                         print_mac(mac, dev->dev_addr));
2885
2886         /* Allocate the transmit buffers */
2887         if (probe && !test_bit(FLAG_MPI,&ai->flags))
2888                 for( i = 0; i < MAX_FIDS; i++ )
2889                         ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
2890
2891         if (setup_proc_entry(dev, dev->priv) < 0)
2892                 goto err_out_wifi;
2893
2894         return dev;
2895
2896 err_out_wifi:
2897         unregister_netdev(ai->wifidev);
2898         free_netdev(ai->wifidev);
2899 err_out_reg:
2900         unregister_netdev(dev);
2901 err_out_map:
2902         if (test_bit(FLAG_MPI,&ai->flags) && pci) {
2903                 pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
2904                 iounmap(ai->pciaux);
2905                 iounmap(ai->pcimem);
2906                 mpi_unmap_card(ai->pci);
2907         }
2908 err_out_res:
2909         if (!is_pcmcia)
2910                 release_region( dev->base_addr, 64 );
2911 err_out_nets:
2912         airo_networks_free(ai);
2913         del_airo_dev(ai);
2914 err_out_free:
2915         free_netdev(dev);
2916         return NULL;
2917 }
2918
2919 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia,
2920                                   struct device *dmdev)
2921 {
2922         return _init_airo_card ( irq, port, is_pcmcia, NULL, dmdev);
2923 }
2924
2925 EXPORT_SYMBOL(init_airo_card);
2926
2927 static int waitbusy (struct airo_info *ai) {
2928         int delay = 0;
2929         while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
2930                 udelay (10);
2931                 if ((++delay % 20) == 0)
2932                         OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2933         }
2934         return delay < 10000;
2935 }
2936
2937 int reset_airo_card( struct net_device *dev )
2938 {
2939         int i;
2940         struct airo_info *ai = dev->priv;
2941         DECLARE_MAC_BUF(mac);
2942
2943         if (reset_card (dev, 1))
2944                 return -1;
2945
2946         if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
2947                 airo_print_err(dev->name, "MAC could not be enabled");
2948                 return -1;
2949         }
2950         airo_print_info(dev->name, "MAC enabled %s",
2951                         print_mac(mac, dev->dev_addr));
2952         /* Allocate the transmit buffers if needed */
2953         if (!test_bit(FLAG_MPI,&ai->flags))
2954                 for( i = 0; i < MAX_FIDS; i++ )
2955                         ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
2956
2957         enable_interrupts( ai );
2958         netif_wake_queue(dev);
2959         return 0;
2960 }
2961
2962 EXPORT_SYMBOL(reset_airo_card);
2963
2964 static void airo_send_event(struct net_device *dev) {
2965         struct airo_info *ai = dev->priv;
2966         union iwreq_data wrqu;
2967         StatusRid status_rid;
2968
2969         clear_bit(JOB_EVENT, &ai->jobs);
2970         PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
2971         up(&ai->sem);
2972         wrqu.data.length = 0;
2973         wrqu.data.flags = 0;
2974         memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
2975         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2976
2977         /* Send event to user space */
2978         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
2979 }
2980
2981 static void airo_process_scan_results (struct airo_info *ai) {
2982         union iwreq_data        wrqu;
2983         BSSListRid bss;
2984         int rc;
2985         BSSListElement * loop_net;
2986         BSSListElement * tmp_net;
2987
2988         /* Blow away current list of scan results */
2989         list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
2990                 list_move_tail (&loop_net->list, &ai->network_free_list);
2991                 /* Don't blow away ->list, just BSS data */
2992                 memset (loop_net, 0, sizeof (loop_net->bss));
2993         }
2994
2995         /* Try to read the first entry of the scan result */
2996         rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
2997         if((rc) || (bss.index == cpu_to_le16(0xffff))) {
2998                 /* No scan results */
2999                 goto out;
3000         }
3001
3002         /* Read and parse all entries */
3003         tmp_net = NULL;
3004         while((!rc) && (bss.index != cpu_to_le16(0xffff))) {
3005                 /* Grab a network off the free list */
3006                 if (!list_empty(&ai->network_free_list)) {
3007                         tmp_net = list_entry(ai->network_free_list.next,
3008                                             BSSListElement, list);
3009                         list_del(ai->network_free_list.next);
3010                 }
3011
3012                 if (tmp_net != NULL) {
3013                         memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
3014                         list_add_tail(&tmp_net->list, &ai->network_list);
3015                         tmp_net = NULL;
3016                 }
3017
3018                 /* Read next entry */
3019                 rc = PC4500_readrid(ai, ai->bssListNext,
3020                                     &bss, ai->bssListRidLen, 0);
3021         }
3022
3023 out:
3024         ai->scan_timeout = 0;
3025         clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
3026         up(&ai->sem);
3027
3028         /* Send an empty event to user space.
3029          * We don't send the received data on
3030          * the event because it would require
3031          * us to do complex transcoding, and
3032          * we want to minimise the work done in
3033          * the irq handler. Use a request to
3034          * extract the data - Jean II */
3035         wrqu.data.length = 0;
3036         wrqu.data.flags = 0;
3037         wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
3038 }
3039
3040 static int airo_thread(void *data) {
3041         struct net_device *dev = data;
3042         struct airo_info *ai = dev->priv;
3043         int locked;
3044
3045         set_freezable();
3046         while(1) {
3047                 /* make swsusp happy with our thread */
3048                 try_to_freeze();
3049
3050                 if (test_bit(JOB_DIE, &ai->jobs))
3051                         break;
3052
3053                 if (ai->jobs) {
3054                         locked = down_interruptible(&ai->sem);
3055                 } else {
3056                         wait_queue_t wait;
3057
3058                         init_waitqueue_entry(&wait, current);
3059                         add_wait_queue(&ai->thr_wait, &wait);
3060                         for (;;) {
3061                                 set_current_state(TASK_INTERRUPTIBLE);
3062                                 if (ai->jobs)
3063                                         break;
3064                                 if (ai->expires || ai->scan_timeout) {
3065                                         if (ai->scan_timeout &&
3066                                                         time_after_eq(jiffies,ai->scan_timeout)){
3067                                                 set_bit(JOB_SCAN_RESULTS, &ai->jobs);
3068                                                 break;
3069                                         } else if (ai->expires &&
3070                                                         time_after_eq(jiffies,ai->expires)){
3071                                                 set_bit(JOB_AUTOWEP, &ai->jobs);
3072                                                 break;
3073                                         }
3074                                         if (!kthread_should_stop() &&
3075                                             !freezing(current)) {
3076                                                 unsigned long wake_at;
3077                                                 if (!ai->expires || !ai->scan_timeout) {
3078                                                         wake_at = max(ai->expires,
3079                                                                 ai->scan_timeout);
3080                                                 } else {
3081                                                         wake_at = min(ai->expires,
3082                                                                 ai->scan_timeout);
3083                                                 }
3084                                                 schedule_timeout(wake_at - jiffies);
3085                                                 continue;
3086                                         }
3087                                 } else if (!kthread_should_stop() &&
3088                                            !freezing(current)) {
3089                                         schedule();
3090                                         continue;
3091                                 }
3092                                 break;
3093                         }
3094                         current->state = TASK_RUNNING;
3095                         remove_wait_queue(&ai->thr_wait, &wait);
3096                         locked = 1;
3097                 }
3098
3099                 if (locked)
3100                         continue;
3101
3102                 if (test_bit(JOB_DIE, &ai->jobs)) {
3103                         up(&ai->sem);
3104                         break;
3105                 }
3106
3107                 if (ai->power.event || test_bit(FLAG_FLASHING, &ai->flags)) {
3108                         up(&ai->sem);
3109                         continue;
3110                 }
3111
3112                 if (test_bit(JOB_XMIT, &ai->jobs))
3113                         airo_end_xmit(dev);
3114                 else if (test_bit(JOB_XMIT11, &ai->jobs))
3115                         airo_end_xmit11(dev);
3116                 else if (test_bit(JOB_STATS, &ai->jobs))
3117                         airo_read_stats(ai);
3118                 else if (test_bit(JOB_WSTATS, &ai->jobs))
3119                         airo_read_wireless_stats(ai);
3120                 else if (test_bit(JOB_PROMISC, &ai->jobs))
3121                         airo_set_promisc(ai);
3122                 else if (test_bit(JOB_MIC, &ai->jobs))
3123                         micinit(ai);
3124                 else if (test_bit(JOB_EVENT, &ai->jobs))
3125                         airo_send_event(dev);
3126                 else if (test_bit(JOB_AUTOWEP, &ai->jobs))
3127                         timer_func(dev);
3128                 else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
3129                         airo_process_scan_results(ai);
3130                 else  /* Shouldn't get here, but we make sure to unlock */
3131                         up(&ai->sem);
3132         }
3133
3134         return 0;
3135 }
3136
3137 static int header_len(__le16 ctl)
3138 {
3139         u16 fc = le16_to_cpu(ctl);
3140         switch (fc & 0xc) {
3141         case 4:
3142                 if ((fc & 0xe0) == 0xc0)
3143                         return 10;      /* one-address control packet */
3144                 return 16;      /* two-address control packet */
3145         case 8:
3146                 if ((fc & 0x300) == 0x300)
3147                         return 30;      /* WDS packet */
3148         }
3149         return 24;
3150 }
3151
3152 static irqreturn_t airo_interrupt(int irq, void *dev_id)
3153 {
3154         struct net_device *dev = dev_id;
3155         u16 status;
3156         u16 fid;
3157         struct airo_info *apriv = dev->priv;
3158         u16 savedInterrupts = 0;
3159         int handled = 0;
3160
3161         if (!netif_device_present(dev))
3162                 return IRQ_NONE;
3163
3164         for (;;) {
3165                 status = IN4500( apriv, EVSTAT );
3166                 if ( !(status & STATUS_INTS) || status == 0xffff ) break;
3167
3168                 handled = 1;
3169
3170                 if ( status & EV_AWAKE ) {
3171                         OUT4500( apriv, EVACK, EV_AWAKE );
3172                         OUT4500( apriv, EVACK, EV_AWAKE );
3173                 }
3174
3175                 if (!savedInterrupts) {
3176                         savedInterrupts = IN4500( apriv, EVINTEN );
3177                         OUT4500( apriv, EVINTEN, 0 );
3178                 }
3179
3180                 if ( status & EV_MIC ) {
3181                         OUT4500( apriv, EVACK, EV_MIC );
3182                         if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
3183                                 set_bit(JOB_MIC, &apriv->jobs);
3184                                 wake_up_interruptible(&apriv->thr_wait);
3185                         }
3186                 }
3187                 if ( status & EV_LINK ) {
3188                         union iwreq_data        wrqu;
3189                         int scan_forceloss = 0;
3190                         /* The link status has changed, if you want to put a
3191                            monitor hook in, do it here.  (Remember that
3192                            interrupts are still disabled!)
3193                         */
3194                         u16 newStatus = IN4500(apriv, LINKSTAT);
3195                         OUT4500( apriv, EVACK, EV_LINK);
3196                         /* Here is what newStatus means: */
3197 #define NOBEACON 0x8000 /* Loss of sync - missed beacons */
3198 #define MAXRETRIES 0x8001 /* Loss of sync - max retries */
3199 #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3200 #define FORCELOSS 0x8003 /* Loss of sync - host request */
3201 #define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
3202 #define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
3203 #define DISASS 0x8200 /* Disassociation (low byte is reason code) */
3204 #define ASSFAIL 0x8400 /* Association failure (low byte is reason
3205                           code) */
3206 #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
3207                            code) */
3208 #define ASSOCIATED 0x0400 /* Associated */
3209 #define REASSOCIATED 0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
3210 #define RC_RESERVED 0 /* Reserved return code */
3211 #define RC_NOREASON 1 /* Unspecified reason */
3212 #define RC_AUTHINV 2 /* Previous authentication invalid */
3213 #define RC_DEAUTH 3 /* Deauthenticated because sending station is
3214                        leaving */
3215 #define RC_NOACT 4 /* Disassociated due to inactivity */
3216 #define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
3217                         all currently associated stations */
3218 #define RC_BADCLASS2 6 /* Class 2 frame received from
3219                           non-Authenticated station */
3220 #define RC_BADCLASS3 7 /* Class 3 frame received from
3221                           non-Associated station */
3222 #define RC_STATLEAVE 8 /* Disassociated because sending station is
3223                           leaving BSS */
3224 #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
3225                        Authenticated with the responding station */
3226                         if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
3227                                 scan_forceloss = 1;
3228                         if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
3229                                 if (auto_wep)
3230                                         apriv->expires = 0;
3231                                 if (apriv->list_bss_task)
3232                                         wake_up_process(apriv->list_bss_task);
3233                                 set_bit(FLAG_UPDATE_UNI, &apriv->flags);
3234                                 set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
3235
3236                                 if (down_trylock(&apriv->sem) != 0) {
3237                                         set_bit(JOB_EVENT, &apriv->jobs);
3238                                         wake_up_interruptible(&apriv->thr_wait);
3239                                 } else
3240                                         airo_send_event(dev);
3241                         } else if (!scan_forceloss) {
3242                                 if (auto_wep && !apriv->expires) {
3243                                         apriv->expires = RUN_AT(3*HZ);
3244                                         wake_up_interruptible(&apriv->thr_wait);
3245                                 }
3246
3247                                 /* Send event to user space */
3248                                 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3249                                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3250                                 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
3251                         }
3252                 }
3253
3254                 /* Check to see if there is something to receive */
3255                 if ( status & EV_RX  ) {
3256                         struct sk_buff *skb = NULL;
3257                         __le16 fc, v;
3258                         u16 len, hdrlen = 0;
3259 #pragma pack(1)
3260                         struct {
3261                                 __le16 status, len;
3262                                 u8 rssi[2];
3263                                 u8 rate;
3264                                 u8 freq;
3265                                 __le16 tmp[4];
3266                         } hdr;
3267 #pragma pack()
3268                         u16 gap;
3269                         __le16 tmpbuf[4];
3270                         __le16 *buffer;
3271
3272                         if (test_bit(FLAG_MPI,&apriv->flags)) {
3273                                 if (test_bit(FLAG_802_11, &apriv->flags))
3274                                         mpi_receive_802_11(apriv);
3275                                 else
3276                                         mpi_receive_802_3(apriv);
3277                                 OUT4500(apriv, EVACK, EV_RX);
3278                                 goto exitrx;
3279                         }
3280
3281                         fid = IN4500( apriv, RXFID );
3282
3283                         /* Get the packet length */
3284                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3285                                 bap_setup (apriv, fid, 4, BAP0);
3286                                 bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0);
3287                                 /* Bad CRC. Ignore packet */
3288                                 if (le16_to_cpu(hdr.status) & 2)
3289                                         hdr.len = 0;
3290                                 if (apriv->wifidev == NULL)
3291                                         hdr.len = 0;
3292                         } else {
3293                                 bap_setup (apriv, fid, 0x36, BAP0);
3294                                 bap_read (apriv, &hdr.len, 2, BAP0);
3295                         }
3296                         len = le16_to_cpu(hdr.len);
3297
3298                         if (len > AIRO_DEF_MTU) {
3299                                 airo_print_err(apriv->dev->name, "Bad size %d", len);
3300                                 goto badrx;
3301                         }
3302                         if (len == 0)
3303                                 goto badrx;
3304
3305                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3306                                 bap_read (apriv, &fc, sizeof(fc), BAP0);
3307                                 hdrlen = header_len(fc);
3308                         } else
3309                                 hdrlen = ETH_ALEN * 2;
3310
3311                         skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
3312                         if ( !skb ) {
3313                                 apriv->stats.rx_dropped++;
3314                                 goto badrx;
3315                         }
3316                         skb_reserve(skb, 2); /* This way the IP header is aligned */
3317                         buffer = (__le16*)skb_put (skb, len + hdrlen);
3318                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3319                                 buffer[0] = fc;
3320                                 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
3321                                 if (hdrlen == 24)
3322                                         bap_read (apriv, tmpbuf, 6, BAP0);
3323
3324                                 bap_read (apriv, &v, sizeof(v), BAP0);
3325                                 gap = le16_to_cpu(v);
3326                                 if (gap) {
3327                                         if (gap <= 8) {
3328                                                 bap_read (apriv, tmpbuf, gap, BAP0);
3329                                         } else {
3330                                                 airo_print_err(apriv->dev->name, "gaplen too "
3331                                                         "big. Problems will follow...");
3332                                         }
3333                                 }
3334                                 bap_read (apriv, buffer + hdrlen/2, len, BAP0);
3335                         } else {
3336                                 MICBuffer micbuf;
3337                                 bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
3338                                 if (apriv->micstats.enabled) {
3339                                         bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0);
3340                                         if (ntohs(micbuf.typelen) > 0x05DC)
3341                                                 bap_setup (apriv, fid, 0x44, BAP0);
3342                                         else {
3343                                                 if (len <= sizeof(micbuf))
3344                                                         goto badmic;
3345
3346                                                 len -= sizeof(micbuf);
3347                                                 skb_trim (skb, len + hdrlen);
3348                                         }
3349                                 }
3350                                 bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
3351                                 if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
3352 badmic:
3353                                         dev_kfree_skb_irq (skb);
3354 badrx:
3355                                         OUT4500( apriv, EVACK, EV_RX);
3356                                         goto exitrx;
3357                                 }
3358                         }
3359 #ifdef WIRELESS_SPY
3360                         if (apriv->spy_data.spy_number > 0) {
3361                                 char *sa;
3362                                 struct iw_quality wstats;
3363                                 /* Prepare spy data : addr + qual */
3364                                 if (!test_bit(FLAG_802_11, &apriv->flags)) {
3365                                         sa = (char*)buffer + 6;
3366                                         bap_setup (apriv, fid, 8, BAP0);
3367                                         bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0);
3368                                 } else
3369                                         sa = (char*)buffer + 10;
3370                                 wstats.qual = hdr.rssi[0];
3371                                 if (apriv->rssi)
3372                                         wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
3373                                 else
3374                                         wstats.level = (hdr.rssi[1] + 321) / 2;
3375                                 wstats.noise = apriv->wstats.qual.noise;
3376                                 wstats.updated = IW_QUAL_LEVEL_UPDATED
3377                                         | IW_QUAL_QUAL_UPDATED
3378                                         | IW_QUAL_DBM;
3379                                 /* Update spy records */
3380                                 wireless_spy_update(dev, sa, &wstats);
3381                         }
3382 #endif /* WIRELESS_SPY */
3383                         OUT4500( apriv, EVACK, EV_RX);
3384
3385                         if (test_bit(FLAG_802_11, &apriv->flags)) {
3386                                 skb_reset_mac_header(skb);
3387                                 skb->pkt_type = PACKET_OTHERHOST;
3388                                 skb->dev = apriv->wifidev;
3389                                 skb->protocol = htons(ETH_P_802_2);
3390                         } else
3391                                 skb->protocol = eth_type_trans(skb,dev);
3392                         skb->dev->last_rx = jiffies;
3393                         skb->ip_summed = CHECKSUM_NONE;
3394
3395                         netif_rx( skb );
3396                 }
3397 exitrx:
3398
3399                 /* Check to see if a packet has been transmitted */
3400                 if (  status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
3401                         int i;
3402                         int len = 0;
3403                         int index = -1;
3404
3405                         if (test_bit(FLAG_MPI,&apriv->flags)) {
3406                                 unsigned long flags;
3407
3408                                 if (status & EV_TXEXC)
3409                                         get_tx_error(apriv, -1);
3410                                 spin_lock_irqsave(&apriv->aux_lock, flags);
3411                                 if (!skb_queue_empty(&apriv->txq)) {
3412                                         spin_unlock_irqrestore(&apriv->aux_lock,flags);
3413                                         mpi_send_packet (dev);
3414                                 } else {
3415                                         clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
3416                                         spin_unlock_irqrestore(&apriv->aux_lock,flags);
3417                                         netif_wake_queue (dev);
3418                                 }
3419                                 OUT4500( apriv, EVACK,
3420                                         status & (EV_TX|EV_TXCPY|EV_TXEXC));
3421                                 goto exittx;
3422                         }
3423
3424                         fid = IN4500(apriv, TXCOMPLFID);
3425
3426                         for( i = 0; i < MAX_FIDS; i++ ) {
3427                                 if ( ( apriv->fids[i] & 0xffff ) == fid ) {
3428                                         len = apriv->fids[i] >> 16;
3429                                         index = i;
3430                                 }
3431                         }
3432                         if (index != -1) {
3433                                 if (status & EV_TXEXC)
3434                                         get_tx_error(apriv, index);
3435                                 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
3436                                 /* Set up to be used again */
3437                                 apriv->fids[index] &= 0xffff;
3438                                 if (index < MAX_FIDS / 2) {
3439                                         if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
3440                                                 netif_wake_queue(dev);
3441                                 } else {
3442                                         if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
3443                                                 netif_wake_queue(apriv->wifidev);
3444                                 }
3445                         } else {
3446                                 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3447                                 airo_print_err(apriv->dev->name, "Unallocated FID was "
3448                                         "used to xmit" );
3449                         }
3450                 }
3451 exittx:
3452                 if ( status & ~STATUS_INTS & ~IGNORE_INTS )
3453                         airo_print_warn(apriv->dev->name, "Got weird status %x",
3454                                 status & ~STATUS_INTS & ~IGNORE_INTS );
3455         }
3456
3457         if (savedInterrupts)
3458                 OUT4500( apriv, EVINTEN, savedInterrupts );
3459
3460         /* done.. */
3461         return IRQ_RETVAL(handled);
3462 }
3463
3464 /*
3465  *  Routines to talk to the card
3466  */
3467
3468 /*
3469  *  This was originally written for the 4500, hence the name
3470  *  NOTE:  If use with 8bit mode and SMP bad things will happen!
3471  *         Why would some one do 8 bit IO in an SMP machine?!?
3472  */
3473 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
3474         if (test_bit(FLAG_MPI,&ai->flags))
3475                 reg <<= 1;
3476         if ( !do8bitIO )
3477                 outw( val, ai->dev->base_addr + reg );
3478         else {
3479                 outb( val & 0xff, ai->dev->base_addr + reg );
3480                 outb( val >> 8, ai->dev->base_addr + reg + 1 );
3481         }
3482 }
3483
3484 static u16 IN4500( struct airo_info *ai, u16 reg ) {
3485         unsigned short rc;
3486
3487         if (test_bit(FLAG_MPI,&ai->flags))
3488                 reg <<= 1;
3489         if ( !do8bitIO )
3490                 rc = inw( ai->dev->base_addr + reg );
3491         else {
3492                 rc = inb( ai->dev->base_addr + reg );
3493                 rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
3494         }
3495         return rc;
3496 }
3497
3498 static int enable_MAC(struct airo_info *ai, int lock)
3499 {
3500         int rc;
3501         Cmd cmd;
3502         Resp rsp;
3503
3504         /* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3505          * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3506          * Note : we could try to use !netif_running(dev) in enable_MAC()
3507          * instead of this flag, but I don't trust it *within* the
3508          * open/close functions, and testing both flags together is
3509          * "cheaper" - Jean II */
3510         if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3511
3512         if (lock && down_interruptible(&ai->sem))
3513                 return -ERESTARTSYS;
3514
3515         if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3516                 memset(&cmd, 0, sizeof(cmd));
3517                 cmd.cmd = MAC_ENABLE;
3518                 rc = issuecommand(ai, &cmd, &rsp);
3519                 if (rc == SUCCESS)
3520                         set_bit(FLAG_ENABLED, &ai->flags);
3521         } else
3522                 rc = SUCCESS;
3523
3524         if (lock)
3525             up(&ai->sem);
3526
3527         if (rc)
3528                 airo_print_err(ai->dev->name, "Cannot enable MAC");
3529         else if ((rsp.status & 0xFF00) != 0) {
3530                 airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
3531                         "rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
3532                 rc = ERROR;
3533         }
3534         return rc;
3535 }
3536
3537 static void disable_MAC( struct airo_info *ai, int lock ) {
3538         Cmd cmd;
3539         Resp rsp;
3540
3541         if (lock && down_interruptible(&ai->sem))
3542                 return;
3543
3544         if (test_bit(FLAG_ENABLED, &ai->flags)) {
3545                 memset(&cmd, 0, sizeof(cmd));
3546                 cmd.cmd = MAC_DISABLE; // disable in case already enabled
3547                 issuecommand(ai, &cmd, &rsp);
3548                 clear_bit(FLAG_ENABLED, &ai->flags);
3549         }
3550         if (lock)
3551                 up(&ai->sem);
3552 }
3553
3554 static void enable_interrupts( struct airo_info *ai ) {
3555         /* Enable the interrupts */
3556         OUT4500( ai, EVINTEN, STATUS_INTS );
3557 }
3558
3559 static void disable_interrupts( struct airo_info *ai ) {
3560         OUT4500( ai, EVINTEN, 0 );
3561 }
3562
3563 static void mpi_receive_802_3(struct airo_info *ai)
3564 {
3565         RxFid rxd;
3566         int len = 0;
3567         struct sk_buff *skb;
3568         char *buffer;
3569         int off = 0;
3570         MICBuffer micbuf;
3571
3572         memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3573         /* Make sure we got something */
3574         if (rxd.rdy && rxd.valid == 0) {
3575                 len = rxd.len + 12;
3576                 if (len < 12 || len > 2048)
3577                         goto badrx;
3578
3579                 skb = dev_alloc_skb(len);
3580                 if (!skb) {
3581                         ai->stats.rx_dropped++;
3582                         goto badrx;
3583                 }
3584                 buffer = skb_put(skb,len);
3585                 memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3586                 if (ai->micstats.enabled) {
3587                         memcpy(&micbuf,
3588                                 ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3589                                 sizeof(micbuf));
3590                         if (ntohs(micbuf.typelen) <= 0x05DC) {
3591                                 if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3592                                         goto badmic;
3593
3594                                 off = sizeof(micbuf);
3595                                 skb_trim (skb, len - off);
3596                         }
3597                 }
3598                 memcpy(buffer + ETH_ALEN * 2,
3599                         ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3600                         len - ETH_ALEN * 2 - off);
3601                 if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3602 badmic:
3603                         dev_kfree_skb_irq (skb);
3604                         goto badrx;
3605                 }
3606 #ifdef WIRELESS_SPY
3607                 if (ai->spy_data.spy_number > 0) {
3608                         char *sa;
3609                         struct iw_quality wstats;
3610                         /* Prepare spy data : addr + qual */
3611                         sa = buffer + ETH_ALEN;
3612                         wstats.qual = 0; /* XXX Where do I get that info from ??? */
3613                         wstats.level = 0;
3614                         wstats.updated = 0;
3615                         /* Update spy records */
3616                         wireless_spy_update(ai->dev, sa, &wstats);
3617                 }
3618 #endif /* WIRELESS_SPY */
3619
3620                 skb->ip_summed = CHECKSUM_NONE;
3621                 skb->protocol = eth_type_trans(skb, ai->dev);
3622                 skb->dev->last_rx = jiffies;
3623                 netif_rx(skb);
3624         }
3625 badrx:
3626         if (rxd.valid == 0) {
3627                 rxd.valid = 1;
3628                 rxd.rdy = 0;
3629                 rxd.len = PKTSIZE;
3630                 memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3631         }
3632 }
3633
3634 void mpi_receive_802_11 (struct airo_info *ai)
3635 {
3636         RxFid rxd;
3637         struct sk_buff *skb = NULL;
3638         u16 len, hdrlen = 0;
3639         __le16 fc;
3640 #pragma pack(1)
3641         struct {
3642                 __le16 status, len;
3643                 u8 rssi[2];
3644                 u8 rate;
3645                 u8 freq;
3646                 __le16 tmp[4];
3647         } hdr;
3648 #pragma pack()
3649         u16 gap;
3650         u16 *buffer;
3651         char *ptr = ai->rxfids[0].virtual_host_addr+4;
3652
3653         memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3654         memcpy ((char *)&hdr, ptr, sizeof(hdr));
3655         ptr += sizeof(hdr);
3656         /* Bad CRC. Ignore packet */
3657         if (le16_to_cpu(hdr.status) & 2)
3658                 hdr.len = 0;
3659         if (ai->wifidev == NULL)
3660                 hdr.len = 0;
3661         len = le16_to_cpu(hdr.len);
3662         if (len > AIRO_DEF_MTU) {
3663                 airo_print_err(ai->dev->name, "Bad size %d", len);
3664                 goto badrx;
3665         }
3666         if (len == 0)
3667                 goto badrx;
3668
3669         fc = get_unaligned((__le16 *)ptr);
3670         hdrlen = header_len(fc);
3671
3672         skb = dev_alloc_skb( len + hdrlen + 2 );
3673         if ( !skb ) {
3674                 ai->stats.rx_dropped++;
3675                 goto badrx;
3676         }
3677         buffer = (u16*)skb_put (skb, len + hdrlen);
3678         memcpy ((char *)buffer, ptr, hdrlen);
3679         ptr += hdrlen;
3680         if (hdrlen == 24)
3681                 ptr += 6;
3682         gap = le16_to_cpu(get_unaligned((__le16 *)ptr));
3683         ptr += sizeof(__le16);
3684         if (gap) {
3685                 if (gap <= 8)
3686                         ptr += gap;
3687                 else
3688                         airo_print_err(ai->dev->name,
3689                             "gaplen too big. Problems will follow...");
3690         }
3691         memcpy ((char *)buffer + hdrlen, ptr, len);
3692         ptr += len;
3693 #ifdef IW_WIRELESS_SPY    /* defined in iw_handler.h */
3694         if (ai->spy_data.spy_number > 0) {
3695                 char *sa;
3696                 struct iw_quality wstats;
3697                 /* Prepare spy data : addr + qual */
3698                 sa = (char*)buffer + 10;
3699                 wstats.qual = hdr.rssi[0];
3700                 if (ai->rssi)
3701                         wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3702                 else
3703                         wstats.level = (hdr.rssi[1] + 321) / 2;
3704                 wstats.noise = ai->wstats.qual.noise;
3705                 wstats.updated = IW_QUAL_QUAL_UPDATED
3706                         | IW_QUAL_LEVEL_UPDATED
3707                         | IW_QUAL_DBM;
3708                 /* Update spy records */
3709                 wireless_spy_update(ai->dev, sa, &wstats);
3710         }
3711 #endif /* IW_WIRELESS_SPY */
3712         skb_reset_mac_header(skb);
3713         skb->pkt_type = PACKET_OTHERHOST;
3714         skb->dev = ai->wifidev;
3715         skb->protocol = htons(ETH_P_802_2);
3716         skb->dev->last_rx = jiffies;
3717         skb->ip_summed = CHECKSUM_NONE;
3718         netif_rx( skb );
3719 badrx:
3720         if (rxd.valid == 0) {
3721                 rxd.valid = 1;
3722                 rxd.rdy = 0;
3723                 rxd.len = PKTSIZE;
3724                 memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3725         }
3726 }
3727
3728 static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3729 {
3730         Cmd cmd;
3731         Resp rsp;
3732         int status;
3733         int i;
3734         SsidRid mySsid;
3735         __le16 lastindex;
3736         WepKeyRid wkr;
3737         int rc;
3738
3739         memset( &mySsid, 0, sizeof( mySsid ) );
3740         kfree (ai->flash);
3741         ai->flash = NULL;
3742
3743         /* The NOP is the first step in getting the card going */
3744         cmd.cmd = NOP;
3745         cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3746         if (lock && down_interruptible(&ai->sem))
3747                 return ERROR;
3748         if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
3749                 if (lock)
3750                         up(&ai->sem);
3751                 return ERROR;
3752         }
3753         disable_MAC( ai, 0);
3754
3755         // Let's figure out if we need to use the AUX port
3756         if (!test_bit(FLAG_MPI,&ai->flags)) {
3757                 cmd.cmd = CMD_ENABLEAUX;
3758                 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3759                         if (lock)
3760                                 up(&ai->sem);
3761                         airo_print_err(ai->dev->name, "Error checking for AUX port");
3762                         return ERROR;
3763                 }
3764                 if (!aux_bap || rsp.status & 0xff00) {
3765                         ai->bap_read = fast_bap_read;
3766                         airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
3767                 } else {
3768                         ai->bap_read = aux_bap_read;
3769                         airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
3770                 }
3771         }
3772         if (lock)
3773                 up(&ai->sem);
3774         if (ai->config.len == 0) {
3775                 tdsRssiRid rssi_rid;
3776                 CapabilityRid cap_rid;
3777
3778                 kfree(ai->APList);
3779                 ai->APList = NULL;
3780                 kfree(ai->SSID);
3781                 ai->SSID = NULL;
3782                 // general configuration (read/modify/write)
3783                 status = readConfigRid(ai, lock);
3784                 if ( status != SUCCESS ) return ERROR;
3785
3786                 status = readCapabilityRid(ai, &cap_rid, lock);
3787                 if ( status != SUCCESS ) return ERROR;
3788
3789                 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3790                 if ( status == SUCCESS ) {
3791                         if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3792                                 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3793                 }
3794                 else {
3795                         kfree(ai->rssi);
3796                         ai->rssi = NULL;
3797                         if (cap_rid.softCap & cpu_to_le16(8))
3798                                 ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3799                         else
3800                                 airo_print_warn(ai->dev->name, "unknown received signal "
3801                                                 "level scale");
3802                 }
3803                 ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3804                 ai->config.authType = AUTH_OPEN;
3805                 ai->config.modulation = MOD_CCK;
3806
3807                 if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
3808                     (cap_rid.extSoftCap & cpu_to_le16(1)) &&
3809                     micsetup(ai) == SUCCESS) {
3810                         ai->config.opmode |= MODE_MIC;
3811                         set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3812                 }
3813
3814                 /* Save off the MAC */
3815                 for( i = 0; i < ETH_ALEN; i++ ) {
3816                         mac[i] = ai->config.macAddr[i];
3817                 }
3818
3819                 /* Check to see if there are any insmod configured
3820                    rates to add */
3821                 if ( rates[0] ) {
3822                         int i = 0;
3823                         memset(ai->config.rates,0,sizeof(ai->config.rates));
3824                         for( i = 0; i < 8 && rates[i]; i++ ) {
3825                                 ai->config.rates[i] = rates[i];
3826                         }
3827                 }
3828                 if ( basic_rate > 0 ) {
3829                         int i;
3830                         for( i = 0; i < 8; i++ ) {
3831                                 if ( ai->config.rates[i] == basic_rate ||
3832                                      !ai->config.rates ) {
3833                                         ai->config.rates[i] = basic_rate | 0x80;
3834                                         break;
3835                                 }
3836                         }
3837                 }
3838                 set_bit (FLAG_COMMIT, &ai->flags);
3839         }
3840
3841         /* Setup the SSIDs if present */
3842         if ( ssids[0] ) {
3843                 int i;
3844                 for( i = 0; i < 3 && ssids[i]; i++ ) {
3845                         size_t len = strlen(ssids[i]);
3846                         if (len > 32)
3847                                 len = 32;
3848                         mySsid.ssids[i].len = cpu_to_le16(len);
3849                         memcpy(mySsid.ssids[i].ssid, ssids[i], len);
3850                 }
3851                 mySsid.len = cpu_to_le16(sizeof(mySsid));
3852         }
3853
3854         status = writeConfigRid(ai, lock);
3855         if ( status != SUCCESS ) return ERROR;
3856
3857         /* Set up the SSID list */
3858         if ( ssids[0] ) {
3859                 status = writeSsidRid(ai, &mySsid, lock);
3860                 if ( status != SUCCESS ) return ERROR;
3861         }
3862
3863         status = enable_MAC(ai, lock);
3864         if (status != SUCCESS)
3865                 return ERROR;
3866
3867         /* Grab the initial wep key, we gotta save it for auto_wep */
3868         rc = readWepKeyRid(ai, &wkr, 1, lock);
3869         if (rc == SUCCESS) do {
3870                 lastindex = wkr.kindex;
3871                 if (wkr.kindex == cpu_to_le16(0xffff)) {
3872                         ai->defindex = wkr.mac[0];
3873                 }
3874                 rc = readWepKeyRid(ai, &wkr, 0, lock);
3875         } while(lastindex != wkr.kindex);
3876
3877         try_auto_wep(ai);
3878
3879         return SUCCESS;
3880 }
3881
3882 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3883         // Im really paranoid about letting it run forever!
3884         int max_tries = 600000;
3885
3886         if (IN4500(ai, EVSTAT) & EV_CMD)
3887                 OUT4500(ai, EVACK, EV_CMD);
3888
3889         OUT4500(ai, PARAM0, pCmd->parm0);
3890         OUT4500(ai, PARAM1, pCmd->parm1);
3891         OUT4500(ai, PARAM2, pCmd->parm2);
3892         OUT4500(ai, COMMAND, pCmd->cmd);
3893
3894         while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3895                 if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3896                         // PC4500 didn't notice command, try again
3897                         OUT4500(ai, COMMAND, pCmd->cmd);
3898                 if (!in_atomic() && (max_tries & 255) == 0)
3899                         schedule();
3900         }
3901
3902         if ( max_tries == -1 ) {
3903                 airo_print_err(ai->dev->name,
3904                         "Max tries exceeded when issueing command");
3905                 if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3906                         OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3907                 return ERROR;
3908         }
3909
3910         // command completed
3911         pRsp->status = IN4500(ai, STATUS);
3912         pRsp->rsp0 = IN4500(ai, RESP0);
3913         pRsp->rsp1 = IN4500(ai, RESP1);
3914         pRsp->rsp2 = IN4500(ai, RESP2);
3915         if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
3916                 airo_print_err(ai->dev->name,
3917                         "cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
3918                         pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
3919                         pRsp->rsp2);
3920
3921         // clear stuck command busy if necessary
3922         if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
3923                 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3924         }
3925         // acknowledge processing the status/response
3926         OUT4500(ai, EVACK, EV_CMD);
3927
3928         return SUCCESS;
3929 }
3930
3931 /* Sets up the bap to start exchange data.  whichbap should
3932  * be one of the BAP0 or BAP1 defines.  Locks should be held before
3933  * calling! */
3934 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3935 {
3936         int timeout = 50;
3937         int max_tries = 3;
3938
3939         OUT4500(ai, SELECT0+whichbap, rid);
3940         OUT4500(ai, OFFSET0+whichbap, offset);
3941         while (1) {
3942                 int status = IN4500(ai, OFFSET0+whichbap);
3943                 if (status & BAP_BUSY) {
3944                         /* This isn't really a timeout, but its kinda
3945                            close */
3946                         if (timeout--) {
3947                                 continue;
3948                         }
3949                 } else if ( status & BAP_ERR ) {
3950                         /* invalid rid or offset */
3951                         airo_print_err(ai->dev->name, "BAP error %x %d",
3952                                 status, whichbap );
3953                         return ERROR;
3954                 } else if (status & BAP_DONE) { // success
3955                         return SUCCESS;
3956                 }
3957                 if ( !(max_tries--) ) {
3958                         airo_print_err(ai->dev->name,
3959                                 "BAP setup error too many retries\n");
3960                         return ERROR;
3961                 }
3962                 // -- PC4500 missed it, try again
3963                 OUT4500(ai, SELECT0+whichbap, rid);
3964                 OUT4500(ai, OFFSET0+whichbap, offset);
3965                 timeout = 50;
3966         }
3967 }
3968
3969 /* should only be called by aux_bap_read.  This aux function and the
3970    following use concepts not documented in the developers guide.  I
3971    got them from a patch given to my by Aironet */
3972 static u16 aux_setup(struct airo_info *ai, u16 page,
3973                      u16 offset, u16 *len)
3974 {
3975         u16 next;
3976
3977         OUT4500(ai, AUXPAGE, page);
3978         OUT4500(ai, AUXOFF, 0);
3979         next = IN4500(ai, AUXDATA);
3980         *len = IN4500(ai, AUXDATA)&0xff;
3981         if (offset != 4) OUT4500(ai, AUXOFF, offset);
3982         return next;
3983 }
3984
3985 /* requires call to bap_setup() first */
3986 static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
3987                         int bytelen, int whichbap)
3988 {
3989         u16 len;
3990         u16 page;
3991         u16 offset;
3992         u16 next;
3993         int words;
3994         int i;
3995         unsigned long flags;
3996
3997         spin_lock_irqsave(&ai->aux_lock, flags);
3998         page = IN4500(ai, SWS0+whichbap);
3999         offset = IN4500(ai, SWS2+whichbap);
4000         next = aux_setup(ai, page, offset, &len);
4001         words = (bytelen+1)>>1;
4002
4003         for (i=0; i<words;) {
4004                 int count;
4005                 count = (len>>1) < (words-i) ? (len>>1) : (words-i);
4006                 if ( !do8bitIO )
4007                         insw( ai->dev->base_addr+DATA0+whichbap,
4008                               pu16Dst+i,count );
4009                 else
4010                         insb( ai->dev->base_addr+DATA0+whichbap,
4011                               pu16Dst+i, count << 1 );
4012                 i += count;
4013                 if (i<words) {
4014                         next = aux_setup(ai, next, 4, &len);
4015                 }
4016         }
4017         spin_unlock_irqrestore(&ai->aux_lock, flags);
4018         return SUCCESS;
4019 }
4020
4021
4022 /* requires call to bap_setup() first */
4023 static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4024                          int bytelen, int whichbap)
4025 {
4026         bytelen = (bytelen + 1) & (~1); // round up to even value
4027         if ( !do8bitIO )
4028                 insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
4029         else
4030                 insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
4031         return SUCCESS;
4032 }
4033
4034 /* requires call to bap_setup() first */
4035 static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
4036                      int bytelen, int whichbap)
4037 {
4038         bytelen = (bytelen + 1) & (~1); // round up to even value
4039         if ( !do8bitIO )
4040                 outsw( ai->dev->base_addr+DATA0+whichbap,
4041                        pu16Src, bytelen>>1 );
4042         else
4043                 outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
4044         return SUCCESS;
4045 }
4046
4047 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
4048 {
4049         Cmd cmd; /* for issuing commands */
4050         Resp rsp; /* response from commands */
4051         u16 status;
4052
4053         memset(&cmd, 0, sizeof(cmd));
4054         cmd.cmd = accmd;
4055         cmd.parm0 = rid;
4056         status = issuecommand(ai, &cmd, &rsp);
4057         if (status != 0) return status;
4058         if ( (rsp.status & 0x7F00) != 0) {
4059                 return (accmd << 8) + (rsp.rsp0 & 0xFF);
4060         }
4061         return 0;
4062 }
4063
4064 /*  Note, that we are using BAP1 which is also used by transmit, so
4065  *  we must get a lock. */
4066 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
4067 {
4068         u16 status;
4069         int rc = SUCCESS;
4070
4071         if (lock) {
4072                 if (down_interruptible(&ai->sem))
4073                         return ERROR;
4074         }
4075         if (test_bit(FLAG_MPI,&ai->flags)) {
4076                 Cmd cmd;
4077                 Resp rsp;
4078
4079                 memset(&cmd, 0, sizeof(cmd));
4080                 memset(&rsp, 0, sizeof(rsp));
4081                 ai->config_desc.rid_desc.valid = 1;
4082                 ai->config_desc.rid_desc.len = RIDSIZE;
4083                 ai->config_desc.rid_desc.rid = 0;
4084                 ai->config_desc.rid_desc.host_addr = ai->ridbus;
4085
4086                 cmd.cmd = CMD_ACCESS;
4087                 cmd.parm0 = rid;
4088
4089                 memcpy_toio(ai->config_desc.card_ram_off,
4090                         &ai->config_desc.rid_desc, sizeof(Rid));
4091
4092                 rc = issuecommand(ai, &cmd, &rsp);
4093
4094                 if (rsp.status & 0x7f00)
4095                         rc = rsp.rsp0;
4096                 if (!rc)
4097                         memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
4098                 goto done;
4099         } else {
4100                 if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4101                         rc = status;
4102                         goto done;
4103                 }
4104                 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4105                         rc = ERROR;
4106                         goto done;
4107                 }
4108                 // read the rid length field
4109                 bap_read(ai, pBuf, 2, BAP1);
4110                 // length for remaining part of rid
4111                 len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
4112
4113                 if ( len <= 2 ) {
4114                         airo_print_err(ai->dev->name,
4115                                 "Rid %x has a length of %d which is too short",
4116                                 (int)rid, (int)len );
4117                         rc = ERROR;
4118                         goto done;
4119                 }
4120                 // read remainder of the rid
4121                 rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
4122         }
4123 done:
4124         if (lock)
4125                 up(&ai->sem);
4126         return rc;
4127 }
4128
4129 /*  Note, that we are using BAP1 which is also used by transmit, so
4130  *  make sure this isnt called when a transmit is happening */
4131 static int PC4500_writerid(struct airo_info *ai, u16 rid,
4132                            const void *pBuf, int len, int lock)
4133 {
4134         u16 status;
4135         int rc = SUCCESS;
4136
4137         *(__le16*)pBuf = cpu_to_le16((u16)len);
4138
4139         if (lock) {
4140                 if (down_interruptible(&ai->sem))
4141                         return ERROR;
4142         }
4143         if (test_bit(FLAG_MPI,&ai->flags)) {
4144                 Cmd cmd;
4145                 Resp rsp;
4146
4147                 if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
4148                         airo_print_err(ai->dev->name,
4149                                 "%s: MAC should be disabled (rid=%04x)",
4150                                 __FUNCTION__, rid);
4151                 memset(&cmd, 0, sizeof(cmd));
4152                 memset(&rsp, 0, sizeof(rsp));
4153
4154                 ai->config_desc.rid_desc.valid = 1;
4155                 ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4156                 ai->config_desc.rid_desc.rid = 0;
4157
4158                 cmd.cmd = CMD_WRITERID;
4159                 cmd.parm0 = rid;
4160
4161                 memcpy_toio(ai->config_desc.card_ram_off,
4162                         &ai->config_desc.rid_desc, sizeof(Rid));
4163
4164                 if (len < 4 || len > 2047) {
4165                         airo_print_err(ai->dev->name, "%s: len=%d", __FUNCTION__, len);
4166                         rc = -1;
4167                 } else {
4168                         memcpy((char *)ai->config_desc.virtual_host_addr,
4169                                 pBuf, len);
4170
4171                         rc = issuecommand(ai, &cmd, &rsp);
4172                         if ((rc & 0xff00) != 0) {
4173                                 airo_print_err(ai->dev->name, "%s: Write rid Error %d",
4174                                                 __FUNCTION__, rc);
4175                                 airo_print_err(ai->dev->name, "%s: Cmd=%04x",
4176                                                 __FUNCTION__, cmd.cmd);
4177                         }
4178
4179                         if ((rsp.status & 0x7f00))
4180                                 rc = rsp.rsp0;
4181                 }
4182         } else {
4183                 // --- first access so that we can write the rid data
4184                 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4185                         rc = status;
4186                         goto done;
4187                 }
4188                 // --- now write the rid data
4189                 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4190                         rc = ERROR;
4191                         goto done;
4192                 }
4193                 bap_write(ai, pBuf, len, BAP1);
4194                 // ---now commit the rid data
4195                 rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4196         }
4197 done:
4198         if (lock)
4199                 up(&ai->sem);
4200         return rc;
4201 }
4202
4203 /* Allocates a FID to be used for transmitting packets.  We only use
4204    one for now. */
4205 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4206 {
4207         unsigned int loop = 3000;
4208         Cmd cmd;
4209         Resp rsp;
4210         u16 txFid;
4211         __le16 txControl;
4212
4213         cmd.cmd = CMD_ALLOCATETX;
4214         cmd.parm0 = lenPayload;
4215         if (down_interruptible(&ai->sem))
4216                 return ERROR;
4217         if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
4218                 txFid = ERROR;
4219                 goto done;
4220         }
4221         if ( (rsp.status & 0xFF00) != 0) {
4222                 txFid = ERROR;
4223                 goto done;
4224         }
4225         /* wait for the allocate event/indication
4226          * It makes me kind of nervous that this can just sit here and spin,
4227          * but in practice it only loops like four times. */
4228         while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4229         if (!loop) {
4230                 txFid = ERROR;
4231                 goto done;
4232         }
4233
4234         // get the allocated fid and acknowledge
4235         txFid = IN4500(ai, TXALLOCFID);
4236         OUT4500(ai, EVACK, EV_ALLOC);
4237
4238         /*  The CARD is pretty cool since it converts the ethernet packet
4239          *  into 802.11.  Also note that we don't release the FID since we
4240          *  will be using the same one over and over again. */
4241         /*  We only have to setup the control once since we are not
4242          *  releasing the fid. */
4243         if (raw)
4244                 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4245                         | TXCTL_ETHERNET | TXCTL_NORELEASE);
4246         else
4247                 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4248                         | TXCTL_ETHERNET | TXCTL_NORELEASE);
4249         if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4250                 txFid = ERROR;
4251         else
4252                 bap_write(ai, &txControl, sizeof(txControl), BAP1);
4253
4254 done:
4255         up(&ai->sem);
4256
4257         return txFid;
4258 }
4259
4260 /* In general BAP1 is dedicated to transmiting packets.  However,
4261    since we need a BAP when accessing RIDs, we also use BAP1 for that.
4262    Make sure the BAP1 spinlock is held when this is called. */
4263 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
4264 {
4265         __le16 payloadLen;
4266         Cmd cmd;
4267         Resp rsp;
4268         int miclen = 0;
4269         u16 txFid = len;
4270         MICBuffer pMic;
4271
4272         len >>= 16;
4273
4274         if (len <= ETH_ALEN * 2) {
4275                 airo_print_warn(ai->dev->name, "Short packet %d", len);
4276                 return ERROR;
4277         }
4278         len -= ETH_ALEN * 2;
4279
4280         if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
4281             (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
4282                 if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
4283                         return ERROR;
4284                 miclen = sizeof(pMic);
4285         }
4286         // packet is destination[6], source[6], payload[len-12]
4287         // write the payload length and dst/src/payload
4288         if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4289         /* The hardware addresses aren't counted as part of the payload, so
4290          * we have to subtract the 12 bytes for the addresses off */
4291         payloadLen = cpu_to_le16(len + miclen);
4292         bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4293         bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
4294         if (miclen)
4295                 bap_write(ai, (__le16*)&pMic, miclen, BAP1);
4296         bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
4297         // issue the transmit command
4298         memset( &cmd, 0, sizeof( cmd ) );
4299         cmd.cmd = CMD_TRANSMIT;
4300         cmd.parm0 = txFid;
4301         if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4302         if ( (rsp.status & 0xFF00) != 0) return ERROR;
4303         return SUCCESS;
4304 }
4305
4306 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
4307 {
4308         __le16 fc, payloadLen;
4309         Cmd cmd;
4310         Resp rsp;
4311         int hdrlen;
4312         static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
4313         /* padding of header to full size + le16 gaplen (6) + gaplen bytes */
4314         u16 txFid = len;
4315         len >>= 16;
4316
4317         fc = *(__le16*)pPacket;
4318         hdrlen = header_len(fc);
4319
4320         if (len < hdrlen) {
4321                 airo_print_warn(ai->dev->name, "Short packet %d", len);
4322                 return ERROR;
4323         }
4324
4325         /* packet is 802.11 header +  payload
4326          * write the payload length and dst/src/payload */
4327         if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4328         /* The 802.11 header aren't counted as part of the payload, so
4329          * we have to subtract the header bytes off */
4330         payloadLen = cpu_to_le16(len-hdrlen);
4331         bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4332         if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4333         bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
4334         bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
4335
4336         bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
4337         // issue the transmit command
4338         memset( &cmd, 0, sizeof( cmd ) );
4339         cmd.cmd = CMD_TRANSMIT;
4340         cmd.parm0 = txFid;
4341         if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4342         if ( (rsp.status & 0xFF00) != 0) return ERROR;
4343         return SUCCESS;
4344 }
4345
4346 /*
4347  *  This is the proc_fs routines.  It is a bit messier than I would
4348  *  like!  Feel free to clean it up!
4349  */
4350
4351 static ssize_t proc_read( struct file *file,
4352                           char __user *buffer,
4353                           size_t len,
4354                           loff_t *offset);
4355
4356 static ssize_t proc_write( struct file *file,
4357                            const char __user *buffer,
4358                            size_t len,
4359                            loff_t *offset );
4360 static int proc_close( struct inode *inode, struct file *file );
4361
4362 static int proc_stats_open( struct inode *inode, struct file *file );
4363 static int proc_statsdelta_open( struct inode *inode, struct file *file );
4364 static int proc_status_open( struct inode *inode, struct file *file );
4365 static int proc_SSID_open( struct inode *inode, struct file *file );
4366 static int proc_APList_open( struct inode *inode, struct file *file );
4367 static int proc_BSSList_open( struct inode *inode, struct file *file );
4368 static int proc_config_open( struct inode *inode, struct file *file );
4369 static int proc_wepkey_open( struct inode *inode, struct file *file );
4370
4371 static const struct file_operations proc_statsdelta_ops = {
4372         .read           = proc_read,
4373         .open           = proc_statsdelta_open,
4374         .release        = proc_close
4375 };
4376
4377 static const struct file_operations proc_stats_ops = {
4378         .read           = proc_read,
4379         .open           = proc_stats_open,
4380         .release        = proc_close
4381 };
4382
4383 static const struct file_operations proc_status_ops = {
4384         .read           = proc_read,
4385         .open           = proc_status_open,
4386         .release        = proc_close
4387 };
4388
4389 static const struct file_operations proc_SSID_ops = {
4390         .read           = proc_read,
4391         .write          = proc_write,
4392         .open           = proc_SSID_open,
4393         .release        = proc_close
4394 };
4395
4396 static const struct file_operations proc_BSSList_ops = {
4397         .read           = proc_read,
4398         .write          = proc_write,
4399         .open           = proc_BSSList_open,
4400         .release        = proc_close
4401 };
4402
4403 static const struct file_operations proc_APList_ops = {
4404         .read           = proc_read,
4405         .write          = proc_write,
4406         .open           = proc_APList_open,
4407         .release        = proc_close
4408 };
4409
4410 static const struct file_operations proc_config_ops = {
4411         .read           = proc_read,
4412         .write          = proc_write,
4413         .open           = proc_config_open,
4414         .release        = proc_close
4415 };
4416
4417 static const struct file_operations proc_wepkey_ops = {
4418         .read           = proc_read,
4419         .write          = proc_write,
4420         .open           = proc_wepkey_open,
4421         .release        = proc_close
4422 };
4423
4424 static struct proc_dir_entry *airo_entry;
4425
4426 struct proc_data {
4427         int release_buffer;
4428         int readlen;
4429         char *rbuffer;
4430         int writelen;
4431         int maxwritelen;
4432         char *wbuffer;
4433         void (*on_close) (struct inode *, struct file *);
4434 };
4435
4436 #ifndef SETPROC_OPS
4437 #define SETPROC_OPS(entry, ops) (entry)->proc_fops = &(ops)
4438 #endif
4439
4440 static int setup_proc_entry( struct net_device *dev,
4441                              struct airo_info *apriv ) {
4442         struct proc_dir_entry *entry;
4443         /* First setup the device directory */
4444         strcpy(apriv->proc_name,dev->name);
4445         apriv->proc_entry = create_proc_entry(apriv->proc_name,
4446                                               S_IFDIR|airo_perm,
4447                                               airo_entry);
4448         if (!apriv->proc_entry)
4449                 goto fail;
4450         apriv->proc_entry->uid = proc_uid;
4451         apriv->proc_entry->gid = proc_gid;
4452         apriv->proc_entry->owner = THIS_MODULE;
4453
4454         /* Setup the StatsDelta */
4455         entry = create_proc_entry("StatsDelta",
4456                                   S_IFREG | (S_IRUGO&proc_perm),
4457                                   apriv->proc_entry);
4458         if (!entry)
4459                 goto fail_stats_delta;
4460         entry->uid = proc_uid;
4461         entry->gid = proc_gid;
4462         entry->data = dev;
4463         entry->owner = THIS_MODULE;
4464         SETPROC_OPS(entry, proc_statsdelta_ops);
4465
4466         /* Setup the Stats */
4467         entry = create_proc_entry("Stats",
4468                                   S_IFREG | (S_IRUGO&proc_perm),
4469                                   apriv->proc_entry);
4470         if (!entry)
4471                 goto fail_stats;
4472         entry->uid = proc_uid;
4473         entry->gid = proc_gid;
4474         entry->data = dev;
4475         entry->owner = THIS_MODULE;
4476         SETPROC_OPS(entry, proc_stats_ops);
4477
4478         /* Setup the Status */
4479         entry = create_proc_entry("Status",
4480                                   S_IFREG | (S_IRUGO&proc_perm),
4481                                   apriv->proc_entry);
4482         if (!entry)
4483                 goto fail_status;
4484         entry->uid = proc_uid;
4485         entry->gid = proc_gid;
4486         entry->data = dev;
4487         entry->owner = THIS_MODULE;
4488         SETPROC_OPS(entry, proc_status_ops);
4489
4490         /* Setup the Config */
4491         entry = create_proc_entry("Config",
4492                                   S_IFREG | proc_perm,
4493                                   apriv->proc_entry);
4494         if (!entry)
4495                 goto fail_config;
4496         entry->uid = proc_uid;
4497         entry->gid = proc_gid;
4498         entry->data = dev;
4499         entry->owner = THIS_MODULE;
4500         SETPROC_OPS(entry, proc_config_ops);
4501
4502         /* Setup the SSID */
4503         entry = create_proc_entry("SSID",
4504                                   S_IFREG | proc_perm,
4505                                   apriv->proc_entry);
4506         if (!entry)
4507                 goto fail_ssid;
4508         entry->uid = proc_uid;
4509         entry->gid = proc_gid;
4510         entry->data = dev;
4511         entry->owner = THIS_MODULE;
4512         SETPROC_OPS(entry, proc_SSID_ops);
4513
4514         /* Setup the APList */
4515         entry = create_proc_entry("APList",
4516                                   S_IFREG | proc_perm,
4517                                   apriv->proc_entry);
4518         if (!entry)
4519                 goto fail_aplist;
4520         entry->uid = proc_uid;
4521         entry->gid = proc_gid;
4522         entry->data = dev;
4523         entry->owner = THIS_MODULE;
4524         SETPROC_OPS(entry, proc_APList_ops);
4525
4526         /* Setup the BSSList */
4527         entry = create_proc_entry("BSSList",
4528                                   S_IFREG | proc_perm,
4529                                   apriv->proc_entry);
4530         if (!entry)
4531                 goto fail_bsslist;
4532         entry->uid = proc_uid;
4533         entry->gid = proc_gid;
4534         entry->data = dev;
4535         entry->owner = THIS_MODULE;
4536         SETPROC_OPS(entry, proc_BSSList_ops);
4537
4538         /* Setup the WepKey */
4539         entry = create_proc_entry("WepKey",
4540                                   S_IFREG | proc_perm,
4541                                   apriv->proc_entry);
4542         if (!entry)
4543                 goto fail_wepkey;
4544         entry->uid = proc_uid;
4545         entry->gid = proc_gid;
4546         entry->data = dev;
4547         entry->owner = THIS_MODULE;
4548         SETPROC_OPS(entry, proc_wepkey_ops);
4549
4550         return 0;
4551
4552 fail_wepkey:
4553         remove_proc_entry("BSSList", apriv->proc_entry);
4554 fail_bsslist:
4555         remove_proc_entry("APList", apriv->proc_entry);
4556 fail_aplist:
4557         remove_proc_entry("SSID", apriv->proc_entry);
4558 fail_ssid:
4559         remove_proc_entry("Config", apriv->proc_entry);
4560 fail_config:
4561         remove_proc_entry("Status", apriv->proc_entry);
4562 fail_status:
4563         remove_proc_entry("Stats", apriv->proc_entry);
4564 fail_stats:
4565         remove_proc_entry("StatsDelta", apriv->proc_entry);
4566 fail_stats_delta:
4567         remove_proc_entry(apriv->proc_name, airo_entry);
4568 fail:
4569         return -ENOMEM;
4570 }
4571
4572 static int takedown_proc_entry( struct net_device *dev,
4573                                 struct airo_info *apriv ) {
4574         if ( !apriv->proc_entry->namelen ) return 0;
4575         remove_proc_entry("Stats",apriv->proc_entry);
4576         remove_proc_entry("StatsDelta",apriv->proc_entry);
4577         remove_proc_entry("Status",apriv->proc_entry);
4578         remove_proc_entry("Config",apriv->proc_entry);
4579         remove_proc_entry("SSID",apriv->proc_entry);
4580         remove_proc_entry("APList",apriv->proc_entry);
4581         remove_proc_entry("BSSList",apriv->proc_entry);
4582         remove_proc_entry("WepKey",apriv->proc_entry);
4583         remove_proc_entry(apriv->proc_name,airo_entry);
4584         return 0;
4585 }
4586
4587 /*
4588  *  What we want from the proc_fs is to be able to efficiently read
4589  *  and write the configuration.  To do this, we want to read the
4590  *  configuration when the file is opened and write it when the file is
4591  *  closed.  So basically we allocate a read buffer at open and fill it
4592  *  with data, and allocate a write buffer and read it at close.
4593  */
4594
4595 /*
4596  *  The read routine is generic, it relies on the preallocated rbuffer
4597  *  to supply the data.
4598  */
4599 static ssize_t proc_read( struct file *file,
4600                           char __user *buffer,
4601                           size_t len,
4602                           loff_t *offset )
4603 {
4604         loff_t pos = *offset;
4605         struct proc_data *priv = (struct proc_data*)file->private_data;
4606
4607         if (!priv->rbuffer)
4608                 return -EINVAL;
4609
4610         if (pos < 0)
4611                 return -EINVAL;
4612         if (pos >= priv->readlen)
4613                 return 0;
4614         if (len > priv->readlen - pos)
4615                 len = priv->readlen - pos;
4616         if (copy_to_user(buffer, priv->rbuffer + pos, len))
4617                 return -EFAULT;
4618         *offset = pos + len;
4619         return len;
4620 }
4621
4622 /*
4623  *  The write routine is generic, it fills in a preallocated rbuffer
4624  *  to supply the data.
4625  */
4626 static ssize_t proc_write( struct file *file,
4627                            const char __user *buffer,
4628                            size_t len,
4629                            loff_t *offset )
4630 {
4631         loff_t pos = *offset;
4632         struct proc_data *priv = (struct proc_data*)file->private_data;
4633
4634         if (!priv->wbuffer)
4635                 return -EINVAL;
4636
4637         if (pos < 0)
4638                 return -EINVAL;
4639         if (pos >= priv->maxwritelen)
4640                 return 0;
4641         if (len > priv->maxwritelen - pos)
4642                 len = priv->maxwritelen - pos;
4643         if (copy_from_user(priv->wbuffer + pos, buffer, len))
4644                 return -EFAULT;
4645         if ( pos + len > priv->writelen )
4646                 priv->writelen = len + file->f_pos;
4647         *offset = pos + len;
4648         return len;
4649 }
4650
4651 static int proc_status_open(struct inode *inode, struct file *file)
4652 {
4653         struct proc_data *data;
4654         struct proc_dir_entry *dp = PDE(inode);
4655         struct net_device *dev = dp->data;
4656         struct airo_info *apriv = dev->priv;
4657         CapabilityRid cap_rid;
4658         StatusRid status_rid;
4659         u16 mode;
4660         int i;
4661
4662         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4663                 return -ENOMEM;
4664         data = (struct proc_data *)file->private_data;
4665         if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4666                 kfree (file->private_data);
4667                 return -ENOMEM;
4668         }
4669
4670         readStatusRid(apriv, &status_rid, 1);
4671         readCapabilityRid(apriv, &cap_rid, 1);
4672
4673         mode = le16_to_cpu(status_rid.mode);
4674
4675         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4676                     mode & 1 ? "CFG ": "",
4677                     mode & 2 ? "ACT ": "",
4678                     mode & 0x10 ? "SYN ": "",
4679                     mode & 0x20 ? "LNK ": "",
4680                     mode & 0x40 ? "LEAP ": "",
4681                     mode & 0x80 ? "PRIV ": "",
4682                     mode & 0x100 ? "KEY ": "",
4683                     mode & 0x200 ? "WEP ": "",
4684                     mode & 0x8000 ? "ERR ": "");
4685         sprintf( data->rbuffer+i, "Mode: %x\n"
4686                  "Signal Strength: %d\n"
4687                  "Signal Quality: %d\n"
4688                  "SSID: %-.*s\n"
4689                  "AP: %-.16s\n"
4690                  "Freq: %d\n"
4691                  "BitRate: %dmbs\n"
4692                  "Driver Version: %s\n"
4693                  "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4694                  "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4695                  "Software Version: %x\nSoftware Subversion: %x\n"
4696                  "Boot block version: %x\n",
4697                  le16_to_cpu(status_rid.mode),
4698                  le16_to_cpu(status_rid.normalizedSignalStrength),
4699                  le16_to_cpu(status_rid.signalQuality),
4700                  le16_to_cpu(status_rid.SSIDlen),
4701                  status_rid.SSID,
4702                  status_rid.apName,
4703                  le16_to_cpu(status_rid.channel),
4704                  le16_to_cpu(status_rid.currentXmitRate) / 2,
4705                  version,
4706                  cap_rid.prodName,
4707                  cap_rid.manName,
4708                  cap_rid.prodVer,
4709                  le16_to_cpu(cap_rid.radioType),
4710                  le16_to_cpu(cap_rid.country),
4711                  le16_to_cpu(cap_rid.hardVer),
4712                  le16_to_cpu(cap_rid.softVer),
4713                  le16_to_cpu(cap_rid.softSubVer),
4714                  le16_to_cpu(cap_rid.bootBlockVer));
4715         data->readlen = strlen( data->rbuffer );
4716         return 0;
4717 }
4718
4719 static int proc_stats_rid_open(struct inode*, struct file*, u16);
4720 static int proc_statsdelta_open( struct inode *inode,
4721                                  struct file *file ) {
4722         if (file->f_mode&FMODE_WRITE) {
4723                 return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4724         }
4725         return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4726 }
4727
4728 static int proc_stats_open( struct inode *inode, struct file *file ) {
4729         return proc_stats_rid_open(inode, file, RID_STATS);
4730 }
4731
4732 static int proc_stats_rid_open( struct inode *inode,
4733                                 struct file *file,
4734                                 u16 rid )
4735 {
4736         struct proc_data *data;
4737         struct proc_dir_entry *dp = PDE(inode);
4738         struct net_device *dev = dp->data;
4739         struct airo_info *apriv = dev->priv;
4740         StatsRid stats;
4741         int i, j;
4742         __le32 *vals = stats.vals;
4743         int len = le16_to_cpu(stats.len);
4744
4745         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4746                 return -ENOMEM;
4747         data = (struct proc_data *)file->private_data;
4748         if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4749                 kfree (file->private_data);
4750                 return -ENOMEM;
4751         }
4752
4753         readStatsRid(apriv, &stats, rid, 1);
4754
4755         j = 0;
4756         for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4757                 if (!statsLabels[i]) continue;
4758                 if (j+strlen(statsLabels[i])+16>4096) {
4759                         airo_print_warn(apriv->dev->name,
4760                                "Potentially disasterous buffer overflow averted!");
4761                         break;
4762                 }
4763                 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4764                                 le32_to_cpu(vals[i]));
4765         }
4766         if (i*4 >= len) {
4767                 airo_print_warn(apriv->dev->name, "Got a short rid");
4768         }
4769         data->readlen = j;
4770         return 0;
4771 }
4772
4773 static int get_dec_u16( char *buffer, int *start, int limit ) {
4774         u16 value;
4775         int valid = 0;
4776         for( value = 0; buffer[*start] >= '0' &&
4777                      buffer[*start] <= '9' &&
4778                      *start < limit; (*start)++ ) {
4779                 valid = 1;
4780                 value *= 10;
4781                 value += buffer[*start] - '0';
4782         }
4783         if ( !valid ) return -1;
4784         return value;
4785 }
4786
4787 static int airo_config_commit(struct net_device *dev,
4788                               struct iw_request_info *info, void *zwrq,
4789                               char *extra);
4790
4791 static void proc_config_on_close( struct inode *inode, struct file *file ) {
4792         struct proc_data *data = file->private_data;
4793         struct proc_dir_entry *dp = PDE(inode);
4794         struct net_device *dev = dp->data;
4795         struct airo_info *ai = dev->priv;
4796         char *line;
4797
4798         if ( !data->writelen ) return;
4799
4800         readConfigRid(ai, 1);
4801         set_bit (FLAG_COMMIT, &ai->flags);
4802
4803         line = data->wbuffer;
4804         while( line[0] ) {
4805 /*** Mode processing */
4806                 if ( !strncmp( line, "Mode: ", 6 ) ) {
4807                         line += 6;
4808                         if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
4809                                         set_bit (FLAG_RESET, &ai->flags);
4810                         ai->config.rmode &= 0xfe00;
4811                         clear_bit (FLAG_802_11, &ai->flags);
4812                         ai->config.opmode &= 0xFF00;
4813                         ai->config.scanMode = SCANMODE_ACTIVE;
4814                         if ( line[0] == 'a' ) {
4815                                 ai->config.opmode |= 0;
4816                         } else {
4817                                 ai->config.opmode |= 1;
4818                                 if ( line[0] == 'r' ) {
4819                                         ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4820                                         ai->config.scanMode = SCANMODE_PASSIVE;
4821                                         set_bit (FLAG_802_11, &ai->flags);
4822                                 } else if ( line[0] == 'y' ) {
4823                                         ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4824                                         ai->config.scanMode = SCANMODE_PASSIVE;
4825                                         set_bit (FLAG_802_11, &ai->flags);
4826                                 } else if ( line[0] == 'l' )
4827                                         ai->config.rmode |= RXMODE_LANMON;
4828                         }
4829                         set_bit (FLAG_COMMIT, &ai->flags);
4830                 }
4831
4832 /*** Radio status */
4833                 else if (!strncmp(line,"Radio: ", 7)) {
4834                         line += 7;
4835                         if (!strncmp(line,"off",3)) {
4836                                 set_bit (FLAG_RADIO_OFF, &ai->flags);
4837                         } else {
4838                                 clear_bit (FLAG_RADIO_OFF, &ai->flags);
4839                         }
4840                 }
4841 /*** NodeName processing */
4842                 else if ( !strncmp( line, "NodeName: ", 10 ) ) {
4843                         int j;
4844
4845                         line += 10;
4846                         memset( ai->config.nodeName, 0, 16 );
4847 /* Do the name, assume a space between the mode and node name */
4848                         for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
4849                                 ai->config.nodeName[j] = line[j];
4850                         }
4851                         set_bit (FLAG_COMMIT, &ai->flags);
4852                 }
4853
4854 /*** PowerMode processing */
4855                 else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
4856                         line += 11;
4857                         if ( !strncmp( line, "PSPCAM", 6 ) ) {
4858                                 ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4859                                 set_bit (FLAG_COMMIT, &ai->flags);
4860                         } else if ( !strncmp( line, "PSP", 3 ) ) {
4861                                 ai->config.powerSaveMode = POWERSAVE_PSP;
4862                                 set_bit (FLAG_COMMIT, &ai->flags);
4863                         } else {
4864                                 ai->config.powerSaveMode = POWERSAVE_CAM;
4865                                 set_bit (FLAG_COMMIT, &ai->flags);
4866                         }
4867                 } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
4868                         int v, i = 0, k = 0; /* i is index into line,
4869                                                 k is index to rates */
4870
4871                         line += 11;
4872                         while((v = get_dec_u16(line, &i, 3))!=-1) {
4873                                 ai->config.rates[k++] = (u8)v;
4874                                 line += i + 1;
4875                                 i = 0;
4876                         }
4877                         set_bit (FLAG_COMMIT, &ai->flags);
4878                 } else if ( !strncmp( line, "Channel: ", 9 ) ) {
4879                         int v, i = 0;
4880                         line += 9;
4881                         v = get_dec_u16(line, &i, i+3);
4882                         if ( v != -1 ) {
4883                                 ai->config.channelSet = (u16)v;
4884                                 set_bit (FLAG_COMMIT, &ai->flags);
4885                         }
4886                 } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
4887                         int v, i = 0;
4888                         line += 11;
4889                         v = get_dec_u16(line, &i, i+3);
4890                         if ( v != -1 ) {
4891                                 ai->config.txPower = (u16)v;
4892                                 set_bit (FLAG_COMMIT, &ai->flags);
4893                         }
4894                 } else if ( !strncmp( line, "WEP: ", 5 ) ) {
4895                         line += 5;
4896                         switch( line[0] ) {
4897                         case 's':
4898                                 ai->config.authType = (u16)AUTH_SHAREDKEY;
4899                                 break;
4900                         case 'e':
4901                                 ai->config.authType = (u16)AUTH_ENCRYPT;
4902                                 break;
4903                         default:
4904                                 ai->config.authType = (u16)AUTH_OPEN;
4905                                 break;
4906                         }
4907                         set_bit (FLAG_COMMIT, &ai->flags);
4908                 } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
4909                         int v, i = 0;
4910
4911                         line += 16;
4912                         v = get_dec_u16(line, &i, 3);
4913                         v = (v<0) ? 0 : ((v>255) ? 255 : v);
4914                         ai->config.longRetryLimit = (u16)v;
4915                         set_bit (FLAG_COMMIT, &ai->flags);
4916                 } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
4917                         int v, i = 0;
4918
4919                         line += 17;
4920                         v = get_dec_u16(line, &i, 3);
4921                         v = (v<0) ? 0 : ((v>255) ? 255 : v);
4922                         ai->config.shortRetryLimit = (u16)v;
4923                         set_bit (FLAG_COMMIT, &ai->flags);
4924                 } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
4925                         int v, i = 0;
4926
4927                         line += 14;
4928                         v = get_dec_u16(line, &i, 4);
4929                         v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4930                         ai->config.rtsThres = (u16)v;
4931                         set_bit (FLAG_COMMIT, &ai->flags);
4932                 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
4933                         int v, i = 0;
4934
4935                         line += 16;
4936                         v = get_dec_u16(line, &i, 5);
4937                         v = (v<0) ? 0 : v;
4938                         ai->config.txLifetime = (u16)v;
4939                         set_bit (FLAG_COMMIT, &ai->flags);
4940                 } else if ( !strncmp( line, "RXMSDULifetime: ", 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.rxLifetime = (u16)v;
4947                         set_bit (FLAG_COMMIT, &ai->flags);
4948                 } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4949                         ai->config.txDiversity =
4950                                 (line[13]=='l') ? 1 :
4951                                 ((line[13]=='r')? 2: 3);
4952                         set_bit (FLAG_COMMIT, &ai->flags);
4953                 } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4954                         ai->config.rxDiversity =
4955                                 (line[13]=='l') ? 1 :
4956                                 ((line[13]=='r')? 2: 3);
4957                         set_bit (FLAG_COMMIT, &ai->flags);
4958                 } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4959                         int v, i = 0;
4960
4961                         line += 15;
4962                         v = get_dec_u16(line, &i, 4);
4963                         v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4964                         v = v & 0xfffe; /* Make sure its even */
4965                         ai->config.fragThresh = (u16)v;
4966                         set_bit (FLAG_COMMIT, &ai->flags);
4967                 } else if (!strncmp(line, "Modulation: ", 12)) {
4968                         line += 12;
4969                         switch(*line) {
4970                         case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4971                         case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4972                         case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4973                         default: airo_print_warn(ai->dev->name, "Unknown modulation");
4974                         }
4975                 } else if (!strncmp(line, "Preamble: ", 10)) {
4976                         line += 10;
4977                         switch(*line) {
4978                         case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4979                         case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4980                         case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4981                         default: airo_print_warn(ai->dev->name, "Unknown preamble");
4982                         }
4983                 } else {
4984                         airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
4985                 }
4986                 while( line[0] && line[0] != '\n' ) line++;
4987                 if ( line[0] ) line++;
4988         }
4989         airo_config_commit(dev, NULL, NULL, NULL);
4990 }
4991
4992 static char *get_rmode(u16 mode) {
4993         switch(mode&0xff) {
4994         case RXMODE_RFMON:  return "rfmon";
4995         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
4996         case RXMODE_LANMON:  return "lanmon";
4997         }
4998         return "ESS";
4999 }
5000
5001 static int proc_config_open( struct inode *inode, struct file *file ) {
5002         struct proc_data *data;
5003         struct proc_dir_entry *dp = PDE(inode);
5004         struct net_device *dev = dp->data;
5005         struct airo_info *ai = dev->priv;
5006         int i;
5007
5008         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5009                 return -ENOMEM;
5010         data = (struct proc_data *)file->private_data;
5011         if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
5012                 kfree (file->private_data);
5013                 return -ENOMEM;
5014         }
5015         if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
5016                 kfree (data->rbuffer);
5017                 kfree (file->private_data);
5018                 return -ENOMEM;
5019         }
5020         data->maxwritelen = 2048;
5021         data->on_close = proc_config_on_close;
5022
5023         readConfigRid(ai, 1);
5024
5025         i = sprintf( data->rbuffer,
5026                      "Mode: %s\n"
5027                      "Radio: %s\n"
5028                      "NodeName: %-16s\n"
5029                      "PowerMode: %s\n"
5030                      "DataRates: %d %d %d %d %d %d %d %d\n"
5031                      "Channel: %d\n"
5032                      "XmitPower: %d\n",
5033                      (ai->config.opmode & 0xFF) == 0 ? "adhoc" :
5034                      (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode):
5035                      (ai->config.opmode & 0xFF) == 2 ? "AP" :
5036                      (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error",
5037                      test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
5038                      ai->config.nodeName,
5039                      ai->config.powerSaveMode == 0 ? "CAM" :
5040                      ai->config.powerSaveMode == 1 ? "PSP" :
5041                      ai->config.powerSaveMode == 2 ? "PSPCAM" : "Error",
5042                      (int)ai->config.rates[0],
5043                      (int)ai->config.rates[1],
5044                      (int)ai->config.rates[2],
5045                      (int)ai->config.rates[3],
5046                      (int)ai->config.rates[4],
5047                      (int)ai->config.rates[5],
5048                      (int)ai->config.rates[6],
5049                      (int)ai->config.rates[7],
5050                      (int)ai->config.channelSet,
5051                      (int)ai->config.txPower
5052                 );
5053         sprintf( data->rbuffer + i,
5054                  "LongRetryLimit: %d\n"
5055                  "ShortRetryLimit: %d\n"
5056                  "RTSThreshold: %d\n"
5057                  "TXMSDULifetime: %d\n"
5058                  "RXMSDULifetime: %d\n"
5059                  "TXDiversity: %s\n"
5060                  "RXDiversity: %s\n"
5061                  "FragThreshold: %d\n"
5062                  "WEP: %s\n"
5063                  "Modulation: %s\n"
5064                  "Preamble: %s\n",
5065                  (int)ai->config.longRetryLimit,
5066                  (int)ai->config.shortRetryLimit,
5067                  (int)ai->config.rtsThres,
5068                  (int)ai->config.txLifetime,
5069                  (int)ai->config.rxLifetime,
5070                  ai->config.txDiversity == 1 ? "left" :
5071                  ai->config.txDiversity == 2 ? "right" : "both",
5072                  ai->config.rxDiversity == 1 ? "left" :
5073                  ai->config.rxDiversity == 2 ? "right" : "both",
5074                  (int)ai->config.fragThresh,
5075                  ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
5076                  ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
5077                  ai->config.modulation == 0 ? "default" :
5078                  ai->config.modulation == MOD_CCK ? "cck" :
5079                  ai->config.modulation == MOD_MOK ? "mok" : "error",
5080                  ai->config.preamble == PREAMBLE_AUTO ? "auto" :
5081                  ai->config.preamble == PREAMBLE_LONG ? "long" :
5082                  ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
5083                 );
5084         data->readlen = strlen( data->rbuffer );
5085         return 0;
5086 }
5087
5088 static void proc_SSID_on_close(struct inode *inode, struct file *file)
5089 {
5090         struct proc_data *data = (struct proc_data *)file->private_data;
5091         struct proc_dir_entry *dp = PDE(inode);
5092         struct net_device *dev = dp->data;
5093         struct airo_info *ai = dev->priv;
5094         SsidRid SSID_rid;
5095         int i;
5096         char *p = data->wbuffer;
5097         char *end = p + data->writelen;
5098
5099         if (!data->writelen)
5100                 return;
5101
5102         *end = '\n'; /* sentinel; we have space for it */
5103
5104         memset(&SSID_rid, 0, sizeof(SSID_rid));
5105
5106         for (i = 0; i < 3 && p < end; i++) {
5107                 int j = 0;
5108                 /* copy up to 32 characters from this line */
5109                 while (*p != '\n' && j < 32)
5110                         SSID_rid.ssids[i].ssid[j++] = *p++;
5111                 if (j == 0)
5112                         break;
5113                 SSID_rid.ssids[i].len = cpu_to_le16(j);
5114                 /* skip to the beginning of the next line */
5115                 while (*p++ != '\n')
5116                         ;
5117         }
5118         if (i)
5119                 SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5120         disable_MAC(ai, 1);
5121         writeSsidRid(ai, &SSID_rid, 1);
5122         enable_MAC(ai, 1);
5123 }
5124
5125 static inline u8 hexVal(char c) {
5126         if (c>='0' && c<='9') return c -= '0';
5127         if (c>='a' && c<='f') return c -= 'a'-10;
5128         if (c>='A' && c<='F') return c -= 'A'-10;
5129         return 0;
5130 }
5131
5132 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
5133         struct proc_data *data = (struct proc_data *)file->private_data;
5134         struct proc_dir_entry *dp = PDE(inode);
5135         struct net_device *dev = dp->data;
5136         struct airo_info *ai = dev->priv;
5137         APListRid APList_rid;
5138         int i;
5139
5140         if ( !data->writelen ) return;
5141
5142         memset( &APList_rid, 0, sizeof(APList_rid) );
5143         APList_rid.len = cpu_to_le16(sizeof(APList_rid));
5144
5145         for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
5146                 int j;
5147                 for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
5148                         switch(j%3) {
5149                         case 0:
5150                                 APList_rid.ap[i][j/3]=
5151                                         hexVal(data->wbuffer[j+i*6*3])<<4;
5152                                 break;
5153                         case 1:
5154                                 APList_rid.ap[i][j/3]|=
5155                                         hexVal(data->wbuffer[j+i*6*3]);
5156                                 break;
5157                         }
5158                 }
5159         }
5160         disable_MAC(ai, 1);
5161         writeAPListRid(ai, &APList_rid, 1);
5162         enable_MAC(ai, 1);
5163 }
5164
5165 /* This function wraps PC4500_writerid with a MAC disable */
5166 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5167                         int len, int dummy ) {
5168         int rc;
5169
5170         disable_MAC(ai, 1);
5171         rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5172         enable_MAC(ai, 1);
5173         return rc;
5174 }
5175
5176 /* Returns the length of the key at the index.  If index == 0xffff
5177  * the index of the transmit key is returned.  If the key doesn't exist,
5178  * -1 will be returned.
5179  */
5180 static int get_wep_key(struct airo_info *ai, u16 index) {
5181         WepKeyRid wkr;
5182         int rc;
5183         __le16 lastindex;
5184
5185         rc = readWepKeyRid(ai, &wkr, 1, 1);
5186         if (rc == SUCCESS) do {
5187                 lastindex = wkr.kindex;
5188                 if (wkr.kindex == cpu_to_le16(index)) {
5189                         if (index == 0xffff) {
5190                                 return wkr.mac[0];
5191                         }
5192                         return le16_to_cpu(wkr.klen);
5193                 }
5194                 readWepKeyRid(ai, &wkr, 0, 1);
5195         } while (lastindex != wkr.kindex);
5196         return -1;
5197 }
5198
5199 static int set_wep_key(struct airo_info *ai, u16 index,
5200                        const char *key, u16 keylen, int perm, int lock )
5201 {
5202         static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5203         WepKeyRid wkr;
5204
5205         memset(&wkr, 0, sizeof(wkr));
5206         if (keylen == 0) {
5207 // We are selecting which key to use
5208                 wkr.len = cpu_to_le16(sizeof(wkr));
5209                 wkr.kindex = cpu_to_le16(0xffff);
5210                 wkr.mac[0] = (char)index;
5211                 if (perm) ai->defindex = (char)index;
5212         } else {
5213 // We are actually setting the key
5214                 wkr.len = cpu_to_le16(sizeof(wkr));
5215                 wkr.kindex = cpu_to_le16(index);
5216                 wkr.klen = cpu_to_le16(keylen);
5217                 memcpy( wkr.key, key, keylen );
5218                 memcpy( wkr.mac, macaddr, ETH_ALEN );
5219         }
5220
5221         if (perm) disable_MAC(ai, lock);
5222         writeWepKeyRid(ai, &wkr, perm, lock);
5223         if (perm) enable_MAC(ai, lock);
5224         return 0;
5225 }
5226
5227 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5228         struct proc_data *data;
5229         struct proc_dir_entry *dp = PDE(inode);
5230         struct net_device *dev = dp->data;
5231         struct airo_info *ai = dev->priv;
5232         int i;
5233         char key[16];
5234         u16 index = 0;
5235         int j = 0;
5236
5237         memset(key, 0, sizeof(key));
5238
5239         data = (struct proc_data *)file->private_data;
5240         if ( !data->writelen ) return;
5241
5242         if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5243             (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5244                 index = data->wbuffer[0] - '0';
5245                 if (data->wbuffer[1] == '\n') {
5246                         set_wep_key(ai, index, NULL, 0, 1, 1);
5247                         return;
5248                 }
5249                 j = 2;
5250         } else {
5251                 airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5252                 return;
5253         }
5254
5255         for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
5256                 switch(i%3) {
5257                 case 0:
5258                         key[i/3] = hexVal(data->wbuffer[i+j])<<4;
5259                         break;
5260                 case 1:
5261                         key[i/3] |= hexVal(data->wbuffer[i+j]);
5262                         break;
5263                 }
5264         }
5265         set_wep_key(ai, index, key, i/3, 1, 1);
5266 }
5267
5268 static int proc_wepkey_open( struct inode *inode, struct file *file )
5269 {
5270         struct proc_data *data;
5271         struct proc_dir_entry *dp = PDE(inode);
5272         struct net_device *dev = dp->data;
5273         struct airo_info *ai = dev->priv;
5274         char *ptr;
5275         WepKeyRid wkr;
5276         __le16 lastindex;
5277         int j=0;
5278         int rc;
5279
5280         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5281                 return -ENOMEM;
5282         memset(&wkr, 0, sizeof(wkr));
5283         data = (struct proc_data *)file->private_data;
5284         if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5285                 kfree (file->private_data);
5286                 return -ENOMEM;
5287         }
5288         data->writelen = 0;
5289         data->maxwritelen = 80;
5290         if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5291                 kfree (data->rbuffer);
5292                 kfree (file->private_data);
5293                 return -ENOMEM;
5294         }
5295         data->on_close = proc_wepkey_on_close;
5296
5297         ptr = data->rbuffer;
5298         strcpy(ptr, "No wep keys\n");
5299         rc = readWepKeyRid(ai, &wkr, 1, 1);
5300         if (rc == SUCCESS) do {
5301                 lastindex = wkr.kindex;
5302                 if (wkr.kindex == cpu_to_le16(0xffff)) {
5303                         j += sprintf(ptr+j, "Tx key = %d\n",
5304                                      (int)wkr.mac[0]);
5305                 } else {
5306                         j += sprintf(ptr+j, "Key %d set with length = %d\n",
5307                                      le16_to_cpu(wkr.kindex),
5308                                      le16_to_cpu(wkr.klen));
5309                 }
5310                 readWepKeyRid(ai, &wkr, 0, 1);
5311         } while((lastindex != wkr.kindex) && (j < 180-30));
5312
5313         data->readlen = strlen( data->rbuffer );
5314         return 0;
5315 }
5316
5317 static int proc_SSID_open(struct inode *inode, struct file *file)
5318 {
5319         struct proc_data *data;
5320         struct proc_dir_entry *dp = PDE(inode);
5321         struct net_device *dev = dp->data;
5322         struct airo_info *ai = dev->priv;
5323         int i;
5324         char *ptr;
5325         SsidRid SSID_rid;
5326
5327         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5328                 return -ENOMEM;
5329         data = (struct proc_data *)file->private_data;
5330         if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5331                 kfree (file->private_data);
5332                 return -ENOMEM;
5333         }
5334         data->writelen = 0;
5335         data->maxwritelen = 33*3;
5336         /* allocate maxwritelen + 1; we'll want a sentinel */
5337         if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5338                 kfree (data->rbuffer);
5339                 kfree (file->private_data);
5340                 return -ENOMEM;
5341         }
5342         data->on_close = proc_SSID_on_close;
5343
5344         readSsidRid(ai, &SSID_rid);
5345         ptr = data->rbuffer;
5346         for (i = 0; i < 3; i++) {
5347                 int j;
5348                 size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5349                 if (!len)
5350                         break;
5351                 if (len > 32)
5352                         len = 32;
5353                 for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5354                         *ptr++ = SSID_rid.ssids[i].ssid[j];
5355                 *ptr++ = '\n';
5356         }
5357         *ptr = '\0';
5358         data->readlen = strlen( data->rbuffer );
5359         return 0;
5360 }
5361
5362 static int proc_APList_open( struct inode *inode, struct file *file ) {
5363         struct proc_data *data;
5364         struct proc_dir_entry *dp = PDE(inode);
5365         struct net_device *dev = dp->data;
5366         struct airo_info *ai = dev->priv;
5367         int i;
5368         char *ptr;
5369         APListRid APList_rid;
5370         DECLARE_MAC_BUF(mac);
5371
5372         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5373                 return -ENOMEM;
5374         data = (struct proc_data *)file->private_data;
5375         if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5376                 kfree (file->private_data);
5377                 return -ENOMEM;
5378         }
5379         data->writelen = 0;
5380         data->maxwritelen = 4*6*3;
5381         if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5382                 kfree (data->rbuffer);
5383                 kfree (file->private_data);
5384                 return -ENOMEM;
5385         }
5386         data->on_close = proc_APList_on_close;
5387
5388         readAPListRid(ai, &APList_rid);
5389         ptr = data->rbuffer;
5390         for( i = 0; i < 4; i++ ) {
5391 // We end when we find a zero MAC
5392                 if ( !*(int*)APList_rid.ap[i] &&
5393                      !*(int*)&APList_rid.ap[i][2]) break;
5394                 ptr += sprintf(ptr, "%s\n",
5395                                print_mac(mac, APList_rid.ap[i]));
5396         }
5397         if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5398
5399         *ptr = '\0';
5400         data->readlen = strlen( data->rbuffer );
5401         return 0;
5402 }
5403
5404 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5405         struct proc_data *data;
5406         struct proc_dir_entry *dp = PDE(inode);
5407         struct net_device *dev = dp->data;
5408         struct airo_info *ai = dev->priv;
5409         char *ptr;
5410         BSSListRid BSSList_rid;
5411         int rc;
5412         /* If doLoseSync is not 1, we won't do a Lose Sync */
5413         int doLoseSync = -1;
5414         DECLARE_MAC_BUF(mac);
5415
5416         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5417                 return -ENOMEM;
5418         data = (struct proc_data *)file->private_data;
5419         if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5420                 kfree (file->private_data);
5421                 return -ENOMEM;
5422         }
5423         data->writelen = 0;
5424         data->maxwritelen = 0;
5425         data->wbuffer = NULL;
5426         data->on_close = NULL;
5427
5428         if (file->f_mode & FMODE_WRITE) {
5429                 if (!(file->f_mode & FMODE_READ)) {
5430                         Cmd cmd;
5431                         Resp rsp;
5432
5433                         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
5434                         memset(&cmd, 0, sizeof(cmd));
5435                         cmd.cmd=CMD_LISTBSS;
5436                         if (down_interruptible(&ai->sem))
5437                                 return -ERESTARTSYS;
5438                         issuecommand(ai, &cmd, &rsp);
5439                         up(&ai->sem);
5440                         data->readlen = 0;
5441                         return 0;
5442                 }
5443                 doLoseSync = 1;
5444         }
5445         ptr = data->rbuffer;
5446         /* There is a race condition here if there are concurrent opens.
5447            Since it is a rare condition, we'll just live with it, otherwise
5448            we have to add a spin lock... */
5449         rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5450         while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
5451                 ptr += sprintf(ptr, "%s %*s rssi = %d",
5452                                print_mac(mac, BSSList_rid.bssid),
5453                                 (int)BSSList_rid.ssidLen,
5454                                 BSSList_rid.ssid,
5455                                 le16_to_cpu(BSSList_rid.dBm));
5456                 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5457                                 le16_to_cpu(BSSList_rid.dsChannel),
5458                                 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5459                                 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5460                                 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5461                                 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5462                 rc = readBSSListRid(ai, 0, &BSSList_rid);
5463         }
5464         *ptr = '\0';
5465         data->readlen = strlen( data->rbuffer );
5466         return 0;
5467 }
5468
5469 static int proc_close( struct inode *inode, struct file *file )
5470 {
5471         struct proc_data *data = file->private_data;
5472
5473         if (data->on_close != NULL)
5474                 data->on_close(inode, file);
5475         kfree(data->rbuffer);
5476         kfree(data->wbuffer);
5477         kfree(data);
5478         return 0;
5479 }
5480
5481 /* Since the card doesn't automatically switch to the right WEP mode,
5482    we will make it do it.  If the card isn't associated, every secs we
5483    will switch WEP modes to see if that will help.  If the card is
5484    associated we will check every minute to see if anything has
5485    changed. */
5486 static void timer_func( struct net_device *dev ) {
5487         struct airo_info *apriv = dev->priv;
5488
5489 /* We don't have a link so try changing the authtype */
5490         readConfigRid(apriv, 0);
5491         disable_MAC(apriv, 0);
5492         switch(apriv->config.authType) {
5493                 case AUTH_ENCRYPT:
5494 /* So drop to OPEN */
5495                         apriv->config.authType = AUTH_OPEN;
5496                         break;
5497                 case AUTH_SHAREDKEY:
5498                         if (apriv->keyindex < auto_wep) {
5499                                 set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
5500                                 apriv->config.authType = AUTH_SHAREDKEY;
5501                                 apriv->keyindex++;
5502                         } else {
5503                                 /* Drop to ENCRYPT */
5504                                 apriv->keyindex = 0;
5505                                 set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
5506                                 apriv->config.authType = AUTH_ENCRYPT;
5507                         }
5508                         break;
5509                 default:  /* We'll escalate to SHAREDKEY */
5510                         apriv->config.authType = AUTH_SHAREDKEY;
5511         }
5512         set_bit (FLAG_COMMIT, &apriv->flags);
5513         writeConfigRid(apriv, 0);
5514         enable_MAC(apriv, 0);
5515         up(&apriv->sem);
5516
5517 /* Schedule check to see if the change worked */
5518         clear_bit(JOB_AUTOWEP, &apriv->jobs);
5519         apriv->expires = RUN_AT(HZ*3);
5520 }
5521
5522 #ifdef CONFIG_PCI
5523 static int __devinit airo_pci_probe(struct pci_dev *pdev,
5524                                     const struct pci_device_id *pent)
5525 {
5526         struct net_device *dev;
5527
5528         if (pci_enable_device(pdev))
5529                 return -ENODEV;
5530         pci_set_master(pdev);
5531
5532         if (pdev->device == 0x5000 || pdev->device == 0xa504)
5533                         dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5534         else
5535                         dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5536         if (!dev) {
5537                 pci_disable_device(pdev);
5538                 return -ENODEV;
5539         }
5540
5541         pci_set_drvdata(pdev, dev);
5542         return 0;
5543 }
5544
5545 static void __devexit airo_pci_remove(struct pci_dev *pdev)
5546 {
5547         struct net_device *dev = pci_get_drvdata(pdev);
5548
5549         airo_print_info(dev->name, "Unregistering...");
5550         stop_airo_card(dev, 1);
5551         pci_disable_device(pdev);
5552         pci_set_drvdata(pdev, NULL);
5553 }
5554
5555 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
5556 {
5557         struct net_device *dev = pci_get_drvdata(pdev);
5558         struct airo_info *ai = dev->priv;
5559         Cmd cmd;
5560         Resp rsp;
5561
5562         if ((ai->APList == NULL) &&
5563                 (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
5564                 return -ENOMEM;
5565         if ((ai->SSID == NULL) &&
5566                 (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
5567                 return -ENOMEM;
5568         readAPListRid(ai, ai->APList);
5569         readSsidRid(ai, ai->SSID);
5570         memset(&cmd, 0, sizeof(cmd));
5571         /* the lock will be released at the end of the resume callback */
5572         if (down_interruptible(&ai->sem))
5573                 return -EAGAIN;
5574         disable_MAC(ai, 0);
5575         netif_device_detach(dev);
5576         ai->power = state;
5577         cmd.cmd=HOSTSLEEP;
5578         issuecommand(ai, &cmd, &rsp);
5579
5580         pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
5581         pci_save_state(pdev);
5582         return pci_set_power_state(pdev, pci_choose_state(pdev, state));
5583 }
5584
5585 static int airo_pci_resume(struct pci_dev *pdev)
5586 {
5587         struct net_device *dev = pci_get_drvdata(pdev);
5588         struct airo_info *ai = dev->priv;
5589         pci_power_t prev_state = pdev->current_state;
5590
5591         pci_set_power_state(pdev, PCI_D0);
5592         pci_restore_state(pdev);
5593         pci_enable_wake(pdev, PCI_D0, 0);
5594
5595         if (prev_state != PCI_D1) {
5596                 reset_card(dev, 0);
5597                 mpi_init_descriptors(ai);
5598                 setup_card(ai, dev->dev_addr, 0);
5599                 clear_bit(FLAG_RADIO_OFF, &ai->flags);
5600                 clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5601         } else {
5602                 OUT4500(ai, EVACK, EV_AWAKEN);
5603                 OUT4500(ai, EVACK, EV_AWAKEN);
5604                 msleep(100);
5605         }
5606
5607         set_bit (FLAG_COMMIT, &ai->flags);
5608         disable_MAC(ai, 0);
5609         msleep(200);
5610         if (ai->SSID) {
5611                 writeSsidRid(ai, ai->SSID, 0);
5612                 kfree(ai->SSID);
5613                 ai->SSID = NULL;
5614         }
5615         if (ai->APList) {
5616                 writeAPListRid(ai, ai->APList, 0);
5617                 kfree(ai->APList);
5618                 ai->APList = NULL;
5619         }
5620         writeConfigRid(ai, 0);
5621         enable_MAC(ai, 0);
5622         ai->power = PMSG_ON;
5623         netif_device_attach(dev);
5624         netif_wake_queue(dev);
5625         enable_interrupts(ai);
5626         up(&ai->sem);
5627         return 0;
5628 }
5629 #endif
5630
5631 static int __init airo_init_module( void )
5632 {
5633         int i;
5634 #if 0
5635         int have_isa_dev = 0;
5636 #endif
5637
5638         airo_entry = create_proc_entry("aironet",
5639                                        S_IFDIR | airo_perm,
5640                                        proc_root_driver);
5641
5642         if (airo_entry) {
5643                 airo_entry->uid = proc_uid;
5644                 airo_entry->gid = proc_gid;
5645         }
5646
5647         for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
5648                 airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5649                         "io=0x%x", irq[i], io[i] );
5650                 if (init_airo_card( irq[i], io[i], 0, NULL ))
5651 #if 0
5652                         have_isa_dev = 1;
5653 #else
5654                         /* do nothing */ ;
5655 #endif
5656         }
5657
5658 #ifdef CONFIG_PCI
5659         airo_print_info("", "Probing for PCI adapters");
5660         i = pci_register_driver(&airo_driver);
5661         airo_print_info("", "Finished probing for PCI adapters");
5662
5663         if (i) {
5664                 remove_proc_entry("aironet", proc_root_driver);
5665                 return i;
5666         }
5667 #endif
5668
5669         /* Always exit with success, as we are a library module
5670          * as well as a driver module
5671          */
5672         return 0;
5673 }
5674
5675 static void __exit airo_cleanup_module( void )
5676 {
5677         struct airo_info *ai;
5678         while(!list_empty(&airo_devices)) {
5679                 ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5680                 airo_print_info(ai->dev->name, "Unregistering...");
5681                 stop_airo_card(ai->dev, 1);
5682         }
5683 #ifdef CONFIG_PCI
5684         pci_unregister_driver(&airo_driver);
5685 #endif
5686         remove_proc_entry("aironet", proc_root_driver);
5687 }
5688
5689 /*
5690  * Initial Wireless Extension code for Aironet driver by :
5691  *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5692  * Conversion to new driver API by :
5693  *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5694  * Javier also did a good amount of work here, adding some new extensions
5695  * and fixing my code. Let's just say that without him this code just
5696  * would not work at all... - Jean II
5697  */
5698
5699 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5700 {
5701         if( !rssi_rid )
5702                 return 0;
5703
5704         return (0x100 - rssi_rid[rssi].rssidBm);
5705 }
5706
5707 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5708 {
5709         int i;
5710
5711         if( !rssi_rid )
5712                 return 0;
5713
5714         for( i = 0; i < 256; i++ )
5715                 if (rssi_rid[i].rssidBm == dbm)
5716                         return rssi_rid[i].rssipct;
5717
5718         return 0;
5719 }
5720
5721
5722 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5723 {
5724         int quality = 0;
5725         u16 sq;
5726
5727         if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5728                 return 0;
5729
5730         if (!(cap_rid->hardCap & cpu_to_le16(8)))
5731                 return 0;
5732
5733         sq = le16_to_cpu(status_rid->signalQuality);
5734         if (memcmp(cap_rid->prodName, "350", 3))
5735                 if (sq > 0x20)
5736                         quality = 0;
5737                 else
5738                         quality = 0x20 - sq;
5739         else
5740                 if (sq > 0xb0)
5741                         quality = 0;
5742                 else if (sq < 0x10)
5743                         quality = 0xa0;
5744                 else
5745                         quality = 0xb0 - sq;
5746         return quality;
5747 }
5748
5749 #define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5750 #define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
5751
5752 /*------------------------------------------------------------------*/
5753 /*
5754  * Wireless Handler : get protocol name
5755  */
5756 static int airo_get_name(struct net_device *dev,
5757                          struct iw_request_info *info,
5758                          char *cwrq,
5759                          char *extra)
5760 {
5761         strcpy(cwrq, "IEEE 802.11-DS");
5762         return 0;
5763 }
5764
5765 /*------------------------------------------------------------------*/
5766 /*
5767  * Wireless Handler : set frequency
5768  */
5769 static int airo_set_freq(struct net_device *dev,
5770                          struct iw_request_info *info,
5771                          struct iw_freq *fwrq,
5772                          char *extra)
5773 {
5774         struct airo_info *local = dev->priv;
5775         int rc = -EINPROGRESS;          /* Call commit handler */
5776
5777         /* If setting by frequency, convert to a channel */
5778         if((fwrq->e == 1) &&
5779            (fwrq->m >= (int) 2.412e8) &&
5780            (fwrq->m <= (int) 2.487e8)) {
5781                 int f = fwrq->m / 100000;
5782                 int c = 0;
5783                 while((c < 14) && (f != frequency_list[c]))
5784                         c++;
5785                 /* Hack to fall through... */
5786                 fwrq->e = 0;
5787                 fwrq->m = c + 1;
5788         }
5789         /* Setting by channel number */
5790         if((fwrq->m > 1000) || (fwrq->e > 0))
5791                 rc = -EOPNOTSUPP;
5792         else {
5793                 int channel = fwrq->m;
5794                 /* We should do a better check than that,
5795                  * based on the card capability !!! */
5796                 if((channel < 1) || (channel > 14)) {
5797                         airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5798                                 fwrq->m);
5799                         rc = -EINVAL;
5800                 } else {
5801                         readConfigRid(local, 1);
5802                         /* Yes ! We can set it !!! */
5803                         local->config.channelSet = (u16) channel;
5804                         set_bit (FLAG_COMMIT, &local->flags);
5805                 }
5806         }
5807         return rc;
5808 }
5809
5810 /*------------------------------------------------------------------*/
5811 /*
5812  * Wireless Handler : get frequency
5813  */
5814 static int airo_get_freq(struct net_device *dev,
5815                          struct iw_request_info *info,
5816                          struct iw_freq *fwrq,
5817                          char *extra)
5818 {
5819         struct airo_info *local = dev->priv;
5820         StatusRid status_rid;           /* Card status info */
5821         int ch;
5822
5823         readConfigRid(local, 1);
5824         if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
5825                 status_rid.channel = cpu_to_le16(local->config.channelSet);
5826         else
5827                 readStatusRid(local, &status_rid, 1);
5828
5829         ch = le16_to_cpu(status_rid.channel);
5830         if((ch > 0) && (ch < 15)) {
5831                 fwrq->m = frequency_list[ch - 1] * 100000;
5832                 fwrq->e = 1;
5833         } else {
5834                 fwrq->m = ch;
5835                 fwrq->e = 0;
5836         }
5837
5838         return 0;
5839 }
5840
5841 /*------------------------------------------------------------------*/
5842 /*
5843  * Wireless Handler : set ESSID
5844  */
5845 static int airo_set_essid(struct net_device *dev,
5846                           struct iw_request_info *info,
5847                           struct iw_point *dwrq,
5848                           char *extra)
5849 {
5850         struct airo_info *local = dev->priv;
5851         SsidRid SSID_rid;               /* SSIDs */
5852
5853         /* Reload the list of current SSID */
5854         readSsidRid(local, &SSID_rid);
5855
5856         /* Check if we asked for `any' */
5857         if(dwrq->flags == 0) {
5858                 /* Just send an empty SSID list */
5859                 memset(&SSID_rid, 0, sizeof(SSID_rid));
5860         } else {
5861                 int     index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5862
5863                 /* Check the size of the string */
5864                 if(dwrq->length > IW_ESSID_MAX_SIZE) {
5865                         return -E2BIG ;
5866                 }
5867                 /* Check if index is valid */
5868                 if((index < 0) || (index >= 4)) {
5869                         return -EINVAL;
5870                 }
5871
5872                 /* Set the SSID */
5873                 memset(SSID_rid.ssids[index].ssid, 0,
5874                        sizeof(SSID_rid.ssids[index].ssid));
5875                 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5876                 SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5877         }
5878         SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5879         /* Write it to the card */
5880         disable_MAC(local, 1);
5881         writeSsidRid(local, &SSID_rid, 1);
5882         enable_MAC(local, 1);
5883
5884         return 0;
5885 }
5886
5887 /*------------------------------------------------------------------*/
5888 /*
5889  * Wireless Handler : get ESSID
5890  */
5891 static int airo_get_essid(struct net_device *dev,
5892                           struct iw_request_info *info,
5893                           struct iw_point *dwrq,
5894                           char *extra)
5895 {
5896         struct airo_info *local = dev->priv;
5897         StatusRid status_rid;           /* Card status info */
5898
5899         readStatusRid(local, &status_rid, 1);
5900
5901         /* Note : if dwrq->flags != 0, we should
5902          * get the relevant SSID from the SSID list... */
5903
5904         /* Get the current SSID */
5905         memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5906         /* If none, we may want to get the one that was set */
5907
5908         /* Push it out ! */
5909         dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5910         dwrq->flags = 1; /* active */
5911
5912         return 0;
5913 }
5914
5915 /*------------------------------------------------------------------*/
5916 /*
5917  * Wireless Handler : set AP address
5918  */
5919 static int airo_set_wap(struct net_device *dev,
5920                         struct iw_request_info *info,
5921                         struct sockaddr *awrq,
5922                         char *extra)
5923 {
5924         struct airo_info *local = dev->priv;
5925         Cmd cmd;
5926         Resp rsp;
5927         APListRid APList_rid;
5928         static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
5929         static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
5930
5931         if (awrq->sa_family != ARPHRD_ETHER)
5932                 return -EINVAL;
5933         else if (!memcmp(any, awrq->sa_data, ETH_ALEN) ||
5934                  !memcmp(off, awrq->sa_data, ETH_ALEN)) {
5935                 memset(&cmd, 0, sizeof(cmd));
5936                 cmd.cmd=CMD_LOSE_SYNC;
5937                 if (down_interruptible(&local->sem))
5938                         return -ERESTARTSYS;
5939                 issuecommand(local, &cmd, &rsp);
5940                 up(&local->sem);
5941         } else {
5942                 memset(&APList_rid, 0, sizeof(APList_rid));
5943                 APList_rid.len = cpu_to_le16(sizeof(APList_rid));
5944                 memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
5945                 disable_MAC(local, 1);
5946                 writeAPListRid(local, &APList_rid, 1);
5947                 enable_MAC(local, 1);
5948         }
5949         return 0;
5950 }
5951
5952 /*------------------------------------------------------------------*/