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