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