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