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