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