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