File: /usr/src/linux/drivers/net/wireless/airo.c
1 /*======================================================================
2
3 Aironet driver for 4500 and 4800 series cards
4
5 This code is released under both the GPL version 2 and BSD licenses.
6 Either license may be used. The respective licenses are found at
7 the end of this file.
8
9 This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10 including portions of which come from the Aironet PC4500
11 Developer's Reference Manual and used with permission. Copyright
12 (C) 1999 Benjamin Reed. All Rights Reserved. Permission to use
13 code in the Developer's manual was granted for this driver by
14 Aironet. Major code contributions were received from Javier Achirica
15 and Jean Tourrilhes <jt@hpl.hp.com>. Code was also integrated from
16 the Cisco Aironet driver for Linux.
17
18 ======================================================================*/
19
20 #include <linux/config.h>
21 #include <linux/version.h>
22 #include <asm/segment.h>
23 #include <linux/init.h>
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/proc_fs.h>
28
29 #include <linux/sched.h>
30 #include <linux/ptrace.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/timer.h>
34 #include <linux/interrupt.h>
35 #include <linux/in.h>
36 #include <asm/io.h>
37 #include <asm/system.h>
38 #include <asm/bitops.h>
39
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>
48
49 #ifdef CONFIG_PCI
50 static struct pci_device_id card_ids[] = __devinitdata {
51 { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
52 { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
53 { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
54 { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
55 { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
56 { 0, }
57 };
58 MODULE_DEVICE_TABLE(pci, card_ids);
59
60 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
61 static void airo_pci_remove(struct pci_dev *);
62
63 static struct pci_driver airo_driver = {
64 name: "airo",
65 id_table: card_ids,
66 probe: airo_pci_probe,
67 remove: airo_pci_remove,
68 };
69 #endif /* CONFIG_PCI */
70
71 /* Include Wireless Extension definition and check version - Jean II */
72 #include <linux/wireless.h>
73 #define WIRELESS_SPY // enable iwspy support
74 #if WIRELESS_EXT < 9
75 #warning "Wireless extension v9 or newer required - please upgrade your kernel"
76 #undef WIRELESS_EXT
77 #undef WIRELESS_SPY
78 #endif
79 #define CISCO_EXT // enable Cisco extensions
80
81 #ifdef CISCO_EXT
82 #include <linux/delay.h>
83 #endif
84
85 /* As you can see this list is HUGH!
86 I really don't know what a lot of these counts are about, but they
87 are all here for completeness. If the IGNLABEL macro is put in
88 infront of the label, that statistic will not be included in the list
89 of statistics in the /proc filesystem */
90
91 #define IGNLABEL 0&(int)
92 static char *statsLabels[] = {
93 "RxOverrun",
94 IGNLABEL "RxPlcpCrcErr",
95 IGNLABEL "RxPlcpFormatErr",
96 IGNLABEL "RxPlcpLengthErr",
97 "RxMacCrcErr",
98 "RxMacCrcOk",
99 "RxWepErr",
100 "RxWepOk",
101 "RetryLong",
102 "RetryShort",
103 "MaxRetries",
104 "NoAck",
105 "NoCts",
106 "RxAck",
107 "RxCts",
108 "TxAck",
109 "TxRts",
110 "TxCts",
111 "TxMc",
112 "TxBc",
113 "TxUcFrags",
114 "TxUcPackets",
115 "TxBeacon",
116 "RxBeacon",
117 "TxSinColl",
118 "TxMulColl",
119 "DefersNo",
120 "DefersProt",
121 "DefersEngy",
122 "DupFram",
123 "RxFragDisc",
124 "TxAged",
125 "RxAged",
126 "LostSync-MaxRetry",
127 "LostSync-MissedBeacons",
128 "LostSync-ArlExceeded",
129 "LostSync-Deauth",
130 "LostSync-Disassoced",
131 "LostSync-TsfTiming",
132 "HostTxMc",
133 "HostTxBc",
134 "HostTxUc",
135 "HostTxFail",
136 "HostRxMc",
137 "HostRxBc",
138 "HostRxUc",
139 "HostRxDiscard",
140 IGNLABEL "HmacTxMc",
141 IGNLABEL "HmacTxBc",
142 IGNLABEL "HmacTxUc",
143 IGNLABEL "HmacTxFail",
144 IGNLABEL "HmacRxMc",
145 IGNLABEL "HmacRxBc",
146 IGNLABEL "HmacRxUc",
147 IGNLABEL "HmacRxDiscard",
148 IGNLABEL "HmacRxAccepted",
149 "SsidMismatch",
150 "ApMismatch",
151 "RatesMismatch",
152 "AuthReject",
153 "AuthTimeout",
154 "AssocReject",
155 "AssocTimeout",
156 IGNLABEL "ReasonOutsideTable",
157 IGNLABEL "ReasonStatus1",
158 IGNLABEL "ReasonStatus2",
159 IGNLABEL "ReasonStatus3",
160 IGNLABEL "ReasonStatus4",
161 IGNLABEL "ReasonStatus5",
162 IGNLABEL "ReasonStatus6",
163 IGNLABEL "ReasonStatus7",
164 IGNLABEL "ReasonStatus8",
165 IGNLABEL "ReasonStatus9",
166 IGNLABEL "ReasonStatus10",
167 IGNLABEL "ReasonStatus11",
168 IGNLABEL "ReasonStatus12",
169 IGNLABEL "ReasonStatus13",
170 IGNLABEL "ReasonStatus14",
171 IGNLABEL "ReasonStatus15",
172 IGNLABEL "ReasonStatus16",
173 IGNLABEL "ReasonStatus17",
174 IGNLABEL "ReasonStatus18",
175 IGNLABEL "ReasonStatus19",
176 "RxMan",
177 "TxMan",
178 "RxRefresh",
179 "TxRefresh",
180 "RxPoll",
181 "TxPoll",
182 "HostRetries",
183 "LostSync-HostReq",
184 "HostTxBytes",
185 "HostRxBytes",
186 "ElapsedUsec",
187 "ElapsedSec",
188 "LostSyncBetterAP",
189 "PrivacyMismatch",
190 "Jammed",
191 "DiscRxNotWepped",
192 "PhyEleMismatch",
193 (char*)-1 };
194 #ifndef RUN_AT
195 #define RUN_AT(x) (jiffies+(x))
196 #endif
197
198
199 /* These variables are for insmod, since it seems that the rates
200 can only be set in setup_card. Rates should be a comma separated
201 (no spaces) list of rates (up to 8). */
202
203 static int rates[8];
204 static int basic_rate;
205 static char *ssids[3];
206
207 static int io[4];
208 static int irq[4];
209
210 static
211 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
212 0 means no limit. For old cards this was 4 */
213
214 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
215 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
216 the bap, needed on some older cards and buses. */
217 static int adhoc;
218
219 static int proc_uid /* = 0 */;
220
221 static int proc_gid /* = 0 */;
222
223 static int airo_perm = 0555;
224
225 static int proc_perm = 0644;
226
227 MODULE_AUTHOR("Benjamin Reed");
228 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
229 cards. Direct support for ISA/PCI cards and support \
230 for PCMCIA when used with airo_cs.");
231 MODULE_LICENSE("Dual BSD/GPL");
232 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340");
233 MODULE_PARM(io,"1-4i");
234 MODULE_PARM(irq,"1-4i");
235 MODULE_PARM(basic_rate,"i");
236 MODULE_PARM(rates,"1-8i");
237 MODULE_PARM(ssids,"1-3s");
238 MODULE_PARM(auto_wep,"i");
239 MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
240 the authentication options until an association is made. The value of \
241 auto_wep is number of the wep keys to check. A value of 2 will try using \
242 the key at index 0 and index 1.");
243 MODULE_PARM(aux_bap,"i");
244 MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
245 than seems to work better for older cards with some older buses. Before \
246 switching it checks that the switch is needed.");
247 MODULE_PARM(maxencrypt, "i");
248 MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
249 encryption. Units are in 512kbs. Zero (default) means there is no limit. \
250 Older cards used to be limited to 2mbs (4).");
251 MODULE_PARM(adhoc, "i");
252 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
253
254 MODULE_PARM(proc_uid, "i");
255 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
256 MODULE_PARM(proc_gid, "i");
257 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
258 MODULE_PARM(airo_perm, "i");
259 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
260 MODULE_PARM(proc_perm, "i");
261 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
262
263 #include <asm/uaccess.h>
264
265 /* This is a kind of sloppy hack to get this information to OUT4500 and
266 IN4500. I would be extremely interested in the situation where this
267 doesnt work though!!! */
268 static int do8bitIO = 0;
269
270 /* Return codes */
271 #define SUCCESS 0
272 #define ERROR -1
273 #define NO_PACKET -2
274
275 /* Commands */
276 #define NOP 0x0010
277 #define MAC_ENABLE 0x0001
278 #define MAC_DISABLE 0x0002
279 #define CMD_LOSE_SYNC 0x0003 /* Not sure what this does... */
280 #define CMD_ACCESS 0x0021
281 #define CMD_ALLOCATETX 0x000a
282 #define CMD_TRANSMIT 0x000b
283 #define HOSTSLEEP 0x85
284 #define CMD_SETMODE 0x0009
285 #define CMD_ENABLEAUX 0x0111
286 #define CMD_SOFTRESET 0x0004
287 #define CMD_LISTBSS 0x0103
288
289 /* Registers */
290 #define COMMAND 0x00
291 #define PARAM0 0x02
292 #define PARAM1 0x04
293 #define PARAM2 0x06
294 #define STATUS 0x08
295 #define RESP0 0x0a
296 #define RESP1 0x0c
297 #define RESP2 0x0e
298 #define LINKSTAT 0x10
299 #define SELECT0 0x18
300 #define OFFSET0 0x1c
301 #define RXFID 0x20
302 #define TXALLOCFID 0x22
303 #define TXCOMPLFID 0x24
304 #define DATA0 0x36
305 #define EVSTAT 0x30
306 #define EVINTEN 0x32
307 #define EVACK 0x34
308 #define SWS0 0x28
309 #define SWS1 0x2a
310 #define SWS2 0x2c
311 #define SWS3 0x2e
312 #define AUXPAGE 0x3A
313 #define AUXOFF 0x3C
314 #define AUXDATA 0x3E
315
316 /* BAP selectors */
317 #define BAP0 0 // Used for receiving packets
318 #define BAP1 2 // Used for xmiting packets and working with RIDS
319
320 /* Flags */
321 #define COMMAND_BUSY 0x8000
322
323 #define BAP_BUSY 0x8000
324 #define BAP_ERR 0x4000
325 #define BAP_DONE 0x2000
326
327 #define PROMISC 0xffff
328 #define NOPROMISC 0x0000
329
330 #define EV_CMD 0x10
331 #define EV_CLEARCOMMANDBUSY 0x4000
332 #define EV_RX 0x01
333 #define EV_TX 0x02
334 #define EV_TXEXC 0x04
335 #define EV_ALLOC 0x08
336 #define EV_LINK 0x80
337 #define EV_AWAKE 0x100
338 #define EV_UNKNOWN 0x800
339 #define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX)
340 #define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
341
342 /* The RIDs */
343 #define RID_CAPABILITIES 0xFF00
344 #define RID_CONFIG 0xFF10
345 #define RID_SSID 0xFF11
346 #define RID_APLIST 0xFF12
347 #define RID_DRVNAME 0xFF13
348 #define RID_ETHERENCAP 0xFF14
349 #define RID_WEP_TEMP 0xFF15
350 #define RID_WEP_PERM 0xFF16
351 #define RID_MODULATION 0xFF17
352 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
353 #define RID_LEAPUSERNAME 0xFF23
354 #define RID_LEAPPASSWORD 0xFF24
355 #define RID_STATUS 0xFF50
356 #define RID_STATS 0xFF68
357 #define RID_STATSDELTA 0xFF69
358 #define RID_STATSDELTACLEAR 0xFF6A
359 #define RID_BSSLISTFIRST 0xFF72
360 #define RID_BSSLISTNEXT 0xFF73
361
362 typedef struct {
363 u16 cmd;
364 u16 parm0;
365 u16 parm1;
366 u16 parm2;
367 } Cmd;
368
369 typedef struct {
370 u16 status;
371 u16 rsp0;
372 u16 rsp1;
373 u16 rsp2;
374 } Resp;
375
376 /*
377 * Rids and endian-ness: The Rids will always be in cpu endian, since
378 * this all the patches from the big-endian guys end up doing that.
379 * so all rid access should use the read/writeXXXRid routines.
380 */
381
382 /* This is redundant for x86 archs, but it seems necessary for ARM */
383 #pragma pack(1)
384
385 /* This structure came from an email sent to me from an engineer at
386 aironet for inclusion into this driver */
387 typedef struct {
388 u16 len;
389 u16 kindex;
390 u8 mac[6];
391 u16 klen;
392 u8 key[16];
393 } WepKeyRid;
394
395 /* These structures are from the Aironet's PC4500 Developers Manual */
396 typedef struct {
397 u16 len;
398 u8 ssid[32];
399 } Ssid;
400
401 typedef struct {
402 u16 len;
403 Ssid ssids[3];
404 } SsidRid;
405
406 typedef struct {
407 u16 len;
408 u16 modulation;
409 #define MOD_DEFAULT 0
410 #define MOD_CCK 1
411 #define MOD_MOK 2
412 } ModulationRid;
413
414 typedef struct {
415 u16 len; /* sizeof(ConfigRid) */
416 u16 opmode; /* operating mode */
417 #define MODE_STA_IBSS 0
418 #define MODE_STA_ESS 1
419 #define MODE_AP 2
420 #define MODE_AP_RPTR 3
421 #define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
422 #define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
423 #define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
424 #define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
425 #define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
426 #define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
427 #define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
428 #define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
429 u16 rmode; /* receive mode */
430 #define RXMODE_BC_MC_ADDR 0
431 #define RXMODE_BC_ADDR 1 /* ignore multicasts */
432 #define RXMODE_ADDR 2 /* ignore multicast and broadcast */
433 #define RXMODE_RFMON 3 /* wireless monitor mode */
434 #define RXMODE_RFMON_ANYBSS 4
435 #define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
436 #define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
437 #define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
438 u16 fragThresh;
439 u16 rtsThres;
440 u8 macAddr[6];
441 u8 rates[8];
442 u16 shortRetryLimit;
443 u16 longRetryLimit;
444 u16 txLifetime; /* in kusec */
445 u16 rxLifetime; /* in kusec */
446 u16 stationary;
447 u16 ordering;
448 u16 u16deviceType; /* for overriding device type */
449 u16 cfpRate;
450 u16 cfpDuration;
451 u16 _reserved1[3];
452 /*---------- Scanning/Associating ----------*/
453 u16 scanMode;
454 #define SCANMODE_ACTIVE 0
455 #define SCANMODE_PASSIVE 1
456 #define SCANMODE_AIROSCAN 2
457 u16 probeDelay; /* in kusec */
458 u16 probeEnergyTimeout; /* in kusec */
459 u16 probeResponseTimeout;
460 u16 beaconListenTimeout;
461 u16 joinNetTimeout;
462 u16 authTimeout;
463 u16 authType;
464 #define AUTH_OPEN 0x1
465 #define AUTH_ENCRYPT 0x101
466 #define AUTH_SHAREDKEY 0x102
467 #define AUTH_ALLOW_UNENCRYPTED 0x200
468 u16 associationTimeout;
469 u16 specifiedApTimeout;
470 u16 offlineScanInterval;
471 u16 offlineScanDuration;
472 u16 linkLossDelay;
473 u16 maxBeaconLostTime;
474 u16 refreshInterval;
475 #define DISABLE_REFRESH 0xFFFF
476 u16 _reserved1a[1];
477 /*---------- Power save operation ----------*/
478 u16 powerSaveMode;
479 #define POWERSAVE_CAM 0
480 #define POWERSAVE_PSP 1
481 #define POWERSAVE_PSPCAM 2
482 u16 sleepForDtims;
483 u16 listenInterval;
484 u16 fastListenInterval;
485 u16 listenDecay;
486 u16 fastListenDelay;
487 u16 _reserved2[2];
488 /*---------- Ap/Ibss config items ----------*/
489 u16 beaconPeriod;
490 u16 atimDuration;
491 u16 hopPeriod;
492 u16 channelSet;
493 u16 channel;
494 u16 dtimPeriod;
495 u16 bridgeDistance;
496 u16 radioID;
497 /*---------- Radio configuration ----------*/
498 u16 radioType;
499 #define RADIOTYPE_DEFAULT 0
500 #define RADIOTYPE_802_11 1
501 #define RADIOTYPE_LEGACY 2
502 u8 rxDiversity;
503 u8 txDiversity;
504 u16 txPower;
505 #define TXPOWER_DEFAULT 0
506 u16 rssiThreshold;
507 #define RSSI_DEFAULT 0
508 u16 modulation;
509 #define PREAMBLE_AUTO 0
510 #define PREAMBLE_LONG 1
511 #define PREAMBLE_SHORT 2
512 u16 preamble;
513 u16 homeProduct;
514 u16 radioSpecific;
515 /*---------- Aironet Extensions ----------*/
516 u8 nodeName[16];
517 u16 arlThreshold;
518 u16 arlDecay;
519 u16 arlDelay;
520 u16 _reserved4[1];
521 /*---------- Aironet Extensions ----------*/
522 u16 magicAction;
523 #define MAGIC_ACTION_STSCHG 1
524 #define MACIC_ACTION_RESUME 2
525 #define MAGIC_IGNORE_MCAST (1<<8)
526 #define MAGIC_IGNORE_BCAST (1<<9)
527 #define MAGIC_SWITCH_TO_PSP (0<<10)
528 #define MAGIC_STAY_IN_CAM (1<<10)
529 u16 magicControl;
530 u16 autoWake;
531 } ConfigRid;
532
533 typedef struct {
534 u16 len;
535 u8 mac[6];
536 u16 mode;
537 u16 errorCode;
538 u16 sigQuality;
539 u16 SSIDlen;
540 char SSID[32];
541 char apName[16];
542 char bssid[4][6];
543 u16 beaconPeriod;
544 u16 dimPeriod;
545 u16 atimDuration;
546 u16 hopPeriod;
547 u16 channelSet;
548 u16 channel;
549 u16 hopsToBackbone;
550 u16 apTotalLoad;
551 u16 generatedLoad;
552 u16 accumulatedArl;
553 u16 signalQuality;
554 u16 currentXmitRate;
555 u16 apDevExtensions;
556 u16 normalizedSignalStrength;
557 u16 _reserved[10];
558 } StatusRid;
559
560 typedef struct {
561 u16 len;
562 u16 spacer;
563 u32 vals[100];
564 } StatsRid;
565
566
567 typedef struct {
568 u16 len;
569 u8 ap[4][6];
570 } APListRid;
571
572 typedef struct {
573 u16 len;
574 char oui[3];
575 char zero;
576 u16 prodNum;
577 char manName[32];
578 char prodName[16];
579 char prodVer[8];
580 char factoryAddr[6];
581 char aironetAddr[6];
582 u16 radioType;
583 u16 country;
584 char callid[6];
585 char supportedRates[8];
586 char rxDiversity;
587 char txDiversity;
588 u16 txPowerLevels[8];
589 u16 hardVer;
590 u16 hardCap;
591 u16 tempRange;
592 u16 softVer;
593 u16 softSubVer;
594 u16 interfaceVer;
595 u16 softCap;
596 u16 bootBlockVer;
597 u16 requiredHard;
598 } CapabilityRid;
599
600 typedef struct {
601 u16 len;
602 u16 index; /* First is 0 and 0xffff means end of list */
603 #define RADIO_FH 1 /* Frequency hopping radio type */
604 #define RADIO_DS 2 /* Direct sequence radio type */
605 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
606 u16 radioType;
607 u8 bssid[6]; /* Mac address of the BSS */
608 u8 zero;
609 u8 ssidLen;
610 u8 ssid[32];
611 u16 rssi;
612 #define CAP_ESS (1<<0)
613 #define CAP_IBSS (1<<1)
614 #define CAP_PRIVACY (1<<4)
615 #define CAP_SHORTHDR (1<<5)
616 u16 cap;
617 u16 beaconInterval;
618 u8 rates[8]; /* Same as rates for config rid */
619 struct { /* For frequency hopping only */
620 u16 dwell;
621 u8 hopSet;
622 u8 hopPattern;
623 u8 hopIndex;
624 u8 fill;
625 } fh;
626 u16 dsChannel;
627 u16 atimWindow;
628 } BSSListRid;
629
630 #pragma pack()
631
632 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
633 #define TXCTL_TXEX (1<<2) /* report if tx fails */
634 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
635 #define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
636 #define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
637 #define TXCTL_LLC (1<<4) /* payload is llc */
638 #define TXCTL_RELEASE (0<<5) /* release after completion */
639 #define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
640
641 #define BUSY_FID 0x10000
642
643 #ifdef CISCO_EXT
644 #define AIROMAGIC 0xa55a
645 #define AIROIOCTL SIOCDEVPRIVATE
646 #define AIROIDIFC AIROIOCTL + 1
647
648 /* Ioctl constants to be used in airo_ioctl.command */
649
650 #define AIROGCAP 0 // Capability rid
651 #define AIROGCFG 1 // USED A LOT
652 #define AIROGSLIST 2 // System ID list
653 #define AIROGVLIST 3 // List of specified AP's
654 #define AIROGDRVNAM 4 // NOTUSED
655 #define AIROGEHTENC 5 // NOTUSED
656 #define AIROGWEPKTMP 6
657 #define AIROGWEPKNV 7
658 #define AIROGSTAT 8
659 #define AIROGSTATSC32 9
660 #define AIROGSTATSD32 10
661
662 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
663
664 #define AIROPCAP AIROGSTATSD32 + 40
665 #define AIROPVLIST AIROPCAP + 1
666 #define AIROPSLIST AIROPVLIST + 1
667 #define AIROPCFG AIROPSLIST + 1
668 #define AIROPSIDS AIROPCFG + 1
669 #define AIROPAPLIST AIROPSIDS + 1
670 #define AIROPMACON AIROPAPLIST + 1 /* Enable mac */
671 #define AIROPMACOFF AIROPMACON + 1 /* Disable mac */
672 #define AIROPSTCLR AIROPMACOFF + 1
673 #define AIROPWEPKEY AIROPSTCLR + 1
674 #define AIROPWEPKEYNV AIROPWEPKEY + 1
675 #define AIROPLEAPPWD AIROPWEPKEYNV + 1
676 #define AIROPLEAPUSR AIROPLEAPPWD + 1
677
678 /* Flash codes */
679
680 #define AIROFLSHRST AIROPWEPKEYNV + 40
681 #define AIROFLSHGCHR AIROFLSHRST + 1
682 #define AIROFLSHSTFL AIROFLSHGCHR + 1
683 #define AIROFLSHPCHR AIROFLSHSTFL + 1
684 #define AIROFLPUTBUF AIROFLSHPCHR + 1
685 #define AIRORESTART AIROFLPUTBUF + 1
686
687 #define FLASHSIZE 32768
688
689 typedef struct aironet_ioctl {
690 unsigned short command; // What to do
691 unsigned short len; // Len of data
692 unsigned char *data; // d-data
693 } aironet_ioctl;
694 #endif /* CISCO_EXT */
695
696 #ifdef WIRELESS_EXT
697 // Frequency list (map channels to frequencies)
698 const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
699 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
700
701 // A few details needed for WEP (Wireless Equivalent Privacy)
702 #define MAX_KEY_SIZE 13 // 128 (?) bits
703 #define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
704 typedef struct wep_key_t {
705 u16 len;
706 u8 key[16]; /* 40-bit and 104-bit keys */
707 } wep_key_t;
708 #endif /* WIRELESS_EXT */
709
710 static const char version[] = "airo.c 0.3 (Ben Reed & Javier Achirica)";
711
712 struct airo_info;
713
714 static int get_dec_u16( char *buffer, int *start, int limit );
715 static void OUT4500( struct airo_info *, u16 register, u16 value );
716 static unsigned short IN4500( struct airo_info *, u16 register );
717 static u16 setup_card(struct airo_info*, u8 *mac, ConfigRid *);
718 static void enable_interrupts(struct airo_info*);
719 static void disable_interrupts(struct airo_info*);
720 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
721 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
722 static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
723 int whichbap);
724 static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
725 int whichbap);
726 static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
727 int whichbap);
728 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
729 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len);
730 static int PC4500_writerid(struct airo_info*, u16 rid, const void
731 *pBuf, int len);
732 static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
733 int len );
734 static u16 transmit_allocate(struct airo_info*, int lenPayload);
735 static int transmit_802_3_packet(struct airo_info*, u16 TxFid, char
736 *pPacket, int len);
737
738 static void airo_interrupt( int irq, void* dev_id, struct pt_regs
739 *regs);
740 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
741 #ifdef WIRELESS_EXT
742 struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
743 #endif /* WIRELESS_EXT */
744 #ifdef CISCO_EXT
745 static int readrids(struct net_device *dev, aironet_ioctl *comp);
746 static int writerids(struct net_device *dev, aironet_ioctl *comp);
747 int flashcard(struct net_device *dev, aironet_ioctl *comp);
748 #endif /* CISCO_EXT */
749
750 struct airo_info {
751 struct net_device_stats stats;
752 int open;
753 struct net_device *dev;
754 /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we
755 use the high bit to mark wether it is in use. */
756 #define MAX_FIDS 6
757 int fids[MAX_FIDS];
758 int registered;
759 ConfigRid config;
760 u16 authtype; // Used with auto_wep
761 char keyindex; // Used with auto wep
762 char defindex; // Used with auto wep
763 struct timer_list timer;
764 struct proc_dir_entry *proc_entry;
765 struct airo_info *next;
766 spinlock_t bap0_lock;
767 spinlock_t bap1_lock;
768 spinlock_t aux_lock;
769 spinlock_t cmd_lock;
770 int flags;
771 #define FLAG_PROMISC IFF_PROMISC
772 #define FLAG_RADIO_OFF 0x02
773 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
774 int whichbap);
775 int (*header_parse)(struct sk_buff*, unsigned char *);
776 unsigned short *flash;
777 #ifdef WIRELESS_EXT
778 int need_commit; // Need to set config
779 struct iw_statistics wstats; // wireless stats
780 #ifdef WIRELESS_SPY
781 int spy_number;
782 u_char spy_address[IW_MAX_SPY][6];
783 struct iw_quality spy_stat[IW_MAX_SPY];
784 #endif /* WIRELESS_SPY */
785 #endif /* WIRELESS_EXT */
786 };
787
788 static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
789 int whichbap) {
790 return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
791 }
792
793 static int setup_proc_entry( struct net_device *dev,
794 struct airo_info *apriv );
795 static int takedown_proc_entry( struct net_device *dev,
796 struct airo_info *apriv );
797
798 static int readBSSListRid(struct airo_info *ai, int first,
799 BSSListRid *list) {
800 int rc;
801 Cmd cmd;
802 Resp rsp;
803
804 if (first == 1) {
805 memset(&cmd, 0, sizeof(cmd));
806 cmd.cmd=CMD_LISTBSS;
807 issuecommand(ai, &cmd, &rsp);
808 /* Let the command take effect */
809 set_current_state (TASK_INTERRUPTIBLE);
810 schedule_timeout (3*HZ);
811 }
812 rc = PC4500_readrid(ai,
813 first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
814 list, sizeof(*list));
815
816 list->len = le16_to_cpu(list->len);
817 list->index = le16_to_cpu(list->index);
818 list->radioType = le16_to_cpu(list->radioType);
819 list->cap = le16_to_cpu(list->cap);
820 list->beaconInterval = le16_to_cpu(list->beaconInterval);
821 list->fh.dwell = le16_to_cpu(list->fh.dwell);
822 list->dsChannel = le16_to_cpu(list->dsChannel);
823 list->atimWindow = le16_to_cpu(list->atimWindow);
824 return rc;
825 }
826
827 static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {
828 int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
829 wkr, sizeof(*wkr));
830
831 wkr->len = le16_to_cpu(wkr->len);
832 wkr->kindex = le16_to_cpu(wkr->kindex);
833 wkr->klen = le16_to_cpu(wkr->klen);
834 return rc;
835 }
836 /* In the writeXXXRid routines we copy the rids so that we don't screwup
837 * the originals when we endian them... */
838 static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm) {
839 int rc;
840 WepKeyRid wkr = *pwkr;
841
842 wkr.len = cpu_to_le16(wkr.len);
843 wkr.kindex = cpu_to_le16(wkr.kindex);
844 wkr.klen = cpu_to_le16(wkr.klen);
845 rc = do_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr));
846 if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc);
847 if (perm) {
848 rc = do_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr));
849 if (rc!=SUCCESS) {
850 printk(KERN_ERR "airo: WEP_PERM set %x\n", rc);
851 }
852 }
853 return rc;
854 }
855
856 static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {
857 int i;
858 int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr));
859
860 ssidr->len = le16_to_cpu(ssidr->len);
861 for(i = 0; i < 3; i++) {
862 ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
863 }
864 return rc;
865 }
866 static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {
867 int rc;
868 int i;
869 SsidRid ssidr = *pssidr;
870
871 ssidr.len = cpu_to_le16(ssidr.len);
872 for(i = 0; i < 3; i++) {
873 ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
874 }
875 rc = do_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr));
876 return rc;
877 }
878 static int readConfigRid(struct airo_info*ai, ConfigRid *cfgr) {
879 int rc = PC4500_readrid(ai, RID_ACTUALCONFIG, cfgr, sizeof(*cfgr));
880 u16 *s;
881
882 for(s = &cfgr->len; s <= &cfgr->rtsThres; s++) *s = le16_to_cpu(*s);
883
884 for(s = &cfgr->shortRetryLimit; s <= &cfgr->radioType; s++)
885 *s = le16_to_cpu(*s);
886
887 for(s = &cfgr->txPower; s <= &cfgr->radioSpecific; s++)
888 *s = le16_to_cpu(*s);
889
890 for(s = &cfgr->arlThreshold; s <= &cfgr->autoWake; s++)
891 *s = le16_to_cpu(*s);
892
893 return rc;
894 }
895 static int writeConfigRid(struct airo_info*ai, ConfigRid *pcfgr) {
896 u16 *s;
897 ConfigRid cfgr = *pcfgr;
898
899 for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
900
901 for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
902 *s = cpu_to_le16(*s);
903
904 for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
905 *s = cpu_to_le16(*s);
906
907 for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)
908 *s = cpu_to_le16(*s);
909
910 return do_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr));
911 }
912 static int readStatusRid(struct airo_info*ai, StatusRid *statr) {
913 int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr));
914 u16 *s;
915
916 statr->len = le16_to_cpu(statr->len);
917 for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
918
919 for(s = &statr->beaconPeriod; s <= &statr->_reserved[9]; s++)
920 *s = le16_to_cpu(*s);
921
922 return rc;
923 }
924 static int readAPListRid(struct airo_info*ai, APListRid *aplr) {
925 int rc = PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr));
926 aplr->len = le16_to_cpu(aplr->len);
927 return rc;
928 }
929 static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {
930 int rc;
931 aplr->len = cpu_to_le16(aplr->len);
932 rc = do_writerid(ai, RID_APLIST, aplr, sizeof(*aplr));
933 return rc;
934 }
935 static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {
936 int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr));
937 u16 *s;
938
939 capr->len = le16_to_cpu(capr->len);
940 capr->prodNum = le16_to_cpu(capr->prodNum);
941 capr->radioType = le16_to_cpu(capr->radioType);
942 capr->country = le16_to_cpu(capr->country);
943 for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
944 *s = le16_to_cpu(*s);
945 return rc;
946 }
947 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid) {
948 int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr));
949 u32 *i;
950
951 sr->len = le16_to_cpu(sr->len);
952 for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);
953 return rc;
954 }
955
956 static int airo_open(struct net_device *dev) {
957 struct airo_info *info = dev->priv;
958
959 enable_interrupts(info);
960
961 netif_start_queue(dev);
962 return 0;
963 }
964
965 static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
966 s16 len;
967 s16 retval = 0;
968 u16 status;
969 u32 flags;
970 s8 *buffer;
971 int i,j;
972 struct airo_info *priv = (struct airo_info*)dev->priv;
973 u32 *fids = priv->fids;
974
975 if ( skb == NULL ) {
976 printk( KERN_ERR "airo: skb == NULL!!!\n" );
977 return 0;
978 }
979
980 /* Find a vacant FID */
981 spin_lock_irqsave(&priv->bap1_lock, flags);
982 for( j = 0, i = -1; j < MAX_FIDS; j++ ) {
983 if ( !( fids[j] & 0xffff0000 ) ) {
984 if ( i == -1 ) i = j;
985 else break;
986 }
987 }
988 if ( j == MAX_FIDS ) netif_stop_queue(dev);
989 if ( i == -1 ) {
990 retval = -EBUSY;
991 goto tx_done;
992 }
993
994 len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; /* check min length*/
995 buffer = skb->data;
996 status = transmit_802_3_packet( priv,
997 fids[i],
998 skb->data, len );
999
1000 if ( status == SUCCESS ) {
1001 /* Mark fid as used & save length for later */
1002 fids[i] |= (len << 16);
1003 dev->trans_start = jiffies;
1004 } else {
1005 priv->stats.tx_errors++;
1006 }
1007 tx_done:
1008 spin_unlock_irqrestore(&priv->bap1_lock, flags);
1009 dev_kfree_skb(skb);
1010 return 0;
1011 }
1012
1013 static struct net_device_stats *airo_get_stats(struct net_device *dev) {
1014 return &(((struct airo_info*)dev->priv)->stats);
1015 }
1016
1017 static int enable_MAC( struct airo_info *ai, Resp *rsp );
1018 static void disable_MAC(struct airo_info *ai);
1019
1020 static void airo_set_multicast_list(struct net_device *dev) {
1021 struct airo_info *ai = (struct airo_info*)dev->priv;
1022 Cmd cmd;
1023 Resp rsp;
1024
1025 /* For some reason this command takes a lot of time (~20 ms) and it's
1026 * run in an interrupt handler, so we'd better be sure we needed it
1027 * before executing it.
1028 */
1029 if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
1030 memset(&cmd, 0, sizeof(cmd));
1031 cmd.cmd=CMD_SETMODE;
1032 cmd.parm0=(dev->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
1033 issuecommand(ai, &cmd, &rsp);
1034 ai->flags^=IFF_PROMISC;
1035 }
1036
1037 if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
1038 /* Turn on multicast. (Should be already setup...) */
1039 }
1040 }
1041
1042 static int airo_set_mac_address(struct net_device *dev, void *p)
1043 {
1044 struct airo_info *ai = (struct airo_info*)dev->priv;
1045 struct sockaddr *addr = p;
1046 ConfigRid cfg;
1047
1048 readConfigRid (ai, &cfg);
1049 memcpy (cfg.macAddr, addr->sa_data, dev->addr_len);
1050 writeConfigRid (ai, &cfg);
1051 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1052 return 0;
1053 }
1054
1055 static int airo_change_mtu(struct net_device *dev, int new_mtu)
1056 {
1057 if ((new_mtu < 68) || (new_mtu > 2400))
1058 return -EINVAL;
1059 dev->mtu = new_mtu;
1060 return 0;
1061 }
1062
1063
1064 static int airo_close(struct net_device *dev) {
1065 struct airo_info *ai = (struct airo_info*)dev->priv;
1066
1067 netif_stop_queue(dev);
1068 disable_interrupts( ai );
1069 return 0;
1070 }
1071
1072 static void del_airo_dev( struct net_device *dev );
1073
1074 void stop_airo_card( struct net_device *dev, int freeres )
1075 {
1076 struct airo_info *ai = (struct airo_info*)dev->priv;
1077 if (ai->flash)
1078 kfree(ai->flash);
1079 takedown_proc_entry( dev, ai );
1080 if (ai->registered) {
1081 unregister_netdev( dev );
1082 ai->registered = 0;
1083 }
1084 disable_interrupts(ai);
1085 free_irq( dev->irq, dev );
1086 if (auto_wep) del_timer_sync(&ai->timer);
1087 if (freeres) {
1088 /* PCMCIA frees this stuff, so only for PCI and ISA */
1089 release_region( dev->base_addr, 64 );
1090 }
1091 del_airo_dev( dev );
1092 kfree( dev );
1093 }
1094
1095 static int add_airo_dev( struct net_device *dev );
1096
1097 struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia )
1098 {
1099 struct net_device *dev;
1100 struct airo_info *ai;
1101 int i, rc;
1102
1103 /* Create the network device object. */
1104 dev = alloc_etherdev(sizeof(*ai));
1105 if (!dev) {
1106 printk(KERN_ERR "airo: Couldn't alloc_etherdev\n");
1107 return NULL;
1108 }
1109 ai = dev->priv;
1110 ai->registered = 1;
1111 ai->dev = dev;
1112 ai->bap0_lock = SPIN_LOCK_UNLOCKED;
1113 ai->bap1_lock = SPIN_LOCK_UNLOCKED;
1114 ai->aux_lock = SPIN_LOCK_UNLOCKED;
1115 ai->cmd_lock = SPIN_LOCK_UNLOCKED;
1116 ai->header_parse = dev->hard_header_parse;
1117 rc = add_airo_dev( dev );
1118 if (rc)
1119 goto err_out_free;
1120
1121 /* The Airo-specific entries in the device structure. */
1122 dev->hard_start_xmit = &airo_start_xmit;
1123 dev->get_stats = &airo_get_stats;
1124 dev->set_multicast_list = &airo_set_multicast_list;
1125 dev->set_mac_address = &airo_set_mac_address;
1126 dev->do_ioctl = &airo_ioctl;
1127 #ifdef WIRELESS_EXT
1128 dev->get_wireless_stats = airo_get_wireless_stats;
1129 #endif /* WIRELESS_EXT */
1130 dev->change_mtu = &airo_change_mtu;
1131 dev->open = &airo_open;
1132 dev->stop = &airo_close;
1133 dev->irq = irq;
1134 dev->base_addr = port;
1135
1136 rc = register_netdev(dev);
1137 if (rc)
1138 goto err_out_unlink;
1139
1140 rc = request_irq( dev->irq, airo_interrupt,
1141 SA_SHIRQ | SA_INTERRUPT, dev->name, dev );
1142 if (rc) {
1143 printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
1144 goto err_out_unregister;
1145 }
1146 if (!is_pcmcia) {
1147 if (!request_region( dev->base_addr, 64, dev->name )) {
1148 rc = -EBUSY;
1149 goto err_out_irq;
1150 }
1151 }
1152
1153 if ( setup_card( ai, dev->dev_addr, &ai->config) != SUCCESS ) {
1154 printk( KERN_ERR "airo: MAC could not be enabled\n" );
1155 rc = -EIO;
1156 goto err_out_res;
1157 }
1158
1159 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
1160 dev->name,
1161 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
1162 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
1163
1164 /* Allocate the transmit buffers */
1165 for( i = 0; i < MAX_FIDS; i++ )
1166 ai->fids[i] = transmit_allocate( ai, 2312 );
1167
1168 setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
1169 netif_start_queue(dev);
1170 SET_MODULE_OWNER(dev);
1171 return dev;
1172
1173 err_out_res:
1174 if (!is_pcmcia)
1175 release_region( dev->base_addr, 64 );
1176 err_out_irq:
1177 free_irq(dev->irq, dev);
1178 err_out_unregister:
1179 unregister_netdev(dev);
1180 err_out_unlink:
1181 del_airo_dev(dev);
1182 err_out_free:
1183 kfree(dev);
1184 return NULL;
1185 }
1186
1187 int waitbusy (struct airo_info *ai) {
1188 int delay = 0;
1189 while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
1190 udelay (10);
1191 if (++delay % 20)
1192 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
1193 }
1194 return delay < 10000;
1195 }
1196
1197 int reset_airo_card( struct net_device *dev ) {
1198 int i;
1199 struct airo_info *ai = (struct airo_info*)dev->priv;
1200
1201 disable_MAC(ai);
1202 waitbusy (ai);
1203 OUT4500(ai,COMMAND,CMD_SOFTRESET);
1204 set_current_state (TASK_UNINTERRUPTIBLE);
1205 schedule_timeout (HZ/5);
1206 waitbusy (ai);
1207 set_current_state (TASK_UNINTERRUPTIBLE);
1208 schedule_timeout (HZ/5);
1209 if ( setup_card(ai, dev->dev_addr, &(ai)->config) != SUCCESS ) {
1210 printk( KERN_ERR "airo: MAC could not be enabled\n" );
1211 return -1;
1212 } else {
1213 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
1214 dev->name,
1215 dev->dev_addr[0],
1216 dev->dev_addr[1],
1217 dev->dev_addr[2],
1218 dev->dev_addr[3],
1219 dev->dev_addr[4],
1220 dev->dev_addr[5]
1221 );
1222 /* Allocate the transmit buffers */
1223 for( i = 0; i < MAX_FIDS; i++ )
1224 ai->fids[i] = transmit_allocate( ai, 2312 );
1225 }
1226 enable_interrupts( ai );
1227 netif_wake_queue(dev);
1228 return 0;
1229 }
1230
1231 int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
1232 {
1233 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
1234 return ETH_ALEN;
1235 }
1236
1237 static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
1238 struct net_device *dev = (struct net_device *)dev_id;
1239 u16 status;
1240 u16 fid;
1241 struct airo_info *apriv = (struct airo_info *)dev->priv;
1242 u16 savedInterrupts;
1243
1244 if (!netif_device_present(dev))
1245 return;
1246
1247 status = IN4500( apriv, EVSTAT );
1248 if ( !status || status == 0xffff ) return;
1249
1250 if ( status & EV_AWAKE ) {
1251 OUT4500( apriv, EVACK, EV_AWAKE );
1252 OUT4500( apriv, EVACK, EV_AWAKE );
1253 }
1254
1255 savedInterrupts = IN4500( apriv, EVINTEN );
1256 OUT4500( apriv, EVINTEN, 0 );
1257
1258 if ( status & EV_LINK ) {
1259 /* The link status has changed, if you want to put a
1260 monitor hook in, do it here. (Remember that
1261 interrupts are still disabled!)
1262 */
1263 u16 newStatus = IN4500(apriv, LINKSTAT);
1264 /* Here is what newStatus means: */
1265 #define NOBEACON 0x8000 /* Loss of sync - missed beacons */
1266 #define MAXRETRIES 0x8001 /* Loss of sync - max retries */
1267 #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
1268 #define FORCELOSS 0x8003 /* Loss of sync - host request */
1269 #define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
1270 #define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
1271 #define DISASS 0x8200 /* Disassociation (low byte is reason code) */
1272 #define ASSFAIL 0x8400 /* Association failure (low byte is reason
1273 code) */
1274 #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
1275 code) */
1276 #define ASSOCIATED 0x0400 /* Assocatied */
1277 #define RC_RESERVED 0 /* Reserved return code */
1278 #define RC_NOREASON 1 /* Unspecified reason */
1279 #define RC_AUTHINV 2 /* Previous authentication invalid */
1280 #define RC_DEAUTH 3 /* Deauthenticated because sending station is
1281 leaving */
1282 #define RC_NOACT 4 /* Disassociated due to inactivity */
1283 #define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
1284 all currently associated stations */
1285 #define RC_BADCLASS2 6 /* Class 2 frame received from
1286 non-Authenticated station */
1287 #define RC_BADCLASS3 7 /* Class 3 frame received from
1288 non-Associated station */
1289 #define RC_STATLEAVE 8 /* Disassociated because sending station is
1290 leaving BSS */
1291 #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
1292 Authenticated with the responding station */
1293 if (newStatus != ASSOCIATED) {
1294 if (auto_wep && !timer_pending(&apriv->timer)) {
1295 apriv->timer.expires = RUN_AT(HZ*3);
1296 add_timer(&apriv->timer);
1297 }
1298 }
1299 }
1300
1301 /* Check to see if there is something to receive */
1302 if ( status & EV_RX ) {
1303 struct sk_buff *skb = NULL;
1304 long flags;
1305 u16 fc, len, hdrlen = 0;
1306 struct {
1307 u16 status, len;
1308 u8 rssi[2];
1309 } hdr;
1310
1311 fid = IN4500( apriv, RXFID );
1312
1313 /* Get the packet length */
1314 spin_lock_irqsave(&apriv->bap0_lock, flags);
1315 if (dev->type == ARPHRD_IEEE80211) {
1316 bap_setup (apriv, fid, 4, BAP0);
1317 bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
1318 /* Bad CRC. Ignore packet */
1319 if (le16_to_cpu(hdr.status) == 2) {
1320 apriv->stats.rx_crc_errors++;
1321 apriv->stats.rx_errors++;
1322 hdr.len = 0;
1323 }
1324 } else {
1325 bap_setup (apriv, fid, 6, BAP0);
1326 bap_read (apriv, (u16*)&hdr.len, 4, BAP0);
1327 }
1328 len = le16_to_cpu(hdr.len);
1329
1330 if (len > 2312) {
1331 apriv->stats.rx_length_errors++;
1332 apriv->stats.rx_errors++;
1333 printk( KERN_ERR
1334 "airo: Bad size %d\n", len );
1335 len = 0;
1336 }
1337 if (len) {
1338 if (dev->type == ARPHRD_IEEE80211) {
1339 bap_setup (apriv, fid, 0x14, BAP0);
1340 bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
1341 if ((le16_to_cpu(fc) & 0x300) == 0x300)
1342 hdrlen = 30;
1343 else
1344 hdrlen = 24;
1345 } else
1346 hdrlen = 12;
1347
1348 skb = dev_alloc_skb( len + hdrlen + 2 );
1349 if ( !skb ) {
1350 apriv->stats.rx_dropped++;
1351 len = 0;
1352 }
1353 }
1354 if (len) {
1355 u16 *buffer;
1356 buffer = (u16*)skb_put (skb, len + hdrlen);
1357 if (dev->type == ARPHRD_IEEE80211) {
1358 u16 gap, tmpbuf[4];
1359 buffer[0] = fc;
1360 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
1361 if (hdrlen == 24)
1362 bap_read (apriv, tmpbuf, 6, BAP0);
1363
1364 bap_read (apriv, &gap, sizeof(gap), BAP0);
1365 gap = le16_to_cpu(gap);
1366 if (gap && gap <= 8)
1367 bap_read (apriv, tmpbuf, gap, BAP0);
1368
1369 bap_read (apriv, buffer + hdrlen/2, len, BAP0);
1370 } else {
1371 bap_setup (apriv, fid, 0x38, BAP0);
1372 bap_read (apriv, buffer,len + hdrlen,BAP0);
1373 }
1374 #ifdef WIRELESS_SPY
1375 if (apriv->spy_number > 0) {
1376 int i;
1377 char *sa;
1378
1379 sa = (char*)buffer + ((dev->type == ARPHRD_IEEE80211) ? 10 : 6);
1380
1381 for (i=0; i<apriv->spy_number; i++)
1382 if (!memcmp(sa,apriv->spy_address[i],6))
1383 {
1384 apriv->spy_stat[i].qual = hdr.rssi[0];
1385 apriv->spy_stat[i].level = hdr.rssi[1];
1386 apriv->spy_stat[i].noise = 0;
1387 apriv->spy_stat[i].updated = 3;
1388 break;
1389 }
1390 }
1391 #endif /* WIRELESS_SPY */
1392 apriv->stats.rx_packets++;
1393 apriv->stats.rx_bytes += len + hdrlen;
1394 dev->last_rx = jiffies;
1395 skb->dev = dev;
1396 skb->ip_summed = CHECKSUM_NONE;
1397 if (dev->type == ARPHRD_IEEE80211) {
1398 skb->mac.raw = skb->data;
1399 skb_pull (skb, hdrlen);
1400 skb->pkt_type = PACKET_OTHERHOST;
1401 skb->protocol = htons(ETH_P_802_2);
1402 } else
1403 skb->protocol = eth_type_trans( skb, dev );
1404
1405 netif_rx( skb );
1406 }
1407 spin_unlock_irqrestore(&apriv->bap0_lock, flags);
1408 }
1409
1410 /* Check to see if a packet has been transmitted */
1411 if ( status & ( EV_TX|EV_TXEXC ) ) {
1412 int i;
1413 int len = 0;
1414 int full = 1;
1415 int index = -1;
1416
1417 fid = IN4500(apriv, TXCOMPLFID);
1418
1419 for( i = 0; i < MAX_FIDS; i++ ) {
1420 if (!(apriv->fids[i] & 0xffff0000)) full = 0;
1421 if ( ( apriv->fids[i] & 0xffff ) == fid ) {
1422 len = apriv->fids[i] >> 16;
1423 index = i;
1424 /* Set up to be used again */
1425 apriv->fids[i] &= 0xffff;
1426 }
1427 }
1428 if (full) netif_wake_queue(dev);
1429 if (index==-1) {
1430 printk( KERN_ERR
1431 "airo: Unallocated FID was used to xmit\n" );
1432 }
1433 if ( status & EV_TX ) {
1434 apriv->stats.tx_packets++;
1435 if(index!=-1)
1436 apriv->stats.tx_bytes += len;
1437 } else {
1438 if (bap_setup(apriv, fid, 0x0004, BAP1) == SUCCESS) {
1439 u16 status;
1440 bap_read(apriv, &status, 2, BAP1);
1441 if (le16_to_cpu(status) & 2)
1442 apriv->stats.tx_aborted_errors++;
1443 if (le16_to_cpu(status) & 4)
1444 apriv->stats.tx_heartbeat_errors++;
1445 if (le16_to_cpu(status) & 0x10)
1446 apriv->stats.tx_carrier_errors++;
1447 }
1448 apriv->stats.tx_errors++;
1449 }
1450 }
1451 if ( status & ~STATUS_INTS & ~IGNORE_INTS )
1452 printk( KERN_WARNING
1453 "airo: Got weird status %x\n",
1454 status & ~STATUS_INTS & ~IGNORE_INTS );
1455 OUT4500( apriv, EVACK, status & STATUS_INTS );
1456 OUT4500( apriv, EVINTEN, savedInterrupts );
1457
1458 /* done.. */
1459 return;
1460 }
1461
1462 /*
1463 * Routines to talk to the card
1464 */
1465
1466 /*
1467 * This was originally written for the 4500, hence the name
1468 * NOTE: If use with 8bit mode and SMP bad things will happen!
1469 * Why would some one do 8 bit IO in an SMP machine?!?
1470 */
1471 static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
1472 if ( !do8bitIO )
1473 outw( val, ai->dev->base_addr + reg );
1474 else {
1475 outb( val & 0xff, ai->dev->base_addr + reg );
1476 outb( val >> 8, ai->dev->base_addr + reg + 1 );
1477 }
1478 }
1479
1480 static u16 IN4500( struct airo_info *ai, u16 reg ) {
1481 unsigned short rc;
1482
1483 if ( !do8bitIO )
1484 rc = inw( ai->dev->base_addr + reg );
1485 else {
1486 rc = inb( ai->dev->base_addr + reg );
1487 rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
1488 }
1489 return rc;
1490 }
1491
1492 static int enable_MAC( struct airo_info *ai, Resp *rsp ) {
1493 Cmd cmd;
1494
1495 if (ai->flags&FLAG_RADIO_OFF) return SUCCESS;
1496 memset(&cmd, 0, sizeof(cmd));
1497 cmd.cmd = MAC_ENABLE;
1498 return issuecommand(ai, &cmd, rsp);
1499 }
1500
1501 static void disable_MAC( struct airo_info *ai ) {
1502 Cmd cmd;
1503 Resp rsp;
1504
1505 memset(&cmd, 0, sizeof(cmd));
1506 cmd.cmd = MAC_DISABLE; // disable in case already enabled
1507 issuecommand(ai, &cmd, &rsp);
1508 }
1509
1510 static void enable_interrupts( struct airo_info *ai ) {
1511 /* Reset the status register */
1512 u16 status = IN4500( ai, EVSTAT );
1513 OUT4500( ai, EVACK, status );
1514 /* Enable the interrupts */
1515 OUT4500( ai, EVINTEN, STATUS_INTS );
1516 /* Note there is a race condition between the last two lines that
1517 I dont know how to get rid of right now... */
1518 }
1519
1520 static void disable_interrupts( struct airo_info *ai ) {
1521 OUT4500( ai, EVINTEN, 0 );
1522 }
1523
1524 static u16 setup_card(struct airo_info *ai, u8 *mac,
1525 ConfigRid *config)
1526 {
1527 Cmd cmd;
1528 Resp rsp;
1529 ConfigRid cfg;
1530 int status;
1531 int i;
1532 SsidRid mySsid;
1533 u16 lastindex;
1534 WepKeyRid wkr;
1535 int rc;
1536
1537 memset( &mySsid, 0, sizeof( mySsid ) );
1538 if (ai->flash) {
1539 kfree (ai->flash);
1540 ai->flash = NULL;
1541 }
1542
1543 /* The NOP is the first step in getting the card going */
1544 cmd.cmd = NOP;
1545 cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
1546 if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
1547 return ERROR;
1548 }
1549 memset(&cmd, 0, sizeof(cmd));
1550 cmd.cmd = MAC_DISABLE; // disable in case already enabled
1551 if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
1552 return ERROR;
1553 }
1554
1555 // Let's figure out if we need to use the AUX port
1556 cmd.cmd = CMD_ENABLEAUX;
1557 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
1558 printk(KERN_ERR "airo: Error checking for AUX port\n");
1559 return ERROR;
1560 }
1561 if (!aux_bap || rsp.status & 0xff00) {
1562 ai->bap_read = fast_bap_read;
1563 printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
1564 } else {
1565 ai->bap_read = aux_bap_read;
1566 printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
1567 }
1568 if ( config->len ) {
1569 cfg = *config;
1570 } else {
1571 // general configuration (read/modify/write)
1572 status = readConfigRid(ai, &cfg);
1573 if ( status != SUCCESS ) return ERROR;
1574 cfg.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
1575
1576 /* Save off the MAC */
1577 for( i = 0; i < 6; i++ ) {
1578 mac[i] = cfg.macAddr[i];
1579 }
1580
1581 /* Check to see if there are any insmod configured
1582 rates to add */
1583 if ( rates ) {
1584 int i = 0;
1585 if ( rates[0] ) memset(cfg.rates,0,sizeof(cfg.rates));
1586 for( i = 0; i < 8 && rates[i]; i++ ) {
1587 cfg.rates[i] = rates[i];
1588 }
1589 }
1590 if ( basic_rate > 0 ) {
1591 int i;
1592 for( i = 0; i < 8; i++ ) {
1593 if ( cfg.rates[i] == basic_rate ||
1594 !cfg.rates ) {
1595 cfg.rates[i] = basic_rate | 0x80;
1596 break;
1597 }
1598 }
1599 }
1600 cfg.authType = ai->authtype;
1601 *config = cfg;
1602 }
1603
1604 /* Setup the SSIDs if present */
1605 if ( ssids[0] ) {
1606 int i = 0;
1607 for( i = 0; i < 3 && ssids[i]; i++ ) {
1608 mySsid.ssids[i].len = strlen(ssids[i]);
1609 if ( mySsid.ssids[i].len > 32 )
1610 mySsid.ssids[i].len = 32;
1611 memcpy(mySsid.ssids[i].ssid, ssids[i],
1612 mySsid.ssids[i].len);
1613 mySsid.ssids[i].len = mySsid.ssids[i].len;
1614 }
1615 }
1616
1617 status = writeConfigRid(ai, &cfg);
1618 if ( status != SUCCESS ) return ERROR;
1619
1620 /* Set up the SSID list */
1621 status = writeSsidRid(ai, &mySsid);
1622 if ( status != SUCCESS ) return ERROR;
1623
1624 /* Grab the initial wep key, we gotta save it for auto_wep */
1625 rc = readWepKeyRid(ai, &wkr, 1);
1626 if (rc == SUCCESS) do {
1627 lastindex = wkr.kindex;
1628 if (wkr.kindex == 0xffff) {
1629 ai->defindex = wkr.mac[0];
1630 }
1631 rc = readWepKeyRid(ai, &wkr, 0);
1632 } while(lastindex != wkr.kindex);
1633
1634 if (auto_wep && !timer_pending(&ai->timer)) {
1635 ai->timer.expires = RUN_AT(HZ*3);
1636 add_timer(&ai->timer);
1637 }
1638 return SUCCESS;
1639 }
1640
1641 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
1642 // Im really paranoid about letting it run forever!
1643 int max_tries = 600000;
1644 int rc = SUCCESS;
1645 long flags;
1646
1647 spin_lock_irqsave(&ai->cmd_lock, flags);
1648 OUT4500(ai, PARAM0, pCmd->parm0);
1649 OUT4500(ai, PARAM1, pCmd->parm1);
1650 OUT4500(ai, PARAM2, pCmd->parm2);
1651 OUT4500(ai, COMMAND, pCmd->cmd);
1652 while ( max_tries-- &&
1653 (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
1654 if ( IN4500(ai, COMMAND) == pCmd->cmd) {
1655 // PC4500 didn't notice command, try again
1656 OUT4500(ai, COMMAND, pCmd->cmd);
1657 }
1658 if (!(max_tries & 255) && !in_interrupt()) {
1659 set_current_state(TASK_RUNNING);
1660 schedule();
1661 }
1662 }
1663 if ( max_tries == -1 ) {
1664 printk( KERN_ERR
1665 "airo: Max tries exceeded when issueing command\n" );
1666 rc = ERROR;
1667 goto done;
1668 }
1669 // command completed
1670 pRsp->status = IN4500(ai, STATUS);
1671 pRsp->rsp0 = IN4500(ai, RESP0);
1672 pRsp->rsp1 = IN4500(ai, RESP1);
1673 pRsp->rsp2 = IN4500(ai, RESP2);
1674
1675 // clear stuck command busy if necessary
1676 if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
1677 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
1678 }
1679 // acknowledge processing the status/response
1680 OUT4500(ai, EVACK, EV_CMD);
1681 done:
1682 spin_unlock_irqrestore(&ai->cmd_lock, flags);
1683 return rc;
1684 }
1685
1686 /* Sets up the bap to start exchange data. whichbap should
1687 * be one of the BAP0 or BAP1 defines. Locks should be held before
1688 * calling! */
1689 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
1690 {
1691 int timeout = 50;
1692 int max_tries = 3;
1693
1694 OUT4500(ai, SELECT0+whichbap, rid);
1695 OUT4500(ai, OFFSET0+whichbap, offset);
1696 while (1) {
1697 int status = IN4500(ai, OFFSET0+whichbap);
1698 if (status & BAP_BUSY) {
1699 /* This isn't really a timeout, but its kinda
1700 close */
1701 if (timeout--) {
1702 continue;
1703 }
1704 } else if ( status & BAP_ERR ) {
1705 /* invalid rid or offset */
1706 printk( KERN_ERR "airo: BAP error %x %d\n",
1707 status, whichbap );
1708 return ERROR;
1709 } else if (status & BAP_DONE) { // success
1710 return SUCCESS;
1711 }
1712 if ( !(max_tries--) ) {
1713 printk( KERN_ERR
1714 "airo: BAP setup error too many retries\n" );
1715 return ERROR;
1716 }
1717 // -- PC4500 missed it, try again
1718 OUT4500(ai, SELECT0+whichbap, rid);
1719 OUT4500(ai, OFFSET0+whichbap, offset);
1720 timeout = 50;
1721 }
1722 }
1723
1724 /* should only be called by aux_bap_read. This aux function and the
1725 following use concepts not documented in the developers guide. I
1726 got them from a patch given to my by Aironet */
1727 static u16 aux_setup(struct airo_info *ai, u16 page,
1728 u16 offset, u16 *len)
1729 {
1730 u16 next;
1731
1732 OUT4500(ai, AUXPAGE, page);
1733 OUT4500(ai, AUXOFF, 0);
1734 next = IN4500(ai, AUXDATA);
1735 *len = IN4500(ai, AUXDATA)&0xff;
1736 if (offset != 4) OUT4500(ai, AUXOFF, offset);
1737 return next;
1738 }
1739
1740 /* requires call to bap_setup() first */
1741 static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
1742 int bytelen, int whichbap)
1743 {
1744 u16 len;
1745 u16 page;
1746 u16 offset;
1747 u16 next;
1748 int words;
1749 int i;
1750 long flags;
1751
1752 spin_lock_irqsave(&ai->aux_lock, flags);
1753 page = IN4500(ai, SWS0+whichbap);
1754 offset = IN4500(ai, SWS2+whichbap);
1755 next = aux_setup(ai, page, offset, &len);
1756 words = (bytelen+1)>>1;
1757
1758 for (i=0; i<words;) {
1759 int count;
1760 count = (len>>1) < (words-i) ? (len>>1) : (words-i);
1761 if ( !do8bitIO )
1762 insw( ai->dev->base_addr+DATA0+whichbap,
1763 pu16Dst+i,count );
1764 else
1765 insb( ai->dev->base_addr+DATA0+whichbap,
1766 pu16Dst+i, count << 1 );
1767 i += count;
1768 if (i<words) {
1769 next = aux_setup(ai, next, 4, &len);
1770 }
1771 }
1772 spin_unlock_irqrestore(&ai->aux_lock, flags);
1773 return SUCCESS;
1774 }
1775
1776
1777 /* requires call to bap_setup() first */
1778 static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
1779 int bytelen, int whichbap)
1780 {
1781 bytelen = (bytelen + 1) & (~1); // round up to even value
1782 if ( !do8bitIO )
1783 insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
1784 else
1785 insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
1786 return SUCCESS;
1787 }
1788
1789 /* requires call to bap_setup() first */
1790 static int bap_write(struct airo_info *ai, const u16 *pu16Src,
1791 int bytelen, int whichbap)
1792 {
1793 bytelen = (bytelen + 1) & (~1); // round up to even value
1794 if ( !do8bitIO )
1795 outsw( ai->dev->base_addr+DATA0+whichbap,
1796 pu16Src, bytelen>>1 );
1797 else
1798 outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
1799 return SUCCESS;
1800 }
1801
1802 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
1803 {
1804 Cmd cmd; /* for issuing commands */
1805 Resp rsp; /* response from commands */
1806 u16 status;
1807
1808 memset(&cmd, 0, sizeof(cmd));
1809 cmd.cmd = accmd;
1810 cmd.parm0 = rid;
1811 status = issuecommand(ai, &cmd, &rsp);
1812 if (status != 0) return status;
1813 if ( (rsp.status & 0x7F00) != 0) {
1814 return (accmd << 8) + (rsp.rsp0 & 0xFF);
1815 }
1816 return 0;
1817 }
1818
1819 /* Note, that we are using BAP1 which is also used by transmit, so
1820 * we must get a lock. */
1821 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len)
1822 {
1823 u16 status;
1824 long flags;
1825 int rc = SUCCESS;
1826
1827 spin_lock_irqsave(&ai->bap1_lock, flags);
1828 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != SUCCESS) {
1829 rc = status;
1830 goto done;
1831 }
1832 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
1833 rc = ERROR;
1834 goto done;
1835 }
1836 // read the rid length field
1837 bap_read(ai, pBuf, 2, BAP1);
1838 // length for remaining part of rid
1839 len = min_t(unsigned int, len, le16_to_cpu(*(u16*)pBuf)) - 2;
1840
1841 if ( len <= 2 ) {
1842 printk( KERN_ERR
1843 "airo: Rid %x has a length of %d which is too short\n",
1844 (int)rid,
1845 (int)len );
1846 rc = ERROR;
1847 goto done;
1848 }
1849 // read remainder of the rid
1850 if (bap_setup(ai, rid, 2, BAP1) != SUCCESS) {
1851 rc = ERROR;
1852 goto done;
1853 }
1854 rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
1855 done:
1856 spin_unlock_irqrestore(&ai->bap1_lock, flags);
1857 return rc;
1858 }
1859
1860 /* Note, that we are using BAP1 which is also used by transmit, so
1861 * make sure this isnt called when a transmit is happening */
1862 static int PC4500_writerid(struct airo_info *ai, u16 rid,
1863 const void *pBuf, int len)
1864 {
1865 u16 status;
1866 long flags;
1867 int rc = SUCCESS;
1868
1869 spin_lock_irqsave(&ai->bap1_lock, flags);
1870 // --- first access so that we can write the rid data
1871 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
1872 rc = status;
1873 goto done;
1874 }
1875 // --- now write the rid data
1876 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
1877 rc = ERROR;
1878 goto done;
1879 }
1880 bap_write(ai, pBuf, len, BAP1);
1881 // ---now commit the rid data
1882 rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
1883 done:
1884 spin_unlock_irqrestore(&ai->bap1_lock, flags);
1885 return rc;
1886 }
1887
1888 /* Allocates a FID to be used for transmitting packets. We only use
1889 one for now. */
1890 static u16 transmit_allocate(struct airo_info *ai, int lenPayload)
1891 {
1892 Cmd cmd;
1893 Resp rsp;
1894 u16 txFid;
1895 u16 txControl;
1896 long flags;
1897
1898 cmd.cmd = CMD_ALLOCATETX;
1899 cmd.parm0 = lenPayload;
1900 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return 0;
1901 if ( (rsp.status & 0xFF00) != 0) return 0;
1902 /* wait for the allocate event/indication
1903 * It makes me kind of nervous that this can just sit here and spin,
1904 * but in practice it only loops like four times. */
1905 while ( (IN4500(ai, EVSTAT) & EV_ALLOC) == 0) ;
1906 // get the allocated fid and acknowledge
1907 txFid = IN4500(ai, TXALLOCFID);
1908 OUT4500(ai, EVACK, EV_ALLOC);
1909
1910 /* The CARD is pretty cool since it converts the ethernet packet
1911 * into 802.11. Also note that we don't release the FID since we
1912 * will be using the same one over and over again. */
1913 /* We only have to setup the control once since we are not
1914 * releasing the fid. */
1915 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
1916 | TXCTL_ETHERNET | TXCTL_NORELEASE);
1917 spin_lock_irqsave(&ai->bap1_lock, flags);
1918 if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS) {
1919 spin_unlock_irqrestore(&ai->bap1_lock, flags);
1920 return ERROR;
1921 }
1922 bap_write(ai, &txControl, sizeof(txControl), BAP1);
1923 spin_unlock_irqrestore(&ai->bap1_lock, flags);
1924
1925 return txFid;
1926 }
1927
1928 /* In general BAP1 is dedicated to transmiting packets. However,
1929 since we need a BAP when accessing RIDs, we also use BAP1 for that.
1930 Make sure the BAP1 spinlock is held when this is called. */
1931 static int transmit_802_3_packet(struct airo_info *ai, u16 txFid,
1932 char *pPacket, int len)
1933 {
1934 u16 payloadLen;
1935 Cmd cmd;
1936 Resp rsp;
1937
1938 if (len < 12) {
1939 printk( KERN_WARNING "Short packet %d\n", len );
1940 return ERROR;
1941 }
1942
1943 // packet is destination[6], source[6], payload[len-12]
1944 // write the payload length and dst/src/payload
1945 if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
1946 /* The hardware addresses aren't counted as part of the payload, so
1947 * we have to subtract the 12 bytes for the addresses off */
1948 payloadLen = cpu_to_le16(len-12);
1949 bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
1950 bap_write(ai, (const u16*)pPacket, len, BAP1);
1951 // issue the transmit command
1952 memset( &cmd, 0, sizeof( cmd ) );
1953 cmd.cmd = CMD_TRANSMIT;
1954 cmd.parm0 = txFid;
1955 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
1956 if ( (rsp.status & 0xFF00) != 0) return ERROR;
1957 return SUCCESS;
1958 }
1959
1960 /*
1961 * This is the proc_fs routines. It is a bit messier than I would
1962 * like! Feel free to clean it up!
1963 */
1964
1965 static ssize_t proc_read( struct file *file,
1966 char *buffer,
1967 size_t len,
1968 loff_t *offset);
1969
1970 static ssize_t proc_write( struct file *file,
1971 const char *buffer,
1972 size_t len,
1973 loff_t *offset );
1974 static int proc_close( struct inode *inode, struct file *file );
1975
1976 static int proc_stats_open( struct inode *inode, struct file *file );
1977 static int proc_statsdelta_open( struct inode *inode, struct file *file );
1978 static int proc_status_open( struct inode *inode, struct file *file );
1979 static int proc_SSID_open( struct inode *inode, struct file *file );
1980 static int proc_APList_open( struct inode *inode, struct file *file );
1981 static int proc_BSSList_open( struct inode *inode, struct file *file );
1982 static int proc_config_open( struct inode *inode, struct file *file );
1983 static int proc_wepkey_open( struct inode *inode, struct file *file );
1984
1985 static struct file_operations proc_statsdelta_ops = {
1986 read: proc_read,
1987 open: proc_statsdelta_open,
1988 release: proc_close
1989 };
1990
1991 static struct file_operations proc_stats_ops = {
1992 read: proc_read,
1993 open: proc_stats_open,
1994 release: proc_close
1995 };
1996
1997 static struct file_operations proc_status_ops = {
1998 read: proc_read,
1999 open: proc_status_open,
2000 release: proc_close
2001 };
2002
2003 static struct file_operations proc_SSID_ops = {
2004 read: proc_read,
2005 write: proc_write,
2006 open: proc_SSID_open,
2007 release: proc_close
2008 };
2009
2010 static struct file_operations proc_BSSList_ops = {
2011 read: proc_read,
2012 write: proc_write,
2013 open: proc_BSSList_open,
2014 release: proc_close
2015 };
2016
2017 static struct file_operations proc_APList_ops = {
2018 read: proc_read,
2019 write: proc_write,
2020 open: proc_APList_open,
2021 release: proc_close
2022 };
2023
2024 static struct file_operations proc_config_ops = {
2025 read: proc_read,
2026 write: proc_write,
2027 open: proc_config_open,
2028 release: proc_close
2029 };
2030
2031 static struct file_operations proc_wepkey_ops = {
2032 read: proc_read,
2033 write: proc_write,
2034 open: proc_wepkey_open,
2035 release: proc_close
2036 };
2037
2038 static struct proc_dir_entry *airo_entry = 0;
2039
2040 struct proc_data {
2041 int release_buffer;
2042 int readlen;
2043 char *rbuffer;
2044 int writelen;
2045 int maxwritelen;
2046 char *wbuffer;
2047 void (*on_close) (struct inode *, struct file *);
2048 };
2049
2050 #ifndef SETPROC_OPS
2051 #define SETPROC_OPS(entry, ops) (entry)->proc_fops = &(ops)
2052 #endif
2053
2054 static int setup_proc_entry( struct net_device *dev,
2055 struct airo_info *apriv ) {
2056 struct proc_dir_entry *entry;
2057 /* First setup the device directory */
2058 apriv->proc_entry = create_proc_entry(dev->name,
2059 S_IFDIR|airo_perm,
2060 airo_entry);
2061 apriv->proc_entry->uid = proc_uid;
2062 apriv->proc_entry->gid = proc_gid;
2063
2064 /* Setup the StatsDelta */
2065 entry = create_proc_entry("StatsDelta",
2066 S_IFREG | (S_IRUGO&proc_perm),
2067 apriv->proc_entry);
2068 entry->uid = proc_uid;
2069 entry->gid = proc_gid;
2070 entry->data = dev;
2071 SETPROC_OPS(entry, proc_statsdelta_ops);
2072
2073 /* Setup the Stats */
2074 entry = create_proc_entry("Stats",
2075 S_IFREG | (S_IRUGO&proc_perm),
2076 apriv->proc_entry);
2077 entry->uid = proc_uid;
2078 entry->gid = proc_gid;
2079 entry->data = dev;
2080 SETPROC_OPS(entry, proc_stats_ops);
2081
2082 /* Setup the Status */
2083 entry = create_proc_entry("Status",
2084 S_IFREG | (S_IRUGO&proc_perm),
2085 apriv->proc_entry);
2086 entry->uid = proc_uid;
2087 entry->gid = proc_gid;
2088 entry->data = dev;
2089 SETPROC_OPS(entry, proc_status_ops);
2090
2091 /* Setup the Config */
2092 entry = create_proc_entry("Config",
2093 S_IFREG | proc_perm,
2094 apriv->proc_entry);
2095 entry->uid = proc_uid;
2096 entry->gid = proc_gid;
2097 entry->data = dev;
2098 SETPROC_OPS(entry, proc_config_ops);
2099
2100 /* Setup the SSID */
2101 entry = create_proc_entry("SSID",
2102 S_IFREG | proc_perm,
2103 apriv->proc_entry);
2104 entry->uid = proc_uid;
2105 entry->gid = proc_gid;
2106 entry->data = dev;
2107 SETPROC_OPS(entry, proc_SSID_ops);
2108
2109 /* Setup the APList */
2110 entry = create_proc_entry("APList",
2111 S_IFREG | proc_perm,
2112 apriv->proc_entry);
2113 entry->uid = proc_uid;
2114 entry->gid = proc_gid;
2115 entry->data = dev;
2116 SETPROC_OPS(entry, proc_APList_ops);
2117
2118 /* Setup the BSSList */
2119 entry = create_proc_entry("BSSList",
2120 S_IFREG | proc_perm,
2121 apriv->proc_entry);
2122 entry->uid = proc_uid;
2123 entry->gid = proc_gid;
2124 entry->data = dev;
2125 SETPROC_OPS(entry, proc_BSSList_ops);
2126
2127 /* Setup the WepKey */
2128 entry = create_proc_entry("WepKey",
2129 S_IFREG | proc_perm,
2130 apriv->proc_entry);
2131 entry->uid = proc_uid;
2132 entry->gid = proc_gid;
2133 entry->data = dev;
2134 SETPROC_OPS(entry, proc_wepkey_ops);
2135
2136 return 0;
2137 }
2138
2139 static int takedown_proc_entry( struct net_device *dev,
2140 struct airo_info *apriv ) {
2141 if ( !apriv->proc_entry->namelen ) return 0;
2142 remove_proc_entry("Stats",apriv->proc_entry);
2143 remove_proc_entry("StatsDelta",apriv->proc_entry);
2144 remove_proc_entry("Status",apriv->proc_entry);
2145 remove_proc_entry("Config",apriv->proc_entry);
2146 remove_proc_entry("SSID",apriv->proc_entry);
2147 remove_proc_entry("APList",apriv->proc_entry);
2148 remove_proc_entry("BSSList",apriv->proc_entry);
2149 remove_proc_entry("WepKey",apriv->proc_entry);
2150 remove_proc_entry(dev->name,airo_entry);
2151 return 0;
2152 }
2153
2154 /*
2155 * What we want from the proc_fs is to be able to efficiently read
2156 * and write the configuration. To do this, we want to read the
2157 * configuration when the file is opened and write it when the file is
2158 * closed. So basically we allocate a read buffer at open and fill it
2159 * with data, and allocate a write buffer and read it at close.
2160 */
2161
2162 /*
2163 * The read routine is generic, it relies on the preallocated rbuffer
2164 * to supply the data.
2165 */
2166 static ssize_t proc_read( struct file *file,
2167 char *buffer,
2168 size_t len,
2169 loff_t *offset )
2170 {
2171 int i;
2172 int pos;
2173 struct proc_data *priv = (struct proc_data*)file->private_data;
2174
2175 if( !priv->rbuffer ) return -EINVAL;
2176
2177 pos = *offset;
2178 for( i = 0; i+pos < priv->readlen && i < len; i++ ) {
2179 if (put_user( priv->rbuffer[i+pos], buffer+i ))
2180 return -EFAULT;
2181 }
2182 *offset += i;
2183 return i;
2184 }
2185
2186 /*
2187 * The write routine is generic, it fills in a preallocated rbuffer
2188 * to supply the data.
2189 */
2190 static ssize_t proc_write( struct file *file,
2191 const char *buffer,
2192 size_t len,
2193 loff_t *offset )
2194 {
2195 int i;
2196 int pos;
2197 struct proc_data *priv = (struct proc_data*)file->private_data;
2198
2199 if ( !priv->wbuffer ) {
2200 return -EINVAL;
2201 }
2202
2203 pos = *offset;
2204
2205 for( i = 0; i + pos < priv->maxwritelen &&
2206 i < len; i++ ) {
2207 if (get_user( priv->wbuffer[i+pos], buffer + i ))
2208 return -EFAULT;
2209 }
2210 if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos;
2211 *offset += i;
2212 return i;
2213 }
2214
2215 static int proc_status_open( struct inode *inode, struct file *file ) {
2216 struct proc_data *data;
2217 struct proc_dir_entry *dp = inode->u.generic_ip;
2218 struct net_device *dev = dp->data;
2219 struct airo_info *apriv = (struct airo_info *)dev->priv;
2220 CapabilityRid cap_rid;
2221 StatusRid status_rid;
2222 int i;
2223
2224 MOD_INC_USE_COUNT;
2225
2226 dp = inode->u.generic_ip;
2227
2228 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2229 return -ENOMEM;
2230 memset(file->private_data, 0, sizeof(struct proc_data));
2231 data = (struct proc_data *)file->private_data;
2232 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
2233 kfree (file->private_data);
2234 return -ENOMEM;
2235 }
2236
2237 readStatusRid(apriv, &status_rid);
2238 readCapabilityRid(apriv, &cap_rid);
2239
2240 i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
2241 status_rid.mode & 1 ? "CFG ": "",
2242 status_rid.mode & 2 ? "ACT ": "",
2243 status_rid.mode & 0x10 ? "SYN ": "",
2244 status_rid.mode & 0x20 ? "LNK ": "",
2245 status_rid.mode & 0x40 ? "LEAP ": "",
2246 status_rid.mode & 0x80 ? "PRIV ": "",
2247 status_rid.mode & 0x100 ? "KEY ": "",
2248 status_rid.mode & 0x200 ? "WEP ": "",
2249 status_rid.mode & 0x8000 ? "ERR ": "");
2250 sprintf( data->rbuffer+i, "Mode: %x\n"
2251 "Signal Strength: %d\n"
2252 "Signal Quality: %d\n"
2253 "SSID: %-.*s\n"
2254 "AP: %-.16s\n"
2255 "Freq: %d\n"
2256 "BitRate: %dmbs\n"
2257 "Driver Version: %s\n"
2258 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
2259 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
2260 "Software Version: %x\nSoftware Subversion: %x\n"
2261 "Boot block version: %x\n",
2262 (int)status_rid.mode,
2263 (int)status_rid.normalizedSignalStrength,
2264 (int)status_rid.signalQuality,
2265 (int)status_rid.SSIDlen,
2266 status_rid.SSID,
2267 status_rid.apName,
2268 (int)status_rid.channel,
2269 (int)status_rid.currentXmitRate/2,
2270 version,
2271 cap_rid.prodName,
2272 cap_rid.manName,
2273 cap_rid.prodVer,
2274 cap_rid.radioType,
2275 cap_rid.country,
2276 cap_rid.hardVer,
2277 (int)cap_rid.softVer,
2278 (int)cap_rid.softSubVer,
2279 (int)cap_rid.bootBlockVer );
2280 data->readlen = strlen( data->rbuffer );
2281 return 0;
2282 }
2283
2284 static int proc_stats_rid_open(struct inode*, struct file*, u16);
2285 static int proc_statsdelta_open( struct inode *inode,
2286 struct file *file ) {
2287 if (file->f_mode&FMODE_WRITE) {
2288 return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
2289 }
2290 return proc_stats_rid_open(inode, file, RID_STATSDELTA);
2291 }
2292
2293 static int proc_stats_open( struct inode *inode, struct file *file ) {
2294 return proc_stats_rid_open(inode, file, RID_STATS);
2295 }
2296
2297 static int proc_stats_rid_open( struct inode *inode,
2298 struct file *file,
2299 u16 rid ) {
2300 struct proc_data *data;
2301 struct proc_dir_entry *dp = inode->u.generic_ip;
2302 struct net_device *dev = dp->data;
2303 struct airo_info *apriv = (struct airo_info *)dev->priv;
2304 StatsRid stats;
2305 int i, j;
2306 int *vals = stats.vals;
2307 MOD_INC_USE_COUNT;
2308
2309
2310 dp = inode->u.generic_ip;
2311
2312 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2313 return -ENOMEM;
2314 memset(file->private_data, 0, sizeof(struct proc_data));
2315 data = (struct proc_data *)file->private_data;
2316 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
2317 kfree (file->private_data);
2318 return -ENOMEM;
2319 }
2320
2321 readStatsRid(apriv, &stats, rid);
2322
2323 j = 0;
2324 for(i=0; (int)statsLabels[i]!=-1 &&
2325 i*4<stats.len; i++){
2326 if (!statsLabels[i]) continue;
2327 if (j+strlen(statsLabels[i])+16>4096) {
2328 printk(KERN_WARNING
2329 "airo: Potentially disasterous buffer overflow averted!\n");
2330 break;
2331 }
2332 j+=sprintf(data->rbuffer+j, "%s: %d\n", statsLabels[i], vals[i]);
2333 }
2334 if (i*4>=stats.len){
2335 printk(KERN_WARNING
2336 "airo: Got a short rid\n");
2337 }
2338 data->readlen = j;
2339 return 0;
2340 }
2341
2342 static int get_dec_u16( char *buffer, int *start, int limit ) {
2343 u16 value;
2344 int valid = 0;
2345 for( value = 0; buffer[*start] >= '0' &&
2346 buffer[*start] <= '9' &&
2347 *start < limit; (*start)++ ) {
2348 valid = 1;
2349 value *= 10;
2350 value += buffer[*start] - '0';
2351 }
2352 if ( !valid ) return -1;
2353 return value;
2354 }
2355
2356 static void checkThrottle(ConfigRid *config) {
2357 int i;
2358 /* Old hardware had a limit on encryption speed */
2359 if (config->authType != AUTH_OPEN && maxencrypt) {
2360 for(i=0; i<8; i++) {
2361 if (config->rates[i] > maxencrypt) {
2362 config->rates[i] = 0;
2363 }
2364 }
2365 }
2366 }
2367
2368 static void proc_config_on_close( struct inode *inode, struct file *file ) {
2369 struct proc_data *data = file->private_data;
2370 struct proc_dir_entry *dp = inode->u.generic_ip;
2371 struct net_device *dev = dp->data;
2372 struct airo_info *ai = (struct airo_info*)dev->priv;
2373 ConfigRid config;
2374 Resp rsp;
2375 char *line;
2376 int need_reset = 0;
2377
2378 if ( !data->writelen ) return;
2379 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2380
2381 disable_MAC(ai);
2382 readConfigRid(ai, &config);
2383
2384 line = data->wbuffer;
2385 while( line[0] ) {
2386 /*** Mode processing */
2387 if ( !strncmp( line, "Mode: ", 6 ) ) {
2388 line += 6;
2389 config.rmode &= 0xfe00;
2390 if ( line[0] == 'a' ) {
2391 config.opmode = 0;
2392 } else {
2393 config.opmode = 1;
2394 if ( line[0] == 'r' )
2395 config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
2396 else if ( line[0] == 'y' )
2397 config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
2398 }
2399 if (config.rmode & RXMODE_DISABLE_802_3_HEADER) {
2400 dev->type = ARPHRD_IEEE80211;
2401 dev->hard_header_parse = wll_header_parse;
2402 } else if (dev->type == ARPHRD_IEEE80211) {
2403 dev->type = ARPHRD_ETHER;
2404 dev->hard_header_parse = ai->header_parse;
2405 need_reset = 1;
2406 }
2407 }
2408
2409 /*** Radio status */
2410 else if (!strncmp(line,"Radio: ", 7)) {
2411 line += 7;
2412 if (!strncmp(line,"off",3)) {
2413 ai->flags |= FLAG_RADIO_OFF;
2414 } else {
2415 ai->flags &= ~FLAG_RADIO_OFF;
2416 }
2417 }
2418 /*** NodeName processing */
2419 else if ( !strncmp( line, "NodeName: ", 10 ) ) {
2420 int j;
2421
2422 line += 10;
2423 memset( config.nodeName, 0, 16 );
2424 /* Do the name, assume a space between the mode and node name */
2425 for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
2426 config.nodeName[j] = line[j];
2427 }
2428 }
2429
2430 /*** PowerMode processing */
2431 else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
2432 line += 11;
2433 if ( !strncmp( line, "PSPCAM", 6 ) ) {
2434 config.powerSaveMode = POWERSAVE_PSPCAM;
2435 } else if ( !strncmp( line, "PSP", 3 ) ) {
2436 config.powerSaveMode = POWERSAVE_PSP;
2437 } else {
2438 config.powerSaveMode = POWERSAVE_CAM;
2439 }
2440 } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
2441 int v, i = 0, k = 0; /* i is index into line,
2442 k is index to rates */
2443
2444 line += 11;
2445 while((v = get_dec_u16(line, &i, 3))!=-1) {
2446 config.rates[k++] = (u8)v;
2447 line += i + 1;
2448 i = 0;
2449 }
2450 } else if ( !strncmp( line, "Channel: ", 9 ) ) {
2451 int v, i = 0;
2452 line += 9;
2453 v = get_dec_u16(line, &i, i+3);
2454 if ( v != -1 )
2455 config.channelSet = (u16)v;
2456 } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
2457 int v, i = 0;
2458 line += 11;
2459 v = get_dec_u16(line, &i, i+3);
2460 if ( v != -1 ) config.txPower = (u16)v;
2461 } else if ( !strncmp( line, "WEP: ", 5 ) ) {
2462 line += 5;
2463 switch( line[0] ) {
2464 case 's':
2465 config.authType = (u16)AUTH_SHAREDKEY;
2466 break;
2467 case 'e':
2468 config.authType = (u16)AUTH_ENCRYPT;
2469 break;
2470 default:
2471 config.authType = (u16)AUTH_OPEN;
2472 break;
2473 }
2474 } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
2475 int v, i = 0;
2476
2477 line += 16;
2478 v = get_dec_u16(line, &i, 3);
2479 v = (v<0) ? 0 : ((v>255) ? 255 : v);
2480 config.longRetryLimit = (u16)v;
2481 } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
2482 int v, i = 0;
2483
2484 line += 17;
2485 v = get_dec_u16(line, &i, 3);
2486 v = (v<0) ? 0 : ((v>255) ? 255 : v);
2487 config.shortRetryLimit = (u16)v;
2488 } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
2489 int v, i = 0;
2490
2491 line += 14;
2492 v = get_dec_u16(line, &i, 4);
2493 v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
2494 config.rtsThres = (u16)v;
2495 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
2496 int v, i = 0;
2497
2498 line += 16;
2499 v = get_dec_u16(line, &i, 5);
2500 v = (v<0) ? 0 : v;
2501 config.txLifetime = (u16)v;
2502 } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
2503 int v, i = 0;
2504
2505 line += 16;
2506 v = get_dec_u16(line, &i, 5);
2507 v = (v<0) ? 0 : v;
2508 config.rxLifetime = (u16)v;
2509 } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
2510 config.txDiversity =
2511 (line[13]=='l') ? 1 :
2512 ((line[13]=='r')? 2: 3);
2513 } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
2514 config.rxDiversity =
2515 (line[13]=='l') ? 1 :
2516 ((line[13]=='r')? 2: 3);
2517 } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
2518 int v, i = 0;
2519
2520 line += 15;
2521 v = get_dec_u16(line, &i, 4);
2522 v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
2523 v = v & 0xfffe; /* Make sure its even */
2524 config.fragThresh = (u16)v;
2525 } else if (!strncmp(line, "Modulation: ", 12)) {
2526 line += 12;
2527 switch(*line) {
2528 case 'd': config.modulation=MOD_DEFAULT; break;
2529 case 'c': config.modulation=MOD_CCK; break;
2530 case 'm': config.modulation=MOD_MOK; break;
2531 default:
2532 printk( KERN_WARNING "airo: Unknown modulation\n" );
2533 }
2534 } else if (!strncmp(line, "Preamble: ", 10)) {
2535 line += 10;
2536 switch(*line) {
2537 case 'a': config.preamble=PREAMBLE_AUTO; break;
2538 case 'l': config.preamble=PREAMBLE_LONG; break;
2539 case 's': config.preamble=PREAMBLE_SHORT; break;
2540 default: printk(KERN_WARNING "airo: Unknown preamble\n");
2541 }
2542 } else {
2543 printk( KERN_WARNING "Couldn't figure out %s\n", line );
2544 }
2545 while( line[0] && line[0] != '\n' ) line++;
2546 if ( line[0] ) line++;
2547 }
2548 checkThrottle(&config);
2549 ai->config = config;
2550 if (need_reset) {
2551 APListRid APList_rid;
2552 SsidRid SSID_rid;
2553
2554 readAPListRid(ai, &APList_rid);
2555 readSsidRid(ai, &SSID_rid);
2556 reset_airo_card(dev);
2557 writeSsidRid(ai, &SSID_rid);
2558 writeAPListRid(ai, &APList_rid);
2559 }
2560 writeConfigRid(ai, &config);
2561 enable_MAC(ai, &rsp);
2562 }
2563
2564 static int proc_config_open( struct inode *inode, struct file *file ) {
2565 struct proc_data *data;
2566 struct proc_dir_entry *dp = inode->u.generic_ip;
2567 struct net_device *dev = dp->data;
2568 struct airo_info *ai = (struct airo_info*)dev->priv;
2569 ConfigRid config;
2570 int i;
2571
2572 MOD_INC_USE_COUNT;
2573
2574 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2575
2576 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2577 return -ENOMEM;
2578 memset(file->private_data, 0, sizeof(struct proc_data));
2579 data = (struct proc_data *)file->private_data;
2580 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
2581 kfree (file->private_data);
2582 return -ENOMEM;
2583 }
2584 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
2585 kfree (data->rbuffer);
2586 kfree (file->private_data);
2587 return -ENOMEM;
2588 }
2589 memset( data->wbuffer, 0, 2048 );
2590 data->maxwritelen = 2048;
2591 data->on_close = proc_config_on_close;
2592
2593 readConfigRid(ai, &config);
2594
2595 i = sprintf( data->rbuffer,
2596 "Mode: %s\n"
2597 "Radio: %s\n"
2598 "NodeName: %-16s\n"
2599 "PowerMode: %s\n"
2600 "DataRates: %d %d %d %d %d %d %d %d\n"
2601 "Channel: %d\n"
2602 "XmitPower: %d\n",
2603 config.opmode == 0 ? "adhoc" :
2604 config.opmode == 1 ? "ESS" :
2605 config.opmode == 2 ? "AP" :
2606 config.opmode == 3 ? "AP RPTR" : "Error",
2607 ai->flags&FLAG_RADIO_OFF ? "off" : "on",
2608 config.nodeName,
2609 config.powerSaveMode == 0 ? "CAM" :
2610 config.powerSaveMode == 1 ? "PSP" :
2611 config.powerSaveMode == 2 ? "PSPCAM" : "Error",
2612 (int)config.rates[0],
2613 (int)config.rates[1],
2614 (int)config.rates[2],
2615 (int)config.rates[3],
2616 (int)config.rates[4],
2617 (int)config.rates[5],
2618 (int)config.rates[6],
2619 (int)config.rates[7],
2620 (int)config.channelSet,
2621 (int)config.txPower
2622 );
2623 sprintf( data->rbuffer + i,
2624 "LongRetryLimit: %d\n"
2625 "ShortRetryLimit: %d\n"
2626 "RTSThreshold: %d\n"
2627 "TXMSDULifetime: %d\n"
2628 "RXMSDULifetime: %d\n"
2629 "TXDiversity: %s\n"
2630 "RXDiversity: %s\n"
2631 "FragThreshold: %d\n"
2632 "WEP: %s\n"
2633 "Modulation: %s\n"
2634 "Preamble: %s\n",
2635 (int)config.longRetryLimit,
2636 (int)config.shortRetryLimit,
2637 (int)config.rtsThres,
2638 (int)config.txLifetime,
2639 (int)config.rxLifetime,
2640 config.txDiversity == 1 ? "left" :
2641 config.txDiversity == 2 ? "right" : "both",
2642 config.rxDiversity == 1 ? "left" :
2643 config.rxDiversity == 2 ? "right" : "both",
2644 (int)config.fragThresh,
2645 config.authType == AUTH_ENCRYPT ? "encrypt" :
2646 config.authType == AUTH_SHAREDKEY ? "shared" : "open",
2647 config.modulation == 0 ? "default" :
2648 config.modulation == MOD_CCK ? "cck" :
2649 config.modulation == MOD_MOK ? "mok" : "error",
2650 config.preamble == PREAMBLE_AUTO ? "auto" :
2651 config.preamble == PREAMBLE_LONG ? "long" :
2652 config.preamble == PREAMBLE_SHORT ? "short" : "error"
2653 );
2654 data->readlen = strlen( data->rbuffer );
2655 return 0;
2656 }
2657
2658 static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
2659 struct proc_data *data = (struct proc_data *)file->private_data;
2660 struct proc_dir_entry *dp = inode->u.generic_ip;
2661 struct net_device *dev = dp->data;
2662 struct airo_info *ai = (struct airo_info*)dev->priv;
2663 SsidRid SSID_rid;
2664 int i;
2665 int offset = 0;
2666
2667 if ( !data->writelen ) return;
2668
2669 memset( &SSID_rid, 0, sizeof( SSID_rid ) );
2670
2671 for( i = 0; i < 3; i++ ) {
2672 int j;
2673 for( j = 0; j+offset < data->writelen && j < 32 &&
2674 data->wbuffer[offset+j] != '\n'; j++ ) {
2675 SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
2676 }
2677 if ( j == 0 ) break;
2678 SSID_rid.ssids[i].len = j;
2679 offset += j;
2680 while( data->wbuffer[offset] != '\n' &&
2681 offset < data->writelen ) offset++;
2682 offset++;
2683 }
2684 writeSsidRid(ai, &SSID_rid);
2685 }
2686
2687 inline static u8 hexVal(char c) {
2688 if (c>='0' && c<='9') return c -= '0';
2689 if (c>='a' && c<='f') return c -= 'a'-10;
2690 if (c>='A' && c<='F') return c -= 'A'-10;
2691 return 0;
2692 }
2693
2694 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
2695 struct proc_data *data = (struct proc_data *)file->private_data;
2696 struct proc_dir_entry *dp = inode->u.generic_ip;
2697 struct net_device *dev = dp->data;
2698 struct airo_info *ai = (struct airo_info*)dev->priv;
2699 APListRid APList_rid;
2700 int i;
2701
2702 if ( !data->writelen ) return;
2703
2704 memset( &APList_rid, 0, sizeof(APList_rid) );
2705 APList_rid.len = sizeof(APList_rid);
2706
2707 for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
2708 int j;
2709 for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
2710 switch(j%3) {
2711 case 0:
2712 APList_rid.ap[i][j/3]=
2713 hexVal(data->wbuffer[j+i*6*3])<<4;
2714 break;
2715 case 1:
2716 APList_rid.ap[i][j/3]|=
2717 hexVal(data->wbuffer[j+i*6*3]);
2718 break;
2719 }
2720 }
2721 }
2722 writeAPListRid(ai, &APList_rid);
2723 }
2724
2725 /* This function wraps PC4500_writerid with a MAC disable */
2726 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
2727 int len ) {
2728 int rc;
2729 Resp rsp;
2730
2731 disable_MAC(ai);
2732 rc = PC4500_writerid(ai, rid, rid_data, len);
2733 enable_MAC(ai, &rsp);
2734 return rc;
2735 }
2736
2737 /* Returns the length of the key at the index. If index == 0xffff
2738 * the index of the transmit key is returned. If the key doesn't exist,
2739 * -1 will be returned.
2740 */
2741 static int get_wep_key(struct airo_info *ai, u16 index) {
2742 WepKeyRid wkr;
2743 int rc;
2744 u16 lastindex;
2745
2746 rc = readWepKeyRid(ai, &wkr, 1);
2747 if (rc == SUCCESS) do {
2748 lastindex = wkr.kindex;
2749 if (wkr.kindex == index) {
2750 if (index == 0xffff) {
2751 return wkr.mac[0];
2752 }
2753 return wkr.klen;
2754 }
2755 readWepKeyRid(ai, &wkr, 0);
2756 } while(lastindex != wkr.kindex);
2757 return -1;
2758 }
2759
2760 static int set_wep_key(struct airo_info *ai, u16 index,
2761 const char *key, u16 keylen, int perm ) {
2762 static const unsigned char macaddr[6] = { 0x01, 0, 0, 0, 0, 0 };
2763 WepKeyRid wkr;
2764
2765 memset(&wkr, 0, sizeof(wkr));
2766 if (keylen == 0) {
2767 // We are selecting which key to use
2768 wkr.len = sizeof(wkr);
2769 wkr.kindex = 0xffff;
2770 wkr.mac[0] = (char)index;
2771 if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
2772 if (perm) ai->defindex = (char)index;
2773 } else {
2774 // We are actually setting the key
2775 wkr.len = sizeof(wkr);
2776 wkr.kindex = index;
2777 wkr.klen = keylen;
2778 memcpy( wkr.key, key, keylen );
2779 memcpy( wkr.mac, macaddr, 6 );
2780 printk(KERN_INFO "Setting key %d\n", index);
2781 }
2782
2783 writeWepKeyRid(ai, &wkr, perm);
2784 return 0;
2785 }
2786
2787 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
2788 struct proc_data *data;
2789 struct proc_dir_entry *dp = inode->u.generic_ip;
2790 struct net_device *dev = dp->data;
2791 struct airo_info *ai = (struct airo_info*)dev->priv;
2792 int i;
2793 char key[16];
2794 u16 index = 0;
2795 int j = 0;
2796
2797 memset(key, 0, sizeof(key));
2798
2799 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2800 data = (struct proc_data *)file->private_data;
2801 if ( !data->writelen ) return;
2802
2803 if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
2804 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
2805 index = data->wbuffer[0] - '0';
2806 if (data->wbuffer[1] == '\n') {
2807 set_wep_key(ai, index, 0, 0, 1);
2808 return;
2809 }
2810 j = 2;
2811 } else {
2812 printk(KERN_ERR "airo: WepKey passed invalid key index\n");
2813 return;
2814 }
2815
2816 for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
2817 switch(i%3) {
2818 case 0:
2819 key[i/3] = hexVal(data->wbuffer[i+j])<<4;
2820 break;
2821 case 1:
2822 key[i/3] |= hexVal(data->wbuffer[i+j]);
2823 break;
2824 }
2825 }
2826 set_wep_key(ai, index, key, i/3, 1);
2827 }
2828
2829 static int proc_wepkey_open( struct inode *inode, struct file *file ) {
2830 struct proc_data *data;
2831 struct proc_dir_entry *dp = inode->u.generic_ip;
2832 struct net_device *dev = dp->data;
2833 struct airo_info *ai = (struct airo_info*)dev->priv;
2834 char *ptr;
2835 WepKeyRid wkr;
2836 u16 lastindex;
2837 int j=0;
2838 int rc;
2839
2840 MOD_INC_USE_COUNT;
2841
2842 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2843
2844 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2845 return -ENOMEM;
2846 memset(file->private_data, 0, sizeof(struct proc_data));
2847 memset(&wkr, 0, sizeof(wkr));
2848 data = (struct proc_data *)file->private_data;
2849 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
2850 kfree (file->private_data);
2851 return -ENOMEM;
2852 }
2853 memset(data->rbuffer, 0, 180);
2854 data->writelen = 0;
2855 data->maxwritelen = 80;
2856 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
2857 kfree (data->rbuffer);
2858 kfree (file->private_data);
2859 return -ENOMEM;
2860 }
2861 memset( data->wbuffer, 0, 80 );
2862 data->on_close = proc_wepkey_on_close;
2863
2864 ptr = data->rbuffer;
2865 strcpy(ptr, "No wep keys\n");
2866 rc = readWepKeyRid(ai, &wkr, 1);
2867 if (rc == SUCCESS) do {
2868 lastindex = wkr.kindex;
2869 if (wkr.kindex == 0xffff) {
2870 j += sprintf(ptr+j, "Tx key = %d\n",
2871 (int)wkr.mac[0]);
2872 } else {
2873 j += sprintf(ptr+j, "Key %d set with length = %d\n",
2874 (int)wkr.kindex, (int)wkr.klen);
2875 }
2876 readWepKeyRid(ai, &wkr, 0);
2877 } while((lastindex != wkr.kindex) && (j < 180-30));
2878
2879 data->readlen = strlen( data->rbuffer );
2880 return 0;
2881 }
2882
2883 static int proc_SSID_open( struct inode *inode, struct file *file ) {
2884 struct proc_data *data;
2885 struct proc_dir_entry *dp = inode->u.generic_ip;
2886 struct net_device *dev = dp->data;
2887 struct airo_info *ai = (struct airo_info*)dev->priv;
2888 int i;
2889 char *ptr;
2890 SsidRid SSID_rid;
2891
2892 MOD_INC_USE_COUNT;
2893
2894 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2895
2896 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2897 return -ENOMEM;
2898 memset(file->private_data, 0, sizeof(struct proc_data));
2899 data = (struct proc_data *)file->private_data;
2900 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
2901 kfree (file->private_data);
2902 return -ENOMEM;
2903 }
2904 data->writelen = 0;
2905 data->maxwritelen = 33*3;
2906 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
2907 kfree (data->rbuffer);
2908 kfree (file->private_data);
2909 return -ENOMEM;
2910 }
2911 memset( data->wbuffer, 0, 33*3 );
2912 data->on_close = proc_SSID_on_close;
2913
2914 readSsidRid(ai, &SSID_rid);
2915 ptr = data->rbuffer;
2916 for( i = 0; i < 3; i++ ) {
2917 int j;
2918 if ( !SSID_rid.ssids[i].len ) break;
2919 for( j = 0; j < 32 &&
2920 j < SSID_rid.ssids[i].len &&
2921 SSID_rid.ssids[i].ssid[j]; j++ ) {
2922 *ptr++ = SSID_rid.ssids[i].ssid[j];
2923 }
2924 *ptr++ = '\n';
2925 }
2926 *ptr = '\0';
2927 data->readlen = strlen( data->rbuffer );
2928 return 0;
2929 }
2930
2931 static int proc_APList_open( struct inode *inode, struct file *file ) {
2932 struct proc_data *data;
2933 struct proc_dir_entry *dp = inode->u.generic_ip;
2934 struct net_device *dev = dp->data;
2935 struct airo_info *ai = (struct airo_info*)dev->priv;
2936 int i;
2937 char *ptr;
2938 APListRid APList_rid;
2939
2940 MOD_INC_USE_COUNT;
2941
2942 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2943
2944 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2945 return -ENOMEM;
2946 memset(file->private_data, 0, sizeof(struct proc_data));
2947 data = (struct proc_data *)file->private_data;
2948 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
2949 kfree (file->private_data);
2950 return -ENOMEM;
2951 }
2952 data->writelen = 0;
2953 data->maxwritelen = 4*6*3;
2954 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
2955 kfree (data->rbuffer);
2956 kfree (file->private_data);
2957 return -ENOMEM;
2958 }
2959 memset( data->wbuffer, 0, data->maxwritelen );
2960 data->on_close = proc_APList_on_close;
2961
2962 readAPListRid(ai, &APList_rid);
2963 ptr = data->rbuffer;
2964 for( i = 0; i < 4; i++ ) {
2965 // We end when we find a zero MAC
2966 if ( !*(int*)APList_rid.ap[i] &&
2967 !*(int*)&APList_rid.ap[i][2]) break;
2968 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n",
2969 (int)APList_rid.ap[i][0],
2970 (int)APList_rid.ap[i][1],
2971 (int)APList_rid.ap[i][2],
2972 (int)APList_rid.ap[i][3],
2973 (int)APList_rid.ap[i][4],
2974 (int)APList_rid.ap[i][5]);
2975 }
2976 if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
2977
2978 *ptr = '\0';
2979 data->readlen = strlen( data->rbuffer );
2980 return 0;
2981 }
2982
2983 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
2984 struct proc_data *data;
2985 struct proc_dir_entry *dp = inode->u.generic_ip;
2986 struct net_device *dev = dp->data;
2987 struct airo_info *ai = (struct airo_info*)dev->priv;
2988 char *ptr;
2989 BSSListRid BSSList_rid;
2990 int rc;
2991 /* If doLoseSync is not 1, we won't do a Lose Sync */
2992 int doLoseSync = -1;
2993
2994 MOD_INC_USE_COUNT;
2995
2996 dp = (struct proc_dir_entry *) inode->u.generic_ip;
2997
2998 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
2999 return -ENOMEM;
3000 memset(file->private_data, 0, sizeof(struct proc_data));
3001 data = (struct proc_data *)file->private_data;
3002 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
3003 kfree (file->private_data);
3004 return -ENOMEM;
3005 }
3006 data->writelen = 0;
3007 data->maxwritelen = 0;
3008 data->wbuffer = 0;
3009 data->on_close = 0;
3010
3011 if (file->f_mode & FMODE_WRITE) {
3012 if (!(file->f_mode & FMODE_READ)) {
3013 Cmd cmd;
3014 Resp rsp;
3015
3016 memset(&cmd, 0, sizeof(cmd));
3017 cmd.cmd=CMD_LISTBSS;
3018 issuecommand(ai, &cmd, &rsp);
3019 data->readlen = 0;
3020 return 0;
3021 }
3022 doLoseSync = 1;
3023 }
3024 ptr = data->rbuffer;
3025 /* There is a race condition here if there are concurrent opens.
3026 Since it is a rare condition, we'll just live with it, otherwise
3027 we have to add a spin lock... */
3028 rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
3029 while(rc == 0 && BSSList_rid.index != 0xffff) {
3030 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x %*s rssi = %d",
3031 (int)BSSList_rid.bssid[0],
3032 (int)BSSList_rid.bssid[1],
3033 (int)BSSList_rid.bssid[2],
3034 (int)BSSList_rid.bssid[3],
3035 (int)BSSList_rid.bssid[4],
3036 (int)BSSList_rid.bssid[5],
3037 (int)BSSList_rid.ssidLen,
3038 BSSList_rid.ssid,
3039 (int)BSSList_rid.rssi);
3040 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
3041 (int)BSSList_rid.dsChannel,
3042 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
3043 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
3044 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
3045 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
3046 rc = readBSSListRid(ai, 0, &BSSList_rid);
3047 }
3048 *ptr = '\0';
3049 data->readlen = strlen( data->rbuffer );
3050 return 0;
3051 }
3052
3053 static int proc_close( struct inode *inode, struct file *file )
3054 {
3055 struct proc_data *data = (struct proc_data *)file->private_data;
3056 if ( data->on_close != NULL ) data->on_close( inode, file );
3057 MOD_DEC_USE_COUNT;
3058 if ( data->rbuffer ) kfree( data->rbuffer );
3059 if ( data->wbuffer ) kfree( data->wbuffer );
3060 kfree( data );
3061 return 0;
3062 }
3063
3064 static struct net_device_list {
3065 struct net_device *dev;
3066 struct net_device_list *next;
3067 } *airo_devices = 0;
3068
3069 /* Since the card doesnt automatically switch to the right WEP mode,
3070 we will make it do it. If the card isn't associated, every secs we
3071 will switch WEP modes to see if that will help. If the card is
3072 associated we will check every minute to see if anything has
3073 changed. */
3074 static void timer_func( u_long data ) {
3075 struct net_device *dev = (struct net_device*)data;
3076 struct airo_info *apriv = (struct airo_info *)dev->priv;
3077 u16 linkstat = IN4500(apriv, LINKSTAT);
3078
3079 if (linkstat != 0x400 ) {
3080 /* We don't have a link so try changing the authtype */
3081 ConfigRid config = apriv->config;
3082
3083 switch(apriv->authtype) {
3084 case AUTH_ENCRYPT:
3085 /* So drop to OPEN */
3086 config.authType = AUTH_OPEN;
3087 apriv->authtype = AUTH_OPEN;
3088 break;
3089 case AUTH_SHAREDKEY:
3090 if (apriv->keyindex < auto_wep) {
3091 set_wep_key(apriv, apriv->keyindex, 0, 0, 0);
3092 config.authType = AUTH_SHAREDKEY;
3093 apriv->authtype = AUTH_SHAREDKEY;
3094 apriv->keyindex++;
3095 } else {
3096 /* Drop to ENCRYPT */
3097 apriv->keyindex = 0;
3098 set_wep_key(apriv, apriv->defindex, 0, 0, 0);
3099 config.authType = AUTH_ENCRYPT;
3100 apriv->authtype = AUTH_ENCRYPT;
3101 }
3102 break;
3103 default: /* We'll escalate to SHAREDKEY */
3104 config.authType = AUTH_SHAREDKEY;
3105 apriv->authtype = AUTH_SHAREDKEY;
3106 }
3107 checkThrottle(&config);
3108 writeConfigRid(apriv, &config);
3109
3110 /* Schedule check to see if the change worked */
3111 apriv->timer.expires = RUN_AT(HZ*3);
3112 add_timer(&apriv->timer);
3113 }
3114 }
3115
3116 static int add_airo_dev( struct net_device *dev ) {
3117 struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
3118 if ( !node )
3119 return -ENOMEM;
3120
3121 if ( auto_wep ) {
3122 struct airo_info *apriv=dev->priv;
3123 struct timer_list *timer = &apriv->timer;
3124
3125 timer->function = timer_func;
3126 timer->data = (u_long)dev;
3127 init_timer(timer);
3128 apriv->authtype = AUTH_SHAREDKEY;
3129 }
3130
3131 node->dev = dev;
3132 node->next = airo_devices;
3133 airo_devices = node;
3134
3135 return 0;
3136 }
3137
3138 static void del_airo_dev( struct net_device *dev ) {
3139 struct net_device_list **p = &airo_devices;
3140 while( *p && ( (*p)->dev != dev ) )
3141 p = &(*p)->next;
3142 if ( *p && (*p)->dev == dev )
3143 *p = (*p)->next;
3144 }
3145
3146 #ifdef CONFIG_PCI
3147 static int __devinit airo_pci_probe(struct pci_dev *pdev,
3148 const struct pci_device_id *pent)
3149 {
3150 pdev->driver_data = init_airo_card(pdev->irq,
3151 pdev->resource[2].start, 0);
3152 if (!pdev->driver_data) {
3153 return -ENODEV;
3154 }
3155 return 0;
3156 }
3157
3158 static void __devexit airo_pci_remove(struct pci_dev *pdev)
3159 {
3160 stop_airo_card(pdev->driver_data, 1);
3161 }
3162 #endif
3163
3164 static int __init airo_init_module( void )
3165 {
3166 int i, rc = 0, have_isa_dev = 0;
3167
3168 airo_entry = create_proc_entry("aironet",
3169 S_IFDIR | airo_perm,
3170 proc_root_driver);
3171 airo_entry->uid = proc_uid;
3172 airo_entry->gid = proc_gid;
3173
3174 for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
3175 printk( KERN_INFO
3176 "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n",
3177 irq[i], io[i] );
3178 if (init_airo_card( irq[i], io[i], 0 ))
3179 have_isa_dev = 1;
3180 }
3181
3182 #ifdef CONFIG_PCI
3183 printk( KERN_INFO "airo: Probing for PCI adapters\n" );
3184 rc = pci_module_init(&airo_driver);
3185 printk( KERN_INFO "airo: Finished probing for PCI adapters\n" );
3186 #endif
3187
3188 /* Always exit with success, as we are a library module
3189 * as well as a driver module
3190 */
3191 return 0;
3192 }
3193
3194 static void __exit airo_cleanup_module( void )
3195 {
3196 while( airo_devices ) {
3197 printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
3198 stop_airo_card( airo_devices->dev, 1 );
3199 }
3200 remove_proc_entry("aironet", proc_root_driver);
3201 }
3202
3203 #ifdef WIRELESS_EXT
3204 /*
3205 * Initial Wireless Extension code for Aironet driver by :
3206 * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
3207 */
3208 #ifndef IW_ENCODE_NOKEY
3209 #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
3210 #define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
3211 #endif /* IW_ENCODE_NOKEY */
3212 #endif /* WIRELESS_EXT */
3213
3214 /*
3215 * This defines the configuration part of the Wireless Extensions
3216 * Note : irq and spinlock protection will occur in the subroutines
3217 *
3218 * TODO :
3219 * o Check input value more carefully and fill correct values in range
3220 * o Implement : POWER, SPY, APLIST
3221 * o Optimise when adapter is closed (aggregate changes, commit later)
3222 * o Test and shakeout the bugs (if any)
3223 *
3224 * Jean II
3225 *
3226 * Javier Achirica did a great job of merging code from the unnamed CISCO
3227 * developer that added support for flashing the card.
3228 */
3229 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3230 {
3231 int i, rc = 0;
3232 #ifdef WIRELESS_EXT
3233 struct airo_info *local = (struct airo_info*) dev->priv;
3234 struct iwreq *wrq = (struct iwreq *) rq;
3235 ConfigRid config; /* Configuration info */
3236 CapabilityRid cap_rid; /* Card capability info */
3237 StatusRid status_rid; /* Card status info */
3238
3239 #ifdef CISCO_EXT
3240 if (cmd != SIOCGIWPRIV && cmd != AIROIOCTL && cmd != AIROIDIFC)
3241 #endif /* CISCO_EXT */
3242 {
3243 /* If the command read some stuff, we better get it out of
3244 * the card first... */
3245 if(IW_IS_GET(cmd))
3246 readStatusRid(local, &status_rid);
3247 if(IW_IS_GET(cmd) || (cmd == SIOCSIWRATE) || (cmd == SIOCSIWENCODE))
3248 readCapabilityRid(local, &cap_rid);
3249 /* Get config in all cases, because SET will just modify it */
3250 readConfigRid(local, &config);
3251 }
3252 #endif /* WIRELESS_EXT */
3253
3254 switch (cmd) {
3255 #ifdef WIRELESS_EXT
3256 // Get name
3257 case SIOCGIWNAME:
3258 strcpy(wrq->u.name, "IEEE 802.11-DS");
3259 break;
3260
3261 // Set frequency/channel
3262 case SIOCSIWFREQ:
3263 /* If setting by frequency, convert to a channel */
3264 if((wrq->u.freq.e == 1) &&
3265 (wrq->u.freq.m >= (int) 2.412e8) &&
3266 (wrq->u.freq.m <= (int) 2.487e8)) {
3267 int f = wrq->u.freq.m / 100000;
3268 int c = 0;
3269 while((c < 14) && (f != frequency_list[c]))
3270 c++;
3271 /* Hack to fall through... */
3272 wrq->u.freq.e = 0;
3273 wrq->u.freq.m = c + 1;
3274 }
3275 /* Setting by channel number */
3276 if((wrq->u.freq.m > 1000) || (wrq->u.freq.e > 0))
3277 rc = -EOPNOTSUPP;
3278 else {
3279 int channel = wrq->u.freq.m;
3280 /* We should do a better check than that,
3281 * based on the card capability !!! */
3282 if((channel < 1) || (channel > 16)) {
3283 printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, wrq->u.freq.m);
3284 rc = -EINVAL;
3285 } else {
3286 /* Yes ! We can set it !!! */
3287 config.channelSet = (u16)(channel - 1);
3288 local->need_commit = 1;
3289 }
3290 }
3291 break;
3292
3293 // Get frequency/channel
3294 case SIOCGIWFREQ:
3295 #ifdef WEXT_USECHANNELS
3296 wrq->u.freq.m = ((int)status_rid.channel) + 1;
3297 wrq->u.freq.e = 0;
3298 #else
3299 {
3300 int f = (int)status_rid.channel;
3301 wrq->u.freq.m = frequency_list[f] * 100000;
3302 wrq->u.freq.e = 1;
3303 }
3304 #endif
3305 break;
3306
3307 // Set desired network name (ESSID)
3308 case SIOCSIWESSID:
3309 if (wrq->u.data.pointer) {
3310 char essid[IW_ESSID_MAX_SIZE + 1];
3311 SsidRid SSID_rid; /* SSIDs */
3312
3313 /* Reload the list of current SSID */
3314 readSsidRid(local, &SSID_rid);
3315
3316 /* Check if we asked for `any' */
3317 if(wrq->u.data.flags == 0) {
3318 /* Just send an empty SSID list */
3319 memset(&SSID_rid, 0, sizeof(SSID_rid));
3320 } else {
3321 int index = (wrq->u.data.flags &
3322 IW_ENCODE_INDEX) - 1;
3323
3324 /* Check the size of the string */
3325 if(wrq->u.data.length > IW_ESSID_MAX_SIZE+1) {
3326 rc = -E2BIG;
3327 break;
3328 }
3329 /* Check if index is valid */
3330 if((index < 0) || (index >= 4)) {
3331 rc = -EINVAL;
3332 break;
3333 }
3334
3335 /* Set the SSID */
3336 memset(essid, 0, sizeof(essid));
3337 if (copy_from_user(essid,
3338 wrq->u.data.pointer,
3339 wrq->u.data.length)) {
3340 rc = -EFAULT;
3341 break;
3342 }
3343 memcpy(SSID_rid.ssids[index].ssid, essid,
3344 sizeof(essid) - 1);
3345 SSID_rid.ssids[index].len = wrq->u.data.length - 1;
3346 }
3347 /* Write it to the card */
3348 writeSsidRid(local, &SSID_rid);
3349 }
3350 break;
3351
3352 // Get current network name (ESSID)
3353 case SIOCGIWESSID:
3354 if (wrq->u.data.pointer) {
3355 char essid[IW_ESSID_MAX_SIZE + 1];
3356
3357 /* Note : if wrq->u.data.flags != 0, we should
3358 * get the relevant SSID from the SSID list... */
3359
3360 /* Get the current SSID */
3361 memcpy(essid, status_rid.SSID, status_rid.SSIDlen);
3362 essid[status_rid.SSIDlen] = '\0';
3363 /* If none, we may want to get the one that was set */
3364
3365 /* Push it out ! */
3366 wrq->u.data.length = strlen(essid) + 1;
3367 wrq->u.data.flags = 1; /* active */
3368 if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)))
3369 rc = -EFAULT;
3370 }
3371 break;
3372
3373 case SIOCSIWAP:
3374 if (wrq->u.ap_addr.sa_family != ARPHRD_ETHER)
3375 rc = -EINVAL;
3376 else {
3377 APListRid APList_rid;
3378
3379 memset(&APList_rid, 0, sizeof(APList_rid));
3380 APList_rid.len = sizeof(APList_rid);
3381 memcpy(APList_rid.ap[0], wrq->u.ap_addr.sa_data, 6);
3382 writeAPListRid(local, &APList_rid);
3383 local->need_commit = 1;
3384 }
3385 break;
3386
3387 // Get current Access Point (BSSID)
3388 case SIOCGIWAP:
3389 /* Tentative. This seems to work, wow, I'm lucky !!! */
3390 memcpy(wrq->u.ap_addr.sa_data, status_rid.bssid[0], 6);
3391 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
3392 break;
3393
3394 // Set desired station name
3395 case SIOCSIWNICKN:
3396 if (wrq->u.data.pointer) {
3397 char name[16 + 1];
3398
3399 /* Check the size of the string */
3400 if(wrq->u.data.length > 16 + 1) {
3401 rc = -E2BIG;
3402 break;
3403 }
3404 memset(name, 0, sizeof(name));
3405 if (copy_from_user(name, wrq->u.data.pointer,
3406 wrq->u.data.length)) {
3407 rc = -EFAULT;
3408 break;
3409 }
3410 memcpy(config.nodeName, name, 16);
3411 local->need_commit = 1;
3412 }
3413 break;
3414
3415 // Get current station name
3416 case SIOCGIWNICKN:
3417 if (wrq->u.data.pointer) {
3418 char name[IW_ESSID_MAX_SIZE + 1];
3419
3420 strncpy(name, config.nodeName, 16);
3421 name[16] = '\0';
3422 wrq->u.data.length = strlen(name) + 1;
3423 if (copy_to_user(wrq->u.data.pointer, name, sizeof(name)))
3424 rc = -EFAULT;
3425 }
3426 break;
3427
3428 // Set the desired bit-rate
3429 case SIOCSIWRATE:
3430 {
3431 /* First : get a valid bit rate value */
3432 u8 brate = 0;
3433 int i;
3434
3435 /* Which type of value ? */
3436 if((wrq->u.bitrate.value < 8) &&
3437 (wrq->u.bitrate.value >= 0)) {
3438 /* Setting by rate index */
3439 /* Find value in the magic rate table */
3440 brate = cap_rid.supportedRates[wrq->u.bitrate.value];
3441 } else {
3442 /* Setting by frequency value */
3443 u8 normvalue = (u8) (wrq->u.bitrate.value/500000);
3444
3445 /* Check if rate is valid */
3446 for(i = 0 ; i < 8 ; i++) {
3447 if(normvalue == cap_rid.supportedRates[i]) {
3448 brate = normvalue;
3449 break;
3450 }
3451 }
3452 }
3453 /* -1 designed the max rate (mostly auto mode) */
3454 if(wrq->u.bitrate.value == -1) {
3455 /* Get the highest available rate */
3456 for(i = 0 ; i < 8 ; i++) {
3457 if(cap_rid.supportedRates[i] == 0)
3458 break;
3459 }
3460 if(i != 0)
3461 brate = cap_rid.supportedRates[i - 1];
3462 }
3463 /* Check that it is valid */
3464 if(brate == 0) {
3465 rc = -EINVAL;
3466 break;
3467 }
3468
3469 /* Now, check if we want a fixed or auto value */
3470 if(wrq->u.bitrate.fixed == 0) {
3471 /* Fill all the rates up to this max rate */
3472 memset(config.rates, 0, 8);
3473 for(i = 0 ; i < 8 ; i++) {
3474 config.rates[i] = cap_rid.supportedRates[i];
3475 if(config.rates[i] == brate)
3476 break;
3477 }
3478 local->need_commit = 1;
3479 } else {
3480 /* Fixed mode */
3481 /* One rate, fixed */
3482 memset(config.rates, 0, 8);
3483 config.rates[0] = brate;
3484 local->need_commit = 1;
3485 }
3486 break;
3487 }
3488
3489 // Get the current bit-rate
3490 case SIOCGIWRATE:
3491 {
3492 int brate = status_rid.currentXmitRate;
3493 wrq->u.bitrate.value = brate * 500000;
3494 /* If more than one rate, set auto */
3495 wrq->u.rts.fixed = (config.rates[1] == 0);
3496 }
3497 break;
3498
3499 // Set the desired RTS threshold
3500 case SIOCSIWRTS:
3501 {
3502 int rthr = wrq->u.rts.value;
3503 if(wrq->u.rts.disabled)
3504 rthr = 2312;
3505 if((rthr < 0) || (rthr > 2312)) {
3506 rc = -EINVAL;
3507 } else {
3508 config.rtsThres = rthr;
3509 local->need_commit = 1;
3510 }
3511 }
3512 break;
3513
3514 // Get the current RTS threshold
3515 case SIOCGIWRTS:
3516 wrq->u.rts.value = config.rtsThres;
3517 wrq->u.rts.disabled = (wrq->u.rts.value >= 2312);
3518 wrq->u.rts.fixed = 1;
3519 break;
3520
3521 // Set the desired fragmentation threshold
3522 case SIOCSIWFRAG:
3523 {
3524 int fthr = wrq->u.frag.value;
3525 if(wrq->u.frag.disabled)
3526 fthr = 2312;
3527 if((fthr < 256) || (fthr > 2312)) {
3528 rc = -EINVAL;
3529 } else {
3530 fthr &= ~0x1; /* Get an even value */
3531 config.fragThresh = (u16)fthr;
3532 local->need_commit = 1;
3533 }
3534 }
3535 break;
3536
3537 // Get the current fragmentation threshold
3538 case SIOCGIWFRAG:
3539 wrq->u.frag.value = config.fragThresh;
3540 wrq->u.frag.disabled = (wrq->u.frag.value >= 2312);
3541 wrq->u.frag.fixed = 1;
3542 break;
3543
3544 // Set mode of operation
3545 case SIOCSIWMODE:
3546 switch(wrq->u.mode) {
3547 case IW_MODE_ADHOC:
3548 config.opmode = MODE_STA_IBSS;
3549 local->need_commit = 1;
3550 break;
3551 case IW_MODE_INFRA:
3552 config.opmode = MODE_STA_ESS;
3553 local->need_commit = 1;
3554 break;
3555 case IW_MODE_MASTER:
3556 config.opmode = MODE_AP;
3557 local->need_commit = 1;
3558 break;
3559 case IW_MODE_REPEAT:
3560 config.opmode = MODE_AP_RPTR;
3561 local->need_commit = 1;
3562 break;
3563 default:
3564 rc = -EINVAL;
3565 }
3566 break;
3567
3568 // Get mode of operation
3569 case SIOCGIWMODE:
3570 /* If not managed, assume it's ad-hoc */
3571 switch (config.opmode & 0xFF) {
3572 case MODE_STA_ESS:
3573 wrq->u.mode = IW_MODE_INFRA;
3574 break;
3575 case MODE_AP:
3576 wrq->u.mode = IW_MODE_MASTER;
3577 break;
3578 case MODE_AP_RPTR:
3579 wrq->u.mode = IW_MODE_REPEAT;
3580 break;
3581 default:
3582 wrq->u.mode = IW_MODE_ADHOC;
3583 }
3584 break;
3585
3586 // Set WEP keys and mode
3587 case SIOCSIWENCODE:
3588 /* Is WEP supported ? */
3589 /* Older firmware doesn't support this...
3590 if(!(cap_rid.softCap & 2)) {
3591 rc = -EOPNOTSUPP;
3592 break;
3593 } */
3594 /* Basic checking: do we have a key to set ? */
3595 if (wrq->u.encoding.pointer != (caddr_t) 0) {
3596 wep_key_t key;
3597 int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
3598 int current_index = get_wep_key(local, 0xffff);
3599 /* Check the size of the key */
3600 if (wrq->u.encoding.length > MAX_KEY_SIZE) {
3601 rc = -EINVAL;
3602 break;
3603 }
3604 /* Check the index (none -> use current) */
3605 if ((index < 0) || (index>=(cap_rid.softCap&0x80)?4:1))
3606 index = current_index;
3607 /* Set the length */
3608 if (wrq->u.encoding.length > MIN_KEY_SIZE)
3609 key.len = MAX_KEY_SIZE;
3610 else
3611 if (wrq->u.encoding.length > 0)
3612 key.len = MIN_KEY_SIZE;
3613 else
3614 /* Disable the key */
3615 key.len = 0;
3616 /* Check if the key is not marked as invalid */
3617 if(!(wrq->u.encoding.flags & IW_ENCODE_NOKEY)) {
3618 /* Cleanup */
3619 memset(key.key, 0, MAX_KEY_SIZE);
3620 /* Copy the key in the driver */
3621 if(copy_from_user(key.key,
3622 wrq->u.encoding.pointer,
3623 wrq->u.encoding.length)) {
3624 key.len = 0;
3625 rc = -EFAULT;
3626 break;
3627 }
3628 /* Send the key to the card */
3629 set_wep_key(local, index, key.key,
3630 key.len, 1);
3631 }
3632 /* WE specify that if a valid key is set, encryption
3633 * should be enabled (user may turn it off later)
3634 * This is also how "iwconfig ethX key on" works */
3635 if((index == current_index) && (key.len > 0) &&
3636 (config.authType == AUTH_OPEN)) {
3637 config.authType = AUTH_ENCRYPT;
3638 local->need_commit = 1;
3639 }
3640 } else {
3641 /* Do we want to just set the transmit key index ? */
3642 int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
3643 if ((index>=0) && (index<(cap_rid.softCap&0x80)?4:1)) {
3644 set_wep_key(local, index, 0, 0, 1);
3645 } else
3646 /* Don't complain if only change the mode */
3647 if(!wrq->u.encoding.flags & IW_ENCODE_MODE) {
3648 rc = -EINVAL;
3649 break;
3650 }
3651 }
3652 /* Read the flags */
3653 if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)
3654 config.authType = AUTH_OPEN; // disable encryption
3655 if(wrq->u.encoding.flags & IW_ENCODE_RESTRICTED)
3656 config.authType = AUTH_SHAREDKEY; // Only Both
3657 if(wrq->u.encoding.flags & IW_ENCODE_OPEN)
3658 config.authType = AUTH_ENCRYPT; // Only Wep
3659 /* Commit the changes if needed */
3660 if(wrq->u.encoding.flags & IW_ENCODE_MODE)
3661 local->need_commit = 1;
3662 break;
3663
3664 // Get the WEP keys and mode
3665 case SIOCGIWENCODE:
3666 /* Is it supported ? */
3667 if(!(cap_rid.softCap & 2)) {
3668 rc = -EOPNOTSUPP;
3669 break;
3670 }
3671 // Only super-user can see WEP key
3672 if (!capable(CAP_NET_ADMIN)) {
3673 rc = -EPERM;
3674 break;
3675 }
3676
3677 // Basic checking...
3678 if (wrq->u.encoding.pointer != (caddr_t) 0) {
3679 char zeros[16];
3680 int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
3681
3682 memset(zeros,0, sizeof(zeros));
3683 /* Check encryption mode */
3684 wrq->u.encoding.flags = IW_ENCODE_NOKEY;
3685 /* Is WEP enabled ??? */
3686 switch(config.authType) {
3687 case AUTH_ENCRYPT:
3688 wrq->u.encoding.flags |= IW_ENCODE_OPEN;
3689 break;
3690 case AUTH_SHAREDKEY:
3691 wrq->u.encoding.flags |= IW_ENCODE_RESTRICTED;
3692 break;
3693 default:
3694 case AUTH_OPEN:
3695 wrq->u.encoding.flags |= IW_ENCODE_DISABLED;
3696 break;
3697 }
3698
3699 /* Which key do we want ? -1 -> tx index */
3700 if((index < 0) || (index >= (cap_rid.softCap&0x80)?4:1))
3701 index = get_wep_key(local, 0xffff);
3702 wrq->u.encoding.flags |= index + 1;
3703 /* Copy the key to the user buffer */
3704 wrq->u.encoding.length = get_wep_key(local, index);
3705 if (wrq->u.encoding.length > 16) {
3706 wrq->u.encoding.length=0;
3707 }
3708
3709 if(copy_to_user(wrq->u.encoding.pointer, zeros,
3710 wrq->u.encoding.length))
3711 rc = -EFAULT;
3712 }
3713 break;
3714
3715 #if WIRELESS_EXT > 9
3716 // Get the current Tx-Power
3717 case SIOCGIWTXPOW:
3718 wrq->u.txpower.value = config.txPower;
3719 wrq->u.txpower.fixed = 1; /* No power control */
3720 wrq->u.txpower.disabled = (local->flags & FLAG_RADIO_OFF);
3721 wrq->u.txpower.flags = IW_TXPOW_MWATT;
3722 break;
3723 case SIOCSIWTXPOW:
3724 if (wrq->u.txpower.disabled) {
3725 local->flags |= FLAG_RADIO_OFF;
3726 local->need_commit = 1;
3727 break;
3728 }
3729 if (wrq->u.txpower.flags != IW_TXPOW_MWATT) {
3730 rc = -EINVAL;
3731 break;
3732 }
3733 local->flags &= ~FLAG_RADIO_OFF;
3734 rc = -EINVAL;
3735 for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
3736 if ((wrq->u.txpower.value==cap_rid.txPowerLevels[i])) {
3737 config.txPower = wrq->u.txpower.value;
3738 local->need_commit = 1;
3739 rc = 0;
3740 break;
3741 }
3742 break;
3743 #endif /* WIRELESS_EXT > 9 */
3744
3745 #if WIRELESS_EXT > 10
3746 case SIOCSIWRETRY:
3747 if(wrq->u.retry.disabled) {
3748 rc = -EINVAL;
3749 break;
3750 }
3751 local->need_commit = 0;
3752 if(wrq->u.retry.flags & IW_RETRY_LIMIT) {
3753 if(wrq->u.retry.flags & IW_RETRY_MAX)
3754 config.longRetryLimit = wrq->u.retry.value;
3755 else if (wrq->u.retry.flags & IW_RETRY_MIN)
3756 config.shortRetryLimit = wrq->u.retry.value;
3757 else {
3758 /* No modifier : set both */
3759 config.longRetryLimit = wrq->u.retry.value;
3760 config.shortRetryLimit = wrq->u.retry.value;
3761 }
3762 local->need_commit = 1;
3763 }
3764 if(wrq->u.retry.flags & IW_RETRY_LIFETIME) {
3765 config.txLifetime = wrq->u.retry.value / 1024;
3766 local->need_commit = 1;
3767 }
3768 if(local->need_commit == 0) {
3769 rc = -EINVAL;
3770 }
3771 break;
3772
3773 case SIOCGIWRETRY:
3774 wrq->u.retry.disabled = 0; /* Can't be disabled */
3775
3776 /* Note : by default, display the min retry number */
3777 if((wrq->u.retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
3778 wrq->u.retry.flags = IW_RETRY_LIFETIME;
3779 wrq->u.retry.value = (int)config.txLifetime * 1024;
3780 } else if((wrq->u.retry.flags & IW_RETRY_MAX)) {
3781 wrq->u.retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
3782 wrq->u.retry.value = (int)config.longRetryLimit;
3783 } else {
3784 wrq->u.retry.flags = IW_RETRY_LIMIT;
3785 wrq->u.retry.value = (int)config.shortRetryLimit;
3786 if((int)config.shortRetryLimit != (int)config.longRetryLimit)
3787 wrq->u.retry.flags |= IW_RETRY_MIN;
3788 }
3789
3790 break;
3791 #endif /* WIRELESS_EXT > 10 */
3792
3793 // Get range of parameters
3794 case SIOCGIWRANGE:
3795 if (wrq->u.data.pointer) {
3796 struct iw_range range;
3797 int i;
3798 int k;
3799
3800 wrq->u.data.length = sizeof(range);
3801 memset(&range, 0, sizeof(range));
3802 range.min_nwid = 0x0000;
3803 range.max_nwid = 0x0000;
3804 range.num_channels = 14;
3805 /* Should be based on cap_rid.country to give only
3806 * what the current card support */
3807 k = 0;
3808 for(i = 0; i < 14; i++) {
3809 range.freq[k].i = i + 1; /* List index */
3810 range.freq[k].m = frequency_list[i] * 100000;
3811 range.freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
3812 }
3813 range.num_frequency = k;
3814
3815 /* Hum... Should put the right values there */
3816 range.max_qual.qual = 10;
3817 range.max_qual.level = 100;
3818 range.max_qual.noise = 0;
3819 range.sensitivity = 65535;
3820
3821 for(i = 0 ; i < 8 ; i++) {
3822 range.bitrate[i] = cap_rid.supportedRates[i] * 500000;
3823 if(range.bitrate[i] == 0)
3824 break;
3825 }
3826 range.num_bitrates = i;
3827
3828 /* Set an indication of the max TCP throughput
3829 * in bit/s that we can expect using this interface.
3830 * May be use for QoS stuff... Jean II */
3831 if(i > 2)
3832 range.throughput = 5 * 1000 * 1000;
3833 else
3834 range.throughput = 1.5 * 1000 * 1000;
3835
3836 range.min_rts = 0;
3837 range.max_rts = 2312;
3838 range.min_frag = 256;
3839 range.max_frag = 2312;
3840
3841 if(cap_rid.softCap & 2) {
3842 // WEP: RC4 40 bits
3843 range.encoding_size[0] = 5;
3844 // RC4 ~128 bits
3845 if (cap_rid.softCap & 0x100) {
3846 range.encoding_size[1] = 13;
3847 range.num_encoding_sizes = 2;
3848 } else
3849 range.num_encoding_sizes = 1;
3850 range.max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1;
3851 } else {
3852 range.num_encoding_sizes = 0;
3853 range.max_encoding_tokens = 0;
3854 }
3855 #if WIRELESS_EXT > 9
3856 range.min_pmp = 0;
3857 range.max_pmp = 5000000; /* 5 secs */
3858 range.min_pmt = 0;
3859 range.max_pmt = 65535 * 1024; /* ??? */
3860 range.pmp_flags = IW_POWER_PERIOD;
3861 range.pmt_flags = IW_POWER_TIMEOUT;
3862 range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
3863
3864 /* Transmit Power - values are in mW */
3865 for(i = 0 ; i < 8 ; i++) {
3866 range.txpower[i] = cap_rid.txPowerLevels[i];
3867 if(range.txpower[i] == 0)
3868 break;
3869 }
3870 range.num_txpower = i;
3871 range.txpower_capa = IW_TXPOW_MWATT;
3872 #endif /* WIRELESS_EXT > 9 */
3873 #if WIRELESS_EXT > 10
3874 range.we_version_source = 11;
3875 range.we_version_compiled = WIRELESS_EXT;
3876 range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
3877 range.retry_flags = IW_RETRY_LIMIT;
3878 range.r_time_flags = IW_RETRY_LIFETIME;
3879 range.min_retry = 1;
3880 range.max_retry = 65535;
3881 range.min_r_time = 1024;
3882 range.max_r_time = 65535 * 1024;
3883 #endif /* WIRELESS_EXT > 10 */
3884
3885 if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
3886 rc = -EFAULT;
3887 }
3888 break;
3889
3890 case SIOCGIWPOWER:
3891 {
3892 int mode = config.powerSaveMode;
3893 if ((wrq->u.power.disabled = (mode == POWERSAVE_CAM)))
3894 break;
3895 if ((wrq->u.power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3896 wrq->u.power.value = (int)config.fastListenDelay * 1024;
3897 wrq->u.power.flags = IW_POWER_TIMEOUT;
3898 } else {
3899 wrq->u.power.value = (int)config.fastListenInterval * 1024;
3900 wrq->u.power.flags = IW_POWER_PERIOD;
3901 }
3902 if ((config.rmode & 0xFF) == RXMODE_ADDR)
3903 wrq->u.power.flags |= IW_POWER_UNICAST_R;
3904 else
3905 wrq->u.power.flags |= IW_POWER_ALL_R;
3906 }
3907 break;
3908
3909 case SIOCSIWPOWER:
3910 if (wrq->u.power.disabled) {
3911 if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
3912 rc = -EINVAL;
3913 break;
3914 }
3915 config.powerSaveMode = POWERSAVE_CAM;
3916 config.rmode &= 0xFF00;
3917 config.rmode |= RXMODE_BC_MC_ADDR;
3918 local->need_commit = 1;
3919 break;
3920 }
3921 if ((wrq->u.power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3922 config.fastListenDelay = (wrq->u.power.value + 500) / 1024;
3923 config.powerSaveMode = POWERSAVE_PSPCAM;
3924 local->need_commit = 1;
3925 } else if ((wrq->u.power.flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
3926 config.fastListenInterval = config.listenInterval = (wrq->u.power.value + 500) / 1024;
3927 config.powerSaveMode = POWERSAVE_PSPCAM;
3928 local->need_commit = 1;
3929 }
3930 switch (wrq->u.power.flags & IW_POWER_MODE) {
3931 case IW_POWER_UNICAST_R:
3932 if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
3933 rc = -EINVAL;
3934 break;
3935 }
3936 config.rmode &= 0xFF00;
3937 config.rmode |= RXMODE_ADDR;
3938 local->need_commit = 1;
3939 break;
3940 case IW_POWER_ALL_R:
3941 if ((config.rmode & 0xFF) >= RXMODE_RFMON) {
3942 rc = -EINVAL;
3943 break;
3944 }
3945 config.rmode &= 0xFF00;
3946 config.rmode |= RXMODE_BC_MC_ADDR;
3947 local->need_commit = 1;
3948 case IW_POWER_ON:
3949 break;
3950 default:
3951 rc = -EINVAL;
3952 }
3953 break;
3954
3955 case SIOCGIWSENS:
3956 wrq->u.sens.value = config.rssiThreshold;
3957 wrq->u.sens.disabled = (wrq->u.sens.value == 0);
3958 wrq->u.sens.fixed = 1;
3959 break;
3960
3961 case SIOCSIWSENS:
3962 config.rssiThreshold = wrq->u.sens.disabled ? RSSI_DEFAULT : wrq->u.sens.value;
3963 local->need_commit = 1;
3964 break;
3965
3966 case SIOCGIWAPLIST:
3967 if (wrq->u.data.pointer) {
3968 int i, rc;
3969 struct sockaddr s[IW_MAX_AP];
3970 struct iw_quality qual[IW_MAX_AP];
3971 BSSListRid BSSList;
3972 int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
3973 for (i = 0; i < IW_MAX_AP; i++) {
3974 if (readBSSListRid(local, loseSync, &BSSList))
3975 break;
3976 loseSync = 0;
3977 memcpy(s[i].sa_data, BSSList.bssid, 6);
3978 s[i].sa_family = ARPHRD_ETHER;
3979 qual[i].level = BSSList.rssi;
3980 qual[i].qual = qual[i].noise = 0;
3981 qual[i].updated = 2;
3982 if (BSSList.index == 0xffff) break;
3983 }
3984 if (!i) {
3985 for (i = 0;
3986 i < min(IW_MAX_AP, 4) &&
3987 (status_rid.bssid[i][0]
3988 & status_rid.bssid[i][1]
3989 & status_rid.bssid[i][2]
3990 & status_rid.bssid[i][3]
3991 & status_rid.bssid[i][4]
3992 & status_rid.bssid[i][5])!=-1 &&
3993 (status_rid.bssid[i][0]
3994 | status_rid.bssid[i][1]
3995 | status_rid.bssid[i][2]
3996 | status_rid.bssid[i][3]
3997 | status_rid.bssid[i][4]
3998 | status_rid.bssid[i][5]);
3999 i++) {
4000 memcpy(s[i].sa_data,
4001 status_rid.bssid[i], 6);
4002 s[i].sa_family = ARPHRD_ETHER;
4003 }
4004 } else {
4005 wrq->u.data.flags = 1; /* Should be define'd */
4006 if (copy_to_user(wrq->u.data.pointer
4007 + sizeof(struct sockaddr)*i,
4008 &qual,
4009 sizeof(struct iw_quality)*i))
4010 rc = -EFAULT;
4011 }
4012 wrq->u.data.length = i;
4013 if (copy_to_user(wrq->u.data.pointer, &s,
4014 sizeof(struct sockaddr)*i))
4015 rc = -EFAULT;
4016 }
4017 break;
4018
4019 #ifdef WIRELESS_SPY
4020 // Set the spy list
4021 case SIOCSIWSPY:
4022 if (wrq->u.data.length > IW_MAX_SPY)
4023 {
4024 rc = -E2BIG;
4025 break;
4026 }
4027 local->spy_number = wrq->u.data.length;
4028 if (local->spy_number > 0)
4029 {
4030 struct sockaddr address[IW_MAX_SPY];
4031 int i;
4032
4033 if (copy_from_user(address, wrq->u.data.pointer,
4034 sizeof(struct sockaddr) * local->spy_number)) {
4035 rc = -EFAULT;
4036 break;
4037 }
4038 for (i=0; i<local->spy_number; i++)
4039 memcpy(local->spy_address[i], address[i].sa_data, 6);
4040 memset(local->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
4041 }
4042 break;
4043
4044 // Get the spy list
4045 case SIOCGIWSPY:
4046 wrq->u.data.length = local->spy_number;
4047 if ((local->spy_number > 0) && (wrq->u.data.pointer))
4048 {
4049 struct sockaddr address[IW_MAX_SPY];
4050 int i;
4051 rc = verify_area(VERIFY_WRITE, wrq->u.data.pointer, (sizeof(struct iw_quality)+sizeof(struct sockaddr)) * IW_MAX_SPY);
4052 if (rc)
4053 break;
4054 for (i=0; i<local->spy_number; i++)
4055 {
4056 memcpy(address[i].sa_data, local->spy_address[i], 6);
4057 address[i].sa_family = AF_UNIX;
4058 }
4059 if (copy_to_user(wrq->u.data.pointer, address, sizeof(struct sockaddr) * local->spy_number)) {
4060 rc = -EFAULT;
4061 break;
4062 }
4063 if (copy_to_user(wrq->u.data.pointer + (sizeof(struct sockaddr)*local->spy_number), local->spy_stat, sizeof(struct iw_quality) * local->spy_number)) {
4064 rc = -EFAULT;
4065 break;
4066 }
4067 for (i=0; i<local->spy_number; i++)
4068 local->spy_stat[i].updated = 0;
4069 }
4070 break;
4071 #endif /* WIRELESS_SPY */
4072
4073 #ifdef CISCO_EXT
4074 case SIOCGIWPRIV:
4075 if(wrq->u.data.pointer)
4076 {
4077 struct iw_priv_args priv[] =
4078 { /* cmd, set_args, get_args, name */
4079 { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl), IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
4080 { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl), IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
4081 };
4082
4083 /* Set the number of ioctl available */
4084 wrq->u.data.length = 2;
4085
4086 /* Copy structure to the user buffer */
4087 if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
4088 sizeof(priv)))
4089 rc = -EFAULT;
4090 }
4091 break;
4092 #endif /* CISCO_EXT */
4093 #endif /* WIRELESS_EXT */
4094
4095 #ifdef CISCO_EXT
4096 case AIROIDIFC:
4097 {
4098 int val = AIROMAGIC;
4099 aironet_ioctl com;
4100 if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
4101 rc = -EFAULT;
4102 else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
4103 rc = -EFAULT;
4104 }
4105 break;
4106
4107 case AIROIOCTL:
4108 /* Get the command struct and hand it off for evaluation by
4109 * the proper subfunction
4110 */
4111 {
4112 aironet_ioctl com;
4113 if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
4114 rc = -EFAULT;
4115 break;
4116 }
4117
4118 /* Seperate R/W functions bracket legality here
4119 */
4120 if ( com.command <= AIROGSTATSD32 )
4121 rc = readrids(dev,&com);
4122 else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR )
4123 rc = writerids(dev,&com);
4124 else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
4125 rc = flashcard(dev,&com);
4126 else
4127 rc = -EINVAL; /* Bad command in ioctl */
4128 }
4129 break;
4130 #endif /* CISCO_EXT */
4131
4132 // All other calls are currently unsupported
4133 default:
4134 rc = -EOPNOTSUPP;
4135 }
4136
4137 #ifdef WIRELESS_EXT
4138 /* Some of the "SET" function may have modified some of the
4139 * parameters. It's now time to commit them in the card */
4140 if(local->need_commit) {
4141 /* A classical optimisation here is to not commit any change
4142 * if the card is not "opened". This is what we do in
4143 * wvlan_cs (see for details).
4144 * For that, we would need to have the config RID saved in
4145 * the airo_info struct and make sure to not re-read it if
4146 * local->need_commit != 0. Then, you need to patch "open"
4147 * to do the final commit of all parameters...
4148 * Jean II */
4149 Resp rsp;
4150
4151 disable_MAC(local);
4152 local->config = config; /* ???? config is local !!! */
4153 checkThrottle(&config);
4154 writeConfigRid(local, &config);
4155 enable_MAC(local, &rsp);
4156
4157 local->need_commit = 0;
4158 }
4159 #endif /* WIRELESS_EXT */
4160
4161 return(rc);
4162 }
4163
4164 #ifdef WIRELESS_EXT
4165 /*
4166 * Get the Wireless stats out of the driver
4167 * Note : irq and spinlock protection will occur in the subroutines
4168 *
4169 * TODO :
4170 * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
4171 * o Find the noise level
4172 * o Convert values to dBm
4173 * o Fill out discard.misc with something interesting
4174 *
4175 * Jean
4176 */
4177 struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
4178 {
4179 struct airo_info *local = (struct airo_info*) dev->priv;
4180 StatusRid status_rid;
4181 StatsRid stats_rid;
4182 int *vals = stats_rid.vals;
4183
4184 /* Get stats out of the card */
4185 readStatusRid(local, &status_rid);
4186 readStatsRid(local, &stats_rid, RID_STATS);
4187
4188 /* The status */
4189 local->wstats.status = status_rid.mode;
4190
4191 /* Signal quality and co. But where is the noise level ??? */
4192 local->wstats.qual.qual = status_rid.signalQuality;
4193 local->wstats.qual.level = status_rid.normalizedSignalStrength;
4194 local->wstats.qual.noise = 0;
4195 local->wstats.qual.updated = 3;
4196
4197 /* Packets discarded in the wireless adapter due to wireless
4198 * specific problems */
4199 local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
4200 local->wstats.discard.code = vals[6];/* RxWepErr */
4201 local->wstats.discard.misc = vals[1] + vals[2] + vals[3] + vals[4] + vals[30] + vals[32];
4202 return (&local->wstats);
4203 }
4204 #endif /* WIRELESS_EXT */
4205
4206 #ifdef CISCO_EXT
4207 /*
4208 * This just translates from driver IOCTL codes to the command codes to
4209 * feed to the radio's host interface. Things can be added/deleted
4210 * as needed. This represents the READ side of control I/O to
4211 * the card
4212 */
4213 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
4214 unsigned short ridcode;
4215 unsigned char iobuf[2048];
4216
4217 switch(comp->command)
4218 {
4219 case AIROGCAP: ridcode = RID_CAPABILITIES; break;
4220 case AIROGCFG: ridcode = RID_CONFIG; break;
4221 case AIROGSLIST: ridcode = RID_SSID; break;
4222 case AIROGVLIST: ridcode = RID_APLIST; break;
4223 case AIROGDRVNAM: ridcode = RID_DRVNAME; break;
4224 case AIROGEHTENC: ridcode = RID_ETHERENCAP; break;
4225 case AIROGWEPKTMP: ridcode = RID_WEP_TEMP;
4226 /* Only super-user can read WEP keys */
4227 if (!capable(CAP_NET_ADMIN))
4228 return -EPERM;
4229 break;
4230 case AIROGWEPKNV: ridcode = RID_WEP_PERM;
4231 /* Only super-user can read WEP keys */
4232 if (!capable(CAP_NET_ADMIN))
4233 return -EPERM;
4234 break;
4235 case AIROGSTAT: ridcode = RID_STATUS; break;
4236 case AIROGSTATSD32: ridcode = RID_STATSDELTA; break;
4237 case AIROGSTATSC32: ridcode = RID_STATS; break;
4238 default:
4239 return -EINVAL;
4240 break;
4241 }
4242
4243 PC4500_readrid((struct airo_info *)dev->priv,ridcode,iobuf,sizeof(iobuf));
4244 /* get the count of bytes in the rid docs say 1st 2 bytes is it.
4245 * then return it to the user
4246 * 9/22/2000 Honor user given length
4247 */
4248
4249 if (copy_to_user(comp->data, iobuf,
4250 min_t(unsigned int, comp->len, sizeof(iobuf))))
4251 return -EFAULT;
4252 return 0;
4253 }
4254
4255 /*
4256 * Danger Will Robinson write the rids here
4257 */
4258
4259 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
4260 int ridcode;
4261 Resp rsp;
4262 static int (* writer)(struct airo_info *, u16 rid, const void *, int);
4263 unsigned char iobuf[2048];
4264
4265 /* Only super-user can write RIDs */
4266 if (!capable(CAP_NET_ADMIN))
4267 return -EPERM;
4268
4269 ridcode = 0;
4270 writer = do_writerid;
4271
4272 switch(comp->command)
4273 {
4274 case AIROPSIDS: ridcode = RID_SSID; break;
4275 case AIROPCAP: ridcode = RID_CAPABILITIES; break;
4276 case AIROPAPLIST: ridcode = RID_APLIST; break;
4277 case AIROPCFG: ridcode = RID_CONFIG; break;
4278 case AIROPWEPKEYNV: ridcode = RID_WEP_PERM; break;
4279 case AIROPLEAPUSR: ridcode = RID_LEAPUSERNAME; break;
4280 case AIROPLEAPPWD: ridcode = RID_LEAPPASSWORD; break;
4281 case AIROPWEPKEY: ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
4282 break;
4283
4284 /* this is not really a rid but a command given to the card
4285 * same with MAC off
4286 */
4287 case AIROPMACON:
4288 if (enable_MAC(dev->priv, &rsp) != 0)
4289 return -EIO;
4290 return 0;
4291
4292 /*
4293 * Evidently this code in the airo driver does not get a symbol
4294 * as disable_MAC. it's probably so short the compiler does not gen one.
4295 */
4296 case AIROPMACOFF:
4297 disable_MAC(dev->priv);
4298 return 0;
4299
4300 /* This command merely clears the counts does not actually store any data
4301 * only reads rid. But as it changes the cards state, I put it in the
4302 * writerid routines.
4303 */
4304 case AIROPSTCLR:
4305 ridcode = RID_STATSDELTACLEAR;
4306
4307 PC4500_readrid(dev->priv,ridcode,iobuf,sizeof(iobuf));
4308
4309 if (copy_to_user(comp->data, iobuf,
4310 min_t(unsigned int, comp->len, sizeof(iobuf))))
4311 return -EFAULT;
4312 return 0;
4313
4314 default:
4315 return -EOPNOTSUPP; /* Blarg! */
4316 }
4317 if(comp->len > sizeof(iobuf))
4318 return -EINVAL;
4319
4320 if (copy_from_user(iobuf,comp->data,comp->len))
4321 return -EFAULT;
4322 if((*writer)((struct airo_info *)dev->priv, ridcode, iobuf,comp->len))
4323 return -EIO;
4324 return 0;
4325 }
4326
4327 /*****************************************************************************
4328 * Ancillary flash / mod functions much black magic lurkes here *
4329 *****************************************************************************
4330 */
4331
4332 /*
4333 * Flash command switch table
4334 */
4335
4336 int flashcard(struct net_device *dev, aironet_ioctl *comp) {
4337 int z;
4338 int cmdreset(struct airo_info *);
4339 int setflashmode(struct airo_info *);
4340 int flashgchar(struct airo_info *,int,int);
4341 int flashpchar(struct airo_info *,int,int);
4342 int flashputbuf(struct airo_info *);
4343 int flashrestart(struct airo_info *,struct net_device *);
4344
4345 /* Only super-user can modify flash */
4346 if (!capable(CAP_NET_ADMIN))
4347 return -EPERM;
4348
4349 switch(comp->command)
4350 {
4351 case AIROFLSHRST:
4352 return cmdreset((struct airo_info *)dev->priv);
4353
4354 case AIROFLSHSTFL:
4355 if (!((struct airo_info *)dev->priv)->flash &&
4356 (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
4357 return -ENOMEM;
4358 return setflashmode((struct airo_info *)dev->priv);
4359
4360 case AIROFLSHGCHR: /* Get char from aux */
4361 if(comp->len != sizeof(int))
4362 return -EINVAL;
4363 if (copy_from_user(&z,comp->data,comp->len))
4364 return -EFAULT;
4365 return flashgchar((struct airo_info *)dev->priv,z,8000);
4366
4367 case AIROFLSHPCHR: /* Send char to card. */
4368 if(comp->len != sizeof(int))
4369 return -EINVAL;
4370 if (copy_from_user(&z,comp->data,comp->len))
4371 return -EFAULT;
4372 return flashpchar((struct airo_info *)dev->priv,z,8000);
4373
4374 case AIROFLPUTBUF: /* Send 32k to card */
4375 if (!((struct airo_info *)dev->priv)->flash)
4376 return -ENOMEM;
4377 if(comp->len > FLASHSIZE)
4378 return -EINVAL;
4379 if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
4380 return -EFAULT;
4381
4382 flashputbuf((struct airo_info *)dev->priv);
4383 return 0;
4384
4385 case AIRORESTART:
4386 if(flashrestart((struct airo_info *)dev->priv,dev))
4387 return -EIO;
4388 return 0;
4389 }
4390 return -EINVAL;
4391 }
4392
4393 #define FLASH_COMMAND 0x7e7e
4394
4395 /*
4396 * STEP 1)
4397 * Disable MAC and do soft reset on
4398 * card.
4399 */
4400
4401 int cmdreset(struct airo_info *ai) {
4402 disable_MAC(ai);
4403
4404 if(!waitbusy (ai)){
4405 printk(KERN_INFO "Waitbusy hang before RESET\n");
4406 return -EBUSY;
4407 }
4408
4409 OUT4500(ai,COMMAND,CMD_SOFTRESET);
4410
4411 set_current_state (TASK_UNINTERRUPTIBLE);
4412 schedule_timeout (HZ); /* WAS 600 12/7/00 */
4413
4414 if(!waitbusy (ai)){
4415 printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
4416 return -EBUSY;
4417 }
4418 return 0;
4419 }
4420
4421 /* STEP 2)
4422 * Put the card in legendary flash
4423 * mode
4424 */
4425
4426 int setflashmode (struct airo_info *ai) {
4427 OUT4500(ai, SWS0, FLASH_COMMAND);
4428 OUT4500(ai, SWS1, FLASH_COMMAND);
4429 OUT4500(ai, SWS0, FLASH_COMMAND);
4430 OUT4500(ai, COMMAND,0x10);
4431 set_current_state (TASK_UNINTERRUPTIBLE);
4432 schedule_timeout (HZ/2); /* 500ms delay */
4433
4434 if(!waitbusy(ai)) {
4435 printk(KERN_INFO "Waitbusy hang after setflash mode\n");
4436 return -EIO;
4437 }
4438 return 0;
4439 }
4440
4441 /* Put character to SWS0 wait for dwelltime
4442 * x 50us for echo .
4443 */
4444
4445 int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
4446 int echo;
4447 int waittime;
4448
4449 byte |= 0x8000;
4450
4451 if(dwelltime == 0 )
4452 dwelltime = 200;
4453
4454 waittime=dwelltime;
4455
4456 /* Wait for busy bit d15 to go false indicating buffer empty */
4457 while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
4458 udelay (50);
4459 waittime -= 50;
4460 }
4461
4462 /* timeout for busy clear wait */
4463 if(waittime <= 0 ){
4464 printk(KERN_INFO "flash putchar busywait timeout! \n");
4465 return -EBUSY;
4466 }
4467
4468 /* Port is clear now write byte and wait for it to echo back */
4469 do {
4470 OUT4500(ai,SWS0,byte);
4471 udelay(50);
4472 dwelltime -= 50;
4473 echo = IN4500(ai,SWS1);
4474 } while (dwelltime >= 0 && echo != byte);
4475
4476 OUT4500(ai,SWS1,0);
4477
4478 return (echo == byte) ? 0 : -EIO;
4479 }
4480
4481 /*
4482 * Get a character from the card matching matchbyte
4483 * Step 3)
4484 */
4485 int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
4486 int rchar;
4487 unsigned char rbyte=0;
4488
4489 do {
4490 rchar = IN4500(ai,SWS1);
4491
4492 if(dwelltime && !(0x8000 & rchar)){
4493 dwelltime -= 10;
4494 mdelay(10);
4495 continue;
4496 }
4497 rbyte = 0xff & rchar;
4498
4499 if( (rbyte == matchbyte) && (0x8000 & rchar) ){
4500 OUT4500(ai,SWS1,0);
4501 return 0;
4502 }
4503 if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
4504 break;
4505 OUT4500(ai,SWS1,0);
4506
4507 }while(dwelltime > 0);
4508 return -EIO;
4509 }
4510
4511 /*
4512 * Transfer 32k of firmware data from user buffer to our buffer and
4513 * send to the card
4514 */
4515
4516 int flashputbuf(struct airo_info *ai){
4517 int nwords;
4518
4519 /* Write stuff */
4520 OUT4500(ai,AUXPAGE,0x100);
4521 OUT4500(ai,AUXOFF,0);
4522
4523 for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
4524 OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
4525 }
4526
4527 OUT4500(ai,SWS0,0x8000);
4528
4529 return 0;
4530 }
4531
4532 /*
4533 *
4534 */
4535 int flashrestart(struct airo_info *ai,struct net_device *dev){
4536 int i,status;
4537
4538 set_current_state (TASK_UNINTERRUPTIBLE);
4539 schedule_timeout (HZ); /* Added 12/7/00 */
4540 status = setup_card(ai, dev->dev_addr,&((struct airo_info*)dev->priv)->config);
4541
4542 for( i = 0; i < MAX_FIDS; i++ ) {
4543 ai->fids[i] = transmit_allocate( ai, 2312 );
4544 }
4545
4546 set_current_state (TASK_UNINTERRUPTIBLE);
4547 schedule_timeout (HZ); /* Added 12/7/00 */
4548 return status;
4549 }
4550 #endif /* CISCO_EXT */
4551
4552 /*
4553 This program is free software; you can redistribute it and/or
4554 modify it under the terms of the GNU General Public License
4555 as published by the Free Software Foundation; either version 2
4556 of the License, or (at your option) any later version.
4557
4558 This program is distributed in the hope that it will be useful,
4559 but WITHOUT ANY WARRANTY; without even the implied warranty of
4560 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4561 GNU General Public License for more details.
4562
4563 In addition:
4564
4565 Redistribution and use in source and binary forms, with or without
4566 modification, are permitted provided that the following conditions
4567 are met:
4568
4569 1. Redistributions of source code must retain the above copyright
4570 notice, this list of conditions and the following disclaimer.
4571 2. Redistributions in binary form must reproduce the above copyright
4572 notice, this list of conditions and the following disclaimer in the
4573 documentation and/or other materials provided with the distribution.
4574 3. The name of the author may not be used to endorse or promote
4575 products derived from this software without specific prior written
4576 permission.
4577
4578 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
4579 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4580 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4581 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
4582 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4583 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
4584 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4585 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4586 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4587 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4588 POSSIBILITY OF SUCH DAMAGE.
4589 */
4590
4591 module_init(airo_init_module);
4592 module_exit(airo_cleanup_module);
4593