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