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