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, 0);
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, 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                        index = i;
3449        }
3450
3451        if (index != -1) {
3452                if (status & EV_TXEXC)
3453                        get_tx_error(ai, index);
3454
3455                OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
3456
3457                /* Set up to be used again */
3458                ai->fids[index] &= 0xffff;
3459                if (index < MAX_FIDS / 2) {
3460                        if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
3461                                netif_wake_queue(ai->dev);
3462                } else {
3463                        if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
3464                                netif_wake_queue(ai->wifidev);
3465                }
3466        } else {
3467                OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3468                airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
3469        }
3470}
3471
3472static irqreturn_t airo_interrupt(int irq, void *dev_id)
3473{
3474        struct net_device *dev = dev_id;
3475        u16 status, savedInterrupts = 0;
3476        struct airo_info *ai = dev->ml_priv;
3477        int handled = 0;
3478
3479        if (!netif_device_present(dev))
3480                return IRQ_NONE;
3481
3482        for (;;) {
3483                status = IN4500(ai, EVSTAT);
3484                if (!(status & STATUS_INTS) || (status == 0xffff))
3485                        break;
3486
3487                handled = 1;
3488
3489                if (status & EV_AWAKE) {
3490                        OUT4500(ai, EVACK, EV_AWAKE);
3491                        OUT4500(ai, EVACK, EV_AWAKE);
3492                }
3493
3494                if (!savedInterrupts) {
3495                        savedInterrupts = IN4500(ai, EVINTEN);
3496                        OUT4500(ai, EVINTEN, 0);
3497                }
3498
3499                if (status & EV_MIC) {
3500                        OUT4500(ai, EVACK, EV_MIC);
3501                        airo_handle_cisco_mic(ai);
3502                }
3503
3504                if (status & EV_LINK) {
3505                        /* Link status changed */
3506                        airo_handle_link(ai);
3507                }
3508
3509                /* Check to see if there is something to receive */
3510                if (status & EV_RX)
3511                        airo_handle_rx(ai);
3512
3513                /* Check to see if a packet has been transmitted */
3514                if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
3515                        airo_handle_tx(ai, status);
3516
3517                if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
3518                        airo_print_warn(ai->dev->name, "Got weird status %x",
3519                                status & ~STATUS_INTS & ~IGNORE_INTS );
3520                }
3521        }
3522
3523        if (savedInterrupts)
3524                OUT4500(ai, EVINTEN, savedInterrupts);
3525
3526        return IRQ_RETVAL(handled);
3527}
3528
3529/*
3530 *  Routines to talk to the card
3531 */
3532
3533/*
3534 *  This was originally written for the 4500, hence the name
3535 *  NOTE:  If use with 8bit mode and SMP bad things will happen!
3536 *         Why would some one do 8 bit IO in an SMP machine?!?
3537 */
3538static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
3539        if (test_bit(FLAG_MPI,&ai->flags))
3540                reg <<= 1;
3541        if ( !do8bitIO )
3542                outw( val, ai->dev->base_addr + reg );
3543        else {
3544                outb( val & 0xff, ai->dev->base_addr + reg );
3545                outb( val >> 8, ai->dev->base_addr + reg + 1 );
3546        }
3547}
3548
3549static u16 IN4500( struct airo_info *ai, u16 reg ) {
3550        unsigned short rc;
3551
3552        if (test_bit(FLAG_MPI,&ai->flags))
3553                reg <<= 1;
3554        if ( !do8bitIO )
3555                rc = inw( ai->dev->base_addr + reg );
3556        else {
3557                rc = inb( ai->dev->base_addr + reg );
3558                rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
3559        }
3560        return rc;
3561}
3562
3563static int enable_MAC(struct airo_info *ai, int lock)
3564{
3565        int rc;
3566        Cmd cmd;
3567        Resp rsp;
3568
3569        /* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3570         * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3571         * Note : we could try to use !netif_running(dev) in enable_MAC()
3572         * instead of this flag, but I don't trust it *within* the
3573         * open/close functions, and testing both flags together is
3574         * "cheaper" - Jean II */
3575        if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3576
3577        if (lock && down_interruptible(&ai->sem))
3578                return -ERESTARTSYS;
3579
3580        if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3581                memset(&cmd, 0, sizeof(cmd));
3582                cmd.cmd = MAC_ENABLE;
3583                rc = issuecommand(ai, &cmd, &rsp);
3584                if (rc == SUCCESS)
3585                        set_bit(FLAG_ENABLED, &ai->flags);
3586        } else
3587                rc = SUCCESS;
3588
3589        if (lock)
3590            up(&ai->sem);
3591
3592        if (rc)
3593                airo_print_err(ai->dev->name, "Cannot enable MAC");
3594        else if ((rsp.status & 0xFF00) != 0) {
3595                airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
3596                        "rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
3597                rc = ERROR;
3598        }
3599        return rc;
3600}
3601
3602static void disable_MAC( struct airo_info *ai, int lock ) {
3603        Cmd cmd;
3604        Resp rsp;
3605
3606        if (lock == 1 && down_interruptible(&ai->sem))
3607                return;
3608
3609        if (test_bit(FLAG_ENABLED, &ai->flags)) {
3610                if (lock != 2) /* lock == 2 means don't disable carrier */
3611                        netif_carrier_off(ai->dev);
3612                memset(&cmd, 0, sizeof(cmd));
3613                cmd.cmd = MAC_DISABLE; // disable in case already enabled
3614                issuecommand(ai, &cmd, &rsp);
3615                clear_bit(FLAG_ENABLED, &ai->flags);
3616        }
3617        if (lock == 1)
3618                up(&ai->sem);
3619}
3620
3621static void enable_interrupts( struct airo_info *ai ) {
3622        /* Enable the interrupts */
3623        OUT4500( ai, EVINTEN, STATUS_INTS );
3624}
3625
3626static void disable_interrupts( struct airo_info *ai ) {
3627        OUT4500( ai, EVINTEN, 0 );
3628}
3629
3630static void mpi_receive_802_3(struct airo_info *ai)
3631{
3632        RxFid rxd;
3633        int len = 0;
3634        struct sk_buff *skb;
3635        char *buffer;
3636        int off = 0;
3637        MICBuffer micbuf;
3638
3639        memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3640        /* Make sure we got something */
3641        if (rxd.rdy && rxd.valid == 0) {
3642                len = rxd.len + 12;
3643                if (len < 12 || len > 2048)
3644                        goto badrx;
3645
3646                skb = dev_alloc_skb(len);
3647                if (!skb) {
3648                        ai->dev->stats.rx_dropped++;
3649                        goto badrx;
3650                }
3651                buffer = skb_put(skb,len);
3652                memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3653                if (ai->micstats.enabled) {
3654                        memcpy(&micbuf,
3655                                ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3656                                sizeof(micbuf));
3657                        if (ntohs(micbuf.typelen) <= 0x05DC) {
3658                                if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3659                                        goto badmic;
3660
3661                                off = sizeof(micbuf);
3662                                skb_trim (skb, len - off);
3663                        }
3664                }
3665                memcpy(buffer + ETH_ALEN * 2,
3666                        ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3667                        len - ETH_ALEN * 2 - off);
3668                if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3669badmic:
3670                        dev_kfree_skb_irq (skb);
3671                        goto badrx;
3672                }
3673#ifdef WIRELESS_SPY
3674                if (ai->spy_data.spy_number > 0) {
3675                        char *sa;
3676                        struct iw_quality wstats;
3677                        /* Prepare spy data : addr + qual */
3678                        sa = buffer + ETH_ALEN;
3679                        wstats.qual = 0; /* XXX Where do I get that info from ??? */
3680                        wstats.level = 0;
3681                        wstats.updated = 0;
3682                        /* Update spy records */
3683                        wireless_spy_update(ai->dev, sa, &wstats);
3684                }
3685#endif /* WIRELESS_SPY */
3686
3687                skb->ip_summed = CHECKSUM_NONE;
3688                skb->protocol = eth_type_trans(skb, ai->dev);
3689                netif_rx(skb);
3690        }
3691badrx:
3692        if (rxd.valid == 0) {
3693                rxd.valid = 1;
3694                rxd.rdy = 0;
3695                rxd.len = PKTSIZE;
3696                memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3697        }
3698}
3699
3700static void mpi_receive_802_11(struct airo_info *ai)
3701{
3702        RxFid rxd;
3703        struct sk_buff *skb = NULL;
3704        u16 len, hdrlen = 0;
3705        __le16 fc;
3706        struct rx_hdr hdr;
3707        u16 gap;
3708        u16 *buffer;
3709        char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3710
3711        memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3712        memcpy ((char *)&hdr, ptr, sizeof(hdr));
3713        ptr += sizeof(hdr);
3714        /* Bad CRC. Ignore packet */
3715        if (le16_to_cpu(hdr.status) & 2)
3716                hdr.len = 0;
3717        if (ai->wifidev == NULL)
3718                hdr.len = 0;
3719        len = le16_to_cpu(hdr.len);
3720        if (len > AIRO_DEF_MTU) {
3721                airo_print_err(ai->dev->name, "Bad size %d", len);
3722                goto badrx;
3723        }
3724        if (len == 0)
3725                goto badrx;
3726
3727        fc = get_unaligned((__le16 *)ptr);
3728        hdrlen = header_len(fc);
3729
3730        skb = dev_alloc_skb( len + hdrlen + 2 );
3731        if ( !skb ) {
3732                ai->dev->stats.rx_dropped++;
3733                goto badrx;
3734        }
3735        buffer = skb_put(skb, len + hdrlen);
3736        memcpy ((char *)buffer, ptr, hdrlen);
3737        ptr += hdrlen;
3738        if (hdrlen == 24)
3739                ptr += 6;
3740        gap = get_unaligned_le16(ptr);
3741        ptr += sizeof(__le16);
3742        if (gap) {
3743                if (gap <= 8)
3744                        ptr += gap;
3745                else
3746                        airo_print_err(ai->dev->name,
3747                            "gaplen too big. Problems will follow...");
3748        }
3749        memcpy ((char *)buffer + hdrlen, ptr, len);
3750        ptr += len;
3751#ifdef IW_WIRELESS_SPY    /* defined in iw_handler.h */
3752        if (ai->spy_data.spy_number > 0) {
3753                char *sa;
3754                struct iw_quality wstats;
3755                /* Prepare spy data : addr + qual */
3756                sa = (char*)buffer + 10;
3757                wstats.qual = hdr.rssi[0];
3758                if (ai->rssi)
3759                        wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3760                else
3761                        wstats.level = (hdr.rssi[1] + 321) / 2;
3762                wstats.noise = ai->wstats.qual.noise;
3763                wstats.updated = IW_QUAL_QUAL_UPDATED
3764                        | IW_QUAL_LEVEL_UPDATED
3765                        | IW_QUAL_DBM;
3766                /* Update spy records */
3767                wireless_spy_update(ai->dev, sa, &wstats);
3768        }
3769#endif /* IW_WIRELESS_SPY */
3770        skb_reset_mac_header(skb);
3771        skb->pkt_type = PACKET_OTHERHOST;
3772        skb->dev = ai->wifidev;
3773        skb->protocol = htons(ETH_P_802_2);
3774        skb->ip_summed = CHECKSUM_NONE;
3775        netif_rx( skb );
3776
3777badrx:
3778        if (rxd.valid == 0) {
3779                rxd.valid = 1;
3780                rxd.rdy = 0;
3781                rxd.len = PKTSIZE;
3782                memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3783        }
3784}
3785
3786static inline void set_auth_type(struct airo_info *local, int auth_type)
3787{
3788        local->config.authType = auth_type;
3789        /* Cache the last auth type used (of AUTH_OPEN and AUTH_ENCRYPT).
3790         * Used by airo_set_auth()
3791         */
3792        if (auth_type == AUTH_OPEN || auth_type == AUTH_ENCRYPT)
3793                local->last_auth = auth_type;
3794}
3795
3796static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3797{
3798        Cmd cmd;
3799        Resp rsp;
3800        int status;
3801        SsidRid mySsid;
3802        __le16 lastindex;
3803        WepKeyRid wkr;
3804        int rc;
3805
3806        memset( &mySsid, 0, sizeof( mySsid ) );
3807        kfree (ai->flash);
3808        ai->flash = NULL;
3809
3810        /* The NOP is the first step in getting the card going */
3811        cmd.cmd = NOP;
3812        cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3813        if (lock && down_interruptible(&ai->sem))
3814                return ERROR;
3815        if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
3816                if (lock)
3817                        up(&ai->sem);
3818                return ERROR;
3819        }
3820        disable_MAC( ai, 0);
3821
3822        // Let's figure out if we need to use the AUX port
3823        if (!test_bit(FLAG_MPI,&ai->flags)) {
3824                cmd.cmd = CMD_ENABLEAUX;
3825                if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3826                        if (lock)
3827                                up(&ai->sem);
3828                        airo_print_err(ai->dev->name, "Error checking for AUX port");
3829                        return ERROR;
3830                }
3831                if (!aux_bap || rsp.status & 0xff00) {
3832                        ai->bap_read = fast_bap_read;
3833                        airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
3834                } else {
3835                        ai->bap_read = aux_bap_read;
3836                        airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
3837                }
3838        }
3839        if (lock)
3840                up(&ai->sem);
3841        if (ai->config.len == 0) {
3842                int i;
3843                tdsRssiRid rssi_rid;
3844                CapabilityRid cap_rid;
3845
3846                kfree(ai->SSID);
3847                ai->SSID = NULL;
3848                // general configuration (read/modify/write)
3849                status = readConfigRid(ai, lock);
3850                if ( status != SUCCESS ) return ERROR;
3851
3852                status = readCapabilityRid(ai, &cap_rid, lock);
3853                if ( status != SUCCESS ) return ERROR;
3854
3855                status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3856                if ( status == SUCCESS ) {
3857                        if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3858                                memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3859                }
3860                else {
3861                        kfree(ai->rssi);
3862                        ai->rssi = NULL;
3863                        if (cap_rid.softCap & cpu_to_le16(8))
3864                                ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3865                        else
3866                                airo_print_warn(ai->dev->name, "unknown received signal "
3867                                                "level scale");
3868                }
3869                ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3870                set_auth_type(ai, AUTH_OPEN);
3871                ai->config.modulation = MOD_CCK;
3872
3873                if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
3874                    (cap_rid.extSoftCap & cpu_to_le16(1)) &&
3875                    micsetup(ai) == SUCCESS) {
3876                        ai->config.opmode |= MODE_MIC;
3877                        set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3878                }
3879
3880                /* Save off the MAC */
3881                for( i = 0; i < ETH_ALEN; i++ ) {
3882                        mac[i] = ai->config.macAddr[i];
3883                }
3884
3885                /* Check to see if there are any insmod configured
3886                   rates to add */
3887                if ( rates[0] ) {
3888                        memset(ai->config.rates,0,sizeof(ai->config.rates));
3889                        for( i = 0; i < 8 && rates[i]; i++ ) {
3890                                ai->config.rates[i] = rates[i];
3891                        }
3892                }
3893                set_bit (FLAG_COMMIT, &ai->flags);
3894        }
3895
3896        /* Setup the SSIDs if present */
3897        if ( ssids[0] ) {
3898                int i;
3899                for( i = 0; i < 3 && ssids[i]; i++ ) {
3900                        size_t len = strlen(ssids[i]);
3901                        if (len > 32)
3902                                len = 32;
3903                        mySsid.ssids[i].len = cpu_to_le16(len);
3904                        memcpy(mySsid.ssids[i].ssid, ssids[i], len);
3905                }
3906                mySsid.len = cpu_to_le16(sizeof(mySsid));
3907        }
3908
3909        status = writeConfigRid(ai, lock);
3910        if ( status != SUCCESS ) return ERROR;
3911
3912        /* Set up the SSID list */
3913        if ( ssids[0] ) {
3914                status = writeSsidRid(ai, &mySsid, lock);
3915                if ( status != SUCCESS ) return ERROR;
3916        }
3917
3918        status = enable_MAC(ai, lock);
3919        if (status != SUCCESS)
3920                return ERROR;
3921
3922        /* Grab the initial wep key, we gotta save it for auto_wep */
3923        rc = readWepKeyRid(ai, &wkr, 1, lock);
3924        if (rc == SUCCESS) do {
3925                lastindex = wkr.kindex;
3926                if (wkr.kindex == cpu_to_le16(0xffff)) {
3927                        ai->defindex = wkr.mac[0];
3928                }
3929                rc = readWepKeyRid(ai, &wkr, 0, lock);
3930        } while(lastindex != wkr.kindex);
3931
3932        try_auto_wep(ai);
3933
3934        return SUCCESS;
3935}
3936
3937static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3938        // Im really paranoid about letting it run forever!
3939        int max_tries = 600000;
3940
3941        if (IN4500(ai, EVSTAT) & EV_CMD)
3942                OUT4500(ai, EVACK, EV_CMD);
3943
3944        OUT4500(ai, PARAM0, pCmd->parm0);
3945        OUT4500(ai, PARAM1, pCmd->parm1);
3946        OUT4500(ai, PARAM2, pCmd->parm2);
3947        OUT4500(ai, COMMAND, pCmd->cmd);
3948
3949        while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3950                if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3951                        // PC4500 didn't notice command, try again
3952                        OUT4500(ai, COMMAND, pCmd->cmd);
3953                if (!in_atomic() && (max_tries & 255) == 0)
3954                        schedule();
3955        }
3956
3957        if ( max_tries == -1 ) {
3958                airo_print_err(ai->dev->name,
3959                        "Max tries exceeded when issuing command");
3960                if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3961                        OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3962                return ERROR;
3963        }
3964
3965        // command completed
3966        pRsp->status = IN4500(ai, STATUS);
3967        pRsp->rsp0 = IN4500(ai, RESP0);
3968        pRsp->rsp1 = IN4500(ai, RESP1);
3969        pRsp->rsp2 = IN4500(ai, RESP2);
3970        if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
3971                airo_print_err(ai->dev->name,
3972                        "cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
3973                        pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
3974                        pRsp->rsp2);
3975
3976        // clear stuck command busy if necessary
3977        if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
3978                OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3979        }
3980        // acknowledge processing the status/response
3981        OUT4500(ai, EVACK, EV_CMD);
3982
3983        return SUCCESS;
3984}
3985
3986/* Sets up the bap to start exchange data.  whichbap should
3987 * be one of the BAP0 or BAP1 defines.  Locks should be held before
3988 * calling! */
3989static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3990{
3991        int timeout = 50;
3992        int max_tries = 3;
3993
3994        OUT4500(ai, SELECT0+whichbap, rid);
3995        OUT4500(ai, OFFSET0+whichbap, offset);
3996        while (1) {
3997                int status = IN4500(ai, OFFSET0+whichbap);
3998                if (status & BAP_BUSY) {
3999                        /* This isn't really a timeout, but its kinda
4000                           close */
4001                        if (timeout--) {
4002                                continue;
4003                        }
4004                } else if ( status & BAP_ERR ) {
4005                        /* invalid rid or offset */
4006                        airo_print_err(ai->dev->name, "BAP error %x %d",
4007                                status, whichbap );
4008                        return ERROR;
4009                } else if (status & BAP_DONE) { // success
4010                        return SUCCESS;
4011                }
4012                if ( !(max_tries--) ) {
4013                        airo_print_err(ai->dev->name,
4014                                "BAP setup error too many retries\n");
4015                        return ERROR;
4016                }
4017                // -- PC4500 missed it, try again
4018                OUT4500(ai, SELECT0+whichbap, rid);
4019                OUT4500(ai, OFFSET0+whichbap, offset);
4020                timeout = 50;
4021        }
4022}
4023
4024/* should only be called by aux_bap_read.  This aux function and the
4025   following use concepts not documented in the developers guide.  I
4026   got them from a patch given to my by Aironet */
4027static u16 aux_setup(struct airo_info *ai, u16 page,
4028                     u16 offset, u16 *len)
4029{
4030        u16 next;
4031
4032        OUT4500(ai, AUXPAGE, page);
4033        OUT4500(ai, AUXOFF, 0);
4034        next = IN4500(ai, AUXDATA);
4035        *len = IN4500(ai, AUXDATA)&0xff;
4036        if (offset != 4) OUT4500(ai, AUXOFF, offset);
4037        return next;
4038}
4039
4040/* requires call to bap_setup() first */
4041static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4042                        int bytelen, int whichbap)
4043{
4044        u16 len;
4045        u16 page;
4046        u16 offset;
4047        u16 next;
4048        int words;
4049        int i;
4050        unsigned long flags;
4051
4052        spin_lock_irqsave(&ai->aux_lock, flags);
4053        page = IN4500(ai, SWS0+whichbap);
4054        offset = IN4500(ai, SWS2+whichbap);
4055        next = aux_setup(ai, page, offset, &len);
4056        words = (bytelen+1)>>1;
4057
4058        for (i=0; i<words;) {
4059                int count;
4060                count = (len>>1) < (words-i) ? (len>>1) : (words-i);
4061                if ( !do8bitIO )
4062                        insw( ai->dev->base_addr+DATA0+whichbap,
4063                              pu16Dst+i,count );
4064                else
4065                        insb( ai->dev->base_addr+DATA0+whichbap,
4066                              pu16Dst+i, count << 1 );
4067                i += count;
4068                if (i<words) {
4069                        next = aux_setup(ai, next, 4, &len);
4070                }
4071        }
4072        spin_unlock_irqrestore(&ai->aux_lock, flags);
4073        return SUCCESS;
4074}
4075
4076
4077/* requires call to bap_setup() first */
4078static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4079                         int bytelen, int whichbap)
4080{
4081        bytelen = (bytelen + 1) & (~1); // round up to even value
4082        if ( !do8bitIO )
4083                insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
4084        else
4085                insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
4086        return SUCCESS;
4087}
4088
4089/* requires call to bap_setup() first */
4090static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
4091                     int bytelen, int whichbap)
4092{
4093        bytelen = (bytelen + 1) & (~1); // round up to even value
4094        if ( !do8bitIO )
4095                outsw( ai->dev->base_addr+DATA0+whichbap,
4096                       pu16Src, bytelen>>1 );
4097        else
4098                outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
4099        return SUCCESS;
4100}
4101
4102static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
4103{
4104        Cmd cmd; /* for issuing commands */
4105        Resp rsp; /* response from commands */
4106        u16 status;
4107
4108        memset(&cmd, 0, sizeof(cmd));
4109        cmd.cmd = accmd;
4110        cmd.parm0 = rid;
4111        status = issuecommand(ai, &cmd, &rsp);
4112        if (status != 0) return status;
4113        if ( (rsp.status & 0x7F00) != 0) {
4114                return (accmd << 8) + (rsp.rsp0 & 0xFF);
4115        }
4116        return 0;
4117}
4118
4119/*  Note, that we are using BAP1 which is also used by transmit, so
4120 *  we must get a lock. */
4121static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
4122{
4123        u16 status;
4124        int rc = SUCCESS;
4125
4126        if (lock) {
4127                if (down_interruptible(&ai->sem))
4128                        return ERROR;
4129        }
4130        if (test_bit(FLAG_MPI,&ai->flags)) {
4131                Cmd cmd;
4132                Resp rsp;
4133
4134                memset(&cmd, 0, sizeof(cmd));
4135                memset(&rsp, 0, sizeof(rsp));
4136                ai->config_desc.rid_desc.valid = 1;
4137                ai->config_desc.rid_desc.len = RIDSIZE;
4138                ai->config_desc.rid_desc.rid = 0;
4139                ai->config_desc.rid_desc.host_addr = ai->ridbus;
4140
4141                cmd.cmd = CMD_ACCESS;
4142                cmd.parm0 = rid;
4143
4144                memcpy_toio(ai->config_desc.card_ram_off,
4145                        &ai->config_desc.rid_desc, sizeof(Rid));
4146
4147                rc = issuecommand(ai, &cmd, &rsp);
4148
4149                if (rsp.status & 0x7f00)
4150                        rc = rsp.rsp0;
4151                if (!rc)
4152                        memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
4153                goto done;
4154        } else {
4155                if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4156                        rc = status;
4157                        goto done;
4158                }
4159                if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4160                        rc = ERROR;
4161                        goto done;
4162                }
4163                // read the rid length field
4164                bap_read(ai, pBuf, 2, BAP1);
4165                // length for remaining part of rid
4166                len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
4167
4168                if ( len <= 2 ) {
4169                        airo_print_err(ai->dev->name,
4170                                "Rid %x has a length of %d which is too short",
4171                                (int)rid, (int)len );
4172                        rc = ERROR;
4173                        goto done;
4174                }
4175                // read remainder of the rid
4176                rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
4177        }
4178done:
4179        if (lock)
4180                up(&ai->sem);
4181        return rc;
4182}
4183
4184/*  Note, that we are using BAP1 which is also used by transmit, so
4185 *  make sure this isn't called when a transmit is happening */
4186static int PC4500_writerid(struct airo_info *ai, u16 rid,
4187                           const void *pBuf, int len, int lock)
4188{
4189        u16 status;
4190        int rc = SUCCESS;
4191
4192        *(__le16*)pBuf = cpu_to_le16((u16)len);
4193
4194        if (lock) {
4195                if (down_interruptible(&ai->sem))
4196                        return ERROR;
4197        }
4198        if (test_bit(FLAG_MPI,&ai->flags)) {
4199                Cmd cmd;
4200                Resp rsp;
4201
4202                if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
4203                        airo_print_err(ai->dev->name,
4204                                "%s: MAC should be disabled (rid=%04x)",
4205                                __func__, rid);
4206                memset(&cmd, 0, sizeof(cmd));
4207                memset(&rsp, 0, sizeof(rsp));
4208
4209                ai->config_desc.rid_desc.valid = 1;
4210                ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4211                ai->config_desc.rid_desc.rid = 0;
4212
4213                cmd.cmd = CMD_WRITERID;
4214                cmd.parm0 = rid;
4215
4216                memcpy_toio(ai->config_desc.card_ram_off,
4217                        &ai->config_desc.rid_desc, sizeof(Rid));
4218
4219                if (len < 4 || len > 2047) {
4220                        airo_print_err(ai->dev->name, "%s: len=%d", __func__, len);
4221                        rc = -1;
4222                } else {
4223                        memcpy(ai->config_desc.virtual_host_addr,
4224                                pBuf, len);
4225
4226                        rc = issuecommand(ai, &cmd, &rsp);
4227                        if ((rc & 0xff00) != 0) {
4228                                airo_print_err(ai->dev->name, "%s: Write rid Error %d",
4229                                                __func__, rc);
4230                                airo_print_err(ai->dev->name, "%s: Cmd=%04x",
4231                                                __func__, cmd.cmd);
4232                        }
4233
4234                        if ((rsp.status & 0x7f00))
4235                                rc = rsp.rsp0;
4236                }
4237        } else {
4238                // --- first access so that we can write the rid data
4239                if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4240                        rc = status;
4241                        goto done;
4242                }
4243                // --- now write the rid data
4244                if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4245                        rc = ERROR;
4246                        goto done;
4247                }
4248                bap_write(ai, pBuf, len, BAP1);
4249                // ---now commit the rid data
4250                rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4251        }
4252done:
4253        if (lock)
4254                up(&ai->sem);
4255        return rc;
4256}
4257
4258/* Allocates a FID to be used for transmitting packets.  We only use
4259   one for now. */
4260static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4261{
4262        unsigned int loop = 3000;
4263        Cmd cmd;
4264        Resp rsp;
4265        u16 txFid;
4266        __le16 txControl;
4267
4268        cmd.cmd = CMD_ALLOCATETX;
4269        cmd.parm0 = lenPayload;
4270        if (down_interruptible(&ai->sem))
4271                return ERROR;
4272        if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
4273                txFid = ERROR;
4274                goto done;
4275        }
4276        if ( (rsp.status & 0xFF00) != 0) {
4277                txFid = ERROR;
4278                goto done;
4279        }
4280        /* wait for the allocate event/indication
4281         * It makes me kind of nervous that this can just sit here and spin,
4282         * but in practice it only loops like four times. */
4283        while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4284        if (!loop) {
4285                txFid = ERROR;
4286                goto done;
4287        }
4288
4289        // get the allocated fid and acknowledge
4290        txFid = IN4500(ai, TXALLOCFID);
4291        OUT4500(ai, EVACK, EV_ALLOC);
4292
4293        /*  The CARD is pretty cool since it converts the ethernet packet
4294         *  into 802.11.  Also note that we don't release the FID since we
4295         *  will be using the same one over and over again. */
4296        /*  We only have to setup the control once since we are not
4297         *  releasing the fid. */
4298        if (raw)
4299                txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4300                        | TXCTL_ETHERNET | TXCTL_NORELEASE);
4301        else
4302                txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4303                        | TXCTL_ETHERNET | TXCTL_NORELEASE);
4304        if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4305                txFid = ERROR;
4306        else
4307                bap_write(ai, &txControl, sizeof(txControl), BAP1);
4308
4309done:
4310        up(&ai->sem);
4311
4312        return txFid;
4313}
4314
4315/* In general BAP1 is dedicated to transmiting packets.  However,
4316   since we need a BAP when accessing RIDs, we also use BAP1 for that.
4317   Make sure the BAP1 spinlock is held when this is called. */
4318static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
4319{
4320        __le16 payloadLen;
4321        Cmd cmd;
4322        Resp rsp;
4323        int miclen = 0;
4324        u16 txFid = len;
4325        MICBuffer pMic;
4326
4327        len >>= 16;
4328
4329        if (len <= ETH_ALEN * 2) {
4330                airo_print_warn(ai->dev->name, "Short packet %d", len);
4331                return ERROR;
4332        }
4333        len -= ETH_ALEN * 2;
4334
4335        if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
4336            (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
4337                if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
4338                        return ERROR;
4339                miclen = sizeof(pMic);
4340        }
4341        // packet is destination[6], source[6], payload[len-12]
4342        // write the payload length and dst/src/payload
4343        if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4344        /* The hardware addresses aren't counted as part of the payload, so
4345         * we have to subtract the 12 bytes for the addresses off */
4346        payloadLen = cpu_to_le16(len + miclen);
4347        bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4348        bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
4349        if (miclen)
4350                bap_write(ai, (__le16*)&pMic, miclen, BAP1);
4351        bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
4352        // issue the transmit command
4353        memset( &cmd, 0, sizeof( cmd ) );
4354        cmd.cmd = CMD_TRANSMIT;
4355        cmd.parm0 = txFid;
4356        if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4357        if ( (rsp.status & 0xFF00) != 0) return ERROR;
4358        return SUCCESS;
4359}
4360
4361static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
4362{
4363        __le16 fc, payloadLen;
4364        Cmd cmd;
4365        Resp rsp;
4366        int hdrlen;
4367        static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
4368        /* padding of header to full size + le16 gaplen (6) + gaplen bytes */
4369        u16 txFid = len;
4370        len >>= 16;
4371
4372        fc = *(__le16*)pPacket;
4373        hdrlen = header_len(fc);
4374
4375        if (len < hdrlen) {
4376                airo_print_warn(ai->dev->name, "Short packet %d", len);
4377                return ERROR;
4378        }
4379
4380        /* packet is 802.11 header +  payload
4381         * write the payload length and dst/src/payload */
4382        if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4383        /* The 802.11 header aren't counted as part of the payload, so
4384         * we have to subtract the header bytes off */
4385        payloadLen = cpu_to_le16(len-hdrlen);
4386        bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4387        if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4388        bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
4389        bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
4390
4391        bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
4392        // issue the transmit command
4393        memset( &cmd, 0, sizeof( cmd ) );
4394        cmd.cmd = CMD_TRANSMIT;
4395        cmd.parm0 = txFid;
4396        if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4397        if ( (rsp.status & 0xFF00) != 0) return ERROR;
4398        return SUCCESS;
4399}
4400
4401/*
4402 *  This is the proc_fs routines.  It is a bit messier than I would
4403 *  like!  Feel free to clean it up!
4404 */
4405
4406static ssize_t proc_read( struct file *file,
4407                          char __user *buffer,
4408                          size_t len,
4409                          loff_t *offset);
4410
4411static ssize_t proc_write( struct file *file,
4412                           const char __user *buffer,
4413                           size_t len,
4414                           loff_t *offset );
4415static int proc_close( struct inode *inode, struct file *file );
4416
4417static int proc_stats_open( struct inode *inode, struct file *file );
4418static int proc_statsdelta_open( struct inode *inode, struct file *file );
4419static int proc_status_open( struct inode *inode, struct file *file );
4420static int proc_SSID_open( struct inode *inode, struct file *file );
4421static int proc_APList_open( struct inode *inode, struct file *file );
4422static int proc_BSSList_open( struct inode *inode, struct file *file );
4423static int proc_config_open( struct inode *inode, struct file *file );
4424static int proc_wepkey_open( struct inode *inode, struct file *file );
4425
4426static const struct file_operations proc_statsdelta_ops = {
4427        .owner          = THIS_MODULE,
4428        .read           = proc_read,
4429        .open           = proc_statsdelta_open,
4430        .release        = proc_close,
4431        .llseek         = default_llseek,
4432};
4433
4434static const struct file_operations proc_stats_ops = {
4435        .owner          = THIS_MODULE,
4436        .read           = proc_read,
4437        .open           = proc_stats_open,
4438        .release        = proc_close,
4439        .llseek         = default_llseek,
4440};
4441
4442static const struct file_operations proc_status_ops = {
4443        .owner          = THIS_MODULE,
4444        .read           = proc_read,
4445        .open           = proc_status_open,
4446        .release        = proc_close,
4447        .llseek         = default_llseek,
4448};
4449
4450static const struct file_operations proc_SSID_ops = {
4451        .owner          = THIS_MODULE,
4452        .read           = proc_read,
4453        .write          = proc_write,
4454        .open           = proc_SSID_open,
4455        .release        = proc_close,
4456        .llseek         = default_llseek,
4457};
4458
4459static const struct file_operations proc_BSSList_ops = {
4460        .owner          = THIS_MODULE,
4461        .read           = proc_read,
4462        .write          = proc_write,
4463        .open           = proc_BSSList_open,
4464        .release        = proc_close,
4465        .llseek         = default_llseek,
4466};
4467
4468static const struct file_operations proc_APList_ops = {
4469        .owner          = THIS_MODULE,
4470        .read           = proc_read,
4471        .write          = proc_write,
4472        .open           = proc_APList_open,
4473        .release        = proc_close,
4474        .llseek         = default_llseek,
4475};
4476
4477static const struct file_operations proc_config_ops = {
4478        .owner          = THIS_MODULE,
4479        .read           = proc_read,
4480        .write          = proc_write,
4481        .open           = proc_config_open,
4482        .release        = proc_close,
4483        .llseek         = default_llseek,
4484};
4485
4486static const struct file_operations proc_wepkey_ops = {
4487        .owner          = THIS_MODULE,
4488        .read           = proc_read,
4489        .write          = proc_write,
4490        .open           = proc_wepkey_open,
4491        .release        = proc_close,
4492        .llseek         = default_llseek,
4493};
4494
4495static struct proc_dir_entry *airo_entry;
4496
4497struct proc_data {
4498        int release_buffer;
4499        int readlen;
4500        char *rbuffer;
4501        int writelen;
4502        int maxwritelen;
4503        char *wbuffer;
4504        void (*on_close) (struct inode *, struct file *);
4505};
4506
4507static int setup_proc_entry( struct net_device *dev,
4508                             struct airo_info *apriv ) {
4509        struct proc_dir_entry *entry;
4510
4511        /* First setup the device directory */
4512        strcpy(apriv->proc_name,dev->name);
4513        apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
4514                                            airo_entry);
4515        if (!apriv->proc_entry)
4516                return -ENOMEM;
4517        proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
4518
4519        /* Setup the StatsDelta */
4520        entry = proc_create_data("StatsDelta", 0444 & proc_perm,
4521                                 apriv->proc_entry, &proc_statsdelta_ops, dev);
4522        if (!entry)
4523                goto fail;
4524        proc_set_user(entry, proc_kuid, proc_kgid);
4525
4526        /* Setup the Stats */
4527        entry = proc_create_data("Stats", 0444 & proc_perm,
4528                                 apriv->proc_entry, &proc_stats_ops, dev);
4529        if (!entry)
4530                goto fail;
4531        proc_set_user(entry, proc_kuid, proc_kgid);
4532
4533        /* Setup the Status */
4534        entry = proc_create_data("Status", 0444 & proc_perm,
4535                                 apriv->proc_entry, &proc_status_ops, dev);
4536        if (!entry)
4537                goto fail;
4538        proc_set_user(entry, proc_kuid, proc_kgid);
4539
4540        /* Setup the Config */
4541        entry = proc_create_data("Config", proc_perm,
4542                                 apriv->proc_entry, &proc_config_ops, dev);
4543        if (!entry)
4544                goto fail;
4545        proc_set_user(entry, proc_kuid, proc_kgid);
4546
4547        /* Setup the SSID */
4548        entry = proc_create_data("SSID", proc_perm,
4549                                 apriv->proc_entry, &proc_SSID_ops, dev);
4550        if (!entry)
4551                goto fail;
4552        proc_set_user(entry, proc_kuid, proc_kgid);
4553
4554        /* Setup the APList */
4555        entry = proc_create_data("APList", proc_perm,
4556                                 apriv->proc_entry, &proc_APList_ops, dev);
4557        if (!entry)
4558                goto fail;
4559        proc_set_user(entry, proc_kuid, proc_kgid);
4560
4561        /* Setup the BSSList */
4562        entry = proc_create_data("BSSList", proc_perm,
4563                                 apriv->proc_entry, &proc_BSSList_ops, dev);
4564        if (!entry)
4565                goto fail;
4566        proc_set_user(entry, proc_kuid, proc_kgid);
4567
4568        /* Setup the WepKey */
4569        entry = proc_create_data("WepKey", proc_perm,
4570                                 apriv->proc_entry, &proc_wepkey_ops, dev);
4571        if (!entry)
4572                goto fail;
4573        proc_set_user(entry, proc_kuid, proc_kgid);
4574        return 0;
4575
4576fail:
4577        remove_proc_subtree(apriv->proc_name, airo_entry);
4578        return -ENOMEM;
4579}
4580
4581static int takedown_proc_entry( struct net_device *dev,
4582                                struct airo_info *apriv )
4583{
4584        remove_proc_subtree(apriv->proc_name, airo_entry);
4585        return 0;
4586}
4587
4588/*
4589 *  What we want from the proc_fs is to be able to efficiently read
4590 *  and write the configuration.  To do this, we want to read the
4591 *  configuration when the file is opened and write it when the file is
4592 *  closed.  So basically we allocate a read buffer at open and fill it
4593 *  with data, and allocate a write buffer and read it at close.
4594 */
4595
4596/*
4597 *  The read routine is generic, it relies on the preallocated rbuffer
4598 *  to supply the data.
4599 */
4600static ssize_t proc_read( struct file *file,
4601                          char __user *buffer,
4602                          size_t len,
4603                          loff_t *offset )
4604{
4605        struct proc_data *priv = file->private_data;
4606
4607        if (!priv->rbuffer)
4608                return -EINVAL;
4609
4610        return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
4611                                        priv->readlen);
4612}
4613
4614/*
4615 *  The write routine is generic, it fills in a preallocated rbuffer
4616 *  to supply the data.
4617 */
4618static ssize_t proc_write( struct file *file,
4619                           const char __user *buffer,
4620                           size_t len,
4621                           loff_t *offset )
4622{
4623        ssize_t ret;
4624        struct proc_data *priv = file->private_data;
4625
4626        if (!priv->wbuffer)
4627                return -EINVAL;
4628
4629        ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
4630                                        buffer, len);
4631        if (ret > 0)
4632                priv->writelen = max_t(int, priv->writelen, *offset);
4633
4634        return ret;
4635}
4636
4637static int proc_status_open(struct inode *inode, struct file *file)
4638{
4639        struct proc_data *data;
4640        struct net_device *dev = PDE_DATA(inode);
4641        struct airo_info *apriv = dev->ml_priv;
4642        CapabilityRid cap_rid;
4643        StatusRid status_rid;
4644        u16 mode;
4645        int i;
4646
4647        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4648                return -ENOMEM;
4649        data = file->private_data;
4650        if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4651                kfree (file->private_data);
4652                return -ENOMEM;
4653        }
4654
4655        readStatusRid(apriv, &status_rid, 1);
4656        readCapabilityRid(apriv, &cap_rid, 1);
4657
4658        mode = le16_to_cpu(status_rid.mode);
4659
4660        i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4661                    mode & 1 ? "CFG ": "",
4662                    mode & 2 ? "ACT ": "",
4663                    mode & 0x10 ? "SYN ": "",
4664                    mode & 0x20 ? "LNK ": "",
4665                    mode & 0x40 ? "LEAP ": "",
4666                    mode & 0x80 ? "PRIV ": "",
4667                    mode & 0x100 ? "KEY ": "",
4668                    mode & 0x200 ? "WEP ": "",
4669                    mode & 0x8000 ? "ERR ": "");
4670        sprintf( data->rbuffer+i, "Mode: %x\n"
4671                 "Signal Strength: %d\n"
4672                 "Signal Quality: %d\n"
4673                 "SSID: %-.*s\n"
4674                 "AP: %-.16s\n"
4675                 "Freq: %d\n"
4676                 "BitRate: %dmbs\n"
4677                 "Driver Version: %s\n"
4678                 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4679                 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4680                 "Software Version: %x\nSoftware Subversion: %x\n"
4681                 "Boot block version: %x\n",
4682                 le16_to_cpu(status_rid.mode),
4683                 le16_to_cpu(status_rid.normalizedSignalStrength),
4684                 le16_to_cpu(status_rid.signalQuality),
4685                 le16_to_cpu(status_rid.SSIDlen),
4686                 status_rid.SSID,
4687                 status_rid.apName,
4688                 le16_to_cpu(status_rid.channel),
4689                 le16_to_cpu(status_rid.currentXmitRate) / 2,
4690                 version,
4691                 cap_rid.prodName,
4692                 cap_rid.manName,
4693                 cap_rid.prodVer,
4694                 le16_to_cpu(cap_rid.radioType),
4695                 le16_to_cpu(cap_rid.country),
4696                 le16_to_cpu(cap_rid.hardVer),
4697                 le16_to_cpu(cap_rid.softVer),
4698                 le16_to_cpu(cap_rid.softSubVer),
4699                 le16_to_cpu(cap_rid.bootBlockVer));
4700        data->readlen = strlen( data->rbuffer );
4701        return 0;
4702}
4703
4704static int proc_stats_rid_open(struct inode*, struct file*, u16);
4705static int proc_statsdelta_open( struct inode *inode,
4706                                 struct file *file ) {
4707        if (file->f_mode&FMODE_WRITE) {
4708                return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4709        }
4710        return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4711}
4712
4713static int proc_stats_open( struct inode *inode, struct file *file ) {
4714        return proc_stats_rid_open(inode, file, RID_STATS);
4715}
4716
4717static int proc_stats_rid_open( struct inode *inode,
4718                                struct file *file,
4719                                u16 rid )
4720{
4721        struct proc_data *data;
4722        struct net_device *dev = PDE_DATA(inode);
4723        struct airo_info *apriv = dev->ml_priv;
4724        StatsRid stats;
4725        int i, j;
4726        __le32 *vals = stats.vals;
4727        int len;
4728
4729        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4730                return -ENOMEM;
4731        data = file->private_data;
4732        if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4733                kfree (file->private_data);
4734                return -ENOMEM;
4735        }
4736
4737        readStatsRid(apriv, &stats, rid, 1);
4738        len = le16_to_cpu(stats.len);
4739
4740        j = 0;
4741        for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4742                if (!statsLabels[i]) continue;
4743                if (j+strlen(statsLabels[i])+16>4096) {
4744                        airo_print_warn(apriv->dev->name,
4745                               "Potentially disastrous buffer overflow averted!");
4746                        break;
4747                }
4748                j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4749                                le32_to_cpu(vals[i]));
4750        }
4751        if (i*4 >= len) {
4752                airo_print_warn(apriv->dev->name, "Got a short rid");
4753        }
4754        data->readlen = j;
4755        return 0;
4756}
4757
4758static int get_dec_u16( char *buffer, int *start, int limit ) {
4759        u16 value;
4760        int valid = 0;
4761        for (value = 0; *start < limit && buffer[*start] >= '0' &&
4762                        buffer[*start] <= '9'; (*start)++) {
4763                valid = 1;
4764                value *= 10;
4765                value += buffer[*start] - '0';
4766        }
4767        if ( !valid ) return -1;
4768        return value;
4769}
4770
4771static int airo_config_commit(struct net_device *dev,
4772                              struct iw_request_info *info, void *zwrq,
4773                              char *extra);
4774
4775static inline int sniffing_mode(struct airo_info *ai)
4776{
4777        return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
4778                le16_to_cpu(RXMODE_RFMON);
4779}
4780
4781static void proc_config_on_close(struct inode *inode, struct file *file)
4782{
4783        struct proc_data *data = file->private_data;
4784        struct net_device *dev = PDE_DATA(inode);
4785        struct airo_info *ai = dev->ml_priv;
4786        char *line;
4787
4788        if ( !data->writelen ) return;
4789
4790        readConfigRid(ai, 1);
4791        set_bit (FLAG_COMMIT, &ai->flags);
4792
4793        line = data->wbuffer;
4794        while( line[0] ) {
4795/*** Mode processing */
4796                if ( !strncmp( line, "Mode: ", 6 ) ) {
4797                        line += 6;
4798                        if (sniffing_mode(ai))
4799                                set_bit (FLAG_RESET, &ai->flags);
4800                        ai->config.rmode &= ~RXMODE_FULL_MASK;
4801                        clear_bit (FLAG_802_11, &ai->flags);
4802                        ai->config.opmode &= ~MODE_CFG_MASK;
4803                        ai->config.scanMode = SCANMODE_ACTIVE;
4804                        if ( line[0] == 'a' ) {
4805                                ai->config.opmode |= MODE_STA_IBSS;
4806                        } else {
4807                                ai->config.opmode |= MODE_STA_ESS;
4808                                if ( line[0] == 'r' ) {
4809                                        ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4810                                        ai->config.scanMode = SCANMODE_PASSIVE;
4811                                        set_bit (FLAG_802_11, &ai->flags);
4812                                } else if ( line[0] == 'y' ) {
4813                                        ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4814                                        ai->config.scanMode = SCANMODE_PASSIVE;
4815                                        set_bit (FLAG_802_11, &ai->flags);
4816                                } else if ( line[0] == 'l' )
4817                                        ai->config.rmode |= RXMODE_LANMON;
4818                        }
4819                        set_bit (FLAG_COMMIT, &ai->flags);
4820                }
4821
4822/*** Radio status */
4823                else if (!strncmp(line,"Radio: ", 7)) {
4824                        line += 7;
4825                        if (!strncmp(line,"off",3)) {
4826                                set_bit (FLAG_RADIO_OFF, &ai->flags);
4827                        } else {
4828                                clear_bit (FLAG_RADIO_OFF, &ai->flags);
4829                        }
4830                }
4831/*** NodeName processing */
4832                else if ( !strncmp( line, "NodeName: ", 10 ) ) {
4833                        int j;
4834
4835                        line += 10;
4836                        memset( ai->config.nodeName, 0, 16 );
4837/* Do the name, assume a space between the mode and node name */
4838                        for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
4839                                ai->config.nodeName[j] = line[j];
4840                        }
4841                        set_bit (FLAG_COMMIT, &ai->flags);
4842                }
4843
4844/*** PowerMode processing */
4845                else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
4846                        line += 11;
4847                        if ( !strncmp( line, "PSPCAM", 6 ) ) {
4848                                ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4849                                set_bit (FLAG_COMMIT, &ai->flags);
4850                        } else if ( !strncmp( line, "PSP", 3 ) ) {
4851                                ai->config.powerSaveMode = POWERSAVE_PSP;
4852                                set_bit (FLAG_COMMIT, &ai->flags);
4853                        } else {
4854                                ai->config.powerSaveMode = POWERSAVE_CAM;
4855                                set_bit (FLAG_COMMIT, &ai->flags);
4856                        }
4857                } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
4858                        int v, i = 0, k = 0; /* i is index into line,
4859                                                k is index to rates */
4860
4861                        line += 11;
4862                        while((v = get_dec_u16(line, &i, 3))!=-1) {
4863                                ai->config.rates[k++] = (u8)v;
4864                                line += i + 1;
4865                                i = 0;
4866                        }
4867                        set_bit (FLAG_COMMIT, &ai->flags);
4868                } else if ( !strncmp( line, "Channel: ", 9 ) ) {
4869                        int v, i = 0;
4870                        line += 9;
4871                        v = get_dec_u16(line, &i, i+3);
4872                        if ( v != -1 ) {
4873                                ai->config.channelSet = cpu_to_le16(v);
4874                                set_bit (FLAG_COMMIT, &ai->flags);
4875                        }
4876                } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
4877                        int v, i = 0;
4878                        line += 11;
4879                        v = get_dec_u16(line, &i, i+3);
4880                        if ( v != -1 ) {
4881                                ai->config.txPower = cpu_to_le16(v);
4882                                set_bit (FLAG_COMMIT, &ai->flags);
4883                        }
4884                } else if ( !strncmp( line, "WEP: ", 5 ) ) {
4885                        line += 5;
4886                        switch( line[0] ) {
4887                        case 's':
4888                                set_auth_type(ai, AUTH_SHAREDKEY);
4889                                break;
4890                        case 'e':
4891                                set_auth_type(ai, AUTH_ENCRYPT);
4892                                break;
4893                        default:
4894                                set_auth_type(ai, AUTH_OPEN);
4895                                break;
4896                        }
4897                        set_bit (FLAG_COMMIT, &ai->flags);
4898                } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
4899                        int v, i = 0;
4900
4901                        line += 16;
4902                        v = get_dec_u16(line, &i, 3);
4903                        v = (v<0) ? 0 : ((v>255) ? 255 : v);
4904                        ai->config.longRetryLimit = cpu_to_le16(v);
4905                        set_bit (FLAG_COMMIT, &ai->flags);
4906                } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
4907                        int v, i = 0;
4908
4909                        line += 17;
4910                        v = get_dec_u16(line, &i, 3);
4911                        v = (v<0) ? 0 : ((v>255) ? 255 : v);
4912                        ai->config.shortRetryLimit = cpu_to_le16(v);
4913                        set_bit (FLAG_COMMIT, &ai->flags);
4914                } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
4915                        int v, i = 0;
4916
4917                        line += 14;
4918                        v = get_dec_u16(line, &i, 4);
4919                        v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4920                        ai->config.rtsThres = cpu_to_le16(v);
4921                        set_bit (FLAG_COMMIT, &ai->flags);
4922                } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
4923                        int v, i = 0;
4924
4925                        line += 16;
4926                        v = get_dec_u16(line, &i, 5);
4927                        v = (v<0) ? 0 : v;
4928                        ai->config.txLifetime = cpu_to_le16(v);
4929                        set_bit (FLAG_COMMIT, &ai->flags);
4930                } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
4931                        int v, i = 0;
4932
4933                        line += 16;
4934                        v = get_dec_u16(line, &i, 5);
4935                        v = (v<0) ? 0 : v;
4936                        ai->config.rxLifetime = cpu_to_le16(v);
4937                        set_bit (FLAG_COMMIT, &ai->flags);
4938                } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4939                        ai->config.txDiversity =
4940                                (line[13]=='l') ? 1 :
4941                                ((line[13]=='r')? 2: 3);
4942                        set_bit (FLAG_COMMIT, &ai->flags);
4943                } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4944                        ai->config.rxDiversity =
4945                                (line[13]=='l') ? 1 :
4946                                ((line[13]=='r')? 2: 3);
4947                        set_bit (FLAG_COMMIT, &ai->flags);
4948                } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4949                        int v, i = 0;
4950
4951                        line += 15;
4952                        v = get_dec_u16(line, &i, 4);
4953                        v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4954                        v = v & 0xfffe; /* Make sure its even */
4955                        ai->config.fragThresh = cpu_to_le16(v);
4956                        set_bit (FLAG_COMMIT, &ai->flags);
4957                } else if (!strncmp(line, "Modulation: ", 12)) {
4958                        line += 12;
4959                        switch(*line) {
4960                        case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4961                        case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4962                        case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4963                        default: airo_print_warn(ai->dev->name, "Unknown modulation");
4964                        }
4965                } else if (!strncmp(line, "Preamble: ", 10)) {
4966                        line += 10;
4967                        switch(*line) {
4968                        case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4969                        case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4970                        case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4971                        default: airo_print_warn(ai->dev->name, "Unknown preamble");
4972                        }
4973                } else {
4974                        airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
4975                }
4976                while( line[0] && line[0] != '\n' ) line++;
4977                if ( line[0] ) line++;
4978        }
4979        airo_config_commit(dev, NULL, NULL, NULL);
4980}
4981
4982static const char *get_rmode(__le16 mode)
4983{
4984        switch(mode & RXMODE_MASK) {
4985        case RXMODE_RFMON:  return "rfmon";
4986        case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
4987        case RXMODE_LANMON:  return "lanmon";
4988        }
4989        return "ESS";
4990}
4991
4992static int proc_config_open(struct inode *inode, struct file *file)
4993{
4994        struct proc_data *data;
4995        struct net_device *dev = PDE_DATA(inode);
4996        struct airo_info *ai = dev->ml_priv;
4997        int i;
4998        __le16 mode;
4999
5000        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5001                return -ENOMEM;
5002        data = file->private_data;
5003        if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
5004                kfree (file->private_data);
5005                return -ENOMEM;
5006        }
5007        if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
5008                kfree (data->rbuffer);
5009                kfree (file->private_data);
5010                return -ENOMEM;
5011        }
5012        data->maxwritelen = 2048;
5013        data->on_close = proc_config_on_close;
5014
5015        readConfigRid(ai, 1);
5016
5017        mode = ai->config.opmode & MODE_CFG_MASK;
5018        i = sprintf( data->rbuffer,
5019                     "Mode: %s\n"
5020                     "Radio: %s\n"
5021                     "NodeName: %-16s\n"
5022                     "PowerMode: %s\n"
5023                     "DataRates: %d %d %d %d %d %d %d %d\n"
5024                     "Channel: %d\n"
5025                     "XmitPower: %d\n",
5026                     mode == MODE_STA_IBSS ? "adhoc" :
5027                     mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
5028                     mode == MODE_AP ? "AP" :
5029                     mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
5030                     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
5031                     ai->config.nodeName,
5032                     ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
5033                     ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
5034                     ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
5035                     "Error",
5036                     (int)ai->config.rates[0],
5037                     (int)ai->config.rates[1],
5038                     (int)ai->config.rates[2],
5039                     (int)ai->config.rates[3],
5040                     (int)ai->config.rates[4],
5041                     (int)ai->config.rates[5],
5042                     (int)ai->config.rates[6],
5043                     (int)ai->config.rates[7],
5044                     le16_to_cpu(ai->config.channelSet),
5045                     le16_to_cpu(ai->config.txPower)
5046                );
5047        sprintf( data->rbuffer + i,
5048                 "LongRetryLimit: %d\n"
5049                 "ShortRetryLimit: %d\n"
5050                 "RTSThreshold: %d\n"
5051                 "TXMSDULifetime: %d\n"
5052                 "RXMSDULifetime: %d\n"
5053                 "TXDiversity: %s\n"
5054                 "RXDiversity: %s\n"
5055                 "FragThreshold: %d\n"
5056                 "WEP: %s\n"
5057                 "Modulation: %s\n"
5058                 "Preamble: %s\n",
5059                 le16_to_cpu(ai->config.longRetryLimit),
5060                 le16_to_cpu(ai->config.shortRetryLimit),
5061                 le16_to_cpu(ai->config.rtsThres),
5062                 le16_to_cpu(ai->config.txLifetime),
5063                 le16_to_cpu(ai->config.rxLifetime),
5064                 ai->config.txDiversity == 1 ? "left" :
5065                 ai->config.txDiversity == 2 ? "right" : "both",
5066                 ai->config.rxDiversity == 1 ? "left" :
5067                 ai->config.rxDiversity == 2 ? "right" : "both",
5068                 le16_to_cpu(ai->config.fragThresh),
5069                 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
5070                 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
5071                 ai->config.modulation == MOD_DEFAULT ? "default" :
5072                 ai->config.modulation == MOD_CCK ? "cck" :
5073                 ai->config.modulation == MOD_MOK ? "mok" : "error",
5074                 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
5075                 ai->config.preamble == PREAMBLE_LONG ? "long" :
5076                 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
5077                );
5078        data->readlen = strlen( data->rbuffer );
5079        return 0;
5080}
5081
5082static void proc_SSID_on_close(struct inode *inode, struct file *file)
5083{
5084        struct proc_data *data = file->private_data;
5085        struct net_device *dev = PDE_DATA(inode);
5086        struct airo_info *ai = dev->ml_priv;
5087        SsidRid SSID_rid;
5088        int i;
5089        char *p = data->wbuffer;
5090        char *end = p + data->writelen;
5091
5092        if (!data->writelen)
5093                return;
5094
5095        *end = '\n'; /* sentinel; we have space for it */
5096
5097        memset(&SSID_rid, 0, sizeof(SSID_rid));
5098
5099        for (i = 0; i < 3 && p < end; i++) {
5100                int j = 0;
5101                /* copy up to 32 characters from this line */
5102                while (*p != '\n' && j < 32)
5103                        SSID_rid.ssids[i].ssid[j++] = *p++;
5104                if (j == 0)
5105                        break;
5106                SSID_rid.ssids[i].len = cpu_to_le16(j);
5107                /* skip to the beginning of the next line */
5108                while (*p++ != '\n')
5109                        ;
5110        }
5111        if (i)
5112                SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5113        disable_MAC(ai, 1);
5114        writeSsidRid(ai, &SSID_rid, 1);
5115        enable_MAC(ai, 1);
5116}
5117
5118static void proc_APList_on_close( struct inode *inode, struct file *file ) {
5119        struct proc_data *data = file->private_data;
5120        struct net_device *dev = PDE_DATA(inode);
5121        struct airo_info *ai = dev->ml_priv;
5122        APListRid *APList_rid = &ai->APList;
5123        int i;
5124
5125        if ( !data->writelen ) return;
5126
5127        memset(APList_rid, 0, sizeof(*APList_rid));
5128        APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5129
5130        for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
5131                mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
5132
5133        disable_MAC(ai, 1);
5134        writeAPListRid(ai, APList_rid, 1);
5135        enable_MAC(ai, 1);
5136}
5137
5138/* This function wraps PC4500_writerid with a MAC disable */
5139static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5140                        int len, int dummy ) {
5141        int rc;
5142
5143        disable_MAC(ai, 1);
5144        rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5145        enable_MAC(ai, 1);
5146        return rc;
5147}
5148
5149/* Returns the WEP key at the specified index, or -1 if that key does
5150 * not exist.  The buffer is assumed to be at least 16 bytes in length.
5151 */
5152static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
5153{
5154        WepKeyRid wkr;
5155        int rc;
5156        __le16 lastindex;
5157
5158        rc = readWepKeyRid(ai, &wkr, 1, 1);
5159        if (rc != SUCCESS)
5160                return -1;
5161        do {
5162                lastindex = wkr.kindex;
5163                if (le16_to_cpu(wkr.kindex) == index) {
5164                        int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
5165                        memcpy(buf, wkr.key, klen);
5166                        return klen;
5167                }
5168                rc = readWepKeyRid(ai, &wkr, 0, 1);
5169                if (rc != SUCCESS)
5170                        return -1;
5171        } while (lastindex != wkr.kindex);
5172        return -1;
5173}
5174
5175static int get_wep_tx_idx(struct airo_info *ai)
5176{
5177        WepKeyRid wkr;
5178        int rc;
5179        __le16 lastindex;
5180
5181        rc = readWepKeyRid(ai, &wkr, 1, 1);
5182        if (rc != SUCCESS)
5183                return -1;
5184        do {
5185                lastindex = wkr.kindex;
5186                if (wkr.kindex == cpu_to_le16(0xffff))
5187                        return wkr.mac[0];
5188                rc = readWepKeyRid(ai, &wkr, 0, 1);
5189                if (rc != SUCCESS)
5190                        return -1;
5191        } while (lastindex != wkr.kindex);
5192        return -1;
5193}
5194
5195static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5196                       u16 keylen, int perm, int lock)
5197{
5198        static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5199        WepKeyRid wkr;
5200        int rc;
5201
5202        if (WARN_ON(keylen == 0))
5203                return -1;
5204
5205        memset(&wkr, 0, sizeof(wkr));
5206        wkr.len = cpu_to_le16(sizeof(wkr));
5207        wkr.kindex = cpu_to_le16(index);
5208        wkr.klen = cpu_to_le16(keylen);
5209        memcpy(wkr.key, key, keylen);
5210        memcpy(wkr.mac, macaddr, ETH_ALEN);
5211
5212        if (perm) disable_MAC(ai, lock);
5213        rc = writeWepKeyRid(ai, &wkr, perm, lock);
5214        if (perm) enable_MAC(ai, lock);
5215        return rc;
5216}
5217
5218static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
5219{
5220        WepKeyRid wkr;
5221        int rc;
5222
5223        memset(&wkr, 0, sizeof(wkr));
5224        wkr.len = cpu_to_le16(sizeof(wkr));
5225        wkr.kindex = cpu_to_le16(0xffff);
5226        wkr.mac[0] = (char)index;
5227
5228        if (perm) {
5229                ai->defindex = (char)index;
5230                disable_MAC(ai, lock);
5231        }
5232
5233        rc = writeWepKeyRid(ai, &wkr, perm, lock);
5234
5235        if (perm)
5236                enable_MAC(ai, lock);
5237        return rc;
5238}
5239
5240static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5241        struct proc_data *data;
5242        struct net_device *dev = PDE_DATA(inode);
5243        struct airo_info *ai = dev->ml_priv;
5244        int i, rc;
5245        char key[16];
5246        u16 index = 0;
5247        int j = 0;
5248
5249        memset(key, 0, sizeof(key));
5250
5251        data = file->private_data;
5252        if ( !data->writelen ) return;
5253
5254        if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5255            (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5256                index = data->wbuffer[0] - '0';
5257                if (data->wbuffer[1] == '\n') {
5258                        rc = set_wep_tx_idx(ai, index, 1, 1);
5259                        if (rc < 0) {
5260                                airo_print_err(ai->dev->name, "failed to set "
5261                                               "WEP transmit index to %d: %d.",
5262                                               index, rc);
5263                        }
5264                        return;
5265                }
5266                j = 2;
5267        } else {
5268                airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5269                return;
5270        }
5271
5272        for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
5273                switch(i%3) {
5274                case 0:
5275                        key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
5276                        break;
5277                case 1:
5278                        key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
5279                        break;
5280                }
5281        }
5282
5283        rc = set_wep_key(ai, index, key, i/3, 1, 1);
5284        if (rc < 0) {
5285                airo_print_err(ai->dev->name, "failed to set WEP key at index "
5286                               "%d: %d.", index, rc);
5287        }
5288}
5289
5290static int proc_wepkey_open( struct inode *inode, struct file *file )
5291{
5292        struct proc_data *data;
5293        struct net_device *dev = PDE_DATA(inode);
5294        struct airo_info *ai = dev->ml_priv;
5295        char *ptr;
5296        WepKeyRid wkr;
5297        __le16 lastindex;
5298        int j=0;
5299        int rc;
5300
5301        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5302                return -ENOMEM;
5303        memset(&wkr, 0, sizeof(wkr));
5304        data = file->private_data;
5305        if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5306                kfree (file->private_data);
5307                return -ENOMEM;
5308        }
5309        data->writelen = 0;
5310        data->maxwritelen = 80;
5311        if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5312                kfree (data->rbuffer);
5313                kfree (file->private_data);
5314                return -ENOMEM;
5315        }
5316        data->on_close = proc_wepkey_on_close;
5317
5318        ptr = data->rbuffer;
5319        strcpy(ptr, "No wep keys\n");
5320        rc = readWepKeyRid(ai, &wkr, 1, 1);
5321        if (rc == SUCCESS) do {
5322                lastindex = wkr.kindex;
5323                if (wkr.kindex == cpu_to_le16(0xffff)) {
5324                        j += sprintf(ptr+j, "Tx key = %d\n",
5325                                     (int)wkr.mac[0]);
5326                } else {
5327                        j += sprintf(ptr+j, "Key %d set with length = %d\n",
5328                                     le16_to_cpu(wkr.kindex),
5329                                     le16_to_cpu(wkr.klen));
5330                }
5331                readWepKeyRid(ai, &wkr, 0, 1);
5332        } while((lastindex != wkr.kindex) && (j < 180-30));
5333
5334        data->readlen = strlen( data->rbuffer );
5335        return 0;
5336}
5337
5338static int proc_SSID_open(struct inode *inode, struct file *file)
5339{
5340        struct proc_data *data;
5341        struct net_device *dev = PDE_DATA(inode);
5342        struct airo_info *ai = dev->ml_priv;
5343        int i;
5344        char *ptr;
5345        SsidRid SSID_rid;
5346
5347        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5348                return -ENOMEM;
5349        data = file->private_data;
5350        if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5351                kfree (file->private_data);
5352                return -ENOMEM;
5353        }
5354        data->writelen = 0;
5355        data->maxwritelen = 33*3;
5356        /* allocate maxwritelen + 1; we'll want a sentinel */
5357        if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5358                kfree (data->rbuffer);
5359                kfree (file->private_data);
5360                return -ENOMEM;
5361        }
5362        data->on_close = proc_SSID_on_close;
5363
5364        readSsidRid(ai, &SSID_rid);
5365        ptr = data->rbuffer;
5366        for (i = 0; i < 3; i++) {
5367                int j;
5368                size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5369                if (!len)
5370                        break;
5371                if (len > 32)
5372                        len = 32;
5373                for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5374                        *ptr++ = SSID_rid.ssids[i].ssid[j];
5375                *ptr++ = '\n';
5376        }
5377        *ptr = '\0';
5378        data->readlen = strlen( data->rbuffer );
5379        return 0;
5380}
5381
5382static int proc_APList_open( struct inode *inode, struct file *file ) {
5383        struct proc_data *data;
5384        struct net_device *dev = PDE_DATA(inode);
5385        struct airo_info *ai = dev->ml_priv;
5386        int i;
5387        char *ptr;
5388        APListRid *APList_rid = &ai->APList;
5389
5390        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5391                return -ENOMEM;
5392        data = file->private_data;
5393        if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5394                kfree (file->private_data);
5395                return -ENOMEM;
5396        }
5397        data->writelen = 0;
5398        data->maxwritelen = 4*6*3;
5399        if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5400                kfree (data->rbuffer);
5401                kfree (file->private_data);
5402                return -ENOMEM;
5403        }
5404        data->on_close = proc_APList_on_close;
5405
5406        ptr = data->rbuffer;
5407        for( i = 0; i < 4; i++ ) {
5408// We end when we find a zero MAC
5409                if ( !*(int*)APList_rid->ap[i] &&
5410                     !*(int*)&APList_rid->ap[i][2]) break;
5411                ptr += sprintf(ptr, "%pM\n", APList_rid->ap[i]);
5412        }
5413        if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5414
5415        *ptr = '\0';
5416        data->readlen = strlen( data->rbuffer );
5417        return 0;
5418}
5419
5420static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5421        struct proc_data *data;
5422        struct net_device *dev = PDE_DATA(inode);
5423        struct airo_info *ai = dev->ml_priv;
5424        char *ptr;
5425        BSSListRid BSSList_rid;
5426        int rc;
5427        /* If doLoseSync is not 1, we won't do a Lose Sync */
5428        int doLoseSync = -1;
5429
5430        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5431                return -ENOMEM;
5432        data = file->private_data;
5433        if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5434                kfree (file->private_data);
5435                return -ENOMEM;
5436        }
5437        data->writelen = 0;
5438        data->maxwritelen = 0;
5439        data->wbuffer = NULL;
5440        data->on_close = NULL;
5441
5442        if (file->f_mode & FMODE_WRITE) {
5443                if (!(file->f_mode & FMODE_READ)) {
5444                        Cmd cmd;
5445                        Resp rsp;
5446
5447                        if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
5448                        memset(&cmd, 0, sizeof(cmd));
5449                        cmd.cmd=CMD_LISTBSS;
5450                        if (down_interruptible(&ai->sem))
5451                                return -ERESTARTSYS;
5452                        issuecommand(ai, &cmd, &rsp);
5453                        up(&ai->sem);
5454                        data->readlen = 0;
5455                        return 0;
5456                }
5457                doLoseSync = 1;
5458        }
5459        ptr = data->rbuffer;
5460        /* There is a race condition here if there are concurrent opens.
5461           Since it is a rare condition, we'll just live with it, otherwise
5462           we have to add a spin lock... */
5463        rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5464        while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
5465                ptr += sprintf(ptr, "%pM %.*s rssi = %d",
5466                               BSSList_rid.bssid,
5467                                (int)BSSList_rid.ssidLen,
5468                                BSSList_rid.ssid,
5469                                le16_to_cpu(BSSList_rid.dBm));
5470                ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5471                                le16_to_cpu(BSSList_rid.dsChannel),
5472                                BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5473                                BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5474                                BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5475                                BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5476                rc = readBSSListRid(ai, 0, &BSSList_rid);
5477        }
5478        *ptr = '\0';
5479        data->readlen = strlen( data->rbuffer );
5480        return 0;
5481}
5482
5483static int proc_close( struct inode *inode, struct file *file )
5484{
5485        struct proc_data *data = file->private_data;
5486
5487        if (data->on_close != NULL)
5488                data->on_close(inode, file);
5489        kfree(data->rbuffer);
5490        kfree(data->wbuffer);
5491        kfree(data);
5492        return 0;
5493}
5494
5495/* Since the card doesn't automatically switch to the right WEP mode,
5496   we will make it do it.  If the card isn't associated, every secs we
5497   will switch WEP modes to see if that will help.  If the card is
5498   associated we will check every minute to see if anything has
5499   changed. */
5500static void timer_func( struct net_device *dev ) {
5501        struct airo_info *apriv = dev->ml_priv;
5502
5503/* We don't have a link so try changing the authtype */
5504        readConfigRid(apriv, 0);
5505        disable_MAC(apriv, 0);
5506        switch(apriv->config.authType) {
5507                case AUTH_ENCRYPT:
5508/* So drop to OPEN */
5509                        apriv->config.authType = AUTH_OPEN;
5510                        break;
5511                case AUTH_SHAREDKEY:
5512                        if (apriv->keyindex < auto_wep) {
5513                                set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5514                                apriv->config.authType = AUTH_SHAREDKEY;
5515                                apriv->keyindex++;
5516                        } else {
5517                                /* Drop to ENCRYPT */
5518                                apriv->keyindex = 0;
5519                                set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5520                                apriv->config.authType = AUTH_ENCRYPT;
5521                        }
5522                        break;
5523                default:  /* We'll escalate to SHAREDKEY */
5524                        apriv->config.authType = AUTH_SHAREDKEY;
5525        }
5526        set_bit (FLAG_COMMIT, &apriv->flags);
5527        writeConfigRid(apriv, 0);
5528        enable_MAC(apriv, 0);
5529        up(&apriv->sem);
5530
5531/* Schedule check to see if the change worked */
5532        clear_bit(JOB_AUTOWEP, &apriv->jobs);
5533        apriv->expires = RUN_AT(HZ*3);
5534}
5535
5536#ifdef CONFIG_PCI
5537static int airo_pci_probe(struct pci_dev *pdev,
5538                                    const struct pci_device_id *pent)
5539{
5540        struct net_device *dev;
5541
5542        if (pci_enable_device(pdev))
5543                return -ENODEV;
5544        pci_set_master(pdev);
5545
5546        if (pdev->device == 0x5000 || pdev->device == 0xa504)
5547                        dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5548        else
5549                        dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5550        if (!dev) {
5551                pci_disable_device(pdev);
5552                return -ENODEV;
5553        }
5554
5555        pci_set_drvdata(pdev, dev);
5556        return 0;
5557}
5558
5559static void airo_pci_remove(struct pci_dev *pdev)
5560{
5561        struct net_device *dev = pci_get_drvdata(pdev);
5562
5563        airo_print_info(dev->name, "Unregistering...");
5564        stop_airo_card(dev, 1);
5565        pci_disable_device(pdev);
5566}
5567
5568static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
5569{
5570        struct net_device *dev = pci_get_drvdata(pdev);
5571        struct airo_info *ai = dev->ml_priv;
5572        Cmd cmd;
5573        Resp rsp;
5574
5575        if (!ai->SSID)
5576                ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
5577        if (!ai->SSID)
5578                return -ENOMEM;
5579        readSsidRid(ai, ai->SSID);
5580        memset(&cmd, 0, sizeof(cmd));
5581        /* the lock will be released at the end of the resume callback */
5582        if (down_interruptible(&ai->sem))
5583                return -EAGAIN;
5584        disable_MAC(ai, 0);
5585        netif_device_detach(dev);
5586        ai->power = state;
5587        cmd.cmd = HOSTSLEEP;
5588        issuecommand(ai, &cmd, &rsp);
5589
5590        pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
5591        pci_save_state(pdev);
5592        pci_set_power_state(pdev, pci_choose_state(pdev, state));
5593        return 0;
5594}
5595
5596static int airo_pci_resume(struct pci_dev *pdev)
5597{
5598        struct net_device *dev = pci_get_drvdata(pdev);
5599        struct airo_info *ai = dev->ml_priv;
5600        pci_power_t prev_state = pdev->current_state;
5601
5602        pci_set_power_state(pdev, PCI_D0);
5603        pci_restore_state(pdev);
5604        pci_enable_wake(pdev, PCI_D0, 0);
5605
5606        if (prev_state != PCI_D1) {
5607                reset_card(dev, 0);
5608                mpi_init_descriptors(ai);
5609                setup_card(ai, dev->dev_addr, 0);
5610                clear_bit(FLAG_RADIO_OFF, &ai->flags);
5611                clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5612        } else {
5613                OUT4500(ai, EVACK, EV_AWAKEN);
5614                OUT4500(ai, EVACK, EV_AWAKEN);
5615                msleep(100);
5616        }
5617
5618        set_bit(FLAG_COMMIT, &ai->flags);
5619        disable_MAC(ai, 0);
5620        msleep(200);
5621        if (ai->SSID) {
5622                writeSsidRid(ai, ai->SSID, 0);
5623                kfree(ai->SSID);
5624                ai->SSID = NULL;
5625        }
5626        writeAPListRid(ai, &ai->APList, 0);
5627        writeConfigRid(ai, 0);
5628        enable_MAC(ai, 0);
5629        ai->power = PMSG_ON;
5630        netif_device_attach(dev);
5631        netif_wake_queue(dev);
5632        enable_interrupts(ai);
5633        up(&ai->sem);
5634        return 0;
5635}
5636#endif
5637
5638static int __init airo_init_module( void )
5639{
5640        int i;
5641
5642        proc_kuid = make_kuid(&init_user_ns, proc_uid);
5643        proc_kgid = make_kgid(&init_user_ns, proc_gid);
5644        if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
5645                return -EINVAL;
5646
5647        airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
5648
5649        if (airo_entry)
5650                proc_set_user(airo_entry, proc_kuid, proc_kgid);
5651
5652        for (i = 0; i < 4 && io[i] && irq[i]; i++) {
5653                airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5654                        "io=0x%x", irq[i], io[i] );
5655                if (init_airo_card( irq[i], io[i], 0, NULL ))
5656                        /* do nothing */ ;
5657        }
5658
5659#ifdef CONFIG_PCI
5660        airo_print_info("", "Probing for PCI adapters");
5661        i = pci_register_driver(&airo_driver);
5662        airo_print_info("", "Finished probing for PCI adapters");
5663
5664        if (i) {
5665                remove_proc_entry("driver/aironet", NULL);
5666                return i;
5667        }
5668#endif
5669
5670        /* Always exit with success, as we are a library module
5671         * as well as a driver module
5672         */
5673        return 0;
5674}
5675
5676static void __exit airo_cleanup_module( void )
5677{
5678        struct airo_info *ai;
5679        while(!list_empty(&airo_devices)) {
5680                ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5681                airo_print_info(ai->dev->name, "Unregistering...");
5682                stop_airo_card(ai->dev, 1);
5683        }
5684#ifdef CONFIG_PCI
5685        pci_unregister_driver(&airo_driver);
5686#endif
5687        remove_proc_entry("driver/aironet", NULL);
5688}
5689
5690/*
5691 * Initial Wireless Extension code for Aironet driver by :
5692 *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5693 * Conversion to new driver API by :
5694 *      Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5695 * Javier also did a good amount of work here, adding some new extensions
5696 * and fixing my code. Let's just say that without him this code just
5697 * would not work at all... - Jean II
5698 */
5699
5700static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5701{
5702        if (!rssi_rid)
5703                return 0;
5704
5705        return (0x100 - rssi_rid[rssi].rssidBm);
5706}
5707
5708static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5709{
5710        int i;
5711
5712        if (!rssi_rid)
5713                return 0;
5714
5715        for (i = 0; i < 256; i++)
5716                if (rssi_rid[i].rssidBm == dbm)
5717                        return rssi_rid[i].rssipct;
5718
5719        return 0;
5720}
5721
5722
5723static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5724{
5725        int quality = 0;
5726        u16 sq;
5727
5728        if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5729                return 0;
5730
5731        if (!(cap_rid->hardCap & cpu_to_le16(8)))
5732                return 0;
5733
5734        sq = le16_to_cpu(status_rid->signalQuality);
5735        if (memcmp(cap_rid->prodName, "350", 3))
5736                if (sq > 0x20)
5737                        quality = 0;
5738                else
5739                        quality = 0x20 - sq;
5740        else
5741                if (sq > 0xb0)
5742                        quality = 0;
5743                else if (sq < 0x10)
5744                        quality = 0xa0;
5745                else
5746                        quality = 0xb0 - sq;
5747        return quality;
5748}
5749
5750#define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5751#define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
5752
5753/*------------------------------------------------------------------*/
5754/*
5755 * Wireless Handler : get protocol name
5756 */
5757static int airo_get_name(struct net_device *dev,
5758                         struct iw_request_info *info,
5759                         char *cwrq,
5760                         char *extra)
5761{
5762        strcpy(cwrq, "IEEE 802.11-DS");
5763        return 0;
5764}
5765
5766/*------------------------------------------------------------------*/
5767/*
5768 * Wireless Handler : set frequency
5769 */
5770static int airo_set_freq(struct net_device *dev,
5771                         struct iw_request_info *info,
5772                         struct iw_freq *fwrq,
5773                         char *extra)
5774{
5775        struct airo_info *local = dev->ml_priv;
5776        int rc = -EINPROGRESS;          /* Call commit handler */
5777
5778        /* If setting by frequency, convert to a channel */
5779        if(fwrq->e == 1) {
5780                int f = fwrq->m / 100000;
5781
5782                /* Hack to fall through... */
5783                fwrq->e = 0;
5784                fwrq->m = ieee80211_frequency_to_channel(f);
5785        }
5786        /* Setting by channel number */
5787        if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
5788                rc = -EOPNOTSUPP;
5789        else {
5790                int channel = fwrq->m;
5791                /* We should do a better check than that,
5792                 * based on the card capability !!! */
5793                if((channel < 1) || (channel > 14)) {
5794                        airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5795                                fwrq->m);
5796                        rc = -EINVAL;
5797                } else {
5798                        readConfigRid(local, 1);
5799                        /* Yes ! We can set it !!! */
5800                        local->config.channelSet = cpu_to_le16(channel);
5801                        set_bit (FLAG_COMMIT, &local->flags);
5802                }
5803        }
5804        return rc;
5805}
5806
5807/*------------------------------------------------------------------*/
5808/*
5809 * Wireless Handler : get frequency
5810 */
5811static int airo_get_freq(struct net_device *dev,
5812                         struct iw_request_info *info,
5813                         struct iw_freq *fwrq,
5814                         char *extra)
5815{
5816        struct airo_info *local = dev->ml_priv;
5817        StatusRid status_rid;           /* Card status info */
5818        int ch;
5819
5820        readConfigRid(local, 1);
5821        if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
5822                status_rid.channel = local->config.channelSet;
5823        else
5824                readStatusRid(local, &status_rid, 1);
5825
5826        ch = le16_to_cpu(status_rid.channel);
5827        if((ch > 0) && (ch < 15)) {
5828                fwrq->m = 100000 *
5829                        ieee80211_channel_to_frequency(ch, NL80211_BAND_2GHZ);
5830                fwrq->e = 1;
5831        } else {
5832                fwrq->m = ch;
5833                fwrq->e = 0;
5834        }
5835
5836        return 0;
5837}
5838
5839/*------------------------------------------------------------------*/
5840/*
5841 * Wireless Handler : set ESSID
5842 */
5843static int airo_set_essid(struct net_device *dev,
5844                          struct iw_request_info *info,
5845                          struct iw_point *dwrq,
5846                          char *extra)
5847{
5848        struct airo_info *local = dev->ml_priv;
5849        SsidRid SSID_rid;               /* SSIDs */
5850
5851        /* Reload the list of current SSID */
5852        readSsidRid(local, &SSID_rid);
5853
5854        /* Check if we asked for `any' */
5855        if (dwrq->flags == 0) {
5856                /* Just send an empty SSID list */
5857                memset(&SSID_rid, 0, sizeof(SSID_rid));
5858        } else {
5859                unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5860
5861                /* Check the size of the string */
5862                if (dwrq->length > IW_ESSID_MAX_SIZE)
5863                        return -E2BIG ;
5864
5865                /* Check if index is valid */
5866                if (index >= ARRAY_SIZE(SSID_rid.ssids))
5867                        return -EINVAL;
5868
5869                /* Set the SSID */
5870                memset(SSID_rid.ssids[index].ssid, 0,
5871                       sizeof(SSID_rid.ssids[index].ssid));
5872                memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5873                SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5874        }
5875        SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5876        /* Write it to the card */
5877        disable_MAC(local, 1);
5878        writeSsidRid(local, &SSID_rid, 1);
5879        enable_MAC(local, 1);
5880
5881        return 0;
5882}
5883
5884/*------------------------------------------------------------------*/
5885/*
5886 * Wireless Handler : get ESSID
5887 */
5888static int airo_get_essid(struct net_device *dev,
5889                          struct iw_request_info *info,
5890                          struct iw_point *dwrq,
5891                          char *extra)
5892{
5893        struct airo_info *local = dev->ml_priv;
5894        StatusRid status_rid;           /* Card status info */
5895
5896        readStatusRid(local, &status_rid, 1);
5897
5898        /* Note : if dwrq->flags != 0, we should
5899         * get the relevant SSID from the SSID list... */
5900
5901        /* Get the current SSID */
5902        memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5903        /* If none, we may want to get the one that was set */
5904
5905        /* Push it out ! */
5906        dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5907        dwrq->flags = 1; /* active */
5908
5909        return 0;
5910}
5911
5912/*------------------------------------------------------------------*/
5913/*
5914 * Wireless Handler : set AP address
5915 */
5916static int airo_set_wap(struct net_device *dev,
5917                        struct iw_request_info *info,
5918                        struct sockaddr *awrq,
5919                        char *extra)
5920{
5921        struct airo_info *local = dev->ml_priv;
5922        Cmd cmd;
5923        Resp rsp;
5924        APListRid *APList_rid = &local->APList;
5925
5926        if (awrq->sa_family != ARPHRD_ETHER)
5927                return -EINVAL;
5928        else if (is_broadcast_ether_addr(awrq->sa_data) ||
5929                 is_zero_ether_addr(awrq->sa_data)) {
5930                memset(&cmd, 0, sizeof(cmd));
5931                cmd.cmd=CMD_LOSE_SYNC;
5932                if (down_interruptible(&local->sem))
5933                        return -ERESTARTSYS;
5934                issuecommand(local, &cmd, &rsp);
5935                up(&local->sem);
5936        } else {
5937                memset(APList_rid, 0, sizeof(*APList_rid));
5938                APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5939                memcpy(APList_rid->ap[0], awrq->sa_data, ETH_ALEN);
5940                disable_MAC(local, 1);
5941                writeAPListRid(local, APList_rid, 1);
5942                enable_MAC(local, 1);
5943        }
5944        return 0;
5945}
5946
5947/*------------------------------------------------------------------*/
5948/*
5949 * Wireless Handler : get AP address
5950 */
5951static int airo_get_wap(struct net_device *dev,
5952                        struct iw_request_info *info,
5953                        struct sockaddr *awrq,
5954                        char *extra)
5955{
5956        struct airo_info *local = dev->ml_priv;
5957        StatusRid status_rid;           /* Card status info */
5958
5959        readStatusRid(local, &status_rid, 1);
5960
5961        /* Tentative. This seems to work, wow, I'm lucky !!! */
5962        memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
5963        awrq->sa_family = ARPHRD_ETHER;
5964
5965        return 0;
5966}
5967
5968/*------------------------------------------------------------------*/
5969/*
5970 * Wireless Handler : set Nickname
5971 */
5972static int airo_set_nick(struct net_device *dev,
5973                         struct iw_request_info *info,
5974                         struct iw_point *dwrq,
5975                         char *extra)
5976{
5977        struct airo_info *local = dev->ml_priv;
5978
5979        /* Check the size of the string */
5980        if(dwrq->length > 16) {
5981                return -E2BIG;
5982        }
5983        readConfigRid(local, 1);
5984        memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
5985        memcpy(local->config.nodeName, extra, dwrq->length);
5986        set_bit (FLAG_COMMIT, &local->flags);
5987
5988        return -EINPROGRESS;            /* Call commit handler */
5989}
5990
5991/*------------------------------------------------------------------*/
5992/*
5993 * Wireless Handler : get Nickname
5994 */
5995static int airo_get_nick(struct net_device *dev,
5996                         struct iw_request_info *info,
5997                         struct iw_point *dwrq,
5998                         char *extra)
5999{
6000        struct airo_info *local = dev->ml_priv;
6001
6002        readConfigRid(local, 1);
6003        strncpy(extra, local->config.nodeName, 16);
6004        extra[16] = '\0';
6005        dwrq->length = strlen(extra);
6006
6007        return 0;
6008}
6009
6010/*------------------------------------------------------------------*/
6011/*
6012 * Wireless Handler : set Bit-Rate
6013 */
6014static int airo_set_rate(struct net_device *dev,
6015                         struct iw_request_info *info,
6016                         struct iw_param *vwrq,
6017                         char *extra)
6018{
6019        struct airo_info *local = dev->ml_priv;
6020        CapabilityRid cap_rid;          /* Card capability info */
6021        u8      brate = 0;
6022        int     i;
6023
6024        /* First : get a valid bit rate value */
6025        readCapabilityRid(local, &cap_rid, 1);
6026
6027        /* Which type of value ? */
6028        if((vwrq->value < 8) && (vwrq->value >= 0)) {
6029                /* Setting by rate index */
6030                /* Find value in the magic rate table */
6031                brate = cap_rid.supportedRates[vwrq->value];
6032        } else {
6033                /* Setting by frequency value */
6034                u8      normvalue = (u8) (vwrq->value/500000);
6035
6036                /* Check if rate is valid */
6037                for(i = 0 ; i < 8 ; i++) {
6038                        if(normvalue == cap_rid.supportedRates[i]) {
6039                                brate = normvalue;
6040                                break;
6041                        }
6042                }
6043        }
6044        /* -1 designed the max rate (mostly auto mode) */
6045        if(vwrq->value == -1) {
6046                /* Get the highest available rate */
6047                for(i = 0 ; i < 8 ; i++) {
6048                        if(cap_rid.supportedRates[i] == 0)
6049                                break;
6050                }
6051                if(i != 0)
6052                        brate = cap_rid.supportedRates[i - 1];
6053        }
6054        /* Check that it is valid */
6055        if(brate == 0) {
6056                return -EINVAL;
6057        }
6058
6059        readConfigRid(local, 1);
6060        /* Now, check if we want a fixed or auto value */
6061        if(vwrq->fixed == 0) {
6062                /* Fill all the rates up to this max rate */
6063                memset(local->config.rates, 0, 8);
6064                for(i = 0 ; i < 8 ; i++) {
6065                        local->config.rates[i] = cap_rid.supportedRates[i];
6066                        if(local->config.rates[i] == brate)
6067                                break;
6068                }
6069        } else {
6070                /* Fixed mode */
6071                /* One rate, fixed */
6072                memset(local->config.rates, 0, 8);
6073                local->config.rates[0] = brate;
6074        }
6075        set_bit (FLAG_COMMIT, &local->flags);
6076
6077        return -EINPROGRESS;            /* Call commit handler */
6078}
6079
6080/*------------------------------------------------------------------*/
6081/*
6082 * Wireless Handler : get Bit-Rate
6083 */
6084static int airo_get_rate(struct net_device *dev,
6085                         struct iw_request_info *info,
6086                         struct iw_param *vwrq,
6087                         char *extra)
6088{
6089        struct airo_info *local = dev->ml_priv;
6090        StatusRid status_rid;           /* Card status info */
6091
6092        readStatusRid(local, &status_rid, 1);
6093
6094        vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6095        /* If more than one rate, set auto */
6096        readConfigRid(local, 1);
6097        vwrq->fixed = (local->config.rates[1] == 0);
6098
6099        return 0;
6100}
6101
6102/*------------------------------------------------------------------*/
6103/*
6104 * Wireless Handler : set RTS threshold
6105 */
6106static int airo_set_rts(struct net_device *dev,
6107                        struct iw_request_info *info,
6108                        struct iw_param *vwrq,
6109                        char *extra)
6110{
6111        struct airo_info *local = dev->ml_priv;
6112        int rthr = vwrq->value;
6113
6114        if(vwrq->disabled)
6115                rthr = AIRO_DEF_MTU;
6116        if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
6117                return -EINVAL;
6118        }
6119        readConfigRid(local, 1);
6120        local->config.rtsThres = cpu_to_le16(rthr);
6121        set_bit (FLAG_COMMIT, &local->flags);
6122
6123        return -EINPROGRESS;            /* Call commit handler */
6124}
6125
6126/*------------------------------------------------------------------*/
6127/*
6128 * Wireless Handler : get RTS threshold
6129 */
6130static int airo_get_rts(struct net_device *dev,
6131                        struct iw_request_info *info,
6132                        struct iw_param *vwrq,
6133                        char *extra)
6134{
6135        struct airo_info *local = dev->ml_priv;
6136
6137        readConfigRid(local, 1);
6138        vwrq->value = le16_to_cpu(local->config.rtsThres);
6139        vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6140        vwrq->fixed = 1;
6141
6142        return 0;
6143}
6144
6145/*------------------------------------------------------------------*/
6146/*
6147 * Wireless Handler : set Fragmentation threshold
6148 */
6149static int airo_set_frag(struct net_device *dev,
6150                         struct iw_request_info *info,
6151                         struct iw_param *vwrq,
6152                         char *extra)
6153{
6154        struct airo_info *local = dev->ml_priv;
6155        int fthr = vwrq->value;
6156
6157        if(vwrq->disabled)
6158                fthr = AIRO_DEF_MTU;
6159        if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
6160                return -EINVAL;
6161        }
6162        fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
6163        readConfigRid(local, 1);
6164        local->config.fragThresh = cpu_to_le16(fthr);
6165        set_bit (FLAG_COMMIT, &local->flags);
6166
6167        return -EINPROGRESS;            /* Call commit handler */
6168}
6169
6170/*------------------------------------------------------------------*/
6171/*
6172 * Wireless Handler : get Fragmentation threshold
6173 */
6174static int airo_get_frag(struct net_device *dev,
6175                         struct iw_request_info *info,
6176                         struct iw_param *vwrq,
6177                         char *extra)
6178{
6179        struct airo_info *local = dev->ml_priv;
6180
6181        readConfigRid(local, 1);
6182        vwrq->value = le16_to_cpu(local->config.fragThresh);
6183        vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6184        vwrq->fixed = 1;
6185
6186        return 0;
6187}
6188
6189/*------------------------------------------------------------------*/
6190/*
6191 * Wireless Handler : set Mode of Operation
6192 */
6193static int airo_set_mode(struct net_device *dev,
6194                         struct iw_request_info *info,
6195                         __u32 *uwrq,
6196                         char *extra)
6197{
6198        struct airo_info *local = dev->ml_priv;
6199        int reset = 0;
6200
6201        readConfigRid(local, 1);
6202        if (sniffing_mode(local))
6203                reset = 1;
6204
6205        switch(*uwrq) {
6206                case IW_MODE_ADHOC:
6207                        local->config.opmode &= ~MODE_CFG_MASK;
6208                        local->config.opmode |= MODE_STA_IBSS;
6209                        local->config.rmode &= ~RXMODE_FULL_MASK;
6210                        local->config.scanMode = SCANMODE_ACTIVE;
6211                        clear_bit (FLAG_802_11, &local->flags);
6212                        break;
6213                case IW_MODE_INFRA:
6214                        local->config.opmode &= ~MODE_CFG_MASK;
6215                        local->config.opmode |= MODE_STA_ESS;
6216                        local->config.rmode &= ~RXMODE_FULL_MASK;
6217                        local->config.scanMode = SCANMODE_ACTIVE;
6218                        clear_bit (FLAG_802_11, &local->flags);
6219                        break;
6220                case IW_MODE_MASTER:
6221                        local->config.opmode &= ~MODE_CFG_MASK;
6222                        local->config.opmode |= MODE_AP;
6223                        local->config.rmode &= ~RXMODE_FULL_MASK;
6224                        local->config.scanMode = SCANMODE_ACTIVE;
6225                        clear_bit (FLAG_802_11, &local->flags);
6226                        break;
6227                case IW_MODE_REPEAT:
6228                        local->config.opmode &= ~MODE_CFG_MASK;
6229                        local->config.opmode |= MODE_AP_RPTR;
6230                        local->config.rmode &= ~RXMODE_FULL_MASK;
6231                        local->config.scanMode = SCANMODE_ACTIVE;
6232                        clear_bit (FLAG_802_11, &local->flags);
6233                        break;
6234                case IW_MODE_MONITOR:
6235                        local->config.opmode &= ~MODE_CFG_MASK;
6236                        local->config.opmode |= MODE_STA_ESS;
6237                        local->config.rmode &= ~RXMODE_FULL_MASK;
6238                        local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6239                        local->config.scanMode = SCANMODE_PASSIVE;
6240                        set_bit (FLAG_802_11, &local->flags);
6241                        break;
6242                default:
6243                        return -EINVAL;
6244        }
6245        if (reset)
6246                set_bit (FLAG_RESET, &local->flags);
6247        set_bit (FLAG_COMMIT, &local->flags);
6248
6249        return -EINPROGRESS;            /* Call commit handler */
6250}
6251
6252/*------------------------------------------------------------------*/
6253/*
6254 * Wireless Handler : get Mode of Operation
6255 */
6256static int airo_get_mode(struct net_device *dev,
6257                         struct iw_request_info *info,
6258                         __u32 *uwrq,
6259                         char *extra)
6260{
6261        struct airo_info *local = dev->ml_priv;
6262
6263        readConfigRid(local, 1);
6264        /* If not managed, assume it's ad-hoc */
6265        switch (local->config.opmode & MODE_CFG_MASK) {
6266                case MODE_STA_ESS:
6267                        *uwrq = IW_MODE_INFRA;
6268                        break;
6269                case MODE_AP:
6270                        *uwrq = IW_MODE_MASTER;
6271                        break;
6272                case MODE_AP_RPTR:
6273                        *uwrq = IW_MODE_REPEAT;
6274                        break;
6275                default:
6276                        *uwrq = IW_MODE_ADHOC;
6277        }
6278
6279        return 0;
6280}
6281
6282static inline int valid_index(struct airo_info *ai, int index)
6283{
6284        return (index >= 0) && (index <= ai->max_wep_idx);
6285}
6286
6287/*------------------------------------------------------------------*/
6288/*
6289 * Wireless Handler : set Encryption Key
6290 */
6291static int airo_set_encode(struct net_device *dev,
6292                           struct iw_request_info *info,
6293                           struct iw_point *dwrq,
6294                           char *extra)
6295{
6296        struct airo_info *local = dev->ml_priv;
6297        int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
6298        __le16 currentAuthType = local->config.authType;
6299        int rc = 0;
6300
6301        if (!local->wep_capable)
6302                return -EOPNOTSUPP;
6303
6304        readConfigRid(local, 1);
6305
6306        /* Basic checking: do we have a key to set ?
6307         * Note : with the new API, it's impossible to get a NULL pointer.
6308         * Therefore, we need to check a key size == 0 instead.
6309         * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6310         * when no key is present (only change flags), but older versions
6311         * don't do it. - Jean II */
6312        if (dwrq->length > 0) {
6313                wep_key_t key;
6314                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6315                int current_index;
6316
6317                /* Check the size of the key */
6318                if (dwrq->length > MAX_KEY_SIZE) {
6319                        return -EINVAL;
6320                }
6321
6322                current_index = get_wep_tx_idx(local);
6323                if (current_index < 0)
6324                        current_index = 0;
6325
6326                /* Check the index (none -> use current) */
6327                if (!valid_index(local, index))
6328                        index = current_index;
6329
6330                /* Set the length */
6331                if (dwrq->length > MIN_KEY_SIZE)
6332                        key.len = MAX_KEY_SIZE;
6333                else
6334                        key.len = MIN_KEY_SIZE;
6335                /* Check if the key is not marked as invalid */
6336                if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6337                        /* Cleanup */
6338                        memset(key.key, 0, MAX_KEY_SIZE);
6339                        /* Copy the key in the driver */
6340                        memcpy(key.key, extra, dwrq->length);
6341                        /* Send the key to the card */
6342                        rc = set_wep_key(local, index, key.key, key.len, perm, 1);
6343                        if (rc < 0) {
6344                                airo_print_err(local->dev->name, "failed to set"
6345                                               " WEP key at index %d: %d.",
6346                                               index, rc);
6347                                return rc;
6348                        }
6349                }
6350                /* WE specify that if a valid key is set, encryption
6351                 * should be enabled (user may turn it off later)
6352                 * This is also how "iwconfig ethX key on" works */
6353                if((index == current_index) && (key.len > 0) &&
6354                   (local->config.authType == AUTH_OPEN))
6355                        set_auth_type(local, AUTH_ENCRYPT);
6356        } else {
6357                /* Do we want to just set the transmit key index ? */
6358                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6359                if (valid_index(local, index)) {
6360                        rc = set_wep_tx_idx(local, index, perm, 1);
6361                        if (rc < 0) {
6362                                airo_print_err(local->dev->name, "failed to set"
6363                                               " WEP transmit index to %d: %d.",
6364                                               index, rc);
6365                                return rc;
6366                        }
6367                } else {
6368                        /* Don't complain if only change the mode */
6369                        if (!(dwrq->flags & IW_ENCODE_MODE))
6370                                return -EINVAL;
6371                }
6372        }
6373        /* Read the flags */
6374        if (dwrq->flags & IW_ENCODE_DISABLED)
6375                set_auth_type(local, AUTH_OPEN);        /* disable encryption */
6376        if(dwrq->flags & IW_ENCODE_RESTRICTED)
6377                set_auth_type(local, AUTH_SHAREDKEY);   /* Only Both */
6378        if (dwrq->flags & IW_ENCODE_OPEN)
6379                set_auth_type(local, AUTH_ENCRYPT);     /* Only Wep */
6380        /* Commit the changes to flags if needed */
6381        if (local->config.authType != currentAuthType)
6382                set_bit (FLAG_COMMIT, &local->flags);
6383        return -EINPROGRESS;            /* Call commit handler */
6384}
6385
6386/*------------------------------------------------------------------*/
6387/*
6388 * Wireless Handler : get Encryption Key
6389 */
6390static int airo_get_encode(struct net_device *dev,
6391                           struct iw_request_info *info,
6392                           struct iw_point *dwrq,
6393                           char *extra)
6394{
6395        struct airo_info *local = dev->ml_priv;
6396        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6397        int wep_key_len;
6398        u8 buf[16];
6399
6400        if (!local->wep_capable)
6401                return -EOPNOTSUPP;
6402
6403        readConfigRid(local, 1);
6404
6405        /* Check encryption mode */
6406        switch(local->config.authType)  {
6407                case AUTH_ENCRYPT:
6408                        dwrq->flags = IW_ENCODE_OPEN;
6409                        break;
6410                case AUTH_SHAREDKEY:
6411                        dwrq->flags = IW_ENCODE_RESTRICTED;
6412                        break;
6413                default:
6414                case AUTH_OPEN:
6415                        dwrq->flags = IW_ENCODE_DISABLED;
6416                        break;
6417        }
6418        /* We can't return the key, so set the proper flag and return zero */
6419        dwrq->flags |= IW_ENCODE_NOKEY;
6420        memset(extra, 0, 16);
6421
6422        /* Which key do we want ? -1 -> tx index */
6423        if (!valid_index(local, index)) {
6424                index = get_wep_tx_idx(local);
6425                if (index < 0)
6426                        index = 0;
6427        }
6428        dwrq->flags |= index + 1;
6429
6430        /* Copy the key to the user buffer */
6431        wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
6432        if (wep_key_len < 0) {
6433                dwrq->length = 0;
6434        } else {
6435                dwrq->length = wep_key_len;
6436                memcpy(extra, buf, dwrq->length);
6437        }
6438
6439        return 0;
6440}
6441
6442/*------------------------------------------------------------------*/
6443/*
6444 * Wireless Handler : set extended Encryption parameters
6445 */
6446static int airo_set_encodeext(struct net_device *dev,
6447                           struct iw_request_info *info,
6448                            union iwreq_data *wrqu,
6449                            char *extra)
6450{
6451        struct airo_info *local = dev->ml_priv;
6452        struct iw_point *encoding = &wrqu->encoding;
6453        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6454        int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6455        __le16 currentAuthType = local->config.authType;
6456        int idx, key_len, alg = ext->alg, set_key = 1, rc;
6457        wep_key_t key;
6458
6459        if (!local->wep_capable)
6460                return -EOPNOTSUPP;
6461
6462        readConfigRid(local, 1);
6463
6464        /* Determine and validate the key index */
6465        idx = encoding->flags & IW_ENCODE_INDEX;
6466        if (idx) {
6467                if (!valid_index(local, idx - 1))
6468                        return -EINVAL;
6469                idx--;
6470        } else {
6471                idx = get_wep_tx_idx(local);
6472                if (idx < 0)
6473                        idx = 0;
6474        }
6475
6476        if (encoding->flags & IW_ENCODE_DISABLED)
6477                alg = IW_ENCODE_ALG_NONE;
6478
6479        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
6480                /* Only set transmit key index here, actual
6481                 * key is set below if needed.
6482                 */
6483                rc = set_wep_tx_idx(local, idx, perm, 1);
6484                if (rc < 0) {
6485                        airo_print_err(local->dev->name, "failed to set "
6486                                       "WEP transmit index to %d: %d.",
6487                                       idx, rc);
6488                        return rc;
6489                }
6490                set_key = ext->key_len > 0 ? 1 : 0;
6491        }
6492
6493        if (set_key) {
6494                /* Set the requested key first */
6495                memset(key.key, 0, MAX_KEY_SIZE);
6496                switch (alg) {
6497                case IW_ENCODE_ALG_NONE:
6498                        key.len = 0;
6499                        break;
6500                case IW_ENCODE_ALG_WEP:
6501                        if (ext->key_len > MIN_KEY_SIZE) {
6502                                key.len = MAX_KEY_SIZE;
6503                        } else if (ext->key_len > 0) {
6504                                key.len = MIN_KEY_SIZE;
6505                        } else {
6506                                return -EINVAL;
6507                        }
6508                        key_len = min (ext->key_len, key.len);
6509                        memcpy(key.key, ext->key, key_len);
6510                        break;
6511                default:
6512                        return -EINVAL;
6513                }
6514                if (key.len == 0) {
6515                        rc = set_wep_tx_idx(local, idx, perm, 1);
6516                        if (rc < 0) {
6517                                airo_print_err(local->dev->name,
6518                                               "failed to set WEP transmit index to %d: %d.",
6519                                               idx, rc);
6520                                return rc;
6521                        }
6522                } else {
6523                        rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6524                        if (rc < 0) {
6525                                airo_print_err(local->dev->name,
6526                                               "failed to set WEP key at index %d: %d.",
6527                                               idx, rc);
6528                                return rc;
6529                        }
6530                }
6531        }
6532
6533        /* Read the flags */
6534        if (encoding->flags & IW_ENCODE_DISABLED)
6535                set_auth_type(local, AUTH_OPEN);        /* disable encryption */
6536        if(encoding->flags & IW_ENCODE_RESTRICTED)
6537                set_auth_type(local, AUTH_SHAREDKEY);   /* Only Both */
6538        if (encoding->flags & IW_ENCODE_OPEN)
6539                set_auth_type(local, AUTH_ENCRYPT);
6540        /* Commit the changes to flags if needed */
6541        if (local->config.authType != currentAuthType)
6542                set_bit (FLAG_COMMIT, &local->flags);
6543
6544        return -EINPROGRESS;
6545}
6546
6547
6548/*------------------------------------------------------------------*/
6549/*
6550 * Wireless Handler : get extended Encryption parameters
6551 */
6552static int airo_get_encodeext(struct net_device *dev,
6553                            struct iw_request_info *info,
6554                            union iwreq_data *wrqu,
6555                            char *extra)
6556{
6557        struct airo_info *local = dev->ml_priv;
6558        struct iw_point *encoding = &wrqu->encoding;
6559        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6560        int idx, max_key_len, wep_key_len;
6561        u8 buf[16];
6562
6563        if (!local->wep_capable)
6564                return -EOPNOTSUPP;
6565
6566        readConfigRid(local, 1);
6567
6568        max_key_len = encoding->length - sizeof(*ext);
6569        if (max_key_len < 0)
6570                return -EINVAL;
6571
6572        idx = encoding->flags & IW_ENCODE_INDEX;
6573        if (idx) {
6574                if (!valid_index(local, idx - 1))
6575                        return -EINVAL;
6576                idx--;
6577        } else {
6578                idx = get_wep_tx_idx(local);
6579                if (idx < 0)
6580                        idx = 0;
6581        }
6582
6583        encoding->flags = idx + 1;
6584        memset(ext, 0, sizeof(*ext));
6585
6586        /* Check encryption mode */
6587        switch(local->config.authType) {
6588                case AUTH_ENCRYPT:
6589                        encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6590                        break;
6591                case AUTH_SHAREDKEY:
6592                        encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6593                        break;
6594                default:
6595                case AUTH_OPEN:
6596                        encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
6597                        break;
6598        }
6599        /* We can't return the key, so set the proper flag and return zero */
6600        encoding->flags |= IW_ENCODE_NOKEY;
6601        memset(extra, 0, 16);
6602        
6603        /* Copy the key to the user buffer */
6604        wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
6605        if (wep_key_len < 0) {
6606                ext->key_len = 0;
6607        } else {
6608                ext->key_len = wep_key_len;
6609                memcpy(extra, buf, ext->key_len);
6610        }
6611
6612        return 0;
6613}
6614
6615
6616/*------------------------------------------------------------------*/
6617/*
6618 * Wireless Handler : set extended authentication parameters
6619 */
6620static int airo_set_auth(struct net_device *dev,
6621                               struct iw_request_info *info,
6622                               union iwreq_data *wrqu, char *extra)
6623{
6624        struct airo_info *local = dev->ml_priv;
6625        struct iw_param *param = &wrqu->param;
6626        __le16 currentAuthType = local->config.authType;
6627
6628        switch (param->flags & IW_AUTH_INDEX) {
6629        case IW_AUTH_WPA_VERSION:
6630        case IW_AUTH_CIPHER_PAIRWISE:
6631        case IW_AUTH_CIPHER_GROUP:
6632        case IW_AUTH_KEY_MGMT:
6633        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6634        case IW_AUTH_PRIVACY_INVOKED:
6635                /*
6636                 * airo does not use these parameters
6637                 */
6638                break;
6639
6640        case IW_AUTH_DROP_UNENCRYPTED:
6641                if (param->value) {
6642                        /* Only change auth type if unencrypted */
6643                        if (currentAuthType == AUTH_OPEN)
6644                                set_auth_type(local, AUTH_ENCRYPT);
6645                } else {
6646                        set_auth_type(local, AUTH_OPEN);
6647                }
6648
6649                /* Commit the changes to flags if needed */
6650                if (local->config.authType != currentAuthType)
6651                        set_bit (FLAG_COMMIT, &local->flags);
6652                break;
6653
6654        case IW_AUTH_80211_AUTH_ALG: {
6655                        if (param->value & IW_AUTH_ALG_SHARED_KEY) {
6656                                set_auth_type(local, AUTH_SHAREDKEY);
6657                        } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
6658                                /* We don't know here if WEP open system or
6659                                 * unencrypted mode was requested - so use the
6660                                 * last mode (of these two) used last time
6661                                 */
6662                                set_auth_type(local, local->last_auth);
6663                        } else
6664                                return -EINVAL;
6665
6666                        /* Commit the changes to flags if needed */
6667                        if (local->config.authType != currentAuthType)
6668                                set_bit (FLAG_COMMIT, &local->flags);
6669                        break;
6670                }
6671
6672        case IW_AUTH_WPA_ENABLED:
6673                /* Silently accept disable of WPA */
6674                if (param->value > 0)
6675                        return -EOPNOTSUPP;
6676                break;
6677
6678        default:
6679                return -EOPNOTSUPP;
6680        }
6681        return -EINPROGRESS;
6682}
6683
6684
6685/*------------------------------------------------------------------*/
6686/*
6687 * Wireless Handler : get extended authentication parameters
6688 */
6689static int airo_get_auth(struct net_device *dev,
6690                               struct iw_request_info *info,
6691                               union iwreq_data *wrqu, char *extra)
6692{
6693        struct airo_info *local = dev->ml_priv;
6694        struct iw_param *param = &wrqu->param;
6695        __le16 currentAuthType = local->config.authType;
6696
6697        switch (param->flags & IW_AUTH_INDEX) {
6698        case IW_AUTH_DROP_UNENCRYPTED:
6699                switch (currentAuthType) {
6700                case AUTH_SHAREDKEY:
6701                case AUTH_ENCRYPT:
6702                        param->value = 1;
6703                        break;
6704                default:
6705                        param->value = 0;
6706                        break;
6707                }
6708                break;
6709
6710        case IW_AUTH_80211_AUTH_ALG:
6711                switch (currentAuthType) {
6712                case AUTH_SHAREDKEY:
6713                        param->value = IW_AUTH_ALG_SHARED_KEY;
6714                        break;
6715                case AUTH_ENCRYPT:
6716                default:
6717                        param->value = IW_AUTH_ALG_OPEN_SYSTEM;
6718                        break;
6719                }
6720                break;
6721
6722        case IW_AUTH_WPA_ENABLED:
6723                param->value = 0;
6724                break;
6725
6726        default:
6727                return -EOPNOTSUPP;
6728        }
6729        return 0;
6730}
6731
6732
6733/*------------------------------------------------------------------*/
6734/*
6735 * Wireless Handler : set Tx-Power
6736 */
6737static int airo_set_txpow(struct net_device *dev,
6738                          struct iw_request_info *info,
6739                          struct iw_param *vwrq,
6740                          char *extra)
6741{
6742        struct airo_info *local = dev->ml_priv;
6743        CapabilityRid cap_rid;          /* Card capability info */
6744        int i;
6745        int rc = -EINVAL;
6746        __le16 v = cpu_to_le16(vwrq->value);
6747
6748        readCapabilityRid(local, &cap_rid, 1);
6749
6750        if (vwrq->disabled) {
6751                set_bit (FLAG_RADIO_OFF, &local->flags);
6752                set_bit (FLAG_COMMIT, &local->flags);
6753                return -EINPROGRESS;            /* Call commit handler */
6754        }
6755        if (vwrq->flags != IW_TXPOW_MWATT) {
6756                return -EINVAL;
6757        }
6758        clear_bit (FLAG_RADIO_OFF, &local->flags);
6759        for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)
6760                if (v == cap_rid.txPowerLevels[i]) {
6761                        readConfigRid(local, 1);
6762                        local->config.txPower = v;
6763                        set_bit (FLAG_COMMIT, &local->flags);
6764                        rc = -EINPROGRESS;      /* Call commit handler */
6765                        break;
6766                }
6767        return rc;
6768}
6769
6770/*------------------------------------------------------------------*/
6771/*
6772 * Wireless Handler : get Tx-Power
6773 */
6774static int airo_get_txpow(struct net_device *dev,
6775                          struct iw_request_info *info,
6776                          struct iw_param *vwrq,
6777                          char *extra)
6778{
6779        struct airo_info *local = dev->ml_priv;
6780
6781        readConfigRid(local, 1);
6782        vwrq->value = le16_to_cpu(local->config.txPower);
6783        vwrq->fixed = 1;        /* No power control */
6784        vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6785        vwrq->flags = IW_TXPOW_MWATT;
6786
6787        return 0;
6788}
6789
6790/*------------------------------------------------------------------*/
6791/*
6792 * Wireless Handler : set Retry limits
6793 */
6794static int airo_set_retry(struct net_device *dev,
6795                          struct iw_request_info *info,
6796                          struct iw_param *vwrq,
6797                          char *extra)
6798{
6799        struct airo_info *local = dev->ml_priv;
6800        int rc = -EINVAL;
6801
6802        if(vwrq->disabled) {
6803                return -EINVAL;
6804        }
6805        readConfigRid(local, 1);
6806        if(vwrq->flags & IW_RETRY_LIMIT) {
6807                __le16 v = cpu_to_le16(vwrq->value);
6808                if(vwrq->flags & IW_RETRY_LONG)
6809                        local->config.longRetryLimit = v;
6810                else if (vwrq->flags & IW_RETRY_SHORT)
6811                        local->config.shortRetryLimit = v;
6812                else {
6813                        /* No modifier : set both */
6814                        local->config.longRetryLimit = v;
6815                        local->config.shortRetryLimit = v;
6816                }
6817                set_bit (FLAG_COMMIT, &local->flags);
6818                rc = -EINPROGRESS;              /* Call commit handler */
6819        }
6820        if(vwrq->flags & IW_RETRY_LIFETIME) {
6821                local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
6822                set_bit (FLAG_COMMIT, &local->flags);
6823                rc = -EINPROGRESS;              /* Call commit handler */
6824        }
6825        return rc;
6826}
6827
6828/*------------------------------------------------------------------*/
6829/*
6830 * Wireless Handler : get Retry limits
6831 */
6832static int airo_get_retry(struct net_device *dev,
6833                          struct iw_request_info *info,
6834                          struct iw_param *vwrq,
6835                          char *extra)
6836{
6837        struct airo_info *local = dev->ml_priv;
6838
6839        vwrq->disabled = 0;      /* Can't be disabled */
6840
6841        readConfigRid(local, 1);
6842        /* Note : by default, display the min retry number */
6843        if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6844                vwrq->flags = IW_RETRY_LIFETIME;
6845                vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
6846        } else if((vwrq->flags & IW_RETRY_LONG)) {
6847                vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6848                vwrq->value = le16_to_cpu(local->config.longRetryLimit);
6849        } else {
6850                vwrq->flags = IW_RETRY_LIMIT;
6851                vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
6852                if(local->config.shortRetryLimit != local->config.longRetryLimit)
6853                        vwrq->flags |= IW_RETRY_SHORT;
6854        }
6855
6856        return 0;
6857}
6858
6859/*------------------------------------------------------------------*/
6860/*
6861 * Wireless Handler : get range info
6862 */
6863static int airo_get_range(struct net_device *dev,
6864                          struct iw_request_info *info,
6865                          struct iw_point *dwrq,
6866                          char *extra)
6867{
6868        struct airo_info *local = dev->ml_priv;
6869        struct iw_range *range = (struct iw_range *) extra;
6870        CapabilityRid cap_rid;          /* Card capability info */
6871        int             i;
6872        int             k;
6873
6874        readCapabilityRid(local, &cap_rid, 1);
6875
6876        dwrq->length = sizeof(struct iw_range);
6877        memset(range, 0, sizeof(*range));
6878        range->min_nwid = 0x0000;
6879        range->max_nwid = 0x0000;
6880        range->num_channels = 14;
6881        /* Should be based on cap_rid.country to give only
6882         * what the current card support */
6883        k = 0;
6884        for(i = 0; i < 14; i++) {
6885                range->freq[k].i = i + 1; /* List index */
6886                range->freq[k].m = 100000 *
6887                     ieee80211_channel_to_frequency(i + 1, NL80211_BAND_2GHZ);
6888                range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
6889        }
6890        range->num_frequency = k;
6891
6892        range->sensitivity = 65535;
6893
6894        /* Hum... Should put the right values there */
6895        if (local->rssi)
6896                range->max_qual.qual = 100;     /* % */
6897        else
6898                range->max_qual.qual = airo_get_max_quality(&cap_rid);
6899        range->max_qual.level = 0x100 - 120;    /* -120 dBm */
6900        range->max_qual.noise = 0x100 - 120;    /* -120 dBm */
6901
6902        /* Experimental measurements - boundary 11/5.5 Mb/s */
6903        /* Note : with or without the (local->rssi), results
6904         * are somewhat different. - Jean II */
6905        if (local->rssi) {
6906                range->avg_qual.qual = 50;              /* % */
6907                range->avg_qual.level = 0x100 - 70;     /* -70 dBm */
6908        } else {
6909                range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6910                range->avg_qual.level = 0x100 - 80;     /* -80 dBm */
6911        }
6912        range->avg_qual.noise = 0x100 - 85;             /* -85 dBm */
6913
6914        for(i = 0 ; i < 8 ; i++) {
6915                range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6916                if(range->bitrate[i] == 0)
6917                        break;
6918        }
6919        range->num_bitrates = i;
6920
6921        /* Set an indication of the max TCP throughput
6922         * in bit/s that we can expect using this interface.
6923         * May be use for QoS stuff... Jean II */
6924        if(i > 2)
6925                range->throughput = 5000 * 1000;
6926        else
6927                range->throughput = 1500 * 1000;
6928
6929        range->min_rts = 0;
6930        range->max_rts = AIRO_DEF_MTU;
6931        range->min_frag = 256;
6932        range->max_frag = AIRO_DEF_MTU;
6933
6934        if(cap_rid.softCap & cpu_to_le16(2)) {
6935                // WEP: RC4 40 bits
6936                range->encoding_size[0] = 5;
6937                // RC4 ~128 bits
6938                if (cap_rid.softCap & cpu_to_le16(0x100)) {
6939                        range->encoding_size[1] = 13;
6940                        range->num_encoding_sizes = 2;
6941                } else
6942                        range->num_encoding_sizes = 1;
6943                range->max_encoding_tokens =
6944                        cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
6945        } else {
6946                range->num_encoding_sizes = 0;
6947                range->max_encoding_tokens = 0;
6948        }
6949        range->min_pmp = 0;
6950        range->max_pmp = 5000000;       /* 5 secs */
6951        range->min_pmt = 0;
6952        range->max_pmt = 65535 * 1024;  /* ??? */
6953        range->pmp_flags = IW_POWER_PERIOD;
6954        range->pmt_flags = IW_POWER_TIMEOUT;
6955        range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
6956
6957        /* Transmit Power - values are in mW */
6958        for(i = 0 ; i < 8 ; i++) {
6959                range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
6960                if(range->txpower[i] == 0)
6961                        break;
6962        }
6963        range->num_txpower = i;
6964        range->txpower_capa = IW_TXPOW_MWATT;
6965        range->we_version_source = 19;
6966        range->we_version_compiled = WIRELESS_EXT;
6967        range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
6968        range->retry_flags = IW_RETRY_LIMIT;
6969        range->r_time_flags = IW_RETRY_LIFETIME;
6970        range->min_retry = 1;
6971        range->max_retry = 65535;
6972        range->min_r_time = 1024;
6973        range->max_r_time = 65535 * 1024;
6974
6975        /* Event capability (kernel + driver) */
6976        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
6977                                IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
6978                                IW_EVENT_CAPA_MASK(SIOCGIWAP) |
6979                                IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
6980        range->event_capa[1] = IW_EVENT_CAPA_K_1;
6981        range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
6982        return 0;
6983}
6984
6985/*------------------------------------------------------------------*/
6986/*
6987 * Wireless Handler : set Power Management
6988 */
6989static int airo_set_power(struct net_device *dev,
6990                          struct iw_request_info *info,
6991                          struct iw_param *vwrq,
6992                          char *extra)
6993{
6994        struct airo_info *local = dev->ml_priv;
6995
6996        readConfigRid(local, 1);
6997        if (vwrq->disabled) {
6998                if (sniffing_mode(local))
6999                        return -EINVAL;
7000                local->config.powerSaveMode = POWERSAVE_CAM;
7001                local->config.rmode &= ~RXMODE_MASK;
7002                local->config.rmode |= RXMODE_BC_MC_ADDR;
7003                set_bit (FLAG_COMMIT, &local->flags);
7004                return -EINPROGRESS;            /* Call commit handler */
7005        }
7006        if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7007                local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
7008                local->config.powerSaveMode = POWERSAVE_PSPCAM;
7009                set_bit (FLAG_COMMIT, &local->flags);
7010        } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
7011                local->config.fastListenInterval =
7012                local->config.listenInterval =
7013                        cpu_to_le16((vwrq->value + 500) / 1024);
7014                local->config.powerSaveMode = POWERSAVE_PSPCAM;
7015                set_bit (FLAG_COMMIT, &local->flags);
7016        }
7017        switch (vwrq->flags & IW_POWER_MODE) {
7018                case IW_POWER_UNICAST_R:
7019                        if (sniffing_mode(local))
7020                                return -EINVAL;
7021                        local->config.rmode &= ~RXMODE_MASK;
7022                        local->config.rmode |= RXMODE_ADDR;
7023                        set_bit (FLAG_COMMIT, &local->flags);
7024                        break;
7025                case IW_POWER_ALL_R:
7026                        if (sniffing_mode(local))
7027                                return -EINVAL;
7028                        local->config.rmode &= ~RXMODE_MASK;
7029                        local->config.rmode |= RXMODE_BC_MC_ADDR;
7030                        set_bit (FLAG_COMMIT, &local->flags);
7031                case IW_POWER_ON:
7032                        /* This is broken, fixme ;-) */
7033                        break;
7034                default:
7035                        return -EINVAL;
7036        }
7037        // Note : we may want to factor local->need_commit here
7038        // Note2 : may also want to factor RXMODE_RFMON test
7039        return -EINPROGRESS;            /* Call commit handler */
7040}
7041
7042/*------------------------------------------------------------------*/
7043/*
7044 * Wireless Handler : get Power Management
7045 */
7046static int airo_get_power(struct net_device *dev,
7047                          struct iw_request_info *info,
7048                          struct iw_param *vwrq,
7049                          char *extra)
7050{
7051        struct airo_info *local = dev->ml_priv;
7052        __le16 mode;
7053
7054        readConfigRid(local, 1);
7055        mode = local->config.powerSaveMode;
7056        if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
7057                return 0;
7058        if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7059                vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
7060                vwrq->flags = IW_POWER_TIMEOUT;
7061        } else {
7062                vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
7063                vwrq->flags = IW_POWER_PERIOD;
7064        }
7065        if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
7066                vwrq->flags |= IW_POWER_UNICAST_R;
7067        else
7068                vwrq->flags |= IW_POWER_ALL_R;
7069
7070        return 0;
7071}
7072
7073/*------------------------------------------------------------------*/
7074/*
7075 * Wireless Handler : set Sensitivity
7076 */
7077static int airo_set_sens(struct net_device *dev,
7078                         struct iw_request_info *info,
7079                         struct iw_param *vwrq,
7080                         char *extra)
7081{
7082        struct airo_info *local = dev->ml_priv;
7083
7084        readConfigRid(local, 1);
7085        local->config.rssiThreshold =
7086                cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
7087        set_bit (FLAG_COMMIT, &local->flags);
7088
7089        return -EINPROGRESS;            /* Call commit handler */
7090}
7091
7092/*------------------------------------------------------------------*/
7093/*
7094 * Wireless Handler : get Sensitivity
7095 */
7096static int airo_get_sens(struct net_device *dev,
7097                         struct iw_request_info *info,
7098                         struct iw_param *vwrq,
7099                         char *extra)
7100{
7101        struct airo_info *local = dev->ml_priv;
7102
7103        readConfigRid(local, 1);
7104        vwrq->value = le16_to_cpu(local->config.rssiThreshold);
7105        vwrq->disabled = (vwrq->value == 0);
7106        vwrq->fixed = 1;
7107
7108        return 0;
7109}
7110
7111/*------------------------------------------------------------------*/
7112/*
7113 * Wireless Handler : get AP List
7114 * Note : this is deprecated in favor of IWSCAN
7115 */
7116static int airo_get_aplist(struct net_device *dev,
7117                           struct iw_request_info *info,
7118                           struct iw_point *dwrq,
7119                           char *extra)
7120{
7121        struct airo_info *local = dev->ml_priv;
7122        struct sockaddr *address = (struct sockaddr *) extra;
7123        struct iw_quality *qual;
7124        BSSListRid BSSList;
7125        int i;
7126        int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7127
7128        qual = kmalloc_array(IW_MAX_AP, sizeof(*qual), GFP_KERNEL);
7129        if (!qual)
7130                return -ENOMEM;
7131
7132        for (i = 0; i < IW_MAX_AP; i++) {
7133                u16 dBm;
7134                if (readBSSListRid(local, loseSync, &BSSList))
7135                        break;
7136                loseSync = 0;
7137                memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
7138                address[i].sa_family = ARPHRD_ETHER;
7139                dBm = le16_to_cpu(BSSList.dBm);
7140                if (local->rssi) {
7141                        qual[i].level = 0x100 - dBm;
7142                        qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
7143                        qual[i].updated = IW_QUAL_QUAL_UPDATED
7144                                        | IW_QUAL_LEVEL_UPDATED
7145                                        | IW_QUAL_DBM;
7146                } else {
7147                        qual[i].level = (dBm + 321) / 2;
7148                        qual[i].qual = 0;
7149                        qual[i].updated = IW_QUAL_QUAL_INVALID
7150                                        | IW_QUAL_LEVEL_UPDATED
7151                                        | IW_QUAL_DBM;
7152                }
7153                qual[i].noise = local->wstats.qual.noise;
7154                if (BSSList.index == cpu_to_le16(0xffff))
7155                        break;
7156        }
7157        if (!i) {
7158                StatusRid status_rid;           /* Card status info */
7159                readStatusRid(local, &status_rid, 1);
7160                for (i = 0;
7161                     i < min(IW_MAX_AP, 4) &&
7162                             (status_rid.bssid[i][0]
7163                              & status_rid.bssid[i][1]
7164                              & status_rid.bssid[i][2]
7165                              & status_rid.bssid[i][3]
7166                              & status_rid.bssid[i][4]
7167                              & status_rid.bssid[i][5])!=0xff &&
7168                             (status_rid.bssid[i][0]
7169                              | status_rid.bssid[i][1]
7170                              | status_rid.bssid[i][2]
7171                              | status_rid.bssid[i][3]
7172                              | status_rid.bssid[i][4]
7173                              | status_rid.bssid[i][5]);
7174                     i++) {
7175                        memcpy(address[i].sa_data,
7176                               status_rid.bssid[i], ETH_ALEN);
7177                        address[i].sa_family = ARPHRD_ETHER;
7178                }
7179        } else {
7180                dwrq->flags = 1; /* Should be define'd */
7181                memcpy(extra + sizeof(struct sockaddr) * i, qual,
7182                       sizeof(struct iw_quality) * i);
7183        }
7184        dwrq->length = i;
7185
7186        kfree(qual);
7187        return 0;
7188}
7189
7190/*------------------------------------------------------------------*/
7191/*
7192 * Wireless Handler : Initiate Scan
7193 */
7194static int airo_set_scan(struct net_device *dev,
7195                         struct iw_request_info *info,
7196                         struct iw_point *dwrq,
7197                         char *extra)
7198{
7199        struct airo_info *ai = dev->ml_priv;
7200        Cmd cmd;
7201        Resp rsp;
7202        int wake = 0;
7203        APListRid APList_rid_empty;
7204
7205        /* Note : you may have realised that, as this is a SET operation,
7206         * this is privileged and therefore a normal user can't
7207         * perform scanning.
7208         * This is not an error, while the device perform scanning,
7209         * traffic doesn't flow, so it's a perfect DoS...
7210         * Jean II */
7211        if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
7212
7213        if (down_interruptible(&ai->sem))
7214                return -ERESTARTSYS;
7215
7216        /* If there's already a scan in progress, don't
7217         * trigger another one. */
7218        if (ai->scan_timeout > 0)
7219                goto out;
7220
7221        /* Clear APList as it affects scan results */
7222        memset(&APList_rid_empty, 0, sizeof(APList_rid_empty));
7223        APList_rid_empty.len = cpu_to_le16(sizeof(APList_rid_empty));
7224        disable_MAC(ai, 2);
7225        writeAPListRid(ai, &APList_rid_empty, 0);
7226        enable_MAC(ai, 0);
7227
7228        /* Initiate a scan command */
7229        ai->scan_timeout = RUN_AT(3*HZ);
7230        memset(&cmd, 0, sizeof(cmd));
7231        cmd.cmd=CMD_LISTBSS;
7232        issuecommand(ai, &cmd, &rsp);
7233        wake = 1;
7234
7235out:
7236        up(&ai->sem);
7237        if (wake)
7238                wake_up_interruptible(&ai->thr_wait);
7239        return 0;
7240}
7241
7242/*------------------------------------------------------------------*/
7243/*
7244 * Translate scan data returned from the card to a card independent
7245 * format that the Wireless Tools will understand - Jean II
7246 */
7247static inline char *airo_translate_scan(struct net_device *dev,
7248                                        struct iw_request_info *info,
7249                                        char *current_ev,
7250                                        char *end_buf,
7251                                        BSSListRid *bss)
7252{
7253        struct airo_info *ai = dev->ml_priv;
7254        struct iw_event         iwe;            /* Temporary buffer */
7255        __le16                  capabilities;
7256        char *                  current_val;    /* For rates */
7257        int                     i;
7258        char *          buf;
7259        u16 dBm;
7260
7261        /* First entry *MUST* be the AP MAC address */
7262        iwe.cmd = SIOCGIWAP;
7263        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7264        memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7265        current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7266                                          &iwe, IW_EV_ADDR_LEN);
7267
7268        /* Other entries will be displayed in the order we give them */
7269
7270        /* Add the ESSID */
7271        iwe.u.data.length = bss->ssidLen;
7272        if(iwe.u.data.length > 32)
7273                iwe.u.data.length = 32;
7274        iwe.cmd = SIOCGIWESSID;
7275        iwe.u.data.flags = 1;
7276        current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7277                                          &iwe, bss->ssid);
7278
7279        /* Add mode */
7280        iwe.cmd = SIOCGIWMODE;
7281        capabilities = bss->cap;
7282        if(capabilities & (CAP_ESS | CAP_IBSS)) {
7283                if(capabilities & CAP_ESS)
7284                        iwe.u.mode = IW_MODE_MASTER;
7285                else
7286                        iwe.u.mode = IW_MODE_ADHOC;
7287                current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7288                                                  &iwe, IW_EV_UINT_LEN);
7289        }
7290
7291        /* Add frequency */
7292        iwe.cmd = SIOCGIWFREQ;
7293        iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7294        iwe.u.freq.m = 100000 *
7295              ieee80211_channel_to_frequency(iwe.u.freq.m, NL80211_BAND_2GHZ);
7296        iwe.u.freq.e = 1;
7297        current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7298                                          &iwe, IW_EV_FREQ_LEN);
7299
7300        dBm = le16_to_cpu(bss->dBm);
7301
7302        /* Add quality statistics */
7303        iwe.cmd = IWEVQUAL;
7304        if (ai->rssi) {
7305                iwe.u.qual.level = 0x100 - dBm;
7306                iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
7307                iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
7308                                | IW_QUAL_LEVEL_UPDATED
7309                                | IW_QUAL_DBM;
7310        } else {
7311                iwe.u.qual.level = (dBm + 321) / 2;
7312                iwe.u.qual.qual = 0;
7313                iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
7314                                | IW_QUAL_LEVEL_UPDATED
7315                                | IW_QUAL_DBM;
7316        }
7317        iwe.u.qual.noise = ai->wstats.qual.noise;
7318        current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7319                                          &iwe, IW_EV_QUAL_LEN);
7320
7321        /* Add encryption capability */
7322        iwe.cmd = SIOCGIWENCODE;
7323        if(capabilities & CAP_PRIVACY)
7324                iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
7325        else
7326                iwe.u.data.flags = IW_ENCODE_DISABLED;
7327        iwe.u.data.length = 0;
7328        current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7329                                          &iwe, bss->ssid);
7330
7331        /* Rate : stuffing multiple values in a single event require a bit
7332         * more of magic - Jean II */
7333        current_val = current_ev + iwe_stream_lcp_len(info);
7334
7335        iwe.cmd = SIOCGIWRATE;
7336        /* Those two flags are ignored... */
7337        iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
7338        /* Max 8 values */
7339        for(i = 0 ; i < 8 ; i++) {
7340                /* NULL terminated */
7341                if(bss->rates[i] == 0)
7342                        break;
7343                /* Bit rate given in 500 kb/s units (+ 0x80) */
7344                iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7345                /* Add new value to event */
7346                current_val = iwe_stream_add_value(info, current_ev,
7347                                                   current_val, end_buf,
7348                                                   &iwe, IW_EV_PARAM_LEN);
7349        }
7350        /* Check if we added any event */
7351        if ((current_val - current_ev) > iwe_stream_lcp_len(info))
7352                current_ev = current_val;
7353
7354        /* Beacon interval */
7355        buf = kmalloc(30, GFP_KERNEL);
7356        if (buf) {
7357                iwe.cmd = IWEVCUSTOM;
7358                sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7359                iwe.u.data.length = strlen(buf);
7360                current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7361                                                  &iwe, buf);
7362                kfree(buf);
7363        }
7364
7365        /* Put WPA/RSN Information Elements into the event stream */
7366        if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
7367                unsigned int num_null_ies = 0;
7368                u16 length = sizeof (bss->extra.iep);
7369                u8 *ie = (void *)&bss->extra.iep;
7370
7371                while ((length >= 2) && (num_null_ies < 2)) {
7372                        if (2 + ie[1] > length) {
7373                                /* Invalid element, don't continue parsing IE */
7374                                break;
7375                        }
7376
7377                        switch (ie[0]) {
7378                        case WLAN_EID_SSID:
7379                                /* Two zero-length SSID elements
7380                                 * mean we're done parsing elements */
7381                                if (!ie[1])
7382                                        num_null_ies++;
7383                                break;
7384
7385                        case WLAN_EID_VENDOR_SPECIFIC:
7386                                if (ie[1] >= 4 &&
7387                                    ie[2] == 0x00 &&
7388                                    ie[3] == 0x50 &&
7389                                    ie[4] == 0xf2 &&
7390                                    ie[5] == 0x01) {
7391                                        iwe.cmd = IWEVGENIE;
7392                                        /* 64 is an arbitrary cut-off */
7393                                        iwe.u.data.length = min(ie[1] + 2,
7394                                                                64);
7395                                        current_ev = iwe_stream_add_point(
7396                                                        info, current_ev,
7397                                                        end_buf, &iwe, ie);
7398                                }
7399                                break;
7400
7401                        case WLAN_EID_RSN:
7402                                iwe.cmd = IWEVGENIE;
7403                                /* 64 is an arbitrary cut-off */
7404                                iwe.u.data.length = min(ie[1] + 2, 64);
7405                                current_ev = iwe_stream_add_point(
7406                                        info, current_ev, end_buf,
7407                                        &iwe, ie);
7408                                break;
7409
7410                        default:
7411                                break;
7412                        }
7413
7414                        length -= 2 + ie[1];
7415                        ie += 2 + ie[1];
7416                }
7417        }
7418        return current_ev;
7419}
7420
7421/*------------------------------------------------------------------*/
7422/*
7423 * Wireless Handler : Read Scan Results
7424 */
7425static int airo_get_scan(struct net_device *dev,
7426                         struct iw_request_info *info,
7427                         struct iw_point *dwrq,
7428                         char *extra)
7429{
7430        struct airo_info *ai = dev->ml_priv;
7431        BSSListElement *net;
7432        int err = 0;
7433        char *current_ev = extra;
7434
7435        /* If a scan is in-progress, return -EAGAIN */
7436        if (ai->scan_timeout > 0)
7437                return -EAGAIN;
7438
7439        if (down_interruptible(&ai->sem))
7440                return -EAGAIN;
7441
7442        list_for_each_entry (net, &ai->network_list, list) {
7443                /* Translate to WE format this entry */
7444                current_ev = airo_translate_scan(dev, info, current_ev,
7445                                                 extra + dwrq->length,
7446                                                 &net->bss);
7447
7448                /* Check if there is space for one more entry */
7449                if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7450                        /* Ask user space to try again with a bigger buffer */
7451                        err = -E2BIG;
7452                        goto out;
7453                }
7454        }
7455
7456        /* Length of data */
7457        dwrq->length = (current_ev - extra);
7458        dwrq->flags = 0;        /* todo */
7459
7460out:
7461        up(&ai->sem);
7462        return err;
7463}
7464
7465/*------------------------------------------------------------------*/
7466/*
7467 * Commit handler : called after a bunch of SET operations
7468 */
7469static int airo_config_commit(struct net_device *dev,
7470                              struct iw_request_info *info,     /* NULL */
7471                              void *zwrq,                       /* NULL */
7472                              char *extra)                      /* NULL */
7473{
7474        struct airo_info *local = dev->ml_priv;
7475
7476        if (!test_bit (FLAG_COMMIT, &local->flags))
7477                return 0;
7478
7479        /* Some of the "SET" function may have modified some of the
7480         * parameters. It's now time to commit them in the card */
7481        disable_MAC(local, 1);
7482        if (test_bit (FLAG_RESET, &local->flags)) {
7483                SsidRid SSID_rid;
7484
7485                readSsidRid(local, &SSID_rid);
7486                if (test_bit(FLAG_MPI,&local->flags))
7487                        setup_card(local, dev->dev_addr, 1 );
7488                else
7489                        reset_airo_card(dev);
7490                disable_MAC(local, 1);
7491                writeSsidRid(local, &SSID_rid, 1);
7492                writeAPListRid(local, &local->APList, 1);
7493        }
7494        if (down_interruptible(&local->sem))
7495                return -ERESTARTSYS;
7496        writeConfigRid(local, 0);
7497        enable_MAC(local, 0);
7498        if (test_bit (FLAG_RESET, &local->flags))
7499                airo_set_promisc(local);
7500        else
7501                up(&local->sem);
7502
7503        return 0;
7504}
7505
7506/*------------------------------------------------------------------*/
7507/*
7508 * Structures to export the Wireless Handlers
7509 */
7510
7511static const struct iw_priv_args airo_private_args[] = {
7512/*{ cmd,         set_args,                            get_args, name } */
7513  { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7514    IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7515  { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7516    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7517};
7518
7519static const iw_handler         airo_handler[] =
7520{
7521        (iw_handler) airo_config_commit,        /* SIOCSIWCOMMIT */
7522        (iw_handler) airo_get_name,             /* SIOCGIWNAME */
7523        (iw_handler) NULL,                      /* SIOCSIWNWID */
7524        (iw_handler) NULL,                      /* SIOCGIWNWID */
7525        (iw_handler) airo_set_freq,             /* SIOCSIWFREQ */
7526        (iw_handler) airo_get_freq,             /* SIOCGIWFREQ */
7527        (iw_handler) airo_set_mode,             /* SIOCSIWMODE */
7528        (iw_handler) airo_get_mode,             /* SIOCGIWMODE */
7529        (iw_handler) airo_set_sens,             /* SIOCSIWSENS */
7530        (iw_handler) airo_get_sens,             /* SIOCGIWSENS */
7531        (iw_handler) NULL,                      /* SIOCSIWRANGE */
7532        (iw_handler) airo_get_range,            /* SIOCGIWRANGE */
7533        (iw_handler) NULL,                      /* SIOCSIWPRIV */
7534        (iw_handler) NULL,                      /* SIOCGIWPRIV */
7535        (iw_handler) NULL,                      /* SIOCSIWSTATS */
7536        (iw_handler) NULL,                      /* SIOCGIWSTATS */
7537        iw_handler_set_spy,                     /* SIOCSIWSPY */
7538        iw_handler_get_spy,                     /* SIOCGIWSPY */
7539        iw_handler_set_thrspy,                  /* SIOCSIWTHRSPY */
7540        iw_handler_get_thrspy,                  /* SIOCGIWTHRSPY */
7541        (iw_handler) airo_set_wap,              /* SIOCSIWAP */
7542        (iw_handler) airo_get_wap,              /* SIOCGIWAP */
7543        (iw_handler) NULL,                      /* -- hole -- */
7544        (iw_handler) airo_get_aplist,           /* SIOCGIWAPLIST */
7545        (iw_handler) airo_set_scan,             /* SIOCSIWSCAN */
7546        (iw_handler) airo_get_scan,             /* SIOCGIWSCAN */
7547        (iw_handler) airo_set_essid,            /* SIOCSIWESSID */
7548        (iw_handler) airo_get_essid,            /* SIOCGIWESSID */
7549        (iw_handler) airo_set_nick,             /* SIOCSIWNICKN */
7550        (iw_handler) airo_get_nick,             /* SIOCGIWNICKN */
7551        (iw_handler) NULL,                      /* -- hole -- */
7552        (iw_handler) NULL,                      /* -- hole -- */
7553        (iw_handler) airo_set_rate,             /* SIOCSIWRATE */
7554        (iw_handler) airo_get_rate,             /* SIOCGIWRATE */
7555        (iw_handler) airo_set_rts,              /* SIOCSIWRTS */
7556        (iw_handler) airo_get_rts,              /* SIOCGIWRTS */
7557        (iw_handler) airo_set_frag,             /* SIOCSIWFRAG */
7558        (iw_handler) airo_get_frag,             /* SIOCGIWFRAG */
7559        (iw_handler) airo_set_txpow,            /* SIOCSIWTXPOW */
7560        (iw_handler) airo_get_txpow,            /* SIOCGIWTXPOW */
7561        (iw_handler) airo_set_retry,            /* SIOCSIWRETRY */
7562        (iw_handler) airo_get_retry,            /* SIOCGIWRETRY */
7563        (iw_handler) airo_set_encode,           /* SIOCSIWENCODE */
7564        (iw_handler) airo_get_encode,           /* SIOCGIWENCODE */
7565        (iw_handler) airo_set_power,            /* SIOCSIWPOWER */
7566        (iw_handler) airo_get_power,            /* SIOCGIWPOWER */
7567        (iw_handler) NULL,                      /* -- hole -- */
7568        (iw_handler) NULL,                      /* -- hole -- */
7569        (iw_handler) NULL,                      /* SIOCSIWGENIE */
7570        (iw_handler) NULL,                      /* SIOCGIWGENIE */
7571        (iw_handler) airo_set_auth,             /* SIOCSIWAUTH */
7572        (iw_handler) airo_get_auth,             /* SIOCGIWAUTH */
7573        (iw_handler) airo_set_encodeext,        /* SIOCSIWENCODEEXT */
7574        (iw_handler) airo_get_encodeext,        /* SIOCGIWENCODEEXT */
7575        (iw_handler) NULL,                      /* SIOCSIWPMKSA */
7576};
7577
7578/* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7579 * We want to force the use of the ioctl code, because those can't be
7580 * won't work the iw_handler code (because they simultaneously read
7581 * and write data and iw_handler can't do that).
7582 * Note that it's perfectly legal to read/write on a single ioctl command,
7583 * you just can't use iwpriv and need to force it via the ioctl handler.
7584 * Jean II */
7585static const iw_handler         airo_private_handler[] =
7586{
7587        NULL,                           /* SIOCIWFIRSTPRIV */
7588};
7589
7590static const struct iw_handler_def      airo_handler_def =
7591{
7592        .num_standard   = ARRAY_SIZE(airo_handler),
7593        .num_private    = ARRAY_SIZE(airo_private_handler),
7594        .num_private_args = ARRAY_SIZE(airo_private_args),
7595        .standard       = airo_handler,
7596        .private        = airo_private_handler,
7597        .private_args   = airo_private_args,
7598        .get_wireless_stats = airo_get_wireless_stats,
7599};
7600
7601/*
7602 * This defines the configuration part of the Wireless Extensions
7603 * Note : irq and spinlock protection will occur in the subroutines
7604 *
7605 * TODO :
7606 *      o Check input value more carefully and fill correct values in range
7607 *      o Test and shakeout the bugs (if any)
7608 *
7609 * Jean II
7610 *
7611 * Javier Achirica did a great job of merging code from the unnamed CISCO
7612 * developer that added support for flashing the card.
7613 */
7614static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7615{
7616        int rc = 0;
7617        struct airo_info *ai = dev->ml_priv;
7618
7619        if (ai->power.event)
7620                return 0;
7621
7622        switch (cmd) {
7623#ifdef CISCO_EXT
7624        case AIROIDIFC:
7625#ifdef AIROOLDIDIFC
7626        case AIROOLDIDIFC:
7627#endif
7628        {
7629                int val = AIROMAGIC;
7630                aironet_ioctl com;
7631                if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
7632                        rc = -EFAULT;
7633                else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
7634                        rc = -EFAULT;
7635        }
7636        break;
7637
7638        case AIROIOCTL:
7639#ifdef AIROOLDIOCTL
7640        case AIROOLDIOCTL:
7641#endif
7642                /* Get the command struct and hand it off for evaluation by
7643                 * the proper subfunction
7644                 */
7645        {
7646                aironet_ioctl com;
7647                if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
7648                        rc = -EFAULT;
7649                        break;
7650                }
7651
7652                /* Separate R/W functions bracket legality here
7653                 */
7654                if ( com.command == AIRORSWVERSION ) {
7655                        if (copy_to_user(com.data, swversion, sizeof(swversion)))
7656                                rc = -EFAULT;
7657                        else
7658                                rc = 0;
7659                }
7660                else if ( com.command <= AIRORRID)
7661                        rc = readrids(dev,&com);
7662                else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
7663                        rc = writerids(dev,&com);
7664                else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
7665                        rc = flashcard(dev,&com);
7666                else
7667                        rc = -EINVAL;      /* Bad command in ioctl */
7668        }
7669        break;
7670#endif /* CISCO_EXT */
7671
7672        // All other calls are currently unsupported
7673        default:
7674                rc = -EOPNOTSUPP;
7675        }
7676        return rc;
7677}
7678
7679/*
7680 * Get the Wireless stats out of the driver
7681 * Note : irq and spinlock protection will occur in the subroutines
7682 *
7683 * TODO :
7684 *      o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7685 *
7686 * Jean
7687 */
7688static void airo_read_wireless_stats(struct airo_info *local)
7689{
7690        StatusRid status_rid;
7691        StatsRid stats_rid;
7692        CapabilityRid cap_rid;
7693        __le32 *vals = stats_rid.vals;
7694
7695        /* Get stats out of the card */
7696        clear_bit(JOB_WSTATS, &local->jobs);
7697        if (local->power.event) {
7698                up(&local->sem);
7699                return;
7700        }
7701        readCapabilityRid(local, &cap_rid, 0);
7702        readStatusRid(local, &status_rid, 0);
7703        readStatsRid(local, &stats_rid, RID_STATS, 0);
7704        up(&local->sem);
7705
7706        /* The status */
7707        local->wstats.status = le16_to_cpu(status_rid.mode);
7708
7709        /* Signal quality and co */
7710        if (local->rssi) {
7711                local->wstats.qual.level =
7712                        airo_rssi_to_dbm(local->rssi,
7713                                         le16_to_cpu(status_rid.sigQuality));
7714                /* normalizedSignalStrength appears to be a percentage */
7715                local->wstats.qual.qual =
7716                        le16_to_cpu(status_rid.normalizedSignalStrength);
7717        } else {
7718                local->wstats.qual.level =
7719                        (le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7720                local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7721        }
7722        if (le16_to_cpu(status_rid.len) >= 124) {
7723                local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7724                local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7725        } else {
7726                local->wstats.qual.noise = 0;
7727                local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
7728        }
7729
7730        /* Packets discarded in the wireless adapter due to wireless
7731         * specific problems */
7732        local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7733                                     le32_to_cpu(vals[57]) +
7734                                     le32_to_cpu(vals[58]); /* SSID Mismatch */
7735        local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7736        local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7737        local->wstats.discard.retries = le32_to_cpu(vals[10]);
7738        local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7739                                     le32_to_cpu(vals[32]);
7740        local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7741}
7742
7743static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7744{
7745        struct airo_info *local =  dev->ml_priv;
7746
7747        if (!test_bit(JOB_WSTATS, &local->jobs)) {
7748                /* Get stats out of the card if available */
7749                if (down_trylock(&local->sem) != 0) {
7750                        set_bit(JOB_WSTATS, &local->jobs);
7751                        wake_up_interruptible(&local->thr_wait);
7752                } else
7753                        airo_read_wireless_stats(local);
7754        }
7755
7756        return &local->wstats;
7757}
7758
7759#ifdef CISCO_EXT
7760/*
7761 * This just translates from driver IOCTL codes to the command codes to
7762 * feed to the radio's host interface. Things can be added/deleted
7763 * as needed.  This represents the READ side of control I/O to
7764 * the card
7765 */
7766static int readrids(struct net_device *dev, aironet_ioctl *comp) {
7767        unsigned short ridcode;
7768        unsigned char *iobuf;
7769        int len;
7770        struct airo_info *ai = dev->ml_priv;
7771
7772        if (test_bit(FLAG_FLASHING, &ai->flags))
7773                return -EIO;
7774
7775        switch(comp->command)
7776        {
7777        case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7778        case AIROGCFG:      ridcode = RID_CONFIG;
7779                if (test_bit(FLAG_COMMIT, &ai->flags)) {
7780                        disable_MAC (ai, 1);
7781                        writeConfigRid (ai, 1);
7782                        enable_MAC(ai, 1);
7783                }
7784                break;
7785        case AIROGSLIST:    ridcode = RID_SSID;         break;
7786        case AIROGVLIST:    ridcode = RID_APLIST;       break;
7787        case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7788        case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7789        case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
7790                /* Only super-user can read WEP keys */
7791                if (!capable(CAP_NET_ADMIN))
7792                        return -EPERM;
7793                break;
7794        case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
7795                /* Only super-user can read WEP keys */
7796                if (!capable(CAP_NET_ADMIN))
7797                        return -EPERM;
7798                break;
7799        case AIROGSTAT:     ridcode = RID_STATUS;       break;
7800        case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7801        case AIROGSTATSC32: ridcode = RID_STATS;        break;
7802        case AIROGMICSTATS:
7803                if (copy_to_user(comp->data, &ai->micstats,
7804                                 min((int)comp->len,(int)sizeof(ai->micstats))))
7805                        return -EFAULT;
7806                return 0;
7807        case AIRORRID:      ridcode = comp->ridnum;     break;
7808        default:
7809                return -EINVAL;
7810        }
7811
7812        if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7813                return -ENOMEM;
7814
7815        PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
7816        /* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7817         * then return it to the user
7818         * 9/22/2000 Honor user given length
7819         */
7820        len = comp->len;
7821
7822        if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7823                kfree (iobuf);
7824                return -EFAULT;
7825        }
7826        kfree (iobuf);
7827        return 0;
7828}
7829
7830/*
7831 * Danger Will Robinson write the rids here
7832 */
7833
7834static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7835        struct airo_info *ai = dev->ml_priv;
7836        int  ridcode;
7837        int  enabled;
7838        int (*writer)(struct airo_info *, u16 rid, const void *, int, int);
7839        unsigned char *iobuf;
7840
7841        /* Only super-user can write RIDs */
7842        if (!capable(CAP_NET_ADMIN))
7843                return -EPERM;
7844
7845        if (test_bit(FLAG_FLASHING, &ai->flags))
7846                return -EIO;
7847
7848        ridcode = 0;
7849        writer = do_writerid;
7850
7851        switch(comp->command)
7852        {
7853        case AIROPSIDS:     ridcode = RID_SSID;         break;
7854        case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7855        case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7856        case AIROPCFG: ai->config.len = 0;
7857                            clear_bit(FLAG_COMMIT, &ai->flags);
7858                            ridcode = RID_CONFIG;       break;
7859        case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7860        case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7861        case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7862        case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7863                break;
7864        case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7865        case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7866
7867                /* this is not really a rid but a command given to the card
7868                 * same with MAC off
7869                 */
7870        case AIROPMACON:
7871                if (enable_MAC(ai, 1) != 0)
7872                        return -EIO;
7873                return 0;
7874
7875                /*
7876                 * Evidently this code in the airo driver does not get a symbol
7877                 * as disable_MAC. it's probably so short the compiler does not gen one.
7878                 */
7879        case AIROPMACOFF:
7880                disable_MAC(ai, 1);
7881                return 0;
7882
7883                /* This command merely clears the counts does not actually store any data
7884                 * only reads rid. But as it changes the cards state, I put it in the
7885                 * writerid routines.
7886                 */
7887        case AIROPSTCLR:
7888                if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7889                        return -ENOMEM;
7890
7891                PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
7892
7893                enabled = ai->micstats.enabled;
7894                memset(&ai->micstats,0,sizeof(ai->micstats));
7895                ai->micstats.enabled = enabled;
7896
7897                if (copy_to_user(comp->data, iobuf,
7898                                 min((int)comp->len, (int)RIDSIZE))) {
7899                        kfree (iobuf);
7900                        return -EFAULT;
7901                }
7902                kfree (iobuf);
7903                return 0;
7904
7905        default:
7906                return -EOPNOTSUPP;     /* Blarg! */
7907        }
7908        if(comp->len > RIDSIZE)
7909                return -EINVAL;
7910
7911        if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7912                return -ENOMEM;
7913
7914        if (copy_from_user(iobuf,comp->data,comp->len)) {
7915                kfree (iobuf);
7916                return -EFAULT;
7917        }
7918
7919        if (comp->command == AIROPCFG) {
7920                ConfigRid *cfg = (ConfigRid *)iobuf;
7921
7922                if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7923                        cfg->opmode |= MODE_MIC;
7924
7925                if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
7926                        set_bit (FLAG_ADHOC, &ai->flags);
7927                else
7928                        clear_bit (FLAG_ADHOC, &ai->flags);
7929        }
7930
7931        if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
7932                kfree (iobuf);
7933                return -EIO;
7934        }
7935        kfree (iobuf);
7936        return 0;
7937}
7938
7939/*****************************************************************************
7940 * Ancillary flash / mod functions much black magic lurkes here              *
7941 *****************************************************************************
7942 */
7943
7944/*
7945 * Flash command switch table
7946 */
7947
7948static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7949        int z;
7950
7951        /* Only super-user can modify flash */
7952        if (!capable(CAP_NET_ADMIN))
7953                return -EPERM;
7954
7955        switch(comp->command)
7956        {
7957        case AIROFLSHRST:
7958                return cmdreset((struct airo_info *)dev->ml_priv);
7959
7960        case AIROFLSHSTFL:
7961                if (!AIRO_FLASH(dev) &&
7962                    (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
7963                        return -ENOMEM;
7964                return setflashmode((struct airo_info *)dev->ml_priv);
7965
7966        case AIROFLSHGCHR: /* Get char from aux */
7967                if(comp->len != sizeof(int))
7968                        return -EINVAL;
7969                if (copy_from_user(&z,comp->data,comp->len))
7970                        return -EFAULT;
7971                return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
7972
7973        case AIROFLSHPCHR: /* Send char to card. */
7974                if(comp->len != sizeof(int))
7975                        return -EINVAL;
7976                if (copy_from_user(&z,comp->data,comp->len))
7977                        return -EFAULT;
7978                return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
7979
7980        case AIROFLPUTBUF: /* Send 32k to card */
7981                if (!AIRO_FLASH(dev))
7982                        return -ENOMEM;
7983                if(comp->len > FLASHSIZE)
7984                        return -EINVAL;
7985                if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
7986                        return -EFAULT;
7987
7988                flashputbuf((struct airo_info *)dev->ml_priv);
7989                return 0;
7990
7991        case AIRORESTART:
7992                if (flashrestart((struct airo_info *)dev->ml_priv, dev))
7993                        return -EIO;
7994                return 0;
7995        }
7996        return -EINVAL;
7997}
7998
7999#define FLASH_COMMAND  0x7e7e
8000
8001/*
8002 * STEP 1)
8003 * Disable MAC and do soft reset on
8004 * card.
8005 */
8006
8007static int cmdreset(struct airo_info *ai) {
8008        disable_MAC(ai, 1);
8009
8010        if(!waitbusy (ai)){
8011                airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
8012                return -EBUSY;
8013        }
8014
8015        OUT4500(ai,COMMAND,CMD_SOFTRESET);
8016
8017        ssleep(1);                      /* WAS 600 12/7/00 */
8018
8019        if(!waitbusy (ai)){
8020                airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
8021                return -EBUSY;
8022        }
8023        return 0;
8024}
8025
8026/* STEP 2)
8027 * Put the card in legendary flash
8028 * mode
8029 */
8030
8031static int setflashmode (struct airo_info *ai) {
8032        set_bit (FLAG_FLASHING, &ai->flags);
8033
8034        OUT4500(ai, SWS0, FLASH_COMMAND);
8035        OUT4500(ai, SWS1, FLASH_COMMAND);
8036        if (probe) {
8037                OUT4500(ai, SWS0, FLASH_COMMAND);
8038                OUT4500(ai, COMMAND,0x10);
8039        } else {
8040                OUT4500(ai, SWS2, FLASH_COMMAND);
8041                OUT4500(ai, SWS3, FLASH_COMMAND);
8042                OUT4500(ai, COMMAND,0);
8043        }
8044        msleep(500);            /* 500ms delay */
8045
8046        if(!waitbusy(ai)) {
8047                clear_bit (FLAG_FLASHING, &ai->flags);
8048                airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
8049                return -EIO;
8050        }
8051        return 0;
8052}
8053
8054/* Put character to SWS0 wait for dwelltime
8055 * x 50us for  echo .
8056 */
8057
8058static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
8059        int echo;
8060        int waittime;
8061
8062        byte |= 0x8000;
8063
8064        if(dwelltime == 0 )
8065                dwelltime = 200;
8066
8067        waittime=dwelltime;
8068
8069        /* Wait for busy bit d15 to go false indicating buffer empty */
8070        while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
8071                udelay (50);
8072                waittime -= 50;
8073        }
8074
8075        /* timeout for busy clear wait */
8076        if(waittime <= 0 ){
8077                airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
8078                return -EBUSY;
8079        }
8080
8081        /* Port is clear now write byte and wait for it to echo back */
8082        do {
8083                OUT4500(ai,SWS0,byte);
8084                udelay(50);
8085                dwelltime -= 50;
8086                echo = IN4500(ai,SWS1);
8087        } while (dwelltime >= 0 && echo != byte);
8088
8089        OUT4500(ai,SWS1,0);
8090
8091        return (echo == byte) ? 0 : -EIO;
8092}
8093
8094/*
8095 * Get a character from the card matching matchbyte
8096 * Step 3)
8097 */
8098static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
8099        int           rchar;
8100        unsigned char rbyte=0;
8101
8102        do {
8103                rchar = IN4500(ai,SWS1);
8104
8105                if(dwelltime && !(0x8000 & rchar)){
8106                        dwelltime -= 10;
8107                        mdelay(10);
8108                        continue;
8109                }
8110                rbyte = 0xff & rchar;
8111
8112                if( (rbyte == matchbyte) && (0x8000 & rchar) ){
8113                        OUT4500(ai,SWS1,0);
8114                        return 0;
8115                }
8116                if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
8117                        break;
8118                OUT4500(ai,SWS1,0);
8119
8120        }while(dwelltime > 0);
8121        return -EIO;
8122}
8123
8124/*
8125 * Transfer 32k of firmware data from user buffer to our buffer and
8126 * send to the card
8127 */
8128
8129static int flashputbuf(struct airo_info *ai){
8130        int            nwords;
8131
8132        /* Write stuff */
8133        if (test_bit(FLAG_MPI,&ai->flags))
8134                memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
8135        else {
8136                OUT4500(ai,AUXPAGE,0x100);
8137                OUT4500(ai,AUXOFF,0);
8138
8139                for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
8140                        OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
8141                }
8142        }
8143        OUT4500(ai,SWS0,0x8000);
8144
8145        return 0;
8146}
8147
8148/*
8149 *
8150 */
8151static int flashrestart(struct airo_info *ai,struct net_device *dev){
8152        int    i,status;
8153
8154        ssleep(1);                      /* Added 12/7/00 */
8155        clear_bit (FLAG_FLASHING, &ai->flags);
8156        if (test_bit(FLAG_MPI, &ai->flags)) {
8157                status = mpi_init_descriptors(ai);
8158                if (status != SUCCESS)
8159                        return status;
8160        }
8161        status = setup_card(ai, dev->dev_addr, 1);
8162
8163        if (!test_bit(FLAG_MPI,&ai->flags))
8164                for( i = 0; i < MAX_FIDS; i++ ) {
8165                        ai->fids[i] = transmit_allocate
8166                                ( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
8167                }
8168
8169        ssleep(1);                      /* Added 12/7/00 */
8170        return status;
8171}
8172#endif /* CISCO_EXT */
8173
8174/*
8175    This program is free software; you can redistribute it and/or
8176    modify it under the terms of the GNU General Public License
8177    as published by the Free Software Foundation; either version 2
8178    of the License, or (at your option) any later version.
8179
8180    This program is distributed in the hope that it will be useful,
8181    but WITHOUT ANY WARRANTY; without even the implied warranty of
8182    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8183    GNU General Public License for more details.
8184
8185    In addition:
8186
8187    Redistribution and use in source and binary forms, with or without
8188    modification, are permitted provided that the following conditions
8189    are met:
8190
8191    1. Redistributions of source code must retain the above copyright
8192       notice, this list of conditions and the following disclaimer.
8193    2. Redistributions in binary form must reproduce the above copyright
8194       notice, this list of conditions and the following disclaimer in the
8195       documentation and/or other materials provided with the distribution.
8196    3. The name of the author may not be used to endorse or promote
8197       products derived from this software without specific prior written
8198       permission.
8199
8200    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8201    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8202    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8203    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
8204    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8205    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8206    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8207    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8208    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
8209    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8210    POSSIBILITY OF SUCH DAMAGE.
8211*/
8212
8213module_init(airo_init_module);
8214module_exit(airo_cleanup_module);
8215