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