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