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