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