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