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