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