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