Linux Audio

Check our new training course

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