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