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