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