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
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.
18 ======================================================================*/
20 #include <linux/config.h>
21 #include <linux/version.h>
22 #include <linux/init.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/proc_fs.h>
28 #include <linux/sched.h>
29 #include <linux/ptrace.h>
30 #include <linux/slab.h>
31 #include <linux/string.h>
32 #include <linux/timer.h>
33 #include <linux/interrupt.h>
35 #include <linux/workqueue.h>
37 #include <asm/system.h>
38 #include <asm/bitops.h>
40 #include <linux/netdevice.h>
41 #include <linux/etherdevice.h>
42 #include <linux/skbuff.h>
43 #include <linux/if_arp.h>
44 #include <linux/ioport.h>
45 #include <linux/config.h>
46 #include <linux/pci.h>
47 #include <asm/uaccess.h>
50 static struct pci_device_id card_ids[] = {
51 { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
52 { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
53 { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
54 { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
55 { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
58 MODULE_DEVICE_TABLE(pci, card_ids);
60 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
61 static void airo_pci_remove(struct pci_dev *);
63 static struct pci_driver airo_driver = {
66 .probe = airo_pci_probe,
67 .remove = __devexit_p(airo_pci_remove),
69 #endif /* CONFIG_PCI */
71 /* Include Wireless Extension definition and check version - Jean II */
72 #include <linux/wireless.h>
73 #define WIRELESS_SPY // enable iwspy support
75 #include <net/iw_handler.h> // New driver API
76 #endif /* WIRELESS_EXT > 12 */
78 #define CISCO_EXT // enable Cisco extensions
80 #include <linux/delay.h>
83 /* Support Cisco MIC feature */
84 /* As this feature requires the AES encryption algorithm, it is not included
85 in the kernel tree. If you want to enable it, you need to download the
86 aes.h, aestab.h and mic.h files from the CVS at
87 http://sf.net/projects/airo-linux/ Put the files in the same directory
88 as airo.c and compile normally */
91 /* Hack to do some power saving */
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) 0
101 static char *statsLabels[] = {
103 IGNLABEL("RxPlcpCrcErr"),
104 IGNLABEL("RxPlcpFormatErr"),
105 IGNLABEL("RxPlcpLengthErr"),
136 "LostSync-MissedBeacons",
137 "LostSync-ArlExceeded",
139 "LostSync-Disassoced",
140 "LostSync-TsfTiming",
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"),
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"),
204 #define RUN_AT(x) (jiffies+(x))
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). */
213 static int basic_rate;
214 static char *ssids[3];
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. */
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 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");
244 MODULE_PARM(io,"1-4i");
245 MODULE_PARM(irq,"1-4i");
246 MODULE_PARM(basic_rate,"i");
247 MODULE_PARM(rates,"1-8i");
248 MODULE_PARM(ssids,"1-3s");
249 MODULE_PARM(auto_wep,"i");
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_PARM(aux_bap,"i");
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_PARM(maxencrypt, "i");
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_PARM(adhoc, "i");
263 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
264 MODULE_PARM(probe, "i");
265 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
267 MODULE_PARM(proc_uid, "i");
268 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
269 MODULE_PARM(proc_gid, "i");
270 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
271 MODULE_PARM(airo_perm, "i");
272 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
273 MODULE_PARM(proc_perm, "i");
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;
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
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
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
367 #define LINKSTAT 0x10
371 #define TXALLOCFID 0x22
372 #define TXCOMPLFID 0x24
386 #define BAP0 0 // Used for receiving packets
387 #define BAP1 2 // Used for xmiting packets and working with RIDS
390 #define COMMAND_BUSY 0x8000
392 #define BAP_BUSY 0x8000
393 #define BAP_ERR 0x4000
394 #define BAP_DONE 0x2000
396 #define PROMISC 0xffff
397 #define NOPROMISC 0x0000
400 #define EV_CLEARCOMMANDBUSY 0x4000
403 #define EV_TXEXC 0x04
404 #define EV_ALLOC 0x08
406 #define EV_AWAKE 0x100
407 #define EV_TXCPY 0x400
408 #define EV_UNKNOWN 0x800
409 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
410 #define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX | EV_MIC )
412 #ifdef CHECK_UNKNOWN_INTS
413 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
415 #define IGNORE_INTS (~STATUS_INTS)
419 #define RID_CAPABILITIES 0xFF00
420 #define RID_APINFO 0xFF01
421 #define RID_RADIOINFO 0xFF02
422 #define RID_UNKNOWN3 0xFF03
423 #define RID_RSSI 0xFF04
424 #define RID_CONFIG 0xFF10
425 #define RID_SSID 0xFF11
426 #define RID_APLIST 0xFF12
427 #define RID_DRVNAME 0xFF13
428 #define RID_ETHERENCAP 0xFF14
429 #define RID_WEP_TEMP 0xFF15
430 #define RID_WEP_PERM 0xFF16
431 #define RID_MODULATION 0xFF17
432 #define RID_OPTIONS 0xFF18
433 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
434 #define RID_FACTORYCONFIG 0xFF21
435 #define RID_UNKNOWN22 0xFF22
436 #define RID_LEAPUSERNAME 0xFF23
437 #define RID_LEAPPASSWORD 0xFF24
438 #define RID_STATUS 0xFF50
439 #define RID_BEACON_HST 0xFF51
440 #define RID_BUSY_HST 0xFF52
441 #define RID_RETRIES_HST 0xFF53
442 #define RID_UNKNOWN54 0xFF54
443 #define RID_UNKNOWN55 0xFF55
444 #define RID_UNKNOWN56 0xFF56
445 #define RID_MIC 0xFF57
446 #define RID_STATS16 0xFF60
447 #define RID_STATS16DELTA 0xFF61
448 #define RID_STATS16DELTACLEAR 0xFF62
449 #define RID_STATS 0xFF68
450 #define RID_STATSDELTA 0xFF69
451 #define RID_STATSDELTACLEAR 0xFF6A
452 #define RID_ECHOTEST_RID 0xFF70
453 #define RID_ECHOTEST_RESULTS 0xFF71
454 #define RID_BSSLISTFIRST 0xFF72
455 #define RID_BSSLISTNEXT 0xFF73
472 * Rids and endian-ness: The Rids will always be in cpu endian, since
473 * this all the patches from the big-endian guys end up doing that.
474 * so all rid access should use the read/writeXXXRid routines.
477 /* This is redundant for x86 archs, but it seems necessary for ARM */
480 /* This structure came from an email sent to me from an engineer at
481 aironet for inclusion into this driver */
490 /* These structures are from the Aironet's PC4500 Developers Manual */
504 #define MOD_DEFAULT 0
510 u16 len; /* sizeof(ConfigRid) */
511 u16 opmode; /* operating mode */
512 #define MODE_STA_IBSS 0
513 #define MODE_STA_ESS 1
515 #define MODE_AP_RPTR 3
516 #define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
517 #define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
518 #define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
519 #define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
520 #define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
521 #define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
522 #define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
523 #define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
524 #define MODE_MIC (1<<15) /* enable MIC */
525 u16 rmode; /* receive mode */
526 #define RXMODE_BC_MC_ADDR 0
527 #define RXMODE_BC_ADDR 1 /* ignore multicasts */
528 #define RXMODE_ADDR 2 /* ignore multicast and broadcast */
529 #define RXMODE_RFMON 3 /* wireless monitor mode */
530 #define RXMODE_RFMON_ANYBSS 4
531 #define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
532 #define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
533 #define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
536 u8 macAddr[ETH_ALEN];
540 u16 txLifetime; /* in kusec */
541 u16 rxLifetime; /* in kusec */
544 u16 u16deviceType; /* for overriding device type */
548 /*---------- Scanning/Associating ----------*/
550 #define SCANMODE_ACTIVE 0
551 #define SCANMODE_PASSIVE 1
552 #define SCANMODE_AIROSCAN 2
553 u16 probeDelay; /* in kusec */
554 u16 probeEnergyTimeout; /* in kusec */
555 u16 probeResponseTimeout;
556 u16 beaconListenTimeout;
560 #define AUTH_OPEN 0x1
561 #define AUTH_ENCRYPT 0x101
562 #define AUTH_SHAREDKEY 0x102
563 #define AUTH_ALLOW_UNENCRYPTED 0x200
564 u16 associationTimeout;
565 u16 specifiedApTimeout;
566 u16 offlineScanInterval;
567 u16 offlineScanDuration;
569 u16 maxBeaconLostTime;
571 #define DISABLE_REFRESH 0xFFFF
573 /*---------- Power save operation ----------*/
575 #define POWERSAVE_CAM 0
576 #define POWERSAVE_PSP 1
577 #define POWERSAVE_PSPCAM 2
580 u16 fastListenInterval;
584 /*---------- Ap/Ibss config items ----------*/
593 /*---------- Radio configuration ----------*/
595 #define RADIOTYPE_DEFAULT 0
596 #define RADIOTYPE_802_11 1
597 #define RADIOTYPE_LEGACY 2
601 #define TXPOWER_DEFAULT 0
603 #define RSSI_DEFAULT 0
605 #define PREAMBLE_AUTO 0
606 #define PREAMBLE_LONG 1
607 #define PREAMBLE_SHORT 2
611 /*---------- Aironet Extensions ----------*/
617 /*---------- Aironet Extensions ----------*/
619 #define MAGIC_ACTION_STSCHG 1
620 #define MACIC_ACTION_RESUME 2
621 #define MAGIC_IGNORE_MCAST (1<<8)
622 #define MAGIC_IGNORE_BCAST (1<<9)
623 #define MAGIC_SWITCH_TO_PSP (0<<10)
624 #define MAGIC_STAY_IN_CAM (1<<10)
638 u8 bssid[4][ETH_ALEN];
652 u16 normalizedSignalStrength;
655 u8 noisePercent; /* Noise percent in last second */
656 u8 noisedBm; /* Noise dBm in last second */
657 u8 noiseAvePercent; /* Noise percent in last minute */
658 u8 noiseAvedBm; /* Noise dBm in last minute */
659 u8 noiseMaxPercent; /* Highest noise percent in last minute */
660 u8 noiseMaxdBm; /* Highest noise dbm in last minute */
664 #define STAT_NOPACKETS 0
665 #define STAT_NOCARRIERSET 10
666 #define STAT_GOTCARRIERSET 11
667 #define STAT_WRONGSSID 20
668 #define STAT_BADCHANNEL 25
669 #define STAT_BADBITRATES 30
670 #define STAT_BADPRIVACY 35
671 #define STAT_APFOUND 40
672 #define STAT_APREJECTED 50
673 #define STAT_AUTHENTICATING 60
674 #define STAT_DEAUTHENTICATED 61
675 #define STAT_AUTHTIMEOUT 62
676 #define STAT_ASSOCIATING 70
677 #define STAT_DEASSOCIATED 71
678 #define STAT_ASSOCTIMEOUT 72
679 #define STAT_NOTAIROAP 73
680 #define STAT_ASSOCIATED 80
681 #define STAT_LEAPING 90
682 #define STAT_LEAPFAILED 91
683 #define STAT_LEAPTIMEDOUT 92
684 #define STAT_LEAPCOMPLETE 93
707 char factoryAddr[ETH_ALEN];
708 char aironetAddr[ETH_ALEN];
711 char callid[ETH_ALEN];
712 char supportedRates[8];
715 u16 txPowerLevels[8];
730 u16 index; /* First is 0 and 0xffff means end of list */
731 #define RADIO_FH 1 /* Frequency hopping radio type */
732 #define RADIO_DS 2 /* Direct sequence radio type */
733 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
735 u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
740 #define CAP_ESS (1<<0)
741 #define CAP_IBSS (1<<1)
742 #define CAP_PRIVACY (1<<4)
743 #define CAP_SHORTHDR (1<<5)
746 u8 rates[8]; /* Same as rates for config rid */
747 struct { /* For frequency hopping only */
801 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
802 #define TXCTL_TXEX (1<<2) /* report if tx fails */
803 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
804 #define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
805 #define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
806 #define TXCTL_LLC (1<<4) /* payload is llc */
807 #define TXCTL_RELEASE (0<<5) /* release after completion */
808 #define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
810 #define BUSY_FID 0x10000
813 #define AIROMAGIC 0xa55a
814 /* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
815 #ifdef SIOCIWFIRSTPRIV
816 #ifdef SIOCDEVPRIVATE
817 #define AIROOLDIOCTL SIOCDEVPRIVATE
818 #define AIROOLDIDIFC AIROOLDIOCTL + 1
819 #endif /* SIOCDEVPRIVATE */
820 #else /* SIOCIWFIRSTPRIV */
821 #define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
822 #endif /* SIOCIWFIRSTPRIV */
823 /* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
824 * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
825 * only and don't return the modified struct ifreq to the application which
826 * is usually a problem. - Jean II */
827 #define AIROIOCTL SIOCIWFIRSTPRIV
828 #define AIROIDIFC AIROIOCTL + 1
830 /* Ioctl constants to be used in airo_ioctl.command */
832 #define AIROGCAP 0 // Capability rid
833 #define AIROGCFG 1 // USED A LOT
834 #define AIROGSLIST 2 // System ID list
835 #define AIROGVLIST 3 // List of specified AP's
836 #define AIROGDRVNAM 4 // NOTUSED
837 #define AIROGEHTENC 5 // NOTUSED
838 #define AIROGWEPKTMP 6
839 #define AIROGWEPKNV 7
841 #define AIROGSTATSC32 9
842 #define AIROGSTATSD32 10
843 #define AIROGMICRID 11
844 #define AIROGMICSTATS 12
845 #define AIROGFLAGS 13
847 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
849 #define AIROPCAP AIROGSTATSD32 + 40
850 #define AIROPVLIST AIROPCAP + 1
851 #define AIROPSLIST AIROPVLIST + 1
852 #define AIROPCFG AIROPSLIST + 1
853 #define AIROPSIDS AIROPCFG + 1
854 #define AIROPAPLIST AIROPSIDS + 1
855 #define AIROPMACON AIROPAPLIST + 1 /* Enable mac */
856 #define AIROPMACOFF AIROPMACON + 1 /* Disable mac */
857 #define AIROPSTCLR AIROPMACOFF + 1
858 #define AIROPWEPKEY AIROPSTCLR + 1
859 #define AIROPWEPKEYNV AIROPWEPKEY + 1
860 #define AIROPLEAPPWD AIROPWEPKEYNV + 1
861 #define AIROPLEAPUSR AIROPLEAPPWD + 1
865 #define AIROFLSHRST AIROPWEPKEYNV + 40
866 #define AIROFLSHGCHR AIROFLSHRST + 1
867 #define AIROFLSHSTFL AIROFLSHGCHR + 1
868 #define AIROFLSHPCHR AIROFLSHSTFL + 1
869 #define AIROFLPUTBUF AIROFLSHPCHR + 1
870 #define AIRORESTART AIROFLPUTBUF + 1
872 #define FLASHSIZE 32768
874 typedef struct aironet_ioctl {
875 unsigned short command; // What to do
876 unsigned short len; // Len of data
877 unsigned char *data; // d-data
879 #endif /* CISCO_EXT */
881 #define NUM_MODULES 2
882 #define MIC_MSGLEN_MAX 2400
883 #define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
887 u8 enabled; // MIC enabled or not
888 u32 rxSuccess; // successful packets received
889 u32 rxIncorrectMIC; // pkts dropped due to incorrect MIC comparison
890 u32 rxNotMICed; // pkts dropped due to not being MIC'd
891 u32 rxMICPlummed; // pkts dropped due to not having a MIC plummed
892 u32 rxWrongSequence; // pkts dropped due to sequence number violation
897 u32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
898 u64 accum; // accumulated mic, reduced to u32 in final()
899 int position; // current position (byte offset) in message
903 } part; // saves partial message word across update() calls
907 emmh32_context seed; // Context - the seed
908 u32 rx; // Received sequence number
909 u32 tx; // Tx sequence number
910 u32 window; // Start of window
911 u8 valid; // Flag to say if context is valid or not
916 miccntx mCtx; // Multicast context
917 miccntx uCtx; // Unicast context
921 // Frequency list (map channels to frequencies)
922 static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
923 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
925 // A few details needed for WEP (Wireless Equivalent Privacy)
926 #define MAX_KEY_SIZE 13 // 128 (?) bits
927 #define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
928 typedef struct wep_key_t {
930 u8 key[16]; /* 40-bit and 104-bit keys */
933 /* Backward compatibility */
934 #ifndef IW_ENCODE_NOKEY
935 #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
936 #define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
937 #endif /* IW_ENCODE_NOKEY */
939 #if WIRELESS_EXT > 12
940 /* List of Wireless Handlers (new API) */
941 static const struct iw_handler_def airo_handler_def;
942 #else /* WIRELESS_EXT > 12 */
943 /* More Wireless Extensions backward compatibility */
944 /* Part of iw_handler prototype we need (apart that we don't need it) */
945 struct iw_request_info {};
946 #endif /* WIRELESS_EXT > 12 */
947 #endif /* WIRELESS_EXT */
949 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
953 static int get_dec_u16( char *buffer, int *start, int limit );
954 static void OUT4500( struct airo_info *, u16 register, u16 value );
955 static unsigned short IN4500( struct airo_info *, u16 register );
956 static u16 setup_card(struct airo_info*, u8 *mac);
957 static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock );
958 static void disable_MAC(struct airo_info *ai, int lock);
959 static void enable_interrupts(struct airo_info*);
960 static void disable_interrupts(struct airo_info*);
961 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
962 static u16 sendcommand(struct airo_info *ai, Cmd *pCmd);
963 static void completecommand(struct airo_info *ai, Resp *pRsp);
964 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
965 static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
967 static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
969 static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
971 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
972 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
973 static int PC4500_writerid(struct airo_info*, u16 rid, const void
974 *pBuf, int len, int lock);
975 static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
976 int len, int dummy );
977 static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
978 static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
979 static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
981 static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
983 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
985 struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
986 #endif /* WIRELESS_EXT */
988 static int readrids(struct net_device *dev, aironet_ioctl *comp);
989 static int writerids(struct net_device *dev, aironet_ioctl *comp);
990 int flashcard(struct net_device *dev, aironet_ioctl *comp);
991 #endif /* CISCO_EXT */
993 static void micinit(struct airo_info *ai, MICRid *micr);
994 static void micsetup(struct airo_info *ai);
995 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
996 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1000 struct net_device_stats stats;
1002 struct net_device *dev;
1003 /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we
1004 use the high bit to mark whether it is in use. */
1009 int need_commit; // Need to set config
1010 char keyindex; // Used with auto wep
1011 char defindex; // Used with auto wep
1012 struct timer_list timer;
1013 struct proc_dir_entry *proc_entry;
1014 struct airo_info *next;
1015 spinlock_t aux_lock;
1016 unsigned long flags;
1017 #define FLAG_PROMISC IFF_PROMISC /* 0x100 - include/linux/if.h */
1018 #define FLAG_RADIO_OFF 0x02 /* User disabling of MAC */
1019 #define FLAG_RADIO_DOWN 0x08 /* ifup/ifdown disabling of MAC */
1020 #define FLAG_FLASHING 0x10
1021 #define FLAG_ADHOC 0x01 /* Needed by MIC */
1022 #define FLAG_MIC_CAPABLE 0x20
1023 #define FLAG_UPDATE_MULTI 0x40
1024 #define FLAG_UPDATE_UNI 0x80
1025 #define FLAG_802_11 0x200
1026 #define FLAG_PENDING_XMIT 0x400
1027 #define FLAG_PENDING_XMIT11 0x800
1028 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
1030 unsigned short *flash;
1032 struct semaphore sem;
1033 struct task_struct *task;
1034 struct work_struct stats_task;
1035 struct work_struct promisc_task;
1037 struct sk_buff *skb;
1039 struct work_struct task;
1041 struct net_device *wifidev;
1043 struct iw_statistics wstats; // wireless stats
1044 unsigned long scan_timestamp; /* Time started to scan */
1045 struct work_struct event_task;
1046 #if WIRELESS_EXT > 15
1047 struct iw_spy_data spy_data;
1048 #else /* WIRELESS_EXT > 15 */
1051 u_char spy_address[IW_MAX_SPY][ETH_ALEN];
1052 struct iw_quality spy_stat[IW_MAX_SPY];
1053 #endif /* WIRELESS_SPY */
1054 #endif /* WIRELESS_EXT > 15 */
1055 #endif /* WIRELESS_EXT */
1058 mic_statistics micstats;
1059 struct work_struct mic_task;
1062 static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
1064 return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
1067 static int setup_proc_entry( struct net_device *dev,
1068 struct airo_info *apriv );
1069 static int takedown_proc_entry( struct net_device *dev,
1070 struct airo_info *apriv );
1076 static int readBSSListRid(struct airo_info *ai, int first,
1083 memset(&cmd, 0, sizeof(cmd));
1084 cmd.cmd=CMD_LISTBSS;
1085 if (down_interruptible(&ai->sem))
1086 return -ERESTARTSYS;
1087 issuecommand(ai, &cmd, &rsp);
1089 /* Let the command take effect */
1090 set_current_state (TASK_INTERRUPTIBLE);
1092 schedule_timeout (3*HZ);
1095 rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
1096 list, sizeof(*list), 1);
1098 list->len = le16_to_cpu(list->len);
1099 list->index = le16_to_cpu(list->index);
1100 list->radioType = le16_to_cpu(list->radioType);
1101 list->cap = le16_to_cpu(list->cap);
1102 list->beaconInterval = le16_to_cpu(list->beaconInterval);
1103 list->fh.dwell = le16_to_cpu(list->fh.dwell);
1104 list->dsChannel = le16_to_cpu(list->dsChannel);
1105 list->atimWindow = le16_to_cpu(list->atimWindow);
1109 static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {
1110 int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
1111 wkr, sizeof(*wkr), 1);
1113 wkr->len = le16_to_cpu(wkr->len);
1114 wkr->kindex = le16_to_cpu(wkr->kindex);
1115 wkr->klen = le16_to_cpu(wkr->klen);
1118 /* In the writeXXXRid routines we copy the rids so that we don't screwup
1119 * the originals when we endian them... */
1120 static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lock) {
1122 WepKeyRid wkr = *pwkr;
1124 wkr.len = cpu_to_le16(wkr.len);
1125 wkr.kindex = cpu_to_le16(wkr.kindex);
1126 wkr.klen = cpu_to_le16(wkr.klen);
1127 rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);
1128 if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc);
1130 rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);
1132 printk(KERN_ERR "airo: WEP_PERM set %x\n", rc);
1138 static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {
1140 int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1142 ssidr->len = le16_to_cpu(ssidr->len);
1143 for(i = 0; i < 3; i++) {
1144 ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
1148 static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {
1151 SsidRid ssidr = *pssidr;
1153 ssidr.len = cpu_to_le16(ssidr.len);
1154 for(i = 0; i < 3; i++) {
1155 ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
1157 rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), 1);
1160 static int readConfigRid(struct airo_info*ai, int lock) {
1168 rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
1172 for(s = &cfg.len; s <= &cfg.rtsThres; s++) *s = le16_to_cpu(*s);
1174 for(s = &cfg.shortRetryLimit; s <= &cfg.radioType; s++)
1175 *s = le16_to_cpu(*s);
1177 for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)
1178 *s = le16_to_cpu(*s);
1180 for(s = &cfg.arlThreshold; s <= &cfg.autoWake; s++)
1181 *s = le16_to_cpu(*s);
1186 static inline void checkThrottle(struct airo_info *ai) {
1188 /* Old hardware had a limit on encryption speed */
1189 if (ai->config.authType != AUTH_OPEN && maxencrypt) {
1190 for(i=0; i<8; i++) {
1191 if (ai->config.rates[i] > maxencrypt) {
1192 ai->config.rates[i] = 0;
1197 static int writeConfigRid(struct airo_info*ai, int lock) {
1201 if (!ai->need_commit)
1204 ai->need_commit = 0;
1208 if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)
1209 ai->flags |= FLAG_ADHOC;
1211 ai->flags &= ~FLAG_ADHOC;
1213 for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
1215 for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
1216 *s = cpu_to_le16(*s);
1218 for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
1219 *s = cpu_to_le16(*s);
1221 for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)
1222 *s = cpu_to_le16(*s);
1224 return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1226 static int readStatusRid(struct airo_info*ai, StatusRid *statr) {
1227 int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), 1);
1230 statr->len = le16_to_cpu(statr->len);
1231 for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
1233 for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++)
1234 *s = le16_to_cpu(*s);
1235 statr->load = le16_to_cpu(statr->load);
1236 statr->assocStatus = le16_to_cpu(statr->assocStatus);
1239 static int readAPListRid(struct airo_info*ai, APListRid *aplr) {
1240 int rc = PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
1241 aplr->len = le16_to_cpu(aplr->len);
1244 static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {
1246 aplr->len = cpu_to_le16(aplr->len);
1247 rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
1250 static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {
1251 int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), 1);
1254 capr->len = le16_to_cpu(capr->len);
1255 capr->prodNum = le16_to_cpu(capr->prodNum);
1256 capr->radioType = le16_to_cpu(capr->radioType);
1257 capr->country = le16_to_cpu(capr->country);
1258 for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
1259 *s = le16_to_cpu(*s);
1262 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
1263 int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1266 sr->len = le16_to_cpu(sr->len);
1267 for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);
1271 static int airo_open(struct net_device *dev) {
1272 struct airo_info *info = dev->priv;
1275 if (info->flags & FLAG_FLASHING)
1278 /* Make sure the card is configured.
1279 * Wireless Extensions may postpone config changes until the card
1280 * is open (to pipeline changes and speed-up card setup). If
1281 * those changes are not yet commited, do it now - Jean II */
1282 if(info->need_commit) {
1283 disable_MAC(info, 1);
1284 writeConfigRid(info, 1);
1287 if (info->wifidev != dev) {
1288 /* Power on the MAC controller (which may have been disabled) */
1289 info->flags &= ~FLAG_RADIO_DOWN;
1290 enable_interrupts(info);
1292 enable_MAC(info, &rsp, 1);
1294 netif_start_queue(dev);
1298 static void get_tx_error(struct airo_info *ai, u32 fid)
1302 if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) == SUCCESS) {
1303 bap_read(ai, &status, 2, BAP0);
1304 if (le16_to_cpu(status) & 2) /* Too many retries */
1305 ai->stats.tx_aborted_errors++;
1306 if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
1307 ai->stats.tx_heartbeat_errors++;
1308 if (le16_to_cpu(status) & 8) /* Aid fail */
1310 if (le16_to_cpu(status) & 0x10) /* MAC disabled */
1311 ai->stats.tx_carrier_errors++;
1312 if (le16_to_cpu(status) & 0x20) /* Association lost */
1314 #if WIRELESS_EXT > 13
1315 /* We produce a TXDROP event only for retry or lifetime
1316 * exceeded, because that's the only status that really mean
1317 * that this particular node went away.
1318 * Other errors means that *we* screwed up. - Jean II */
1319 if ((le16_to_cpu(status) & 2) ||
1320 (le16_to_cpu(status) & 4)) {
1321 union iwreq_data wrqu;
1324 /* Faster to skip over useless data than to do
1325 * another bap_setup(). We are at offset 0x6 and
1326 * need to go to 0x18 and read 6 bytes - Jean II */
1327 bap_read(ai, (u16 *) junk, 0x18, BAP0);
1329 /* Copy 802.11 dest address.
1330 * We use the 802.11 header because the frame may
1331 * not be 802.3 or may be mangled...
1332 * In Ad-Hoc mode, it will be the node address.
1333 * In managed mode, it will be most likely the AP addr
1334 * User space will figure out how to convert it to
1335 * whatever it needs (IP address or else).
1337 memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
1338 wrqu.addr.sa_family = ARPHRD_ETHER;
1340 /* Send event to user space */
1341 wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
1343 #endif /* WIRELESS_EXT > 13 */
1347 static void airo_do_xmit(struct net_device *dev) {
1350 struct airo_info *priv = dev->priv;
1351 struct sk_buff *skb = priv->xmit.skb;
1352 int fid = priv->xmit.fid;
1353 u32 *fids = priv->fids;
1355 if (down_trylock(&priv->sem) != 0) {
1356 priv->flags |= FLAG_PENDING_XMIT;
1357 netif_stop_queue(dev);
1358 priv->xmit.task.func = (void (*)(void *))airo_do_xmit;
1359 priv->xmit.task.data = (void *)dev;
1360 schedule_work(&priv->xmit.task);
1363 status = transmit_802_3_packet (priv, fids[fid], skb->data);
1365 priv->flags &= ~FLAG_PENDING_XMIT;
1368 if ( status == SUCCESS ) {
1369 dev->trans_start = jiffies;
1370 for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
1372 priv->fids[fid] &= 0xffff;
1373 priv->stats.tx_window_errors++;
1375 if (i < MAX_FIDS / 2)
1376 netif_wake_queue(dev);
1380 static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1383 struct airo_info *priv = dev->priv;
1384 u32 *fids = priv->fids;
1386 if ( skb == NULL ) {
1387 printk( KERN_ERR "airo: skb == NULL!!!\n" );
1391 /* Find a vacant FID */
1392 for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
1393 for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
1395 if ( j >= MAX_FIDS / 2 ) {
1396 netif_stop_queue(dev);
1398 if (i == MAX_FIDS / 2) {
1399 priv->stats.tx_fifo_errors++;
1403 /* check min length*/
1404 len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1405 /* Mark fid as used & save length for later */
1406 fids[i] |= (len << 16);
1407 priv->xmit.skb = skb;
1413 static void airo_do_xmit11(struct net_device *dev) {
1416 struct airo_info *priv = dev->priv;
1417 struct sk_buff *skb = priv->xmit11.skb;
1418 int fid = priv->xmit11.fid;
1419 u32 *fids = priv->fids;
1421 if (down_trylock(&priv->sem) != 0) {
1422 priv->flags |= FLAG_PENDING_XMIT11;
1423 netif_stop_queue(dev);
1424 priv->xmit11.task.func = (void (*)(void *))airo_do_xmit11;
1425 priv->xmit11.task.data = (void *)dev;
1426 schedule_work(&priv->xmit11.task);
1429 status = transmit_802_11_packet (priv, fids[fid], skb->data);
1431 priv->flags &= ~FLAG_PENDING_XMIT11;
1434 if ( status == SUCCESS ) {
1435 dev->trans_start = jiffies;
1436 for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
1438 priv->fids[fid] &= 0xffff;
1439 priv->stats.tx_window_errors++;
1442 netif_wake_queue(dev);
1446 static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
1449 struct airo_info *priv = dev->priv;
1450 u32 *fids = priv->fids;
1452 if ( skb == NULL ) {
1453 printk( KERN_ERR "airo: skb == NULL!!!\n" );
1457 /* Find a vacant FID */
1458 for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
1459 for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
1461 if ( j >= MAX_FIDS ) {
1462 netif_stop_queue(dev);
1464 if (i == MAX_FIDS) {
1465 priv->stats.tx_fifo_errors++;
1469 /* check min length*/
1470 len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1471 /* Mark fid as used & save length for later */
1472 fids[i] |= (len << 16);
1473 priv->xmit11.skb = skb;
1474 priv->xmit11.fid = i;
1475 airo_do_xmit11(dev);
1479 static void airo_read_stats(struct airo_info *ai) {
1481 u32 *vals = stats_rid.vals;
1483 if (down_trylock(&ai->sem) == 0) {
1484 readStatsRid(ai, &stats_rid, RID_STATS, 0);
1487 ai->stats.rx_packets = vals[43] + vals[44] + vals[45];
1488 ai->stats.tx_packets = vals[39] + vals[40] + vals[41];
1489 ai->stats.rx_bytes = vals[92];
1490 ai->stats.tx_bytes = vals[91];
1491 ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4];
1492 ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors;
1493 ai->stats.multicast = vals[43];
1494 ai->stats.collisions = vals[89];
1496 /* detailed rx_errors: */
1497 ai->stats.rx_length_errors = vals[3];
1498 ai->stats.rx_crc_errors = vals[4];
1499 ai->stats.rx_frame_errors = vals[2];
1500 ai->stats.rx_fifo_errors = vals[0];
1502 ai->stats_task.func = (void (*)(void *))airo_read_stats;
1503 ai->stats_task.data = (void *)ai;
1504 schedule_work(&ai->stats_task);
1508 struct net_device_stats *airo_get_stats(struct net_device *dev)
1510 struct airo_info *local = dev->priv;
1512 /* Get stats out of the card if available */
1513 airo_read_stats(local);
1515 return &local->stats;
1518 static void airo_end_promisc(struct airo_info *ai) {
1521 if ((IN4500(ai, EVSTAT) & EV_CMD) != 0) {
1522 completecommand(ai, &rsp);
1525 ai->promisc_task.func = (void (*)(void *))airo_end_promisc;
1526 ai->promisc_task.data = (void *)ai;
1527 schedule_work(&ai->promisc_task);
1531 static void airo_set_promisc(struct airo_info *ai) {
1534 if (down_trylock(&ai->sem) == 0) {
1535 memset(&cmd, 0, sizeof(cmd));
1536 cmd.cmd=CMD_SETMODE;
1537 cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
1538 sendcommand(ai, &cmd);
1539 airo_end_promisc(ai);
1541 ai->promisc_task.func = (void (*)(void *))airo_set_promisc;
1542 ai->promisc_task.data = (void *)ai;
1543 schedule_work(&ai->promisc_task);
1547 static void airo_set_multicast_list(struct net_device *dev) {
1548 struct airo_info *ai = dev->priv;
1550 if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
1551 ai->flags ^= IFF_PROMISC;
1552 airo_set_promisc(ai);
1555 if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
1556 /* Turn on multicast. (Should be already setup...) */
1560 static int airo_set_mac_address(struct net_device *dev, void *p)
1562 struct airo_info *ai = dev->priv;
1563 struct sockaddr *addr = p;
1566 memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
1567 ai->need_commit = 1;
1569 writeConfigRid (ai, 1);
1570 enable_MAC(ai, &rsp, 1);
1571 memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
1573 memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
1577 static int airo_change_mtu(struct net_device *dev, int new_mtu)
1579 if ((new_mtu < 68) || (new_mtu > 2400))
1586 static int airo_close(struct net_device *dev) {
1587 struct airo_info *ai = dev->priv;
1589 netif_stop_queue(dev);
1591 if (ai->wifidev != dev) {
1592 #ifdef POWER_ON_DOWN
1593 /* Shut power to the card. The idea is that the user can save
1594 * power when he doesn't need the card with "ifconfig down".
1595 * That's the method that is most friendly towards the network
1596 * stack (i.e. the network stack won't try to broadcast
1597 * anything on the interface and routes are gone. Jean II */
1598 ai->flags |= FLAG_RADIO_DOWN;
1601 disable_interrupts( ai );
1606 static void del_airo_dev( struct net_device *dev );
1608 void stop_airo_card( struct net_device *dev, int freeres )
1610 struct airo_info *ai = dev->priv;
1611 disable_interrupts(ai);
1612 free_irq( dev->irq, dev );
1614 del_timer_sync(&ai->timer);
1615 takedown_proc_entry( dev, ai );
1616 if (ai->registered) {
1617 unregister_netdev( dev );
1619 unregister_netdev(ai->wifidev);
1625 flush_scheduled_work();
1631 /* PCMCIA frees this stuff, so only for PCI and ISA */
1632 release_region( dev->base_addr, 64 );
1634 del_airo_dev( dev );
1638 EXPORT_SYMBOL(stop_airo_card);
1640 static int add_airo_dev( struct net_device *dev );
1642 int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
1644 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
1648 static void wifi_setup(struct net_device *dev, struct net_device *ethdev)
1650 struct airo_info *ai = ethdev->priv;
1652 dev->hard_header = 0;
1653 dev->rebuild_header = 0;
1654 dev->hard_header_cache = 0;
1655 dev->header_cache_update= 0;
1657 dev->hard_header_parse = wll_header_parse;
1658 dev->hard_start_xmit = &airo_start_xmit11;
1659 dev->get_stats = &airo_get_stats;
1660 dev->set_mac_address = &airo_set_mac_address;
1661 dev->do_ioctl = &airo_ioctl;
1663 dev->get_wireless_stats = airo_get_wireless_stats;
1664 #if WIRELESS_EXT > 12
1665 dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;
1666 #endif /* WIRELESS_EXT > 12 */
1667 #endif /* WIRELESS_EXT */
1668 dev->change_mtu = &airo_change_mtu;
1669 dev->open = &airo_open;
1670 dev->stop = &airo_close;
1671 dev->irq = ethdev->irq;
1672 dev->base_addr = ethdev->base_addr;
1674 dev->type = ARPHRD_IEEE80211;
1675 dev->hard_header_len = ETH_HLEN;
1677 dev->addr_len = ETH_ALEN;
1678 memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
1679 dev->tx_queue_len = 100;
1681 memset(dev->broadcast,0xFF, ETH_ALEN);
1683 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
1686 static struct net_device *init_wifidev(struct airo_info *ai,
1687 struct net_device *ethdev)
1690 struct net_device *dev = (struct net_device*)kmalloc(sizeof *dev,GFP_KERNEL);
1692 memset(dev, 0, sizeof(*dev));
1694 strcpy(dev->name, "wifi%d");
1696 wifi_setup(dev, ethdev);
1697 err = register_netdev(dev);
1705 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
1707 struct net_device *dev;
1708 struct airo_info *ai;
1711 /* Create the network device object. */
1712 dev = alloc_etherdev(sizeof(*ai));
1714 printk(KERN_ERR "airo: Couldn't alloc_etherdev\n");
1717 if (dev_alloc_name(dev, dev->name) < 0) {
1718 printk(KERN_ERR "airo: Couldn't get name!\n");
1726 ai->aux_lock = SPIN_LOCK_UNLOCKED;
1727 sema_init(&ai->sem, 1);
1728 ai->need_commit = 0;
1730 rc = add_airo_dev( dev );
1734 /* The Airo-specific entries in the device structure. */
1735 dev->hard_start_xmit = &airo_start_xmit;
1736 dev->get_stats = &airo_get_stats;
1737 dev->set_multicast_list = &airo_set_multicast_list;
1738 dev->set_mac_address = &airo_set_mac_address;
1739 dev->do_ioctl = &airo_ioctl;
1741 dev->get_wireless_stats = airo_get_wireless_stats;
1742 #if WIRELESS_EXT > 12
1743 dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;
1744 #endif /* WIRELESS_EXT > 12 */
1745 #endif /* WIRELESS_EXT */
1746 dev->change_mtu = &airo_change_mtu;
1747 dev->open = &airo_open;
1748 dev->stop = &airo_close;
1750 dev->base_addr = port;
1752 rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
1754 printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
1755 goto err_out_unlink;
1758 if (!request_region( dev->base_addr, 64, dev->name )) {
1765 if ( setup_card( ai, dev->dev_addr ) != SUCCESS ) {
1766 printk( KERN_ERR "airo: MAC could not be enabled\n" );
1771 ai->bap_read = fast_bap_read;
1772 ai->flags |= FLAG_FLASHING;
1775 rc = register_netdev(dev);
1778 ai->wifidev = init_wifidev(ai, dev);
1781 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
1783 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
1784 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
1786 /* Allocate the transmit buffers */
1788 for( i = 0; i < MAX_FIDS; i++ )
1789 ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
1791 setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
1792 netif_start_queue(dev);
1793 SET_MODULE_OWNER(dev);
1798 release_region( dev->base_addr, 64 );
1800 free_irq(dev->irq, dev);
1808 EXPORT_SYMBOL(init_airo_card);
1810 static int waitbusy (struct airo_info *ai) {
1812 while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
1815 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
1817 return delay < 10000;
1820 int reset_airo_card( struct net_device *dev ) {
1822 struct airo_info *ai = dev->priv;
1825 if (down_interruptible(&ai->sem))
1828 OUT4500(ai,COMMAND,CMD_SOFTRESET);
1829 set_current_state (TASK_UNINTERRUPTIBLE);
1830 schedule_timeout (HZ/5);
1832 set_current_state (TASK_UNINTERRUPTIBLE);
1833 schedule_timeout (HZ/5);
1834 if ( setup_card(ai, dev->dev_addr ) != SUCCESS ) {
1835 printk( KERN_ERR "airo: MAC could not be enabled\n" );
1839 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
1848 /* Allocate the transmit buffers */
1849 for( i = 0; i < MAX_FIDS; i++ )
1850 ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
1852 enable_interrupts( ai );
1853 netif_wake_queue(dev);
1858 EXPORT_SYMBOL(reset_airo_card);
1860 #if WIRELESS_EXT > 13
1861 static void airo_send_event(struct net_device *dev) {
1862 struct airo_info *ai = dev->priv;
1863 union iwreq_data wrqu;
1864 StatusRid status_rid;
1866 if (down_trylock(&ai->sem) == 0) {
1867 PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
1869 wrqu.data.length = 0;
1870 wrqu.data.flags = 0;
1871 memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
1872 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1874 /* Send event to user space */
1875 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1877 ai->event_task.func = (void (*)(void *))airo_send_event;
1878 ai->event_task.data = (void *)dev;
1879 schedule_work(&ai->event_task);
1884 static void airo_read_mic(struct airo_info *ai) {
1887 if (down_trylock(&ai->sem) == 0) {
1888 PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1891 micinit (ai, &mic_rid);
1894 ai->mic_task.func = (void (*)(void *))airo_read_mic;
1895 ai->mic_task.data = (void *)ai;
1896 schedule_work(&ai->mic_task);
1900 static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
1901 struct net_device *dev = (struct net_device *)dev_id;
1904 struct airo_info *apriv = dev->priv;
1905 u16 savedInterrupts = 0;
1908 if (!netif_device_present(dev))
1912 status = IN4500( apriv, EVSTAT );
1913 if ( !(status & STATUS_INTS) || status == 0xffff ) break;
1917 if ( status & EV_AWAKE ) {
1918 OUT4500( apriv, EVACK, EV_AWAKE );
1919 OUT4500( apriv, EVACK, EV_AWAKE );
1922 if (!savedInterrupts) {
1923 savedInterrupts = IN4500( apriv, EVINTEN );
1924 OUT4500( apriv, EVINTEN, 0 );
1927 if ( status & EV_MIC ) {
1928 OUT4500( apriv, EVACK, EV_MIC );
1929 if (apriv->flags & FLAG_MIC_CAPABLE)
1930 airo_read_mic( apriv );
1932 if ( status & EV_LINK ) {
1933 #if WIRELESS_EXT > 13
1934 union iwreq_data wrqu;
1935 #endif /* WIRELESS_EXT > 13 */
1936 /* The link status has changed, if you want to put a
1937 monitor hook in, do it here. (Remember that
1938 interrupts are still disabled!)
1940 u16 newStatus = IN4500(apriv, LINKSTAT);
1941 OUT4500( apriv, EVACK, EV_LINK);
1942 /* Here is what newStatus means: */
1943 #define NOBEACON 0x8000 /* Loss of sync - missed beacons */
1944 #define MAXRETRIES 0x8001 /* Loss of sync - max retries */
1945 #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
1946 #define FORCELOSS 0x8003 /* Loss of sync - host request */
1947 #define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
1948 #define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
1949 #define DISASS 0x8200 /* Disassociation (low byte is reason code) */
1950 #define ASSFAIL 0x8400 /* Association failure (low byte is reason
1952 #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
1954 #define ASSOCIATED 0x0400 /* Assocatied */
1955 #define RC_RESERVED 0 /* Reserved return code */
1956 #define RC_NOREASON 1 /* Unspecified reason */
1957 #define RC_AUTHINV 2 /* Previous authentication invalid */
1958 #define RC_DEAUTH 3 /* Deauthenticated because sending station is
1960 #define RC_NOACT 4 /* Disassociated due to inactivity */
1961 #define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
1962 all currently associated stations */
1963 #define RC_BADCLASS2 6 /* Class 2 frame received from
1964 non-Authenticated station */
1965 #define RC_BADCLASS3 7 /* Class 3 frame received from
1966 non-Associated station */
1967 #define RC_STATLEAVE 8 /* Disassociated because sending station is
1969 #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
1970 Authenticated with the responding station */
1971 if (newStatus != ASSOCIATED) {
1972 if (auto_wep && !timer_pending(&apriv->timer)) {
1973 apriv->timer.expires = RUN_AT(HZ*3);
1974 add_timer(&apriv->timer);
1977 struct task_struct *task = apriv->task;
1979 wake_up_process (task);
1980 apriv->flags|=FLAG_UPDATE_UNI|FLAG_UPDATE_MULTI;
1982 #if WIRELESS_EXT > 13
1983 /* Question : is ASSOCIATED the only status
1984 * that is valid ? We want to catch handover
1985 * and reassociations as valid status
1987 if(newStatus == ASSOCIATED) {
1988 if (apriv->scan_timestamp) {
1989 /* Send an empty event to user space.
1990 * We don't send the received data on
1991 * the event because it would require
1992 * us to do complex transcoding, and
1993 * we want to minimise the work done in
1994 * the irq handler. Use a request to
1995 * extract the data - Jean II */
1996 wrqu.data.length = 0;
1997 wrqu.data.flags = 0;
1998 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1999 apriv->scan_timestamp = 0;
2001 airo_send_event(dev);
2003 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
2004 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2006 /* Send event to user space */
2007 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
2009 #endif /* WIRELESS_EXT > 13 */
2012 /* Check to see if there is something to receive */
2013 if ( status & EV_RX ) {
2014 struct sk_buff *skb = NULL;
2015 u16 fc, len, hdrlen = 0;
2029 fid = IN4500( apriv, RXFID );
2031 /* Get the packet length */
2032 if (apriv->flags & FLAG_802_11) {
2033 bap_setup (apriv, fid, 4, BAP0);
2034 bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
2035 /* Bad CRC. Ignore packet */
2036 if (le16_to_cpu(hdr.status) & 2)
2038 if (apriv->wifidev == NULL)
2041 bap_setup (apriv, fid, 0x36, BAP0);
2042 bap_read (apriv, (u16*)&hdr.len, 2, BAP0);
2044 len = le16_to_cpu(hdr.len);
2047 printk( KERN_ERR "airo: Bad size %d\n", len );
2051 if (apriv->flags & FLAG_802_11) {
2052 bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
2053 fc = le16_to_cpu(fc);
2056 if ((fc & 0xe0) == 0xc0)
2062 if ((fc&0x300)==0x300){
2070 hdrlen = ETH_ALEN * 2;
2072 skb = dev_alloc_skb( len + hdrlen + 2 );
2074 apriv->stats.rx_dropped++;
2079 buffer = (u16*)skb_put (skb, len + hdrlen);
2080 if (apriv->flags & FLAG_802_11) {
2082 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
2084 bap_read (apriv, tmpbuf, 6, BAP0);
2086 bap_read (apriv, &gap, sizeof(gap), BAP0);
2087 gap = le16_to_cpu(gap);
2090 bap_read (apriv, tmpbuf, gap, BAP0);
2092 printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n");
2096 bap_read (apriv, buffer + hdrlen/2, len, BAP0);
2099 bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
2100 if (apriv->micstats.enabled) {
2101 bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
2102 if (ntohs(micbuf.typelen) > 0x05DC)
2103 bap_setup (apriv, fid, 0x44, BAP0);
2105 len -= sizeof(micbuf);
2108 skb_trim (skb, len + hdrlen);
2111 bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
2113 if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
2114 dev_kfree_skb_irq (skb);
2121 #if WIRELESS_EXT > 15
2122 #ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
2123 if (apriv->spy_data.spy_number > 0) {
2125 struct iw_quality wstats;
2126 /* Prepare spy data : addr + qual */
2127 sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6);
2128 if (!(apriv->flags & FLAG_802_11)) {
2129 bap_setup (apriv, fid, 8, BAP0);
2130 bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
2132 wstats.qual = hdr.rssi[0];
2134 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
2136 wstats.level = (hdr.rssi[1] + 321) / 2;
2138 /* Update spy records */
2139 wireless_spy_update(dev, sa, &wstats);
2141 #endif /* IW_WIRELESS_SPY */
2142 #else /* WIRELESS_EXT > 15 */
2144 if (apriv->spy_number > 0) {
2148 sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6);
2150 for (i=0; i<apriv->spy_number; i++)
2151 if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN))
2153 if (!(apriv->flags & FLAG_802_11)) {
2154 bap_setup (apriv, fid, 8, BAP0);
2155 bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
2157 apriv->spy_stat[i].qual = hdr.rssi[0];
2159 apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
2161 apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
2162 apriv->spy_stat[i].noise = 0;
2163 apriv->spy_stat[i].updated = 3;
2167 #endif /* WIRELESS_SPY */
2168 #endif /* WIRELESS_EXT > 15 */
2169 OUT4500( apriv, EVACK, EV_RX);
2171 if (apriv->flags & FLAG_802_11) {
2172 skb->mac.raw = skb->data;
2173 skb->pkt_type = PACKET_OTHERHOST;
2174 skb->dev = apriv->wifidev;
2175 skb->protocol = htons(ETH_P_802_2);
2178 skb->protocol = eth_type_trans(skb,dev);
2180 skb->dev->last_rx = jiffies;
2181 skb->ip_summed = CHECKSUM_NONE;
2185 OUT4500( apriv, EVACK, EV_RX);
2188 /* Check to see if a packet has been transmitted */
2189 if ( status & ( EV_TX|EV_TXEXC ) ) {
2194 fid = IN4500(apriv, TXCOMPLFID);
2196 for( i = 0; i < MAX_FIDS; i++ ) {
2197 if ( ( apriv->fids[i] & 0xffff ) == fid ) {
2198 len = apriv->fids[i] >> 16;
2203 if (status & EV_TXEXC)
2204 get_tx_error(apriv, index);
2205 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
2206 /* Set up to be used again */
2207 apriv->fids[index] &= 0xffff;
2208 if (index < MAX_FIDS / 2) {
2209 if (!(apriv->flags & FLAG_PENDING_XMIT))
2210 netif_wake_queue(dev);
2212 if (!(apriv->flags & FLAG_PENDING_XMIT11))
2213 netif_wake_queue(apriv->wifidev);
2216 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
2217 printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
2220 if ( status & ~STATUS_INTS & ~IGNORE_INTS )
2221 printk( KERN_WARNING "airo: Got weird status %x\n",
2222 status & ~STATUS_INTS & ~IGNORE_INTS );
2225 if (savedInterrupts)
2226 OUT4500( apriv, EVINTEN, savedInterrupts );
2229 return IRQ_RETVAL(handled);
2233 * Routines to talk to the card
2237 * This was originally written for the 4500, hence the name
2238 * NOTE: If use with 8bit mode and SMP bad things will happen!
2239 * Why would some one do 8 bit IO in an SMP machine?!?
2241 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
2243 outw( val, ai->dev->base_addr + reg );
2245 outb( val & 0xff, ai->dev->base_addr + reg );
2246 outb( val >> 8, ai->dev->base_addr + reg + 1 );
2250 static u16 IN4500( struct airo_info *ai, u16 reg ) {
2254 rc = inw( ai->dev->base_addr + reg );
2256 rc = inb( ai->dev->base_addr + reg );
2257 rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
2262 static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
2266 /* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
2267 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
2268 * Note : we could try to use !netif_running(dev) in enable_MAC()
2269 * instead of this flag, but I don't trust it *within* the
2270 * open/close functions, and testing both flags together is
2271 * "cheaper" - Jean II */
2272 if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS;
2273 memset(&cmd, 0, sizeof(cmd));
2274 cmd.cmd = MAC_ENABLE;
2276 return issuecommand(ai, &cmd, rsp);
2278 if (down_interruptible(&ai->sem))
2279 return -ERESTARTSYS;
2280 rc = issuecommand(ai, &cmd, rsp);
2285 static void disable_MAC( struct airo_info *ai, int lock ) {
2289 memset(&cmd, 0, sizeof(cmd));
2290 cmd.cmd = MAC_DISABLE; // disable in case already enabled
2292 issuecommand(ai, &cmd, &rsp);
2296 if (down_interruptible(&ai->sem))
2298 issuecommand(ai, &cmd, &rsp);
2302 static void enable_interrupts( struct airo_info *ai ) {
2303 /* Reset the status register */
2304 u16 status = IN4500( ai, EVSTAT );
2305 OUT4500( ai, EVACK, status );
2306 /* Enable the interrupts */
2307 OUT4500( ai, EVINTEN, STATUS_INTS );
2308 /* Note there is a race condition between the last two lines that
2309 I don't know how to get rid of right now... */
2312 static void disable_interrupts( struct airo_info *ai ) {
2313 OUT4500( ai, EVINTEN, 0 );
2316 static u16 setup_card(struct airo_info *ai, u8 *mac)
2327 memset( &mySsid, 0, sizeof( mySsid ) );
2333 /* The NOP is the first step in getting the card going */
2335 cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
2336 if (down_interruptible(&ai->sem))
2338 if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
2342 memset(&cmd, 0, sizeof(cmd));
2343 cmd.cmd = MAC_DISABLE; // disable in case already enabled
2344 if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
2349 // Let's figure out if we need to use the AUX port
2350 cmd.cmd = CMD_ENABLEAUX;
2351 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
2353 printk(KERN_ERR "airo: Error checking for AUX port\n");
2356 if (!aux_bap || rsp.status & 0xff00) {
2357 ai->bap_read = fast_bap_read;
2358 printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
2360 ai->bap_read = aux_bap_read;
2361 printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
2364 if (ai->config.len == 0) {
2365 tdsRssiRid rssi_rid;
2366 CapabilityRid cap_rid;
2368 // general configuration (read/modify/write)
2369 status = readConfigRid(ai, 1);
2370 if ( status != SUCCESS ) return ERROR;
2372 status = readCapabilityRid(ai, &cap_rid);
2373 if ( status != SUCCESS ) return ERROR;
2375 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),1);
2376 if ( status == SUCCESS ) {
2377 if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
2378 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
2385 if (cap_rid.softCap & 8)
2386 ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
2388 printk(KERN_WARNING "airo: unknown received signal level scale\n");
2390 ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
2393 if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1)) {
2394 ai->config.opmode |= MODE_MIC;
2395 ai->flags |= FLAG_MIC_CAPABLE;
2400 /* Save off the MAC */
2401 for( i = 0; i < ETH_ALEN; i++ ) {
2402 mac[i] = ai->config.macAddr[i];
2405 /* Check to see if there are any insmod configured
2409 if ( rates[0] ) memset(ai->config.rates,0,sizeof(ai->config.rates));
2410 for( i = 0; i < 8 && rates[i]; i++ ) {
2411 ai->config.rates[i] = rates[i];
2414 if ( basic_rate > 0 ) {
2416 for( i = 0; i < 8; i++ ) {
2417 if ( ai->config.rates[i] == basic_rate ||
2418 !ai->config.rates ) {
2419 ai->config.rates[i] = basic_rate | 0x80;
2424 ai->need_commit = 1;
2427 /* Setup the SSIDs if present */
2430 for( i = 0; i < 3 && ssids[i]; i++ ) {
2431 mySsid.ssids[i].len = strlen(ssids[i]);
2432 if ( mySsid.ssids[i].len > 32 )
2433 mySsid.ssids[i].len = 32;
2434 memcpy(mySsid.ssids[i].ssid, ssids[i],
2435 mySsid.ssids[i].len);
2439 status = writeConfigRid(ai, 1);
2440 if ( status != SUCCESS ) return ERROR;
2442 /* Set up the SSID list */
2443 status = writeSsidRid(ai, &mySsid);
2444 if ( status != SUCCESS ) return ERROR;
2446 status = enable_MAC(ai, &rsp, 1);
2447 if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
2448 printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
2452 /* Grab the initial wep key, we gotta save it for auto_wep */
2453 rc = readWepKeyRid(ai, &wkr, 1);
2454 if (rc == SUCCESS) do {
2455 lastindex = wkr.kindex;
2456 if (wkr.kindex == 0xffff) {
2457 ai->defindex = wkr.mac[0];
2459 rc = readWepKeyRid(ai, &wkr, 0);
2460 } while(lastindex != wkr.kindex);
2462 if (auto_wep && !timer_pending(&ai->timer)) {
2463 ai->timer.expires = RUN_AT(HZ*3);
2464 add_timer(&ai->timer);
2469 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
2470 // Im really paranoid about letting it run forever!
2471 int max_tries = 600000;
2473 if (sendcommand(ai, pCmd) == (u16)ERROR)
2476 while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
2477 if (!in_interrupt() && (max_tries & 255) == 0)
2480 if ( max_tries == -1 ) {
2482 "airo: Max tries exceeded waiting for command\n" );
2485 completecommand(ai, pRsp);
2489 static u16 sendcommand(struct airo_info *ai, Cmd *pCmd) {
2490 // Im really paranoid about letting it run forever!
2491 int max_tries = 600000;
2494 OUT4500(ai, PARAM0, pCmd->parm0);
2495 OUT4500(ai, PARAM1, pCmd->parm1);
2496 OUT4500(ai, PARAM2, pCmd->parm2);
2497 OUT4500(ai, COMMAND, pCmd->cmd);
2498 while ( max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0 &&
2499 (cmd = IN4500(ai, COMMAND)) != 0 )
2500 if (cmd == pCmd->cmd)
2501 // PC4500 didn't notice command, try again
2502 OUT4500(ai, COMMAND, pCmd->cmd);
2503 if ( max_tries == -1 ) {
2505 "airo: Max tries exceeded when issueing command\n" );
2511 static void completecommand(struct airo_info *ai, Resp *pRsp) {
2512 // command completed
2513 pRsp->status = IN4500(ai, STATUS);
2514 pRsp->rsp0 = IN4500(ai, RESP0);
2515 pRsp->rsp1 = IN4500(ai, RESP1);
2516 pRsp->rsp2 = IN4500(ai, RESP2);
2518 // clear stuck command busy if necessary
2519 if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
2520 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2522 // acknowledge processing the status/response
2523 OUT4500(ai, EVACK, EV_CMD);
2526 /* Sets up the bap to start exchange data. whichbap should
2527 * be one of the BAP0 or BAP1 defines. Locks should be held before
2529 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
2534 OUT4500(ai, SELECT0+whichbap, rid);
2535 OUT4500(ai, OFFSET0+whichbap, offset);
2537 int status = IN4500(ai, OFFSET0+whichbap);
2538 if (status & BAP_BUSY) {
2539 /* This isn't really a timeout, but its kinda
2544 } else if ( status & BAP_ERR ) {
2545 /* invalid rid or offset */
2546 printk( KERN_ERR "airo: BAP error %x %d\n",
2549 } else if (status & BAP_DONE) { // success
2552 if ( !(max_tries--) ) {
2554 "airo: BAP setup error too many retries\n" );
2557 // -- PC4500 missed it, try again
2558 OUT4500(ai, SELECT0+whichbap, rid);
2559 OUT4500(ai, OFFSET0+whichbap, offset);
2564 /* should only be called by aux_bap_read. This aux function and the
2565 following use concepts not documented in the developers guide. I
2566 got them from a patch given to my by Aironet */
2567 static u16 aux_setup(struct airo_info *ai, u16 page,
2568 u16 offset, u16 *len)
2572 OUT4500(ai, AUXPAGE, page);
2573 OUT4500(ai, AUXOFF, 0);
2574 next = IN4500(ai, AUXDATA);
2575 *len = IN4500(ai, AUXDATA)&0xff;
2576 if (offset != 4) OUT4500(ai, AUXOFF, offset);
2580 /* requires call to bap_setup() first */
2581 static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
2582 int bytelen, int whichbap)
2590 unsigned long flags;
2592 spin_lock_irqsave(&ai->aux_lock, flags);
2593 page = IN4500(ai, SWS0+whichbap);
2594 offset = IN4500(ai, SWS2+whichbap);
2595 next = aux_setup(ai, page, offset, &len);
2596 words = (bytelen+1)>>1;
2598 for (i=0; i<words;) {
2600 count = (len>>1) < (words-i) ? (len>>1) : (words-i);
2602 insw( ai->dev->base_addr+DATA0+whichbap,
2605 insb( ai->dev->base_addr+DATA0+whichbap,
2606 pu16Dst+i, count << 1 );
2609 next = aux_setup(ai, next, 4, &len);
2612 spin_unlock_irqrestore(&ai->aux_lock, flags);
2617 /* requires call to bap_setup() first */
2618 static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
2619 int bytelen, int whichbap)
2621 bytelen = (bytelen + 1) & (~1); // round up to even value
2623 insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
2625 insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
2629 /* requires call to bap_setup() first */
2630 static int bap_write(struct airo_info *ai, const u16 *pu16Src,
2631 int bytelen, int whichbap)
2633 bytelen = (bytelen + 1) & (~1); // round up to even value
2635 outsw( ai->dev->base_addr+DATA0+whichbap,
2636 pu16Src, bytelen>>1 );
2638 outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
2642 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
2644 Cmd cmd; /* for issuing commands */
2645 Resp rsp; /* response from commands */
2648 memset(&cmd, 0, sizeof(cmd));
2651 status = issuecommand(ai, &cmd, &rsp);
2652 if (status != 0) return status;
2653 if ( (rsp.status & 0x7F00) != 0) {
2654 return (accmd << 8) + (rsp.rsp0 & 0xFF);
2659 /* Note, that we are using BAP1 which is also used by transmit, so
2660 * we must get a lock. */
2661 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
2667 if (down_interruptible(&ai->sem))
2670 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
2674 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
2678 // read the rid length field
2679 bap_read(ai, pBuf, 2, BAP1);
2680 // length for remaining part of rid
2681 len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
2685 "airo: Rid %x has a length of %d which is too short\n",
2691 // read remainder of the rid
2692 rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
2699 /* Note, that we are using BAP1 which is also used by transmit, so
2700 * make sure this isnt called when a transmit is happening */
2701 static int PC4500_writerid(struct airo_info *ai, u16 rid,
2702 const void *pBuf, int len, int lock)
2707 *(u16*)pBuf = cpu_to_le16((u16)len);
2710 if (down_interruptible(&ai->sem))
2713 // --- first access so that we can write the rid data
2714 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
2718 // --- now write the rid data
2719 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
2723 bap_write(ai, pBuf, len, BAP1);
2724 // ---now commit the rid data
2725 rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
2732 /* Allocates a FID to be used for transmitting packets. We only use
2734 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
2736 unsigned int loop = 3000;
2742 cmd.cmd = CMD_ALLOCATETX;
2743 cmd.parm0 = lenPayload;
2744 if (down_interruptible(&ai->sem))
2746 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
2750 if ( (rsp.status & 0xFF00) != 0) {
2754 /* wait for the allocate event/indication
2755 * It makes me kind of nervous that this can just sit here and spin,
2756 * but in practice it only loops like four times. */
2757 while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
2763 // get the allocated fid and acknowledge
2764 txFid = IN4500(ai, TXALLOCFID);
2765 OUT4500(ai, EVACK, EV_ALLOC);
2767 /* The CARD is pretty cool since it converts the ethernet packet
2768 * into 802.11. Also note that we don't release the FID since we
2769 * will be using the same one over and over again. */
2770 /* We only have to setup the control once since we are not
2771 * releasing the fid. */
2773 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
2774 | TXCTL_ETHERNET | TXCTL_NORELEASE);
2776 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
2777 | TXCTL_ETHERNET | TXCTL_NORELEASE);
2778 if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
2781 bap_write(ai, &txControl, sizeof(txControl), BAP1);
2789 /* In general BAP1 is dedicated to transmiting packets. However,
2790 since we need a BAP when accessing RIDs, we also use BAP1 for that.
2791 Make sure the BAP1 spinlock is held when this is called. */
2792 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
2803 if (len <= ETH_ALEN * 2) {
2804 printk( KERN_WARNING "Short packet %d\n", len );
2807 len -= ETH_ALEN * 2;
2810 if ((ai->flags & FLAG_MIC_CAPABLE) && ai->micstats.enabled &&
2811 (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
2812 if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
2814 miclen = sizeof(pMic);
2818 // packet is destination[6], source[6], payload[len-12]
2819 // write the payload length and dst/src/payload
2820 if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
2821 /* The hardware addresses aren't counted as part of the payload, so
2822 * we have to subtract the 12 bytes for the addresses off */
2823 payloadLen = cpu_to_le16(len + miclen);
2824 bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
2825 bap_write(ai, (const u16*)pPacket, sizeof(etherHead), BAP1);
2827 bap_write(ai, (const u16*)&pMic, miclen, BAP1);
2828 bap_write(ai, (const u16*)(pPacket + sizeof(etherHead)), len, BAP1);
2829 // issue the transmit command
2830 memset( &cmd, 0, sizeof( cmd ) );
2831 cmd.cmd = CMD_TRANSMIT;
2833 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
2834 if ( (rsp.status & 0xFF00) != 0) return ERROR;
2838 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
2853 fc = le16_to_cpu(*(const u16*)pPacket);
2856 if ((fc & 0xe0) == 0xc0)
2862 if ((fc&0x300)==0x300){
2871 printk( KERN_WARNING "Short packet %d\n", len );
2875 /* packet is 802.11 header + payload
2876 * write the payload length and dst/src/payload */
2877 if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
2878 /* The 802.11 header aren't counted as part of the payload, so
2879 * we have to subtract the header bytes off */
2880 payloadLen = cpu_to_le16(len-hdrlen);
2881 bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
2882 if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
2883 bap_write(ai, (const u16*)pPacket, hdrlen, BAP1);
2884 bap_write(ai, hdrlen == 30 ?
2885 (const u16*)&gap.gaplen : (const u16*)&gap, 38 - hdrlen, BAP1);
2887 bap_write(ai, (const u16*)(pPacket + hdrlen), len - hdrlen, BAP1);
2888 // issue the transmit command
2889 memset( &cmd, 0, sizeof( cmd ) );
2890 cmd.cmd = CMD_TRANSMIT;
2892 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
2893 if ( (rsp.status & 0xFF00) != 0) return ERROR;
2898 * This is the proc_fs routines. It is a bit messier than I would
2899 * like! Feel free to clean it up!
2902 static ssize_t proc_read( struct file *file,
2907 static ssize_t proc_write( struct file *file,
2911 static int proc_close( struct inode *inode, struct file *file );
2913 static int proc_stats_open( struct inode *inode, struct file *file );
2914 static int proc_statsdelta_open( struct inode *inode, struct file *file );
2915 static int proc_status_open( struct inode *inode, struct file *file );
2916 static int proc_SSID_open( struct inode *inode, struct file *file );
2917 static int proc_APList_open( struct inode *inode, struct file *file );
2918 static int proc_BSSList_open( struct inode *inode, struct file *file );
2919 static int proc_config_open( struct inode *inode, struct file *file );
2920 static int proc_wepkey_open( struct inode *inode, struct file *file );
2922 static struct file_operations proc_statsdelta_ops = {
2924 .open = proc_statsdelta_open,
2925 .release = proc_close
2928 static struct file_operations proc_stats_ops = {
2930 .open = proc_stats_open,
2931 .release = proc_close
2934 static struct file_operations proc_status_ops = {
2936 .open = proc_status_open,
2937 .release = proc_close
2940 static struct file_operations proc_SSID_ops = {
2942 .write = proc_write,
2943 .open = proc_SSID_open,
2944 .release = proc_close
2947 static struct file_operations proc_BSSList_ops = {
2949 .write = proc_write,
2950 .open = proc_BSSList_open,
2951 .release = proc_close
2954 static struct file_operations proc_APList_ops = {
2956 .write = proc_write,
2957 .open = proc_APList_open,
2958 .release = proc_close
2961 static struct file_operations proc_config_ops = {
2963 .write = proc_write,
2964 .open = proc_config_open,
2965 .release = proc_close
2968 static struct file_operations proc_wepkey_ops = {
2970 .write = proc_write,
2971 .open = proc_wepkey_open,
2972 .release = proc_close
2975 static struct proc_dir_entry *airo_entry = 0;
2984 void (*on_close) (struct inode *, struct file *);
2988 #define SETPROC_OPS(entry, ops) (entry)->proc_fops = &(ops)
2991 static int setup_proc_entry( struct net_device *dev,
2992 struct airo_info *apriv ) {
2993 struct proc_dir_entry *entry;
2994 /* First setup the device directory */
2995 apriv->proc_entry = create_proc_entry(dev->name,
2998 apriv->proc_entry->uid = proc_uid;
2999 apriv->proc_entry->gid = proc_gid;
3000 apriv->proc_entry->owner = THIS_MODULE;
3002 /* Setup the StatsDelta */
3003 entry = create_proc_entry("StatsDelta",
3004 S_IFREG | (S_IRUGO&proc_perm),
3006 entry->uid = proc_uid;
3007 entry->gid = proc_gid;
3009 entry->owner = THIS_MODULE;
3010 SETPROC_OPS(entry, proc_statsdelta_ops);
3012 /* Setup the Stats */
3013 entry = create_proc_entry("Stats",
3014 S_IFREG | (S_IRUGO&proc_perm),
3016 entry->uid = proc_uid;
3017 entry->gid = proc_gid;
3019 entry->owner = THIS_MODULE;
3020 SETPROC_OPS(entry, proc_stats_ops);
3022 /* Setup the Status */
3023 entry = create_proc_entry("Status",
3024 S_IFREG | (S_IRUGO&proc_perm),
3026 entry->uid = proc_uid;
3027 entry->gid = proc_gid;
3029 entry->owner = THIS_MODULE;
3030 SETPROC_OPS(entry, proc_status_ops);
3032 /* Setup the Config */
3033 entry = create_proc_entry("Config",
3034 S_IFREG | proc_perm,
3036 entry->uid = proc_uid;
3037 entry->gid = proc_gid;
3039 entry->owner = THIS_MODULE;
3040 SETPROC_OPS(entry, proc_config_ops);
3042 /* Setup the SSID */
3043 entry = create_proc_entry("SSID",
3044 S_IFREG | proc_perm,
3046 entry->uid = proc_uid;
3047 entry->gid = proc_gid;
3049 entry->owner = THIS_MODULE;
3050 SETPROC_OPS(entry, proc_SSID_ops);
3052 /* Setup the APList */
3053 entry = create_proc_entry("APList",
3054 S_IFREG | proc_perm,
3056 entry->uid = proc_uid;
3057 entry->gid = proc_gid;
3059 entry->owner = THIS_MODULE;
3060 SETPROC_OPS(entry, proc_APList_ops);
3062 /* Setup the BSSList */
3063 entry = create_proc_entry("BSSList",
3064 S_IFREG | proc_perm,
3066 entry->uid = proc_uid;
3067 entry->gid = proc_gid;
3069 entry->owner = THIS_MODULE;
3070 SETPROC_OPS(entry, proc_BSSList_ops);
3072 /* Setup the WepKey */
3073 entry = create_proc_entry("WepKey",
3074 S_IFREG | proc_perm,
3076 entry->uid = proc_uid;
3077 entry->gid = proc_gid;
3079 entry->owner = THIS_MODULE;
3080 SETPROC_OPS(entry, proc_wepkey_ops);
3085 static int takedown_proc_entry( struct net_device *dev,
3086 struct airo_info *apriv ) {
3087 if ( !apriv->proc_entry->namelen ) return 0;
3088 remove_proc_entry("Stats",apriv->proc_entry);
3089 remove_proc_entry("StatsDelta",apriv->proc_entry);
3090 remove_proc_entry("Status",apriv->proc_entry);
3091 remove_proc_entry("Config",apriv->proc_entry);
3092 remove_proc_entry("SSID",apriv->proc_entry);
3093 remove_proc_entry("APList",apriv->proc_entry);
3094 remove_proc_entry("BSSList",apriv->proc_entry);
3095 remove_proc_entry("WepKey",apriv->proc_entry);
3096 remove_proc_entry(dev->name,airo_entry);
3101 * What we want from the proc_fs is to be able to efficiently read
3102 * and write the configuration. To do this, we want to read the
3103 * configuration when the file is opened and write it when the file is
3104 * closed. So basically we allocate a read buffer at open and fill it
3105 * with data, and allocate a write buffer and read it at close.
3109 * The read routine is generic, it relies on the preallocated rbuffer
3110 * to supply the data.
3112 static ssize_t proc_read( struct file *file,
3119 struct proc_data *priv = (struct proc_data*)file->private_data;
3121 if( !priv->rbuffer ) return -EINVAL;
3124 for( i = 0; i+pos < priv->readlen && i < len; i++ ) {
3125 if (put_user( priv->rbuffer[i+pos], buffer+i ))
3133 * The write routine is generic, it fills in a preallocated rbuffer
3134 * to supply the data.
3136 static ssize_t proc_write( struct file *file,
3143 struct proc_data *priv = (struct proc_data*)file->private_data;
3145 if ( !priv->wbuffer ) {
3151 for( i = 0; i + pos < priv->maxwritelen &&
3153 if (get_user( priv->wbuffer[i+pos], buffer + i ))
3156 if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos;
3161 static int proc_status_open( struct inode *inode, struct file *file ) {
3162 struct proc_data *data;
3163 struct proc_dir_entry *dp = PDE(inode);
3164 struct net_device *dev = dp->data;
3165 struct airo_info *apriv = dev->priv;
3166 CapabilityRid cap_rid;
3167 StatusRid status_rid;
3170 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3172 memset(file->private_data, 0, sizeof(struct proc_data));
3173 data = (struct proc_data *)file->private_data;
3174 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
3175 kfree (file->private_data);
3179 readStatusRid(apriv, &status_rid);
3180 readCapabilityRid(apriv, &cap_rid);
3182 i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
3183 status_rid.mode & 1 ? "CFG ": "",
3184 status_rid.mode & 2 ? "ACT ": "",
3185 status_rid.mode & 0x10 ? "SYN ": "",
3186 status_rid.mode & 0x20 ? "LNK ": "",
3187 status_rid.mode & 0x40 ? "LEAP ": "",
3188 status_rid.mode & 0x80 ? "PRIV ": "",
3189 status_rid.mode & 0x100 ? "KEY ": "",
3190 status_rid.mode & 0x200 ? "WEP ": "",
3191 status_rid.mode & 0x8000 ? "ERR ": "");
3192 sprintf( data->rbuffer+i, "Mode: %x\n"
3193 "Signal Strength: %d\n"
3194 "Signal Quality: %d\n"
3199 "Driver Version: %s\n"
3200 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
3201 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
3202 "Software Version: %x\nSoftware Subversion: %x\n"
3203 "Boot block version: %x\n",
3204 (int)status_rid.mode,
3205 (int)status_rid.normalizedSignalStrength,
3206 (int)status_rid.signalQuality,
3207 (int)status_rid.SSIDlen,
3210 (int)status_rid.channel,
3211 (int)status_rid.currentXmitRate/2,
3219 (int)cap_rid.softVer,
3220 (int)cap_rid.softSubVer,
3221 (int)cap_rid.bootBlockVer );
3222 data->readlen = strlen( data->rbuffer );
3226 static int proc_stats_rid_open(struct inode*, struct file*, u16);
3227 static int proc_statsdelta_open( struct inode *inode,
3228 struct file *file ) {
3229 if (file->f_mode&FMODE_WRITE) {
3230 return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
3232 return proc_stats_rid_open(inode, file, RID_STATSDELTA);
3235 static int proc_stats_open( struct inode *inode, struct file *file ) {
3236 return proc_stats_rid_open(inode, file, RID_STATS);
3239 static int proc_stats_rid_open( struct inode *inode,
3242 struct proc_data *data;
3243 struct proc_dir_entry *dp = PDE(inode);
3244 struct net_device *dev = dp->data;
3245 struct airo_info *apriv = dev->priv;
3248 int *vals = stats.vals;
3250 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3252 memset(file->private_data, 0, sizeof(struct proc_data));
3253 data = (struct proc_data *)file->private_data;
3254 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
3255 kfree (file->private_data);
3259 readStatsRid(apriv, &stats, rid, 1);
3262 for(i=0; statsLabels[i]!=(char *)-1 &&
3263 i*4<stats.len; i++){
3264 if (!statsLabels[i]) continue;
3265 if (j+strlen(statsLabels[i])+16>4096) {
3267 "airo: Potentially disasterous buffer overflow averted!\n");
3270 j+=sprintf(data->rbuffer+j, "%s: %d\n", statsLabels[i], vals[i]);
3272 if (i*4>=stats.len){
3274 "airo: Got a short rid\n");
3280 static int get_dec_u16( char *buffer, int *start, int limit ) {
3283 for( value = 0; buffer[*start] >= '0' &&
3284 buffer[*start] <= '9' &&
3285 *start < limit; (*start)++ ) {
3288 value += buffer[*start] - '0';
3290 if ( !valid ) return -1;
3294 static int airo_config_commit(struct net_device *dev,
3295 struct iw_request_info *info, void *zwrq,
3298 static void proc_config_on_close( struct inode *inode, struct file *file ) {
3299 struct proc_data *data = file->private_data;
3300 struct proc_dir_entry *dp = PDE(inode);
3301 struct net_device *dev = dp->data;
3302 struct airo_info *ai = dev->priv;
3305 if ( !data->writelen ) return;
3307 readConfigRid(ai, 1);
3308 ai->need_commit = 1;
3310 line = data->wbuffer;
3312 /*** Mode processing */
3313 if ( !strncmp( line, "Mode: ", 6 ) ) {
3315 if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
3316 ai->need_commit = 2;
3317 ai->config.rmode &= 0xfe00;
3318 ai->flags &= ~FLAG_802_11;
3319 ai->config.opmode &= 0xFF00;
3320 ai->config.scanMode = SCANMODE_ACTIVE;
3321 if ( line[0] == 'a' ) {
3322 ai->config.opmode |= 0;
3324 ai->config.opmode |= 1;
3325 if ( line[0] == 'r' ) {
3326 ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
3327 ai->config.scanMode = SCANMODE_PASSIVE;
3328 ai->flags |= FLAG_802_11;
3329 } else if ( line[0] == 'y' ) {
3330 ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
3331 ai->config.scanMode = SCANMODE_PASSIVE;
3332 ai->flags |= FLAG_802_11;
3333 } else if ( line[0] == 'l' )
3334 ai->config.rmode |= RXMODE_LANMON;
3336 ai->need_commit = 1;
3339 /*** Radio status */
3340 else if (!strncmp(line,"Radio: ", 7)) {
3342 if (!strncmp(line,"off",3)) {
3343 ai->flags |= FLAG_RADIO_OFF;
3345 ai->flags &= ~FLAG_RADIO_OFF;
3348 /*** NodeName processing */
3349 else if ( !strncmp( line, "NodeName: ", 10 ) ) {
3353 memset( ai->config.nodeName, 0, 16 );
3354 /* Do the name, assume a space between the mode and node name */
3355 for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
3356 ai->config.nodeName[j] = line[j];
3358 ai->need_commit = 1;
3361 /*** PowerMode processing */
3362 else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
3364 if ( !strncmp( line, "PSPCAM", 6 ) ) {
3365 ai->config.powerSaveMode = POWERSAVE_PSPCAM;
3366 ai->need_commit = 1;
3367 } else if ( !strncmp( line, "PSP", 3 ) ) {
3368 ai->config.powerSaveMode = POWERSAVE_PSP;
3369 ai->need_commit = 1;
3371 ai->config.powerSaveMode = POWERSAVE_CAM;
3372 ai->need_commit = 1;
3374 } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
3375 int v, i = 0, k = 0; /* i is index into line,
3376 k is index to rates */
3379 while((v = get_dec_u16(line, &i, 3))!=-1) {
3380 ai->config.rates[k++] = (u8)v;
3384 ai->need_commit = 1;
3385 } else if ( !strncmp( line, "Channel: ", 9 ) ) {
3388 v = get_dec_u16(line, &i, i+3);
3390 ai->config.channelSet = (u16)v;
3391 ai->need_commit = 1;
3393 } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
3396 v = get_dec_u16(line, &i, i+3);
3398 ai->config.txPower = (u16)v;
3399 ai->need_commit = 1;
3401 } else if ( !strncmp( line, "WEP: ", 5 ) ) {
3405 ai->config.authType = (u16)AUTH_SHAREDKEY;
3408 ai->config.authType = (u16)AUTH_ENCRYPT;
3411 ai->config.authType = (u16)AUTH_OPEN;
3414 ai->need_commit = 1;
3415 } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
3419 v = get_dec_u16(line, &i, 3);
3420 v = (v<0) ? 0 : ((v>255) ? 255 : v);
3421 ai->config.longRetryLimit = (u16)v;
3422 ai->need_commit = 1;
3423 } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
3427 v = get_dec_u16(line, &i, 3);
3428 v = (v<0) ? 0 : ((v>255) ? 255 : v);
3429 ai->config.shortRetryLimit = (u16)v;
3430 ai->need_commit = 1;
3431 } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
3435 v = get_dec_u16(line, &i, 4);
3436 v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
3437 ai->config.rtsThres = (u16)v;
3438 ai->need_commit = 1;
3439 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
3443 v = get_dec_u16(line, &i, 5);
3445 ai->config.txLifetime = (u16)v;
3446 ai->need_commit = 1;
3447 } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
3451 v = get_dec_u16(line, &i, 5);
3453 ai->config.rxLifetime = (u16)v;
3454 ai->need_commit = 1;
3455 } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
3456 ai->config.txDiversity =
3457 (line[13]=='l') ? 1 :
3458 ((line[13]=='r')? 2: 3);
3459 ai->need_commit = 1;
3460 } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
3461 ai->config.rxDiversity =
3462 (line[13]=='l') ? 1 :
3463 ((line[13]=='r')? 2: 3);
3464 ai->need_commit = 1;
3465 } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
3469 v = get_dec_u16(line, &i, 4);
3470 v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
3471 v = v & 0xfffe; /* Make sure its even */
3472 ai->config.fragThresh = (u16)v;
3473 ai->need_commit = 1;
3474 } else if (!strncmp(line, "Modulation: ", 12)) {
3477 case 'd': ai->config.modulation=MOD_DEFAULT; ai->need_commit=1; break;
3478 case 'c': ai->config.modulation=MOD_CCK; ai->need_commit=1; break;
3479 case 'm': ai->config.modulation=MOD_MOK; ai->need_commit=1; break;
3481 printk( KERN_WARNING "airo: Unknown modulation\n" );
3483 } else if (!strncmp(line, "Preamble: ", 10)) {
3486 case 'a': ai->config.preamble=PREAMBLE_AUTO; ai->need_commit=1; break;
3487 case 'l': ai->config.preamble=PREAMBLE_LONG; ai->need_commit=1; break;
3488 case 's': ai->config.preamble=PREAMBLE_SHORT; ai->need_commit=1; break;
3489 default: printk(KERN_WARNING "airo: Unknown preamble\n");
3492 printk( KERN_WARNING "Couldn't figure out %s\n", line );
3494 while( line[0] && line[0] != '\n' ) line++;
3495 if ( line[0] ) line++;
3497 airo_config_commit(dev, NULL, NULL, NULL);
3500 static char *get_rmode(u16 mode) {
3502 case RXMODE_RFMON: return "rfmon";
3503 case RXMODE_RFMON_ANYBSS: return "yna (any) bss rfmon";
3504 case RXMODE_LANMON: return "lanmon";
3509 static int proc_config_open( struct inode *inode, struct file *file ) {
3510 struct proc_data *data;
3511 struct proc_dir_entry *dp = PDE(inode);
3512 struct net_device *dev = dp->data;
3513 struct airo_info *ai = dev->priv;
3516 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3518 memset(file->private_data, 0, sizeof(struct proc_data));
3519 data = (struct proc_data *)file->private_data;
3520 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
3521 kfree (file->private_data);
3524 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
3525 kfree (data->rbuffer);
3526 kfree (file->private_data);
3529 memset( data->wbuffer, 0, 2048 );
3530 data->maxwritelen = 2048;
3531 data->on_close = proc_config_on_close;
3533 readConfigRid(ai, 1);
3535 i = sprintf( data->rbuffer,
3540 "DataRates: %d %d %d %d %d %d %d %d\n"
3543 (ai->config.opmode & 0xFF) == 0 ? "adhoc" :
3544 (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode):
3545 (ai->config.opmode & 0xFF) == 2 ? "AP" :
3546 (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error",
3547 ai->flags&FLAG_RADIO_OFF ? "off" : "on",
3548 ai->config.nodeName,
3549 ai->config.powerSaveMode == 0 ? "CAM" :
3550 ai->config.powerSaveMode == 1 ? "PSP" :
3551 ai->config.powerSaveMode == 2 ? "PSPCAM" : "Error",
3552 (int)ai->config.rates[0],
3553 (int)ai->config.rates[1],
3554 (int)ai->config.rates[2],
3555 (int)ai->config.rates[3],
3556 (int)ai->config.rates[4],
3557 (int)ai->config.rates[5],
3558 (int)ai->config.rates[6],
3559 (int)ai->config.rates[7],
3560 (int)ai->config.channelSet,
3561 (int)ai->config.txPower
3563 sprintf( data->rbuffer + i,
3564 "LongRetryLimit: %d\n"
3565 "ShortRetryLimit: %d\n"
3566 "RTSThreshold: %d\n"
3567 "TXMSDULifetime: %d\n"
3568 "RXMSDULifetime: %d\n"
3571 "FragThreshold: %d\n"
3575 (int)ai->config.longRetryLimit,
3576 (int)ai->config.shortRetryLimit,
3577 (int)ai->config.rtsThres,
3578 (int)ai->config.txLifetime,
3579 (int)ai->config.rxLifetime,
3580 ai->config.txDiversity == 1 ? "left" :
3581 ai->config.txDiversity == 2 ? "right" : "both",
3582 ai->config.rxDiversity == 1 ? "left" :
3583 ai->config.rxDiversity == 2 ? "right" : "both",
3584 (int)ai->config.fragThresh,
3585 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
3586 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
3587 ai->config.modulation == 0 ? "default" :
3588 ai->config.modulation == MOD_CCK ? "cck" :
3589 ai->config.modulation == MOD_MOK ? "mok" : "error",
3590 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
3591 ai->config.preamble == PREAMBLE_LONG ? "long" :
3592 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
3594 data->readlen = strlen( data->rbuffer );
3598 static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
3599 struct proc_data *data = (struct proc_data *)file->private_data;
3600 struct proc_dir_entry *dp = PDE(inode);
3601 struct net_device *dev = dp->data;
3602 struct airo_info *ai = dev->priv;
3608 if ( !data->writelen ) return;
3610 memset( &SSID_rid, 0, sizeof( SSID_rid ) );
3612 for( i = 0; i < 3; i++ ) {
3614 for( j = 0; j+offset < data->writelen && j < 32 &&
3615 data->wbuffer[offset+j] != '\n'; j++ ) {
3616 SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
3618 if ( j == 0 ) break;
3619 SSID_rid.ssids[i].len = j;
3621 while( data->wbuffer[offset] != '\n' &&
3622 offset < data->writelen ) offset++;
3626 writeSsidRid(ai, &SSID_rid);
3627 enable_MAC(ai, &rsp, 1);
3630 inline static u8 hexVal(char c) {
3631 if (c>='0' && c<='9') return c -= '0';
3632 if (c>='a' && c<='f') return c -= 'a'-10;
3633 if (c>='A' && c<='F') return c -= 'A'-10;
3637 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
3638 struct proc_data *data = (struct proc_data *)file->private_data;
3639 struct proc_dir_entry *dp = PDE(inode);
3640 struct net_device *dev = dp->data;
3641 struct airo_info *ai = dev->priv;
3642 APListRid APList_rid;
3646 if ( !data->writelen ) return;
3648 memset( &APList_rid, 0, sizeof(APList_rid) );
3649 APList_rid.len = sizeof(APList_rid);
3651 for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
3653 for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
3656 APList_rid.ap[i][j/3]=
3657 hexVal(data->wbuffer[j+i*6*3])<<4;
3660 APList_rid.ap[i][j/3]|=
3661 hexVal(data->wbuffer[j+i*6*3]);
3667 writeAPListRid(ai, &APList_rid);
3668 enable_MAC(ai, &rsp, 1);
3671 /* This function wraps PC4500_writerid with a MAC disable */
3672 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
3673 int len, int dummy ) {
3678 rc = PC4500_writerid(ai, rid, rid_data, len, 1);
3679 enable_MAC(ai, &rsp, 1);
3683 /* Returns the length of the key at the index. If index == 0xffff
3684 * the index of the transmit key is returned. If the key doesn't exist,
3685 * -1 will be returned.
3687 static int get_wep_key(struct airo_info *ai, u16 index) {
3692 rc = readWepKeyRid(ai, &wkr, 1);
3693 if (rc == SUCCESS) do {
3694 lastindex = wkr.kindex;
3695 if (wkr.kindex == index) {
3696 if (index == 0xffff) {
3701 readWepKeyRid(ai, &wkr, 0);
3702 } while(lastindex != wkr.kindex);
3706 static int set_wep_key(struct airo_info *ai, u16 index,
3707 const char *key, u16 keylen, int perm, int lock ) {
3708 static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
3711 memset(&wkr, 0, sizeof(wkr));
3713 // We are selecting which key to use
3714 wkr.len = sizeof(wkr);
3715 wkr.kindex = 0xffff;
3716 wkr.mac[0] = (char)index;
3717 if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
3718 if (perm) ai->defindex = (char)index;
3720 // We are actually setting the key
3721 wkr.len = sizeof(wkr);
3724 memcpy( wkr.key, key, keylen );
3725 memcpy( wkr.mac, macaddr, ETH_ALEN );
3726 printk(KERN_INFO "Setting key %d\n", index);
3729 writeWepKeyRid(ai, &wkr, perm, lock);
3733 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
3734 struct proc_data *data;
3735 struct proc_dir_entry *dp = PDE(inode);
3736 struct net_device *dev = dp->data;
3737 struct airo_info *ai = dev->priv;
3743 memset(key, 0, sizeof(key));
3745 data = (struct proc_data *)file->private_data;
3746 if ( !data->writelen ) return;
3748 if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
3749 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
3750 index = data->wbuffer[0] - '0';
3751 if (data->wbuffer[1] == '\n') {
3752 set_wep_key(ai, index, 0, 0, 1, 1);
3757 printk(KERN_ERR "airo: WepKey passed invalid key index\n");
3761 for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
3764 key[i/3] = hexVal(data->wbuffer[i+j])<<4;
3767 key[i/3] |= hexVal(data->wbuffer[i+j]);
3771 set_wep_key(ai, index, key, i/3, 1, 1);
3774 static int proc_wepkey_open( struct inode *inode, struct file *file ) {
3775 struct proc_data *data;
3776 struct proc_dir_entry *dp = PDE(inode);
3777 struct net_device *dev = dp->data;
3778 struct airo_info *ai = dev->priv;
3785 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3787 memset(file->private_data, 0, sizeof(struct proc_data));
3788 memset(&wkr, 0, sizeof(wkr));
3789 data = (struct proc_data *)file->private_data;
3790 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
3791 kfree (file->private_data);
3794 memset(data->rbuffer, 0, 180);
3796 data->maxwritelen = 80;
3797 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
3798 kfree (data->rbuffer);
3799 kfree (file->private_data);
3802 memset( data->wbuffer, 0, 80 );
3803 data->on_close = proc_wepkey_on_close;
3805 ptr = data->rbuffer;
3806 strcpy(ptr, "No wep keys\n");
3807 rc = readWepKeyRid(ai, &wkr, 1);
3808 if (rc == SUCCESS) do {
3809 lastindex = wkr.kindex;
3810 if (wkr.kindex == 0xffff) {
3811 j += sprintf(ptr+j, "Tx key = %d\n",
3814 j += sprintf(ptr+j, "Key %d set with length = %d\n",
3815 (int)wkr.kindex, (int)wkr.klen);
3817 readWepKeyRid(ai, &wkr, 0);
3818 } while((lastindex != wkr.kindex) && (j < 180-30));
3820 data->readlen = strlen( data->rbuffer );
3824 static int proc_SSID_open( struct inode *inode, struct file *file ) {
3825 struct proc_data *data;
3826 struct proc_dir_entry *dp = PDE(inode);
3827 struct net_device *dev = dp->data;
3828 struct airo_info *ai = dev->priv;
3833 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3835 memset(file->private_data, 0, sizeof(struct proc_data));
3836 data = (struct proc_data *)file->private_data;
3837 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
3838 kfree (file->private_data);
3842 data->maxwritelen = 33*3;
3843 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
3844 kfree (data->rbuffer);
3845 kfree (file->private_data);
3848 memset( data->wbuffer, 0, 33*3 );
3849 data->on_close = proc_SSID_on_close;
3851 readSsidRid(ai, &SSID_rid);
3852 ptr = data->rbuffer;
3853 for( i = 0; i < 3; i++ ) {
3855 if ( !SSID_rid.ssids[i].len ) break;
3856 for( j = 0; j < 32 &&
3857 j < SSID_rid.ssids[i].len &&
3858 SSID_rid.ssids[i].ssid[j]; j++ ) {
3859 *ptr++ = SSID_rid.ssids[i].ssid[j];
3864 data->readlen = strlen( data->rbuffer );
3868 static int proc_APList_open( struct inode *inode, struct file *file ) {
3869 struct proc_data *data;
3870 struct proc_dir_entry *dp = PDE(inode);
3871 struct net_device *dev = dp->data;
3872 struct airo_info *ai = dev->priv;
3875 APListRid APList_rid;
3877 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3879 memset(file->private_data, 0, sizeof(struct proc_data));
3880 data = (struct proc_data *)file->private_data;
3881 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
3882 kfree (file->private_data);
3886 data->maxwritelen = 4*6*3;
3887 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
3888 kfree (data->rbuffer);
3889 kfree (file->private_data);
3892 memset( data->wbuffer, 0, data->maxwritelen );
3893 data->on_close = proc_APList_on_close;
3895 readAPListRid(ai, &APList_rid);
3896 ptr = data->rbuffer;
3897 for( i = 0; i < 4; i++ ) {
3898 // We end when we find a zero MAC
3899 if ( !*(int*)APList_rid.ap[i] &&
3900 !*(int*)&APList_rid.ap[i][2]) break;
3901 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n",
3902 (int)APList_rid.ap[i][0],
3903 (int)APList_rid.ap[i][1],
3904 (int)APList_rid.ap[i][2],
3905 (int)APList_rid.ap[i][3],
3906 (int)APList_rid.ap[i][4],
3907 (int)APList_rid.ap[i][5]);
3909 if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
3912 data->readlen = strlen( data->rbuffer );
3916 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
3917 struct proc_data *data;
3918 struct proc_dir_entry *dp = PDE(inode);
3919 struct net_device *dev = dp->data;
3920 struct airo_info *ai = dev->priv;
3922 BSSListRid BSSList_rid;
3924 /* If doLoseSync is not 1, we won't do a Lose Sync */
3925 int doLoseSync = -1;
3927 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
3929 memset(file->private_data, 0, sizeof(struct proc_data));
3930 data = (struct proc_data *)file->private_data;
3931 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
3932 kfree (file->private_data);
3936 data->maxwritelen = 0;
3940 if (file->f_mode & FMODE_WRITE) {
3941 if (!(file->f_mode & FMODE_READ)) {
3945 memset(&cmd, 0, sizeof(cmd));
3946 cmd.cmd=CMD_LISTBSS;
3947 if (down_interruptible(&ai->sem))
3948 return -ERESTARTSYS;
3949 issuecommand(ai, &cmd, &rsp);
3956 ptr = data->rbuffer;
3957 /* There is a race condition here if there are concurrent opens.
3958 Since it is a rare condition, we'll just live with it, otherwise
3959 we have to add a spin lock... */
3960 rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
3961 while(rc == 0 && BSSList_rid.index != 0xffff) {
3962 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x %*s rssi = %d",
3963 (int)BSSList_rid.bssid[0],
3964 (int)BSSList_rid.bssid[1],
3965 (int)BSSList_rid.bssid[2],
3966 (int)BSSList_rid.bssid[3],
3967 (int)BSSList_rid.bssid[4],
3968 (int)BSSList_rid.bssid[5],
3969 (int)BSSList_rid.ssidLen,
3971 (int)BSSList_rid.rssi);
3972 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
3973 (int)BSSList_rid.dsChannel,
3974 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
3975 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
3976 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
3977 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
3978 rc = readBSSListRid(ai, 0, &BSSList_rid);
3981 data->readlen = strlen( data->rbuffer );
3985 static int proc_close( struct inode *inode, struct file *file )
3987 struct proc_data *data = (struct proc_data *)file->private_data;
3988 if ( data->on_close != NULL ) data->on_close( inode, file );
3989 if ( data->rbuffer ) kfree( data->rbuffer );
3990 if ( data->wbuffer ) kfree( data->wbuffer );
3995 static struct net_device_list {
3996 struct net_device *dev;
3997 struct net_device_list *next;
3998 } *airo_devices = 0;
4000 /* Since the card doesn't automatically switch to the right WEP mode,
4001 we will make it do it. If the card isn't associated, every secs we
4002 will switch WEP modes to see if that will help. If the card is
4003 associated we will check every minute to see if anything has
4005 static void timer_func( u_long data ) {
4006 struct net_device *dev = (struct net_device*)data;
4007 struct airo_info *apriv = dev->priv;
4008 u16 linkstat = IN4500(apriv, LINKSTAT);
4011 if (!(apriv->flags & FLAG_FLASHING) && (linkstat != 0x400)) {
4012 /* We don't have a link so try changing the authtype */
4013 if (down_trylock(&apriv->sem) != 0) {
4014 apriv->timer.expires = RUN_AT(1);
4015 add_timer(&apriv->timer);
4019 readConfigRid(apriv, 0);
4020 disable_MAC(apriv, 0);
4021 switch(apriv->config.authType) {
4023 /* So drop to OPEN */
4024 apriv->config.authType = AUTH_OPEN;
4026 case AUTH_SHAREDKEY:
4027 if (apriv->keyindex < auto_wep) {
4028 set_wep_key(apriv, apriv->keyindex, 0, 0, 0, 0);
4029 apriv->config.authType = AUTH_SHAREDKEY;
4032 /* Drop to ENCRYPT */
4033 apriv->keyindex = 0;
4034 set_wep_key(apriv, apriv->defindex, 0, 0, 0, 0);
4035 apriv->config.authType = AUTH_ENCRYPT;
4038 default: /* We'll escalate to SHAREDKEY */
4039 apriv->config.authType = AUTH_SHAREDKEY;
4041 apriv->need_commit = 1;
4042 writeConfigRid(apriv, 0);
4043 enable_MAC(apriv, &rsp, 0);
4046 /* Schedule check to see if the change worked */
4047 apriv->timer.expires = RUN_AT(HZ*3);
4048 add_timer(&apriv->timer);
4052 static int add_airo_dev( struct net_device *dev ) {
4053 struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
4058 struct airo_info *apriv=dev->priv;
4059 struct timer_list *timer = &apriv->timer;
4061 timer->function = timer_func;
4062 timer->data = (u_long)dev;
4067 node->next = airo_devices;
4068 airo_devices = node;
4073 static void del_airo_dev( struct net_device *dev ) {
4074 struct net_device_list **p = &airo_devices;
4075 while( *p && ( (*p)->dev != dev ) )
4077 if ( *p && (*p)->dev == dev )
4082 static int __devinit airo_pci_probe(struct pci_dev *pdev,
4083 const struct pci_device_id *pent)
4085 struct net_device *dev;
4087 if (pci_enable_device(pdev))
4089 pci_set_master(pdev);
4091 dev = init_airo_card(pdev->irq, pdev->resource[2].start, 0);
4095 pci_set_drvdata(pdev, dev);
4099 static void __devexit airo_pci_remove(struct pci_dev *pdev)
4101 stop_airo_card(pci_get_drvdata(pdev), 1);
4105 static int __init airo_init_module( void )
4107 int i, rc = 0, have_isa_dev = 0;
4109 airo_entry = create_proc_entry("aironet",
4110 S_IFDIR | airo_perm,
4112 airo_entry->uid = proc_uid;
4113 airo_entry->gid = proc_gid;
4115 for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
4117 "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n",
4119 if (init_airo_card( irq[i], io[i], 0 ))
4124 printk( KERN_INFO "airo: Probing for PCI adapters\n" );
4125 rc = pci_module_init(&airo_driver);
4126 printk( KERN_INFO "airo: Finished probing for PCI adapters\n" );
4129 /* Always exit with success, as we are a library module
4130 * as well as a driver module
4135 static void __exit airo_cleanup_module( void )
4137 while( airo_devices ) {
4138 printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
4139 stop_airo_card( airo_devices->dev, 1 );
4141 remove_proc_entry("aironet", proc_root_driver);
4146 * Initial Wireless Extension code for Aironet driver by :
4147 * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
4148 * Conversion to new driver API by :
4149 * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
4150 * Javier also did a good amount of work here, adding some new extensions
4151 * and fixing my code. Let's just say that without him this code just
4152 * would not work at all... - Jean II
4155 /*------------------------------------------------------------------*/
4157 * Wireless Handler : get protocol name
4159 static int airo_get_name(struct net_device *dev,
4160 struct iw_request_info *info,
4164 strcpy(cwrq, "IEEE 802.11-DS");
4168 /*------------------------------------------------------------------*/
4170 * Wireless Handler : set frequency
4172 static int airo_set_freq(struct net_device *dev,
4173 struct iw_request_info *info,
4174 struct iw_freq *fwrq,
4177 struct airo_info *local = dev->priv;
4178 int rc = -EINPROGRESS; /* Call commit handler */
4180 /* If setting by frequency, convert to a channel */
4181 if((fwrq->e == 1) &&
4182 (fwrq->m >= (int) 2.412e8) &&
4183 (fwrq->m <= (int) 2.487e8)) {
4184 int f = fwrq->m / 100000;
4186 while((c < 14) && (f != frequency_list[c]))
4188 /* Hack to fall through... */
4192 /* Setting by channel number */
4193 if((fwrq->m > 1000) || (fwrq->e > 0))
4196 int channel = fwrq->m;
4197 /* We should do a better check than that,
4198 * based on the card capability !!! */
4199 if((channel < 1) || (channel > 16)) {
4200 printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m);
4203 /* Yes ! We can set it !!! */
4204 local->config.channelSet = (u16)(channel - 1);
4205 local->need_commit = 1;
4211 /*------------------------------------------------------------------*/
4213 * Wireless Handler : get frequency
4215 static int airo_get_freq(struct net_device *dev,
4216 struct iw_request_info *info,
4217 struct iw_freq *fwrq,
4220 struct airo_info *local = dev->priv;
4221 StatusRid status_rid; /* Card status info */
4223 if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
4224 status_rid.channel = local->config.channelSet;
4226 readStatusRid(local, &status_rid);
4228 #ifdef WEXT_USECHANNELS
4229 fwrq->m = ((int)status_rid.channel) + 1;
4233 int f = (int)status_rid.channel;
4234 fwrq->m = frequency_list[f] * 100000;
4242 /*------------------------------------------------------------------*/
4244 * Wireless Handler : set ESSID
4246 static int airo_set_essid(struct net_device *dev,
4247 struct iw_request_info *info,
4248 struct iw_point *dwrq,
4251 struct airo_info *local = dev->priv;
4253 SsidRid SSID_rid; /* SSIDs */
4255 /* Reload the list of current SSID */
4256 readSsidRid(local, &SSID_rid);
4258 /* Check if we asked for `any' */
4259 if(dwrq->flags == 0) {
4260 /* Just send an empty SSID list */
4261 memset(&SSID_rid, 0, sizeof(SSID_rid));
4263 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4265 /* Check the size of the string */
4266 if(dwrq->length > IW_ESSID_MAX_SIZE+1) {
4269 /* Check if index is valid */
4270 if((index < 0) || (index >= 4)) {
4275 memset(SSID_rid.ssids[index].ssid, 0,
4276 sizeof(SSID_rid.ssids[index].ssid));
4277 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
4278 SSID_rid.ssids[index].len = dwrq->length - 1;
4280 /* Write it to the card */
4281 disable_MAC(local, 1);
4282 writeSsidRid(local, &SSID_rid);
4283 enable_MAC(local, &rsp, 1);
4288 /*------------------------------------------------------------------*/
4290 * Wireless Handler : get ESSID
4292 static int airo_get_essid(struct net_device *dev,
4293 struct iw_request_info *info,
4294 struct iw_point *dwrq,
4297 struct airo_info *local = dev->priv;
4298 StatusRid status_rid; /* Card status info */
4300 readStatusRid(local, &status_rid);
4302 /* Note : if dwrq->flags != 0, we should
4303 * get the relevant SSID from the SSID list... */
4305 /* Get the current SSID */
4306 memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
4307 extra[status_rid.SSIDlen] = '\0';
4308 /* If none, we may want to get the one that was set */
4311 dwrq->length = status_rid.SSIDlen + 1;
4312 dwrq->flags = 1; /* active */
4317 /*------------------------------------------------------------------*/
4319 * Wireless Handler : set AP address
4321 static int airo_set_wap(struct net_device *dev,
4322 struct iw_request_info *info,
4323 struct sockaddr *awrq,
4326 struct airo_info *local = dev->priv;
4329 APListRid APList_rid;
4330 static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
4332 if (awrq->sa_family != ARPHRD_ETHER)
4334 else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
4335 memset(&cmd, 0, sizeof(cmd));
4336 cmd.cmd=CMD_LOSE_SYNC;
4337 if (down_interruptible(&local->sem))
4338 return -ERESTARTSYS;
4339 issuecommand(local, &cmd, &rsp);
4342 memset(&APList_rid, 0, sizeof(APList_rid));
4343 APList_rid.len = sizeof(APList_rid);
4344 memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
4345 disable_MAC(local, 1);
4346 writeAPListRid(local, &APList_rid);
4347 enable_MAC(local, &rsp, 1);
4352 /*------------------------------------------------------------------*/
4354 * Wireless Handler : get AP address
4356 static int airo_get_wap(struct net_device *dev,
4357 struct iw_request_info *info,
4358 struct sockaddr *awrq,
4361 struct airo_info *local = dev->priv;
4362 StatusRid status_rid; /* Card status info */
4364 readStatusRid(local, &status_rid);
4366 /* Tentative. This seems to work, wow, I'm lucky !!! */
4367 memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
4368 awrq->sa_family = ARPHRD_ETHER;
4373 /*------------------------------------------------------------------*/
4375 * Wireless Handler : set Nickname
4377 static int airo_set_nick(struct net_device *dev,
4378 struct iw_request_info *info,
4379 struct iw_point *dwrq,
4382 struct airo_info *local = dev->priv;
4384 /* Check the size of the string */
4385 if(dwrq->length > 16 + 1) {
4388 memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
4389 memcpy(local->config.nodeName, extra, dwrq->length);
4390 local->need_commit = 1;
4392 return -EINPROGRESS; /* Call commit handler */
4395 /*------------------------------------------------------------------*/
4397 * Wireless Handler : get Nickname
4399 static int airo_get_nick(struct net_device *dev,
4400 struct iw_request_info *info,
4401 struct iw_point *dwrq,
4404 struct airo_info *local = dev->priv;
4406 strncpy(extra, local->config.nodeName, 16);
4408 dwrq->length = strlen(extra) + 1;
4413 /*------------------------------------------------------------------*/
4415 * Wireless Handler : set Bit-Rate
4417 static int airo_set_rate(struct net_device *dev,
4418 struct iw_request_info *info,
4419 struct iw_param *vwrq,
4422 struct airo_info *local = dev->priv;
4423 CapabilityRid cap_rid; /* Card capability info */
4427 /* First : get a valid bit rate value */
4428 readCapabilityRid(local, &cap_rid);
4430 /* Which type of value ? */
4431 if((vwrq->value < 8) && (vwrq->value >= 0)) {
4432 /* Setting by rate index */
4433 /* Find value in the magic rate table */
4434 brate = cap_rid.supportedRates[vwrq->value];
4436 /* Setting by frequency value */
4437 u8 normvalue = (u8) (vwrq->value/500000);
4439 /* Check if rate is valid */
4440 for(i = 0 ; i < 8 ; i++) {
4441 if(normvalue == cap_rid.supportedRates[i]) {
4447 /* -1 designed the max rate (mostly auto mode) */
4448 if(vwrq->value == -1) {
4449 /* Get the highest available rate */
4450 for(i = 0 ; i < 8 ; i++) {
4451 if(cap_rid.supportedRates[i] == 0)
4455 brate = cap_rid.supportedRates[i - 1];
4457 /* Check that it is valid */
4462 /* Now, check if we want a fixed or auto value */
4463 if(vwrq->fixed == 0) {
4464 /* Fill all the rates up to this max rate */
4465 memset(local->config.rates, 0, 8);
4466 for(i = 0 ; i < 8 ; i++) {
4467 local->config.rates[i] = cap_rid.supportedRates[i];
4468 if(local->config.rates[i] == brate)
4473 /* One rate, fixed */
4474 memset(local->config.rates, 0, 8);
4475 local->config.rates[0] = brate;
4477 local->need_commit = 1;
4479 return -EINPROGRESS; /* Call commit handler */
4482 /*------------------------------------------------------------------*/
4484 * Wireless Handler : get Bit-Rate
4486 static int airo_get_rate(struct net_device *dev,
4487 struct iw_request_info *info,
4488 struct iw_param *vwrq,
4491 struct airo_info *local = dev->priv;
4492 StatusRid status_rid; /* Card status info */
4494 readStatusRid(local, &status_rid);
4496 vwrq->value = status_rid.currentXmitRate * 500000;
4497 /* If more than one rate, set auto */
4498 vwrq->fixed = (local->config.rates[1] == 0);
4503 /*------------------------------------------------------------------*/
4505 * Wireless Handler : set RTS threshold
4507 static int airo_set_rts(struct net_device *dev,
4508 struct iw_request_info *info,
4509 struct iw_param *vwrq,
4512 struct airo_info *local = dev->priv;
4513 int rthr = vwrq->value;
4517 if((rthr < 0) || (rthr > 2312)) {
4520 local->config.rtsThres = rthr;
4521 local->need_commit = 1;
4523 return -EINPROGRESS; /* Call commit handler */
4526 /*------------------------------------------------------------------*/
4528 * Wireless Handler : get RTS threshold
4530 static int airo_get_rts(struct net_device *dev,
4531 struct iw_request_info *info,
4532 struct iw_param *vwrq,
4535 struct airo_info *local = dev->priv;
4537 vwrq->value = local->config.rtsThres;
4538 vwrq->disabled = (vwrq->value >= 2312);
4544 /*------------------------------------------------------------------*/
4546 * Wireless Handler : set Fragmentation threshold
4548 static int airo_set_frag(struct net_device *dev,
4549 struct iw_request_info *info,
4550 struct iw_param *vwrq,
4553 struct airo_info *local = dev->priv;
4554 int fthr = vwrq->value;
4558 if((fthr < 256) || (fthr > 2312)) {
4561 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
4562 local->config.fragThresh = (u16)fthr;
4563 local->need_commit = 1;
4565 return -EINPROGRESS; /* Call commit handler */
4568 /*------------------------------------------------------------------*/
4570 * Wireless Handler : get Fragmentation threshold
4572 static int airo_get_frag(struct net_device *dev,
4573 struct iw_request_info *info,
4574 struct iw_param *vwrq,
4577 struct airo_info *local = dev->priv;
4579 vwrq->value = local->config.fragThresh;
4580 vwrq->disabled = (vwrq->value >= 2312);
4586 /*------------------------------------------------------------------*/
4588 * Wireless Handler : set Mode of Operation
4590 static int airo_set_mode(struct net_device *dev,
4591 struct iw_request_info *info,
4595 struct airo_info *local = dev->priv;
4598 if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
4603 local->config.opmode &= 0xFF00;
4604 local->config.opmode |= MODE_STA_IBSS;
4605 local->config.rmode &= 0xfe00;
4606 local->config.scanMode = SCANMODE_ACTIVE;
4607 local->flags &= ~FLAG_802_11;
4610 local->config.opmode &= 0xFF00;
4611 local->config.opmode |= MODE_STA_ESS;
4612 local->config.rmode &= 0xfe00;
4613 local->config.scanMode = SCANMODE_ACTIVE;
4614 local->flags &= ~FLAG_802_11;
4616 case IW_MODE_MASTER:
4617 local->config.opmode &= 0xFF00;
4618 local->config.opmode |= MODE_AP;
4619 local->config.rmode &= 0xfe00;
4620 local->config.scanMode = SCANMODE_ACTIVE;
4621 local->flags &= ~FLAG_802_11;
4623 case IW_MODE_REPEAT:
4624 local->config.opmode &= 0xFF00;
4625 local->config.opmode |= MODE_AP_RPTR;
4626 local->config.rmode &= 0xfe00;
4627 local->config.scanMode = SCANMODE_ACTIVE;
4628 local->flags &= ~FLAG_802_11;
4630 case IW_MODE_MONITOR:
4631 local->config.opmode &= 0xFF00;
4632 local->config.opmode |= MODE_STA_ESS;
4633 local->config.rmode &= 0xfe00;
4634 local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4635 local->config.scanMode = SCANMODE_PASSIVE;
4636 local->flags |= FLAG_802_11;
4641 local->need_commit = commit;
4643 return -EINPROGRESS; /* Call commit handler */
4646 /*------------------------------------------------------------------*/
4648 * Wireless Handler : get Mode of Operation
4650 static int airo_get_mode(struct net_device *dev,
4651 struct iw_request_info *info,
4655 struct airo_info *local = dev->priv;
4657 /* If not managed, assume it's ad-hoc */
4658 switch (local->config.opmode & 0xFF) {
4660 *uwrq = IW_MODE_INFRA;
4663 *uwrq = IW_MODE_MASTER;
4666 *uwrq = IW_MODE_REPEAT;
4669 *uwrq = IW_MODE_ADHOC;
4675 /*------------------------------------------------------------------*/
4677 * Wireless Handler : set Encryption Key
4679 static int airo_set_encode(struct net_device *dev,
4680 struct iw_request_info *info,
4681 struct iw_point *dwrq,
4684 struct airo_info *local = dev->priv;
4685 CapabilityRid cap_rid; /* Card capability info */
4687 /* Is WEP supported ? */
4688 readCapabilityRid(local, &cap_rid);
4689 /* Older firmware doesn't support this...
4690 if(!(cap_rid.softCap & 2)) {
4694 /* Basic checking: do we have a key to set ?
4695 * Note : with the new API, it's impossible to get a NULL pointer.
4696 * Therefore, we need to check a key size == 0 instead.
4697 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
4698 * when no key is present (only change flags), but older versions
4699 * don't do it. - Jean II */
4700 if (dwrq->length > 0) {
4702 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4703 int current_index = get_wep_key(local, 0xffff);
4704 /* Check the size of the key */
4705 if (dwrq->length > MAX_KEY_SIZE) {
4708 /* Check the index (none -> use current) */
4709 if ((index < 0) || (index>=(cap_rid.softCap&0x80)?4:1))
4710 index = current_index;
4711 /* Set the length */
4712 if (dwrq->length > MIN_KEY_SIZE)
4713 key.len = MAX_KEY_SIZE;
4715 if (dwrq->length > 0)
4716 key.len = MIN_KEY_SIZE;
4718 /* Disable the key */
4720 /* Check if the key is not marked as invalid */
4721 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
4723 memset(key.key, 0, MAX_KEY_SIZE);
4724 /* Copy the key in the driver */
4725 memcpy(key.key, extra, dwrq->length);
4726 /* Send the key to the card */
4727 set_wep_key(local, index, key.key, key.len, 1, 1);
4729 /* WE specify that if a valid key is set, encryption
4730 * should be enabled (user may turn it off later)
4731 * This is also how "iwconfig ethX key on" works */
4732 if((index == current_index) && (key.len > 0) &&
4733 (local->config.authType == AUTH_OPEN)) {
4734 local->config.authType = AUTH_ENCRYPT;
4735 local->need_commit = 1;
4738 /* Do we want to just set the transmit key index ? */
4739 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4740 if ((index>=0) && (index<(cap_rid.softCap&0x80)?4:1)) {
4741 set_wep_key(local, index, 0, 0, 1, 1);
4743 /* Don't complain if only change the mode */
4744 if(!dwrq->flags & IW_ENCODE_MODE) {
4748 /* Read the flags */
4749 if(dwrq->flags & IW_ENCODE_DISABLED)
4750 local->config.authType = AUTH_OPEN; // disable encryption
4751 if(dwrq->flags & IW_ENCODE_RESTRICTED)
4752 local->config.authType = AUTH_SHAREDKEY; // Only Both
4753 if(dwrq->flags & IW_ENCODE_OPEN)
4754 local->config.authType = AUTH_ENCRYPT; // Only Wep
4755 /* Commit the changes to flags if needed */
4756 if(dwrq->flags & IW_ENCODE_MODE)
4757 local->need_commit = 1;
4758 return -EINPROGRESS; /* Call commit handler */
4761 /*------------------------------------------------------------------*/
4763 * Wireless Handler : get Encryption Key
4765 static int airo_get_encode(struct net_device *dev,
4766 struct iw_request_info *info,
4767 struct iw_point *dwrq,
4770 struct airo_info *local = dev->priv;
4771 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
4772 CapabilityRid cap_rid; /* Card capability info */
4774 /* Is it supported ? */
4775 readCapabilityRid(local, &cap_rid);
4776 if(!(cap_rid.softCap & 2)) {
4779 /* Check encryption mode */
4780 switch(local->config.authType) {
4782 dwrq->flags = IW_ENCODE_OPEN;
4784 case AUTH_SHAREDKEY:
4785 dwrq->flags = IW_ENCODE_RESTRICTED;
4789 dwrq->flags = IW_ENCODE_DISABLED;
4792 /* We can't return the key, so set the proper flag and return zero */
4793 dwrq->flags |= IW_ENCODE_NOKEY;
4794 memset(extra, 0, 16);
4796 /* Which key do we want ? -1 -> tx index */
4797 if((index < 0) || (index >= (cap_rid.softCap & 0x80) ? 4 : 1))
4798 index = get_wep_key(local, 0xffff);
4799 dwrq->flags |= index + 1;
4800 /* Copy the key to the user buffer */
4801 dwrq->length = get_wep_key(local, index);
4802 if (dwrq->length > 16) {
4808 /*------------------------------------------------------------------*/
4810 * Wireless Handler : set Tx-Power
4812 static int airo_set_txpow(struct net_device *dev,
4813 struct iw_request_info *info,
4814 struct iw_param *vwrq,
4817 struct airo_info *local = dev->priv;
4818 CapabilityRid cap_rid; /* Card capability info */
4822 readCapabilityRid(local, &cap_rid);
4824 if (vwrq->disabled) {
4825 local->flags |= FLAG_RADIO_OFF;
4826 local->need_commit = 1;
4827 return -EINPROGRESS; /* Call commit handler */
4829 if (vwrq->flags != IW_TXPOW_MWATT) {
4832 local->flags &= ~FLAG_RADIO_OFF;
4833 for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
4834 if ((vwrq->value==cap_rid.txPowerLevels[i])) {
4835 local->config.txPower = vwrq->value;
4836 local->need_commit = 1;
4837 rc = -EINPROGRESS; /* Call commit handler */
4843 /*------------------------------------------------------------------*/
4845 * Wireless Handler : get Tx-Power
4847 static int airo_get_txpow(struct net_device *dev,
4848 struct iw_request_info *info,
4849 struct iw_param *vwrq,
4852 struct airo_info *local = dev->priv;
4854 vwrq->value = local->config.txPower;
4855 vwrq->fixed = 1; /* No power control */
4856 vwrq->disabled = (local->flags & FLAG_RADIO_OFF);
4857 vwrq->flags = IW_TXPOW_MWATT;
4862 /*------------------------------------------------------------------*/
4864 * Wireless Handler : set Retry limits
4866 static int airo_set_retry(struct net_device *dev,
4867 struct iw_request_info *info,
4868 struct iw_param *vwrq,
4871 struct airo_info *local = dev->priv;
4874 if(vwrq->disabled) {
4877 if(vwrq->flags & IW_RETRY_LIMIT) {
4878 if(vwrq->flags & IW_RETRY_MAX)
4879 local->config.longRetryLimit = vwrq->value;
4880 else if (vwrq->flags & IW_RETRY_MIN)
4881 local->config.shortRetryLimit = vwrq->value;
4883 /* No modifier : set both */
4884 local->config.longRetryLimit = vwrq->value;
4885 local->config.shortRetryLimit = vwrq->value;
4887 local->need_commit = 1;
4888 rc = -EINPROGRESS; /* Call commit handler */
4890 if(vwrq->flags & IW_RETRY_LIFETIME) {
4891 local->config.txLifetime = vwrq->value / 1024;
4892 local->need_commit = 1;
4893 rc = -EINPROGRESS; /* Call commit handler */
4898 /*------------------------------------------------------------------*/
4900 * Wireless Handler : get Retry limits
4902 static int airo_get_retry(struct net_device *dev,
4903 struct iw_request_info *info,
4904 struct iw_param *vwrq,
4907 struct airo_info *local = dev->priv;
4909 vwrq->disabled = 0; /* Can't be disabled */
4911 /* Note : by default, display the min retry number */
4912 if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
4913 vwrq->flags = IW_RETRY_LIFETIME;
4914 vwrq->value = (int)local->config.txLifetime * 1024;
4915 } else if((vwrq->flags & IW_RETRY_MAX)) {
4916 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
4917 vwrq->value = (int)local->config.longRetryLimit;
4919 vwrq->flags = IW_RETRY_LIMIT;
4920 vwrq->value = (int)local->config.shortRetryLimit;
4921 if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
4922 vwrq->flags |= IW_RETRY_MIN;
4928 /*------------------------------------------------------------------*/
4930 * Wireless Handler : get range info
4932 static int airo_get_range(struct net_device *dev,
4933 struct iw_request_info *info,
4934 struct iw_point *dwrq,
4937 struct airo_info *local = dev->priv;
4938 struct iw_range *range = (struct iw_range *) extra;
4939 CapabilityRid cap_rid; /* Card capability info */
4943 readCapabilityRid(local, &cap_rid);
4945 dwrq->length = sizeof(struct iw_range);
4946 memset(range, 0, sizeof(*range));
4947 range->min_nwid = 0x0000;
4948 range->max_nwid = 0x0000;
4949 range->num_channels = 14;
4950 /* Should be based on cap_rid.country to give only
4951 * what the current card support */
4953 for(i = 0; i < 14; i++) {
4954 range->freq[k].i = i + 1; /* List index */
4955 range->freq[k].m = frequency_list[i] * 100000;
4956 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
4958 range->num_frequency = k;
4960 /* Hum... Should put the right values there */
4961 range->max_qual.qual = 10;
4962 range->max_qual.level = 0x100 - 120; /* -120 dBm */
4963 range->max_qual.noise = 0;
4964 range->sensitivity = 65535;
4966 for(i = 0 ; i < 8 ; i++) {
4967 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
4968 if(range->bitrate[i] == 0)
4971 range->num_bitrates = i;
4973 /* Set an indication of the max TCP throughput
4974 * in bit/s that we can expect using this interface.
4975 * May be use for QoS stuff... Jean II */
4977 range->throughput = 5000 * 1000;
4979 range->throughput = 1500 * 1000;
4982 range->max_rts = 2312;
4983 range->min_frag = 256;
4984 range->max_frag = 2312;
4986 if(cap_rid.softCap & 2) {
4988 range->encoding_size[0] = 5;
4990 if (cap_rid.softCap & 0x100) {
4991 range->encoding_size[1] = 13;
4992 range->num_encoding_sizes = 2;
4994 range->num_encoding_sizes = 1;
4995 range->max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1;
4997 range->num_encoding_sizes = 0;
4998 range->max_encoding_tokens = 0;
5001 range->max_pmp = 5000000; /* 5 secs */
5003 range->max_pmt = 65535 * 1024; /* ??? */
5004 range->pmp_flags = IW_POWER_PERIOD;
5005 range->pmt_flags = IW_POWER_TIMEOUT;
5006 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
5008 /* Transmit Power - values are in mW */
5009 for(i = 0 ; i < 8 ; i++) {
5010 range->txpower[i] = cap_rid.txPowerLevels[i];
5011 if(range->txpower[i] == 0)
5014 range->num_txpower = i;
5015 range->txpower_capa = IW_TXPOW_MWATT;
5016 range->we_version_source = 12;
5017 range->we_version_compiled = WIRELESS_EXT;
5018 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
5019 range->retry_flags = IW_RETRY_LIMIT;
5020 range->r_time_flags = IW_RETRY_LIFETIME;
5021 range->min_retry = 1;
5022 range->max_retry = 65535;
5023 range->min_r_time = 1024;
5024 range->max_r_time = 65535 * 1024;
5025 /* Experimental measurements - boundary 11/5.5 Mb/s */
5026 /* Note : with or without the (local->rssi), results
5027 * are somewhat different. - Jean II */
5028 range->avg_qual.qual = 6;
5030 range->avg_qual.level = 186; /* -70 dBm */
5032 range->avg_qual.level = 176; /* -80 dBm */
5033 range->avg_qual.noise = 0;
5038 /*------------------------------------------------------------------*/
5040 * Wireless Handler : set Power Management
5042 static int airo_set_power(struct net_device *dev,
5043 struct iw_request_info *info,
5044 struct iw_param *vwrq,
5047 struct airo_info *local = dev->priv;
5049 if (vwrq->disabled) {
5050 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
5053 local->config.powerSaveMode = POWERSAVE_CAM;
5054 local->config.rmode &= 0xFF00;
5055 local->config.rmode |= RXMODE_BC_MC_ADDR;
5056 local->need_commit = 1;
5057 return -EINPROGRESS; /* Call commit handler */
5059 if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
5060 local->config.fastListenDelay = (vwrq->value + 500) / 1024;
5061 local->config.powerSaveMode = POWERSAVE_PSPCAM;
5062 local->need_commit = 1;
5063 } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
5064 local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
5065 local->config.powerSaveMode = POWERSAVE_PSPCAM;
5066 local->need_commit = 1;
5068 switch (vwrq->flags & IW_POWER_MODE) {
5069 case IW_POWER_UNICAST_R:
5070 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
5073 local->config.rmode &= 0xFF00;
5074 local->config.rmode |= RXMODE_ADDR;
5075 local->need_commit = 1;
5077 case IW_POWER_ALL_R:
5078 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
5081 local->config.rmode &= 0xFF00;
5082 local->config.rmode |= RXMODE_BC_MC_ADDR;
5083 local->need_commit = 1;
5089 // Note : we may want to factor local->need_commit here
5090 // Note2 : may also want to factor RXMODE_RFMON test
5091 return -EINPROGRESS; /* Call commit handler */
5094 /*------------------------------------------------------------------*/
5096 * Wireless Handler : get Power Management
5098 static int airo_get_power(struct net_device *dev,
5099 struct iw_request_info *info,
5100 struct iw_param *vwrq,
5103 struct airo_info *local = dev->priv;
5105 int mode = local->config.powerSaveMode;
5106 if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
5108 if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
5109 vwrq->value = (int)local->config.fastListenDelay * 1024;
5110 vwrq->flags = IW_POWER_TIMEOUT;
5112 vwrq->value = (int)local->config.fastListenInterval * 1024;
5113 vwrq->flags = IW_POWER_PERIOD;
5115 if ((local->config.rmode & 0xFF) == RXMODE_ADDR)
5116 vwrq->flags |= IW_POWER_UNICAST_R;
5118 vwrq->flags |= IW_POWER_ALL_R;
5123 /*------------------------------------------------------------------*/
5125 * Wireless Handler : set Sensitivity
5127 static int airo_set_sens(struct net_device *dev,
5128 struct iw_request_info *info,
5129 struct iw_param *vwrq,
5132 struct airo_info *local = dev->priv;
5134 local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
5135 local->need_commit = 1;
5137 return -EINPROGRESS; /* Call commit handler */
5140 /*------------------------------------------------------------------*/
5142 * Wireless Handler : get Sensitivity
5144 static int airo_get_sens(struct net_device *dev,
5145 struct iw_request_info *info,
5146 struct iw_param *vwrq,
5149 struct airo_info *local = dev->priv;
5151 vwrq->value = local->config.rssiThreshold;
5152 vwrq->disabled = (vwrq->value == 0);
5158 /*------------------------------------------------------------------*/
5160 * Wireless Handler : get AP List
5161 * Note : this is deprecated in favor of IWSCAN
5163 static int airo_get_aplist(struct net_device *dev,
5164 struct iw_request_info *info,
5165 struct iw_point *dwrq,
5168 struct airo_info *local = dev->priv;
5169 struct sockaddr *address = (struct sockaddr *) extra;
5170 struct iw_quality qual[IW_MAX_AP];
5173 int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
5175 for (i = 0; i < IW_MAX_AP; i++) {
5176 if (readBSSListRid(local, loseSync, &BSSList))
5179 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
5180 address[i].sa_family = ARPHRD_ETHER;
5182 qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
5184 qual[i].level = (BSSList.rssi + 321) / 2;
5185 qual[i].qual = qual[i].noise = 0;
5186 qual[i].updated = 2;
5187 if (BSSList.index == 0xffff)
5191 StatusRid status_rid; /* Card status info */
5192 readStatusRid(local, &status_rid);
5194 i < min(IW_MAX_AP, 4) &&
5195 (status_rid.bssid[i][0]
5196 & status_rid.bssid[i][1]
5197 & status_rid.bssid[i][2]
5198 & status_rid.bssid[i][3]
5199 & status_rid.bssid[i][4]
5200 & status_rid.bssid[i][5])!=0xff &&
5201 (status_rid.bssid[i][0]
5202 | status_rid.bssid[i][1]
5203 | status_rid.bssid[i][2]
5204 | status_rid.bssid[i][3]
5205 | status_rid.bssid[i][4]
5206 | status_rid.bssid[i][5]);
5208 memcpy(address[i].sa_data,
5209 status_rid.bssid[i], ETH_ALEN);
5210 address[i].sa_family = ARPHRD_ETHER;
5213 dwrq->flags = 1; /* Should be define'd */
5214 memcpy(extra + sizeof(struct sockaddr)*i,
5215 &qual, sizeof(struct iw_quality)*i);
5222 #if WIRELESS_EXT > 13
5223 /*------------------------------------------------------------------*/
5225 * Wireless Handler : Initiate Scan
5227 static int airo_set_scan(struct net_device *dev,
5228 struct iw_request_info *info,
5229 struct iw_param *vwrq,
5232 struct airo_info *ai = dev->priv;
5236 /* Note : you may have realised that, as this is a SET operation,
5237 * this is privileged and therefore a normal user can't
5239 * This is not an error, while the device perform scanning,
5240 * traffic doesn't flow, so it's a perfect DoS...
5243 /* Initiate a scan command */
5244 memset(&cmd, 0, sizeof(cmd));
5245 cmd.cmd=CMD_LISTBSS;
5246 if (down_interruptible(&ai->sem))
5247 return -ERESTARTSYS;
5248 issuecommand(ai, &cmd, &rsp);
5249 ai->scan_timestamp = jiffies;
5252 /* At this point, just return to the user. */
5257 /*------------------------------------------------------------------*/
5259 * Translate scan data returned from the card to a card independent
5260 * format that the Wireless Tools will understand - Jean II
5262 static inline char *airo_translate_scan(struct net_device *dev,
5267 struct airo_info *ai = dev->priv;
5268 struct iw_event iwe; /* Temporary buffer */
5270 char * current_val; /* For rates */
5273 /* First entry *MUST* be the AP MAC address */
5274 iwe.cmd = SIOCGIWAP;
5275 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
5276 memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
5277 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
5279 /* Other entries will be displayed in the order we give them */
5282 iwe.u.data.length = list->ssidLen;
5283 if(iwe.u.data.length > 32)
5284 iwe.u.data.length = 32;
5285 iwe.cmd = SIOCGIWESSID;
5286 iwe.u.data.flags = 1;
5287 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
5290 iwe.cmd = SIOCGIWMODE;
5291 capabilities = le16_to_cpu(list->cap);
5292 if(capabilities & (CAP_ESS | CAP_IBSS)) {
5293 if(capabilities & CAP_ESS)
5294 iwe.u.mode = IW_MODE_MASTER;
5296 iwe.u.mode = IW_MODE_ADHOC;
5297 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
5301 iwe.cmd = SIOCGIWFREQ;
5302 iwe.u.freq.m = le16_to_cpu(list->dsChannel);
5303 iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
5305 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
5307 /* Add quality statistics */
5310 iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm;
5312 iwe.u.qual.level = (list->rssi + 321) / 2;
5313 iwe.u.qual.noise = 0;
5314 iwe.u.qual.qual = 0;
5315 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
5317 /* Add encryption capability */
5318 iwe.cmd = SIOCGIWENCODE;
5319 if(capabilities & CAP_PRIVACY)
5320 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
5322 iwe.u.data.flags = IW_ENCODE_DISABLED;
5323 iwe.u.data.length = 0;
5324 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
5326 /* Rate : stuffing multiple values in a single event require a bit
5327 * more of magic - Jean II */
5328 current_val = current_ev + IW_EV_LCP_LEN;
5330 iwe.cmd = SIOCGIWRATE;
5331 /* Those two flags are ignored... */
5332 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
5334 for(i = 0 ; i < 8 ; i++) {
5335 /* NULL terminated */
5336 if(list->rates[i] == 0)
5338 /* Bit rate given in 500 kb/s units (+ 0x80) */
5339 iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000);
5340 /* Add new value to event */
5341 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
5343 /* Check if we added any event */
5344 if((current_val - current_ev) > IW_EV_LCP_LEN)
5345 current_ev = current_val;
5347 /* The other data in the scan result are not really
5348 * interesting, so for now drop it - Jean II */
5352 /*------------------------------------------------------------------*/
5354 * Wireless Handler : Read Scan Results
5356 static int airo_get_scan(struct net_device *dev,
5357 struct iw_request_info *info,
5358 struct iw_point *dwrq,
5361 struct airo_info *ai = dev->priv;
5364 char *current_ev = extra;
5366 /* When we are associated again, the scan has surely finished.
5367 * Just in case, let's make sure enough time has elapsed since
5368 * we started the scan. - Javier */
5369 if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) {
5370 /* Important note : we don't want to block the caller
5371 * until results are ready for various reasons.
5372 * First, managing wait queues is complex and racy
5373 * (there may be multiple simultaneous callers).
5374 * Second, we grab some rtnetlink lock before comming
5375 * here (in dev_ioctl()).
5376 * Third, the caller can wait on the Wireless Event
5380 ai->scan_timestamp = 0;
5382 /* There's only a race with proc_BSSList_open(), but its
5383 * consequences are begnign. So I don't bother fixing it - Javier */
5385 /* Try to read the first entry of the scan result */
5386 rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1);
5387 if((rc) || (BSSList.index == 0xffff)) {
5388 /* Client error, no scan results...
5389 * The caller need to restart the scan. */
5393 /* Read and parse all entries */
5394 while((!rc) && (BSSList.index != 0xffff)) {
5395 /* Translate to WE format this entry */
5396 current_ev = airo_translate_scan(dev, current_ev,
5397 extra + IW_SCAN_MAX_DATA,
5400 /* Read next entry */
5401 rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
5402 &BSSList, sizeof(BSSList), 1);
5404 /* Length of data */
5405 dwrq->length = (current_ev - extra);
5406 dwrq->flags = 0; /* todo */
5410 #endif /* WIRELESS_EXT > 13 */
5412 #if WIRELESS_EXT <= 15
5414 /*------------------------------------------------------------------*/
5416 * Wireless Handler : set Spy List
5418 static int airo_set_spy(struct net_device *dev,
5419 struct iw_request_info *info,
5420 struct iw_point *dwrq,
5423 struct airo_info *local = dev->priv;
5424 struct sockaddr *address = (struct sockaddr *) extra;
5426 /* Disable spy while we copy the addresses.
5427 * As we don't disable interrupts, we need to do this to avoid races */
5428 local->spy_number = 0;
5430 if (dwrq->length > 0) {
5433 /* Copy addresses */
5434 for (i = 0; i < dwrq->length; i++)
5435 memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
5437 memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
5439 /* Enable addresses */
5440 local->spy_number = dwrq->length;
5445 /*------------------------------------------------------------------*/
5447 * Wireless Handler : get Spy List
5449 static int airo_get_spy(struct net_device *dev,
5450 struct iw_request_info *info,
5451 struct iw_point *dwrq,
5454 struct airo_info *local = dev->priv;
5455 struct sockaddr *address = (struct sockaddr *) extra;
5458 dwrq->length = local->spy_number;
5460 /* Copy addresses. */
5461 for(i = 0; i < local->spy_number; i++) {
5462 memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN);
5463 address[i].sa_family = AF_UNIX;
5465 /* Copy stats to the user buffer (just after). */
5466 if(local->spy_number > 0)
5467 memcpy(extra + (sizeof(struct sockaddr) * local->spy_number),
5468 local->spy_stat, sizeof(struct iw_quality) * local->spy_number);
5469 /* Reset updated flags. */
5470 for (i=0; i<local->spy_number; i++)
5471 local->spy_stat[i].updated = 0;
5474 #endif /* WIRELESS_SPY */
5475 #endif /* WIRELESS_EXT <= 15 */
5477 /*------------------------------------------------------------------*/
5479 * Commit handler : called after a bunch of SET operations
5481 static int airo_config_commit(struct net_device *dev,
5482 struct iw_request_info *info, /* NULL */
5483 void *zwrq, /* NULL */
5484 char *extra) /* NULL */
5486 struct airo_info *local = dev->priv;
5489 if (!local->need_commit)
5492 /* Some of the "SET" function may have modified some of the
5493 * parameters. It's now time to commit them in the card */
5494 disable_MAC(local, 1);
5495 if (local->need_commit > 1) {
5496 APListRid APList_rid;
5499 readAPListRid(local, &APList_rid);
5500 readSsidRid(local, &SSID_rid);
5501 reset_airo_card(dev);
5502 disable_MAC(local, 1);
5503 writeSsidRid(local, &SSID_rid);
5504 writeAPListRid(local, &APList_rid);
5506 writeConfigRid(local, 1);
5507 enable_MAC(local, &rsp, 1);
5508 if (local->need_commit > 1)
5509 airo_set_promisc(local);
5514 /*------------------------------------------------------------------*/
5516 * Structures to export the Wireless Handlers
5519 static const struct iw_priv_args airo_private_args[] = {
5520 /*{ cmd, set_args, get_args, name } */
5521 { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
5522 IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
5523 { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
5524 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
5527 #if WIRELESS_EXT > 12
5528 static const iw_handler airo_handler[] =
5530 (iw_handler) airo_config_commit, /* SIOCSIWCOMMIT */
5531 (iw_handler) airo_get_name, /* SIOCGIWNAME */
5532 (iw_handler) NULL, /* SIOCSIWNWID */
5533 (iw_handler) NULL, /* SIOCGIWNWID */
5534 (iw_handler) airo_set_freq, /* SIOCSIWFREQ */
5535 (iw_handler) airo_get_freq, /* SIOCGIWFREQ */
5536 (iw_handler) airo_set_mode, /* SIOCSIWMODE */
5537 (iw_handler) airo_get_mode, /* SIOCGIWMODE */
5538 (iw_handler) airo_set_sens, /* SIOCSIWSENS */
5539 (iw_handler) airo_get_sens, /* SIOCGIWSENS */
5540 (iw_handler) NULL, /* SIOCSIWRANGE */
5541 (iw_handler) airo_get_range, /* SIOCGIWRANGE */
5542 (iw_handler) NULL, /* SIOCSIWPRIV */
5543 (iw_handler) NULL, /* SIOCGIWPRIV */
5544 (iw_handler) NULL, /* SIOCSIWSTATS */
5545 (iw_handler) NULL, /* SIOCGIWSTATS */
5546 #if WIRELESS_EXT > 15
5547 iw_handler_set_spy, /* SIOCSIWSPY */
5548 iw_handler_get_spy, /* SIOCGIWSPY */
5549 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
5550 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
5551 #else /* WIRELESS_EXT > 15 */
5553 (iw_handler) airo_set_spy, /* SIOCSIWSPY */
5554 (iw_handler) airo_get_spy, /* SIOCGIWSPY */
5555 #else /* WIRELESS_SPY */
5556 (iw_handler) NULL, /* SIOCSIWSPY */
5557 (iw_handler) NULL, /* SIOCGIWSPY */
5558 #endif /* WIRELESS_SPY */
5559 (iw_handler) NULL, /* -- hole -- */
5560 (iw_handler) NULL, /* -- hole -- */
5561 #endif /* WIRELESS_EXT > 15 */
5562 (iw_handler) airo_set_wap, /* SIOCSIWAP */
5563 (iw_handler) airo_get_wap, /* SIOCGIWAP */
5564 (iw_handler) NULL, /* -- hole -- */
5565 (iw_handler) airo_get_aplist, /* SIOCGIWAPLIST */
5566 #if WIRELESS_EXT > 13
5567 (iw_handler) airo_set_scan, /* SIOCSIWSCAN */
5568 (iw_handler) airo_get_scan, /* SIOCGIWSCAN */
5569 #else /* WIRELESS_EXT > 13 */
5570 (iw_handler) NULL, /* SIOCSIWSCAN */
5571 (iw_handler) NULL, /* SIOCGIWSCAN */
5572 #endif /* WIRELESS_EXT > 13 */
5573 (iw_handler) airo_set_essid, /* SIOCSIWESSID */
5574 (iw_handler) airo_get_essid, /* SIOCGIWESSID */
5575 (iw_handler) airo_set_nick, /* SIOCSIWNICKN */
5576 (iw_handler) airo_get_nick, /* SIOCGIWNICKN */
5577 (iw_handler) NULL, /* -- hole -- */
5578 (iw_handler) NULL, /* -- hole -- */
5579 (iw_handler) airo_set_rate, /* SIOCSIWRATE */
5580 (iw_handler) airo_get_rate, /* SIOCGIWRATE */
5581 (iw_handler) airo_set_rts, /* SIOCSIWRTS */
5582 (iw_handler) airo_get_rts, /* SIOCGIWRTS */
5583 (iw_handler) airo_set_frag, /* SIOCSIWFRAG */
5584 (iw_handler) airo_get_frag, /* SIOCGIWFRAG */
5585 (iw_handler) airo_set_txpow, /* SIOCSIWTXPOW */
5586 (iw_handler) airo_get_txpow, /* SIOCGIWTXPOW */
5587 (iw_handler) airo_set_retry, /* SIOCSIWRETRY */
5588 (iw_handler) airo_get_retry, /* SIOCGIWRETRY */
5589 (iw_handler) airo_set_encode, /* SIOCSIWENCODE */
5590 (iw_handler) airo_get_encode, /* SIOCGIWENCODE */
5591 (iw_handler) airo_set_power, /* SIOCSIWPOWER */
5592 (iw_handler) airo_get_power, /* SIOCGIWPOWER */
5595 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
5596 * We want to force the use of the ioctl code, because those can't be
5597 * won't work the iw_handler code (because they simultaneously read
5598 * and write data and iw_handler can't do that).
5599 * Note that it's perfectly legal to read/write on a single ioctl command,
5600 * you just can't use iwpriv and need to force it via the ioctl handler.
5602 static const iw_handler airo_private_handler[] =
5604 NULL, /* SIOCIWFIRSTPRIV */
5607 static const struct iw_handler_def airo_handler_def =
5609 .num_standard = sizeof(airo_handler)/sizeof(iw_handler),
5610 .num_private = sizeof(airo_private_handler)/sizeof(iw_handler),
5611 .num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args),
5612 .standard = (iw_handler *) airo_handler,
5613 .private = (iw_handler *) airo_private_handler,
5614 .private_args = (struct iw_priv_args *) airo_private_args,
5615 #if 0 && WIRELESS_EXT > 15
5616 .spy_offset = ((void *) (&((struct airo_info *) NULL)->spy_data) -
5618 #endif /* WIRELESS_EXT > 15 */
5622 #endif /* WIRELESS_EXT > 12 */
5623 #endif /* WIRELESS_EXT */
5626 * This defines the configuration part of the Wireless Extensions
5627 * Note : irq and spinlock protection will occur in the subroutines
5630 * o Check input value more carefully and fill correct values in range
5631 * o Test and shakeout the bugs (if any)
5635 * Javier Achirica did a great job of merging code from the unnamed CISCO
5636 * developer that added support for flashing the card.
5638 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5641 #if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
5642 struct iwreq *wrq = (struct iwreq *) rq;
5643 #endif /* WIRELESS_EXT < 13 */
5646 /* WE 13 and higher will use airo_handler_def */
5647 #if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
5648 case SIOCGIWNAME: // Get name
5649 airo_get_name(dev, NULL, (char *) &(wrq->u.name), NULL);
5652 case SIOCSIWFREQ: // Set frequency/channel
5653 rc = airo_set_freq(dev, NULL, &(wrq->u.freq), NULL);
5656 case SIOCGIWFREQ: // Get frequency/channel
5657 rc = airo_get_freq(dev, NULL, &(wrq->u.freq), NULL);
5660 case SIOCSIWESSID: // Set desired network name (ESSID)
5662 char essidbuf[IW_ESSID_MAX_SIZE+1];
5663 if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
5667 if (copy_from_user(essidbuf, wrq->u.essid.pointer,
5668 wrq->u.essid.length)) {
5672 rc = airo_set_essid(dev, NULL,
5673 &(wrq->u.essid), essidbuf);
5677 case SIOCGIWESSID: // Get current network name (ESSID)
5679 char essidbuf[IW_ESSID_MAX_SIZE+1];
5680 if (wrq->u.essid.pointer)
5681 rc = airo_get_essid(dev, NULL,
5682 &(wrq->u.essid), essidbuf);
5683 if ( copy_to_user(wrq->u.essid.pointer,
5685 wrq->u.essid.length) )
5691 rc = airo_set_wap(dev, NULL, &(wrq->u.ap_addr), NULL);
5694 case SIOCGIWAP: // Get current Access Point (BSSID)
5695 rc = airo_get_wap(dev, NULL, &(wrq->u.ap_addr), NULL);
5698 case SIOCSIWNICKN: // Set desired station name
5700 char nickbuf[IW_ESSID_MAX_SIZE+1];
5701 if (wrq->u.data.length > IW_ESSID_MAX_SIZE) {
5705 if (copy_from_user(nickbuf, wrq->u.data.pointer,
5706 wrq->u.data.length)) {
5710 rc = airo_set_nick(dev, NULL,
5711 &(wrq->u.data), nickbuf);
5715 case SIOCGIWNICKN: // Get current station name
5717 char nickbuf[IW_ESSID_MAX_SIZE+1];
5718 if (wrq->u.data.pointer)
5719 rc = airo_get_nick(dev, NULL,
5720 &(wrq->u.data), nickbuf);
5721 if ( copy_to_user(wrq->u.data.pointer,
5723 wrq->u.data.length) )
5728 case SIOCSIWRATE: // Set the desired bit-rate
5729 rc = airo_set_rate(dev, NULL, &(wrq->u.bitrate), NULL);
5732 case SIOCGIWRATE: // Get the current bit-rate
5733 rc = airo_get_rate(dev, NULL, &(wrq->u.bitrate), NULL);
5736 case SIOCSIWRTS: // Set the desired RTS threshold
5737 rc = airo_set_rts(dev, NULL, &(wrq->u.rts), NULL);
5740 case SIOCGIWRTS: // Get the current RTS threshold
5741 rc = airo_get_rts(dev, NULL, &(wrq->u.rts), NULL);
5744 case SIOCSIWFRAG: // Set the desired fragmentation threshold
5745 rc = airo_set_frag(dev, NULL, &(wrq->u.frag), NULL);
5748 case SIOCGIWFRAG: // Get the current fragmentation threshold
5749 rc = airo_get_frag(dev, NULL, &(wrq->u.frag), NULL);
5752 case SIOCSIWMODE: // Set mode of operation
5753 rc = airo_set_mode(dev, NULL, &(wrq->u.mode), NULL);
5756 case SIOCGIWMODE: // Get mode of operation
5757 rc = airo_get_mode(dev, NULL, &(wrq->u.mode), NULL);
5760 case SIOCSIWENCODE: // Set WEP keys and mode
5762 char keybuf[MAX_KEY_SIZE];
5763 if (wrq->u.encoding.pointer) {
5764 /* We actually have a key to set */
5765 if (wrq->u.encoding.length > MAX_KEY_SIZE) {
5769 if (copy_from_user(keybuf,
5770 wrq->u.encoding.pointer,
5771 wrq->u.encoding.length)) {
5775 } else if (wrq->u.encoding.length != 0) {
5779 rc = airo_set_encode(dev, NULL,
5780 &(wrq->u.encoding), keybuf);
5784 case SIOCGIWENCODE: // Get the WEP keys and mode
5785 // Only super-user can see WEP key
5786 // Note : this is needed only for very old versions of WE
5787 if (!capable(CAP_NET_ADMIN)) {
5792 char keybuf[MAX_KEY_SIZE];
5793 rc = airo_get_encode(dev, NULL,
5794 &(wrq->u.encoding), keybuf);
5795 if (wrq->u.encoding.pointer) {
5796 if (copy_to_user(wrq->u.encoding.pointer,
5798 wrq->u.encoding.length))
5804 case SIOCGIWTXPOW: // Get the current Tx-Power
5805 rc=airo_get_txpow(dev, NULL, &(wrq->u.txpower), NULL);
5808 rc=airo_set_txpow(dev, NULL, &(wrq->u.txpower), NULL);
5812 rc=airo_set_retry(dev, NULL, &(wrq->u.retry), NULL);
5815 rc=airo_get_retry(dev, NULL, &(wrq->u.retry), NULL);
5818 case SIOCGIWRANGE: // Get range of parameters
5820 struct iw_range range;
5821 rc = airo_get_range(dev, NULL,
5822 &(wrq->u.data), (char *) &range);
5823 if (copy_to_user(wrq->u.data.pointer, &range,
5824 sizeof(struct iw_range)))
5830 rc=airo_get_power(dev, NULL, &(wrq->u.power), NULL);
5834 rc=airo_set_power(dev, NULL, &(wrq->u.power), NULL);
5838 rc = airo_get_sens(dev, NULL, &(wrq->u.sens), NULL);
5842 rc = airo_set_sens(dev, NULL, &(wrq->u.sens), NULL);
5847 char buffer[IW_MAX_AP * (sizeof(struct sockaddr) +
5848 sizeof(struct iw_quality))];
5849 if (wrq->u.data.pointer) {
5850 rc = airo_get_aplist(dev, NULL,
5851 &(wrq->u.data), buffer);
5852 if (copy_to_user(wrq->u.data.pointer,
5854 (wrq->u.data.length *
5855 (sizeof(struct sockaddr) +
5856 sizeof(struct iw_quality)))
5864 case SIOCSIWSPY: // Set the spy list
5866 struct sockaddr address[IW_MAX_SPY];
5867 /* Check the number of addresses */
5868 if (wrq->u.data.length > IW_MAX_SPY) {
5872 /* Get the data in the driver */
5873 if (wrq->u.data.pointer) {
5874 if (copy_from_user((char *) address,
5875 wrq->u.data.pointer,
5876 sizeof(struct sockaddr) *
5877 wrq->u.data.length)) {
5881 } else if (wrq->u.data.length != 0) {
5885 rc=airo_set_spy(dev, NULL, &(wrq->u.data),
5890 case SIOCGIWSPY: // Get the spy list
5892 char buffer[IW_MAX_SPY * (sizeof(struct sockaddr) +
5893 sizeof(struct iw_quality))];
5894 if (wrq->u.data.pointer) {
5895 rc = airo_get_spy(dev, NULL,
5896 &(wrq->u.data), buffer);
5897 if (copy_to_user(wrq->u.data.pointer,
5899 (wrq->u.data.length *
5900 (sizeof(struct sockaddr) +
5901 sizeof(struct iw_quality)))
5907 #endif /* WIRELESS_SPY */
5911 if(wrq->u.data.pointer) {
5912 /* Set the number of ioctl available */
5913 wrq->u.data.length = sizeof(airo_private_args) / sizeof( airo_private_args[0]);
5915 /* Copy structure to the user buffer */
5916 if(copy_to_user(wrq->u.data.pointer,
5917 (u_char *) airo_private_args,
5918 sizeof(airo_private_args)))
5922 #endif /* CISCO_EXT */
5923 #endif /* WIRELESS_EXT < 13 */
5931 int val = AIROMAGIC;
5933 if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
5935 else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
5944 /* Get the command struct and hand it off for evaluation by
5945 * the proper subfunction
5949 if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
5954 /* Separate R/W functions bracket legality here
5956 if ( com.command <= AIROGMICSTATS )
5957 rc = readrids(dev,&com);
5958 else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR )
5959 rc = writerids(dev,&com);
5960 else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
5961 rc = flashcard(dev,&com);
5963 rc = -EINVAL; /* Bad command in ioctl */
5966 #endif /* CISCO_EXT */
5968 // All other calls are currently unsupported
5973 #if defined(WIRELESS_EXT) && WIRELESS_EXT < 13
5974 /* WE 13 and higher will use airo_config_commit */
5975 /* Some of the "SET" function may have modified some of the
5976 * parameters. It's now time to commit them in the card */
5977 airo_config_commit(dev, NULL, NULL, NULL);
5978 if (rc == -EINPROGRESS)
5980 #endif /* WIRELESS_EXT < 13 */
5987 * Get the Wireless stats out of the driver
5988 * Note : irq and spinlock protection will occur in the subroutines
5991 * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
5995 struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
5997 struct airo_info *local = dev->priv;
5998 StatusRid status_rid;
6000 u32 *vals = stats_rid.vals;
6002 /* Get stats out of the card */
6003 readStatusRid(local, &status_rid);
6004 readStatsRid(local, &stats_rid, RID_STATS, 1);
6007 local->wstats.status = status_rid.mode;
6009 /* Signal quality and co. But where is the noise level ??? */
6010 local->wstats.qual.qual = status_rid.signalQuality;
6012 local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
6014 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
6015 if (status_rid.len >= 124) {
6016 local->wstats.qual.noise = 256 - status_rid.noisedBm;
6017 local->wstats.qual.updated = 7;
6019 local->wstats.qual.noise = 0;
6020 local->wstats.qual.updated = 3;
6023 /* Packets discarded in the wireless adapter due to wireless
6024 * specific problems */
6025 local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
6026 local->wstats.discard.code = vals[6];/* RxWepErr */
6027 local->wstats.discard.fragment = vals[30];
6028 local->wstats.discard.retries = vals[10];
6029 local->wstats.discard.misc = vals[1] + vals[32];
6030 local->wstats.miss.beacon = vals[34];
6031 return &local->wstats;
6033 #endif /* WIRELESS_EXT */
6036 #define RIDS_SIZE 2048
6038 * This just translates from driver IOCTL codes to the command codes to
6039 * feed to the radio's host interface. Things can be added/deleted
6040 * as needed. This represents the READ side of control I/O to
6043 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
6044 unsigned short ridcode;
6045 unsigned char *iobuf;
6046 struct airo_info *ai = dev->priv;
6048 if (ai->flags & FLAG_FLASHING)
6051 switch(comp->command)
6053 case AIROGCAP: ridcode = RID_CAPABILITIES; break;
6054 case AIROGCFG: writeConfigRid (ai, 1);
6055 ridcode = RID_CONFIG; break;
6056 case AIROGSLIST: ridcode = RID_SSID; break;
6057 case AIROGVLIST: ridcode = RID_APLIST; break;
6058 case AIROGDRVNAM: ridcode = RID_DRVNAME; break;
6059 case AIROGEHTENC: ridcode = RID_ETHERENCAP; break;
6060 case AIROGWEPKTMP: ridcode = RID_WEP_TEMP;
6061 /* Only super-user can read WEP keys */
6062 if (!capable(CAP_NET_ADMIN))
6065 case AIROGWEPKNV: ridcode = RID_WEP_PERM;
6066 /* Only super-user can read WEP keys */
6067 if (!capable(CAP_NET_ADMIN))
6070 case AIROGSTAT: ridcode = RID_STATUS; break;
6071 case AIROGSTATSD32: ridcode = RID_STATSDELTA; break;
6072 case AIROGSTATSC32: ridcode = RID_STATS; break;
6074 if (copy_to_user(comp->data, &ai->micstats,
6075 min((int)comp->len,(int)sizeof(ai->micstats))))
6083 if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
6086 PC4500_readrid(ai,ridcode,iobuf,RIDS_SIZE, 1);
6087 /* get the count of bytes in the rid docs say 1st 2 bytes is it.
6088 * then return it to the user
6089 * 9/22/2000 Honor user given length
6092 if (copy_to_user(comp->data, iobuf,
6093 min((int)comp->len, (int)RIDS_SIZE))) {
6102 * Danger Will Robinson write the rids here
6105 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
6106 struct airo_info *ai = dev->priv;
6107 int ridcode, enabled;
6109 static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
6110 unsigned char *iobuf;
6112 /* Only super-user can write RIDs */
6113 if (!capable(CAP_NET_ADMIN))
6116 if (ai->flags & FLAG_FLASHING)
6120 writer = do_writerid;
6122 switch(comp->command)
6124 case AIROPSIDS: ridcode = RID_SSID; break;
6125 case AIROPCAP: ridcode = RID_CAPABILITIES; break;
6126 case AIROPAPLIST: ridcode = RID_APLIST; break;
6127 case AIROPCFG: ai->config.len = 0;
6128 ridcode = RID_CONFIG; break;
6129 case AIROPWEPKEYNV: ridcode = RID_WEP_PERM; break;
6130 case AIROPLEAPUSR: ridcode = RID_LEAPUSERNAME; break;
6131 case AIROPLEAPPWD: ridcode = RID_LEAPPASSWORD; break;
6132 case AIROPWEPKEY: ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
6135 /* this is not really a rid but a command given to the card
6139 if (enable_MAC(ai, &rsp, 1) != 0)
6144 * Evidently this code in the airo driver does not get a symbol
6145 * as disable_MAC. it's probably so short the compiler does not gen one.
6151 /* This command merely clears the counts does not actually store any data
6152 * only reads rid. But as it changes the cards state, I put it in the
6153 * writerid routines.
6156 if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
6159 PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDS_SIZE, 1);
6161 enabled = ai->micstats.enabled;
6162 memset(&ai->micstats,0,sizeof(ai->micstats));
6163 ai->micstats.enabled = enabled;
6165 if (copy_to_user(comp->data, iobuf,
6166 min((int)comp->len, (int)RIDS_SIZE))) {
6174 return -EOPNOTSUPP; /* Blarg! */
6176 if(comp->len > RIDS_SIZE)
6179 if ((iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL)) == NULL)
6182 if (copy_from_user(iobuf,comp->data,comp->len)) {
6187 if (comp->command == AIROPCFG) {
6188 ConfigRid *cfg = (ConfigRid *)iobuf;
6190 if (ai->flags & FLAG_MIC_CAPABLE)
6191 cfg->opmode |= MODE_MIC;
6193 if ((cfg->opmode & 0xFF) == MODE_STA_IBSS)
6194 ai->flags |= FLAG_ADHOC;
6196 ai->flags &= ~FLAG_ADHOC;
6199 if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
6207 /*****************************************************************************
6208 * Ancillary flash / mod functions much black magic lurkes here *
6209 *****************************************************************************
6213 * Flash command switch table
6216 int flashcard(struct net_device *dev, aironet_ioctl *comp) {
6218 int cmdreset(struct airo_info *);
6219 int setflashmode(struct airo_info *);
6220 int flashgchar(struct airo_info *,int,int);
6221 int flashpchar(struct airo_info *,int,int);
6222 int flashputbuf(struct airo_info *);
6223 int flashrestart(struct airo_info *,struct net_device *);
6225 /* Only super-user can modify flash */
6226 if (!capable(CAP_NET_ADMIN))
6229 switch(comp->command)
6232 return cmdreset((struct airo_info *)dev->priv);
6235 if (!((struct airo_info *)dev->priv)->flash &&
6236 (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
6238 return setflashmode((struct airo_info *)dev->priv);
6240 case AIROFLSHGCHR: /* Get char from aux */
6241 if(comp->len != sizeof(int))
6243 if (copy_from_user(&z,comp->data,comp->len))
6245 return flashgchar((struct airo_info *)dev->priv,z,8000);
6247 case AIROFLSHPCHR: /* Send char to card. */
6248 if(comp->len != sizeof(int))
6250 if (copy_from_user(&z,comp->data,comp->len))
6252 return flashpchar((struct airo_info *)dev->priv,z,8000);
6254 case AIROFLPUTBUF: /* Send 32k to card */
6255 if (!((struct airo_info *)dev->priv)->flash)
6257 if(comp->len > FLASHSIZE)
6259 if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
6262 flashputbuf((struct airo_info *)dev->priv);
6266 if(flashrestart((struct airo_info *)dev->priv,dev))
6273 #define FLASH_COMMAND 0x7e7e
6277 * Disable MAC and do soft reset on
6281 int cmdreset(struct airo_info *ai) {
6285 printk(KERN_INFO "Waitbusy hang before RESET\n");
6289 OUT4500(ai,COMMAND,CMD_SOFTRESET);
6291 set_current_state (TASK_UNINTERRUPTIBLE);
6292 schedule_timeout (HZ); /* WAS 600 12/7/00 */
6295 printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
6302 * Put the card in legendary flash
6306 int setflashmode (struct airo_info *ai) {
6307 ai->flags |= FLAG_FLASHING;
6309 OUT4500(ai, SWS0, FLASH_COMMAND);
6310 OUT4500(ai, SWS1, FLASH_COMMAND);
6312 OUT4500(ai, SWS0, FLASH_COMMAND);
6313 OUT4500(ai, COMMAND,0x10);
6315 OUT4500(ai, SWS2, FLASH_COMMAND);
6316 OUT4500(ai, SWS3, FLASH_COMMAND);
6317 OUT4500(ai, COMMAND,0);
6319 set_current_state (TASK_UNINTERRUPTIBLE);
6320 schedule_timeout (HZ/2); /* 500ms delay */
6323 ai->flags &= ~FLAG_FLASHING;
6324 printk(KERN_INFO "Waitbusy hang after setflash mode\n");
6330 /* Put character to SWS0 wait for dwelltime
6334 int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
6345 /* Wait for busy bit d15 to go false indicating buffer empty */
6346 while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
6351 /* timeout for busy clear wait */
6353 printk(KERN_INFO "flash putchar busywait timeout! \n");
6357 /* Port is clear now write byte and wait for it to echo back */
6359 OUT4500(ai,SWS0,byte);
6362 echo = IN4500(ai,SWS1);
6363 } while (dwelltime >= 0 && echo != byte);
6367 return (echo == byte) ? 0 : -EIO;
6371 * Get a character from the card matching matchbyte
6374 int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
6376 unsigned char rbyte=0;
6379 rchar = IN4500(ai,SWS1);
6381 if(dwelltime && !(0x8000 & rchar)){
6386 rbyte = 0xff & rchar;
6388 if( (rbyte == matchbyte) && (0x8000 & rchar) ){
6392 if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
6396 }while(dwelltime > 0);
6401 * Transfer 32k of firmware data from user buffer to our buffer and
6405 int flashputbuf(struct airo_info *ai){
6409 OUT4500(ai,AUXPAGE,0x100);
6410 OUT4500(ai,AUXOFF,0);
6412 for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
6413 OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
6416 OUT4500(ai,SWS0,0x8000);
6424 int flashrestart(struct airo_info *ai,struct net_device *dev){
6427 set_current_state (TASK_UNINTERRUPTIBLE);
6428 schedule_timeout (HZ); /* Added 12/7/00 */
6429 ai->flags &= ~FLAG_FLASHING;
6430 status = setup_card(ai, dev->dev_addr);
6432 for( i = 0; i < MAX_FIDS; i++ ) {
6433 ai->fids[i] = transmit_allocate( ai, 2312, i >= MAX_FIDS / 2 );
6436 set_current_state (TASK_UNINTERRUPTIBLE);
6437 schedule_timeout (HZ); /* Added 12/7/00 */
6440 #endif /* CISCO_EXT */
6443 This program is free software; you can redistribute it and/or
6444 modify it under the terms of the GNU General Public License
6445 as published by the Free Software Foundation; either version 2
6446 of the License, or (at your option) any later version.
6448 This program is distributed in the hope that it will be useful,
6449 but WITHOUT ANY WARRANTY; without even the implied warranty of
6450 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6451 GNU General Public License for more details.
6455 Redistribution and use in source and binary forms, with or without
6456 modification, are permitted provided that the following conditions
6459 1. Redistributions of source code must retain the above copyright
6460 notice, this list of conditions and the following disclaimer.
6461 2. Redistributions in binary form must reproduce the above copyright
6462 notice, this list of conditions and the following disclaimer in the
6463 documentation and/or other materials provided with the distribution.
6464 3. The name of the author may not be used to endorse or promote
6465 products derived from this software without specific prior written
6468 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6469 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6470 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6471 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
6472 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6473 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6474 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6475 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
6476 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
6477 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6478 POSSIBILITY OF SUCH DAMAGE.
6481 module_init(airo_init_module);
6482 module_exit(airo_cleanup_module);