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