]> err.no Git - linux-2.6/blob - drivers/net/wireless/airo.c
airo: sanitize handling of StatusRid
[linux-2.6] / drivers / net / wireless / airo.c
1 /*======================================================================
2
3     Aironet driver for 4500 and 4800 series cards
4
5     This code is released under both the GPL version 2 and BSD licenses.
6     Either license may be used.  The respective licenses are found at
7     the end of this file.
8
9     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10     including portions of which come from the Aironet PC4500
11     Developer's Reference Manual and used with permission.  Copyright
12     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
13     code in the Developer's manual was granted for this driver by
14     Aironet.  Major code contributions were received from Javier Achirica
15     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
16     Code was also integrated from the Cisco Aironet driver for Linux.
17     Support for MPI350 cards was added by Fabrice Bellet
18     <fabrice@bellet.info>.
19
20 ======================================================================*/
21
22 #include <linux/err.h>
23 #include <linux/init.h>
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/proc_fs.h>
28
29 #include <linux/sched.h>
30 #include <linux/ptrace.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/timer.h>
34 #include <linux/interrupt.h>
35 #include <linux/in.h>
36 #include <linux/bitops.h>
37 #include <linux/scatterlist.h>
38 #include <linux/crypto.h>
39 #include <asm/io.h>
40 #include <asm/system.h>
41 #include <asm/unaligned.h>
42
43 #include <linux/netdevice.h>
44 #include <linux/etherdevice.h>
45 #include <linux/skbuff.h>
46 #include <linux/if_arp.h>
47 #include <linux/ioport.h>
48 #include <linux/pci.h>
49 #include <asm/uaccess.h>
50 #include <net/ieee80211.h>
51 #include <linux/kthread.h>
52 #include <linux/freezer.h>
53
54 #include "airo.h"
55
56 #define DRV_NAME "airo"
57
58 #ifdef CONFIG_PCI
59 static struct pci_device_id card_ids[] = {
60         { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
61         { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
62         { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
63         { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
64         { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
65         { 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
66         { 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
67         { 0, }
68 };
69 MODULE_DEVICE_TABLE(pci, card_ids);
70
71 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
72 static void airo_pci_remove(struct pci_dev *);
73 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
74 static int airo_pci_resume(struct pci_dev *pdev);
75
76 static struct pci_driver airo_driver = {
77         .name     = DRV_NAME,
78         .id_table = card_ids,
79         .probe    = airo_pci_probe,
80         .remove   = __devexit_p(airo_pci_remove),
81         .suspend  = airo_pci_suspend,
82         .resume   = airo_pci_resume,
83 };
84 #endif /* CONFIG_PCI */
85
86 /* Include Wireless Extension definition and check version - Jean II */
87 #include <linux/wireless.h>
88 #define WIRELESS_SPY            // enable iwspy support
89 #include <net/iw_handler.h>     // New driver API
90
91 #define CISCO_EXT               // enable Cisco extensions
92 #ifdef CISCO_EXT
93 #include <linux/delay.h>
94 #endif
95
96 /* Hack to do some power saving */
97 #define POWER_ON_DOWN
98
99 /* As you can see this list is HUGH!
100    I really don't know what a lot of these counts are about, but they
101    are all here for completeness.  If the IGNLABEL macro is put in
102    infront of the label, that statistic will not be included in the list
103    of statistics in the /proc filesystem */
104
105 #define IGNLABEL(comment) NULL
106 static char *statsLabels[] = {
107         "RxOverrun",
108         IGNLABEL("RxPlcpCrcErr"),
109         IGNLABEL("RxPlcpFormatErr"),
110         IGNLABEL("RxPlcpLengthErr"),
111         "RxMacCrcErr",
112         "RxMacCrcOk",
113         "RxWepErr",
114         "RxWepOk",
115         "RetryLong",
116         "RetryShort",
117         "MaxRetries",
118         "NoAck",
119         "NoCts",
120         "RxAck",
121         "RxCts",
122         "TxAck",
123         "TxRts",
124         "TxCts",
125         "TxMc",
126         "TxBc",
127         "TxUcFrags",
128         "TxUcPackets",
129         "TxBeacon",
130         "RxBeacon",
131         "TxSinColl",
132         "TxMulColl",
133         "DefersNo",
134         "DefersProt",
135         "DefersEngy",
136         "DupFram",
137         "RxFragDisc",
138         "TxAged",
139         "RxAged",
140         "LostSync-MaxRetry",
141         "LostSync-MissedBeacons",
142         "LostSync-ArlExceeded",
143         "LostSync-Deauth",
144         "LostSync-Disassoced",
145         "LostSync-TsfTiming",
146         "HostTxMc",
147         "HostTxBc",
148         "HostTxUc",
149         "HostTxFail",
150         "HostRxMc",
151         "HostRxBc",
152         "HostRxUc",
153         "HostRxDiscard",
154         IGNLABEL("HmacTxMc"),
155         IGNLABEL("HmacTxBc"),
156         IGNLABEL("HmacTxUc"),
157         IGNLABEL("HmacTxFail"),
158         IGNLABEL("HmacRxMc"),
159         IGNLABEL("HmacRxBc"),
160         IGNLABEL("HmacRxUc"),
161         IGNLABEL("HmacRxDiscard"),
162         IGNLABEL("HmacRxAccepted"),
163         "SsidMismatch",
164         "ApMismatch",
165         "RatesMismatch",
166         "AuthReject",
167         "AuthTimeout",
168         "AssocReject",
169         "AssocTimeout",
170         IGNLABEL("ReasonOutsideTable"),
171         IGNLABEL("ReasonStatus1"),
172         IGNLABEL("ReasonStatus2"),
173         IGNLABEL("ReasonStatus3"),
174         IGNLABEL("ReasonStatus4"),
175         IGNLABEL("ReasonStatus5"),
176         IGNLABEL("ReasonStatus6"),
177         IGNLABEL("ReasonStatus7"),
178         IGNLABEL("ReasonStatus8"),
179         IGNLABEL("ReasonStatus9"),
180         IGNLABEL("ReasonStatus10"),
181         IGNLABEL("ReasonStatus11"),
182         IGNLABEL("ReasonStatus12"),
183         IGNLABEL("ReasonStatus13"),
184         IGNLABEL("ReasonStatus14"),
185         IGNLABEL("ReasonStatus15"),
186         IGNLABEL("ReasonStatus16"),
187         IGNLABEL("ReasonStatus17"),
188         IGNLABEL("ReasonStatus18"),
189         IGNLABEL("ReasonStatus19"),
190         "RxMan",
191         "TxMan",
192         "RxRefresh",
193         "TxRefresh",
194         "RxPoll",
195         "TxPoll",
196         "HostRetries",
197         "LostSync-HostReq",
198         "HostTxBytes",
199         "HostRxBytes",
200         "ElapsedUsec",
201         "ElapsedSec",
202         "LostSyncBetterAP",
203         "PrivacyMismatch",
204         "Jammed",
205         "DiscRxNotWepped",
206         "PhyEleMismatch",
207         (char*)-1 };
208 #ifndef RUN_AT
209 #define RUN_AT(x) (jiffies+(x))
210 #endif
211
212
213 /* These variables are for insmod, since it seems that the rates
214    can only be set in setup_card.  Rates should be a comma separated
215    (no spaces) list of rates (up to 8). */
216
217 static int rates[8];
218 static int basic_rate;
219 static char *ssids[3];
220
221 static int io[4];
222 static int irq[4];
223
224 static
225 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
226                        0 means no limit.  For old cards this was 4 */
227
228 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
229 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
230                     the bap, needed on some older cards and buses. */
231 static int adhoc;
232
233 static int probe = 1;
234
235 static int proc_uid /* = 0 */;
236
237 static int proc_gid /* = 0 */;
238
239 static int airo_perm = 0555;
240
241 static int proc_perm = 0644;
242
243 MODULE_AUTHOR("Benjamin Reed");
244 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
245 cards.  Direct support for ISA/PCI/MPI cards and support \
246 for PCMCIA when used with airo_cs.");
247 MODULE_LICENSE("Dual BSD/GPL");
248 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
249 module_param_array(io, int, NULL, 0);
250 module_param_array(irq, int, NULL, 0);
251 module_param(basic_rate, int, 0);
252 module_param_array(rates, int, NULL, 0);
253 module_param_array(ssids, charp, NULL, 0);
254 module_param(auto_wep, int, 0);
255 MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
256 the authentication options until an association is made.  The value of \
257 auto_wep is number of the wep keys to check.  A value of 2 will try using \
258 the key at index 0 and index 1.");
259 module_param(aux_bap, int, 0);
260 MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
261 than seems to work better for older cards with some older buses.  Before \
262 switching it checks that the switch is needed.");
263 module_param(maxencrypt, int, 0);
264 MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
265 encryption.  Units are in 512kbs.  Zero (default) means there is no limit. \
266 Older cards used to be limited to 2mbs (4).");
267 module_param(adhoc, int, 0);
268 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
269 module_param(probe, int, 0);
270 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
271
272 module_param(proc_uid, int, 0);
273 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
274 module_param(proc_gid, int, 0);
275 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
276 module_param(airo_perm, int, 0);
277 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
278 module_param(proc_perm, int, 0);
279 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
280
281 /* This is a kind of sloppy hack to get this information to OUT4500 and
282    IN4500.  I would be extremely interested in the situation where this
283    doesn't work though!!! */
284 static int do8bitIO = 0;
285
286 /* Return codes */
287 #define SUCCESS 0
288 #define ERROR -1
289 #define NO_PACKET -2
290
291 /* Commands */
292 #define NOP2            0x0000
293 #define MAC_ENABLE      0x0001
294 #define MAC_DISABLE     0x0002
295 #define CMD_LOSE_SYNC   0x0003 /* Not sure what this does... */
296 #define CMD_SOFTRESET   0x0004
297 #define HOSTSLEEP       0x0005
298 #define CMD_MAGIC_PKT   0x0006
299 #define CMD_SETWAKEMASK 0x0007
300 #define CMD_READCFG     0x0008
301 #define CMD_SETMODE     0x0009
302 #define CMD_ALLOCATETX  0x000a
303 #define CMD_TRANSMIT    0x000b
304 #define CMD_DEALLOCATETX 0x000c
305 #define NOP             0x0010
306 #define CMD_WORKAROUND  0x0011
307 #define CMD_ALLOCATEAUX 0x0020
308 #define CMD_ACCESS      0x0021
309 #define CMD_PCIBAP      0x0022
310 #define CMD_PCIAUX      0x0023
311 #define CMD_ALLOCBUF    0x0028
312 #define CMD_GETTLV      0x0029
313 #define CMD_PUTTLV      0x002a
314 #define CMD_DELTLV      0x002b
315 #define CMD_FINDNEXTTLV 0x002c
316 #define CMD_PSPNODES    0x0030
317 #define CMD_SETCW       0x0031    
318 #define CMD_SETPCF      0x0032    
319 #define CMD_SETPHYREG   0x003e
320 #define CMD_TXTEST      0x003f
321 #define MAC_ENABLETX    0x0101
322 #define CMD_LISTBSS     0x0103
323 #define CMD_SAVECFG     0x0108
324 #define CMD_ENABLEAUX   0x0111
325 #define CMD_WRITERID    0x0121
326 #define CMD_USEPSPNODES 0x0130
327 #define MAC_ENABLERX    0x0201
328
329 /* Command errors */
330 #define ERROR_QUALIF 0x00
331 #define ERROR_ILLCMD 0x01
332 #define ERROR_ILLFMT 0x02
333 #define ERROR_INVFID 0x03
334 #define ERROR_INVRID 0x04
335 #define ERROR_LARGE 0x05
336 #define ERROR_NDISABL 0x06
337 #define ERROR_ALLOCBSY 0x07
338 #define ERROR_NORD 0x0B
339 #define ERROR_NOWR 0x0C
340 #define ERROR_INVFIDTX 0x0D
341 #define ERROR_TESTACT 0x0E
342 #define ERROR_TAGNFND 0x12
343 #define ERROR_DECODE 0x20
344 #define ERROR_DESCUNAV 0x21
345 #define ERROR_BADLEN 0x22
346 #define ERROR_MODE 0x80
347 #define ERROR_HOP 0x81
348 #define ERROR_BINTER 0x82
349 #define ERROR_RXMODE 0x83
350 #define ERROR_MACADDR 0x84
351 #define ERROR_RATES 0x85
352 #define ERROR_ORDER 0x86
353 #define ERROR_SCAN 0x87
354 #define ERROR_AUTH 0x88
355 #define ERROR_PSMODE 0x89
356 #define ERROR_RTYPE 0x8A
357 #define ERROR_DIVER 0x8B
358 #define ERROR_SSID 0x8C
359 #define ERROR_APLIST 0x8D
360 #define ERROR_AUTOWAKE 0x8E
361 #define ERROR_LEAP 0x8F
362
363 /* Registers */
364 #define COMMAND 0x00
365 #define PARAM0 0x02
366 #define PARAM1 0x04
367 #define PARAM2 0x06
368 #define STATUS 0x08
369 #define RESP0 0x0a
370 #define RESP1 0x0c
371 #define RESP2 0x0e
372 #define LINKSTAT 0x10
373 #define SELECT0 0x18
374 #define OFFSET0 0x1c
375 #define RXFID 0x20
376 #define TXALLOCFID 0x22
377 #define TXCOMPLFID 0x24
378 #define DATA0 0x36
379 #define EVSTAT 0x30
380 #define EVINTEN 0x32
381 #define EVACK 0x34
382 #define SWS0 0x28
383 #define SWS1 0x2a
384 #define SWS2 0x2c
385 #define SWS3 0x2e
386 #define AUXPAGE 0x3A
387 #define AUXOFF 0x3C
388 #define AUXDATA 0x3E
389
390 #define FID_TX 1
391 #define FID_RX 2
392 /* Offset into aux memory for descriptors */
393 #define AUX_OFFSET 0x800
394 /* Size of allocated packets */
395 #define PKTSIZE 1840
396 #define RIDSIZE 2048
397 /* Size of the transmit queue */
398 #define MAXTXQ 64
399
400 /* BAP selectors */
401 #define BAP0 0 // Used for receiving packets
402 #define BAP1 2 // Used for xmiting packets and working with RIDS
403
404 /* Flags */
405 #define COMMAND_BUSY 0x8000
406
407 #define BAP_BUSY 0x8000
408 #define BAP_ERR 0x4000
409 #define BAP_DONE 0x2000
410
411 #define PROMISC 0xffff
412 #define NOPROMISC 0x0000
413
414 #define EV_CMD 0x10
415 #define EV_CLEARCOMMANDBUSY 0x4000
416 #define EV_RX 0x01
417 #define EV_TX 0x02
418 #define EV_TXEXC 0x04
419 #define EV_ALLOC 0x08
420 #define EV_LINK 0x80
421 #define EV_AWAKE 0x100
422 #define EV_TXCPY 0x400
423 #define EV_UNKNOWN 0x800
424 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
425 #define EV_AWAKEN 0x2000
426 #define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
427
428 #ifdef CHECK_UNKNOWN_INTS
429 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
430 #else
431 #define IGNORE_INTS (~STATUS_INTS)
432 #endif
433
434 /* RID TYPES */
435 #define RID_RW 0x20
436
437 /* The RIDs */
438 #define RID_CAPABILITIES 0xFF00
439 #define RID_APINFO     0xFF01
440 #define RID_RADIOINFO  0xFF02
441 #define RID_UNKNOWN3   0xFF03
442 #define RID_RSSI       0xFF04
443 #define RID_CONFIG     0xFF10
444 #define RID_SSID       0xFF11
445 #define RID_APLIST     0xFF12
446 #define RID_DRVNAME    0xFF13
447 #define RID_ETHERENCAP 0xFF14
448 #define RID_WEP_TEMP   0xFF15
449 #define RID_WEP_PERM   0xFF16
450 #define RID_MODULATION 0xFF17
451 #define RID_OPTIONS    0xFF18
452 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
453 #define RID_FACTORYCONFIG 0xFF21
454 #define RID_UNKNOWN22  0xFF22
455 #define RID_LEAPUSERNAME 0xFF23
456 #define RID_LEAPPASSWORD 0xFF24
457 #define RID_STATUS     0xFF50
458 #define RID_BEACON_HST 0xFF51
459 #define RID_BUSY_HST   0xFF52
460 #define RID_RETRIES_HST 0xFF53
461 #define RID_UNKNOWN54  0xFF54
462 #define RID_UNKNOWN55  0xFF55
463 #define RID_UNKNOWN56  0xFF56
464 #define RID_MIC        0xFF57
465 #define RID_STATS16    0xFF60
466 #define RID_STATS16DELTA 0xFF61
467 #define RID_STATS16DELTACLEAR 0xFF62
468 #define RID_STATS      0xFF68
469 #define RID_STATSDELTA 0xFF69
470 #define RID_STATSDELTACLEAR 0xFF6A
471 #define RID_ECHOTEST_RID 0xFF70
472 #define RID_ECHOTEST_RESULTS 0xFF71
473 #define RID_BSSLISTFIRST 0xFF72
474 #define RID_BSSLISTNEXT  0xFF73
475 #define RID_WPA_BSSLISTFIRST 0xFF74
476 #define RID_WPA_BSSLISTNEXT  0xFF75
477
478 typedef struct {
479         u16 cmd;
480         u16 parm0;
481         u16 parm1;
482         u16 parm2;
483 } Cmd;
484
485 typedef struct {
486         u16 status;
487         u16 rsp0;
488         u16 rsp1;
489         u16 rsp2;
490 } Resp;
491
492 /*
493  * Rids and endian-ness:  The Rids will always be in cpu endian, since
494  * this all the patches from the big-endian guys end up doing that.
495  * so all rid access should use the read/writeXXXRid routines.
496  */
497
498 /* This is redundant for x86 archs, but it seems necessary for ARM */
499 #pragma pack(1)
500
501 /* This structure came from an email sent to me from an engineer at
502    aironet for inclusion into this driver */
503 typedef struct {
504         __le16 len;
505         __le16 kindex;
506         u8 mac[ETH_ALEN];
507         __le16 klen;
508         u8 key[16];
509 } WepKeyRid;
510
511 /* These structures are from the Aironet's PC4500 Developers Manual */
512 typedef struct {
513         __le16 len;
514         u8 ssid[32];
515 } Ssid;
516
517 typedef struct {
518         __le16 len;
519         Ssid ssids[3];
520 } SsidRid;
521
522 typedef struct {
523         u16 len;
524         u16 modulation;
525 #define MOD_DEFAULT 0
526 #define MOD_CCK 1
527 #define MOD_MOK 2
528 } ModulationRid;
529
530 typedef struct {
531         u16 len; /* sizeof(ConfigRid) */
532         u16 opmode; /* operating mode */
533 #define MODE_STA_IBSS 0
534 #define MODE_STA_ESS 1
535 #define MODE_AP 2
536 #define MODE_AP_RPTR 3
537 #define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
538 #define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
539 #define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
540 #define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
541 #define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
542 #define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
543 #define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
544 #define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
545 #define MODE_MIC (1<<15) /* enable MIC */
546         u16 rmode; /* receive mode */
547 #define RXMODE_BC_MC_ADDR 0
548 #define RXMODE_BC_ADDR 1 /* ignore multicasts */
549 #define RXMODE_ADDR 2 /* ignore multicast and broadcast */
550 #define RXMODE_RFMON 3 /* wireless monitor mode */
551 #define RXMODE_RFMON_ANYBSS 4
552 #define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
553 #define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
554 #define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
555         u16 fragThresh;
556         u16 rtsThres;
557         u8 macAddr[ETH_ALEN];
558         u8 rates[8];
559         u16 shortRetryLimit;
560         u16 longRetryLimit;
561         u16 txLifetime; /* in kusec */
562         u16 rxLifetime; /* in kusec */
563         u16 stationary;
564         u16 ordering;
565         u16 u16deviceType; /* for overriding device type */
566         u16 cfpRate;
567         u16 cfpDuration;
568         u16 _reserved1[3];
569         /*---------- Scanning/Associating ----------*/
570         u16 scanMode;
571 #define SCANMODE_ACTIVE 0
572 #define SCANMODE_PASSIVE 1
573 #define SCANMODE_AIROSCAN 2
574         u16 probeDelay; /* in kusec */
575         u16 probeEnergyTimeout; /* in kusec */
576         u16 probeResponseTimeout;
577         u16 beaconListenTimeout;
578         u16 joinNetTimeout;
579         u16 authTimeout;
580         u16 authType;
581 #define AUTH_OPEN 0x1
582 #define AUTH_ENCRYPT 0x101
583 #define AUTH_SHAREDKEY 0x102
584 #define AUTH_ALLOW_UNENCRYPTED 0x200
585         u16 associationTimeout;
586         u16 specifiedApTimeout;
587         u16 offlineScanInterval;
588         u16 offlineScanDuration;
589         u16 linkLossDelay;
590         u16 maxBeaconLostTime;
591         u16 refreshInterval;
592 #define DISABLE_REFRESH 0xFFFF
593         u16 _reserved1a[1];
594         /*---------- Power save operation ----------*/
595         u16 powerSaveMode;
596 #define POWERSAVE_CAM 0
597 #define POWERSAVE_PSP 1
598 #define POWERSAVE_PSPCAM 2
599         u16 sleepForDtims;
600         u16 listenInterval;
601         u16 fastListenInterval;
602         u16 listenDecay;
603         u16 fastListenDelay;
604         u16 _reserved2[2];
605         /*---------- Ap/Ibss config items ----------*/
606         u16 beaconPeriod;
607         u16 atimDuration;
608         u16 hopPeriod;
609         u16 channelSet;
610         u16 channel;
611         u16 dtimPeriod;
612         u16 bridgeDistance;
613         u16 radioID;
614         /*---------- Radio configuration ----------*/
615         u16 radioType;
616 #define RADIOTYPE_DEFAULT 0
617 #define RADIOTYPE_802_11 1
618 #define RADIOTYPE_LEGACY 2
619         u8 rxDiversity;
620         u8 txDiversity;
621         u16 txPower;
622 #define TXPOWER_DEFAULT 0
623         u16 rssiThreshold;
624 #define RSSI_DEFAULT 0
625         u16 modulation;
626 #define PREAMBLE_AUTO 0
627 #define PREAMBLE_LONG 1
628 #define PREAMBLE_SHORT 2
629         u16 preamble;
630         u16 homeProduct;
631         u16 radioSpecific;
632         /*---------- Aironet Extensions ----------*/
633         u8 nodeName[16];
634         u16 arlThreshold;
635         u16 arlDecay;
636         u16 arlDelay;
637         u16 _reserved4[1];
638         /*---------- Aironet Extensions ----------*/
639         u8 magicAction;
640 #define MAGIC_ACTION_STSCHG 1
641 #define MAGIC_ACTION_RESUME 2
642 #define MAGIC_IGNORE_MCAST (1<<8)
643 #define MAGIC_IGNORE_BCAST (1<<9)
644 #define MAGIC_SWITCH_TO_PSP (0<<10)
645 #define MAGIC_STAY_IN_CAM (1<<10)
646         u8 magicControl;
647         u16 autoWake;
648 } ConfigRid;
649
650 typedef struct {
651         __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 /*------------------------------------------------------------------*/
5953 /*
5954  * Wireless Handler : get AP address
5955  */
5956 static int airo_get_wap(struct net_device *dev,
5957                         struct iw_request_info *info,
5958                         struct sockaddr *awrq,
5959                         char *extra)
5960 {
5961         struct airo_info *local = dev->priv;
5962         StatusRid status_rid;           /* Card status info */
5963
5964         readStatusRid(local, &status_rid, 1);
5965
5966         /* Tentative. This seems to work, wow, I'm lucky !!! */
5967         memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
5968         awrq->sa_family = ARPHRD_ETHER;
5969
5970         return 0;
5971 }
5972
5973 /*------------------------------------------------------------------*/
5974 /*
5975  * Wireless Handler : set Nickname
5976  */
5977 static int airo_set_nick(struct net_device *dev,
5978                          struct iw_request_info *info,
5979                          struct iw_point *dwrq,
5980                          char *extra)
5981 {
5982         struct airo_info *local = dev->priv;
5983
5984         /* Check the size of the string */
5985         if(dwrq->length > 16) {
5986                 return -E2BIG;
5987         }
5988         readConfigRid(local, 1);
5989         memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
5990         memcpy(local->config.nodeName, extra, dwrq->length);
5991         set_bit (FLAG_COMMIT, &local->flags);
5992
5993         return -EINPROGRESS;            /* Call commit handler */
5994 }
5995
5996 /*------------------------------------------------------------------*/
5997 /*
5998  * Wireless Handler : get Nickname
5999  */
6000 static int airo_get_nick(struct net_device *dev,
6001                          struct iw_request_info *info,
6002                          struct iw_point *dwrq,
6003                          char *extra)
6004 {
6005         struct airo_info *local = dev->priv;
6006
6007         readConfigRid(local, 1);
6008         strncpy(extra, local->config.nodeName, 16);
6009         extra[16] = '\0';
6010         dwrq->length = strlen(extra);
6011
6012         return 0;
6013 }
6014
6015 /*------------------------------------------------------------------*/
6016 /*
6017  * Wireless Handler : set Bit-Rate
6018  */
6019 static int airo_set_rate(struct net_device *dev,
6020                          struct iw_request_info *info,
6021                          struct iw_param *vwrq,
6022                          char *extra)
6023 {
6024         struct airo_info *local = dev->priv;
6025         CapabilityRid cap_rid;          /* Card capability info */
6026         u8      brate = 0;
6027         int     i;
6028
6029         /* First : get a valid bit rate value */
6030         readCapabilityRid(local, &cap_rid, 1);
6031
6032         /* Which type of value ? */
6033         if((vwrq->value < 8) && (vwrq->value >= 0)) {
6034                 /* Setting by rate index */
6035                 /* Find value in the magic rate table */
6036                 brate = cap_rid.supportedRates[vwrq->value];
6037         } else {
6038                 /* Setting by frequency value */
6039                 u8      normvalue = (u8) (vwrq->value/500000);
6040
6041                 /* Check if rate is valid */
6042                 for(i = 0 ; i < 8 ; i++) {
6043                         if(normvalue == cap_rid.supportedRates[i]) {
6044                                 brate = normvalue;
6045                                 break;
6046                         }
6047                 }
6048         }
6049         /* -1 designed the max rate (mostly auto mode) */
6050         if(vwrq->value == -1) {
6051                 /* Get the highest available rate */
6052                 for(i = 0 ; i < 8 ; i++) {
6053                         if(cap_rid.supportedRates[i] == 0)
6054                                 break;
6055                 }
6056                 if(i != 0)
6057                         brate = cap_rid.supportedRates[i - 1];
6058         }
6059         /* Check that it is valid */
6060         if(brate == 0) {
6061                 return -EINVAL;
6062         }
6063
6064         readConfigRid(local, 1);
6065         /* Now, check if we want a fixed or auto value */
6066         if(vwrq->fixed == 0) {
6067                 /* Fill all the rates up to this max rate */
6068                 memset(local->config.rates, 0, 8);
6069                 for(i = 0 ; i < 8 ; i++) {
6070                         local->config.rates[i] = cap_rid.supportedRates[i];
6071                         if(local->config.rates[i] == brate)
6072                                 break;
6073                 }
6074         } else {
6075                 /* Fixed mode */
6076                 /* One rate, fixed */
6077                 memset(local->config.rates, 0, 8);
6078                 local->config.rates[0] = brate;
6079         }
6080         set_bit (FLAG_COMMIT, &local->flags);
6081
6082         return -EINPROGRESS;            /* Call commit handler */
6083 }
6084
6085 /*------------------------------------------------------------------*/
6086 /*
6087  * Wireless Handler : get Bit-Rate
6088  */
6089 static int airo_get_rate(struct net_device *dev,
6090                          struct iw_request_info *info,
6091                          struct iw_param *vwrq,
6092                          char *extra)
6093 {
6094         struct airo_info *local = dev->priv;
6095         StatusRid status_rid;           /* Card status info */
6096
6097         readStatusRid(local, &status_rid, 1);
6098
6099         vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6100         /* If more than one rate, set auto */
6101         readConfigRid(local, 1);
6102         vwrq->fixed = (local->config.rates[1] == 0);
6103
6104         return 0;
6105 }
6106
6107 /*------------------------------------------------------------------*/
6108 /*
6109  * Wireless Handler : set RTS threshold
6110  */
6111 static int airo_set_rts(struct net_device *dev,
6112                         struct iw_request_info *info,
6113                         struct iw_param *vwrq,
6114                         char *extra)
6115 {
6116         struct airo_info *local = dev->priv;
6117         int rthr = vwrq->value;
6118
6119         if(vwrq->disabled)
6120                 rthr = AIRO_DEF_MTU;
6121         if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
6122                 return -EINVAL;
6123         }
6124         readConfigRid(local, 1);
6125         local->config.rtsThres = rthr;
6126         set_bit (FLAG_COMMIT, &local->flags);
6127
6128         return -EINPROGRESS;            /* Call commit handler */
6129 }
6130
6131 /*------------------------------------------------------------------*/
6132 /*
6133  * Wireless Handler : get RTS threshold
6134  */
6135 static int airo_get_rts(struct net_device *dev,
6136                         struct iw_request_info *info,
6137                         struct iw_param *vwrq,
6138                         char *extra)
6139 {
6140         struct airo_info *local = dev->priv;
6141
6142         readConfigRid(local, 1);
6143         vwrq->value = local->config.rtsThres;
6144         vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6145         vwrq->fixed = 1;
6146
6147         return 0;
6148 }
6149
6150 /*------------------------------------------------------------------*/
6151 /*
6152  * Wireless Handler : set Fragmentation threshold
6153  */
6154 static int airo_set_frag(struct net_device *dev,
6155                          struct iw_request_info *info,
6156                          struct iw_param *vwrq,
6157                          char *extra)
6158 {
6159         struct airo_info *local = dev->priv;
6160         int fthr = vwrq->value;
6161
6162         if(vwrq->disabled)
6163                 fthr = AIRO_DEF_MTU;
6164         if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
6165                 return -EINVAL;
6166         }
6167         fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
6168         readConfigRid(local, 1);
6169         local->config.fragThresh = (u16)fthr;
6170         set_bit (FLAG_COMMIT, &local->flags);
6171
6172         return -EINPROGRESS;            /* Call commit handler */
6173 }
6174
6175 /*------------------------------------------------------------------*/
6176 /*
6177  * Wireless Handler : get Fragmentation threshold
6178  */
6179 static int airo_get_frag(struct net_device *dev,
6180                          struct iw_request_info *info,
6181                          struct iw_param *vwrq,
6182                          char *extra)
6183 {
6184         struct airo_info *local = dev->priv;
6185
6186         readConfigRid(local, 1);
6187         vwrq->value = local->config.fragThresh;
6188         vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6189         vwrq->fixed = 1;
6190
6191         return 0;
6192 }
6193
6194 /*------------------------------------------------------------------*/
6195 /*
6196  * Wireless Handler : set Mode of Operation
6197  */
6198 static int airo_set_mode(struct net_device *dev,
6199                          struct iw_request_info *info,
6200                          __u32 *uwrq,
6201                          char *extra)
6202 {
6203         struct airo_info *local = dev->priv;
6204         int reset = 0;
6205
6206         readConfigRid(local, 1);
6207         if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
6208                 reset = 1;
6209
6210         switch(*uwrq) {
6211                 case IW_MODE_ADHOC:
6212                         local->config.opmode &= 0xFF00;
6213                         local->config.opmode |= MODE_STA_IBSS;
6214                         local->config.rmode &= 0xfe00;
6215                         local->config.scanMode = SCANMODE_ACTIVE;
6216                         clear_bit (FLAG_802_11, &local->flags);
6217                         break;
6218                 case IW_MODE_INFRA:
6219                         local->config.opmode &= 0xFF00;
6220                         local->config.opmode |= MODE_STA_ESS;
6221                         local->config.rmode &= 0xfe00;
6222                         local->config.scanMode = SCANMODE_ACTIVE;
6223                         clear_bit (FLAG_802_11, &local->flags);
6224                         break;
6225                 case IW_MODE_MASTER:
6226                         local->config.opmode &= 0xFF00;
6227                         local->config.opmode |= MODE_AP;
6228                         local->config.rmode &= 0xfe00;
6229                         local->config.scanMode = SCANMODE_ACTIVE;
6230                         clear_bit (FLAG_802_11, &local->flags);
6231                         break;
6232                 case IW_MODE_REPEAT:
6233                         local->config.opmode &= 0xFF00;
6234                         local->config.opmode |= MODE_AP_RPTR;
6235                         local->config.rmode &= 0xfe00;
6236                         local->config.scanMode = SCANMODE_ACTIVE;
6237                         clear_bit (FLAG_802_11, &local->flags);
6238                         break;
6239                 case IW_MODE_MONITOR:
6240                         local->config.opmode &= 0xFF00;
6241                         local->config.opmode |= MODE_STA_ESS;
6242                         local->config.rmode &= 0xfe00;
6243                         local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6244                         local->config.scanMode = SCANMODE_PASSIVE;
6245                         set_bit (FLAG_802_11, &local->flags);
6246                         break;
6247                 default:
6248                         return -EINVAL;
6249         }
6250         if (reset)
6251                 set_bit (FLAG_RESET, &local->flags);
6252         set_bit (FLAG_COMMIT, &local->flags);
6253
6254         return -EINPROGRESS;            /* Call commit handler */
6255 }
6256
6257 /*------------------------------------------------------------------*/
6258 /*
6259  * Wireless Handler : get Mode of Operation
6260  */
6261 static int airo_get_mode(struct net_device *dev,
6262                          struct iw_request_info *info,
6263                          __u32 *uwrq,
6264                          char *extra)
6265 {
6266         struct airo_info *local = dev->priv;
6267
6268         readConfigRid(local, 1);
6269         /* If not managed, assume it's ad-hoc */
6270         switch (local->config.opmode & 0xFF) {
6271                 case MODE_STA_ESS:
6272                         *uwrq = IW_MODE_INFRA;
6273                         break;
6274                 case MODE_AP:
6275                         *uwrq = IW_MODE_MASTER;
6276                         break;
6277                 case MODE_AP_RPTR:
6278                         *uwrq = IW_MODE_REPEAT;
6279                         break;
6280                 default:
6281                         *uwrq = IW_MODE_ADHOC;
6282         }
6283
6284         return 0;
6285 }
6286
6287 static inline int valid_index(CapabilityRid *p, int index)
6288 {
6289         if (index < 0)
6290                 return 0;
6291         return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
6292 }
6293
6294 /*------------------------------------------------------------------*/
6295 /*
6296  * Wireless Handler : set Encryption Key
6297  */
6298 static int airo_set_encode(struct net_device *dev,
6299                            struct iw_request_info *info,
6300                            struct iw_point *dwrq,
6301                            char *extra)
6302 {
6303         struct airo_info *local = dev->priv;
6304         CapabilityRid cap_rid;          /* Card capability info */
6305         int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
6306         u16 currentAuthType = local->config.authType;
6307
6308         /* Is WEP supported ? */
6309         readCapabilityRid(local, &cap_rid, 1);
6310         /* Older firmware doesn't support this...
6311         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6312                 return -EOPNOTSUPP;
6313         } */
6314         readConfigRid(local, 1);
6315
6316         /* Basic checking: do we have a key to set ?
6317          * Note : with the new API, it's impossible to get a NULL pointer.
6318          * Therefore, we need to check a key size == 0 instead.
6319          * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6320          * when no key is present (only change flags), but older versions
6321          * don't do it. - Jean II */
6322         if (dwrq->length > 0) {
6323                 wep_key_t key;
6324                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6325                 int current_index = get_wep_key(local, 0xffff);
6326                 /* Check the size of the key */
6327                 if (dwrq->length > MAX_KEY_SIZE) {
6328                         return -EINVAL;
6329                 }
6330                 /* Check the index (none -> use current) */
6331                 if (!valid_index(&cap_rid, index))
6332                         index = current_index;
6333                 /* Set the length */
6334                 if (dwrq->length > MIN_KEY_SIZE)
6335                         key.len = MAX_KEY_SIZE;
6336                 else
6337                         if (dwrq->length > 0)
6338                                 key.len = MIN_KEY_SIZE;
6339                         else
6340                                 /* Disable the key */
6341                                 key.len = 0;
6342                 /* Check if the key is not marked as invalid */
6343                 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6344                         /* Cleanup */
6345                         memset(key.key, 0, MAX_KEY_SIZE);
6346                         /* Copy the key in the driver */
6347                         memcpy(key.key, extra, dwrq->length);
6348                         /* Send the key to the card */
6349                         set_wep_key(local, index, key.key, key.len, perm, 1);
6350                 }
6351                 /* WE specify that if a valid key is set, encryption
6352                  * should be enabled (user may turn it off later)
6353                  * This is also how "iwconfig ethX key on" works */
6354                 if((index == current_index) && (key.len > 0) &&
6355                    (local->config.authType == AUTH_OPEN)) {
6356                         local->config.authType = AUTH_ENCRYPT;
6357                 }
6358         } else {
6359                 /* Do we want to just set the transmit key index ? */
6360                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6361                 if (valid_index(&cap_rid, index)) {
6362                         set_wep_key(local, index, NULL, 0, perm, 1);
6363                 } else
6364                         /* Don't complain if only change the mode */
6365                         if (!(dwrq->flags & IW_ENCODE_MODE))
6366                                 return -EINVAL;
6367         }
6368         /* Read the flags */
6369         if(dwrq->flags & IW_ENCODE_DISABLED)
6370                 local->config.authType = AUTH_OPEN;     // disable encryption
6371         if(dwrq->flags & IW_ENCODE_RESTRICTED)
6372                 local->config.authType = AUTH_SHAREDKEY;        // Only Both
6373         if(dwrq->flags & IW_ENCODE_OPEN)
6374                 local->config.authType = AUTH_ENCRYPT;  // Only Wep
6375         /* Commit the changes to flags if needed */
6376         if (local->config.authType != currentAuthType)
6377                 set_bit (FLAG_COMMIT, &local->flags);
6378         return -EINPROGRESS;            /* Call commit handler */
6379 }
6380
6381 /*------------------------------------------------------------------*/
6382 /*
6383  * Wireless Handler : get Encryption Key
6384  */
6385 static int airo_get_encode(struct net_device *dev,
6386                            struct iw_request_info *info,
6387                            struct iw_point *dwrq,
6388                            char *extra)
6389 {
6390         struct airo_info *local = dev->priv;
6391         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6392         CapabilityRid cap_rid;          /* Card capability info */
6393
6394         /* Is it supported ? */
6395         readCapabilityRid(local, &cap_rid, 1);
6396         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6397                 return -EOPNOTSUPP;
6398         }
6399         readConfigRid(local, 1);
6400         /* Check encryption mode */
6401         switch(local->config.authType)  {
6402                 case AUTH_ENCRYPT:
6403                         dwrq->flags = IW_ENCODE_OPEN;
6404                         break;
6405                 case AUTH_SHAREDKEY:
6406                         dwrq->flags = IW_ENCODE_RESTRICTED;
6407                         break;
6408                 default:
6409                 case AUTH_OPEN:
6410                         dwrq->flags = IW_ENCODE_DISABLED;
6411                         break;
6412         }
6413         /* We can't return the key, so set the proper flag and return zero */
6414         dwrq->flags |= IW_ENCODE_NOKEY;
6415         memset(extra, 0, 16);
6416
6417         /* Which key do we want ? -1 -> tx index */
6418         if (!valid_index(&cap_rid, index))
6419                 index = get_wep_key(local, 0xffff);
6420         dwrq->flags |= index + 1;
6421         /* Copy the key to the user buffer */
6422         dwrq->length = get_wep_key(local, index);
6423         if (dwrq->length > 16) {
6424                 dwrq->length=0;
6425         }
6426         return 0;
6427 }
6428
6429 /*------------------------------------------------------------------*/
6430 /*
6431  * Wireless Handler : set extended Encryption parameters
6432  */
6433 static int airo_set_encodeext(struct net_device *dev,
6434                            struct iw_request_info *info,
6435                             union iwreq_data *wrqu,
6436                             char *extra)
6437 {
6438         struct airo_info *local = dev->priv;
6439         struct iw_point *encoding = &wrqu->encoding;
6440         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6441         CapabilityRid cap_rid;          /* Card capability info */
6442         int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6443         u16 currentAuthType = local->config.authType;
6444         int idx, key_len, alg = ext->alg, set_key = 1;
6445         wep_key_t key;
6446
6447         /* Is WEP supported ? */
6448         readCapabilityRid(local, &cap_rid, 1);
6449         /* Older firmware doesn't support this...
6450         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6451                 return -EOPNOTSUPP;
6452         } */
6453         readConfigRid(local, 1);
6454
6455         /* Determine and validate the key index */
6456         idx = encoding->flags & IW_ENCODE_INDEX;
6457         if (idx) {
6458                 if (!valid_index(&cap_rid, idx - 1))
6459                         return -EINVAL;
6460                 idx--;
6461         } else
6462                 idx = get_wep_key(local, 0xffff);
6463
6464         if (encoding->flags & IW_ENCODE_DISABLED)
6465                 alg = IW_ENCODE_ALG_NONE;
6466
6467         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
6468                 /* Only set transmit key index here, actual
6469                  * key is set below if needed.
6470                  */
6471                 set_wep_key(local, idx, NULL, 0, perm, 1);
6472                 set_key = ext->key_len > 0 ? 1 : 0;
6473         }
6474
6475         if (set_key) {
6476                 /* Set the requested key first */
6477                 memset(key.key, 0, MAX_KEY_SIZE);
6478                 switch (alg) {
6479                 case IW_ENCODE_ALG_NONE:
6480                         key.len = 0;
6481                         break;
6482                 case IW_ENCODE_ALG_WEP:
6483                         if (ext->key_len > MIN_KEY_SIZE) {
6484                                 key.len = MAX_KEY_SIZE;
6485                         } else if (ext->key_len > 0) {
6486                                 key.len = MIN_KEY_SIZE;
6487                         } else {
6488                                 return -EINVAL;
6489                         }
6490                         key_len = min (ext->key_len, key.len);
6491                         memcpy(key.key, ext->key, key_len);
6492                         break;
6493                 default:
6494                         return -EINVAL;
6495                 }
6496                 /* Send the key to the card */
6497                 set_wep_key(local, idx, key.key, key.len, perm, 1);
6498         }
6499
6500         /* Read the flags */
6501         if(encoding->flags & IW_ENCODE_DISABLED)
6502                 local->config.authType = AUTH_OPEN;     // disable encryption
6503         if(encoding->flags & IW_ENCODE_RESTRICTED)
6504                 local->config.authType = AUTH_SHAREDKEY;        // Only Both
6505         if(encoding->flags & IW_ENCODE_OPEN)
6506                 local->config.authType = AUTH_ENCRYPT;  // Only Wep
6507         /* Commit the changes to flags if needed */
6508         if (local->config.authType != currentAuthType)
6509                 set_bit (FLAG_COMMIT, &local->flags);
6510
6511         return -EINPROGRESS;
6512 }
6513
6514
6515 /*------------------------------------------------------------------*/
6516 /*
6517  * Wireless Handler : get extended Encryption parameters
6518  */
6519 static int airo_get_encodeext(struct net_device *dev,
6520                             struct iw_request_info *info,
6521                             union iwreq_data *wrqu,
6522                             char *extra)
6523 {
6524         struct airo_info *local = dev->priv;
6525         struct iw_point *encoding = &wrqu->encoding;
6526         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6527         CapabilityRid cap_rid;          /* Card capability info */
6528         int idx, max_key_len;
6529
6530         /* Is it supported ? */
6531         readCapabilityRid(local, &cap_rid, 1);
6532         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6533                 return -EOPNOTSUPP;
6534         }
6535         readConfigRid(local, 1);
6536
6537         max_key_len = encoding->length - sizeof(*ext);
6538         if (max_key_len < 0)
6539                 return -EINVAL;
6540
6541         idx = encoding->flags & IW_ENCODE_INDEX;
6542         if (idx) {
6543                 if (!valid_index(&cap_rid, idx - 1))
6544                         return -EINVAL;
6545                 idx--;
6546         } else
6547                 idx = get_wep_key(local, 0xffff);
6548
6549         encoding->flags = idx + 1;
6550         memset(ext, 0, sizeof(*ext));
6551
6552         /* Check encryption mode */
6553         switch(local->config.authType) {
6554                 case AUTH_ENCRYPT:
6555                         encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6556                         break;
6557                 case AUTH_SHAREDKEY:
6558                         encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6559                         break;
6560                 default:
6561                 case AUTH_OPEN:
6562                         encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
6563                         break;
6564         }
6565         /* We can't return the key, so set the proper flag and return zero */
6566         encoding->flags |= IW_ENCODE_NOKEY;
6567         memset(extra, 0, 16);
6568         
6569         /* Copy the key to the user buffer */
6570         ext->key_len = get_wep_key(local, idx);
6571         if (ext->key_len > 16) {
6572                 ext->key_len=0;
6573         }
6574
6575         return 0;
6576 }
6577
6578
6579 /*------------------------------------------------------------------*/
6580 /*
6581  * Wireless Handler : set extended authentication parameters
6582  */
6583 static int airo_set_auth(struct net_device *dev,
6584                                struct iw_request_info *info,
6585                                union iwreq_data *wrqu, char *extra)
6586 {
6587         struct airo_info *local = dev->priv;
6588         struct iw_param *param = &wrqu->param;
6589         u16 currentAuthType = local->config.authType;
6590
6591         switch (param->flags & IW_AUTH_INDEX) {
6592         case IW_AUTH_WPA_VERSION:
6593         case IW_AUTH_CIPHER_PAIRWISE:
6594         case IW_AUTH_CIPHER_GROUP:
6595         case IW_AUTH_KEY_MGMT:
6596         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6597         case IW_AUTH_PRIVACY_INVOKED:
6598                 /*
6599                  * airo does not use these parameters
6600                  */
6601                 break;
6602
6603         case IW_AUTH_DROP_UNENCRYPTED:
6604                 if (param->value) {
6605                         /* Only change auth type if unencrypted */
6606                         if (currentAuthType == AUTH_OPEN)
6607                                 local->config.authType = AUTH_ENCRYPT;
6608                 } else {
6609                         local->config.authType = AUTH_OPEN;
6610                 }
6611
6612                 /* Commit the changes to flags if needed */
6613                 if (local->config.authType != currentAuthType)
6614                         set_bit (FLAG_COMMIT, &local->flags);
6615                 break;
6616
6617         case IW_AUTH_80211_AUTH_ALG: {
6618                         /* FIXME: What about AUTH_OPEN?  This API seems to
6619                          * disallow setting our auth to AUTH_OPEN.
6620                          */
6621                         if (param->value & IW_AUTH_ALG_SHARED_KEY) {
6622                                 local->config.authType = AUTH_SHAREDKEY;
6623                         } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
6624                                 local->config.authType = AUTH_ENCRYPT;
6625                         } else
6626                                 return -EINVAL;
6627                         break;
6628
6629                         /* Commit the changes to flags if needed */
6630                         if (local->config.authType != currentAuthType)
6631                                 set_bit (FLAG_COMMIT, &local->flags);
6632                 }
6633
6634         case IW_AUTH_WPA_ENABLED:
6635                 /* Silently accept disable of WPA */
6636                 if (param->value > 0)
6637                         return -EOPNOTSUPP;
6638                 break;
6639
6640         default:
6641                 return -EOPNOTSUPP;
6642         }
6643         return -EINPROGRESS;
6644 }
6645
6646
6647 /*------------------------------------------------------------------*/
6648 /*
6649  * Wireless Handler : get extended authentication parameters
6650  */
6651 static int airo_get_auth(struct net_device *dev,
6652                                struct iw_request_info *info,
6653                                union iwreq_data *wrqu, char *extra)
6654 {
6655         struct airo_info *local = dev->priv;
6656         struct iw_param *param = &wrqu->param;
6657         u16 currentAuthType = local->config.authType;
6658
6659         switch (param->flags & IW_AUTH_INDEX) {
6660         case IW_AUTH_DROP_UNENCRYPTED:
6661                 switch (currentAuthType) {
6662                 case AUTH_SHAREDKEY:
6663                 case AUTH_ENCRYPT:
6664                         param->value = 1;
6665                         break;
6666                 default:
6667                         param->value = 0;
6668                         break;
6669                 }
6670                 break;
6671
6672         case IW_AUTH_80211_AUTH_ALG:
6673                 switch (currentAuthType) {
6674                 case AUTH_SHAREDKEY:
6675                         param->value = IW_AUTH_ALG_SHARED_KEY;
6676                         break;
6677                 case AUTH_ENCRYPT:
6678                 default:
6679                         param->value = IW_AUTH_ALG_OPEN_SYSTEM;
6680                         break;
6681                 }
6682                 break;
6683
6684         case IW_AUTH_WPA_ENABLED:
6685                 param->value = 0;
6686                 break;
6687
6688         default:
6689                 return -EOPNOTSUPP;
6690         }
6691         return 0;
6692 }
6693
6694
6695 /*------------------------------------------------------------------*/
6696 /*
6697  * Wireless Handler : set Tx-Power
6698  */
6699 static int airo_set_txpow(struct net_device *dev,
6700                           struct iw_request_info *info,
6701                           struct iw_param *vwrq,
6702                           char *extra)
6703 {
6704         struct airo_info *local = dev->priv;
6705         CapabilityRid cap_rid;          /* Card capability info */
6706         int i;
6707         int rc = -EINVAL;
6708
6709         readCapabilityRid(local, &cap_rid, 1);
6710
6711         if (vwrq->disabled) {
6712                 set_bit (FLAG_RADIO_OFF, &local->flags);
6713                 set_bit (FLAG_COMMIT, &local->flags);
6714                 return -EINPROGRESS;            /* Call commit handler */
6715         }
6716         if (vwrq->flags != IW_TXPOW_MWATT) {
6717                 return -EINVAL;
6718         }
6719         clear_bit (FLAG_RADIO_OFF, &local->flags);
6720         for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
6721                 if (vwrq->value == le16_to_cpu(cap_rid.txPowerLevels[i])) {
6722                         readConfigRid(local, 1);
6723                         local->config.txPower = vwrq->value;
6724                         set_bit (FLAG_COMMIT, &local->flags);
6725                         rc = -EINPROGRESS;      /* Call commit handler */
6726                         break;
6727                 }
6728         return rc;
6729 }
6730
6731 /*------------------------------------------------------------------*/
6732 /*
6733  * Wireless Handler : get Tx-Power
6734  */
6735 static int airo_get_txpow(struct net_device *dev,
6736                           struct iw_request_info *info,
6737                           struct iw_param *vwrq,
6738                           char *extra)
6739 {
6740         struct airo_info *local = dev->priv;
6741
6742         readConfigRid(local, 1);
6743         vwrq->value = local->config.txPower;
6744         vwrq->fixed = 1;        /* No power control */
6745         vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6746         vwrq->flags = IW_TXPOW_MWATT;
6747
6748         return 0;
6749 }
6750
6751 /*------------------------------------------------------------------*/
6752 /*
6753  * Wireless Handler : set Retry limits
6754  */
6755 static int airo_set_retry(struct net_device *dev,
6756                           struct iw_request_info *info,
6757                           struct iw_param *vwrq,
6758                           char *extra)
6759 {
6760         struct airo_info *local = dev->priv;
6761         int rc = -EINVAL;
6762
6763         if(vwrq->disabled) {
6764                 return -EINVAL;
6765         }
6766         readConfigRid(local, 1);
6767         if(vwrq->flags & IW_RETRY_LIMIT) {
6768                 if(vwrq->flags & IW_RETRY_LONG)
6769                         local->config.longRetryLimit = vwrq->value;
6770                 else if (vwrq->flags & IW_RETRY_SHORT)
6771                         local->config.shortRetryLimit = vwrq->value;
6772                 else {
6773                         /* No modifier : set both */
6774                         local->config.longRetryLimit = vwrq->value;
6775                         local->config.shortRetryLimit = vwrq->value;
6776                 }
6777                 set_bit (FLAG_COMMIT, &local->flags);
6778                 rc = -EINPROGRESS;              /* Call commit handler */
6779         }
6780         if(vwrq->flags & IW_RETRY_LIFETIME) {
6781                 local->config.txLifetime = vwrq->value / 1024;
6782                 set_bit (FLAG_COMMIT, &local->flags);
6783                 rc = -EINPROGRESS;              /* Call commit handler */
6784         }
6785         return rc;
6786 }
6787
6788 /*------------------------------------------------------------------*/
6789 /*
6790  * Wireless Handler : get Retry limits
6791  */
6792 static int airo_get_retry(struct net_device *dev,
6793                           struct iw_request_info *info,
6794                           struct iw_param *vwrq,
6795                           char *extra)
6796 {
6797         struct airo_info *local = dev->priv;
6798
6799         vwrq->disabled = 0;      /* Can't be disabled */
6800
6801         readConfigRid(local, 1);
6802         /* Note : by default, display the min retry number */
6803         if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6804                 vwrq->flags = IW_RETRY_LIFETIME;
6805                 vwrq->value = (int)local->config.txLifetime * 1024;
6806         } else if((vwrq->flags & IW_RETRY_LONG)) {
6807                 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6808                 vwrq->value = (int)local->config.longRetryLimit;
6809         } else {
6810                 vwrq->flags = IW_RETRY_LIMIT;
6811                 vwrq->value = (int)local->config.shortRetryLimit;
6812                 if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
6813                         vwrq->flags |= IW_RETRY_SHORT;
6814         }
6815
6816         return 0;
6817 }
6818
6819 /*------------------------------------------------------------------*/
6820 /*
6821  * Wireless Handler : get range info
6822  */
6823 static int airo_get_range(struct net_device *dev,
6824                           struct iw_request_info *info,
6825                           struct iw_point *dwrq,
6826                           char *extra)
6827 {
6828         struct airo_info *local = dev->priv;
6829         struct iw_range *range = (struct iw_range *) extra;
6830         CapabilityRid cap_rid;          /* Card capability info */
6831         int             i;
6832         int             k;
6833
6834         readCapabilityRid(local, &cap_rid, 1);
6835
6836         dwrq->length = sizeof(struct iw_range);
6837         memset(range, 0, sizeof(*range));
6838         range->min_nwid = 0x0000;
6839         range->max_nwid = 0x0000;
6840         range->num_channels = 14;
6841         /* Should be based on cap_rid.country to give only
6842          * what the current card support */
6843         k = 0;
6844         for(i = 0; i < 14; i++) {
6845                 range->freq[k].i = i + 1; /* List index */
6846                 range->freq[k].m = frequency_list[i] * 100000;
6847                 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
6848         }
6849         range->num_frequency = k;
6850
6851         range->sensitivity = 65535;
6852
6853         /* Hum... Should put the right values there */
6854         if (local->rssi)
6855                 range->max_qual.qual = 100;     /* % */
6856         else
6857                 range->max_qual.qual = airo_get_max_quality(&cap_rid);
6858         range->max_qual.level = 0x100 - 120;    /* -120 dBm */
6859         range->max_qual.noise = 0x100 - 120;    /* -120 dBm */
6860
6861         /* Experimental measurements - boundary 11/5.5 Mb/s */
6862         /* Note : with or without the (local->rssi), results
6863          * are somewhat different. - Jean II */
6864         if (local->rssi) {
6865                 range->avg_qual.qual = 50;              /* % */
6866                 range->avg_qual.level = 0x100 - 70;     /* -70 dBm */
6867         } else {
6868                 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6869                 range->avg_qual.level = 0x100 - 80;     /* -80 dBm */
6870         }
6871         range->avg_qual.noise = 0x100 - 85;             /* -85 dBm */
6872
6873         for(i = 0 ; i < 8 ; i++) {
6874                 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6875                 if(range->bitrate[i] == 0)
6876                         break;
6877         }
6878         range->num_bitrates = i;
6879
6880         /* Set an indication of the max TCP throughput
6881          * in bit/s that we can expect using this interface.
6882          * May be use for QoS stuff... Jean II */
6883         if(i > 2)
6884                 range->throughput = 5000 * 1000;
6885         else
6886                 range->throughput = 1500 * 1000;
6887
6888         range->min_rts = 0;
6889         range->max_rts = AIRO_DEF_MTU;
6890         range->min_frag = 256;
6891         range->max_frag = AIRO_DEF_MTU;
6892
6893         if(cap_rid.softCap & cpu_to_le16(2)) {
6894                 // WEP: RC4 40 bits
6895                 range->encoding_size[0] = 5;
6896                 // RC4 ~128 bits
6897                 if (cap_rid.softCap & cpu_to_le16(0x100)) {
6898                         range->encoding_size[1] = 13;
6899                         range->num_encoding_sizes = 2;
6900                 } else
6901                         range->num_encoding_sizes = 1;
6902                 range->max_encoding_tokens =
6903                         cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
6904         } else {
6905                 range->num_encoding_sizes = 0;
6906                 range->max_encoding_tokens = 0;
6907         }
6908         range->min_pmp = 0;
6909         range->max_pmp = 5000000;       /* 5 secs */
6910         range->min_pmt = 0;
6911         range->max_pmt = 65535 * 1024;  /* ??? */
6912         range->pmp_flags = IW_POWER_PERIOD;
6913         range->pmt_flags = IW_POWER_TIMEOUT;
6914         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
6915
6916         /* Transmit Power - values are in mW */
6917         for(i = 0 ; i < 8 ; i++) {
6918                 range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
6919                 if(range->txpower[i] == 0)
6920                         break;
6921         }
6922         range->num_txpower = i;
6923         range->txpower_capa = IW_TXPOW_MWATT;
6924         range->we_version_source = 19;
6925         range->we_version_compiled = WIRELESS_EXT;
6926         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
6927         range->retry_flags = IW_RETRY_LIMIT;
6928         range->r_time_flags = IW_RETRY_LIFETIME;
6929         range->min_retry = 1;
6930         range->max_retry = 65535;
6931         range->min_r_time = 1024;
6932         range->max_r_time = 65535 * 1024;
6933
6934         /* Event capability (kernel + driver) */
6935         range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
6936                                 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
6937                                 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
6938                                 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
6939         range->event_capa[1] = IW_EVENT_CAPA_K_1;
6940         range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
6941         return 0;
6942 }
6943
6944 /*------------------------------------------------------------------*/
6945 /*
6946  * Wireless Handler : set Power Management
6947  */
6948 static int airo_set_power(struct net_device *dev,
6949                           struct iw_request_info *info,
6950                           struct iw_param *vwrq,
6951                           char *extra)
6952 {
6953         struct airo_info *local = dev->priv;
6954
6955         readConfigRid(local, 1);
6956         if (vwrq->disabled) {
6957                 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6958                         return -EINVAL;
6959                 }
6960                 local->config.powerSaveMode = POWERSAVE_CAM;
6961                 local->config.rmode &= 0xFF00;
6962                 local->config.rmode |= RXMODE_BC_MC_ADDR;
6963                 set_bit (FLAG_COMMIT, &local->flags);
6964                 return -EINPROGRESS;            /* Call commit handler */
6965         }
6966         if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6967                 local->config.fastListenDelay = (vwrq->value + 500) / 1024;
6968                 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6969                 set_bit (FLAG_COMMIT, &local->flags);
6970         } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
6971                 local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
6972                 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6973                 set_bit (FLAG_COMMIT, &local->flags);
6974         }
6975         switch (vwrq->flags & IW_POWER_MODE) {
6976                 case IW_POWER_UNICAST_R:
6977                         if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6978                                 return -EINVAL;
6979                         }
6980                         local->config.rmode &= 0xFF00;
6981                         local->config.rmode |= RXMODE_ADDR;
6982                         set_bit (FLAG_COMMIT, &local->flags);
6983                         break;
6984                 case IW_POWER_ALL_R:
6985                         if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6986                                 return -EINVAL;
6987                         }
6988                         local->config.rmode &= 0xFF00;
6989                         local->config.rmode |= RXMODE_BC_MC_ADDR;
6990                         set_bit (FLAG_COMMIT, &local->flags);
6991                 case IW_POWER_ON:
6992                         /* This is broken, fixme ;-) */
6993                         break;
6994                 default:
6995                         return -EINVAL;
6996         }
6997         // Note : we may want to factor local->need_commit here
6998         // Note2 : may also want to factor RXMODE_RFMON test
6999         return -EINPROGRESS;            /* Call commit handler */
7000 }
7001
7002 /*------------------------------------------------------------------*/
7003 /*
7004  * Wireless Handler : get Power Management
7005  */
7006 static int airo_get_power(struct net_device *dev,
7007                           struct iw_request_info *info,
7008                           struct iw_param *vwrq,
7009                           char *extra)
7010 {
7011         struct airo_info *local = dev->priv;
7012         int mode;
7013
7014         readConfigRid(local, 1);
7015         mode = local->config.powerSaveMode;
7016         if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
7017                 return 0;
7018         if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7019                 vwrq->value = (int)local->config.fastListenDelay * 1024;
7020                 vwrq->flags = IW_POWER_TIMEOUT;
7021         } else {
7022                 vwrq->value = (int)local->config.fastListenInterval * 1024;
7023                 vwrq->flags = IW_POWER_PERIOD;
7024         }
7025         if ((local->config.rmode & 0xFF) == RXMODE_ADDR)
7026                 vwrq->flags |= IW_POWER_UNICAST_R;
7027         else
7028                 vwrq->flags |= IW_POWER_ALL_R;
7029
7030         return 0;
7031 }
7032
7033 /*------------------------------------------------------------------*/
7034 /*
7035  * Wireless Handler : set Sensitivity
7036  */
7037 static int airo_set_sens(struct net_device *dev,
7038                          struct iw_request_info *info,
7039                          struct iw_param *vwrq,
7040                          char *extra)
7041 {
7042         struct airo_info *local = dev->priv;
7043
7044         readConfigRid(local, 1);
7045         local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
7046         set_bit (FLAG_COMMIT, &local->flags);
7047
7048         return -EINPROGRESS;            /* Call commit handler */
7049 }
7050
7051 /*------------------------------------------------------------------*/
7052 /*
7053  * Wireless Handler : get Sensitivity
7054  */
7055 static int airo_get_sens(struct net_device *dev,
7056                          struct iw_request_info *info,
7057                          struct iw_param *vwrq,
7058                          char *extra)
7059 {
7060         struct airo_info *local = dev->priv;
7061
7062         readConfigRid(local, 1);
7063         vwrq->value = local->config.rssiThreshold;
7064         vwrq->disabled = (vwrq->value == 0);
7065         vwrq->fixed = 1;
7066
7067         return 0;
7068 }
7069
7070 /*------------------------------------------------------------------*/
7071 /*
7072  * Wireless Handler : get AP List
7073  * Note : this is deprecated in favor of IWSCAN
7074  */
7075 static int airo_get_aplist(struct net_device *dev,
7076                            struct iw_request_info *info,
7077                            struct iw_point *dwrq,
7078                            char *extra)
7079 {
7080         struct airo_info *local = dev->priv;
7081         struct sockaddr *address = (struct sockaddr *) extra;
7082         struct iw_quality qual[IW_MAX_AP];
7083         BSSListRid BSSList;
7084         int i;
7085         int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7086
7087         for (i = 0; i < IW_MAX_AP; i++) {
7088                 u16 dBm;
7089                 if (readBSSListRid(local, loseSync, &BSSList))
7090                         break;
7091                 loseSync = 0;
7092                 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
7093                 address[i].sa_family = ARPHRD_ETHER;
7094                 dBm = le16_to_cpu(BSSList.dBm);
7095                 if (local->rssi) {
7096                         qual[i].level = 0x100 - dBm;
7097                         qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
7098                         qual[i].updated = IW_QUAL_QUAL_UPDATED
7099                                         | IW_QUAL_LEVEL_UPDATED
7100                                         | IW_QUAL_DBM;
7101                 } else {
7102                         qual[i].level = (dBm + 321) / 2;
7103                         qual[i].qual = 0;
7104                         qual[i].updated = IW_QUAL_QUAL_INVALID
7105                                         | IW_QUAL_LEVEL_UPDATED
7106                                         | IW_QUAL_DBM;
7107                 }
7108                 qual[i].noise = local->wstats.qual.noise;
7109                 if (BSSList.index == cpu_to_le16(0xffff))
7110                         break;
7111         }
7112         if (!i) {
7113                 StatusRid status_rid;           /* Card status info */
7114                 readStatusRid(local, &status_rid, 1);
7115                 for (i = 0;
7116                      i < min(IW_MAX_AP, 4) &&
7117                              (status_rid.bssid[i][0]
7118                               & status_rid.bssid[i][1]
7119                               & status_rid.bssid[i][2]
7120                               & status_rid.bssid[i][3]
7121                               & status_rid.bssid[i][4]
7122                               & status_rid.bssid[i][5])!=0xff &&
7123                              (status_rid.bssid[i][0]
7124                               | status_rid.bssid[i][1]
7125                               | status_rid.bssid[i][2]
7126                               | status_rid.bssid[i][3]
7127                               | status_rid.bssid[i][4]
7128                               | status_rid.bssid[i][5]);
7129                      i++) {
7130                         memcpy(address[i].sa_data,
7131                                status_rid.bssid[i], ETH_ALEN);
7132                         address[i].sa_family = ARPHRD_ETHER;
7133                 }
7134         } else {
7135                 dwrq->flags = 1; /* Should be define'd */
7136                 memcpy(extra + sizeof(struct sockaddr)*i,
7137                        &qual,  sizeof(struct iw_quality)*i);
7138         }
7139         dwrq->length = i;
7140
7141         return 0;
7142 }
7143
7144 /*------------------------------------------------------------------*/
7145 /*
7146  * Wireless Handler : Initiate Scan
7147  */
7148 static int airo_set_scan(struct net_device *dev,
7149                          struct iw_request_info *info,
7150                          struct iw_param *vwrq,
7151                          char *extra)
7152 {
7153         struct airo_info *ai = dev->priv;
7154         Cmd cmd;
7155         Resp rsp;
7156         int wake = 0;
7157
7158         /* Note : you may have realised that, as this is a SET operation,
7159          * this is privileged and therefore a normal user can't
7160          * perform scanning.
7161          * This is not an error, while the device perform scanning,
7162          * traffic doesn't flow, so it's a perfect DoS...
7163          * Jean II */
7164         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
7165
7166         if (down_interruptible(&ai->sem))
7167                 return -ERESTARTSYS;
7168
7169         /* If there's already a scan in progress, don't
7170          * trigger another one. */
7171         if (ai->scan_timeout > 0)
7172                 goto out;
7173
7174         /* Initiate a scan command */
7175         ai->scan_timeout = RUN_AT(3*HZ);
7176         memset(&cmd, 0, sizeof(cmd));
7177         cmd.cmd=CMD_LISTBSS;
7178         issuecommand(ai, &cmd, &rsp);
7179         wake = 1;
7180
7181 out:
7182         up(&ai->sem);
7183         if (wake)
7184                 wake_up_interruptible(&ai->thr_wait);
7185         return 0;
7186 }
7187
7188 /*------------------------------------------------------------------*/
7189 /*
7190  * Translate scan data returned from the card to a card independent
7191  * format that the Wireless Tools will understand - Jean II
7192  */
7193 static inline char *airo_translate_scan(struct net_device *dev,
7194                                         char *current_ev,
7195                                         char *end_buf,
7196                                         BSSListRid *bss)
7197 {
7198         struct airo_info *ai = dev->priv;
7199         struct iw_event         iwe;            /* Temporary buffer */
7200         __le16                  capabilities;
7201         char *                  current_val;    /* For rates */
7202         int                     i;
7203         char *          buf;
7204         u16 dBm;
7205
7206         /* First entry *MUST* be the AP MAC address */
7207         iwe.cmd = SIOCGIWAP;
7208         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7209         memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7210         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
7211
7212         /* Other entries will be displayed in the order we give them */
7213
7214         /* Add the ESSID */
7215         iwe.u.data.length = bss->ssidLen;
7216         if(iwe.u.data.length > 32)
7217                 iwe.u.data.length = 32;
7218         iwe.cmd = SIOCGIWESSID;
7219         iwe.u.data.flags = 1;
7220         current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
7221
7222         /* Add mode */
7223         iwe.cmd = SIOCGIWMODE;
7224         capabilities = bss->cap;
7225         if(capabilities & (CAP_ESS | CAP_IBSS)) {
7226                 if(capabilities & CAP_ESS)
7227                         iwe.u.mode = IW_MODE_MASTER;
7228                 else
7229                         iwe.u.mode = IW_MODE_ADHOC;
7230                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
7231         }
7232
7233         /* Add frequency */
7234         iwe.cmd = SIOCGIWFREQ;
7235         iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7236         /* iwe.u.freq.m containt the channel (starting 1), our 
7237          * frequency_list array start at index 0...
7238          */
7239         iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
7240         iwe.u.freq.e = 1;
7241         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
7242
7243         dBm = le16_to_cpu(bss->dBm);
7244
7245         /* Add quality statistics */
7246         iwe.cmd = IWEVQUAL;
7247         if (ai->rssi) {
7248                 iwe.u.qual.level = 0x100 - dBm;
7249                 iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
7250                 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
7251                                 | IW_QUAL_LEVEL_UPDATED
7252                                 | IW_QUAL_DBM;
7253         } else {
7254                 iwe.u.qual.level = (dBm + 321) / 2;
7255                 iwe.u.qual.qual = 0;
7256                 iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
7257                                 | IW_QUAL_LEVEL_UPDATED
7258                                 | IW_QUAL_DBM;
7259         }
7260         iwe.u.qual.noise = ai->wstats.qual.noise;
7261         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
7262
7263         /* Add encryption capability */
7264         iwe.cmd = SIOCGIWENCODE;
7265         if(capabilities & CAP_PRIVACY)
7266                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
7267         else
7268                 iwe.u.data.flags = IW_ENCODE_DISABLED;
7269         iwe.u.data.length = 0;
7270         current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
7271
7272         /* Rate : stuffing multiple values in a single event require a bit
7273          * more of magic - Jean II */
7274         current_val = current_ev + IW_EV_LCP_LEN;
7275
7276         iwe.cmd = SIOCGIWRATE;
7277         /* Those two flags are ignored... */
7278         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
7279         /* Max 8 values */
7280         for(i = 0 ; i < 8 ; i++) {
7281                 /* NULL terminated */
7282                 if(bss->rates[i] == 0)
7283                         break;
7284                 /* Bit rate given in 500 kb/s units (+ 0x80) */
7285                 iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7286                 /* Add new value to event */
7287                 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
7288         }
7289         /* Check if we added any event */
7290         if((current_val - current_ev) > IW_EV_LCP_LEN)
7291                 current_ev = current_val;
7292
7293         /* Beacon interval */
7294         buf = kmalloc(30, GFP_KERNEL);
7295         if (buf) {
7296                 iwe.cmd = IWEVCUSTOM;
7297                 sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7298                 iwe.u.data.length = strlen(buf);
7299                 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
7300                 kfree(buf);
7301         }
7302
7303         /* Put WPA/RSN Information Elements into the event stream */
7304         if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
7305                 unsigned int num_null_ies = 0;
7306                 u16 length = sizeof (bss->extra.iep);
7307                 struct ieee80211_info_element *info_element =
7308                         (struct ieee80211_info_element *) &bss->extra.iep;
7309
7310                 while ((length >= sizeof(*info_element)) && (num_null_ies < 2)) {
7311                         if (sizeof(*info_element) + info_element->len > length) {
7312                                 /* Invalid element, don't continue parsing IE */
7313                                 break;
7314                         }
7315
7316                         switch (info_element->id) {
7317                         case MFIE_TYPE_SSID:
7318                                 /* Two zero-length SSID elements
7319                                  * mean we're done parsing elements */
7320                                 if (!info_element->len)
7321                                         num_null_ies++;
7322                                 break;
7323
7324                         case MFIE_TYPE_GENERIC:
7325                                 if (info_element->len >= 4 &&
7326                                     info_element->data[0] == 0x00 &&
7327                                     info_element->data[1] == 0x50 &&
7328                                     info_element->data[2] == 0xf2 &&
7329                                     info_element->data[3] == 0x01) {
7330                                         iwe.cmd = IWEVGENIE;
7331                                         iwe.u.data.length = min(info_element->len + 2,
7332                                                                   MAX_WPA_IE_LEN);
7333                                         current_ev = iwe_stream_add_point(current_ev, end_buf,
7334                                                         &iwe, (char *) info_element);
7335                                 }
7336                                 break;
7337
7338                         case MFIE_TYPE_RSN:
7339                                 iwe.cmd = IWEVGENIE;
7340                                 iwe.u.data.length = min(info_element->len + 2,
7341                                                           MAX_WPA_IE_LEN);
7342                                 current_ev = iwe_stream_add_point(current_ev, end_buf,
7343                                                 &iwe, (char *) info_element);
7344                                 break;
7345
7346                         default:
7347                                 break;
7348                         }
7349
7350                         length -= sizeof(*info_element) + info_element->len;
7351                         info_element =
7352                             (struct ieee80211_info_element *)&info_element->
7353                             data[info_element->len];
7354                 }
7355         }
7356         return current_ev;
7357 }
7358
7359 /*------------------------------------------------------------------*/
7360 /*
7361  * Wireless Handler : Read Scan Results
7362  */
7363 static int airo_get_scan(struct net_device *dev,
7364                          struct iw_request_info *info,
7365                          struct iw_point *dwrq,
7366                          char *extra)
7367 {
7368         struct airo_info *ai = dev->priv;
7369         BSSListElement *net;
7370         int err = 0;
7371         char *current_ev = extra;
7372
7373         /* If a scan is in-progress, return -EAGAIN */
7374         if (ai->scan_timeout > 0)
7375                 return -EAGAIN;
7376
7377         if (down_interruptible(&ai->sem))
7378                 return -EAGAIN;
7379
7380         list_for_each_entry (net, &ai->network_list, list) {
7381                 /* Translate to WE format this entry */
7382                 current_ev = airo_translate_scan(dev, current_ev,
7383                                                  extra + dwrq->length,
7384                                                  &net->bss);
7385
7386                 /* Check if there is space for one more entry */
7387                 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7388                         /* Ask user space to try again with a bigger buffer */
7389                         err = -E2BIG;
7390                         goto out;
7391                 }
7392         }
7393
7394         /* Length of data */
7395         dwrq->length = (current_ev - extra);
7396         dwrq->flags = 0;        /* todo */
7397
7398 out:
7399         up(&ai->sem);
7400         return err;
7401 }
7402
7403 /*------------------------------------------------------------------*/
7404 /*
7405  * Commit handler : called after a bunch of SET operations
7406  */
7407 static int airo_config_commit(struct net_device *dev,
7408                               struct iw_request_info *info,     /* NULL */
7409                               void *zwrq,                       /* NULL */
7410                               char *extra)                      /* NULL */
7411 {
7412         struct airo_info *local = dev->priv;
7413
7414         if (!test_bit (FLAG_COMMIT, &local->flags))
7415                 return 0;
7416
7417         /* Some of the "SET" function may have modified some of the
7418          * parameters. It's now time to commit them in the card */
7419         disable_MAC(local, 1);
7420         if (test_bit (FLAG_RESET, &local->flags)) {
7421                 APListRid APList_rid;
7422                 SsidRid SSID_rid;
7423
7424                 readAPListRid(local, &APList_rid);
7425                 readSsidRid(local, &SSID_rid);
7426                 if (test_bit(FLAG_MPI,&local->flags))
7427                         setup_card(local, dev->dev_addr, 1 );
7428                 else
7429                         reset_airo_card(dev);
7430                 disable_MAC(local, 1);
7431                 writeSsidRid(local, &SSID_rid, 1);
7432                 writeAPListRid(local, &APList_rid, 1);
7433         }
7434         if (down_interruptible(&local->sem))
7435                 return -ERESTARTSYS;
7436         writeConfigRid(local, 0);
7437         enable_MAC(local, 0);
7438         if (test_bit (FLAG_RESET, &local->flags))
7439                 airo_set_promisc(local);
7440         else
7441                 up(&local->sem);
7442
7443         return 0;
7444 }
7445
7446 /*------------------------------------------------------------------*/
7447 /*
7448  * Structures to export the Wireless Handlers
7449  */
7450
7451 static const struct iw_priv_args airo_private_args[] = {
7452 /*{ cmd,         set_args,                            get_args, name } */
7453   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7454     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7455   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7456     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7457 };
7458
7459 static const iw_handler         airo_handler[] =
7460 {
7461         (iw_handler) airo_config_commit,        /* SIOCSIWCOMMIT */
7462         (iw_handler) airo_get_name,             /* SIOCGIWNAME */
7463         (iw_handler) NULL,                      /* SIOCSIWNWID */
7464         (iw_handler) NULL,                      /* SIOCGIWNWID */
7465         (iw_handler) airo_set_freq,             /* SIOCSIWFREQ */
7466         (iw_handler) airo_get_freq,             /* SIOCGIWFREQ */
7467         (iw_handler) airo_set_mode,             /* SIOCSIWMODE */
7468         (iw_handler) airo_get_mode,             /* SIOCGIWMODE */
7469         (iw_handler) airo_set_sens,             /* SIOCSIWSENS */
7470         (iw_handler) airo_get_sens,             /* SIOCGIWSENS */
7471         (iw_handler) NULL,                      /* SIOCSIWRANGE */
7472         (iw_handler) airo_get_range,            /* SIOCGIWRANGE */
7473         (iw_handler) NULL,                      /* SIOCSIWPRIV */
7474         (iw_handler) NULL,                      /* SIOCGIWPRIV */
7475         (iw_handler) NULL,                      /* SIOCSIWSTATS */
7476         (iw_handler) NULL,                      /* SIOCGIWSTATS */
7477         iw_handler_set_spy,                     /* SIOCSIWSPY */
7478         iw_handler_get_spy,                     /* SIOCGIWSPY */
7479         iw_handler_set_thrspy,                  /* SIOCSIWTHRSPY */
7480         iw_handler_get_thrspy,                  /* SIOCGIWTHRSPY */
7481         (iw_handler) airo_set_wap,              /* SIOCSIWAP */
7482         (iw_handler) airo_get_wap,              /* SIOCGIWAP */
7483         (iw_handler) NULL,                      /* -- hole -- */
7484         (iw_handler) airo_get_aplist,           /* SIOCGIWAPLIST */
7485         (iw_handler) airo_set_scan,             /* SIOCSIWSCAN */
7486         (iw_handler) airo_get_scan,             /* SIOCGIWSCAN */
7487         (iw_handler) airo_set_essid,            /* SIOCSIWESSID */
7488         (iw_handler) airo_get_essid,            /* SIOCGIWESSID */
7489         (iw_handler) airo_set_nick,             /* SIOCSIWNICKN */
7490         (iw_handler) airo_get_nick,             /* SIOCGIWNICKN */
7491         (iw_handler) NULL,                      /* -- hole -- */
7492         (iw_handler) NULL,                      /* -- hole -- */
7493         (iw_handler) airo_set_rate,             /* SIOCSIWRATE */
7494         (iw_handler) airo_get_rate,             /* SIOCGIWRATE */
7495         (iw_handler) airo_set_rts,              /* SIOCSIWRTS */
7496         (iw_handler) airo_get_rts,              /* SIOCGIWRTS */
7497         (iw_handler) airo_set_frag,             /* SIOCSIWFRAG */
7498         (iw_handler) airo_get_frag,             /* SIOCGIWFRAG */
7499         (iw_handler) airo_set_txpow,            /* SIOCSIWTXPOW */
7500         (iw_handler) airo_get_txpow,            /* SIOCGIWTXPOW */
7501         (iw_handler) airo_set_retry,            /* SIOCSIWRETRY */
7502         (iw_handler) airo_get_retry,            /* SIOCGIWRETRY */
7503         (iw_handler) airo_set_encode,           /* SIOCSIWENCODE */
7504         (iw_handler) airo_get_encode,           /* SIOCGIWENCODE */
7505         (iw_handler) airo_set_power,            /* SIOCSIWPOWER */
7506         (iw_handler) airo_get_power,            /* SIOCGIWPOWER */
7507         (iw_handler) NULL,                      /* -- hole -- */
7508         (iw_handler) NULL,                      /* -- hole -- */
7509         (iw_handler) NULL,                      /* SIOCSIWGENIE */
7510         (iw_handler) NULL,                      /* SIOCGIWGENIE */
7511         (iw_handler) airo_set_auth,             /* SIOCSIWAUTH */
7512         (iw_handler) airo_get_auth,             /* SIOCGIWAUTH */
7513         (iw_handler) airo_set_encodeext,        /* SIOCSIWENCODEEXT */
7514         (iw_handler) airo_get_encodeext,        /* SIOCGIWENCODEEXT */
7515         (iw_handler) NULL,                      /* SIOCSIWPMKSA */
7516 };
7517
7518 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7519  * We want to force the use of the ioctl code, because those can't be
7520  * won't work the iw_handler code (because they simultaneously read
7521  * and write data and iw_handler can't do that).
7522  * Note that it's perfectly legal to read/write on a single ioctl command,
7523  * you just can't use iwpriv and need to force it via the ioctl handler.
7524  * Jean II */
7525 static const iw_handler         airo_private_handler[] =
7526 {
7527         NULL,                           /* SIOCIWFIRSTPRIV */
7528 };
7529
7530 static const struct iw_handler_def      airo_handler_def =
7531 {
7532         .num_standard   = ARRAY_SIZE(airo_handler),
7533         .num_private    = ARRAY_SIZE(airo_private_handler),
7534         .num_private_args = ARRAY_SIZE(airo_private_args),
7535         .standard       = airo_handler,
7536         .private        = airo_private_handler,
7537         .private_args   = airo_private_args,
7538         .get_wireless_stats = airo_get_wireless_stats,
7539 };
7540
7541 /*
7542  * This defines the configuration part of the Wireless Extensions
7543  * Note : irq and spinlock protection will occur in the subroutines
7544  *
7545  * TODO :
7546  *      o Check input value more carefully and fill correct values in range
7547  *      o Test and shakeout the bugs (if any)
7548  *
7549  * Jean II
7550  *
7551  * Javier Achirica did a great job of merging code from the unnamed CISCO
7552  * developer that added support for flashing the card.
7553  */
7554 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7555 {
7556         int rc = 0;
7557         struct airo_info *ai = (struct airo_info *)dev->priv;
7558
7559         if (ai->power.event)
7560                 return 0;
7561
7562         switch (cmd) {
7563 #ifdef CISCO_EXT
7564         case AIROIDIFC:
7565 #ifdef AIROOLDIDIFC
7566         case AIROOLDIDIFC:
7567 #endif
7568         {
7569                 int val = AIROMAGIC;
7570                 aironet_ioctl com;
7571                 if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
7572                         rc = -EFAULT;
7573                 else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
7574                         rc = -EFAULT;
7575         }
7576         break;
7577
7578         case AIROIOCTL:
7579 #ifdef AIROOLDIOCTL
7580         case AIROOLDIOCTL:
7581 #endif
7582                 /* Get the command struct and hand it off for evaluation by
7583                  * the proper subfunction
7584                  */
7585         {
7586                 aironet_ioctl com;
7587                 if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
7588                         rc = -EFAULT;
7589                         break;
7590                 }
7591
7592                 /* Separate R/W functions bracket legality here
7593                  */
7594                 if ( com.command == AIRORSWVERSION ) {
7595                         if (copy_to_user(com.data, swversion, sizeof(swversion)))
7596                                 rc = -EFAULT;
7597                         else
7598                                 rc = 0;
7599                 }
7600                 else if ( com.command <= AIRORRID)
7601                         rc = readrids(dev,&com);
7602                 else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
7603                         rc = writerids(dev,&com);
7604                 else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
7605                         rc = flashcard(dev,&com);
7606                 else
7607                         rc = -EINVAL;      /* Bad command in ioctl */
7608         }
7609         break;
7610 #endif /* CISCO_EXT */
7611
7612         // All other calls are currently unsupported
7613         default:
7614                 rc = -EOPNOTSUPP;
7615         }
7616         return rc;
7617 }
7618
7619 /*
7620  * Get the Wireless stats out of the driver
7621  * Note : irq and spinlock protection will occur in the subroutines
7622  *
7623  * TODO :
7624  *      o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7625  *
7626  * Jean
7627  */
7628 static void airo_read_wireless_stats(struct airo_info *local)
7629 {
7630         StatusRid status_rid;
7631         StatsRid stats_rid;
7632         CapabilityRid cap_rid;
7633         __le32 *vals = stats_rid.vals;
7634
7635         /* Get stats out of the card */
7636         clear_bit(JOB_WSTATS, &local->jobs);
7637         if (local->power.event) {
7638                 up(&local->sem);
7639                 return;
7640         }
7641         readCapabilityRid(local, &cap_rid, 0);
7642         readStatusRid(local, &status_rid, 0);
7643         readStatsRid(local, &stats_rid, RID_STATS, 0);
7644         up(&local->sem);
7645
7646         /* The status */
7647         local->wstats.status = le16_to_cpu(status_rid.mode);
7648
7649         /* Signal quality and co */
7650         if (local->rssi) {
7651                 local->wstats.qual.level =
7652                         airo_rssi_to_dbm(local->rssi,
7653                                          le16_to_cpu(status_rid.sigQuality));
7654                 /* normalizedSignalStrength appears to be a percentage */
7655                 local->wstats.qual.qual =
7656                         le16_to_cpu(status_rid.normalizedSignalStrength);
7657         } else {
7658                 local->wstats.qual.level =
7659                         (le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7660                 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7661         }
7662         if (le16_to_cpu(status_rid.len) >= 124) {
7663                 local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7664                 local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7665         } else {
7666                 local->wstats.qual.noise = 0;
7667                 local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
7668         }
7669
7670         /* Packets discarded in the wireless adapter due to wireless
7671          * specific problems */
7672         local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7673                                      le32_to_cpu(vals[57]) +
7674                                      le32_to_cpu(vals[58]); /* SSID Mismatch */
7675         local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7676         local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7677         local->wstats.discard.retries = le32_to_cpu(vals[10]);
7678         local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7679                                      le32_to_cpu(vals[32]);
7680         local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7681 }
7682
7683 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7684 {
7685         struct airo_info *local =  dev->priv;
7686
7687         if (!test_bit(JOB_WSTATS, &local->jobs)) {
7688                 /* Get stats out of the card if available */
7689                 if (down_trylock(&local->sem) != 0) {
7690                         set_bit(JOB_WSTATS, &local->jobs);
7691                         wake_up_interruptible(&local->thr_wait);
7692                 } else
7693                         airo_read_wireless_stats(local);
7694         }
7695
7696         return &local->wstats;
7697 }
7698
7699 #ifdef CISCO_EXT
7700 /*
7701  * This just translates from driver IOCTL codes to the command codes to
7702  * feed to the radio's host interface. Things can be added/deleted
7703  * as needed.  This represents the READ side of control I/O to
7704  * the card
7705  */
7706 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
7707         unsigned short ridcode;
7708         unsigned char *iobuf;
7709         int len;
7710         struct airo_info *ai = dev->priv;
7711
7712         if (test_bit(FLAG_FLASHING, &ai->flags))
7713                 return -EIO;
7714
7715         switch(comp->command)
7716         {
7717         case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7718         case AIROGCFG:      ridcode = RID_CONFIG;
7719                 if (test_bit(FLAG_COMMIT, &ai->flags)) {
7720                         disable_MAC (ai, 1);
7721                         writeConfigRid (ai, 1);
7722                         enable_MAC(ai, 1);
7723                 }
7724                 break;
7725         case AIROGSLIST:    ridcode = RID_SSID;         break;
7726         case AIROGVLIST:    ridcode = RID_APLIST;       break;
7727         case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7728         case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7729         case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
7730                 /* Only super-user can read WEP keys */
7731                 if (!capable(CAP_NET_ADMIN))
7732                         return -EPERM;
7733                 break;
7734         case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
7735                 /* Only super-user can read WEP keys */
7736                 if (!capable(CAP_NET_ADMIN))
7737                         return -EPERM;
7738                 break;
7739         case AIROGSTAT:     ridcode = RID_STATUS;       break;
7740         case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7741         case AIROGSTATSC32: ridcode = RID_STATS;        break;
7742         case AIROGMICSTATS:
7743                 if (copy_to_user(comp->data, &ai->micstats,
7744                                  min((int)comp->len,(int)sizeof(ai->micstats))))
7745                         return -EFAULT;
7746                 return 0;
7747         case AIRORRID:      ridcode = comp->ridnum;     break;
7748         default:
7749                 return -EINVAL;
7750                 break;
7751         }
7752
7753         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7754                 return -ENOMEM;
7755
7756         PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
7757         /* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7758          * then return it to the user
7759          * 9/22/2000 Honor user given length
7760          */
7761         len = comp->len;
7762
7763         if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7764                 kfree (iobuf);
7765                 return -EFAULT;
7766         }
7767         kfree (iobuf);
7768         return 0;
7769 }
7770
7771 /*
7772  * Danger Will Robinson write the rids here
7773  */
7774
7775 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7776         struct airo_info *ai = dev->priv;
7777         int  ridcode;
7778         int  enabled;
7779         static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
7780         unsigned char *iobuf;
7781
7782         /* Only super-user can write RIDs */
7783         if (!capable(CAP_NET_ADMIN))
7784                 return -EPERM;
7785
7786         if (test_bit(FLAG_FLASHING, &ai->flags))
7787                 return -EIO;
7788
7789         ridcode = 0;
7790         writer = do_writerid;
7791
7792         switch(comp->command)
7793         {
7794         case AIROPSIDS:     ridcode = RID_SSID;         break;
7795         case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7796         case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7797         case AIROPCFG: ai->config.len = 0;
7798                             clear_bit(FLAG_COMMIT, &ai->flags);
7799                             ridcode = RID_CONFIG;       break;
7800         case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7801         case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7802         case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7803         case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7804                 break;
7805         case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7806         case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7807
7808                 /* this is not really a rid but a command given to the card
7809                  * same with MAC off
7810                  */
7811         case AIROPMACON:
7812                 if (enable_MAC(ai, 1) != 0)
7813                         return -EIO;
7814                 return 0;
7815
7816                 /*
7817                  * Evidently this code in the airo driver does not get a symbol
7818                  * as disable_MAC. it's probably so short the compiler does not gen one.
7819                  */
7820         case AIROPMACOFF:
7821                 disable_MAC(ai, 1);
7822                 return 0;
7823
7824                 /* This command merely clears the counts does not actually store any data
7825                  * only reads rid. But as it changes the cards state, I put it in the
7826                  * writerid routines.
7827                  */
7828         case AIROPSTCLR:
7829                 if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7830                         return -ENOMEM;
7831
7832                 PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
7833
7834                 enabled = ai->micstats.enabled;
7835                 memset(&ai->micstats,0,sizeof(ai->micstats));
7836                 ai->micstats.enabled = enabled;
7837
7838                 if (copy_to_user(comp->data, iobuf,
7839                                  min((int)comp->len, (int)RIDSIZE))) {
7840                         kfree (iobuf);
7841                         return -EFAULT;
7842                 }
7843                 kfree (iobuf);
7844                 return 0;
7845
7846         default:
7847                 return -EOPNOTSUPP;     /* Blarg! */
7848         }
7849         if(comp->len > RIDSIZE)
7850                 return -EINVAL;
7851
7852         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7853                 return -ENOMEM;
7854
7855         if (copy_from_user(iobuf,comp->data,comp->len)) {
7856                 kfree (iobuf);
7857                 return -EFAULT;
7858         }
7859
7860         if (comp->command == AIROPCFG) {
7861                 ConfigRid *cfg = (ConfigRid *)iobuf;
7862
7863                 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7864                         cfg->opmode |= cpu_to_le16(MODE_MIC);
7865
7866                 if ((le16_to_cpu(cfg->opmode) & 0xFF) == MODE_STA_IBSS)
7867                         set_bit (FLAG_ADHOC, &ai->flags);
7868                 else
7869                         clear_bit (FLAG_ADHOC, &ai->flags);
7870         }
7871
7872         if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
7873                 kfree (iobuf);
7874                 return -EIO;
7875         }
7876         kfree (iobuf);
7877         return 0;
7878 }
7879
7880 /*****************************************************************************
7881  * Ancillary flash / mod functions much black magic lurkes here              *
7882  *****************************************************************************
7883  */
7884
7885 /*
7886  * Flash command switch table
7887  */
7888
7889 static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7890         int z;
7891
7892         /* Only super-user can modify flash */
7893         if (!capable(CAP_NET_ADMIN))
7894                 return -EPERM;
7895
7896         switch(comp->command)
7897         {
7898         case AIROFLSHRST:
7899                 return cmdreset((struct airo_info *)dev->priv);
7900
7901         case AIROFLSHSTFL:
7902                 if (!((struct airo_info *)dev->priv)->flash &&
7903                         (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
7904                         return -ENOMEM;
7905                 return setflashmode((struct airo_info *)dev->priv);
7906
7907         case AIROFLSHGCHR: /* Get char from aux */
7908                 if(comp->len != sizeof(int))
7909                         return -EINVAL;
7910                 if (copy_from_user(&z,comp->data,comp->len))
7911                         return -EFAULT;
7912                 return flashgchar((struct airo_info *)dev->priv,z,8000);
7913
7914         case AIROFLSHPCHR: /* Send char to card. */
7915                 if(comp->len != sizeof(int))
7916                         return -EINVAL;
7917                 if (copy_from_user(&z,comp->data,comp->len))
7918                         return -EFAULT;
7919                 return flashpchar((struct airo_info *)dev->priv,z,8000);
7920
7921         case AIROFLPUTBUF: /* Send 32k to card */
7922                 if (!((struct airo_info *)dev->priv)->flash)
7923                         return -ENOMEM;
7924                 if(comp->len > FLASHSIZE)
7925                         return -EINVAL;
7926                 if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
7927                         return -EFAULT;
7928
7929                 flashputbuf((struct airo_info *)dev->priv);
7930                 return 0;
7931
7932         case AIRORESTART:
7933                 if(flashrestart((struct airo_info *)dev->priv,dev))
7934                         return -EIO;
7935                 return 0;
7936         }
7937         return -EINVAL;
7938 }
7939
7940 #define FLASH_COMMAND  0x7e7e
7941
7942 /*
7943  * STEP 1)
7944  * Disable MAC and do soft reset on
7945  * card.
7946  */
7947
7948 static int cmdreset(struct airo_info *ai) {
7949         disable_MAC(ai, 1);
7950
7951         if(!waitbusy (ai)){
7952                 airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
7953                 return -EBUSY;
7954         }
7955
7956         OUT4500(ai,COMMAND,CMD_SOFTRESET);
7957
7958         ssleep(1);                      /* WAS 600 12/7/00 */
7959
7960         if(!waitbusy (ai)){
7961                 airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
7962                 return -EBUSY;
7963         }
7964         return 0;
7965 }
7966
7967 /* STEP 2)
7968  * Put the card in legendary flash
7969  * mode
7970  */
7971
7972 static int setflashmode (struct airo_info *ai) {
7973         set_bit (FLAG_FLASHING, &ai->flags);
7974
7975         OUT4500(ai, SWS0, FLASH_COMMAND);
7976         OUT4500(ai, SWS1, FLASH_COMMAND);
7977         if (probe) {
7978                 OUT4500(ai, SWS0, FLASH_COMMAND);
7979                 OUT4500(ai, COMMAND,0x10);
7980         } else {
7981                 OUT4500(ai, SWS2, FLASH_COMMAND);
7982                 OUT4500(ai, SWS3, FLASH_COMMAND);
7983                 OUT4500(ai, COMMAND,0);
7984         }
7985         msleep(500);            /* 500ms delay */
7986
7987         if(!waitbusy(ai)) {
7988                 clear_bit (FLAG_FLASHING, &ai->flags);
7989                 airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
7990                 return -EIO;
7991         }
7992         return 0;
7993 }
7994
7995 /* Put character to SWS0 wait for dwelltime
7996  * x 50us for  echo .
7997  */
7998
7999 static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
8000         int echo;
8001         int waittime;
8002
8003         byte |= 0x8000;
8004
8005         if(dwelltime == 0 )
8006                 dwelltime = 200;
8007
8008         waittime=dwelltime;
8009
8010         /* Wait for busy bit d15 to go false indicating buffer empty */
8011         while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
8012                 udelay (50);
8013                 waittime -= 50;
8014         }
8015
8016         /* timeout for busy clear wait */
8017         if(waittime <= 0 ){
8018                 airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
8019                 return -EBUSY;
8020         }
8021
8022         /* Port is clear now write byte and wait for it to echo back */
8023         do {
8024                 OUT4500(ai,SWS0,byte);
8025                 udelay(50);
8026                 dwelltime -= 50;
8027                 echo = IN4500(ai,SWS1);
8028         } while (dwelltime >= 0 && echo != byte);
8029
8030         OUT4500(ai,SWS1,0);
8031
8032         return (echo == byte) ? 0 : -EIO;
8033 }
8034
8035 /*
8036  * Get a character from the card matching matchbyte
8037  * Step 3)
8038  */
8039 static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
8040         int           rchar;
8041         unsigned char rbyte=0;
8042
8043         do {
8044                 rchar = IN4500(ai,SWS1);
8045
8046                 if(dwelltime && !(0x8000 & rchar)){
8047                         dwelltime -= 10;
8048                         mdelay(10);
8049                         continue;
8050                 }
8051                 rbyte = 0xff & rchar;
8052
8053                 if( (rbyte == matchbyte) && (0x8000 & rchar) ){
8054                         OUT4500(ai,SWS1,0);
8055                         return 0;
8056                 }
8057                 if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
8058                         break;
8059                 OUT4500(ai,SWS1,0);
8060
8061         }while(dwelltime > 0);
8062         return -EIO;
8063 }
8064
8065 /*
8066  * Transfer 32k of firmware data from user buffer to our buffer and
8067  * send to the card
8068  */
8069
8070 static int flashputbuf(struct airo_info *ai){
8071         int            nwords;
8072
8073         /* Write stuff */
8074         if (test_bit(FLAG_MPI,&ai->flags))
8075                 memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
8076         else {
8077                 OUT4500(ai,AUXPAGE,0x100);
8078                 OUT4500(ai,AUXOFF,0);
8079
8080                 for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
8081                         OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
8082                 }
8083         }
8084         OUT4500(ai,SWS0,0x8000);
8085
8086         return 0;
8087 }
8088
8089 /*
8090  *
8091  */
8092 static int flashrestart(struct airo_info *ai,struct net_device *dev){
8093         int    i,status;
8094
8095         ssleep(1);                      /* Added 12/7/00 */
8096         clear_bit (FLAG_FLASHING, &ai->flags);
8097         if (test_bit(FLAG_MPI, &ai->flags)) {
8098                 status = mpi_init_descriptors(ai);
8099                 if (status != SUCCESS)
8100                         return status;
8101         }
8102         status = setup_card(ai, dev->dev_addr, 1);
8103
8104         if (!test_bit(FLAG_MPI,&ai->flags))
8105                 for( i = 0; i < MAX_FIDS; i++ ) {
8106                         ai->fids[i] = transmit_allocate
8107                                 ( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
8108                 }
8109
8110         ssleep(1);                      /* Added 12/7/00 */
8111         return status;
8112 }
8113 #endif /* CISCO_EXT */
8114
8115 /*
8116     This program is free software; you can redistribute it and/or
8117     modify it under the terms of the GNU General Public License
8118     as published by the Free Software Foundation; either version 2
8119     of the License, or (at your option) any later version.
8120
8121     This program is distributed in the hope that it will be useful,
8122     but WITHOUT ANY WARRANTY; without even the implied warranty of
8123     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8124     GNU General Public License for more details.
8125
8126     In addition:
8127
8128     Redistribution and use in source and binary forms, with or without
8129     modification, are permitted provided that the following conditions
8130     are met:
8131
8132     1. Redistributions of source code must retain the above copyright
8133        notice, this list of conditions and the following disclaimer.
8134     2. Redistributions in binary form must reproduce the above copyright
8135        notice, this list of conditions and the following disclaimer in the
8136        documentation and/or other materials provided with the distribution.
8137     3. The name of the author may not be used to endorse or promote
8138        products derived from this software without specific prior written
8139        permission.
8140
8141     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8142     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8143     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8144     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
8145     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8146     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8147     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8148     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8149     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
8150     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8151     POSSIBILITY OF SUCH DAMAGE.
8152 */
8153
8154 module_init(airo_init_module);
8155 module_exit(airo_cleanup_module);