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