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