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