Back to home page

OSCL-LXR

 
 

    


0001 /*======================================================================
0002 
0003     Aironet driver for 4500 and 4800 series cards
0004 
0005     This code is released under both the GPL version 2 and BSD licenses.
0006     Either license may be used.  The respective licenses are found at
0007     the end of this file.
0008 
0009     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
0010     including portions of which come from the Aironet PC4500
0011     Developer's Reference Manual and used with permission.  Copyright
0012     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
0013     code in the Developer's manual was granted for this driver by
0014     Aironet.  Major code contributions were received from Javier Achirica
0015     <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
0016     Code was also integrated from the Cisco Aironet driver for Linux.
0017     Support for MPI350 cards was added by Fabrice Bellet
0018     <fabrice@bellet.info>.
0019 
0020 ======================================================================*/
0021 
0022 #include <linux/err.h>
0023 #include <linux/init.h>
0024 
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/proc_fs.h>
0028 
0029 #include <linux/sched.h>
0030 #include <linux/ptrace.h>
0031 #include <linux/slab.h>
0032 #include <linux/string.h>
0033 #include <linux/timer.h>
0034 #include <linux/interrupt.h>
0035 #include <linux/in.h>
0036 #include <linux/bitops.h>
0037 #include <linux/scatterlist.h>
0038 #include <linux/crypto.h>
0039 #include <linux/io.h>
0040 #include <asm/unaligned.h>
0041 
0042 #include <linux/netdevice.h>
0043 #include <linux/etherdevice.h>
0044 #include <linux/skbuff.h>
0045 #include <linux/if_arp.h>
0046 #include <linux/ioport.h>
0047 #include <linux/pci.h>
0048 #include <linux/uaccess.h>
0049 #include <linux/kthread.h>
0050 #include <linux/freezer.h>
0051 
0052 #include <crypto/aes.h>
0053 #include <crypto/skcipher.h>
0054 
0055 #include <net/cfg80211.h>
0056 #include <net/iw_handler.h>
0057 
0058 #include "airo.h"
0059 
0060 #define DRV_NAME "airo"
0061 
0062 #ifdef CONFIG_PCI
0063 static const struct pci_device_id card_ids[] = {
0064     { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
0065     { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
0066     { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
0067     { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
0068     { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
0069     { 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
0070     { 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
0071     { 0, }
0072 };
0073 MODULE_DEVICE_TABLE(pci, card_ids);
0074 
0075 static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
0076 static void airo_pci_remove(struct pci_dev *);
0077 static int __maybe_unused airo_pci_suspend(struct device *dev);
0078 static int __maybe_unused airo_pci_resume(struct device *dev);
0079 
0080 static SIMPLE_DEV_PM_OPS(airo_pci_pm_ops,
0081              airo_pci_suspend,
0082              airo_pci_resume);
0083 
0084 static struct pci_driver airo_driver = {
0085     .name      = DRV_NAME,
0086     .id_table  = card_ids,
0087     .probe     = airo_pci_probe,
0088     .remove    = airo_pci_remove,
0089     .driver.pm = &airo_pci_pm_ops,
0090 };
0091 #endif /* CONFIG_PCI */
0092 
0093 /* Include Wireless Extension definition and check version - Jean II */
0094 #include <linux/wireless.h>
0095 #define WIRELESS_SPY        /* enable iwspy support */
0096 
0097 #define CISCO_EXT       /* enable Cisco extensions */
0098 #ifdef CISCO_EXT
0099 #include <linux/delay.h>
0100 #endif
0101 
0102 /* Hack to do some power saving */
0103 #define POWER_ON_DOWN
0104 
0105 /* As you can see this list is HUGH!
0106    I really don't know what a lot of these counts are about, but they
0107    are all here for completeness.  If the IGNLABEL macro is put in
0108    infront of the label, that statistic will not be included in the list
0109    of statistics in the /proc filesystem */
0110 
0111 #define IGNLABEL(comment) NULL
0112 static const char *statsLabels[] = {
0113     "RxOverrun",
0114     IGNLABEL("RxPlcpCrcErr"),
0115     IGNLABEL("RxPlcpFormatErr"),
0116     IGNLABEL("RxPlcpLengthErr"),
0117     "RxMacCrcErr",
0118     "RxMacCrcOk",
0119     "RxWepErr",
0120     "RxWepOk",
0121     "RetryLong",
0122     "RetryShort",
0123     "MaxRetries",
0124     "NoAck",
0125     "NoCts",
0126     "RxAck",
0127     "RxCts",
0128     "TxAck",
0129     "TxRts",
0130     "TxCts",
0131     "TxMc",
0132     "TxBc",
0133     "TxUcFrags",
0134     "TxUcPackets",
0135     "TxBeacon",
0136     "RxBeacon",
0137     "TxSinColl",
0138     "TxMulColl",
0139     "DefersNo",
0140     "DefersProt",
0141     "DefersEngy",
0142     "DupFram",
0143     "RxFragDisc",
0144     "TxAged",
0145     "RxAged",
0146     "LostSync-MaxRetry",
0147     "LostSync-MissedBeacons",
0148     "LostSync-ArlExceeded",
0149     "LostSync-Deauth",
0150     "LostSync-Disassoced",
0151     "LostSync-TsfTiming",
0152     "HostTxMc",
0153     "HostTxBc",
0154     "HostTxUc",
0155     "HostTxFail",
0156     "HostRxMc",
0157     "HostRxBc",
0158     "HostRxUc",
0159     "HostRxDiscard",
0160     IGNLABEL("HmacTxMc"),
0161     IGNLABEL("HmacTxBc"),
0162     IGNLABEL("HmacTxUc"),
0163     IGNLABEL("HmacTxFail"),
0164     IGNLABEL("HmacRxMc"),
0165     IGNLABEL("HmacRxBc"),
0166     IGNLABEL("HmacRxUc"),
0167     IGNLABEL("HmacRxDiscard"),
0168     IGNLABEL("HmacRxAccepted"),
0169     "SsidMismatch",
0170     "ApMismatch",
0171     "RatesMismatch",
0172     "AuthReject",
0173     "AuthTimeout",
0174     "AssocReject",
0175     "AssocTimeout",
0176     IGNLABEL("ReasonOutsideTable"),
0177     IGNLABEL("ReasonStatus1"),
0178     IGNLABEL("ReasonStatus2"),
0179     IGNLABEL("ReasonStatus3"),
0180     IGNLABEL("ReasonStatus4"),
0181     IGNLABEL("ReasonStatus5"),
0182     IGNLABEL("ReasonStatus6"),
0183     IGNLABEL("ReasonStatus7"),
0184     IGNLABEL("ReasonStatus8"),
0185     IGNLABEL("ReasonStatus9"),
0186     IGNLABEL("ReasonStatus10"),
0187     IGNLABEL("ReasonStatus11"),
0188     IGNLABEL("ReasonStatus12"),
0189     IGNLABEL("ReasonStatus13"),
0190     IGNLABEL("ReasonStatus14"),
0191     IGNLABEL("ReasonStatus15"),
0192     IGNLABEL("ReasonStatus16"),
0193     IGNLABEL("ReasonStatus17"),
0194     IGNLABEL("ReasonStatus18"),
0195     IGNLABEL("ReasonStatus19"),
0196     "RxMan",
0197     "TxMan",
0198     "RxRefresh",
0199     "TxRefresh",
0200     "RxPoll",
0201     "TxPoll",
0202     "HostRetries",
0203     "LostSync-HostReq",
0204     "HostTxBytes",
0205     "HostRxBytes",
0206     "ElapsedUsec",
0207     "ElapsedSec",
0208     "LostSyncBetterAP",
0209     "PrivacyMismatch",
0210     "Jammed",
0211     "DiscRxNotWepped",
0212     "PhyEleMismatch",
0213     (char*)-1 };
0214 #ifndef RUN_AT
0215 #define RUN_AT(x) (jiffies+(x))
0216 #endif
0217 
0218 
0219 /* These variables are for insmod, since it seems that the rates
0220    can only be set in setup_card.  Rates should be a comma separated
0221    (no spaces) list of rates (up to 8). */
0222 
0223 static int rates[8];
0224 static char *ssids[3];
0225 
0226 static int io[4];
0227 static int irq[4];
0228 
0229 static
0230 int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
0231                0 means no limit.  For old cards this was 4 */
0232 
0233 static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
0234 static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
0235             the bap, needed on some older cards and buses. */
0236 static int adhoc;
0237 
0238 static int probe = 1;
0239 
0240 static kuid_t proc_kuid;
0241 static int proc_uid /* = 0 */;
0242 
0243 static kgid_t proc_kgid;
0244 static int proc_gid /* = 0 */;
0245 
0246 static int airo_perm = 0555;
0247 
0248 static int proc_perm = 0644;
0249 
0250 MODULE_AUTHOR("Benjamin Reed");
0251 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards.  "
0252            "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.");
0253 MODULE_LICENSE("Dual BSD/GPL");
0254 module_param_hw_array(io, int, ioport, NULL, 0);
0255 module_param_hw_array(irq, int, irq, NULL, 0);
0256 module_param_array(rates, int, NULL, 0);
0257 module_param_array(ssids, charp, NULL, 0);
0258 module_param(auto_wep, int, 0);
0259 MODULE_PARM_DESC(auto_wep,
0260          "If non-zero, the driver will keep looping through the authentication options until an association is made.  "
0261          "The value of auto_wep is number of the wep keys to check.  "
0262          "A value of 2 will try using the key at index 0 and index 1.");
0263 module_param(aux_bap, int, 0);
0264 MODULE_PARM_DESC(aux_bap,
0265          "If non-zero, the driver will switch into a mode that seems to work better for older cards with some older buses.  "
0266          "Before switching it checks that the switch is needed.");
0267 module_param(maxencrypt, int, 0);
0268 MODULE_PARM_DESC(maxencrypt,
0269          "The maximum speed that the card can do encryption.  "
0270          "Units are in 512kbs.  "
0271          "Zero (default) means there is no limit.  "
0272          "Older cards used to be limited to 2mbs (4).");
0273 module_param(adhoc, int, 0);
0274 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
0275 module_param(probe, int, 0);
0276 MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
0277 
0278 module_param(proc_uid, int, 0);
0279 MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
0280 module_param(proc_gid, int, 0);
0281 MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
0282 module_param(airo_perm, int, 0);
0283 MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
0284 module_param(proc_perm, int, 0);
0285 MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
0286 
0287 /* This is a kind of sloppy hack to get this information to OUT4500 and
0288    IN4500.  I would be extremely interested in the situation where this
0289    doesn't work though!!! */
0290 static int do8bitIO /* = 0 */;
0291 
0292 /* Return codes */
0293 #define SUCCESS 0
0294 #define ERROR -1
0295 #define NO_PACKET -2
0296 
0297 /* Commands */
0298 #define NOP2        0x0000
0299 #define MAC_ENABLE  0x0001
0300 #define MAC_DISABLE 0x0002
0301 #define CMD_LOSE_SYNC   0x0003 /* Not sure what this does... */
0302 #define CMD_SOFTRESET   0x0004
0303 #define HOSTSLEEP   0x0005
0304 #define CMD_MAGIC_PKT   0x0006
0305 #define CMD_SETWAKEMASK 0x0007
0306 #define CMD_READCFG 0x0008
0307 #define CMD_SETMODE 0x0009
0308 #define CMD_ALLOCATETX  0x000a
0309 #define CMD_TRANSMIT    0x000b
0310 #define CMD_DEALLOCATETX 0x000c
0311 #define NOP     0x0010
0312 #define CMD_WORKAROUND  0x0011
0313 #define CMD_ALLOCATEAUX 0x0020
0314 #define CMD_ACCESS  0x0021
0315 #define CMD_PCIBAP  0x0022
0316 #define CMD_PCIAUX  0x0023
0317 #define CMD_ALLOCBUF    0x0028
0318 #define CMD_GETTLV  0x0029
0319 #define CMD_PUTTLV  0x002a
0320 #define CMD_DELTLV  0x002b
0321 #define CMD_FINDNEXTTLV 0x002c
0322 #define CMD_PSPNODES    0x0030
0323 #define CMD_SETCW   0x0031
0324 #define CMD_SETPCF  0x0032
0325 #define CMD_SETPHYREG   0x003e
0326 #define CMD_TXTEST  0x003f
0327 #define MAC_ENABLETX    0x0101
0328 #define CMD_LISTBSS 0x0103
0329 #define CMD_SAVECFG 0x0108
0330 #define CMD_ENABLEAUX   0x0111
0331 #define CMD_WRITERID    0x0121
0332 #define CMD_USEPSPNODES 0x0130
0333 #define MAC_ENABLERX    0x0201
0334 
0335 /* Command errors */
0336 #define ERROR_QUALIF 0x00
0337 #define ERROR_ILLCMD 0x01
0338 #define ERROR_ILLFMT 0x02
0339 #define ERROR_INVFID 0x03
0340 #define ERROR_INVRID 0x04
0341 #define ERROR_LARGE 0x05
0342 #define ERROR_NDISABL 0x06
0343 #define ERROR_ALLOCBSY 0x07
0344 #define ERROR_NORD 0x0B
0345 #define ERROR_NOWR 0x0C
0346 #define ERROR_INVFIDTX 0x0D
0347 #define ERROR_TESTACT 0x0E
0348 #define ERROR_TAGNFND 0x12
0349 #define ERROR_DECODE 0x20
0350 #define ERROR_DESCUNAV 0x21
0351 #define ERROR_BADLEN 0x22
0352 #define ERROR_MODE 0x80
0353 #define ERROR_HOP 0x81
0354 #define ERROR_BINTER 0x82
0355 #define ERROR_RXMODE 0x83
0356 #define ERROR_MACADDR 0x84
0357 #define ERROR_RATES 0x85
0358 #define ERROR_ORDER 0x86
0359 #define ERROR_SCAN 0x87
0360 #define ERROR_AUTH 0x88
0361 #define ERROR_PSMODE 0x89
0362 #define ERROR_RTYPE 0x8A
0363 #define ERROR_DIVER 0x8B
0364 #define ERROR_SSID 0x8C
0365 #define ERROR_APLIST 0x8D
0366 #define ERROR_AUTOWAKE 0x8E
0367 #define ERROR_LEAP 0x8F
0368 
0369 /* Registers */
0370 #define COMMAND 0x00
0371 #define PARAM0 0x02
0372 #define PARAM1 0x04
0373 #define PARAM2 0x06
0374 #define STATUS 0x08
0375 #define RESP0 0x0a
0376 #define RESP1 0x0c
0377 #define RESP2 0x0e
0378 #define LINKSTAT 0x10
0379 #define SELECT0 0x18
0380 #define OFFSET0 0x1c
0381 #define RXFID 0x20
0382 #define TXALLOCFID 0x22
0383 #define TXCOMPLFID 0x24
0384 #define DATA0 0x36
0385 #define EVSTAT 0x30
0386 #define EVINTEN 0x32
0387 #define EVACK 0x34
0388 #define SWS0 0x28
0389 #define SWS1 0x2a
0390 #define SWS2 0x2c
0391 #define SWS3 0x2e
0392 #define AUXPAGE 0x3A
0393 #define AUXOFF 0x3C
0394 #define AUXDATA 0x3E
0395 
0396 #define FID_TX 1
0397 #define FID_RX 2
0398 /* Offset into aux memory for descriptors */
0399 #define AUX_OFFSET 0x800
0400 /* Size of allocated packets */
0401 #define PKTSIZE 1840
0402 #define RIDSIZE 2048
0403 /* Size of the transmit queue */
0404 #define MAXTXQ 64
0405 
0406 /* BAP selectors */
0407 #define BAP0 0 /* Used for receiving packets */
0408 #define BAP1 2 /* Used for xmiting packets and working with RIDS */
0409 
0410 /* Flags */
0411 #define COMMAND_BUSY 0x8000
0412 
0413 #define BAP_BUSY 0x8000
0414 #define BAP_ERR 0x4000
0415 #define BAP_DONE 0x2000
0416 
0417 #define PROMISC 0xffff
0418 #define NOPROMISC 0x0000
0419 
0420 #define EV_CMD 0x10
0421 #define EV_CLEARCOMMANDBUSY 0x4000
0422 #define EV_RX 0x01
0423 #define EV_TX 0x02
0424 #define EV_TXEXC 0x04
0425 #define EV_ALLOC 0x08
0426 #define EV_LINK 0x80
0427 #define EV_AWAKE 0x100
0428 #define EV_TXCPY 0x400
0429 #define EV_UNKNOWN 0x800
0430 #define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
0431 #define EV_AWAKEN 0x2000
0432 #define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
0433 
0434 #ifdef CHECK_UNKNOWN_INTS
0435 #define IGNORE_INTS (EV_CMD | EV_UNKNOWN)
0436 #else
0437 #define IGNORE_INTS (~STATUS_INTS)
0438 #endif
0439 
0440 /* RID TYPES */
0441 #define RID_RW 0x20
0442 
0443 /* The RIDs */
0444 #define RID_CAPABILITIES 0xFF00
0445 #define RID_APINFO     0xFF01
0446 #define RID_RADIOINFO  0xFF02
0447 #define RID_UNKNOWN3   0xFF03
0448 #define RID_RSSI       0xFF04
0449 #define RID_CONFIG     0xFF10
0450 #define RID_SSID       0xFF11
0451 #define RID_APLIST     0xFF12
0452 #define RID_DRVNAME    0xFF13
0453 #define RID_ETHERENCAP 0xFF14
0454 #define RID_WEP_TEMP   0xFF15
0455 #define RID_WEP_PERM   0xFF16
0456 #define RID_MODULATION 0xFF17
0457 #define RID_OPTIONS    0xFF18
0458 #define RID_ACTUALCONFIG 0xFF20 /*readonly*/
0459 #define RID_FACTORYCONFIG 0xFF21
0460 #define RID_UNKNOWN22  0xFF22
0461 #define RID_LEAPUSERNAME 0xFF23
0462 #define RID_LEAPPASSWORD 0xFF24
0463 #define RID_STATUS     0xFF50
0464 #define RID_BEACON_HST 0xFF51
0465 #define RID_BUSY_HST   0xFF52
0466 #define RID_RETRIES_HST 0xFF53
0467 #define RID_UNKNOWN54  0xFF54
0468 #define RID_UNKNOWN55  0xFF55
0469 #define RID_UNKNOWN56  0xFF56
0470 #define RID_MIC        0xFF57
0471 #define RID_STATS16    0xFF60
0472 #define RID_STATS16DELTA 0xFF61
0473 #define RID_STATS16DELTACLEAR 0xFF62
0474 #define RID_STATS      0xFF68
0475 #define RID_STATSDELTA 0xFF69
0476 #define RID_STATSDELTACLEAR 0xFF6A
0477 #define RID_ECHOTEST_RID 0xFF70
0478 #define RID_ECHOTEST_RESULTS 0xFF71
0479 #define RID_BSSLISTFIRST 0xFF72
0480 #define RID_BSSLISTNEXT  0xFF73
0481 #define RID_WPA_BSSLISTFIRST 0xFF74
0482 #define RID_WPA_BSSLISTNEXT  0xFF75
0483 
0484 typedef struct {
0485     u16 cmd;
0486     u16 parm0;
0487     u16 parm1;
0488     u16 parm2;
0489 } Cmd;
0490 
0491 typedef struct {
0492     u16 status;
0493     u16 rsp0;
0494     u16 rsp1;
0495     u16 rsp2;
0496 } Resp;
0497 
0498 /*
0499  * Rids and endian-ness:  The Rids will always be in cpu endian, since
0500  * this all the patches from the big-endian guys end up doing that.
0501  * so all rid access should use the read/writeXXXRid routines.
0502  */
0503 
0504 /* This structure came from an email sent to me from an engineer at
0505    aironet for inclusion into this driver */
0506 typedef struct WepKeyRid WepKeyRid;
0507 struct WepKeyRid {
0508     __le16 len;
0509     __le16 kindex;
0510     u8 mac[ETH_ALEN];
0511     __le16 klen;
0512     u8 key[16];
0513 } __packed;
0514 
0515 /* These structures are from the Aironet's PC4500 Developers Manual */
0516 typedef struct Ssid Ssid;
0517 struct Ssid {
0518     __le16 len;
0519     u8 ssid[32];
0520 } __packed;
0521 
0522 typedef struct SsidRid SsidRid;
0523 struct SsidRid {
0524     __le16 len;
0525     Ssid ssids[3];
0526 } __packed;
0527 
0528 typedef struct ModulationRid ModulationRid;
0529 struct ModulationRid {
0530         __le16 len;
0531         __le16 modulation;
0532 #define MOD_DEFAULT cpu_to_le16(0)
0533 #define MOD_CCK cpu_to_le16(1)
0534 #define MOD_MOK cpu_to_le16(2)
0535 } __packed;
0536 
0537 typedef struct ConfigRid ConfigRid;
0538 struct ConfigRid {
0539     __le16 len; /* sizeof(ConfigRid) */
0540     __le16 opmode; /* operating mode */
0541 #define MODE_STA_IBSS cpu_to_le16(0)
0542 #define MODE_STA_ESS cpu_to_le16(1)
0543 #define MODE_AP cpu_to_le16(2)
0544 #define MODE_AP_RPTR cpu_to_le16(3)
0545 #define MODE_CFG_MASK cpu_to_le16(0xff)
0546 #define MODE_ETHERNET_HOST cpu_to_le16(0<<8) /* rx payloads converted */
0547 #define MODE_LLC_HOST cpu_to_le16(1<<8) /* rx payloads left as is */
0548 #define MODE_AIRONET_EXTEND cpu_to_le16(1<<9) /* enable Aironet extensions */
0549 #define MODE_AP_INTERFACE cpu_to_le16(1<<10) /* enable ap interface extensions */
0550 #define MODE_ANTENNA_ALIGN cpu_to_le16(1<<11) /* enable antenna alignment */
0551 #define MODE_ETHER_LLC cpu_to_le16(1<<12) /* enable ethernet LLC */
0552 #define MODE_LEAF_NODE cpu_to_le16(1<<13) /* enable leaf node bridge */
0553 #define MODE_CF_POLLABLE cpu_to_le16(1<<14) /* enable CF pollable */
0554 #define MODE_MIC cpu_to_le16(1<<15) /* enable MIC */
0555     __le16 rmode; /* receive mode */
0556 #define RXMODE_BC_MC_ADDR cpu_to_le16(0)
0557 #define RXMODE_BC_ADDR cpu_to_le16(1) /* ignore multicasts */
0558 #define RXMODE_ADDR cpu_to_le16(2) /* ignore multicast and broadcast */
0559 #define RXMODE_RFMON cpu_to_le16(3) /* wireless monitor mode */
0560 #define RXMODE_RFMON_ANYBSS cpu_to_le16(4)
0561 #define RXMODE_LANMON cpu_to_le16(5) /* lan style monitor -- data packets only */
0562 #define RXMODE_MASK cpu_to_le16(255)
0563 #define RXMODE_DISABLE_802_3_HEADER cpu_to_le16(1<<8) /* disables 802.3 header on rx */
0564 #define RXMODE_FULL_MASK (RXMODE_MASK | RXMODE_DISABLE_802_3_HEADER)
0565 #define RXMODE_NORMALIZED_RSSI cpu_to_le16(1<<9) /* return normalized RSSI */
0566     __le16 fragThresh;
0567     __le16 rtsThres;
0568     u8 macAddr[ETH_ALEN];
0569     u8 rates[8];
0570     __le16 shortRetryLimit;
0571     __le16 longRetryLimit;
0572     __le16 txLifetime; /* in kusec */
0573     __le16 rxLifetime; /* in kusec */
0574     __le16 stationary;
0575     __le16 ordering;
0576     __le16 u16deviceType; /* for overriding device type */
0577     __le16 cfpRate;
0578     __le16 cfpDuration;
0579     __le16 _reserved1[3];
0580     /*---------- Scanning/Associating ----------*/
0581     __le16 scanMode;
0582 #define SCANMODE_ACTIVE cpu_to_le16(0)
0583 #define SCANMODE_PASSIVE cpu_to_le16(1)
0584 #define SCANMODE_AIROSCAN cpu_to_le16(2)
0585     __le16 probeDelay; /* in kusec */
0586     __le16 probeEnergyTimeout; /* in kusec */
0587         __le16 probeResponseTimeout;
0588     __le16 beaconListenTimeout;
0589     __le16 joinNetTimeout;
0590     __le16 authTimeout;
0591     __le16 authType;
0592 #define AUTH_OPEN cpu_to_le16(0x1)
0593 #define AUTH_ENCRYPT cpu_to_le16(0x101)
0594 #define AUTH_SHAREDKEY cpu_to_le16(0x102)
0595 #define AUTH_ALLOW_UNENCRYPTED cpu_to_le16(0x200)
0596     __le16 associationTimeout;
0597     __le16 specifiedApTimeout;
0598     __le16 offlineScanInterval;
0599     __le16 offlineScanDuration;
0600     __le16 linkLossDelay;
0601     __le16 maxBeaconLostTime;
0602     __le16 refreshInterval;
0603 #define DISABLE_REFRESH cpu_to_le16(0xFFFF)
0604     __le16 _reserved1a[1];
0605     /*---------- Power save operation ----------*/
0606     __le16 powerSaveMode;
0607 #define POWERSAVE_CAM cpu_to_le16(0)
0608 #define POWERSAVE_PSP cpu_to_le16(1)
0609 #define POWERSAVE_PSPCAM cpu_to_le16(2)
0610     __le16 sleepForDtims;
0611     __le16 listenInterval;
0612     __le16 fastListenInterval;
0613     __le16 listenDecay;
0614     __le16 fastListenDelay;
0615     __le16 _reserved2[2];
0616     /*---------- Ap/Ibss config items ----------*/
0617     __le16 beaconPeriod;
0618     __le16 atimDuration;
0619     __le16 hopPeriod;
0620     __le16 channelSet;
0621     __le16 channel;
0622     __le16 dtimPeriod;
0623     __le16 bridgeDistance;
0624     __le16 radioID;
0625     /*---------- Radio configuration ----------*/
0626     __le16 radioType;
0627 #define RADIOTYPE_DEFAULT cpu_to_le16(0)
0628 #define RADIOTYPE_802_11 cpu_to_le16(1)
0629 #define RADIOTYPE_LEGACY cpu_to_le16(2)
0630     u8 rxDiversity;
0631     u8 txDiversity;
0632     __le16 txPower;
0633 #define TXPOWER_DEFAULT 0
0634     __le16 rssiThreshold;
0635 #define RSSI_DEFAULT 0
0636         __le16 modulation;
0637 #define PREAMBLE_AUTO cpu_to_le16(0)
0638 #define PREAMBLE_LONG cpu_to_le16(1)
0639 #define PREAMBLE_SHORT cpu_to_le16(2)
0640     __le16 preamble;
0641     __le16 homeProduct;
0642     __le16 radioSpecific;
0643     /*---------- Aironet Extensions ----------*/
0644     u8 nodeName[16];
0645     __le16 arlThreshold;
0646     __le16 arlDecay;
0647     __le16 arlDelay;
0648     __le16 _reserved4[1];
0649     /*---------- Aironet Extensions ----------*/
0650     u8 magicAction;
0651 #define MAGIC_ACTION_STSCHG 1
0652 #define MAGIC_ACTION_RESUME 2
0653 #define MAGIC_IGNORE_MCAST (1<<8)
0654 #define MAGIC_IGNORE_BCAST (1<<9)
0655 #define MAGIC_SWITCH_TO_PSP (0<<10)
0656 #define MAGIC_STAY_IN_CAM (1<<10)
0657     u8 magicControl;
0658     __le16 autoWake;
0659 } __packed;
0660 
0661 typedef struct StatusRid StatusRid;
0662 struct StatusRid {
0663     __le16 len;
0664     u8 mac[ETH_ALEN];
0665     __le16 mode;
0666     __le16 errorCode;
0667     __le16 sigQuality;
0668     __le16 SSIDlen;
0669     char SSID[32];
0670     char apName[16];
0671     u8 bssid[4][ETH_ALEN];
0672     __le16 beaconPeriod;
0673     __le16 dimPeriod;
0674     __le16 atimDuration;
0675     __le16 hopPeriod;
0676     __le16 channelSet;
0677     __le16 channel;
0678     __le16 hopsToBackbone;
0679     __le16 apTotalLoad;
0680     __le16 generatedLoad;
0681     __le16 accumulatedArl;
0682     __le16 signalQuality;
0683     __le16 currentXmitRate;
0684     __le16 apDevExtensions;
0685     __le16 normalizedSignalStrength;
0686     __le16 shortPreamble;
0687     u8 apIP[4];
0688     u8 noisePercent; /* Noise percent in last second */
0689     u8 noisedBm; /* Noise dBm in last second */
0690     u8 noiseAvePercent; /* Noise percent in last minute */
0691     u8 noiseAvedBm; /* Noise dBm in last minute */
0692     u8 noiseMaxPercent; /* Highest noise percent in last minute */
0693     u8 noiseMaxdBm; /* Highest noise dbm in last minute */
0694     __le16 load;
0695     u8 carrier[4];
0696     __le16 assocStatus;
0697 #define STAT_NOPACKETS 0
0698 #define STAT_NOCARRIERSET 10
0699 #define STAT_GOTCARRIERSET 11
0700 #define STAT_WRONGSSID 20
0701 #define STAT_BADCHANNEL 25
0702 #define STAT_BADBITRATES 30
0703 #define STAT_BADPRIVACY 35
0704 #define STAT_APFOUND 40
0705 #define STAT_APREJECTED 50
0706 #define STAT_AUTHENTICATING 60
0707 #define STAT_DEAUTHENTICATED 61
0708 #define STAT_AUTHTIMEOUT 62
0709 #define STAT_ASSOCIATING 70
0710 #define STAT_DEASSOCIATED 71
0711 #define STAT_ASSOCTIMEOUT 72
0712 #define STAT_NOTAIROAP 73
0713 #define STAT_ASSOCIATED 80
0714 #define STAT_LEAPING 90
0715 #define STAT_LEAPFAILED 91
0716 #define STAT_LEAPTIMEDOUT 92
0717 #define STAT_LEAPCOMPLETE 93
0718 } __packed;
0719 
0720 typedef struct StatsRid StatsRid;
0721 struct StatsRid {
0722     __le16 len;
0723     __le16 spacer;
0724     __le32 vals[100];
0725 } __packed;
0726 
0727 typedef struct APListRid APListRid;
0728 struct APListRid {
0729     __le16 len;
0730     u8 ap[4][ETH_ALEN];
0731 } __packed;
0732 
0733 typedef struct CapabilityRid CapabilityRid;
0734 struct CapabilityRid {
0735     __le16 len;
0736     char oui[3];
0737     char zero;
0738     __le16 prodNum;
0739     char manName[32];
0740     char prodName[16];
0741     char prodVer[8];
0742     char factoryAddr[ETH_ALEN];
0743     char aironetAddr[ETH_ALEN];
0744     __le16 radioType;
0745     __le16 country;
0746     char callid[ETH_ALEN];
0747     char supportedRates[8];
0748     char rxDiversity;
0749     char txDiversity;
0750     __le16 txPowerLevels[8];
0751     __le16 hardVer;
0752     __le16 hardCap;
0753     __le16 tempRange;
0754     __le16 softVer;
0755     __le16 softSubVer;
0756     __le16 interfaceVer;
0757     __le16 softCap;
0758     __le16 bootBlockVer;
0759     __le16 requiredHard;
0760     __le16 extSoftCap;
0761 } __packed;
0762 
0763 /* Only present on firmware >= 5.30.17 */
0764 typedef struct BSSListRidExtra BSSListRidExtra;
0765 struct BSSListRidExtra {
0766   __le16 unknown[4];
0767   u8 fixed[12]; /* WLAN management frame */
0768   u8 iep[624];
0769 } __packed;
0770 
0771 typedef struct BSSListRid BSSListRid;
0772 struct BSSListRid {
0773   __le16 len;
0774   __le16 index; /* First is 0 and 0xffff means end of list */
0775 #define RADIO_FH 1 /* Frequency hopping radio type */
0776 #define RADIO_DS 2 /* Direct sequence radio type */
0777 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
0778   __le16 radioType;
0779   u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
0780   u8 zero;
0781   u8 ssidLen;
0782   u8 ssid[32];
0783   __le16 dBm;
0784 #define CAP_ESS cpu_to_le16(1<<0)
0785 #define CAP_IBSS cpu_to_le16(1<<1)
0786 #define CAP_PRIVACY cpu_to_le16(1<<4)
0787 #define CAP_SHORTHDR cpu_to_le16(1<<5)
0788   __le16 cap;
0789   __le16 beaconInterval;
0790   u8 rates[8]; /* Same as rates for config rid */
0791   struct { /* For frequency hopping only */
0792     __le16 dwell;
0793     u8 hopSet;
0794     u8 hopPattern;
0795     u8 hopIndex;
0796     u8 fill;
0797   } fh;
0798   __le16 dsChannel;
0799   __le16 atimWindow;
0800 
0801   /* Only present on firmware >= 5.30.17 */
0802   BSSListRidExtra extra;
0803 } __packed;
0804 
0805 typedef struct {
0806   BSSListRid bss;
0807   struct list_head list;
0808 } BSSListElement;
0809 
0810 typedef struct tdsRssiEntry tdsRssiEntry;
0811 struct tdsRssiEntry {
0812   u8 rssipct;
0813   u8 rssidBm;
0814 } __packed;
0815 
0816 typedef struct tdsRssiRid tdsRssiRid;
0817 struct tdsRssiRid {
0818   u16 len;
0819   tdsRssiEntry x[256];
0820 } __packed;
0821 
0822 typedef struct MICRid MICRid;
0823 struct MICRid {
0824     __le16 len;
0825     __le16 state;
0826     __le16 multicastValid;
0827     u8  multicast[16];
0828     __le16 unicastValid;
0829     u8  unicast[16];
0830 } __packed;
0831 
0832 typedef struct MICBuffer MICBuffer;
0833 struct MICBuffer {
0834     __be16 typelen;
0835 
0836     union {
0837         u8 snap[8];
0838         struct {
0839         u8 dsap;
0840         u8 ssap;
0841         u8 control;
0842         u8 orgcode[3];
0843         u8 fieldtype[2];
0844         } llc;
0845     } u;
0846     __be32 mic;
0847     __be32 seq;
0848 } __packed;
0849 
0850 typedef struct {
0851     u8 da[ETH_ALEN];
0852     u8 sa[ETH_ALEN];
0853 } etherHead;
0854 
0855 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
0856 #define TXCTL_TXEX (1<<2) /* report if tx fails */
0857 #define TXCTL_802_3 (0<<3) /* 802.3 packet */
0858 #define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
0859 #define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
0860 #define TXCTL_LLC (1<<4) /* payload is llc */
0861 #define TXCTL_RELEASE (0<<5) /* release after completion */
0862 #define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
0863 
0864 #define BUSY_FID 0x10000
0865 
0866 #ifdef CISCO_EXT
0867 #define AIROMAGIC   0xa55a
0868 /* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
0869 #ifdef SIOCIWFIRSTPRIV
0870 #ifdef SIOCDEVPRIVATE
0871 #define AIROOLDIOCTL    SIOCDEVPRIVATE
0872 #define AIROOLDIDIFC    AIROOLDIOCTL + 1
0873 #endif /* SIOCDEVPRIVATE */
0874 #else /* SIOCIWFIRSTPRIV */
0875 #define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
0876 #endif /* SIOCIWFIRSTPRIV */
0877 /* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
0878  * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
0879  * only and don't return the modified struct ifreq to the application which
0880  * is usually a problem. - Jean II */
0881 #define AIROIOCTL   SIOCIWFIRSTPRIV
0882 #define AIROIDIFC   AIROIOCTL + 1
0883 
0884 /* Ioctl constants to be used in airo_ioctl.command */
0885 
0886 #define AIROGCAP        0   // Capability rid
0887 #define AIROGCFG        1       // USED A LOT
0888 #define AIROGSLIST      2   // System ID list
0889 #define AIROGVLIST      3       // List of specified AP's
0890 #define AIROGDRVNAM     4   //  NOTUSED
0891 #define AIROGEHTENC     5   // NOTUSED
0892 #define AIROGWEPKTMP        6
0893 #define AIROGWEPKNV     7
0894 #define AIROGSTAT       8
0895 #define AIROGSTATSC32       9
0896 #define AIROGSTATSD32       10
0897 #define AIROGMICRID     11
0898 #define AIROGMICSTATS       12
0899 #define AIROGFLAGS      13
0900 #define AIROGID         14
0901 #define AIRORRID        15
0902 #define AIRORSWVERSION      17
0903 
0904 /* Leave gap of 40 commands after AIROGSTATSD32 for future */
0905 
0906 #define AIROPCAP                AIROGSTATSD32 + 40
0907 #define AIROPVLIST              AIROPCAP      + 1
0908 #define AIROPSLIST      AIROPVLIST    + 1
0909 #define AIROPCFG        AIROPSLIST    + 1
0910 #define AIROPSIDS       AIROPCFG      + 1
0911 #define AIROPAPLIST     AIROPSIDS     + 1
0912 #define AIROPMACON      AIROPAPLIST   + 1   /* Enable mac  */
0913 #define AIROPMACOFF     AIROPMACON    + 1   /* Disable mac */
0914 #define AIROPSTCLR      AIROPMACOFF   + 1
0915 #define AIROPWEPKEY     AIROPSTCLR    + 1
0916 #define AIROPWEPKEYNV       AIROPWEPKEY   + 1
0917 #define AIROPLEAPPWD            AIROPWEPKEYNV + 1
0918 #define AIROPLEAPUSR            AIROPLEAPPWD  + 1
0919 
0920 /* Flash codes */
0921 
0922 #define AIROFLSHRST        AIROPWEPKEYNV  + 40
0923 #define AIROFLSHGCHR           AIROFLSHRST    + 1
0924 #define AIROFLSHSTFL           AIROFLSHGCHR   + 1
0925 #define AIROFLSHPCHR           AIROFLSHSTFL   + 1
0926 #define AIROFLPUTBUF           AIROFLSHPCHR   + 1
0927 #define AIRORESTART            AIROFLPUTBUF   + 1
0928 
0929 #define FLASHSIZE   32768
0930 #define AUXMEMSIZE  (256 * 1024)
0931 
0932 typedef struct aironet_ioctl {
0933     unsigned short command;     // What to do
0934     unsigned short len;     // Len of data
0935     unsigned short ridnum;      // rid number
0936     unsigned char __user *data; // d-data
0937 } aironet_ioctl;
0938 
0939 static const char swversion[] = "2.1";
0940 #endif /* CISCO_EXT */
0941 
0942 #define NUM_MODULES       2
0943 #define MIC_MSGLEN_MAX    2400
0944 #define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
0945 #define AIRO_DEF_MTU      2312
0946 
0947 typedef struct {
0948     u32   size;            // size
0949     u8    enabled;         // MIC enabled or not
0950     u32   rxSuccess;       // successful packets received
0951     u32   rxIncorrectMIC;  // pkts dropped due to incorrect MIC comparison
0952     u32   rxNotMICed;      // pkts dropped due to not being MIC'd
0953     u32   rxMICPlummed;    // pkts dropped due to not having a MIC plummed
0954     u32   rxWrongSequence; // pkts dropped due to sequence number violation
0955     u32   reserve[32];
0956 } mic_statistics;
0957 
0958 typedef struct {
0959     __be32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
0960     u64 accum;  // accumulated mic, reduced to u32 in final()
0961     int position;   // current position (byte offset) in message
0962     union {
0963         u8  d8[4];
0964         __be32 d32;
0965     } part; // saves partial message word across update() calls
0966 } emmh32_context;
0967 
0968 typedef struct {
0969     emmh32_context seed;        // Context - the seed
0970     u32      rx;        // Received sequence number
0971     u32      tx;        // Tx sequence number
0972     u32      window;    // Start of window
0973     u8       valid;     // Flag to say if context is valid or not
0974     u8       key[16];
0975 } miccntx;
0976 
0977 typedef struct {
0978     miccntx mCtx;       // Multicast context
0979     miccntx uCtx;       // Unicast context
0980 } mic_module;
0981 
0982 typedef struct {
0983     unsigned int  rid: 16;
0984     unsigned int  len: 15;
0985     unsigned int  valid: 1;
0986     dma_addr_t host_addr;
0987 } Rid;
0988 
0989 typedef struct {
0990     unsigned int  offset: 15;
0991     unsigned int  eoc: 1;
0992     unsigned int  len: 15;
0993     unsigned int  valid: 1;
0994     dma_addr_t host_addr;
0995 } TxFid;
0996 
0997 struct rx_hdr {
0998     __le16 status, len;
0999     u8 rssi[2];
1000     u8 rate;
1001     u8 freq;
1002     __le16 tmp[4];
1003 } __packed;
1004 
1005 typedef struct {
1006     unsigned int  ctl: 15;
1007     unsigned int  rdy: 1;
1008     unsigned int  len: 15;
1009     unsigned int  valid: 1;
1010     dma_addr_t host_addr;
1011 } RxFid;
1012 
1013 /*
1014  * Host receive descriptor
1015  */
1016 typedef struct {
1017     unsigned char __iomem *card_ram_off; /* offset into card memory of the
1018                         desc */
1019     RxFid         rx_desc;           /* card receive descriptor */
1020     char          *virtual_host_addr;    /* virtual address of host receive
1021                             buffer */
1022     int           pending;
1023 } HostRxDesc;
1024 
1025 /*
1026  * Host transmit descriptor
1027  */
1028 typedef struct {
1029     unsigned char __iomem *card_ram_off;         /* offset into card memory of the
1030                         desc */
1031     TxFid         tx_desc;           /* card transmit descriptor */
1032     char          *virtual_host_addr;    /* virtual address of host receive
1033                             buffer */
1034     int           pending;
1035 } HostTxDesc;
1036 
1037 /*
1038  * Host RID descriptor
1039  */
1040 typedef struct {
1041     unsigned char __iomem *card_ram_off;      /* offset into card memory of the
1042                          descriptor */
1043     Rid           rid_desc;       /* card RID descriptor */
1044     char          *virtual_host_addr; /* virtual address of host receive
1045                          buffer */
1046 } HostRidDesc;
1047 
1048 typedef struct {
1049     u16 sw0;
1050     u16 sw1;
1051     u16 status;
1052     u16 len;
1053 #define HOST_SET (1 << 0)
1054 #define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
1055 #define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
1056 #define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
1057 #define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
1058 #define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
1059 #define HOST_CLR_AID (1 << 7) /* clear AID failure */
1060 #define HOST_RTS (1 << 9) /* Force RTS use */
1061 #define HOST_SHORT (1 << 10) /* Do short preamble */
1062     u16 ctl;
1063     u16 aid;
1064     u16 retries;
1065     u16 fill;
1066 } TxCtlHdr;
1067 
1068 typedef struct {
1069         u16 ctl;
1070         u16 duration;
1071         char addr1[6];
1072         char addr2[6];
1073         char addr3[6];
1074         u16 seq;
1075         char addr4[6];
1076 } WifiHdr;
1077 
1078 
1079 typedef struct {
1080     TxCtlHdr ctlhdr;
1081     u16 fill1;
1082     u16 fill2;
1083     WifiHdr wifihdr;
1084     u16 gaplen;
1085     u16 status;
1086 } WifiCtlHdr;
1087 
1088 static WifiCtlHdr wifictlhdr8023 = {
1089     .ctlhdr = {
1090         .ctl    = HOST_DONT_RLSE,
1091     }
1092 };
1093 
1094 // A few details needed for WEP (Wireless Equivalent Privacy)
1095 #define MAX_KEY_SIZE 13         // 128 (?) bits
1096 #define MIN_KEY_SIZE  5         // 40 bits RC4 - WEP
1097 typedef struct wep_key_t {
1098     u16 len;
1099     u8  key[16];    /* 40-bit and 104-bit keys */
1100 } wep_key_t;
1101 
1102 /* List of Wireless Handlers (new API) */
1103 static const struct iw_handler_def  airo_handler_def;
1104 
1105 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
1106 
1107 struct airo_info;
1108 
1109 static int get_dec_u16(char *buffer, int *start, int limit);
1110 static void OUT4500(struct airo_info *, u16 reg, u16 value);
1111 static unsigned short IN4500(struct airo_info *, u16 reg);
1112 static u16 setup_card(struct airo_info*, struct net_device *dev, int lock);
1113 static int enable_MAC(struct airo_info *ai, int lock);
1114 static void disable_MAC(struct airo_info *ai, int lock);
1115 static void enable_interrupts(struct airo_info*);
1116 static void disable_interrupts(struct airo_info*);
1117 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp,
1118             bool may_sleep);
1119 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
1120 static int aux_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
1121             int whichbap);
1122 static int fast_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
1123              int whichbap);
1124 static int bap_write(struct airo_info*, const __le16 *pu16Src, int bytelen,
1125              int whichbap);
1126 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
1127 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
1128 static int PC4500_writerid(struct airo_info*, u16 rid, const void
1129                *pBuf, int len, int lock);
1130 static int do_writerid(struct airo_info*, u16 rid, const void *rid_data,
1131             int len, int dummy);
1132 static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
1133 static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket,
1134                  bool may_sleep);
1135 static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket,
1136                   bool may_sleep);
1137 
1138 static int mpi_send_packet(struct net_device *dev);
1139 static void mpi_unmap_card(struct pci_dev *pci);
1140 static void mpi_receive_802_3(struct airo_info *ai);
1141 static void mpi_receive_802_11(struct airo_info *ai);
1142 static int waitbusy(struct airo_info *ai);
1143 
1144 static irqreturn_t airo_interrupt(int irq, void* dev_id);
1145 static int airo_thread(void *data);
1146 static void timer_func(struct net_device *dev);
1147 static int airo_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *, int cmd);
1148 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev);
1149 #ifdef CISCO_EXT
1150 static int readrids(struct net_device *dev, aironet_ioctl *comp);
1151 static int writerids(struct net_device *dev, aironet_ioctl *comp);
1152 static int flashcard(struct net_device *dev, aironet_ioctl *comp);
1153 #endif /* CISCO_EXT */
1154 static void micinit(struct airo_info *ai);
1155 static int micsetup(struct airo_info *ai);
1156 static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
1157 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1158 
1159 static u8 airo_rssi_to_dbm(tdsRssiEntry *rssi_rid, u8 rssi);
1160 static u8 airo_dbm_to_pct(tdsRssiEntry *rssi_rid, u8 dbm);
1161 
1162 static void airo_networks_free(struct airo_info *ai);
1163 
1164 struct airo_info {
1165     struct net_device             *dev;
1166     struct list_head              dev_list;
1167     /* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
1168        use the high bit to mark whether it is in use. */
1169 #define MAX_FIDS 6
1170 #define MPI_MAX_FIDS 1
1171     u32                           fids[MAX_FIDS];
1172     ConfigRid config;
1173     char keyindex; // Used with auto wep
1174     char defindex; // Used with auto wep
1175     struct proc_dir_entry *proc_entry;
1176         spinlock_t aux_lock;
1177 #define FLAG_RADIO_OFF  0   /* User disabling of MAC */
1178 #define FLAG_RADIO_DOWN 1   /* ifup/ifdown disabling of MAC */
1179 #define FLAG_RADIO_MASK 0x03
1180 #define FLAG_ENABLED    2
1181 #define FLAG_ADHOC  3   /* Needed by MIC */
1182 #define FLAG_MIC_CAPABLE 4
1183 #define FLAG_UPDATE_MULTI 5
1184 #define FLAG_UPDATE_UNI 6
1185 #define FLAG_802_11 7
1186 #define FLAG_PROMISC    8   /* IFF_PROMISC 0x100 - include/linux/if.h */
1187 #define FLAG_PENDING_XMIT 9
1188 #define FLAG_PENDING_XMIT11 10
1189 #define FLAG_MPI    11
1190 #define FLAG_REGISTERED 12
1191 #define FLAG_COMMIT 13
1192 #define FLAG_RESET  14
1193 #define FLAG_FLASHING   15
1194 #define FLAG_WPA_CAPABLE    16
1195     unsigned long flags;
1196 #define JOB_DIE 0
1197 #define JOB_XMIT    1
1198 #define JOB_XMIT11  2
1199 #define JOB_STATS   3
1200 #define JOB_PROMISC 4
1201 #define JOB_MIC 5
1202 #define JOB_EVENT   6
1203 #define JOB_AUTOWEP 7
1204 #define JOB_SCAN_RESULTS  9
1205     unsigned long jobs;
1206     int (*bap_read)(struct airo_info*, __le16 *pu16Dst, int bytelen,
1207             int whichbap);
1208     unsigned short *flash;
1209     tdsRssiEntry *rssi;
1210     struct task_struct *list_bss_task;
1211     struct task_struct *airo_thread_task;
1212     struct semaphore sem;
1213     wait_queue_head_t thr_wait;
1214     unsigned long expires;
1215     struct {
1216         struct sk_buff *skb;
1217         int fid;
1218     } xmit, xmit11;
1219     struct net_device *wifidev;
1220     struct iw_statistics    wstats;     // wireless stats
1221     unsigned long       scan_timeout;   /* Time scan should be read */
1222     struct iw_spy_data  spy_data;
1223     struct iw_public_data   wireless_data;
1224     /* MIC stuff */
1225     struct crypto_sync_skcipher *tfm;
1226     mic_module      mod[2];
1227     mic_statistics      micstats;
1228     HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
1229     HostTxDesc txfids[MPI_MAX_FIDS];
1230     HostRidDesc config_desc;
1231     unsigned long ridbus; // phys addr of config_desc
1232     struct sk_buff_head txq;// tx queue used by mpi350 code
1233     struct pci_dev          *pci;
1234     unsigned char       __iomem *pcimem;
1235     unsigned char       __iomem *pciaux;
1236     unsigned char       *shared;
1237     dma_addr_t      shared_dma;
1238     pm_message_t        power;
1239     SsidRid         *SSID;
1240     APListRid       APList;
1241 #define PCI_SHARED_LEN      2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
1242     char            proc_name[IFNAMSIZ];
1243 
1244     int         wep_capable;
1245     int         max_wep_idx;
1246     int         last_auth;
1247 
1248     /* WPA-related stuff */
1249     unsigned int bssListFirst;
1250     unsigned int bssListNext;
1251     unsigned int bssListRidLen;
1252 
1253     struct list_head network_list;
1254     struct list_head network_free_list;
1255     BSSListElement *networks;
1256 };
1257 
1258 static inline int bap_read(struct airo_info *ai, __le16 *pu16Dst, int bytelen,
1259                int whichbap)
1260 {
1261     return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
1262 }
1263 
1264 static int setup_proc_entry(struct net_device *dev,
1265                  struct airo_info *apriv);
1266 static int takedown_proc_entry(struct net_device *dev,
1267                 struct airo_info *apriv);
1268 
1269 static int cmdreset(struct airo_info *ai);
1270 static int setflashmode(struct airo_info *ai);
1271 static int flashgchar(struct airo_info *ai, int matchbyte, int dwelltime);
1272 static int flashputbuf(struct airo_info *ai);
1273 static int flashrestart(struct airo_info *ai, struct net_device *dev);
1274 
1275 #define airo_print(type, name, fmt, args...) \
1276     printk(type DRV_NAME "(%s): " fmt "\n", name, ##args)
1277 
1278 #define airo_print_info(name, fmt, args...) \
1279     airo_print(KERN_INFO, name, fmt, ##args)
1280 
1281 #define airo_print_dbg(name, fmt, args...) \
1282     airo_print(KERN_DEBUG, name, fmt, ##args)
1283 
1284 #define airo_print_warn(name, fmt, args...) \
1285     airo_print(KERN_WARNING, name, fmt, ##args)
1286 
1287 #define airo_print_err(name, fmt, args...) \
1288     airo_print(KERN_ERR, name, fmt, ##args)
1289 
1290 #define AIRO_FLASH(dev) (((struct airo_info *)dev->ml_priv)->flash)
1291 
1292 /***********************************************************************
1293  *                              MIC ROUTINES                           *
1294  ***********************************************************************
1295  */
1296 
1297 static int RxSeqValid(struct airo_info *ai, miccntx *context, int mcast, u32 micSeq);
1298 static void MoveWindow(miccntx *context, u32 micSeq);
1299 static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1300                struct crypto_sync_skcipher *tfm);
1301 static void emmh32_init(emmh32_context *context);
1302 static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1303 static void emmh32_final(emmh32_context *context, u8 digest[4]);
1304 static int flashpchar(struct airo_info *ai, int byte, int dwelltime);
1305 
1306 static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
1307                 struct crypto_sync_skcipher *tfm)
1308 {
1309     /* If the current MIC context is valid and its key is the same as
1310      * the MIC register, there's nothing to do.
1311      */
1312     if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
1313         return;
1314 
1315     /* Age current mic Context */
1316     memcpy(old, cur, sizeof(*cur));
1317 
1318     /* Initialize new context */
1319     memcpy(cur->key, key, key_len);
1320     cur->window  = 33; /* Window always points to the middle */
1321     cur->rx      = 0;  /* Rx Sequence numbers */
1322     cur->tx      = 0;  /* Tx sequence numbers */
1323     cur->valid   = 1;  /* Key is now valid */
1324 
1325     /* Give key to mic seed */
1326     emmh32_setseed(&cur->seed, key, key_len, tfm);
1327 }
1328 
1329 /* micinit - Initialize mic seed */
1330 
1331 static void micinit(struct airo_info *ai)
1332 {
1333     MICRid mic_rid;
1334 
1335     clear_bit(JOB_MIC, &ai->jobs);
1336     PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1337     up(&ai->sem);
1338 
1339     ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
1340     if (!ai->micstats.enabled) {
1341         /* So next time we have a valid key and mic is enabled, we will
1342          * update the sequence number if the key is the same as before.
1343          */
1344         ai->mod[0].uCtx.valid = 0;
1345         ai->mod[0].mCtx.valid = 0;
1346         return;
1347     }
1348 
1349     if (mic_rid.multicastValid) {
1350         age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
1351                         mic_rid.multicast, sizeof(mic_rid.multicast),
1352                         ai->tfm);
1353     }
1354 
1355     if (mic_rid.unicastValid) {
1356         age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
1357                 mic_rid.unicast, sizeof(mic_rid.unicast),
1358                 ai->tfm);
1359     }
1360 }
1361 
1362 /* micsetup - Get ready for business */
1363 
1364 static int micsetup(struct airo_info *ai)
1365 {
1366     int i;
1367 
1368     if (ai->tfm == NULL)
1369         ai->tfm = crypto_alloc_sync_skcipher("ctr(aes)", 0, 0);
1370 
1371         if (IS_ERR(ai->tfm)) {
1372                 airo_print_err(ai->dev->name, "failed to load transform for AES");
1373                 ai->tfm = NULL;
1374                 return ERROR;
1375         }
1376 
1377     for (i = 0; i < NUM_MODULES; i++) {
1378         memset(&ai->mod[i].mCtx, 0, sizeof(miccntx));
1379         memset(&ai->mod[i].uCtx, 0, sizeof(miccntx));
1380     }
1381     return SUCCESS;
1382 }
1383 
1384 static const u8 micsnap[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
1385 
1386 /*===========================================================================
1387  * Description: Mic a packet
1388  *
1389  *      Inputs: etherHead * pointer to an 802.3 frame
1390  *
1391  *     Returns: BOOLEAN if successful, otherwise false.
1392  *             PacketTxLen will be updated with the mic'd packets size.
1393  *
1394  *    Caveats: It is assumed that the frame buffer will already
1395  *             be big enough to hold the largets mic message possible.
1396  *            (No memory allocation is done here).
1397  *
1398  *    Author: sbraneky (10/15/01)
1399  *    Merciless hacks by rwilcher (1/14/02)
1400  */
1401 
1402 static int encapsulate(struct airo_info *ai, etherHead *frame, MICBuffer *mic, int payLen)
1403 {
1404     miccntx   *context;
1405 
1406     // Determine correct context
1407     // If not adhoc, always use unicast key
1408 
1409     if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
1410         context = &ai->mod[0].mCtx;
1411     else
1412         context = &ai->mod[0].uCtx;
1413 
1414     if (!context->valid)
1415         return ERROR;
1416 
1417     mic->typelen = htons(payLen + 16); //Length of Mic'd packet
1418 
1419     memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
1420 
1421     // Add Tx sequence
1422     mic->seq = htonl(context->tx);
1423     context->tx += 2;
1424 
1425     emmh32_init(&context->seed); // Mic the packet
1426     emmh32_update(&context->seed, frame->da, ETH_ALEN * 2); // DA, SA
1427     emmh32_update(&context->seed, (u8*)&mic->typelen, 10); // Type/Length and Snap
1428     emmh32_update(&context->seed, (u8*)&mic->seq, sizeof(mic->seq)); //SEQ
1429     emmh32_update(&context->seed, (u8*)(frame + 1), payLen); //payload
1430     emmh32_final(&context->seed, (u8*)&mic->mic);
1431 
1432     /*    New Type/length ?????????? */
1433     mic->typelen = 0; //Let NIC know it could be an oversized packet
1434     return SUCCESS;
1435 }
1436 
1437 typedef enum {
1438     NONE,
1439     NOMIC,
1440     NOMICPLUMMED,
1441     SEQUENCE,
1442     INCORRECTMIC,
1443 } mic_error;
1444 
1445 /*===========================================================================
1446  *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet
1447  *               (removes the MIC stuff) if packet is a valid packet.
1448  *
1449  *       Inputs: etherHead  pointer to the 802.3 packet
1450  *
1451  *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
1452  *
1453  *      Author: sbraneky (10/15/01)
1454  *    Merciless hacks by rwilcher (1/14/02)
1455  *---------------------------------------------------------------------------
1456  */
1457 
1458 static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
1459 {
1460     int      i;
1461     u32      micSEQ;
1462     miccntx  *context;
1463     u8       digest[4];
1464     mic_error micError = NONE;
1465 
1466     // Check if the packet is a Mic'd packet
1467 
1468     if (!ai->micstats.enabled) {
1469         //No Mic set or Mic OFF but we received a MIC'd packet.
1470         if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
1471             ai->micstats.rxMICPlummed++;
1472             return ERROR;
1473         }
1474         return SUCCESS;
1475     }
1476 
1477     if (ntohs(mic->typelen) == 0x888E)
1478         return SUCCESS;
1479 
1480     if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
1481         // Mic enabled but packet isn't Mic'd
1482         ai->micstats.rxMICPlummed++;
1483             return ERROR;
1484     }
1485 
1486     micSEQ = ntohl(mic->seq);            //store SEQ as CPU order
1487 
1488     //At this point we a have a mic'd packet and mic is enabled
1489     //Now do the mic error checking.
1490 
1491     //Receive seq must be odd
1492     if ((micSEQ & 1) == 0) {
1493         ai->micstats.rxWrongSequence++;
1494         return ERROR;
1495     }
1496 
1497     for (i = 0; i < NUM_MODULES; i++) {
1498         int mcast = eth->da[0] & 1;
1499         //Determine proper context
1500         context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
1501 
1502         //Make sure context is valid
1503         if (!context->valid) {
1504             if (i == 0)
1505                 micError = NOMICPLUMMED;
1506             continue;
1507         }
1508         //DeMic it
1509 
1510         if (!mic->typelen)
1511             mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
1512 
1513         emmh32_init(&context->seed);
1514         emmh32_update(&context->seed, eth->da, ETH_ALEN*2);
1515         emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap));
1516         emmh32_update(&context->seed, (u8 *)&mic->seq, sizeof(mic->seq));
1517         emmh32_update(&context->seed, (u8 *)(eth + 1), payLen);
1518         //Calculate MIC
1519         emmh32_final(&context->seed, digest);
1520 
1521         if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
1522           //Invalid Mic
1523             if (i == 0)
1524                 micError = INCORRECTMIC;
1525             continue;
1526         }
1527 
1528         //Check Sequence number if mics pass
1529         if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
1530             ai->micstats.rxSuccess++;
1531             return SUCCESS;
1532         }
1533         if (i == 0)
1534             micError = SEQUENCE;
1535     }
1536 
1537     // Update statistics
1538     switch (micError) {
1539         case NOMICPLUMMED: ai->micstats.rxMICPlummed++;   break;
1540         case SEQUENCE:    ai->micstats.rxWrongSequence++; break;
1541         case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
1542         case NONE:  break;
1543         case NOMIC: break;
1544     }
1545     return ERROR;
1546 }
1547 
1548 /*===========================================================================
1549  * Description:  Checks the Rx Seq number to make sure it is valid
1550  *               and hasn't already been received
1551  *
1552  *     Inputs: miccntx - mic context to check seq against
1553  *             micSeq  - the Mic seq number
1554  *
1555  *    Returns: TRUE if valid otherwise FALSE.
1556  *
1557  *    Author: sbraneky (10/15/01)
1558  *    Merciless hacks by rwilcher (1/14/02)
1559  *---------------------------------------------------------------------------
1560  */
1561 
1562 static int RxSeqValid(struct airo_info *ai, miccntx *context, int mcast, u32 micSeq)
1563 {
1564     u32 seq, index;
1565 
1566     //Allow for the ap being rebooted - if it is then use the next
1567     //sequence number of the current sequence number - might go backwards
1568 
1569     if (mcast) {
1570         if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
1571             clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
1572             context->window = (micSeq > 33) ? micSeq : 33;
1573             context->rx     = 0;        // Reset rx
1574         }
1575     } else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
1576         clear_bit (FLAG_UPDATE_UNI, &ai->flags);
1577         context->window = (micSeq > 33) ? micSeq : 33; // Move window
1578         context->rx     = 0;        // Reset rx
1579     }
1580 
1581     //Make sequence number relative to START of window
1582     seq = micSeq - (context->window - 33);
1583 
1584     //Too old of a SEQ number to check.
1585     if ((s32)seq < 0)
1586         return ERROR;
1587 
1588     if (seq > 64) {
1589         //Window is infinite forward
1590         MoveWindow(context, micSeq);
1591         return SUCCESS;
1592     }
1593 
1594     // We are in the window. Now check the context rx bit to see if it was already sent
1595     seq >>= 1;         //divide by 2 because we only have odd numbers
1596     index = 1 << seq;  //Get an index number
1597 
1598     if (!(context->rx & index)) {
1599         //micSEQ falls inside the window.
1600         //Add seqence number to the list of received numbers.
1601         context->rx |= index;
1602 
1603         MoveWindow(context, micSeq);
1604 
1605         return SUCCESS;
1606     }
1607     return ERROR;
1608 }
1609 
1610 static void MoveWindow(miccntx *context, u32 micSeq)
1611 {
1612     u32 shift;
1613 
1614     //Move window if seq greater than the middle of the window
1615     if (micSeq > context->window) {
1616         shift = (micSeq - context->window) >> 1;
1617 
1618             //Shift out old
1619         if (shift < 32)
1620             context->rx >>= shift;
1621         else
1622             context->rx = 0;
1623 
1624         context->window = micSeq;      //Move window
1625     }
1626 }
1627 
1628 /*==============================================*/
1629 /*========== EMMH ROUTINES  ====================*/
1630 /*==============================================*/
1631 
1632 /* mic accumulate */
1633 #define MIC_ACCUM(val)  \
1634     context->accum += (u64)(val) * be32_to_cpu(context->coeff[coeff_position++]);
1635 
1636 /* expand the key to fill the MMH coefficient array */
1637 static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1638                struct crypto_sync_skcipher *tfm)
1639 {
1640   /* take the keying material, expand if necessary, truncate at 16-bytes */
1641   /* run through AES counter mode to generate context->coeff[] */
1642 
1643     SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
1644     struct scatterlist sg;
1645     u8 iv[AES_BLOCK_SIZE] = {};
1646     int ret;
1647 
1648     crypto_sync_skcipher_setkey(tfm, pkey, 16);
1649 
1650     memset(context->coeff, 0, sizeof(context->coeff));
1651     sg_init_one(&sg, context->coeff, sizeof(context->coeff));
1652 
1653     skcipher_request_set_sync_tfm(req, tfm);
1654     skcipher_request_set_callback(req, 0, NULL, NULL);
1655     skcipher_request_set_crypt(req, &sg, &sg, sizeof(context->coeff), iv);
1656 
1657     ret = crypto_skcipher_encrypt(req);
1658     WARN_ON_ONCE(ret);
1659 }
1660 
1661 /* prepare for calculation of a new mic */
1662 static void emmh32_init(emmh32_context *context)
1663 {
1664     /* prepare for new mic calculation */
1665     context->accum = 0;
1666     context->position = 0;
1667 }
1668 
1669 /* add some bytes to the mic calculation */
1670 static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1671 {
1672     int coeff_position, byte_position;
1673 
1674     if (len == 0) return;
1675 
1676     coeff_position = context->position >> 2;
1677 
1678     /* deal with partial 32-bit word left over from last update */
1679     byte_position = context->position & 3;
1680     if (byte_position) {
1681         /* have a partial word in part to deal with */
1682         do {
1683             if (len == 0) return;
1684             context->part.d8[byte_position++] = *pOctets++;
1685             context->position++;
1686             len--;
1687         } while (byte_position < 4);
1688         MIC_ACCUM(ntohl(context->part.d32));
1689     }
1690 
1691     /* deal with full 32-bit words */
1692     while (len >= 4) {
1693         MIC_ACCUM(ntohl(*(__be32 *)pOctets));
1694         context->position += 4;
1695         pOctets += 4;
1696         len -= 4;
1697     }
1698 
1699     /* deal with partial 32-bit word that will be left over from this update */
1700     byte_position = 0;
1701     while (len > 0) {
1702         context->part.d8[byte_position++] = *pOctets++;
1703         context->position++;
1704         len--;
1705     }
1706 }
1707 
1708 /* mask used to zero empty bytes for final partial word */
1709 static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1710 
1711 /* calculate the mic */
1712 static void emmh32_final(emmh32_context *context, u8 digest[4])
1713 {
1714     int coeff_position, byte_position;
1715     u32 val;
1716 
1717     u64 sum, utmp;
1718     s64 stmp;
1719 
1720     coeff_position = context->position >> 2;
1721 
1722     /* deal with partial 32-bit word left over from last update */
1723     byte_position = context->position & 3;
1724     if (byte_position) {
1725         /* have a partial word in part to deal with */
1726         val = ntohl(context->part.d32);
1727         MIC_ACCUM(val & mask32[byte_position]); /* zero empty bytes */
1728     }
1729 
1730     /* reduce the accumulated u64 to a 32-bit MIC */
1731     sum = context->accum;
1732     stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);
1733     utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
1734     sum = utmp & 0xffffffffLL;
1735     if (utmp > 0x10000000fLL)
1736         sum -= 15;
1737 
1738     val = (u32)sum;
1739     digest[0] = (val>>24) & 0xFF;
1740     digest[1] = (val>>16) & 0xFF;
1741     digest[2] = (val>>8) & 0xFF;
1742     digest[3] = val & 0xFF;
1743 }
1744 
1745 static int readBSSListRid(struct airo_info *ai, int first,
1746               BSSListRid *list)
1747 {
1748     Cmd cmd;
1749     Resp rsp;
1750 
1751     if (first == 1) {
1752         if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
1753         memset(&cmd, 0, sizeof(cmd));
1754         cmd.cmd = CMD_LISTBSS;
1755         if (down_interruptible(&ai->sem))
1756             return -ERESTARTSYS;
1757         ai->list_bss_task = current;
1758         issuecommand(ai, &cmd, &rsp, true);
1759         up(&ai->sem);
1760         /* Let the command take effect */
1761         schedule_timeout_uninterruptible(3 * HZ);
1762         ai->list_bss_task = NULL;
1763     }
1764     return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
1765                 list, ai->bssListRidLen, 1);
1766 }
1767 
1768 static int readWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int temp, int lock)
1769 {
1770     return PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
1771                 wkr, sizeof(*wkr), lock);
1772 }
1773 
1774 static int writeWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int perm, int lock)
1775 {
1776     int rc;
1777     rc = PC4500_writerid(ai, RID_WEP_TEMP, wkr, sizeof(*wkr), lock);
1778     if (rc!=SUCCESS)
1779         airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
1780     if (perm) {
1781         rc = PC4500_writerid(ai, RID_WEP_PERM, wkr, sizeof(*wkr), lock);
1782         if (rc!=SUCCESS)
1783             airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
1784     }
1785     return rc;
1786 }
1787 
1788 static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
1789 {
1790     return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1791 }
1792 
1793 static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
1794 {
1795     return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
1796 }
1797 
1798 static int readConfigRid(struct airo_info *ai, int lock)
1799 {
1800     int rc;
1801     ConfigRid cfg;
1802 
1803     if (ai->config.len)
1804         return SUCCESS;
1805 
1806     rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
1807     if (rc != SUCCESS)
1808         return rc;
1809 
1810     ai->config = cfg;
1811     return SUCCESS;
1812 }
1813 
1814 static inline void checkThrottle(struct airo_info *ai)
1815 {
1816     int i;
1817 /* Old hardware had a limit on encryption speed */
1818     if (ai->config.authType != AUTH_OPEN && maxencrypt) {
1819         for (i = 0; i<8; i++) {
1820             if (ai->config.rates[i] > maxencrypt) {
1821                 ai->config.rates[i] = 0;
1822             }
1823         }
1824     }
1825 }
1826 
1827 static int writeConfigRid(struct airo_info *ai, int lock)
1828 {
1829     ConfigRid cfgr;
1830 
1831     if (!test_bit (FLAG_COMMIT, &ai->flags))
1832         return SUCCESS;
1833 
1834     clear_bit (FLAG_COMMIT, &ai->flags);
1835     clear_bit (FLAG_RESET, &ai->flags);
1836     checkThrottle(ai);
1837     cfgr = ai->config;
1838 
1839     if ((cfgr.opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
1840         set_bit(FLAG_ADHOC, &ai->flags);
1841     else
1842         clear_bit(FLAG_ADHOC, &ai->flags);
1843 
1844     return PC4500_writerid(ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1845 }
1846 
1847 static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
1848 {
1849     return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1850 }
1851 
1852 static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
1853 {
1854     return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
1855 }
1856 
1857 static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
1858 {
1859     return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1860 }
1861 
1862 static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
1863 {
1864     return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1865 }
1866 
1867 static void try_auto_wep(struct airo_info *ai)
1868 {
1869     if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
1870         ai->expires = RUN_AT(3*HZ);
1871         wake_up_interruptible(&ai->thr_wait);
1872     }
1873 }
1874 
1875 static int airo_open(struct net_device *dev)
1876 {
1877     struct airo_info *ai = dev->ml_priv;
1878     int rc = 0;
1879 
1880     if (test_bit(FLAG_FLASHING, &ai->flags))
1881         return -EIO;
1882 
1883     /* Make sure the card is configured.
1884      * Wireless Extensions may postpone config changes until the card
1885      * is open (to pipeline changes and speed-up card setup). If
1886      * those changes are not yet committed, do it now - Jean II */
1887     if (test_bit(FLAG_COMMIT, &ai->flags)) {
1888         disable_MAC(ai, 1);
1889         writeConfigRid(ai, 1);
1890     }
1891 
1892     if (ai->wifidev != dev) {
1893         clear_bit(JOB_DIE, &ai->jobs);
1894         ai->airo_thread_task = kthread_run(airo_thread, dev, "%s",
1895                            dev->name);
1896         if (IS_ERR(ai->airo_thread_task))
1897             return (int)PTR_ERR(ai->airo_thread_task);
1898 
1899         rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
1900             dev->name, dev);
1901         if (rc) {
1902             airo_print_err(dev->name,
1903                 "register interrupt %d failed, rc %d",
1904                 dev->irq, rc);
1905             set_bit(JOB_DIE, &ai->jobs);
1906             kthread_stop(ai->airo_thread_task);
1907             return rc;
1908         }
1909 
1910         /* Power on the MAC controller (which may have been disabled) */
1911         clear_bit(FLAG_RADIO_DOWN, &ai->flags);
1912         enable_interrupts(ai);
1913 
1914         try_auto_wep(ai);
1915     }
1916     enable_MAC(ai, 1);
1917 
1918     netif_start_queue(dev);
1919     return 0;
1920 }
1921 
1922 static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
1923                     struct net_device *dev)
1924 {
1925     int npacks, pending;
1926     unsigned long flags;
1927     struct airo_info *ai = dev->ml_priv;
1928 
1929     if (!skb) {
1930         airo_print_err(dev->name, "%s: skb == NULL!",__func__);
1931         return NETDEV_TX_OK;
1932     }
1933     if (skb_padto(skb, ETH_ZLEN)) {
1934         dev->stats.tx_dropped++;
1935         return NETDEV_TX_OK;
1936     }
1937     npacks = skb_queue_len (&ai->txq);
1938 
1939     if (npacks >= MAXTXQ - 1) {
1940         netif_stop_queue (dev);
1941         if (npacks > MAXTXQ) {
1942             dev->stats.tx_fifo_errors++;
1943             return NETDEV_TX_BUSY;
1944         }
1945         skb_queue_tail (&ai->txq, skb);
1946         return NETDEV_TX_OK;
1947     }
1948 
1949     spin_lock_irqsave(&ai->aux_lock, flags);
1950     skb_queue_tail (&ai->txq, skb);
1951     pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
1952     spin_unlock_irqrestore(&ai->aux_lock, flags);
1953     netif_wake_queue (dev);
1954 
1955     if (pending == 0) {
1956         set_bit(FLAG_PENDING_XMIT, &ai->flags);
1957         mpi_send_packet (dev);
1958     }
1959     return NETDEV_TX_OK;
1960 }
1961 
1962 /*
1963  * @mpi_send_packet
1964  *
1965  * Attempt to transmit a packet. Can be called from interrupt
1966  * or transmit . return number of packets we tried to send
1967  */
1968 
1969 static int mpi_send_packet (struct net_device *dev)
1970 {
1971     struct sk_buff *skb;
1972     unsigned char *buffer;
1973     s16 len;
1974     __le16 *payloadLen;
1975     struct airo_info *ai = dev->ml_priv;
1976     u8 *sendbuf;
1977 
1978     /* get a packet to send */
1979 
1980     if ((skb = skb_dequeue(&ai->txq)) == NULL) {
1981         airo_print_err(dev->name,
1982             "%s: Dequeue'd zero in send_packet()",
1983             __func__);
1984         return 0;
1985     }
1986 
1987     /* check min length*/
1988     len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1989     buffer = skb->data;
1990 
1991     ai->txfids[0].tx_desc.offset = 0;
1992     ai->txfids[0].tx_desc.valid = 1;
1993     ai->txfids[0].tx_desc.eoc = 1;
1994     ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
1995 
1996 /*
1997  * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
1998  * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
1999  * is immediately after it. ------------------------------------------------
2000  *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
2001  *                         ------------------------------------------------
2002  */
2003 
2004     memcpy(ai->txfids[0].virtual_host_addr,
2005         (char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
2006 
2007     payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
2008         sizeof(wifictlhdr8023));
2009     sendbuf = ai->txfids[0].virtual_host_addr +
2010         sizeof(wifictlhdr8023) + 2 ;
2011 
2012     /*
2013      * Firmware automatically puts 802 header on so
2014      * we don't need to account for it in the length
2015      */
2016     if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
2017         (ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
2018         MICBuffer pMic;
2019 
2020         if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
2021             return ERROR;
2022 
2023         *payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
2024         ai->txfids[0].tx_desc.len += sizeof(pMic);
2025         /* copy data into airo dma buffer */
2026         memcpy (sendbuf, buffer, sizeof(etherHead));
2027         buffer += sizeof(etherHead);
2028         sendbuf += sizeof(etherHead);
2029         memcpy (sendbuf, &pMic, sizeof(pMic));
2030         sendbuf += sizeof(pMic);
2031         memcpy (sendbuf, buffer, len - sizeof(etherHead));
2032     } else {
2033         *payloadLen = cpu_to_le16(len - sizeof(etherHead));
2034 
2035         netif_trans_update(dev);
2036 
2037         /* copy data into airo dma buffer */
2038         memcpy(sendbuf, buffer, len);
2039     }
2040 
2041     memcpy_toio(ai->txfids[0].card_ram_off,
2042         &ai->txfids[0].tx_desc, sizeof(TxFid));
2043 
2044     OUT4500(ai, EVACK, 8);
2045 
2046     dev_kfree_skb_any(skb);
2047     return 1;
2048 }
2049 
2050 static void get_tx_error(struct airo_info *ai, s32 fid)
2051 {
2052     __le16 status;
2053 
2054     if (fid < 0)
2055         status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
2056     else {
2057         if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
2058             return;
2059         bap_read(ai, &status, 2, BAP0);
2060     }
2061     if (le16_to_cpu(status) & 2) /* Too many retries */
2062         ai->dev->stats.tx_aborted_errors++;
2063     if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
2064         ai->dev->stats.tx_heartbeat_errors++;
2065     if (le16_to_cpu(status) & 8) /* Aid fail */
2066         { }
2067     if (le16_to_cpu(status) & 0x10) /* MAC disabled */
2068         ai->dev->stats.tx_carrier_errors++;
2069     if (le16_to_cpu(status) & 0x20) /* Association lost */
2070         { }
2071     /* We produce a TXDROP event only for retry or lifetime
2072      * exceeded, because that's the only status that really mean
2073      * that this particular node went away.
2074      * Other errors means that *we* screwed up. - Jean II */
2075     if ((le16_to_cpu(status) & 2) ||
2076          (le16_to_cpu(status) & 4)) {
2077         union iwreq_data    wrqu;
2078         char junk[0x18];
2079 
2080         /* Faster to skip over useless data than to do
2081          * another bap_setup(). We are at offset 0x6 and
2082          * need to go to 0x18 and read 6 bytes - Jean II */
2083         bap_read(ai, (__le16 *) junk, 0x18, BAP0);
2084 
2085         /* Copy 802.11 dest address.
2086          * We use the 802.11 header because the frame may
2087          * not be 802.3 or may be mangled...
2088          * In Ad-Hoc mode, it will be the node address.
2089          * In managed mode, it will be most likely the AP addr
2090          * User space will figure out how to convert it to
2091          * whatever it needs (IP address or else).
2092          * - Jean II */
2093         memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
2094         wrqu.addr.sa_family = ARPHRD_ETHER;
2095 
2096         /* Send event to user space */
2097         wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
2098     }
2099 }
2100 
2101 static void airo_end_xmit(struct net_device *dev, bool may_sleep)
2102 {
2103     u16 status;
2104     int i;
2105     struct airo_info *priv = dev->ml_priv;
2106     struct sk_buff *skb = priv->xmit.skb;
2107     int fid = priv->xmit.fid;
2108     u32 *fids = priv->fids;
2109 
2110     clear_bit(JOB_XMIT, &priv->jobs);
2111     clear_bit(FLAG_PENDING_XMIT, &priv->flags);
2112     status = transmit_802_3_packet(priv, fids[fid], skb->data, may_sleep);
2113     up(&priv->sem);
2114 
2115     i = 0;
2116     if (status == SUCCESS) {
2117         netif_trans_update(dev);
2118         for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
2119     } else {
2120         priv->fids[fid] &= 0xffff;
2121         dev->stats.tx_window_errors++;
2122     }
2123     if (i < MAX_FIDS / 2)
2124         netif_wake_queue(dev);
2125     dev_kfree_skb(skb);
2126 }
2127 
2128 static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
2129                      struct net_device *dev)
2130 {
2131     s16 len;
2132     int i, j;
2133     struct airo_info *priv = dev->ml_priv;
2134     u32 *fids = priv->fids;
2135 
2136     if (skb == NULL) {
2137         airo_print_err(dev->name, "%s: skb == NULL!", __func__);
2138         return NETDEV_TX_OK;
2139     }
2140     if (skb_padto(skb, ETH_ZLEN)) {
2141         dev->stats.tx_dropped++;
2142         return NETDEV_TX_OK;
2143     }
2144 
2145     /* Find a vacant FID */
2146     for (i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++);
2147     for (j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++);
2148 
2149     if (j >= MAX_FIDS / 2) {
2150         netif_stop_queue(dev);
2151 
2152         if (i == MAX_FIDS / 2) {
2153             dev->stats.tx_fifo_errors++;
2154             return NETDEV_TX_BUSY;
2155         }
2156     }
2157     /* check min length*/
2158     len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2159         /* Mark fid as used & save length for later */
2160     fids[i] |= (len << 16);
2161     priv->xmit.skb = skb;
2162     priv->xmit.fid = i;
2163     if (down_trylock(&priv->sem) != 0) {
2164         set_bit(FLAG_PENDING_XMIT, &priv->flags);
2165         netif_stop_queue(dev);
2166         set_bit(JOB_XMIT, &priv->jobs);
2167         wake_up_interruptible(&priv->thr_wait);
2168     } else
2169         airo_end_xmit(dev, false);
2170     return NETDEV_TX_OK;
2171 }
2172 
2173 static void airo_end_xmit11(struct net_device *dev, bool may_sleep)
2174 {
2175     u16 status;
2176     int i;
2177     struct airo_info *priv = dev->ml_priv;
2178     struct sk_buff *skb = priv->xmit11.skb;
2179     int fid = priv->xmit11.fid;
2180     u32 *fids = priv->fids;
2181 
2182     clear_bit(JOB_XMIT11, &priv->jobs);
2183     clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
2184     status = transmit_802_11_packet(priv, fids[fid], skb->data, may_sleep);
2185     up(&priv->sem);
2186 
2187     i = MAX_FIDS / 2;
2188     if (status == SUCCESS) {
2189         netif_trans_update(dev);
2190         for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
2191     } else {
2192         priv->fids[fid] &= 0xffff;
2193         dev->stats.tx_window_errors++;
2194     }
2195     if (i < MAX_FIDS)
2196         netif_wake_queue(dev);
2197     dev_kfree_skb(skb);
2198 }
2199 
2200 static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
2201                        struct net_device *dev)
2202 {
2203     s16 len;
2204     int i, j;
2205     struct airo_info *priv = dev->ml_priv;
2206     u32 *fids = priv->fids;
2207 
2208     if (test_bit(FLAG_MPI, &priv->flags)) {
2209         /* Not implemented yet for MPI350 */
2210         netif_stop_queue(dev);
2211         dev_kfree_skb_any(skb);
2212         return NETDEV_TX_OK;
2213     }
2214 
2215     if (skb == NULL) {
2216         airo_print_err(dev->name, "%s: skb == NULL!", __func__);
2217         return NETDEV_TX_OK;
2218     }
2219     if (skb_padto(skb, ETH_ZLEN)) {
2220         dev->stats.tx_dropped++;
2221         return NETDEV_TX_OK;
2222     }
2223 
2224     /* Find a vacant FID */
2225     for (i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++);
2226     for (j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++);
2227 
2228     if (j >= MAX_FIDS) {
2229         netif_stop_queue(dev);
2230 
2231         if (i == MAX_FIDS) {
2232             dev->stats.tx_fifo_errors++;
2233             return NETDEV_TX_BUSY;
2234         }
2235     }
2236     /* check min length*/
2237     len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2238         /* Mark fid as used & save length for later */
2239     fids[i] |= (len << 16);
2240     priv->xmit11.skb = skb;
2241     priv->xmit11.fid = i;
2242     if (down_trylock(&priv->sem) != 0) {
2243         set_bit(FLAG_PENDING_XMIT11, &priv->flags);
2244         netif_stop_queue(dev);
2245         set_bit(JOB_XMIT11, &priv->jobs);
2246         wake_up_interruptible(&priv->thr_wait);
2247     } else
2248         airo_end_xmit11(dev, false);
2249     return NETDEV_TX_OK;
2250 }
2251 
2252 static void airo_read_stats(struct net_device *dev)
2253 {
2254     struct airo_info *ai = dev->ml_priv;
2255     StatsRid stats_rid;
2256     __le32 *vals = stats_rid.vals;
2257 
2258     clear_bit(JOB_STATS, &ai->jobs);
2259     if (ai->power.event) {
2260         up(&ai->sem);
2261         return;
2262     }
2263     readStatsRid(ai, &stats_rid, RID_STATS, 0);
2264     up(&ai->sem);
2265 
2266     dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
2267                    le32_to_cpu(vals[45]);
2268     dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
2269                    le32_to_cpu(vals[41]);
2270     dev->stats.rx_bytes = le32_to_cpu(vals[92]);
2271     dev->stats.tx_bytes = le32_to_cpu(vals[91]);
2272     dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
2273                   le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
2274     dev->stats.tx_errors = le32_to_cpu(vals[42]) +
2275                   dev->stats.tx_fifo_errors;
2276     dev->stats.multicast = le32_to_cpu(vals[43]);
2277     dev->stats.collisions = le32_to_cpu(vals[89]);
2278 
2279     /* detailed rx_errors: */
2280     dev->stats.rx_length_errors = le32_to_cpu(vals[3]);
2281     dev->stats.rx_crc_errors = le32_to_cpu(vals[4]);
2282     dev->stats.rx_frame_errors = le32_to_cpu(vals[2]);
2283     dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
2284 }
2285 
2286 static struct net_device_stats *airo_get_stats(struct net_device *dev)
2287 {
2288     struct airo_info *local =  dev->ml_priv;
2289 
2290     if (!test_bit(JOB_STATS, &local->jobs)) {
2291         set_bit(JOB_STATS, &local->jobs);
2292         wake_up_interruptible(&local->thr_wait);
2293     }
2294 
2295     return &dev->stats;
2296 }
2297 
2298 static void airo_set_promisc(struct airo_info *ai, bool may_sleep)
2299 {
2300     Cmd cmd;
2301     Resp rsp;
2302 
2303     memset(&cmd, 0, sizeof(cmd));
2304     cmd.cmd = CMD_SETMODE;
2305     clear_bit(JOB_PROMISC, &ai->jobs);
2306     cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
2307     issuecommand(ai, &cmd, &rsp, may_sleep);
2308     up(&ai->sem);
2309 }
2310 
2311 static void airo_set_multicast_list(struct net_device *dev)
2312 {
2313     struct airo_info *ai = dev->ml_priv;
2314 
2315     if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
2316         change_bit(FLAG_PROMISC, &ai->flags);
2317         if (down_trylock(&ai->sem) != 0) {
2318             set_bit(JOB_PROMISC, &ai->jobs);
2319             wake_up_interruptible(&ai->thr_wait);
2320         } else
2321             airo_set_promisc(ai, false);
2322     }
2323 
2324     if ((dev->flags&IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
2325         /* Turn on multicast.  (Should be already setup...) */
2326     }
2327 }
2328 
2329 static int airo_set_mac_address(struct net_device *dev, void *p)
2330 {
2331     struct airo_info *ai = dev->ml_priv;
2332     struct sockaddr *addr = p;
2333 
2334     readConfigRid(ai, 1);
2335     memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
2336     set_bit (FLAG_COMMIT, &ai->flags);
2337     disable_MAC(ai, 1);
2338     writeConfigRid (ai, 1);
2339     enable_MAC(ai, 1);
2340     dev_addr_set(ai->dev, addr->sa_data);
2341     if (ai->wifidev)
2342         dev_addr_set(ai->wifidev, addr->sa_data);
2343     return 0;
2344 }
2345 
2346 static LIST_HEAD(airo_devices);
2347 
2348 static void add_airo_dev(struct airo_info *ai)
2349 {
2350     /* Upper layers already keep track of PCI devices,
2351      * so we only need to remember our non-PCI cards. */
2352     if (!ai->pci)
2353         list_add_tail(&ai->dev_list, &airo_devices);
2354 }
2355 
2356 static void del_airo_dev(struct airo_info *ai)
2357 {
2358     if (!ai->pci)
2359         list_del(&ai->dev_list);
2360 }
2361 
2362 static int airo_close(struct net_device *dev)
2363 {
2364     struct airo_info *ai = dev->ml_priv;
2365 
2366     netif_stop_queue(dev);
2367 
2368     if (ai->wifidev != dev) {
2369 #ifdef POWER_ON_DOWN
2370         /* Shut power to the card. The idea is that the user can save
2371          * power when he doesn't need the card with "ifconfig down".
2372          * That's the method that is most friendly towards the network
2373          * stack (i.e. the network stack won't try to broadcast
2374          * anything on the interface and routes are gone. Jean II */
2375         set_bit(FLAG_RADIO_DOWN, &ai->flags);
2376         disable_MAC(ai, 1);
2377 #endif
2378         disable_interrupts(ai);
2379 
2380         free_irq(dev->irq, dev);
2381 
2382         set_bit(JOB_DIE, &ai->jobs);
2383         kthread_stop(ai->airo_thread_task);
2384     }
2385     return 0;
2386 }
2387 
2388 void stop_airo_card(struct net_device *dev, int freeres)
2389 {
2390     struct airo_info *ai = dev->ml_priv;
2391 
2392     set_bit(FLAG_RADIO_DOWN, &ai->flags);
2393     disable_MAC(ai, 1);
2394     disable_interrupts(ai);
2395     takedown_proc_entry(dev, ai);
2396     if (test_bit(FLAG_REGISTERED, &ai->flags)) {
2397         unregister_netdev(dev);
2398         if (ai->wifidev) {
2399             unregister_netdev(ai->wifidev);
2400             free_netdev(ai->wifidev);
2401             ai->wifidev = NULL;
2402         }
2403         clear_bit(FLAG_REGISTERED, &ai->flags);
2404     }
2405     /*
2406      * Clean out tx queue
2407      */
2408     if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
2409         struct sk_buff *skb = NULL;
2410         for (;(skb = skb_dequeue(&ai->txq));)
2411             dev_kfree_skb(skb);
2412     }
2413 
2414     airo_networks_free (ai);
2415 
2416     kfree(ai->flash);
2417     kfree(ai->rssi);
2418     kfree(ai->SSID);
2419     if (freeres) {
2420         /* PCMCIA frees this stuff, so only for PCI and ISA */
2421         release_region(dev->base_addr, 64);
2422         if (test_bit(FLAG_MPI, &ai->flags)) {
2423             if (ai->pci)
2424                 mpi_unmap_card(ai->pci);
2425             if (ai->pcimem)
2426                 iounmap(ai->pcimem);
2427             if (ai->pciaux)
2428                 iounmap(ai->pciaux);
2429             dma_free_coherent(&ai->pci->dev, PCI_SHARED_LEN,
2430                       ai->shared, ai->shared_dma);
2431         }
2432         }
2433     crypto_free_sync_skcipher(ai->tfm);
2434     del_airo_dev(ai);
2435     free_netdev(dev);
2436 }
2437 
2438 EXPORT_SYMBOL(stop_airo_card);
2439 
2440 static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr)
2441 {
2442     memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
2443     return ETH_ALEN;
2444 }
2445 
2446 static void mpi_unmap_card(struct pci_dev *pci)
2447 {
2448     unsigned long mem_start = pci_resource_start(pci, 1);
2449     unsigned long mem_len = pci_resource_len(pci, 1);
2450     unsigned long aux_start = pci_resource_start(pci, 2);
2451     unsigned long aux_len = AUXMEMSIZE;
2452 
2453     release_mem_region(aux_start, aux_len);
2454     release_mem_region(mem_start, mem_len);
2455 }
2456 
2457 /*************************************************************
2458  *  This routine assumes that descriptors have been setup .
2459  *  Run at insmod time or after reset when the descriptors
2460  *  have been initialized . Returns 0 if all is well nz
2461  *  otherwise . Does not allocate memory but sets up card
2462  *  using previously allocated descriptors.
2463  */
2464 static int mpi_init_descriptors (struct airo_info *ai)
2465 {
2466     Cmd cmd;
2467     Resp rsp;
2468     int i;
2469     int rc = SUCCESS;
2470 
2471     /* Alloc  card RX descriptors */
2472     netif_stop_queue(ai->dev);
2473 
2474     memset(&rsp, 0, sizeof(rsp));
2475     memset(&cmd, 0, sizeof(cmd));
2476 
2477     cmd.cmd = CMD_ALLOCATEAUX;
2478     cmd.parm0 = FID_RX;
2479     cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
2480     cmd.parm2 = MPI_MAX_FIDS;
2481     rc = issuecommand(ai, &cmd, &rsp, true);
2482     if (rc != SUCCESS) {
2483         airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
2484         return rc;
2485     }
2486 
2487     for (i = 0; i<MPI_MAX_FIDS; i++) {
2488         memcpy_toio(ai->rxfids[i].card_ram_off,
2489             &ai->rxfids[i].rx_desc, sizeof(RxFid));
2490     }
2491 
2492     /* Alloc card TX descriptors */
2493 
2494     memset(&rsp, 0, sizeof(rsp));
2495     memset(&cmd, 0, sizeof(cmd));
2496 
2497     cmd.cmd = CMD_ALLOCATEAUX;
2498     cmd.parm0 = FID_TX;
2499     cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
2500     cmd.parm2 = MPI_MAX_FIDS;
2501 
2502     for (i = 0; i<MPI_MAX_FIDS; i++) {
2503         ai->txfids[i].tx_desc.valid = 1;
2504         memcpy_toio(ai->txfids[i].card_ram_off,
2505             &ai->txfids[i].tx_desc, sizeof(TxFid));
2506     }
2507     ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2508 
2509     rc = issuecommand(ai, &cmd, &rsp, true);
2510     if (rc != SUCCESS) {
2511         airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
2512         return rc;
2513     }
2514 
2515     /* Alloc card Rid descriptor */
2516     memset(&rsp, 0, sizeof(rsp));
2517     memset(&cmd, 0, sizeof(cmd));
2518 
2519     cmd.cmd = CMD_ALLOCATEAUX;
2520     cmd.parm0 = RID_RW;
2521     cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
2522     cmd.parm2 = 1; /* Magic number... */
2523     rc = issuecommand(ai, &cmd, &rsp, true);
2524     if (rc != SUCCESS) {
2525         airo_print_err(ai->dev->name, "Couldn't allocate RID");
2526         return rc;
2527     }
2528 
2529     memcpy_toio(ai->config_desc.card_ram_off,
2530         &ai->config_desc.rid_desc, sizeof(Rid));
2531 
2532     return rc;
2533 }
2534 
2535 /*
2536  * We are setting up three things here:
2537  * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
2538  * 2) Map PCI memory for issuing commands.
2539  * 3) Allocate memory (shared) to send and receive ethernet frames.
2540  */
2541 static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
2542 {
2543     unsigned long mem_start, mem_len, aux_start, aux_len;
2544     int rc = -1;
2545     int i;
2546     dma_addr_t busaddroff;
2547     unsigned char *vpackoff;
2548     unsigned char __iomem *pciaddroff;
2549 
2550     mem_start = pci_resource_start(pci, 1);
2551     mem_len = pci_resource_len(pci, 1);
2552     aux_start = pci_resource_start(pci, 2);
2553     aux_len = AUXMEMSIZE;
2554 
2555     if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
2556         airo_print_err("", "Couldn't get region %x[%x]",
2557             (int)mem_start, (int)mem_len);
2558         goto out;
2559     }
2560     if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
2561         airo_print_err("", "Couldn't get region %x[%x]",
2562             (int)aux_start, (int)aux_len);
2563         goto free_region1;
2564     }
2565 
2566     ai->pcimem = ioremap(mem_start, mem_len);
2567     if (!ai->pcimem) {
2568         airo_print_err("", "Couldn't map region %x[%x]",
2569             (int)mem_start, (int)mem_len);
2570         goto free_region2;
2571     }
2572     ai->pciaux = ioremap(aux_start, aux_len);
2573     if (!ai->pciaux) {
2574         airo_print_err("", "Couldn't map region %x[%x]",
2575             (int)aux_start, (int)aux_len);
2576         goto free_memmap;
2577     }
2578 
2579     /* Reserve PKTSIZE for each fid and 2K for the Rids */
2580     ai->shared = dma_alloc_coherent(&pci->dev, PCI_SHARED_LEN,
2581                     &ai->shared_dma, GFP_KERNEL);
2582     if (!ai->shared) {
2583         airo_print_err("", "Couldn't alloc_coherent %d",
2584             PCI_SHARED_LEN);
2585         goto free_auxmap;
2586     }
2587 
2588     /*
2589      * Setup descriptor RX, TX, CONFIG
2590      */
2591     busaddroff = ai->shared_dma;
2592     pciaddroff = ai->pciaux + AUX_OFFSET;
2593     vpackoff   = ai->shared;
2594 
2595     /* RX descriptor setup */
2596     for (i = 0; i < MPI_MAX_FIDS; i++) {
2597         ai->rxfids[i].pending = 0;
2598         ai->rxfids[i].card_ram_off = pciaddroff;
2599         ai->rxfids[i].virtual_host_addr = vpackoff;
2600         ai->rxfids[i].rx_desc.host_addr = busaddroff;
2601         ai->rxfids[i].rx_desc.valid = 1;
2602         ai->rxfids[i].rx_desc.len = PKTSIZE;
2603         ai->rxfids[i].rx_desc.rdy = 0;
2604 
2605         pciaddroff += sizeof(RxFid);
2606         busaddroff += PKTSIZE;
2607         vpackoff   += PKTSIZE;
2608     }
2609 
2610     /* TX descriptor setup */
2611     for (i = 0; i < MPI_MAX_FIDS; i++) {
2612         ai->txfids[i].card_ram_off = pciaddroff;
2613         ai->txfids[i].virtual_host_addr = vpackoff;
2614         ai->txfids[i].tx_desc.valid = 1;
2615         ai->txfids[i].tx_desc.host_addr = busaddroff;
2616         memcpy(ai->txfids[i].virtual_host_addr,
2617             &wifictlhdr8023, sizeof(wifictlhdr8023));
2618 
2619         pciaddroff += sizeof(TxFid);
2620         busaddroff += PKTSIZE;
2621         vpackoff   += PKTSIZE;
2622     }
2623     ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2624 
2625     /* Rid descriptor setup */
2626     ai->config_desc.card_ram_off = pciaddroff;
2627     ai->config_desc.virtual_host_addr = vpackoff;
2628     ai->config_desc.rid_desc.host_addr = busaddroff;
2629     ai->ridbus = busaddroff;
2630     ai->config_desc.rid_desc.rid = 0;
2631     ai->config_desc.rid_desc.len = RIDSIZE;
2632     ai->config_desc.rid_desc.valid = 1;
2633     pciaddroff += sizeof(Rid);
2634     busaddroff += RIDSIZE;
2635     vpackoff   += RIDSIZE;
2636 
2637     /* Tell card about descriptors */
2638     if (mpi_init_descriptors (ai) != SUCCESS)
2639         goto free_shared;
2640 
2641     return 0;
2642  free_shared:
2643     dma_free_coherent(&pci->dev, PCI_SHARED_LEN, ai->shared,
2644               ai->shared_dma);
2645  free_auxmap:
2646     iounmap(ai->pciaux);
2647  free_memmap:
2648     iounmap(ai->pcimem);
2649  free_region2:
2650     release_mem_region(aux_start, aux_len);
2651  free_region1:
2652     release_mem_region(mem_start, mem_len);
2653  out:
2654     return rc;
2655 }
2656 
2657 static const struct header_ops airo_header_ops = {
2658     .parse = wll_header_parse,
2659 };
2660 
2661 static const struct net_device_ops airo11_netdev_ops = {
2662     .ndo_open       = airo_open,
2663     .ndo_stop       = airo_close,
2664     .ndo_start_xmit     = airo_start_xmit11,
2665     .ndo_get_stats      = airo_get_stats,
2666     .ndo_set_mac_address    = airo_set_mac_address,
2667     .ndo_siocdevprivate = airo_siocdevprivate,
2668 };
2669 
2670 static void wifi_setup(struct net_device *dev)
2671 {
2672     dev->netdev_ops = &airo11_netdev_ops;
2673     dev->header_ops = &airo_header_ops;
2674     dev->wireless_handlers = &airo_handler_def;
2675 
2676     dev->type               = ARPHRD_IEEE80211;
2677     dev->hard_header_len    = ETH_HLEN;
2678     dev->mtu                = AIRO_DEF_MTU;
2679     dev->min_mtu            = 68;
2680     dev->max_mtu            = MIC_MSGLEN_MAX;
2681     dev->addr_len           = ETH_ALEN;
2682     dev->tx_queue_len       = 100;
2683 
2684     eth_broadcast_addr(dev->broadcast);
2685 
2686     dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
2687 }
2688 
2689 static struct net_device *init_wifidev(struct airo_info *ai,
2690                     struct net_device *ethdev)
2691 {
2692     int err;
2693     struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN,
2694                           wifi_setup);
2695     if (!dev)
2696         return NULL;
2697     dev->ml_priv = ethdev->ml_priv;
2698     dev->irq = ethdev->irq;
2699     dev->base_addr = ethdev->base_addr;
2700     dev->wireless_data = ethdev->wireless_data;
2701     SET_NETDEV_DEV(dev, ethdev->dev.parent);
2702     eth_hw_addr_inherit(dev, ethdev);
2703     err = register_netdev(dev);
2704     if (err<0) {
2705         free_netdev(dev);
2706         return NULL;
2707     }
2708     return dev;
2709 }
2710 
2711 static int reset_card(struct net_device *dev, int lock)
2712 {
2713     struct airo_info *ai = dev->ml_priv;
2714 
2715     if (lock && down_interruptible(&ai->sem))
2716         return -1;
2717     waitbusy (ai);
2718     OUT4500(ai, COMMAND, CMD_SOFTRESET);
2719     msleep(200);
2720     waitbusy (ai);
2721     msleep(200);
2722     if (lock)
2723         up(&ai->sem);
2724     return 0;
2725 }
2726 
2727 #define AIRO_MAX_NETWORK_COUNT  64
2728 static int airo_networks_allocate(struct airo_info *ai)
2729 {
2730     if (ai->networks)
2731         return 0;
2732 
2733     ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
2734                    GFP_KERNEL);
2735     if (!ai->networks) {
2736         airo_print_warn("", "Out of memory allocating beacons");
2737         return -ENOMEM;
2738     }
2739 
2740     return 0;
2741 }
2742 
2743 static void airo_networks_free(struct airo_info *ai)
2744 {
2745     kfree(ai->networks);
2746     ai->networks = NULL;
2747 }
2748 
2749 static void airo_networks_initialize(struct airo_info *ai)
2750 {
2751     int i;
2752 
2753     INIT_LIST_HEAD(&ai->network_free_list);
2754     INIT_LIST_HEAD(&ai->network_list);
2755     for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
2756         list_add_tail(&ai->networks[i].list,
2757                   &ai->network_free_list);
2758 }
2759 
2760 static const struct net_device_ops airo_netdev_ops = {
2761     .ndo_open       = airo_open,
2762     .ndo_stop       = airo_close,
2763     .ndo_start_xmit     = airo_start_xmit,
2764     .ndo_get_stats      = airo_get_stats,
2765     .ndo_set_rx_mode    = airo_set_multicast_list,
2766     .ndo_set_mac_address    = airo_set_mac_address,
2767     .ndo_siocdevprivate = airo_siocdevprivate,
2768     .ndo_validate_addr  = eth_validate_addr,
2769 };
2770 
2771 static const struct net_device_ops mpi_netdev_ops = {
2772     .ndo_open       = airo_open,
2773     .ndo_stop       = airo_close,
2774     .ndo_start_xmit     = mpi_start_xmit,
2775     .ndo_get_stats      = airo_get_stats,
2776     .ndo_set_rx_mode    = airo_set_multicast_list,
2777     .ndo_set_mac_address    = airo_set_mac_address,
2778     .ndo_siocdevprivate = airo_siocdevprivate,
2779     .ndo_validate_addr  = eth_validate_addr,
2780 };
2781 
2782 
2783 static struct net_device *_init_airo_card(unsigned short irq, int port,
2784                        int is_pcmcia, struct pci_dev *pci,
2785                        struct device *dmdev)
2786 {
2787     struct net_device *dev;
2788     struct airo_info *ai;
2789     int i, rc;
2790     CapabilityRid cap_rid;
2791 
2792     /* Create the network device object. */
2793     dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup);
2794     if (!dev) {
2795         airo_print_err("", "Couldn't alloc_etherdev");
2796         return NULL;
2797     }
2798 
2799     ai = dev->ml_priv = netdev_priv(dev);
2800     ai->wifidev = NULL;
2801     ai->flags = 1 << FLAG_RADIO_DOWN;
2802     ai->jobs = 0;
2803     ai->dev = dev;
2804     if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2805         airo_print_dbg("", "Found an MPI350 card");
2806         set_bit(FLAG_MPI, &ai->flags);
2807     }
2808     spin_lock_init(&ai->aux_lock);
2809     sema_init(&ai->sem, 1);
2810     ai->config.len = 0;
2811     ai->pci = pci;
2812     init_waitqueue_head (&ai->thr_wait);
2813     ai->tfm = NULL;
2814     add_airo_dev(ai);
2815     ai->APList.len = cpu_to_le16(sizeof(struct APListRid));
2816 
2817     if (airo_networks_allocate (ai))
2818         goto err_out_free;
2819     airo_networks_initialize (ai);
2820 
2821     skb_queue_head_init (&ai->txq);
2822 
2823     /* The Airo-specific entries in the device structure. */
2824     if (test_bit(FLAG_MPI,&ai->flags))
2825         dev->netdev_ops = &mpi_netdev_ops;
2826     else
2827         dev->netdev_ops = &airo_netdev_ops;
2828     dev->wireless_handlers = &airo_handler_def;
2829     ai->wireless_data.spy_data = &ai->spy_data;
2830     dev->wireless_data = &ai->wireless_data;
2831     dev->irq = irq;
2832     dev->base_addr = port;
2833     dev->priv_flags &= ~IFF_TX_SKB_SHARING;
2834     dev->max_mtu = MIC_MSGLEN_MAX;
2835 
2836     SET_NETDEV_DEV(dev, dmdev);
2837 
2838     reset_card (dev, 1);
2839     msleep(400);
2840 
2841     if (!is_pcmcia) {
2842         if (!request_region(dev->base_addr, 64, DRV_NAME)) {
2843             rc = -EBUSY;
2844             airo_print_err(dev->name, "Couldn't request region");
2845             goto err_out_nets;
2846         }
2847     }
2848 
2849     if (test_bit(FLAG_MPI,&ai->flags)) {
2850         if (mpi_map_card(ai, pci)) {
2851             airo_print_err("", "Could not map memory");
2852             goto err_out_res;
2853         }
2854     }
2855 
2856     if (probe) {
2857         if (setup_card(ai, dev, 1) != SUCCESS) {
2858             airo_print_err(dev->name, "MAC could not be enabled");
2859             rc = -EIO;
2860             goto err_out_map;
2861         }
2862     } else if (!test_bit(FLAG_MPI,&ai->flags)) {
2863         ai->bap_read = fast_bap_read;
2864         set_bit(FLAG_FLASHING, &ai->flags);
2865     }
2866 
2867     strcpy(dev->name, "eth%d");
2868     rc = register_netdev(dev);
2869     if (rc) {
2870         airo_print_err(dev->name, "Couldn't register_netdev");
2871         goto err_out_map;
2872     }
2873     ai->wifidev = init_wifidev(ai, dev);
2874     if (!ai->wifidev)
2875         goto err_out_reg;
2876 
2877     rc = readCapabilityRid(ai, &cap_rid, 1);
2878     if (rc != SUCCESS) {
2879         rc = -EIO;
2880         goto err_out_wifi;
2881     }
2882     /* WEP capability discovery */
2883     ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2884     ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2885 
2886     airo_print_info(dev->name, "Firmware version %x.%x.%02d",
2887                     ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2888                     (le16_to_cpu(cap_rid.softVer) & 0xFF),
2889                     le16_to_cpu(cap_rid.softSubVer));
2890 
2891     /* Test for WPA support */
2892     /* Only firmware versions 5.30.17 or better can do WPA */
2893     if (le16_to_cpu(cap_rid.softVer) > 0x530
2894      || (le16_to_cpu(cap_rid.softVer) == 0x530
2895           && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2896         airo_print_info(ai->dev->name, "WPA supported.");
2897 
2898         set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2899         ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2900         ai->bssListNext = RID_WPA_BSSLISTNEXT;
2901         ai->bssListRidLen = sizeof(BSSListRid);
2902     } else {
2903         airo_print_info(ai->dev->name, "WPA unsupported with firmware "
2904             "versions older than 5.30.17.");
2905 
2906         ai->bssListFirst = RID_BSSLISTFIRST;
2907         ai->bssListNext = RID_BSSLISTNEXT;
2908         ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2909     }
2910 
2911     set_bit(FLAG_REGISTERED,&ai->flags);
2912     airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2913 
2914     /* Allocate the transmit buffers */
2915     if (probe && !test_bit(FLAG_MPI,&ai->flags))
2916         for (i = 0; i < MAX_FIDS; i++)
2917             ai->fids[i] = transmit_allocate(ai, AIRO_DEF_MTU, i>=MAX_FIDS/2);
2918 
2919     if (setup_proc_entry(dev, dev->ml_priv) < 0)
2920         goto err_out_wifi;
2921 
2922     return dev;
2923 
2924 err_out_wifi:
2925     unregister_netdev(ai->wifidev);
2926     free_netdev(ai->wifidev);
2927 err_out_reg:
2928     unregister_netdev(dev);
2929 err_out_map:
2930     if (test_bit(FLAG_MPI,&ai->flags) && pci) {
2931         dma_free_coherent(&pci->dev, PCI_SHARED_LEN, ai->shared,
2932                   ai->shared_dma);
2933         iounmap(ai->pciaux);
2934         iounmap(ai->pcimem);
2935         mpi_unmap_card(ai->pci);
2936     }
2937 err_out_res:
2938     if (!is_pcmcia)
2939         release_region(dev->base_addr, 64);
2940 err_out_nets:
2941     airo_networks_free(ai);
2942 err_out_free:
2943     del_airo_dev(ai);
2944     free_netdev(dev);
2945     return NULL;
2946 }
2947 
2948 struct net_device *init_airo_card(unsigned short irq, int port, int is_pcmcia,
2949                   struct device *dmdev)
2950 {
2951     return _init_airo_card (irq, port, is_pcmcia, NULL, dmdev);
2952 }
2953 
2954 EXPORT_SYMBOL(init_airo_card);
2955 
2956 static int waitbusy (struct airo_info *ai)
2957 {
2958     int delay = 0;
2959     while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) {
2960         udelay (10);
2961         if ((++delay % 20) == 0)
2962             OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2963     }
2964     return delay < 10000;
2965 }
2966 
2967 int reset_airo_card(struct net_device *dev)
2968 {
2969     int i;
2970     struct airo_info *ai = dev->ml_priv;
2971 
2972     if (reset_card (dev, 1))
2973         return -1;
2974 
2975     if (setup_card(ai, dev, 1) != SUCCESS) {
2976         airo_print_err(dev->name, "MAC could not be enabled");
2977         return -1;
2978     }
2979     airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2980     /* Allocate the transmit buffers if needed */
2981     if (!test_bit(FLAG_MPI,&ai->flags))
2982         for (i = 0; i < MAX_FIDS; i++)
2983             ai->fids[i] = transmit_allocate (ai, AIRO_DEF_MTU, i>=MAX_FIDS/2);
2984 
2985     enable_interrupts(ai);
2986     netif_wake_queue(dev);
2987     return 0;
2988 }
2989 
2990 EXPORT_SYMBOL(reset_airo_card);
2991 
2992 static void airo_send_event(struct net_device *dev)
2993 {
2994     struct airo_info *ai = dev->ml_priv;
2995     union iwreq_data wrqu;
2996     StatusRid status_rid;
2997 
2998     clear_bit(JOB_EVENT, &ai->jobs);
2999     PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
3000     up(&ai->sem);
3001     wrqu.data.length = 0;
3002     wrqu.data.flags = 0;
3003     memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
3004     wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3005 
3006     /* Send event to user space */
3007     wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
3008 }
3009 
3010 static void airo_process_scan_results (struct airo_info *ai)
3011 {
3012     union iwreq_data    wrqu;
3013     BSSListRid bss;
3014     int rc;
3015     BSSListElement * loop_net;
3016     BSSListElement * tmp_net;
3017 
3018     /* Blow away current list of scan results */
3019     list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
3020         list_move_tail (&loop_net->list, &ai->network_free_list);
3021         /* Don't blow away ->list, just BSS data */
3022         memset (loop_net, 0, sizeof (loop_net->bss));
3023     }
3024 
3025     /* Try to read the first entry of the scan result */
3026     rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
3027     if ((rc) || (bss.index == cpu_to_le16(0xffff))) {
3028         /* No scan results */
3029         goto out;
3030     }
3031 
3032     /* Read and parse all entries */
3033     tmp_net = NULL;
3034     while ((!rc) && (bss.index != cpu_to_le16(0xffff))) {
3035         /* Grab a network off the free list */
3036         if (!list_empty(&ai->network_free_list)) {
3037             tmp_net = list_entry(ai->network_free_list.next,
3038                         BSSListElement, list);
3039             list_del(ai->network_free_list.next);
3040         }
3041 
3042         if (tmp_net != NULL) {
3043             memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
3044             list_add_tail(&tmp_net->list, &ai->network_list);
3045             tmp_net = NULL;
3046         }
3047 
3048         /* Read next entry */
3049         rc = PC4500_readrid(ai, ai->bssListNext,
3050                     &bss, ai->bssListRidLen, 0);
3051     }
3052 
3053 out:
3054     /* write APList back (we cleared it in airo_set_scan) */
3055     disable_MAC(ai, 2);
3056     writeAPListRid(ai, &ai->APList, 0);
3057     enable_MAC(ai, 0);
3058 
3059     ai->scan_timeout = 0;
3060     clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
3061     up(&ai->sem);
3062 
3063     /* Send an empty event to user space.
3064      * We don't send the received data on
3065      * the event because it would require
3066      * us to do complex transcoding, and
3067      * we want to minimise the work done in
3068      * the irq handler. Use a request to
3069      * extract the data - Jean II */
3070     wrqu.data.length = 0;
3071     wrqu.data.flags = 0;
3072     wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
3073 }
3074 
3075 static int airo_thread(void *data)
3076 {
3077     struct net_device *dev = data;
3078     struct airo_info *ai = dev->ml_priv;
3079     int locked;
3080 
3081     set_freezable();
3082     while (1) {
3083         /* make swsusp happy with our thread */
3084         try_to_freeze();
3085 
3086         if (test_bit(JOB_DIE, &ai->jobs))
3087             break;
3088 
3089         if (ai->jobs) {
3090             locked = down_interruptible(&ai->sem);
3091         } else {
3092             wait_queue_entry_t wait;
3093 
3094             init_waitqueue_entry(&wait, current);
3095             add_wait_queue(&ai->thr_wait, &wait);
3096             for (;;) {
3097                 set_current_state(TASK_INTERRUPTIBLE);
3098                 if (ai->jobs)
3099                     break;
3100                 if (ai->expires || ai->scan_timeout) {
3101                     if (ai->scan_timeout &&
3102                             time_after_eq(jiffies, ai->scan_timeout)) {
3103                         set_bit(JOB_SCAN_RESULTS, &ai->jobs);
3104                         break;
3105                     } else if (ai->expires &&
3106                             time_after_eq(jiffies, ai->expires)) {
3107                         set_bit(JOB_AUTOWEP, &ai->jobs);
3108                         break;
3109                     }
3110                     if (!kthread_should_stop() &&
3111                         !freezing(current)) {
3112                         unsigned long wake_at;
3113                         if (!ai->expires || !ai->scan_timeout) {
3114                             wake_at = max(ai->expires,
3115                                 ai->scan_timeout);
3116                         } else {
3117                             wake_at = min(ai->expires,
3118                                 ai->scan_timeout);
3119                         }
3120                         schedule_timeout(wake_at - jiffies);
3121                         continue;
3122                     }
3123                 } else if (!kthread_should_stop() &&
3124                        !freezing(current)) {
3125                     schedule();
3126                     continue;
3127                 }
3128                 break;
3129             }
3130             __set_current_state(TASK_RUNNING);
3131             remove_wait_queue(&ai->thr_wait, &wait);
3132             locked = 1;
3133         }
3134 
3135         if (locked)
3136             continue;
3137 
3138         if (test_bit(JOB_DIE, &ai->jobs)) {
3139             up(&ai->sem);
3140             break;
3141         }
3142 
3143         if (ai->power.event || test_bit(FLAG_FLASHING, &ai->flags)) {
3144             up(&ai->sem);
3145             continue;
3146         }
3147 
3148         if (test_bit(JOB_XMIT, &ai->jobs))
3149             airo_end_xmit(dev, true);
3150         else if (test_bit(JOB_XMIT11, &ai->jobs))
3151             airo_end_xmit11(dev, true);
3152         else if (test_bit(JOB_STATS, &ai->jobs))
3153             airo_read_stats(dev);
3154         else if (test_bit(JOB_PROMISC, &ai->jobs))
3155             airo_set_promisc(ai, true);
3156         else if (test_bit(JOB_MIC, &ai->jobs))
3157             micinit(ai);
3158         else if (test_bit(JOB_EVENT, &ai->jobs))
3159             airo_send_event(dev);
3160         else if (test_bit(JOB_AUTOWEP, &ai->jobs))
3161             timer_func(dev);
3162         else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
3163             airo_process_scan_results(ai);
3164         else  /* Shouldn't get here, but we make sure to unlock */
3165             up(&ai->sem);
3166     }
3167 
3168     return 0;
3169 }
3170 
3171 static int header_len(__le16 ctl)
3172 {
3173     u16 fc = le16_to_cpu(ctl);
3174     switch (fc & 0xc) {
3175     case 4:
3176         if ((fc & 0xe0) == 0xc0)
3177             return 10;  /* one-address control packet */
3178         return 16;  /* two-address control packet */
3179     case 8:
3180         if ((fc & 0x300) == 0x300)
3181             return 30;  /* WDS packet */
3182     }
3183     return 24;
3184 }
3185 
3186 static void airo_handle_cisco_mic(struct airo_info *ai)
3187 {
3188     if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
3189         set_bit(JOB_MIC, &ai->jobs);
3190         wake_up_interruptible(&ai->thr_wait);
3191     }
3192 }
3193 
3194 /* Airo Status codes */
3195 #define STAT_NOBEACON   0x8000 /* Loss of sync - missed beacons */
3196 #define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */
3197 #define STAT_MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3198 #define STAT_FORCELOSS  0x8003 /* Loss of sync - host request */
3199 #define STAT_TSFSYNC    0x8004 /* Loss of sync - TSF synchronization */
3200 #define STAT_DEAUTH 0x8100 /* low byte is 802.11 reason code */
3201 #define STAT_DISASSOC   0x8200 /* low byte is 802.11 reason code */
3202 #define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */
3203 #define STAT_AUTH_FAIL  0x0300 /* low byte is 802.11 reason code */
3204 #define STAT_ASSOC  0x0400 /* Associated */
3205 #define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
3206 
3207 static void airo_print_status(const char *devname, u16 status)
3208 {
3209     u8 reason = status & 0xFF;
3210 
3211     switch (status & 0xFF00) {
3212     case STAT_NOBEACON:
3213         switch (status) {
3214         case STAT_NOBEACON:
3215             airo_print_dbg(devname, "link lost (missed beacons)");
3216             break;
3217         case STAT_MAXRETRIES:
3218         case STAT_MAXARL:
3219             airo_print_dbg(devname, "link lost (max retries)");
3220             break;
3221         case STAT_FORCELOSS:
3222             airo_print_dbg(devname, "link lost (local choice)");
3223             break;
3224         case STAT_TSFSYNC:
3225             airo_print_dbg(devname, "link lost (TSF sync lost)");
3226             break;
3227         default:
3228             airo_print_dbg(devname, "unknown status %x\n", status);
3229             break;
3230         }
3231         break;
3232     case STAT_DEAUTH:
3233         airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
3234         break;
3235     case STAT_DISASSOC:
3236         airo_print_dbg(devname, "disassociated (reason: %d)", reason);
3237         break;
3238     case STAT_ASSOC_FAIL:
3239         airo_print_dbg(devname, "association failed (reason: %d)",
3240                    reason);
3241         break;
3242     case STAT_AUTH_FAIL:
3243         airo_print_dbg(devname, "authentication failed (reason: %d)",
3244                    reason);
3245         break;
3246     case STAT_ASSOC:
3247     case STAT_REASSOC:
3248         break;
3249     default:
3250         airo_print_dbg(devname, "unknown status %x\n", status);
3251         break;
3252     }
3253 }
3254 
3255 static void airo_handle_link(struct airo_info *ai)
3256 {
3257     union iwreq_data wrqu;
3258     int scan_forceloss = 0;
3259     u16 status;
3260 
3261     /* Get new status and acknowledge the link change */
3262     status = le16_to_cpu(IN4500(ai, LINKSTAT));
3263     OUT4500(ai, EVACK, EV_LINK);
3264 
3265     if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
3266         scan_forceloss = 1;
3267 
3268     airo_print_status(ai->dev->name, status);
3269 
3270     if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
3271         if (auto_wep)
3272             ai->expires = 0;
3273         if (ai->list_bss_task)
3274             wake_up_process(ai->list_bss_task);
3275         set_bit(FLAG_UPDATE_UNI, &ai->flags);
3276         set_bit(FLAG_UPDATE_MULTI, &ai->flags);
3277 
3278         set_bit(JOB_EVENT, &ai->jobs);
3279         wake_up_interruptible(&ai->thr_wait);
3280 
3281         netif_carrier_on(ai->dev);
3282     } else if (!scan_forceloss) {
3283         if (auto_wep && !ai->expires) {
3284             ai->expires = RUN_AT(3*HZ);
3285             wake_up_interruptible(&ai->thr_wait);
3286         }
3287 
3288         /* Send event to user space */
3289         eth_zero_addr(wrqu.ap_addr.sa_data);
3290         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3291         wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
3292         netif_carrier_off(ai->dev);
3293     } else {
3294         netif_carrier_off(ai->dev);
3295     }
3296 }
3297 
3298 static void airo_handle_rx(struct airo_info *ai)
3299 {
3300     struct sk_buff *skb = NULL;
3301     __le16 fc, v, *buffer, tmpbuf[4];
3302     u16 len, hdrlen = 0, gap, fid;
3303     struct rx_hdr hdr;
3304     int success = 0;
3305 
3306     if (test_bit(FLAG_MPI, &ai->flags)) {
3307         if (test_bit(FLAG_802_11, &ai->flags))
3308             mpi_receive_802_11(ai);
3309         else
3310             mpi_receive_802_3(ai);
3311         OUT4500(ai, EVACK, EV_RX);
3312         return;
3313     }
3314 
3315     fid = IN4500(ai, RXFID);
3316 
3317     /* Get the packet length */
3318     if (test_bit(FLAG_802_11, &ai->flags)) {
3319         bap_setup (ai, fid, 4, BAP0);
3320         bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
3321         /* Bad CRC. Ignore packet */
3322         if (le16_to_cpu(hdr.status) & 2)
3323             hdr.len = 0;
3324         if (ai->wifidev == NULL)
3325             hdr.len = 0;
3326     } else {
3327         bap_setup(ai, fid, 0x36, BAP0);
3328         bap_read(ai, &hdr.len, 2, BAP0);
3329     }
3330     len = le16_to_cpu(hdr.len);
3331 
3332     if (len > AIRO_DEF_MTU) {
3333         airo_print_err(ai->dev->name, "Bad size %d", len);
3334         goto done;
3335     }
3336     if (len == 0)
3337         goto done;
3338 
3339     if (test_bit(FLAG_802_11, &ai->flags)) {
3340         bap_read(ai, &fc, sizeof (fc), BAP0);
3341         hdrlen = header_len(fc);
3342     } else
3343         hdrlen = ETH_ALEN * 2;
3344 
3345     skb = dev_alloc_skb(len + hdrlen + 2 + 2);
3346     if (!skb) {
3347         ai->dev->stats.rx_dropped++;
3348         goto done;
3349     }
3350 
3351     skb_reserve(skb, 2); /* This way the IP header is aligned */
3352     buffer = skb_put(skb, len + hdrlen);
3353     if (test_bit(FLAG_802_11, &ai->flags)) {
3354         buffer[0] = fc;
3355         bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
3356         if (hdrlen == 24)
3357             bap_read(ai, tmpbuf, 6, BAP0);
3358 
3359         bap_read(ai, &v, sizeof(v), BAP0);
3360         gap = le16_to_cpu(v);
3361         if (gap) {
3362             if (gap <= 8) {
3363                 bap_read(ai, tmpbuf, gap, BAP0);
3364             } else {
3365                 airo_print_err(ai->dev->name, "gaplen too "
3366                     "big. Problems will follow...");
3367             }
3368         }
3369         bap_read(ai, buffer + hdrlen/2, len, BAP0);
3370     } else {
3371         MICBuffer micbuf;
3372 
3373         bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
3374         if (ai->micstats.enabled) {
3375             bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
3376             if (ntohs(micbuf.typelen) > 0x05DC)
3377                 bap_setup(ai, fid, 0x44, BAP0);
3378             else {
3379                 if (len <= sizeof (micbuf)) {
3380                     dev_kfree_skb_irq(skb);
3381                     goto done;
3382                 }
3383 
3384                 len -= sizeof(micbuf);
3385                 skb_trim(skb, len + hdrlen);
3386             }
3387         }
3388 
3389         bap_read(ai, buffer + ETH_ALEN, len, BAP0);
3390         if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
3391             dev_kfree_skb_irq (skb);
3392         else
3393             success = 1;
3394     }
3395 
3396 #ifdef WIRELESS_SPY
3397     if (success && (ai->spy_data.spy_number > 0)) {
3398         char *sa;
3399         struct iw_quality wstats;
3400 
3401         /* Prepare spy data : addr + qual */
3402         if (!test_bit(FLAG_802_11, &ai->flags)) {
3403             sa = (char *) buffer + 6;
3404             bap_setup(ai, fid, 8, BAP0);
3405             bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
3406         } else
3407             sa = (char *) buffer + 10;
3408         wstats.qual = hdr.rssi[0];
3409         if (ai->rssi)
3410             wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3411         else
3412             wstats.level = (hdr.rssi[1] + 321) / 2;
3413         wstats.noise = ai->wstats.qual.noise;
3414         wstats.updated =  IW_QUAL_LEVEL_UPDATED
3415                 | IW_QUAL_QUAL_UPDATED
3416                 | IW_QUAL_DBM;
3417         /* Update spy records */
3418         wireless_spy_update(ai->dev, sa, &wstats);
3419     }
3420 #endif /* WIRELESS_SPY */
3421 
3422 done:
3423     OUT4500(ai, EVACK, EV_RX);
3424 
3425     if (success) {
3426         if (test_bit(FLAG_802_11, &ai->flags)) {
3427             skb_reset_mac_header(skb);
3428             skb->pkt_type = PACKET_OTHERHOST;
3429             skb->dev = ai->wifidev;
3430             skb->protocol = htons(ETH_P_802_2);
3431         } else
3432             skb->protocol = eth_type_trans(skb, ai->dev);
3433         skb->ip_summed = CHECKSUM_NONE;
3434 
3435         netif_rx(skb);
3436     }
3437 }
3438 
3439 static void airo_handle_tx(struct airo_info *ai, u16 status)
3440 {
3441     int i, index = -1;
3442     u16 fid;
3443 
3444     if (test_bit(FLAG_MPI, &ai->flags)) {
3445         unsigned long flags;
3446 
3447         if (status & EV_TXEXC)
3448             get_tx_error(ai, -1);
3449 
3450         spin_lock_irqsave(&ai->aux_lock, flags);
3451         if (!skb_queue_empty(&ai->txq)) {
3452             spin_unlock_irqrestore(&ai->aux_lock, flags);
3453             mpi_send_packet(ai->dev);
3454         } else {
3455             clear_bit(FLAG_PENDING_XMIT, &ai->flags);
3456             spin_unlock_irqrestore(&ai->aux_lock, flags);
3457             netif_wake_queue(ai->dev);
3458         }
3459         OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3460         return;
3461     }
3462 
3463     fid = IN4500(ai, TXCOMPLFID);
3464 
3465     for (i = 0; i < MAX_FIDS; i++) {
3466         if ((ai->fids[i] & 0xffff) == fid)
3467             index = i;
3468     }
3469 
3470     if (index != -1) {
3471         if (status & EV_TXEXC)
3472             get_tx_error(ai, index);
3473 
3474         OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
3475 
3476         /* Set up to be used again */
3477         ai->fids[index] &= 0xffff;
3478         if (index < MAX_FIDS / 2) {
3479             if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
3480                 netif_wake_queue(ai->dev);
3481         } else {
3482             if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
3483                 netif_wake_queue(ai->wifidev);
3484         }
3485     } else {
3486         OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3487         airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
3488     }
3489 }
3490 
3491 static irqreturn_t airo_interrupt(int irq, void *dev_id)
3492 {
3493     struct net_device *dev = dev_id;
3494     u16 status, savedInterrupts = 0;
3495     struct airo_info *ai = dev->ml_priv;
3496     int handled = 0;
3497 
3498     if (!netif_device_present(dev))
3499         return IRQ_NONE;
3500 
3501     for (;;) {
3502         status = IN4500(ai, EVSTAT);
3503         if (!(status & STATUS_INTS) || (status == 0xffff))
3504             break;
3505 
3506         handled = 1;
3507 
3508         if (status & EV_AWAKE) {
3509             OUT4500(ai, EVACK, EV_AWAKE);
3510             OUT4500(ai, EVACK, EV_AWAKE);
3511         }
3512 
3513         if (!savedInterrupts) {
3514             savedInterrupts = IN4500(ai, EVINTEN);
3515             OUT4500(ai, EVINTEN, 0);
3516         }
3517 
3518         if (status & EV_MIC) {
3519             OUT4500(ai, EVACK, EV_MIC);
3520             airo_handle_cisco_mic(ai);
3521         }
3522 
3523         if (status & EV_LINK) {
3524             /* Link status changed */
3525             airo_handle_link(ai);
3526         }
3527 
3528         /* Check to see if there is something to receive */
3529         if (status & EV_RX)
3530             airo_handle_rx(ai);
3531 
3532         /* Check to see if a packet has been transmitted */
3533         if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
3534             airo_handle_tx(ai, status);
3535 
3536         if (status & ~STATUS_INTS & ~IGNORE_INTS) {
3537             airo_print_warn(ai->dev->name, "Got weird status %x",
3538                 status & ~STATUS_INTS & ~IGNORE_INTS);
3539         }
3540     }
3541 
3542     if (savedInterrupts)
3543         OUT4500(ai, EVINTEN, savedInterrupts);
3544 
3545     return IRQ_RETVAL(handled);
3546 }
3547 
3548 /*
3549  *  Routines to talk to the card
3550  */
3551 
3552 /*
3553  *  This was originally written for the 4500, hence the name
3554  *  NOTE:  If use with 8bit mode and SMP bad things will happen!
3555  *         Why would some one do 8 bit IO in an SMP machine?!?
3556  */
3557 static void OUT4500(struct airo_info *ai, u16 reg, u16 val)
3558 {
3559     if (test_bit(FLAG_MPI,&ai->flags))
3560         reg <<= 1;
3561     if (!do8bitIO)
3562         outw(val, ai->dev->base_addr + reg);
3563     else {
3564         outb(val & 0xff, ai->dev->base_addr + reg);
3565         outb(val >> 8, ai->dev->base_addr + reg + 1);
3566     }
3567 }
3568 
3569 static u16 IN4500(struct airo_info *ai, u16 reg)
3570 {
3571     unsigned short rc;
3572 
3573     if (test_bit(FLAG_MPI,&ai->flags))
3574         reg <<= 1;
3575     if (!do8bitIO)
3576         rc = inw(ai->dev->base_addr + reg);
3577     else {
3578         rc = inb(ai->dev->base_addr + reg);
3579         rc += ((int)inb(ai->dev->base_addr + reg + 1)) << 8;
3580     }
3581     return rc;
3582 }
3583 
3584 static int enable_MAC(struct airo_info *ai, int lock)
3585 {
3586     int rc;
3587     Cmd cmd;
3588     Resp rsp;
3589 
3590     /* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3591      * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3592      * Note : we could try to use !netif_running(dev) in enable_MAC()
3593      * instead of this flag, but I don't trust it *within* the
3594      * open/close functions, and testing both flags together is
3595      * "cheaper" - Jean II */
3596     if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3597 
3598     if (lock && down_interruptible(&ai->sem))
3599         return -ERESTARTSYS;
3600 
3601     if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3602         memset(&cmd, 0, sizeof(cmd));
3603         cmd.cmd = MAC_ENABLE;
3604         rc = issuecommand(ai, &cmd, &rsp, true);
3605         if (rc == SUCCESS)
3606             set_bit(FLAG_ENABLED, &ai->flags);
3607     } else
3608         rc = SUCCESS;
3609 
3610     if (lock)
3611         up(&ai->sem);
3612 
3613     if (rc)
3614         airo_print_err(ai->dev->name, "Cannot enable MAC");
3615     else if ((rsp.status & 0xFF00) != 0) {
3616         airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
3617             "rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
3618         rc = ERROR;
3619     }
3620     return rc;
3621 }
3622 
3623 static void disable_MAC(struct airo_info *ai, int lock)
3624 {
3625         Cmd cmd;
3626     Resp rsp;
3627 
3628     if (lock == 1 && down_interruptible(&ai->sem))
3629         return;
3630 
3631     if (test_bit(FLAG_ENABLED, &ai->flags)) {
3632         if (lock != 2) /* lock == 2 means don't disable carrier */
3633             netif_carrier_off(ai->dev);
3634         memset(&cmd, 0, sizeof(cmd));
3635         cmd.cmd = MAC_DISABLE; // disable in case already enabled
3636         issuecommand(ai, &cmd, &rsp, true);
3637         clear_bit(FLAG_ENABLED, &ai->flags);
3638     }
3639     if (lock == 1)
3640         up(&ai->sem);
3641 }
3642 
3643 static void enable_interrupts(struct airo_info *ai)
3644 {
3645     /* Enable the interrupts */
3646     OUT4500(ai, EVINTEN, STATUS_INTS);
3647 }
3648 
3649 static void disable_interrupts(struct airo_info *ai)
3650 {
3651     OUT4500(ai, EVINTEN, 0);
3652 }
3653 
3654 static void mpi_receive_802_3(struct airo_info *ai)
3655 {
3656     RxFid rxd;
3657     int len = 0;
3658     struct sk_buff *skb;
3659     char *buffer;
3660     int off = 0;
3661     MICBuffer micbuf;
3662 
3663     memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3664     /* Make sure we got something */
3665     if (rxd.rdy && rxd.valid == 0) {
3666         len = rxd.len + 12;
3667         if (len < 12 || len > 2048)
3668             goto badrx;
3669 
3670         skb = dev_alloc_skb(len);
3671         if (!skb) {
3672             ai->dev->stats.rx_dropped++;
3673             goto badrx;
3674         }
3675         buffer = skb_put(skb, len);
3676         memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3677         if (ai->micstats.enabled) {
3678             memcpy(&micbuf,
3679                 ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3680                 sizeof(micbuf));
3681             if (ntohs(micbuf.typelen) <= 0x05DC) {
3682                 if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3683                     goto badmic;
3684 
3685                 off = sizeof(micbuf);
3686                 skb_trim (skb, len - off);
3687             }
3688         }
3689         memcpy(buffer + ETH_ALEN * 2,
3690             ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3691             len - ETH_ALEN * 2 - off);
3692         if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3693 badmic:
3694             dev_kfree_skb_irq (skb);
3695             goto badrx;
3696         }
3697 #ifdef WIRELESS_SPY
3698         if (ai->spy_data.spy_number > 0) {
3699             char *sa;
3700             struct iw_quality wstats;
3701             /* Prepare spy data : addr + qual */
3702             sa = buffer + ETH_ALEN;
3703             wstats.qual = 0; /* XXX Where do I get that info from ??? */
3704             wstats.level = 0;
3705             wstats.updated = 0;
3706             /* Update spy records */
3707             wireless_spy_update(ai->dev, sa, &wstats);
3708         }
3709 #endif /* WIRELESS_SPY */
3710 
3711         skb->ip_summed = CHECKSUM_NONE;
3712         skb->protocol = eth_type_trans(skb, ai->dev);
3713         netif_rx(skb);
3714     }
3715 badrx:
3716     if (rxd.valid == 0) {
3717         rxd.valid = 1;
3718         rxd.rdy = 0;
3719         rxd.len = PKTSIZE;
3720         memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3721     }
3722 }
3723 
3724 static void mpi_receive_802_11(struct airo_info *ai)
3725 {
3726     RxFid rxd;
3727     struct sk_buff *skb = NULL;
3728     u16 len, hdrlen = 0;
3729     __le16 fc;
3730     struct rx_hdr hdr;
3731     u16 gap;
3732     u16 *buffer;
3733     char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3734 
3735     memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3736     memcpy ((char *)&hdr, ptr, sizeof(hdr));
3737     ptr += sizeof(hdr);
3738     /* Bad CRC. Ignore packet */
3739     if (le16_to_cpu(hdr.status) & 2)
3740         hdr.len = 0;
3741     if (ai->wifidev == NULL)
3742         hdr.len = 0;
3743     len = le16_to_cpu(hdr.len);
3744     if (len > AIRO_DEF_MTU) {
3745         airo_print_err(ai->dev->name, "Bad size %d", len);
3746         goto badrx;
3747     }
3748     if (len == 0)
3749         goto badrx;
3750 
3751     fc = get_unaligned((__le16 *)ptr);
3752     hdrlen = header_len(fc);
3753 
3754     skb = dev_alloc_skb(len + hdrlen + 2);
3755     if (!skb) {
3756         ai->dev->stats.rx_dropped++;
3757         goto badrx;
3758     }
3759     buffer = skb_put(skb, len + hdrlen);
3760     memcpy ((char *)buffer, ptr, hdrlen);
3761     ptr += hdrlen;
3762     if (hdrlen == 24)
3763         ptr += 6;
3764     gap = get_unaligned_le16(ptr);
3765     ptr += sizeof(__le16);
3766     if (gap) {
3767         if (gap <= 8)
3768             ptr += gap;
3769         else
3770             airo_print_err(ai->dev->name,
3771                 "gaplen too big. Problems will follow...");
3772     }
3773     memcpy ((char *)buffer + hdrlen, ptr, len);
3774     ptr += len;
3775 #ifdef IW_WIRELESS_SPY    /* defined in iw_handler.h */
3776     if (ai->spy_data.spy_number > 0) {
3777         char *sa;
3778         struct iw_quality wstats;
3779         /* Prepare spy data : addr + qual */
3780         sa = (char*)buffer + 10;
3781         wstats.qual = hdr.rssi[0];
3782         if (ai->rssi)
3783             wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3784         else
3785             wstats.level = (hdr.rssi[1] + 321) / 2;
3786         wstats.noise = ai->wstats.qual.noise;
3787         wstats.updated = IW_QUAL_QUAL_UPDATED
3788             | IW_QUAL_LEVEL_UPDATED
3789             | IW_QUAL_DBM;
3790         /* Update spy records */
3791         wireless_spy_update(ai->dev, sa, &wstats);
3792     }
3793 #endif /* IW_WIRELESS_SPY */
3794     skb_reset_mac_header(skb);
3795     skb->pkt_type = PACKET_OTHERHOST;
3796     skb->dev = ai->wifidev;
3797     skb->protocol = htons(ETH_P_802_2);
3798     skb->ip_summed = CHECKSUM_NONE;
3799     netif_rx(skb);
3800 
3801 badrx:
3802     if (rxd.valid == 0) {
3803         rxd.valid = 1;
3804         rxd.rdy = 0;
3805         rxd.len = PKTSIZE;
3806         memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3807     }
3808 }
3809 
3810 static inline void set_auth_type(struct airo_info *local, int auth_type)
3811 {
3812     local->config.authType = auth_type;
3813     /* Cache the last auth type used (of AUTH_OPEN and AUTH_ENCRYPT).
3814      * Used by airo_set_auth()
3815      */
3816     if (auth_type == AUTH_OPEN || auth_type == AUTH_ENCRYPT)
3817         local->last_auth = auth_type;
3818 }
3819 
3820 static int noinline_for_stack airo_readconfig(struct airo_info *ai,
3821                           struct net_device *dev, int lock)
3822 {
3823     int i, status;
3824     /* large variables, so don't inline this function,
3825      * maybe change to kmalloc
3826      */
3827     tdsRssiRid rssi_rid;
3828     CapabilityRid cap_rid;
3829 
3830     kfree(ai->SSID);
3831     ai->SSID = NULL;
3832     // general configuration (read/modify/write)
3833     status = readConfigRid(ai, lock);
3834     if (status != SUCCESS) return ERROR;
3835 
3836     status = readCapabilityRid(ai, &cap_rid, lock);
3837     if (status != SUCCESS) return ERROR;
3838 
3839     status = PC4500_readrid(ai, RID_RSSI, &rssi_rid, sizeof(rssi_rid), lock);
3840     if (status == SUCCESS) {
3841         if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3842             memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3843     }
3844     else {
3845         kfree(ai->rssi);
3846         ai->rssi = NULL;
3847         if (cap_rid.softCap & cpu_to_le16(8))
3848             ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3849         else
3850             airo_print_warn(ai->dev->name, "unknown received signal "
3851                     "level scale");
3852     }
3853     ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3854     set_auth_type(ai, AUTH_OPEN);
3855     ai->config.modulation = MOD_CCK;
3856 
3857     if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
3858         (cap_rid.extSoftCap & cpu_to_le16(1)) &&
3859         micsetup(ai) == SUCCESS) {
3860         ai->config.opmode |= MODE_MIC;
3861         set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3862     }
3863 
3864     /* Save off the MAC */
3865     eth_hw_addr_set(dev, ai->config.macAddr);
3866 
3867     /* Check to see if there are any insmod configured
3868        rates to add */
3869     if (rates[0]) {
3870         memset(ai->config.rates, 0, sizeof(ai->config.rates));
3871         for (i = 0; i < 8 && rates[i]; i++) {
3872             ai->config.rates[i] = rates[i];
3873         }
3874     }
3875     set_bit (FLAG_COMMIT, &ai->flags);
3876 
3877     return SUCCESS;
3878 }
3879 
3880 
3881 static u16 setup_card(struct airo_info *ai, struct net_device *dev, int lock)
3882 {
3883     Cmd cmd;
3884     Resp rsp;
3885     int status;
3886     SsidRid mySsid;
3887     __le16 lastindex;
3888     WepKeyRid wkr;
3889     int rc;
3890 
3891     memset(&mySsid, 0, sizeof(mySsid));
3892     kfree (ai->flash);
3893     ai->flash = NULL;
3894 
3895     /* The NOP is the first step in getting the card going */
3896     cmd.cmd = NOP;
3897     cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3898     if (lock && down_interruptible(&ai->sem))
3899         return ERROR;
3900     if (issuecommand(ai, &cmd, &rsp, true) != SUCCESS) {
3901         if (lock)
3902             up(&ai->sem);
3903         return ERROR;
3904     }
3905     disable_MAC(ai, 0);
3906 
3907     // Let's figure out if we need to use the AUX port
3908     if (!test_bit(FLAG_MPI,&ai->flags)) {
3909         cmd.cmd = CMD_ENABLEAUX;
3910         if (issuecommand(ai, &cmd, &rsp, true) != SUCCESS) {
3911             if (lock)
3912                 up(&ai->sem);
3913             airo_print_err(ai->dev->name, "Error checking for AUX port");
3914             return ERROR;
3915         }
3916         if (!aux_bap || rsp.status & 0xff00) {
3917             ai->bap_read = fast_bap_read;
3918             airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
3919         } else {
3920             ai->bap_read = aux_bap_read;
3921             airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
3922         }
3923     }
3924     if (lock)
3925         up(&ai->sem);
3926     if (ai->config.len == 0) {
3927         status = airo_readconfig(ai, dev, lock);
3928         if (status != SUCCESS)
3929             return ERROR;
3930     }
3931 
3932     /* Setup the SSIDs if present */
3933     if (ssids[0]) {
3934         int i;
3935         for (i = 0; i < 3 && ssids[i]; i++) {
3936             size_t len = strlen(ssids[i]);
3937             if (len > 32)
3938                 len = 32;
3939             mySsid.ssids[i].len = cpu_to_le16(len);
3940             memcpy(mySsid.ssids[i].ssid, ssids[i], len);
3941         }
3942         mySsid.len = cpu_to_le16(sizeof(mySsid));
3943     }
3944 
3945     status = writeConfigRid(ai, lock);
3946     if (status != SUCCESS) return ERROR;
3947 
3948     /* Set up the SSID list */
3949     if (ssids[0]) {
3950         status = writeSsidRid(ai, &mySsid, lock);
3951         if (status != SUCCESS) return ERROR;
3952     }
3953 
3954     status = enable_MAC(ai, lock);
3955     if (status != SUCCESS)
3956         return ERROR;
3957 
3958     /* Grab the initial wep key, we gotta save it for auto_wep */
3959     rc = readWepKeyRid(ai, &wkr, 1, lock);
3960     if (rc == SUCCESS) do {
3961         lastindex = wkr.kindex;
3962         if (wkr.kindex == cpu_to_le16(0xffff)) {
3963             ai->defindex = wkr.mac[0];
3964         }
3965         rc = readWepKeyRid(ai, &wkr, 0, lock);
3966     } while (lastindex != wkr.kindex);
3967 
3968     try_auto_wep(ai);
3969 
3970     return SUCCESS;
3971 }
3972 
3973 static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp,
3974             bool may_sleep)
3975 {
3976         // Im really paranoid about letting it run forever!
3977     int max_tries = 600000;
3978 
3979     if (IN4500(ai, EVSTAT) & EV_CMD)
3980         OUT4500(ai, EVACK, EV_CMD);
3981 
3982     OUT4500(ai, PARAM0, pCmd->parm0);
3983     OUT4500(ai, PARAM1, pCmd->parm1);
3984     OUT4500(ai, PARAM2, pCmd->parm2);
3985     OUT4500(ai, COMMAND, pCmd->cmd);
3986 
3987     while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3988         if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3989             // PC4500 didn't notice command, try again
3990             OUT4500(ai, COMMAND, pCmd->cmd);
3991         if (may_sleep && (max_tries & 255) == 0)
3992             cond_resched();
3993     }
3994 
3995     if (max_tries == -1) {
3996         airo_print_err(ai->dev->name,
3997             "Max tries exceeded when issuing command");
3998         if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3999             OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
4000         return ERROR;
4001     }
4002 
4003     // command completed
4004     pRsp->status = IN4500(ai, STATUS);
4005     pRsp->rsp0 = IN4500(ai, RESP0);
4006     pRsp->rsp1 = IN4500(ai, RESP1);
4007     pRsp->rsp2 = IN4500(ai, RESP2);
4008     if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
4009         airo_print_err(ai->dev->name,
4010             "cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
4011             pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
4012             pRsp->rsp2);
4013 
4014     // clear stuck command busy if necessary
4015     if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
4016         OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
4017     }
4018     // acknowledge processing the status/response
4019     OUT4500(ai, EVACK, EV_CMD);
4020 
4021     return SUCCESS;
4022 }
4023 
4024 /* Sets up the bap to start exchange data.  whichbap should
4025  * be one of the BAP0 or BAP1 defines.  Locks should be held before
4026  * calling! */
4027 static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap)
4028 {
4029     int timeout = 50;
4030     int max_tries = 3;
4031 
4032     OUT4500(ai, SELECT0+whichbap, rid);
4033     OUT4500(ai, OFFSET0+whichbap, offset);
4034     while (1) {
4035         int status = IN4500(ai, OFFSET0+whichbap);
4036         if (status & BAP_BUSY) {
4037                         /* This isn't really a timeout, but its kinda
4038                close */
4039             if (timeout--) {
4040                 continue;
4041             }
4042         } else if (status & BAP_ERR) {
4043             /* invalid rid or offset */
4044             airo_print_err(ai->dev->name, "BAP error %x %d",
4045                 status, whichbap);
4046             return ERROR;
4047         } else if (status & BAP_DONE) { // success
4048             return SUCCESS;
4049         }
4050         if (!(max_tries--)) {
4051             airo_print_err(ai->dev->name,
4052                 "BAP setup error too many retries\n");
4053             return ERROR;
4054         }
4055         // -- PC4500 missed it, try again
4056         OUT4500(ai, SELECT0+whichbap, rid);
4057         OUT4500(ai, OFFSET0+whichbap, offset);
4058         timeout = 50;
4059     }
4060 }
4061 
4062 /* should only be called by aux_bap_read.  This aux function and the
4063    following use concepts not documented in the developers guide.  I
4064    got them from a patch given to my by Aironet */
4065 static u16 aux_setup(struct airo_info *ai, u16 page,
4066              u16 offset, u16 *len)
4067 {
4068     u16 next;
4069 
4070     OUT4500(ai, AUXPAGE, page);
4071     OUT4500(ai, AUXOFF, 0);
4072     next = IN4500(ai, AUXDATA);
4073     *len = IN4500(ai, AUXDATA)&0xff;
4074     if (offset != 4) OUT4500(ai, AUXOFF, offset);
4075     return next;
4076 }
4077 
4078 /* requires call to bap_setup() first */
4079 static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4080             int bytelen, int whichbap)
4081 {
4082     u16 len;
4083     u16 page;
4084     u16 offset;
4085     u16 next;
4086     int words;
4087     int i;
4088     unsigned long flags;
4089 
4090     spin_lock_irqsave(&ai->aux_lock, flags);
4091     page = IN4500(ai, SWS0+whichbap);
4092     offset = IN4500(ai, SWS2+whichbap);
4093     next = aux_setup(ai, page, offset, &len);
4094     words = (bytelen+1)>>1;
4095 
4096     for (i = 0; i<words;) {
4097         int count;
4098         count = (len>>1) < (words-i) ? (len>>1) : (words-i);
4099         if (!do8bitIO)
4100             insw(ai->dev->base_addr+DATA0+whichbap,
4101                   pu16Dst+i, count);
4102         else
4103             insb(ai->dev->base_addr+DATA0+whichbap,
4104                   pu16Dst+i, count << 1);
4105         i += count;
4106         if (i<words) {
4107             next = aux_setup(ai, next, 4, &len);
4108         }
4109     }
4110     spin_unlock_irqrestore(&ai->aux_lock, flags);
4111     return SUCCESS;
4112 }
4113 
4114 
4115 /* requires call to bap_setup() first */
4116 static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4117              int bytelen, int whichbap)
4118 {
4119     bytelen = (bytelen + 1) & (~1); // round up to even value
4120     if (!do8bitIO)
4121         insw(ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1);
4122     else
4123         insb(ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen);
4124     return SUCCESS;
4125 }
4126 
4127 /* requires call to bap_setup() first */
4128 static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
4129              int bytelen, int whichbap)
4130 {
4131     bytelen = (bytelen + 1) & (~1); // round up to even value
4132     if (!do8bitIO)
4133         outsw(ai->dev->base_addr+DATA0+whichbap,
4134                pu16Src, bytelen>>1);
4135     else
4136         outsb(ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen);
4137     return SUCCESS;
4138 }
4139 
4140 static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
4141 {
4142     Cmd cmd; /* for issuing commands */
4143     Resp rsp; /* response from commands */
4144     u16 status;
4145 
4146     memset(&cmd, 0, sizeof(cmd));
4147     cmd.cmd = accmd;
4148     cmd.parm0 = rid;
4149     status = issuecommand(ai, &cmd, &rsp, true);
4150     if (status != 0) return status;
4151     if ((rsp.status & 0x7F00) != 0) {
4152         return (accmd << 8) + (rsp.rsp0 & 0xFF);
4153     }
4154     return 0;
4155 }
4156 
4157 /*  Note, that we are using BAP1 which is also used by transmit, so
4158  *  we must get a lock. */
4159 static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
4160 {
4161     u16 status;
4162         int rc = SUCCESS;
4163 
4164     if (lock) {
4165         if (down_interruptible(&ai->sem))
4166             return ERROR;
4167     }
4168     if (test_bit(FLAG_MPI,&ai->flags)) {
4169         Cmd cmd;
4170         Resp rsp;
4171 
4172         memset(&cmd, 0, sizeof(cmd));
4173         memset(&rsp, 0, sizeof(rsp));
4174         ai->config_desc.rid_desc.valid = 1;
4175         ai->config_desc.rid_desc.len = RIDSIZE;
4176         ai->config_desc.rid_desc.rid = 0;
4177         ai->config_desc.rid_desc.host_addr = ai->ridbus;
4178 
4179         cmd.cmd = CMD_ACCESS;
4180         cmd.parm0 = rid;
4181 
4182         memcpy_toio(ai->config_desc.card_ram_off,
4183             &ai->config_desc.rid_desc, sizeof(Rid));
4184 
4185         rc = issuecommand(ai, &cmd, &rsp, true);
4186 
4187         if (rsp.status & 0x7f00)
4188             rc = rsp.rsp0;
4189         if (!rc)
4190             memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
4191         goto done;
4192     } else {
4193         if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4194                     rc = status;
4195                     goto done;
4196             }
4197         if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4198             rc = ERROR;
4199                     goto done;
4200             }
4201         // read the rid length field
4202         bap_read(ai, pBuf, 2, BAP1);
4203         // length for remaining part of rid
4204         len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
4205 
4206         if (len <= 2) {
4207             airo_print_err(ai->dev->name,
4208                 "Rid %x has a length of %d which is too short",
4209                 (int)rid, (int)len);
4210             rc = ERROR;
4211                     goto done;
4212         }
4213         // read remainder of the rid
4214         rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
4215     }
4216 done:
4217     if (lock)
4218         up(&ai->sem);
4219     return rc;
4220 }
4221 
4222 /*  Note, that we are using BAP1 which is also used by transmit, so
4223  *  make sure this isn't called when a transmit is happening */
4224 static int PC4500_writerid(struct airo_info *ai, u16 rid,
4225                const void *pBuf, int len, int lock)
4226 {
4227     u16 status;
4228     int rc = SUCCESS;
4229 
4230     *(__le16*)pBuf = cpu_to_le16((u16)len);
4231 
4232     if (lock) {
4233         if (down_interruptible(&ai->sem))
4234             return ERROR;
4235     }
4236     if (test_bit(FLAG_MPI,&ai->flags)) {
4237         Cmd cmd;
4238         Resp rsp;
4239 
4240         if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
4241             airo_print_err(ai->dev->name,
4242                 "%s: MAC should be disabled (rid=%04x)",
4243                 __func__, rid);
4244         memset(&cmd, 0, sizeof(cmd));
4245         memset(&rsp, 0, sizeof(rsp));
4246 
4247         ai->config_desc.rid_desc.valid = 1;
4248         ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4249         ai->config_desc.rid_desc.rid = 0;
4250 
4251         cmd.cmd = CMD_WRITERID;
4252         cmd.parm0 = rid;
4253 
4254         memcpy_toio(ai->config_desc.card_ram_off,
4255             &ai->config_desc.rid_desc, sizeof(Rid));
4256 
4257         if (len < 4 || len > 2047) {
4258             airo_print_err(ai->dev->name, "%s: len=%d", __func__, len);
4259             rc = -1;
4260         } else {
4261             memcpy(ai->config_desc.virtual_host_addr,
4262                 pBuf, len);
4263 
4264             rc = issuecommand(ai, &cmd, &rsp, true);
4265             if ((rc & 0xff00) != 0) {
4266                 airo_print_err(ai->dev->name, "%s: Write rid Error %d",
4267                         __func__, rc);
4268                 airo_print_err(ai->dev->name, "%s: Cmd=%04x",
4269                         __func__, cmd.cmd);
4270             }
4271 
4272             if ((rsp.status & 0x7f00))
4273                 rc = rsp.rsp0;
4274         }
4275     } else {
4276         // --- first access so that we can write the rid data
4277         if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4278                     rc = status;
4279                     goto done;
4280             }
4281         // --- now write the rid data
4282         if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4283                     rc = ERROR;
4284                     goto done;
4285             }
4286         bap_write(ai, pBuf, len, BAP1);
4287         // ---now commit the rid data
4288         rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4289     }
4290 done:
4291     if (lock)
4292         up(&ai->sem);
4293         return rc;
4294 }
4295 
4296 /* Allocates a FID to be used for transmitting packets.  We only use
4297    one for now. */
4298 static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4299 {
4300     unsigned int loop = 3000;
4301     Cmd cmd;
4302     Resp rsp;
4303     u16 txFid;
4304     __le16 txControl;
4305 
4306     cmd.cmd = CMD_ALLOCATETX;
4307     cmd.parm0 = lenPayload;
4308     if (down_interruptible(&ai->sem))
4309         return ERROR;
4310     if (issuecommand(ai, &cmd, &rsp, true) != SUCCESS) {
4311         txFid = ERROR;
4312         goto done;
4313     }
4314     if ((rsp.status & 0xFF00) != 0) {
4315         txFid = ERROR;
4316         goto done;
4317     }
4318     /* wait for the allocate event/indication
4319      * It makes me kind of nervous that this can just sit here and spin,
4320      * but in practice it only loops like four times. */
4321     while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4322     if (!loop) {
4323         txFid = ERROR;
4324         goto done;
4325     }
4326 
4327     // get the allocated fid and acknowledge
4328     txFid = IN4500(ai, TXALLOCFID);
4329     OUT4500(ai, EVACK, EV_ALLOC);
4330 
4331     /*  The CARD is pretty cool since it converts the ethernet packet
4332      *  into 802.11.  Also note that we don't release the FID since we
4333      *  will be using the same one over and over again. */
4334     /*  We only have to setup the control once since we are not
4335      *  releasing the fid. */
4336     if (raw)
4337         txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4338             | TXCTL_ETHERNET | TXCTL_NORELEASE);
4339     else
4340         txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4341             | TXCTL_ETHERNET | TXCTL_NORELEASE);
4342     if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4343         txFid = ERROR;
4344     else
4345         bap_write(ai, &txControl, sizeof(txControl), BAP1);
4346 
4347 done:
4348     up(&ai->sem);
4349 
4350     return txFid;
4351 }
4352 
4353 /* In general BAP1 is dedicated to transmiting packets.  However,
4354    since we need a BAP when accessing RIDs, we also use BAP1 for that.
4355    Make sure the BAP1 spinlock is held when this is called. */
4356 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket,
4357                  bool may_sleep)
4358 {
4359     __le16 payloadLen;
4360     Cmd cmd;
4361     Resp rsp;
4362     int miclen = 0;
4363     u16 txFid = len;
4364     MICBuffer pMic;
4365 
4366     len >>= 16;
4367 
4368     if (len <= ETH_ALEN * 2) {
4369         airo_print_warn(ai->dev->name, "Short packet %d", len);
4370         return ERROR;
4371     }
4372     len -= ETH_ALEN * 2;
4373 
4374     if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
4375         (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
4376         if (encapsulate(ai, (etherHead *)pPacket,&pMic, len) != SUCCESS)
4377             return ERROR;
4378         miclen = sizeof(pMic);
4379     }
4380     // packet is destination[6], source[6], payload[len-12]
4381     // write the payload length and dst/src/payload
4382     if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4383     /* The hardware addresses aren't counted as part of the payload, so
4384      * we have to subtract the 12 bytes for the addresses off */
4385     payloadLen = cpu_to_le16(len + miclen);
4386     bap_write(ai, &payloadLen, sizeof(payloadLen), BAP1);
4387     bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
4388     if (miclen)
4389         bap_write(ai, (__le16*)&pMic, miclen, BAP1);
4390     bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
4391     // issue the transmit command
4392     memset(&cmd, 0, sizeof(cmd));
4393     cmd.cmd = CMD_TRANSMIT;
4394     cmd.parm0 = txFid;
4395     if (issuecommand(ai, &cmd, &rsp, may_sleep) != SUCCESS)
4396         return ERROR;
4397     if ((rsp.status & 0xFF00) != 0) return ERROR;
4398     return SUCCESS;
4399 }
4400 
4401 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket,
4402                   bool may_sleep)
4403 {
4404     __le16 fc, payloadLen;
4405     Cmd cmd;
4406     Resp rsp;
4407     int hdrlen;
4408     static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
4409     /* padding of header to full size + le16 gaplen (6) + gaplen bytes */
4410     u16 txFid = len;
4411     len >>= 16;
4412 
4413     fc = *(__le16*)pPacket;
4414     hdrlen = header_len(fc);
4415 
4416     if (len < hdrlen) {
4417         airo_print_warn(ai->dev->name, "Short packet %d", len);
4418         return ERROR;
4419     }
4420 
4421     /* packet is 802.11 header +  payload
4422      * write the payload length and dst/src/payload */
4423     if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4424     /* The 802.11 header aren't counted as part of the payload, so
4425      * we have to subtract the header bytes off */
4426     payloadLen = cpu_to_le16(len-hdrlen);
4427     bap_write(ai, &payloadLen, sizeof(payloadLen), BAP1);
4428     if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4429     bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
4430     bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
4431 
4432     bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
4433     // issue the transmit command
4434     memset(&cmd, 0, sizeof(cmd));
4435     cmd.cmd = CMD_TRANSMIT;
4436     cmd.parm0 = txFid;
4437     if (issuecommand(ai, &cmd, &rsp, may_sleep) != SUCCESS)
4438         return ERROR;
4439     if ((rsp.status & 0xFF00) != 0) return ERROR;
4440     return SUCCESS;
4441 }
4442 
4443 /*
4444  *  This is the proc_fs routines.  It is a bit messier than I would
4445  *  like!  Feel free to clean it up!
4446  */
4447 
4448 static ssize_t proc_read(struct file *file,
4449               char __user *buffer,
4450               size_t len,
4451               loff_t *offset);
4452 
4453 static ssize_t proc_write(struct file *file,
4454                const char __user *buffer,
4455                size_t len,
4456                loff_t *offset);
4457 static int proc_close(struct inode *inode, struct file *file);
4458 
4459 static int proc_stats_open(struct inode *inode, struct file *file);
4460 static int proc_statsdelta_open(struct inode *inode, struct file *file);
4461 static int proc_status_open(struct inode *inode, struct file *file);
4462 static int proc_SSID_open(struct inode *inode, struct file *file);
4463 static int proc_APList_open(struct inode *inode, struct file *file);
4464 static int proc_BSSList_open(struct inode *inode, struct file *file);
4465 static int proc_config_open(struct inode *inode, struct file *file);
4466 static int proc_wepkey_open(struct inode *inode, struct file *file);
4467 
4468 static const struct proc_ops proc_statsdelta_ops = {
4469     .proc_read  = proc_read,
4470     .proc_open  = proc_statsdelta_open,
4471     .proc_release   = proc_close,
4472     .proc_lseek = default_llseek,
4473 };
4474 
4475 static const struct proc_ops proc_stats_ops = {
4476     .proc_read  = proc_read,
4477     .proc_open  = proc_stats_open,
4478     .proc_release   = proc_close,
4479     .proc_lseek = default_llseek,
4480 };
4481 
4482 static const struct proc_ops proc_status_ops = {
4483     .proc_read  = proc_read,
4484     .proc_open  = proc_status_open,
4485     .proc_release   = proc_close,
4486     .proc_lseek = default_llseek,
4487 };
4488 
4489 static const struct proc_ops proc_SSID_ops = {
4490     .proc_read  = proc_read,
4491     .proc_write = proc_write,
4492     .proc_open  = proc_SSID_open,
4493     .proc_release   = proc_close,
4494     .proc_lseek = default_llseek,
4495 };
4496 
4497 static const struct proc_ops proc_BSSList_ops = {
4498     .proc_read  = proc_read,
4499     .proc_write = proc_write,
4500     .proc_open  = proc_BSSList_open,
4501     .proc_release   = proc_close,
4502     .proc_lseek = default_llseek,
4503 };
4504 
4505 static const struct proc_ops proc_APList_ops = {
4506     .proc_read  = proc_read,
4507     .proc_write = proc_write,
4508     .proc_open  = proc_APList_open,
4509     .proc_release   = proc_close,
4510     .proc_lseek = default_llseek,
4511 };
4512 
4513 static const struct proc_ops proc_config_ops = {
4514     .proc_read  = proc_read,
4515     .proc_write = proc_write,
4516     .proc_open  = proc_config_open,
4517     .proc_release   = proc_close,
4518     .proc_lseek = default_llseek,
4519 };
4520 
4521 static const struct proc_ops proc_wepkey_ops = {
4522     .proc_read  = proc_read,
4523     .proc_write = proc_write,
4524     .proc_open  = proc_wepkey_open,
4525     .proc_release   = proc_close,
4526     .proc_lseek = default_llseek,
4527 };
4528 
4529 static struct proc_dir_entry *airo_entry;
4530 
4531 struct proc_data {
4532     int release_buffer;
4533     int readlen;
4534     char *rbuffer;
4535     int writelen;
4536     int maxwritelen;
4537     char *wbuffer;
4538     void (*on_close) (struct inode *, struct file *);
4539 };
4540 
4541 static int setup_proc_entry(struct net_device *dev,
4542                  struct airo_info *apriv)
4543 {
4544     struct proc_dir_entry *entry;
4545 
4546     /* First setup the device directory */
4547     strcpy(apriv->proc_name, dev->name);
4548     apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
4549                         airo_entry);
4550     if (!apriv->proc_entry)
4551         return -ENOMEM;
4552     proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
4553 
4554     /* Setup the StatsDelta */
4555     entry = proc_create_data("StatsDelta", 0444 & proc_perm,
4556                  apriv->proc_entry, &proc_statsdelta_ops, dev);
4557     if (!entry)
4558         goto fail;
4559     proc_set_user(entry, proc_kuid, proc_kgid);
4560 
4561     /* Setup the Stats */
4562     entry = proc_create_data("Stats", 0444 & proc_perm,
4563                  apriv->proc_entry, &proc_stats_ops, dev);
4564     if (!entry)
4565         goto fail;
4566     proc_set_user(entry, proc_kuid, proc_kgid);
4567 
4568     /* Setup the Status */
4569     entry = proc_create_data("Status", 0444 & proc_perm,
4570                  apriv->proc_entry, &proc_status_ops, dev);
4571     if (!entry)
4572         goto fail;
4573     proc_set_user(entry, proc_kuid, proc_kgid);
4574 
4575     /* Setup the Config */
4576     entry = proc_create_data("Config", proc_perm,
4577                  apriv->proc_entry, &proc_config_ops, dev);
4578     if (!entry)
4579         goto fail;
4580     proc_set_user(entry, proc_kuid, proc_kgid);
4581 
4582     /* Setup the SSID */
4583     entry = proc_create_data("SSID", proc_perm,
4584                  apriv->proc_entry, &proc_SSID_ops, dev);
4585     if (!entry)
4586         goto fail;
4587     proc_set_user(entry, proc_kuid, proc_kgid);
4588 
4589     /* Setup the APList */
4590     entry = proc_create_data("APList", proc_perm,
4591                  apriv->proc_entry, &proc_APList_ops, dev);
4592     if (!entry)
4593         goto fail;
4594     proc_set_user(entry, proc_kuid, proc_kgid);
4595 
4596     /* Setup the BSSList */
4597     entry = proc_create_data("BSSList", proc_perm,
4598                  apriv->proc_entry, &proc_BSSList_ops, dev);
4599     if (!entry)
4600         goto fail;
4601     proc_set_user(entry, proc_kuid, proc_kgid);
4602 
4603     /* Setup the WepKey */
4604     entry = proc_create_data("WepKey", proc_perm,
4605                  apriv->proc_entry, &proc_wepkey_ops, dev);
4606     if (!entry)
4607         goto fail;
4608     proc_set_user(entry, proc_kuid, proc_kgid);
4609     return 0;
4610 
4611 fail:
4612     remove_proc_subtree(apriv->proc_name, airo_entry);
4613     return -ENOMEM;
4614 }
4615 
4616 static int takedown_proc_entry(struct net_device *dev,
4617                 struct airo_info *apriv)
4618 {
4619     remove_proc_subtree(apriv->proc_name, airo_entry);
4620     return 0;
4621 }
4622 
4623 /*
4624  *  What we want from the proc_fs is to be able to efficiently read
4625  *  and write the configuration.  To do this, we want to read the
4626  *  configuration when the file is opened and write it when the file is
4627  *  closed.  So basically we allocate a read buffer at open and fill it
4628  *  with data, and allocate a write buffer and read it at close.
4629  */
4630 
4631 /*
4632  *  The read routine is generic, it relies on the preallocated rbuffer
4633  *  to supply the data.
4634  */
4635 static ssize_t proc_read(struct file *file,
4636               char __user *buffer,
4637               size_t len,
4638               loff_t *offset)
4639 {
4640     struct proc_data *priv = file->private_data;
4641 
4642     if (!priv->rbuffer)
4643         return -EINVAL;
4644 
4645     return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
4646                     priv->readlen);
4647 }
4648 
4649 /*
4650  *  The write routine is generic, it fills in a preallocated rbuffer
4651  *  to supply the data.
4652  */
4653 static ssize_t proc_write(struct file *file,
4654                const char __user *buffer,
4655                size_t len,
4656                loff_t *offset)
4657 {
4658     ssize_t ret;
4659     struct proc_data *priv = file->private_data;
4660 
4661     if (!priv->wbuffer)
4662         return -EINVAL;
4663 
4664     ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
4665                     buffer, len);
4666     if (ret > 0)
4667         priv->writelen = max_t(int, priv->writelen, *offset);
4668 
4669     return ret;
4670 }
4671 
4672 static int proc_status_open(struct inode *inode, struct file *file)
4673 {
4674     struct proc_data *data;
4675     struct net_device *dev = pde_data(inode);
4676     struct airo_info *apriv = dev->ml_priv;
4677     CapabilityRid cap_rid;
4678     StatusRid status_rid;
4679     u16 mode;
4680     int i;
4681 
4682     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
4683         return -ENOMEM;
4684     data = file->private_data;
4685     if ((data->rbuffer = kmalloc(2048, GFP_KERNEL)) == NULL) {
4686         kfree (file->private_data);
4687         return -ENOMEM;
4688     }
4689 
4690     readStatusRid(apriv, &status_rid, 1);
4691     readCapabilityRid(apriv, &cap_rid, 1);
4692 
4693     mode = le16_to_cpu(status_rid.mode);
4694 
4695         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4696                     mode & 1 ? "CFG ": "",
4697                     mode & 2 ? "ACT ": "",
4698                     mode & 0x10 ? "SYN ": "",
4699                     mode & 0x20 ? "LNK ": "",
4700                     mode & 0x40 ? "LEAP ": "",
4701                     mode & 0x80 ? "PRIV ": "",
4702                     mode & 0x100 ? "KEY ": "",
4703                     mode & 0x200 ? "WEP ": "",
4704                     mode & 0x8000 ? "ERR ": "");
4705     sprintf(data->rbuffer+i, "Mode: %x\n"
4706          "Signal Strength: %d\n"
4707          "Signal Quality: %d\n"
4708          "SSID: %-.*s\n"
4709          "AP: %-.16s\n"
4710          "Freq: %d\n"
4711          "BitRate: %dmbs\n"
4712          "Driver Version: %s\n"
4713          "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4714          "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4715          "Software Version: %x\nSoftware Subversion: %x\n"
4716          "Boot block version: %x\n",
4717          le16_to_cpu(status_rid.mode),
4718          le16_to_cpu(status_rid.normalizedSignalStrength),
4719          le16_to_cpu(status_rid.signalQuality),
4720          le16_to_cpu(status_rid.SSIDlen),
4721          status_rid.SSID,
4722          status_rid.apName,
4723          le16_to_cpu(status_rid.channel),
4724          le16_to_cpu(status_rid.currentXmitRate) / 2,
4725          version,
4726          cap_rid.prodName,
4727          cap_rid.manName,
4728          cap_rid.prodVer,
4729          le16_to_cpu(cap_rid.radioType),
4730          le16_to_cpu(cap_rid.country),
4731          le16_to_cpu(cap_rid.hardVer),
4732          le16_to_cpu(cap_rid.softVer),
4733          le16_to_cpu(cap_rid.softSubVer),
4734          le16_to_cpu(cap_rid.bootBlockVer));
4735     data->readlen = strlen(data->rbuffer);
4736     return 0;
4737 }
4738 
4739 static int proc_stats_rid_open(struct inode*, struct file*, u16);
4740 static int proc_statsdelta_open(struct inode *inode,
4741                  struct file *file)
4742 {
4743     if (file->f_mode&FMODE_WRITE) {
4744         return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4745     }
4746     return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4747 }
4748 
4749 static int proc_stats_open(struct inode *inode, struct file *file)
4750 {
4751     return proc_stats_rid_open(inode, file, RID_STATS);
4752 }
4753 
4754 static int proc_stats_rid_open(struct inode *inode,
4755                 struct file *file,
4756                 u16 rid)
4757 {
4758     struct proc_data *data;
4759     struct net_device *dev = pde_data(inode);
4760     struct airo_info *apriv = dev->ml_priv;
4761     StatsRid stats;
4762     int i, j;
4763     __le32 *vals = stats.vals;
4764     int len;
4765 
4766     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
4767         return -ENOMEM;
4768     data = file->private_data;
4769     if ((data->rbuffer = kmalloc(4096, GFP_KERNEL)) == NULL) {
4770         kfree (file->private_data);
4771         return -ENOMEM;
4772     }
4773 
4774     readStatsRid(apriv, &stats, rid, 1);
4775     len = le16_to_cpu(stats.len);
4776 
4777         j = 0;
4778     for (i = 0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4779         if (!statsLabels[i]) continue;
4780         if (j+strlen(statsLabels[i])+16>4096) {
4781             airo_print_warn(apriv->dev->name,
4782                    "Potentially disastrous buffer overflow averted!");
4783             break;
4784         }
4785         j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4786                 le32_to_cpu(vals[i]));
4787     }
4788     if (i*4 >= len) {
4789         airo_print_warn(apriv->dev->name, "Got a short rid");
4790     }
4791     data->readlen = j;
4792     return 0;
4793 }
4794 
4795 static int get_dec_u16(char *buffer, int *start, int limit)
4796 {
4797     u16 value;
4798     int valid = 0;
4799     for (value = 0; *start < limit && buffer[*start] >= '0' &&
4800             buffer[*start] <= '9'; (*start)++) {
4801         valid = 1;
4802         value *= 10;
4803         value += buffer[*start] - '0';
4804     }
4805     if (!valid) return -1;
4806     return value;
4807 }
4808 
4809 static int airo_config_commit(struct net_device *dev,
4810                   struct iw_request_info *info, void *zwrq,
4811                   char *extra);
4812 
4813 static inline int sniffing_mode(struct airo_info *ai)
4814 {
4815     return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
4816         le16_to_cpu(RXMODE_RFMON);
4817 }
4818 
4819 static void proc_config_on_close(struct inode *inode, struct file *file)
4820 {
4821     struct proc_data *data = file->private_data;
4822     struct net_device *dev = pde_data(inode);
4823     struct airo_info *ai = dev->ml_priv;
4824     char *line;
4825 
4826     if (!data->writelen) return;
4827 
4828     readConfigRid(ai, 1);
4829     set_bit (FLAG_COMMIT, &ai->flags);
4830 
4831     line = data->wbuffer;
4832     while (line[0]) {
4833 /*** Mode processing */
4834         if (!strncmp(line, "Mode: ", 6)) {
4835             line += 6;
4836             if (sniffing_mode(ai))
4837                 set_bit (FLAG_RESET, &ai->flags);
4838             ai->config.rmode &= ~RXMODE_FULL_MASK;
4839             clear_bit (FLAG_802_11, &ai->flags);
4840             ai->config.opmode &= ~MODE_CFG_MASK;
4841             ai->config.scanMode = SCANMODE_ACTIVE;
4842             if (line[0] == 'a') {
4843                 ai->config.opmode |= MODE_STA_IBSS;
4844             } else {
4845                 ai->config.opmode |= MODE_STA_ESS;
4846                 if (line[0] == 'r') {
4847                     ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4848                     ai->config.scanMode = SCANMODE_PASSIVE;
4849                     set_bit (FLAG_802_11, &ai->flags);
4850                 } else if (line[0] == 'y') {
4851                     ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4852                     ai->config.scanMode = SCANMODE_PASSIVE;
4853                     set_bit (FLAG_802_11, &ai->flags);
4854                 } else if (line[0] == 'l')
4855                     ai->config.rmode |= RXMODE_LANMON;
4856             }
4857             set_bit (FLAG_COMMIT, &ai->flags);
4858         }
4859 
4860 /*** Radio status */
4861         else if (!strncmp(line,"Radio: ", 7)) {
4862             line += 7;
4863             if (!strncmp(line,"off", 3)) {
4864                 set_bit (FLAG_RADIO_OFF, &ai->flags);
4865             } else {
4866                 clear_bit (FLAG_RADIO_OFF, &ai->flags);
4867             }
4868         }
4869 /*** NodeName processing */
4870         else if (!strncmp(line, "NodeName: ", 10)) {
4871             int j;
4872 
4873             line += 10;
4874             memset(ai->config.nodeName, 0, 16);
4875 /* Do the name, assume a space between the mode and node name */
4876             for (j = 0; j < 16 && line[j] != '\n'; j++) {
4877                 ai->config.nodeName[j] = line[j];
4878             }
4879             set_bit (FLAG_COMMIT, &ai->flags);
4880         }
4881 
4882 /*** PowerMode processing */
4883         else if (!strncmp(line, "PowerMode: ", 11)) {
4884             line += 11;
4885             if (!strncmp(line, "PSPCAM", 6)) {
4886                 ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4887                 set_bit (FLAG_COMMIT, &ai->flags);
4888             } else if (!strncmp(line, "PSP", 3)) {
4889                 ai->config.powerSaveMode = POWERSAVE_PSP;
4890                 set_bit (FLAG_COMMIT, &ai->flags);
4891             } else {
4892                 ai->config.powerSaveMode = POWERSAVE_CAM;
4893                 set_bit (FLAG_COMMIT, &ai->flags);
4894             }
4895         } else if (!strncmp(line, "DataRates: ", 11)) {
4896             int v, i = 0, k = 0; /* i is index into line,
4897                         k is index to rates */
4898 
4899             line += 11;
4900             while ((v = get_dec_u16(line, &i, 3))!=-1) {
4901                 ai->config.rates[k++] = (u8)v;
4902                 line += i + 1;
4903                 i = 0;
4904             }
4905             set_bit (FLAG_COMMIT, &ai->flags);
4906         } else if (!strncmp(line, "Channel: ", 9)) {
4907             int v, i = 0;
4908             line += 9;
4909             v = get_dec_u16(line, &i, i+3);
4910             if (v != -1) {
4911                 ai->config.channelSet = cpu_to_le16(v);
4912                 set_bit (FLAG_COMMIT, &ai->flags);
4913             }
4914         } else if (!strncmp(line, "XmitPower: ", 11)) {
4915             int v, i = 0;
4916             line += 11;
4917             v = get_dec_u16(line, &i, i+3);
4918             if (v != -1) {
4919                 ai->config.txPower = cpu_to_le16(v);
4920                 set_bit (FLAG_COMMIT, &ai->flags);
4921             }
4922         } else if (!strncmp(line, "WEP: ", 5)) {
4923             line += 5;
4924             switch(line[0]) {
4925             case 's':
4926                 set_auth_type(ai, AUTH_SHAREDKEY);
4927                 break;
4928             case 'e':
4929                 set_auth_type(ai, AUTH_ENCRYPT);
4930                 break;
4931             default:
4932                 set_auth_type(ai, AUTH_OPEN);
4933                 break;
4934             }
4935             set_bit (FLAG_COMMIT, &ai->flags);
4936         } else if (!strncmp(line, "LongRetryLimit: ", 16)) {
4937             int v, i = 0;
4938 
4939             line += 16;
4940             v = get_dec_u16(line, &i, 3);
4941             v = (v<0) ? 0 : ((v>255) ? 255 : v);
4942             ai->config.longRetryLimit = cpu_to_le16(v);
4943             set_bit (FLAG_COMMIT, &ai->flags);
4944         } else if (!strncmp(line, "ShortRetryLimit: ", 17)) {
4945             int v, i = 0;
4946 
4947             line += 17;
4948             v = get_dec_u16(line, &i, 3);
4949             v = (v<0) ? 0 : ((v>255) ? 255 : v);
4950             ai->config.shortRetryLimit = cpu_to_le16(v);
4951             set_bit (FLAG_COMMIT, &ai->flags);
4952         } else if (!strncmp(line, "RTSThreshold: ", 14)) {
4953             int v, i = 0;
4954 
4955             line += 14;
4956             v = get_dec_u16(line, &i, 4);
4957             v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4958             ai->config.rtsThres = cpu_to_le16(v);
4959             set_bit (FLAG_COMMIT, &ai->flags);
4960         } else if (!strncmp(line, "TXMSDULifetime: ", 16)) {
4961             int v, i = 0;
4962 
4963             line += 16;
4964             v = get_dec_u16(line, &i, 5);
4965             v = (v<0) ? 0 : v;
4966             ai->config.txLifetime = cpu_to_le16(v);
4967             set_bit (FLAG_COMMIT, &ai->flags);
4968         } else if (!strncmp(line, "RXMSDULifetime: ", 16)) {
4969             int v, i = 0;
4970 
4971             line += 16;
4972             v = get_dec_u16(line, &i, 5);
4973             v = (v<0) ? 0 : v;
4974             ai->config.rxLifetime = cpu_to_le16(v);
4975             set_bit (FLAG_COMMIT, &ai->flags);
4976         } else if (!strncmp(line, "TXDiversity: ", 13)) {
4977             ai->config.txDiversity =
4978                 (line[13]=='l') ? 1 :
4979                 ((line[13]=='r')? 2: 3);
4980             set_bit (FLAG_COMMIT, &ai->flags);
4981         } else if (!strncmp(line, "RXDiversity: ", 13)) {
4982             ai->config.rxDiversity =
4983                 (line[13]=='l') ? 1 :
4984                 ((line[13]=='r')? 2: 3);
4985             set_bit (FLAG_COMMIT, &ai->flags);
4986         } else if (!strncmp(line, "FragThreshold: ", 15)) {
4987             int v, i = 0;
4988 
4989             line += 15;
4990             v = get_dec_u16(line, &i, 4);
4991             v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4992             v = v & 0xfffe; /* Make sure its even */
4993             ai->config.fragThresh = cpu_to_le16(v);
4994             set_bit (FLAG_COMMIT, &ai->flags);
4995         } else if (!strncmp(line, "Modulation: ", 12)) {
4996             line += 12;
4997             switch(*line) {
4998             case 'd':  ai->config.modulation = MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4999             case 'c':  ai->config.modulation = MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
5000             case 'm':  ai->config.modulation = MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
5001             default: airo_print_warn(ai->dev->name, "Unknown modulation");
5002             }
5003         } else if (!strncmp(line, "Preamble: ", 10)) {
5004             line += 10;
5005             switch(*line) {
5006             case 'a': ai->config.preamble = PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
5007             case 'l': ai->config.preamble = PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
5008             case 's': ai->config.preamble = PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
5009             default: airo_print_warn(ai->dev->name, "Unknown preamble");
5010             }
5011         } else {
5012             airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
5013         }
5014         while (line[0] && line[0] != '\n') line++;
5015         if (line[0]) line++;
5016     }
5017     airo_config_commit(dev, NULL, NULL, NULL);
5018 }
5019 
5020 static const char *get_rmode(__le16 mode)
5021 {
5022         switch(mode & RXMODE_MASK) {
5023         case RXMODE_RFMON:  return "rfmon";
5024         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
5025         case RXMODE_LANMON:  return "lanmon";
5026         }
5027         return "ESS";
5028 }
5029 
5030 static int proc_config_open(struct inode *inode, struct file *file)
5031 {
5032     struct proc_data *data;
5033     struct net_device *dev = pde_data(inode);
5034     struct airo_info *ai = dev->ml_priv;
5035     int i;
5036     __le16 mode;
5037 
5038     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5039         return -ENOMEM;
5040     data = file->private_data;
5041     if ((data->rbuffer = kmalloc(2048, GFP_KERNEL)) == NULL) {
5042         kfree (file->private_data);
5043         return -ENOMEM;
5044     }
5045     if ((data->wbuffer = kzalloc(2048, GFP_KERNEL)) == NULL) {
5046         kfree (data->rbuffer);
5047         kfree (file->private_data);
5048         return -ENOMEM;
5049     }
5050     data->maxwritelen = 2048;
5051     data->on_close = proc_config_on_close;
5052 
5053     readConfigRid(ai, 1);
5054 
5055     mode = ai->config.opmode & MODE_CFG_MASK;
5056     i = sprintf(data->rbuffer,
5057              "Mode: %s\n"
5058              "Radio: %s\n"
5059              "NodeName: %-16s\n"
5060              "PowerMode: %s\n"
5061              "DataRates: %d %d %d %d %d %d %d %d\n"
5062              "Channel: %d\n"
5063              "XmitPower: %d\n",
5064              mode == MODE_STA_IBSS ? "adhoc" :
5065              mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
5066              mode == MODE_AP ? "AP" :
5067              mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
5068              test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
5069              ai->config.nodeName,
5070              ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
5071              ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
5072              ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
5073              "Error",
5074              (int)ai->config.rates[0],
5075              (int)ai->config.rates[1],
5076              (int)ai->config.rates[2],
5077              (int)ai->config.rates[3],
5078              (int)ai->config.rates[4],
5079              (int)ai->config.rates[5],
5080              (int)ai->config.rates[6],
5081              (int)ai->config.rates[7],
5082              le16_to_cpu(ai->config.channelSet),
5083              le16_to_cpu(ai->config.txPower)
5084         );
5085     sprintf(data->rbuffer + i,
5086          "LongRetryLimit: %d\n"
5087          "ShortRetryLimit: %d\n"
5088          "RTSThreshold: %d\n"
5089          "TXMSDULifetime: %d\n"
5090          "RXMSDULifetime: %d\n"
5091          "TXDiversity: %s\n"
5092          "RXDiversity: %s\n"
5093          "FragThreshold: %d\n"
5094          "WEP: %s\n"
5095          "Modulation: %s\n"
5096          "Preamble: %s\n",
5097          le16_to_cpu(ai->config.longRetryLimit),
5098          le16_to_cpu(ai->config.shortRetryLimit),
5099          le16_to_cpu(ai->config.rtsThres),
5100          le16_to_cpu(ai->config.txLifetime),
5101          le16_to_cpu(ai->config.rxLifetime),
5102          ai->config.txDiversity == 1 ? "left" :
5103          ai->config.txDiversity == 2 ? "right" : "both",
5104          ai->config.rxDiversity == 1 ? "left" :
5105          ai->config.rxDiversity == 2 ? "right" : "both",
5106          le16_to_cpu(ai->config.fragThresh),
5107          ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
5108          ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
5109          ai->config.modulation == MOD_DEFAULT ? "default" :
5110          ai->config.modulation == MOD_CCK ? "cck" :
5111          ai->config.modulation == MOD_MOK ? "mok" : "error",
5112          ai->config.preamble == PREAMBLE_AUTO ? "auto" :
5113          ai->config.preamble == PREAMBLE_LONG ? "long" :
5114          ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
5115         );
5116     data->readlen = strlen(data->rbuffer);
5117     return 0;
5118 }
5119 
5120 static void proc_SSID_on_close(struct inode *inode, struct file *file)
5121 {
5122     struct proc_data *data = file->private_data;
5123     struct net_device *dev = pde_data(inode);
5124     struct airo_info *ai = dev->ml_priv;
5125     SsidRid SSID_rid;
5126     int i;
5127     char *p = data->wbuffer;
5128     char *end = p + data->writelen;
5129 
5130     if (!data->writelen)
5131         return;
5132 
5133     *end = '\n'; /* sentinel; we have space for it */
5134 
5135     memset(&SSID_rid, 0, sizeof(SSID_rid));
5136 
5137     for (i = 0; i < 3 && p < end; i++) {
5138         int j = 0;
5139         /* copy up to 32 characters from this line */
5140         while (*p != '\n' && j < 32)
5141             SSID_rid.ssids[i].ssid[j++] = *p++;
5142         if (j == 0)
5143             break;
5144         SSID_rid.ssids[i].len = cpu_to_le16(j);
5145         /* skip to the beginning of the next line */
5146         while (*p++ != '\n')
5147             ;
5148     }
5149     if (i)
5150         SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5151     disable_MAC(ai, 1);
5152     writeSsidRid(ai, &SSID_rid, 1);
5153     enable_MAC(ai, 1);
5154 }
5155 
5156 static void proc_APList_on_close(struct inode *inode, struct file *file)
5157 {
5158     struct proc_data *data = file->private_data;
5159     struct net_device *dev = pde_data(inode);
5160     struct airo_info *ai = dev->ml_priv;
5161     APListRid *APList_rid = &ai->APList;
5162     int i;
5163 
5164     if (!data->writelen) return;
5165 
5166     memset(APList_rid, 0, sizeof(*APList_rid));
5167     APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5168 
5169     for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
5170         mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
5171 
5172     disable_MAC(ai, 1);
5173     writeAPListRid(ai, APList_rid, 1);
5174     enable_MAC(ai, 1);
5175 }
5176 
5177 /* This function wraps PC4500_writerid with a MAC disable */
5178 static int do_writerid(struct airo_info *ai, u16 rid, const void *rid_data,
5179             int len, int dummy)
5180 {
5181     int rc;
5182 
5183     disable_MAC(ai, 1);
5184     rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5185     enable_MAC(ai, 1);
5186     return rc;
5187 }
5188 
5189 /* Returns the WEP key at the specified index, or -1 if that key does
5190  * not exist.  The buffer is assumed to be at least 16 bytes in length.
5191  */
5192 static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
5193 {
5194     WepKeyRid wkr;
5195     int rc;
5196     __le16 lastindex;
5197 
5198     rc = readWepKeyRid(ai, &wkr, 1, 1);
5199     if (rc != SUCCESS)
5200         return -1;
5201     do {
5202         lastindex = wkr.kindex;
5203         if (le16_to_cpu(wkr.kindex) == index) {
5204             int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
5205             memcpy(buf, wkr.key, klen);
5206             return klen;
5207         }
5208         rc = readWepKeyRid(ai, &wkr, 0, 1);
5209         if (rc != SUCCESS)
5210             return -1;
5211     } while (lastindex != wkr.kindex);
5212     return -1;
5213 }
5214 
5215 static int get_wep_tx_idx(struct airo_info *ai)
5216 {
5217     WepKeyRid wkr;
5218     int rc;
5219     __le16 lastindex;
5220 
5221     rc = readWepKeyRid(ai, &wkr, 1, 1);
5222     if (rc != SUCCESS)
5223         return -1;
5224     do {
5225         lastindex = wkr.kindex;
5226         if (wkr.kindex == cpu_to_le16(0xffff))
5227             return wkr.mac[0];
5228         rc = readWepKeyRid(ai, &wkr, 0, 1);
5229         if (rc != SUCCESS)
5230             return -1;
5231     } while (lastindex != wkr.kindex);
5232     return -1;
5233 }
5234 
5235 static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5236                u16 keylen, int perm, int lock)
5237 {
5238     static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5239     WepKeyRid wkr;
5240     int rc;
5241 
5242     if (WARN_ON(keylen == 0))
5243         return -1;
5244 
5245     memset(&wkr, 0, sizeof(wkr));
5246     wkr.len = cpu_to_le16(sizeof(wkr));
5247     wkr.kindex = cpu_to_le16(index);
5248     wkr.klen = cpu_to_le16(keylen);
5249     memcpy(wkr.key, key, keylen);
5250     memcpy(wkr.mac, macaddr, ETH_ALEN);
5251 
5252     if (perm) disable_MAC(ai, lock);
5253     rc = writeWepKeyRid(ai, &wkr, perm, lock);
5254     if (perm) enable_MAC(ai, lock);
5255     return rc;
5256 }
5257 
5258 static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
5259 {
5260     WepKeyRid wkr;
5261     int rc;
5262 
5263     memset(&wkr, 0, sizeof(wkr));
5264     wkr.len = cpu_to_le16(sizeof(wkr));
5265     wkr.kindex = cpu_to_le16(0xffff);
5266     wkr.mac[0] = (char)index;
5267 
5268     if (perm) {
5269         ai->defindex = (char)index;
5270         disable_MAC(ai, lock);
5271     }
5272 
5273     rc = writeWepKeyRid(ai, &wkr, perm, lock);
5274 
5275     if (perm)
5276         enable_MAC(ai, lock);
5277     return rc;
5278 }
5279 
5280 static void proc_wepkey_on_close(struct inode *inode, struct file *file)
5281 {
5282     struct proc_data *data;
5283     struct net_device *dev = pde_data(inode);
5284     struct airo_info *ai = dev->ml_priv;
5285     int i, rc;
5286     char key[16];
5287     u16 index = 0;
5288     int j = 0;
5289 
5290     memset(key, 0, sizeof(key));
5291 
5292     data = file->private_data;
5293     if (!data->writelen) return;
5294 
5295     if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5296         (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5297         index = data->wbuffer[0] - '0';
5298         if (data->wbuffer[1] == '\n') {
5299             rc = set_wep_tx_idx(ai, index, 1, 1);
5300             if (rc < 0) {
5301                 airo_print_err(ai->dev->name, "failed to set "
5302                                "WEP transmit index to %d: %d.",
5303                                index, rc);
5304             }
5305             return;
5306         }
5307         j = 2;
5308     } else {
5309         airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5310         return;
5311     }
5312 
5313     for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) {
5314         switch(i%3) {
5315         case 0:
5316             key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
5317             break;
5318         case 1:
5319             key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
5320             break;
5321         }
5322     }
5323 
5324     rc = set_wep_key(ai, index, key, i/3, 1, 1);
5325     if (rc < 0) {
5326         airo_print_err(ai->dev->name, "failed to set WEP key at index "
5327                        "%d: %d.", index, rc);
5328     }
5329 }
5330 
5331 static int proc_wepkey_open(struct inode *inode, struct file *file)
5332 {
5333     struct proc_data *data;
5334     struct net_device *dev = pde_data(inode);
5335     struct airo_info *ai = dev->ml_priv;
5336     char *ptr;
5337     WepKeyRid wkr;
5338     __le16 lastindex;
5339     int j = 0;
5340     int rc;
5341 
5342     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5343         return -ENOMEM;
5344     memset(&wkr, 0, sizeof(wkr));
5345     data = file->private_data;
5346     if ((data->rbuffer = kzalloc(180, GFP_KERNEL)) == NULL) {
5347         kfree (file->private_data);
5348         return -ENOMEM;
5349     }
5350     data->writelen = 0;
5351     data->maxwritelen = 80;
5352     if ((data->wbuffer = kzalloc(80, GFP_KERNEL)) == NULL) {
5353         kfree (data->rbuffer);
5354         kfree (file->private_data);
5355         return -ENOMEM;
5356     }
5357     data->on_close = proc_wepkey_on_close;
5358 
5359     ptr = data->rbuffer;
5360     strcpy(ptr, "No wep keys\n");
5361     rc = readWepKeyRid(ai, &wkr, 1, 1);
5362     if (rc == SUCCESS) do {
5363         lastindex = wkr.kindex;
5364         if (wkr.kindex == cpu_to_le16(0xffff)) {
5365             j += sprintf(ptr+j, "Tx key = %d\n",
5366                      (int)wkr.mac[0]);
5367         } else {
5368             j += sprintf(ptr+j, "Key %d set with length = %d\n",
5369                      le16_to_cpu(wkr.kindex),
5370                      le16_to_cpu(wkr.klen));
5371         }
5372         readWepKeyRid(ai, &wkr, 0, 1);
5373     } while ((lastindex != wkr.kindex) && (j < 180-30));
5374 
5375     data->readlen = strlen(data->rbuffer);
5376     return 0;
5377 }
5378 
5379 static int proc_SSID_open(struct inode *inode, struct file *file)
5380 {
5381     struct proc_data *data;
5382     struct net_device *dev = pde_data(inode);
5383     struct airo_info *ai = dev->ml_priv;
5384     int i;
5385     char *ptr;
5386     SsidRid SSID_rid;
5387 
5388     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5389         return -ENOMEM;
5390     data = file->private_data;
5391     if ((data->rbuffer = kmalloc(104, GFP_KERNEL)) == NULL) {
5392         kfree (file->private_data);
5393         return -ENOMEM;
5394     }
5395     data->writelen = 0;
5396     data->maxwritelen = 33*3;
5397     /* allocate maxwritelen + 1; we'll want a sentinel */
5398     if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5399         kfree (data->rbuffer);
5400         kfree (file->private_data);
5401         return -ENOMEM;
5402     }
5403     data->on_close = proc_SSID_on_close;
5404 
5405     readSsidRid(ai, &SSID_rid);
5406     ptr = data->rbuffer;
5407     for (i = 0; i < 3; i++) {
5408         int j;
5409         size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5410         if (!len)
5411             break;
5412         if (len > 32)
5413             len = 32;
5414         for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5415             *ptr++ = SSID_rid.ssids[i].ssid[j];
5416         *ptr++ = '\n';
5417     }
5418     *ptr = '\0';
5419     data->readlen = strlen(data->rbuffer);
5420     return 0;
5421 }
5422 
5423 static int proc_APList_open(struct inode *inode, struct file *file)
5424 {
5425     struct proc_data *data;
5426     struct net_device *dev = pde_data(inode);
5427     struct airo_info *ai = dev->ml_priv;
5428     int i;
5429     char *ptr;
5430     APListRid *APList_rid = &ai->APList;
5431 
5432     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5433         return -ENOMEM;
5434     data = file->private_data;
5435     if ((data->rbuffer = kmalloc(104, GFP_KERNEL)) == NULL) {
5436         kfree (file->private_data);
5437         return -ENOMEM;
5438     }
5439     data->writelen = 0;
5440     data->maxwritelen = 4*6*3;
5441     if ((data->wbuffer = kzalloc(data->maxwritelen, GFP_KERNEL)) == NULL) {
5442         kfree (data->rbuffer);
5443         kfree (file->private_data);
5444         return -ENOMEM;
5445     }
5446     data->on_close = proc_APList_on_close;
5447 
5448     ptr = data->rbuffer;
5449     for (i = 0; i < 4; i++) {
5450 // We end when we find a zero MAC
5451         if (!*(int*)APList_rid->ap[i] &&
5452              !*(int*)&APList_rid->ap[i][2]) break;
5453         ptr += sprintf(ptr, "%pM\n", APList_rid->ap[i]);
5454     }
5455     if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5456 
5457     *ptr = '\0';
5458     data->readlen = strlen(data->rbuffer);
5459     return 0;
5460 }
5461 
5462 static int proc_BSSList_open(struct inode *inode, struct file *file)
5463 {
5464     struct proc_data *data;
5465     struct net_device *dev = pde_data(inode);
5466     struct airo_info *ai = dev->ml_priv;
5467     char *ptr;
5468     BSSListRid BSSList_rid;
5469     int rc;
5470     /* If doLoseSync is not 1, we won't do a Lose Sync */
5471     int doLoseSync = -1;
5472 
5473     if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5474         return -ENOMEM;
5475     data = file->private_data;
5476     if ((data->rbuffer = kmalloc(1024, GFP_KERNEL)) == NULL) {
5477         kfree (file->private_data);
5478         return -ENOMEM;
5479     }
5480     data->writelen = 0;
5481     data->maxwritelen = 0;
5482     data->wbuffer = NULL;
5483     data->on_close = NULL;
5484 
5485     if (file->f_mode & FMODE_WRITE) {
5486         if (!(file->f_mode & FMODE_READ)) {
5487             Cmd cmd;
5488             Resp rsp;
5489 
5490             if (ai->flags & FLAG_RADIO_MASK) {
5491                 kfree(data->rbuffer);
5492                 kfree(file->private_data);
5493                 return -ENETDOWN;
5494             }
5495             memset(&cmd, 0, sizeof(cmd));
5496             cmd.cmd = CMD_LISTBSS;
5497             if (down_interruptible(&ai->sem)) {
5498                 kfree(data->rbuffer);
5499                 kfree(file->private_data);
5500                 return -ERESTARTSYS;
5501             }
5502             issuecommand(ai, &cmd, &rsp, true);
5503             up(&ai->sem);
5504             data->readlen = 0;
5505             return 0;
5506         }
5507         doLoseSync = 1;
5508     }
5509     ptr = data->rbuffer;
5510     /* There is a race condition here if there are concurrent opens.
5511            Since it is a rare condition, we'll just live with it, otherwise
5512            we have to add a spin lock... */
5513     rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5514     while (rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
5515         ptr += sprintf(ptr, "%pM %.*s rssi = %d",
5516                    BSSList_rid.bssid,
5517                 (int)BSSList_rid.ssidLen,
5518                 BSSList_rid.ssid,
5519                 le16_to_cpu(BSSList_rid.dBm));
5520         ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5521                 le16_to_cpu(BSSList_rid.dsChannel),
5522                 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5523                 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5524                 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5525                 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5526         rc = readBSSListRid(ai, 0, &BSSList_rid);
5527     }
5528     *ptr = '\0';
5529     data->readlen = strlen(data->rbuffer);
5530     return 0;
5531 }
5532 
5533 static int proc_close(struct inode *inode, struct file *file)
5534 {
5535     struct proc_data *data = file->private_data;
5536 
5537     if (data->on_close != NULL)
5538         data->on_close(inode, file);
5539     kfree(data->rbuffer);
5540     kfree(data->wbuffer);
5541     kfree(data);
5542     return 0;
5543 }
5544 
5545 /* Since the card doesn't automatically switch to the right WEP mode,
5546    we will make it do it.  If the card isn't associated, every secs we
5547    will switch WEP modes to see if that will help.  If the card is
5548    associated we will check every minute to see if anything has
5549    changed. */
5550 static void timer_func(struct net_device *dev)
5551 {
5552     struct airo_info *apriv = dev->ml_priv;
5553 
5554 /* We don't have a link so try changing the authtype */
5555     readConfigRid(apriv, 0);
5556     disable_MAC(apriv, 0);
5557     switch(apriv->config.authType) {
5558         case AUTH_ENCRYPT:
5559 /* So drop to OPEN */
5560             apriv->config.authType = AUTH_OPEN;
5561             break;
5562         case AUTH_SHAREDKEY:
5563             if (apriv->keyindex < auto_wep) {
5564                 set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5565                 apriv->config.authType = AUTH_SHAREDKEY;
5566                 apriv->keyindex++;
5567             } else {
5568                     /* Drop to ENCRYPT */
5569                 apriv->keyindex = 0;
5570                 set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5571                 apriv->config.authType = AUTH_ENCRYPT;
5572             }
5573             break;
5574         default:  /* We'll escalate to SHAREDKEY */
5575             apriv->config.authType = AUTH_SHAREDKEY;
5576     }
5577     set_bit (FLAG_COMMIT, &apriv->flags);
5578     writeConfigRid(apriv, 0);
5579     enable_MAC(apriv, 0);
5580     up(&apriv->sem);
5581 
5582 /* Schedule check to see if the change worked */
5583     clear_bit(JOB_AUTOWEP, &apriv->jobs);
5584     apriv->expires = RUN_AT(HZ*3);
5585 }
5586 
5587 #ifdef CONFIG_PCI
5588 static int airo_pci_probe(struct pci_dev *pdev,
5589                     const struct pci_device_id *pent)
5590 {
5591     struct net_device *dev;
5592 
5593     if (pci_enable_device(pdev))
5594         return -ENODEV;
5595     pci_set_master(pdev);
5596 
5597     if (pdev->device == 0x5000 || pdev->device == 0xa504)
5598             dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5599     else
5600             dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5601     if (!dev) {
5602         pci_disable_device(pdev);
5603         return -ENODEV;
5604     }
5605 
5606     pci_set_drvdata(pdev, dev);
5607     return 0;
5608 }
5609 
5610 static void airo_pci_remove(struct pci_dev *pdev)
5611 {
5612     struct net_device *dev = pci_get_drvdata(pdev);
5613 
5614     airo_print_info(dev->name, "Unregistering...");
5615     stop_airo_card(dev, 1);
5616     pci_disable_device(pdev);
5617 }
5618 
5619 static int __maybe_unused airo_pci_suspend(struct device *dev_d)
5620 {
5621     struct net_device *dev = dev_get_drvdata(dev_d);
5622     struct airo_info *ai = dev->ml_priv;
5623     Cmd cmd;
5624     Resp rsp;
5625 
5626     if (!ai->SSID)
5627         ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
5628     if (!ai->SSID)
5629         return -ENOMEM;
5630     readSsidRid(ai, ai->SSID);
5631     memset(&cmd, 0, sizeof(cmd));
5632     /* the lock will be released at the end of the resume callback */
5633     if (down_interruptible(&ai->sem))
5634         return -EAGAIN;
5635     disable_MAC(ai, 0);
5636     netif_device_detach(dev);
5637     ai->power = PMSG_SUSPEND;
5638     cmd.cmd = HOSTSLEEP;
5639     issuecommand(ai, &cmd, &rsp, true);
5640 
5641     device_wakeup_enable(dev_d);
5642     return 0;
5643 }
5644 
5645 static int __maybe_unused airo_pci_resume(struct device *dev_d)
5646 {
5647     struct net_device *dev = dev_get_drvdata(dev_d);
5648     struct airo_info *ai = dev->ml_priv;
5649     pci_power_t prev_state = to_pci_dev(dev_d)->current_state;
5650 
5651     device_wakeup_disable(dev_d);
5652 
5653     if (prev_state != PCI_D1) {
5654         reset_card(dev, 0);
5655         mpi_init_descriptors(ai);
5656         setup_card(ai, dev, 0);
5657         clear_bit(FLAG_RADIO_OFF, &ai->flags);
5658         clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5659     } else {
5660         OUT4500(ai, EVACK, EV_AWAKEN);
5661         OUT4500(ai, EVACK, EV_AWAKEN);
5662         msleep(100);
5663     }
5664 
5665     set_bit(FLAG_COMMIT, &ai->flags);
5666     disable_MAC(ai, 0);
5667         msleep(200);
5668     if (ai->SSID) {
5669         writeSsidRid(ai, ai->SSID, 0);
5670         kfree(ai->SSID);
5671         ai->SSID = NULL;
5672     }
5673     writeAPListRid(ai, &ai->APList, 0);
5674     writeConfigRid(ai, 0);
5675     enable_MAC(ai, 0);
5676     ai->power = PMSG_ON;
5677     netif_device_attach(dev);
5678     netif_wake_queue(dev);
5679     enable_interrupts(ai);
5680     up(&ai->sem);
5681     return 0;
5682 }
5683 #endif
5684 
5685 static int __init airo_init_module(void)
5686 {
5687     int i;
5688 
5689     proc_kuid = make_kuid(&init_user_ns, proc_uid);
5690     proc_kgid = make_kgid(&init_user_ns, proc_gid);
5691     if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
5692         return -EINVAL;
5693 
5694     airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
5695 
5696     if (airo_entry)
5697         proc_set_user(airo_entry, proc_kuid, proc_kgid);
5698 
5699     for (i = 0; i < 4 && io[i] && irq[i]; i++) {
5700         airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5701             "io = 0x%x", irq[i], io[i]);
5702         if (init_airo_card(irq[i], io[i], 0, NULL)) {
5703             /* do nothing */ ;
5704         }
5705     }
5706 
5707 #ifdef CONFIG_PCI
5708     airo_print_info("", "Probing for PCI adapters");
5709     i = pci_register_driver(&airo_driver);
5710     airo_print_info("", "Finished probing for PCI adapters");
5711 
5712     if (i) {
5713         remove_proc_entry("driver/aironet", NULL);
5714         return i;
5715     }
5716 #endif
5717 
5718     /* Always exit with success, as we are a library module
5719      * as well as a driver module
5720      */
5721     return 0;
5722 }
5723 
5724 static void __exit airo_cleanup_module(void)
5725 {
5726     struct airo_info *ai;
5727     while (!list_empty(&airo_devices)) {
5728         ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5729         airo_print_info(ai->dev->name, "Unregistering...");
5730         stop_airo_card(ai->dev, 1);
5731     }
5732 #ifdef CONFIG_PCI
5733     pci_unregister_driver(&airo_driver);
5734 #endif
5735     remove_proc_entry("driver/aironet", NULL);
5736 }
5737 
5738 /*
5739  * Initial Wireless Extension code for Aironet driver by :
5740  *  Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5741  * Conversion to new driver API by :
5742  *  Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5743  * Javier also did a good amount of work here, adding some new extensions
5744  * and fixing my code. Let's just say that without him this code just
5745  * would not work at all... - Jean II
5746  */
5747 
5748 static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5749 {
5750     if (!rssi_rid)
5751         return 0;
5752 
5753     return (0x100 - rssi_rid[rssi].rssidBm);
5754 }
5755 
5756 static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5757 {
5758     int i;
5759 
5760     if (!rssi_rid)
5761         return 0;
5762 
5763     for (i = 0; i < 256; i++)
5764         if (rssi_rid[i].rssidBm == dbm)
5765             return rssi_rid[i].rssipct;
5766 
5767     return 0;
5768 }
5769 
5770 
5771 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5772 {
5773     int quality = 0;
5774     u16 sq;
5775 
5776     if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5777         return 0;
5778 
5779     if (!(cap_rid->hardCap & cpu_to_le16(8)))
5780         return 0;
5781 
5782     sq = le16_to_cpu(status_rid->signalQuality);
5783     if (memcmp(cap_rid->prodName, "350", 3))
5784         if (sq > 0x20)
5785             quality = 0;
5786         else
5787             quality = 0x20 - sq;
5788     else
5789         if (sq > 0xb0)
5790             quality = 0;
5791         else if (sq < 0x10)
5792             quality = 0xa0;
5793         else
5794             quality = 0xb0 - sq;
5795     return quality;
5796 }
5797 
5798 #define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5799 #define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50)
5800 
5801 /*------------------------------------------------------------------*/
5802 /*
5803  * Wireless Handler : get protocol name
5804  */
5805 static int airo_get_name(struct net_device *dev,
5806              struct iw_request_info *info,
5807              char *cwrq,
5808              char *extra)
5809 {
5810     strcpy(cwrq, "IEEE 802.11-DS");
5811     return 0;
5812 }
5813 
5814 /*------------------------------------------------------------------*/
5815 /*
5816  * Wireless Handler : set frequency
5817  */
5818 static int airo_set_freq(struct net_device *dev,
5819              struct iw_request_info *info,
5820              struct iw_freq *fwrq,
5821              char *extra)
5822 {
5823     struct airo_info *local = dev->ml_priv;
5824     int rc = -EINPROGRESS;      /* Call commit handler */
5825 
5826     /* If setting by frequency, convert to a channel */
5827     if (fwrq->e == 1) {
5828         int f = fwrq->m / 100000;
5829 
5830         /* Hack to fall through... */
5831         fwrq->e = 0;
5832         fwrq->m = ieee80211_frequency_to_channel(f);
5833     }
5834     /* Setting by channel number */
5835     if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
5836         rc = -EOPNOTSUPP;
5837     else {
5838         int channel = fwrq->m;
5839         /* We should do a better check than that,
5840          * based on the card capability !!! */
5841         if ((channel < 1) || (channel > 14)) {
5842             airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5843                 fwrq->m);
5844             rc = -EINVAL;
5845         } else {
5846             readConfigRid(local, 1);
5847             /* Yes ! We can set it !!! */
5848             local->config.channelSet = cpu_to_le16(channel);
5849             set_bit (FLAG_COMMIT, &local->flags);
5850         }
5851     }
5852     return rc;
5853 }
5854 
5855 /*------------------------------------------------------------------*/
5856 /*
5857  * Wireless Handler : get frequency
5858  */
5859 static int airo_get_freq(struct net_device *dev,
5860              struct iw_request_info *info,
5861              struct iw_freq *fwrq,
5862              char *extra)
5863 {
5864     struct airo_info *local = dev->ml_priv;
5865     StatusRid status_rid;       /* Card status info */
5866     int ch;
5867 
5868     readConfigRid(local, 1);
5869     if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
5870         status_rid.channel = local->config.channelSet;
5871     else
5872         readStatusRid(local, &status_rid, 1);
5873 
5874     ch = le16_to_cpu(status_rid.channel);
5875     if ((ch > 0) && (ch < 15)) {
5876         fwrq->m = 100000 *
5877             ieee80211_channel_to_frequency(ch, NL80211_BAND_2GHZ);
5878         fwrq->e = 1;
5879     } else {
5880         fwrq->m = ch;
5881         fwrq->e = 0;
5882     }
5883 
5884     return 0;
5885 }
5886 
5887 /*------------------------------------------------------------------*/
5888 /*
5889  * Wireless Handler : set ESSID
5890  */
5891 static int airo_set_essid(struct net_device *dev,
5892               struct iw_request_info *info,
5893               struct iw_point *dwrq,
5894               char *extra)
5895 {
5896     struct airo_info *local = dev->ml_priv;
5897     SsidRid SSID_rid;       /* SSIDs */
5898 
5899     /* Reload the list of current SSID */
5900     readSsidRid(local, &SSID_rid);
5901 
5902     /* Check if we asked for `any' */
5903     if (dwrq->flags == 0) {
5904         /* Just send an empty SSID list */
5905         memset(&SSID_rid, 0, sizeof(SSID_rid));
5906     } else {
5907         unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5908 
5909         /* Check the size of the string */
5910         if (dwrq->length > IW_ESSID_MAX_SIZE)
5911             return -E2BIG ;
5912 
5913         /* Check if index is valid */
5914         if (index >= ARRAY_SIZE(SSID_rid.ssids))
5915             return -EINVAL;
5916 
5917         /* Set the SSID */
5918         memset(SSID_rid.ssids[index].ssid, 0,
5919                sizeof(SSID_rid.ssids[index].ssid));
5920         memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5921         SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5922     }
5923     SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5924     /* Write it to the card */
5925     disable_MAC(local, 1);
5926     writeSsidRid(local, &SSID_rid, 1);
5927     enable_MAC(local, 1);
5928 
5929     return 0;
5930 }
5931 
5932 /*------------------------------------------------------------------*/
5933 /*
5934  * Wireless Handler : get ESSID
5935  */
5936 static int airo_get_essid(struct net_device *dev,
5937               struct iw_request_info *info,
5938               struct iw_point *dwrq,
5939               char *extra)
5940 {
5941     struct airo_info *local = dev->ml_priv;
5942     StatusRid status_rid;       /* Card status info */
5943 
5944     readStatusRid(local, &status_rid, 1);
5945 
5946     /* Note : if dwrq->flags != 0, we should
5947      * get the relevant SSID from the SSID list... */
5948 
5949     /* Get the current SSID */
5950     memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5951     /* If none, we may want to get the one that was set */
5952 
5953     /* Push it out ! */
5954     dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5955     dwrq->flags = 1; /* active */
5956 
5957     return 0;
5958 }
5959 
5960 /*------------------------------------------------------------------*/
5961 /*
5962  * Wireless Handler : set AP address
5963  */
5964 static int airo_set_wap(struct net_device *dev,
5965             struct iw_request_info *info,
5966             struct sockaddr *awrq,
5967             char *extra)
5968 {
5969     struct airo_info *local = dev->ml_priv;
5970     Cmd cmd;
5971     Resp rsp;
5972     APListRid *APList_rid = &local->APList;
5973 
5974     if (awrq->sa_family != ARPHRD_ETHER)
5975         return -EINVAL;
5976     else if (is_broadcast_ether_addr(awrq->sa_data) ||
5977          is_zero_ether_addr(awrq->sa_data)) {
5978         memset(&cmd, 0, sizeof(cmd));
5979         cmd.cmd = CMD_LOSE_SYNC;
5980         if (down_interruptible(&local->sem))
5981             return -ERESTARTSYS;
5982         issuecommand(local, &cmd, &rsp, true);
5983         up(&local->sem);
5984     } else {
5985         memset(APList_rid, 0, sizeof(*APList_rid));
5986         APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5987         memcpy(APList_rid->ap[0], awrq->sa_data, ETH_ALEN);
5988         disable_MAC(local, 1);
5989         writeAPListRid(local, APList_rid, 1);
5990         enable_MAC(local, 1);
5991     }
5992     return 0;
5993 }
5994 
5995 /*------------------------------------------------------------------*/
5996 /*
5997  * Wireless Handler : get AP address
5998  */
5999 static int airo_get_wap(struct net_device *dev,
6000             struct iw_request_info *info,
6001             struct sockaddr *awrq,
6002             char *extra)
6003 {
6004     struct airo_info *local = dev->ml_priv;
6005     StatusRid status_rid;       /* Card status info */
6006 
6007     readStatusRid(local, &status_rid, 1);
6008 
6009     /* Tentative. This seems to work, wow, I'm lucky !!! */
6010     memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
6011     awrq->sa_family = ARPHRD_ETHER;
6012 
6013     return 0;
6014 }
6015 
6016 /*------------------------------------------------------------------*/
6017 /*
6018  * Wireless Handler : set Nickname
6019  */
6020 static int airo_set_nick(struct net_device *dev,
6021              struct iw_request_info *info,
6022              struct iw_point *dwrq,
6023              char *extra)
6024 {
6025     struct airo_info *local = dev->ml_priv;
6026 
6027     /* Check the size of the string */
6028     if (dwrq->length > 16) {
6029         return -E2BIG;
6030     }
6031     readConfigRid(local, 1);
6032     memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
6033     memcpy(local->config.nodeName, extra, dwrq->length);
6034     set_bit (FLAG_COMMIT, &local->flags);
6035 
6036     return -EINPROGRESS;        /* Call commit handler */
6037 }
6038 
6039 /*------------------------------------------------------------------*/
6040 /*
6041  * Wireless Handler : get Nickname
6042  */
6043 static int airo_get_nick(struct net_device *dev,
6044              struct iw_request_info *info,
6045              struct iw_point *dwrq,
6046              char *extra)
6047 {
6048     struct airo_info *local = dev->ml_priv;
6049 
6050     readConfigRid(local, 1);
6051     strncpy(extra, local->config.nodeName, 16);
6052     extra[16] = '\0';
6053     dwrq->length = strlen(extra);
6054 
6055     return 0;
6056 }
6057 
6058 /*------------------------------------------------------------------*/
6059 /*
6060  * Wireless Handler : set Bit-Rate
6061  */
6062 static int airo_set_rate(struct net_device *dev,
6063              struct iw_request_info *info,
6064              struct iw_param *vwrq,
6065              char *extra)
6066 {
6067     struct airo_info *local = dev->ml_priv;
6068     CapabilityRid cap_rid;      /* Card capability info */
6069     u8  brate = 0;
6070     int i;
6071 
6072     /* First : get a valid bit rate value */
6073     readCapabilityRid(local, &cap_rid, 1);
6074 
6075     /* Which type of value ? */
6076     if ((vwrq->value < 8) && (vwrq->value >= 0)) {
6077         /* Setting by rate index */
6078         /* Find value in the magic rate table */
6079         brate = cap_rid.supportedRates[vwrq->value];
6080     } else {
6081         /* Setting by frequency value */
6082         u8  normvalue = (u8) (vwrq->value/500000);
6083 
6084         /* Check if rate is valid */
6085         for (i = 0 ; i < 8 ; i++) {
6086             if (normvalue == cap_rid.supportedRates[i]) {
6087                 brate = normvalue;
6088                 break;
6089             }
6090         }
6091     }
6092     /* -1 designed the max rate (mostly auto mode) */
6093     if (vwrq->value == -1) {
6094         /* Get the highest available rate */
6095         for (i = 0 ; i < 8 ; i++) {
6096             if (cap_rid.supportedRates[i] == 0)
6097                 break;
6098         }
6099         if (i != 0)
6100             brate = cap_rid.supportedRates[i - 1];
6101     }
6102     /* Check that it is valid */
6103     if (brate == 0) {
6104         return -EINVAL;
6105     }
6106 
6107     readConfigRid(local, 1);
6108     /* Now, check if we want a fixed or auto value */
6109     if (vwrq->fixed == 0) {
6110         /* Fill all the rates up to this max rate */
6111         memset(local->config.rates, 0, 8);
6112         for (i = 0 ; i < 8 ; i++) {
6113             local->config.rates[i] = cap_rid.supportedRates[i];
6114             if (local->config.rates[i] == brate)
6115                 break;
6116         }
6117     } else {
6118         /* Fixed mode */
6119         /* One rate, fixed */
6120         memset(local->config.rates, 0, 8);
6121         local->config.rates[0] = brate;
6122     }
6123     set_bit (FLAG_COMMIT, &local->flags);
6124 
6125     return -EINPROGRESS;        /* Call commit handler */
6126 }
6127 
6128 /*------------------------------------------------------------------*/
6129 /*
6130  * Wireless Handler : get Bit-Rate
6131  */
6132 static int airo_get_rate(struct net_device *dev,
6133              struct iw_request_info *info,
6134              struct iw_param *vwrq,
6135              char *extra)
6136 {
6137     struct airo_info *local = dev->ml_priv;
6138     StatusRid status_rid;       /* Card status info */
6139 
6140     readStatusRid(local, &status_rid, 1);
6141 
6142     vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6143     /* If more than one rate, set auto */
6144     readConfigRid(local, 1);
6145     vwrq->fixed = (local->config.rates[1] == 0);
6146 
6147     return 0;
6148 }
6149 
6150 /*------------------------------------------------------------------*/
6151 /*
6152  * Wireless Handler : set RTS threshold
6153  */
6154 static int airo_set_rts(struct net_device *dev,
6155             struct iw_request_info *info,
6156             struct iw_param *vwrq,
6157             char *extra)
6158 {
6159     struct airo_info *local = dev->ml_priv;
6160     int rthr = vwrq->value;
6161 
6162     if (vwrq->disabled)
6163         rthr = AIRO_DEF_MTU;
6164     if ((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
6165         return -EINVAL;
6166     }
6167     readConfigRid(local, 1);
6168     local->config.rtsThres = cpu_to_le16(rthr);
6169     set_bit (FLAG_COMMIT, &local->flags);
6170 
6171     return -EINPROGRESS;        /* Call commit handler */
6172 }
6173 
6174 /*------------------------------------------------------------------*/
6175 /*
6176  * Wireless Handler : get RTS threshold
6177  */
6178 static int airo_get_rts(struct net_device *dev,
6179             struct iw_request_info *info,
6180             struct iw_param *vwrq,
6181             char *extra)
6182 {
6183     struct airo_info *local = dev->ml_priv;
6184 
6185     readConfigRid(local, 1);
6186     vwrq->value = le16_to_cpu(local->config.rtsThres);
6187     vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6188     vwrq->fixed = 1;
6189 
6190     return 0;
6191 }
6192 
6193 /*------------------------------------------------------------------*/
6194 /*
6195  * Wireless Handler : set Fragmentation threshold
6196  */
6197 static int airo_set_frag(struct net_device *dev,
6198              struct iw_request_info *info,
6199              struct iw_param *vwrq,
6200              char *extra)
6201 {
6202     struct airo_info *local = dev->ml_priv;
6203     int fthr = vwrq->value;
6204 
6205     if (vwrq->disabled)
6206         fthr = AIRO_DEF_MTU;
6207     if ((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
6208         return -EINVAL;
6209     }
6210     fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
6211     readConfigRid(local, 1);
6212     local->config.fragThresh = cpu_to_le16(fthr);
6213     set_bit (FLAG_COMMIT, &local->flags);
6214 
6215     return -EINPROGRESS;        /* Call commit handler */
6216 }
6217 
6218 /*------------------------------------------------------------------*/
6219 /*
6220  * Wireless Handler : get Fragmentation threshold
6221  */
6222 static int airo_get_frag(struct net_device *dev,
6223              struct iw_request_info *info,
6224              struct iw_param *vwrq,
6225              char *extra)
6226 {
6227     struct airo_info *local = dev->ml_priv;
6228 
6229     readConfigRid(local, 1);
6230     vwrq->value = le16_to_cpu(local->config.fragThresh);
6231     vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6232     vwrq->fixed = 1;
6233 
6234     return 0;
6235 }
6236 
6237 /*------------------------------------------------------------------*/
6238 /*
6239  * Wireless Handler : set Mode of Operation
6240  */
6241 static int airo_set_mode(struct net_device *dev,
6242              struct iw_request_info *info,
6243              __u32 *uwrq,
6244              char *extra)
6245 {
6246     struct airo_info *local = dev->ml_priv;
6247     int reset = 0;
6248 
6249     readConfigRid(local, 1);
6250     if (sniffing_mode(local))
6251         reset = 1;
6252 
6253     switch(*uwrq) {
6254         case IW_MODE_ADHOC:
6255             local->config.opmode &= ~MODE_CFG_MASK;
6256             local->config.opmode |= MODE_STA_IBSS;
6257             local->config.rmode &= ~RXMODE_FULL_MASK;
6258             local->config.scanMode = SCANMODE_ACTIVE;
6259             clear_bit (FLAG_802_11, &local->flags);
6260             break;
6261         case IW_MODE_INFRA:
6262             local->config.opmode &= ~MODE_CFG_MASK;
6263             local->config.opmode |= MODE_STA_ESS;
6264             local->config.rmode &= ~RXMODE_FULL_MASK;
6265             local->config.scanMode = SCANMODE_ACTIVE;
6266             clear_bit (FLAG_802_11, &local->flags);
6267             break;
6268         case IW_MODE_MASTER:
6269             local->config.opmode &= ~MODE_CFG_MASK;
6270             local->config.opmode |= MODE_AP;
6271             local->config.rmode &= ~RXMODE_FULL_MASK;
6272             local->config.scanMode = SCANMODE_ACTIVE;
6273             clear_bit (FLAG_802_11, &local->flags);
6274             break;
6275         case IW_MODE_REPEAT:
6276             local->config.opmode &= ~MODE_CFG_MASK;
6277             local->config.opmode |= MODE_AP_RPTR;
6278             local->config.rmode &= ~RXMODE_FULL_MASK;
6279             local->config.scanMode = SCANMODE_ACTIVE;
6280             clear_bit (FLAG_802_11, &local->flags);
6281             break;
6282         case IW_MODE_MONITOR:
6283             local->config.opmode &= ~MODE_CFG_MASK;
6284             local->config.opmode |= MODE_STA_ESS;
6285             local->config.rmode &= ~RXMODE_FULL_MASK;
6286             local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6287             local->config.scanMode = SCANMODE_PASSIVE;
6288             set_bit (FLAG_802_11, &local->flags);
6289             break;
6290         default:
6291             return -EINVAL;
6292     }
6293     if (reset)
6294         set_bit (FLAG_RESET, &local->flags);
6295     set_bit (FLAG_COMMIT, &local->flags);
6296 
6297     return -EINPROGRESS;        /* Call commit handler */
6298 }
6299 
6300 /*------------------------------------------------------------------*/
6301 /*
6302  * Wireless Handler : get Mode of Operation
6303  */
6304 static int airo_get_mode(struct net_device *dev,
6305              struct iw_request_info *info,
6306              __u32 *uwrq,
6307              char *extra)
6308 {
6309     struct airo_info *local = dev->ml_priv;
6310 
6311     readConfigRid(local, 1);
6312     /* If not managed, assume it's ad-hoc */
6313     switch (local->config.opmode & MODE_CFG_MASK) {
6314         case MODE_STA_ESS:
6315             *uwrq = IW_MODE_INFRA;
6316             break;
6317         case MODE_AP:
6318             *uwrq = IW_MODE_MASTER;
6319             break;
6320         case MODE_AP_RPTR:
6321             *uwrq = IW_MODE_REPEAT;
6322             break;
6323         default:
6324             *uwrq = IW_MODE_ADHOC;
6325     }
6326 
6327     return 0;
6328 }
6329 
6330 static inline int valid_index(struct airo_info *ai, int index)
6331 {
6332     return (index >= 0) && (index <= ai->max_wep_idx);
6333 }
6334 
6335 /*------------------------------------------------------------------*/
6336 /*
6337  * Wireless Handler : set Encryption Key
6338  */
6339 static int airo_set_encode(struct net_device *dev,
6340                struct iw_request_info *info,
6341                struct iw_point *dwrq,
6342                char *extra)
6343 {
6344     struct airo_info *local = dev->ml_priv;
6345     int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
6346     __le16 currentAuthType = local->config.authType;
6347     int rc = 0;
6348 
6349     if (!local->wep_capable)
6350         return -EOPNOTSUPP;
6351 
6352     readConfigRid(local, 1);
6353 
6354     /* Basic checking: do we have a key to set ?
6355      * Note : with the new API, it's impossible to get a NULL pointer.
6356      * Therefore, we need to check a key size == 0 instead.
6357      * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6358      * when no key is present (only change flags), but older versions
6359      * don't do it. - Jean II */
6360     if (dwrq->length > 0) {
6361         wep_key_t key;
6362         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6363         int current_index;
6364 
6365         /* Check the size of the key */
6366         if (dwrq->length > MAX_KEY_SIZE) {
6367             return -EINVAL;
6368         }
6369 
6370         current_index = get_wep_tx_idx(local);
6371         if (current_index < 0)
6372             current_index = 0;
6373 
6374         /* Check the index (none -> use current) */
6375         if (!valid_index(local, index))
6376             index = current_index;
6377 
6378         /* Set the length */
6379         if (dwrq->length > MIN_KEY_SIZE)
6380             key.len = MAX_KEY_SIZE;
6381         else
6382             key.len = MIN_KEY_SIZE;
6383         /* Check if the key is not marked as invalid */
6384         if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
6385             /* Cleanup */
6386             memset(key.key, 0, MAX_KEY_SIZE);
6387             /* Copy the key in the driver */
6388             memcpy(key.key, extra, dwrq->length);
6389             /* Send the key to the card */
6390             rc = set_wep_key(local, index, key.key, key.len, perm, 1);
6391             if (rc < 0) {
6392                 airo_print_err(local->dev->name, "failed to set"
6393                                " WEP key at index %d: %d.",
6394                                index, rc);
6395                 return rc;
6396             }
6397         }
6398         /* WE specify that if a valid key is set, encryption
6399          * should be enabled (user may turn it off later)
6400          * This is also how "iwconfig ethX key on" works */
6401         if ((index == current_index) && (key.len > 0) &&
6402            (local->config.authType == AUTH_OPEN))
6403             set_auth_type(local, AUTH_ENCRYPT);
6404     } else {
6405         /* Do we want to just set the transmit key index ? */
6406         int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6407         if (valid_index(local, index)) {
6408             rc = set_wep_tx_idx(local, index, perm, 1);
6409             if (rc < 0) {
6410                 airo_print_err(local->dev->name, "failed to set"
6411                                " WEP transmit index to %d: %d.",
6412                                index, rc);
6413                 return rc;
6414             }
6415         } else {
6416             /* Don't complain if only change the mode */
6417             if (!(dwrq->flags & IW_ENCODE_MODE))
6418                 return -EINVAL;
6419         }
6420     }
6421     /* Read the flags */
6422     if (dwrq->flags & IW_ENCODE_DISABLED)
6423         set_auth_type(local, AUTH_OPEN);    /* disable encryption */
6424     if (dwrq->flags & IW_ENCODE_RESTRICTED)
6425         set_auth_type(local, AUTH_SHAREDKEY);   /* Only Both */
6426     if (dwrq->flags & IW_ENCODE_OPEN)
6427         set_auth_type(local, AUTH_ENCRYPT); /* Only Wep */
6428     /* Commit the changes to flags if needed */
6429     if (local->config.authType != currentAuthType)
6430         set_bit (FLAG_COMMIT, &local->flags);
6431     return -EINPROGRESS;        /* Call commit handler */
6432 }
6433 
6434 /*------------------------------------------------------------------*/
6435 /*
6436  * Wireless Handler : get Encryption Key
6437  */
6438 static int airo_get_encode(struct net_device *dev,
6439                struct iw_request_info *info,
6440                struct iw_point *dwrq,
6441                char *extra)
6442 {
6443     struct airo_info *local = dev->ml_priv;
6444     int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6445     int wep_key_len;
6446     u8 buf[16];
6447 
6448     if (!local->wep_capable)
6449         return -EOPNOTSUPP;
6450 
6451     readConfigRid(local, 1);
6452 
6453     /* Check encryption mode */
6454     switch(local->config.authType)  {
6455         case AUTH_ENCRYPT:
6456             dwrq->flags = IW_ENCODE_OPEN;
6457             break;
6458         case AUTH_SHAREDKEY:
6459             dwrq->flags = IW_ENCODE_RESTRICTED;
6460             break;
6461         default:
6462         case AUTH_OPEN:
6463             dwrq->flags = IW_ENCODE_DISABLED;
6464             break;
6465     }
6466     /* We can't return the key, so set the proper flag and return zero */
6467     dwrq->flags |= IW_ENCODE_NOKEY;
6468     memset(extra, 0, 16);
6469 
6470     /* Which key do we want ? -1 -> tx index */
6471     if (!valid_index(local, index)) {
6472         index = get_wep_tx_idx(local);
6473         if (index < 0)
6474             index = 0;
6475     }
6476     dwrq->flags |= index + 1;
6477 
6478     /* Copy the key to the user buffer */
6479     wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
6480     if (wep_key_len < 0) {
6481         dwrq->length = 0;
6482     } else {
6483         dwrq->length = wep_key_len;
6484         memcpy(extra, buf, dwrq->length);
6485     }
6486 
6487     return 0;
6488 }
6489 
6490 /*------------------------------------------------------------------*/
6491 /*
6492  * Wireless Handler : set extended Encryption parameters
6493  */
6494 static int airo_set_encodeext(struct net_device *dev,
6495                struct iw_request_info *info,
6496                 union iwreq_data *wrqu,
6497                 char *extra)
6498 {
6499     struct airo_info *local = dev->ml_priv;
6500     struct iw_point *encoding = &wrqu->encoding;
6501     struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6502     int perm = (encoding->flags & IW_ENCODE_TEMP ? 0 : 1);
6503     __le16 currentAuthType = local->config.authType;
6504     int idx, key_len, alg = ext->alg, set_key = 1, rc;
6505     wep_key_t key;
6506 
6507     if (!local->wep_capable)
6508         return -EOPNOTSUPP;
6509 
6510     readConfigRid(local, 1);
6511 
6512     /* Determine and validate the key index */
6513     idx = encoding->flags & IW_ENCODE_INDEX;
6514     if (idx) {
6515         if (!valid_index(local, idx - 1))
6516             return -EINVAL;
6517         idx--;
6518     } else {
6519         idx = get_wep_tx_idx(local);
6520         if (idx < 0)
6521             idx = 0;
6522     }
6523 
6524     if (encoding->flags & IW_ENCODE_DISABLED)
6525         alg = IW_ENCODE_ALG_NONE;
6526 
6527     if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
6528         /* Only set transmit key index here, actual
6529          * key is set below if needed.
6530          */
6531         rc = set_wep_tx_idx(local, idx, perm, 1);
6532         if (rc < 0) {
6533             airo_print_err(local->dev->name, "failed to set "
6534                            "WEP transmit index to %d: %d.",
6535                            idx, rc);
6536             return rc;
6537         }
6538         set_key = ext->key_len > 0 ? 1 : 0;
6539     }
6540 
6541     if (set_key) {
6542         /* Set the requested key first */
6543         memset(key.key, 0, MAX_KEY_SIZE);
6544         switch (alg) {
6545         case IW_ENCODE_ALG_NONE:
6546             key.len = 0;
6547             break;
6548         case IW_ENCODE_ALG_WEP:
6549             if (ext->key_len > MIN_KEY_SIZE) {
6550                 key.len = MAX_KEY_SIZE;
6551             } else if (ext->key_len > 0) {
6552                 key.len = MIN_KEY_SIZE;
6553             } else {
6554                 return -EINVAL;
6555             }
6556             key_len = min (ext->key_len, key.len);
6557             memcpy(key.key, ext->key, key_len);
6558             break;
6559         default:
6560             return -EINVAL;
6561         }
6562         if (key.len == 0) {
6563             rc = set_wep_tx_idx(local, idx, perm, 1);
6564             if (rc < 0) {
6565                 airo_print_err(local->dev->name,
6566                            "failed to set WEP transmit index to %d: %d.",
6567                            idx, rc);
6568                 return rc;
6569             }
6570         } else {
6571             rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6572             if (rc < 0) {
6573                 airo_print_err(local->dev->name,
6574                            "failed to set WEP key at index %d: %d.",
6575                            idx, rc);
6576                 return rc;
6577             }
6578         }
6579     }
6580 
6581     /* Read the flags */
6582     if (encoding->flags & IW_ENCODE_DISABLED)
6583         set_auth_type(local, AUTH_OPEN);    /* disable encryption */
6584     if (encoding->flags & IW_ENCODE_RESTRICTED)
6585         set_auth_type(local, AUTH_SHAREDKEY);   /* Only Both */
6586     if (encoding->flags & IW_ENCODE_OPEN)
6587         set_auth_type(local, AUTH_ENCRYPT);
6588     /* Commit the changes to flags if needed */
6589     if (local->config.authType != currentAuthType)
6590         set_bit (FLAG_COMMIT, &local->flags);
6591 
6592     return -EINPROGRESS;
6593 }
6594 
6595 
6596 /*------------------------------------------------------------------*/
6597 /*
6598  * Wireless Handler : get extended Encryption parameters
6599  */
6600 static int airo_get_encodeext(struct net_device *dev,
6601                 struct iw_request_info *info,
6602                 union iwreq_data *wrqu,
6603                 char *extra)
6604 {
6605     struct airo_info *local = dev->ml_priv;
6606     struct iw_point *encoding = &wrqu->encoding;
6607     struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6608     int idx, max_key_len, wep_key_len;
6609     u8 buf[16];
6610 
6611     if (!local->wep_capable)
6612         return -EOPNOTSUPP;
6613 
6614     readConfigRid(local, 1);
6615 
6616     max_key_len = encoding->length - sizeof(*ext);
6617     if (max_key_len < 0)
6618         return -EINVAL;
6619 
6620     idx = encoding->flags & IW_ENCODE_INDEX;
6621     if (idx) {
6622         if (!valid_index(local, idx - 1))
6623             return -EINVAL;
6624         idx--;
6625     } else {
6626         idx = get_wep_tx_idx(local);
6627         if (idx < 0)
6628             idx = 0;
6629     }
6630 
6631     encoding->flags = idx + 1;
6632     memset(ext, 0, sizeof(*ext));
6633 
6634     /* Check encryption mode */
6635     switch(local->config.authType) {
6636         case AUTH_ENCRYPT:
6637             encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6638             break;
6639         case AUTH_SHAREDKEY:
6640             encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6641             break;
6642         default:
6643         case AUTH_OPEN:
6644             encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
6645             break;
6646     }
6647     /* We can't return the key, so set the proper flag and return zero */
6648     encoding->flags |= IW_ENCODE_NOKEY;
6649     memset(extra, 0, 16);
6650 
6651     /* Copy the key to the user buffer */
6652     wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
6653     if (wep_key_len < 0) {
6654         ext->key_len = 0;
6655     } else {
6656         ext->key_len = wep_key_len;
6657         memcpy(extra, buf, ext->key_len);
6658     }
6659 
6660     return 0;
6661 }
6662 
6663 
6664 /*------------------------------------------------------------------*/
6665 /*
6666  * Wireless Handler : set extended authentication parameters
6667  */
6668 static int airo_set_auth(struct net_device *dev,
6669                    struct iw_request_info *info,
6670                    union iwreq_data *wrqu, char *extra)
6671 {
6672     struct airo_info *local = dev->ml_priv;
6673     struct iw_param *param = &wrqu->param;
6674     __le16 currentAuthType = local->config.authType;
6675 
6676     switch (param->flags & IW_AUTH_INDEX) {
6677     case IW_AUTH_WPA_VERSION:
6678     case IW_AUTH_CIPHER_PAIRWISE:
6679     case IW_AUTH_CIPHER_GROUP:
6680     case IW_AUTH_KEY_MGMT:
6681     case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6682     case IW_AUTH_PRIVACY_INVOKED:
6683         /*
6684          * airo does not use these parameters
6685          */
6686         break;
6687 
6688     case IW_AUTH_DROP_UNENCRYPTED:
6689         if (param->value) {
6690             /* Only change auth type if unencrypted */
6691             if (currentAuthType == AUTH_OPEN)
6692                 set_auth_type(local, AUTH_ENCRYPT);
6693         } else {
6694             set_auth_type(local, AUTH_OPEN);
6695         }
6696 
6697         /* Commit the changes to flags if needed */
6698         if (local->config.authType != currentAuthType)
6699             set_bit (FLAG_COMMIT, &local->flags);
6700         break;
6701 
6702     case IW_AUTH_80211_AUTH_ALG: {
6703             if (param->value & IW_AUTH_ALG_SHARED_KEY) {
6704                 set_auth_type(local, AUTH_SHAREDKEY);
6705             } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
6706                 /* We don't know here if WEP open system or
6707                  * unencrypted mode was requested - so use the
6708                  * last mode (of these two) used last time
6709                  */
6710                 set_auth_type(local, local->last_auth);
6711             } else
6712                 return -EINVAL;
6713 
6714             /* Commit the changes to flags if needed */
6715             if (local->config.authType != currentAuthType)
6716                 set_bit (FLAG_COMMIT, &local->flags);
6717             break;
6718         }
6719 
6720     case IW_AUTH_WPA_ENABLED:
6721         /* Silently accept disable of WPA */
6722         if (param->value > 0)
6723             return -EOPNOTSUPP;
6724         break;
6725 
6726     default:
6727         return -EOPNOTSUPP;
6728     }
6729     return -EINPROGRESS;
6730 }
6731 
6732 
6733 /*------------------------------------------------------------------*/
6734 /*
6735  * Wireless Handler : get extended authentication parameters
6736  */
6737 static int airo_get_auth(struct net_device *dev,
6738                    struct iw_request_info *info,
6739                    union iwreq_data *wrqu, char *extra)
6740 {
6741     struct airo_info *local = dev->ml_priv;
6742     struct iw_param *param = &wrqu->param;
6743     __le16 currentAuthType = local->config.authType;
6744 
6745     switch (param->flags & IW_AUTH_INDEX) {
6746     case IW_AUTH_DROP_UNENCRYPTED:
6747         switch (currentAuthType) {
6748         case AUTH_SHAREDKEY:
6749         case AUTH_ENCRYPT:
6750             param->value = 1;
6751             break;
6752         default:
6753             param->value = 0;
6754             break;
6755         }
6756         break;
6757 
6758     case IW_AUTH_80211_AUTH_ALG:
6759         switch (currentAuthType) {
6760         case AUTH_SHAREDKEY:
6761             param->value = IW_AUTH_ALG_SHARED_KEY;
6762             break;
6763         case AUTH_ENCRYPT:
6764         default:
6765             param->value = IW_AUTH_ALG_OPEN_SYSTEM;
6766             break;
6767         }
6768         break;
6769 
6770     case IW_AUTH_WPA_ENABLED:
6771         param->value = 0;
6772         break;
6773 
6774     default:
6775         return -EOPNOTSUPP;
6776     }
6777     return 0;
6778 }
6779 
6780 
6781 /*------------------------------------------------------------------*/
6782 /*
6783  * Wireless Handler : set Tx-Power
6784  */
6785 static int airo_set_txpow(struct net_device *dev,
6786               struct iw_request_info *info,
6787               struct iw_param *vwrq,
6788               char *extra)
6789 {
6790     struct airo_info *local = dev->ml_priv;
6791     CapabilityRid cap_rid;      /* Card capability info */
6792     int i;
6793     int rc = -EINVAL;
6794     __le16 v = cpu_to_le16(vwrq->value);
6795 
6796     readCapabilityRid(local, &cap_rid, 1);
6797 
6798     if (vwrq->disabled) {
6799         set_bit (FLAG_RADIO_OFF, &local->flags);
6800         set_bit (FLAG_COMMIT, &local->flags);
6801         return -EINPROGRESS;        /* Call commit handler */
6802     }
6803     if (vwrq->flags != IW_TXPOW_MWATT) {
6804         return -EINVAL;
6805     }
6806     clear_bit (FLAG_RADIO_OFF, &local->flags);
6807     for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)
6808         if (v == cap_rid.txPowerLevels[i]) {
6809             readConfigRid(local, 1);
6810             local->config.txPower = v;
6811             set_bit (FLAG_COMMIT, &local->flags);
6812             rc = -EINPROGRESS;  /* Call commit handler */
6813             break;
6814         }
6815     return rc;
6816 }
6817 
6818 /*------------------------------------------------------------------*/
6819 /*
6820  * Wireless Handler : get Tx-Power
6821  */
6822 static int airo_get_txpow(struct net_device *dev,
6823               struct iw_request_info *info,
6824               struct iw_param *vwrq,
6825               char *extra)
6826 {
6827     struct airo_info *local = dev->ml_priv;
6828 
6829     readConfigRid(local, 1);
6830     vwrq->value = le16_to_cpu(local->config.txPower);
6831     vwrq->fixed = 1;    /* No power control */
6832     vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6833     vwrq->flags = IW_TXPOW_MWATT;
6834 
6835     return 0;
6836 }
6837 
6838 /*------------------------------------------------------------------*/
6839 /*
6840  * Wireless Handler : set Retry limits
6841  */
6842 static int airo_set_retry(struct net_device *dev,
6843               struct iw_request_info *info,
6844               struct iw_param *vwrq,
6845               char *extra)
6846 {
6847     struct airo_info *local = dev->ml_priv;
6848     int rc = -EINVAL;
6849 
6850     if (vwrq->disabled) {
6851         return -EINVAL;
6852     }
6853     readConfigRid(local, 1);
6854     if (vwrq->flags & IW_RETRY_LIMIT) {
6855         __le16 v = cpu_to_le16(vwrq->value);
6856         if (vwrq->flags & IW_RETRY_LONG)
6857             local->config.longRetryLimit = v;
6858         else if (vwrq->flags & IW_RETRY_SHORT)
6859             local->config.shortRetryLimit = v;
6860         else {
6861             /* No modifier : set both */
6862             local->config.longRetryLimit = v;
6863             local->config.shortRetryLimit = v;
6864         }
6865         set_bit (FLAG_COMMIT, &local->flags);
6866         rc = -EINPROGRESS;      /* Call commit handler */
6867     }
6868     if (vwrq->flags & IW_RETRY_LIFETIME) {
6869         local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
6870         set_bit (FLAG_COMMIT, &local->flags);
6871         rc = -EINPROGRESS;      /* Call commit handler */
6872     }
6873     return rc;
6874 }
6875 
6876 /*------------------------------------------------------------------*/
6877 /*
6878  * Wireless Handler : get Retry limits
6879  */
6880 static int airo_get_retry(struct net_device *dev,
6881               struct iw_request_info *info,
6882               struct iw_param *vwrq,
6883               char *extra)
6884 {
6885     struct airo_info *local = dev->ml_priv;
6886 
6887     vwrq->disabled = 0;      /* Can't be disabled */
6888 
6889     readConfigRid(local, 1);
6890     /* Note : by default, display the min retry number */
6891     if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6892         vwrq->flags = IW_RETRY_LIFETIME;
6893         vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
6894     } else if ((vwrq->flags & IW_RETRY_LONG)) {
6895         vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6896         vwrq->value = le16_to_cpu(local->config.longRetryLimit);
6897     } else {
6898         vwrq->flags = IW_RETRY_LIMIT;
6899         vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
6900         if (local->config.shortRetryLimit != local->config.longRetryLimit)
6901             vwrq->flags |= IW_RETRY_SHORT;
6902     }
6903 
6904     return 0;
6905 }
6906 
6907 /*------------------------------------------------------------------*/
6908 /*
6909  * Wireless Handler : get range info
6910  */
6911 static int airo_get_range(struct net_device *dev,
6912               struct iw_request_info *info,
6913               struct iw_point *dwrq,
6914               char *extra)
6915 {
6916     struct airo_info *local = dev->ml_priv;
6917     struct iw_range *range = (struct iw_range *) extra;
6918     CapabilityRid cap_rid;      /* Card capability info */
6919     int     i;
6920     int     k;
6921 
6922     readCapabilityRid(local, &cap_rid, 1);
6923 
6924     dwrq->length = sizeof(struct iw_range);
6925     memset(range, 0, sizeof(*range));
6926     range->min_nwid = 0x0000;
6927     range->max_nwid = 0x0000;
6928     range->num_channels = 14;
6929     /* Should be based on cap_rid.country to give only
6930      * what the current card support */
6931     k = 0;
6932     for (i = 0; i < 14; i++) {
6933         range->freq[k].i = i + 1; /* List index */
6934         range->freq[k].m = 100000 *
6935              ieee80211_channel_to_frequency(i + 1, NL80211_BAND_2GHZ);
6936         range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
6937     }
6938     range->num_frequency = k;
6939 
6940     range->sensitivity = 65535;
6941 
6942     /* Hum... Should put the right values there */
6943     if (local->rssi)
6944         range->max_qual.qual = 100; /* % */
6945     else
6946         range->max_qual.qual = airo_get_max_quality(&cap_rid);
6947     range->max_qual.level = 0x100 - 120;    /* -120 dBm */
6948     range->max_qual.noise = 0x100 - 120;    /* -120 dBm */
6949 
6950     /* Experimental measurements - boundary 11/5.5 Mb/s */
6951     /* Note : with or without the (local->rssi), results
6952      * are somewhat different. - Jean II */
6953     if (local->rssi) {
6954         range->avg_qual.qual = 50;      /* % */
6955         range->avg_qual.level = 0x100 - 70; /* -70 dBm */
6956     } else {
6957         range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6958         range->avg_qual.level = 0x100 - 80; /* -80 dBm */
6959     }
6960     range->avg_qual.noise = 0x100 - 85;     /* -85 dBm */
6961 
6962     for (i = 0 ; i < 8 ; i++) {
6963         range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6964         if (range->bitrate[i] == 0)
6965             break;
6966     }
6967     range->num_bitrates = i;
6968 
6969     /* Set an indication of the max TCP throughput
6970      * in bit/s that we can expect using this interface.
6971      * May be use for QoS stuff... Jean II */
6972     if (i > 2)
6973         range->throughput = 5000 * 1000;
6974     else
6975         range->throughput = 1500 * 1000;
6976 
6977     range->min_rts = 0;
6978     range->max_rts = AIRO_DEF_MTU;
6979     range->min_frag = 256;
6980     range->max_frag = AIRO_DEF_MTU;
6981 
6982     if (cap_rid.softCap & cpu_to_le16(2)) {
6983         // WEP: RC4 40 bits
6984         range->encoding_size[0] = 5;
6985         // RC4 ~128 bits
6986         if (cap_rid.softCap & cpu_to_le16(0x100)) {
6987             range->encoding_size[1] = 13;
6988             range->num_encoding_sizes = 2;
6989         } else
6990             range->num_encoding_sizes = 1;
6991         range->max_encoding_tokens =
6992             cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
6993     } else {
6994         range->num_encoding_sizes = 0;
6995         range->max_encoding_tokens = 0;
6996     }
6997     range->min_pmp = 0;
6998     range->max_pmp = 5000000;   /* 5 secs */
6999     range->min_pmt = 0;
7000     range->max_pmt = 65535 * 1024;  /* ??? */
7001     range->pmp_flags = IW_POWER_PERIOD;
7002     range->pmt_flags = IW_POWER_TIMEOUT;
7003     range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
7004 
7005     /* Transmit Power - values are in mW */
7006     for (i = 0 ; i < 8 ; i++) {
7007         range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
7008         if (range->txpower[i] == 0)
7009             break;
7010     }
7011     range->num_txpower = i;
7012     range->txpower_capa = IW_TXPOW_MWATT;
7013     range->we_version_source = 19;
7014     range->we_version_compiled = WIRELESS_EXT;
7015     range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
7016     range->retry_flags = IW_RETRY_LIMIT;
7017     range->r_time_flags = IW_RETRY_LIFETIME;
7018     range->min_retry = 1;
7019     range->max_retry = 65535;
7020     range->min_r_time = 1024;
7021     range->max_r_time = 65535 * 1024;
7022 
7023     /* Event capability (kernel + driver) */
7024     range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
7025                 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
7026                 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
7027                 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
7028     range->event_capa[1] = IW_EVENT_CAPA_K_1;
7029     range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
7030     return 0;
7031 }
7032 
7033 /*------------------------------------------------------------------*/
7034 /*
7035  * Wireless Handler : set Power Management
7036  */
7037 static int airo_set_power(struct net_device *dev,
7038               struct iw_request_info *info,
7039               struct iw_param *vwrq,
7040               char *extra)
7041 {
7042     struct airo_info *local = dev->ml_priv;
7043 
7044     readConfigRid(local, 1);
7045     if (vwrq->disabled) {
7046         if (sniffing_mode(local))
7047             return -EINVAL;
7048         local->config.powerSaveMode = POWERSAVE_CAM;
7049         local->config.rmode &= ~RXMODE_MASK;
7050         local->config.rmode |= RXMODE_BC_MC_ADDR;
7051         set_bit (FLAG_COMMIT, &local->flags);
7052         return -EINPROGRESS;        /* Call commit handler */
7053     }
7054     if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7055         local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
7056         local->config.powerSaveMode = POWERSAVE_PSPCAM;
7057         set_bit (FLAG_COMMIT, &local->flags);
7058     } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
7059         local->config.fastListenInterval =
7060         local->config.listenInterval =
7061             cpu_to_le16((vwrq->value + 500) / 1024);
7062         local->config.powerSaveMode = POWERSAVE_PSPCAM;
7063         set_bit (FLAG_COMMIT, &local->flags);
7064     }
7065     switch (vwrq->flags & IW_POWER_MODE) {
7066         case IW_POWER_UNICAST_R:
7067             if (sniffing_mode(local))
7068                 return -EINVAL;
7069             local->config.rmode &= ~RXMODE_MASK;
7070             local->config.rmode |= RXMODE_ADDR;
7071             set_bit (FLAG_COMMIT, &local->flags);
7072             break;
7073         case IW_POWER_ALL_R:
7074             if (sniffing_mode(local))
7075                 return -EINVAL;
7076             local->config.rmode &= ~RXMODE_MASK;
7077             local->config.rmode |= RXMODE_BC_MC_ADDR;
7078             set_bit (FLAG_COMMIT, &local->flags);
7079             break;
7080         case IW_POWER_ON:
7081             /* This is broken, fixme ;-) */
7082             break;
7083         default:
7084             return -EINVAL;
7085     }
7086     // Note : we may want to factor local->need_commit here
7087     // Note2 : may also want to factor RXMODE_RFMON test
7088     return -EINPROGRESS;        /* Call commit handler */
7089 }
7090 
7091 /*------------------------------------------------------------------*/
7092 /*
7093  * Wireless Handler : get Power Management
7094  */
7095 static int airo_get_power(struct net_device *dev,
7096               struct iw_request_info *info,
7097               struct iw_param *vwrq,
7098               char *extra)
7099 {
7100     struct airo_info *local = dev->ml_priv;
7101     __le16 mode;
7102 
7103     readConfigRid(local, 1);
7104     mode = local->config.powerSaveMode;
7105     if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
7106         return 0;
7107     if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7108         vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
7109         vwrq->flags = IW_POWER_TIMEOUT;
7110     } else {
7111         vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
7112         vwrq->flags = IW_POWER_PERIOD;
7113     }
7114     if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
7115         vwrq->flags |= IW_POWER_UNICAST_R;
7116     else
7117         vwrq->flags |= IW_POWER_ALL_R;
7118 
7119     return 0;
7120 }
7121 
7122 /*------------------------------------------------------------------*/
7123 /*
7124  * Wireless Handler : set Sensitivity
7125  */
7126 static int airo_set_sens(struct net_device *dev,
7127              struct iw_request_info *info,
7128              struct iw_param *vwrq,
7129              char *extra)
7130 {
7131     struct airo_info *local = dev->ml_priv;
7132 
7133     readConfigRid(local, 1);
7134     local->config.rssiThreshold =
7135         cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
7136     set_bit (FLAG_COMMIT, &local->flags);
7137 
7138     return -EINPROGRESS;        /* Call commit handler */
7139 }
7140 
7141 /*------------------------------------------------------------------*/
7142 /*
7143  * Wireless Handler : get Sensitivity
7144  */
7145 static int airo_get_sens(struct net_device *dev,
7146              struct iw_request_info *info,
7147              struct iw_param *vwrq,
7148              char *extra)
7149 {
7150     struct airo_info *local = dev->ml_priv;
7151 
7152     readConfigRid(local, 1);
7153     vwrq->value = le16_to_cpu(local->config.rssiThreshold);
7154     vwrq->disabled = (vwrq->value == 0);
7155     vwrq->fixed = 1;
7156 
7157     return 0;
7158 }
7159 
7160 /*------------------------------------------------------------------*/
7161 /*
7162  * Wireless Handler : get AP List
7163  * Note : this is deprecated in favor of IWSCAN
7164  */
7165 static int airo_get_aplist(struct net_device *dev,
7166                struct iw_request_info *info,
7167                struct iw_point *dwrq,
7168                char *extra)
7169 {
7170     struct airo_info *local = dev->ml_priv;
7171     struct sockaddr *address = (struct sockaddr *) extra;
7172     struct iw_quality *qual;
7173     BSSListRid BSSList;
7174     int i;
7175     int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7176 
7177     qual = kmalloc_array(IW_MAX_AP, sizeof(*qual), GFP_KERNEL);
7178     if (!qual)
7179         return -ENOMEM;
7180 
7181     for (i = 0; i < IW_MAX_AP; i++) {
7182         u16 dBm;
7183         if (readBSSListRid(local, loseSync, &BSSList))
7184             break;
7185         loseSync = 0;
7186         memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
7187         address[i].sa_family = ARPHRD_ETHER;
7188         dBm = le16_to_cpu(BSSList.dBm);
7189         if (local->rssi) {
7190             qual[i].level = 0x100 - dBm;
7191             qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
7192             qual[i].updated = IW_QUAL_QUAL_UPDATED
7193                     | IW_QUAL_LEVEL_UPDATED
7194                     | IW_QUAL_DBM;
7195         } else {
7196             qual[i].level = (dBm + 321) / 2;
7197             qual[i].qual = 0;
7198             qual[i].updated = IW_QUAL_QUAL_INVALID
7199                     | IW_QUAL_LEVEL_UPDATED
7200                     | IW_QUAL_DBM;
7201         }
7202         qual[i].noise = local->wstats.qual.noise;
7203         if (BSSList.index == cpu_to_le16(0xffff))
7204             break;
7205     }
7206     if (!i) {
7207         StatusRid status_rid;       /* Card status info */
7208         readStatusRid(local, &status_rid, 1);
7209         for (i = 0;
7210              i < min(IW_MAX_AP, 4) &&
7211                  (status_rid.bssid[i][0]
7212                   & status_rid.bssid[i][1]
7213                   & status_rid.bssid[i][2]
7214                   & status_rid.bssid[i][3]
7215                   & status_rid.bssid[i][4]
7216                   & status_rid.bssid[i][5])!=0xff &&
7217                  (status_rid.bssid[i][0]
7218                   | status_rid.bssid[i][1]
7219                   | status_rid.bssid[i][2]
7220                   | status_rid.bssid[i][3]
7221                   | status_rid.bssid[i][4]
7222                   | status_rid.bssid[i][5]);
7223              i++) {
7224             memcpy(address[i].sa_data,
7225                    status_rid.bssid[i], ETH_ALEN);
7226             address[i].sa_family = ARPHRD_ETHER;
7227         }
7228     } else {
7229         dwrq->flags = 1; /* Should be define'd */
7230         memcpy(extra + sizeof(struct sockaddr) * i, qual,
7231                sizeof(struct iw_quality) * i);
7232     }
7233     dwrq->length = i;
7234 
7235     kfree(qual);
7236     return 0;
7237 }
7238 
7239 /*------------------------------------------------------------------*/
7240 /*
7241  * Wireless Handler : Initiate Scan
7242  */
7243 static int airo_set_scan(struct net_device *dev,
7244              struct iw_request_info *info,
7245              struct iw_point *dwrq,
7246              char *extra)
7247 {
7248     struct airo_info *ai = dev->ml_priv;
7249     Cmd cmd;
7250     Resp rsp;
7251     int wake = 0;
7252     APListRid APList_rid_empty;
7253 
7254     /* Note : you may have realised that, as this is a SET operation,
7255      * this is privileged and therefore a normal user can't
7256      * perform scanning.
7257      * This is not an error, while the device perform scanning,
7258      * traffic doesn't flow, so it's a perfect DoS...
7259      * Jean II */
7260     if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
7261 
7262     if (down_interruptible(&ai->sem))
7263         return -ERESTARTSYS;
7264 
7265     /* If there's already a scan in progress, don't
7266      * trigger another one. */
7267     if (ai->scan_timeout > 0)
7268         goto out;
7269 
7270     /* Clear APList as it affects scan results */
7271     memset(&APList_rid_empty, 0, sizeof(APList_rid_empty));
7272     APList_rid_empty.len = cpu_to_le16(sizeof(APList_rid_empty));
7273     disable_MAC(ai, 2);
7274     writeAPListRid(ai, &APList_rid_empty, 0);
7275     enable_MAC(ai, 0);
7276 
7277     /* Initiate a scan command */
7278     ai->scan_timeout = RUN_AT(3*HZ);
7279     memset(&cmd, 0, sizeof(cmd));
7280     cmd.cmd = CMD_LISTBSS;
7281     issuecommand(ai, &cmd, &rsp, true);
7282     wake = 1;
7283 
7284 out:
7285     up(&ai->sem);
7286     if (wake)
7287         wake_up_interruptible(&ai->thr_wait);
7288     return 0;
7289 }
7290 
7291 /*------------------------------------------------------------------*/
7292 /*
7293  * Translate scan data returned from the card to a card independent
7294  * format that the Wireless Tools will understand - Jean II
7295  */
7296 static inline char *airo_translate_scan(struct net_device *dev,
7297                     struct iw_request_info *info,
7298                     char *current_ev,
7299                     char *end_buf,
7300                     BSSListRid *bss)
7301 {
7302     struct airo_info *ai = dev->ml_priv;
7303     struct iw_event     iwe;        /* Temporary buffer */
7304     __le16          capabilities;
7305     char *          current_val;    /* For rates */
7306     int         i;
7307     char *      buf;
7308     u16 dBm;
7309 
7310     /* First entry *MUST* be the AP MAC address */
7311     iwe.cmd = SIOCGIWAP;
7312     iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7313     memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7314     current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7315                       &iwe, IW_EV_ADDR_LEN);
7316 
7317     /* Other entries will be displayed in the order we give them */
7318 
7319     /* Add the ESSID */
7320     iwe.u.data.length = bss->ssidLen;
7321     if (iwe.u.data.length > 32)
7322         iwe.u.data.length = 32;
7323     iwe.cmd = SIOCGIWESSID;
7324     iwe.u.data.flags = 1;
7325     current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7326                       &iwe, bss->ssid);
7327 
7328     /* Add mode */
7329     iwe.cmd = SIOCGIWMODE;
7330     capabilities = bss->cap;
7331     if (capabilities & (CAP_ESS | CAP_IBSS)) {
7332         if (capabilities & CAP_ESS)
7333             iwe.u.mode = IW_MODE_MASTER;
7334         else
7335             iwe.u.mode = IW_MODE_ADHOC;
7336         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7337                           &iwe, IW_EV_UINT_LEN);
7338     }
7339 
7340     /* Add frequency */
7341     iwe.cmd = SIOCGIWFREQ;
7342     iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7343     iwe.u.freq.m = 100000 *
7344           ieee80211_channel_to_frequency(iwe.u.freq.m, NL80211_BAND_2GHZ);
7345     iwe.u.freq.e = 1;
7346     current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7347                       &iwe, IW_EV_FREQ_LEN);
7348 
7349     dBm = le16_to_cpu(bss->dBm);
7350 
7351     /* Add quality statistics */
7352     iwe.cmd = IWEVQUAL;
7353     if (ai->rssi) {
7354         iwe.u.qual.level = 0x100 - dBm;
7355         iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
7356         iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
7357                 | IW_QUAL_LEVEL_UPDATED
7358                 | IW_QUAL_DBM;
7359     } else {
7360         iwe.u.qual.level = (dBm + 321) / 2;
7361         iwe.u.qual.qual = 0;
7362         iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
7363                 | IW_QUAL_LEVEL_UPDATED
7364                 | IW_QUAL_DBM;
7365     }
7366     iwe.u.qual.noise = ai->wstats.qual.noise;
7367     current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7368                       &iwe, IW_EV_QUAL_LEN);
7369 
7370     /* Add encryption capability */
7371     iwe.cmd = SIOCGIWENCODE;
7372     if (capabilities & CAP_PRIVACY)
7373         iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
7374     else
7375         iwe.u.data.flags = IW_ENCODE_DISABLED;
7376     iwe.u.data.length = 0;
7377     current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7378                       &iwe, bss->ssid);
7379 
7380     /* Rate : stuffing multiple values in a single event require a bit
7381      * more of magic - Jean II */
7382     current_val = current_ev + iwe_stream_lcp_len(info);
7383 
7384     iwe.cmd = SIOCGIWRATE;
7385     /* Those two flags are ignored... */
7386     iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
7387     /* Max 8 values */
7388     for (i = 0 ; i < 8 ; i++) {
7389         /* NULL terminated */
7390         if (bss->rates[i] == 0)
7391             break;
7392         /* Bit rate given in 500 kb/s units (+ 0x80) */
7393         iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7394         /* Add new value to event */
7395         current_val = iwe_stream_add_value(info, current_ev,
7396                            current_val, end_buf,
7397                            &iwe, IW_EV_PARAM_LEN);
7398     }
7399     /* Check if we added any event */
7400     if ((current_val - current_ev) > iwe_stream_lcp_len(info))
7401         current_ev = current_val;
7402 
7403     /* Beacon interval */
7404     buf = kmalloc(30, GFP_KERNEL);
7405     if (buf) {
7406         iwe.cmd = IWEVCUSTOM;
7407         sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7408         iwe.u.data.length = strlen(buf);
7409         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7410                           &iwe, buf);
7411         kfree(buf);
7412     }
7413 
7414     /* Put WPA/RSN Information Elements into the event stream */
7415     if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
7416         unsigned int num_null_ies = 0;
7417         u16 length = sizeof (bss->extra.iep);
7418         u8 *ie = (void *)&bss->extra.iep;
7419 
7420         while ((length >= 2) && (num_null_ies < 2)) {
7421             if (2 + ie[1] > length) {
7422                 /* Invalid element, don't continue parsing IE */
7423                 break;
7424             }
7425 
7426             switch (ie[0]) {
7427             case WLAN_EID_SSID:
7428                 /* Two zero-length SSID elements
7429                  * mean we're done parsing elements */
7430                 if (!ie[1])
7431                     num_null_ies++;
7432                 break;
7433 
7434             case WLAN_EID_VENDOR_SPECIFIC:
7435                 if (ie[1] >= 4 &&
7436                     ie[2] == 0x00 &&
7437                     ie[3] == 0x50 &&
7438                     ie[4] == 0xf2 &&
7439                     ie[5] == 0x01) {
7440                     iwe.cmd = IWEVGENIE;
7441                     /* 64 is an arbitrary cut-off */
7442                     iwe.u.data.length = min(ie[1] + 2,
7443                                 64);
7444                     current_ev = iwe_stream_add_point(
7445                             info, current_ev,
7446                             end_buf, &iwe, ie);
7447                 }
7448                 break;
7449 
7450             case WLAN_EID_RSN:
7451                 iwe.cmd = IWEVGENIE;
7452                 /* 64 is an arbitrary cut-off */
7453                 iwe.u.data.length = min(ie[1] + 2, 64);
7454                 current_ev = iwe_stream_add_point(
7455                     info, current_ev, end_buf,
7456                     &iwe, ie);
7457                 break;
7458 
7459             default:
7460                 break;
7461             }
7462 
7463             length -= 2 + ie[1];
7464             ie += 2 + ie[1];
7465         }
7466     }
7467     return current_ev;
7468 }
7469 
7470 /*------------------------------------------------------------------*/
7471 /*
7472  * Wireless Handler : Read Scan Results
7473  */
7474 static int airo_get_scan(struct net_device *dev,
7475              struct iw_request_info *info,
7476              struct iw_point *dwrq,
7477              char *extra)
7478 {
7479     struct airo_info *ai = dev->ml_priv;
7480     BSSListElement *net;
7481     int err = 0;
7482     char *current_ev = extra;
7483 
7484     /* If a scan is in-progress, return -EAGAIN */
7485     if (ai->scan_timeout > 0)
7486         return -EAGAIN;
7487 
7488     if (down_interruptible(&ai->sem))
7489         return -EAGAIN;
7490 
7491     list_for_each_entry (net, &ai->network_list, list) {
7492         /* Translate to WE format this entry */
7493         current_ev = airo_translate_scan(dev, info, current_ev,
7494                          extra + dwrq->length,
7495                          &net->bss);
7496 
7497         /* Check if there is space for one more entry */
7498         if ((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7499             /* Ask user space to try again with a bigger buffer */
7500             err = -E2BIG;
7501             goto out;
7502         }
7503     }
7504 
7505     /* Length of data */
7506     dwrq->length = (current_ev - extra);
7507     dwrq->flags = 0;    /* todo */
7508 
7509 out:
7510     up(&ai->sem);
7511     return err;
7512 }
7513 
7514 /*------------------------------------------------------------------*/
7515 /*
7516  * Commit handler : called after a bunch of SET operations
7517  */
7518 static int airo_config_commit(struct net_device *dev,
7519                   struct iw_request_info *info, /* NULL */
7520                   void *zwrq,           /* NULL */
7521                   char *extra)          /* NULL */
7522 {
7523     struct airo_info *local = dev->ml_priv;
7524 
7525     if (!test_bit (FLAG_COMMIT, &local->flags))
7526         return 0;
7527 
7528     /* Some of the "SET" function may have modified some of the
7529      * parameters. It's now time to commit them in the card */
7530     disable_MAC(local, 1);
7531     if (test_bit (FLAG_RESET, &local->flags)) {
7532         SsidRid SSID_rid;
7533 
7534         readSsidRid(local, &SSID_rid);
7535         if (test_bit(FLAG_MPI,&local->flags))
7536             setup_card(local, dev, 1);
7537         else
7538             reset_airo_card(dev);
7539         disable_MAC(local, 1);
7540         writeSsidRid(local, &SSID_rid, 1);
7541         writeAPListRid(local, &local->APList, 1);
7542     }
7543     if (down_interruptible(&local->sem))
7544         return -ERESTARTSYS;
7545     writeConfigRid(local, 0);
7546     enable_MAC(local, 0);
7547     if (test_bit (FLAG_RESET, &local->flags))
7548         airo_set_promisc(local, true);
7549     else
7550         up(&local->sem);
7551 
7552     return 0;
7553 }
7554 
7555 /*------------------------------------------------------------------*/
7556 /*
7557  * Structures to export the Wireless Handlers
7558  */
7559 
7560 static const struct iw_priv_args airo_private_args[] = {
7561 /*{ cmd,         set_args,                            get_args, name } */
7562   { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7563     IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7564   { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7565     IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7566 };
7567 
7568 static const iw_handler     airo_handler[] =
7569 {
7570     (iw_handler) airo_config_commit,    /* SIOCSIWCOMMIT */
7571     (iw_handler) airo_get_name,     /* SIOCGIWNAME */
7572     (iw_handler) NULL,          /* SIOCSIWNWID */
7573     (iw_handler) NULL,          /* SIOCGIWNWID */
7574     (iw_handler) airo_set_freq,     /* SIOCSIWFREQ */
7575     (iw_handler) airo_get_freq,     /* SIOCGIWFREQ */
7576     (iw_handler) airo_set_mode,     /* SIOCSIWMODE */
7577     (iw_handler) airo_get_mode,     /* SIOCGIWMODE */
7578     (iw_handler) airo_set_sens,     /* SIOCSIWSENS */
7579     (iw_handler) airo_get_sens,     /* SIOCGIWSENS */
7580     (iw_handler) NULL,          /* SIOCSIWRANGE */
7581     (iw_handler) airo_get_range,        /* SIOCGIWRANGE */
7582     (iw_handler) NULL,          /* SIOCSIWPRIV */
7583     (iw_handler) NULL,          /* SIOCGIWPRIV */
7584     (iw_handler) NULL,          /* SIOCSIWSTATS */
7585     (iw_handler) NULL,          /* SIOCGIWSTATS */
7586     iw_handler_set_spy,         /* SIOCSIWSPY */
7587     iw_handler_get_spy,         /* SIOCGIWSPY */
7588     iw_handler_set_thrspy,          /* SIOCSIWTHRSPY */
7589     iw_handler_get_thrspy,          /* SIOCGIWTHRSPY */
7590     (iw_handler) airo_set_wap,      /* SIOCSIWAP */
7591     (iw_handler) airo_get_wap,      /* SIOCGIWAP */
7592     (iw_handler) NULL,          /* -- hole -- */
7593     (iw_handler) airo_get_aplist,       /* SIOCGIWAPLIST */
7594     (iw_handler) airo_set_scan,     /* SIOCSIWSCAN */
7595     (iw_handler) airo_get_scan,     /* SIOCGIWSCAN */
7596     (iw_handler) airo_set_essid,        /* SIOCSIWESSID */
7597     (iw_handler) airo_get_essid,        /* SIOCGIWESSID */
7598     (iw_handler) airo_set_nick,     /* SIOCSIWNICKN */
7599     (iw_handler) airo_get_nick,     /* SIOCGIWNICKN */
7600     (iw_handler) NULL,          /* -- hole -- */
7601     (iw_handler) NULL,          /* -- hole -- */
7602     (iw_handler) airo_set_rate,     /* SIOCSIWRATE */
7603     (iw_handler) airo_get_rate,     /* SIOCGIWRATE */
7604     (iw_handler) airo_set_rts,      /* SIOCSIWRTS */
7605     (iw_handler) airo_get_rts,      /* SIOCGIWRTS */
7606     (iw_handler) airo_set_frag,     /* SIOCSIWFRAG */
7607     (iw_handler) airo_get_frag,     /* SIOCGIWFRAG */
7608     (iw_handler) airo_set_txpow,        /* SIOCSIWTXPOW */
7609     (iw_handler) airo_get_txpow,        /* SIOCGIWTXPOW */
7610     (iw_handler) airo_set_retry,        /* SIOCSIWRETRY */
7611     (iw_handler) airo_get_retry,        /* SIOCGIWRETRY */
7612     (iw_handler) airo_set_encode,       /* SIOCSIWENCODE */
7613     (iw_handler) airo_get_encode,       /* SIOCGIWENCODE */
7614     (iw_handler) airo_set_power,        /* SIOCSIWPOWER */
7615     (iw_handler) airo_get_power,        /* SIOCGIWPOWER */
7616     (iw_handler) NULL,          /* -- hole -- */
7617     (iw_handler) NULL,          /* -- hole -- */
7618     (iw_handler) NULL,          /* SIOCSIWGENIE */
7619     (iw_handler) NULL,          /* SIOCGIWGENIE */
7620     (iw_handler) airo_set_auth,     /* SIOCSIWAUTH */
7621     (iw_handler) airo_get_auth,     /* SIOCGIWAUTH */
7622     (iw_handler) airo_set_encodeext,    /* SIOCSIWENCODEEXT */
7623     (iw_handler) airo_get_encodeext,    /* SIOCGIWENCODEEXT */
7624     (iw_handler) NULL,          /* SIOCSIWPMKSA */
7625 };
7626 
7627 /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7628  * We want to force the use of the ioctl code, because those can't be
7629  * won't work the iw_handler code (because they simultaneously read
7630  * and write data and iw_handler can't do that).
7631  * Note that it's perfectly legal to read/write on a single ioctl command,
7632  * you just can't use iwpriv and need to force it via the ioctl handler.
7633  * Jean II */
7634 static const iw_handler     airo_private_handler[] =
7635 {
7636     NULL,               /* SIOCIWFIRSTPRIV */
7637 };
7638 
7639 static const struct iw_handler_def  airo_handler_def =
7640 {
7641     .num_standard   = ARRAY_SIZE(airo_handler),
7642     .num_private    = ARRAY_SIZE(airo_private_handler),
7643     .num_private_args = ARRAY_SIZE(airo_private_args),
7644     .standard   = airo_handler,
7645     .private    = airo_private_handler,
7646     .private_args   = airo_private_args,
7647     .get_wireless_stats = airo_get_wireless_stats,
7648 };
7649 
7650 /*
7651  * This defines the configuration part of the Wireless Extensions
7652  * Note : irq and spinlock protection will occur in the subroutines
7653  *
7654  * TODO :
7655  *  o Check input value more carefully and fill correct values in range
7656  *  o Test and shakeout the bugs (if any)
7657  *
7658  * Jean II
7659  *
7660  * Javier Achirica did a great job of merging code from the unnamed CISCO
7661  * developer that added support for flashing the card.
7662  */
7663 static int airo_siocdevprivate(struct net_device *dev, struct ifreq *rq,
7664                    void __user *data, int cmd)
7665 {
7666     int rc = 0;
7667     struct airo_info *ai = dev->ml_priv;
7668 
7669     if (ai->power.event)
7670         return 0;
7671 
7672     switch (cmd) {
7673 #ifdef CISCO_EXT
7674     case AIROIDIFC:
7675 #ifdef AIROOLDIDIFC
7676     case AIROOLDIDIFC:
7677 #endif
7678     {
7679         int val = AIROMAGIC;
7680         aironet_ioctl com;
7681         if (copy_from_user(&com, data, sizeof(com)))
7682             rc = -EFAULT;
7683         else if (copy_to_user(com.data, (char *)&val, sizeof(val)))
7684             rc = -EFAULT;
7685     }
7686     break;
7687 
7688     case AIROIOCTL:
7689 #ifdef AIROOLDIOCTL
7690     case AIROOLDIOCTL:
7691 #endif
7692         /* Get the command struct and hand it off for evaluation by
7693          * the proper subfunction
7694          */
7695     {
7696         aironet_ioctl com;
7697         if (copy_from_user(&com, data, sizeof(com))) {
7698             rc = -EFAULT;
7699             break;
7700         }
7701 
7702         /* Separate R/W functions bracket legality here
7703          */
7704         if (com.command == AIRORSWVERSION) {
7705             if (copy_to_user(com.data, swversion, sizeof(swversion)))
7706                 rc = -EFAULT;
7707             else
7708                 rc = 0;
7709         }
7710         else if (com.command <= AIRORRID)
7711             rc = readrids(dev,&com);
7712         else if (com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2))
7713             rc = writerids(dev,&com);
7714         else if (com.command >= AIROFLSHRST && com.command <= AIRORESTART)
7715             rc = flashcard(dev,&com);
7716         else
7717             rc = -EINVAL;      /* Bad command in ioctl */
7718     }
7719     break;
7720 #endif /* CISCO_EXT */
7721 
7722     // All other calls are currently unsupported
7723     default:
7724         rc = -EOPNOTSUPP;
7725     }
7726     return rc;
7727 }
7728 
7729 /*
7730  * Get the Wireless stats out of the driver
7731  * Note : irq and spinlock protection will occur in the subroutines
7732  *
7733  * TODO :
7734  *  o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7735  *
7736  * Jean
7737  */
7738 static void airo_read_wireless_stats(struct airo_info *local)
7739 {
7740     StatusRid status_rid;
7741     StatsRid stats_rid;
7742     CapabilityRid cap_rid;
7743     __le32 *vals = stats_rid.vals;
7744 
7745     /* Get stats out of the card */
7746     if (local->power.event)
7747         return;
7748 
7749     readCapabilityRid(local, &cap_rid, 0);
7750     readStatusRid(local, &status_rid, 0);
7751     readStatsRid(local, &stats_rid, RID_STATS, 0);
7752 
7753     /* The status */
7754     local->wstats.status = le16_to_cpu(status_rid.mode);
7755 
7756     /* Signal quality and co */
7757     if (local->rssi) {
7758         local->wstats.qual.level =
7759             airo_rssi_to_dbm(local->rssi,
7760                      le16_to_cpu(status_rid.sigQuality));
7761         /* normalizedSignalStrength appears to be a percentage */
7762         local->wstats.qual.qual =
7763             le16_to_cpu(status_rid.normalizedSignalStrength);
7764     } else {
7765         local->wstats.qual.level =
7766             (le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7767         local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7768     }
7769     if (le16_to_cpu(status_rid.len) >= 124) {
7770         local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7771         local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7772     } else {
7773         local->wstats.qual.noise = 0;
7774         local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
7775     }
7776 
7777     /* Packets discarded in the wireless adapter due to wireless
7778      * specific problems */
7779     local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7780                      le32_to_cpu(vals[57]) +
7781                      le32_to_cpu(vals[58]); /* SSID Mismatch */
7782     local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7783     local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7784     local->wstats.discard.retries = le32_to_cpu(vals[10]);
7785     local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7786                      le32_to_cpu(vals[32]);
7787     local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7788 }
7789 
7790 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7791 {
7792     struct airo_info *local =  dev->ml_priv;
7793 
7794     if (!down_interruptible(&local->sem)) {
7795         airo_read_wireless_stats(local);
7796         up(&local->sem);
7797     }
7798     return &local->wstats;
7799 }
7800 
7801 #ifdef CISCO_EXT
7802 /*
7803  * This just translates from driver IOCTL codes to the command codes to
7804  * feed to the radio's host interface. Things can be added/deleted
7805  * as needed.  This represents the READ side of control I/O to
7806  * the card
7807  */
7808 static int readrids(struct net_device *dev, aironet_ioctl *comp)
7809 {
7810     unsigned short ridcode;
7811     unsigned char *iobuf;
7812     int len;
7813     struct airo_info *ai = dev->ml_priv;
7814 
7815     if (test_bit(FLAG_FLASHING, &ai->flags))
7816         return -EIO;
7817 
7818     switch(comp->command)
7819     {
7820     case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7821     case AIROGCFG:      ridcode = RID_CONFIG;
7822         if (test_bit(FLAG_COMMIT, &ai->flags)) {
7823             disable_MAC (ai, 1);
7824             writeConfigRid (ai, 1);
7825             enable_MAC(ai, 1);
7826         }
7827         break;
7828     case AIROGSLIST:    ridcode = RID_SSID;         break;
7829     case AIROGVLIST:    ridcode = RID_APLIST;       break;
7830     case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7831     case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7832     case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP; break;
7833     case AIROGWEPKNV:   ridcode = RID_WEP_PERM; break;
7834     case AIROGSTAT:     ridcode = RID_STATUS;       break;
7835     case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7836     case AIROGSTATSC32: ridcode = RID_STATS;        break;
7837     case AIROGMICSTATS:
7838         if (copy_to_user(comp->data, &ai->micstats,
7839                  min((int)comp->len, (int)sizeof(ai->micstats))))
7840             return -EFAULT;
7841         return 0;
7842     case AIRORRID:      ridcode = comp->ridnum;     break;
7843     default:
7844         return -EINVAL;
7845     }
7846 
7847     if (ridcode == RID_WEP_TEMP || ridcode == RID_WEP_PERM) {
7848         /* Only super-user can read WEP keys */
7849         if (!capable(CAP_NET_ADMIN))
7850             return -EPERM;
7851     }
7852 
7853     if ((iobuf = kzalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7854         return -ENOMEM;
7855 
7856     PC4500_readrid(ai, ridcode, iobuf, RIDSIZE, 1);
7857     /* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7858      * then return it to the user
7859      * 9/22/2000 Honor user given length
7860      */
7861     len = comp->len;
7862 
7863     if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7864         kfree (iobuf);
7865         return -EFAULT;
7866     }
7867     kfree (iobuf);
7868     return 0;
7869 }
7870 
7871 /*
7872  * Danger Will Robinson write the rids here
7873  */
7874 
7875 static int writerids(struct net_device *dev, aironet_ioctl *comp)
7876 {
7877     struct airo_info *ai = dev->ml_priv;
7878     int  ridcode;
7879         int  enabled;
7880     int (*writer)(struct airo_info *, u16 rid, const void *, int, int);
7881     unsigned char *iobuf;
7882 
7883     /* Only super-user can write RIDs */
7884     if (!capable(CAP_NET_ADMIN))
7885         return -EPERM;
7886 
7887     if (test_bit(FLAG_FLASHING, &ai->flags))
7888         return -EIO;
7889 
7890     ridcode = 0;
7891     writer = do_writerid;
7892 
7893     switch(comp->command)
7894     {
7895     case AIROPSIDS:     ridcode = RID_SSID;         break;
7896     case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7897     case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7898     case AIROPCFG: ai->config.len = 0;
7899                 clear_bit(FLAG_COMMIT, &ai->flags);
7900                 ridcode = RID_CONFIG;       break;
7901     case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7902     case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7903     case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7904     case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7905         break;
7906     case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7907     case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7908 
7909         /* this is not really a rid but a command given to the card
7910          * same with MAC off
7911          */
7912     case AIROPMACON:
7913         if (enable_MAC(ai, 1) != 0)
7914             return -EIO;
7915         return 0;
7916 
7917         /*
7918          * Evidently this code in the airo driver does not get a symbol
7919          * as disable_MAC. it's probably so short the compiler does not gen one.
7920          */
7921     case AIROPMACOFF:
7922         disable_MAC(ai, 1);
7923         return 0;
7924 
7925         /* This command merely clears the counts does not actually store any data
7926          * only reads rid. But as it changes the cards state, I put it in the
7927          * writerid routines.
7928          */
7929     case AIROPSTCLR:
7930         if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7931             return -ENOMEM;
7932 
7933         PC4500_readrid(ai, RID_STATSDELTACLEAR, iobuf, RIDSIZE, 1);
7934 
7935         enabled = ai->micstats.enabled;
7936         memset(&ai->micstats, 0, sizeof(ai->micstats));
7937         ai->micstats.enabled = enabled;
7938 
7939         if (copy_to_user(comp->data, iobuf,
7940                  min((int)comp->len, (int)RIDSIZE))) {
7941             kfree (iobuf);
7942             return -EFAULT;
7943         }
7944         kfree (iobuf);
7945         return 0;
7946 
7947     default:
7948         return -EOPNOTSUPP; /* Blarg! */
7949     }
7950     if (comp->len > RIDSIZE)
7951         return -EINVAL;
7952 
7953     if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7954         return -ENOMEM;
7955 
7956     if (copy_from_user(iobuf, comp->data, comp->len)) {
7957         kfree (iobuf);
7958         return -EFAULT;
7959     }
7960 
7961     if (comp->command == AIROPCFG) {
7962         ConfigRid *cfg = (ConfigRid *)iobuf;
7963 
7964         if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7965             cfg->opmode |= MODE_MIC;
7966 
7967         if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
7968             set_bit (FLAG_ADHOC, &ai->flags);
7969         else
7970             clear_bit (FLAG_ADHOC, &ai->flags);
7971     }
7972 
7973     if ((*writer)(ai, ridcode, iobuf, comp->len, 1)) {
7974         kfree (iobuf);
7975         return -EIO;
7976     }
7977     kfree (iobuf);
7978     return 0;
7979 }
7980 
7981 /*****************************************************************************
7982  * Ancillary flash / mod functions much black magic lurkes here              *
7983  *****************************************************************************
7984  */
7985 
7986 /*
7987  * Flash command switch table
7988  */
7989 
7990 static int flashcard(struct net_device *dev, aironet_ioctl *comp)
7991 {
7992     int z;
7993 
7994     /* Only super-user can modify flash */
7995     if (!capable(CAP_NET_ADMIN))
7996         return -EPERM;
7997 
7998     switch(comp->command)
7999     {
8000     case AIROFLSHRST:
8001         return cmdreset((struct airo_info *)dev->ml_priv);
8002 
8003     case AIROFLSHSTFL:
8004         if (!AIRO_FLASH(dev) &&
8005             (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
8006             return -ENOMEM;
8007         return setflashmode((struct airo_info *)dev->ml_priv);
8008 
8009     case AIROFLSHGCHR: /* Get char from aux */
8010         if (comp->len != sizeof(int))
8011             return -EINVAL;
8012         if (copy_from_user(&z, comp->data, comp->len))
8013             return -EFAULT;
8014         return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
8015 
8016     case AIROFLSHPCHR: /* Send char to card. */
8017         if (comp->len != sizeof(int))
8018             return -EINVAL;
8019         if (copy_from_user(&z, comp->data, comp->len))
8020             return -EFAULT;
8021         return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
8022 
8023     case AIROFLPUTBUF: /* Send 32k to card */
8024         if (!AIRO_FLASH(dev))
8025             return -ENOMEM;
8026         if (comp->len > FLASHSIZE)
8027             return -EINVAL;
8028         if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
8029             return -EFAULT;
8030 
8031         flashputbuf((struct airo_info *)dev->ml_priv);
8032         return 0;
8033 
8034     case AIRORESTART:
8035         if (flashrestart((struct airo_info *)dev->ml_priv, dev))
8036             return -EIO;
8037         return 0;
8038     }
8039     return -EINVAL;
8040 }
8041 
8042 #define FLASH_COMMAND  0x7e7e
8043 
8044 /*
8045  * STEP 1)
8046  * Disable MAC and do soft reset on
8047  * card.
8048  */
8049 
8050 static int cmdreset(struct airo_info *ai)
8051 {
8052     disable_MAC(ai, 1);
8053 
8054     if (!waitbusy (ai)) {
8055         airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
8056         return -EBUSY;
8057     }
8058 
8059     OUT4500(ai, COMMAND, CMD_SOFTRESET);
8060 
8061     ssleep(1);          /* WAS 600 12/7/00 */
8062 
8063     if (!waitbusy (ai)) {
8064         airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
8065         return -EBUSY;
8066     }
8067     return 0;
8068 }
8069 
8070 /* STEP 2)
8071  * Put the card in legendary flash
8072  * mode
8073  */
8074 
8075 static int setflashmode (struct airo_info *ai)
8076 {
8077     set_bit (FLAG_FLASHING, &ai->flags);
8078 
8079     OUT4500(ai, SWS0, FLASH_COMMAND);
8080     OUT4500(ai, SWS1, FLASH_COMMAND);
8081     if (probe) {
8082         OUT4500(ai, SWS0, FLASH_COMMAND);
8083         OUT4500(ai, COMMAND, 0x10);
8084     } else {
8085         OUT4500(ai, SWS2, FLASH_COMMAND);
8086         OUT4500(ai, SWS3, FLASH_COMMAND);
8087         OUT4500(ai, COMMAND, 0);
8088     }
8089     msleep(500);        /* 500ms delay */
8090 
8091     if (!waitbusy(ai)) {
8092         clear_bit (FLAG_FLASHING, &ai->flags);
8093         airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
8094         return -EIO;
8095     }
8096     return 0;
8097 }
8098 
8099 /* Put character to SWS0 wait for dwelltime
8100  * x 50us for  echo .
8101  */
8102 
8103 static int flashpchar(struct airo_info *ai, int byte, int dwelltime)
8104 {
8105     int echo;
8106     int waittime;
8107 
8108     byte |= 0x8000;
8109 
8110     if (dwelltime == 0)
8111         dwelltime = 200;
8112 
8113     waittime = dwelltime;
8114 
8115     /* Wait for busy bit d15 to go false indicating buffer empty */
8116     while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
8117         udelay (50);
8118         waittime -= 50;
8119     }
8120 
8121     /* timeout for busy clear wait */
8122     if (waittime <= 0) {
8123         airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
8124         return -EBUSY;
8125     }
8126 
8127     /* Port is clear now write byte and wait for it to echo back */
8128     do {
8129         OUT4500(ai, SWS0, byte);
8130         udelay(50);
8131         dwelltime -= 50;
8132         echo = IN4500(ai, SWS1);
8133     } while (dwelltime >= 0 && echo != byte);
8134 
8135     OUT4500(ai, SWS1, 0);
8136 
8137     return (echo == byte) ? 0 : -EIO;
8138 }
8139 
8140 /*
8141  * Get a character from the card matching matchbyte
8142  * Step 3)
8143  */
8144 static int flashgchar(struct airo_info *ai, int matchbyte, int dwelltime)
8145 {
8146     int           rchar;
8147     unsigned char rbyte = 0;
8148 
8149     do {
8150         rchar = IN4500(ai, SWS1);
8151 
8152         if (dwelltime && !(0x8000 & rchar)) {
8153             dwelltime -= 10;
8154             mdelay(10);
8155             continue;
8156         }
8157         rbyte = 0xff & rchar;
8158 
8159         if ((rbyte == matchbyte) && (0x8000 & rchar)) {
8160             OUT4500(ai, SWS1, 0);
8161             return 0;
8162         }
8163         if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
8164             break;
8165         OUT4500(ai, SWS1, 0);
8166 
8167     } while (dwelltime > 0);
8168     return -EIO;
8169 }
8170 
8171 /*
8172  * Transfer 32k of firmware data from user buffer to our buffer and
8173  * send to the card
8174  */
8175 
8176 static int flashputbuf(struct airo_info *ai)
8177 {
8178     int            nwords;
8179 
8180     /* Write stuff */
8181     if (test_bit(FLAG_MPI,&ai->flags))
8182         memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
8183     else {
8184         OUT4500(ai, AUXPAGE, 0x100);
8185         OUT4500(ai, AUXOFF, 0);
8186 
8187         for (nwords = 0; nwords != FLASHSIZE / 2; nwords++) {
8188             OUT4500(ai, AUXDATA, ai->flash[nwords] & 0xffff);
8189         }
8190     }
8191     OUT4500(ai, SWS0, 0x8000);
8192 
8193     return 0;
8194 }
8195 
8196 /*
8197  *
8198  */
8199 static int flashrestart(struct airo_info *ai, struct net_device *dev)
8200 {
8201     int    i, status;
8202 
8203     ssleep(1);          /* Added 12/7/00 */
8204     clear_bit (FLAG_FLASHING, &ai->flags);
8205     if (test_bit(FLAG_MPI, &ai->flags)) {
8206         status = mpi_init_descriptors(ai);
8207         if (status != SUCCESS)
8208             return status;
8209     }
8210     status = setup_card(ai, dev, 1);
8211 
8212     if (!test_bit(FLAG_MPI,&ai->flags))
8213         for (i = 0; i < MAX_FIDS; i++) {
8214             ai->fids[i] = transmit_allocate
8215                 (ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2);
8216         }
8217 
8218     ssleep(1);          /* Added 12/7/00 */
8219     return status;
8220 }
8221 #endif /* CISCO_EXT */
8222 
8223 /*
8224     This program is free software; you can redistribute it and/or
8225     modify it under the terms of the GNU General Public License
8226     as published by the Free Software Foundation; either version 2
8227     of the License, or (at your option) any later version.
8228 
8229     This program is distributed in the hope that it will be useful,
8230     but WITHOUT ANY WARRANTY; without even the implied warranty of
8231     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8232     GNU General Public License for more details.
8233 
8234     In addition:
8235 
8236     Redistribution and use in source and binary forms, with or without
8237     modification, are permitted provided that the following conditions
8238     are met:
8239 
8240     1. Redistributions of source code must retain the above copyright
8241        notice, this list of conditions and the following disclaimer.
8242     2. Redistributions in binary form must reproduce the above copyright
8243        notice, this list of conditions and the following disclaimer in the
8244        documentation and/or other materials provided with the distribution.
8245     3. The name of the author may not be used to endorse or promote
8246        products derived from this software without specific prior written
8247        permission.
8248 
8249     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8250     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8251     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8252     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
8253     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8254     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8255     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8256     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8257     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
8258     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8259     POSSIBILITY OF SUCH DAMAGE.
8260 */
8261 
8262 module_init(airo_init_module);
8263 module_exit(airo_cleanup_module);