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