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