]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/wireless/airo.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / airo.c
1 /*======================================================================
2
3     Aironet driver for 4500 and 4800 series cards
4
5     This code is released under both the GPL version 2 and BSD licenses.
6     Either license may be used.  The respective licenses are found at
7     the end of this file.
8
9     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10     including portions of which come from the Aironet PC4500
11     Developer's Reference Manual and used with permission.  Copyright
12     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
13     code in the Developer's manual was granted for this driver by
14     Aironet.  Major code contributions were received from Javier Achirica
15     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
16     Code was also integrated from the Cisco Aironet driver for Linux.
17     Support for MPI350 cards was added by Fabrice Bellet
18     <fabrice@bellet.info>.
19
20 ======================================================================*/
21
22 #include <linux/err.h>
23 #include <linux/init.h>
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/proc_fs.h>
28
29 #include <linux/sched.h>
30 #include <linux/ptrace.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/timer.h>
34 #include <linux/interrupt.h>
35 #include <linux/in.h>
36 #include <linux/bitops.h>
37 #include <linux/scatterlist.h>
38 #include <linux/crypto.h>
39 #include <asm/io.h>
40 #include <asm/system.h>
41 #include <asm/unaligned.h>
42
43 #include <linux/netdevice.h>
44 #include <linux/etherdevice.h>
45 #include <linux/skbuff.h>
46 #include <linux/if_arp.h>
47 #include <linux/ioport.h>
48 #include <linux/pci.h>
49 #include <asm/uaccess.h>
50 #include <net/ieee80211.h>
51 #include <linux/kthread.h>
52 #include <linux/freezer.h>
53
54 #include "airo.h"
55
56 #define DRV_NAME "airo"
57
58 #ifdef CONFIG_PCI
59 static struct pci_device_id card_ids[] = {
60         { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
61         { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
62         { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
63         { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
64         { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
65         { 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
66         { 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
67         { 0, }
68 };
69 MODULE_DEVICE_TABLE(pci, card_ids);
70
71 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
72 static void airo_pci_remove(struct pci_dev *);
73 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
74 static int airo_pci_resume(struct pci_dev *pdev);
75
76 static struct pci_driver airo_driver = {
77         .name     = DRV_NAME,
78         .id_table = card_ids,
79         .probe    = airo_pci_probe,
80         .remove   = __devexit_p(airo_pci_remove),
81         .suspend  = airo_pci_suspend,
82         .resume   = airo_pci_resume,
83 };
84 #endif /* CONFIG_PCI */
85
86 /* Include Wireless Extension definition and check version - Jean II */
87 #include <linux/wireless.h>
88 #define WIRELESS_SPY            // enable iwspy support
89 #include <net/iw_handler.h>     // New driver API
90
91 #define CISCO_EXT               // enable Cisco extensions
92 #ifdef CISCO_EXT
93 #include <linux/delay.h>
94 #endif
95
96 /* Hack to do some power saving */
97 #define POWER_ON_DOWN
98
99 /* As you can see this list is HUGH!
100    I really don't know what a lot of these counts are about, but they
101    are all here for completeness.  If the IGNLABEL macro is put in
102    infront of the label, that statistic will not be included in the list
103    of statistics in the /proc filesystem */
104
105 #define IGNLABEL(comment) NULL
106 static char *statsLabels[] = {
107         "RxOverrun",
108         IGNLABEL("RxPlcpCrcErr"),
109         IGNLABEL("RxPlcpFormatErr"),
110         IGNLABEL("RxPlcpLengthErr"),
111         "RxMacCrcErr",
112         "RxMacCrcOk",
113         "RxWepErr",
114         "RxWepOk",
115         "RetryLong",
116         "RetryShort",
117         "MaxRetries",
118         "NoAck",
119         "NoCts",
120         "RxAck",
121         "RxCts",
122         "TxAck",
123         "TxRts",
124         "TxCts",
125         "TxMc",
126         "TxBc",
127         "TxUcFrags",
128         "TxUcPackets",
129         "TxBeacon",
130         "RxBeacon",
131         "TxSinColl",
132         "TxMulColl",
133         "DefersNo",
134         "DefersProt",
135         "DefersEngy",
136         "DupFram",
137         "RxFragDisc",
138         "TxAged",
139         "RxAged",
140         "LostSync-MaxRetry",
141         "LostSync-MissedBeacons",
142         "LostSync-ArlExceeded",
143         "LostSync-Deauth",
144         "LostSync-Disassoced",
145         "LostSync-TsfTiming",
146         "HostTxMc",
147         "HostTxBc",
148         "HostTxUc",
149         "HostTxFail",
150         "HostRxMc",
151         "HostRxBc",
152         "HostRxUc",
153         "HostRxDiscard",
154         IGNLABEL("HmacTxMc"),
155         IGNLABEL("HmacTxBc"),
156         IGNLABEL("HmacTxUc"),
157         IGNLABEL("HmacTxFail"),
158         IGNLABEL("HmacRxMc"),
159         IGNLABEL("HmacRxBc"),
160         IGNLABEL("HmacRxUc"),
161         IGNLABEL("HmacRxDiscard"),
162         IGNLABEL("HmacRxAccepted"),
163         "SsidMismatch",
164         "ApMismatch",
165         "RatesMismatch",
166         "AuthReject",
167         "AuthTimeout",
168         "AssocReject",
169         "AssocTimeout",
170         IGNLABEL("ReasonOutsideTable"),
171         IGNLABEL("ReasonStatus1"),
172         IGNLABEL("ReasonStatus2"),
173         IGNLABEL("ReasonStatus3"),
174         IGNLABEL("ReasonStatus4"),
175         IGNLABEL("ReasonStatus5"),
176         IGNLABEL("ReasonStatus6"),
177         IGNLABEL("ReasonStatus7"),
178         IGNLABEL("ReasonStatus8"),
179         IGNLABEL("ReasonStatus9"),
180         IGNLABEL("ReasonStatus10"),
181         IGNLABEL("ReasonStatus11"),
182         IGNLABEL("ReasonStatus12"),
183         IGNLABEL("ReasonStatus13"),
184         IGNLABEL("ReasonStatus14"),
185         IGNLABEL("ReasonStatus15"),
186         IGNLABEL("ReasonStatus16"),
187         IGNLABEL("ReasonStatus17"),
188         IGNLABEL("ReasonStatus18"),
189         IGNLABEL("ReasonStatus19"),
190         "RxMan",
191         "TxMan",
192         "RxRefresh",
193         "TxRefresh",
194         "RxPoll",
195         "TxPoll",
196         "HostRetries",
197         "LostSync-HostReq",
198         "HostTxBytes",
199         "HostRxBytes",
200         "ElapsedUsec",
201         "ElapsedSec",
202         "LostSyncBetterAP",
203         "PrivacyMismatch",
204         "Jammed",
205         "DiscRxNotWepped",
206         "PhyEleMismatch",
207         (char*)-1 };
208 #ifndef RUN_AT
209 #define RUN_AT(x) (jiffies+(x))
210 #endif
211
212
213 /* These variables are for insmod, since it seems that the rates
214    can only be set in setup_card.  Rates should be a comma separated
215    (no spaces) list of rates (up to 8). */
216
217 static int rates[8];
218 static int basic_rate;
219 static char *ssids[3];
220
221 static int io[4];
222 static int irq[4];
223
224 static
225 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
226                        0 means no limit.  For old cards this was 4 */
227
228 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
229 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
230                     the bap, needed on some older cards and buses. */
231 static int adhoc;
232
233 static int probe = 1;
234
235 static int proc_uid /* = 0 */;
236
237 static int proc_gid /* = 0 */;
238
239 static int airo_perm = 0555;
240
241 static int proc_perm = 0644;
242
243 MODULE_AUTHOR("Benjamin Reed");
244 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
245 cards.  Direct support for ISA/PCI/MPI cards and support \
246 for PCMCIA when used with airo_cs.");
247 MODULE_LICENSE("Dual BSD/GPL");
248 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
249 module_param_array(io, int, NULL, 0);
250 module_param_array(irq, int, NULL, 0);
251 module_param(basic_rate, int, 0);
252 module_param_array(rates, int, NULL, 0);
253 module_param_array(ssids, charp, NULL, 0);
254 module_param(auto_wep, int, 0);
255 MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
256 the authentication options until an association is made.  The value of \
257 auto_wep is number of the wep keys to check.  A value of 2 will try using \
258 the key at index 0 and index 1.");
259 module_param(aux_bap, int, 0);
260 MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
261 than seems to work better for older cards with some older buses.  Before \
262 switching it checks that the switch is needed.");
263 module_param(maxencrypt, int, 0);
264 MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
265 encryption.  Units are in 512kbs.  Zero (default) means there is no limit. \
266 Older cards used to be limited to 2mbs (4).");
267 module_param(adhoc, int, 0);
268 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
269 module_param(probe, int, 0);
270 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
271
272 module_param(proc_uid, int, 0);
273 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
274 module_param(proc_gid, int, 0);
275 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
276 module_param(airo_perm, int, 0);
277 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
278 module_param(proc_perm, int, 0);
279 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
280
281 /* This is a kind of sloppy hack to get this information to OUT4500 and
282    IN4500.  I would be extremely interested in the situation where this
283    doesn't work though!!! */
284 static int do8bitIO = 0;
285
286 /* Return codes */
287 #define SUCCESS 0
288 #define ERROR -1
289 #define NO_PACKET -2
290
291 /* Commands */
292 #define NOP2            0x0000
293 #define MAC_ENABLE      0x0001
294 #define MAC_DISABLE     0x0002
295 #define CMD_LOSE_SYNC   0x0003 /* Not sure what this does... */
296 #define CMD_SOFTRESET   0x0004
297 #define HOSTSLEEP       0x0005
298 #define CMD_MAGIC_PKT   0x0006
299 #define CMD_SETWAKEMASK 0x0007
300 #define CMD_READCFG     0x0008
301 #define CMD_SETMODE     0x0009
302 #define CMD_ALLOCATETX  0x000a
303 #define CMD_TRANSMIT    0x000b
304 #define CMD_DEALLOCATETX 0x000c
305 #define NOP             0x0010
306 #define CMD_WORKAROUND  0x0011
307 #define CMD_ALLOCATEAUX 0x0020
308 #define CMD_ACCESS      0x0021
309 #define CMD_PCIBAP      0x0022
310 #define CMD_PCIAUX      0x0023
311 #define CMD_ALLOCBUF    0x0028
312 #define CMD_GETTLV      0x0029
313 #define CMD_PUTTLV      0x002a
314 #define CMD_DELTLV      0x002b
315 #define CMD_FINDNEXTTLV 0x002c
316 #define CMD_PSPNODES    0x0030
317 #define CMD_SETCW       0x0031    
318 #define CMD_SETPCF      0x0032    
319 #define CMD_SETPHYREG   0x003e
320 #define CMD_TXTEST      0x003f
321 #define MAC_ENABLETX    0x0101
322 #define CMD_LISTBSS     0x0103
323 #define CMD_SAVECFG     0x0108
324 #define CMD_ENABLEAUX   0x0111
325 #define CMD_WRITERID    0x0121
326 #define CMD_USEPSPNODES 0x0130
327 #define MAC_ENABLERX    0x0201
328
329 /* Command errors */
330 #define ERROR_QUALIF 0x00
331 #define ERROR_ILLCMD 0x01
332 #define ERROR_ILLFMT 0x02
333 #define ERROR_INVFID 0x03
334 #define ERROR_INVRID 0x04
335 #define ERROR_LARGE 0x05
336 #define ERROR_NDISABL 0x06
337 #define ERROR_ALLOCBSY 0x07
338 #define ERROR_NORD 0x0B
339 #define ERROR_NOWR 0x0C
340 #define ERROR_INVFIDTX 0x0D
341 #define ERROR_TESTACT 0x0E
342 #define ERROR_TAGNFND 0x12
343 #define ERROR_DECODE 0x20
344 #define ERROR_DESCUNAV 0x21
345 #define ERROR_BADLEN 0x22
346 #define ERROR_MODE 0x80
347 #define ERROR_HOP 0x81
348 #define ERROR_BINTER 0x82
349 #define ERROR_RXMODE 0x83
350 #define ERROR_MACADDR 0x84
351 #define ERROR_RATES 0x85
352 #define ERROR_ORDER 0x86
353 #define ERROR_SCAN 0x87
354 #define ERROR_AUTH 0x88
355 #define ERROR_PSMODE 0x89
356 #define ERROR_RTYPE 0x8A
357 #define ERROR_DIVER 0x8B
358 #define ERROR_SSID 0x8C
359 #define ERROR_APLIST 0x8D
360 #define ERROR_AUTOWAKE 0x8E
361 #define ERROR_LEAP 0x8F
362
363 /* Registers */
364 #define COMMAND 0x00
365 #define PARAM0 0x02
366 #define PARAM1 0x04
367 #define PARAM2 0x06
368 #define STATUS 0x08
369 #define RESP0 0x0a
370 #define RESP1 0x0c
371 #define RESP2 0x0e
372 #define LINKSTAT 0x10
373 #define SELECT0 0x18
374 #define OFFSET0 0x1c
375 #define RXFID 0x20
376 #define TXALLOCFID 0x22
377 #define TXCOMPLFID 0x24
378 #define DATA0 0x36
379 #define EVSTAT 0x30
380 #define EVINTEN 0x32
381 #define EVACK 0x34
382 #define SWS0 0x28
383 #define SWS1 0x2a
384 #define SWS2 0x2c
385 #define SWS3 0x2e
386 #define AUXPAGE 0x3A
387 #define AUXOFF 0x3C
388 #define AUXDATA 0x3E
389
390 #define FID_TX 1
391 #define FID_RX 2
392 /* Offset into aux memory for descriptors */
393 #define AUX_OFFSET 0x800
394 /* Size of allocated packets */
395 #define PKTSIZE 1840
396 #define RIDSIZE 2048
397 /* Size of the transmit queue */
398 #define MAXTXQ 64
399
400 /* BAP selectors */
401 #define BAP0 0 // Used for receiving packets
402 #define BAP1 2 // Used for xmiting packets and working with RIDS
403
404 /* Flags */
405 #define COMMAND_BUSY 0x8000
406
407 #define BAP_BUSY 0x8000
408 #define BAP_ERR 0x4000
409 #define BAP_DONE 0x2000
410
411 #define PROMISC 0xffff
412 #define NOPROMISC 0x0000
413
414 #define EV_CMD 0x10
415 #define EV_CLEARCOMMANDBUSY 0x4000
416 #define EV_RX 0x01
417 #define EV_TX 0x02
418 #define EV_TXEXC 0x04
419 #define EV_ALLOC 0x08
420 #define EV_LINK 0x80
421 #define EV_AWAKE 0x100
422 #define EV_TXCPY 0x400
423 #define EV_UNKNOWN 0x800
424 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
425 #define EV_AWAKEN 0x2000
426 #define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
427
428 #ifdef CHECK_UNKNOWN_INTS
429 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
430 #else
431 #define IGNORE_INTS (~STATUS_INTS)
432 #endif
433
434 /* RID TYPES */
435 #define RID_RW 0x20
436
437 /* The RIDs */
438 #define RID_CAPABILITIES 0xFF00
439 #define RID_APINFO     0xFF01
440 #define RID_RADIOINFO  0xFF02
441 #define RID_UNKNOWN3   0xFF03
442 #define RID_RSSI       0xFF04
443 #define RID_CONFIG     0xFF10
444 #define RID_SSID       0xFF11
445 #define RID_APLIST     0xFF12
446 #define RID_DRVNAME    0xFF13
447 #define RID_ETHERENCAP 0xFF14
448 #define RID_WEP_TEMP   0xFF15
449 #define RID_WEP_PERM   0xFF16
450 #define RID_MODULATION 0xFF17
451 #define RID_OPTIONS    0xFF18
452 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
453 #define RID_FACTORYCONFIG 0xFF21
454 #define RID_UNKNOWN22  0xFF22
455 #define RID_LEAPUSERNAME 0xFF23
456 #define RID_LEAPPASSWORD 0xFF24
457 #define RID_STATUS     0xFF50
458 #define RID_BEACON_HST 0xFF51
459 #define RID_BUSY_HST   0xFF52
460 #define RID_RETRIES_HST 0xFF53
461 #define RID_UNKNOWN54  0xFF54
462 #define RID_UNKNOWN55  0xFF55
463 #define RID_UNKNOWN56  0xFF56
464 #define RID_MIC        0xFF57
465 #define RID_STATS16    0xFF60
466 #define RID_STATS16DELTA 0xFF61
467 #define RID_STATS16DELTACLEAR 0xFF62
468 #define RID_STATS      0xFF68
469 #define RID_STATSDELTA 0xFF69
470 #define RID_STATSDELTACLEAR 0xFF6A
471 #define RID_ECHOTEST_RID 0xFF70
472 #define RID_ECHOTEST_RESULTS 0xFF71
473 #define RID_BSSLISTFIRST 0xFF72
474 #define RID_BSSLISTNEXT  0xFF73
475 #define RID_WPA_BSSLISTFIRST 0xFF74
476 #define RID_WPA_BSSLISTNEXT  0xFF75
477
478 typedef struct {
479         u16 cmd;
480         u16 parm0;
481         u16 parm1;
482         u16 parm2;
483 } Cmd;
484
485 typedef struct {
486         u16 status;
487         u16 rsp0;
488         u16 rsp1;
489         u16 rsp2;
490 } Resp;
491
492 /*
493  * Rids and endian-ness:  The Rids will always be in cpu endian, since
494  * this all the patches from the big-endian guys end up doing that.
495  * so all rid access should use the read/writeXXXRid routines.
496  */
497
498 /* This is redundant for x86 archs, but it seems necessary for ARM */
499 #pragma pack(1)
500
501 /* This structure came from an email sent to me from an engineer at
502    aironet for inclusion into this driver */
503 typedef struct {
504         __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         loff_t pos = *offset;
4565         struct proc_data *priv = (struct proc_data*)file->private_data;
4566
4567         if (!priv->rbuffer)
4568                 return -EINVAL;
4569
4570         if (pos < 0)
4571                 return -EINVAL;
4572         if (pos >= priv->readlen)
4573                 return 0;
4574         if (len > priv->readlen - pos)
4575                 len = priv->readlen - pos;
4576         if (copy_to_user(buffer, priv->rbuffer + pos, len))
4577                 return -EFAULT;
4578         *offset = pos + len;
4579         return len;
4580 }
4581
4582 /*
4583  *  The write routine is generic, it fills in a preallocated rbuffer
4584  *  to supply the data.
4585  */
4586 static ssize_t proc_write( struct file *file,
4587                            const char __user *buffer,
4588                            size_t len,
4589                            loff_t *offset )
4590 {
4591         loff_t pos = *offset;
4592         struct proc_data *priv = (struct proc_data*)file->private_data;
4593
4594         if (!priv->wbuffer)
4595                 return -EINVAL;
4596
4597         if (pos < 0)
4598                 return -EINVAL;
4599         if (pos >= priv->maxwritelen)
4600                 return 0;
4601         if (len > priv->maxwritelen - pos)
4602                 len = priv->maxwritelen - pos;
4603         if (copy_from_user(priv->wbuffer + pos, buffer, len))
4604                 return -EFAULT;
4605         if ( pos + len > priv->writelen )
4606                 priv->writelen = len + file->f_pos;
4607         *offset = pos + len;
4608         return len;
4609 }
4610
4611 static int proc_status_open(struct inode *inode, struct file *file)
4612 {
4613         struct proc_data *data;
4614         struct proc_dir_entry *dp = PDE(inode);
4615         struct net_device *dev = dp->data;
4616         struct airo_info *apriv = dev->priv;
4617         CapabilityRid cap_rid;
4618         StatusRid status_rid;
4619         u16 mode;
4620         int i;
4621
4622         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4623                 return -ENOMEM;
4624         data = (struct proc_data *)file->private_data;
4625         if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4626                 kfree (file->private_data);
4627                 return -ENOMEM;
4628         }
4629
4630         readStatusRid(apriv, &status_rid, 1);
4631         readCapabilityRid(apriv, &cap_rid, 1);
4632
4633         mode = le16_to_cpu(status_rid.mode);
4634
4635         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4636                     mode & 1 ? "CFG ": "",
4637                     mode & 2 ? "ACT ": "",
4638                     mode & 0x10 ? "SYN ": "",
4639                     mode & 0x20 ? "LNK ": "",
4640                     mode & 0x40 ? "LEAP ": "",
4641                     mode & 0x80 ? "PRIV ": "",
4642                     mode & 0x100 ? "KEY ": "",
4643                     mode & 0x200 ? "WEP ": "",
4644                     mode & 0x8000 ? "ERR ": "");
4645         sprintf( data->rbuffer+i, "Mode: %x\n"
4646                  "Signal Strength: %d\n"
4647                  "Signal Quality: %d\n"
4648                  "SSID: %-.*s\n"
4649                  "AP: %-.16s\n"
4650                  "Freq: %d\n"
4651                  "BitRate: %dmbs\n"
4652                  "Driver Version: %s\n"
4653                  "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4654                  "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4655                  "Software Version: %x\nSoftware Subversion: %x\n"
4656                  "Boot block version: %x\n",
4657                  le16_to_cpu(status_rid.mode),
4658                  le16_to_cpu(status_rid.normalizedSignalStrength),
4659                  le16_to_cpu(status_rid.signalQuality),
4660                  le16_to_cpu(status_rid.SSIDlen),
4661                  status_rid.SSID,
4662                  status_rid.apName,
4663                  le16_to_cpu(status_rid.channel),
4664                  le16_to_cpu(status_rid.currentXmitRate) / 2,
4665                  version,
4666                  cap_rid.prodName,
4667                  cap_rid.manName,
4668                  cap_rid.prodVer,
4669                  le16_to_cpu(cap_rid.radioType),
4670                  le16_to_cpu(cap_rid.country),
4671                  le16_to_cpu(cap_rid.hardVer),
4672                  le16_to_cpu(cap_rid.softVer),
4673                  le16_to_cpu(cap_rid.softSubVer),
4674                  le16_to_cpu(cap_rid.bootBlockVer));
4675         data->readlen = strlen( data->rbuffer );
4676         return 0;
4677 }
4678
4679 static int proc_stats_rid_open(struct inode*, struct file*, u16);
4680 static int proc_statsdelta_open( struct inode *inode,
4681                                  struct file *file ) {
4682         if (file->f_mode&FMODE_WRITE) {
4683                 return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4684         }
4685         return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4686 }
4687
4688 static int proc_stats_open( struct inode *inode, struct file *file ) {
4689         return proc_stats_rid_open(inode, file, RID_STATS);
4690 }
4691
4692 static int proc_stats_rid_open( struct inode *inode,
4693                                 struct file *file,
4694                                 u16 rid )
4695 {
4696         struct proc_data *data;
4697         struct proc_dir_entry *dp = PDE(inode);
4698         struct net_device *dev = dp->data;
4699         struct airo_info *apriv = dev->priv;
4700         StatsRid stats;
4701         int i, j;
4702         __le32 *vals = stats.vals;
4703         int len = le16_to_cpu(stats.len);
4704
4705         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4706                 return -ENOMEM;
4707         data = (struct proc_data *)file->private_data;
4708         if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4709                 kfree (file->private_data);
4710                 return -ENOMEM;
4711         }
4712
4713         readStatsRid(apriv, &stats, rid, 1);
4714
4715         j = 0;
4716         for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4717                 if (!statsLabels[i]) continue;
4718                 if (j+strlen(statsLabels[i])+16>4096) {
4719                         airo_print_warn(apriv->dev->name,
4720                                "Potentially disasterous buffer overflow averted!");
4721                         break;
4722                 }
4723                 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4724                                 le32_to_cpu(vals[i]));
4725         }
4726         if (i*4 >= len) {
4727                 airo_print_warn(apriv->dev->name, "Got a short rid");
4728         }
4729         data->readlen = j;
4730         return 0;
4731 }
4732
4733 static int get_dec_u16( char *buffer, int *start, int limit ) {
4734         u16 value;
4735         int valid = 0;
4736         for( value = 0; buffer[*start] >= '0' &&
4737                      buffer[*start] <= '9' &&
4738                      *start < limit; (*start)++ ) {
4739                 valid = 1;
4740                 value *= 10;
4741                 value += buffer[*start] - '0';
4742         }
4743         if ( !valid ) return -1;
4744         return value;
4745 }
4746
4747 static int airo_config_commit(struct net_device *dev,
4748                               struct iw_request_info *info, void *zwrq,
4749                               char *extra);
4750
4751 static inline int sniffing_mode(struct airo_info *ai)
4752 {
4753         return le16_to_cpu(ai->config.rmode & RXMODE_MASK) >=
4754                 le16_to_cpu(RXMODE_RFMON);
4755 }
4756
4757 static void proc_config_on_close(struct inode *inode, struct file *file)
4758 {
4759         struct proc_data *data = file->private_data;
4760         struct proc_dir_entry *dp = PDE(inode);
4761         struct net_device *dev = dp->data;
4762         struct airo_info *ai = dev->priv;
4763         char *line;
4764
4765         if ( !data->writelen ) return;
4766
4767         readConfigRid(ai, 1);
4768         set_bit (FLAG_COMMIT, &ai->flags);
4769
4770         line = data->wbuffer;
4771         while( line[0] ) {
4772 /*** Mode processing */
4773                 if ( !strncmp( line, "Mode: ", 6 ) ) {
4774                         line += 6;
4775                         if (sniffing_mode(ai))
4776                                 set_bit (FLAG_RESET, &ai->flags);
4777                         ai->config.rmode &= ~RXMODE_FULL_MASK;
4778                         clear_bit (FLAG_802_11, &ai->flags);
4779                         ai->config.opmode &= ~MODE_CFG_MASK;
4780                         ai->config.scanMode = SCANMODE_ACTIVE;
4781                         if ( line[0] == 'a' ) {
4782                                 ai->config.opmode |= MODE_STA_IBSS;
4783                         } else {
4784                                 ai->config.opmode |= MODE_STA_ESS;
4785                                 if ( line[0] == 'r' ) {
4786                                         ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4787                                         ai->config.scanMode = SCANMODE_PASSIVE;
4788                                         set_bit (FLAG_802_11, &ai->flags);
4789                                 } else if ( line[0] == 'y' ) {
4790                                         ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4791                                         ai->config.scanMode = SCANMODE_PASSIVE;
4792                                         set_bit (FLAG_802_11, &ai->flags);
4793                                 } else if ( line[0] == 'l' )
4794                                         ai->config.rmode |= RXMODE_LANMON;
4795                         }
4796                         set_bit (FLAG_COMMIT, &ai->flags);
4797                 }
4798
4799 /*** Radio status */
4800                 else if (!strncmp(line,"Radio: ", 7)) {
4801                         line += 7;
4802                         if (!strncmp(line,"off",3)) {
4803                                 set_bit (FLAG_RADIO_OFF, &ai->flags);
4804                         } else {
4805                                 clear_bit (FLAG_RADIO_OFF, &ai->flags);
4806                         }
4807                 }
4808 /*** NodeName processing */
4809                 else if ( !strncmp( line, "NodeName: ", 10 ) ) {
4810                         int j;
4811
4812                         line += 10;
4813                         memset( ai->config.nodeName, 0, 16 );
4814 /* Do the name, assume a space between the mode and node name */
4815                         for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
4816                                 ai->config.nodeName[j] = line[j];
4817                         }
4818                         set_bit (FLAG_COMMIT, &ai->flags);
4819                 }
4820
4821 /*** PowerMode processing */
4822                 else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
4823                         line += 11;
4824                         if ( !strncmp( line, "PSPCAM", 6 ) ) {
4825                                 ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4826                                 set_bit (FLAG_COMMIT, &ai->flags);
4827                         } else if ( !strncmp( line, "PSP", 3 ) ) {
4828                                 ai->config.powerSaveMode = POWERSAVE_PSP;
4829                                 set_bit (FLAG_COMMIT, &ai->flags);
4830                         } else {
4831                                 ai->config.powerSaveMode = POWERSAVE_CAM;
4832                                 set_bit (FLAG_COMMIT, &ai->flags);
4833                         }
4834                 } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
4835                         int v, i = 0, k = 0; /* i is index into line,
4836                                                 k is index to rates */
4837
4838                         line += 11;
4839                         while((v = get_dec_u16(line, &i, 3))!=-1) {
4840                                 ai->config.rates[k++] = (u8)v;
4841                                 line += i + 1;
4842                                 i = 0;
4843                         }
4844                         set_bit (FLAG_COMMIT, &ai->flags);
4845                 } else if ( !strncmp( line, "Channel: ", 9 ) ) {
4846                         int v, i = 0;
4847                         line += 9;
4848                         v = get_dec_u16(line, &i, i+3);
4849                         if ( v != -1 ) {
4850                                 ai->config.channelSet = cpu_to_le16(v);
4851                                 set_bit (FLAG_COMMIT, &ai->flags);
4852                         }
4853                 } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
4854                         int v, i = 0;
4855                         line += 11;
4856                         v = get_dec_u16(line, &i, i+3);
4857                         if ( v != -1 ) {
4858                                 ai->config.txPower = cpu_to_le16(v);
4859                                 set_bit (FLAG_COMMIT, &ai->flags);
4860                         }
4861                 } else if ( !strncmp( line, "WEP: ", 5 ) ) {
4862                         line += 5;
4863                         switch( line[0] ) {
4864                         case 's':
4865                                 ai->config.authType = AUTH_SHAREDKEY;
4866                                 break;
4867                         case 'e':
4868                                 ai->config.authType = AUTH_ENCRYPT;
4869                                 break;
4870                         default:
4871                                 ai->config.authType = AUTH_OPEN;
4872                                 break;
4873                         }
4874                         set_bit (FLAG_COMMIT, &ai->flags);
4875                 } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
4876                         int v, i = 0;
4877
4878                         line += 16;
4879                         v = get_dec_u16(line, &i, 3);
4880                         v = (v<0) ? 0 : ((v>255) ? 255 : v);
4881                         ai->config.longRetryLimit = cpu_to_le16(v);
4882                         set_bit (FLAG_COMMIT, &ai->flags);
4883                 } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
4884                         int v, i = 0;
4885
4886                         line += 17;
4887                         v = get_dec_u16(line, &i, 3);
4888                         v = (v<0) ? 0 : ((v>255) ? 255 : v);
4889                         ai->config.shortRetryLimit = cpu_to_le16(v);
4890                         set_bit (FLAG_COMMIT, &ai->flags);
4891                 } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
4892                         int v, i = 0;
4893
4894                         line += 14;
4895                         v = get_dec_u16(line, &i, 4);
4896                         v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4897                         ai->config.rtsThres = cpu_to_le16(v);
4898                         set_bit (FLAG_COMMIT, &ai->flags);
4899                 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
4900                         int v, i = 0;
4901
4902                         line += 16;
4903                         v = get_dec_u16(line, &i, 5);
4904                         v = (v<0) ? 0 : v;
4905                         ai->config.txLifetime = cpu_to_le16(v);
4906                         set_bit (FLAG_COMMIT, &ai->flags);
4907                 } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
4908                         int v, i = 0;
4909
4910                         line += 16;
4911                         v = get_dec_u16(line, &i, 5);
4912                         v = (v<0) ? 0 : v;
4913                         ai->config.rxLifetime = cpu_to_le16(v);
4914                         set_bit (FLAG_COMMIT, &ai->flags);
4915                 } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4916                         ai->config.txDiversity =
4917                                 (line[13]=='l') ? 1 :
4918                                 ((line[13]=='r')? 2: 3);
4919                         set_bit (FLAG_COMMIT, &ai->flags);
4920                 } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4921                         ai->config.rxDiversity =
4922                                 (line[13]=='l') ? 1 :
4923                                 ((line[13]=='r')? 2: 3);
4924                         set_bit (FLAG_COMMIT, &ai->flags);
4925                 } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4926                         int v, i = 0;
4927
4928                         line += 15;
4929                         v = get_dec_u16(line, &i, 4);
4930                         v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4931                         v = v & 0xfffe; /* Make sure its even */
4932                         ai->config.fragThresh = cpu_to_le16(v);
4933                         set_bit (FLAG_COMMIT, &ai->flags);
4934                 } else if (!strncmp(line, "Modulation: ", 12)) {
4935                         line += 12;
4936                         switch(*line) {
4937                         case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4938                         case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4939                         case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4940                         default: airo_print_warn(ai->dev->name, "Unknown modulation");
4941                         }
4942                 } else if (!strncmp(line, "Preamble: ", 10)) {
4943                         line += 10;
4944                         switch(*line) {
4945                         case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4946                         case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4947                         case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4948                         default: airo_print_warn(ai->dev->name, "Unknown preamble");
4949                         }
4950                 } else {
4951                         airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
4952                 }
4953                 while( line[0] && line[0] != '\n' ) line++;
4954                 if ( line[0] ) line++;
4955         }
4956         airo_config_commit(dev, NULL, NULL, NULL);
4957 }
4958
4959 static char *get_rmode(__le16 mode)
4960 {
4961         switch(mode & RXMODE_MASK) {
4962         case RXMODE_RFMON:  return "rfmon";
4963         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
4964         case RXMODE_LANMON:  return "lanmon";
4965         }
4966         return "ESS";
4967 }
4968
4969 static int proc_config_open(struct inode *inode, struct file *file)
4970 {
4971         struct proc_data *data;
4972         struct proc_dir_entry *dp = PDE(inode);
4973         struct net_device *dev = dp->data;
4974         struct airo_info *ai = dev->priv;
4975         int i;
4976         __le16 mode;
4977
4978         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4979                 return -ENOMEM;
4980         data = (struct proc_data *)file->private_data;
4981         if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4982                 kfree (file->private_data);
4983                 return -ENOMEM;
4984         }
4985         if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
4986                 kfree (data->rbuffer);
4987                 kfree (file->private_data);
4988                 return -ENOMEM;
4989         }
4990         data->maxwritelen = 2048;
4991         data->on_close = proc_config_on_close;
4992
4993         readConfigRid(ai, 1);
4994
4995         mode = ai->config.opmode & MODE_CFG_MASK;
4996         i = sprintf( data->rbuffer,
4997                      "Mode: %s\n"
4998                      "Radio: %s\n"
4999                      "NodeName: %-16s\n"
5000                      "PowerMode: %s\n"
5001                      "DataRates: %d %d %d %d %d %d %d %d\n"
5002                      "Channel: %d\n"
5003                      "XmitPower: %d\n",
5004                      mode == MODE_STA_IBSS ? "adhoc" :
5005                      mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
5006                      mode == MODE_AP ? "AP" :
5007                      mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
5008                      test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
5009                      ai->config.nodeName,
5010                      ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
5011                      ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
5012                      ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
5013                      "Error",
5014                      (int)ai->config.rates[0],
5015                      (int)ai->config.rates[1],
5016                      (int)ai->config.rates[2],
5017                      (int)ai->config.rates[3],
5018                      (int)ai->config.rates[4],
5019                      (int)ai->config.rates[5],
5020                      (int)ai->config.rates[6],
5021                      (int)ai->config.rates[7],
5022                      le16_to_cpu(ai->config.channelSet),
5023                      le16_to_cpu(ai->config.txPower)
5024                 );
5025         sprintf( data->rbuffer + i,
5026                  "LongRetryLimit: %d\n"
5027                  "ShortRetryLimit: %d\n"
5028                  "RTSThreshold: %d\n"
5029                  "TXMSDULifetime: %d\n"
5030                  "RXMSDULifetime: %d\n"
5031                  "TXDiversity: %s\n"
5032                  "RXDiversity: %s\n"
5033                  "FragThreshold: %d\n"
5034                  "WEP: %s\n"
5035                  "Modulation: %s\n"
5036                  "Preamble: %s\n",
5037                  le16_to_cpu(ai->config.longRetryLimit),
5038                  le16_to_cpu(ai->config.shortRetryLimit),
5039                  le16_to_cpu(ai->config.rtsThres),
5040                  le16_to_cpu(ai->config.txLifetime),
5041                  le16_to_cpu(ai->config.rxLifetime),
5042                  ai->config.txDiversity == 1 ? "left" :
5043                  ai->config.txDiversity == 2 ? "right" : "both",
5044                  ai->config.rxDiversity == 1 ? "left" :
5045                  ai->config.rxDiversity == 2 ? "right" : "both",
5046                  le16_to_cpu(ai->config.fragThresh),
5047                  ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
5048                  ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
5049                  ai->config.modulation == MOD_DEFAULT ? "default" :
5050                  ai->config.modulation == MOD_CCK ? "cck" :
5051                  ai->config.modulation == MOD_MOK ? "mok" : "error",
5052                  ai->config.preamble == PREAMBLE_AUTO ? "auto" :
5053                  ai->config.preamble == PREAMBLE_LONG ? "long" :
5054                  ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
5055                 );
5056         data->readlen = strlen( data->rbuffer );
5057         return 0;
5058 }
5059
5060 static void proc_SSID_on_close(struct inode *inode, struct file *file)
5061 {
5062         struct proc_data *data = (struct proc_data *)file->private_data;
5063         struct proc_dir_entry *dp = PDE(inode);
5064         struct net_device *dev = dp->data;
5065         struct airo_info *ai = dev->priv;
5066         SsidRid SSID_rid;
5067         int i;
5068         char *p = data->wbuffer;
5069         char *end = p + data->writelen;
5070
5071         if (!data->writelen)
5072                 return;
5073
5074         *end = '\n'; /* sentinel; we have space for it */
5075
5076         memset(&SSID_rid, 0, sizeof(SSID_rid));
5077
5078         for (i = 0; i < 3 && p < end; i++) {
5079                 int j = 0;
5080                 /* copy up to 32 characters from this line */
5081                 while (*p != '\n' && j < 32)
5082                         SSID_rid.ssids[i].ssid[j++] = *p++;
5083                 if (j == 0)
5084                         break;
5085                 SSID_rid.ssids[i].len = cpu_to_le16(j);
5086                 /* skip to the beginning of the next line */
5087                 while (*p++ != '\n')
5088                         ;
5089         }
5090         if (i)
5091                 SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5092         disable_MAC(ai, 1);
5093         writeSsidRid(ai, &SSID_rid, 1);
5094         enable_MAC(ai, 1);
5095 }
5096
5097 static inline u8 hexVal(char c) {
5098         if (c>='0' && c<='9') return c -= '0';
5099         if (c>='a' && c<='f') return c -= 'a'-10;
5100         if (c>='A' && c<='F') return c -= 'A'-10;
5101         return 0;
5102 }
5103
5104 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
5105         struct proc_data *data = (struct proc_data *)file->private_data;
5106         struct proc_dir_entry *dp = PDE(inode);
5107         struct net_device *dev = dp->data;
5108         struct airo_info *ai = dev->priv;
5109         APListRid APList_rid;
5110         int i;
5111
5112         if ( !data->writelen ) return;
5113
5114         memset( &APList_rid, 0, sizeof(APList_rid) );
5115         APList_rid.len = cpu_to_le16(sizeof(APList_rid));
5116
5117         for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
5118                 int j;
5119                 for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
5120                         switch(j%3) {
5121                         case 0:
5122                                 APList_rid.ap[i][j/3]=
5123                                         hexVal(data->wbuffer[j+i*6*3])<<4;
5124                                 break;
5125                         case 1:
5126                                 APList_rid.ap[i][j/3]|=
5127                                         hexVal(data->wbuffer[j+i*6*3]);
5128                                 break;
5129                         }
5130                 }
5131         }
5132         disable_MAC(ai, 1);
5133         writeAPListRid(ai, &APList_rid, 1);
5134         enable_MAC(ai, 1);
5135 }
5136
5137 /* This function wraps PC4500_writerid with a MAC disable */
5138 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5139                         int len, int dummy ) {
5140         int rc;
5141
5142         disable_MAC(ai, 1);
5143         rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5144         enable_MAC(ai, 1);
5145         return rc;
5146 }
5147
5148 /* Returns the length of the key at the index.  If index == 0xffff
5149  * the index of the transmit key is returned.  If the key doesn't exist,
5150  * -1 will be returned.
5151  */
5152 static int get_wep_key(struct airo_info *ai, u16 index) {
5153         WepKeyRid wkr;
5154         int rc;
5155         __le16 lastindex;
5156
5157         rc = readWepKeyRid(ai, &wkr, 1, 1);
5158         if (rc == SUCCESS) do {
5159                 lastindex = wkr.kindex;
5160                 if (wkr.kindex == cpu_to_le16(index)) {
5161                         if (index == 0xffff) {
5162                                 return wkr.mac[0];
5163                         }
5164                         return le16_to_cpu(wkr.klen);
5165                 }
5166                 readWepKeyRid(ai, &wkr, 0, 1);
5167         } while (lastindex != wkr.kindex);
5168         return -1;
5169 }
5170
5171 static int set_wep_key(struct airo_info *ai, u16 index,
5172                        const char *key, u16 keylen, int perm, int lock )
5173 {
5174         static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5175         WepKeyRid wkr;
5176
5177         memset(&wkr, 0, sizeof(wkr));
5178         if (keylen == 0) {
5179 // We are selecting which key to use
5180                 wkr.len = cpu_to_le16(sizeof(wkr));
5181                 wkr.kindex = cpu_to_le16(0xffff);
5182                 wkr.mac[0] = (char)index;
5183                 if (perm) ai->defindex = (char)index;
5184         } else {
5185 // We are actually setting the key
5186                 wkr.len = cpu_to_le16(sizeof(wkr));
5187                 wkr.kindex = cpu_to_le16(index);
5188                 wkr.klen = cpu_to_le16(keylen);
5189                 memcpy( wkr.key, key, keylen );
5190                 memcpy( wkr.mac, macaddr, ETH_ALEN );
5191         }
5192
5193         if (perm) disable_MAC(ai, lock);
5194         writeWepKeyRid(ai, &wkr, perm, lock);
5195         if (perm) enable_MAC(ai, lock);
5196         return 0;
5197 }
5198
5199 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5200         struct proc_data *data;
5201         struct proc_dir_entry *dp = PDE(inode);
5202         struct net_device *dev = dp->data;
5203         struct airo_info *ai = dev->priv;
5204         int i;
5205         char key[16];
5206         u16 index = 0;
5207         int j = 0;
5208
5209         memset(key, 0, sizeof(key));
5210
5211         data = (struct proc_data *)file->private_data;
5212         if ( !data->writelen ) return;
5213
5214         if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5215             (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5216                 index = data->wbuffer[0] - '0';
5217                 if (data->wbuffer[1] == '\n') {
5218                         set_wep_key(ai, index, NULL, 0, 1, 1);
5219                         return;
5220                 }
5221                 j = 2;
5222         } else {
5223                 airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5224                 return;
5225         }
5226
5227         for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
5228                 switch(i%3) {
5229                 case 0:
5230                         key[i/3] = hexVal(data->wbuffer[i+j])<<4;
5231                         break;
5232                 case 1:
5233                         key[i/3] |= hexVal(data->wbuffer[i+j]);
5234                         break;
5235                 }
5236         }
5237         set_wep_key(ai, index, key, i/3, 1, 1);
5238 }
5239
5240 static int proc_wepkey_open( struct inode *inode, struct file *file )
5241 {
5242         struct proc_data *data;
5243         struct proc_dir_entry *dp = PDE(inode);
5244         struct net_device *dev = dp->data;
5245         struct airo_info *ai = dev->priv;
5246         char *ptr;
5247         WepKeyRid wkr;
5248         __le16 lastindex;
5249         int j=0;
5250         int rc;
5251
5252         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5253                 return -ENOMEM;
5254         memset(&wkr, 0, sizeof(wkr));
5255         data = (struct proc_data *)file->private_data;
5256         if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5257                 kfree (file->private_data);
5258                 return -ENOMEM;
5259         }
5260         data->writelen = 0;
5261         data->maxwritelen = 80;
5262         if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5263                 kfree (data->rbuffer);
5264                 kfree (file->private_data);
5265                 return -ENOMEM;
5266         }
5267         data->on_close = proc_wepkey_on_close;
5268
5269         ptr = data->rbuffer;
5270         strcpy(ptr, "No wep keys\n");
5271         rc = readWepKeyRid(ai, &wkr, 1, 1);
5272         if (rc == SUCCESS) do {
5273                 lastindex = wkr.kindex;
5274                 if (wkr.kindex == cpu_to_le16(0xffff)) {
5275                         j += sprintf(ptr+j, "Tx key = %d\n",
5276                                      (int)wkr.mac[0]);
5277                 } else {
5278                         j += sprintf(ptr+j, "Key %d set with length = %d\n",
5279                                      le16_to_cpu(wkr.kindex),
5280                                      le16_to_cpu(wkr.klen));
5281                 }
5282                 readWepKeyRid(ai, &wkr, 0, 1);
5283         } while((lastindex != wkr.kindex) && (j < 180-30));
5284
5285         data->readlen = strlen( data->rbuffer );
5286         return 0;
5287 }
5288
5289 static int proc_SSID_open(struct inode *inode, struct file *file)
5290 {
5291         struct proc_data *data;
5292         struct proc_dir_entry *dp = PDE(inode);
5293         struct net_device *dev = dp->data;
5294         struct airo_info *ai = dev->priv;
5295         int i;
5296         char *ptr;
5297         SsidRid SSID_rid;
5298
5299         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5300                 return -ENOMEM;
5301         data = (struct proc_data *)file->private_data;
5302         if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5303                 kfree (file->private_data);
5304                 return -ENOMEM;
5305         }
5306         data->writelen = 0;
5307         data->maxwritelen = 33*3;
5308         /* allocate maxwritelen + 1; we'll want a sentinel */
5309         if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5310                 kfree (data->rbuffer);
5311                 kfree (file->private_data);
5312                 return -ENOMEM;
5313         }
5314         data->on_close = proc_SSID_on_close;
5315
5316         readSsidRid(ai, &SSID_rid);
5317         ptr = data->rbuffer;
5318         for (i = 0; i < 3; i++) {
5319                 int j;
5320                 size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5321                 if (!len)
5322                         break;
5323                 if (len > 32)
5324                         len = 32;
5325                 for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5326                         *ptr++ = SSID_rid.ssids[i].ssid[j];
5327                 *ptr++ = '\n';
5328         }
5329         *ptr = '\0';
5330         data->readlen = strlen( data->rbuffer );
5331         return 0;
5332 }
5333
5334 static int proc_APList_open( struct inode *inode, struct file *file ) {
5335         struct proc_data *data;
5336         struct proc_dir_entry *dp = PDE(inode);
5337         struct net_device *dev = dp->data;
5338         struct airo_info *ai = dev->priv;
5339         int i;
5340         char *ptr;
5341         APListRid APList_rid;
5342         DECLARE_MAC_BUF(mac);
5343
5344         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5345                 return -ENOMEM;
5346         data = (struct proc_data *)file->private_data;
5347         if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5348                 kfree (file->private_data);
5349                 return -ENOMEM;
5350         }
5351         data->writelen = 0;
5352         data->maxwritelen = 4*6*3;
5353         if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5354                 kfree (data->rbuffer);
5355                 kfree (file->private_data);
5356                 return -ENOMEM;
5357         }
5358         data->on_close = proc_APList_on_close;
5359
5360         readAPListRid(ai, &APList_rid);
5361         ptr = data->rbuffer;
5362         for( i = 0; i < 4; i++ ) {
5363 // We end when we find a zero MAC
5364                 if ( !*(int*)APList_rid.ap[i] &&
5365                      !*(int*)&APList_rid.ap[i][2]) break;
5366                 ptr += sprintf(ptr, "%s\n",
5367                                print_mac(mac, APList_rid.ap[i]));
5368         }
5369         if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5370
5371         *ptr = '\0';
5372         data->readlen = strlen( data->rbuffer );
5373         return 0;
5374 }
5375
5376 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5377         struct proc_data *data;
5378         struct proc_dir_entry *dp = PDE(inode);
5379         struct net_device *dev = dp->data;
5380         struct airo_info *ai = dev->priv;
5381         char *ptr;
5382         BSSListRid BSSList_rid;
5383         int rc;
5384         /* If doLoseSync is not 1, we won't do a Lose Sync */
5385         int doLoseSync = -1;
5386         DECLARE_MAC_BUF(mac);
5387
5388         if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5389                 return -ENOMEM;
5390         data = (struct proc_data *)file->private_data;
5391         if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5392                 kfree (file->private_data);
5393                 return -ENOMEM;
5394         }
5395         data->writelen = 0;
5396         data->maxwritelen = 0;
5397         data->wbuffer = NULL;
5398         data->on_close = NULL;
5399
5400         if (file->f_mode & FMODE_WRITE) {
5401                 if (!(file->f_mode & FMODE_READ)) {
5402                         Cmd cmd;
5403                         Resp rsp;
5404
5405                         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
5406                         memset(&cmd, 0, sizeof(cmd));
5407                         cmd.cmd=CMD_LISTBSS;
5408                         if (down_interruptible(&ai->sem))
5409                                 return -ERESTARTSYS;
5410                         issuecommand(ai, &cmd, &rsp);
5411                         up(&ai->sem);
5412                         data->readlen = 0;
5413                         return 0;
5414                 }
5415                 doLoseSync = 1;
5416         }
5417         ptr = data->rbuffer;
5418         /* There is a race condition here if there are concurrent opens.
5419            Since it is a rare condition, we'll just live with it, otherwise
5420            we have to add a spin lock... */
5421         rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5422         while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
5423                 ptr += sprintf(ptr, "%s %*s rssi = %d",
5424                                print_mac(mac, BSSList_rid.bssid),
5425                                 (int)BSSList_rid.ssidLen,
5426                                 BSSList_rid.ssid,
5427                                 le16_to_cpu(BSSList_rid.dBm));
5428                 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5429                                 le16_to_cpu(BSSList_rid.dsChannel),
5430                                 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5431                                 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5432                                 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5433                                 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5434                 rc = readBSSListRid(ai, 0, &BSSList_rid);
5435         }
5436         *ptr = '\0';
5437         data->readlen = strlen( data->rbuffer );
5438         return 0;
5439 }
5440
5441 static int proc_close( struct inode *inode, struct file *file )
5442 {
5443         struct proc_data *data = file->private_data;
5444
5445         if (data->on_close != NULL)
5446                 data->on_close(inode, file);
5447         kfree(data->rbuffer);
5448         kfree(data->wbuffer);
5449         kfree(data);
5450         return 0;
5451 }
5452
5453 /* Since the card doesn't automatically switch to the right WEP mode,
5454    we will make it do it.  If the card isn't associated, every secs we
5455    will switch WEP modes to see if that will help.  If the card is
5456    associated we will check every minute to see if anything has
5457    changed. */
5458 static void timer_func( struct net_device *dev ) {
5459         struct airo_info *apriv = dev->priv;
5460
5461 /* We don't have a link so try changing the authtype */
5462         readConfigRid(apriv, 0);
5463         disable_MAC(apriv, 0);
5464         switch(apriv->config.authType) {
5465                 case AUTH_ENCRYPT:
5466 /* So drop to OPEN */
5467                         apriv->config.authType = AUTH_OPEN;
5468                         break;
5469                 case AUTH_SHAREDKEY:
5470                         if (apriv->keyindex < auto_wep) {
5471                                 set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
5472                                 apriv->config.authType = AUTH_SHAREDKEY;
5473                                 apriv->keyindex++;
5474                         } else {
5475                                 /* Drop to ENCRYPT */
5476                                 apriv->keyindex = 0;
5477                                 set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
5478                                 apriv->config.authType = AUTH_ENCRYPT;
5479                         }
5480                         break;
5481                 default:  /* We'll escalate to SHAREDKEY */
5482                         apriv->config.authType = AUTH_SHAREDKEY;
5483         }
5484         set_bit (FLAG_COMMIT, &apriv->flags);
5485         writeConfigRid(apriv, 0);
5486         enable_MAC(apriv, 0);
5487         up(&apriv->sem);
5488
5489 /* Schedule check to see if the change worked */
5490         clear_bit(JOB_AUTOWEP, &apriv->jobs);
5491         apriv->expires = RUN_AT(HZ*3);
5492 }
5493
5494 #ifdef CONFIG_PCI
5495 static int __devinit airo_pci_probe(struct pci_dev *pdev,
5496                                     const struct pci_device_id *pent)
5497 {
5498         struct net_device *dev;
5499
5500         if (pci_enable_device(pdev))
5501                 return -ENODEV;
5502         pci_set_master(pdev);
5503
5504         if (pdev->device == 0x5000 || pdev->device == 0xa504)
5505                         dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5506         else
5507                         dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5508         if (!dev) {
5509                 pci_disable_device(pdev);
5510                 return -ENODEV;
5511         }
5512
5513         pci_set_drvdata(pdev, dev);
5514         return 0;
5515 }
5516
5517 static void __devexit airo_pci_remove(struct pci_dev *pdev)
5518 {
5519         struct net_device *dev = pci_get_drvdata(pdev);
5520
5521         airo_print_info(dev->name, "Unregistering...");
5522         stop_airo_card(dev, 1);
5523         pci_disable_device(pdev);
5524         pci_set_drvdata(pdev, NULL);
5525 }
5526
5527 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
5528 {
5529         struct net_device *dev = pci_get_drvdata(pdev);
5530         struct airo_info *ai = dev->priv;
5531         Cmd cmd;
5532         Resp rsp;
5533
5534         if ((ai->APList == NULL) &&
5535                 (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
5536                 return -ENOMEM;
5537         if ((ai->SSID == NULL) &&
5538                 (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
5539                 return -ENOMEM;
5540         readAPListRid(ai, ai->APList);
5541         readSsidRid(ai, ai->SSID);
5542         memset(&cmd, 0, sizeof(cmd));
5543         /* the lock will be released at the end of the resume callback */
5544         if (down_interruptible(&ai->sem))
5545                 return -EAGAIN;
5546         disable_MAC(ai, 0);
5547         netif_device_detach(dev);
5548         ai->power = state;
5549         cmd.cmd=HOSTSLEEP;
5550         issuecommand(ai, &cmd, &rsp);
5551
5552         pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
5553         pci_save_state(pdev);
5554         return pci_set_power_state(pdev, pci_choose_state(pdev, state));
5555 }
5556
5557 static int airo_pci_resume(struct pci_dev *pdev)
5558 {
5559         struct net_device *dev = pci_get_drvdata(pdev);
5560         struct airo_info *ai = dev->priv;
5561         pci_power_t prev_state = pdev->current_state;
5562
5563         pci_set_power_state(pdev, PCI_D0);
5564         pci_restore_state(pdev);
5565         pci_enable_wake(pdev, PCI_D0, 0);
5566
5567         if (prev_state != PCI_D1) {
5568                 reset_card(dev, 0);
5569                 mpi_init_descriptors(ai);
5570                 setup_card(ai, dev->dev_addr, 0);
5571                 clear_bit(FLAG_RADIO_OFF, &ai->flags);
5572                 clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5573         } else {
5574                 OUT4500(ai, EVACK, EV_AWAKEN);
5575                 OUT4500(ai, EVACK, EV_AWAKEN);
5576                 msleep(100);
5577         }
5578
5579         set_bit (FLAG_COMMIT, &ai->flags);
5580         disable_MAC(ai, 0);
5581         msleep(200);
5582         if (ai->SSID) {
5583                 writeSsidRid(ai, ai->SSID, 0);
5584                 kfree(ai->SSID);
5585                 ai->SSID = NULL;
5586         }
5587         if (ai->APList) {
5588                 writeAPListRid(ai, ai->APList, 0);
5589                 kfree(ai->APList);
5590                 ai->APList = NULL;
5591         }
5592         writeConfigRid(ai, 0);
5593         enable_MAC(ai, 0);
5594         ai->power = PMSG_ON;
5595         netif_device_attach(dev);
5596         netif_wake_queue(dev);
5597         enable_interrupts(ai);
5598         up(&ai->sem);
5599         return 0;
5600 }
5601 #endif
5602
5603 static int __init airo_init_module( void )
5604 {
5605         int i;
5606 #if 0
5607         int have_isa_dev = 0;
5608 #endif
5609
5610         airo_entry = create_proc_entry("driver/aironet",
5611                                        S_IFDIR | airo_perm,
5612                                        NULL);
5613
5614         if (airo_entry) {
5615                 airo_entry->uid = proc_uid;
5616                 airo_entry->gid = proc_gid;
5617         }
5618
5619         for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
5620                 airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5621                         "io=0x%x", irq[i], io[i] );
5622                 if (init_airo_card( irq[i], io[i], 0, NULL ))
5623 #if 0
5624                         have_isa_dev = 1;
5625 #else
5626                         /* do nothing */ ;
5627 #endif
5628         }
5629
5630 #ifdef CONFIG_PCI
5631         airo_print_info("", "Probing for PCI adapters");
5632         i = pci_register_driver(&airo_driver);
5633         airo_print_info("", "Finished probing for PCI adapters");
5634
5635         if (i) {
5636                 remove_proc_entry("driver/aironet", NULL);
5637                 return i;
5638         }
5639 #endif
5640
5641         /* Always exit with success, as we are a library module
5642          * as well as a driver module
5643          */
5644         return 0;
5645 }
5646
5647 static void __exit airo_cleanup_module( void )
5648 {
5649         struct airo_info *ai;
5650         while(!list_empty(&airo_devices)) {
5651                 ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5652                 airo_print_info(ai->dev->name, "Unregistering...");
5653                 stop_airo_card(ai->dev, 1);
5654         }
5655 #ifdef CONFIG_PCI
5656         pci_unregister_driver(&airo_driver);
5657 #endif
5658         remove_proc_entry("driver/aironet", NULL);
5659 }
5660
5661 /*
5662  * Initial Wireless Extension code for Aironet driver by :
5663  *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5664  * Conversion to new driver API by :
5665  *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5666  * Javier also did a good amount of work here, adding some new extensions
5667  * and fixing my code. Let's just say that without him this code just
5668  * would not work at all... - Jean II
5669  */
5670
5671 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5672 {
5673         if( !rssi_rid )
5674                 return 0;
5675
5676         return (0x100 - rssi_rid[rssi].rssidBm);
5677 }
5678
5679 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5680 {
5681         int i;
5682
5683         if( !rssi_rid )
5684                 return 0;
5685
5686         for( i = 0; i < 256; i++ )
5687                 if (rssi_rid[i].rssidBm == dbm)
5688                         return rssi_rid[i].rssipct;
5689
5690         return 0;
5691 }
5692
5693
5694 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5695 {
5696         int quality = 0;
5697         u16 sq;
5698
5699         if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5700                 return 0;
5701
5702         if (!(cap_rid->hardCap & cpu_to_le16(8)))
5703                 return 0;
5704
5705         sq = le16_to_cpu(status_rid->signalQuality);
5706         if (memcmp(cap_rid->prodName, "350", 3))
5707                 if (sq > 0x20)
5708                         quality = 0;
5709                 else
5710                         quality = 0x20 - sq;
5711         else
5712                 if (sq > 0xb0)
5713                         quality = 0;
5714                 else if (sq < 0x10)
5715                         quality = 0xa0;
5716                 else
5717                         quality = 0xb0 - sq;
5718         return quality;
5719 }
5720
5721 #define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5722 #define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
5723
5724 /*------------------------------------------------------------------*/
5725 /*
5726  * Wireless Handler : get protocol name
5727  */
5728 static int airo_get_name(struct net_device *dev,
5729                          struct iw_request_info *info,
5730                          char *cwrq,
5731                          char *extra)
5732 {
5733         strcpy(cwrq, "IEEE 802.11-DS");
5734         return 0;
5735 }
5736
5737 /*------------------------------------------------------------------*/
5738 /*
5739  * Wireless Handler : set frequency
5740  */
5741 static int airo_set_freq(struct net_device *dev,
5742                          struct iw_request_info *info,
5743                          struct iw_freq *fwrq,
5744                          char *extra)
5745 {
5746         struct airo_info *local = dev->priv;
5747         int rc = -EINPROGRESS;          /* Call commit handler */
5748
5749         /* If setting by frequency, convert to a channel */
5750         if((fwrq->e == 1) &&
5751            (fwrq->m >= (int) 2.412e8) &&
5752            (fwrq->m <= (int) 2.487e8)) {
5753                 int f = fwrq->m / 100000;
5754                 int c = 0;
5755                 while((c < 14) && (f != frequency_list[c]))
5756                         c++;
5757                 /* Hack to fall through... */
5758                 fwrq->e = 0;
5759                 fwrq->m = c + 1;
5760         }
5761         /* Setting by channel number */
5762         if((fwrq->m > 1000) || (fwrq->e > 0))
5763                 rc = -EOPNOTSUPP;
5764         else {
5765                 int channel = fwrq->m;
5766                 /* We should do a better check than that,
5767                  * based on the card capability !!! */
5768                 if((channel < 1) || (channel > 14)) {
5769                         airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5770                                 fwrq->m);
5771                         rc = -EINVAL;
5772                 } else {
5773                         readConfigRid(local, 1);
5774                         /* Yes ! We can set it !!! */
5775                         local->config.channelSet = cpu_to_le16(channel);
5776                         set_bit (FLAG_COMMIT, &local->flags);
5777                 }
5778         }
5779         return rc;
5780 }
5781
5782 /*------------------------------------------------------------------*/
5783 /*
5784  * Wireless Handler : get frequency
5785  */
5786 static int airo_get_freq(struct net_device *dev,
5787                          struct iw_request_info *info,
5788                          struct iw_freq *fwrq,
5789                          char *extra)
5790 {
5791         struct airo_info *local = dev->priv;
5792         StatusRid status_rid;           /* Card status info */
5793         int ch;
5794
5795         readConfigRid(local, 1);
5796         if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
5797                 status_rid.channel = local->config.channelSet;
5798         else
5799                 readStatusRid(local, &status_rid, 1);
5800
5801         ch = le16_to_cpu(status_rid.channel);
5802         if((ch > 0) && (ch < 15)) {
5803                 fwrq->m = frequency_list[ch - 1] * 100000;
5804                 fwrq->e = 1;
5805         } else {
5806                 fwrq->m = ch;
5807                 fwrq->e = 0;
5808         }
5809
5810         return 0;
5811 }
5812
5813 /*------------------------------------------------------------------*/
5814 /*
5815  * Wireless Handler : set ESSID
5816  */
5817 static int airo_set_essid(struct net_device *dev,
5818                           struct iw_request_info *info,
5819                           struct iw_point *dwrq,
5820                           char *extra)
5821 {
5822         struct airo_info *local = dev->priv;
5823         SsidRid SSID_rid;               /* SSIDs */
5824
5825         /* Reload the list of current SSID */
5826         readSsidRid(local, &SSID_rid);
5827
5828         /* Check if we asked for `any' */
5829         if(dwrq->flags == 0) {
5830                 /* Just send an empty SSID list */
5831                 memset(&SSID_rid, 0, sizeof(SSID_rid));
5832         } else {
5833                 int     index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5834
5835                 /* Check the size of the string */
5836                 if(dwrq->length > IW_ESSID_MAX_SIZE) {
5837                         return -E2BIG ;
5838                 }
5839                 /* Check if index is valid */
5840                 if((index < 0) || (index >= 4)) {
5841                         return -EINVAL;
5842                 }
5843
5844                 /* Set the SSID */
5845                 memset(SSID_rid.ssids[index].ssid, 0,
5846                        sizeof(SSID_rid.ssids[index].ssid));
5847                 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5848                 SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5849         }
5850         SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5851         /* Write it to the card */
5852         disable_MAC(local, 1);
5853         writeSsidRid(local, &SSID_rid, 1);
5854         enable_MAC(local, 1);
5855
5856         return 0;
5857 }
5858
5859 /*------------------------------------------------------------------*/
5860 /*
5861  * Wireless Handler : get ESSID
5862  */
5863 static int airo_get_essid(struct net_device *dev,
5864                           struct iw_request_info *info,
5865                           struct iw_point *dwrq,
5866                           char *extra)
5867 {
5868         struct airo_info *local = dev->priv;
5869         StatusRid status_rid;           /* Card status info */
5870
5871         readStatusRid(local, &status_rid, 1);
5872
5873         /* Note : if dwrq->flags != 0, we should
5874          * get the relevant SSID from the SSID list... */
5875
5876         /* Get the current SSID */
5877         memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5878         /* If none, we may want to get the one that was set */
5879
5880         /* Push it out ! */
5881         dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5882         dwrq->flags = 1; /* active */
5883
5884         return 0;
5885 }
5886
5887 /*------------------------------------------------------------------*/
5888 /*
5889  * Wireless Handler : set AP address
5890  */
5891 static int airo_set_wap(struct net_device *dev,
5892                         struct iw_request_info *info,
5893                         struct sockaddr *awrq,
5894                         char *extra)
5895 {
5896         struct airo_info *local = dev->priv;
5897         Cmd cmd;
5898         Resp rsp;
5899         APListRid APList_rid;
5900         static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
5901         static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
5902
5903         if (awrq->sa_family != ARPHRD_ETHER)
5904                 return -EINVAL;
5905         else if (!memcmp(any, awrq->sa_data, ETH_ALEN) ||
5906                  !memcmp(off, awrq->sa_data, ETH_ALEN)) {
5907                 memset(&cmd, 0, sizeof(cmd));
5908                 cmd.cmd=CMD_LOSE_SYNC;
5909                 if (down_interruptible(&local->sem))
5910                         return -ERESTARTSYS;
5911                 issuecommand(local, &cmd, &rsp);
5912                 up(&local->sem);
5913         } else {
5914                 memset(&APList_rid, 0, sizeof(APList_rid));
5915                 APList_rid.len = cpu_to_le16(sizeof(APList_rid));
5916                 memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
5917                 disable_MAC(local, 1);
5918                 writeAPListRid(local, &APList_rid, 1);
5919                 enable_MAC(local, 1);
5920         }
5921         return 0;
5922 }
5923
5924 /*------------------------------------------------------------------*/
5925 /*
5926  * Wireless Handler : get AP address
5927  */
5928 static int airo_get_wap(struct net_device *dev,
5929                         struct iw_request_info *info,
5930                         struct sockaddr *awrq,
5931                         char *extra)
5932 {
5933         struct airo_info *local = dev->priv;
5934         StatusRid status_rid;           /* Card status info */
5935
5936         readStatusRid(local, &status_rid, 1);
5937
5938         /* Tentative. This seems to work, wow, I'm lucky !!! */
5939         memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
5940         awrq->sa_family = ARPHRD_ETHER;
5941
5942         return 0;
5943 }
5944
5945 /*------------------------------------------------------------------*/
5946 /*
5947  * Wireless Handler : set Nickname
5948  */
5949 static int airo_set_nick(struct net_device *dev,
5950                          struct iw_request_info *info,
5951                          struct iw_point *dwrq,
5952                          char *extra)
5953 {
5954         struct airo_info *local = dev->priv;
5955
5956         /* Check the size of the string */
5957         if(dwrq->length > 16) {
5958                 return -E2BIG;
5959         }
5960         readConfigRid(local, 1);
5961         memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
5962         memcpy(local->config.nodeName, extra, dwrq->length);
5963         set_bit (FLAG_COMMIT, &local->flags);
5964
5965         return -EINPROGRESS;            /* Call commit handler */
5966 }
5967
5968 /*------------------------------------------------------------------*/
5969 /*
5970  * Wireless Handler : get Nickname
5971  */
5972 static int airo_get_nick(struct net_device *dev,
5973                          struct iw_request_info *info,
5974                          struct iw_point *dwrq,
5975                          char *extra)
5976 {
5977         struct airo_info *local = dev->priv;
5978
5979         readConfigRid(local, 1);
5980         strncpy(extra, local->config.nodeName, 16);
5981         extra[16] = '\0';
5982         dwrq->length = strlen(extra);
5983
5984         return 0;
5985 }
5986
5987 /*------------------------------------------------------------------*/
5988 /*
5989  * Wireless Handler : set Bit-Rate
5990  */
5991 static int airo_set_rate(struct net_device *dev,
5992                          struct iw_request_info *info,
5993                          struct iw_param *vwrq,
5994                          char *extra)
5995 {
5996         struct airo_info *local = dev->priv;
5997         CapabilityRid cap_rid;          /* Card capability info */
5998         u8      brate = 0;
5999         int     i;
6000
6001         /* First : get a valid bit rate value */
6002         readCapabilityRid(local, &cap_rid, 1);
6003
6004         /* Which type of value ? */
6005         if((vwrq->value < 8) && (vwrq->value >= 0)) {
6006                 /* Setting by rate index */
6007                 /* Find value in the magic rate table */
6008                 brate = cap_rid.supportedRates[vwrq->value];
6009         } else {
6010                 /* Setting by frequency value */
6011                 u8      normvalue = (u8) (vwrq->value/500000);
6012
6013                 /* Check if rate is valid */
6014                 for(i = 0 ; i < 8 ; i++) {
6015                         if(normvalue == cap_rid.supportedRates[i]) {
6016                                 brate = normvalue;
6017                                 break;
6018                         }
6019                 }
6020         }
6021         /* -1 designed the max rate (mostly auto mode) */
6022         if(vwrq->value == -1) {
6023                 /* Get the highest available rate */
6024                 for(i = 0 ; i < 8 ; i++) {
6025                         if(cap_rid.supportedRates[i] == 0)
6026                                 break;
6027                 }
6028                 if(i != 0)
6029                         brate = cap_rid.supportedRates[i - 1];
6030         }
6031         /* Check that it is valid */
6032         if(brate == 0) {
6033                 return -EINVAL;
6034         }
6035
6036         readConfigRid(local, 1);
6037         /* Now, check if we want a fixed or auto value */
6038         if(vwrq->fixed == 0) {
6039                 /* Fill all the rates up to this max rate */
6040                 memset(local->config.rates, 0, 8);
6041                 for(i = 0 ; i < 8 ; i++) {
6042                         local->config.rates[i] = cap_rid.supportedRates[i];
6043                         if(local->config.rates[i] == brate)
6044                                 break;
6045                 }
6046         } else {
6047                 /* Fixed mode */
6048                 /* One rate, fixed */
6049                 memset(local->config.rates, 0, 8);
6050                 local->config.rates[0] = brate;
6051         }
6052         set_bit (FLAG_COMMIT, &local->flags);
6053
6054         return -EINPROGRESS;            /* Call commit handler */
6055 }
6056
6057 /*------------------------------------------------------------------*/
6058 /*
6059  * Wireless Handler : get Bit-Rate
6060  */
6061 static int airo_get_rate(struct net_device *dev,
6062                          struct iw_request_info *info,
6063                          struct iw_param *vwrq,
6064                          char *extra)
6065 {
6066         struct airo_info *local = dev->priv;
6067         StatusRid status_rid;           /* Card status info */
6068
6069         readStatusRid(local, &status_rid, 1);
6070
6071         vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6072         /* If more than one rate, set auto */
6073         readConfigRid(local, 1);
6074         vwrq->fixed = (local->config.rates[1] == 0);
6075
6076         return 0;
6077 }
6078
6079 /*------------------------------------------------------------------*/
6080 /*
6081  * Wireless Handler : set RTS threshold
6082  */
6083 static int airo_set_rts(struct net_device *dev,
6084                         struct iw_request_info *info,
6085                         struct iw_param *vwrq,
6086                         char *extra)
6087 {
6088         struct airo_info *local = dev->priv;
6089         int rthr = vwrq->value;
6090
6091         if(vwrq->disabled)
6092                 rthr = AIRO_DEF_MTU;
6093         if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
6094                 return -EINVAL;
6095         }
6096         readConfigRid(local, 1);
6097         local->config.rtsThres = cpu_to_le16(rthr);
6098         set_bit (FLAG_COMMIT, &local->flags);
6099
6100         return -EINPROGRESS;            /* Call commit handler */
6101 }
6102
6103 /*------------------------------------------------------------------*/
6104 /*
6105  * Wireless Handler : get RTS threshold
6106  */
6107 static int airo_get_rts(struct net_device *dev,
6108                         struct iw_request_info *info,
6109                         struct iw_param *vwrq,
6110                         char *extra)
6111 {
6112         struct airo_info *local = dev->priv;
6113
6114         readConfigRid(local, 1);
6115         vwrq->value = le16_to_cpu(local->config.rtsThres);
6116         vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6117         vwrq->fixed = 1;
6118
6119         return 0;
6120 }
6121
6122 /*------------------------------------------------------------------*/
6123 /*
6124  * Wireless Handler : set Fragmentation threshold
6125  */
6126 static int airo_set_frag(struct net_device *dev,
6127                          struct iw_request_info *info,
6128                          struct iw_param *vwrq,
6129                          char *extra)
6130 {
6131         struct airo_info *local = dev->priv;
6132         int fthr = vwrq->value;
6133
6134         if(vwrq->disabled)
6135                 fthr = AIRO_DEF_MTU;
6136         if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
6137                 return -EINVAL;
6138         }
6139         fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
6140         readConfigRid(local, 1);
6141         local->config.fragThresh = cpu_to_le16(fthr);
6142         set_bit (FLAG_COMMIT, &local->flags);
6143
6144         return -EINPROGRESS;            /* Call commit handler */
6145 }
6146
6147 /*------------------------------------------------------------------*/
6148 /*
6149  * Wireless Handler : get Fragmentation threshold
6150  */
6151 static int airo_get_frag(struct net_device *dev,
6152                          struct iw_request_info *info,
6153                          struct iw_param *vwrq,
6154                          char *extra)
6155 {
6156         struct airo_info *local = dev->priv;
6157
6158         readConfigRid(local, 1);
6159         vwrq->value = le16_to_cpu(local->config.fragThresh);
6160         vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6161         vwrq->fixed = 1;
6162
6163         return 0;
6164 }
6165
6166 /*------------------------------------------------------------------*/
6167 /*
6168  * Wireless Handler : set Mode of Operation
6169  */
6170 static int airo_set_mode(struct net_device *dev,
6171                          struct iw_request_info *info,
6172                          __u32 *uwrq,
6173                          char *extra)
6174 {
6175         struct airo_info *local = dev->priv;
6176         int reset = 0;
6177
6178         readConfigRid(local, 1);
6179         if (sniffing_mode(local))
6180                 reset = 1;
6181
6182         switch(*uwrq) {
6183                 case IW_MODE_ADHOC:
6184                         local->config.opmode &= ~MODE_CFG_MASK;
6185                         local->config.opmode |= MODE_STA_IBSS;
6186                         local->config.rmode &= ~RXMODE_FULL_MASK;
6187                         local->config.scanMode = SCANMODE_ACTIVE;
6188                         clear_bit (FLAG_802_11, &local->flags);
6189                         break;
6190                 case IW_MODE_INFRA:
6191                         local->config.opmode &= ~MODE_CFG_MASK;
6192                         local->config.opmode |= MODE_STA_ESS;
6193                         local->config.rmode &= ~RXMODE_FULL_MASK;
6194                         local->config.scanMode = SCANMODE_ACTIVE;
6195                         clear_bit (FLAG_802_11, &local->flags);
6196                         break;
6197                 case IW_MODE_MASTER:
6198                         local->config.opmode &= ~MODE_CFG_MASK;
6199                         local->config.opmode |= MODE_AP;
6200                         local->config.rmode &= ~RXMODE_FULL_MASK;
6201                         local->config.scanMode = SCANMODE_ACTIVE;
6202                         clear_bit (FLAG_802_11, &local->flags);
6203                         break;
6204                 case IW_MODE_REPEAT:
6205                         local->config.opmode &= ~MODE_CFG_MASK;
6206                         local->config.opmode |= MODE_AP_RPTR;
6207                         local->config.rmode &= ~RXMODE_FULL_MASK;
6208                         local->config.scanMode = SCANMODE_ACTIVE;
6209                         clear_bit (FLAG_802_11, &local->flags);
6210                         break;
6211                 case IW_MODE_MONITOR:
6212                         local->config.opmode &= ~MODE_CFG_MASK;
6213                         local->config.opmode |= MODE_STA_ESS;
6214                         local->config.rmode &= ~RXMODE_FULL_MASK;
6215                         local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6216                         local->config.scanMode = SCANMODE_PASSIVE;
6217                         set_bit (FLAG_802_11, &local->flags);
6218                         break;
6219                 default:
6220                         return -EINVAL;
6221         }
6222         if (reset)
6223                 set_bit (FLAG_RESET, &local->flags);
6224         set_bit (FLAG_COMMIT, &local->flags);
6225
6226         return -EINPROGRESS;            /* Call commit handler */
6227 }
6228
6229 /*------------------------------------------------------------------*/
6230 /*
6231  * Wireless Handler : get Mode of Operation
6232  */
6233 static int airo_get_mode(struct net_device *dev,
6234                          struct iw_request_info *info,
6235                          __u32 *uwrq,
6236                          char *extra)
6237 {
6238         struct airo_info *local = dev->priv;
6239
6240         readConfigRid(local, 1);
6241         /* If not managed, assume it's ad-hoc */
6242         switch (local->config.opmode & MODE_CFG_MASK) {
6243                 case MODE_STA_ESS:
6244                         *uwrq = IW_MODE_INFRA;
6245                         break;
6246                 case MODE_AP:
6247                         *uwrq = IW_MODE_MASTER;
6248                         break;
6249                 case MODE_AP_RPTR:
6250                         *uwrq = IW_MODE_REPEAT;
6251                         break;
6252                 default:
6253                         *uwrq = IW_MODE_ADHOC;
6254         }
6255
6256         return 0;
6257 }
6258
6259 static inline int valid_index(CapabilityRid *p, int index)
6260 {
6261         if (index < 0)
6262                 return 0;
6263         return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
6264 }
6265
6266 /*------------------------------------------------------------------*/
6267 /*
6268  * Wireless Handler : set Encryption Key
6269  */
6270 static int airo_set_encode(struct net_device *dev,
6271                            struct iw_request_info *info,
6272                            struct iw_point *dwrq,
6273                            char *extra)
6274 {
6275         struct airo_info *local = dev->priv;
6276         CapabilityRid cap_rid;          /* Card capability info */
6277         int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
6278         __le16 currentAuthType = local->config.authType;
6279
6280         /* Is WEP supported ? */
6281         readCapabilityRid(local, &cap_rid, 1);
6282         /* Older firmware doesn't support this...
6283         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6284                 return -EOPNOTSUPP;
6285         } */
6286         readConfigRid(local, 1);
6287
6288         /* Basic checking: do we have a key to set ?
6289          * Note : with the new API, it's impossible to get a NULL pointer.
6290          * Therefore, we need to check a key size == 0 instead.
6291          * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6292          * when no key is present (only change flags), but older versions
6293          * don't do it. - Jean II */
6294         if (dwrq->length > 0) {
6295                 wep_key_t key;
6296                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6297                 int current_index = get_wep_key(local, 0xffff);
6298                 /* Check the size of the key */
6299                 if (dwrq->length > MAX_KEY_SIZE) {
6300                         return -EINVAL;
6301                 }
6302                 /* Check the index (none -> use current) */
6303                 if (!valid_index(&cap_rid, index))
6304                         index = current_index;
6305                 /* Set the length */
6306                 if (dwrq->length > MIN_KEY_SIZE)
6307                         key.len = MAX_KEY_SIZE;
6308                 else
6309                         if (dwrq->length > 0)
6310                                 key.len = MIN_KEY_SIZE;
6311                         else
6312                                 /* Disable the key */
6313                                 key.len = 0;
6314                 /* Check if the key is not marked as invalid */
6315                 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6316                         /* Cleanup */
6317                         memset(key.key, 0, MAX_KEY_SIZE);
6318                         /* Copy the key in the driver */
6319                         memcpy(key.key, extra, dwrq->length);
6320                         /* Send the key to the card */
6321                         set_wep_key(local, index, key.key, key.len, perm, 1);
6322                 }
6323                 /* WE specify that if a valid key is set, encryption
6324                  * should be enabled (user may turn it off later)
6325                  * This is also how "iwconfig ethX key on" works */
6326                 if((index == current_index) && (key.len > 0) &&
6327                    (local->config.authType == AUTH_OPEN)) {
6328                         local->config.authType = AUTH_ENCRYPT;
6329                 }
6330         } else {
6331                 /* Do we want to just set the transmit key index ? */
6332                 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6333                 if (valid_index(&cap_rid, index)) {
6334                         set_wep_key(local, index, NULL, 0, perm, 1);
6335                 } else
6336                         /* Don't complain if only change the mode */
6337                         if (!(dwrq->flags & IW_ENCODE_MODE))
6338                                 return -EINVAL;
6339         }
6340         /* Read the flags */
6341         if(dwrq->flags & IW_ENCODE_DISABLED)
6342                 local->config.authType = AUTH_OPEN;     // disable encryption
6343         if(dwrq->flags & IW_ENCODE_RESTRICTED)
6344                 local->config.authType = AUTH_SHAREDKEY;        // Only Both
6345         if(dwrq->flags & IW_ENCODE_OPEN)
6346                 local->config.authType = AUTH_ENCRYPT;  // Only Wep
6347         /* Commit the changes to flags if needed */
6348         if (local->config.authType != currentAuthType)
6349                 set_bit (FLAG_COMMIT, &local->flags);
6350         return -EINPROGRESS;            /* Call commit handler */
6351 }
6352
6353 /*------------------------------------------------------------------*/
6354 /*
6355  * Wireless Handler : get Encryption Key
6356  */
6357 static int airo_get_encode(struct net_device *dev,
6358                            struct iw_request_info *info,
6359                            struct iw_point *dwrq,
6360                            char *extra)
6361 {
6362         struct airo_info *local = dev->priv;
6363         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6364         CapabilityRid cap_rid;          /* Card capability info */
6365
6366         /* Is it supported ? */
6367         readCapabilityRid(local, &cap_rid, 1);
6368         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6369                 return -EOPNOTSUPP;
6370         }
6371         readConfigRid(local, 1);
6372         /* Check encryption mode */
6373         switch(local->config.authType)  {
6374                 case AUTH_ENCRYPT:
6375                         dwrq->flags = IW_ENCODE_OPEN;
6376                         break;
6377                 case AUTH_SHAREDKEY:
6378                         dwrq->flags = IW_ENCODE_RESTRICTED;
6379                         break;
6380                 default:
6381                 case AUTH_OPEN:
6382                         dwrq->flags = IW_ENCODE_DISABLED;
6383                         break;
6384         }
6385         /* We can't return the key, so set the proper flag and return zero */
6386         dwrq->flags |= IW_ENCODE_NOKEY;
6387         memset(extra, 0, 16);
6388
6389         /* Which key do we want ? -1 -> tx index */
6390         if (!valid_index(&cap_rid, index))
6391                 index = get_wep_key(local, 0xffff);
6392         dwrq->flags |= index + 1;
6393         /* Copy the key to the user buffer */
6394         dwrq->length = get_wep_key(local, index);
6395         if (dwrq->length > 16) {
6396                 dwrq->length=0;
6397         }
6398         return 0;
6399 }
6400
6401 /*------------------------------------------------------------------*/
6402 /*
6403  * Wireless Handler : set extended Encryption parameters
6404  */
6405 static int airo_set_encodeext(struct net_device *dev,
6406                            struct iw_request_info *info,
6407                             union iwreq_data *wrqu,
6408                             char *extra)
6409 {
6410         struct airo_info *local = dev->priv;
6411         struct iw_point *encoding = &wrqu->encoding;
6412         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6413         CapabilityRid cap_rid;          /* Card capability info */
6414         int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6415         __le16 currentAuthType = local->config.authType;
6416         int idx, key_len, alg = ext->alg, set_key = 1;
6417         wep_key_t key;
6418
6419         /* Is WEP supported ? */
6420         readCapabilityRid(local, &cap_rid, 1);
6421         /* Older firmware doesn't support this...
6422         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6423                 return -EOPNOTSUPP;
6424         } */
6425         readConfigRid(local, 1);
6426
6427         /* Determine and validate the key index */
6428         idx = encoding->flags & IW_ENCODE_INDEX;
6429         if (idx) {
6430                 if (!valid_index(&cap_rid, idx - 1))
6431                         return -EINVAL;
6432                 idx--;
6433         } else
6434                 idx = get_wep_key(local, 0xffff);
6435
6436         if (encoding->flags & IW_ENCODE_DISABLED)
6437                 alg = IW_ENCODE_ALG_NONE;
6438
6439         if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
6440                 /* Only set transmit key index here, actual
6441                  * key is set below if needed.
6442                  */
6443                 set_wep_key(local, idx, NULL, 0, perm, 1);
6444                 set_key = ext->key_len > 0 ? 1 : 0;
6445         }
6446
6447         if (set_key) {
6448                 /* Set the requested key first */
6449                 memset(key.key, 0, MAX_KEY_SIZE);
6450                 switch (alg) {
6451                 case IW_ENCODE_ALG_NONE:
6452                         key.len = 0;
6453                         break;
6454                 case IW_ENCODE_ALG_WEP:
6455                         if (ext->key_len > MIN_KEY_SIZE) {
6456                                 key.len = MAX_KEY_SIZE;
6457                         } else if (ext->key_len > 0) {
6458                                 key.len = MIN_KEY_SIZE;
6459                         } else {
6460                                 return -EINVAL;
6461                         }
6462                         key_len = min (ext->key_len, key.len);
6463                         memcpy(key.key, ext->key, key_len);
6464                         break;
6465                 default:
6466                         return -EINVAL;
6467                 }
6468                 /* Send the key to the card */
6469                 set_wep_key(local, idx, key.key, key.len, perm, 1);
6470         }
6471
6472         /* Read the flags */
6473         if(encoding->flags & IW_ENCODE_DISABLED)
6474                 local->config.authType = AUTH_OPEN;     // disable encryption
6475         if(encoding->flags & IW_ENCODE_RESTRICTED)
6476                 local->config.authType = AUTH_SHAREDKEY;        // Only Both
6477         if(encoding->flags & IW_ENCODE_OPEN)
6478                 local->config.authType = AUTH_ENCRYPT;  // Only Wep
6479         /* Commit the changes to flags if needed */
6480         if (local->config.authType != currentAuthType)
6481                 set_bit (FLAG_COMMIT, &local->flags);
6482
6483         return -EINPROGRESS;
6484 }
6485
6486
6487 /*------------------------------------------------------------------*/
6488 /*
6489  * Wireless Handler : get extended Encryption parameters
6490  */
6491 static int airo_get_encodeext(struct net_device *dev,
6492                             struct iw_request_info *info,
6493                             union iwreq_data *wrqu,
6494                             char *extra)
6495 {
6496         struct airo_info *local = dev->priv;
6497         struct iw_point *encoding = &wrqu->encoding;
6498         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6499         CapabilityRid cap_rid;          /* Card capability info */
6500         int idx, max_key_len;
6501
6502         /* Is it supported ? */
6503         readCapabilityRid(local, &cap_rid, 1);
6504         if(!(cap_rid.softCap & cpu_to_le16(2))) {
6505                 return -EOPNOTSUPP;
6506         }
6507         readConfigRid(local, 1);
6508
6509         max_key_len = encoding->length - sizeof(*ext);
6510         if (max_key_len < 0)
6511                 return -EINVAL;
6512
6513         idx = encoding->flags & IW_ENCODE_INDEX;
6514         if (idx) {
6515                 if (!valid_index(&cap_rid, idx - 1))
6516                         return -EINVAL;
6517                 idx--;
6518         } else
6519                 idx = get_wep_key(local, 0xffff);
6520
6521         encoding->flags = idx + 1;
6522         memset(ext, 0, sizeof(*ext));
6523
6524         /* Check encryption mode */
6525         switch(local->config.authType) {
6526                 case AUTH_ENCRYPT:
6527                         encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6528                         break;
6529                 case AUTH_SHAREDKEY:
6530                         encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6531                         break;
6532                 default:
6533                 case AUTH_OPEN:
6534                         encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
6535                         break;
6536         }
6537         /* We can't return the key, so set the proper flag and return zero */
6538         encoding->flags |= IW_ENCODE_NOKEY;
6539         memset(extra, 0, 16);
6540         
6541         /* Copy the key to the user buffer */
6542         ext->key_len = get_wep_key(local, idx);
6543         if (ext->key_len > 16) {
6544                 ext->key_len=0;
6545         }
6546
6547         return 0;
6548 }
6549
6550
6551 /*------------------------------------------------------------------*/
6552 /*
6553  * Wireless Handler : set extended authentication parameters
6554  */
6555 static int airo_set_auth(struct net_device *dev,
6556                                struct iw_request_info *info,
6557                                union iwreq_data *wrqu, char *extra)
6558 {
6559         struct airo_info *local = dev->priv;
6560         struct iw_param *param = &wrqu->param;
6561         __le16 currentAuthType = local->config.authType;
6562
6563         switch (param->flags & IW_AUTH_INDEX) {
6564         case IW_AUTH_WPA_VERSION:
6565         case IW_AUTH_CIPHER_PAIRWISE:
6566         case IW_AUTH_CIPHER_GROUP:
6567         case IW_AUTH_KEY_MGMT:
6568         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6569         case IW_AUTH_PRIVACY_INVOKED:
6570                 /*
6571                  * airo does not use these parameters
6572                  */
6573                 break;
6574
6575         case IW_AUTH_DROP_UNENCRYPTED:
6576                 if (param->value) {
6577                         /* Only change auth type if unencrypted */
6578                         if (currentAuthType == AUTH_OPEN)
6579                                 local->config.authType = AUTH_ENCRYPT;
6580                 } else {
6581                         local->config.authType = AUTH_OPEN;
6582                 }
6583
6584                 /* Commit the changes to flags if needed */
6585                 if (local->config.authType != currentAuthType)
6586                         set_bit (FLAG_COMMIT, &local->flags);
6587                 break;
6588
6589         case IW_AUTH_80211_AUTH_ALG: {
6590                         /* FIXME: What about AUTH_OPEN?  This API seems to
6591                          * disallow setting our auth to AUTH_OPEN.
6592                          */
6593                         if (param->value & IW_AUTH_ALG_SHARED_KEY) {
6594                                 local->config.authType = AUTH_SHAREDKEY;
6595                         } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
6596                                 local->config.authType = AUTH_ENCRYPT;
6597                         } else
6598                                 return -EINVAL;
6599                         break;
6600
6601                         /* Commit the changes to flags if needed */
6602                         if (local->config.authType != currentAuthType)
6603                                 set_bit (FLAG_COMMIT, &local->flags);
6604                 }
6605
6606         case IW_AUTH_WPA_ENABLED:
6607                 /* Silently accept disable of WPA */
6608                 if (param->value > 0)
6609                         return -EOPNOTSUPP;
6610                 break;
6611
6612         default:
6613                 return -EOPNOTSUPP;
6614         }
6615         return -EINPROGRESS;
6616 }
6617
6618
6619 /*------------------------------------------------------------------*/
6620 /*
6621  * Wireless Handler : get extended authentication parameters
6622  */
6623 static int airo_get_auth(struct net_device *dev,
6624                                struct iw_request_info *info,
6625                                union iwreq_data *wrqu, char *extra)
6626 {
6627         struct airo_info *local = dev->priv;
6628         struct iw_param *param = &wrqu->param;
6629         __le16 currentAuthType = local->config.authType;
6630
6631         switch (param->flags & IW_AUTH_INDEX) {
6632         case IW_AUTH_DROP_UNENCRYPTED:
6633                 switch (currentAuthType) {
6634                 case AUTH_SHAREDKEY:
6635                 case AUTH_ENCRYPT:
6636                         param->value = 1;
6637                         break;
6638                 default:
6639                         param->value = 0;
6640                         break;
6641                 }
6642                 break;
6643
6644         case IW_AUTH_80211_AUTH_ALG:
6645                 switch (currentAuthType) {
6646                 case AUTH_SHAREDKEY:
6647                         param->value = IW_AUTH_ALG_SHARED_KEY;
6648                         break;
6649                 case AUTH_ENCRYPT:
6650                 default:
6651                         param->value = IW_AUTH_ALG_OPEN_SYSTEM;
6652                         break;
6653                 }
6654                 break;
6655
6656         case IW_AUTH_WPA_ENABLED:
6657                 param->value = 0;
6658                 break;
6659
6660         default:
6661                 return -EOPNOTSUPP;
6662         }
6663         return 0;
6664 }
6665
6666
6667 /*------------------------------------------------------------------*/
6668 /*
6669  * Wireless Handler : set Tx-Power
6670  */
6671 static int airo_set_txpow(struct net_device *dev,
6672                           struct iw_request_info *info,
6673                           struct iw_param *vwrq,
6674                           char *extra)
6675 {
6676         struct airo_info *local = dev->priv;
6677         CapabilityRid cap_rid;          /* Card capability info */
6678         int i;
6679         int rc = -EINVAL;
6680         __le16 v = cpu_to_le16(vwrq->value);
6681
6682         readCapabilityRid(local, &cap_rid, 1);
6683
6684         if (vwrq->disabled) {
6685                 set_bit (FLAG_RADIO_OFF, &local->flags);
6686                 set_bit (FLAG_COMMIT, &local->flags);
6687                 return -EINPROGRESS;            /* Call commit handler */
6688         }
6689         if (vwrq->flags != IW_TXPOW_MWATT) {
6690                 return -EINVAL;
6691         }
6692         clear_bit (FLAG_RADIO_OFF, &local->flags);
6693         for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
6694                 if (v == cap_rid.txPowerLevels[i]) {
6695                         readConfigRid(local, 1);
6696                         local->config.txPower = v;
6697                         set_bit (FLAG_COMMIT, &local->flags);
6698                         rc = -EINPROGRESS;      /* Call commit handler */
6699                         break;
6700                 }
6701         return rc;
6702 }
6703
6704 /*------------------------------------------------------------------*/
6705 /*
6706  * Wireless Handler : get Tx-Power
6707  */
6708 static int airo_get_txpow(struct net_device *dev,
6709                           struct iw_request_info *info,
6710                           struct iw_param *vwrq,
6711                           char *extra)
6712 {
6713         struct airo_info *local = dev->priv;
6714
6715         readConfigRid(local, 1);
6716         vwrq->value = le16_to_cpu(local->config.txPower);
6717         vwrq->fixed = 1;        /* No power control */
6718         vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6719         vwrq->flags = IW_TXPOW_MWATT;
6720
6721         return 0;
6722 }
6723
6724 /*------------------------------------------------------------------*/
6725 /*
6726  * Wireless Handler : set Retry limits
6727  */
6728 static int airo_set_retry(struct net_device *dev,
6729                           struct iw_request_info *info,
6730                           struct iw_param *vwrq,
6731                           char *extra)
6732 {
6733         struct airo_info *local = dev->priv;
6734         int rc = -EINVAL;
6735
6736         if(vwrq->disabled) {
6737                 return -EINVAL;
6738         }
6739         readConfigRid(local, 1);
6740         if(vwrq->flags & IW_RETRY_LIMIT) {
6741                 __le16 v = cpu_to_le16(vwrq->value);
6742                 if(vwrq->flags & IW_RETRY_LONG)
6743                         local->config.longRetryLimit = v;
6744                 else if (vwrq->flags & IW_RETRY_SHORT)
6745                         local->config.shortRetryLimit = v;
6746                 else {
6747                         /* No modifier : set both */
6748                         local->config.longRetryLimit = v;
6749                         local->config.shortRetryLimit = v;
6750                 }
6751                 set_bit (FLAG_COMMIT, &local->flags);
6752                 rc = -EINPROGRESS;              /* Call commit handler */
6753         }
6754         if(vwrq->flags & IW_RETRY_LIFETIME) {
6755                 local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
6756                 set_bit (FLAG_COMMIT, &local->flags);
6757                 rc = -EINPROGRESS;              /* Call commit handler */
6758         }
6759         return rc;
6760 }
6761
6762 /*------------------------------------------------------------------*/
6763 /*
6764  * Wireless Handler : get Retry limits
6765  */
6766 static int airo_get_retry(struct net_device *dev,
6767                           struct iw_request_info *info,
6768                           struct iw_param *vwrq,
6769                           char *extra)
6770 {
6771         struct airo_info *local = dev->priv;
6772
6773         vwrq->disabled = 0;      /* Can't be disabled */
6774
6775         readConfigRid(local, 1);
6776         /* Note : by default, display the min retry number */
6777         if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6778                 vwrq->flags = IW_RETRY_LIFETIME;
6779                 vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
6780         } else if((vwrq->flags & IW_RETRY_LONG)) {
6781                 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6782                 vwrq->value = le16_to_cpu(local->config.longRetryLimit);
6783         } else {
6784                 vwrq->flags = IW_RETRY_LIMIT;
6785                 vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
6786                 if(local->config.shortRetryLimit != local->config.longRetryLimit)
6787                         vwrq->flags |= IW_RETRY_SHORT;
6788         }
6789
6790         return 0;
6791 }
6792
6793 /*------------------------------------------------------------------*/
6794 /*
6795  * Wireless Handler : get range info
6796  */
6797 static int airo_get_range(struct net_device *dev,
6798                           struct iw_request_info *info,
6799                           struct iw_point *dwrq,
6800                           char *extra)
6801 {
6802         struct airo_info *local = dev->priv;
6803         struct iw_range *range = (struct iw_range *) extra;
6804         CapabilityRid cap_rid;          /* Card capability info */
6805         int             i;
6806         int             k;
6807
6808         readCapabilityRid(local, &cap_rid, 1);
6809
6810         dwrq->length = sizeof(struct iw_range);
6811         memset(range, 0, sizeof(*range));
6812         range->min_nwid = 0x0000;
6813         range->max_nwid = 0x0000;
6814         range->num_channels = 14;
6815         /* Should be based on cap_rid.country to give only
6816          * what the current card support */
6817         k = 0;
6818         for(i = 0; i < 14; i++) {
6819                 range->freq[k].i = i + 1; /* List index */
6820                 range->freq[k].m = frequency_list[i] * 100000;
6821                 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
6822         }
6823         range->num_frequency = k;
6824
6825         range->sensitivity = 65535;
6826
6827         /* Hum... Should put the right values there */
6828         if (local->rssi)
6829                 range->max_qual.qual = 100;     /* % */
6830         else
6831                 range->max_qual.qual = airo_get_max_quality(&cap_rid);
6832         range->max_qual.level = 0x100 - 120;    /* -120 dBm */
6833         range->max_qual.noise = 0x100 - 120;    /* -120 dBm */
6834
6835         /* Experimental measurements - boundary 11/5.5 Mb/s */
6836         /* Note : with or without the (local->rssi), results
6837          * are somewhat different. - Jean II */
6838         if (local->rssi) {
6839                 range->avg_qual.qual = 50;              /* % */
6840                 range->avg_qual.level = 0x100 - 70;     /* -70 dBm */
6841         } else {
6842                 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6843                 range->avg_qual.level = 0x100 - 80;     /* -80 dBm */
6844         }
6845         range->avg_qual.noise = 0x100 - 85;             /* -85 dBm */
6846
6847         for(i = 0 ; i < 8 ; i++) {
6848                 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6849                 if(range->bitrate[i] == 0)
6850                         break;
6851         }
6852         range->num_bitrates = i;
6853
6854         /* Set an indication of the max TCP throughput
6855          * in bit/s that we can expect using this interface.
6856          * May be use for QoS stuff... Jean II */
6857         if(i > 2)
6858                 range->throughput = 5000 * 1000;
6859         else
6860                 range->throughput = 1500 * 1000;
6861
6862         range->min_rts = 0;
6863         range->max_rts = AIRO_DEF_MTU;
6864         range->min_frag = 256;
6865         range->max_frag = AIRO_DEF_MTU;
6866
6867         if(cap_rid.softCap & cpu_to_le16(2)) {
6868                 // WEP: RC4 40 bits
6869                 range->encoding_size[0] = 5;
6870                 // RC4 ~128 bits
6871                 if (cap_rid.softCap & cpu_to_le16(0x100)) {
6872                         range->encoding_size[1] = 13;
6873                         range->num_encoding_sizes = 2;
6874                 } else
6875                         range->num_encoding_sizes = 1;
6876                 range->max_encoding_tokens =
6877                         cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
6878         } else {
6879                 range->num_encoding_sizes = 0;
6880                 range->max_encoding_tokens = 0;
6881         }
6882         range->min_pmp = 0;
6883         range->max_pmp = 5000000;       /* 5 secs */
6884         range->min_pmt = 0;
6885         range->max_pmt = 65535 * 1024;  /* ??? */
6886         range->pmp_flags = IW_POWER_PERIOD;
6887         range->pmt_flags = IW_POWER_TIMEOUT;
6888         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
6889
6890         /* Transmit Power - values are in mW */
6891         for(i = 0 ; i < 8 ; i++) {
6892                 range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
6893                 if(range->txpower[i] == 0)
6894                         break;
6895         }
6896         range->num_txpower = i;
6897         range->txpower_capa = IW_TXPOW_MWATT;
6898         range->we_version_source = 19;
6899         range->we_version_compiled = WIRELESS_EXT;
6900         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
6901         range->retry_flags = IW_RETRY_LIMIT;
6902         range->r_time_flags = IW_RETRY_LIFETIME;
6903         range->min_retry = 1;
6904         range->max_retry = 65535;
6905         range->min_r_time = 1024;
6906         range->max_r_time = 65535 * 1024;
6907
6908         /* Event capability (kernel + driver) */
6909         range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
6910                                 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
6911                                 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
6912                                 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
6913         range->event_capa[1] = IW_EVENT_CAPA_K_1;
6914         range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
6915         return 0;
6916 }
6917
6918 /*------------------------------------------------------------------*/
6919 /*
6920  * Wireless Handler : set Power Management
6921  */
6922 static int airo_set_power(struct net_device *dev,
6923                           struct iw_request_info *info,
6924                           struct iw_param *vwrq,
6925                           char *extra)
6926 {
6927         struct airo_info *local = dev->priv;
6928
6929         readConfigRid(local, 1);
6930         if (vwrq->disabled) {
6931                 if (sniffing_mode(local))
6932                         return -EINVAL;
6933                 local->config.powerSaveMode = POWERSAVE_CAM;
6934                 local->config.rmode &= ~RXMODE_MASK;
6935                 local->config.rmode |= RXMODE_BC_MC_ADDR;
6936                 set_bit (FLAG_COMMIT, &local->flags);
6937                 return -EINPROGRESS;            /* Call commit handler */
6938         }
6939         if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6940                 local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
6941                 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6942                 set_bit (FLAG_COMMIT, &local->flags);
6943         } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
6944                 local->config.fastListenInterval =
6945                 local->config.listenInterval =
6946                         cpu_to_le16((vwrq->value + 500) / 1024);
6947                 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6948                 set_bit (FLAG_COMMIT, &local->flags);
6949         }
6950         switch (vwrq->flags & IW_POWER_MODE) {
6951                 case IW_POWER_UNICAST_R:
6952                         if (sniffing_mode(local))
6953                                 return -EINVAL;
6954                         local->config.rmode &= ~RXMODE_MASK;
6955                         local->config.rmode |= RXMODE_ADDR;
6956                         set_bit (FLAG_COMMIT, &local->flags);
6957                         break;
6958                 case IW_POWER_ALL_R:
6959                         if (sniffing_mode(local))
6960                                 return -EINVAL;
6961                         local->config.rmode &= ~RXMODE_MASK;
6962                         local->config.rmode |= RXMODE_BC_MC_ADDR;
6963                         set_bit (FLAG_COMMIT, &local->flags);
6964                 case IW_POWER_ON:
6965                         /* This is broken, fixme ;-) */
6966                         break;
6967                 default:
6968                         return -EINVAL;
6969         }
6970         // Note : we may want to factor local->need_commit here
6971         // Note2 : may also want to factor RXMODE_RFMON test
6972         return -EINPROGRESS;            /* Call commit handler */
6973 }
6974
6975 /*------------------------------------------------------------------*/
6976 /*
6977  * Wireless Handler : get Power Management
6978  */
6979 static int airo_get_power(struct net_device *dev,
6980                           struct iw_request_info *info,
6981                           struct iw_param *vwrq,
6982                           char *extra)
6983 {
6984         struct airo_info *local = dev->priv;
6985         __le16 mode;
6986
6987         readConfigRid(local, 1);
6988         mode = local->config.powerSaveMode;
6989         if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
6990                 return 0;
6991         if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6992                 vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
6993                 vwrq->flags = IW_POWER_TIMEOUT;
6994         } else {
6995                 vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
6996                 vwrq->flags = IW_POWER_PERIOD;
6997         }
6998         if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
6999                 vwrq->flags |= IW_POWER_UNICAST_R;
7000         else
7001                 vwrq->flags |= IW_POWER_ALL_R;
7002
7003         return 0;
7004 }
7005
7006 /*------------------------------------------------------------------*/
7007 /*
7008  * Wireless Handler : set Sensitivity
7009  */
7010 static int airo_set_sens(struct net_device *dev,
7011                          struct iw_request_info *info,
7012                          struct iw_param *vwrq,
7013                          char *extra)
7014 {
7015         struct airo_info *local = dev->priv;
7016
7017         readConfigRid(local, 1);
7018         local->config.rssiThreshold =
7019                 cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
7020         set_bit (FLAG_COMMIT, &local->flags);
7021
7022         return -EINPROGRESS;            /* Call commit handler */
7023 }
7024
7025 /*------------------------------------------------------------------*/
7026 /*
7027  * Wireless Handler : get Sensitivity
7028  */
7029 static int airo_get_sens(struct net_device *dev,
7030                          struct iw_request_info *info,
7031                          struct iw_param *vwrq,
7032                          char *extra)
7033 {
7034         struct airo_info *local = dev->priv;
7035
7036         readConfigRid(local, 1);
7037         vwrq->value = le16_to_cpu(local->config.rssiThreshold);
7038         vwrq->disabled = (vwrq->value == 0);
7039         vwrq->fixed = 1;
7040
7041         return 0;
7042 }
7043
7044 /*------------------------------------------------------------------*/
7045 /*
7046  * Wireless Handler : get AP List
7047  * Note : this is deprecated in favor of IWSCAN
7048  */
7049 static int airo_get_aplist(struct net_device *dev,
7050                            struct iw_request_info *info,
7051                            struct iw_point *dwrq,
7052                            char *extra)
7053 {
7054         struct airo_info *local = dev->priv;
7055         struct sockaddr *address = (struct sockaddr *) extra;
7056         struct iw_quality qual[IW_MAX_AP];
7057         BSSListRid BSSList;
7058         int i;
7059         int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7060
7061         for (i = 0; i < IW_MAX_AP; i++) {
7062                 u16 dBm;
7063                 if (readBSSListRid(local, loseSync, &BSSList))
7064                         break;
7065                 loseSync = 0;
7066                 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
7067                 address[i].sa_family = ARPHRD_ETHER;
7068                 dBm = le16_to_cpu(BSSList.dBm);
7069                 if (local->rssi) {
7070                         qual[i].level = 0x100 - dBm;
7071                         qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
7072                         qual[i].updated = IW_QUAL_QUAL_UPDATED
7073                                         | IW_QUAL_LEVEL_UPDATED
7074                                         | IW_QUAL_DBM;
7075                 } else {
7076                         qual[i].level = (dBm + 321) / 2;
7077                         qual[i].qual = 0;
7078                         qual[i].updated = IW_QUAL_QUAL_INVALID
7079                                         | IW_QUAL_LEVEL_UPDATED
7080                                         | IW_QUAL_DBM;
7081                 }
7082                 qual[i].noise = local->wstats.qual.noise;
7083                 if (BSSList.index == cpu_to_le16(0xffff))
7084                         break;
7085         }
7086         if (!i) {
7087                 StatusRid status_rid;           /* Card status info */
7088                 readStatusRid(local, &status_rid, 1);
7089                 for (i = 0;
7090                      i < min(IW_MAX_AP, 4) &&
7091                              (status_rid.bssid[i][0]
7092                               & status_rid.bssid[i][1]
7093                               & status_rid.bssid[i][2]
7094                               & status_rid.bssid[i][3]
7095                               & status_rid.bssid[i][4]
7096                               & status_rid.bssid[i][5])!=0xff &&
7097                              (status_rid.bssid[i][0]
7098                               | status_rid.bssid[i][1]
7099                               | status_rid.bssid[i][2]
7100                               | status_rid.bssid[i][3]
7101                               | status_rid.bssid[i][4]
7102                               | status_rid.bssid[i][5]);
7103                      i++) {
7104                         memcpy(address[i].sa_data,
7105                                status_rid.bssid[i], ETH_ALEN);
7106                         address[i].sa_family = ARPHRD_ETHER;
7107                 }
7108         } else {
7109                 dwrq->flags = 1; /* Should be define'd */
7110                 memcpy(extra + sizeof(struct sockaddr)*i,
7111                        &qual,  sizeof(struct iw_quality)*i);
7112         }
7113         dwrq->length = i;
7114
7115         return 0;
7116 }
7117
7118 /*------------------------------------------------------------------*/
7119 /*
7120  * Wireless Handler : Initiate Scan
7121  */
7122 static int airo_set_scan(struct net_device *dev,
7123                          struct iw_request_info *info,
7124                          struct iw_param *vwrq,
7125                          char *extra)
7126 {
7127         struct airo_info *ai = dev->priv;
7128         Cmd cmd;
7129         Resp rsp;
7130         int wake = 0;
7131
7132         /* Note : you may have realised that, as this is a SET operation,
7133          * this is privileged and therefore a normal user can't
7134          * perform scanning.
7135          * This is not an error, while the device perform scanning,
7136          * traffic doesn't flow, so it's a perfect DoS...
7137          * Jean II */
7138         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
7139
7140         if (down_interruptible(&ai->sem))
7141                 return -ERESTARTSYS;
7142
7143         /* If there's already a scan in progress, don't
7144          * trigger another one. */
7145         if (ai->scan_timeout > 0)
7146                 goto out;
7147
7148         /* Initiate a scan command */
7149         ai->scan_timeout = RUN_AT(3*HZ);
7150         memset(&cmd, 0, sizeof(cmd));
7151         cmd.cmd=CMD_LISTBSS;
7152         issuecommand(ai, &cmd, &rsp);
7153         wake = 1;
7154
7155 out:
7156         up(&ai->sem);
7157         if (wake)
7158                 wake_up_interruptible(&ai->thr_wait);
7159         return 0;
7160 }
7161
7162 /*------------------------------------------------------------------*/
7163 /*
7164  * Translate scan data returned from the card to a card independent
7165  * format that the Wireless Tools will understand - Jean II
7166  */
7167 static inline char *airo_translate_scan(struct net_device *dev,
7168                                         char *current_ev,
7169                                         char *end_buf,
7170                                         BSSListRid *bss)
7171 {
7172         struct airo_info *ai = dev->priv;
7173         struct iw_event         iwe;            /* Temporary buffer */
7174         __le16                  capabilities;
7175         char *                  current_val;    /* For rates */
7176         int                     i;
7177         char *          buf;
7178         u16 dBm;
7179
7180         /* First entry *MUST* be the AP MAC address */
7181         iwe.cmd = SIOCGIWAP;
7182         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7183         memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7184         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
7185
7186         /* Other entries will be displayed in the order we give them */
7187
7188         /* Add the ESSID */
7189         iwe.u.data.length = bss->ssidLen;
7190         if(iwe.u.data.length > 32)
7191                 iwe.u.data.length = 32;
7192         iwe.cmd = SIOCGIWESSID;
7193         iwe.u.data.flags = 1;
7194         current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
7195
7196         /* Add mode */
7197         iwe.cmd = SIOCGIWMODE;
7198         capabilities = bss->cap;
7199         if(capabilities & (CAP_ESS | CAP_IBSS)) {
7200                 if(capabilities & CAP_ESS)
7201                         iwe.u.mode = IW_MODE_MASTER;
7202                 else
7203                         iwe.u.mode = IW_MODE_ADHOC;
7204                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
7205         }
7206
7207         /* Add frequency */
7208         iwe.cmd = SIOCGIWFREQ;
7209         iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7210         /* iwe.u.freq.m containt the channel (starting 1), our 
7211          * frequency_list array start at index 0...
7212          */
7213         iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
7214         iwe.u.freq.e = 1;
7215         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
7216
7217         dBm = le16_to_cpu(bss->dBm);
7218
7219         /* Add quality statistics */
7220         iwe.cmd = IWEVQUAL;
7221         if (ai->rssi) {
7222                 iwe.u.qual.level = 0x100 - dBm;
7223                 iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
7224                 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
7225                                 | IW_QUAL_LEVEL_UPDATED
7226                                 | IW_QUAL_DBM;
7227         } else {
7228                 iwe.u.qual.level = (dBm + 321) / 2;
7229                 iwe.u.qual.qual = 0;
7230                 iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
7231                                 | IW_QUAL_LEVEL_UPDATED
7232                                 | IW_QUAL_DBM;
7233         }
7234         iwe.u.qual.noise = ai->wstats.qual.noise;
7235         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
7236
7237         /* Add encryption capability */
7238         iwe.cmd = SIOCGIWENCODE;
7239         if(capabilities & CAP_PRIVACY)
7240                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
7241         else
7242                 iwe.u.data.flags = IW_ENCODE_DISABLED;
7243         iwe.u.data.length = 0;
7244         current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
7245
7246         /* Rate : stuffing multiple values in a single event require a bit
7247          * more of magic - Jean II */
7248         current_val = current_ev + IW_EV_LCP_LEN;
7249
7250         iwe.cmd = SIOCGIWRATE;
7251         /* Those two flags are ignored... */
7252         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
7253         /* Max 8 values */
7254         for(i = 0 ; i < 8 ; i++) {
7255                 /* NULL terminated */
7256                 if(bss->rates[i] == 0)
7257                         break;
7258                 /* Bit rate given in 500 kb/s units (+ 0x80) */
7259                 iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7260                 /* Add new value to event */
7261                 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
7262         }
7263         /* Check if we added any event */
7264         if((current_val - current_ev) > IW_EV_LCP_LEN)
7265                 current_ev = current_val;
7266
7267         /* Beacon interval */
7268         buf = kmalloc(30, GFP_KERNEL);
7269         if (buf) {
7270                 iwe.cmd = IWEVCUSTOM;
7271                 sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7272                 iwe.u.data.length = strlen(buf);
7273                 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
7274                 kfree(buf);
7275         }
7276
7277         /* Put WPA/RSN Information Elements into the event stream */
7278         if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
7279                 unsigned int num_null_ies = 0;
7280                 u16 length = sizeof (bss->extra.iep);
7281                 struct ieee80211_info_element *info_element =
7282                         (struct ieee80211_info_element *) &bss->extra.iep;
7283
7284                 while ((length >= sizeof(*info_element)) && (num_null_ies < 2)) {
7285                         if (sizeof(*info_element) + info_element->len > length) {
7286                                 /* Invalid element, don't continue parsing IE */
7287                                 break;
7288                         }
7289
7290                         switch (info_element->id) {
7291                         case MFIE_TYPE_SSID:
7292                                 /* Two zero-length SSID elements
7293                                  * mean we're done parsing elements */
7294                                 if (!info_element->len)
7295                                         num_null_ies++;
7296                                 break;
7297
7298                         case MFIE_TYPE_GENERIC:
7299                                 if (info_element->len >= 4 &&
7300                                     info_element->data[0] == 0x00 &&
7301                                     info_element->data[1] == 0x50 &&
7302                                     info_element->data[2] == 0xf2 &&
7303                                     info_element->data[3] == 0x01) {
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                                 }
7310                                 break;
7311
7312                         case MFIE_TYPE_RSN:
7313                                 iwe.cmd = IWEVGENIE;
7314                                 iwe.u.data.length = min(info_element->len + 2,
7315                                                           MAX_WPA_IE_LEN);
7316                                 current_ev = iwe_stream_add_point(current_ev, end_buf,
7317                                                 &iwe, (char *) info_element);
7318                                 break;
7319
7320                         default:
7321                                 break;
7322                         }
7323
7324                         length -= sizeof(*info_element) + info_element->len;
7325                         info_element =
7326                             (struct ieee80211_info_element *)&info_element->
7327                             data[info_element->len];
7328                 }
7329         }
7330         return current_ev;
7331 }
7332
7333 /*------------------------------------------------------------------*/
7334 /*
7335  * Wireless Handler : Read Scan Results
7336  */
7337 static int airo_get_scan(struct net_device *dev,
7338                          struct iw_request_info *info,
7339                          struct iw_point *dwrq,
7340                          char *extra)
7341 {
7342         struct airo_info *ai = dev->priv;
7343         BSSListElement *net;
7344         int err = 0;
7345         char *current_ev = extra;
7346
7347         /* If a scan is in-progress, return -EAGAIN */
7348         if (ai->scan_timeout > 0)
7349                 return -EAGAIN;
7350
7351         if (down_interruptible(&ai->sem))
7352                 return -EAGAIN;
7353
7354         list_for_each_entry (net, &ai->network_list, list) {
7355                 /* Translate to WE format this entry */
7356                 current_ev = airo_translate_scan(dev, current_ev,
7357                                                  extra + dwrq->length,
7358                                                  &net->bss);
7359
7360                 /* Check if there is space for one more entry */
7361                 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7362                         /* Ask user space to try again with a bigger buffer */
7363                         err = -E2BIG;
7364                         goto out;
7365                 }
7366         }
7367
7368         /* Length of data */
7369         dwrq->length = (current_ev - extra);
7370         dwrq->flags = 0;        /* todo */
7371
7372 out:
7373         up(&ai->sem);
7374         return err;
7375 }
7376
7377 /*------------------------------------------------------------------*/
7378 /*
7379  * Commit handler : called after a bunch of SET operations
7380  */
7381 static int airo_config_commit(struct net_device *dev,
7382                               struct iw_request_info *info,     /* NULL */
7383                               void *zwrq,                       /* NULL */
7384                               char *extra)                      /* NULL */
7385 {
7386         struct airo_info *local = dev->priv;
7387
7388         if (!test_bit (FLAG_COMMIT, &local->flags))
7389                 return 0;
7390
7391         /* Some of the "SET" function may have modified some of the
7392          * parameters. It's now time to commit them in the card */
7393         disable_MAC(local, 1);
7394         if (test_bit (FLAG_RESET, &local->flags)) {
7395                 APListRid APList_rid;
7396                 SsidRid SSID_rid;
7397
7398                 readAPListRid(local, &APList_rid);
7399                 readSsidRid(local, &SSID_rid);
7400                 if (test_bit(FLAG_MPI,&local->flags))
7401                         setup_card(local, dev->dev_addr, 1 );
7402                 else
7403                         reset_airo_card(dev);
7404                 disable_MAC(local, 1);
7405                 writeSsidRid(local, &SSID_rid, 1);
7406                 writeAPListRid(local, &APList_rid, 1);
7407         }
7408         if (down_interruptible(&local->sem))
7409                 return -ERESTARTSYS;
7410         writeConfigRid(local, 0);
7411         enable_MAC(local, 0);
7412         if (test_bit (FLAG_RESET, &local->flags))
7413                 airo_set_promisc(local);
7414         else
7415                 up(&local->sem);
7416
7417         return 0;
7418 }
7419
7420 /*------------------------------------------------------------------*/
7421 /*
7422  * Structures to export the Wireless Handlers
7423  */
7424
7425 static const struct iw_priv_args airo_private_args[] = {
7426 /*{ cmd,         set_args,                            get_args, name } */
7427   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7428     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7429   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7430     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7431 };
7432
7433 static const iw_handler         airo_handler[] =
7434 {
7435         (iw_handler) airo_config_commit,        /* SIOCSIWCOMMIT */
7436         (iw_handler) airo_get_name,             /* SIOCGIWNAME */
7437         (iw_handler) NULL,                      /* SIOCSIWNWID */
7438         (iw_handler) NULL,                      /* SIOCGIWNWID */
7439         (iw_handler) airo_set_freq,             /* SIOCSIWFREQ */
7440         (iw_handler) airo_get_freq,             /* SIOCGIWFREQ */
7441         (iw_handler) airo_set_mode,             /* SIOCSIWMODE */
7442         (iw_handler) airo_get_mode,             /* SIOCGIWMODE */
7443         (iw_handler) airo_set_sens,             /* SIOCSIWSENS */
7444         (iw_handler) airo_get_sens,             /* SIOCGIWSENS */
7445         (iw_handler) NULL,                      /* SIOCSIWRANGE */
7446         (iw_handler) airo_get_range,            /* SIOCGIWRANGE */
7447         (iw_handler) NULL,                      /* SIOCSIWPRIV */
7448         (iw_handler) NULL,                      /* SIOCGIWPRIV */
7449         (iw_handler) NULL,                      /* SIOCSIWSTATS */
7450         (iw_handler) NULL,                      /* SIOCGIWSTATS */
7451         iw_handler_set_spy,                     /* SIOCSIWSPY */
7452         iw_handler_get_spy,                     /* SIOCGIWSPY */
7453         iw_handler_set_thrspy,                  /* SIOCSIWTHRSPY */
7454         iw_handler_get_thrspy,                  /* SIOCGIWTHRSPY */
7455         (iw_handler) airo_set_wap,              /* SIOCSIWAP */
7456         (iw_handler) airo_get_wap,              /* SIOCGIWAP */
7457         (iw_handler) NULL,                      /* -- hole -- */
7458         (iw_handler) airo_get_aplist,           /* SIOCGIWAPLIST */
7459         (iw_handler) airo_set_scan,             /* SIOCSIWSCAN */
7460         (iw_handler) airo_get_scan,             /* SIOCGIWSCAN */
7461         (iw_handler) airo_set_essid,            /* SIOCSIWESSID */
7462         (iw_handler) airo_get_essid,            /* SIOCGIWESSID */
7463         (iw_handler) airo_set_nick,             /* SIOCSIWNICKN */
7464         (iw_handler) airo_get_nick,             /* SIOCGIWNICKN */
7465         (iw_handler) NULL,                      /* -- hole -- */
7466         (iw_handler) NULL,                      /* -- hole -- */
7467         (iw_handler) airo_set_rate,             /* SIOCSIWRATE */
7468         (iw_handler) airo_get_rate,             /* SIOCGIWRATE */
7469         (iw_handler) airo_set_rts,              /* SIOCSIWRTS */
7470         (iw_handler) airo_get_rts,              /* SIOCGIWRTS */
7471         (iw_handler) airo_set_frag,             /* SIOCSIWFRAG */
7472         (iw_handler) airo_get_frag,             /* SIOCGIWFRAG */
7473         (iw_handler) airo_set_txpow,            /* SIOCSIWTXPOW */
7474         (iw_handler) airo_get_txpow,            /* SIOCGIWTXPOW */
7475         (iw_handler) airo_set_retry,            /* SIOCSIWRETRY */
7476         (iw_handler) airo_get_retry,            /* SIOCGIWRETRY */
7477         (iw_handler) airo_set_encode,           /* SIOCSIWENCODE */
7478         (iw_handler) airo_get_encode,           /* SIOCGIWENCODE */
7479         (iw_handler) airo_set_power,            /* SIOCSIWPOWER */
7480         (iw_handler) airo_get_power,            /* SIOCGIWPOWER */
7481         (iw_handler) NULL,                      /* -- hole -- */
7482         (iw_handler) NULL,                      /* -- hole -- */
7483         (iw_handler) NULL,                      /* SIOCSIWGENIE */
7484         (iw_handler) NULL,                      /* SIOCGIWGENIE */
7485         (iw_handler) airo_set_auth,             /* SIOCSIWAUTH */
7486         (iw_handler) airo_get_auth,             /* SIOCGIWAUTH */
7487         (iw_handler) airo_set_encodeext,        /* SIOCSIWENCODEEXT */
7488         (iw_handler) airo_get_encodeext,        /* SIOCGIWENCODEEXT */
7489         (iw_handler) NULL,                      /* SIOCSIWPMKSA */
7490 };
7491
7492 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7493  * We want to force the use of the ioctl code, because those can't be
7494  * won't work the iw_handler code (because they simultaneously read
7495  * and write data and iw_handler can't do that).
7496  * Note that it's perfectly legal to read/write on a single ioctl command,
7497  * you just can't use iwpriv and need to force it via the ioctl handler.
7498  * Jean II */
7499 static const iw_handler         airo_private_handler[] =
7500 {
7501         NULL,                           /* SIOCIWFIRSTPRIV */
7502 };
7503
7504 static const struct iw_handler_def      airo_handler_def =
7505 {
7506         .num_standard   = ARRAY_SIZE(airo_handler),
7507         .num_private    = ARRAY_SIZE(airo_private_handler),
7508         .num_private_args = ARRAY_SIZE(airo_private_args),
7509         .standard       = airo_handler,
7510         .private        = airo_private_handler,
7511         .private_args   = airo_private_args,
7512         .get_wireless_stats = airo_get_wireless_stats,
7513 };
7514
7515 /*
7516  * This defines the configuration part of the Wireless Extensions
7517  * Note : irq and spinlock protection will occur in the subroutines
7518  *
7519  * TODO :
7520  *      o Check input value more carefully and fill correct values in range
7521  *      o Test and shakeout the bugs (if any)
7522  *
7523  * Jean II
7524  *
7525  * Javier Achirica did a great job of merging code from the unnamed CISCO
7526  * developer that added support for flashing the card.
7527  */
7528 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7529 {
7530         int rc = 0;
7531         struct airo_info *ai = (struct airo_info *)dev->priv;
7532
7533         if (ai->power.event)
7534                 return 0;
7535
7536         switch (cmd) {
7537 #ifdef CISCO_EXT
7538         case AIROIDIFC:
7539 #ifdef AIROOLDIDIFC
7540         case AIROOLDIDIFC:
7541 #endif
7542         {
7543                 int val = AIROMAGIC;
7544                 aironet_ioctl com;
7545                 if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
7546                         rc = -EFAULT;
7547                 else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
7548                         rc = -EFAULT;
7549         }
7550         break;
7551
7552         case AIROIOCTL:
7553 #ifdef AIROOLDIOCTL
7554         case AIROOLDIOCTL:
7555 #endif
7556                 /* Get the command struct and hand it off for evaluation by
7557                  * the proper subfunction
7558                  */
7559         {
7560                 aironet_ioctl com;
7561                 if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
7562                         rc = -EFAULT;
7563                         break;
7564                 }
7565
7566                 /* Separate R/W functions bracket legality here
7567                  */
7568                 if ( com.command == AIRORSWVERSION ) {
7569                         if (copy_to_user(com.data, swversion, sizeof(swversion)))
7570                                 rc = -EFAULT;
7571                         else
7572                                 rc = 0;
7573                 }
7574                 else if ( com.command <= AIRORRID)
7575                         rc = readrids(dev,&com);
7576                 else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
7577                         rc = writerids(dev,&com);
7578                 else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
7579                         rc = flashcard(dev,&com);
7580                 else
7581                         rc = -EINVAL;      /* Bad command in ioctl */
7582         }
7583         break;
7584 #endif /* CISCO_EXT */
7585
7586         // All other calls are currently unsupported
7587         default:
7588                 rc = -EOPNOTSUPP;
7589         }
7590         return rc;
7591 }
7592
7593 /*
7594  * Get the Wireless stats out of the driver
7595  * Note : irq and spinlock protection will occur in the subroutines
7596  *
7597  * TODO :
7598  *      o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7599  *
7600  * Jean
7601  */
7602 static void airo_read_wireless_stats(struct airo_info *local)
7603 {
7604         StatusRid status_rid;
7605         StatsRid stats_rid;
7606         CapabilityRid cap_rid;
7607         __le32 *vals = stats_rid.vals;
7608
7609         /* Get stats out of the card */
7610         clear_bit(JOB_WSTATS, &local->jobs);
7611         if (local->power.event) {
7612                 up(&local->sem);
7613                 return;
7614         }
7615         readCapabilityRid(local, &cap_rid, 0);
7616         readStatusRid(local, &status_rid, 0);
7617         readStatsRid(local, &stats_rid, RID_STATS, 0);
7618         up(&local->sem);
7619
7620         /* The status */
7621         local->wstats.status = le16_to_cpu(status_rid.mode);
7622
7623         /* Signal quality and co */
7624         if (local->rssi) {
7625                 local->wstats.qual.level =
7626                         airo_rssi_to_dbm(local->rssi,
7627                                          le16_to_cpu(status_rid.sigQuality));
7628                 /* normalizedSignalStrength appears to be a percentage */
7629                 local->wstats.qual.qual =
7630                         le16_to_cpu(status_rid.normalizedSignalStrength);
7631         } else {
7632                 local->wstats.qual.level =
7633                         (le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7634                 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7635         }
7636         if (le16_to_cpu(status_rid.len) >= 124) {
7637                 local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7638                 local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7639         } else {
7640                 local->wstats.qual.noise = 0;
7641                 local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
7642         }
7643
7644         /* Packets discarded in the wireless adapter due to wireless
7645          * specific problems */
7646         local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7647                                      le32_to_cpu(vals[57]) +
7648                                      le32_to_cpu(vals[58]); /* SSID Mismatch */
7649         local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7650         local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7651         local->wstats.discard.retries = le32_to_cpu(vals[10]);
7652         local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7653                                      le32_to_cpu(vals[32]);
7654         local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7655 }
7656
7657 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7658 {
7659         struct airo_info *local =  dev->priv;
7660
7661         if (!test_bit(JOB_WSTATS, &local->jobs)) {
7662                 /* Get stats out of the card if available */
7663                 if (down_trylock(&local->sem) != 0) {
7664                         set_bit(JOB_WSTATS, &local->jobs);
7665                         wake_up_interruptible(&local->thr_wait);
7666                 } else
7667                         airo_read_wireless_stats(local);
7668         }
7669
7670         return &local->wstats;
7671 }
7672
7673 #ifdef CISCO_EXT
7674 /*
7675  * This just translates from driver IOCTL codes to the command codes to
7676  * feed to the radio's host interface. Things can be added/deleted
7677  * as needed.  This represents the READ side of control I/O to
7678  * the card
7679  */
7680 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
7681         unsigned short ridcode;
7682         unsigned char *iobuf;
7683         int len;
7684         struct airo_info *ai = dev->priv;
7685
7686         if (test_bit(FLAG_FLASHING, &ai->flags))
7687                 return -EIO;
7688
7689         switch(comp->command)
7690         {
7691         case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7692         case AIROGCFG:      ridcode = RID_CONFIG;
7693                 if (test_bit(FLAG_COMMIT, &ai->flags)) {
7694                         disable_MAC (ai, 1);
7695                         writeConfigRid (ai, 1);
7696                         enable_MAC(ai, 1);
7697                 }
7698                 break;
7699         case AIROGSLIST:    ridcode = RID_SSID;         break;
7700         case AIROGVLIST:    ridcode = RID_APLIST;       break;
7701         case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7702         case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7703         case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
7704                 /* Only super-user can read WEP keys */
7705                 if (!capable(CAP_NET_ADMIN))
7706                         return -EPERM;
7707                 break;
7708         case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
7709                 /* Only super-user can read WEP keys */
7710                 if (!capable(CAP_NET_ADMIN))
7711                         return -EPERM;
7712                 break;
7713         case AIROGSTAT:     ridcode = RID_STATUS;       break;
7714         case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7715         case AIROGSTATSC32: ridcode = RID_STATS;        break;
7716         case AIROGMICSTATS:
7717                 if (copy_to_user(comp->data, &ai->micstats,
7718                                  min((int)comp->len,(int)sizeof(ai->micstats))))
7719                         return -EFAULT;
7720                 return 0;
7721         case AIRORRID:      ridcode = comp->ridnum;     break;
7722         default:
7723                 return -EINVAL;
7724                 break;
7725         }
7726
7727         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7728                 return -ENOMEM;
7729
7730         PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
7731         /* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7732          * then return it to the user
7733          * 9/22/2000 Honor user given length
7734          */
7735         len = comp->len;
7736
7737         if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7738                 kfree (iobuf);
7739                 return -EFAULT;
7740         }
7741         kfree (iobuf);
7742         return 0;
7743 }
7744
7745 /*
7746  * Danger Will Robinson write the rids here
7747  */
7748
7749 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7750         struct airo_info *ai = dev->priv;
7751         int  ridcode;
7752         int  enabled;
7753         static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
7754         unsigned char *iobuf;
7755
7756         /* Only super-user can write RIDs */
7757         if (!capable(CAP_NET_ADMIN))
7758                 return -EPERM;
7759
7760         if (test_bit(FLAG_FLASHING, &ai->flags))
7761                 return -EIO;
7762
7763         ridcode = 0;
7764         writer = do_writerid;
7765
7766         switch(comp->command)
7767         {
7768         case AIROPSIDS:     ridcode = RID_SSID;         break;
7769         case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7770         case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7771         case AIROPCFG: ai->config.len = 0;
7772                             clear_bit(FLAG_COMMIT, &ai->flags);
7773                             ridcode = RID_CONFIG;       break;
7774         case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7775         case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7776         case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7777         case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7778                 break;
7779         case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7780         case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7781
7782                 /* this is not really a rid but a command given to the card
7783                  * same with MAC off
7784                  */
7785         case AIROPMACON:
7786                 if (enable_MAC(ai, 1) != 0)
7787                         return -EIO;
7788                 return 0;
7789
7790                 /*
7791                  * Evidently this code in the airo driver does not get a symbol
7792                  * as disable_MAC. it's probably so short the compiler does not gen one.
7793                  */
7794         case AIROPMACOFF:
7795                 disable_MAC(ai, 1);
7796                 return 0;
7797
7798                 /* This command merely clears the counts does not actually store any data
7799                  * only reads rid. But as it changes the cards state, I put it in the
7800                  * writerid routines.
7801                  */
7802         case AIROPSTCLR:
7803                 if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7804                         return -ENOMEM;
7805
7806                 PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
7807
7808                 enabled = ai->micstats.enabled;
7809                 memset(&ai->micstats,0,sizeof(ai->micstats));
7810                 ai->micstats.enabled = enabled;
7811
7812                 if (copy_to_user(comp->data, iobuf,
7813                                  min((int)comp->len, (int)RIDSIZE))) {
7814                         kfree (iobuf);
7815                         return -EFAULT;
7816                 }
7817                 kfree (iobuf);
7818                 return 0;
7819
7820         default:
7821                 return -EOPNOTSUPP;     /* Blarg! */
7822         }
7823         if(comp->len > RIDSIZE)
7824                 return -EINVAL;
7825
7826         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7827                 return -ENOMEM;
7828
7829         if (copy_from_user(iobuf,comp->data,comp->len)) {
7830                 kfree (iobuf);
7831                 return -EFAULT;
7832         }
7833
7834         if (comp->command == AIROPCFG) {
7835                 ConfigRid *cfg = (ConfigRid *)iobuf;
7836
7837                 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7838                         cfg->opmode |= MODE_MIC;
7839
7840                 if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
7841                         set_bit (FLAG_ADHOC, &ai->flags);
7842                 else
7843                         clear_bit (FLAG_ADHOC, &ai->flags);
7844         }
7845
7846         if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
7847                 kfree (iobuf);
7848                 return -EIO;
7849         }
7850         kfree (iobuf);
7851         return 0;
7852 }
7853
7854 /*****************************************************************************
7855  * Ancillary flash / mod functions much black magic lurkes here              *
7856  *****************************************************************************
7857  */
7858
7859 /*
7860  * Flash command switch table
7861  */
7862
7863 static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7864         int z;
7865
7866         /* Only super-user can modify flash */
7867         if (!capable(CAP_NET_ADMIN))
7868                 return -EPERM;
7869
7870         switch(comp->command)
7871         {
7872         case AIROFLSHRST:
7873                 return cmdreset((struct airo_info *)dev->priv);
7874
7875         case AIROFLSHSTFL:
7876                 if (!((struct airo_info *)dev->priv)->flash &&
7877                         (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
7878                         return -ENOMEM;
7879                 return setflashmode((struct airo_info *)dev->priv);
7880
7881         case AIROFLSHGCHR: /* Get char from aux */
7882                 if(comp->len != sizeof(int))
7883                         return -EINVAL;
7884                 if (copy_from_user(&z,comp->data,comp->len))
7885                         return -EFAULT;
7886                 return flashgchar((struct airo_info *)dev->priv,z,8000);
7887
7888         case AIROFLSHPCHR: /* Send char to card. */
7889                 if(comp->len != sizeof(int))
7890                         return -EINVAL;
7891                 if (copy_from_user(&z,comp->data,comp->len))
7892                         return -EFAULT;
7893                 return flashpchar((struct airo_info *)dev->priv,z,8000);
7894
7895         case AIROFLPUTBUF: /* Send 32k to card */
7896                 if (!((struct airo_info *)dev->priv)->flash)
7897                         return -ENOMEM;
7898                 if(comp->len > FLASHSIZE)
7899                         return -EINVAL;
7900                 if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
7901                         return -EFAULT;
7902
7903                 flashputbuf((struct airo_info *)dev->priv);
7904                 return 0;
7905
7906         case AIRORESTART:
7907                 if(flashrestart((struct airo_info *)dev->priv,dev))
7908                         return -EIO;
7909                 return 0;
7910         }
7911         return -EINVAL;
7912 }
7913
7914 #define FLASH_COMMAND  0x7e7e
7915
7916 /*
7917  * STEP 1)
7918  * Disable MAC and do soft reset on
7919  * card.
7920  */
7921
7922 static int cmdreset(struct airo_info *ai) {
7923         disable_MAC(ai, 1);
7924
7925         if(!waitbusy (ai)){
7926                 airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
7927                 return -EBUSY;
7928         }
7929
7930         OUT4500(ai,COMMAND,CMD_SOFTRESET);
7931
7932         ssleep(1);                      /* WAS 600 12/7/00 */
7933
7934         if(!waitbusy (ai)){
7935                 airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
7936                 return -EBUSY;
7937         }
7938         return 0;
7939 }
7940
7941 /* STEP 2)
7942  * Put the card in legendary flash
7943  * mode
7944  */
7945
7946 static int setflashmode (struct airo_info *ai) {
7947         set_bit (FLAG_FLASHING, &ai->flags);
7948
7949         OUT4500(ai, SWS0, FLASH_COMMAND);
7950         OUT4500(ai, SWS1, FLASH_COMMAND);
7951         if (probe) {
7952                 OUT4500(ai, SWS0, FLASH_COMMAND);
7953                 OUT4500(ai, COMMAND,0x10);
7954         } else {
7955                 OUT4500(ai, SWS2, FLASH_COMMAND);
7956                 OUT4500(ai, SWS3, FLASH_COMMAND);
7957                 OUT4500(ai, COMMAND,0);
7958         }
7959         msleep(500);            /* 500ms delay */
7960
7961         if(!waitbusy(ai)) {
7962                 clear_bit (FLAG_FLASHING, &ai->flags);
7963                 airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
7964                 return -EIO;
7965         }
7966         return 0;
7967 }
7968
7969 /* Put character to SWS0 wait for dwelltime
7970  * x 50us for  echo .
7971  */
7972
7973 static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7974         int echo;
7975         int waittime;
7976
7977         byte |= 0x8000;
7978
7979         if(dwelltime == 0 )
7980                 dwelltime = 200;
7981
7982         waittime=dwelltime;
7983
7984         /* Wait for busy bit d15 to go false indicating buffer empty */
7985         while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
7986                 udelay (50);
7987                 waittime -= 50;
7988         }
7989
7990         /* timeout for busy clear wait */
7991         if(waittime <= 0 ){
7992                 airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
7993                 return -EBUSY;
7994         }
7995
7996         /* Port is clear now write byte and wait for it to echo back */
7997         do {
7998                 OUT4500(ai,SWS0,byte);
7999                 udelay(50);
8000                 dwelltime -= 50;
8001                 echo = IN4500(ai,SWS1);
8002         } while (dwelltime >= 0 && echo != byte);
8003
8004         OUT4500(ai,SWS1,0);
8005
8006         return (echo == byte) ? 0 : -EIO;
8007 }
8008
8009 /*
8010  * Get a character from the card matching matchbyte
8011  * Step 3)
8012  */
8013 static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
8014         int           rchar;
8015         unsigned char rbyte=0;
8016
8017         do {
8018                 rchar = IN4500(ai,SWS1);
8019
8020                 if(dwelltime && !(0x8000 & rchar)){
8021                         dwelltime -= 10;
8022                         mdelay(10);
8023                         continue;
8024                 }
8025                 rbyte = 0xff & rchar;
8026
8027                 if( (rbyte == matchbyte) && (0x8000 & rchar) ){
8028                         OUT4500(ai,SWS1,0);
8029                         return 0;
8030                 }
8031                 if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
8032                         break;
8033                 OUT4500(ai,SWS1,0);
8034
8035         }while(dwelltime > 0);
8036         return -EIO;
8037 }
8038
8039 /*
8040  * Transfer 32k of firmware data from user buffer to our buffer and
8041  * send to the card
8042  */
8043
8044 static int flashputbuf(struct airo_info *ai){
8045         int            nwords;
8046
8047         /* Write stuff */
8048         if (test_bit(FLAG_MPI,&ai->flags))
8049                 memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
8050         else {
8051                 OUT4500(ai,AUXPAGE,0x100);
8052                 OUT4500(ai,AUXOFF,0);
8053
8054                 for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
8055                         OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
8056                 }
8057         }
8058         OUT4500(ai,SWS0,0x8000);
8059
8060         return 0;
8061 }
8062
8063 /*
8064  *
8065  */
8066 static int flashrestart(struct airo_info *ai,struct net_device *dev){
8067         int    i,status;
8068
8069         ssleep(1);                      /* Added 12/7/00 */
8070         clear_bit (FLAG_FLASHING, &ai->flags);
8071         if (test_bit(FLAG_MPI, &ai->flags)) {
8072                 status = mpi_init_descriptors(ai);
8073                 if (status != SUCCESS)
8074                         return status;
8075         }
8076         status = setup_card(ai, dev->dev_addr, 1);
8077
8078         if (!test_bit(FLAG_MPI,&ai->flags))
8079                 for( i = 0; i < MAX_FIDS; i++ ) {
8080                         ai->fids[i] = transmit_allocate
8081                                 ( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
8082                 }
8083
8084         ssleep(1);                      /* Added 12/7/00 */
8085         return status;
8086 }
8087 #endif /* CISCO_EXT */
8088
8089 /*
8090     This program is free software; you can redistribute it and/or
8091     modify it under the terms of the GNU General Public License
8092     as published by the Free Software Foundation; either version 2
8093     of the License, or (at your option) any later version.
8094
8095     This program is distributed in the hope that it will be useful,
8096     but WITHOUT ANY WARRANTY; without even the implied warranty of
8097     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8098     GNU General Public License for more details.
8099
8100     In addition:
8101
8102     Redistribution and use in source and binary forms, with or without
8103     modification, are permitted provided that the following conditions
8104     are met:
8105
8106     1. Redistributions of source code must retain the above copyright
8107        notice, this list of conditions and the following disclaimer.
8108     2. Redistributions in binary form must reproduce the above copyright
8109        notice, this list of conditions and the following disclaimer in the
8110        documentation and/or other materials provided with the distribution.
8111     3. The name of the author may not be used to endorse or promote
8112        products derived from this software without specific prior written
8113        permission.
8114
8115     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8116     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8117     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8118     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
8119     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8120     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8121     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8122     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8123     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
8124     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8125     POSSIBILITY OF SUCH DAMAGE.
8126 */
8127
8128 module_init(airo_init_module);
8129 module_exit(airo_cleanup_module);