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