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