Linux Audio

Check our new training course

In-person Linux kernel drivers training

Jun 16-20, 2025
Register
Loading...
v4.17
   1/*======================================================================
   2
   3    Aironet driver for 4500 and 4800 series cards
   4
   5    This code is released under both the GPL version 2 and BSD licenses.
   6    Either license may be used.  The respective licenses are found at
   7    the end of this file.
   8
   9    This code was developed by Benjamin Reed <breed@users.sourceforge.net>
  10    including portions of which come from the Aironet PC4500
  11    Developer's Reference Manual and used with permission.  Copyright
  12    (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
  13    code in the Developer's manual was granted for this driver by
  14    Aironet.  Major code contributions were received from Javier Achirica
  15    <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
  16    Code was also integrated from the Cisco Aironet driver for Linux.
  17    Support for MPI350 cards was added by Fabrice Bellet
  18    <fabrice@bellet.info>.
  19
  20======================================================================*/
  21
  22#include <linux/err.h>
  23#include <linux/init.h>
  24
  25#include <linux/kernel.h>
  26#include <linux/module.h>
  27#include <linux/proc_fs.h>
  28
  29#include <linux/sched.h>
  30#include <linux/ptrace.h>
  31#include <linux/slab.h>
  32#include <linux/string.h>
  33#include <linux/timer.h>
  34#include <linux/interrupt.h>
  35#include <linux/in.h>
  36#include <linux/bitops.h>
  37#include <linux/scatterlist.h>
  38#include <linux/crypto.h>
  39#include <linux/io.h>
  40#include <asm/unaligned.h>
  41
  42#include <linux/netdevice.h>
  43#include <linux/etherdevice.h>
  44#include <linux/skbuff.h>
  45#include <linux/if_arp.h>
  46#include <linux/ioport.h>
  47#include <linux/pci.h>
  48#include <linux/uaccess.h>
  49#include <linux/kthread.h>
  50#include <linux/freezer.h>
  51
 
 
 
  52#include <net/cfg80211.h>
  53#include <net/iw_handler.h>
  54
  55#include "airo.h"
  56
  57#define DRV_NAME "airo"
  58
  59#ifdef CONFIG_PCI
  60static const struct pci_device_id card_ids[] = {
  61	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
  62	{ 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
  63	{ 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
  64	{ 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
  65	{ 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
  66	{ 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
  67	{ 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
  68	{ 0, }
  69};
  70MODULE_DEVICE_TABLE(pci, card_ids);
  71
  72static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
  73static void airo_pci_remove(struct pci_dev *);
  74static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
  75static int airo_pci_resume(struct pci_dev *pdev);
 
 
 
 
  76
  77static struct pci_driver airo_driver = {
  78	.name     = DRV_NAME,
  79	.id_table = card_ids,
  80	.probe    = airo_pci_probe,
  81	.remove   = airo_pci_remove,
  82	.suspend  = airo_pci_suspend,
  83	.resume   = airo_pci_resume,
  84};
  85#endif /* CONFIG_PCI */
  86
  87/* Include Wireless Extension definition and check version - Jean II */
  88#include <linux/wireless.h>
  89#define WIRELESS_SPY		/* enable iwspy support */
  90
  91#define CISCO_EXT		/* enable Cisco extensions */
  92#ifdef CISCO_EXT
  93#include <linux/delay.h>
  94#endif
  95
  96/* Hack to do some power saving */
  97#define POWER_ON_DOWN
  98
  99/* As you can see this list is HUGH!
 100   I really don't know what a lot of these counts are about, but they
 101   are all here for completeness.  If the IGNLABEL macro is put in
 102   infront of the label, that statistic will not be included in the list
 103   of statistics in the /proc filesystem */
 104
 105#define IGNLABEL(comment) NULL
 106static const char *statsLabels[] = {
 107	"RxOverrun",
 108	IGNLABEL("RxPlcpCrcErr"),
 109	IGNLABEL("RxPlcpFormatErr"),
 110	IGNLABEL("RxPlcpLengthErr"),
 111	"RxMacCrcErr",
 112	"RxMacCrcOk",
 113	"RxWepErr",
 114	"RxWepOk",
 115	"RetryLong",
 116	"RetryShort",
 117	"MaxRetries",
 118	"NoAck",
 119	"NoCts",
 120	"RxAck",
 121	"RxCts",
 122	"TxAck",
 123	"TxRts",
 124	"TxCts",
 125	"TxMc",
 126	"TxBc",
 127	"TxUcFrags",
 128	"TxUcPackets",
 129	"TxBeacon",
 130	"RxBeacon",
 131	"TxSinColl",
 132	"TxMulColl",
 133	"DefersNo",
 134	"DefersProt",
 135	"DefersEngy",
 136	"DupFram",
 137	"RxFragDisc",
 138	"TxAged",
 139	"RxAged",
 140	"LostSync-MaxRetry",
 141	"LostSync-MissedBeacons",
 142	"LostSync-ArlExceeded",
 143	"LostSync-Deauth",
 144	"LostSync-Disassoced",
 145	"LostSync-TsfTiming",
 146	"HostTxMc",
 147	"HostTxBc",
 148	"HostTxUc",
 149	"HostTxFail",
 150	"HostRxMc",
 151	"HostRxBc",
 152	"HostRxUc",
 153	"HostRxDiscard",
 154	IGNLABEL("HmacTxMc"),
 155	IGNLABEL("HmacTxBc"),
 156	IGNLABEL("HmacTxUc"),
 157	IGNLABEL("HmacTxFail"),
 158	IGNLABEL("HmacRxMc"),
 159	IGNLABEL("HmacRxBc"),
 160	IGNLABEL("HmacRxUc"),
 161	IGNLABEL("HmacRxDiscard"),
 162	IGNLABEL("HmacRxAccepted"),
 163	"SsidMismatch",
 164	"ApMismatch",
 165	"RatesMismatch",
 166	"AuthReject",
 167	"AuthTimeout",
 168	"AssocReject",
 169	"AssocTimeout",
 170	IGNLABEL("ReasonOutsideTable"),
 171	IGNLABEL("ReasonStatus1"),
 172	IGNLABEL("ReasonStatus2"),
 173	IGNLABEL("ReasonStatus3"),
 174	IGNLABEL("ReasonStatus4"),
 175	IGNLABEL("ReasonStatus5"),
 176	IGNLABEL("ReasonStatus6"),
 177	IGNLABEL("ReasonStatus7"),
 178	IGNLABEL("ReasonStatus8"),
 179	IGNLABEL("ReasonStatus9"),
 180	IGNLABEL("ReasonStatus10"),
 181	IGNLABEL("ReasonStatus11"),
 182	IGNLABEL("ReasonStatus12"),
 183	IGNLABEL("ReasonStatus13"),
 184	IGNLABEL("ReasonStatus14"),
 185	IGNLABEL("ReasonStatus15"),
 186	IGNLABEL("ReasonStatus16"),
 187	IGNLABEL("ReasonStatus17"),
 188	IGNLABEL("ReasonStatus18"),
 189	IGNLABEL("ReasonStatus19"),
 190	"RxMan",
 191	"TxMan",
 192	"RxRefresh",
 193	"TxRefresh",
 194	"RxPoll",
 195	"TxPoll",
 196	"HostRetries",
 197	"LostSync-HostReq",
 198	"HostTxBytes",
 199	"HostRxBytes",
 200	"ElapsedUsec",
 201	"ElapsedSec",
 202	"LostSyncBetterAP",
 203	"PrivacyMismatch",
 204	"Jammed",
 205	"DiscRxNotWepped",
 206	"PhyEleMismatch",
 207	(char*)-1 };
 208#ifndef RUN_AT
 209#define RUN_AT(x) (jiffies+(x))
 210#endif
 211
 212
 213/* These variables are for insmod, since it seems that the rates
 214   can only be set in setup_card.  Rates should be a comma separated
 215   (no spaces) list of rates (up to 8). */
 216
 217static int rates[8];
 218static char *ssids[3];
 219
 220static int io[4];
 221static int irq[4];
 222
 223static
 224int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
 225		       0 means no limit.  For old cards this was 4 */
 226
 227static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
 228static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
 229		    the bap, needed on some older cards and buses. */
 230static int adhoc;
 231
 232static int probe = 1;
 233
 234static kuid_t proc_kuid;
 235static int proc_uid /* = 0 */;
 236
 237static kgid_t proc_kgid;
 238static int proc_gid /* = 0 */;
 239
 240static int airo_perm = 0555;
 241
 242static int proc_perm = 0644;
 243
 244MODULE_AUTHOR("Benjamin Reed");
 245MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards.  "
 246		   "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.");
 247MODULE_LICENSE("Dual BSD/GPL");
 248MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
 249module_param_hw_array(io, int, ioport, NULL, 0);
 250module_param_hw_array(irq, int, irq, NULL, 0);
 251module_param_array(rates, int, NULL, 0);
 252module_param_array(ssids, charp, NULL, 0);
 253module_param(auto_wep, int, 0);
 254MODULE_PARM_DESC(auto_wep,
 255		 "If non-zero, the driver will keep looping through the authentication options until an association is made.  "
 256		 "The value of auto_wep is number of the wep keys to check.  "
 257		 "A value of 2 will try using the key at index 0 and index 1.");
 258module_param(aux_bap, int, 0);
 259MODULE_PARM_DESC(aux_bap,
 260		 "If non-zero, the driver will switch into a mode that seems to work better for older cards with some older buses.  "
 261		 "Before switching it checks that the switch is needed.");
 262module_param(maxencrypt, int, 0);
 263MODULE_PARM_DESC(maxencrypt,
 264		 "The maximum speed that the card can do encryption.  "
 265		 "Units are in 512kbs.  "
 266		 "Zero (default) means there is no limit.  "
 267		 "Older cards used to be limited to 2mbs (4).");
 268module_param(adhoc, int, 0);
 269MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
 270module_param(probe, int, 0);
 271MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
 272
 273module_param(proc_uid, int, 0);
 274MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
 275module_param(proc_gid, int, 0);
 276MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
 277module_param(airo_perm, int, 0);
 278MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
 279module_param(proc_perm, int, 0);
 280MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
 281
 282/* This is a kind of sloppy hack to get this information to OUT4500 and
 283   IN4500.  I would be extremely interested in the situation where this
 284   doesn't work though!!! */
 285static int do8bitIO /* = 0 */;
 286
 287/* Return codes */
 288#define SUCCESS 0
 289#define ERROR -1
 290#define NO_PACKET -2
 291
 292/* Commands */
 293#define NOP2		0x0000
 294#define MAC_ENABLE	0x0001
 295#define MAC_DISABLE	0x0002
 296#define CMD_LOSE_SYNC	0x0003 /* Not sure what this does... */
 297#define CMD_SOFTRESET	0x0004
 298#define HOSTSLEEP	0x0005
 299#define CMD_MAGIC_PKT	0x0006
 300#define CMD_SETWAKEMASK	0x0007
 301#define CMD_READCFG	0x0008
 302#define CMD_SETMODE	0x0009
 303#define CMD_ALLOCATETX	0x000a
 304#define CMD_TRANSMIT	0x000b
 305#define CMD_DEALLOCATETX 0x000c
 306#define NOP		0x0010
 307#define CMD_WORKAROUND	0x0011
 308#define CMD_ALLOCATEAUX 0x0020
 309#define CMD_ACCESS	0x0021
 310#define CMD_PCIBAP	0x0022
 311#define CMD_PCIAUX	0x0023
 312#define CMD_ALLOCBUF	0x0028
 313#define CMD_GETTLV	0x0029
 314#define CMD_PUTTLV	0x002a
 315#define CMD_DELTLV	0x002b
 316#define CMD_FINDNEXTTLV	0x002c
 317#define CMD_PSPNODES	0x0030
 318#define CMD_SETCW	0x0031    
 319#define CMD_SETPCF	0x0032    
 320#define CMD_SETPHYREG	0x003e
 321#define CMD_TXTEST	0x003f
 322#define MAC_ENABLETX	0x0101
 323#define CMD_LISTBSS	0x0103
 324#define CMD_SAVECFG	0x0108
 325#define CMD_ENABLEAUX	0x0111
 326#define CMD_WRITERID	0x0121
 327#define CMD_USEPSPNODES	0x0130
 328#define MAC_ENABLERX	0x0201
 329
 330/* Command errors */
 331#define ERROR_QUALIF 0x00
 332#define ERROR_ILLCMD 0x01
 333#define ERROR_ILLFMT 0x02
 334#define ERROR_INVFID 0x03
 335#define ERROR_INVRID 0x04
 336#define ERROR_LARGE 0x05
 337#define ERROR_NDISABL 0x06
 338#define ERROR_ALLOCBSY 0x07
 339#define ERROR_NORD 0x0B
 340#define ERROR_NOWR 0x0C
 341#define ERROR_INVFIDTX 0x0D
 342#define ERROR_TESTACT 0x0E
 343#define ERROR_TAGNFND 0x12
 344#define ERROR_DECODE 0x20
 345#define ERROR_DESCUNAV 0x21
 346#define ERROR_BADLEN 0x22
 347#define ERROR_MODE 0x80
 348#define ERROR_HOP 0x81
 349#define ERROR_BINTER 0x82
 350#define ERROR_RXMODE 0x83
 351#define ERROR_MACADDR 0x84
 352#define ERROR_RATES 0x85
 353#define ERROR_ORDER 0x86
 354#define ERROR_SCAN 0x87
 355#define ERROR_AUTH 0x88
 356#define ERROR_PSMODE 0x89
 357#define ERROR_RTYPE 0x8A
 358#define ERROR_DIVER 0x8B
 359#define ERROR_SSID 0x8C
 360#define ERROR_APLIST 0x8D
 361#define ERROR_AUTOWAKE 0x8E
 362#define ERROR_LEAP 0x8F
 363
 364/* Registers */
 365#define COMMAND 0x00
 366#define PARAM0 0x02
 367#define PARAM1 0x04
 368#define PARAM2 0x06
 369#define STATUS 0x08
 370#define RESP0 0x0a
 371#define RESP1 0x0c
 372#define RESP2 0x0e
 373#define LINKSTAT 0x10
 374#define SELECT0 0x18
 375#define OFFSET0 0x1c
 376#define RXFID 0x20
 377#define TXALLOCFID 0x22
 378#define TXCOMPLFID 0x24
 379#define DATA0 0x36
 380#define EVSTAT 0x30
 381#define EVINTEN 0x32
 382#define EVACK 0x34
 383#define SWS0 0x28
 384#define SWS1 0x2a
 385#define SWS2 0x2c
 386#define SWS3 0x2e
 387#define AUXPAGE 0x3A
 388#define AUXOFF 0x3C
 389#define AUXDATA 0x3E
 390
 391#define FID_TX 1
 392#define FID_RX 2
 393/* Offset into aux memory for descriptors */
 394#define AUX_OFFSET 0x800
 395/* Size of allocated packets */
 396#define PKTSIZE 1840
 397#define RIDSIZE 2048
 398/* Size of the transmit queue */
 399#define MAXTXQ 64
 400
 401/* BAP selectors */
 402#define BAP0 0 /* Used for receiving packets */
 403#define BAP1 2 /* Used for xmiting packets and working with RIDS */
 404
 405/* Flags */
 406#define COMMAND_BUSY 0x8000
 407
 408#define BAP_BUSY 0x8000
 409#define BAP_ERR 0x4000
 410#define BAP_DONE 0x2000
 411
 412#define PROMISC 0xffff
 413#define NOPROMISC 0x0000
 414
 415#define EV_CMD 0x10
 416#define EV_CLEARCOMMANDBUSY 0x4000
 417#define EV_RX 0x01
 418#define EV_TX 0x02
 419#define EV_TXEXC 0x04
 420#define EV_ALLOC 0x08
 421#define EV_LINK 0x80
 422#define EV_AWAKE 0x100
 423#define EV_TXCPY 0x400
 424#define EV_UNKNOWN 0x800
 425#define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
 426#define EV_AWAKEN 0x2000
 427#define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
 428
 429#ifdef CHECK_UNKNOWN_INTS
 430#define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
 431#else
 432#define IGNORE_INTS (~STATUS_INTS)
 433#endif
 434
 435/* RID TYPES */
 436#define RID_RW 0x20
 437
 438/* The RIDs */
 439#define RID_CAPABILITIES 0xFF00
 440#define RID_APINFO     0xFF01
 441#define RID_RADIOINFO  0xFF02
 442#define RID_UNKNOWN3   0xFF03
 443#define RID_RSSI       0xFF04
 444#define RID_CONFIG     0xFF10
 445#define RID_SSID       0xFF11
 446#define RID_APLIST     0xFF12
 447#define RID_DRVNAME    0xFF13
 448#define RID_ETHERENCAP 0xFF14
 449#define RID_WEP_TEMP   0xFF15
 450#define RID_WEP_PERM   0xFF16
 451#define RID_MODULATION 0xFF17
 452#define RID_OPTIONS    0xFF18
 453#define RID_ACTUALCONFIG 0xFF20 /*readonly*/
 454#define RID_FACTORYCONFIG 0xFF21
 455#define RID_UNKNOWN22  0xFF22
 456#define RID_LEAPUSERNAME 0xFF23
 457#define RID_LEAPPASSWORD 0xFF24
 458#define RID_STATUS     0xFF50
 459#define RID_BEACON_HST 0xFF51
 460#define RID_BUSY_HST   0xFF52
 461#define RID_RETRIES_HST 0xFF53
 462#define RID_UNKNOWN54  0xFF54
 463#define RID_UNKNOWN55  0xFF55
 464#define RID_UNKNOWN56  0xFF56
 465#define RID_MIC        0xFF57
 466#define RID_STATS16    0xFF60
 467#define RID_STATS16DELTA 0xFF61
 468#define RID_STATS16DELTACLEAR 0xFF62
 469#define RID_STATS      0xFF68
 470#define RID_STATSDELTA 0xFF69
 471#define RID_STATSDELTACLEAR 0xFF6A
 472#define RID_ECHOTEST_RID 0xFF70
 473#define RID_ECHOTEST_RESULTS 0xFF71
 474#define RID_BSSLISTFIRST 0xFF72
 475#define RID_BSSLISTNEXT  0xFF73
 476#define RID_WPA_BSSLISTFIRST 0xFF74
 477#define RID_WPA_BSSLISTNEXT  0xFF75
 478
 479typedef struct {
 480	u16 cmd;
 481	u16 parm0;
 482	u16 parm1;
 483	u16 parm2;
 484} Cmd;
 485
 486typedef struct {
 487	u16 status;
 488	u16 rsp0;
 489	u16 rsp1;
 490	u16 rsp2;
 491} Resp;
 492
 493/*
 494 * Rids and endian-ness:  The Rids will always be in cpu endian, since
 495 * this all the patches from the big-endian guys end up doing that.
 496 * so all rid access should use the read/writeXXXRid routines.
 497 */
 498
 499/* This structure came from an email sent to me from an engineer at
 500   aironet for inclusion into this driver */
 501typedef struct WepKeyRid WepKeyRid;
 502struct WepKeyRid {
 503	__le16 len;
 504	__le16 kindex;
 505	u8 mac[ETH_ALEN];
 506	__le16 klen;
 507	u8 key[16];
 508} __packed;
 509
 510/* These structures are from the Aironet's PC4500 Developers Manual */
 511typedef struct Ssid Ssid;
 512struct Ssid {
 513	__le16 len;
 514	u8 ssid[32];
 515} __packed;
 516
 517typedef struct SsidRid SsidRid;
 518struct SsidRid {
 519	__le16 len;
 520	Ssid ssids[3];
 521} __packed;
 522
 523typedef struct ModulationRid ModulationRid;
 524struct ModulationRid {
 525        __le16 len;
 526        __le16 modulation;
 527#define MOD_DEFAULT cpu_to_le16(0)
 528#define MOD_CCK cpu_to_le16(1)
 529#define MOD_MOK cpu_to_le16(2)
 530} __packed;
 531
 532typedef struct ConfigRid ConfigRid;
 533struct ConfigRid {
 534	__le16 len; /* sizeof(ConfigRid) */
 535	__le16 opmode; /* operating mode */
 536#define MODE_STA_IBSS cpu_to_le16(0)
 537#define MODE_STA_ESS cpu_to_le16(1)
 538#define MODE_AP cpu_to_le16(2)
 539#define MODE_AP_RPTR cpu_to_le16(3)
 540#define MODE_CFG_MASK cpu_to_le16(0xff)
 541#define MODE_ETHERNET_HOST cpu_to_le16(0<<8) /* rx payloads converted */
 542#define MODE_LLC_HOST cpu_to_le16(1<<8) /* rx payloads left as is */
 543#define MODE_AIRONET_EXTEND cpu_to_le16(1<<9) /* enable Aironet extenstions */
 544#define MODE_AP_INTERFACE cpu_to_le16(1<<10) /* enable ap interface extensions */
 545#define MODE_ANTENNA_ALIGN cpu_to_le16(1<<11) /* enable antenna alignment */
 546#define MODE_ETHER_LLC cpu_to_le16(1<<12) /* enable ethernet LLC */
 547#define MODE_LEAF_NODE cpu_to_le16(1<<13) /* enable leaf node bridge */
 548#define MODE_CF_POLLABLE cpu_to_le16(1<<14) /* enable CF pollable */
 549#define MODE_MIC cpu_to_le16(1<<15) /* enable MIC */
 550	__le16 rmode; /* receive mode */
 551#define RXMODE_BC_MC_ADDR cpu_to_le16(0)
 552#define RXMODE_BC_ADDR cpu_to_le16(1) /* ignore multicasts */
 553#define RXMODE_ADDR cpu_to_le16(2) /* ignore multicast and broadcast */
 554#define RXMODE_RFMON cpu_to_le16(3) /* wireless monitor mode */
 555#define RXMODE_RFMON_ANYBSS cpu_to_le16(4)
 556#define RXMODE_LANMON cpu_to_le16(5) /* lan style monitor -- data packets only */
 557#define RXMODE_MASK cpu_to_le16(255)
 558#define RXMODE_DISABLE_802_3_HEADER cpu_to_le16(1<<8) /* disables 802.3 header on rx */
 559#define RXMODE_FULL_MASK (RXMODE_MASK | RXMODE_DISABLE_802_3_HEADER)
 560#define RXMODE_NORMALIZED_RSSI cpu_to_le16(1<<9) /* return normalized RSSI */
 561	__le16 fragThresh;
 562	__le16 rtsThres;
 563	u8 macAddr[ETH_ALEN];
 564	u8 rates[8];
 565	__le16 shortRetryLimit;
 566	__le16 longRetryLimit;
 567	__le16 txLifetime; /* in kusec */
 568	__le16 rxLifetime; /* in kusec */
 569	__le16 stationary;
 570	__le16 ordering;
 571	__le16 u16deviceType; /* for overriding device type */
 572	__le16 cfpRate;
 573	__le16 cfpDuration;
 574	__le16 _reserved1[3];
 575	/*---------- Scanning/Associating ----------*/
 576	__le16 scanMode;
 577#define SCANMODE_ACTIVE cpu_to_le16(0)
 578#define SCANMODE_PASSIVE cpu_to_le16(1)
 579#define SCANMODE_AIROSCAN cpu_to_le16(2)
 580	__le16 probeDelay; /* in kusec */
 581	__le16 probeEnergyTimeout; /* in kusec */
 582        __le16 probeResponseTimeout;
 583	__le16 beaconListenTimeout;
 584	__le16 joinNetTimeout;
 585	__le16 authTimeout;
 586	__le16 authType;
 587#define AUTH_OPEN cpu_to_le16(0x1)
 588#define AUTH_ENCRYPT cpu_to_le16(0x101)
 589#define AUTH_SHAREDKEY cpu_to_le16(0x102)
 590#define AUTH_ALLOW_UNENCRYPTED cpu_to_le16(0x200)
 591	__le16 associationTimeout;
 592	__le16 specifiedApTimeout;
 593	__le16 offlineScanInterval;
 594	__le16 offlineScanDuration;
 595	__le16 linkLossDelay;
 596	__le16 maxBeaconLostTime;
 597	__le16 refreshInterval;
 598#define DISABLE_REFRESH cpu_to_le16(0xFFFF)
 599	__le16 _reserved1a[1];
 600	/*---------- Power save operation ----------*/
 601	__le16 powerSaveMode;
 602#define POWERSAVE_CAM cpu_to_le16(0)
 603#define POWERSAVE_PSP cpu_to_le16(1)
 604#define POWERSAVE_PSPCAM cpu_to_le16(2)
 605	__le16 sleepForDtims;
 606	__le16 listenInterval;
 607	__le16 fastListenInterval;
 608	__le16 listenDecay;
 609	__le16 fastListenDelay;
 610	__le16 _reserved2[2];
 611	/*---------- Ap/Ibss config items ----------*/
 612	__le16 beaconPeriod;
 613	__le16 atimDuration;
 614	__le16 hopPeriod;
 615	__le16 channelSet;
 616	__le16 channel;
 617	__le16 dtimPeriod;
 618	__le16 bridgeDistance;
 619	__le16 radioID;
 620	/*---------- Radio configuration ----------*/
 621	__le16 radioType;
 622#define RADIOTYPE_DEFAULT cpu_to_le16(0)
 623#define RADIOTYPE_802_11 cpu_to_le16(1)
 624#define RADIOTYPE_LEGACY cpu_to_le16(2)
 625	u8 rxDiversity;
 626	u8 txDiversity;
 627	__le16 txPower;
 628#define TXPOWER_DEFAULT 0
 629	__le16 rssiThreshold;
 630#define RSSI_DEFAULT 0
 631        __le16 modulation;
 632#define PREAMBLE_AUTO cpu_to_le16(0)
 633#define PREAMBLE_LONG cpu_to_le16(1)
 634#define PREAMBLE_SHORT cpu_to_le16(2)
 635	__le16 preamble;
 636	__le16 homeProduct;
 637	__le16 radioSpecific;
 638	/*---------- Aironet Extensions ----------*/
 639	u8 nodeName[16];
 640	__le16 arlThreshold;
 641	__le16 arlDecay;
 642	__le16 arlDelay;
 643	__le16 _reserved4[1];
 644	/*---------- Aironet Extensions ----------*/
 645	u8 magicAction;
 646#define MAGIC_ACTION_STSCHG 1
 647#define MAGIC_ACTION_RESUME 2
 648#define MAGIC_IGNORE_MCAST (1<<8)
 649#define MAGIC_IGNORE_BCAST (1<<9)
 650#define MAGIC_SWITCH_TO_PSP (0<<10)
 651#define MAGIC_STAY_IN_CAM (1<<10)
 652	u8 magicControl;
 653	__le16 autoWake;
 654} __packed;
 655
 656typedef struct StatusRid StatusRid;
 657struct StatusRid {
 658	__le16 len;
 659	u8 mac[ETH_ALEN];
 660	__le16 mode;
 661	__le16 errorCode;
 662	__le16 sigQuality;
 663	__le16 SSIDlen;
 664	char SSID[32];
 665	char apName[16];
 666	u8 bssid[4][ETH_ALEN];
 667	__le16 beaconPeriod;
 668	__le16 dimPeriod;
 669	__le16 atimDuration;
 670	__le16 hopPeriod;
 671	__le16 channelSet;
 672	__le16 channel;
 673	__le16 hopsToBackbone;
 674	__le16 apTotalLoad;
 675	__le16 generatedLoad;
 676	__le16 accumulatedArl;
 677	__le16 signalQuality;
 678	__le16 currentXmitRate;
 679	__le16 apDevExtensions;
 680	__le16 normalizedSignalStrength;
 681	__le16 shortPreamble;
 682	u8 apIP[4];
 683	u8 noisePercent; /* Noise percent in last second */
 684	u8 noisedBm; /* Noise dBm in last second */
 685	u8 noiseAvePercent; /* Noise percent in last minute */
 686	u8 noiseAvedBm; /* Noise dBm in last minute */
 687	u8 noiseMaxPercent; /* Highest noise percent in last minute */
 688	u8 noiseMaxdBm; /* Highest noise dbm in last minute */
 689	__le16 load;
 690	u8 carrier[4];
 691	__le16 assocStatus;
 692#define STAT_NOPACKETS 0
 693#define STAT_NOCARRIERSET 10
 694#define STAT_GOTCARRIERSET 11
 695#define STAT_WRONGSSID 20
 696#define STAT_BADCHANNEL 25
 697#define STAT_BADBITRATES 30
 698#define STAT_BADPRIVACY 35
 699#define STAT_APFOUND 40
 700#define STAT_APREJECTED 50
 701#define STAT_AUTHENTICATING 60
 702#define STAT_DEAUTHENTICATED 61
 703#define STAT_AUTHTIMEOUT 62
 704#define STAT_ASSOCIATING 70
 705#define STAT_DEASSOCIATED 71
 706#define STAT_ASSOCTIMEOUT 72
 707#define STAT_NOTAIROAP 73
 708#define STAT_ASSOCIATED 80
 709#define STAT_LEAPING 90
 710#define STAT_LEAPFAILED 91
 711#define STAT_LEAPTIMEDOUT 92
 712#define STAT_LEAPCOMPLETE 93
 713} __packed;
 714
 715typedef struct StatsRid StatsRid;
 716struct StatsRid {
 717	__le16 len;
 718	__le16 spacer;
 719	__le32 vals[100];
 720} __packed;
 721
 722typedef struct APListRid APListRid;
 723struct APListRid {
 724	__le16 len;
 725	u8 ap[4][ETH_ALEN];
 726} __packed;
 727
 728typedef struct CapabilityRid CapabilityRid;
 729struct CapabilityRid {
 730	__le16 len;
 731	char oui[3];
 732	char zero;
 733	__le16 prodNum;
 734	char manName[32];
 735	char prodName[16];
 736	char prodVer[8];
 737	char factoryAddr[ETH_ALEN];
 738	char aironetAddr[ETH_ALEN];
 739	__le16 radioType;
 740	__le16 country;
 741	char callid[ETH_ALEN];
 742	char supportedRates[8];
 743	char rxDiversity;
 744	char txDiversity;
 745	__le16 txPowerLevels[8];
 746	__le16 hardVer;
 747	__le16 hardCap;
 748	__le16 tempRange;
 749	__le16 softVer;
 750	__le16 softSubVer;
 751	__le16 interfaceVer;
 752	__le16 softCap;
 753	__le16 bootBlockVer;
 754	__le16 requiredHard;
 755	__le16 extSoftCap;
 756} __packed;
 757
 758/* Only present on firmware >= 5.30.17 */
 759typedef struct BSSListRidExtra BSSListRidExtra;
 760struct BSSListRidExtra {
 761  __le16 unknown[4];
 762  u8 fixed[12]; /* WLAN management frame */
 763  u8 iep[624];
 764} __packed;
 765
 766typedef struct BSSListRid BSSListRid;
 767struct BSSListRid {
 768  __le16 len;
 769  __le16 index; /* First is 0 and 0xffff means end of list */
 770#define RADIO_FH 1 /* Frequency hopping radio type */
 771#define RADIO_DS 2 /* Direct sequence radio type */
 772#define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
 773  __le16 radioType;
 774  u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
 775  u8 zero;
 776  u8 ssidLen;
 777  u8 ssid[32];
 778  __le16 dBm;
 779#define CAP_ESS cpu_to_le16(1<<0)
 780#define CAP_IBSS cpu_to_le16(1<<1)
 781#define CAP_PRIVACY cpu_to_le16(1<<4)
 782#define CAP_SHORTHDR cpu_to_le16(1<<5)
 783  __le16 cap;
 784  __le16 beaconInterval;
 785  u8 rates[8]; /* Same as rates for config rid */
 786  struct { /* For frequency hopping only */
 787    __le16 dwell;
 788    u8 hopSet;
 789    u8 hopPattern;
 790    u8 hopIndex;
 791    u8 fill;
 792  } fh;
 793  __le16 dsChannel;
 794  __le16 atimWindow;
 795
 796  /* Only present on firmware >= 5.30.17 */
 797  BSSListRidExtra extra;
 798} __packed;
 799
 800typedef struct {
 801  BSSListRid bss;
 802  struct list_head list;
 803} BSSListElement;
 804
 805typedef struct tdsRssiEntry tdsRssiEntry;
 806struct tdsRssiEntry {
 807  u8 rssipct;
 808  u8 rssidBm;
 809} __packed;
 810
 811typedef struct tdsRssiRid tdsRssiRid;
 812struct tdsRssiRid {
 813  u16 len;
 814  tdsRssiEntry x[256];
 815} __packed;
 816
 817typedef struct MICRid MICRid;
 818struct MICRid {
 819	__le16 len;
 820	__le16 state;
 821	__le16 multicastValid;
 822	u8  multicast[16];
 823	__le16 unicastValid;
 824	u8  unicast[16];
 825} __packed;
 826
 827typedef struct MICBuffer MICBuffer;
 828struct MICBuffer {
 829	__be16 typelen;
 830
 831	union {
 832	    u8 snap[8];
 833	    struct {
 834		u8 dsap;
 835		u8 ssap;
 836		u8 control;
 837		u8 orgcode[3];
 838		u8 fieldtype[2];
 839	    } llc;
 840	} u;
 841	__be32 mic;
 842	__be32 seq;
 843} __packed;
 844
 845typedef struct {
 846	u8 da[ETH_ALEN];
 847	u8 sa[ETH_ALEN];
 848} etherHead;
 849
 850#define TXCTL_TXOK (1<<1) /* report if tx is ok */
 851#define TXCTL_TXEX (1<<2) /* report if tx fails */
 852#define TXCTL_802_3 (0<<3) /* 802.3 packet */
 853#define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
 854#define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
 855#define TXCTL_LLC (1<<4) /* payload is llc */
 856#define TXCTL_RELEASE (0<<5) /* release after completion */
 857#define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
 858
 859#define BUSY_FID 0x10000
 860
 861#ifdef CISCO_EXT
 862#define AIROMAGIC	0xa55a
 863/* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
 864#ifdef SIOCIWFIRSTPRIV
 865#ifdef SIOCDEVPRIVATE
 866#define AIROOLDIOCTL	SIOCDEVPRIVATE
 867#define AIROOLDIDIFC 	AIROOLDIOCTL + 1
 868#endif /* SIOCDEVPRIVATE */
 869#else /* SIOCIWFIRSTPRIV */
 870#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
 871#endif /* SIOCIWFIRSTPRIV */
 872/* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
 873 * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
 874 * only and don't return the modified struct ifreq to the application which
 875 * is usually a problem. - Jean II */
 876#define AIROIOCTL	SIOCIWFIRSTPRIV
 877#define AIROIDIFC 	AIROIOCTL + 1
 878
 879/* Ioctl constants to be used in airo_ioctl.command */
 880
 881#define	AIROGCAP  		0	// Capability rid
 882#define AIROGCFG		1       // USED A LOT
 883#define AIROGSLIST		2	// System ID list
 884#define AIROGVLIST		3       // List of specified AP's
 885#define AIROGDRVNAM		4	//  NOTUSED
 886#define AIROGEHTENC		5	// NOTUSED
 887#define AIROGWEPKTMP		6
 888#define AIROGWEPKNV		7
 889#define AIROGSTAT		8
 890#define AIROGSTATSC32		9
 891#define AIROGSTATSD32		10
 892#define AIROGMICRID		11
 893#define AIROGMICSTATS		12
 894#define AIROGFLAGS		13
 895#define AIROGID			14
 896#define AIRORRID		15
 897#define AIRORSWVERSION		17
 898
 899/* Leave gap of 40 commands after AIROGSTATSD32 for future */
 900
 901#define AIROPCAP               	AIROGSTATSD32 + 40
 902#define AIROPVLIST              AIROPCAP      + 1
 903#define AIROPSLIST		AIROPVLIST    + 1
 904#define AIROPCFG		AIROPSLIST    + 1
 905#define AIROPSIDS		AIROPCFG      + 1
 906#define AIROPAPLIST		AIROPSIDS     + 1
 907#define AIROPMACON		AIROPAPLIST   + 1	/* Enable mac  */
 908#define AIROPMACOFF		AIROPMACON    + 1 	/* Disable mac */
 909#define AIROPSTCLR		AIROPMACOFF   + 1
 910#define AIROPWEPKEY		AIROPSTCLR    + 1
 911#define AIROPWEPKEYNV		AIROPWEPKEY   + 1
 912#define AIROPLEAPPWD            AIROPWEPKEYNV + 1
 913#define AIROPLEAPUSR            AIROPLEAPPWD  + 1
 914
 915/* Flash codes */
 916
 917#define AIROFLSHRST	       AIROPWEPKEYNV  + 40
 918#define AIROFLSHGCHR           AIROFLSHRST    + 1
 919#define AIROFLSHSTFL           AIROFLSHGCHR   + 1
 920#define AIROFLSHPCHR           AIROFLSHSTFL   + 1
 921#define AIROFLPUTBUF           AIROFLSHPCHR   + 1
 922#define AIRORESTART            AIROFLPUTBUF   + 1
 923
 924#define FLASHSIZE	32768
 925#define AUXMEMSIZE	(256 * 1024)
 926
 927typedef struct aironet_ioctl {
 928	unsigned short command;		// What to do
 929	unsigned short len;		// Len of data
 930	unsigned short ridnum;		// rid number
 931	unsigned char __user *data;	// d-data
 932} aironet_ioctl;
 933
 934static const char swversion[] = "2.1";
 935#endif /* CISCO_EXT */
 936
 937#define NUM_MODULES       2
 938#define MIC_MSGLEN_MAX    2400
 939#define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
 940#define AIRO_DEF_MTU      2312
 941
 942typedef struct {
 943	u32   size;            // size
 944	u8    enabled;         // MIC enabled or not
 945	u32   rxSuccess;       // successful packets received
 946	u32   rxIncorrectMIC;  // pkts dropped due to incorrect MIC comparison
 947	u32   rxNotMICed;      // pkts dropped due to not being MIC'd
 948	u32   rxMICPlummed;    // pkts dropped due to not having a MIC plummed
 949	u32   rxWrongSequence; // pkts dropped due to sequence number violation
 950	u32   reserve[32];
 951} mic_statistics;
 952
 953typedef struct {
 954	u32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
 955	u64 accum;	// accumulated mic, reduced to u32 in final()
 956	int position;	// current position (byte offset) in message
 957	union {
 958		u8  d8[4];
 959		__be32 d32;
 960	} part;	// saves partial message word across update() calls
 961} emmh32_context;
 962
 963typedef struct {
 964	emmh32_context seed;	    // Context - the seed
 965	u32		 rx;	    // Received sequence number
 966	u32		 tx;	    // Tx sequence number
 967	u32		 window;    // Start of window
 968	u8		 valid;	    // Flag to say if context is valid or not
 969	u8		 key[16];
 970} miccntx;
 971
 972typedef struct {
 973	miccntx mCtx;		// Multicast context
 974	miccntx uCtx;		// Unicast context
 975} mic_module;
 976
 977typedef struct {
 978	unsigned int  rid: 16;
 979	unsigned int  len: 15;
 980	unsigned int  valid: 1;
 981	dma_addr_t host_addr;
 982} Rid;
 983
 984typedef struct {
 985	unsigned int  offset: 15;
 986	unsigned int  eoc: 1;
 987	unsigned int  len: 15;
 988	unsigned int  valid: 1;
 989	dma_addr_t host_addr;
 990} TxFid;
 991
 992struct rx_hdr {
 993	__le16 status, len;
 994	u8 rssi[2];
 995	u8 rate;
 996	u8 freq;
 997	__le16 tmp[4];
 998} __packed;
 999
1000typedef struct {
1001	unsigned int  ctl: 15;
1002	unsigned int  rdy: 1;
1003	unsigned int  len: 15;
1004	unsigned int  valid: 1;
1005	dma_addr_t host_addr;
1006} RxFid;
1007
1008/*
1009 * Host receive descriptor
1010 */
1011typedef struct {
1012	unsigned char __iomem *card_ram_off; /* offset into card memory of the
1013						desc */
1014	RxFid         rx_desc;		     /* card receive descriptor */
1015	char          *virtual_host_addr;    /* virtual address of host receive
1016					        buffer */
1017	int           pending;
1018} HostRxDesc;
1019
1020/*
1021 * Host transmit descriptor
1022 */
1023typedef struct {
1024	unsigned char __iomem *card_ram_off;	     /* offset into card memory of the
1025						desc */
1026	TxFid         tx_desc;		     /* card transmit descriptor */
1027	char          *virtual_host_addr;    /* virtual address of host receive
1028					        buffer */
1029	int           pending;
1030} HostTxDesc;
1031
1032/*
1033 * Host RID descriptor
1034 */
1035typedef struct {
1036	unsigned char __iomem *card_ram_off;      /* offset into card memory of the
1037					     descriptor */
1038	Rid           rid_desc;		  /* card RID descriptor */
1039	char          *virtual_host_addr; /* virtual address of host receive
1040					     buffer */
1041} HostRidDesc;
1042
1043typedef struct {
1044	u16 sw0;
1045	u16 sw1;
1046	u16 status;
1047	u16 len;
1048#define HOST_SET (1 << 0)
1049#define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
1050#define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
1051#define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
1052#define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
1053#define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
1054#define HOST_CLR_AID (1 << 7) /* clear AID failure */
1055#define HOST_RTS (1 << 9) /* Force RTS use */
1056#define HOST_SHORT (1 << 10) /* Do short preamble */
1057	u16 ctl;
1058	u16 aid;
1059	u16 retries;
1060	u16 fill;
1061} TxCtlHdr;
1062
1063typedef struct {
1064        u16 ctl;
1065        u16 duration;
1066        char addr1[6];
1067        char addr2[6];
1068        char addr3[6];
1069        u16 seq;
1070        char addr4[6];
1071} WifiHdr;
1072
1073
1074typedef struct {
1075	TxCtlHdr ctlhdr;
1076	u16 fill1;
1077	u16 fill2;
1078	WifiHdr wifihdr;
1079	u16 gaplen;
1080	u16 status;
1081} WifiCtlHdr;
1082
1083static WifiCtlHdr wifictlhdr8023 = {
1084	.ctlhdr = {
1085		.ctl	= HOST_DONT_RLSE,
1086	}
1087};
1088
1089// A few details needed for WEP (Wireless Equivalent Privacy)
1090#define MAX_KEY_SIZE 13			// 128 (?) bits
1091#define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
1092typedef struct wep_key_t {
1093	u16	len;
1094	u8	key[16];	/* 40-bit and 104-bit keys */
1095} wep_key_t;
1096
1097/* List of Wireless Handlers (new API) */
1098static const struct iw_handler_def	airo_handler_def;
1099
1100static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
1101
1102struct airo_info;
1103
1104static int get_dec_u16( char *buffer, int *start, int limit );
1105static void OUT4500( struct airo_info *, u16 reg, u16 value );
1106static unsigned short IN4500( struct airo_info *, u16 reg );
1107static u16 setup_card(struct airo_info*, u8 *mac, int lock);
1108static int enable_MAC(struct airo_info *ai, int lock);
1109static void disable_MAC(struct airo_info *ai, int lock);
1110static void enable_interrupts(struct airo_info*);
1111static void disable_interrupts(struct airo_info*);
1112static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
 
1113static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
1114static int aux_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
1115			int whichbap);
1116static int fast_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
1117			 int whichbap);
1118static int bap_write(struct airo_info*, const __le16 *pu16Src, int bytelen,
1119		     int whichbap);
1120static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
1121static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
1122static int PC4500_writerid(struct airo_info*, u16 rid, const void
1123			   *pBuf, int len, int lock);
1124static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
1125			int len, int dummy );
1126static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
1127static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
1128static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
 
 
1129
1130static int mpi_send_packet (struct net_device *dev);
1131static void mpi_unmap_card(struct pci_dev *pci);
1132static void mpi_receive_802_3(struct airo_info *ai);
1133static void mpi_receive_802_11(struct airo_info *ai);
1134static int waitbusy (struct airo_info *ai);
1135
1136static irqreturn_t airo_interrupt( int irq, void* dev_id);
1137static int airo_thread(void *data);
1138static void timer_func( struct net_device *dev );
1139static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
1140static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
1141static void airo_read_wireless_stats (struct airo_info *local);
1142#ifdef CISCO_EXT
1143static int readrids(struct net_device *dev, aironet_ioctl *comp);
1144static int writerids(struct net_device *dev, aironet_ioctl *comp);
1145static int flashcard(struct net_device *dev, aironet_ioctl *comp);
1146#endif /* CISCO_EXT */
1147static void micinit(struct airo_info *ai);
1148static int micsetup(struct airo_info *ai);
1149static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
1150static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1151
1152static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
1153static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
1154
1155static void airo_networks_free(struct airo_info *ai);
1156
1157struct airo_info {
1158	struct net_device             *dev;
1159	struct list_head              dev_list;
1160	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
1161	   use the high bit to mark whether it is in use. */
1162#define MAX_FIDS 6
1163#define MPI_MAX_FIDS 1
1164	u32                           fids[MAX_FIDS];
1165	ConfigRid config;
1166	char keyindex; // Used with auto wep
1167	char defindex; // Used with auto wep
1168	struct proc_dir_entry *proc_entry;
1169        spinlock_t aux_lock;
1170#define FLAG_RADIO_OFF	0	/* User disabling of MAC */
1171#define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */
1172#define FLAG_RADIO_MASK 0x03
1173#define FLAG_ENABLED	2
1174#define FLAG_ADHOC	3	/* Needed by MIC */
1175#define FLAG_MIC_CAPABLE 4
1176#define FLAG_UPDATE_MULTI 5
1177#define FLAG_UPDATE_UNI 6
1178#define FLAG_802_11	7
1179#define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
1180#define FLAG_PENDING_XMIT 9
1181#define FLAG_PENDING_XMIT11 10
1182#define FLAG_MPI	11
1183#define FLAG_REGISTERED	12
1184#define FLAG_COMMIT	13
1185#define FLAG_RESET	14
1186#define FLAG_FLASHING	15
1187#define FLAG_WPA_CAPABLE	16
1188	unsigned long flags;
1189#define JOB_DIE	0
1190#define JOB_XMIT	1
1191#define JOB_XMIT11	2
1192#define JOB_STATS	3
1193#define JOB_PROMISC	4
1194#define JOB_MIC	5
1195#define JOB_EVENT	6
1196#define JOB_AUTOWEP	7
1197#define JOB_WSTATS	8
1198#define JOB_SCAN_RESULTS  9
1199	unsigned long jobs;
1200	int (*bap_read)(struct airo_info*, __le16 *pu16Dst, int bytelen,
1201			int whichbap);
1202	unsigned short *flash;
1203	tdsRssiEntry *rssi;
1204	struct task_struct *list_bss_task;
1205	struct task_struct *airo_thread_task;
1206	struct semaphore sem;
1207	wait_queue_head_t thr_wait;
1208	unsigned long expires;
1209	struct {
1210		struct sk_buff *skb;
1211		int fid;
1212	} xmit, xmit11;
1213	struct net_device *wifidev;
1214	struct iw_statistics	wstats;		// wireless stats
1215	unsigned long		scan_timeout;	/* Time scan should be read */
1216	struct iw_spy_data	spy_data;
1217	struct iw_public_data	wireless_data;
1218	/* MIC stuff */
1219	struct crypto_cipher	*tfm;
1220	mic_module		mod[2];
1221	mic_statistics		micstats;
1222	HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
1223	HostTxDesc txfids[MPI_MAX_FIDS];
1224	HostRidDesc config_desc;
1225	unsigned long ridbus; // phys addr of config_desc
1226	struct sk_buff_head txq;// tx queue used by mpi350 code
1227	struct pci_dev          *pci;
1228	unsigned char		__iomem *pcimem;
1229	unsigned char		__iomem *pciaux;
1230	unsigned char		*shared;
1231	dma_addr_t		shared_dma;
1232	pm_message_t		power;
1233	SsidRid			*SSID;
1234	APListRid		APList;
1235#define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
1236	char			proc_name[IFNAMSIZ];
1237
1238	int			wep_capable;
1239	int			max_wep_idx;
1240	int			last_auth;
1241
1242	/* WPA-related stuff */
1243	unsigned int bssListFirst;
1244	unsigned int bssListNext;
1245	unsigned int bssListRidLen;
1246
1247	struct list_head network_list;
1248	struct list_head network_free_list;
1249	BSSListElement *networks;
1250};
1251
1252static inline int bap_read(struct airo_info *ai, __le16 *pu16Dst, int bytelen,
1253			   int whichbap)
1254{
1255	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
1256}
1257
1258static int setup_proc_entry( struct net_device *dev,
1259			     struct airo_info *apriv );
1260static int takedown_proc_entry( struct net_device *dev,
1261				struct airo_info *apriv );
1262
1263static int cmdreset(struct airo_info *ai);
1264static int setflashmode (struct airo_info *ai);
1265static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
1266static int flashputbuf(struct airo_info *ai);
1267static int flashrestart(struct airo_info *ai,struct net_device *dev);
1268
1269#define airo_print(type, name, fmt, args...) \
1270	printk(type DRV_NAME "(%s): " fmt "\n", name, ##args)
1271
1272#define airo_print_info(name, fmt, args...) \
1273	airo_print(KERN_INFO, name, fmt, ##args)
1274
1275#define airo_print_dbg(name, fmt, args...) \
1276	airo_print(KERN_DEBUG, name, fmt, ##args)
1277
1278#define airo_print_warn(name, fmt, args...) \
1279	airo_print(KERN_WARNING, name, fmt, ##args)
1280
1281#define airo_print_err(name, fmt, args...) \
1282	airo_print(KERN_ERR, name, fmt, ##args)
1283
1284#define AIRO_FLASH(dev) (((struct airo_info *)dev->ml_priv)->flash)
1285
1286/***********************************************************************
1287 *                              MIC ROUTINES                           *
1288 ***********************************************************************
1289 */
1290
1291static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
1292static void MoveWindow(miccntx *context, u32 micSeq);
1293static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1294			   struct crypto_cipher *tfm);
1295static void emmh32_init(emmh32_context *context);
1296static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1297static void emmh32_final(emmh32_context *context, u8 digest[4]);
1298static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
1299
1300static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
1301			    struct crypto_cipher *tfm)
1302{
1303	/* If the current MIC context is valid and its key is the same as
1304	 * the MIC register, there's nothing to do.
1305	 */
1306	if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
1307		return;
1308
1309	/* Age current mic Context */
1310	memcpy(old, cur, sizeof(*cur));
1311
1312	/* Initialize new context */
1313	memcpy(cur->key, key, key_len);
1314	cur->window  = 33; /* Window always points to the middle */
1315	cur->rx      = 0;  /* Rx Sequence numbers */
1316	cur->tx      = 0;  /* Tx sequence numbers */
1317	cur->valid   = 1;  /* Key is now valid */
1318
1319	/* Give key to mic seed */
1320	emmh32_setseed(&cur->seed, key, key_len, tfm);
1321}
1322
1323/* micinit - Initialize mic seed */
1324
1325static void micinit(struct airo_info *ai)
1326{
1327	MICRid mic_rid;
1328
1329	clear_bit(JOB_MIC, &ai->jobs);
1330	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1331	up(&ai->sem);
1332
1333	ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
1334	if (!ai->micstats.enabled) {
1335		/* So next time we have a valid key and mic is enabled, we will
1336		 * update the sequence number if the key is the same as before.
1337		 */
1338		ai->mod[0].uCtx.valid = 0;
1339		ai->mod[0].mCtx.valid = 0;
1340		return;
1341	}
1342
1343	if (mic_rid.multicastValid) {
1344		age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
1345		                mic_rid.multicast, sizeof(mic_rid.multicast),
1346		                ai->tfm);
1347	}
1348
1349	if (mic_rid.unicastValid) {
1350		age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
1351				mic_rid.unicast, sizeof(mic_rid.unicast),
1352				ai->tfm);
1353	}
1354}
1355
1356/* micsetup - Get ready for business */
1357
1358static int micsetup(struct airo_info *ai) {
 
1359	int i;
1360
1361	if (ai->tfm == NULL)
1362	        ai->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
1363
1364        if (IS_ERR(ai->tfm)) {
1365                airo_print_err(ai->dev->name, "failed to load transform for AES");
1366                ai->tfm = NULL;
1367                return ERROR;
1368        }
1369
1370	for (i=0; i < NUM_MODULES; i++) {
1371		memset(&ai->mod[i].mCtx,0,sizeof(miccntx));
1372		memset(&ai->mod[i].uCtx,0,sizeof(miccntx));
1373	}
1374	return SUCCESS;
1375}
1376
1377static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
1378
1379/*===========================================================================
1380 * Description: Mic a packet
1381 *    
1382 *      Inputs: etherHead * pointer to an 802.3 frame
1383 *    
1384 *     Returns: BOOLEAN if successful, otherwise false.
1385 *             PacketTxLen will be updated with the mic'd packets size.
1386 *
1387 *    Caveats: It is assumed that the frame buffer will already
1388 *             be big enough to hold the largets mic message possible.
1389 *            (No memory allocation is done here).
1390 *  
1391 *    Author: sbraneky (10/15/01)
1392 *    Merciless hacks by rwilcher (1/14/02)
1393 */
1394
1395static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen)
1396{
1397	miccntx   *context;
1398
1399	// Determine correct context
1400	// If not adhoc, always use unicast key
1401
1402	if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
1403		context = &ai->mod[0].mCtx;
1404	else
1405		context = &ai->mod[0].uCtx;
1406  
1407	if (!context->valid)
1408		return ERROR;
1409
1410	mic->typelen = htons(payLen + 16); //Length of Mic'd packet
1411
1412	memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
1413
1414	// Add Tx sequence
1415	mic->seq = htonl(context->tx);
1416	context->tx += 2;
1417
1418	emmh32_init(&context->seed); // Mic the packet
1419	emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA
1420	emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap
1421	emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ
1422	emmh32_update(&context->seed,(u8*)(frame + 1),payLen); //payload
1423	emmh32_final(&context->seed, (u8*)&mic->mic);
1424
1425	/*    New Type/length ?????????? */
1426	mic->typelen = 0; //Let NIC know it could be an oversized packet
1427	return SUCCESS;
1428}
1429
1430typedef enum {
1431    NONE,
1432    NOMIC,
1433    NOMICPLUMMED,
1434    SEQUENCE,
1435    INCORRECTMIC,
1436} mic_error;
1437
1438/*===========================================================================
1439 *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet
1440 *               (removes the MIC stuff) if packet is a valid packet.
1441 *      
1442 *       Inputs: etherHead  pointer to the 802.3 packet             
1443 *     
1444 *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
1445 *     
1446 *      Author: sbraneky (10/15/01)
1447 *    Merciless hacks by rwilcher (1/14/02)
1448 *---------------------------------------------------------------------------
1449 */
1450
1451static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
1452{
1453	int      i;
1454	u32      micSEQ;
1455	miccntx  *context;
1456	u8       digest[4];
1457	mic_error micError = NONE;
1458
1459	// Check if the packet is a Mic'd packet
1460
1461	if (!ai->micstats.enabled) {
1462		//No Mic set or Mic OFF but we received a MIC'd packet.
1463		if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
1464			ai->micstats.rxMICPlummed++;
1465			return ERROR;
1466		}
1467		return SUCCESS;
1468	}
1469
1470	if (ntohs(mic->typelen) == 0x888E)
1471		return SUCCESS;
1472
1473	if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
1474	    // Mic enabled but packet isn't Mic'd
1475		ai->micstats.rxMICPlummed++;
1476	    	return ERROR;
1477	}
1478
1479	micSEQ = ntohl(mic->seq);            //store SEQ as CPU order
1480
1481	//At this point we a have a mic'd packet and mic is enabled
1482	//Now do the mic error checking.
1483
1484	//Receive seq must be odd
1485	if ( (micSEQ & 1) == 0 ) {
1486		ai->micstats.rxWrongSequence++;
1487		return ERROR;
1488	}
1489
1490	for (i = 0; i < NUM_MODULES; i++) {
1491		int mcast = eth->da[0] & 1;
1492		//Determine proper context 
1493		context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
1494	
1495		//Make sure context is valid
1496		if (!context->valid) {
1497			if (i == 0)
1498				micError = NOMICPLUMMED;
1499			continue;                
1500		}
1501	       	//DeMic it 
1502
1503		if (!mic->typelen)
1504			mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
1505	
1506		emmh32_init(&context->seed);
1507		emmh32_update(&context->seed, eth->da, ETH_ALEN*2); 
1508		emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap)); 
1509		emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq));	
1510		emmh32_update(&context->seed, (u8 *)(eth + 1),payLen);	
1511		//Calculate MIC
1512		emmh32_final(&context->seed, digest);
1513	
1514		if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
1515		  //Invalid Mic
1516			if (i == 0)
1517				micError = INCORRECTMIC;
1518			continue;
1519		}
1520
1521		//Check Sequence number if mics pass
1522		if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
1523			ai->micstats.rxSuccess++;
1524			return SUCCESS;
1525		}
1526		if (i == 0)
1527			micError = SEQUENCE;
1528	}
1529
1530	// Update statistics
1531	switch (micError) {
1532		case NOMICPLUMMED: ai->micstats.rxMICPlummed++;   break;
1533		case SEQUENCE:    ai->micstats.rxWrongSequence++; break;
1534		case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
1535		case NONE:  break;
1536		case NOMIC: break;
1537	}
1538	return ERROR;
1539}
1540
1541/*===========================================================================
1542 * Description:  Checks the Rx Seq number to make sure it is valid
1543 *               and hasn't already been received
1544 *   
1545 *     Inputs: miccntx - mic context to check seq against
1546 *             micSeq  - the Mic seq number
1547 *   
1548 *    Returns: TRUE if valid otherwise FALSE. 
1549 *
1550 *    Author: sbraneky (10/15/01)
1551 *    Merciless hacks by rwilcher (1/14/02)
1552 *---------------------------------------------------------------------------
1553 */
1554
1555static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq)
1556{
1557	u32 seq,index;
1558
1559	//Allow for the ap being rebooted - if it is then use the next 
1560	//sequence number of the current sequence number - might go backwards
1561
1562	if (mcast) {
1563		if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
1564			clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
1565			context->window = (micSeq > 33) ? micSeq : 33;
1566			context->rx     = 0;        // Reset rx
1567		}
1568	} else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
1569		clear_bit (FLAG_UPDATE_UNI, &ai->flags);
1570		context->window = (micSeq > 33) ? micSeq : 33; // Move window
1571		context->rx     = 0;        // Reset rx
1572	}
1573
1574	//Make sequence number relative to START of window
1575	seq = micSeq - (context->window - 33);
1576
1577	//Too old of a SEQ number to check.
1578	if ((s32)seq < 0)
1579		return ERROR;
1580    
1581	if ( seq > 64 ) {
1582		//Window is infinite forward
1583		MoveWindow(context,micSeq);
1584		return SUCCESS;
1585	}
1586
1587	// We are in the window. Now check the context rx bit to see if it was already sent
1588	seq >>= 1;         //divide by 2 because we only have odd numbers
1589	index = 1 << seq;  //Get an index number
1590
1591	if (!(context->rx & index)) {
1592		//micSEQ falls inside the window.
1593		//Add seqence number to the list of received numbers.
1594		context->rx |= index;
1595
1596		MoveWindow(context,micSeq);
1597
1598		return SUCCESS;
1599	}
1600	return ERROR;
1601}
1602
1603static void MoveWindow(miccntx *context, u32 micSeq)
1604{
1605	u32 shift;
1606
1607	//Move window if seq greater than the middle of the window
1608	if (micSeq > context->window) {
1609		shift = (micSeq - context->window) >> 1;
1610    
1611		    //Shift out old
1612		if (shift < 32)
1613			context->rx >>= shift;
1614		else
1615			context->rx = 0;
1616
1617		context->window = micSeq;      //Move window
1618	}
1619}
1620
1621/*==============================================*/
1622/*========== EMMH ROUTINES  ====================*/
1623/*==============================================*/
1624
1625/* mic accumulate */
1626#define MIC_ACCUM(val)	\
1627	context->accum += (u64)(val) * context->coeff[coeff_position++];
1628
1629static unsigned char aes_counter[16];
1630
1631/* expand the key to fill the MMH coefficient array */
1632static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1633			   struct crypto_cipher *tfm)
1634{
1635  /* take the keying material, expand if necessary, truncate at 16-bytes */
1636  /* run through AES counter mode to generate context->coeff[] */
1637  
1638	int i,j;
1639	u32 counter;
1640	u8 *cipher, plain[16];
1641
1642	crypto_cipher_setkey(tfm, pkey, 16);
1643	counter = 0;
1644	for (i = 0; i < ARRAY_SIZE(context->coeff); ) {
1645		aes_counter[15] = (u8)(counter >> 0);
1646		aes_counter[14] = (u8)(counter >> 8);
1647		aes_counter[13] = (u8)(counter >> 16);
1648		aes_counter[12] = (u8)(counter >> 24);
1649		counter++;
1650		memcpy (plain, aes_counter, 16);
1651		crypto_cipher_encrypt_one(tfm, plain, plain);
1652		cipher = plain;
1653		for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
1654			context->coeff[i++] = ntohl(*(__be32 *)&cipher[j]);
1655			j += 4;
1656		}
1657	}
1658}
1659
1660/* prepare for calculation of a new mic */
1661static void emmh32_init(emmh32_context *context)
1662{
1663	/* prepare for new mic calculation */
1664	context->accum = 0;
1665	context->position = 0;
1666}
1667
1668/* add some bytes to the mic calculation */
1669static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1670{
1671	int	coeff_position, byte_position;
1672  
1673	if (len == 0) return;
1674  
1675	coeff_position = context->position >> 2;
1676  
1677	/* deal with partial 32-bit word left over from last update */
1678	byte_position = context->position & 3;
1679	if (byte_position) {
1680		/* have a partial word in part to deal with */
1681		do {
1682			if (len == 0) return;
1683			context->part.d8[byte_position++] = *pOctets++;
1684			context->position++;
1685			len--;
1686		} while (byte_position < 4);
1687		MIC_ACCUM(ntohl(context->part.d32));
1688	}
1689
1690	/* deal with full 32-bit words */
1691	while (len >= 4) {
1692		MIC_ACCUM(ntohl(*(__be32 *)pOctets));
1693		context->position += 4;
1694		pOctets += 4;
1695		len -= 4;
1696	}
1697
1698	/* deal with partial 32-bit word that will be left over from this update */
1699	byte_position = 0;
1700	while (len > 0) {
1701		context->part.d8[byte_position++] = *pOctets++;
1702		context->position++;
1703		len--;
1704	}
1705}
1706
1707/* mask used to zero empty bytes for final partial word */
1708static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1709
1710/* calculate the mic */
1711static void emmh32_final(emmh32_context *context, u8 digest[4])
1712{
1713	int	coeff_position, byte_position;
1714	u32	val;
1715  
1716	u64 sum, utmp;
1717	s64 stmp;
1718
1719	coeff_position = context->position >> 2;
1720  
1721	/* deal with partial 32-bit word left over from last update */
1722	byte_position = context->position & 3;
1723	if (byte_position) {
1724		/* have a partial word in part to deal with */
1725		val = ntohl(context->part.d32);
1726		MIC_ACCUM(val & mask32[byte_position]);	/* zero empty bytes */
1727	}
1728
1729	/* reduce the accumulated u64 to a 32-bit MIC */
1730	sum = context->accum;
1731	stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);
1732	utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
1733	sum = utmp & 0xffffffffLL;
1734	if (utmp > 0x10000000fLL)
1735		sum -= 15;
1736
1737	val = (u32)sum;
1738	digest[0] = (val>>24) & 0xFF;
1739	digest[1] = (val>>16) & 0xFF;
1740	digest[2] = (val>>8) & 0xFF;
1741	digest[3] = val & 0xFF;
1742}
1743
1744static int readBSSListRid(struct airo_info *ai, int first,
1745		      BSSListRid *list)
1746{
1747	Cmd cmd;
1748	Resp rsp;
1749
1750	if (first == 1) {
1751		if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
1752		memset(&cmd, 0, sizeof(cmd));
1753		cmd.cmd=CMD_LISTBSS;
1754		if (down_interruptible(&ai->sem))
1755			return -ERESTARTSYS;
1756		ai->list_bss_task = current;
1757		issuecommand(ai, &cmd, &rsp);
1758		up(&ai->sem);
1759		/* Let the command take effect */
1760		schedule_timeout_uninterruptible(3 * HZ);
1761		ai->list_bss_task = NULL;
1762	}
1763	return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
1764			    list, ai->bssListRidLen, 1);
1765}
1766
1767static int readWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int temp, int lock)
1768{
1769	return PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
1770				wkr, sizeof(*wkr), lock);
1771}
1772
1773static int writeWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int perm, int lock)
1774{
1775	int rc;
1776	rc = PC4500_writerid(ai, RID_WEP_TEMP, wkr, sizeof(*wkr), lock);
1777	if (rc!=SUCCESS)
1778		airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
1779	if (perm) {
1780		rc = PC4500_writerid(ai, RID_WEP_PERM, wkr, sizeof(*wkr), lock);
1781		if (rc!=SUCCESS)
1782			airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
1783	}
1784	return rc;
1785}
1786
1787static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
1788{
1789	return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1790}
1791
1792static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
1793{
1794	return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
1795}
1796
1797static int readConfigRid(struct airo_info *ai, int lock)
1798{
1799	int rc;
1800	ConfigRid cfg;
1801
1802	if (ai->config.len)
1803		return SUCCESS;
1804
1805	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
1806	if (rc != SUCCESS)
1807		return rc;
1808
1809	ai->config = cfg;
1810	return SUCCESS;
1811}
1812
1813static inline void checkThrottle(struct airo_info *ai)
1814{
1815	int i;
1816/* Old hardware had a limit on encryption speed */
1817	if (ai->config.authType != AUTH_OPEN && maxencrypt) {
1818		for(i=0; i<8; i++) {
1819			if (ai->config.rates[i] > maxencrypt) {
1820				ai->config.rates[i] = 0;
1821			}
1822		}
1823	}
1824}
1825
1826static int writeConfigRid(struct airo_info *ai, int lock)
1827{
1828	ConfigRid cfgr;
1829
1830	if (!test_bit (FLAG_COMMIT, &ai->flags))
1831		return SUCCESS;
1832
1833	clear_bit (FLAG_COMMIT, &ai->flags);
1834	clear_bit (FLAG_RESET, &ai->flags);
1835	checkThrottle(ai);
1836	cfgr = ai->config;
1837
1838	if ((cfgr.opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
1839		set_bit(FLAG_ADHOC, &ai->flags);
1840	else
1841		clear_bit(FLAG_ADHOC, &ai->flags);
1842
1843	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1844}
1845
1846static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
1847{
1848	return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1849}
1850
1851static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
1852{
1853	return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
1854}
1855
1856static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
1857{
1858	return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1859}
1860
1861static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
1862{
1863	return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1864}
1865
1866static void try_auto_wep(struct airo_info *ai)
1867{
1868	if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
1869		ai->expires = RUN_AT(3*HZ);
1870		wake_up_interruptible(&ai->thr_wait);
1871	}
1872}
1873
1874static int airo_open(struct net_device *dev) {
 
1875	struct airo_info *ai = dev->ml_priv;
1876	int rc = 0;
1877
1878	if (test_bit(FLAG_FLASHING, &ai->flags))
1879		return -EIO;
1880
1881	/* Make sure the card is configured.
1882	 * Wireless Extensions may postpone config changes until the card
1883	 * is open (to pipeline changes and speed-up card setup). If
1884	 * those changes are not yet committed, do it now - Jean II */
1885	if (test_bit(FLAG_COMMIT, &ai->flags)) {
1886		disable_MAC(ai, 1);
1887		writeConfigRid(ai, 1);
1888	}
1889
1890	if (ai->wifidev != dev) {
1891		clear_bit(JOB_DIE, &ai->jobs);
1892		ai->airo_thread_task = kthread_run(airo_thread, dev, "%s",
1893						   dev->name);
1894		if (IS_ERR(ai->airo_thread_task))
1895			return (int)PTR_ERR(ai->airo_thread_task);
1896
1897		rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
1898			dev->name, dev);
1899		if (rc) {
1900			airo_print_err(dev->name,
1901				"register interrupt %d failed, rc %d",
1902				dev->irq, rc);
1903			set_bit(JOB_DIE, &ai->jobs);
1904			kthread_stop(ai->airo_thread_task);
1905			return rc;
1906		}
1907
1908		/* Power on the MAC controller (which may have been disabled) */
1909		clear_bit(FLAG_RADIO_DOWN, &ai->flags);
1910		enable_interrupts(ai);
1911
1912		try_auto_wep(ai);
1913	}
1914	enable_MAC(ai, 1);
1915
1916	netif_start_queue(dev);
1917	return 0;
1918}
1919
1920static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
1921					struct net_device *dev)
1922{
1923	int npacks, pending;
1924	unsigned long flags;
1925	struct airo_info *ai = dev->ml_priv;
1926
1927	if (!skb) {
1928		airo_print_err(dev->name, "%s: skb == NULL!",__func__);
1929		return NETDEV_TX_OK;
1930	}
 
 
 
 
1931	npacks = skb_queue_len (&ai->txq);
1932
1933	if (npacks >= MAXTXQ - 1) {
1934		netif_stop_queue (dev);
1935		if (npacks > MAXTXQ) {
1936			dev->stats.tx_fifo_errors++;
1937			return NETDEV_TX_BUSY;
1938		}
1939		skb_queue_tail (&ai->txq, skb);
1940		return NETDEV_TX_OK;
1941	}
1942
1943	spin_lock_irqsave(&ai->aux_lock, flags);
1944	skb_queue_tail (&ai->txq, skb);
1945	pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
1946	spin_unlock_irqrestore(&ai->aux_lock,flags);
1947	netif_wake_queue (dev);
1948
1949	if (pending == 0) {
1950		set_bit(FLAG_PENDING_XMIT, &ai->flags);
1951		mpi_send_packet (dev);
1952	}
1953	return NETDEV_TX_OK;
1954}
1955
1956/*
1957 * @mpi_send_packet
1958 *
1959 * Attempt to transmit a packet. Can be called from interrupt
1960 * or transmit . return number of packets we tried to send
1961 */
1962
1963static int mpi_send_packet (struct net_device *dev)
1964{
1965	struct sk_buff *skb;
1966	unsigned char *buffer;
1967	s16 len;
1968	__le16 *payloadLen;
1969	struct airo_info *ai = dev->ml_priv;
1970	u8 *sendbuf;
1971
1972	/* get a packet to send */
1973
1974	if ((skb = skb_dequeue(&ai->txq)) == NULL) {
1975		airo_print_err(dev->name,
1976			"%s: Dequeue'd zero in send_packet()",
1977			__func__);
1978		return 0;
1979	}
1980
1981	/* check min length*/
1982	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1983	buffer = skb->data;
1984
1985	ai->txfids[0].tx_desc.offset = 0;
1986	ai->txfids[0].tx_desc.valid = 1;
1987	ai->txfids[0].tx_desc.eoc = 1;
1988	ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
1989
1990/*
1991 * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
1992 * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
1993 * is immediately after it. ------------------------------------------------
1994 *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
1995 *                         ------------------------------------------------
1996 */
1997
1998	memcpy(ai->txfids[0].virtual_host_addr,
1999		(char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
2000
2001	payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
2002		sizeof(wifictlhdr8023));
2003	sendbuf = ai->txfids[0].virtual_host_addr +
2004		sizeof(wifictlhdr8023) + 2 ;
2005
2006	/*
2007	 * Firmware automatically puts 802 header on so
2008	 * we don't need to account for it in the length
2009	 */
2010	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
2011		(ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
2012		MICBuffer pMic;
2013
2014		if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
2015			return ERROR;
2016
2017		*payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
2018		ai->txfids[0].tx_desc.len += sizeof(pMic);
2019		/* copy data into airo dma buffer */
2020		memcpy (sendbuf, buffer, sizeof(etherHead));
2021		buffer += sizeof(etherHead);
2022		sendbuf += sizeof(etherHead);
2023		memcpy (sendbuf, &pMic, sizeof(pMic));
2024		sendbuf += sizeof(pMic);
2025		memcpy (sendbuf, buffer, len - sizeof(etherHead));
2026	} else {
2027		*payloadLen = cpu_to_le16(len - sizeof(etherHead));
2028
2029		netif_trans_update(dev);
2030
2031		/* copy data into airo dma buffer */
2032		memcpy(sendbuf, buffer, len);
2033	}
2034
2035	memcpy_toio(ai->txfids[0].card_ram_off,
2036		&ai->txfids[0].tx_desc, sizeof(TxFid));
2037
2038	OUT4500(ai, EVACK, 8);
2039
2040	dev_kfree_skb_any(skb);
2041	return 1;
2042}
2043
2044static void get_tx_error(struct airo_info *ai, s32 fid)
2045{
2046	__le16 status;
2047
2048	if (fid < 0)
2049		status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
2050	else {
2051		if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
2052			return;
2053		bap_read(ai, &status, 2, BAP0);
2054	}
2055	if (le16_to_cpu(status) & 2) /* Too many retries */
2056		ai->dev->stats.tx_aborted_errors++;
2057	if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
2058		ai->dev->stats.tx_heartbeat_errors++;
2059	if (le16_to_cpu(status) & 8) /* Aid fail */
2060		{ }
2061	if (le16_to_cpu(status) & 0x10) /* MAC disabled */
2062		ai->dev->stats.tx_carrier_errors++;
2063	if (le16_to_cpu(status) & 0x20) /* Association lost */
2064		{ }
2065	/* We produce a TXDROP event only for retry or lifetime
2066	 * exceeded, because that's the only status that really mean
2067	 * that this particular node went away.
2068	 * Other errors means that *we* screwed up. - Jean II */
2069	if ((le16_to_cpu(status) & 2) ||
2070	     (le16_to_cpu(status) & 4)) {
2071		union iwreq_data	wrqu;
2072		char junk[0x18];
2073
2074		/* Faster to skip over useless data than to do
2075		 * another bap_setup(). We are at offset 0x6 and
2076		 * need to go to 0x18 and read 6 bytes - Jean II */
2077		bap_read(ai, (__le16 *) junk, 0x18, BAP0);
2078
2079		/* Copy 802.11 dest address.
2080		 * We use the 802.11 header because the frame may
2081		 * not be 802.3 or may be mangled...
2082		 * In Ad-Hoc mode, it will be the node address.
2083		 * In managed mode, it will be most likely the AP addr
2084		 * User space will figure out how to convert it to
2085		 * whatever it needs (IP address or else).
2086		 * - Jean II */
2087		memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
2088		wrqu.addr.sa_family = ARPHRD_ETHER;
2089
2090		/* Send event to user space */
2091		wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
2092	}
2093}
2094
2095static void airo_end_xmit(struct net_device *dev) {
 
2096	u16 status;
2097	int i;
2098	struct airo_info *priv = dev->ml_priv;
2099	struct sk_buff *skb = priv->xmit.skb;
2100	int fid = priv->xmit.fid;
2101	u32 *fids = priv->fids;
2102
2103	clear_bit(JOB_XMIT, &priv->jobs);
2104	clear_bit(FLAG_PENDING_XMIT, &priv->flags);
2105	status = transmit_802_3_packet (priv, fids[fid], skb->data);
2106	up(&priv->sem);
2107
2108	i = 0;
2109	if ( status == SUCCESS ) {
2110		netif_trans_update(dev);
2111		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
2112	} else {
2113		priv->fids[fid] &= 0xffff;
2114		dev->stats.tx_window_errors++;
2115	}
2116	if (i < MAX_FIDS / 2)
2117		netif_wake_queue(dev);
2118	dev_kfree_skb(skb);
2119}
2120
2121static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
2122					 struct net_device *dev)
2123{
2124	s16 len;
2125	int i, j;
2126	struct airo_info *priv = dev->ml_priv;
2127	u32 *fids = priv->fids;
2128
2129	if ( skb == NULL ) {
2130		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
2131		return NETDEV_TX_OK;
2132	}
 
 
 
 
2133
2134	/* Find a vacant FID */
2135	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
2136	for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
2137
2138	if ( j >= MAX_FIDS / 2 ) {
2139		netif_stop_queue(dev);
2140
2141		if (i == MAX_FIDS / 2) {
2142			dev->stats.tx_fifo_errors++;
2143			return NETDEV_TX_BUSY;
2144		}
2145	}
2146	/* check min length*/
2147	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2148        /* Mark fid as used & save length for later */
2149	fids[i] |= (len << 16);
2150	priv->xmit.skb = skb;
2151	priv->xmit.fid = i;
2152	if (down_trylock(&priv->sem) != 0) {
2153		set_bit(FLAG_PENDING_XMIT, &priv->flags);
2154		netif_stop_queue(dev);
2155		set_bit(JOB_XMIT, &priv->jobs);
2156		wake_up_interruptible(&priv->thr_wait);
2157	} else
2158		airo_end_xmit(dev);
2159	return NETDEV_TX_OK;
2160}
2161
2162static void airo_end_xmit11(struct net_device *dev) {
 
2163	u16 status;
2164	int i;
2165	struct airo_info *priv = dev->ml_priv;
2166	struct sk_buff *skb = priv->xmit11.skb;
2167	int fid = priv->xmit11.fid;
2168	u32 *fids = priv->fids;
2169
2170	clear_bit(JOB_XMIT11, &priv->jobs);
2171	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
2172	status = transmit_802_11_packet (priv, fids[fid], skb->data);
2173	up(&priv->sem);
2174
2175	i = MAX_FIDS / 2;
2176	if ( status == SUCCESS ) {
2177		netif_trans_update(dev);
2178		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
2179	} else {
2180		priv->fids[fid] &= 0xffff;
2181		dev->stats.tx_window_errors++;
2182	}
2183	if (i < MAX_FIDS)
2184		netif_wake_queue(dev);
2185	dev_kfree_skb(skb);
2186}
2187
2188static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
2189					   struct net_device *dev)
2190{
2191	s16 len;
2192	int i, j;
2193	struct airo_info *priv = dev->ml_priv;
2194	u32 *fids = priv->fids;
2195
2196	if (test_bit(FLAG_MPI, &priv->flags)) {
2197		/* Not implemented yet for MPI350 */
2198		netif_stop_queue(dev);
2199		dev_kfree_skb_any(skb);
2200		return NETDEV_TX_OK;
2201	}
2202
2203	if ( skb == NULL ) {
2204		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
2205		return NETDEV_TX_OK;
2206	}
 
 
 
 
2207
2208	/* Find a vacant FID */
2209	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
2210	for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
2211
2212	if ( j >= MAX_FIDS ) {
2213		netif_stop_queue(dev);
2214
2215		if (i == MAX_FIDS) {
2216			dev->stats.tx_fifo_errors++;
2217			return NETDEV_TX_BUSY;
2218		}
2219	}
2220	/* check min length*/
2221	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2222        /* Mark fid as used & save length for later */
2223	fids[i] |= (len << 16);
2224	priv->xmit11.skb = skb;
2225	priv->xmit11.fid = i;
2226	if (down_trylock(&priv->sem) != 0) {
2227		set_bit(FLAG_PENDING_XMIT11, &priv->flags);
2228		netif_stop_queue(dev);
2229		set_bit(JOB_XMIT11, &priv->jobs);
2230		wake_up_interruptible(&priv->thr_wait);
2231	} else
2232		airo_end_xmit11(dev);
2233	return NETDEV_TX_OK;
2234}
2235
2236static void airo_read_stats(struct net_device *dev)
2237{
2238	struct airo_info *ai = dev->ml_priv;
2239	StatsRid stats_rid;
2240	__le32 *vals = stats_rid.vals;
2241
2242	clear_bit(JOB_STATS, &ai->jobs);
2243	if (ai->power.event) {
2244		up(&ai->sem);
2245		return;
2246	}
2247	readStatsRid(ai, &stats_rid, RID_STATS, 0);
2248	up(&ai->sem);
2249
2250	dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
2251			       le32_to_cpu(vals[45]);
2252	dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
2253			       le32_to_cpu(vals[41]);
2254	dev->stats.rx_bytes = le32_to_cpu(vals[92]);
2255	dev->stats.tx_bytes = le32_to_cpu(vals[91]);
2256	dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
2257			      le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
2258	dev->stats.tx_errors = le32_to_cpu(vals[42]) +
2259			      dev->stats.tx_fifo_errors;
2260	dev->stats.multicast = le32_to_cpu(vals[43]);
2261	dev->stats.collisions = le32_to_cpu(vals[89]);
2262
2263	/* detailed rx_errors: */
2264	dev->stats.rx_length_errors = le32_to_cpu(vals[3]);
2265	dev->stats.rx_crc_errors = le32_to_cpu(vals[4]);
2266	dev->stats.rx_frame_errors = le32_to_cpu(vals[2]);
2267	dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
2268}
2269
2270static struct net_device_stats *airo_get_stats(struct net_device *dev)
2271{
2272	struct airo_info *local =  dev->ml_priv;
2273
2274	if (!test_bit(JOB_STATS, &local->jobs)) {
2275		/* Get stats out of the card if available */
2276		if (down_trylock(&local->sem) != 0) {
2277			set_bit(JOB_STATS, &local->jobs);
2278			wake_up_interruptible(&local->thr_wait);
2279		} else
2280			airo_read_stats(dev);
2281	}
2282
2283	return &dev->stats;
2284}
2285
2286static void airo_set_promisc(struct airo_info *ai) {
 
2287	Cmd cmd;
2288	Resp rsp;
2289
2290	memset(&cmd, 0, sizeof(cmd));
2291	cmd.cmd=CMD_SETMODE;
2292	clear_bit(JOB_PROMISC, &ai->jobs);
2293	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
2294	issuecommand(ai, &cmd, &rsp);
2295	up(&ai->sem);
2296}
2297
2298static void airo_set_multicast_list(struct net_device *dev) {
 
2299	struct airo_info *ai = dev->ml_priv;
2300
2301	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
2302		change_bit(FLAG_PROMISC, &ai->flags);
2303		if (down_trylock(&ai->sem) != 0) {
2304			set_bit(JOB_PROMISC, &ai->jobs);
2305			wake_up_interruptible(&ai->thr_wait);
2306		} else
2307			airo_set_promisc(ai);
2308	}
2309
2310	if ((dev->flags&IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
2311		/* Turn on multicast.  (Should be already setup...) */
2312	}
2313}
2314
2315static int airo_set_mac_address(struct net_device *dev, void *p)
2316{
2317	struct airo_info *ai = dev->ml_priv;
2318	struct sockaddr *addr = p;
2319
2320	readConfigRid(ai, 1);
2321	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
2322	set_bit (FLAG_COMMIT, &ai->flags);
2323	disable_MAC(ai, 1);
2324	writeConfigRid (ai, 1);
2325	enable_MAC(ai, 1);
2326	memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
2327	if (ai->wifidev)
2328		memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
2329	return 0;
2330}
2331
2332static LIST_HEAD(airo_devices);
2333
2334static void add_airo_dev(struct airo_info *ai)
2335{
2336	/* Upper layers already keep track of PCI devices,
2337	 * so we only need to remember our non-PCI cards. */
2338	if (!ai->pci)
2339		list_add_tail(&ai->dev_list, &airo_devices);
2340}
2341
2342static void del_airo_dev(struct airo_info *ai)
2343{
2344	if (!ai->pci)
2345		list_del(&ai->dev_list);
2346}
2347
2348static int airo_close(struct net_device *dev) {
 
2349	struct airo_info *ai = dev->ml_priv;
2350
2351	netif_stop_queue(dev);
2352
2353	if (ai->wifidev != dev) {
2354#ifdef POWER_ON_DOWN
2355		/* Shut power to the card. The idea is that the user can save
2356		 * power when he doesn't need the card with "ifconfig down".
2357		 * That's the method that is most friendly towards the network
2358		 * stack (i.e. the network stack won't try to broadcast
2359		 * anything on the interface and routes are gone. Jean II */
2360		set_bit(FLAG_RADIO_DOWN, &ai->flags);
2361		disable_MAC(ai, 1);
2362#endif
2363		disable_interrupts( ai );
2364
2365		free_irq(dev->irq, dev);
2366
2367		set_bit(JOB_DIE, &ai->jobs);
2368		kthread_stop(ai->airo_thread_task);
2369	}
2370	return 0;
2371}
2372
2373void stop_airo_card( struct net_device *dev, int freeres )
2374{
2375	struct airo_info *ai = dev->ml_priv;
2376
2377	set_bit(FLAG_RADIO_DOWN, &ai->flags);
2378	disable_MAC(ai, 1);
2379	disable_interrupts(ai);
2380	takedown_proc_entry( dev, ai );
2381	if (test_bit(FLAG_REGISTERED, &ai->flags)) {
2382		unregister_netdev( dev );
2383		if (ai->wifidev) {
2384			unregister_netdev(ai->wifidev);
2385			free_netdev(ai->wifidev);
2386			ai->wifidev = NULL;
2387		}
2388		clear_bit(FLAG_REGISTERED, &ai->flags);
2389	}
2390	/*
2391	 * Clean out tx queue
2392	 */
2393	if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
2394		struct sk_buff *skb = NULL;
2395		for (;(skb = skb_dequeue(&ai->txq));)
2396			dev_kfree_skb(skb);
2397	}
2398
2399	airo_networks_free (ai);
2400
2401	kfree(ai->flash);
2402	kfree(ai->rssi);
2403	kfree(ai->SSID);
2404	if (freeres) {
2405		/* PCMCIA frees this stuff, so only for PCI and ISA */
2406	        release_region( dev->base_addr, 64 );
2407		if (test_bit(FLAG_MPI, &ai->flags)) {
2408			if (ai->pci)
2409				mpi_unmap_card(ai->pci);
2410			if (ai->pcimem)
2411				iounmap(ai->pcimem);
2412			if (ai->pciaux)
2413				iounmap(ai->pciaux);
2414			pci_free_consistent(ai->pci, PCI_SHARED_LEN,
2415				ai->shared, ai->shared_dma);
2416		}
2417        }
2418	crypto_free_cipher(ai->tfm);
2419	del_airo_dev(ai);
2420	free_netdev( dev );
2421}
2422
2423EXPORT_SYMBOL(stop_airo_card);
2424
2425static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr)
2426{
2427	memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
2428	return ETH_ALEN;
2429}
2430
2431static void mpi_unmap_card(struct pci_dev *pci)
2432{
2433	unsigned long mem_start = pci_resource_start(pci, 1);
2434	unsigned long mem_len = pci_resource_len(pci, 1);
2435	unsigned long aux_start = pci_resource_start(pci, 2);
2436	unsigned long aux_len = AUXMEMSIZE;
2437
2438	release_mem_region(aux_start, aux_len);
2439	release_mem_region(mem_start, mem_len);
2440}
2441
2442/*************************************************************
2443 *  This routine assumes that descriptors have been setup .
2444 *  Run at insmod time or after reset  when the decriptors
2445 *  have been initialized . Returns 0 if all is well nz
2446 *  otherwise . Does not allocate memory but sets up card
2447 *  using previously allocated descriptors.
2448 */
2449static int mpi_init_descriptors (struct airo_info *ai)
2450{
2451	Cmd cmd;
2452	Resp rsp;
2453	int i;
2454	int rc = SUCCESS;
2455
2456	/* Alloc  card RX descriptors */
2457	netif_stop_queue(ai->dev);
2458
2459	memset(&rsp,0,sizeof(rsp));
2460	memset(&cmd,0,sizeof(cmd));
2461
2462	cmd.cmd = CMD_ALLOCATEAUX;
2463	cmd.parm0 = FID_RX;
2464	cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
2465	cmd.parm2 = MPI_MAX_FIDS;
2466	rc=issuecommand(ai, &cmd, &rsp);
2467	if (rc != SUCCESS) {
2468		airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
2469		return rc;
2470	}
2471
2472	for (i=0; i<MPI_MAX_FIDS; i++) {
2473		memcpy_toio(ai->rxfids[i].card_ram_off,
2474			&ai->rxfids[i].rx_desc, sizeof(RxFid));
2475	}
2476
2477	/* Alloc card TX descriptors */
2478
2479	memset(&rsp,0,sizeof(rsp));
2480	memset(&cmd,0,sizeof(cmd));
2481
2482	cmd.cmd = CMD_ALLOCATEAUX;
2483	cmd.parm0 = FID_TX;
2484	cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
2485	cmd.parm2 = MPI_MAX_FIDS;
2486
2487	for (i=0; i<MPI_MAX_FIDS; i++) {
2488		ai->txfids[i].tx_desc.valid = 1;
2489		memcpy_toio(ai->txfids[i].card_ram_off,
2490			&ai->txfids[i].tx_desc, sizeof(TxFid));
2491	}
2492	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2493
2494	rc=issuecommand(ai, &cmd, &rsp);
2495	if (rc != SUCCESS) {
2496		airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
2497		return rc;
2498	}
2499
2500	/* Alloc card Rid descriptor */
2501	memset(&rsp,0,sizeof(rsp));
2502	memset(&cmd,0,sizeof(cmd));
2503
2504	cmd.cmd = CMD_ALLOCATEAUX;
2505	cmd.parm0 = RID_RW;
2506	cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
2507	cmd.parm2 = 1; /* Magic number... */
2508	rc=issuecommand(ai, &cmd, &rsp);
2509	if (rc != SUCCESS) {
2510		airo_print_err(ai->dev->name, "Couldn't allocate RID");
2511		return rc;
2512	}
2513
2514	memcpy_toio(ai->config_desc.card_ram_off,
2515		&ai->config_desc.rid_desc, sizeof(Rid));
2516
2517	return rc;
2518}
2519
2520/*
2521 * We are setting up three things here:
2522 * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
2523 * 2) Map PCI memory for issuing commands.
2524 * 3) Allocate memory (shared) to send and receive ethernet frames.
2525 */
2526static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
2527{
2528	unsigned long mem_start, mem_len, aux_start, aux_len;
2529	int rc = -1;
2530	int i;
2531	dma_addr_t busaddroff;
2532	unsigned char *vpackoff;
2533	unsigned char __iomem *pciaddroff;
2534
2535	mem_start = pci_resource_start(pci, 1);
2536	mem_len = pci_resource_len(pci, 1);
2537	aux_start = pci_resource_start(pci, 2);
2538	aux_len = AUXMEMSIZE;
2539
2540	if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
2541		airo_print_err("", "Couldn't get region %x[%x]",
2542			(int)mem_start, (int)mem_len);
2543		goto out;
2544	}
2545	if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
2546		airo_print_err("", "Couldn't get region %x[%x]",
2547			(int)aux_start, (int)aux_len);
2548		goto free_region1;
2549	}
2550
2551	ai->pcimem = ioremap(mem_start, mem_len);
2552	if (!ai->pcimem) {
2553		airo_print_err("", "Couldn't map region %x[%x]",
2554			(int)mem_start, (int)mem_len);
2555		goto free_region2;
2556	}
2557	ai->pciaux = ioremap(aux_start, aux_len);
2558	if (!ai->pciaux) {
2559		airo_print_err("", "Couldn't map region %x[%x]",
2560			(int)aux_start, (int)aux_len);
2561		goto free_memmap;
2562	}
2563
2564	/* Reserve PKTSIZE for each fid and 2K for the Rids */
2565	ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
 
2566	if (!ai->shared) {
2567		airo_print_err("", "Couldn't alloc_consistent %d",
2568			PCI_SHARED_LEN);
2569		goto free_auxmap;
2570	}
2571
2572	/*
2573	 * Setup descriptor RX, TX, CONFIG
2574	 */
2575	busaddroff = ai->shared_dma;
2576	pciaddroff = ai->pciaux + AUX_OFFSET;
2577	vpackoff   = ai->shared;
2578
2579	/* RX descriptor setup */
2580	for(i = 0; i < MPI_MAX_FIDS; i++) {
2581		ai->rxfids[i].pending = 0;
2582		ai->rxfids[i].card_ram_off = pciaddroff;
2583		ai->rxfids[i].virtual_host_addr = vpackoff;
2584		ai->rxfids[i].rx_desc.host_addr = busaddroff;
2585		ai->rxfids[i].rx_desc.valid = 1;
2586		ai->rxfids[i].rx_desc.len = PKTSIZE;
2587		ai->rxfids[i].rx_desc.rdy = 0;
2588
2589		pciaddroff += sizeof(RxFid);
2590		busaddroff += PKTSIZE;
2591		vpackoff   += PKTSIZE;
2592	}
2593
2594	/* TX descriptor setup */
2595	for(i = 0; i < MPI_MAX_FIDS; i++) {
2596		ai->txfids[i].card_ram_off = pciaddroff;
2597		ai->txfids[i].virtual_host_addr = vpackoff;
2598		ai->txfids[i].tx_desc.valid = 1;
2599		ai->txfids[i].tx_desc.host_addr = busaddroff;
2600		memcpy(ai->txfids[i].virtual_host_addr,
2601			&wifictlhdr8023, sizeof(wifictlhdr8023));
2602
2603		pciaddroff += sizeof(TxFid);
2604		busaddroff += PKTSIZE;
2605		vpackoff   += PKTSIZE;
2606	}
2607	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2608
2609	/* Rid descriptor setup */
2610	ai->config_desc.card_ram_off = pciaddroff;
2611	ai->config_desc.virtual_host_addr = vpackoff;
2612	ai->config_desc.rid_desc.host_addr = busaddroff;
2613	ai->ridbus = busaddroff;
2614	ai->config_desc.rid_desc.rid = 0;
2615	ai->config_desc.rid_desc.len = RIDSIZE;
2616	ai->config_desc.rid_desc.valid = 1;
2617	pciaddroff += sizeof(Rid);
2618	busaddroff += RIDSIZE;
2619	vpackoff   += RIDSIZE;
2620
2621	/* Tell card about descriptors */
2622	if (mpi_init_descriptors (ai) != SUCCESS)
2623		goto free_shared;
2624
2625	return 0;
2626 free_shared:
2627	pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
 
2628 free_auxmap:
2629	iounmap(ai->pciaux);
2630 free_memmap:
2631	iounmap(ai->pcimem);
2632 free_region2:
2633	release_mem_region(aux_start, aux_len);
2634 free_region1:
2635	release_mem_region(mem_start, mem_len);
2636 out:
2637	return rc;
2638}
2639
2640static const struct header_ops airo_header_ops = {
2641	.parse = wll_header_parse,
2642};
2643
2644static const struct net_device_ops airo11_netdev_ops = {
2645	.ndo_open 		= airo_open,
2646	.ndo_stop 		= airo_close,
2647	.ndo_start_xmit 	= airo_start_xmit11,
2648	.ndo_get_stats 		= airo_get_stats,
2649	.ndo_set_mac_address	= airo_set_mac_address,
2650	.ndo_do_ioctl		= airo_ioctl,
2651};
2652
2653static void wifi_setup(struct net_device *dev)
2654{
2655	dev->netdev_ops = &airo11_netdev_ops;
2656	dev->header_ops = &airo_header_ops;
2657	dev->wireless_handlers = &airo_handler_def;
2658
2659	dev->type               = ARPHRD_IEEE80211;
2660	dev->hard_header_len    = ETH_HLEN;
2661	dev->mtu                = AIRO_DEF_MTU;
2662	dev->min_mtu            = 68;
2663	dev->max_mtu            = MIC_MSGLEN_MAX;
2664	dev->addr_len           = ETH_ALEN;
2665	dev->tx_queue_len       = 100; 
2666
2667	eth_broadcast_addr(dev->broadcast);
2668
2669	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
2670}
2671
2672static struct net_device *init_wifidev(struct airo_info *ai,
2673					struct net_device *ethdev)
2674{
2675	int err;
2676	struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN,
2677					      wifi_setup);
2678	if (!dev)
2679		return NULL;
2680	dev->ml_priv = ethdev->ml_priv;
2681	dev->irq = ethdev->irq;
2682	dev->base_addr = ethdev->base_addr;
2683	dev->wireless_data = ethdev->wireless_data;
2684	SET_NETDEV_DEV(dev, ethdev->dev.parent);
2685	eth_hw_addr_inherit(dev, ethdev);
2686	err = register_netdev(dev);
2687	if (err<0) {
2688		free_netdev(dev);
2689		return NULL;
2690	}
2691	return dev;
2692}
2693
2694static int reset_card( struct net_device *dev , int lock) {
 
2695	struct airo_info *ai = dev->ml_priv;
2696
2697	if (lock && down_interruptible(&ai->sem))
2698		return -1;
2699	waitbusy (ai);
2700	OUT4500(ai,COMMAND,CMD_SOFTRESET);
2701	msleep(200);
2702	waitbusy (ai);
2703	msleep(200);
2704	if (lock)
2705		up(&ai->sem);
2706	return 0;
2707}
2708
2709#define AIRO_MAX_NETWORK_COUNT	64
2710static int airo_networks_allocate(struct airo_info *ai)
2711{
2712	if (ai->networks)
2713		return 0;
2714
2715	ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
2716			       GFP_KERNEL);
2717	if (!ai->networks) {
2718		airo_print_warn("", "Out of memory allocating beacons");
2719		return -ENOMEM;
2720	}
2721
2722	return 0;
2723}
2724
2725static void airo_networks_free(struct airo_info *ai)
2726{
2727	kfree(ai->networks);
2728	ai->networks = NULL;
2729}
2730
2731static void airo_networks_initialize(struct airo_info *ai)
2732{
2733	int i;
2734
2735	INIT_LIST_HEAD(&ai->network_free_list);
2736	INIT_LIST_HEAD(&ai->network_list);
2737	for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
2738		list_add_tail(&ai->networks[i].list,
2739			      &ai->network_free_list);
2740}
2741
2742static const struct net_device_ops airo_netdev_ops = {
2743	.ndo_open		= airo_open,
2744	.ndo_stop		= airo_close,
2745	.ndo_start_xmit		= airo_start_xmit,
2746	.ndo_get_stats		= airo_get_stats,
2747	.ndo_set_rx_mode	= airo_set_multicast_list,
2748	.ndo_set_mac_address	= airo_set_mac_address,
2749	.ndo_do_ioctl		= airo_ioctl,
2750	.ndo_validate_addr	= eth_validate_addr,
2751};
2752
2753static const struct net_device_ops mpi_netdev_ops = {
2754	.ndo_open		= airo_open,
2755	.ndo_stop		= airo_close,
2756	.ndo_start_xmit		= mpi_start_xmit,
2757	.ndo_get_stats		= airo_get_stats,
2758	.ndo_set_rx_mode	= airo_set_multicast_list,
2759	.ndo_set_mac_address	= airo_set_mac_address,
2760	.ndo_do_ioctl		= airo_ioctl,
2761	.ndo_validate_addr	= eth_validate_addr,
2762};
2763
2764
2765static struct net_device *_init_airo_card( unsigned short irq, int port,
2766					   int is_pcmcia, struct pci_dev *pci,
2767					   struct device *dmdev )
2768{
2769	struct net_device *dev;
2770	struct airo_info *ai;
2771	int i, rc;
2772	CapabilityRid cap_rid;
2773
2774	/* Create the network device object. */
2775	dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup);
2776	if (!dev) {
2777		airo_print_err("", "Couldn't alloc_etherdev");
2778		return NULL;
2779	}
2780
2781	ai = dev->ml_priv = netdev_priv(dev);
2782	ai->wifidev = NULL;
2783	ai->flags = 1 << FLAG_RADIO_DOWN;
2784	ai->jobs = 0;
2785	ai->dev = dev;
2786	if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2787		airo_print_dbg("", "Found an MPI350 card");
2788		set_bit(FLAG_MPI, &ai->flags);
2789	}
2790	spin_lock_init(&ai->aux_lock);
2791	sema_init(&ai->sem, 1);
2792	ai->config.len = 0;
2793	ai->pci = pci;
2794	init_waitqueue_head (&ai->thr_wait);
2795	ai->tfm = NULL;
2796	add_airo_dev(ai);
2797	ai->APList.len = cpu_to_le16(sizeof(struct APListRid));
2798
2799	if (airo_networks_allocate (ai))
2800		goto err_out_free;
2801	airo_networks_initialize (ai);
2802
2803	skb_queue_head_init (&ai->txq);
2804
2805	/* The Airo-specific entries in the device structure. */
2806	if (test_bit(FLAG_MPI,&ai->flags))
2807		dev->netdev_ops = &mpi_netdev_ops;
2808	else
2809		dev->netdev_ops = &airo_netdev_ops;
2810	dev->wireless_handlers = &airo_handler_def;
2811	ai->wireless_data.spy_data = &ai->spy_data;
2812	dev->wireless_data = &ai->wireless_data;
2813	dev->irq = irq;
2814	dev->base_addr = port;
2815	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
2816	dev->max_mtu = MIC_MSGLEN_MAX;
2817
2818	SET_NETDEV_DEV(dev, dmdev);
2819
2820	reset_card (dev, 1);
2821	msleep(400);
2822
2823	if (!is_pcmcia) {
2824		if (!request_region(dev->base_addr, 64, DRV_NAME)) {
2825			rc = -EBUSY;
2826			airo_print_err(dev->name, "Couldn't request region");
2827			goto err_out_nets;
2828		}
2829	}
2830
2831	if (test_bit(FLAG_MPI,&ai->flags)) {
2832		if (mpi_map_card(ai, pci)) {
2833			airo_print_err("", "Could not map memory");
2834			goto err_out_res;
2835		}
2836	}
2837
2838	if (probe) {
2839		if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
2840			airo_print_err(dev->name, "MAC could not be enabled" );
2841			rc = -EIO;
2842			goto err_out_map;
2843		}
2844	} else if (!test_bit(FLAG_MPI,&ai->flags)) {
2845		ai->bap_read = fast_bap_read;
2846		set_bit(FLAG_FLASHING, &ai->flags);
2847	}
2848
2849	strcpy(dev->name, "eth%d");
2850	rc = register_netdev(dev);
2851	if (rc) {
2852		airo_print_err(dev->name, "Couldn't register_netdev");
2853		goto err_out_map;
2854	}
2855	ai->wifidev = init_wifidev(ai, dev);
2856	if (!ai->wifidev)
2857		goto err_out_reg;
2858
2859	rc = readCapabilityRid(ai, &cap_rid, 1);
2860	if (rc != SUCCESS) {
2861		rc = -EIO;
2862		goto err_out_wifi;
2863	}
2864	/* WEP capability discovery */
2865	ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2866	ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2867
2868	airo_print_info(dev->name, "Firmware version %x.%x.%02d",
2869	                ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2870	                (le16_to_cpu(cap_rid.softVer) & 0xFF),
2871	                le16_to_cpu(cap_rid.softSubVer));
2872
2873	/* Test for WPA support */
2874	/* Only firmware versions 5.30.17 or better can do WPA */
2875	if (le16_to_cpu(cap_rid.softVer) > 0x530
2876	 || (le16_to_cpu(cap_rid.softVer) == 0x530
2877	      && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2878		airo_print_info(ai->dev->name, "WPA supported.");
2879
2880		set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2881		ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2882		ai->bssListNext = RID_WPA_BSSLISTNEXT;
2883		ai->bssListRidLen = sizeof(BSSListRid);
2884	} else {
2885		airo_print_info(ai->dev->name, "WPA unsupported with firmware "
2886			"versions older than 5.30.17.");
2887
2888		ai->bssListFirst = RID_BSSLISTFIRST;
2889		ai->bssListNext = RID_BSSLISTNEXT;
2890		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2891	}
2892
2893	set_bit(FLAG_REGISTERED,&ai->flags);
2894	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2895
2896	/* Allocate the transmit buffers */
2897	if (probe && !test_bit(FLAG_MPI,&ai->flags))
2898		for( i = 0; i < MAX_FIDS; i++ )
2899			ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
2900
2901	if (setup_proc_entry(dev, dev->ml_priv) < 0)
2902		goto err_out_wifi;
2903
2904	return dev;
2905
2906err_out_wifi:
2907	unregister_netdev(ai->wifidev);
2908	free_netdev(ai->wifidev);
2909err_out_reg:
2910	unregister_netdev(dev);
2911err_out_map:
2912	if (test_bit(FLAG_MPI,&ai->flags) && pci) {
2913		pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
 
2914		iounmap(ai->pciaux);
2915		iounmap(ai->pcimem);
2916		mpi_unmap_card(ai->pci);
2917	}
2918err_out_res:
2919	if (!is_pcmcia)
2920	        release_region( dev->base_addr, 64 );
2921err_out_nets:
2922	airo_networks_free(ai);
2923err_out_free:
2924	del_airo_dev(ai);
2925	free_netdev(dev);
2926	return NULL;
2927}
2928
2929struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia,
2930				  struct device *dmdev)
2931{
2932	return _init_airo_card ( irq, port, is_pcmcia, NULL, dmdev);
2933}
2934
2935EXPORT_SYMBOL(init_airo_card);
2936
2937static int waitbusy (struct airo_info *ai) {
 
2938	int delay = 0;
2939	while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) {
2940		udelay (10);
2941		if ((++delay % 20) == 0)
2942			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2943	}
2944	return delay < 10000;
2945}
2946
2947int reset_airo_card( struct net_device *dev )
2948{
2949	int i;
2950	struct airo_info *ai = dev->ml_priv;
2951
2952	if (reset_card (dev, 1))
2953		return -1;
2954
2955	if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
2956		airo_print_err(dev->name, "MAC could not be enabled");
2957		return -1;
2958	}
2959	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2960	/* Allocate the transmit buffers if needed */
2961	if (!test_bit(FLAG_MPI,&ai->flags))
2962		for( i = 0; i < MAX_FIDS; i++ )
2963			ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
2964
2965	enable_interrupts( ai );
2966	netif_wake_queue(dev);
2967	return 0;
2968}
2969
2970EXPORT_SYMBOL(reset_airo_card);
2971
2972static void airo_send_event(struct net_device *dev) {
 
2973	struct airo_info *ai = dev->ml_priv;
2974	union iwreq_data wrqu;
2975	StatusRid status_rid;
2976
2977	clear_bit(JOB_EVENT, &ai->jobs);
2978	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
2979	up(&ai->sem);
2980	wrqu.data.length = 0;
2981	wrqu.data.flags = 0;
2982	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
2983	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2984
2985	/* Send event to user space */
2986	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
2987}
2988
2989static void airo_process_scan_results (struct airo_info *ai) {
 
2990	union iwreq_data	wrqu;
2991	BSSListRid bss;
2992	int rc;
2993	BSSListElement * loop_net;
2994	BSSListElement * tmp_net;
2995
2996	/* Blow away current list of scan results */
2997	list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
2998		list_move_tail (&loop_net->list, &ai->network_free_list);
2999		/* Don't blow away ->list, just BSS data */
3000		memset (loop_net, 0, sizeof (loop_net->bss));
3001	}
3002
3003	/* Try to read the first entry of the scan result */
3004	rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
3005	if((rc) || (bss.index == cpu_to_le16(0xffff))) {
3006		/* No scan results */
3007		goto out;
3008	}
3009
3010	/* Read and parse all entries */
3011	tmp_net = NULL;
3012	while((!rc) && (bss.index != cpu_to_le16(0xffff))) {
3013		/* Grab a network off the free list */
3014		if (!list_empty(&ai->network_free_list)) {
3015			tmp_net = list_entry(ai->network_free_list.next,
3016					    BSSListElement, list);
3017			list_del(ai->network_free_list.next);
3018		}
3019
3020		if (tmp_net != NULL) {
3021			memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
3022			list_add_tail(&tmp_net->list, &ai->network_list);
3023			tmp_net = NULL;
3024		}
3025
3026		/* Read next entry */
3027		rc = PC4500_readrid(ai, ai->bssListNext,
3028				    &bss, ai->bssListRidLen, 0);
3029	}
3030
3031out:
3032	/* write APList back (we cleared it in airo_set_scan) */
3033	disable_MAC(ai, 2);
3034	writeAPListRid(ai, &ai->APList, 0);
3035	enable_MAC(ai, 0);
3036
3037	ai->scan_timeout = 0;
3038	clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
3039	up(&ai->sem);
3040
3041	/* Send an empty event to user space.
3042	 * We don't send the received data on
3043	 * the event because it would require
3044	 * us to do complex transcoding, and
3045	 * we want to minimise the work done in
3046	 * the irq handler. Use a request to
3047	 * extract the data - Jean II */
3048	wrqu.data.length = 0;
3049	wrqu.data.flags = 0;
3050	wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
3051}
3052
3053static int airo_thread(void *data) {
 
3054	struct net_device *dev = data;
3055	struct airo_info *ai = dev->ml_priv;
3056	int locked;
3057
3058	set_freezable();
3059	while(1) {
3060		/* make swsusp happy with our thread */
3061		try_to_freeze();
3062
3063		if (test_bit(JOB_DIE, &ai->jobs))
3064			break;
3065
3066		if (ai->jobs) {
3067			locked = down_interruptible(&ai->sem);
3068		} else {
3069			wait_queue_entry_t wait;
3070
3071			init_waitqueue_entry(&wait, current);
3072			add_wait_queue(&ai->thr_wait, &wait);
3073			for (;;) {
3074				set_current_state(TASK_INTERRUPTIBLE);
3075				if (ai->jobs)
3076					break;
3077				if (ai->expires || ai->scan_timeout) {
3078					if (ai->scan_timeout &&
3079							time_after_eq(jiffies,ai->scan_timeout)){
3080						set_bit(JOB_SCAN_RESULTS, &ai->jobs);
3081						break;
3082					} else if (ai->expires &&
3083							time_after_eq(jiffies,ai->expires)){
3084						set_bit(JOB_AUTOWEP, &ai->jobs);
3085						break;
3086					}
3087					if (!kthread_should_stop() &&
3088					    !freezing(current)) {
3089						unsigned long wake_at;
3090						if (!ai->expires || !ai->scan_timeout) {
3091							wake_at = max(ai->expires,
3092								ai->scan_timeout);
3093						} else {
3094							wake_at = min(ai->expires,
3095								ai->scan_timeout);
3096						}
3097						schedule_timeout(wake_at - jiffies);
3098						continue;
3099					}
3100				} else if (!kthread_should_stop() &&
3101					   !freezing(current)) {
3102					schedule();
3103					continue;
3104				}
3105				break;
3106			}
3107			current->state = TASK_RUNNING;
3108			remove_wait_queue(&ai->thr_wait, &wait);
3109			locked = 1;
3110		}
3111
3112		if (locked)
3113			continue;
3114
3115		if (test_bit(JOB_DIE, &ai->jobs)) {
3116			up(&ai->sem);
3117			break;
3118		}
3119
3120		if (ai->power.event || test_bit(FLAG_FLASHING, &ai->flags)) {
3121			up(&ai->sem);
3122			continue;
3123		}
3124
3125		if (test_bit(JOB_XMIT, &ai->jobs))
3126			airo_end_xmit(dev);
3127		else if (test_bit(JOB_XMIT11, &ai->jobs))
3128			airo_end_xmit11(dev);
3129		else if (test_bit(JOB_STATS, &ai->jobs))
3130			airo_read_stats(dev);
3131		else if (test_bit(JOB_WSTATS, &ai->jobs))
3132			airo_read_wireless_stats(ai);
3133		else if (test_bit(JOB_PROMISC, &ai->jobs))
3134			airo_set_promisc(ai);
3135		else if (test_bit(JOB_MIC, &ai->jobs))
3136			micinit(ai);
3137		else if (test_bit(JOB_EVENT, &ai->jobs))
3138			airo_send_event(dev);
3139		else if (test_bit(JOB_AUTOWEP, &ai->jobs))
3140			timer_func(dev);
3141		else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
3142			airo_process_scan_results(ai);
3143		else  /* Shouldn't get here, but we make sure to unlock */
3144			up(&ai->sem);
3145	}
3146
3147	return 0;
3148}
3149
3150static int header_len(__le16 ctl)
3151{
3152	u16 fc = le16_to_cpu(ctl);
3153	switch (fc & 0xc) {
3154	case 4:
3155		if ((fc & 0xe0) == 0xc0)
3156			return 10;	/* one-address control packet */
3157		return 16;	/* two-address control packet */
3158	case 8:
3159		if ((fc & 0x300) == 0x300)
3160			return 30;	/* WDS packet */
3161	}
3162	return 24;
3163}
3164
3165static void airo_handle_cisco_mic(struct airo_info *ai)
3166{
3167	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
3168		set_bit(JOB_MIC, &ai->jobs);
3169		wake_up_interruptible(&ai->thr_wait);
3170	}
3171}
3172
3173/* Airo Status codes */
3174#define STAT_NOBEACON	0x8000 /* Loss of sync - missed beacons */
3175#define STAT_MAXRETRIES	0x8001 /* Loss of sync - max retries */
3176#define STAT_MAXARL	0x8002 /* Loss of sync - average retry level exceeded*/
3177#define STAT_FORCELOSS	0x8003 /* Loss of sync - host request */
3178#define STAT_TSFSYNC	0x8004 /* Loss of sync - TSF synchronization */
3179#define STAT_DEAUTH	0x8100 /* low byte is 802.11 reason code */
3180#define STAT_DISASSOC	0x8200 /* low byte is 802.11 reason code */
3181#define STAT_ASSOC_FAIL	0x8400 /* low byte is 802.11 reason code */
3182#define STAT_AUTH_FAIL	0x0300 /* low byte is 802.11 reason code */
3183#define STAT_ASSOC	0x0400 /* Associated */
3184#define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
3185
3186static void airo_print_status(const char *devname, u16 status)
3187{
3188	u8 reason = status & 0xFF;
3189
3190	switch (status & 0xFF00) {
3191	case STAT_NOBEACON:
3192		switch (status) {
3193		case STAT_NOBEACON:
3194			airo_print_dbg(devname, "link lost (missed beacons)");
3195			break;
3196		case STAT_MAXRETRIES:
3197		case STAT_MAXARL:
3198			airo_print_dbg(devname, "link lost (max retries)");
3199			break;
3200		case STAT_FORCELOSS:
3201			airo_print_dbg(devname, "link lost (local choice)");
3202			break;
3203		case STAT_TSFSYNC:
3204			airo_print_dbg(devname, "link lost (TSF sync lost)");
3205			break;
3206		default:
3207			airo_print_dbg(devname, "unknown status %x\n", status);
3208			break;
3209		}
3210		break;
3211	case STAT_DEAUTH:
3212		airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
3213		break;
3214	case STAT_DISASSOC:
3215		airo_print_dbg(devname, "disassociated (reason: %d)", reason);
3216		break;
3217	case STAT_ASSOC_FAIL:
3218		airo_print_dbg(devname, "association failed (reason: %d)",
3219			       reason);
3220		break;
3221	case STAT_AUTH_FAIL:
3222		airo_print_dbg(devname, "authentication failed (reason: %d)",
3223			       reason);
3224		break;
3225	case STAT_ASSOC:
3226	case STAT_REASSOC:
3227		break;
3228	default:
3229		airo_print_dbg(devname, "unknown status %x\n", status);
3230		break;
3231	}
3232}
3233
3234static void airo_handle_link(struct airo_info *ai)
3235{
3236	union iwreq_data wrqu;
3237	int scan_forceloss = 0;
3238	u16 status;
3239
3240	/* Get new status and acknowledge the link change */
3241	status = le16_to_cpu(IN4500(ai, LINKSTAT));
3242	OUT4500(ai, EVACK, EV_LINK);
3243
3244	if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
3245		scan_forceloss = 1;
3246
3247	airo_print_status(ai->dev->name, status);
3248
3249	if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
3250		if (auto_wep)
3251			ai->expires = 0;
3252		if (ai->list_bss_task)
3253			wake_up_process(ai->list_bss_task);
3254		set_bit(FLAG_UPDATE_UNI, &ai->flags);
3255		set_bit(FLAG_UPDATE_MULTI, &ai->flags);
3256
3257		if (down_trylock(&ai->sem) != 0) {
3258			set_bit(JOB_EVENT, &ai->jobs);
3259			wake_up_interruptible(&ai->thr_wait);
3260		} else
3261			airo_send_event(ai->dev);
3262		netif_carrier_on(ai->dev);
3263	} else if (!scan_forceloss) {
3264		if (auto_wep && !ai->expires) {
3265			ai->expires = RUN_AT(3*HZ);
3266			wake_up_interruptible(&ai->thr_wait);
3267		}
3268
3269		/* Send event to user space */
3270		eth_zero_addr(wrqu.ap_addr.sa_data);
3271		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3272		wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
3273		netif_carrier_off(ai->dev);
3274	} else {
3275		netif_carrier_off(ai->dev);
3276	}
3277}
3278
3279static void airo_handle_rx(struct airo_info *ai)
3280{
3281	struct sk_buff *skb = NULL;
3282	__le16 fc, v, *buffer, tmpbuf[4];
3283	u16 len, hdrlen = 0, gap, fid;
3284	struct rx_hdr hdr;
3285	int success = 0;
3286
3287	if (test_bit(FLAG_MPI, &ai->flags)) {
3288		if (test_bit(FLAG_802_11, &ai->flags))
3289			mpi_receive_802_11(ai);
3290		else
3291			mpi_receive_802_3(ai);
3292		OUT4500(ai, EVACK, EV_RX);
3293		return;
3294	}
3295
3296	fid = IN4500(ai, RXFID);
3297
3298	/* Get the packet length */
3299	if (test_bit(FLAG_802_11, &ai->flags)) {
3300		bap_setup (ai, fid, 4, BAP0);
3301		bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
3302		/* Bad CRC. Ignore packet */
3303		if (le16_to_cpu(hdr.status) & 2)
3304			hdr.len = 0;
3305		if (ai->wifidev == NULL)
3306			hdr.len = 0;
3307	} else {
3308		bap_setup(ai, fid, 0x36, BAP0);
3309		bap_read(ai, &hdr.len, 2, BAP0);
3310	}
3311	len = le16_to_cpu(hdr.len);
3312
3313	if (len > AIRO_DEF_MTU) {
3314		airo_print_err(ai->dev->name, "Bad size %d", len);
3315		goto done;
3316	}
3317	if (len == 0)
3318		goto done;
3319
3320	if (test_bit(FLAG_802_11, &ai->flags)) {
3321		bap_read(ai, &fc, sizeof (fc), BAP0);
3322		hdrlen = header_len(fc);
3323	} else
3324		hdrlen = ETH_ALEN * 2;
3325
3326	skb = dev_alloc_skb(len + hdrlen + 2 + 2);
3327	if (!skb) {
3328		ai->dev->stats.rx_dropped++;
3329		goto done;
3330	}
3331
3332	skb_reserve(skb, 2); /* This way the IP header is aligned */
3333	buffer = skb_put(skb, len + hdrlen);
3334	if (test_bit(FLAG_802_11, &ai->flags)) {
3335		buffer[0] = fc;
3336		bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
3337		if (hdrlen == 24)
3338			bap_read(ai, tmpbuf, 6, BAP0);
3339
3340		bap_read(ai, &v, sizeof(v), BAP0);
3341		gap = le16_to_cpu(v);
3342		if (gap) {
3343			if (gap <= 8) {
3344				bap_read(ai, tmpbuf, gap, BAP0);
3345			} else {
3346				airo_print_err(ai->dev->name, "gaplen too "
3347					"big. Problems will follow...");
3348			}
3349		}
3350		bap_read(ai, buffer + hdrlen/2, len, BAP0);
3351	} else {
3352		MICBuffer micbuf;
3353
3354		bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
3355		if (ai->micstats.enabled) {
3356			bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
3357			if (ntohs(micbuf.typelen) > 0x05DC)
3358				bap_setup(ai, fid, 0x44, BAP0);
3359			else {
3360				if (len <= sizeof (micbuf)) {
3361					dev_kfree_skb_irq(skb);
3362					goto done;
3363				}
3364
3365				len -= sizeof(micbuf);
3366				skb_trim(skb, len + hdrlen);
3367			}
3368		}
3369
3370		bap_read(ai, buffer + ETH_ALEN, len, BAP0);
3371		if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
3372			dev_kfree_skb_irq (skb);
3373		else
3374			success = 1;
3375	}
3376
3377#ifdef WIRELESS_SPY
3378	if (success && (ai->spy_data.spy_number > 0)) {
3379		char *sa;
3380		struct iw_quality wstats;
3381
3382		/* Prepare spy data : addr + qual */
3383		if (!test_bit(FLAG_802_11, &ai->flags)) {
3384			sa = (char *) buffer + 6;
3385			bap_setup(ai, fid, 8, BAP0);
3386			bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
3387		} else
3388			sa = (char *) buffer + 10;
3389		wstats.qual = hdr.rssi[0];
3390		if (ai->rssi)
3391			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3392		else
3393			wstats.level = (hdr.rssi[1] + 321) / 2;
3394		wstats.noise = ai->wstats.qual.noise;
3395		wstats.updated =  IW_QUAL_LEVEL_UPDATED
3396				| IW_QUAL_QUAL_UPDATED
3397				| IW_QUAL_DBM;
3398		/* Update spy records */
3399		wireless_spy_update(ai->dev, sa, &wstats);
3400	}
3401#endif /* WIRELESS_SPY */
3402
3403done:
3404	OUT4500(ai, EVACK, EV_RX);
3405
3406	if (success) {
3407		if (test_bit(FLAG_802_11, &ai->flags)) {
3408			skb_reset_mac_header(skb);
3409			skb->pkt_type = PACKET_OTHERHOST;
3410			skb->dev = ai->wifidev;
3411			skb->protocol = htons(ETH_P_802_2);
3412		} else
3413			skb->protocol = eth_type_trans(skb, ai->dev);
3414		skb->ip_summed = CHECKSUM_NONE;
3415
3416		netif_rx(skb);
3417	}
3418}
3419
3420static void airo_handle_tx(struct airo_info *ai, u16 status)
3421{
3422	int i, len = 0, index = -1;
3423	u16 fid;
3424
3425	if (test_bit(FLAG_MPI, &ai->flags)) {
3426		unsigned long flags;
3427
3428		if (status & EV_TXEXC)
3429			get_tx_error(ai, -1);
3430
3431		spin_lock_irqsave(&ai->aux_lock, flags);
3432		if (!skb_queue_empty(&ai->txq)) {
3433			spin_unlock_irqrestore(&ai->aux_lock,flags);
3434			mpi_send_packet(ai->dev);
3435		} else {
3436			clear_bit(FLAG_PENDING_XMIT, &ai->flags);
3437			spin_unlock_irqrestore(&ai->aux_lock,flags);
3438			netif_wake_queue(ai->dev);
3439		}
3440		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3441		return;
3442	}
3443
3444	fid = IN4500(ai, TXCOMPLFID);
3445
3446	for(i = 0; i < MAX_FIDS; i++) {
3447		if ((ai->fids[i] & 0xffff) == fid) {
3448			len = ai->fids[i] >> 16;
3449			index = i;
3450		}
3451	}
3452
3453	if (index != -1) {
3454		if (status & EV_TXEXC)
3455			get_tx_error(ai, index);
3456
3457		OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
3458
3459		/* Set up to be used again */
3460		ai->fids[index] &= 0xffff;
3461		if (index < MAX_FIDS / 2) {
3462			if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
3463				netif_wake_queue(ai->dev);
3464		} else {
3465			if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
3466				netif_wake_queue(ai->wifidev);
3467		}
3468	} else {
3469		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3470		airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
3471	}
3472}
3473
3474static irqreturn_t airo_interrupt(int irq, void *dev_id)
3475{
3476	struct net_device *dev = dev_id;
3477	u16 status, savedInterrupts = 0;
3478	struct airo_info *ai = dev->ml_priv;
3479	int handled = 0;
3480
3481	if (!netif_device_present(dev))
3482		return IRQ_NONE;
3483
3484	for (;;) {
3485		status = IN4500(ai, EVSTAT);
3486		if (!(status & STATUS_INTS) || (status == 0xffff))
3487			break;
3488
3489		handled = 1;
3490
3491		if (status & EV_AWAKE) {
3492			OUT4500(ai, EVACK, EV_AWAKE);
3493			OUT4500(ai, EVACK, EV_AWAKE);
3494		}
3495
3496		if (!savedInterrupts) {
3497			savedInterrupts = IN4500(ai, EVINTEN);
3498			OUT4500(ai, EVINTEN, 0);
3499		}
3500
3501		if (status & EV_MIC) {
3502			OUT4500(ai, EVACK, EV_MIC);
3503			airo_handle_cisco_mic(ai);
3504		}
3505
3506		if (status & EV_LINK) {
3507			/* Link status changed */
3508			airo_handle_link(ai);
3509		}
3510
3511		/* Check to see if there is something to receive */
3512		if (status & EV_RX)
3513			airo_handle_rx(ai);
3514
3515		/* Check to see if a packet has been transmitted */
3516		if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
3517			airo_handle_tx(ai, status);
3518
3519		if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
3520			airo_print_warn(ai->dev->name, "Got weird status %x",
3521				status & ~STATUS_INTS & ~IGNORE_INTS );
3522		}
3523	}
3524
3525	if (savedInterrupts)
3526		OUT4500(ai, EVINTEN, savedInterrupts);
3527
3528	return IRQ_RETVAL(handled);
3529}
3530
3531/*
3532 *  Routines to talk to the card
3533 */
3534
3535/*
3536 *  This was originally written for the 4500, hence the name
3537 *  NOTE:  If use with 8bit mode and SMP bad things will happen!
3538 *         Why would some one do 8 bit IO in an SMP machine?!?
3539 */
3540static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
 
3541	if (test_bit(FLAG_MPI,&ai->flags))
3542		reg <<= 1;
3543	if ( !do8bitIO )
3544		outw( val, ai->dev->base_addr + reg );
3545	else {
3546		outb( val & 0xff, ai->dev->base_addr + reg );
3547		outb( val >> 8, ai->dev->base_addr + reg + 1 );
3548	}
3549}
3550
3551static u16 IN4500( struct airo_info *ai, u16 reg ) {
 
3552	unsigned short rc;
3553
3554	if (test_bit(FLAG_MPI,&ai->flags))
3555		reg <<= 1;
3556	if ( !do8bitIO )
3557		rc = inw( ai->dev->base_addr + reg );
3558	else {
3559		rc = inb( ai->dev->base_addr + reg );
3560		rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
3561	}
3562	return rc;
3563}
3564
3565static int enable_MAC(struct airo_info *ai, int lock)
3566{
3567	int rc;
3568	Cmd cmd;
3569	Resp rsp;
3570
3571	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3572	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3573	 * Note : we could try to use !netif_running(dev) in enable_MAC()
3574	 * instead of this flag, but I don't trust it *within* the
3575	 * open/close functions, and testing both flags together is
3576	 * "cheaper" - Jean II */
3577	if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3578
3579	if (lock && down_interruptible(&ai->sem))
3580		return -ERESTARTSYS;
3581
3582	if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3583		memset(&cmd, 0, sizeof(cmd));
3584		cmd.cmd = MAC_ENABLE;
3585		rc = issuecommand(ai, &cmd, &rsp);
3586		if (rc == SUCCESS)
3587			set_bit(FLAG_ENABLED, &ai->flags);
3588	} else
3589		rc = SUCCESS;
3590
3591	if (lock)
3592	    up(&ai->sem);
3593
3594	if (rc)
3595		airo_print_err(ai->dev->name, "Cannot enable MAC");
3596	else if ((rsp.status & 0xFF00) != 0) {
3597		airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
3598			"rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
3599		rc = ERROR;
3600	}
3601	return rc;
3602}
3603
3604static void disable_MAC( struct airo_info *ai, int lock ) {
 
3605        Cmd cmd;
3606	Resp rsp;
3607
3608	if (lock == 1 && down_interruptible(&ai->sem))
3609		return;
3610
3611	if (test_bit(FLAG_ENABLED, &ai->flags)) {
3612		if (lock != 2) /* lock == 2 means don't disable carrier */
3613			netif_carrier_off(ai->dev);
3614		memset(&cmd, 0, sizeof(cmd));
3615		cmd.cmd = MAC_DISABLE; // disable in case already enabled
3616		issuecommand(ai, &cmd, &rsp);
3617		clear_bit(FLAG_ENABLED, &ai->flags);
3618	}
3619	if (lock == 1)
3620		up(&ai->sem);
3621}
3622
3623static void enable_interrupts( struct airo_info *ai ) {
 
3624	/* Enable the interrupts */
3625	OUT4500( ai, EVINTEN, STATUS_INTS );
3626}
3627
3628static void disable_interrupts( struct airo_info *ai ) {
3629	OUT4500( ai, EVINTEN, 0 );
 
3630}
3631
3632static void mpi_receive_802_3(struct airo_info *ai)
3633{
3634	RxFid rxd;
3635	int len = 0;
3636	struct sk_buff *skb;
3637	char *buffer;
3638	int off = 0;
3639	MICBuffer micbuf;
3640
3641	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3642	/* Make sure we got something */
3643	if (rxd.rdy && rxd.valid == 0) {
3644		len = rxd.len + 12;
3645		if (len < 12 || len > 2048)
3646			goto badrx;
3647
3648		skb = dev_alloc_skb(len);
3649		if (!skb) {
3650			ai->dev->stats.rx_dropped++;
3651			goto badrx;
3652		}
3653		buffer = skb_put(skb,len);
3654		memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3655		if (ai->micstats.enabled) {
3656			memcpy(&micbuf,
3657				ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3658				sizeof(micbuf));
3659			if (ntohs(micbuf.typelen) <= 0x05DC) {
3660				if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3661					goto badmic;
3662
3663				off = sizeof(micbuf);
3664				skb_trim (skb, len - off);
3665			}
3666		}
3667		memcpy(buffer + ETH_ALEN * 2,
3668			ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3669			len - ETH_ALEN * 2 - off);
3670		if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3671badmic:
3672			dev_kfree_skb_irq (skb);
3673			goto badrx;
3674		}
3675#ifdef WIRELESS_SPY
3676		if (ai->spy_data.spy_number > 0) {
3677			char *sa;
3678			struct iw_quality wstats;
3679			/* Prepare spy data : addr + qual */
3680			sa = buffer + ETH_ALEN;
3681			wstats.qual = 0; /* XXX Where do I get that info from ??? */
3682			wstats.level = 0;
3683			wstats.updated = 0;
3684			/* Update spy records */
3685			wireless_spy_update(ai->dev, sa, &wstats);
3686		}
3687#endif /* WIRELESS_SPY */
3688
3689		skb->ip_summed = CHECKSUM_NONE;
3690		skb->protocol = eth_type_trans(skb, ai->dev);
3691		netif_rx(skb);
3692	}
3693badrx:
3694	if (rxd.valid == 0) {
3695		rxd.valid = 1;
3696		rxd.rdy = 0;
3697		rxd.len = PKTSIZE;
3698		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3699	}
3700}
3701
3702static void mpi_receive_802_11(struct airo_info *ai)
3703{
3704	RxFid rxd;
3705	struct sk_buff *skb = NULL;
3706	u16 len, hdrlen = 0;
3707	__le16 fc;
3708	struct rx_hdr hdr;
3709	u16 gap;
3710	u16 *buffer;
3711	char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3712
3713	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3714	memcpy ((char *)&hdr, ptr, sizeof(hdr));
3715	ptr += sizeof(hdr);
3716	/* Bad CRC. Ignore packet */
3717	if (le16_to_cpu(hdr.status) & 2)
3718		hdr.len = 0;
3719	if (ai->wifidev == NULL)
3720		hdr.len = 0;
3721	len = le16_to_cpu(hdr.len);
3722	if (len > AIRO_DEF_MTU) {
3723		airo_print_err(ai->dev->name, "Bad size %d", len);
3724		goto badrx;
3725	}
3726	if (len == 0)
3727		goto badrx;
3728
3729	fc = get_unaligned((__le16 *)ptr);
3730	hdrlen = header_len(fc);
3731
3732	skb = dev_alloc_skb( len + hdrlen + 2 );
3733	if ( !skb ) {
3734		ai->dev->stats.rx_dropped++;
3735		goto badrx;
3736	}
3737	buffer = skb_put(skb, len + hdrlen);
3738	memcpy ((char *)buffer, ptr, hdrlen);
3739	ptr += hdrlen;
3740	if (hdrlen == 24)
3741		ptr += 6;
3742	gap = get_unaligned_le16(ptr);
3743	ptr += sizeof(__le16);
3744	if (gap) {
3745		if (gap <= 8)
3746			ptr += gap;
3747		else
3748			airo_print_err(ai->dev->name,
3749			    "gaplen too big. Problems will follow...");
3750	}
3751	memcpy ((char *)buffer + hdrlen, ptr, len);
3752	ptr += len;
3753#ifdef IW_WIRELESS_SPY	  /* defined in iw_handler.h */
3754	if (ai->spy_data.spy_number > 0) {
3755		char *sa;
3756		struct iw_quality wstats;
3757		/* Prepare spy data : addr + qual */
3758		sa = (char*)buffer + 10;
3759		wstats.qual = hdr.rssi[0];
3760		if (ai->rssi)
3761			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3762		else
3763			wstats.level = (hdr.rssi[1] + 321) / 2;
3764		wstats.noise = ai->wstats.qual.noise;
3765		wstats.updated = IW_QUAL_QUAL_UPDATED
3766			| IW_QUAL_LEVEL_UPDATED
3767			| IW_QUAL_DBM;
3768		/* Update spy records */
3769		wireless_spy_update(ai->dev, sa, &wstats);
3770	}
3771#endif /* IW_WIRELESS_SPY */
3772	skb_reset_mac_header(skb);
3773	skb->pkt_type = PACKET_OTHERHOST;
3774	skb->dev = ai->wifidev;
3775	skb->protocol = htons(ETH_P_802_2);
3776	skb->ip_summed = CHECKSUM_NONE;
3777	netif_rx( skb );
3778
3779badrx:
3780	if (rxd.valid == 0) {
3781		rxd.valid = 1;
3782		rxd.rdy = 0;
3783		rxd.len = PKTSIZE;
3784		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3785	}
3786}
3787
3788static inline void set_auth_type(struct airo_info *local, int auth_type)
3789{
3790	local->config.authType = auth_type;
3791	/* Cache the last auth type used (of AUTH_OPEN and AUTH_ENCRYPT).
3792	 * Used by airo_set_auth()
3793	 */
3794	if (auth_type == AUTH_OPEN || auth_type == AUTH_ENCRYPT)
3795		local->last_auth = auth_type;
3796}
3797
3798static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3799{
3800	Cmd cmd;
3801	Resp rsp;
3802	int status;
3803	SsidRid mySsid;
3804	__le16 lastindex;
3805	WepKeyRid wkr;
3806	int rc;
3807
3808	memset( &mySsid, 0, sizeof( mySsid ) );
3809	kfree (ai->flash);
3810	ai->flash = NULL;
3811
3812	/* The NOP is the first step in getting the card going */
3813	cmd.cmd = NOP;
3814	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3815	if (lock && down_interruptible(&ai->sem))
3816		return ERROR;
3817	if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
3818		if (lock)
3819			up(&ai->sem);
3820		return ERROR;
3821	}
3822	disable_MAC( ai, 0);
3823
3824	// Let's figure out if we need to use the AUX port
3825	if (!test_bit(FLAG_MPI,&ai->flags)) {
3826		cmd.cmd = CMD_ENABLEAUX;
3827		if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3828			if (lock)
3829				up(&ai->sem);
3830			airo_print_err(ai->dev->name, "Error checking for AUX port");
3831			return ERROR;
3832		}
3833		if (!aux_bap || rsp.status & 0xff00) {
3834			ai->bap_read = fast_bap_read;
3835			airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
3836		} else {
3837			ai->bap_read = aux_bap_read;
3838			airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
3839		}
3840	}
3841	if (lock)
3842		up(&ai->sem);
3843	if (ai->config.len == 0) {
3844		int i;
3845		tdsRssiRid rssi_rid;
3846		CapabilityRid cap_rid;
3847
3848		kfree(ai->SSID);
3849		ai->SSID = NULL;
3850		// general configuration (read/modify/write)
3851		status = readConfigRid(ai, lock);
3852		if ( status != SUCCESS ) return ERROR;
3853
3854		status = readCapabilityRid(ai, &cap_rid, lock);
3855		if ( status != SUCCESS ) return ERROR;
3856
3857		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3858		if ( status == SUCCESS ) {
3859			if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3860				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3861		}
3862		else {
3863			kfree(ai->rssi);
3864			ai->rssi = NULL;
3865			if (cap_rid.softCap & cpu_to_le16(8))
3866				ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3867			else
3868				airo_print_warn(ai->dev->name, "unknown received signal "
3869						"level scale");
3870		}
3871		ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3872		set_auth_type(ai, AUTH_OPEN);
3873		ai->config.modulation = MOD_CCK;
3874
3875		if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
3876		    (cap_rid.extSoftCap & cpu_to_le16(1)) &&
3877		    micsetup(ai) == SUCCESS) {
3878			ai->config.opmode |= MODE_MIC;
3879			set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3880		}
3881
3882		/* Save off the MAC */
3883		for( i = 0; i < ETH_ALEN; i++ ) {
3884			mac[i] = ai->config.macAddr[i];
3885		}
3886
3887		/* Check to see if there are any insmod configured
3888		   rates to add */
3889		if ( rates[0] ) {
3890			memset(ai->config.rates,0,sizeof(ai->config.rates));
3891			for( i = 0; i < 8 && rates[i]; i++ ) {
3892				ai->config.rates[i] = rates[i];
3893			}
3894		}
3895		set_bit (FLAG_COMMIT, &ai->flags);
3896	}
3897
3898	/* Setup the SSIDs if present */
3899	if ( ssids[0] ) {
3900		int i;
3901		for( i = 0; i < 3 && ssids[i]; i++ ) {
3902			size_t len = strlen(ssids[i]);
3903			if (len > 32)
3904				len = 32;
3905			mySsid.ssids[i].len = cpu_to_le16(len);
3906			memcpy(mySsid.ssids[i].ssid, ssids[i], len);
3907		}
3908		mySsid.len = cpu_to_le16(sizeof(mySsid));
3909	}
3910
3911	status = writeConfigRid(ai, lock);
3912	if ( status != SUCCESS ) return ERROR;
3913
3914	/* Set up the SSID list */
3915	if ( ssids[0] ) {
3916		status = writeSsidRid(ai, &mySsid, lock);
3917		if ( status != SUCCESS ) return ERROR;
3918	}
3919
3920	status = enable_MAC(ai, lock);
3921	if (status != SUCCESS)
3922		return ERROR;
3923
3924	/* Grab the initial wep key, we gotta save it for auto_wep */
3925	rc = readWepKeyRid(ai, &wkr, 1, lock);
3926	if (rc == SUCCESS) do {
3927		lastindex = wkr.kindex;
3928		if (wkr.kindex == cpu_to_le16(0xffff)) {
3929			ai->defindex = wkr.mac[0];
3930		}
3931		rc = readWepKeyRid(ai, &wkr, 0, lock);
3932	} while(lastindex != wkr.kindex);
3933
3934	try_auto_wep(ai);
3935
3936	return SUCCESS;
3937}
3938
3939static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
 
 
3940        // Im really paranoid about letting it run forever!
3941	int max_tries = 600000;
3942
3943	if (IN4500(ai, EVSTAT) & EV_CMD)
3944		OUT4500(ai, EVACK, EV_CMD);
3945
3946	OUT4500(ai, PARAM0, pCmd->parm0);
3947	OUT4500(ai, PARAM1, pCmd->parm1);
3948	OUT4500(ai, PARAM2, pCmd->parm2);
3949	OUT4500(ai, COMMAND, pCmd->cmd);
3950
3951	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3952		if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3953			// PC4500 didn't notice command, try again
3954			OUT4500(ai, COMMAND, pCmd->cmd);
3955		if (!in_atomic() && (max_tries & 255) == 0)
3956			schedule();
3957	}
3958
3959	if ( max_tries == -1 ) {
3960		airo_print_err(ai->dev->name,
3961			"Max tries exceeded when issuing command");
3962		if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3963			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3964		return ERROR;
3965	}
3966
3967	// command completed
3968	pRsp->status = IN4500(ai, STATUS);
3969	pRsp->rsp0 = IN4500(ai, RESP0);
3970	pRsp->rsp1 = IN4500(ai, RESP1);
3971	pRsp->rsp2 = IN4500(ai, RESP2);
3972	if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
3973		airo_print_err(ai->dev->name,
3974			"cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
3975			pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
3976			pRsp->rsp2);
3977
3978	// clear stuck command busy if necessary
3979	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
3980		OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3981	}
3982	// acknowledge processing the status/response
3983	OUT4500(ai, EVACK, EV_CMD);
3984
3985	return SUCCESS;
3986}
3987
3988/* Sets up the bap to start exchange data.  whichbap should
3989 * be one of the BAP0 or BAP1 defines.  Locks should be held before
3990 * calling! */
3991static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3992{
3993	int timeout = 50;
3994	int max_tries = 3;
3995
3996	OUT4500(ai, SELECT0+whichbap, rid);
3997	OUT4500(ai, OFFSET0+whichbap, offset);
3998	while (1) {
3999		int status = IN4500(ai, OFFSET0+whichbap);
4000		if (status & BAP_BUSY) {
4001                        /* This isn't really a timeout, but its kinda
4002			   close */
4003			if (timeout--) {
4004				continue;
4005			}
4006		} else if ( status & BAP_ERR ) {
4007			/* invalid rid or offset */
4008			airo_print_err(ai->dev->name, "BAP error %x %d",
4009				status, whichbap );
4010			return ERROR;
4011		} else if (status & BAP_DONE) { // success
4012			return SUCCESS;
4013		}
4014		if ( !(max_tries--) ) {
4015			airo_print_err(ai->dev->name,
4016				"BAP setup error too many retries\n");
4017			return ERROR;
4018		}
4019		// -- PC4500 missed it, try again
4020		OUT4500(ai, SELECT0+whichbap, rid);
4021		OUT4500(ai, OFFSET0+whichbap, offset);
4022		timeout = 50;
4023	}
4024}
4025
4026/* should only be called by aux_bap_read.  This aux function and the
4027   following use concepts not documented in the developers guide.  I
4028   got them from a patch given to my by Aironet */
4029static u16 aux_setup(struct airo_info *ai, u16 page,
4030		     u16 offset, u16 *len)
4031{
4032	u16 next;
4033
4034	OUT4500(ai, AUXPAGE, page);
4035	OUT4500(ai, AUXOFF, 0);
4036	next = IN4500(ai, AUXDATA);
4037	*len = IN4500(ai, AUXDATA)&0xff;
4038	if (offset != 4) OUT4500(ai, AUXOFF, offset);
4039	return next;
4040}
4041
4042/* requires call to bap_setup() first */
4043static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4044			int bytelen, int whichbap)
4045{
4046	u16 len;
4047	u16 page;
4048	u16 offset;
4049	u16 next;
4050	int words;
4051	int i;
4052	unsigned long flags;
4053
4054	spin_lock_irqsave(&ai->aux_lock, flags);
4055	page = IN4500(ai, SWS0+whichbap);
4056	offset = IN4500(ai, SWS2+whichbap);
4057	next = aux_setup(ai, page, offset, &len);
4058	words = (bytelen+1)>>1;
4059
4060	for (i=0; i<words;) {
4061		int count;
4062		count = (len>>1) < (words-i) ? (len>>1) : (words-i);
4063		if ( !do8bitIO )
4064			insw( ai->dev->base_addr+DATA0+whichbap,
4065			      pu16Dst+i,count );
4066		else
4067			insb( ai->dev->base_addr+DATA0+whichbap,
4068			      pu16Dst+i, count << 1 );
4069		i += count;
4070		if (i<words) {
4071			next = aux_setup(ai, next, 4, &len);
4072		}
4073	}
4074	spin_unlock_irqrestore(&ai->aux_lock, flags);
4075	return SUCCESS;
4076}
4077
4078
4079/* requires call to bap_setup() first */
4080static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4081			 int bytelen, int whichbap)
4082{
4083	bytelen = (bytelen + 1) & (~1); // round up to even value
4084	if ( !do8bitIO )
4085		insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
4086	else
4087		insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
4088	return SUCCESS;
4089}
4090
4091/* requires call to bap_setup() first */
4092static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
4093		     int bytelen, int whichbap)
4094{
4095	bytelen = (bytelen + 1) & (~1); // round up to even value
4096	if ( !do8bitIO )
4097		outsw( ai->dev->base_addr+DATA0+whichbap,
4098		       pu16Src, bytelen>>1 );
4099	else
4100		outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
4101	return SUCCESS;
4102}
4103
4104static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
4105{
4106	Cmd cmd; /* for issuing commands */
4107	Resp rsp; /* response from commands */
4108	u16 status;
4109
4110	memset(&cmd, 0, sizeof(cmd));
4111	cmd.cmd = accmd;
4112	cmd.parm0 = rid;
4113	status = issuecommand(ai, &cmd, &rsp);
4114	if (status != 0) return status;
4115	if ( (rsp.status & 0x7F00) != 0) {
4116		return (accmd << 8) + (rsp.rsp0 & 0xFF);
4117	}
4118	return 0;
4119}
4120
4121/*  Note, that we are using BAP1 which is also used by transmit, so
4122 *  we must get a lock. */
4123static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
4124{
4125	u16 status;
4126        int rc = SUCCESS;
4127
4128	if (lock) {
4129		if (down_interruptible(&ai->sem))
4130			return ERROR;
4131	}
4132	if (test_bit(FLAG_MPI,&ai->flags)) {
4133		Cmd cmd;
4134		Resp rsp;
4135
4136		memset(&cmd, 0, sizeof(cmd));
4137		memset(&rsp, 0, sizeof(rsp));
4138		ai->config_desc.rid_desc.valid = 1;
4139		ai->config_desc.rid_desc.len = RIDSIZE;
4140		ai->config_desc.rid_desc.rid = 0;
4141		ai->config_desc.rid_desc.host_addr = ai->ridbus;
4142
4143		cmd.cmd = CMD_ACCESS;
4144		cmd.parm0 = rid;
4145
4146		memcpy_toio(ai->config_desc.card_ram_off,
4147			&ai->config_desc.rid_desc, sizeof(Rid));
4148
4149		rc = issuecommand(ai, &cmd, &rsp);
4150
4151		if (rsp.status & 0x7f00)
4152			rc = rsp.rsp0;
4153		if (!rc)
4154			memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
4155		goto done;
4156	} else {
4157		if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4158	                rc = status;
4159	                goto done;
4160	        }
4161		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4162			rc = ERROR;
4163	                goto done;
4164	        }
4165		// read the rid length field
4166		bap_read(ai, pBuf, 2, BAP1);
4167		// length for remaining part of rid
4168		len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
4169
4170		if ( len <= 2 ) {
4171			airo_print_err(ai->dev->name,
4172				"Rid %x has a length of %d which is too short",
4173				(int)rid, (int)len );
4174			rc = ERROR;
4175	                goto done;
4176		}
4177		// read remainder of the rid
4178		rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
4179	}
4180done:
4181	if (lock)
4182		up(&ai->sem);
4183	return rc;
4184}
4185
4186/*  Note, that we are using BAP1 which is also used by transmit, so
4187 *  make sure this isn't called when a transmit is happening */
4188static int PC4500_writerid(struct airo_info *ai, u16 rid,
4189			   const void *pBuf, int len, int lock)
4190{
4191	u16 status;
4192	int rc = SUCCESS;
4193
4194	*(__le16*)pBuf = cpu_to_le16((u16)len);
4195
4196	if (lock) {
4197		if (down_interruptible(&ai->sem))
4198			return ERROR;
4199	}
4200	if (test_bit(FLAG_MPI,&ai->flags)) {
4201		Cmd cmd;
4202		Resp rsp;
4203
4204		if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
4205			airo_print_err(ai->dev->name,
4206				"%s: MAC should be disabled (rid=%04x)",
4207				__func__, rid);
4208		memset(&cmd, 0, sizeof(cmd));
4209		memset(&rsp, 0, sizeof(rsp));
4210
4211		ai->config_desc.rid_desc.valid = 1;
4212		ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4213		ai->config_desc.rid_desc.rid = 0;
4214
4215		cmd.cmd = CMD_WRITERID;
4216		cmd.parm0 = rid;
4217
4218		memcpy_toio(ai->config_desc.card_ram_off,
4219			&ai->config_desc.rid_desc, sizeof(Rid));
4220
4221		if (len < 4 || len > 2047) {
4222			airo_print_err(ai->dev->name, "%s: len=%d", __func__, len);
4223			rc = -1;
4224		} else {
4225			memcpy(ai->config_desc.virtual_host_addr,
4226				pBuf, len);
4227
4228			rc = issuecommand(ai, &cmd, &rsp);
4229			if ((rc & 0xff00) != 0) {
4230				airo_print_err(ai->dev->name, "%s: Write rid Error %d",
4231						__func__, rc);
4232				airo_print_err(ai->dev->name, "%s: Cmd=%04x",
4233						__func__, cmd.cmd);
4234			}
4235
4236			if ((rsp.status & 0x7f00))
4237				rc = rsp.rsp0;
4238		}
4239	} else {
4240		// --- first access so that we can write the rid data
4241		if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4242	                rc = status;
4243	                goto done;
4244	        }
4245		// --- now write the rid data
4246		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4247	                rc = ERROR;
4248	                goto done;
4249	        }
4250		bap_write(ai, pBuf, len, BAP1);
4251		// ---now commit the rid data
4252		rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4253	}
4254done:
4255	if (lock)
4256		up(&ai->sem);
4257        return rc;
4258}
4259
4260/* Allocates a FID to be used for transmitting packets.  We only use
4261   one for now. */
4262static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4263{
4264	unsigned int loop = 3000;
4265	Cmd cmd;
4266	Resp rsp;
4267	u16 txFid;
4268	__le16 txControl;
4269
4270	cmd.cmd = CMD_ALLOCATETX;
4271	cmd.parm0 = lenPayload;
4272	if (down_interruptible(&ai->sem))
4273		return ERROR;
4274	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
4275		txFid = ERROR;
4276		goto done;
4277	}
4278	if ( (rsp.status & 0xFF00) != 0) {
4279		txFid = ERROR;
4280		goto done;
4281	}
4282	/* wait for the allocate event/indication
4283	 * It makes me kind of nervous that this can just sit here and spin,
4284	 * but in practice it only loops like four times. */
4285	while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4286	if (!loop) {
4287		txFid = ERROR;
4288		goto done;
4289	}
4290
4291	// get the allocated fid and acknowledge
4292	txFid = IN4500(ai, TXALLOCFID);
4293	OUT4500(ai, EVACK, EV_ALLOC);
4294
4295	/*  The CARD is pretty cool since it converts the ethernet packet
4296	 *  into 802.11.  Also note that we don't release the FID since we
4297	 *  will be using the same one over and over again. */
4298	/*  We only have to setup the control once since we are not
4299	 *  releasing the fid. */
4300	if (raw)
4301		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4302			| TXCTL_ETHERNET | TXCTL_NORELEASE);
4303	else
4304		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4305			| TXCTL_ETHERNET | TXCTL_NORELEASE);
4306	if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4307		txFid = ERROR;
4308	else
4309		bap_write(ai, &txControl, sizeof(txControl), BAP1);
4310
4311done:
4312	up(&ai->sem);
4313
4314	return txFid;
4315}
4316
4317/* In general BAP1 is dedicated to transmiting packets.  However,
4318   since we need a BAP when accessing RIDs, we also use BAP1 for that.
4319   Make sure the BAP1 spinlock is held when this is called. */
4320static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
 
4321{
4322	__le16 payloadLen;
4323	Cmd cmd;
4324	Resp rsp;
4325	int miclen = 0;
4326	u16 txFid = len;
4327	MICBuffer pMic;
4328
4329	len >>= 16;
4330
4331	if (len <= ETH_ALEN * 2) {
4332		airo_print_warn(ai->dev->name, "Short packet %d", len);
4333		return ERROR;
4334	}
4335	len -= ETH_ALEN * 2;
4336
4337	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
4338	    (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
4339		if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
4340			return ERROR;
4341		miclen = sizeof(pMic);
4342	}
4343	// packet is destination[6], source[6], payload[len-12]
4344	// write the payload length and dst/src/payload
4345	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4346	/* The hardware addresses aren't counted as part of the payload, so
4347	 * we have to subtract the 12 bytes for the addresses off */
4348	payloadLen = cpu_to_le16(len + miclen);
4349	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4350	bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
4351	if (miclen)
4352		bap_write(ai, (__le16*)&pMic, miclen, BAP1);
4353	bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
4354	// issue the transmit command
4355	memset( &cmd, 0, sizeof( cmd ) );
4356	cmd.cmd = CMD_TRANSMIT;
4357	cmd.parm0 = txFid;
4358	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4359	if ( (rsp.status & 0xFF00) != 0) return ERROR;
 
4360	return SUCCESS;
4361}
4362
4363static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
 
4364{
4365	__le16 fc, payloadLen;
4366	Cmd cmd;
4367	Resp rsp;
4368	int hdrlen;
4369	static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
4370	/* padding of header to full size + le16 gaplen (6) + gaplen bytes */
4371	u16 txFid = len;
4372	len >>= 16;
4373
4374	fc = *(__le16*)pPacket;
4375	hdrlen = header_len(fc);
4376
4377	if (len < hdrlen) {
4378		airo_print_warn(ai->dev->name, "Short packet %d", len);
4379		return ERROR;
4380	}
4381
4382	/* packet is 802.11 header +  payload
4383	 * write the payload length and dst/src/payload */
4384	if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4385	/* The 802.11 header aren't counted as part of the payload, so
4386	 * we have to subtract the header bytes off */
4387	payloadLen = cpu_to_le16(len-hdrlen);
4388	bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4389	if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4390	bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
4391	bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
4392
4393	bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
4394	// issue the transmit command
4395	memset( &cmd, 0, sizeof( cmd ) );
4396	cmd.cmd = CMD_TRANSMIT;
4397	cmd.parm0 = txFid;
4398	if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4399	if ( (rsp.status & 0xFF00) != 0) return ERROR;
 
4400	return SUCCESS;
4401}
4402
4403/*
4404 *  This is the proc_fs routines.  It is a bit messier than I would
4405 *  like!  Feel free to clean it up!
4406 */
4407
4408static ssize_t proc_read( struct file *file,
4409			  char __user *buffer,
4410			  size_t len,
4411			  loff_t *offset);
4412
4413static ssize_t proc_write( struct file *file,
4414			   const char __user *buffer,
4415			   size_t len,
4416			   loff_t *offset );
4417static int proc_close( struct inode *inode, struct file *file );
4418
4419static int proc_stats_open( struct inode *inode, struct file *file );
4420static int proc_statsdelta_open( struct inode *inode, struct file *file );
4421static int proc_status_open( struct inode *inode, struct file *file );
4422static int proc_SSID_open( struct inode *inode, struct file *file );
4423static int proc_APList_open( struct inode *inode, struct file *file );
4424static int proc_BSSList_open( struct inode *inode, struct file *file );
4425static int proc_config_open( struct inode *inode, struct file *file );
4426static int proc_wepkey_open( struct inode *inode, struct file *file );
4427
4428static const struct file_operations proc_statsdelta_ops = {
4429	.owner		= THIS_MODULE,
4430	.read		= proc_read,
4431	.open		= proc_statsdelta_open,
4432	.release	= proc_close,
4433	.llseek		= default_llseek,
4434};
4435
4436static const struct file_operations proc_stats_ops = {
4437	.owner		= THIS_MODULE,
4438	.read		= proc_read,
4439	.open		= proc_stats_open,
4440	.release	= proc_close,
4441	.llseek		= default_llseek,
4442};
4443
4444static const struct file_operations proc_status_ops = {
4445	.owner		= THIS_MODULE,
4446	.read		= proc_read,
4447	.open		= proc_status_open,
4448	.release	= proc_close,
4449	.llseek		= default_llseek,
4450};
4451
4452static const struct file_operations proc_SSID_ops = {
4453	.owner		= THIS_MODULE,
4454	.read		= proc_read,
4455	.write		= proc_write,
4456	.open		= proc_SSID_open,
4457	.release	= proc_close,
4458	.llseek		= default_llseek,
4459};
4460
4461static const struct file_operations proc_BSSList_ops = {
4462	.owner		= THIS_MODULE,
4463	.read		= proc_read,
4464	.write		= proc_write,
4465	.open		= proc_BSSList_open,
4466	.release	= proc_close,
4467	.llseek		= default_llseek,
4468};
4469
4470static const struct file_operations proc_APList_ops = {
4471	.owner		= THIS_MODULE,
4472	.read		= proc_read,
4473	.write		= proc_write,
4474	.open		= proc_APList_open,
4475	.release	= proc_close,
4476	.llseek		= default_llseek,
4477};
4478
4479static const struct file_operations proc_config_ops = {
4480	.owner		= THIS_MODULE,
4481	.read		= proc_read,
4482	.write		= proc_write,
4483	.open		= proc_config_open,
4484	.release	= proc_close,
4485	.llseek		= default_llseek,
4486};
4487
4488static const struct file_operations proc_wepkey_ops = {
4489	.owner		= THIS_MODULE,
4490	.read		= proc_read,
4491	.write		= proc_write,
4492	.open		= proc_wepkey_open,
4493	.release	= proc_close,
4494	.llseek		= default_llseek,
4495};
4496
4497static struct proc_dir_entry *airo_entry;
4498
4499struct proc_data {
4500	int release_buffer;
4501	int readlen;
4502	char *rbuffer;
4503	int writelen;
4504	int maxwritelen;
4505	char *wbuffer;
4506	void (*on_close) (struct inode *, struct file *);
4507};
4508
4509static int setup_proc_entry( struct net_device *dev,
4510			     struct airo_info *apriv ) {
 
4511	struct proc_dir_entry *entry;
4512
4513	/* First setup the device directory */
4514	strcpy(apriv->proc_name,dev->name);
4515	apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
4516					    airo_entry);
4517	if (!apriv->proc_entry)
4518		return -ENOMEM;
4519	proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
4520
4521	/* Setup the StatsDelta */
4522	entry = proc_create_data("StatsDelta", 0444 & proc_perm,
4523				 apriv->proc_entry, &proc_statsdelta_ops, dev);
4524	if (!entry)
4525		goto fail;
4526	proc_set_user(entry, proc_kuid, proc_kgid);
4527
4528	/* Setup the Stats */
4529	entry = proc_create_data("Stats", 0444 & proc_perm,
4530				 apriv->proc_entry, &proc_stats_ops, dev);
4531	if (!entry)
4532		goto fail;
4533	proc_set_user(entry, proc_kuid, proc_kgid);
4534
4535	/* Setup the Status */
4536	entry = proc_create_data("Status", 0444 & proc_perm,
4537				 apriv->proc_entry, &proc_status_ops, dev);
4538	if (!entry)
4539		goto fail;
4540	proc_set_user(entry, proc_kuid, proc_kgid);
4541
4542	/* Setup the Config */
4543	entry = proc_create_data("Config", proc_perm,
4544				 apriv->proc_entry, &proc_config_ops, dev);
4545	if (!entry)
4546		goto fail;
4547	proc_set_user(entry, proc_kuid, proc_kgid);
4548
4549	/* Setup the SSID */
4550	entry = proc_create_data("SSID", proc_perm,
4551				 apriv->proc_entry, &proc_SSID_ops, dev);
4552	if (!entry)
4553		goto fail;
4554	proc_set_user(entry, proc_kuid, proc_kgid);
4555
4556	/* Setup the APList */
4557	entry = proc_create_data("APList", proc_perm,
4558				 apriv->proc_entry, &proc_APList_ops, dev);
4559	if (!entry)
4560		goto fail;
4561	proc_set_user(entry, proc_kuid, proc_kgid);
4562
4563	/* Setup the BSSList */
4564	entry = proc_create_data("BSSList", proc_perm,
4565				 apriv->proc_entry, &proc_BSSList_ops, dev);
4566	if (!entry)
4567		goto fail;
4568	proc_set_user(entry, proc_kuid, proc_kgid);
4569
4570	/* Setup the WepKey */
4571	entry = proc_create_data("WepKey", proc_perm,
4572				 apriv->proc_entry, &proc_wepkey_ops, dev);
4573	if (!entry)
4574		goto fail;
4575	proc_set_user(entry, proc_kuid, proc_kgid);
4576	return 0;
4577
4578fail:
4579	remove_proc_subtree(apriv->proc_name, airo_entry);
4580	return -ENOMEM;
4581}
4582
4583static int takedown_proc_entry( struct net_device *dev,
4584				struct airo_info *apriv )
4585{
4586	remove_proc_subtree(apriv->proc_name, airo_entry);
4587	return 0;
4588}
4589
4590/*
4591 *  What we want from the proc_fs is to be able to efficiently read
4592 *  and write the configuration.  To do this, we want to read the
4593 *  configuration when the file is opened and write it when the file is
4594 *  closed.  So basically we allocate a read buffer at open and fill it
4595 *  with data, and allocate a write buffer and read it at close.
4596 */
4597
4598/*
4599 *  The read routine is generic, it relies on the preallocated rbuffer
4600 *  to supply the data.
4601 */
4602static ssize_t proc_read( struct file *file,
4603			  char __user *buffer,
4604			  size_t len,
4605			  loff_t *offset )
4606{
4607	struct proc_data *priv = file->private_data;
4608
4609	if (!priv->rbuffer)
4610		return -EINVAL;
4611
4612	return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
4613					priv->readlen);
4614}
4615
4616/*
4617 *  The write routine is generic, it fills in a preallocated rbuffer
4618 *  to supply the data.
4619 */
4620static ssize_t proc_write( struct file *file,
4621			   const char __user *buffer,
4622			   size_t len,
4623			   loff_t *offset )
4624{
4625	ssize_t ret;
4626	struct proc_data *priv = file->private_data;
4627
4628	if (!priv->wbuffer)
4629		return -EINVAL;
4630
4631	ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
4632					buffer, len);
4633	if (ret > 0)
4634		priv->writelen = max_t(int, priv->writelen, *offset);
4635
4636	return ret;
4637}
4638
4639static int proc_status_open(struct inode *inode, struct file *file)
4640{
4641	struct proc_data *data;
4642	struct net_device *dev = PDE_DATA(inode);
4643	struct airo_info *apriv = dev->ml_priv;
4644	CapabilityRid cap_rid;
4645	StatusRid status_rid;
4646	u16 mode;
4647	int i;
4648
4649	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4650		return -ENOMEM;
4651	data = file->private_data;
4652	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4653		kfree (file->private_data);
4654		return -ENOMEM;
4655	}
4656
4657	readStatusRid(apriv, &status_rid, 1);
4658	readCapabilityRid(apriv, &cap_rid, 1);
4659
4660	mode = le16_to_cpu(status_rid.mode);
4661
4662        i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4663                    mode & 1 ? "CFG ": "",
4664                    mode & 2 ? "ACT ": "",
4665                    mode & 0x10 ? "SYN ": "",
4666                    mode & 0x20 ? "LNK ": "",
4667                    mode & 0x40 ? "LEAP ": "",
4668                    mode & 0x80 ? "PRIV ": "",
4669                    mode & 0x100 ? "KEY ": "",
4670                    mode & 0x200 ? "WEP ": "",
4671                    mode & 0x8000 ? "ERR ": "");
4672	sprintf( data->rbuffer+i, "Mode: %x\n"
4673		 "Signal Strength: %d\n"
4674		 "Signal Quality: %d\n"
4675		 "SSID: %-.*s\n"
4676		 "AP: %-.16s\n"
4677		 "Freq: %d\n"
4678		 "BitRate: %dmbs\n"
4679		 "Driver Version: %s\n"
4680		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4681		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4682		 "Software Version: %x\nSoftware Subversion: %x\n"
4683		 "Boot block version: %x\n",
4684		 le16_to_cpu(status_rid.mode),
4685		 le16_to_cpu(status_rid.normalizedSignalStrength),
4686		 le16_to_cpu(status_rid.signalQuality),
4687		 le16_to_cpu(status_rid.SSIDlen),
4688		 status_rid.SSID,
4689		 status_rid.apName,
4690		 le16_to_cpu(status_rid.channel),
4691		 le16_to_cpu(status_rid.currentXmitRate) / 2,
4692		 version,
4693		 cap_rid.prodName,
4694		 cap_rid.manName,
4695		 cap_rid.prodVer,
4696		 le16_to_cpu(cap_rid.radioType),
4697		 le16_to_cpu(cap_rid.country),
4698		 le16_to_cpu(cap_rid.hardVer),
4699		 le16_to_cpu(cap_rid.softVer),
4700		 le16_to_cpu(cap_rid.softSubVer),
4701		 le16_to_cpu(cap_rid.bootBlockVer));
4702	data->readlen = strlen( data->rbuffer );
4703	return 0;
4704}
4705
4706static int proc_stats_rid_open(struct inode*, struct file*, u16);
4707static int proc_statsdelta_open( struct inode *inode,
4708				 struct file *file ) {
 
4709	if (file->f_mode&FMODE_WRITE) {
4710		return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4711	}
4712	return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4713}
4714
4715static int proc_stats_open( struct inode *inode, struct file *file ) {
 
4716	return proc_stats_rid_open(inode, file, RID_STATS);
4717}
4718
4719static int proc_stats_rid_open( struct inode *inode,
4720				struct file *file,
4721				u16 rid )
4722{
4723	struct proc_data *data;
4724	struct net_device *dev = PDE_DATA(inode);
4725	struct airo_info *apriv = dev->ml_priv;
4726	StatsRid stats;
4727	int i, j;
4728	__le32 *vals = stats.vals;
4729	int len;
4730
4731	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4732		return -ENOMEM;
4733	data = file->private_data;
4734	if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4735		kfree (file->private_data);
4736		return -ENOMEM;
4737	}
4738
4739	readStatsRid(apriv, &stats, rid, 1);
4740	len = le16_to_cpu(stats.len);
4741
4742        j = 0;
4743	for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4744		if (!statsLabels[i]) continue;
4745		if (j+strlen(statsLabels[i])+16>4096) {
4746			airo_print_warn(apriv->dev->name,
4747			       "Potentially disastrous buffer overflow averted!");
4748			break;
4749		}
4750		j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4751				le32_to_cpu(vals[i]));
4752	}
4753	if (i*4 >= len) {
4754		airo_print_warn(apriv->dev->name, "Got a short rid");
4755	}
4756	data->readlen = j;
4757	return 0;
4758}
4759
4760static int get_dec_u16( char *buffer, int *start, int limit ) {
 
4761	u16 value;
4762	int valid = 0;
4763	for (value = 0; *start < limit && buffer[*start] >= '0' &&
4764			buffer[*start] <= '9'; (*start)++) {
4765		valid = 1;
4766		value *= 10;
4767		value += buffer[*start] - '0';
4768	}
4769	if ( !valid ) return -1;
4770	return value;
4771}
4772
4773static int airo_config_commit(struct net_device *dev,
4774			      struct iw_request_info *info, void *zwrq,
 
4775			      char *extra);
4776
4777static inline int sniffing_mode(struct airo_info *ai)
4778{
4779	return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
4780		le16_to_cpu(RXMODE_RFMON);
4781}
4782
4783static void proc_config_on_close(struct inode *inode, struct file *file)
4784{
4785	struct proc_data *data = file->private_data;
4786	struct net_device *dev = PDE_DATA(inode);
4787	struct airo_info *ai = dev->ml_priv;
4788	char *line;
4789
4790	if ( !data->writelen ) return;
4791
4792	readConfigRid(ai, 1);
4793	set_bit (FLAG_COMMIT, &ai->flags);
4794
4795	line = data->wbuffer;
4796	while( line[0] ) {
4797/*** Mode processing */
4798		if ( !strncmp( line, "Mode: ", 6 ) ) {
4799			line += 6;
4800			if (sniffing_mode(ai))
4801				set_bit (FLAG_RESET, &ai->flags);
4802			ai->config.rmode &= ~RXMODE_FULL_MASK;
4803			clear_bit (FLAG_802_11, &ai->flags);
4804			ai->config.opmode &= ~MODE_CFG_MASK;
4805			ai->config.scanMode = SCANMODE_ACTIVE;
4806			if ( line[0] == 'a' ) {
4807				ai->config.opmode |= MODE_STA_IBSS;
4808			} else {
4809				ai->config.opmode |= MODE_STA_ESS;
4810				if ( line[0] == 'r' ) {
4811					ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4812					ai->config.scanMode = SCANMODE_PASSIVE;
4813					set_bit (FLAG_802_11, &ai->flags);
4814				} else if ( line[0] == 'y' ) {
4815					ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4816					ai->config.scanMode = SCANMODE_PASSIVE;
4817					set_bit (FLAG_802_11, &ai->flags);
4818				} else if ( line[0] == 'l' )
4819					ai->config.rmode |= RXMODE_LANMON;
4820			}
4821			set_bit (FLAG_COMMIT, &ai->flags);
4822		}
4823
4824/*** Radio status */
4825		else if (!strncmp(line,"Radio: ", 7)) {
4826			line += 7;
4827			if (!strncmp(line,"off",3)) {
4828				set_bit (FLAG_RADIO_OFF, &ai->flags);
4829			} else {
4830				clear_bit (FLAG_RADIO_OFF, &ai->flags);
4831			}
4832		}
4833/*** NodeName processing */
4834		else if ( !strncmp( line, "NodeName: ", 10 ) ) {
4835			int j;
4836
4837			line += 10;
4838			memset( ai->config.nodeName, 0, 16 );
4839/* Do the name, assume a space between the mode and node name */
4840			for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
4841				ai->config.nodeName[j] = line[j];
4842			}
4843			set_bit (FLAG_COMMIT, &ai->flags);
4844		}
4845
4846/*** PowerMode processing */
4847		else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
4848			line += 11;
4849			if ( !strncmp( line, "PSPCAM", 6 ) ) {
4850				ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4851				set_bit (FLAG_COMMIT, &ai->flags);
4852			} else if ( !strncmp( line, "PSP", 3 ) ) {
4853				ai->config.powerSaveMode = POWERSAVE_PSP;
4854				set_bit (FLAG_COMMIT, &ai->flags);
4855			} else {
4856				ai->config.powerSaveMode = POWERSAVE_CAM;
4857				set_bit (FLAG_COMMIT, &ai->flags);
4858			}
4859		} else if ( !strncmp( line, "DataRates: ", 11 ) ) {
4860			int v, i = 0, k = 0; /* i is index into line,
4861						k is index to rates */
4862
4863			line += 11;
4864			while((v = get_dec_u16(line, &i, 3))!=-1) {
4865				ai->config.rates[k++] = (u8)v;
4866				line += i + 1;
4867				i = 0;
4868			}
4869			set_bit (FLAG_COMMIT, &ai->flags);
4870		} else if ( !strncmp( line, "Channel: ", 9 ) ) {
4871			int v, i = 0;
4872			line += 9;
4873			v = get_dec_u16(line, &i, i+3);
4874			if ( v != -1 ) {
4875				ai->config.channelSet = cpu_to_le16(v);
4876				set_bit (FLAG_COMMIT, &ai->flags);
4877			}
4878		} else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
4879			int v, i = 0;
4880			line += 11;
4881			v = get_dec_u16(line, &i, i+3);
4882			if ( v != -1 ) {
4883				ai->config.txPower = cpu_to_le16(v);
4884				set_bit (FLAG_COMMIT, &ai->flags);
4885			}
4886		} else if ( !strncmp( line, "WEP: ", 5 ) ) {
4887			line += 5;
4888			switch( line[0] ) {
4889			case 's':
4890				set_auth_type(ai, AUTH_SHAREDKEY);
4891				break;
4892			case 'e':
4893				set_auth_type(ai, AUTH_ENCRYPT);
4894				break;
4895			default:
4896				set_auth_type(ai, AUTH_OPEN);
4897				break;
4898			}
4899			set_bit (FLAG_COMMIT, &ai->flags);
4900		} else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
4901			int v, i = 0;
4902
4903			line += 16;
4904			v = get_dec_u16(line, &i, 3);
4905			v = (v<0) ? 0 : ((v>255) ? 255 : v);
4906			ai->config.longRetryLimit = cpu_to_le16(v);
4907			set_bit (FLAG_COMMIT, &ai->flags);
4908		} else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
4909			int v, i = 0;
4910
4911			line += 17;
4912			v = get_dec_u16(line, &i, 3);
4913			v = (v<0) ? 0 : ((v>255) ? 255 : v);
4914			ai->config.shortRetryLimit = cpu_to_le16(v);
4915			set_bit (FLAG_COMMIT, &ai->flags);
4916		} else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
4917			int v, i = 0;
4918
4919			line += 14;
4920			v = get_dec_u16(line, &i, 4);
4921			v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4922			ai->config.rtsThres = cpu_to_le16(v);
4923			set_bit (FLAG_COMMIT, &ai->flags);
4924		} else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
4925			int v, i = 0;
4926
4927			line += 16;
4928			v = get_dec_u16(line, &i, 5);
4929			v = (v<0) ? 0 : v;
4930			ai->config.txLifetime = cpu_to_le16(v);
4931			set_bit (FLAG_COMMIT, &ai->flags);
4932		} else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
4933			int v, i = 0;
4934
4935			line += 16;
4936			v = get_dec_u16(line, &i, 5);
4937			v = (v<0) ? 0 : v;
4938			ai->config.rxLifetime = cpu_to_le16(v);
4939			set_bit (FLAG_COMMIT, &ai->flags);
4940		} else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4941			ai->config.txDiversity =
4942				(line[13]=='l') ? 1 :
4943				((line[13]=='r')? 2: 3);
4944			set_bit (FLAG_COMMIT, &ai->flags);
4945		} else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4946			ai->config.rxDiversity =
4947				(line[13]=='l') ? 1 :
4948				((line[13]=='r')? 2: 3);
4949			set_bit (FLAG_COMMIT, &ai->flags);
4950		} else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4951			int v, i = 0;
4952
4953			line += 15;
4954			v = get_dec_u16(line, &i, 4);
4955			v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4956			v = v & 0xfffe; /* Make sure its even */
4957			ai->config.fragThresh = cpu_to_le16(v);
4958			set_bit (FLAG_COMMIT, &ai->flags);
4959		} else if (!strncmp(line, "Modulation: ", 12)) {
4960			line += 12;
4961			switch(*line) {
4962			case 'd':  ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4963			case 'c':  ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4964			case 'm':  ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4965			default: airo_print_warn(ai->dev->name, "Unknown modulation");
4966			}
4967		} else if (!strncmp(line, "Preamble: ", 10)) {
4968			line += 10;
4969			switch(*line) {
4970			case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4971			case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4972			case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4973			default: airo_print_warn(ai->dev->name, "Unknown preamble");
4974			}
4975		} else {
4976			airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
4977		}
4978		while( line[0] && line[0] != '\n' ) line++;
4979		if ( line[0] ) line++;
4980	}
4981	airo_config_commit(dev, NULL, NULL, NULL);
4982}
4983
4984static const char *get_rmode(__le16 mode)
4985{
4986        switch(mode & RXMODE_MASK) {
4987        case RXMODE_RFMON:  return "rfmon";
4988        case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
4989        case RXMODE_LANMON:  return "lanmon";
4990        }
4991        return "ESS";
4992}
4993
4994static int proc_config_open(struct inode *inode, struct file *file)
4995{
4996	struct proc_data *data;
4997	struct net_device *dev = PDE_DATA(inode);
4998	struct airo_info *ai = dev->ml_priv;
4999	int i;
5000	__le16 mode;
5001
5002	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5003		return -ENOMEM;
5004	data = file->private_data;
5005	if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
5006		kfree (file->private_data);
5007		return -ENOMEM;
5008	}
5009	if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
5010		kfree (data->rbuffer);
5011		kfree (file->private_data);
5012		return -ENOMEM;
5013	}
5014	data->maxwritelen = 2048;
5015	data->on_close = proc_config_on_close;
5016
5017	readConfigRid(ai, 1);
5018
5019	mode = ai->config.opmode & MODE_CFG_MASK;
5020	i = sprintf( data->rbuffer,
5021		     "Mode: %s\n"
5022		     "Radio: %s\n"
5023		     "NodeName: %-16s\n"
5024		     "PowerMode: %s\n"
5025		     "DataRates: %d %d %d %d %d %d %d %d\n"
5026		     "Channel: %d\n"
5027		     "XmitPower: %d\n",
5028		     mode == MODE_STA_IBSS ? "adhoc" :
5029		     mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
5030		     mode == MODE_AP ? "AP" :
5031		     mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
5032		     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
5033		     ai->config.nodeName,
5034		     ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
5035		     ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
5036		     ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
5037		     "Error",
5038		     (int)ai->config.rates[0],
5039		     (int)ai->config.rates[1],
5040		     (int)ai->config.rates[2],
5041		     (int)ai->config.rates[3],
5042		     (int)ai->config.rates[4],
5043		     (int)ai->config.rates[5],
5044		     (int)ai->config.rates[6],
5045		     (int)ai->config.rates[7],
5046		     le16_to_cpu(ai->config.channelSet),
5047		     le16_to_cpu(ai->config.txPower)
5048		);
5049	sprintf( data->rbuffer + i,
5050		 "LongRetryLimit: %d\n"
5051		 "ShortRetryLimit: %d\n"
5052		 "RTSThreshold: %d\n"
5053		 "TXMSDULifetime: %d\n"
5054		 "RXMSDULifetime: %d\n"
5055		 "TXDiversity: %s\n"
5056		 "RXDiversity: %s\n"
5057		 "FragThreshold: %d\n"
5058		 "WEP: %s\n"
5059		 "Modulation: %s\n"
5060		 "Preamble: %s\n",
5061		 le16_to_cpu(ai->config.longRetryLimit),
5062		 le16_to_cpu(ai->config.shortRetryLimit),
5063		 le16_to_cpu(ai->config.rtsThres),
5064		 le16_to_cpu(ai->config.txLifetime),
5065		 le16_to_cpu(ai->config.rxLifetime),
5066		 ai->config.txDiversity == 1 ? "left" :
5067		 ai->config.txDiversity == 2 ? "right" : "both",
5068		 ai->config.rxDiversity == 1 ? "left" :
5069		 ai->config.rxDiversity == 2 ? "right" : "both",
5070		 le16_to_cpu(ai->config.fragThresh),
5071		 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
5072		 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
5073		 ai->config.modulation == MOD_DEFAULT ? "default" :
5074		 ai->config.modulation == MOD_CCK ? "cck" :
5075		 ai->config.modulation == MOD_MOK ? "mok" : "error",
5076		 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
5077		 ai->config.preamble == PREAMBLE_LONG ? "long" :
5078		 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
5079		);
5080	data->readlen = strlen( data->rbuffer );
5081	return 0;
5082}
5083
5084static void proc_SSID_on_close(struct inode *inode, struct file *file)
5085{
5086	struct proc_data *data = file->private_data;
5087	struct net_device *dev = PDE_DATA(inode);
5088	struct airo_info *ai = dev->ml_priv;
5089	SsidRid SSID_rid;
5090	int i;
5091	char *p = data->wbuffer;
5092	char *end = p + data->writelen;
5093
5094	if (!data->writelen)
5095		return;
5096
5097	*end = '\n'; /* sentinel; we have space for it */
5098
5099	memset(&SSID_rid, 0, sizeof(SSID_rid));
5100
5101	for (i = 0; i < 3 && p < end; i++) {
5102		int j = 0;
5103		/* copy up to 32 characters from this line */
5104		while (*p != '\n' && j < 32)
5105			SSID_rid.ssids[i].ssid[j++] = *p++;
5106		if (j == 0)
5107			break;
5108		SSID_rid.ssids[i].len = cpu_to_le16(j);
5109		/* skip to the beginning of the next line */
5110		while (*p++ != '\n')
5111			;
5112	}
5113	if (i)
5114		SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5115	disable_MAC(ai, 1);
5116	writeSsidRid(ai, &SSID_rid, 1);
5117	enable_MAC(ai, 1);
5118}
5119
5120static void proc_APList_on_close( struct inode *inode, struct file *file ) {
 
5121	struct proc_data *data = file->private_data;
5122	struct net_device *dev = PDE_DATA(inode);
5123	struct airo_info *ai = dev->ml_priv;
5124	APListRid *APList_rid = &ai->APList;
5125	int i;
5126
5127	if ( !data->writelen ) return;
5128
5129	memset(APList_rid, 0, sizeof(*APList_rid));
5130	APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5131
5132	for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
5133		mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
5134
5135	disable_MAC(ai, 1);
5136	writeAPListRid(ai, APList_rid, 1);
5137	enable_MAC(ai, 1);
5138}
5139
5140/* This function wraps PC4500_writerid with a MAC disable */
5141static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5142			int len, int dummy ) {
 
5143	int rc;
5144
5145	disable_MAC(ai, 1);
5146	rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5147	enable_MAC(ai, 1);
5148	return rc;
5149}
5150
5151/* Returns the WEP key at the specified index, or -1 if that key does
5152 * not exist.  The buffer is assumed to be at least 16 bytes in length.
5153 */
5154static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
5155{
5156	WepKeyRid wkr;
5157	int rc;
5158	__le16 lastindex;
5159
5160	rc = readWepKeyRid(ai, &wkr, 1, 1);
5161	if (rc != SUCCESS)
5162		return -1;
5163	do {
5164		lastindex = wkr.kindex;
5165		if (le16_to_cpu(wkr.kindex) == index) {
5166			int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
5167			memcpy(buf, wkr.key, klen);
5168			return klen;
5169		}
5170		rc = readWepKeyRid(ai, &wkr, 0, 1);
5171		if (rc != SUCCESS)
5172			return -1;
5173	} while (lastindex != wkr.kindex);
5174	return -1;
5175}
5176
5177static int get_wep_tx_idx(struct airo_info *ai)
5178{
5179	WepKeyRid wkr;
5180	int rc;
5181	__le16 lastindex;
5182
5183	rc = readWepKeyRid(ai, &wkr, 1, 1);
5184	if (rc != SUCCESS)
5185		return -1;
5186	do {
5187		lastindex = wkr.kindex;
5188		if (wkr.kindex == cpu_to_le16(0xffff))
5189			return wkr.mac[0];
5190		rc = readWepKeyRid(ai, &wkr, 0, 1);
5191		if (rc != SUCCESS)
5192			return -1;
5193	} while (lastindex != wkr.kindex);
5194	return -1;
5195}
5196
5197static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5198		       u16 keylen, int perm, int lock)
5199{
5200	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5201	WepKeyRid wkr;
5202	int rc;
5203
5204	if (WARN_ON(keylen == 0))
5205		return -1;
5206
5207	memset(&wkr, 0, sizeof(wkr));
5208	wkr.len = cpu_to_le16(sizeof(wkr));
5209	wkr.kindex = cpu_to_le16(index);
5210	wkr.klen = cpu_to_le16(keylen);
5211	memcpy(wkr.key, key, keylen);
5212	memcpy(wkr.mac, macaddr, ETH_ALEN);
5213
5214	if (perm) disable_MAC(ai, lock);
5215	rc = writeWepKeyRid(ai, &wkr, perm, lock);
5216	if (perm) enable_MAC(ai, lock);
5217	return rc;
5218}
5219
5220static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
5221{
5222	WepKeyRid wkr;
5223	int rc;
5224
5225	memset(&wkr, 0, sizeof(wkr));
5226	wkr.len = cpu_to_le16(sizeof(wkr));
5227	wkr.kindex = cpu_to_le16(0xffff);
5228	wkr.mac[0] = (char)index;
5229
5230	if (perm) {
5231		ai->defindex = (char)index;
5232		disable_MAC(ai, lock);
5233	}
5234
5235	rc = writeWepKeyRid(ai, &wkr, perm, lock);
5236
5237	if (perm)
5238		enable_MAC(ai, lock);
5239	return rc;
5240}
5241
5242static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
 
5243	struct proc_data *data;
5244	struct net_device *dev = PDE_DATA(inode);
5245	struct airo_info *ai = dev->ml_priv;
5246	int i, rc;
5247	char key[16];
5248	u16 index = 0;
5249	int j = 0;
5250
5251	memset(key, 0, sizeof(key));
5252
5253	data = file->private_data;
5254	if ( !data->writelen ) return;
5255
5256	if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5257	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5258		index = data->wbuffer[0] - '0';
5259		if (data->wbuffer[1] == '\n') {
5260			rc = set_wep_tx_idx(ai, index, 1, 1);
5261			if (rc < 0) {
5262				airo_print_err(ai->dev->name, "failed to set "
5263				               "WEP transmit index to %d: %d.",
5264				               index, rc);
5265			}
5266			return;
5267		}
5268		j = 2;
5269	} else {
5270		airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5271		return;
5272	}
5273
5274	for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
 
 
 
 
 
 
 
 
 
 
5275		switch(i%3) {
5276		case 0:
5277			key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
5278			break;
5279		case 1:
5280			key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
5281			break;
5282		}
5283	}
5284
5285	rc = set_wep_key(ai, index, key, i/3, 1, 1);
5286	if (rc < 0) {
5287		airo_print_err(ai->dev->name, "failed to set WEP key at index "
5288		               "%d: %d.", index, rc);
5289	}
5290}
5291
5292static int proc_wepkey_open( struct inode *inode, struct file *file )
5293{
5294	struct proc_data *data;
5295	struct net_device *dev = PDE_DATA(inode);
5296	struct airo_info *ai = dev->ml_priv;
5297	char *ptr;
5298	WepKeyRid wkr;
5299	__le16 lastindex;
5300	int j=0;
5301	int rc;
5302
5303	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5304		return -ENOMEM;
5305	memset(&wkr, 0, sizeof(wkr));
5306	data = file->private_data;
5307	if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5308		kfree (file->private_data);
5309		return -ENOMEM;
5310	}
5311	data->writelen = 0;
5312	data->maxwritelen = 80;
5313	if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5314		kfree (data->rbuffer);
5315		kfree (file->private_data);
5316		return -ENOMEM;
5317	}
5318	data->on_close = proc_wepkey_on_close;
5319
5320	ptr = data->rbuffer;
5321	strcpy(ptr, "No wep keys\n");
5322	rc = readWepKeyRid(ai, &wkr, 1, 1);
5323	if (rc == SUCCESS) do {
5324		lastindex = wkr.kindex;
5325		if (wkr.kindex == cpu_to_le16(0xffff)) {
5326			j += sprintf(ptr+j, "Tx key = %d\n",
5327				     (int)wkr.mac[0]);
5328		} else {
5329			j += sprintf(ptr+j, "Key %d set with length = %d\n",
5330				     le16_to_cpu(wkr.kindex),
5331				     le16_to_cpu(wkr.klen));
5332		}
5333		readWepKeyRid(ai, &wkr, 0, 1);
5334	} while((lastindex != wkr.kindex) && (j < 180-30));
5335
5336	data->readlen = strlen( data->rbuffer );
5337	return 0;
5338}
5339
5340static int proc_SSID_open(struct inode *inode, struct file *file)
5341{
5342	struct proc_data *data;
5343	struct net_device *dev = PDE_DATA(inode);
5344	struct airo_info *ai = dev->ml_priv;
5345	int i;
5346	char *ptr;
5347	SsidRid SSID_rid;
5348
5349	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5350		return -ENOMEM;
5351	data = file->private_data;
5352	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5353		kfree (file->private_data);
5354		return -ENOMEM;
5355	}
5356	data->writelen = 0;
5357	data->maxwritelen = 33*3;
5358	/* allocate maxwritelen + 1; we'll want a sentinel */
5359	if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5360		kfree (data->rbuffer);
5361		kfree (file->private_data);
5362		return -ENOMEM;
5363	}
5364	data->on_close = proc_SSID_on_close;
5365
5366	readSsidRid(ai, &SSID_rid);
5367	ptr = data->rbuffer;
5368	for (i = 0; i < 3; i++) {
5369		int j;
5370		size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5371		if (!len)
5372			break;
5373		if (len > 32)
5374			len = 32;
5375		for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5376			*ptr++ = SSID_rid.ssids[i].ssid[j];
5377		*ptr++ = '\n';
5378	}
5379	*ptr = '\0';
5380	data->readlen = strlen( data->rbuffer );
5381	return 0;
5382}
5383
5384static int proc_APList_open( struct inode *inode, struct file *file ) {
 
5385	struct proc_data *data;
5386	struct net_device *dev = PDE_DATA(inode);
5387	struct airo_info *ai = dev->ml_priv;
5388	int i;
5389	char *ptr;
5390	APListRid *APList_rid = &ai->APList;
5391
5392	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5393		return -ENOMEM;
5394	data = file->private_data;
5395	if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5396		kfree (file->private_data);
5397		return -ENOMEM;
5398	}
5399	data->writelen = 0;
5400	data->maxwritelen = 4*6*3;
5401	if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5402		kfree (data->rbuffer);
5403		kfree (file->private_data);
5404		return -ENOMEM;
5405	}
5406	data->on_close = proc_APList_on_close;
5407
5408	ptr = data->rbuffer;
5409	for( i = 0; i < 4; i++ ) {
5410// We end when we find a zero MAC
5411		if ( !*(int*)APList_rid->ap[i] &&
5412		     !*(int*)&APList_rid->ap[i][2]) break;
5413		ptr += sprintf(ptr, "%pM\n", APList_rid->ap[i]);
5414	}
5415	if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5416
5417	*ptr = '\0';
5418	data->readlen = strlen( data->rbuffer );
5419	return 0;
5420}
5421
5422static int proc_BSSList_open( struct inode *inode, struct file *file ) {
 
5423	struct proc_data *data;
5424	struct net_device *dev = PDE_DATA(inode);
5425	struct airo_info *ai = dev->ml_priv;
5426	char *ptr;
5427	BSSListRid BSSList_rid;
5428	int rc;
5429	/* If doLoseSync is not 1, we won't do a Lose Sync */
5430	int doLoseSync = -1;
5431
5432	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5433		return -ENOMEM;
5434	data = file->private_data;
5435	if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5436		kfree (file->private_data);
5437		return -ENOMEM;
5438	}
5439	data->writelen = 0;
5440	data->maxwritelen = 0;
5441	data->wbuffer = NULL;
5442	data->on_close = NULL;
5443
5444	if (file->f_mode & FMODE_WRITE) {
5445		if (!(file->f_mode & FMODE_READ)) {
5446			Cmd cmd;
5447			Resp rsp;
5448
5449			if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
 
 
 
 
5450			memset(&cmd, 0, sizeof(cmd));
5451			cmd.cmd=CMD_LISTBSS;
5452			if (down_interruptible(&ai->sem))
 
 
5453				return -ERESTARTSYS;
5454			issuecommand(ai, &cmd, &rsp);
 
5455			up(&ai->sem);
5456			data->readlen = 0;
5457			return 0;
5458		}
5459		doLoseSync = 1;
5460	}
5461	ptr = data->rbuffer;
5462	/* There is a race condition here if there are concurrent opens.
5463           Since it is a rare condition, we'll just live with it, otherwise
5464           we have to add a spin lock... */
5465	rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5466	while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
5467		ptr += sprintf(ptr, "%pM %*s rssi = %d",
5468			       BSSList_rid.bssid,
5469				(int)BSSList_rid.ssidLen,
5470				BSSList_rid.ssid,
5471				le16_to_cpu(BSSList_rid.dBm));
5472		ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5473				le16_to_cpu(BSSList_rid.dsChannel),
5474				BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5475				BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5476				BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5477				BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5478		rc = readBSSListRid(ai, 0, &BSSList_rid);
5479	}
5480	*ptr = '\0';
5481	data->readlen = strlen( data->rbuffer );
5482	return 0;
5483}
5484
5485static int proc_close( struct inode *inode, struct file *file )
5486{
5487	struct proc_data *data = file->private_data;
5488
5489	if (data->on_close != NULL)
5490		data->on_close(inode, file);
5491	kfree(data->rbuffer);
5492	kfree(data->wbuffer);
5493	kfree(data);
5494	return 0;
5495}
5496
5497/* Since the card doesn't automatically switch to the right WEP mode,
5498   we will make it do it.  If the card isn't associated, every secs we
5499   will switch WEP modes to see if that will help.  If the card is
5500   associated we will check every minute to see if anything has
5501   changed. */
5502static void timer_func( struct net_device *dev ) {
 
5503	struct airo_info *apriv = dev->ml_priv;
5504
5505/* We don't have a link so try changing the authtype */
5506	readConfigRid(apriv, 0);
5507	disable_MAC(apriv, 0);
5508	switch(apriv->config.authType) {
5509		case AUTH_ENCRYPT:
5510/* So drop to OPEN */
5511			apriv->config.authType = AUTH_OPEN;
5512			break;
5513		case AUTH_SHAREDKEY:
5514			if (apriv->keyindex < auto_wep) {
5515				set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5516				apriv->config.authType = AUTH_SHAREDKEY;
5517				apriv->keyindex++;
5518			} else {
5519			        /* Drop to ENCRYPT */
5520				apriv->keyindex = 0;
5521				set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5522				apriv->config.authType = AUTH_ENCRYPT;
5523			}
5524			break;
5525		default:  /* We'll escalate to SHAREDKEY */
5526			apriv->config.authType = AUTH_SHAREDKEY;
5527	}
5528	set_bit (FLAG_COMMIT, &apriv->flags);
5529	writeConfigRid(apriv, 0);
5530	enable_MAC(apriv, 0);
5531	up(&apriv->sem);
5532
5533/* Schedule check to see if the change worked */
5534	clear_bit(JOB_AUTOWEP, &apriv->jobs);
5535	apriv->expires = RUN_AT(HZ*3);
5536}
5537
5538#ifdef CONFIG_PCI
5539static int airo_pci_probe(struct pci_dev *pdev,
5540				    const struct pci_device_id *pent)
5541{
5542	struct net_device *dev;
5543
5544	if (pci_enable_device(pdev))
5545		return -ENODEV;
5546	pci_set_master(pdev);
5547
5548	if (pdev->device == 0x5000 || pdev->device == 0xa504)
5549			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5550	else
5551			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5552	if (!dev) {
5553		pci_disable_device(pdev);
5554		return -ENODEV;
5555	}
5556
5557	pci_set_drvdata(pdev, dev);
5558	return 0;
5559}
5560
5561static void airo_pci_remove(struct pci_dev *pdev)
5562{
5563	struct net_device *dev = pci_get_drvdata(pdev);
5564
5565	airo_print_info(dev->name, "Unregistering...");
5566	stop_airo_card(dev, 1);
5567	pci_disable_device(pdev);
5568}
5569
5570static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
5571{
5572	struct net_device *dev = pci_get_drvdata(pdev);
5573	struct airo_info *ai = dev->ml_priv;
5574	Cmd cmd;
5575	Resp rsp;
5576
5577	if (!ai->SSID)
5578		ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
5579	if (!ai->SSID)
5580		return -ENOMEM;
5581	readSsidRid(ai, ai->SSID);
5582	memset(&cmd, 0, sizeof(cmd));
5583	/* the lock will be released at the end of the resume callback */
5584	if (down_interruptible(&ai->sem))
5585		return -EAGAIN;
5586	disable_MAC(ai, 0);
5587	netif_device_detach(dev);
5588	ai->power = state;
5589	cmd.cmd = HOSTSLEEP;
5590	issuecommand(ai, &cmd, &rsp);
5591
5592	pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
5593	pci_save_state(pdev);
5594	pci_set_power_state(pdev, pci_choose_state(pdev, state));
5595	return 0;
5596}
5597
5598static int airo_pci_resume(struct pci_dev *pdev)
5599{
5600	struct net_device *dev = pci_get_drvdata(pdev);
5601	struct airo_info *ai = dev->ml_priv;
5602	pci_power_t prev_state = pdev->current_state;
5603
5604	pci_set_power_state(pdev, PCI_D0);
5605	pci_restore_state(pdev);
5606	pci_enable_wake(pdev, PCI_D0, 0);
5607
5608	if (prev_state != PCI_D1) {
5609		reset_card(dev, 0);
5610		mpi_init_descriptors(ai);
5611		setup_card(ai, dev->dev_addr, 0);
5612		clear_bit(FLAG_RADIO_OFF, &ai->flags);
5613		clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5614	} else {
5615		OUT4500(ai, EVACK, EV_AWAKEN);
5616		OUT4500(ai, EVACK, EV_AWAKEN);
5617		msleep(100);
5618	}
5619
5620	set_bit(FLAG_COMMIT, &ai->flags);
5621	disable_MAC(ai, 0);
5622        msleep(200);
5623	if (ai->SSID) {
5624		writeSsidRid(ai, ai->SSID, 0);
5625		kfree(ai->SSID);
5626		ai->SSID = NULL;
5627	}
5628	writeAPListRid(ai, &ai->APList, 0);
5629	writeConfigRid(ai, 0);
5630	enable_MAC(ai, 0);
5631	ai->power = PMSG_ON;
5632	netif_device_attach(dev);
5633	netif_wake_queue(dev);
5634	enable_interrupts(ai);
5635	up(&ai->sem);
5636	return 0;
5637}
5638#endif
5639
5640static int __init airo_init_module( void )
5641{
5642	int i;
5643
5644	proc_kuid = make_kuid(&init_user_ns, proc_uid);
5645	proc_kgid = make_kgid(&init_user_ns, proc_gid);
5646	if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
5647		return -EINVAL;
5648
5649	airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
5650
5651	if (airo_entry)
5652		proc_set_user(airo_entry, proc_kuid, proc_kgid);
5653
5654	for (i = 0; i < 4 && io[i] && irq[i]; i++) {
5655		airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5656			"io=0x%x", irq[i], io[i] );
5657		if (init_airo_card( irq[i], io[i], 0, NULL ))
5658			/* do nothing */ ;
 
5659	}
5660
5661#ifdef CONFIG_PCI
5662	airo_print_info("", "Probing for PCI adapters");
5663	i = pci_register_driver(&airo_driver);
5664	airo_print_info("", "Finished probing for PCI adapters");
5665
5666	if (i) {
5667		remove_proc_entry("driver/aironet", NULL);
5668		return i;
5669	}
5670#endif
5671
5672	/* Always exit with success, as we are a library module
5673	 * as well as a driver module
5674	 */
5675	return 0;
5676}
5677
5678static void __exit airo_cleanup_module( void )
5679{
5680	struct airo_info *ai;
5681	while(!list_empty(&airo_devices)) {
5682		ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5683		airo_print_info(ai->dev->name, "Unregistering...");
5684		stop_airo_card(ai->dev, 1);
5685	}
5686#ifdef CONFIG_PCI
5687	pci_unregister_driver(&airo_driver);
5688#endif
5689	remove_proc_entry("driver/aironet", NULL);
5690}
5691
5692/*
5693 * Initial Wireless Extension code for Aironet driver by :
5694 *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5695 * Conversion to new driver API by :
5696 *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5697 * Javier also did a good amount of work here, adding some new extensions
5698 * and fixing my code. Let's just say that without him this code just
5699 * would not work at all... - Jean II
5700 */
5701
5702static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5703{
5704	if (!rssi_rid)
5705		return 0;
5706
5707	return (0x100 - rssi_rid[rssi].rssidBm);
5708}
5709
5710static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5711{
5712	int i;
5713
5714	if (!rssi_rid)
5715		return 0;
5716
5717	for (i = 0; i < 256; i++)
5718		if (rssi_rid[i].rssidBm == dbm)
5719			return rssi_rid[i].rssipct;
5720
5721	return 0;
5722}
5723
5724
5725static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5726{
5727	int quality = 0;
5728	u16 sq;
5729
5730	if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5731		return 0;
5732
5733	if (!(cap_rid->hardCap & cpu_to_le16(8)))
5734		return 0;
5735
5736	sq = le16_to_cpu(status_rid->signalQuality);
5737	if (memcmp(cap_rid->prodName, "350", 3))
5738		if (sq > 0x20)
5739			quality = 0;
5740		else
5741			quality = 0x20 - sq;
5742	else
5743		if (sq > 0xb0)
5744			quality = 0;
5745		else if (sq < 0x10)
5746			quality = 0xa0;
5747		else
5748			quality = 0xb0 - sq;
5749	return quality;
5750}
5751
5752#define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5753#define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
5754
5755/*------------------------------------------------------------------*/
5756/*
5757 * Wireless Handler : get protocol name
5758 */
5759static int airo_get_name(struct net_device *dev,
5760			 struct iw_request_info *info,
5761			 char *cwrq,
5762			 char *extra)
5763{
5764	strcpy(cwrq, "IEEE 802.11-DS");
5765	return 0;
5766}
5767
5768/*------------------------------------------------------------------*/
5769/*
5770 * Wireless Handler : set frequency
5771 */
5772static int airo_set_freq(struct net_device *dev,
5773			 struct iw_request_info *info,
5774			 struct iw_freq *fwrq,
5775			 char *extra)
5776{
 
5777	struct airo_info *local = dev->ml_priv;
5778	int rc = -EINPROGRESS;		/* Call commit handler */
5779
5780	/* If setting by frequency, convert to a channel */
5781	if(fwrq->e == 1) {
5782		int f = fwrq->m / 100000;
5783
5784		/* Hack to fall through... */
5785		fwrq->e = 0;
5786		fwrq->m = ieee80211_frequency_to_channel(f);
5787	}
5788	/* Setting by channel number */
5789	if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
5790		rc = -EOPNOTSUPP;
5791	else {
5792		int channel = fwrq->m;
5793		/* We should do a better check than that,
5794		 * based on the card capability !!! */
5795		if((channel < 1) || (channel > 14)) {
5796			airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5797				fwrq->m);
5798			rc = -EINVAL;
5799		} else {
5800			readConfigRid(local, 1);
5801			/* Yes ! We can set it !!! */
5802			local->config.channelSet = cpu_to_le16(channel);
5803			set_bit (FLAG_COMMIT, &local->flags);
5804		}
5805	}
5806	return rc;
5807}
5808
5809/*------------------------------------------------------------------*/
5810/*
5811 * Wireless Handler : get frequency
5812 */
5813static int airo_get_freq(struct net_device *dev,
5814			 struct iw_request_info *info,
5815			 struct iw_freq *fwrq,
5816			 char *extra)
5817{
 
5818	struct airo_info *local = dev->ml_priv;
5819	StatusRid status_rid;		/* Card status info */
5820	int ch;
5821
5822	readConfigRid(local, 1);
5823	if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
5824		status_rid.channel = local->config.channelSet;
5825	else
5826		readStatusRid(local, &status_rid, 1);
5827
5828	ch = le16_to_cpu(status_rid.channel);
5829	if((ch > 0) && (ch < 15)) {
5830		fwrq->m = 100000 *
5831			ieee80211_channel_to_frequency(ch, NL80211_BAND_2GHZ);
5832		fwrq->e = 1;
5833	} else {
5834		fwrq->m = ch;
5835		fwrq->e = 0;
5836	}
5837
5838	return 0;
5839}
5840
5841/*------------------------------------------------------------------*/
5842/*
5843 * Wireless Handler : set ESSID
5844 */
5845static int airo_set_essid(struct net_device *dev,
5846			  struct iw_request_info *info,
5847			  struct iw_point *dwrq,
5848			  char *extra)
5849{
 
5850	struct airo_info *local = dev->ml_priv;
5851	SsidRid SSID_rid;		/* SSIDs */
5852
5853	/* Reload the list of current SSID */
5854	readSsidRid(local, &SSID_rid);
5855
5856	/* Check if we asked for `any' */
5857	if (dwrq->flags == 0) {
5858		/* Just send an empty SSID list */
5859		memset(&SSID_rid, 0, sizeof(SSID_rid));
5860	} else {
5861		unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5862
5863		/* Check the size of the string */
5864		if (dwrq->length > IW_ESSID_MAX_SIZE)
5865			return -E2BIG ;
5866
5867		/* Check if index is valid */
5868		if (index >= ARRAY_SIZE(SSID_rid.ssids))
5869			return -EINVAL;
5870
5871		/* Set the SSID */
5872		memset(SSID_rid.ssids[index].ssid, 0,
5873		       sizeof(SSID_rid.ssids[index].ssid));
5874		memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5875		SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5876	}
5877	SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5878	/* Write it to the card */
5879	disable_MAC(local, 1);
5880	writeSsidRid(local, &SSID_rid, 1);
5881	enable_MAC(local, 1);
5882
5883	return 0;
5884}
5885
5886/*------------------------------------------------------------------*/
5887/*
5888 * Wireless Handler : get ESSID
5889 */
5890static int airo_get_essid(struct net_device *dev,
5891			  struct iw_request_info *info,
5892			  struct iw_point *dwrq,
5893			  char *extra)
5894{
 
5895	struct airo_info *local = dev->ml_priv;
5896	StatusRid status_rid;		/* Card status info */
5897
5898	readStatusRid(local, &status_rid, 1);
5899
5900	/* Note : if dwrq->flags != 0, we should
5901	 * get the relevant SSID from the SSID list... */
5902
5903	/* Get the current SSID */
5904	memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5905	/* If none, we may want to get the one that was set */
5906
5907	/* Push it out ! */
5908	dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5909	dwrq->flags = 1; /* active */
5910
5911	return 0;
5912}
5913
5914/*------------------------------------------------------------------*/
5915/*
5916 * Wireless Handler : set AP address
5917 */
5918static int airo_set_wap(struct net_device *dev,
5919			struct iw_request_info *info,
5920			struct sockaddr *awrq,
5921			char *extra)
5922{
 
5923	struct airo_info *local = dev->ml_priv;
5924	Cmd cmd;
5925	Resp rsp;
5926	APListRid *APList_rid = &local->APList;
5927
5928	if (awrq->sa_family != ARPHRD_ETHER)
5929		return -EINVAL;
5930	else if (is_broadcast_ether_addr(awrq->sa_data) ||
5931		 is_zero_ether_addr(awrq->sa_data)) {
5932		memset(&cmd, 0, sizeof(cmd));
5933		cmd.cmd=CMD_LOSE_SYNC;
5934		if (down_interruptible(&local->sem))
5935			return -ERESTARTSYS;
5936		issuecommand(local, &cmd, &rsp);
5937		up(&local->sem);
5938	} else {
5939		memset(APList_rid, 0, sizeof(*APList_rid));
5940		APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5941		memcpy(APList_rid->ap[0], awrq->sa_data, ETH_ALEN);
5942		disable_MAC(local, 1);
5943		writeAPListRid(local, APList_rid, 1);
5944		enable_MAC(local, 1);
5945	}
5946	return 0;
5947}
5948
5949/*------------------------------------------------------------------*/
5950/*
5951 * Wireless Handler : get AP address
5952 */
5953static int airo_get_wap(struct net_device *dev,
5954			struct iw_request_info *info,
5955			struct sockaddr *awrq,
5956			char *extra)
5957{
 
5958	struct airo_info *local = dev->ml_priv;
5959	StatusRid status_rid;		/* Card status info */
5960
5961	readStatusRid(local, &status_rid, 1);
5962
5963	/* Tentative. This seems to work, wow, I'm lucky !!! */
5964	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
5965	awrq->sa_family = ARPHRD_ETHER;
5966
5967	return 0;
5968}
5969
5970/*------------------------------------------------------------------*/
5971/*
5972 * Wireless Handler : set Nickname
5973 */
5974static int airo_set_nick(struct net_device *dev,
5975			 struct iw_request_info *info,
5976			 struct iw_point *dwrq,
5977			 char *extra)
5978{
 
5979	struct airo_info *local = dev->ml_priv;
5980
5981	/* Check the size of the string */
5982	if(dwrq->length > 16) {
5983		return -E2BIG;
5984	}
5985	readConfigRid(local, 1);
5986	memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
5987	memcpy(local->config.nodeName, extra, dwrq->length);
5988	set_bit (FLAG_COMMIT, &local->flags);
5989
5990	return -EINPROGRESS;		/* Call commit handler */
5991}
5992
5993/*------------------------------------------------------------------*/
5994/*
5995 * Wireless Handler : get Nickname
5996 */
5997static int airo_get_nick(struct net_device *dev,
5998			 struct iw_request_info *info,
5999			 struct iw_point *dwrq,
6000			 char *extra)
6001{
 
6002	struct airo_info *local = dev->ml_priv;
6003
6004	readConfigRid(local, 1);
6005	strncpy(extra, local->config.nodeName, 16);
6006	extra[16] = '\0';
6007	dwrq->length = strlen(extra);
6008
6009	return 0;
6010}
6011
6012/*------------------------------------------------------------------*/
6013/*
6014 * Wireless Handler : set Bit-Rate
6015 */
6016static int airo_set_rate(struct net_device *dev,
6017			 struct iw_request_info *info,
6018			 struct iw_param *vwrq,
6019			 char *extra)
6020{
 
6021	struct airo_info *local = dev->ml_priv;
6022	CapabilityRid cap_rid;		/* Card capability info */
6023	u8	brate = 0;
6024	int	i;
6025
6026	/* First : get a valid bit rate value */
6027	readCapabilityRid(local, &cap_rid, 1);
6028
6029	/* Which type of value ? */
6030	if((vwrq->value < 8) && (vwrq->value >= 0)) {
6031		/* Setting by rate index */
6032		/* Find value in the magic rate table */
6033		brate = cap_rid.supportedRates[vwrq->value];
6034	} else {
6035		/* Setting by frequency value */
6036		u8	normvalue = (u8) (vwrq->value/500000);
6037
6038		/* Check if rate is valid */
6039		for(i = 0 ; i < 8 ; i++) {
6040			if(normvalue == cap_rid.supportedRates[i]) {
6041				brate = normvalue;
6042				break;
6043			}
6044		}
6045	}
6046	/* -1 designed the max rate (mostly auto mode) */
6047	if(vwrq->value == -1) {
6048		/* Get the highest available rate */
6049		for(i = 0 ; i < 8 ; i++) {
6050			if(cap_rid.supportedRates[i] == 0)
6051				break;
6052		}
6053		if(i != 0)
6054			brate = cap_rid.supportedRates[i - 1];
6055	}
6056	/* Check that it is valid */
6057	if(brate == 0) {
6058		return -EINVAL;
6059	}
6060
6061	readConfigRid(local, 1);
6062	/* Now, check if we want a fixed or auto value */
6063	if(vwrq->fixed == 0) {
6064		/* Fill all the rates up to this max rate */
6065		memset(local->config.rates, 0, 8);
6066		for(i = 0 ; i < 8 ; i++) {
6067			local->config.rates[i] = cap_rid.supportedRates[i];
6068			if(local->config.rates[i] == brate)
6069				break;
6070		}
6071	} else {
6072		/* Fixed mode */
6073		/* One rate, fixed */
6074		memset(local->config.rates, 0, 8);
6075		local->config.rates[0] = brate;
6076	}
6077	set_bit (FLAG_COMMIT, &local->flags);
6078
6079	return -EINPROGRESS;		/* Call commit handler */
6080}
6081
6082/*------------------------------------------------------------------*/
6083/*
6084 * Wireless Handler : get Bit-Rate
6085 */
6086static int airo_get_rate(struct net_device *dev,
6087			 struct iw_request_info *info,
6088			 struct iw_param *vwrq,
6089			 char *extra)
6090{
 
6091	struct airo_info *local = dev->ml_priv;
6092	StatusRid status_rid;		/* Card status info */
6093
6094	readStatusRid(local, &status_rid, 1);
6095
6096	vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6097	/* If more than one rate, set auto */
6098	readConfigRid(local, 1);
6099	vwrq->fixed = (local->config.rates[1] == 0);
6100
6101	return 0;
6102}
6103
6104/*------------------------------------------------------------------*/
6105/*
6106 * Wireless Handler : set RTS threshold
6107 */
6108static int airo_set_rts(struct net_device *dev,
6109			struct iw_request_info *info,
6110			struct iw_param *vwrq,
6111			char *extra)
6112{
 
6113	struct airo_info *local = dev->ml_priv;
6114	int rthr = vwrq->value;
6115
6116	if(vwrq->disabled)
6117		rthr = AIRO_DEF_MTU;
6118	if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
6119		return -EINVAL;
6120	}
6121	readConfigRid(local, 1);
6122	local->config.rtsThres = cpu_to_le16(rthr);
6123	set_bit (FLAG_COMMIT, &local->flags);
6124
6125	return -EINPROGRESS;		/* Call commit handler */
6126}
6127
6128/*------------------------------------------------------------------*/
6129/*
6130 * Wireless Handler : get RTS threshold
6131 */
6132static int airo_get_rts(struct net_device *dev,
6133			struct iw_request_info *info,
6134			struct iw_param *vwrq,
6135			char *extra)
6136{
 
6137	struct airo_info *local = dev->ml_priv;
6138
6139	readConfigRid(local, 1);
6140	vwrq->value = le16_to_cpu(local->config.rtsThres);
6141	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6142	vwrq->fixed = 1;
6143
6144	return 0;
6145}
6146
6147/*------------------------------------------------------------------*/
6148/*
6149 * Wireless Handler : set Fragmentation threshold
6150 */
6151static int airo_set_frag(struct net_device *dev,
6152			 struct iw_request_info *info,
6153			 struct iw_param *vwrq,
6154			 char *extra)
6155{
 
6156	struct airo_info *local = dev->ml_priv;
6157	int fthr = vwrq->value;
6158
6159	if(vwrq->disabled)
6160		fthr = AIRO_DEF_MTU;
6161	if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
6162		return -EINVAL;
6163	}
6164	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
6165	readConfigRid(local, 1);
6166	local->config.fragThresh = cpu_to_le16(fthr);
6167	set_bit (FLAG_COMMIT, &local->flags);
6168
6169	return -EINPROGRESS;		/* Call commit handler */
6170}
6171
6172/*------------------------------------------------------------------*/
6173/*
6174 * Wireless Handler : get Fragmentation threshold
6175 */
6176static int airo_get_frag(struct net_device *dev,
6177			 struct iw_request_info *info,
6178			 struct iw_param *vwrq,
6179			 char *extra)
6180{
 
6181	struct airo_info *local = dev->ml_priv;
6182
6183	readConfigRid(local, 1);
6184	vwrq->value = le16_to_cpu(local->config.fragThresh);
6185	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6186	vwrq->fixed = 1;
6187
6188	return 0;
6189}
6190
6191/*------------------------------------------------------------------*/
6192/*
6193 * Wireless Handler : set Mode of Operation
6194 */
6195static int airo_set_mode(struct net_device *dev,
6196			 struct iw_request_info *info,
6197			 __u32 *uwrq,
6198			 char *extra)
6199{
 
6200	struct airo_info *local = dev->ml_priv;
6201	int reset = 0;
6202
6203	readConfigRid(local, 1);
6204	if (sniffing_mode(local))
6205		reset = 1;
6206
6207	switch(*uwrq) {
6208		case IW_MODE_ADHOC:
6209			local->config.opmode &= ~MODE_CFG_MASK;
6210			local->config.opmode |= MODE_STA_IBSS;
6211			local->config.rmode &= ~RXMODE_FULL_MASK;
6212			local->config.scanMode = SCANMODE_ACTIVE;
6213			clear_bit (FLAG_802_11, &local->flags);
6214			break;
6215		case IW_MODE_INFRA:
6216			local->config.opmode &= ~MODE_CFG_MASK;
6217			local->config.opmode |= MODE_STA_ESS;
6218			local->config.rmode &= ~RXMODE_FULL_MASK;
6219			local->config.scanMode = SCANMODE_ACTIVE;
6220			clear_bit (FLAG_802_11, &local->flags);
6221			break;
6222		case IW_MODE_MASTER:
6223			local->config.opmode &= ~MODE_CFG_MASK;
6224			local->config.opmode |= MODE_AP;
6225			local->config.rmode &= ~RXMODE_FULL_MASK;
6226			local->config.scanMode = SCANMODE_ACTIVE;
6227			clear_bit (FLAG_802_11, &local->flags);
6228			break;
6229		case IW_MODE_REPEAT:
6230			local->config.opmode &= ~MODE_CFG_MASK;
6231			local->config.opmode |= MODE_AP_RPTR;
6232			local->config.rmode &= ~RXMODE_FULL_MASK;
6233			local->config.scanMode = SCANMODE_ACTIVE;
6234			clear_bit (FLAG_802_11, &local->flags);
6235			break;
6236		case IW_MODE_MONITOR:
6237			local->config.opmode &= ~MODE_CFG_MASK;
6238			local->config.opmode |= MODE_STA_ESS;
6239			local->config.rmode &= ~RXMODE_FULL_MASK;
6240			local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6241			local->config.scanMode = SCANMODE_PASSIVE;
6242			set_bit (FLAG_802_11, &local->flags);
6243			break;
6244		default:
6245			return -EINVAL;
6246	}
6247	if (reset)
6248		set_bit (FLAG_RESET, &local->flags);
6249	set_bit (FLAG_COMMIT, &local->flags);
6250
6251	return -EINPROGRESS;		/* Call commit handler */
6252}
6253
6254/*------------------------------------------------------------------*/
6255/*
6256 * Wireless Handler : get Mode of Operation
6257 */
6258static int airo_get_mode(struct net_device *dev,
6259			 struct iw_request_info *info,
6260			 __u32 *uwrq,
6261			 char *extra)
6262{
6263	struct airo_info *local = dev->ml_priv;
6264
6265	readConfigRid(local, 1);
6266	/* If not managed, assume it's ad-hoc */
6267	switch (local->config.opmode & MODE_CFG_MASK) {
6268		case MODE_STA_ESS:
6269			*uwrq = IW_MODE_INFRA;
6270			break;
6271		case MODE_AP:
6272			*uwrq = IW_MODE_MASTER;
6273			break;
6274		case MODE_AP_RPTR:
6275			*uwrq = IW_MODE_REPEAT;
6276			break;
6277		default:
6278			*uwrq = IW_MODE_ADHOC;
6279	}
6280
6281	return 0;
6282}
6283
6284static inline int valid_index(struct airo_info *ai, int index)
6285{
6286	return (index >= 0) && (index <= ai->max_wep_idx);
6287}
6288
6289/*------------------------------------------------------------------*/
6290/*
6291 * Wireless Handler : set Encryption Key
6292 */
6293static int airo_set_encode(struct net_device *dev,
6294			   struct iw_request_info *info,
6295			   struct iw_point *dwrq,
6296			   char *extra)
6297{
 
6298	struct airo_info *local = dev->ml_priv;
6299	int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
6300	__le16 currentAuthType = local->config.authType;
6301	int rc = 0;
6302
6303	if (!local->wep_capable)
6304		return -EOPNOTSUPP;
6305
6306	readConfigRid(local, 1);
6307
6308	/* Basic checking: do we have a key to set ?
6309	 * Note : with the new API, it's impossible to get a NULL pointer.
6310	 * Therefore, we need to check a key size == 0 instead.
6311	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6312	 * when no key is present (only change flags), but older versions
6313	 * don't do it. - Jean II */
6314	if (dwrq->length > 0) {
6315		wep_key_t key;
6316		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6317		int current_index;
6318
6319		/* Check the size of the key */
6320		if (dwrq->length > MAX_KEY_SIZE) {
6321			return -EINVAL;
6322		}
6323
6324		current_index = get_wep_tx_idx(local);
6325		if (current_index < 0)
6326			current_index = 0;
6327
6328		/* Check the index (none -> use current) */
6329		if (!valid_index(local, index))
6330			index = current_index;
6331
6332		/* Set the length */
6333		if (dwrq->length > MIN_KEY_SIZE)
6334			key.len = MAX_KEY_SIZE;
6335		else
6336			key.len = MIN_KEY_SIZE;
6337		/* Check if the key is not marked as invalid */
6338		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6339			/* Cleanup */
6340			memset(key.key, 0, MAX_KEY_SIZE);
6341			/* Copy the key in the driver */
6342			memcpy(key.key, extra, dwrq->length);
6343			/* Send the key to the card */
6344			rc = set_wep_key(local, index, key.key, key.len, perm, 1);
6345			if (rc < 0) {
6346				airo_print_err(local->dev->name, "failed to set"
6347				               " WEP key at index %d: %d.",
6348				               index, rc);
6349				return rc;
6350			}
6351		}
6352		/* WE specify that if a valid key is set, encryption
6353		 * should be enabled (user may turn it off later)
6354		 * This is also how "iwconfig ethX key on" works */
6355		if((index == current_index) && (key.len > 0) &&
6356		   (local->config.authType == AUTH_OPEN))
6357			set_auth_type(local, AUTH_ENCRYPT);
6358	} else {
6359		/* Do we want to just set the transmit key index ? */
6360		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6361		if (valid_index(local, index)) {
6362			rc = set_wep_tx_idx(local, index, perm, 1);
6363			if (rc < 0) {
6364				airo_print_err(local->dev->name, "failed to set"
6365				               " WEP transmit index to %d: %d.",
6366				               index, rc);
6367				return rc;
6368			}
6369		} else {
6370			/* Don't complain if only change the mode */
6371			if (!(dwrq->flags & IW_ENCODE_MODE))
6372				return -EINVAL;
6373		}
6374	}
6375	/* Read the flags */
6376	if (dwrq->flags & IW_ENCODE_DISABLED)
6377		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
6378	if(dwrq->flags & IW_ENCODE_RESTRICTED)
6379		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
6380	if (dwrq->flags & IW_ENCODE_OPEN)
6381		set_auth_type(local, AUTH_ENCRYPT);	/* Only Wep */
6382	/* Commit the changes to flags if needed */
6383	if (local->config.authType != currentAuthType)
6384		set_bit (FLAG_COMMIT, &local->flags);
6385	return -EINPROGRESS;		/* Call commit handler */
6386}
6387
6388/*------------------------------------------------------------------*/
6389/*
6390 * Wireless Handler : get Encryption Key
6391 */
6392static int airo_get_encode(struct net_device *dev,
6393			   struct iw_request_info *info,
6394			   struct iw_point *dwrq,
6395			   char *extra)
6396{
 
6397	struct airo_info *local = dev->ml_priv;
6398	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6399	int wep_key_len;
6400	u8 buf[16];
6401
6402	if (!local->wep_capable)
6403		return -EOPNOTSUPP;
6404
6405	readConfigRid(local, 1);
6406
6407	/* Check encryption mode */
6408	switch(local->config.authType)	{
6409		case AUTH_ENCRYPT:
6410			dwrq->flags = IW_ENCODE_OPEN;
6411			break;
6412		case AUTH_SHAREDKEY:
6413			dwrq->flags = IW_ENCODE_RESTRICTED;
6414			break;
6415		default:
6416		case AUTH_OPEN:
6417			dwrq->flags = IW_ENCODE_DISABLED;
6418			break;
6419	}
6420	/* We can't return the key, so set the proper flag and return zero */
6421	dwrq->flags |= IW_ENCODE_NOKEY;
6422	memset(extra, 0, 16);
6423
6424	/* Which key do we want ? -1 -> tx index */
6425	if (!valid_index(local, index)) {
6426		index = get_wep_tx_idx(local);
6427		if (index < 0)
6428			index = 0;
6429	}
6430	dwrq->flags |= index + 1;
6431
6432	/* Copy the key to the user buffer */
6433	wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
6434	if (wep_key_len < 0) {
6435		dwrq->length = 0;
6436	} else {
6437		dwrq->length = wep_key_len;
6438		memcpy(extra, buf, dwrq->length);
6439	}
6440
6441	return 0;
6442}
6443
6444/*------------------------------------------------------------------*/
6445/*
6446 * Wireless Handler : set extended Encryption parameters
6447 */
6448static int airo_set_encodeext(struct net_device *dev,
6449			   struct iw_request_info *info,
6450			    union iwreq_data *wrqu,
6451			    char *extra)
6452{
6453	struct airo_info *local = dev->ml_priv;
6454	struct iw_point *encoding = &wrqu->encoding;
6455	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6456	int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
6457	__le16 currentAuthType = local->config.authType;
6458	int idx, key_len, alg = ext->alg, set_key = 1, rc;
6459	wep_key_t key;
6460
6461	if (!local->wep_capable)
6462		return -EOPNOTSUPP;
6463
6464	readConfigRid(local, 1);
6465
6466	/* Determine and validate the key index */
6467	idx = encoding->flags & IW_ENCODE_INDEX;
6468	if (idx) {
6469		if (!valid_index(local, idx - 1))
6470			return -EINVAL;
6471		idx--;
6472	} else {
6473		idx = get_wep_tx_idx(local);
6474		if (idx < 0)
6475			idx = 0;
6476	}
6477
6478	if (encoding->flags & IW_ENCODE_DISABLED)
6479		alg = IW_ENCODE_ALG_NONE;
6480
6481	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
6482		/* Only set transmit key index here, actual
6483		 * key is set below if needed.
6484		 */
6485		rc = set_wep_tx_idx(local, idx, perm, 1);
6486		if (rc < 0) {
6487			airo_print_err(local->dev->name, "failed to set "
6488			               "WEP transmit index to %d: %d.",
6489			               idx, rc);
6490			return rc;
6491		}
6492		set_key = ext->key_len > 0 ? 1 : 0;
6493	}
6494
6495	if (set_key) {
6496		/* Set the requested key first */
6497		memset(key.key, 0, MAX_KEY_SIZE);
6498		switch (alg) {
6499		case IW_ENCODE_ALG_NONE:
6500			key.len = 0;
6501			break;
6502		case IW_ENCODE_ALG_WEP:
6503			if (ext->key_len > MIN_KEY_SIZE) {
6504				key.len = MAX_KEY_SIZE;
6505			} else if (ext->key_len > 0) {
6506				key.len = MIN_KEY_SIZE;
6507			} else {
6508				return -EINVAL;
6509			}
6510			key_len = min (ext->key_len, key.len);
6511			memcpy(key.key, ext->key, key_len);
6512			break;
6513		default:
6514			return -EINVAL;
6515		}
6516		if (key.len == 0) {
6517			rc = set_wep_tx_idx(local, idx, perm, 1);
6518			if (rc < 0) {
6519				airo_print_err(local->dev->name,
6520					       "failed to set WEP transmit index to %d: %d.",
6521					       idx, rc);
6522				return rc;
6523			}
6524		} else {
6525			rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6526			if (rc < 0) {
6527				airo_print_err(local->dev->name,
6528					       "failed to set WEP key at index %d: %d.",
6529					       idx, rc);
6530				return rc;
6531			}
6532		}
6533	}
6534
6535	/* Read the flags */
6536	if (encoding->flags & IW_ENCODE_DISABLED)
6537		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
6538	if(encoding->flags & IW_ENCODE_RESTRICTED)
6539		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
6540	if (encoding->flags & IW_ENCODE_OPEN)
6541		set_auth_type(local, AUTH_ENCRYPT);
6542	/* Commit the changes to flags if needed */
6543	if (local->config.authType != currentAuthType)
6544		set_bit (FLAG_COMMIT, &local->flags);
6545
6546	return -EINPROGRESS;
6547}
6548
6549
6550/*------------------------------------------------------------------*/
6551/*
6552 * Wireless Handler : get extended Encryption parameters
6553 */
6554static int airo_get_encodeext(struct net_device *dev,
6555			    struct iw_request_info *info,
6556			    union iwreq_data *wrqu,
6557			    char *extra)
6558{
6559	struct airo_info *local = dev->ml_priv;
6560	struct iw_point *encoding = &wrqu->encoding;
6561	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6562	int idx, max_key_len, wep_key_len;
6563	u8 buf[16];
6564
6565	if (!local->wep_capable)
6566		return -EOPNOTSUPP;
6567
6568	readConfigRid(local, 1);
6569
6570	max_key_len = encoding->length - sizeof(*ext);
6571	if (max_key_len < 0)
6572		return -EINVAL;
6573
6574	idx = encoding->flags & IW_ENCODE_INDEX;
6575	if (idx) {
6576		if (!valid_index(local, idx - 1))
6577			return -EINVAL;
6578		idx--;
6579	} else {
6580		idx = get_wep_tx_idx(local);
6581		if (idx < 0)
6582			idx = 0;
6583	}
6584
6585	encoding->flags = idx + 1;
6586	memset(ext, 0, sizeof(*ext));
6587
6588	/* Check encryption mode */
6589	switch(local->config.authType) {
6590		case AUTH_ENCRYPT:
6591			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6592			break;
6593		case AUTH_SHAREDKEY:
6594			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6595			break;
6596		default:
6597		case AUTH_OPEN:
6598			encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
6599			break;
6600	}
6601	/* We can't return the key, so set the proper flag and return zero */
6602	encoding->flags |= IW_ENCODE_NOKEY;
6603	memset(extra, 0, 16);
6604	
6605	/* Copy the key to the user buffer */
6606	wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
6607	if (wep_key_len < 0) {
6608		ext->key_len = 0;
6609	} else {
6610		ext->key_len = wep_key_len;
6611		memcpy(extra, buf, ext->key_len);
6612	}
6613
6614	return 0;
6615}
6616
6617
6618/*------------------------------------------------------------------*/
6619/*
6620 * Wireless Handler : set extended authentication parameters
6621 */
6622static int airo_set_auth(struct net_device *dev,
6623			       struct iw_request_info *info,
6624			       union iwreq_data *wrqu, char *extra)
6625{
6626	struct airo_info *local = dev->ml_priv;
6627	struct iw_param *param = &wrqu->param;
6628	__le16 currentAuthType = local->config.authType;
6629
6630	switch (param->flags & IW_AUTH_INDEX) {
6631	case IW_AUTH_WPA_VERSION:
6632	case IW_AUTH_CIPHER_PAIRWISE:
6633	case IW_AUTH_CIPHER_GROUP:
6634	case IW_AUTH_KEY_MGMT:
6635	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6636	case IW_AUTH_PRIVACY_INVOKED:
6637		/*
6638		 * airo does not use these parameters
6639		 */
6640		break;
6641
6642	case IW_AUTH_DROP_UNENCRYPTED:
6643		if (param->value) {
6644			/* Only change auth type if unencrypted */
6645			if (currentAuthType == AUTH_OPEN)
6646				set_auth_type(local, AUTH_ENCRYPT);
6647		} else {
6648			set_auth_type(local, AUTH_OPEN);
6649		}
6650
6651		/* Commit the changes to flags if needed */
6652		if (local->config.authType != currentAuthType)
6653			set_bit (FLAG_COMMIT, &local->flags);
6654		break;
6655
6656	case IW_AUTH_80211_AUTH_ALG: {
6657			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
6658				set_auth_type(local, AUTH_SHAREDKEY);
6659			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
6660				/* We don't know here if WEP open system or
6661				 * unencrypted mode was requested - so use the
6662				 * last mode (of these two) used last time
6663				 */
6664				set_auth_type(local, local->last_auth);
6665			} else
6666				return -EINVAL;
6667
6668			/* Commit the changes to flags if needed */
6669			if (local->config.authType != currentAuthType)
6670				set_bit (FLAG_COMMIT, &local->flags);
6671			break;
6672		}
6673
6674	case IW_AUTH_WPA_ENABLED:
6675		/* Silently accept disable of WPA */
6676		if (param->value > 0)
6677			return -EOPNOTSUPP;
6678		break;
6679
6680	default:
6681		return -EOPNOTSUPP;
6682	}
6683	return -EINPROGRESS;
6684}
6685
6686
6687/*------------------------------------------------------------------*/
6688/*
6689 * Wireless Handler : get extended authentication parameters
6690 */
6691static int airo_get_auth(struct net_device *dev,
6692			       struct iw_request_info *info,
6693			       union iwreq_data *wrqu, char *extra)
6694{
6695	struct airo_info *local = dev->ml_priv;
6696	struct iw_param *param = &wrqu->param;
6697	__le16 currentAuthType = local->config.authType;
6698
6699	switch (param->flags & IW_AUTH_INDEX) {
6700	case IW_AUTH_DROP_UNENCRYPTED:
6701		switch (currentAuthType) {
6702		case AUTH_SHAREDKEY:
6703		case AUTH_ENCRYPT:
6704			param->value = 1;
6705			break;
6706		default:
6707			param->value = 0;
6708			break;
6709		}
6710		break;
6711
6712	case IW_AUTH_80211_AUTH_ALG:
6713		switch (currentAuthType) {
6714		case AUTH_SHAREDKEY:
6715			param->value = IW_AUTH_ALG_SHARED_KEY;
6716			break;
6717		case AUTH_ENCRYPT:
6718		default:
6719			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
6720			break;
6721		}
6722		break;
6723
6724	case IW_AUTH_WPA_ENABLED:
6725		param->value = 0;
6726		break;
6727
6728	default:
6729		return -EOPNOTSUPP;
6730	}
6731	return 0;
6732}
6733
6734
6735/*------------------------------------------------------------------*/
6736/*
6737 * Wireless Handler : set Tx-Power
6738 */
6739static int airo_set_txpow(struct net_device *dev,
6740			  struct iw_request_info *info,
6741			  struct iw_param *vwrq,
6742			  char *extra)
6743{
 
6744	struct airo_info *local = dev->ml_priv;
6745	CapabilityRid cap_rid;		/* Card capability info */
6746	int i;
6747	int rc = -EINVAL;
6748	__le16 v = cpu_to_le16(vwrq->value);
6749
6750	readCapabilityRid(local, &cap_rid, 1);
6751
6752	if (vwrq->disabled) {
6753		set_bit (FLAG_RADIO_OFF, &local->flags);
6754		set_bit (FLAG_COMMIT, &local->flags);
6755		return -EINPROGRESS;		/* Call commit handler */
6756	}
6757	if (vwrq->flags != IW_TXPOW_MWATT) {
6758		return -EINVAL;
6759	}
6760	clear_bit (FLAG_RADIO_OFF, &local->flags);
6761	for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)
6762		if (v == cap_rid.txPowerLevels[i]) {
6763			readConfigRid(local, 1);
6764			local->config.txPower = v;
6765			set_bit (FLAG_COMMIT, &local->flags);
6766			rc = -EINPROGRESS;	/* Call commit handler */
6767			break;
6768		}
6769	return rc;
6770}
6771
6772/*------------------------------------------------------------------*/
6773/*
6774 * Wireless Handler : get Tx-Power
6775 */
6776static int airo_get_txpow(struct net_device *dev,
6777			  struct iw_request_info *info,
6778			  struct iw_param *vwrq,
6779			  char *extra)
6780{
 
6781	struct airo_info *local = dev->ml_priv;
6782
6783	readConfigRid(local, 1);
6784	vwrq->value = le16_to_cpu(local->config.txPower);
6785	vwrq->fixed = 1;	/* No power control */
6786	vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6787	vwrq->flags = IW_TXPOW_MWATT;
6788
6789	return 0;
6790}
6791
6792/*------------------------------------------------------------------*/
6793/*
6794 * Wireless Handler : set Retry limits
6795 */
6796static int airo_set_retry(struct net_device *dev,
6797			  struct iw_request_info *info,
6798			  struct iw_param *vwrq,
6799			  char *extra)
6800{
 
6801	struct airo_info *local = dev->ml_priv;
6802	int rc = -EINVAL;
6803
6804	if(vwrq->disabled) {
6805		return -EINVAL;
6806	}
6807	readConfigRid(local, 1);
6808	if(vwrq->flags & IW_RETRY_LIMIT) {
6809		__le16 v = cpu_to_le16(vwrq->value);
6810		if(vwrq->flags & IW_RETRY_LONG)
6811			local->config.longRetryLimit = v;
6812		else if (vwrq->flags & IW_RETRY_SHORT)
6813			local->config.shortRetryLimit = v;
6814		else {
6815			/* No modifier : set both */
6816			local->config.longRetryLimit = v;
6817			local->config.shortRetryLimit = v;
6818		}
6819		set_bit (FLAG_COMMIT, &local->flags);
6820		rc = -EINPROGRESS;		/* Call commit handler */
6821	}
6822	if(vwrq->flags & IW_RETRY_LIFETIME) {
6823		local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
6824		set_bit (FLAG_COMMIT, &local->flags);
6825		rc = -EINPROGRESS;		/* Call commit handler */
6826	}
6827	return rc;
6828}
6829
6830/*------------------------------------------------------------------*/
6831/*
6832 * Wireless Handler : get Retry limits
6833 */
6834static int airo_get_retry(struct net_device *dev,
6835			  struct iw_request_info *info,
6836			  struct iw_param *vwrq,
6837			  char *extra)
6838{
 
6839	struct airo_info *local = dev->ml_priv;
6840
6841	vwrq->disabled = 0;      /* Can't be disabled */
6842
6843	readConfigRid(local, 1);
6844	/* Note : by default, display the min retry number */
6845	if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6846		vwrq->flags = IW_RETRY_LIFETIME;
6847		vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
6848	} else if((vwrq->flags & IW_RETRY_LONG)) {
6849		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6850		vwrq->value = le16_to_cpu(local->config.longRetryLimit);
6851	} else {
6852		vwrq->flags = IW_RETRY_LIMIT;
6853		vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
6854		if(local->config.shortRetryLimit != local->config.longRetryLimit)
6855			vwrq->flags |= IW_RETRY_SHORT;
6856	}
6857
6858	return 0;
6859}
6860
6861/*------------------------------------------------------------------*/
6862/*
6863 * Wireless Handler : get range info
6864 */
6865static int airo_get_range(struct net_device *dev,
6866			  struct iw_request_info *info,
6867			  struct iw_point *dwrq,
6868			  char *extra)
6869{
 
6870	struct airo_info *local = dev->ml_priv;
6871	struct iw_range *range = (struct iw_range *) extra;
6872	CapabilityRid cap_rid;		/* Card capability info */
6873	int		i;
6874	int		k;
6875
6876	readCapabilityRid(local, &cap_rid, 1);
6877
6878	dwrq->length = sizeof(struct iw_range);
6879	memset(range, 0, sizeof(*range));
6880	range->min_nwid = 0x0000;
6881	range->max_nwid = 0x0000;
6882	range->num_channels = 14;
6883	/* Should be based on cap_rid.country to give only
6884	 * what the current card support */
6885	k = 0;
6886	for(i = 0; i < 14; i++) {
6887		range->freq[k].i = i + 1; /* List index */
6888		range->freq[k].m = 100000 *
6889		     ieee80211_channel_to_frequency(i + 1, NL80211_BAND_2GHZ);
6890		range->freq[k++].e = 1;	/* Values in MHz -> * 10^5 * 10 */
6891	}
6892	range->num_frequency = k;
6893
6894	range->sensitivity = 65535;
6895
6896	/* Hum... Should put the right values there */
6897	if (local->rssi)
6898		range->max_qual.qual = 100;	/* % */
6899	else
6900		range->max_qual.qual = airo_get_max_quality(&cap_rid);
6901	range->max_qual.level = 0x100 - 120;	/* -120 dBm */
6902	range->max_qual.noise = 0x100 - 120;	/* -120 dBm */
6903
6904	/* Experimental measurements - boundary 11/5.5 Mb/s */
6905	/* Note : with or without the (local->rssi), results
6906	 * are somewhat different. - Jean II */
6907	if (local->rssi) {
6908		range->avg_qual.qual = 50;		/* % */
6909		range->avg_qual.level = 0x100 - 70;	/* -70 dBm */
6910	} else {
6911		range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6912		range->avg_qual.level = 0x100 - 80;	/* -80 dBm */
6913	}
6914	range->avg_qual.noise = 0x100 - 85;		/* -85 dBm */
6915
6916	for(i = 0 ; i < 8 ; i++) {
6917		range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6918		if(range->bitrate[i] == 0)
6919			break;
6920	}
6921	range->num_bitrates = i;
6922
6923	/* Set an indication of the max TCP throughput
6924	 * in bit/s that we can expect using this interface.
6925	 * May be use for QoS stuff... Jean II */
6926	if(i > 2)
6927		range->throughput = 5000 * 1000;
6928	else
6929		range->throughput = 1500 * 1000;
6930
6931	range->min_rts = 0;
6932	range->max_rts = AIRO_DEF_MTU;
6933	range->min_frag = 256;
6934	range->max_frag = AIRO_DEF_MTU;
6935
6936	if(cap_rid.softCap & cpu_to_le16(2)) {
6937		// WEP: RC4 40 bits
6938		range->encoding_size[0] = 5;
6939		// RC4 ~128 bits
6940		if (cap_rid.softCap & cpu_to_le16(0x100)) {
6941			range->encoding_size[1] = 13;
6942			range->num_encoding_sizes = 2;
6943		} else
6944			range->num_encoding_sizes = 1;
6945		range->max_encoding_tokens =
6946			cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
6947	} else {
6948		range->num_encoding_sizes = 0;
6949		range->max_encoding_tokens = 0;
6950	}
6951	range->min_pmp = 0;
6952	range->max_pmp = 5000000;	/* 5 secs */
6953	range->min_pmt = 0;
6954	range->max_pmt = 65535 * 1024;	/* ??? */
6955	range->pmp_flags = IW_POWER_PERIOD;
6956	range->pmt_flags = IW_POWER_TIMEOUT;
6957	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
6958
6959	/* Transmit Power - values are in mW */
6960	for(i = 0 ; i < 8 ; i++) {
6961		range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
6962		if(range->txpower[i] == 0)
6963			break;
6964	}
6965	range->num_txpower = i;
6966	range->txpower_capa = IW_TXPOW_MWATT;
6967	range->we_version_source = 19;
6968	range->we_version_compiled = WIRELESS_EXT;
6969	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
6970	range->retry_flags = IW_RETRY_LIMIT;
6971	range->r_time_flags = IW_RETRY_LIFETIME;
6972	range->min_retry = 1;
6973	range->max_retry = 65535;
6974	range->min_r_time = 1024;
6975	range->max_r_time = 65535 * 1024;
6976
6977	/* Event capability (kernel + driver) */
6978	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
6979				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
6980				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
6981				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
6982	range->event_capa[1] = IW_EVENT_CAPA_K_1;
6983	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
6984	return 0;
6985}
6986
6987/*------------------------------------------------------------------*/
6988/*
6989 * Wireless Handler : set Power Management
6990 */
6991static int airo_set_power(struct net_device *dev,
6992			  struct iw_request_info *info,
6993			  struct iw_param *vwrq,
6994			  char *extra)
6995{
 
6996	struct airo_info *local = dev->ml_priv;
6997
6998	readConfigRid(local, 1);
6999	if (vwrq->disabled) {
7000		if (sniffing_mode(local))
7001			return -EINVAL;
7002		local->config.powerSaveMode = POWERSAVE_CAM;
7003		local->config.rmode &= ~RXMODE_MASK;
7004		local->config.rmode |= RXMODE_BC_MC_ADDR;
7005		set_bit (FLAG_COMMIT, &local->flags);
7006		return -EINPROGRESS;		/* Call commit handler */
7007	}
7008	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7009		local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
7010		local->config.powerSaveMode = POWERSAVE_PSPCAM;
7011		set_bit (FLAG_COMMIT, &local->flags);
7012	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
7013		local->config.fastListenInterval =
7014		local->config.listenInterval =
7015			cpu_to_le16((vwrq->value + 500) / 1024);
7016		local->config.powerSaveMode = POWERSAVE_PSPCAM;
7017		set_bit (FLAG_COMMIT, &local->flags);
7018	}
7019	switch (vwrq->flags & IW_POWER_MODE) {
7020		case IW_POWER_UNICAST_R:
7021			if (sniffing_mode(local))
7022				return -EINVAL;
7023			local->config.rmode &= ~RXMODE_MASK;
7024			local->config.rmode |= RXMODE_ADDR;
7025			set_bit (FLAG_COMMIT, &local->flags);
7026			break;
7027		case IW_POWER_ALL_R:
7028			if (sniffing_mode(local))
7029				return -EINVAL;
7030			local->config.rmode &= ~RXMODE_MASK;
7031			local->config.rmode |= RXMODE_BC_MC_ADDR;
7032			set_bit (FLAG_COMMIT, &local->flags);
 
7033		case IW_POWER_ON:
7034			/* This is broken, fixme ;-) */
7035			break;
7036		default:
7037			return -EINVAL;
7038	}
7039	// Note : we may want to factor local->need_commit here
7040	// Note2 : may also want to factor RXMODE_RFMON test
7041	return -EINPROGRESS;		/* Call commit handler */
7042}
7043
7044/*------------------------------------------------------------------*/
7045/*
7046 * Wireless Handler : get Power Management
7047 */
7048static int airo_get_power(struct net_device *dev,
7049			  struct iw_request_info *info,
7050			  struct iw_param *vwrq,
7051			  char *extra)
7052{
 
7053	struct airo_info *local = dev->ml_priv;
7054	__le16 mode;
7055
7056	readConfigRid(local, 1);
7057	mode = local->config.powerSaveMode;
7058	if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
7059		return 0;
7060	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7061		vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
7062		vwrq->flags = IW_POWER_TIMEOUT;
7063	} else {
7064		vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
7065		vwrq->flags = IW_POWER_PERIOD;
7066	}
7067	if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
7068		vwrq->flags |= IW_POWER_UNICAST_R;
7069	else
7070		vwrq->flags |= IW_POWER_ALL_R;
7071
7072	return 0;
7073}
7074
7075/*------------------------------------------------------------------*/
7076/*
7077 * Wireless Handler : set Sensitivity
7078 */
7079static int airo_set_sens(struct net_device *dev,
7080			 struct iw_request_info *info,
7081			 struct iw_param *vwrq,
7082			 char *extra)
7083{
 
7084	struct airo_info *local = dev->ml_priv;
7085
7086	readConfigRid(local, 1);
7087	local->config.rssiThreshold =
7088		cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
7089	set_bit (FLAG_COMMIT, &local->flags);
7090
7091	return -EINPROGRESS;		/* Call commit handler */
7092}
7093
7094/*------------------------------------------------------------------*/
7095/*
7096 * Wireless Handler : get Sensitivity
7097 */
7098static int airo_get_sens(struct net_device *dev,
7099			 struct iw_request_info *info,
7100			 struct iw_param *vwrq,
7101			 char *extra)
7102{
 
7103	struct airo_info *local = dev->ml_priv;
7104
7105	readConfigRid(local, 1);
7106	vwrq->value = le16_to_cpu(local->config.rssiThreshold);
7107	vwrq->disabled = (vwrq->value == 0);
7108	vwrq->fixed = 1;
7109
7110	return 0;
7111}
7112
7113/*------------------------------------------------------------------*/
7114/*
7115 * Wireless Handler : get AP List
7116 * Note : this is deprecated in favor of IWSCAN
7117 */
7118static int airo_get_aplist(struct net_device *dev,
7119			   struct iw_request_info *info,
7120			   struct iw_point *dwrq,
7121			   char *extra)
7122{
 
7123	struct airo_info *local = dev->ml_priv;
7124	struct sockaddr *address = (struct sockaddr *) extra;
7125	struct iw_quality *qual;
7126	BSSListRid BSSList;
7127	int i;
7128	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7129
7130	qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
7131	if (!qual)
7132		return -ENOMEM;
7133
7134	for (i = 0; i < IW_MAX_AP; i++) {
7135		u16 dBm;
7136		if (readBSSListRid(local, loseSync, &BSSList))
7137			break;
7138		loseSync = 0;
7139		memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
7140		address[i].sa_family = ARPHRD_ETHER;
7141		dBm = le16_to_cpu(BSSList.dBm);
7142		if (local->rssi) {
7143			qual[i].level = 0x100 - dBm;
7144			qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
7145			qual[i].updated = IW_QUAL_QUAL_UPDATED
7146					| IW_QUAL_LEVEL_UPDATED
7147					| IW_QUAL_DBM;
7148		} else {
7149			qual[i].level = (dBm + 321) / 2;
7150			qual[i].qual = 0;
7151			qual[i].updated = IW_QUAL_QUAL_INVALID
7152					| IW_QUAL_LEVEL_UPDATED
7153					| IW_QUAL_DBM;
7154		}
7155		qual[i].noise = local->wstats.qual.noise;
7156		if (BSSList.index == cpu_to_le16(0xffff))
7157			break;
7158	}
7159	if (!i) {
7160		StatusRid status_rid;		/* Card status info */
7161		readStatusRid(local, &status_rid, 1);
7162		for (i = 0;
7163		     i < min(IW_MAX_AP, 4) &&
7164			     (status_rid.bssid[i][0]
7165			      & status_rid.bssid[i][1]
7166			      & status_rid.bssid[i][2]
7167			      & status_rid.bssid[i][3]
7168			      & status_rid.bssid[i][4]
7169			      & status_rid.bssid[i][5])!=0xff &&
7170			     (status_rid.bssid[i][0]
7171			      | status_rid.bssid[i][1]
7172			      | status_rid.bssid[i][2]
7173			      | status_rid.bssid[i][3]
7174			      | status_rid.bssid[i][4]
7175			      | status_rid.bssid[i][5]);
7176		     i++) {
7177			memcpy(address[i].sa_data,
7178			       status_rid.bssid[i], ETH_ALEN);
7179			address[i].sa_family = ARPHRD_ETHER;
7180		}
7181	} else {
7182		dwrq->flags = 1; /* Should be define'd */
7183		memcpy(extra + sizeof(struct sockaddr) * i, qual,
7184		       sizeof(struct iw_quality) * i);
7185	}
7186	dwrq->length = i;
7187
7188	kfree(qual);
7189	return 0;
7190}
7191
7192/*------------------------------------------------------------------*/
7193/*
7194 * Wireless Handler : Initiate Scan
7195 */
7196static int airo_set_scan(struct net_device *dev,
7197			 struct iw_request_info *info,
7198			 struct iw_point *dwrq,
7199			 char *extra)
7200{
7201	struct airo_info *ai = dev->ml_priv;
7202	Cmd cmd;
7203	Resp rsp;
7204	int wake = 0;
7205	APListRid APList_rid_empty;
7206
7207	/* Note : you may have realised that, as this is a SET operation,
7208	 * this is privileged and therefore a normal user can't
7209	 * perform scanning.
7210	 * This is not an error, while the device perform scanning,
7211	 * traffic doesn't flow, so it's a perfect DoS...
7212	 * Jean II */
7213	if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
7214
7215	if (down_interruptible(&ai->sem))
7216		return -ERESTARTSYS;
7217
7218	/* If there's already a scan in progress, don't
7219	 * trigger another one. */
7220	if (ai->scan_timeout > 0)
7221		goto out;
7222
7223	/* Clear APList as it affects scan results */
7224	memset(&APList_rid_empty, 0, sizeof(APList_rid_empty));
7225	APList_rid_empty.len = cpu_to_le16(sizeof(APList_rid_empty));
7226	disable_MAC(ai, 2);
7227	writeAPListRid(ai, &APList_rid_empty, 0);
7228	enable_MAC(ai, 0);
7229
7230	/* Initiate a scan command */
7231	ai->scan_timeout = RUN_AT(3*HZ);
7232	memset(&cmd, 0, sizeof(cmd));
7233	cmd.cmd=CMD_LISTBSS;
7234	issuecommand(ai, &cmd, &rsp);
7235	wake = 1;
7236
7237out:
7238	up(&ai->sem);
7239	if (wake)
7240		wake_up_interruptible(&ai->thr_wait);
7241	return 0;
7242}
7243
7244/*------------------------------------------------------------------*/
7245/*
7246 * Translate scan data returned from the card to a card independent
7247 * format that the Wireless Tools will understand - Jean II
7248 */
7249static inline char *airo_translate_scan(struct net_device *dev,
7250					struct iw_request_info *info,
7251					char *current_ev,
7252					char *end_buf,
7253					BSSListRid *bss)
7254{
7255	struct airo_info *ai = dev->ml_priv;
7256	struct iw_event		iwe;		/* Temporary buffer */
7257	__le16			capabilities;
7258	char *			current_val;	/* For rates */
7259	int			i;
7260	char *		buf;
7261	u16 dBm;
7262
7263	/* First entry *MUST* be the AP MAC address */
7264	iwe.cmd = SIOCGIWAP;
7265	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7266	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7267	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7268					  &iwe, IW_EV_ADDR_LEN);
7269
7270	/* Other entries will be displayed in the order we give them */
7271
7272	/* Add the ESSID */
7273	iwe.u.data.length = bss->ssidLen;
7274	if(iwe.u.data.length > 32)
7275		iwe.u.data.length = 32;
7276	iwe.cmd = SIOCGIWESSID;
7277	iwe.u.data.flags = 1;
7278	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7279					  &iwe, bss->ssid);
7280
7281	/* Add mode */
7282	iwe.cmd = SIOCGIWMODE;
7283	capabilities = bss->cap;
7284	if(capabilities & (CAP_ESS | CAP_IBSS)) {
7285		if(capabilities & CAP_ESS)
7286			iwe.u.mode = IW_MODE_MASTER;
7287		else
7288			iwe.u.mode = IW_MODE_ADHOC;
7289		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7290						  &iwe, IW_EV_UINT_LEN);
7291	}
7292
7293	/* Add frequency */
7294	iwe.cmd = SIOCGIWFREQ;
7295	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7296	iwe.u.freq.m = 100000 *
7297	      ieee80211_channel_to_frequency(iwe.u.freq.m, NL80211_BAND_2GHZ);
7298	iwe.u.freq.e = 1;
7299	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7300					  &iwe, IW_EV_FREQ_LEN);
7301
7302	dBm = le16_to_cpu(bss->dBm);
7303
7304	/* Add quality statistics */
7305	iwe.cmd = IWEVQUAL;
7306	if (ai->rssi) {
7307		iwe.u.qual.level = 0x100 - dBm;
7308		iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
7309		iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
7310				| IW_QUAL_LEVEL_UPDATED
7311				| IW_QUAL_DBM;
7312	} else {
7313		iwe.u.qual.level = (dBm + 321) / 2;
7314		iwe.u.qual.qual = 0;
7315		iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
7316				| IW_QUAL_LEVEL_UPDATED
7317				| IW_QUAL_DBM;
7318	}
7319	iwe.u.qual.noise = ai->wstats.qual.noise;
7320	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7321					  &iwe, IW_EV_QUAL_LEN);
7322
7323	/* Add encryption capability */
7324	iwe.cmd = SIOCGIWENCODE;
7325	if(capabilities & CAP_PRIVACY)
7326		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
7327	else
7328		iwe.u.data.flags = IW_ENCODE_DISABLED;
7329	iwe.u.data.length = 0;
7330	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7331					  &iwe, bss->ssid);
7332
7333	/* Rate : stuffing multiple values in a single event require a bit
7334	 * more of magic - Jean II */
7335	current_val = current_ev + iwe_stream_lcp_len(info);
7336
7337	iwe.cmd = SIOCGIWRATE;
7338	/* Those two flags are ignored... */
7339	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
7340	/* Max 8 values */
7341	for(i = 0 ; i < 8 ; i++) {
7342		/* NULL terminated */
7343		if(bss->rates[i] == 0)
7344			break;
7345		/* Bit rate given in 500 kb/s units (+ 0x80) */
7346		iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7347		/* Add new value to event */
7348		current_val = iwe_stream_add_value(info, current_ev,
7349						   current_val, end_buf,
7350						   &iwe, IW_EV_PARAM_LEN);
7351	}
7352	/* Check if we added any event */
7353	if ((current_val - current_ev) > iwe_stream_lcp_len(info))
7354		current_ev = current_val;
7355
7356	/* Beacon interval */
7357	buf = kmalloc(30, GFP_KERNEL);
7358	if (buf) {
7359		iwe.cmd = IWEVCUSTOM;
7360		sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7361		iwe.u.data.length = strlen(buf);
7362		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7363						  &iwe, buf);
7364		kfree(buf);
7365	}
7366
7367	/* Put WPA/RSN Information Elements into the event stream */
7368	if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
7369		unsigned int num_null_ies = 0;
7370		u16 length = sizeof (bss->extra.iep);
7371		u8 *ie = (void *)&bss->extra.iep;
7372
7373		while ((length >= 2) && (num_null_ies < 2)) {
7374			if (2 + ie[1] > length) {
7375				/* Invalid element, don't continue parsing IE */
7376				break;
7377			}
7378
7379			switch (ie[0]) {
7380			case WLAN_EID_SSID:
7381				/* Two zero-length SSID elements
7382				 * mean we're done parsing elements */
7383				if (!ie[1])
7384					num_null_ies++;
7385				break;
7386
7387			case WLAN_EID_VENDOR_SPECIFIC:
7388				if (ie[1] >= 4 &&
7389				    ie[2] == 0x00 &&
7390				    ie[3] == 0x50 &&
7391				    ie[4] == 0xf2 &&
7392				    ie[5] == 0x01) {
7393					iwe.cmd = IWEVGENIE;
7394					/* 64 is an arbitrary cut-off */
7395					iwe.u.data.length = min(ie[1] + 2,
7396								64);
7397					current_ev = iwe_stream_add_point(
7398							info, current_ev,
7399							end_buf, &iwe, ie);
7400				}
7401				break;
7402
7403			case WLAN_EID_RSN:
7404				iwe.cmd = IWEVGENIE;
7405				/* 64 is an arbitrary cut-off */
7406				iwe.u.data.length = min(ie[1] + 2, 64);
7407				current_ev = iwe_stream_add_point(
7408					info, current_ev, end_buf,
7409					&iwe, ie);
7410				break;
7411
7412			default:
7413				break;
7414			}
7415
7416			length -= 2 + ie[1];
7417			ie += 2 + ie[1];
7418		}
7419	}
7420	return current_ev;
7421}
7422
7423/*------------------------------------------------------------------*/
7424/*
7425 * Wireless Handler : Read Scan Results
7426 */
7427static int airo_get_scan(struct net_device *dev,
7428			 struct iw_request_info *info,
7429			 struct iw_point *dwrq,
7430			 char *extra)
7431{
 
7432	struct airo_info *ai = dev->ml_priv;
7433	BSSListElement *net;
7434	int err = 0;
7435	char *current_ev = extra;
7436
7437	/* If a scan is in-progress, return -EAGAIN */
7438	if (ai->scan_timeout > 0)
7439		return -EAGAIN;
7440
7441	if (down_interruptible(&ai->sem))
7442		return -EAGAIN;
7443
7444	list_for_each_entry (net, &ai->network_list, list) {
7445		/* Translate to WE format this entry */
7446		current_ev = airo_translate_scan(dev, info, current_ev,
7447						 extra + dwrq->length,
7448						 &net->bss);
7449
7450		/* Check if there is space for one more entry */
7451		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7452			/* Ask user space to try again with a bigger buffer */
7453			err = -E2BIG;
7454			goto out;
7455		}
7456	}
7457
7458	/* Length of data */
7459	dwrq->length = (current_ev - extra);
7460	dwrq->flags = 0;	/* todo */
7461
7462out:
7463	up(&ai->sem);
7464	return err;
7465}
7466
7467/*------------------------------------------------------------------*/
7468/*
7469 * Commit handler : called after a bunch of SET operations
7470 */
7471static int airo_config_commit(struct net_device *dev,
7472			      struct iw_request_info *info,	/* NULL */
7473			      void *zwrq,			/* NULL */
7474			      char *extra)			/* NULL */
7475{
7476	struct airo_info *local = dev->ml_priv;
7477
7478	if (!test_bit (FLAG_COMMIT, &local->flags))
7479		return 0;
7480
7481	/* Some of the "SET" function may have modified some of the
7482	 * parameters. It's now time to commit them in the card */
7483	disable_MAC(local, 1);
7484	if (test_bit (FLAG_RESET, &local->flags)) {
7485		SsidRid SSID_rid;
7486
7487		readSsidRid(local, &SSID_rid);
7488		if (test_bit(FLAG_MPI,&local->flags))
7489			setup_card(local, dev->dev_addr, 1 );
7490		else
7491			reset_airo_card(dev);
7492		disable_MAC(local, 1);
7493		writeSsidRid(local, &SSID_rid, 1);
7494		writeAPListRid(local, &local->APList, 1);
7495	}
7496	if (down_interruptible(&local->sem))
7497		return -ERESTARTSYS;
7498	writeConfigRid(local, 0);
7499	enable_MAC(local, 0);
7500	if (test_bit (FLAG_RESET, &local->flags))
7501		airo_set_promisc(local);
7502	else
7503		up(&local->sem);
7504
7505	return 0;
7506}
7507
7508/*------------------------------------------------------------------*/
7509/*
7510 * Structures to export the Wireless Handlers
7511 */
7512
7513static const struct iw_priv_args airo_private_args[] = {
7514/*{ cmd,         set_args,                            get_args, name } */
7515  { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7516    IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7517  { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7518    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7519};
7520
7521static const iw_handler		airo_handler[] =
7522{
7523	(iw_handler) airo_config_commit,	/* SIOCSIWCOMMIT */
7524	(iw_handler) airo_get_name,		/* SIOCGIWNAME */
7525	(iw_handler) NULL,			/* SIOCSIWNWID */
7526	(iw_handler) NULL,			/* SIOCGIWNWID */
7527	(iw_handler) airo_set_freq,		/* SIOCSIWFREQ */
7528	(iw_handler) airo_get_freq,		/* SIOCGIWFREQ */
7529	(iw_handler) airo_set_mode,		/* SIOCSIWMODE */
7530	(iw_handler) airo_get_mode,		/* SIOCGIWMODE */
7531	(iw_handler) airo_set_sens,		/* SIOCSIWSENS */
7532	(iw_handler) airo_get_sens,		/* SIOCGIWSENS */
7533	(iw_handler) NULL,			/* SIOCSIWRANGE */
7534	(iw_handler) airo_get_range,		/* SIOCGIWRANGE */
7535	(iw_handler) NULL,			/* SIOCSIWPRIV */
7536	(iw_handler) NULL,			/* SIOCGIWPRIV */
7537	(iw_handler) NULL,			/* SIOCSIWSTATS */
7538	(iw_handler) NULL,			/* SIOCGIWSTATS */
7539	iw_handler_set_spy,			/* SIOCSIWSPY */
7540	iw_handler_get_spy,			/* SIOCGIWSPY */
7541	iw_handler_set_thrspy,			/* SIOCSIWTHRSPY */
7542	iw_handler_get_thrspy,			/* SIOCGIWTHRSPY */
7543	(iw_handler) airo_set_wap,		/* SIOCSIWAP */
7544	(iw_handler) airo_get_wap,		/* SIOCGIWAP */
7545	(iw_handler) NULL,			/* -- hole -- */
7546	(iw_handler) airo_get_aplist,		/* SIOCGIWAPLIST */
7547	(iw_handler) airo_set_scan,		/* SIOCSIWSCAN */
7548	(iw_handler) airo_get_scan,		/* SIOCGIWSCAN */
7549	(iw_handler) airo_set_essid,		/* SIOCSIWESSID */
7550	(iw_handler) airo_get_essid,		/* SIOCGIWESSID */
7551	(iw_handler) airo_set_nick,		/* SIOCSIWNICKN */
7552	(iw_handler) airo_get_nick,		/* SIOCGIWNICKN */
7553	(iw_handler) NULL,			/* -- hole -- */
7554	(iw_handler) NULL,			/* -- hole -- */
7555	(iw_handler) airo_set_rate,		/* SIOCSIWRATE */
7556	(iw_handler) airo_get_rate,		/* SIOCGIWRATE */
7557	(iw_handler) airo_set_rts,		/* SIOCSIWRTS */
7558	(iw_handler) airo_get_rts,		/* SIOCGIWRTS */
7559	(iw_handler) airo_set_frag,		/* SIOCSIWFRAG */
7560	(iw_handler) airo_get_frag,		/* SIOCGIWFRAG */
7561	(iw_handler) airo_set_txpow,		/* SIOCSIWTXPOW */
7562	(iw_handler) airo_get_txpow,		/* SIOCGIWTXPOW */
7563	(iw_handler) airo_set_retry,		/* SIOCSIWRETRY */
7564	(iw_handler) airo_get_retry,		/* SIOCGIWRETRY */
7565	(iw_handler) airo_set_encode,		/* SIOCSIWENCODE */
7566	(iw_handler) airo_get_encode,		/* SIOCGIWENCODE */
7567	(iw_handler) airo_set_power,		/* SIOCSIWPOWER */
7568	(iw_handler) airo_get_power,		/* SIOCGIWPOWER */
7569	(iw_handler) NULL,			/* -- hole -- */
7570	(iw_handler) NULL,			/* -- hole -- */
7571	(iw_handler) NULL,			/* SIOCSIWGENIE */
7572	(iw_handler) NULL,			/* SIOCGIWGENIE */
7573	(iw_handler) airo_set_auth,		/* SIOCSIWAUTH */
7574	(iw_handler) airo_get_auth,		/* SIOCGIWAUTH */
7575	(iw_handler) airo_set_encodeext,	/* SIOCSIWENCODEEXT */
7576	(iw_handler) airo_get_encodeext,	/* SIOCGIWENCODEEXT */
7577	(iw_handler) NULL,			/* SIOCSIWPMKSA */
7578};
7579
7580/* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7581 * We want to force the use of the ioctl code, because those can't be
7582 * won't work the iw_handler code (because they simultaneously read
7583 * and write data and iw_handler can't do that).
7584 * Note that it's perfectly legal to read/write on a single ioctl command,
7585 * you just can't use iwpriv and need to force it via the ioctl handler.
7586 * Jean II */
7587static const iw_handler		airo_private_handler[] =
7588{
7589	NULL,				/* SIOCIWFIRSTPRIV */
7590};
7591
7592static const struct iw_handler_def	airo_handler_def =
7593{
7594	.num_standard	= ARRAY_SIZE(airo_handler),
7595	.num_private	= ARRAY_SIZE(airo_private_handler),
7596	.num_private_args = ARRAY_SIZE(airo_private_args),
7597	.standard	= airo_handler,
7598	.private	= airo_private_handler,
7599	.private_args	= airo_private_args,
7600	.get_wireless_stats = airo_get_wireless_stats,
7601};
7602
7603/*
7604 * This defines the configuration part of the Wireless Extensions
7605 * Note : irq and spinlock protection will occur in the subroutines
7606 *
7607 * TODO :
7608 *	o Check input value more carefully and fill correct values in range
7609 *	o Test and shakeout the bugs (if any)
7610 *
7611 * Jean II
7612 *
7613 * Javier Achirica did a great job of merging code from the unnamed CISCO
7614 * developer that added support for flashing the card.
7615 */
7616static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
7617{
7618	int rc = 0;
7619	struct airo_info *ai = dev->ml_priv;
7620
7621	if (ai->power.event)
7622		return 0;
7623
7624	switch (cmd) {
7625#ifdef CISCO_EXT
7626	case AIROIDIFC:
7627#ifdef AIROOLDIDIFC
7628	case AIROOLDIDIFC:
7629#endif
7630	{
7631		int val = AIROMAGIC;
7632		aironet_ioctl com;
7633		if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
7634			rc = -EFAULT;
7635		else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
7636			rc = -EFAULT;
7637	}
7638	break;
7639
7640	case AIROIOCTL:
7641#ifdef AIROOLDIOCTL
7642	case AIROOLDIOCTL:
7643#endif
7644		/* Get the command struct and hand it off for evaluation by
7645		 * the proper subfunction
7646		 */
7647	{
7648		aironet_ioctl com;
7649		if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
7650			rc = -EFAULT;
7651			break;
7652		}
7653
7654		/* Separate R/W functions bracket legality here
7655		 */
7656		if ( com.command == AIRORSWVERSION ) {
7657			if (copy_to_user(com.data, swversion, sizeof(swversion)))
7658				rc = -EFAULT;
7659			else
7660				rc = 0;
7661		}
7662		else if ( com.command <= AIRORRID)
7663			rc = readrids(dev,&com);
7664		else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
7665			rc = writerids(dev,&com);
7666		else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
7667			rc = flashcard(dev,&com);
7668		else
7669			rc = -EINVAL;      /* Bad command in ioctl */
7670	}
7671	break;
7672#endif /* CISCO_EXT */
7673
7674	// All other calls are currently unsupported
7675	default:
7676		rc = -EOPNOTSUPP;
7677	}
7678	return rc;
7679}
7680
7681/*
7682 * Get the Wireless stats out of the driver
7683 * Note : irq and spinlock protection will occur in the subroutines
7684 *
7685 * TODO :
7686 *	o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7687 *
7688 * Jean
7689 */
7690static void airo_read_wireless_stats(struct airo_info *local)
7691{
7692	StatusRid status_rid;
7693	StatsRid stats_rid;
7694	CapabilityRid cap_rid;
7695	__le32 *vals = stats_rid.vals;
7696
7697	/* Get stats out of the card */
7698	clear_bit(JOB_WSTATS, &local->jobs);
7699	if (local->power.event) {
7700		up(&local->sem);
7701		return;
7702	}
7703	readCapabilityRid(local, &cap_rid, 0);
7704	readStatusRid(local, &status_rid, 0);
7705	readStatsRid(local, &stats_rid, RID_STATS, 0);
7706	up(&local->sem);
7707
7708	/* The status */
7709	local->wstats.status = le16_to_cpu(status_rid.mode);
7710
7711	/* Signal quality and co */
7712	if (local->rssi) {
7713		local->wstats.qual.level =
7714			airo_rssi_to_dbm(local->rssi,
7715					 le16_to_cpu(status_rid.sigQuality));
7716		/* normalizedSignalStrength appears to be a percentage */
7717		local->wstats.qual.qual =
7718			le16_to_cpu(status_rid.normalizedSignalStrength);
7719	} else {
7720		local->wstats.qual.level =
7721			(le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7722		local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7723	}
7724	if (le16_to_cpu(status_rid.len) >= 124) {
7725		local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7726		local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7727	} else {
7728		local->wstats.qual.noise = 0;
7729		local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
7730	}
7731
7732	/* Packets discarded in the wireless adapter due to wireless
7733	 * specific problems */
7734	local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7735				     le32_to_cpu(vals[57]) +
7736				     le32_to_cpu(vals[58]); /* SSID Mismatch */
7737	local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7738	local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7739	local->wstats.discard.retries = le32_to_cpu(vals[10]);
7740	local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7741				     le32_to_cpu(vals[32]);
7742	local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7743}
7744
7745static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7746{
7747	struct airo_info *local =  dev->ml_priv;
7748
7749	if (!test_bit(JOB_WSTATS, &local->jobs)) {
7750		/* Get stats out of the card if available */
7751		if (down_trylock(&local->sem) != 0) {
7752			set_bit(JOB_WSTATS, &local->jobs);
7753			wake_up_interruptible(&local->thr_wait);
7754		} else
7755			airo_read_wireless_stats(local);
7756	}
7757
7758	return &local->wstats;
7759}
7760
7761#ifdef CISCO_EXT
7762/*
7763 * This just translates from driver IOCTL codes to the command codes to
7764 * feed to the radio's host interface. Things can be added/deleted
7765 * as needed.  This represents the READ side of control I/O to
7766 * the card
7767 */
7768static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 
7769	unsigned short ridcode;
7770	unsigned char *iobuf;
7771	int len;
7772	struct airo_info *ai = dev->ml_priv;
7773
7774	if (test_bit(FLAG_FLASHING, &ai->flags))
7775		return -EIO;
7776
7777	switch(comp->command)
7778	{
7779	case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7780	case AIROGCFG:      ridcode = RID_CONFIG;
7781		if (test_bit(FLAG_COMMIT, &ai->flags)) {
7782			disable_MAC (ai, 1);
7783			writeConfigRid (ai, 1);
7784			enable_MAC(ai, 1);
7785		}
7786		break;
7787	case AIROGSLIST:    ridcode = RID_SSID;         break;
7788	case AIROGVLIST:    ridcode = RID_APLIST;       break;
7789	case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7790	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7791	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
7792		/* Only super-user can read WEP keys */
7793		if (!capable(CAP_NET_ADMIN))
7794			return -EPERM;
7795		break;
7796	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
7797		/* Only super-user can read WEP keys */
7798		if (!capable(CAP_NET_ADMIN))
7799			return -EPERM;
7800		break;
7801	case AIROGSTAT:     ridcode = RID_STATUS;       break;
7802	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7803	case AIROGSTATSC32: ridcode = RID_STATS;        break;
7804	case AIROGMICSTATS:
7805		if (copy_to_user(comp->data, &ai->micstats,
7806				 min((int)comp->len,(int)sizeof(ai->micstats))))
7807			return -EFAULT;
7808		return 0;
7809	case AIRORRID:      ridcode = comp->ridnum;     break;
7810	default:
7811		return -EINVAL;
7812	}
7813
7814	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
 
 
 
 
 
 
7815		return -ENOMEM;
7816
7817	PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
7818	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7819	 * then return it to the user
7820	 * 9/22/2000 Honor user given length
7821	 */
7822	len = comp->len;
7823
7824	if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7825		kfree (iobuf);
7826		return -EFAULT;
7827	}
7828	kfree (iobuf);
7829	return 0;
7830}
7831
7832/*
7833 * Danger Will Robinson write the rids here
7834 */
7835
7836static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 
7837	struct airo_info *ai = dev->ml_priv;
7838	int  ridcode;
7839        int  enabled;
7840	int (*writer)(struct airo_info *, u16 rid, const void *, int, int);
7841	unsigned char *iobuf;
7842
7843	/* Only super-user can write RIDs */
7844	if (!capable(CAP_NET_ADMIN))
7845		return -EPERM;
7846
7847	if (test_bit(FLAG_FLASHING, &ai->flags))
7848		return -EIO;
7849
7850	ridcode = 0;
7851	writer = do_writerid;
7852
7853	switch(comp->command)
7854	{
7855	case AIROPSIDS:     ridcode = RID_SSID;         break;
7856	case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7857	case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7858	case AIROPCFG: ai->config.len = 0;
7859			    clear_bit(FLAG_COMMIT, &ai->flags);
7860			    ridcode = RID_CONFIG;       break;
7861	case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7862	case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7863	case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7864	case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7865		break;
7866	case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7867	case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7868
7869		/* this is not really a rid but a command given to the card
7870		 * same with MAC off
7871		 */
7872	case AIROPMACON:
7873		if (enable_MAC(ai, 1) != 0)
7874			return -EIO;
7875		return 0;
7876
7877		/*
7878		 * Evidently this code in the airo driver does not get a symbol
7879		 * as disable_MAC. it's probably so short the compiler does not gen one.
7880		 */
7881	case AIROPMACOFF:
7882		disable_MAC(ai, 1);
7883		return 0;
7884
7885		/* This command merely clears the counts does not actually store any data
7886		 * only reads rid. But as it changes the cards state, I put it in the
7887		 * writerid routines.
7888		 */
7889	case AIROPSTCLR:
7890		if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7891			return -ENOMEM;
7892
7893		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
7894
7895		enabled = ai->micstats.enabled;
7896		memset(&ai->micstats,0,sizeof(ai->micstats));
7897		ai->micstats.enabled = enabled;
7898
7899		if (copy_to_user(comp->data, iobuf,
7900				 min((int)comp->len, (int)RIDSIZE))) {
7901			kfree (iobuf);
7902			return -EFAULT;
7903		}
7904		kfree (iobuf);
7905		return 0;
7906
7907	default:
7908		return -EOPNOTSUPP;	/* Blarg! */
7909	}
7910	if(comp->len > RIDSIZE)
7911		return -EINVAL;
7912
7913	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7914		return -ENOMEM;
7915
7916	if (copy_from_user(iobuf,comp->data,comp->len)) {
7917		kfree (iobuf);
7918		return -EFAULT;
7919	}
7920
7921	if (comp->command == AIROPCFG) {
7922		ConfigRid *cfg = (ConfigRid *)iobuf;
7923
7924		if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7925			cfg->opmode |= MODE_MIC;
7926
7927		if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
7928			set_bit (FLAG_ADHOC, &ai->flags);
7929		else
7930			clear_bit (FLAG_ADHOC, &ai->flags);
7931	}
7932
7933	if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
7934		kfree (iobuf);
7935		return -EIO;
7936	}
7937	kfree (iobuf);
7938	return 0;
7939}
7940
7941/*****************************************************************************
7942 * Ancillary flash / mod functions much black magic lurkes here              *
7943 *****************************************************************************
7944 */
7945
7946/*
7947 * Flash command switch table
7948 */
7949
7950static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
 
7951	int z;
7952
7953	/* Only super-user can modify flash */
7954	if (!capable(CAP_NET_ADMIN))
7955		return -EPERM;
7956
7957	switch(comp->command)
7958	{
7959	case AIROFLSHRST:
7960		return cmdreset((struct airo_info *)dev->ml_priv);
7961
7962	case AIROFLSHSTFL:
7963		if (!AIRO_FLASH(dev) &&
7964		    (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
7965			return -ENOMEM;
7966		return setflashmode((struct airo_info *)dev->ml_priv);
7967
7968	case AIROFLSHGCHR: /* Get char from aux */
7969		if(comp->len != sizeof(int))
7970			return -EINVAL;
7971		if (copy_from_user(&z,comp->data,comp->len))
7972			return -EFAULT;
7973		return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
7974
7975	case AIROFLSHPCHR: /* Send char to card. */
7976		if(comp->len != sizeof(int))
7977			return -EINVAL;
7978		if (copy_from_user(&z,comp->data,comp->len))
7979			return -EFAULT;
7980		return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
7981
7982	case AIROFLPUTBUF: /* Send 32k to card */
7983		if (!AIRO_FLASH(dev))
7984			return -ENOMEM;
7985		if(comp->len > FLASHSIZE)
7986			return -EINVAL;
7987		if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
7988			return -EFAULT;
7989
7990		flashputbuf((struct airo_info *)dev->ml_priv);
7991		return 0;
7992
7993	case AIRORESTART:
7994		if (flashrestart((struct airo_info *)dev->ml_priv, dev))
7995			return -EIO;
7996		return 0;
7997	}
7998	return -EINVAL;
7999}
8000
8001#define FLASH_COMMAND  0x7e7e
8002
8003/*
8004 * STEP 1)
8005 * Disable MAC and do soft reset on
8006 * card.
8007 */
8008
8009static int cmdreset(struct airo_info *ai) {
 
8010	disable_MAC(ai, 1);
8011
8012	if(!waitbusy (ai)){
8013		airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
8014		return -EBUSY;
8015	}
8016
8017	OUT4500(ai,COMMAND,CMD_SOFTRESET);
8018
8019	ssleep(1);			/* WAS 600 12/7/00 */
8020
8021	if(!waitbusy (ai)){
8022		airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
8023		return -EBUSY;
8024	}
8025	return 0;
8026}
8027
8028/* STEP 2)
8029 * Put the card in legendary flash
8030 * mode
8031 */
8032
8033static int setflashmode (struct airo_info *ai) {
 
8034	set_bit (FLAG_FLASHING, &ai->flags);
8035
8036	OUT4500(ai, SWS0, FLASH_COMMAND);
8037	OUT4500(ai, SWS1, FLASH_COMMAND);
8038	if (probe) {
8039		OUT4500(ai, SWS0, FLASH_COMMAND);
8040		OUT4500(ai, COMMAND,0x10);
8041	} else {
8042		OUT4500(ai, SWS2, FLASH_COMMAND);
8043		OUT4500(ai, SWS3, FLASH_COMMAND);
8044		OUT4500(ai, COMMAND,0);
8045	}
8046	msleep(500);		/* 500ms delay */
8047
8048	if(!waitbusy(ai)) {
8049		clear_bit (FLAG_FLASHING, &ai->flags);
8050		airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
8051		return -EIO;
8052	}
8053	return 0;
8054}
8055
8056/* Put character to SWS0 wait for dwelltime
8057 * x 50us for  echo .
8058 */
8059
8060static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
 
8061	int echo;
8062	int waittime;
8063
8064	byte |= 0x8000;
8065
8066	if(dwelltime == 0 )
8067		dwelltime = 200;
8068
8069	waittime=dwelltime;
8070
8071	/* Wait for busy bit d15 to go false indicating buffer empty */
8072	while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
8073		udelay (50);
8074		waittime -= 50;
8075	}
8076
8077	/* timeout for busy clear wait */
8078	if(waittime <= 0 ){
8079		airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
8080		return -EBUSY;
8081	}
8082
8083	/* Port is clear now write byte and wait for it to echo back */
8084	do {
8085		OUT4500(ai,SWS0,byte);
8086		udelay(50);
8087		dwelltime -= 50;
8088		echo = IN4500(ai,SWS1);
8089	} while (dwelltime >= 0 && echo != byte);
8090
8091	OUT4500(ai,SWS1,0);
8092
8093	return (echo == byte) ? 0 : -EIO;
8094}
8095
8096/*
8097 * Get a character from the card matching matchbyte
8098 * Step 3)
8099 */
8100static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
 
8101	int           rchar;
8102	unsigned char rbyte=0;
8103
8104	do {
8105		rchar = IN4500(ai,SWS1);
8106
8107		if(dwelltime && !(0x8000 & rchar)){
8108			dwelltime -= 10;
8109			mdelay(10);
8110			continue;
8111		}
8112		rbyte = 0xff & rchar;
8113
8114		if( (rbyte == matchbyte) && (0x8000 & rchar) ){
8115			OUT4500(ai,SWS1,0);
8116			return 0;
8117		}
8118		if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
8119			break;
8120		OUT4500(ai,SWS1,0);
8121
8122	}while(dwelltime > 0);
8123	return -EIO;
8124}
8125
8126/*
8127 * Transfer 32k of firmware data from user buffer to our buffer and
8128 * send to the card
8129 */
8130
8131static int flashputbuf(struct airo_info *ai){
 
8132	int            nwords;
8133
8134	/* Write stuff */
8135	if (test_bit(FLAG_MPI,&ai->flags))
8136		memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
8137	else {
8138		OUT4500(ai,AUXPAGE,0x100);
8139		OUT4500(ai,AUXOFF,0);
8140
8141		for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
8142			OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
8143		}
8144	}
8145	OUT4500(ai,SWS0,0x8000);
8146
8147	return 0;
8148}
8149
8150/*
8151 *
8152 */
8153static int flashrestart(struct airo_info *ai,struct net_device *dev){
8154	int    i,status;
 
8155
8156	ssleep(1);			/* Added 12/7/00 */
8157	clear_bit (FLAG_FLASHING, &ai->flags);
8158	if (test_bit(FLAG_MPI, &ai->flags)) {
8159		status = mpi_init_descriptors(ai);
8160		if (status != SUCCESS)
8161			return status;
8162	}
8163	status = setup_card(ai, dev->dev_addr, 1);
8164
8165	if (!test_bit(FLAG_MPI,&ai->flags))
8166		for( i = 0; i < MAX_FIDS; i++ ) {
8167			ai->fids[i] = transmit_allocate
8168				( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
8169		}
8170
8171	ssleep(1);			/* Added 12/7/00 */
8172	return status;
8173}
8174#endif /* CISCO_EXT */
8175
8176/*
8177    This program is free software; you can redistribute it and/or
8178    modify it under the terms of the GNU General Public License
8179    as published by the Free Software Foundation; either version 2
8180    of the License, or (at your option) any later version.
8181
8182    This program is distributed in the hope that it will be useful,
8183    but WITHOUT ANY WARRANTY; without even the implied warranty of
8184    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8185    GNU General Public License for more details.
8186
8187    In addition:
8188
8189    Redistribution and use in source and binary forms, with or without
8190    modification, are permitted provided that the following conditions
8191    are met:
8192
8193    1. Redistributions of source code must retain the above copyright
8194       notice, this list of conditions and the following disclaimer.
8195    2. Redistributions in binary form must reproduce the above copyright
8196       notice, this list of conditions and the following disclaimer in the
8197       documentation and/or other materials provided with the distribution.
8198    3. The name of the author may not be used to endorse or promote
8199       products derived from this software without specific prior written
8200       permission.
8201
8202    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8203    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8204    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8205    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
8206    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8207    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8208    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8209    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8210    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
8211    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8212    POSSIBILITY OF SUCH DAMAGE.
8213*/
8214
8215module_init(airo_init_module);
8216module_exit(airo_cleanup_module);
v6.2
   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_param_hw_array(io, int, ioport, NULL, 0);
 255module_param_hw_array(irq, int, irq, NULL, 0);
 256module_param_array(rates, int, NULL, 0);
 257module_param_array(ssids, charp, NULL, 0);
 258module_param(auto_wep, int, 0);
 259MODULE_PARM_DESC(auto_wep,
 260		 "If non-zero, the driver will keep looping through the authentication options until an association is made.  "
 261		 "The value of auto_wep is number of the wep keys to check.  "
 262		 "A value of 2 will try using the key at index 0 and index 1.");
 263module_param(aux_bap, int, 0);
 264MODULE_PARM_DESC(aux_bap,
 265		 "If non-zero, the driver will switch into a mode that seems to work better for older cards with some older buses.  "
 266		 "Before switching it checks that the switch is needed.");
 267module_param(maxencrypt, int, 0);
 268MODULE_PARM_DESC(maxencrypt,
 269		 "The maximum speed that the card can do encryption.  "
 270		 "Units are in 512kbs.  "
 271		 "Zero (default) means there is no limit.  "
 272		 "Older cards used to be limited to 2mbs (4).");
 273module_param(adhoc, int, 0);
 274MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
 275module_param(probe, int, 0);
 276MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
 277
 278module_param(proc_uid, int, 0);
 279MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
 280module_param(proc_gid, int, 0);
 281MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
 282module_param(airo_perm, int, 0);
 283MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
 284module_param(proc_perm, int, 0);
 285MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
 286
 287/* This is a kind of sloppy hack to get this information to OUT4500 and
 288   IN4500.  I would be extremely interested in the situation where this
 289   doesn't work though!!! */
 290static int do8bitIO /* = 0 */;
 291
 292/* Return codes */
 293#define SUCCESS 0
 294#define ERROR -1
 295#define NO_PACKET -2
 296
 297/* Commands */
 298#define NOP2		0x0000
 299#define MAC_ENABLE	0x0001
 300#define MAC_DISABLE	0x0002
 301#define CMD_LOSE_SYNC	0x0003 /* Not sure what this does... */
 302#define CMD_SOFTRESET	0x0004
 303#define HOSTSLEEP	0x0005
 304#define CMD_MAGIC_PKT	0x0006
 305#define CMD_SETWAKEMASK	0x0007
 306#define CMD_READCFG	0x0008
 307#define CMD_SETMODE	0x0009
 308#define CMD_ALLOCATETX	0x000a
 309#define CMD_TRANSMIT	0x000b
 310#define CMD_DEALLOCATETX 0x000c
 311#define NOP		0x0010
 312#define CMD_WORKAROUND	0x0011
 313#define CMD_ALLOCATEAUX 0x0020
 314#define CMD_ACCESS	0x0021
 315#define CMD_PCIBAP	0x0022
 316#define CMD_PCIAUX	0x0023
 317#define CMD_ALLOCBUF	0x0028
 318#define CMD_GETTLV	0x0029
 319#define CMD_PUTTLV	0x002a
 320#define CMD_DELTLV	0x002b
 321#define CMD_FINDNEXTTLV	0x002c
 322#define CMD_PSPNODES	0x0030
 323#define CMD_SETCW	0x0031
 324#define CMD_SETPCF	0x0032
 325#define CMD_SETPHYREG	0x003e
 326#define CMD_TXTEST	0x003f
 327#define MAC_ENABLETX	0x0101
 328#define CMD_LISTBSS	0x0103
 329#define CMD_SAVECFG	0x0108
 330#define CMD_ENABLEAUX	0x0111
 331#define CMD_WRITERID	0x0121
 332#define CMD_USEPSPNODES	0x0130
 333#define MAC_ENABLERX	0x0201
 334
 335/* Command errors */
 336#define ERROR_QUALIF 0x00
 337#define ERROR_ILLCMD 0x01
 338#define ERROR_ILLFMT 0x02
 339#define ERROR_INVFID 0x03
 340#define ERROR_INVRID 0x04
 341#define ERROR_LARGE 0x05
 342#define ERROR_NDISABL 0x06
 343#define ERROR_ALLOCBSY 0x07
 344#define ERROR_NORD 0x0B
 345#define ERROR_NOWR 0x0C
 346#define ERROR_INVFIDTX 0x0D
 347#define ERROR_TESTACT 0x0E
 348#define ERROR_TAGNFND 0x12
 349#define ERROR_DECODE 0x20
 350#define ERROR_DESCUNAV 0x21
 351#define ERROR_BADLEN 0x22
 352#define ERROR_MODE 0x80
 353#define ERROR_HOP 0x81
 354#define ERROR_BINTER 0x82
 355#define ERROR_RXMODE 0x83
 356#define ERROR_MACADDR 0x84
 357#define ERROR_RATES 0x85
 358#define ERROR_ORDER 0x86
 359#define ERROR_SCAN 0x87
 360#define ERROR_AUTH 0x88
 361#define ERROR_PSMODE 0x89
 362#define ERROR_RTYPE 0x8A
 363#define ERROR_DIVER 0x8B
 364#define ERROR_SSID 0x8C
 365#define ERROR_APLIST 0x8D
 366#define ERROR_AUTOWAKE 0x8E
 367#define ERROR_LEAP 0x8F
 368
 369/* Registers */
 370#define COMMAND 0x00
 371#define PARAM0 0x02
 372#define PARAM1 0x04
 373#define PARAM2 0x06
 374#define STATUS 0x08
 375#define RESP0 0x0a
 376#define RESP1 0x0c
 377#define RESP2 0x0e
 378#define LINKSTAT 0x10
 379#define SELECT0 0x18
 380#define OFFSET0 0x1c
 381#define RXFID 0x20
 382#define TXALLOCFID 0x22
 383#define TXCOMPLFID 0x24
 384#define DATA0 0x36
 385#define EVSTAT 0x30
 386#define EVINTEN 0x32
 387#define EVACK 0x34
 388#define SWS0 0x28
 389#define SWS1 0x2a
 390#define SWS2 0x2c
 391#define SWS3 0x2e
 392#define AUXPAGE 0x3A
 393#define AUXOFF 0x3C
 394#define AUXDATA 0x3E
 395
 396#define FID_TX 1
 397#define FID_RX 2
 398/* Offset into aux memory for descriptors */
 399#define AUX_OFFSET 0x800
 400/* Size of allocated packets */
 401#define PKTSIZE 1840
 402#define RIDSIZE 2048
 403/* Size of the transmit queue */
 404#define MAXTXQ 64
 405
 406/* BAP selectors */
 407#define BAP0 0 /* Used for receiving packets */
 408#define BAP1 2 /* Used for xmiting packets and working with RIDS */
 409
 410/* Flags */
 411#define COMMAND_BUSY 0x8000
 412
 413#define BAP_BUSY 0x8000
 414#define BAP_ERR 0x4000
 415#define BAP_DONE 0x2000
 416
 417#define PROMISC 0xffff
 418#define NOPROMISC 0x0000
 419
 420#define EV_CMD 0x10
 421#define EV_CLEARCOMMANDBUSY 0x4000
 422#define EV_RX 0x01
 423#define EV_TX 0x02
 424#define EV_TXEXC 0x04
 425#define EV_ALLOC 0x08
 426#define EV_LINK 0x80
 427#define EV_AWAKE 0x100
 428#define EV_TXCPY 0x400
 429#define EV_UNKNOWN 0x800
 430#define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
 431#define EV_AWAKEN 0x2000
 432#define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
 433
 434#ifdef CHECK_UNKNOWN_INTS
 435#define IGNORE_INTS (EV_CMD | EV_UNKNOWN)
 436#else
 437#define IGNORE_INTS (~STATUS_INTS)
 438#endif
 439
 440/* RID TYPES */
 441#define RID_RW 0x20
 442
 443/* The RIDs */
 444#define RID_CAPABILITIES 0xFF00
 445#define RID_APINFO     0xFF01
 446#define RID_RADIOINFO  0xFF02
 447#define RID_UNKNOWN3   0xFF03
 448#define RID_RSSI       0xFF04
 449#define RID_CONFIG     0xFF10
 450#define RID_SSID       0xFF11
 451#define RID_APLIST     0xFF12
 452#define RID_DRVNAME    0xFF13
 453#define RID_ETHERENCAP 0xFF14
 454#define RID_WEP_TEMP   0xFF15
 455#define RID_WEP_PERM   0xFF16
 456#define RID_MODULATION 0xFF17
 457#define RID_OPTIONS    0xFF18
 458#define RID_ACTUALCONFIG 0xFF20 /*readonly*/
 459#define RID_FACTORYCONFIG 0xFF21
 460#define RID_UNKNOWN22  0xFF22
 461#define RID_LEAPUSERNAME 0xFF23
 462#define RID_LEAPPASSWORD 0xFF24
 463#define RID_STATUS     0xFF50
 464#define RID_BEACON_HST 0xFF51
 465#define RID_BUSY_HST   0xFF52
 466#define RID_RETRIES_HST 0xFF53
 467#define RID_UNKNOWN54  0xFF54
 468#define RID_UNKNOWN55  0xFF55
 469#define RID_UNKNOWN56  0xFF56
 470#define RID_MIC        0xFF57
 471#define RID_STATS16    0xFF60
 472#define RID_STATS16DELTA 0xFF61
 473#define RID_STATS16DELTACLEAR 0xFF62
 474#define RID_STATS      0xFF68
 475#define RID_STATSDELTA 0xFF69
 476#define RID_STATSDELTACLEAR 0xFF6A
 477#define RID_ECHOTEST_RID 0xFF70
 478#define RID_ECHOTEST_RESULTS 0xFF71
 479#define RID_BSSLISTFIRST 0xFF72
 480#define RID_BSSLISTNEXT  0xFF73
 481#define RID_WPA_BSSLISTFIRST 0xFF74
 482#define RID_WPA_BSSLISTNEXT  0xFF75
 483
 484typedef struct {
 485	u16 cmd;
 486	u16 parm0;
 487	u16 parm1;
 488	u16 parm2;
 489} Cmd;
 490
 491typedef struct {
 492	u16 status;
 493	u16 rsp0;
 494	u16 rsp1;
 495	u16 rsp2;
 496} Resp;
 497
 498/*
 499 * Rids and endian-ness:  The Rids will always be in cpu endian, since
 500 * this all the patches from the big-endian guys end up doing that.
 501 * so all rid access should use the read/writeXXXRid routines.
 502 */
 503
 504/* This structure came from an email sent to me from an engineer at
 505   aironet for inclusion into this driver */
 506typedef struct WepKeyRid WepKeyRid;
 507struct WepKeyRid {
 508	__le16 len;
 509	__le16 kindex;
 510	u8 mac[ETH_ALEN];
 511	__le16 klen;
 512	u8 key[16];
 513} __packed;
 514
 515/* These structures are from the Aironet's PC4500 Developers Manual */
 516typedef struct Ssid Ssid;
 517struct Ssid {
 518	__le16 len;
 519	u8 ssid[32];
 520} __packed;
 521
 522typedef struct SsidRid SsidRid;
 523struct SsidRid {
 524	__le16 len;
 525	Ssid ssids[3];
 526} __packed;
 527
 528typedef struct ModulationRid ModulationRid;
 529struct ModulationRid {
 530        __le16 len;
 531        __le16 modulation;
 532#define MOD_DEFAULT cpu_to_le16(0)
 533#define MOD_CCK cpu_to_le16(1)
 534#define MOD_MOK cpu_to_le16(2)
 535} __packed;
 536
 537typedef struct ConfigRid ConfigRid;
 538struct ConfigRid {
 539	__le16 len; /* sizeof(ConfigRid) */
 540	__le16 opmode; /* operating mode */
 541#define MODE_STA_IBSS cpu_to_le16(0)
 542#define MODE_STA_ESS cpu_to_le16(1)
 543#define MODE_AP cpu_to_le16(2)
 544#define MODE_AP_RPTR cpu_to_le16(3)
 545#define MODE_CFG_MASK cpu_to_le16(0xff)
 546#define MODE_ETHERNET_HOST cpu_to_le16(0<<8) /* rx payloads converted */
 547#define MODE_LLC_HOST cpu_to_le16(1<<8) /* rx payloads left as is */
 548#define MODE_AIRONET_EXTEND cpu_to_le16(1<<9) /* enable Aironet extensions */
 549#define MODE_AP_INTERFACE cpu_to_le16(1<<10) /* enable ap interface extensions */
 550#define MODE_ANTENNA_ALIGN cpu_to_le16(1<<11) /* enable antenna alignment */
 551#define MODE_ETHER_LLC cpu_to_le16(1<<12) /* enable ethernet LLC */
 552#define MODE_LEAF_NODE cpu_to_le16(1<<13) /* enable leaf node bridge */
 553#define MODE_CF_POLLABLE cpu_to_le16(1<<14) /* enable CF pollable */
 554#define MODE_MIC cpu_to_le16(1<<15) /* enable MIC */
 555	__le16 rmode; /* receive mode */
 556#define RXMODE_BC_MC_ADDR cpu_to_le16(0)
 557#define RXMODE_BC_ADDR cpu_to_le16(1) /* ignore multicasts */
 558#define RXMODE_ADDR cpu_to_le16(2) /* ignore multicast and broadcast */
 559#define RXMODE_RFMON cpu_to_le16(3) /* wireless monitor mode */
 560#define RXMODE_RFMON_ANYBSS cpu_to_le16(4)
 561#define RXMODE_LANMON cpu_to_le16(5) /* lan style monitor -- data packets only */
 562#define RXMODE_MASK cpu_to_le16(255)
 563#define RXMODE_DISABLE_802_3_HEADER cpu_to_le16(1<<8) /* disables 802.3 header on rx */
 564#define RXMODE_FULL_MASK (RXMODE_MASK | RXMODE_DISABLE_802_3_HEADER)
 565#define RXMODE_NORMALIZED_RSSI cpu_to_le16(1<<9) /* return normalized RSSI */
 566	__le16 fragThresh;
 567	__le16 rtsThres;
 568	u8 macAddr[ETH_ALEN];
 569	u8 rates[8];
 570	__le16 shortRetryLimit;
 571	__le16 longRetryLimit;
 572	__le16 txLifetime; /* in kusec */
 573	__le16 rxLifetime; /* in kusec */
 574	__le16 stationary;
 575	__le16 ordering;
 576	__le16 u16deviceType; /* for overriding device type */
 577	__le16 cfpRate;
 578	__le16 cfpDuration;
 579	__le16 _reserved1[3];
 580	/*---------- Scanning/Associating ----------*/
 581	__le16 scanMode;
 582#define SCANMODE_ACTIVE cpu_to_le16(0)
 583#define SCANMODE_PASSIVE cpu_to_le16(1)
 584#define SCANMODE_AIROSCAN cpu_to_le16(2)
 585	__le16 probeDelay; /* in kusec */
 586	__le16 probeEnergyTimeout; /* in kusec */
 587        __le16 probeResponseTimeout;
 588	__le16 beaconListenTimeout;
 589	__le16 joinNetTimeout;
 590	__le16 authTimeout;
 591	__le16 authType;
 592#define AUTH_OPEN cpu_to_le16(0x1)
 593#define AUTH_ENCRYPT cpu_to_le16(0x101)
 594#define AUTH_SHAREDKEY cpu_to_le16(0x102)
 595#define AUTH_ALLOW_UNENCRYPTED cpu_to_le16(0x200)
 596	__le16 associationTimeout;
 597	__le16 specifiedApTimeout;
 598	__le16 offlineScanInterval;
 599	__le16 offlineScanDuration;
 600	__le16 linkLossDelay;
 601	__le16 maxBeaconLostTime;
 602	__le16 refreshInterval;
 603#define DISABLE_REFRESH cpu_to_le16(0xFFFF)
 604	__le16 _reserved1a[1];
 605	/*---------- Power save operation ----------*/
 606	__le16 powerSaveMode;
 607#define POWERSAVE_CAM cpu_to_le16(0)
 608#define POWERSAVE_PSP cpu_to_le16(1)
 609#define POWERSAVE_PSPCAM cpu_to_le16(2)
 610	__le16 sleepForDtims;
 611	__le16 listenInterval;
 612	__le16 fastListenInterval;
 613	__le16 listenDecay;
 614	__le16 fastListenDelay;
 615	__le16 _reserved2[2];
 616	/*---------- Ap/Ibss config items ----------*/
 617	__le16 beaconPeriod;
 618	__le16 atimDuration;
 619	__le16 hopPeriod;
 620	__le16 channelSet;
 621	__le16 channel;
 622	__le16 dtimPeriod;
 623	__le16 bridgeDistance;
 624	__le16 radioID;
 625	/*---------- Radio configuration ----------*/
 626	__le16 radioType;
 627#define RADIOTYPE_DEFAULT cpu_to_le16(0)
 628#define RADIOTYPE_802_11 cpu_to_le16(1)
 629#define RADIOTYPE_LEGACY cpu_to_le16(2)
 630	u8 rxDiversity;
 631	u8 txDiversity;
 632	__le16 txPower;
 633#define TXPOWER_DEFAULT 0
 634	__le16 rssiThreshold;
 635#define RSSI_DEFAULT 0
 636        __le16 modulation;
 637#define PREAMBLE_AUTO cpu_to_le16(0)
 638#define PREAMBLE_LONG cpu_to_le16(1)
 639#define PREAMBLE_SHORT cpu_to_le16(2)
 640	__le16 preamble;
 641	__le16 homeProduct;
 642	__le16 radioSpecific;
 643	/*---------- Aironet Extensions ----------*/
 644	u8 nodeName[16];
 645	__le16 arlThreshold;
 646	__le16 arlDecay;
 647	__le16 arlDelay;
 648	__le16 _reserved4[1];
 649	/*---------- Aironet Extensions ----------*/
 650	u8 magicAction;
 651#define MAGIC_ACTION_STSCHG 1
 652#define MAGIC_ACTION_RESUME 2
 653#define MAGIC_IGNORE_MCAST (1<<8)
 654#define MAGIC_IGNORE_BCAST (1<<9)
 655#define MAGIC_SWITCH_TO_PSP (0<<10)
 656#define MAGIC_STAY_IN_CAM (1<<10)
 657	u8 magicControl;
 658	__le16 autoWake;
 659} __packed;
 660
 661typedef struct StatusRid StatusRid;
 662struct StatusRid {
 663	__le16 len;
 664	u8 mac[ETH_ALEN];
 665	__le16 mode;
 666	__le16 errorCode;
 667	__le16 sigQuality;
 668	__le16 SSIDlen;
 669	char SSID[32];
 670	char apName[16];
 671	u8 bssid[4][ETH_ALEN];
 672	__le16 beaconPeriod;
 673	__le16 dimPeriod;
 674	__le16 atimDuration;
 675	__le16 hopPeriod;
 676	__le16 channelSet;
 677	__le16 channel;
 678	__le16 hopsToBackbone;
 679	__le16 apTotalLoad;
 680	__le16 generatedLoad;
 681	__le16 accumulatedArl;
 682	__le16 signalQuality;
 683	__le16 currentXmitRate;
 684	__le16 apDevExtensions;
 685	__le16 normalizedSignalStrength;
 686	__le16 shortPreamble;
 687	u8 apIP[4];
 688	u8 noisePercent; /* Noise percent in last second */
 689	u8 noisedBm; /* Noise dBm in last second */
 690	u8 noiseAvePercent; /* Noise percent in last minute */
 691	u8 noiseAvedBm; /* Noise dBm in last minute */
 692	u8 noiseMaxPercent; /* Highest noise percent in last minute */
 693	u8 noiseMaxdBm; /* Highest noise dbm in last minute */
 694	__le16 load;
 695	u8 carrier[4];
 696	__le16 assocStatus;
 697#define STAT_NOPACKETS 0
 698#define STAT_NOCARRIERSET 10
 699#define STAT_GOTCARRIERSET 11
 700#define STAT_WRONGSSID 20
 701#define STAT_BADCHANNEL 25
 702#define STAT_BADBITRATES 30
 703#define STAT_BADPRIVACY 35
 704#define STAT_APFOUND 40
 705#define STAT_APREJECTED 50
 706#define STAT_AUTHENTICATING 60
 707#define STAT_DEAUTHENTICATED 61
 708#define STAT_AUTHTIMEOUT 62
 709#define STAT_ASSOCIATING 70
 710#define STAT_DEASSOCIATED 71
 711#define STAT_ASSOCTIMEOUT 72
 712#define STAT_NOTAIROAP 73
 713#define STAT_ASSOCIATED 80
 714#define STAT_LEAPING 90
 715#define STAT_LEAPFAILED 91
 716#define STAT_LEAPTIMEDOUT 92
 717#define STAT_LEAPCOMPLETE 93
 718} __packed;
 719
 720typedef struct StatsRid StatsRid;
 721struct StatsRid {
 722	__le16 len;
 723	__le16 spacer;
 724	__le32 vals[100];
 725} __packed;
 726
 727typedef struct APListRid APListRid;
 728struct APListRid {
 729	__le16 len;
 730	u8 ap[4][ETH_ALEN];
 731} __packed;
 732
 733typedef struct CapabilityRid CapabilityRid;
 734struct CapabilityRid {
 735	__le16 len;
 736	char oui[3];
 737	char zero;
 738	__le16 prodNum;
 739	char manName[32];
 740	char prodName[16];
 741	char prodVer[8];
 742	char factoryAddr[ETH_ALEN];
 743	char aironetAddr[ETH_ALEN];
 744	__le16 radioType;
 745	__le16 country;
 746	char callid[ETH_ALEN];
 747	char supportedRates[8];
 748	char rxDiversity;
 749	char txDiversity;
 750	__le16 txPowerLevels[8];
 751	__le16 hardVer;
 752	__le16 hardCap;
 753	__le16 tempRange;
 754	__le16 softVer;
 755	__le16 softSubVer;
 756	__le16 interfaceVer;
 757	__le16 softCap;
 758	__le16 bootBlockVer;
 759	__le16 requiredHard;
 760	__le16 extSoftCap;
 761} __packed;
 762
 763/* Only present on firmware >= 5.30.17 */
 764typedef struct BSSListRidExtra BSSListRidExtra;
 765struct BSSListRidExtra {
 766  __le16 unknown[4];
 767  u8 fixed[12]; /* WLAN management frame */
 768  u8 iep[624];
 769} __packed;
 770
 771typedef struct BSSListRid BSSListRid;
 772struct BSSListRid {
 773  __le16 len;
 774  __le16 index; /* First is 0 and 0xffff means end of list */
 775#define RADIO_FH 1 /* Frequency hopping radio type */
 776#define RADIO_DS 2 /* Direct sequence radio type */
 777#define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
 778  __le16 radioType;
 779  u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
 780  u8 zero;
 781  u8 ssidLen;
 782  u8 ssid[32];
 783  __le16 dBm;
 784#define CAP_ESS cpu_to_le16(1<<0)
 785#define CAP_IBSS cpu_to_le16(1<<1)
 786#define CAP_PRIVACY cpu_to_le16(1<<4)
 787#define CAP_SHORTHDR cpu_to_le16(1<<5)
 788  __le16 cap;
 789  __le16 beaconInterval;
 790  u8 rates[8]; /* Same as rates for config rid */
 791  struct { /* For frequency hopping only */
 792    __le16 dwell;
 793    u8 hopSet;
 794    u8 hopPattern;
 795    u8 hopIndex;
 796    u8 fill;
 797  } fh;
 798  __le16 dsChannel;
 799  __le16 atimWindow;
 800
 801  /* Only present on firmware >= 5.30.17 */
 802  BSSListRidExtra extra;
 803} __packed;
 804
 805typedef struct {
 806  BSSListRid bss;
 807  struct list_head list;
 808} BSSListElement;
 809
 810typedef struct tdsRssiEntry tdsRssiEntry;
 811struct tdsRssiEntry {
 812  u8 rssipct;
 813  u8 rssidBm;
 814} __packed;
 815
 816typedef struct tdsRssiRid tdsRssiRid;
 817struct tdsRssiRid {
 818  u16 len;
 819  tdsRssiEntry x[256];
 820} __packed;
 821
 822typedef struct MICRid MICRid;
 823struct MICRid {
 824	__le16 len;
 825	__le16 state;
 826	__le16 multicastValid;
 827	u8  multicast[16];
 828	__le16 unicastValid;
 829	u8  unicast[16];
 830} __packed;
 831
 832typedef struct MICBuffer MICBuffer;
 833struct MICBuffer {
 834	__be16 typelen;
 835
 836	union {
 837	    u8 snap[8];
 838	    struct {
 839		u8 dsap;
 840		u8 ssap;
 841		u8 control;
 842		u8 orgcode[3];
 843		u8 fieldtype[2];
 844	    } llc;
 845	} u;
 846	__be32 mic;
 847	__be32 seq;
 848} __packed;
 849
 850typedef struct {
 851	u8 da[ETH_ALEN];
 852	u8 sa[ETH_ALEN];
 853} etherHead;
 854
 855#define TXCTL_TXOK (1<<1) /* report if tx is ok */
 856#define TXCTL_TXEX (1<<2) /* report if tx fails */
 857#define TXCTL_802_3 (0<<3) /* 802.3 packet */
 858#define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
 859#define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
 860#define TXCTL_LLC (1<<4) /* payload is llc */
 861#define TXCTL_RELEASE (0<<5) /* release after completion */
 862#define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
 863
 864#define BUSY_FID 0x10000
 865
 866#ifdef CISCO_EXT
 867#define AIROMAGIC	0xa55a
 868/* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
 869#ifdef SIOCIWFIRSTPRIV
 870#ifdef SIOCDEVPRIVATE
 871#define AIROOLDIOCTL	SIOCDEVPRIVATE
 872#define AIROOLDIDIFC 	AIROOLDIOCTL + 1
 873#endif /* SIOCDEVPRIVATE */
 874#else /* SIOCIWFIRSTPRIV */
 875#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
 876#endif /* SIOCIWFIRSTPRIV */
 877/* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
 878 * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
 879 * only and don't return the modified struct ifreq to the application which
 880 * is usually a problem. - Jean II */
 881#define AIROIOCTL	SIOCIWFIRSTPRIV
 882#define AIROIDIFC 	AIROIOCTL + 1
 883
 884/* Ioctl constants to be used in airo_ioctl.command */
 885
 886#define	AIROGCAP  		0	// Capability rid
 887#define AIROGCFG		1       // USED A LOT
 888#define AIROGSLIST		2	// System ID list
 889#define AIROGVLIST		3       // List of specified AP's
 890#define AIROGDRVNAM		4	//  NOTUSED
 891#define AIROGEHTENC		5	// NOTUSED
 892#define AIROGWEPKTMP		6
 893#define AIROGWEPKNV		7
 894#define AIROGSTAT		8
 895#define AIROGSTATSC32		9
 896#define AIROGSTATSD32		10
 897#define AIROGMICRID		11
 898#define AIROGMICSTATS		12
 899#define AIROGFLAGS		13
 900#define AIROGID			14
 901#define AIRORRID		15
 902#define AIRORSWVERSION		17
 903
 904/* Leave gap of 40 commands after AIROGSTATSD32 for future */
 905
 906#define AIROPCAP               	AIROGSTATSD32 + 40
 907#define AIROPVLIST              AIROPCAP      + 1
 908#define AIROPSLIST		AIROPVLIST    + 1
 909#define AIROPCFG		AIROPSLIST    + 1
 910#define AIROPSIDS		AIROPCFG      + 1
 911#define AIROPAPLIST		AIROPSIDS     + 1
 912#define AIROPMACON		AIROPAPLIST   + 1	/* Enable mac  */
 913#define AIROPMACOFF		AIROPMACON    + 1 	/* Disable mac */
 914#define AIROPSTCLR		AIROPMACOFF   + 1
 915#define AIROPWEPKEY		AIROPSTCLR    + 1
 916#define AIROPWEPKEYNV		AIROPWEPKEY   + 1
 917#define AIROPLEAPPWD            AIROPWEPKEYNV + 1
 918#define AIROPLEAPUSR            AIROPLEAPPWD  + 1
 919
 920/* Flash codes */
 921
 922#define AIROFLSHRST	       AIROPWEPKEYNV  + 40
 923#define AIROFLSHGCHR           AIROFLSHRST    + 1
 924#define AIROFLSHSTFL           AIROFLSHGCHR   + 1
 925#define AIROFLSHPCHR           AIROFLSHSTFL   + 1
 926#define AIROFLPUTBUF           AIROFLSHPCHR   + 1
 927#define AIRORESTART            AIROFLPUTBUF   + 1
 928
 929#define FLASHSIZE	32768
 930#define AUXMEMSIZE	(256 * 1024)
 931
 932typedef struct aironet_ioctl {
 933	unsigned short command;		// What to do
 934	unsigned short len;		// Len of data
 935	unsigned short ridnum;		// rid number
 936	unsigned char __user *data;	// d-data
 937} aironet_ioctl;
 938
 939static const char swversion[] = "2.1";
 940#endif /* CISCO_EXT */
 941
 942#define NUM_MODULES       2
 943#define MIC_MSGLEN_MAX    2400
 944#define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
 945#define AIRO_DEF_MTU      2312
 946
 947typedef struct {
 948	u32   size;            // size
 949	u8    enabled;         // MIC enabled or not
 950	u32   rxSuccess;       // successful packets received
 951	u32   rxIncorrectMIC;  // pkts dropped due to incorrect MIC comparison
 952	u32   rxNotMICed;      // pkts dropped due to not being MIC'd
 953	u32   rxMICPlummed;    // pkts dropped due to not having a MIC plummed
 954	u32   rxWrongSequence; // pkts dropped due to sequence number violation
 955	u32   reserve[32];
 956} mic_statistics;
 957
 958typedef struct {
 959	__be32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
 960	u64 accum;	// accumulated mic, reduced to u32 in final()
 961	int position;	// current position (byte offset) in message
 962	union {
 963		u8  d8[4];
 964		__be32 d32;
 965	} part;	// saves partial message word across update() calls
 966} emmh32_context;
 967
 968typedef struct {
 969	emmh32_context seed;	    // Context - the seed
 970	u32		 rx;	    // Received sequence number
 971	u32		 tx;	    // Tx sequence number
 972	u32		 window;    // Start of window
 973	u8		 valid;	    // Flag to say if context is valid or not
 974	u8		 key[16];
 975} miccntx;
 976
 977typedef struct {
 978	miccntx mCtx;		// Multicast context
 979	miccntx uCtx;		// Unicast context
 980} mic_module;
 981
 982typedef struct {
 983	unsigned int  rid: 16;
 984	unsigned int  len: 15;
 985	unsigned int  valid: 1;
 986	dma_addr_t host_addr;
 987} Rid;
 988
 989typedef struct {
 990	unsigned int  offset: 15;
 991	unsigned int  eoc: 1;
 992	unsigned int  len: 15;
 993	unsigned int  valid: 1;
 994	dma_addr_t host_addr;
 995} TxFid;
 996
 997struct rx_hdr {
 998	__le16 status, len;
 999	u8 rssi[2];
1000	u8 rate;
1001	u8 freq;
1002	__le16 tmp[4];
1003} __packed;
1004
1005typedef struct {
1006	unsigned int  ctl: 15;
1007	unsigned int  rdy: 1;
1008	unsigned int  len: 15;
1009	unsigned int  valid: 1;
1010	dma_addr_t host_addr;
1011} RxFid;
1012
1013/*
1014 * Host receive descriptor
1015 */
1016typedef struct {
1017	unsigned char __iomem *card_ram_off; /* offset into card memory of the
1018						desc */
1019	RxFid         rx_desc;		     /* card receive descriptor */
1020	char          *virtual_host_addr;    /* virtual address of host receive
1021					        buffer */
1022	int           pending;
1023} HostRxDesc;
1024
1025/*
1026 * Host transmit descriptor
1027 */
1028typedef struct {
1029	unsigned char __iomem *card_ram_off;	     /* offset into card memory of the
1030						desc */
1031	TxFid         tx_desc;		     /* card transmit descriptor */
1032	char          *virtual_host_addr;    /* virtual address of host receive
1033					        buffer */
1034	int           pending;
1035} HostTxDesc;
1036
1037/*
1038 * Host RID descriptor
1039 */
1040typedef struct {
1041	unsigned char __iomem *card_ram_off;      /* offset into card memory of the
1042					     descriptor */
1043	Rid           rid_desc;		  /* card RID descriptor */
1044	char          *virtual_host_addr; /* virtual address of host receive
1045					     buffer */
1046} HostRidDesc;
1047
1048typedef struct {
1049	u16 sw0;
1050	u16 sw1;
1051	u16 status;
1052	u16 len;
1053#define HOST_SET (1 << 0)
1054#define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
1055#define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
1056#define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
1057#define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
1058#define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
1059#define HOST_CLR_AID (1 << 7) /* clear AID failure */
1060#define HOST_RTS (1 << 9) /* Force RTS use */
1061#define HOST_SHORT (1 << 10) /* Do short preamble */
1062	u16 ctl;
1063	u16 aid;
1064	u16 retries;
1065	u16 fill;
1066} TxCtlHdr;
1067
1068typedef struct {
1069        u16 ctl;
1070        u16 duration;
1071        char addr1[6];
1072        char addr2[6];
1073        char addr3[6];
1074        u16 seq;
1075        char addr4[6];
1076} WifiHdr;
1077
1078
1079typedef struct {
1080	TxCtlHdr ctlhdr;
1081	u16 fill1;
1082	u16 fill2;
1083	WifiHdr wifihdr;
1084	u16 gaplen;
1085	u16 status;
1086} WifiCtlHdr;
1087
1088static WifiCtlHdr wifictlhdr8023 = {
1089	.ctlhdr = {
1090		.ctl	= HOST_DONT_RLSE,
1091	}
1092};
1093
1094// A few details needed for WEP (Wireless Equivalent Privacy)
1095#define MAX_KEY_SIZE 13			// 128 (?) bits
1096#define MIN_KEY_SIZE  5			// 40 bits RC4 - WEP
1097typedef struct wep_key_t {
1098	u16	len;
1099	u8	key[16];	/* 40-bit and 104-bit keys */
1100} wep_key_t;
1101
1102/* List of Wireless Handlers (new API) */
1103static const struct iw_handler_def	airo_handler_def;
1104
1105static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
1106
1107struct airo_info;
1108
1109static int get_dec_u16(char *buffer, int *start, int limit);
1110static void OUT4500(struct airo_info *, u16 reg, u16 value);
1111static unsigned short IN4500(struct airo_info *, u16 reg);
1112static u16 setup_card(struct airo_info*, struct net_device *dev, int lock);
1113static int enable_MAC(struct airo_info *ai, int lock);
1114static void disable_MAC(struct airo_info *ai, int lock);
1115static void enable_interrupts(struct airo_info*);
1116static void disable_interrupts(struct airo_info*);
1117static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp,
1118			bool may_sleep);
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,
1134				 bool may_sleep);
1135static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket,
1136				  bool may_sleep);
1137
1138static int mpi_send_packet(struct net_device *dev);
1139static void mpi_unmap_card(struct pci_dev *pci);
1140static void mpi_receive_802_3(struct airo_info *ai);
1141static void mpi_receive_802_11(struct airo_info *ai);
1142static int waitbusy(struct airo_info *ai);
1143
1144static irqreturn_t airo_interrupt(int irq, void* dev_id);
1145static int airo_thread(void *data);
1146static void timer_func(struct net_device *dev);
1147static int airo_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *, int cmd);
1148static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev);
 
1149#ifdef CISCO_EXT
1150static int readrids(struct net_device *dev, aironet_ioctl *comp);
1151static int writerids(struct net_device *dev, aironet_ioctl *comp);
1152static int flashcard(struct net_device *dev, aironet_ioctl *comp);
1153#endif /* CISCO_EXT */
1154static void micinit(struct airo_info *ai);
1155static int micsetup(struct airo_info *ai);
1156static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
1157static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1158
1159static u8 airo_rssi_to_dbm(tdsRssiEntry *rssi_rid, u8 rssi);
1160static u8 airo_dbm_to_pct(tdsRssiEntry *rssi_rid, u8 dbm);
1161
1162static void airo_networks_free(struct airo_info *ai);
1163
1164struct airo_info {
1165	struct net_device             *dev;
1166	struct list_head              dev_list;
1167	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we
1168	   use the high bit to mark whether it is in use. */
1169#define MAX_FIDS 6
1170#define MPI_MAX_FIDS 1
1171	u32                           fids[MAX_FIDS];
1172	ConfigRid config;
1173	char keyindex; // Used with auto wep
1174	char defindex; // Used with auto wep
1175	struct proc_dir_entry *proc_entry;
1176        spinlock_t aux_lock;
1177#define FLAG_RADIO_OFF	0	/* User disabling of MAC */
1178#define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */
1179#define FLAG_RADIO_MASK 0x03
1180#define FLAG_ENABLED	2
1181#define FLAG_ADHOC	3	/* Needed by MIC */
1182#define FLAG_MIC_CAPABLE 4
1183#define FLAG_UPDATE_MULTI 5
1184#define FLAG_UPDATE_UNI 6
1185#define FLAG_802_11	7
1186#define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */
1187#define FLAG_PENDING_XMIT 9
1188#define FLAG_PENDING_XMIT11 10
1189#define FLAG_MPI	11
1190#define FLAG_REGISTERED	12
1191#define FLAG_COMMIT	13
1192#define FLAG_RESET	14
1193#define FLAG_FLASHING	15
1194#define FLAG_WPA_CAPABLE	16
1195	unsigned long flags;
1196#define JOB_DIE	0
1197#define JOB_XMIT	1
1198#define JOB_XMIT11	2
1199#define JOB_STATS	3
1200#define JOB_PROMISC	4
1201#define JOB_MIC	5
1202#define JOB_EVENT	6
1203#define JOB_AUTOWEP	7
 
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{
1366	int i;
1367
1368	if (ai->tfm == NULL)
1369		ai->tfm = crypto_alloc_sync_skcipher("ctr(aes)", 0, 0);
1370
1371        if (IS_ERR(ai->tfm)) {
1372                airo_print_err(ai->dev->name, "failed to load transform for AES");
1373                ai->tfm = NULL;
1374                return ERROR;
1375        }
1376
1377	for (i = 0; i < NUM_MODULES; i++) {
1378		memset(&ai->mod[i].mCtx, 0, sizeof(miccntx));
1379		memset(&ai->mod[i].uCtx, 0, sizeof(miccntx));
1380	}
1381	return SUCCESS;
1382}
1383
1384static const u8 micsnap[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
1385
1386/*===========================================================================
1387 * Description: Mic a packet
1388 *
1389 *      Inputs: etherHead * pointer to an 802.3 frame
1390 *
1391 *     Returns: BOOLEAN if successful, otherwise false.
1392 *             PacketTxLen will be updated with the mic'd packets size.
1393 *
1394 *    Caveats: It is assumed that the frame buffer will already
1395 *             be big enough to hold the largets mic message possible.
1396 *            (No memory allocation is done here).
1397 *
1398 *    Author: sbraneky (10/15/01)
1399 *    Merciless hacks by rwilcher (1/14/02)
1400 */
1401
1402static int encapsulate(struct airo_info *ai, etherHead *frame, MICBuffer *mic, int payLen)
1403{
1404	miccntx   *context;
1405
1406	// Determine correct context
1407	// If not adhoc, always use unicast key
1408
1409	if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
1410		context = &ai->mod[0].mCtx;
1411	else
1412		context = &ai->mod[0].uCtx;
1413
1414	if (!context->valid)
1415		return ERROR;
1416
1417	mic->typelen = htons(payLen + 16); //Length of Mic'd packet
1418
1419	memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
1420
1421	// Add Tx sequence
1422	mic->seq = htonl(context->tx);
1423	context->tx += 2;
1424
1425	emmh32_init(&context->seed); // Mic the packet
1426	emmh32_update(&context->seed, frame->da, ETH_ALEN * 2); // DA, SA
1427	emmh32_update(&context->seed, (u8*)&mic->typelen, 10); // Type/Length and Snap
1428	emmh32_update(&context->seed, (u8*)&mic->seq, sizeof(mic->seq)); //SEQ
1429	emmh32_update(&context->seed, (u8*)(frame + 1), payLen); //payload
1430	emmh32_final(&context->seed, (u8*)&mic->mic);
1431
1432	/*    New Type/length ?????????? */
1433	mic->typelen = 0; //Let NIC know it could be an oversized packet
1434	return SUCCESS;
1435}
1436
1437typedef enum {
1438    NONE,
1439    NOMIC,
1440    NOMICPLUMMED,
1441    SEQUENCE,
1442    INCORRECTMIC,
1443} mic_error;
1444
1445/*===========================================================================
1446 *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet
1447 *               (removes the MIC stuff) if packet is a valid packet.
1448 *
1449 *       Inputs: etherHead  pointer to the 802.3 packet
1450 *
1451 *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
1452 *
1453 *      Author: sbraneky (10/15/01)
1454 *    Merciless hacks by rwilcher (1/14/02)
1455 *---------------------------------------------------------------------------
1456 */
1457
1458static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
1459{
1460	int      i;
1461	u32      micSEQ;
1462	miccntx  *context;
1463	u8       digest[4];
1464	mic_error micError = NONE;
1465
1466	// Check if the packet is a Mic'd packet
1467
1468	if (!ai->micstats.enabled) {
1469		//No Mic set or Mic OFF but we received a MIC'd packet.
1470		if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
1471			ai->micstats.rxMICPlummed++;
1472			return ERROR;
1473		}
1474		return SUCCESS;
1475	}
1476
1477	if (ntohs(mic->typelen) == 0x888E)
1478		return SUCCESS;
1479
1480	if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
1481	    // Mic enabled but packet isn't Mic'd
1482		ai->micstats.rxMICPlummed++;
1483	    	return ERROR;
1484	}
1485
1486	micSEQ = ntohl(mic->seq);            //store SEQ as CPU order
1487
1488	//At this point we a have a mic'd packet and mic is enabled
1489	//Now do the mic error checking.
1490
1491	//Receive seq must be odd
1492	if ((micSEQ & 1) == 0) {
1493		ai->micstats.rxWrongSequence++;
1494		return ERROR;
1495	}
1496
1497	for (i = 0; i < NUM_MODULES; i++) {
1498		int mcast = eth->da[0] & 1;
1499		//Determine proper context
1500		context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
1501
1502		//Make sure context is valid
1503		if (!context->valid) {
1504			if (i == 0)
1505				micError = NOMICPLUMMED;
1506			continue;
1507		}
1508		//DeMic it
1509
1510		if (!mic->typelen)
1511			mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
1512
1513		emmh32_init(&context->seed);
1514		emmh32_update(&context->seed, eth->da, ETH_ALEN*2);
1515		emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap));
1516		emmh32_update(&context->seed, (u8 *)&mic->seq, sizeof(mic->seq));
1517		emmh32_update(&context->seed, (u8 *)(eth + 1), payLen);
1518		//Calculate MIC
1519		emmh32_final(&context->seed, digest);
1520
1521		if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
1522		  //Invalid Mic
1523			if (i == 0)
1524				micError = INCORRECTMIC;
1525			continue;
1526		}
1527
1528		//Check Sequence number if mics pass
1529		if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
1530			ai->micstats.rxSuccess++;
1531			return SUCCESS;
1532		}
1533		if (i == 0)
1534			micError = SEQUENCE;
1535	}
1536
1537	// Update statistics
1538	switch (micError) {
1539		case NOMICPLUMMED: ai->micstats.rxMICPlummed++;   break;
1540		case SEQUENCE:    ai->micstats.rxWrongSequence++; break;
1541		case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
1542		case NONE:  break;
1543		case NOMIC: break;
1544	}
1545	return ERROR;
1546}
1547
1548/*===========================================================================
1549 * Description:  Checks the Rx Seq number to make sure it is valid
1550 *               and hasn't already been received
1551 *
1552 *     Inputs: miccntx - mic context to check seq against
1553 *             micSeq  - the Mic seq number
1554 *
1555 *    Returns: TRUE if valid otherwise FALSE.
1556 *
1557 *    Author: sbraneky (10/15/01)
1558 *    Merciless hacks by rwilcher (1/14/02)
1559 *---------------------------------------------------------------------------
1560 */
1561
1562static int RxSeqValid(struct airo_info *ai, miccntx *context, int mcast, u32 micSeq)
1563{
1564	u32 seq, index;
1565
1566	//Allow for the ap being rebooted - if it is then use the next
1567	//sequence number of the current sequence number - might go backwards
1568
1569	if (mcast) {
1570		if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
1571			clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
1572			context->window = (micSeq > 33) ? micSeq : 33;
1573			context->rx     = 0;        // Reset rx
1574		}
1575	} else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
1576		clear_bit (FLAG_UPDATE_UNI, &ai->flags);
1577		context->window = (micSeq > 33) ? micSeq : 33; // Move window
1578		context->rx     = 0;        // Reset rx
1579	}
1580
1581	//Make sequence number relative to START of window
1582	seq = micSeq - (context->window - 33);
1583
1584	//Too old of a SEQ number to check.
1585	if ((s32)seq < 0)
1586		return ERROR;
1587
1588	if (seq > 64) {
1589		//Window is infinite forward
1590		MoveWindow(context, micSeq);
1591		return SUCCESS;
1592	}
1593
1594	// We are in the window. Now check the context rx bit to see if it was already sent
1595	seq >>= 1;         //divide by 2 because we only have odd numbers
1596	index = 1 << seq;  //Get an index number
1597
1598	if (!(context->rx & index)) {
1599		//micSEQ falls inside the window.
1600		//Add seqence number to the list of received numbers.
1601		context->rx |= index;
1602
1603		MoveWindow(context, micSeq);
1604
1605		return SUCCESS;
1606	}
1607	return ERROR;
1608}
1609
1610static void MoveWindow(miccntx *context, u32 micSeq)
1611{
1612	u32 shift;
1613
1614	//Move window if seq greater than the middle of the window
1615	if (micSeq > context->window) {
1616		shift = (micSeq - context->window) >> 1;
1617
1618		    //Shift out old
1619		if (shift < 32)
1620			context->rx >>= shift;
1621		else
1622			context->rx = 0;
1623
1624		context->window = micSeq;      //Move window
1625	}
1626}
1627
1628/*==============================================*/
1629/*========== EMMH ROUTINES  ====================*/
1630/*==============================================*/
1631
1632/* mic accumulate */
1633#define MIC_ACCUM(val)	\
1634	context->accum += (u64)(val) * be32_to_cpu(context->coeff[coeff_position++]);
 
 
1635
1636/* expand the key to fill the MMH coefficient array */
1637static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1638			   struct crypto_sync_skcipher *tfm)
1639{
1640  /* take the keying material, expand if necessary, truncate at 16-bytes */
1641  /* run through AES counter mode to generate context->coeff[] */
1642
1643	SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
1644	struct scatterlist sg;
1645	u8 iv[AES_BLOCK_SIZE] = {};
1646	int ret;
1647
1648	crypto_sync_skcipher_setkey(tfm, pkey, 16);
1649
1650	memset(context->coeff, 0, sizeof(context->coeff));
1651	sg_init_one(&sg, context->coeff, sizeof(context->coeff));
1652
1653	skcipher_request_set_sync_tfm(req, tfm);
1654	skcipher_request_set_callback(req, 0, NULL, NULL);
1655	skcipher_request_set_crypt(req, &sg, &sg, sizeof(context->coeff), iv);
1656
1657	ret = crypto_skcipher_encrypt(req);
1658	WARN_ON_ONCE(ret);
 
 
 
 
1659}
1660
1661/* prepare for calculation of a new mic */
1662static void emmh32_init(emmh32_context *context)
1663{
1664	/* prepare for new mic calculation */
1665	context->accum = 0;
1666	context->position = 0;
1667}
1668
1669/* add some bytes to the mic calculation */
1670static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1671{
1672	int	coeff_position, byte_position;
1673
1674	if (len == 0) return;
1675
1676	coeff_position = context->position >> 2;
1677
1678	/* deal with partial 32-bit word left over from last update */
1679	byte_position = context->position & 3;
1680	if (byte_position) {
1681		/* have a partial word in part to deal with */
1682		do {
1683			if (len == 0) return;
1684			context->part.d8[byte_position++] = *pOctets++;
1685			context->position++;
1686			len--;
1687		} while (byte_position < 4);
1688		MIC_ACCUM(ntohl(context->part.d32));
1689	}
1690
1691	/* deal with full 32-bit words */
1692	while (len >= 4) {
1693		MIC_ACCUM(ntohl(*(__be32 *)pOctets));
1694		context->position += 4;
1695		pOctets += 4;
1696		len -= 4;
1697	}
1698
1699	/* deal with partial 32-bit word that will be left over from this update */
1700	byte_position = 0;
1701	while (len > 0) {
1702		context->part.d8[byte_position++] = *pOctets++;
1703		context->position++;
1704		len--;
1705	}
1706}
1707
1708/* mask used to zero empty bytes for final partial word */
1709static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1710
1711/* calculate the mic */
1712static void emmh32_final(emmh32_context *context, u8 digest[4])
1713{
1714	int	coeff_position, byte_position;
1715	u32	val;
1716
1717	u64 sum, utmp;
1718	s64 stmp;
1719
1720	coeff_position = context->position >> 2;
1721
1722	/* deal with partial 32-bit word left over from last update */
1723	byte_position = context->position & 3;
1724	if (byte_position) {
1725		/* have a partial word in part to deal with */
1726		val = ntohl(context->part.d32);
1727		MIC_ACCUM(val & mask32[byte_position]);	/* zero empty bytes */
1728	}
1729
1730	/* reduce the accumulated u64 to a 32-bit MIC */
1731	sum = context->accum;
1732	stmp = (sum  & 0xffffffffLL) - ((sum >> 32)  * 15);
1733	utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
1734	sum = utmp & 0xffffffffLL;
1735	if (utmp > 0x10000000fLL)
1736		sum -= 15;
1737
1738	val = (u32)sum;
1739	digest[0] = (val>>24) & 0xFF;
1740	digest[1] = (val>>16) & 0xFF;
1741	digest[2] = (val>>8) & 0xFF;
1742	digest[3] = val & 0xFF;
1743}
1744
1745static int readBSSListRid(struct airo_info *ai, int first,
1746		      BSSListRid *list)
1747{
1748	Cmd cmd;
1749	Resp rsp;
1750
1751	if (first == 1) {
1752		if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
1753		memset(&cmd, 0, sizeof(cmd));
1754		cmd.cmd = CMD_LISTBSS;
1755		if (down_interruptible(&ai->sem))
1756			return -ERESTARTSYS;
1757		ai->list_bss_task = current;
1758		issuecommand(ai, &cmd, &rsp, true);
1759		up(&ai->sem);
1760		/* Let the command take effect */
1761		schedule_timeout_uninterruptible(3 * HZ);
1762		ai->list_bss_task = NULL;
1763	}
1764	return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
1765			    list, ai->bssListRidLen, 1);
1766}
1767
1768static int readWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int temp, int lock)
1769{
1770	return PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
1771				wkr, sizeof(*wkr), lock);
1772}
1773
1774static int writeWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int perm, int lock)
1775{
1776	int rc;
1777	rc = PC4500_writerid(ai, RID_WEP_TEMP, wkr, sizeof(*wkr), lock);
1778	if (rc!=SUCCESS)
1779		airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
1780	if (perm) {
1781		rc = PC4500_writerid(ai, RID_WEP_PERM, wkr, sizeof(*wkr), lock);
1782		if (rc!=SUCCESS)
1783			airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
1784	}
1785	return rc;
1786}
1787
1788static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
1789{
1790	return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1791}
1792
1793static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
1794{
1795	return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
1796}
1797
1798static int readConfigRid(struct airo_info *ai, int lock)
1799{
1800	int rc;
1801	ConfigRid cfg;
1802
1803	if (ai->config.len)
1804		return SUCCESS;
1805
1806	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
1807	if (rc != SUCCESS)
1808		return rc;
1809
1810	ai->config = cfg;
1811	return SUCCESS;
1812}
1813
1814static inline void checkThrottle(struct airo_info *ai)
1815{
1816	int i;
1817/* Old hardware had a limit on encryption speed */
1818	if (ai->config.authType != AUTH_OPEN && maxencrypt) {
1819		for (i = 0; i<8; i++) {
1820			if (ai->config.rates[i] > maxencrypt) {
1821				ai->config.rates[i] = 0;
1822			}
1823		}
1824	}
1825}
1826
1827static int writeConfigRid(struct airo_info *ai, int lock)
1828{
1829	ConfigRid cfgr;
1830
1831	if (!test_bit (FLAG_COMMIT, &ai->flags))
1832		return SUCCESS;
1833
1834	clear_bit (FLAG_COMMIT, &ai->flags);
1835	clear_bit (FLAG_RESET, &ai->flags);
1836	checkThrottle(ai);
1837	cfgr = ai->config;
1838
1839	if ((cfgr.opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
1840		set_bit(FLAG_ADHOC, &ai->flags);
1841	else
1842		clear_bit(FLAG_ADHOC, &ai->flags);
1843
1844	return PC4500_writerid(ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1845}
1846
1847static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
1848{
1849	return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1850}
1851
1852static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
1853{
1854	return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
1855}
1856
1857static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
1858{
1859	return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1860}
1861
1862static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
1863{
1864	return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1865}
1866
1867static void try_auto_wep(struct airo_info *ai)
1868{
1869	if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
1870		ai->expires = RUN_AT(3*HZ);
1871		wake_up_interruptible(&ai->thr_wait);
1872	}
1873}
1874
1875static int airo_open(struct net_device *dev)
1876{
1877	struct airo_info *ai = dev->ml_priv;
1878	int rc = 0;
1879
1880	if (test_bit(FLAG_FLASHING, &ai->flags))
1881		return -EIO;
1882
1883	/* Make sure the card is configured.
1884	 * Wireless Extensions may postpone config changes until the card
1885	 * is open (to pipeline changes and speed-up card setup). If
1886	 * those changes are not yet committed, do it now - Jean II */
1887	if (test_bit(FLAG_COMMIT, &ai->flags)) {
1888		disable_MAC(ai, 1);
1889		writeConfigRid(ai, 1);
1890	}
1891
1892	if (ai->wifidev != dev) {
1893		clear_bit(JOB_DIE, &ai->jobs);
1894		ai->airo_thread_task = kthread_run(airo_thread, dev, "%s",
1895						   dev->name);
1896		if (IS_ERR(ai->airo_thread_task))
1897			return (int)PTR_ERR(ai->airo_thread_task);
1898
1899		rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
1900			dev->name, dev);
1901		if (rc) {
1902			airo_print_err(dev->name,
1903				"register interrupt %d failed, rc %d",
1904				dev->irq, rc);
1905			set_bit(JOB_DIE, &ai->jobs);
1906			kthread_stop(ai->airo_thread_task);
1907			return rc;
1908		}
1909
1910		/* Power on the MAC controller (which may have been disabled) */
1911		clear_bit(FLAG_RADIO_DOWN, &ai->flags);
1912		enable_interrupts(ai);
1913
1914		try_auto_wep(ai);
1915	}
1916	enable_MAC(ai, 1);
1917
1918	netif_start_queue(dev);
1919	return 0;
1920}
1921
1922static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
1923					struct net_device *dev)
1924{
1925	int npacks, pending;
1926	unsigned long flags;
1927	struct airo_info *ai = dev->ml_priv;
1928
1929	if (!skb) {
1930		airo_print_err(dev->name, "%s: skb == NULL!",__func__);
1931		return NETDEV_TX_OK;
1932	}
1933	if (skb_padto(skb, ETH_ZLEN)) {
1934		dev->stats.tx_dropped++;
1935		return NETDEV_TX_OK;
1936	}
1937	npacks = skb_queue_len (&ai->txq);
1938
1939	if (npacks >= MAXTXQ - 1) {
1940		netif_stop_queue (dev);
1941		if (npacks > MAXTXQ) {
1942			dev->stats.tx_fifo_errors++;
1943			return NETDEV_TX_BUSY;
1944		}
1945		skb_queue_tail (&ai->txq, skb);
1946		return NETDEV_TX_OK;
1947	}
1948
1949	spin_lock_irqsave(&ai->aux_lock, flags);
1950	skb_queue_tail (&ai->txq, skb);
1951	pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
1952	spin_unlock_irqrestore(&ai->aux_lock, flags);
1953	netif_wake_queue (dev);
1954
1955	if (pending == 0) {
1956		set_bit(FLAG_PENDING_XMIT, &ai->flags);
1957		mpi_send_packet (dev);
1958	}
1959	return NETDEV_TX_OK;
1960}
1961
1962/*
1963 * @mpi_send_packet
1964 *
1965 * Attempt to transmit a packet. Can be called from interrupt
1966 * or transmit . return number of packets we tried to send
1967 */
1968
1969static int mpi_send_packet (struct net_device *dev)
1970{
1971	struct sk_buff *skb;
1972	unsigned char *buffer;
1973	s16 len;
1974	__le16 *payloadLen;
1975	struct airo_info *ai = dev->ml_priv;
1976	u8 *sendbuf;
1977
1978	/* get a packet to send */
1979
1980	if ((skb = skb_dequeue(&ai->txq)) == NULL) {
1981		airo_print_err(dev->name,
1982			"%s: Dequeue'd zero in send_packet()",
1983			__func__);
1984		return 0;
1985	}
1986
1987	/* check min length*/
1988	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1989	buffer = skb->data;
1990
1991	ai->txfids[0].tx_desc.offset = 0;
1992	ai->txfids[0].tx_desc.valid = 1;
1993	ai->txfids[0].tx_desc.eoc = 1;
1994	ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
1995
1996/*
1997 * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
1998 * right after  TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
1999 * is immediately after it. ------------------------------------------------
2000 *                         |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
2001 *                         ------------------------------------------------
2002 */
2003
2004	memcpy(ai->txfids[0].virtual_host_addr,
2005		(char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
2006
2007	payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
2008		sizeof(wifictlhdr8023));
2009	sendbuf = ai->txfids[0].virtual_host_addr +
2010		sizeof(wifictlhdr8023) + 2 ;
2011
2012	/*
2013	 * Firmware automatically puts 802 header on so
2014	 * we don't need to account for it in the length
2015	 */
2016	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
2017		(ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
2018		MICBuffer pMic;
2019
2020		if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
2021			return ERROR;
2022
2023		*payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
2024		ai->txfids[0].tx_desc.len += sizeof(pMic);
2025		/* copy data into airo dma buffer */
2026		memcpy (sendbuf, buffer, sizeof(etherHead));
2027		buffer += sizeof(etherHead);
2028		sendbuf += sizeof(etherHead);
2029		memcpy (sendbuf, &pMic, sizeof(pMic));
2030		sendbuf += sizeof(pMic);
2031		memcpy (sendbuf, buffer, len - sizeof(etherHead));
2032	} else {
2033		*payloadLen = cpu_to_le16(len - sizeof(etherHead));
2034
2035		netif_trans_update(dev);
2036
2037		/* copy data into airo dma buffer */
2038		memcpy(sendbuf, buffer, len);
2039	}
2040
2041	memcpy_toio(ai->txfids[0].card_ram_off,
2042		&ai->txfids[0].tx_desc, sizeof(TxFid));
2043
2044	OUT4500(ai, EVACK, 8);
2045
2046	dev_kfree_skb_any(skb);
2047	return 1;
2048}
2049
2050static void get_tx_error(struct airo_info *ai, s32 fid)
2051{
2052	__le16 status;
2053
2054	if (fid < 0)
2055		status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
2056	else {
2057		if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
2058			return;
2059		bap_read(ai, &status, 2, BAP0);
2060	}
2061	if (le16_to_cpu(status) & 2) /* Too many retries */
2062		ai->dev->stats.tx_aborted_errors++;
2063	if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
2064		ai->dev->stats.tx_heartbeat_errors++;
2065	if (le16_to_cpu(status) & 8) /* Aid fail */
2066		{ }
2067	if (le16_to_cpu(status) & 0x10) /* MAC disabled */
2068		ai->dev->stats.tx_carrier_errors++;
2069	if (le16_to_cpu(status) & 0x20) /* Association lost */
2070		{ }
2071	/* We produce a TXDROP event only for retry or lifetime
2072	 * exceeded, because that's the only status that really mean
2073	 * that this particular node went away.
2074	 * Other errors means that *we* screwed up. - Jean II */
2075	if ((le16_to_cpu(status) & 2) ||
2076	     (le16_to_cpu(status) & 4)) {
2077		union iwreq_data	wrqu;
2078		char junk[0x18];
2079
2080		/* Faster to skip over useless data than to do
2081		 * another bap_setup(). We are at offset 0x6 and
2082		 * need to go to 0x18 and read 6 bytes - Jean II */
2083		bap_read(ai, (__le16 *) junk, 0x18, BAP0);
2084
2085		/* Copy 802.11 dest address.
2086		 * We use the 802.11 header because the frame may
2087		 * not be 802.3 or may be mangled...
2088		 * In Ad-Hoc mode, it will be the node address.
2089		 * In managed mode, it will be most likely the AP addr
2090		 * User space will figure out how to convert it to
2091		 * whatever it needs (IP address or else).
2092		 * - Jean II */
2093		memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
2094		wrqu.addr.sa_family = ARPHRD_ETHER;
2095
2096		/* Send event to user space */
2097		wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
2098	}
2099}
2100
2101static void airo_end_xmit(struct net_device *dev, bool may_sleep)
2102{
2103	u16 status;
2104	int i;
2105	struct airo_info *priv = dev->ml_priv;
2106	struct sk_buff *skb = priv->xmit.skb;
2107	int fid = priv->xmit.fid;
2108	u32 *fids = priv->fids;
2109
2110	clear_bit(JOB_XMIT, &priv->jobs);
2111	clear_bit(FLAG_PENDING_XMIT, &priv->flags);
2112	status = transmit_802_3_packet(priv, fids[fid], skb->data, may_sleep);
2113	up(&priv->sem);
2114
2115	i = 0;
2116	if (status == SUCCESS) {
2117		netif_trans_update(dev);
2118		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
2119	} else {
2120		priv->fids[fid] &= 0xffff;
2121		dev->stats.tx_window_errors++;
2122	}
2123	if (i < MAX_FIDS / 2)
2124		netif_wake_queue(dev);
2125	dev_kfree_skb(skb);
2126}
2127
2128static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
2129					 struct net_device *dev)
2130{
2131	s16 len;
2132	int i, j;
2133	struct airo_info *priv = dev->ml_priv;
2134	u32 *fids = priv->fids;
2135
2136	if (skb == NULL) {
2137		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
2138		return NETDEV_TX_OK;
2139	}
2140	if (skb_padto(skb, ETH_ZLEN)) {
2141		dev->stats.tx_dropped++;
2142		return NETDEV_TX_OK;
2143	}
2144
2145	/* Find a vacant FID */
2146	for (i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++);
2147	for (j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++);
2148
2149	if (j >= MAX_FIDS / 2) {
2150		netif_stop_queue(dev);
2151
2152		if (i == MAX_FIDS / 2) {
2153			dev->stats.tx_fifo_errors++;
2154			return NETDEV_TX_BUSY;
2155		}
2156	}
2157	/* check min length*/
2158	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2159        /* Mark fid as used & save length for later */
2160	fids[i] |= (len << 16);
2161	priv->xmit.skb = skb;
2162	priv->xmit.fid = i;
2163	if (down_trylock(&priv->sem) != 0) {
2164		set_bit(FLAG_PENDING_XMIT, &priv->flags);
2165		netif_stop_queue(dev);
2166		set_bit(JOB_XMIT, &priv->jobs);
2167		wake_up_interruptible(&priv->thr_wait);
2168	} else
2169		airo_end_xmit(dev, false);
2170	return NETDEV_TX_OK;
2171}
2172
2173static void airo_end_xmit11(struct net_device *dev, bool may_sleep)
2174{
2175	u16 status;
2176	int i;
2177	struct airo_info *priv = dev->ml_priv;
2178	struct sk_buff *skb = priv->xmit11.skb;
2179	int fid = priv->xmit11.fid;
2180	u32 *fids = priv->fids;
2181
2182	clear_bit(JOB_XMIT11, &priv->jobs);
2183	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
2184	status = transmit_802_11_packet(priv, fids[fid], skb->data, may_sleep);
2185	up(&priv->sem);
2186
2187	i = MAX_FIDS / 2;
2188	if (status == SUCCESS) {
2189		netif_trans_update(dev);
2190		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
2191	} else {
2192		priv->fids[fid] &= 0xffff;
2193		dev->stats.tx_window_errors++;
2194	}
2195	if (i < MAX_FIDS)
2196		netif_wake_queue(dev);
2197	dev_kfree_skb(skb);
2198}
2199
2200static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
2201					   struct net_device *dev)
2202{
2203	s16 len;
2204	int i, j;
2205	struct airo_info *priv = dev->ml_priv;
2206	u32 *fids = priv->fids;
2207
2208	if (test_bit(FLAG_MPI, &priv->flags)) {
2209		/* Not implemented yet for MPI350 */
2210		netif_stop_queue(dev);
2211		dev_kfree_skb_any(skb);
2212		return NETDEV_TX_OK;
2213	}
2214
2215	if (skb == NULL) {
2216		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
2217		return NETDEV_TX_OK;
2218	}
2219	if (skb_padto(skb, ETH_ZLEN)) {
2220		dev->stats.tx_dropped++;
2221		return NETDEV_TX_OK;
2222	}
2223
2224	/* Find a vacant FID */
2225	for (i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++);
2226	for (j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++);
2227
2228	if (j >= MAX_FIDS) {
2229		netif_stop_queue(dev);
2230
2231		if (i == MAX_FIDS) {
2232			dev->stats.tx_fifo_errors++;
2233			return NETDEV_TX_BUSY;
2234		}
2235	}
2236	/* check min length*/
2237	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2238        /* Mark fid as used & save length for later */
2239	fids[i] |= (len << 16);
2240	priv->xmit11.skb = skb;
2241	priv->xmit11.fid = i;
2242	if (down_trylock(&priv->sem) != 0) {
2243		set_bit(FLAG_PENDING_XMIT11, &priv->flags);
2244		netif_stop_queue(dev);
2245		set_bit(JOB_XMIT11, &priv->jobs);
2246		wake_up_interruptible(&priv->thr_wait);
2247	} else
2248		airo_end_xmit11(dev, false);
2249	return NETDEV_TX_OK;
2250}
2251
2252static void airo_read_stats(struct net_device *dev)
2253{
2254	struct airo_info *ai = dev->ml_priv;
2255	StatsRid stats_rid;
2256	__le32 *vals = stats_rid.vals;
2257
2258	clear_bit(JOB_STATS, &ai->jobs);
2259	if (ai->power.event) {
2260		up(&ai->sem);
2261		return;
2262	}
2263	readStatsRid(ai, &stats_rid, RID_STATS, 0);
2264	up(&ai->sem);
2265
2266	dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
2267			       le32_to_cpu(vals[45]);
2268	dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
2269			       le32_to_cpu(vals[41]);
2270	dev->stats.rx_bytes = le32_to_cpu(vals[92]);
2271	dev->stats.tx_bytes = le32_to_cpu(vals[91]);
2272	dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
2273			      le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
2274	dev->stats.tx_errors = le32_to_cpu(vals[42]) +
2275			      dev->stats.tx_fifo_errors;
2276	dev->stats.multicast = le32_to_cpu(vals[43]);
2277	dev->stats.collisions = le32_to_cpu(vals[89]);
2278
2279	/* detailed rx_errors: */
2280	dev->stats.rx_length_errors = le32_to_cpu(vals[3]);
2281	dev->stats.rx_crc_errors = le32_to_cpu(vals[4]);
2282	dev->stats.rx_frame_errors = le32_to_cpu(vals[2]);
2283	dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
2284}
2285
2286static struct net_device_stats *airo_get_stats(struct net_device *dev)
2287{
2288	struct airo_info *local =  dev->ml_priv;
2289
2290	if (!test_bit(JOB_STATS, &local->jobs)) {
2291		set_bit(JOB_STATS, &local->jobs);
2292		wake_up_interruptible(&local->thr_wait);
 
 
 
 
2293	}
2294
2295	return &dev->stats;
2296}
2297
2298static void airo_set_promisc(struct airo_info *ai, bool may_sleep)
2299{
2300	Cmd cmd;
2301	Resp rsp;
2302
2303	memset(&cmd, 0, sizeof(cmd));
2304	cmd.cmd = CMD_SETMODE;
2305	clear_bit(JOB_PROMISC, &ai->jobs);
2306	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
2307	issuecommand(ai, &cmd, &rsp, may_sleep);
2308	up(&ai->sem);
2309}
2310
2311static void airo_set_multicast_list(struct net_device *dev)
2312{
2313	struct airo_info *ai = dev->ml_priv;
2314
2315	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
2316		change_bit(FLAG_PROMISC, &ai->flags);
2317		if (down_trylock(&ai->sem) != 0) {
2318			set_bit(JOB_PROMISC, &ai->jobs);
2319			wake_up_interruptible(&ai->thr_wait);
2320		} else
2321			airo_set_promisc(ai, false);
2322	}
2323
2324	if ((dev->flags&IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
2325		/* Turn on multicast.  (Should be already setup...) */
2326	}
2327}
2328
2329static int airo_set_mac_address(struct net_device *dev, void *p)
2330{
2331	struct airo_info *ai = dev->ml_priv;
2332	struct sockaddr *addr = p;
2333
2334	readConfigRid(ai, 1);
2335	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
2336	set_bit (FLAG_COMMIT, &ai->flags);
2337	disable_MAC(ai, 1);
2338	writeConfigRid (ai, 1);
2339	enable_MAC(ai, 1);
2340	dev_addr_set(ai->dev, addr->sa_data);
2341	if (ai->wifidev)
2342		dev_addr_set(ai->wifidev, addr->sa_data);
2343	return 0;
2344}
2345
2346static LIST_HEAD(airo_devices);
2347
2348static void add_airo_dev(struct airo_info *ai)
2349{
2350	/* Upper layers already keep track of PCI devices,
2351	 * so we only need to remember our non-PCI cards. */
2352	if (!ai->pci)
2353		list_add_tail(&ai->dev_list, &airo_devices);
2354}
2355
2356static void del_airo_dev(struct airo_info *ai)
2357{
2358	if (!ai->pci)
2359		list_del(&ai->dev_list);
2360}
2361
2362static int airo_close(struct net_device *dev)
2363{
2364	struct airo_info *ai = dev->ml_priv;
2365
2366	netif_stop_queue(dev);
2367
2368	if (ai->wifidev != dev) {
2369#ifdef POWER_ON_DOWN
2370		/* Shut power to the card. The idea is that the user can save
2371		 * power when he doesn't need the card with "ifconfig down".
2372		 * That's the method that is most friendly towards the network
2373		 * stack (i.e. the network stack won't try to broadcast
2374		 * anything on the interface and routes are gone. Jean II */
2375		set_bit(FLAG_RADIO_DOWN, &ai->flags);
2376		disable_MAC(ai, 1);
2377#endif
2378		disable_interrupts(ai);
2379
2380		free_irq(dev->irq, dev);
2381
2382		set_bit(JOB_DIE, &ai->jobs);
2383		kthread_stop(ai->airo_thread_task);
2384	}
2385	return 0;
2386}
2387
2388void stop_airo_card(struct net_device *dev, int freeres)
2389{
2390	struct airo_info *ai = dev->ml_priv;
2391
2392	set_bit(FLAG_RADIO_DOWN, &ai->flags);
2393	disable_MAC(ai, 1);
2394	disable_interrupts(ai);
2395	takedown_proc_entry(dev, ai);
2396	if (test_bit(FLAG_REGISTERED, &ai->flags)) {
2397		unregister_netdev(dev);
2398		if (ai->wifidev) {
2399			unregister_netdev(ai->wifidev);
2400			free_netdev(ai->wifidev);
2401			ai->wifidev = NULL;
2402		}
2403		clear_bit(FLAG_REGISTERED, &ai->flags);
2404	}
2405	/*
2406	 * Clean out tx queue
2407	 */
2408	if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
2409		struct sk_buff *skb = NULL;
2410		for (;(skb = skb_dequeue(&ai->txq));)
2411			dev_kfree_skb(skb);
2412	}
2413
2414	airo_networks_free (ai);
2415
2416	kfree(ai->flash);
2417	kfree(ai->rssi);
2418	kfree(ai->SSID);
2419	if (freeres) {
2420		/* PCMCIA frees this stuff, so only for PCI and ISA */
2421		release_region(dev->base_addr, 64);
2422		if (test_bit(FLAG_MPI, &ai->flags)) {
2423			if (ai->pci)
2424				mpi_unmap_card(ai->pci);
2425			if (ai->pcimem)
2426				iounmap(ai->pcimem);
2427			if (ai->pciaux)
2428				iounmap(ai->pciaux);
2429			dma_free_coherent(&ai->pci->dev, PCI_SHARED_LEN,
2430					  ai->shared, ai->shared_dma);
2431		}
2432        }
2433	crypto_free_sync_skcipher(ai->tfm);
2434	del_airo_dev(ai);
2435	free_netdev(dev);
2436}
2437
2438EXPORT_SYMBOL(stop_airo_card);
2439
2440static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr)
2441{
2442	memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN);
2443	return ETH_ALEN;
2444}
2445
2446static void mpi_unmap_card(struct pci_dev *pci)
2447{
2448	unsigned long mem_start = pci_resource_start(pci, 1);
2449	unsigned long mem_len = pci_resource_len(pci, 1);
2450	unsigned long aux_start = pci_resource_start(pci, 2);
2451	unsigned long aux_len = AUXMEMSIZE;
2452
2453	release_mem_region(aux_start, aux_len);
2454	release_mem_region(mem_start, mem_len);
2455}
2456
2457/*************************************************************
2458 *  This routine assumes that descriptors have been setup .
2459 *  Run at insmod time or after reset when the descriptors
2460 *  have been initialized . Returns 0 if all is well nz
2461 *  otherwise . Does not allocate memory but sets up card
2462 *  using previously allocated descriptors.
2463 */
2464static int mpi_init_descriptors (struct airo_info *ai)
2465{
2466	Cmd cmd;
2467	Resp rsp;
2468	int i;
2469	int rc = SUCCESS;
2470
2471	/* Alloc  card RX descriptors */
2472	netif_stop_queue(ai->dev);
2473
2474	memset(&rsp, 0, sizeof(rsp));
2475	memset(&cmd, 0, sizeof(cmd));
2476
2477	cmd.cmd = CMD_ALLOCATEAUX;
2478	cmd.parm0 = FID_RX;
2479	cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
2480	cmd.parm2 = MPI_MAX_FIDS;
2481	rc = issuecommand(ai, &cmd, &rsp, true);
2482	if (rc != SUCCESS) {
2483		airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
2484		return rc;
2485	}
2486
2487	for (i = 0; i<MPI_MAX_FIDS; i++) {
2488		memcpy_toio(ai->rxfids[i].card_ram_off,
2489			&ai->rxfids[i].rx_desc, sizeof(RxFid));
2490	}
2491
2492	/* Alloc card TX descriptors */
2493
2494	memset(&rsp, 0, sizeof(rsp));
2495	memset(&cmd, 0, sizeof(cmd));
2496
2497	cmd.cmd = CMD_ALLOCATEAUX;
2498	cmd.parm0 = FID_TX;
2499	cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
2500	cmd.parm2 = MPI_MAX_FIDS;
2501
2502	for (i = 0; i<MPI_MAX_FIDS; i++) {
2503		ai->txfids[i].tx_desc.valid = 1;
2504		memcpy_toio(ai->txfids[i].card_ram_off,
2505			&ai->txfids[i].tx_desc, sizeof(TxFid));
2506	}
2507	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2508
2509	rc = issuecommand(ai, &cmd, &rsp, true);
2510	if (rc != SUCCESS) {
2511		airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
2512		return rc;
2513	}
2514
2515	/* Alloc card Rid descriptor */
2516	memset(&rsp, 0, sizeof(rsp));
2517	memset(&cmd, 0, sizeof(cmd));
2518
2519	cmd.cmd = CMD_ALLOCATEAUX;
2520	cmd.parm0 = RID_RW;
2521	cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
2522	cmd.parm2 = 1; /* Magic number... */
2523	rc = issuecommand(ai, &cmd, &rsp, true);
2524	if (rc != SUCCESS) {
2525		airo_print_err(ai->dev->name, "Couldn't allocate RID");
2526		return rc;
2527	}
2528
2529	memcpy_toio(ai->config_desc.card_ram_off,
2530		&ai->config_desc.rid_desc, sizeof(Rid));
2531
2532	return rc;
2533}
2534
2535/*
2536 * We are setting up three things here:
2537 * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
2538 * 2) Map PCI memory for issuing commands.
2539 * 3) Allocate memory (shared) to send and receive ethernet frames.
2540 */
2541static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
2542{
2543	unsigned long mem_start, mem_len, aux_start, aux_len;
2544	int rc = -1;
2545	int i;
2546	dma_addr_t busaddroff;
2547	unsigned char *vpackoff;
2548	unsigned char __iomem *pciaddroff;
2549
2550	mem_start = pci_resource_start(pci, 1);
2551	mem_len = pci_resource_len(pci, 1);
2552	aux_start = pci_resource_start(pci, 2);
2553	aux_len = AUXMEMSIZE;
2554
2555	if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
2556		airo_print_err("", "Couldn't get region %x[%x]",
2557			(int)mem_start, (int)mem_len);
2558		goto out;
2559	}
2560	if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
2561		airo_print_err("", "Couldn't get region %x[%x]",
2562			(int)aux_start, (int)aux_len);
2563		goto free_region1;
2564	}
2565
2566	ai->pcimem = ioremap(mem_start, mem_len);
2567	if (!ai->pcimem) {
2568		airo_print_err("", "Couldn't map region %x[%x]",
2569			(int)mem_start, (int)mem_len);
2570		goto free_region2;
2571	}
2572	ai->pciaux = ioremap(aux_start, aux_len);
2573	if (!ai->pciaux) {
2574		airo_print_err("", "Couldn't map region %x[%x]",
2575			(int)aux_start, (int)aux_len);
2576		goto free_memmap;
2577	}
2578
2579	/* Reserve PKTSIZE for each fid and 2K for the Rids */
2580	ai->shared = dma_alloc_coherent(&pci->dev, PCI_SHARED_LEN,
2581					&ai->shared_dma, GFP_KERNEL);
2582	if (!ai->shared) {
2583		airo_print_err("", "Couldn't alloc_coherent %d",
2584			PCI_SHARED_LEN);
2585		goto free_auxmap;
2586	}
2587
2588	/*
2589	 * Setup descriptor RX, TX, CONFIG
2590	 */
2591	busaddroff = ai->shared_dma;
2592	pciaddroff = ai->pciaux + AUX_OFFSET;
2593	vpackoff   = ai->shared;
2594
2595	/* RX descriptor setup */
2596	for (i = 0; i < MPI_MAX_FIDS; i++) {
2597		ai->rxfids[i].pending = 0;
2598		ai->rxfids[i].card_ram_off = pciaddroff;
2599		ai->rxfids[i].virtual_host_addr = vpackoff;
2600		ai->rxfids[i].rx_desc.host_addr = busaddroff;
2601		ai->rxfids[i].rx_desc.valid = 1;
2602		ai->rxfids[i].rx_desc.len = PKTSIZE;
2603		ai->rxfids[i].rx_desc.rdy = 0;
2604
2605		pciaddroff += sizeof(RxFid);
2606		busaddroff += PKTSIZE;
2607		vpackoff   += PKTSIZE;
2608	}
2609
2610	/* TX descriptor setup */
2611	for (i = 0; i < MPI_MAX_FIDS; i++) {
2612		ai->txfids[i].card_ram_off = pciaddroff;
2613		ai->txfids[i].virtual_host_addr = vpackoff;
2614		ai->txfids[i].tx_desc.valid = 1;
2615		ai->txfids[i].tx_desc.host_addr = busaddroff;
2616		memcpy(ai->txfids[i].virtual_host_addr,
2617			&wifictlhdr8023, sizeof(wifictlhdr8023));
2618
2619		pciaddroff += sizeof(TxFid);
2620		busaddroff += PKTSIZE;
2621		vpackoff   += PKTSIZE;
2622	}
2623	ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2624
2625	/* Rid descriptor setup */
2626	ai->config_desc.card_ram_off = pciaddroff;
2627	ai->config_desc.virtual_host_addr = vpackoff;
2628	ai->config_desc.rid_desc.host_addr = busaddroff;
2629	ai->ridbus = busaddroff;
2630	ai->config_desc.rid_desc.rid = 0;
2631	ai->config_desc.rid_desc.len = RIDSIZE;
2632	ai->config_desc.rid_desc.valid = 1;
2633	pciaddroff += sizeof(Rid);
2634	busaddroff += RIDSIZE;
2635	vpackoff   += RIDSIZE;
2636
2637	/* Tell card about descriptors */
2638	if (mpi_init_descriptors (ai) != SUCCESS)
2639		goto free_shared;
2640
2641	return 0;
2642 free_shared:
2643	dma_free_coherent(&pci->dev, PCI_SHARED_LEN, ai->shared,
2644			  ai->shared_dma);
2645 free_auxmap:
2646	iounmap(ai->pciaux);
2647 free_memmap:
2648	iounmap(ai->pcimem);
2649 free_region2:
2650	release_mem_region(aux_start, aux_len);
2651 free_region1:
2652	release_mem_region(mem_start, mem_len);
2653 out:
2654	return rc;
2655}
2656
2657static const struct header_ops airo_header_ops = {
2658	.parse = wll_header_parse,
2659};
2660
2661static const struct net_device_ops airo11_netdev_ops = {
2662	.ndo_open 		= airo_open,
2663	.ndo_stop 		= airo_close,
2664	.ndo_start_xmit 	= airo_start_xmit11,
2665	.ndo_get_stats 		= airo_get_stats,
2666	.ndo_set_mac_address	= airo_set_mac_address,
2667	.ndo_siocdevprivate	= airo_siocdevprivate,
2668};
2669
2670static void wifi_setup(struct net_device *dev)
2671{
2672	dev->netdev_ops = &airo11_netdev_ops;
2673	dev->header_ops = &airo_header_ops;
2674	dev->wireless_handlers = &airo_handler_def;
2675
2676	dev->type               = ARPHRD_IEEE80211;
2677	dev->hard_header_len    = ETH_HLEN;
2678	dev->mtu                = AIRO_DEF_MTU;
2679	dev->min_mtu            = 68;
2680	dev->max_mtu            = MIC_MSGLEN_MAX;
2681	dev->addr_len           = ETH_ALEN;
2682	dev->tx_queue_len       = 100;
2683
2684	eth_broadcast_addr(dev->broadcast);
2685
2686	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
2687}
2688
2689static struct net_device *init_wifidev(struct airo_info *ai,
2690					struct net_device *ethdev)
2691{
2692	int err;
2693	struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN,
2694					      wifi_setup);
2695	if (!dev)
2696		return NULL;
2697	dev->ml_priv = ethdev->ml_priv;
2698	dev->irq = ethdev->irq;
2699	dev->base_addr = ethdev->base_addr;
2700	dev->wireless_data = ethdev->wireless_data;
2701	SET_NETDEV_DEV(dev, ethdev->dev.parent);
2702	eth_hw_addr_inherit(dev, ethdev);
2703	err = register_netdev(dev);
2704	if (err<0) {
2705		free_netdev(dev);
2706		return NULL;
2707	}
2708	return dev;
2709}
2710
2711static int reset_card(struct net_device *dev, int lock)
2712{
2713	struct airo_info *ai = dev->ml_priv;
2714
2715	if (lock && down_interruptible(&ai->sem))
2716		return -1;
2717	waitbusy (ai);
2718	OUT4500(ai, COMMAND, CMD_SOFTRESET);
2719	msleep(200);
2720	waitbusy (ai);
2721	msleep(200);
2722	if (lock)
2723		up(&ai->sem);
2724	return 0;
2725}
2726
2727#define AIRO_MAX_NETWORK_COUNT	64
2728static int airo_networks_allocate(struct airo_info *ai)
2729{
2730	if (ai->networks)
2731		return 0;
2732
2733	ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement),
2734			       GFP_KERNEL);
2735	if (!ai->networks) {
2736		airo_print_warn("", "Out of memory allocating beacons");
2737		return -ENOMEM;
2738	}
2739
2740	return 0;
2741}
2742
2743static void airo_networks_free(struct airo_info *ai)
2744{
2745	kfree(ai->networks);
2746	ai->networks = NULL;
2747}
2748
2749static void airo_networks_initialize(struct airo_info *ai)
2750{
2751	int i;
2752
2753	INIT_LIST_HEAD(&ai->network_free_list);
2754	INIT_LIST_HEAD(&ai->network_list);
2755	for (i = 0; i < AIRO_MAX_NETWORK_COUNT; i++)
2756		list_add_tail(&ai->networks[i].list,
2757			      &ai->network_free_list);
2758}
2759
2760static const struct net_device_ops airo_netdev_ops = {
2761	.ndo_open		= airo_open,
2762	.ndo_stop		= airo_close,
2763	.ndo_start_xmit		= airo_start_xmit,
2764	.ndo_get_stats		= airo_get_stats,
2765	.ndo_set_rx_mode	= airo_set_multicast_list,
2766	.ndo_set_mac_address	= airo_set_mac_address,
2767	.ndo_siocdevprivate	= airo_siocdevprivate,
2768	.ndo_validate_addr	= eth_validate_addr,
2769};
2770
2771static const struct net_device_ops mpi_netdev_ops = {
2772	.ndo_open		= airo_open,
2773	.ndo_stop		= airo_close,
2774	.ndo_start_xmit		= mpi_start_xmit,
2775	.ndo_get_stats		= airo_get_stats,
2776	.ndo_set_rx_mode	= airo_set_multicast_list,
2777	.ndo_set_mac_address	= airo_set_mac_address,
2778	.ndo_siocdevprivate	= airo_siocdevprivate,
2779	.ndo_validate_addr	= eth_validate_addr,
2780};
2781
2782
2783static struct net_device *_init_airo_card(unsigned short irq, int port,
2784					   int is_pcmcia, struct pci_dev *pci,
2785					   struct device *dmdev)
2786{
2787	struct net_device *dev;
2788	struct airo_info *ai;
2789	int i, rc;
2790	CapabilityRid cap_rid;
2791
2792	/* Create the network device object. */
2793	dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup);
2794	if (!dev) {
2795		airo_print_err("", "Couldn't alloc_etherdev");
2796		return NULL;
2797	}
2798
2799	ai = dev->ml_priv = netdev_priv(dev);
2800	ai->wifidev = NULL;
2801	ai->flags = 1 << FLAG_RADIO_DOWN;
2802	ai->jobs = 0;
2803	ai->dev = dev;
2804	if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2805		airo_print_dbg("", "Found an MPI350 card");
2806		set_bit(FLAG_MPI, &ai->flags);
2807	}
2808	spin_lock_init(&ai->aux_lock);
2809	sema_init(&ai->sem, 1);
2810	ai->config.len = 0;
2811	ai->pci = pci;
2812	init_waitqueue_head (&ai->thr_wait);
2813	ai->tfm = NULL;
2814	add_airo_dev(ai);
2815	ai->APList.len = cpu_to_le16(sizeof(struct APListRid));
2816
2817	if (airo_networks_allocate (ai))
2818		goto err_out_free;
2819	airo_networks_initialize (ai);
2820
2821	skb_queue_head_init (&ai->txq);
2822
2823	/* The Airo-specific entries in the device structure. */
2824	if (test_bit(FLAG_MPI,&ai->flags))
2825		dev->netdev_ops = &mpi_netdev_ops;
2826	else
2827		dev->netdev_ops = &airo_netdev_ops;
2828	dev->wireless_handlers = &airo_handler_def;
2829	ai->wireless_data.spy_data = &ai->spy_data;
2830	dev->wireless_data = &ai->wireless_data;
2831	dev->irq = irq;
2832	dev->base_addr = port;
2833	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
2834	dev->max_mtu = MIC_MSGLEN_MAX;
2835
2836	SET_NETDEV_DEV(dev, dmdev);
2837
2838	reset_card (dev, 1);
2839	msleep(400);
2840
2841	if (!is_pcmcia) {
2842		if (!request_region(dev->base_addr, 64, DRV_NAME)) {
2843			rc = -EBUSY;
2844			airo_print_err(dev->name, "Couldn't request region");
2845			goto err_out_nets;
2846		}
2847	}
2848
2849	if (test_bit(FLAG_MPI,&ai->flags)) {
2850		if (mpi_map_card(ai, pci)) {
2851			airo_print_err("", "Could not map memory");
2852			goto err_out_res;
2853		}
2854	}
2855
2856	if (probe) {
2857		if (setup_card(ai, dev, 1) != SUCCESS) {
2858			airo_print_err(dev->name, "MAC could not be enabled");
2859			rc = -EIO;
2860			goto err_out_map;
2861		}
2862	} else if (!test_bit(FLAG_MPI,&ai->flags)) {
2863		ai->bap_read = fast_bap_read;
2864		set_bit(FLAG_FLASHING, &ai->flags);
2865	}
2866
2867	strcpy(dev->name, "eth%d");
2868	rc = register_netdev(dev);
2869	if (rc) {
2870		airo_print_err(dev->name, "Couldn't register_netdev");
2871		goto err_out_map;
2872	}
2873	ai->wifidev = init_wifidev(ai, dev);
2874	if (!ai->wifidev)
2875		goto err_out_reg;
2876
2877	rc = readCapabilityRid(ai, &cap_rid, 1);
2878	if (rc != SUCCESS) {
2879		rc = -EIO;
2880		goto err_out_wifi;
2881	}
2882	/* WEP capability discovery */
2883	ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
2884	ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
2885
2886	airo_print_info(dev->name, "Firmware version %x.%x.%02d",
2887	                ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
2888	                (le16_to_cpu(cap_rid.softVer) & 0xFF),
2889	                le16_to_cpu(cap_rid.softSubVer));
2890
2891	/* Test for WPA support */
2892	/* Only firmware versions 5.30.17 or better can do WPA */
2893	if (le16_to_cpu(cap_rid.softVer) > 0x530
2894	 || (le16_to_cpu(cap_rid.softVer) == 0x530
2895	      && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
2896		airo_print_info(ai->dev->name, "WPA supported.");
2897
2898		set_bit(FLAG_WPA_CAPABLE, &ai->flags);
2899		ai->bssListFirst = RID_WPA_BSSLISTFIRST;
2900		ai->bssListNext = RID_WPA_BSSLISTNEXT;
2901		ai->bssListRidLen = sizeof(BSSListRid);
2902	} else {
2903		airo_print_info(ai->dev->name, "WPA unsupported with firmware "
2904			"versions older than 5.30.17.");
2905
2906		ai->bssListFirst = RID_BSSLISTFIRST;
2907		ai->bssListNext = RID_BSSLISTNEXT;
2908		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
2909	}
2910
2911	set_bit(FLAG_REGISTERED,&ai->flags);
2912	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2913
2914	/* Allocate the transmit buffers */
2915	if (probe && !test_bit(FLAG_MPI,&ai->flags))
2916		for (i = 0; i < MAX_FIDS; i++)
2917			ai->fids[i] = transmit_allocate(ai, AIRO_DEF_MTU, i>=MAX_FIDS/2);
2918
2919	if (setup_proc_entry(dev, dev->ml_priv) < 0)
2920		goto err_out_wifi;
2921
2922	return dev;
2923
2924err_out_wifi:
2925	unregister_netdev(ai->wifidev);
2926	free_netdev(ai->wifidev);
2927err_out_reg:
2928	unregister_netdev(dev);
2929err_out_map:
2930	if (test_bit(FLAG_MPI,&ai->flags) && pci) {
2931		dma_free_coherent(&pci->dev, PCI_SHARED_LEN, ai->shared,
2932				  ai->shared_dma);
2933		iounmap(ai->pciaux);
2934		iounmap(ai->pcimem);
2935		mpi_unmap_card(ai->pci);
2936	}
2937err_out_res:
2938	if (!is_pcmcia)
2939		release_region(dev->base_addr, 64);
2940err_out_nets:
2941	airo_networks_free(ai);
2942err_out_free:
2943	del_airo_dev(ai);
2944	free_netdev(dev);
2945	return NULL;
2946}
2947
2948struct net_device *init_airo_card(unsigned short irq, int port, int is_pcmcia,
2949				  struct device *dmdev)
2950{
2951	return _init_airo_card (irq, port, is_pcmcia, NULL, dmdev);
2952}
2953
2954EXPORT_SYMBOL(init_airo_card);
2955
2956static int waitbusy (struct airo_info *ai)
2957{
2958	int delay = 0;
2959	while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) {
2960		udelay (10);
2961		if ((++delay % 20) == 0)
2962			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2963	}
2964	return delay < 10000;
2965}
2966
2967int reset_airo_card(struct net_device *dev)
2968{
2969	int i;
2970	struct airo_info *ai = dev->ml_priv;
2971
2972	if (reset_card (dev, 1))
2973		return -1;
2974
2975	if (setup_card(ai, dev, 1) != SUCCESS) {
2976		airo_print_err(dev->name, "MAC could not be enabled");
2977		return -1;
2978	}
2979	airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
2980	/* Allocate the transmit buffers if needed */
2981	if (!test_bit(FLAG_MPI,&ai->flags))
2982		for (i = 0; i < MAX_FIDS; i++)
2983			ai->fids[i] = transmit_allocate (ai, AIRO_DEF_MTU, i>=MAX_FIDS/2);
2984
2985	enable_interrupts(ai);
2986	netif_wake_queue(dev);
2987	return 0;
2988}
2989
2990EXPORT_SYMBOL(reset_airo_card);
2991
2992static void airo_send_event(struct net_device *dev)
2993{
2994	struct airo_info *ai = dev->ml_priv;
2995	union iwreq_data wrqu;
2996	StatusRid status_rid;
2997
2998	clear_bit(JOB_EVENT, &ai->jobs);
2999	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
3000	up(&ai->sem);
3001	wrqu.data.length = 0;
3002	wrqu.data.flags = 0;
3003	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
3004	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3005
3006	/* Send event to user space */
3007	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
3008}
3009
3010static void airo_process_scan_results (struct airo_info *ai)
3011{
3012	union iwreq_data	wrqu;
3013	BSSListRid bss;
3014	int rc;
3015	BSSListElement * loop_net;
3016	BSSListElement * tmp_net;
3017
3018	/* Blow away current list of scan results */
3019	list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
3020		list_move_tail (&loop_net->list, &ai->network_free_list);
3021		/* Don't blow away ->list, just BSS data */
3022		memset (loop_net, 0, sizeof (loop_net->bss));
3023	}
3024
3025	/* Try to read the first entry of the scan result */
3026	rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
3027	if ((rc) || (bss.index == cpu_to_le16(0xffff))) {
3028		/* No scan results */
3029		goto out;
3030	}
3031
3032	/* Read and parse all entries */
3033	tmp_net = NULL;
3034	while ((!rc) && (bss.index != cpu_to_le16(0xffff))) {
3035		/* Grab a network off the free list */
3036		if (!list_empty(&ai->network_free_list)) {
3037			tmp_net = list_entry(ai->network_free_list.next,
3038					    BSSListElement, list);
3039			list_del(ai->network_free_list.next);
3040		}
3041
3042		if (tmp_net != NULL) {
3043			memcpy(tmp_net, &bss, sizeof(tmp_net->bss));
3044			list_add_tail(&tmp_net->list, &ai->network_list);
3045			tmp_net = NULL;
3046		}
3047
3048		/* Read next entry */
3049		rc = PC4500_readrid(ai, ai->bssListNext,
3050				    &bss, ai->bssListRidLen, 0);
3051	}
3052
3053out:
3054	/* write APList back (we cleared it in airo_set_scan) */
3055	disable_MAC(ai, 2);
3056	writeAPListRid(ai, &ai->APList, 0);
3057	enable_MAC(ai, 0);
3058
3059	ai->scan_timeout = 0;
3060	clear_bit(JOB_SCAN_RESULTS, &ai->jobs);
3061	up(&ai->sem);
3062
3063	/* Send an empty event to user space.
3064	 * We don't send the received data on
3065	 * the event because it would require
3066	 * us to do complex transcoding, and
3067	 * we want to minimise the work done in
3068	 * the irq handler. Use a request to
3069	 * extract the data - Jean II */
3070	wrqu.data.length = 0;
3071	wrqu.data.flags = 0;
3072	wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
3073}
3074
3075static int airo_thread(void *data)
3076{
3077	struct net_device *dev = data;
3078	struct airo_info *ai = dev->ml_priv;
3079	int locked;
3080
3081	set_freezable();
3082	while (1) {
3083		/* make swsusp happy with our thread */
3084		try_to_freeze();
3085
3086		if (test_bit(JOB_DIE, &ai->jobs))
3087			break;
3088
3089		if (ai->jobs) {
3090			locked = down_interruptible(&ai->sem);
3091		} else {
3092			wait_queue_entry_t wait;
3093
3094			init_waitqueue_entry(&wait, current);
3095			add_wait_queue(&ai->thr_wait, &wait);
3096			for (;;) {
3097				set_current_state(TASK_INTERRUPTIBLE);
3098				if (ai->jobs)
3099					break;
3100				if (ai->expires || ai->scan_timeout) {
3101					if (ai->scan_timeout &&
3102							time_after_eq(jiffies, ai->scan_timeout)) {
3103						set_bit(JOB_SCAN_RESULTS, &ai->jobs);
3104						break;
3105					} else if (ai->expires &&
3106							time_after_eq(jiffies, ai->expires)) {
3107						set_bit(JOB_AUTOWEP, &ai->jobs);
3108						break;
3109					}
3110					if (!kthread_should_stop() &&
3111					    !freezing(current)) {
3112						unsigned long wake_at;
3113						if (!ai->expires || !ai->scan_timeout) {
3114							wake_at = max(ai->expires,
3115								ai->scan_timeout);
3116						} else {
3117							wake_at = min(ai->expires,
3118								ai->scan_timeout);
3119						}
3120						schedule_timeout(wake_at - jiffies);
3121						continue;
3122					}
3123				} else if (!kthread_should_stop() &&
3124					   !freezing(current)) {
3125					schedule();
3126					continue;
3127				}
3128				break;
3129			}
3130			__set_current_state(TASK_RUNNING);
3131			remove_wait_queue(&ai->thr_wait, &wait);
3132			locked = 1;
3133		}
3134
3135		if (locked)
3136			continue;
3137
3138		if (test_bit(JOB_DIE, &ai->jobs)) {
3139			up(&ai->sem);
3140			break;
3141		}
3142
3143		if (ai->power.event || test_bit(FLAG_FLASHING, &ai->flags)) {
3144			up(&ai->sem);
3145			continue;
3146		}
3147
3148		if (test_bit(JOB_XMIT, &ai->jobs))
3149			airo_end_xmit(dev, true);
3150		else if (test_bit(JOB_XMIT11, &ai->jobs))
3151			airo_end_xmit11(dev, true);
3152		else if (test_bit(JOB_STATS, &ai->jobs))
3153			airo_read_stats(dev);
 
 
3154		else if (test_bit(JOB_PROMISC, &ai->jobs))
3155			airo_set_promisc(ai, true);
3156		else if (test_bit(JOB_MIC, &ai->jobs))
3157			micinit(ai);
3158		else if (test_bit(JOB_EVENT, &ai->jobs))
3159			airo_send_event(dev);
3160		else if (test_bit(JOB_AUTOWEP, &ai->jobs))
3161			timer_func(dev);
3162		else if (test_bit(JOB_SCAN_RESULTS, &ai->jobs))
3163			airo_process_scan_results(ai);
3164		else  /* Shouldn't get here, but we make sure to unlock */
3165			up(&ai->sem);
3166	}
3167
3168	return 0;
3169}
3170
3171static int header_len(__le16 ctl)
3172{
3173	u16 fc = le16_to_cpu(ctl);
3174	switch (fc & 0xc) {
3175	case 4:
3176		if ((fc & 0xe0) == 0xc0)
3177			return 10;	/* one-address control packet */
3178		return 16;	/* two-address control packet */
3179	case 8:
3180		if ((fc & 0x300) == 0x300)
3181			return 30;	/* WDS packet */
3182	}
3183	return 24;
3184}
3185
3186static void airo_handle_cisco_mic(struct airo_info *ai)
3187{
3188	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
3189		set_bit(JOB_MIC, &ai->jobs);
3190		wake_up_interruptible(&ai->thr_wait);
3191	}
3192}
3193
3194/* Airo Status codes */
3195#define STAT_NOBEACON	0x8000 /* Loss of sync - missed beacons */
3196#define STAT_MAXRETRIES	0x8001 /* Loss of sync - max retries */
3197#define STAT_MAXARL	0x8002 /* Loss of sync - average retry level exceeded*/
3198#define STAT_FORCELOSS	0x8003 /* Loss of sync - host request */
3199#define STAT_TSFSYNC	0x8004 /* Loss of sync - TSF synchronization */
3200#define STAT_DEAUTH	0x8100 /* low byte is 802.11 reason code */
3201#define STAT_DISASSOC	0x8200 /* low byte is 802.11 reason code */
3202#define STAT_ASSOC_FAIL	0x8400 /* low byte is 802.11 reason code */
3203#define STAT_AUTH_FAIL	0x0300 /* low byte is 802.11 reason code */
3204#define STAT_ASSOC	0x0400 /* Associated */
3205#define STAT_REASSOC    0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
3206
3207static void airo_print_status(const char *devname, u16 status)
3208{
3209	u8 reason = status & 0xFF;
3210
3211	switch (status & 0xFF00) {
3212	case STAT_NOBEACON:
3213		switch (status) {
3214		case STAT_NOBEACON:
3215			airo_print_dbg(devname, "link lost (missed beacons)");
3216			break;
3217		case STAT_MAXRETRIES:
3218		case STAT_MAXARL:
3219			airo_print_dbg(devname, "link lost (max retries)");
3220			break;
3221		case STAT_FORCELOSS:
3222			airo_print_dbg(devname, "link lost (local choice)");
3223			break;
3224		case STAT_TSFSYNC:
3225			airo_print_dbg(devname, "link lost (TSF sync lost)");
3226			break;
3227		default:
3228			airo_print_dbg(devname, "unknown status %x\n", status);
3229			break;
3230		}
3231		break;
3232	case STAT_DEAUTH:
3233		airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
3234		break;
3235	case STAT_DISASSOC:
3236		airo_print_dbg(devname, "disassociated (reason: %d)", reason);
3237		break;
3238	case STAT_ASSOC_FAIL:
3239		airo_print_dbg(devname, "association failed (reason: %d)",
3240			       reason);
3241		break;
3242	case STAT_AUTH_FAIL:
3243		airo_print_dbg(devname, "authentication failed (reason: %d)",
3244			       reason);
3245		break;
3246	case STAT_ASSOC:
3247	case STAT_REASSOC:
3248		break;
3249	default:
3250		airo_print_dbg(devname, "unknown status %x\n", status);
3251		break;
3252	}
3253}
3254
3255static void airo_handle_link(struct airo_info *ai)
3256{
3257	union iwreq_data wrqu;
3258	int scan_forceloss = 0;
3259	u16 status;
3260
3261	/* Get new status and acknowledge the link change */
3262	status = le16_to_cpu(IN4500(ai, LINKSTAT));
3263	OUT4500(ai, EVACK, EV_LINK);
3264
3265	if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
3266		scan_forceloss = 1;
3267
3268	airo_print_status(ai->dev->name, status);
3269
3270	if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
3271		if (auto_wep)
3272			ai->expires = 0;
3273		if (ai->list_bss_task)
3274			wake_up_process(ai->list_bss_task);
3275		set_bit(FLAG_UPDATE_UNI, &ai->flags);
3276		set_bit(FLAG_UPDATE_MULTI, &ai->flags);
3277
3278		set_bit(JOB_EVENT, &ai->jobs);
3279		wake_up_interruptible(&ai->thr_wait);
3280
 
 
3281		netif_carrier_on(ai->dev);
3282	} else if (!scan_forceloss) {
3283		if (auto_wep && !ai->expires) {
3284			ai->expires = RUN_AT(3*HZ);
3285			wake_up_interruptible(&ai->thr_wait);
3286		}
3287
3288		/* Send event to user space */
3289		eth_zero_addr(wrqu.ap_addr.sa_data);
3290		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3291		wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
3292		netif_carrier_off(ai->dev);
3293	} else {
3294		netif_carrier_off(ai->dev);
3295	}
3296}
3297
3298static void airo_handle_rx(struct airo_info *ai)
3299{
3300	struct sk_buff *skb = NULL;
3301	__le16 fc, v, *buffer, tmpbuf[4];
3302	u16 len, hdrlen = 0, gap, fid;
3303	struct rx_hdr hdr;
3304	int success = 0;
3305
3306	if (test_bit(FLAG_MPI, &ai->flags)) {
3307		if (test_bit(FLAG_802_11, &ai->flags))
3308			mpi_receive_802_11(ai);
3309		else
3310			mpi_receive_802_3(ai);
3311		OUT4500(ai, EVACK, EV_RX);
3312		return;
3313	}
3314
3315	fid = IN4500(ai, RXFID);
3316
3317	/* Get the packet length */
3318	if (test_bit(FLAG_802_11, &ai->flags)) {
3319		bap_setup (ai, fid, 4, BAP0);
3320		bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
3321		/* Bad CRC. Ignore packet */
3322		if (le16_to_cpu(hdr.status) & 2)
3323			hdr.len = 0;
3324		if (ai->wifidev == NULL)
3325			hdr.len = 0;
3326	} else {
3327		bap_setup(ai, fid, 0x36, BAP0);
3328		bap_read(ai, &hdr.len, 2, BAP0);
3329	}
3330	len = le16_to_cpu(hdr.len);
3331
3332	if (len > AIRO_DEF_MTU) {
3333		airo_print_err(ai->dev->name, "Bad size %d", len);
3334		goto done;
3335	}
3336	if (len == 0)
3337		goto done;
3338
3339	if (test_bit(FLAG_802_11, &ai->flags)) {
3340		bap_read(ai, &fc, sizeof (fc), BAP0);
3341		hdrlen = header_len(fc);
3342	} else
3343		hdrlen = ETH_ALEN * 2;
3344
3345	skb = dev_alloc_skb(len + hdrlen + 2 + 2);
3346	if (!skb) {
3347		ai->dev->stats.rx_dropped++;
3348		goto done;
3349	}
3350
3351	skb_reserve(skb, 2); /* This way the IP header is aligned */
3352	buffer = skb_put(skb, len + hdrlen);
3353	if (test_bit(FLAG_802_11, &ai->flags)) {
3354		buffer[0] = fc;
3355		bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
3356		if (hdrlen == 24)
3357			bap_read(ai, tmpbuf, 6, BAP0);
3358
3359		bap_read(ai, &v, sizeof(v), BAP0);
3360		gap = le16_to_cpu(v);
3361		if (gap) {
3362			if (gap <= 8) {
3363				bap_read(ai, tmpbuf, gap, BAP0);
3364			} else {
3365				airo_print_err(ai->dev->name, "gaplen too "
3366					"big. Problems will follow...");
3367			}
3368		}
3369		bap_read(ai, buffer + hdrlen/2, len, BAP0);
3370	} else {
3371		MICBuffer micbuf;
3372
3373		bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
3374		if (ai->micstats.enabled) {
3375			bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
3376			if (ntohs(micbuf.typelen) > 0x05DC)
3377				bap_setup(ai, fid, 0x44, BAP0);
3378			else {
3379				if (len <= sizeof (micbuf)) {
3380					dev_kfree_skb_irq(skb);
3381					goto done;
3382				}
3383
3384				len -= sizeof(micbuf);
3385				skb_trim(skb, len + hdrlen);
3386			}
3387		}
3388
3389		bap_read(ai, buffer + ETH_ALEN, len, BAP0);
3390		if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
3391			dev_kfree_skb_irq (skb);
3392		else
3393			success = 1;
3394	}
3395
3396#ifdef WIRELESS_SPY
3397	if (success && (ai->spy_data.spy_number > 0)) {
3398		char *sa;
3399		struct iw_quality wstats;
3400
3401		/* Prepare spy data : addr + qual */
3402		if (!test_bit(FLAG_802_11, &ai->flags)) {
3403			sa = (char *) buffer + 6;
3404			bap_setup(ai, fid, 8, BAP0);
3405			bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
3406		} else
3407			sa = (char *) buffer + 10;
3408		wstats.qual = hdr.rssi[0];
3409		if (ai->rssi)
3410			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3411		else
3412			wstats.level = (hdr.rssi[1] + 321) / 2;
3413		wstats.noise = ai->wstats.qual.noise;
3414		wstats.updated =  IW_QUAL_LEVEL_UPDATED
3415				| IW_QUAL_QUAL_UPDATED
3416				| IW_QUAL_DBM;
3417		/* Update spy records */
3418		wireless_spy_update(ai->dev, sa, &wstats);
3419	}
3420#endif /* WIRELESS_SPY */
3421
3422done:
3423	OUT4500(ai, EVACK, EV_RX);
3424
3425	if (success) {
3426		if (test_bit(FLAG_802_11, &ai->flags)) {
3427			skb_reset_mac_header(skb);
3428			skb->pkt_type = PACKET_OTHERHOST;
3429			skb->dev = ai->wifidev;
3430			skb->protocol = htons(ETH_P_802_2);
3431		} else
3432			skb->protocol = eth_type_trans(skb, ai->dev);
3433		skb->ip_summed = CHECKSUM_NONE;
3434
3435		netif_rx(skb);
3436	}
3437}
3438
3439static void airo_handle_tx(struct airo_info *ai, u16 status)
3440{
3441	int i, index = -1;
3442	u16 fid;
3443
3444	if (test_bit(FLAG_MPI, &ai->flags)) {
3445		unsigned long flags;
3446
3447		if (status & EV_TXEXC)
3448			get_tx_error(ai, -1);
3449
3450		spin_lock_irqsave(&ai->aux_lock, flags);
3451		if (!skb_queue_empty(&ai->txq)) {
3452			spin_unlock_irqrestore(&ai->aux_lock, flags);
3453			mpi_send_packet(ai->dev);
3454		} else {
3455			clear_bit(FLAG_PENDING_XMIT, &ai->flags);
3456			spin_unlock_irqrestore(&ai->aux_lock, flags);
3457			netif_wake_queue(ai->dev);
3458		}
3459		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3460		return;
3461	}
3462
3463	fid = IN4500(ai, TXCOMPLFID);
3464
3465	for (i = 0; i < MAX_FIDS; i++) {
3466		if ((ai->fids[i] & 0xffff) == fid)
 
3467			index = i;
 
3468	}
3469
3470	if (index != -1) {
3471		if (status & EV_TXEXC)
3472			get_tx_error(ai, index);
3473
3474		OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
3475
3476		/* Set up to be used again */
3477		ai->fids[index] &= 0xffff;
3478		if (index < MAX_FIDS / 2) {
3479			if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
3480				netif_wake_queue(ai->dev);
3481		} else {
3482			if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
3483				netif_wake_queue(ai->wifidev);
3484		}
3485	} else {
3486		OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3487		airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
3488	}
3489}
3490
3491static irqreturn_t airo_interrupt(int irq, void *dev_id)
3492{
3493	struct net_device *dev = dev_id;
3494	u16 status, savedInterrupts = 0;
3495	struct airo_info *ai = dev->ml_priv;
3496	int handled = 0;
3497
3498	if (!netif_device_present(dev))
3499		return IRQ_NONE;
3500
3501	for (;;) {
3502		status = IN4500(ai, EVSTAT);
3503		if (!(status & STATUS_INTS) || (status == 0xffff))
3504			break;
3505
3506		handled = 1;
3507
3508		if (status & EV_AWAKE) {
3509			OUT4500(ai, EVACK, EV_AWAKE);
3510			OUT4500(ai, EVACK, EV_AWAKE);
3511		}
3512
3513		if (!savedInterrupts) {
3514			savedInterrupts = IN4500(ai, EVINTEN);
3515			OUT4500(ai, EVINTEN, 0);
3516		}
3517
3518		if (status & EV_MIC) {
3519			OUT4500(ai, EVACK, EV_MIC);
3520			airo_handle_cisco_mic(ai);
3521		}
3522
3523		if (status & EV_LINK) {
3524			/* Link status changed */
3525			airo_handle_link(ai);
3526		}
3527
3528		/* Check to see if there is something to receive */
3529		if (status & EV_RX)
3530			airo_handle_rx(ai);
3531
3532		/* Check to see if a packet has been transmitted */
3533		if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
3534			airo_handle_tx(ai, status);
3535
3536		if (status & ~STATUS_INTS & ~IGNORE_INTS) {
3537			airo_print_warn(ai->dev->name, "Got weird status %x",
3538				status & ~STATUS_INTS & ~IGNORE_INTS);
3539		}
3540	}
3541
3542	if (savedInterrupts)
3543		OUT4500(ai, EVINTEN, savedInterrupts);
3544
3545	return IRQ_RETVAL(handled);
3546}
3547
3548/*
3549 *  Routines to talk to the card
3550 */
3551
3552/*
3553 *  This was originally written for the 4500, hence the name
3554 *  NOTE:  If use with 8bit mode and SMP bad things will happen!
3555 *         Why would some one do 8 bit IO in an SMP machine?!?
3556 */
3557static void OUT4500(struct airo_info *ai, u16 reg, u16 val)
3558{
3559	if (test_bit(FLAG_MPI,&ai->flags))
3560		reg <<= 1;
3561	if (!do8bitIO)
3562		outw(val, ai->dev->base_addr + reg);
3563	else {
3564		outb(val & 0xff, ai->dev->base_addr + reg);
3565		outb(val >> 8, ai->dev->base_addr + reg + 1);
3566	}
3567}
3568
3569static u16 IN4500(struct airo_info *ai, u16 reg)
3570{
3571	unsigned short rc;
3572
3573	if (test_bit(FLAG_MPI,&ai->flags))
3574		reg <<= 1;
3575	if (!do8bitIO)
3576		rc = inw(ai->dev->base_addr + reg);
3577	else {
3578		rc = inb(ai->dev->base_addr + reg);
3579		rc += ((int)inb(ai->dev->base_addr + reg + 1)) << 8;
3580	}
3581	return rc;
3582}
3583
3584static int enable_MAC(struct airo_info *ai, int lock)
3585{
3586	int rc;
3587	Cmd cmd;
3588	Resp rsp;
3589
3590	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3591	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3592	 * Note : we could try to use !netif_running(dev) in enable_MAC()
3593	 * instead of this flag, but I don't trust it *within* the
3594	 * open/close functions, and testing both flags together is
3595	 * "cheaper" - Jean II */
3596	if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3597
3598	if (lock && down_interruptible(&ai->sem))
3599		return -ERESTARTSYS;
3600
3601	if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3602		memset(&cmd, 0, sizeof(cmd));
3603		cmd.cmd = MAC_ENABLE;
3604		rc = issuecommand(ai, &cmd, &rsp, true);
3605		if (rc == SUCCESS)
3606			set_bit(FLAG_ENABLED, &ai->flags);
3607	} else
3608		rc = SUCCESS;
3609
3610	if (lock)
3611	    up(&ai->sem);
3612
3613	if (rc)
3614		airo_print_err(ai->dev->name, "Cannot enable MAC");
3615	else if ((rsp.status & 0xFF00) != 0) {
3616		airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
3617			"rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
3618		rc = ERROR;
3619	}
3620	return rc;
3621}
3622
3623static void disable_MAC(struct airo_info *ai, int lock)
3624{
3625        Cmd cmd;
3626	Resp rsp;
3627
3628	if (lock == 1 && down_interruptible(&ai->sem))
3629		return;
3630
3631	if (test_bit(FLAG_ENABLED, &ai->flags)) {
3632		if (lock != 2) /* lock == 2 means don't disable carrier */
3633			netif_carrier_off(ai->dev);
3634		memset(&cmd, 0, sizeof(cmd));
3635		cmd.cmd = MAC_DISABLE; // disable in case already enabled
3636		issuecommand(ai, &cmd, &rsp, true);
3637		clear_bit(FLAG_ENABLED, &ai->flags);
3638	}
3639	if (lock == 1)
3640		up(&ai->sem);
3641}
3642
3643static void enable_interrupts(struct airo_info *ai)
3644{
3645	/* Enable the interrupts */
3646	OUT4500(ai, EVINTEN, STATUS_INTS);
3647}
3648
3649static void disable_interrupts(struct airo_info *ai)
3650{
3651	OUT4500(ai, EVINTEN, 0);
3652}
3653
3654static void mpi_receive_802_3(struct airo_info *ai)
3655{
3656	RxFid rxd;
3657	int len = 0;
3658	struct sk_buff *skb;
3659	char *buffer;
3660	int off = 0;
3661	MICBuffer micbuf;
3662
3663	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3664	/* Make sure we got something */
3665	if (rxd.rdy && rxd.valid == 0) {
3666		len = rxd.len + 12;
3667		if (len < 12 || len > 2048)
3668			goto badrx;
3669
3670		skb = dev_alloc_skb(len);
3671		if (!skb) {
3672			ai->dev->stats.rx_dropped++;
3673			goto badrx;
3674		}
3675		buffer = skb_put(skb, len);
3676		memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3677		if (ai->micstats.enabled) {
3678			memcpy(&micbuf,
3679				ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3680				sizeof(micbuf));
3681			if (ntohs(micbuf.typelen) <= 0x05DC) {
3682				if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3683					goto badmic;
3684
3685				off = sizeof(micbuf);
3686				skb_trim (skb, len - off);
3687			}
3688		}
3689		memcpy(buffer + ETH_ALEN * 2,
3690			ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3691			len - ETH_ALEN * 2 - off);
3692		if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3693badmic:
3694			dev_kfree_skb_irq (skb);
3695			goto badrx;
3696		}
3697#ifdef WIRELESS_SPY
3698		if (ai->spy_data.spy_number > 0) {
3699			char *sa;
3700			struct iw_quality wstats;
3701			/* Prepare spy data : addr + qual */
3702			sa = buffer + ETH_ALEN;
3703			wstats.qual = 0; /* XXX Where do I get that info from ??? */
3704			wstats.level = 0;
3705			wstats.updated = 0;
3706			/* Update spy records */
3707			wireless_spy_update(ai->dev, sa, &wstats);
3708		}
3709#endif /* WIRELESS_SPY */
3710
3711		skb->ip_summed = CHECKSUM_NONE;
3712		skb->protocol = eth_type_trans(skb, ai->dev);
3713		netif_rx(skb);
3714	}
3715badrx:
3716	if (rxd.valid == 0) {
3717		rxd.valid = 1;
3718		rxd.rdy = 0;
3719		rxd.len = PKTSIZE;
3720		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3721	}
3722}
3723
3724static void mpi_receive_802_11(struct airo_info *ai)
3725{
3726	RxFid rxd;
3727	struct sk_buff *skb = NULL;
3728	u16 len, hdrlen = 0;
3729	__le16 fc;
3730	struct rx_hdr hdr;
3731	u16 gap;
3732	u16 *buffer;
3733	char *ptr = ai->rxfids[0].virtual_host_addr + 4;
3734
3735	memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3736	memcpy ((char *)&hdr, ptr, sizeof(hdr));
3737	ptr += sizeof(hdr);
3738	/* Bad CRC. Ignore packet */
3739	if (le16_to_cpu(hdr.status) & 2)
3740		hdr.len = 0;
3741	if (ai->wifidev == NULL)
3742		hdr.len = 0;
3743	len = le16_to_cpu(hdr.len);
3744	if (len > AIRO_DEF_MTU) {
3745		airo_print_err(ai->dev->name, "Bad size %d", len);
3746		goto badrx;
3747	}
3748	if (len == 0)
3749		goto badrx;
3750
3751	fc = get_unaligned((__le16 *)ptr);
3752	hdrlen = header_len(fc);
3753
3754	skb = dev_alloc_skb(len + hdrlen + 2);
3755	if (!skb) {
3756		ai->dev->stats.rx_dropped++;
3757		goto badrx;
3758	}
3759	buffer = skb_put(skb, len + hdrlen);
3760	memcpy ((char *)buffer, ptr, hdrlen);
3761	ptr += hdrlen;
3762	if (hdrlen == 24)
3763		ptr += 6;
3764	gap = get_unaligned_le16(ptr);
3765	ptr += sizeof(__le16);
3766	if (gap) {
3767		if (gap <= 8)
3768			ptr += gap;
3769		else
3770			airo_print_err(ai->dev->name,
3771			    "gaplen too big. Problems will follow...");
3772	}
3773	memcpy ((char *)buffer + hdrlen, ptr, len);
3774	ptr += len;
3775#ifdef IW_WIRELESS_SPY	  /* defined in iw_handler.h */
3776	if (ai->spy_data.spy_number > 0) {
3777		char *sa;
3778		struct iw_quality wstats;
3779		/* Prepare spy data : addr + qual */
3780		sa = (char*)buffer + 10;
3781		wstats.qual = hdr.rssi[0];
3782		if (ai->rssi)
3783			wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3784		else
3785			wstats.level = (hdr.rssi[1] + 321) / 2;
3786		wstats.noise = ai->wstats.qual.noise;
3787		wstats.updated = IW_QUAL_QUAL_UPDATED
3788			| IW_QUAL_LEVEL_UPDATED
3789			| IW_QUAL_DBM;
3790		/* Update spy records */
3791		wireless_spy_update(ai->dev, sa, &wstats);
3792	}
3793#endif /* IW_WIRELESS_SPY */
3794	skb_reset_mac_header(skb);
3795	skb->pkt_type = PACKET_OTHERHOST;
3796	skb->dev = ai->wifidev;
3797	skb->protocol = htons(ETH_P_802_2);
3798	skb->ip_summed = CHECKSUM_NONE;
3799	netif_rx(skb);
3800
3801badrx:
3802	if (rxd.valid == 0) {
3803		rxd.valid = 1;
3804		rxd.rdy = 0;
3805		rxd.len = PKTSIZE;
3806		memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3807	}
3808}
3809
3810static inline void set_auth_type(struct airo_info *local, int auth_type)
3811{
3812	local->config.authType = auth_type;
3813	/* Cache the last auth type used (of AUTH_OPEN and AUTH_ENCRYPT).
3814	 * Used by airo_set_auth()
3815	 */
3816	if (auth_type == AUTH_OPEN || auth_type == AUTH_ENCRYPT)
3817		local->last_auth = auth_type;
3818}
3819
3820static int noinline_for_stack airo_readconfig(struct airo_info *ai,
3821					      struct net_device *dev, int lock)
3822{
3823	int i, status;
3824	/* large variables, so don't inline this function,
3825	 * maybe change to kmalloc
3826	 */
3827	tdsRssiRid rssi_rid;
3828	CapabilityRid cap_rid;
3829
3830	kfree(ai->SSID);
3831	ai->SSID = NULL;
3832	// general configuration (read/modify/write)
3833	status = readConfigRid(ai, lock);
3834	if (status != SUCCESS) return ERROR;
3835
3836	status = readCapabilityRid(ai, &cap_rid, lock);
3837	if (status != SUCCESS) return ERROR;
3838
3839	status = PC4500_readrid(ai, RID_RSSI, &rssi_rid, sizeof(rssi_rid), lock);
3840	if (status == SUCCESS) {
3841		if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3842			memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
3843	}
3844	else {
3845		kfree(ai->rssi);
3846		ai->rssi = NULL;
3847		if (cap_rid.softCap & cpu_to_le16(8))
3848			ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3849		else
3850			airo_print_warn(ai->dev->name, "unknown received signal "
3851					"level scale");
3852	}
3853	ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3854	set_auth_type(ai, AUTH_OPEN);
3855	ai->config.modulation = MOD_CCK;
3856
3857	if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
3858	    (cap_rid.extSoftCap & cpu_to_le16(1)) &&
3859	    micsetup(ai) == SUCCESS) {
3860		ai->config.opmode |= MODE_MIC;
3861		set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3862	}
3863
3864	/* Save off the MAC */
3865	eth_hw_addr_set(dev, ai->config.macAddr);
3866
3867	/* Check to see if there are any insmod configured
3868	   rates to add */
3869	if (rates[0]) {
3870		memset(ai->config.rates, 0, sizeof(ai->config.rates));
3871		for (i = 0; i < 8 && rates[i]; i++) {
3872			ai->config.rates[i] = rates[i];
3873		}
3874	}
3875	set_bit (FLAG_COMMIT, &ai->flags);
3876
3877	return SUCCESS;
3878}
3879
3880
3881static u16 setup_card(struct airo_info *ai, struct net_device *dev, int lock)
3882{
3883	Cmd cmd;
3884	Resp rsp;
3885	int status;
3886	SsidRid mySsid;
3887	__le16 lastindex;
3888	WepKeyRid wkr;
3889	int rc;
3890
3891	memset(&mySsid, 0, sizeof(mySsid));
3892	kfree (ai->flash);
3893	ai->flash = NULL;
3894
3895	/* The NOP is the first step in getting the card going */
3896	cmd.cmd = NOP;
3897	cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3898	if (lock && down_interruptible(&ai->sem))
3899		return ERROR;
3900	if (issuecommand(ai, &cmd, &rsp, true) != SUCCESS) {
3901		if (lock)
3902			up(&ai->sem);
3903		return ERROR;
3904	}
3905	disable_MAC(ai, 0);
3906
3907	// Let's figure out if we need to use the AUX port
3908	if (!test_bit(FLAG_MPI,&ai->flags)) {
3909		cmd.cmd = CMD_ENABLEAUX;
3910		if (issuecommand(ai, &cmd, &rsp, true) != SUCCESS) {
3911			if (lock)
3912				up(&ai->sem);
3913			airo_print_err(ai->dev->name, "Error checking for AUX port");
3914			return ERROR;
3915		}
3916		if (!aux_bap || rsp.status & 0xff00) {
3917			ai->bap_read = fast_bap_read;
3918			airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
3919		} else {
3920			ai->bap_read = aux_bap_read;
3921			airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
3922		}
3923	}
3924	if (lock)
3925		up(&ai->sem);
3926	if (ai->config.len == 0) {
3927		status = airo_readconfig(ai, dev, lock);
3928		if (status != SUCCESS)
3929			return ERROR;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3930	}
3931
3932	/* Setup the SSIDs if present */
3933	if (ssids[0]) {
3934		int i;
3935		for (i = 0; i < 3 && ssids[i]; i++) {
3936			size_t len = strlen(ssids[i]);
3937			if (len > 32)
3938				len = 32;
3939			mySsid.ssids[i].len = cpu_to_le16(len);
3940			memcpy(mySsid.ssids[i].ssid, ssids[i], len);
3941		}
3942		mySsid.len = cpu_to_le16(sizeof(mySsid));
3943	}
3944
3945	status = writeConfigRid(ai, lock);
3946	if (status != SUCCESS) return ERROR;
3947
3948	/* Set up the SSID list */
3949	if (ssids[0]) {
3950		status = writeSsidRid(ai, &mySsid, lock);
3951		if (status != SUCCESS) return ERROR;
3952	}
3953
3954	status = enable_MAC(ai, lock);
3955	if (status != SUCCESS)
3956		return ERROR;
3957
3958	/* Grab the initial wep key, we gotta save it for auto_wep */
3959	rc = readWepKeyRid(ai, &wkr, 1, lock);
3960	if (rc == SUCCESS) do {
3961		lastindex = wkr.kindex;
3962		if (wkr.kindex == cpu_to_le16(0xffff)) {
3963			ai->defindex = wkr.mac[0];
3964		}
3965		rc = readWepKeyRid(ai, &wkr, 0, lock);
3966	} while (lastindex != wkr.kindex);
3967
3968	try_auto_wep(ai);
3969
3970	return SUCCESS;
3971}
3972
3973static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp,
3974			bool may_sleep)
3975{
3976        // Im really paranoid about letting it run forever!
3977	int max_tries = 600000;
3978
3979	if (IN4500(ai, EVSTAT) & EV_CMD)
3980		OUT4500(ai, EVACK, EV_CMD);
3981
3982	OUT4500(ai, PARAM0, pCmd->parm0);
3983	OUT4500(ai, PARAM1, pCmd->parm1);
3984	OUT4500(ai, PARAM2, pCmd->parm2);
3985	OUT4500(ai, COMMAND, pCmd->cmd);
3986
3987	while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3988		if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3989			// PC4500 didn't notice command, try again
3990			OUT4500(ai, COMMAND, pCmd->cmd);
3991		if (may_sleep && (max_tries & 255) == 0)
3992			cond_resched();
3993	}
3994
3995	if (max_tries == -1) {
3996		airo_print_err(ai->dev->name,
3997			"Max tries exceeded when issuing command");
3998		if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3999			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
4000		return ERROR;
4001	}
4002
4003	// command completed
4004	pRsp->status = IN4500(ai, STATUS);
4005	pRsp->rsp0 = IN4500(ai, RESP0);
4006	pRsp->rsp1 = IN4500(ai, RESP1);
4007	pRsp->rsp2 = IN4500(ai, RESP2);
4008	if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
4009		airo_print_err(ai->dev->name,
4010			"cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
4011			pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
4012			pRsp->rsp2);
4013
4014	// clear stuck command busy if necessary
4015	if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
4016		OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
4017	}
4018	// acknowledge processing the status/response
4019	OUT4500(ai, EVACK, EV_CMD);
4020
4021	return SUCCESS;
4022}
4023
4024/* Sets up the bap to start exchange data.  whichbap should
4025 * be one of the BAP0 or BAP1 defines.  Locks should be held before
4026 * calling! */
4027static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap)
4028{
4029	int timeout = 50;
4030	int max_tries = 3;
4031
4032	OUT4500(ai, SELECT0+whichbap, rid);
4033	OUT4500(ai, OFFSET0+whichbap, offset);
4034	while (1) {
4035		int status = IN4500(ai, OFFSET0+whichbap);
4036		if (status & BAP_BUSY) {
4037                        /* This isn't really a timeout, but its kinda
4038			   close */
4039			if (timeout--) {
4040				continue;
4041			}
4042		} else if (status & BAP_ERR) {
4043			/* invalid rid or offset */
4044			airo_print_err(ai->dev->name, "BAP error %x %d",
4045				status, whichbap);
4046			return ERROR;
4047		} else if (status & BAP_DONE) { // success
4048			return SUCCESS;
4049		}
4050		if (!(max_tries--)) {
4051			airo_print_err(ai->dev->name,
4052				"BAP setup error too many retries\n");
4053			return ERROR;
4054		}
4055		// -- PC4500 missed it, try again
4056		OUT4500(ai, SELECT0+whichbap, rid);
4057		OUT4500(ai, OFFSET0+whichbap, offset);
4058		timeout = 50;
4059	}
4060}
4061
4062/* should only be called by aux_bap_read.  This aux function and the
4063   following use concepts not documented in the developers guide.  I
4064   got them from a patch given to my by Aironet */
4065static u16 aux_setup(struct airo_info *ai, u16 page,
4066		     u16 offset, u16 *len)
4067{
4068	u16 next;
4069
4070	OUT4500(ai, AUXPAGE, page);
4071	OUT4500(ai, AUXOFF, 0);
4072	next = IN4500(ai, AUXDATA);
4073	*len = IN4500(ai, AUXDATA)&0xff;
4074	if (offset != 4) OUT4500(ai, AUXOFF, offset);
4075	return next;
4076}
4077
4078/* requires call to bap_setup() first */
4079static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4080			int bytelen, int whichbap)
4081{
4082	u16 len;
4083	u16 page;
4084	u16 offset;
4085	u16 next;
4086	int words;
4087	int i;
4088	unsigned long flags;
4089
4090	spin_lock_irqsave(&ai->aux_lock, flags);
4091	page = IN4500(ai, SWS0+whichbap);
4092	offset = IN4500(ai, SWS2+whichbap);
4093	next = aux_setup(ai, page, offset, &len);
4094	words = (bytelen+1)>>1;
4095
4096	for (i = 0; i<words;) {
4097		int count;
4098		count = (len>>1) < (words-i) ? (len>>1) : (words-i);
4099		if (!do8bitIO)
4100			insw(ai->dev->base_addr+DATA0+whichbap,
4101			      pu16Dst+i, count);
4102		else
4103			insb(ai->dev->base_addr+DATA0+whichbap,
4104			      pu16Dst+i, count << 1);
4105		i += count;
4106		if (i<words) {
4107			next = aux_setup(ai, next, 4, &len);
4108		}
4109	}
4110	spin_unlock_irqrestore(&ai->aux_lock, flags);
4111	return SUCCESS;
4112}
4113
4114
4115/* requires call to bap_setup() first */
4116static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
4117			 int bytelen, int whichbap)
4118{
4119	bytelen = (bytelen + 1) & (~1); // round up to even value
4120	if (!do8bitIO)
4121		insw(ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1);
4122	else
4123		insb(ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen);
4124	return SUCCESS;
4125}
4126
4127/* requires call to bap_setup() first */
4128static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
4129		     int bytelen, int whichbap)
4130{
4131	bytelen = (bytelen + 1) & (~1); // round up to even value
4132	if (!do8bitIO)
4133		outsw(ai->dev->base_addr+DATA0+whichbap,
4134		       pu16Src, bytelen>>1);
4135	else
4136		outsb(ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen);
4137	return SUCCESS;
4138}
4139
4140static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
4141{
4142	Cmd cmd; /* for issuing commands */
4143	Resp rsp; /* response from commands */
4144	u16 status;
4145
4146	memset(&cmd, 0, sizeof(cmd));
4147	cmd.cmd = accmd;
4148	cmd.parm0 = rid;
4149	status = issuecommand(ai, &cmd, &rsp, true);
4150	if (status != 0) return status;
4151	if ((rsp.status & 0x7F00) != 0) {
4152		return (accmd << 8) + (rsp.rsp0 & 0xFF);
4153	}
4154	return 0;
4155}
4156
4157/*  Note, that we are using BAP1 which is also used by transmit, so
4158 *  we must get a lock. */
4159static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
4160{
4161	u16 status;
4162        int rc = SUCCESS;
4163
4164	if (lock) {
4165		if (down_interruptible(&ai->sem))
4166			return ERROR;
4167	}
4168	if (test_bit(FLAG_MPI,&ai->flags)) {
4169		Cmd cmd;
4170		Resp rsp;
4171
4172		memset(&cmd, 0, sizeof(cmd));
4173		memset(&rsp, 0, sizeof(rsp));
4174		ai->config_desc.rid_desc.valid = 1;
4175		ai->config_desc.rid_desc.len = RIDSIZE;
4176		ai->config_desc.rid_desc.rid = 0;
4177		ai->config_desc.rid_desc.host_addr = ai->ridbus;
4178
4179		cmd.cmd = CMD_ACCESS;
4180		cmd.parm0 = rid;
4181
4182		memcpy_toio(ai->config_desc.card_ram_off,
4183			&ai->config_desc.rid_desc, sizeof(Rid));
4184
4185		rc = issuecommand(ai, &cmd, &rsp, true);
4186
4187		if (rsp.status & 0x7f00)
4188			rc = rsp.rsp0;
4189		if (!rc)
4190			memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
4191		goto done;
4192	} else {
4193		if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4194	                rc = status;
4195	                goto done;
4196	        }
4197		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4198			rc = ERROR;
4199	                goto done;
4200	        }
4201		// read the rid length field
4202		bap_read(ai, pBuf, 2, BAP1);
4203		// length for remaining part of rid
4204		len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
4205
4206		if (len <= 2) {
4207			airo_print_err(ai->dev->name,
4208				"Rid %x has a length of %d which is too short",
4209				(int)rid, (int)len);
4210			rc = ERROR;
4211	                goto done;
4212		}
4213		// read remainder of the rid
4214		rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
4215	}
4216done:
4217	if (lock)
4218		up(&ai->sem);
4219	return rc;
4220}
4221
4222/*  Note, that we are using BAP1 which is also used by transmit, so
4223 *  make sure this isn't called when a transmit is happening */
4224static int PC4500_writerid(struct airo_info *ai, u16 rid,
4225			   const void *pBuf, int len, int lock)
4226{
4227	u16 status;
4228	int rc = SUCCESS;
4229
4230	*(__le16*)pBuf = cpu_to_le16((u16)len);
4231
4232	if (lock) {
4233		if (down_interruptible(&ai->sem))
4234			return ERROR;
4235	}
4236	if (test_bit(FLAG_MPI,&ai->flags)) {
4237		Cmd cmd;
4238		Resp rsp;
4239
4240		if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
4241			airo_print_err(ai->dev->name,
4242				"%s: MAC should be disabled (rid=%04x)",
4243				__func__, rid);
4244		memset(&cmd, 0, sizeof(cmd));
4245		memset(&rsp, 0, sizeof(rsp));
4246
4247		ai->config_desc.rid_desc.valid = 1;
4248		ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4249		ai->config_desc.rid_desc.rid = 0;
4250
4251		cmd.cmd = CMD_WRITERID;
4252		cmd.parm0 = rid;
4253
4254		memcpy_toio(ai->config_desc.card_ram_off,
4255			&ai->config_desc.rid_desc, sizeof(Rid));
4256
4257		if (len < 4 || len > 2047) {
4258			airo_print_err(ai->dev->name, "%s: len=%d", __func__, len);
4259			rc = -1;
4260		} else {
4261			memcpy(ai->config_desc.virtual_host_addr,
4262				pBuf, len);
4263
4264			rc = issuecommand(ai, &cmd, &rsp, true);
4265			if ((rc & 0xff00) != 0) {
4266				airo_print_err(ai->dev->name, "%s: Write rid Error %d",
4267						__func__, rc);
4268				airo_print_err(ai->dev->name, "%s: Cmd=%04x",
4269						__func__, cmd.cmd);
4270			}
4271
4272			if ((rsp.status & 0x7f00))
4273				rc = rsp.rsp0;
4274		}
4275	} else {
4276		// --- first access so that we can write the rid data
4277		if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4278	                rc = status;
4279	                goto done;
4280	        }
4281		// --- now write the rid data
4282		if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4283	                rc = ERROR;
4284	                goto done;
4285	        }
4286		bap_write(ai, pBuf, len, BAP1);
4287		// ---now commit the rid data
4288		rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4289	}
4290done:
4291	if (lock)
4292		up(&ai->sem);
4293        return rc;
4294}
4295
4296/* Allocates a FID to be used for transmitting packets.  We only use
4297   one for now. */
4298static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4299{
4300	unsigned int loop = 3000;
4301	Cmd cmd;
4302	Resp rsp;
4303	u16 txFid;
4304	__le16 txControl;
4305
4306	cmd.cmd = CMD_ALLOCATETX;
4307	cmd.parm0 = lenPayload;
4308	if (down_interruptible(&ai->sem))
4309		return ERROR;
4310	if (issuecommand(ai, &cmd, &rsp, true) != SUCCESS) {
4311		txFid = ERROR;
4312		goto done;
4313	}
4314	if ((rsp.status & 0xFF00) != 0) {
4315		txFid = ERROR;
4316		goto done;
4317	}
4318	/* wait for the allocate event/indication
4319	 * It makes me kind of nervous that this can just sit here and spin,
4320	 * but in practice it only loops like four times. */
4321	while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4322	if (!loop) {
4323		txFid = ERROR;
4324		goto done;
4325	}
4326
4327	// get the allocated fid and acknowledge
4328	txFid = IN4500(ai, TXALLOCFID);
4329	OUT4500(ai, EVACK, EV_ALLOC);
4330
4331	/*  The CARD is pretty cool since it converts the ethernet packet
4332	 *  into 802.11.  Also note that we don't release the FID since we
4333	 *  will be using the same one over and over again. */
4334	/*  We only have to setup the control once since we are not
4335	 *  releasing the fid. */
4336	if (raw)
4337		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4338			| TXCTL_ETHERNET | TXCTL_NORELEASE);
4339	else
4340		txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4341			| TXCTL_ETHERNET | TXCTL_NORELEASE);
4342	if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4343		txFid = ERROR;
4344	else
4345		bap_write(ai, &txControl, sizeof(txControl), BAP1);
4346
4347done:
4348	up(&ai->sem);
4349
4350	return txFid;
4351}
4352
4353/* In general BAP1 is dedicated to transmiting packets.  However,
4354   since we need a BAP when accessing RIDs, we also use BAP1 for that.
4355   Make sure the BAP1 spinlock is held when this is called. */
4356static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket,
4357				 bool may_sleep)
4358{
4359	__le16 payloadLen;
4360	Cmd cmd;
4361	Resp rsp;
4362	int miclen = 0;
4363	u16 txFid = len;
4364	MICBuffer pMic;
4365
4366	len >>= 16;
4367
4368	if (len <= ETH_ALEN * 2) {
4369		airo_print_warn(ai->dev->name, "Short packet %d", len);
4370		return ERROR;
4371	}
4372	len -= ETH_ALEN * 2;
4373
4374	if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
4375	    (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
4376		if (encapsulate(ai, (etherHead *)pPacket,&pMic, len) != SUCCESS)
4377			return ERROR;
4378		miclen = sizeof(pMic);
4379	}
4380	// packet is destination[6], source[6], payload[len-12]
4381	// write the payload length and dst/src/payload
4382	if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4383	/* The hardware addresses aren't counted as part of the payload, so
4384	 * we have to subtract the 12 bytes for the addresses off */
4385	payloadLen = cpu_to_le16(len + miclen);
4386	bap_write(ai, &payloadLen, sizeof(payloadLen), BAP1);
4387	bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
4388	if (miclen)
4389		bap_write(ai, (__le16*)&pMic, miclen, BAP1);
4390	bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
4391	// issue the transmit command
4392	memset(&cmd, 0, sizeof(cmd));
4393	cmd.cmd = CMD_TRANSMIT;
4394	cmd.parm0 = txFid;
4395	if (issuecommand(ai, &cmd, &rsp, may_sleep) != SUCCESS)
4396		return ERROR;
4397	if ((rsp.status & 0xFF00) != 0) return ERROR;
4398	return SUCCESS;
4399}
4400
4401static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket,
4402				  bool may_sleep)
4403{
4404	__le16 fc, payloadLen;
4405	Cmd cmd;
4406	Resp rsp;
4407	int hdrlen;
4408	static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
4409	/* padding of header to full size + le16 gaplen (6) + gaplen bytes */
4410	u16 txFid = len;
4411	len >>= 16;
4412
4413	fc = *(__le16*)pPacket;
4414	hdrlen = header_len(fc);
4415
4416	if (len < hdrlen) {
4417		airo_print_warn(ai->dev->name, "Short packet %d", len);
4418		return ERROR;
4419	}
4420
4421	/* packet is 802.11 header +  payload
4422	 * write the payload length and dst/src/payload */
4423	if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4424	/* The 802.11 header aren't counted as part of the payload, so
4425	 * we have to subtract the header bytes off */
4426	payloadLen = cpu_to_le16(len-hdrlen);
4427	bap_write(ai, &payloadLen, sizeof(payloadLen), BAP1);
4428	if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4429	bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
4430	bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
4431
4432	bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
4433	// issue the transmit command
4434	memset(&cmd, 0, sizeof(cmd));
4435	cmd.cmd = CMD_TRANSMIT;
4436	cmd.parm0 = txFid;
4437	if (issuecommand(ai, &cmd, &rsp, may_sleep) != SUCCESS)
4438		return ERROR;
4439	if ((rsp.status & 0xFF00) != 0) return ERROR;
4440	return SUCCESS;
4441}
4442
4443/*
4444 *  This is the proc_fs routines.  It is a bit messier than I would
4445 *  like!  Feel free to clean it up!
4446 */
4447
4448static ssize_t proc_read(struct file *file,
4449			  char __user *buffer,
4450			  size_t len,
4451			  loff_t *offset);
4452
4453static ssize_t proc_write(struct file *file,
4454			   const char __user *buffer,
4455			   size_t len,
4456			   loff_t *offset);
4457static int proc_close(struct inode *inode, struct file *file);
4458
4459static int proc_stats_open(struct inode *inode, struct file *file);
4460static int proc_statsdelta_open(struct inode *inode, struct file *file);
4461static int proc_status_open(struct inode *inode, struct file *file);
4462static int proc_SSID_open(struct inode *inode, struct file *file);
4463static int proc_APList_open(struct inode *inode, struct file *file);
4464static int proc_BSSList_open(struct inode *inode, struct file *file);
4465static int proc_config_open(struct inode *inode, struct file *file);
4466static int proc_wepkey_open(struct inode *inode, struct file *file);
4467
4468static const struct proc_ops proc_statsdelta_ops = {
4469	.proc_read	= proc_read,
4470	.proc_open	= proc_statsdelta_open,
4471	.proc_release	= proc_close,
4472	.proc_lseek	= default_llseek,
 
4473};
4474
4475static const struct proc_ops proc_stats_ops = {
4476	.proc_read	= proc_read,
4477	.proc_open	= proc_stats_open,
4478	.proc_release	= proc_close,
4479	.proc_lseek	= default_llseek,
 
4480};
4481
4482static const struct proc_ops proc_status_ops = {
4483	.proc_read	= proc_read,
4484	.proc_open	= proc_status_open,
4485	.proc_release	= proc_close,
4486	.proc_lseek	= default_llseek,
 
4487};
4488
4489static const struct proc_ops proc_SSID_ops = {
4490	.proc_read	= proc_read,
4491	.proc_write	= proc_write,
4492	.proc_open	= proc_SSID_open,
4493	.proc_release	= proc_close,
4494	.proc_lseek	= default_llseek,
 
4495};
4496
4497static const struct proc_ops proc_BSSList_ops = {
4498	.proc_read	= proc_read,
4499	.proc_write	= proc_write,
4500	.proc_open	= proc_BSSList_open,
4501	.proc_release	= proc_close,
4502	.proc_lseek	= default_llseek,
 
4503};
4504
4505static const struct proc_ops proc_APList_ops = {
4506	.proc_read	= proc_read,
4507	.proc_write	= proc_write,
4508	.proc_open	= proc_APList_open,
4509	.proc_release	= proc_close,
4510	.proc_lseek	= default_llseek,
 
4511};
4512
4513static const struct proc_ops proc_config_ops = {
4514	.proc_read	= proc_read,
4515	.proc_write	= proc_write,
4516	.proc_open	= proc_config_open,
4517	.proc_release	= proc_close,
4518	.proc_lseek	= default_llseek,
 
4519};
4520
4521static const struct proc_ops proc_wepkey_ops = {
4522	.proc_read	= proc_read,
4523	.proc_write	= proc_write,
4524	.proc_open	= proc_wepkey_open,
4525	.proc_release	= proc_close,
4526	.proc_lseek	= default_llseek,
 
4527};
4528
4529static struct proc_dir_entry *airo_entry;
4530
4531struct proc_data {
4532	int release_buffer;
4533	int readlen;
4534	char *rbuffer;
4535	int writelen;
4536	int maxwritelen;
4537	char *wbuffer;
4538	void (*on_close) (struct inode *, struct file *);
4539};
4540
4541static int setup_proc_entry(struct net_device *dev,
4542			     struct airo_info *apriv)
4543{
4544	struct proc_dir_entry *entry;
4545
4546	/* First setup the device directory */
4547	strcpy(apriv->proc_name, dev->name);
4548	apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
4549					    airo_entry);
4550	if (!apriv->proc_entry)
4551		return -ENOMEM;
4552	proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
4553
4554	/* Setup the StatsDelta */
4555	entry = proc_create_data("StatsDelta", 0444 & proc_perm,
4556				 apriv->proc_entry, &proc_statsdelta_ops, dev);
4557	if (!entry)
4558		goto fail;
4559	proc_set_user(entry, proc_kuid, proc_kgid);
4560
4561	/* Setup the Stats */
4562	entry = proc_create_data("Stats", 0444 & proc_perm,
4563				 apriv->proc_entry, &proc_stats_ops, dev);
4564	if (!entry)
4565		goto fail;
4566	proc_set_user(entry, proc_kuid, proc_kgid);
4567
4568	/* Setup the Status */
4569	entry = proc_create_data("Status", 0444 & proc_perm,
4570				 apriv->proc_entry, &proc_status_ops, dev);
4571	if (!entry)
4572		goto fail;
4573	proc_set_user(entry, proc_kuid, proc_kgid);
4574
4575	/* Setup the Config */
4576	entry = proc_create_data("Config", proc_perm,
4577				 apriv->proc_entry, &proc_config_ops, dev);
4578	if (!entry)
4579		goto fail;
4580	proc_set_user(entry, proc_kuid, proc_kgid);
4581
4582	/* Setup the SSID */
4583	entry = proc_create_data("SSID", proc_perm,
4584				 apriv->proc_entry, &proc_SSID_ops, dev);
4585	if (!entry)
4586		goto fail;
4587	proc_set_user(entry, proc_kuid, proc_kgid);
4588
4589	/* Setup the APList */
4590	entry = proc_create_data("APList", proc_perm,
4591				 apriv->proc_entry, &proc_APList_ops, dev);
4592	if (!entry)
4593		goto fail;
4594	proc_set_user(entry, proc_kuid, proc_kgid);
4595
4596	/* Setup the BSSList */
4597	entry = proc_create_data("BSSList", proc_perm,
4598				 apriv->proc_entry, &proc_BSSList_ops, dev);
4599	if (!entry)
4600		goto fail;
4601	proc_set_user(entry, proc_kuid, proc_kgid);
4602
4603	/* Setup the WepKey */
4604	entry = proc_create_data("WepKey", proc_perm,
4605				 apriv->proc_entry, &proc_wepkey_ops, dev);
4606	if (!entry)
4607		goto fail;
4608	proc_set_user(entry, proc_kuid, proc_kgid);
4609	return 0;
4610
4611fail:
4612	remove_proc_subtree(apriv->proc_name, airo_entry);
4613	return -ENOMEM;
4614}
4615
4616static int takedown_proc_entry(struct net_device *dev,
4617				struct airo_info *apriv)
4618{
4619	remove_proc_subtree(apriv->proc_name, airo_entry);
4620	return 0;
4621}
4622
4623/*
4624 *  What we want from the proc_fs is to be able to efficiently read
4625 *  and write the configuration.  To do this, we want to read the
4626 *  configuration when the file is opened and write it when the file is
4627 *  closed.  So basically we allocate a read buffer at open and fill it
4628 *  with data, and allocate a write buffer and read it at close.
4629 */
4630
4631/*
4632 *  The read routine is generic, it relies on the preallocated rbuffer
4633 *  to supply the data.
4634 */
4635static ssize_t proc_read(struct file *file,
4636			  char __user *buffer,
4637			  size_t len,
4638			  loff_t *offset)
4639{
4640	struct proc_data *priv = file->private_data;
4641
4642	if (!priv->rbuffer)
4643		return -EINVAL;
4644
4645	return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
4646					priv->readlen);
4647}
4648
4649/*
4650 *  The write routine is generic, it fills in a preallocated rbuffer
4651 *  to supply the data.
4652 */
4653static ssize_t proc_write(struct file *file,
4654			   const char __user *buffer,
4655			   size_t len,
4656			   loff_t *offset)
4657{
4658	ssize_t ret;
4659	struct proc_data *priv = file->private_data;
4660
4661	if (!priv->wbuffer)
4662		return -EINVAL;
4663
4664	ret = simple_write_to_buffer(priv->wbuffer, priv->maxwritelen, offset,
4665					buffer, len);
4666	if (ret > 0)
4667		priv->writelen = max_t(int, priv->writelen, *offset);
4668
4669	return ret;
4670}
4671
4672static int proc_status_open(struct inode *inode, struct file *file)
4673{
4674	struct proc_data *data;
4675	struct net_device *dev = pde_data(inode);
4676	struct airo_info *apriv = dev->ml_priv;
4677	CapabilityRid cap_rid;
4678	StatusRid status_rid;
4679	u16 mode;
4680	int i;
4681
4682	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
4683		return -ENOMEM;
4684	data = file->private_data;
4685	if ((data->rbuffer = kmalloc(2048, GFP_KERNEL)) == NULL) {
4686		kfree (file->private_data);
4687		return -ENOMEM;
4688	}
4689
4690	readStatusRid(apriv, &status_rid, 1);
4691	readCapabilityRid(apriv, &cap_rid, 1);
4692
4693	mode = le16_to_cpu(status_rid.mode);
4694
4695        i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4696                    mode & 1 ? "CFG ": "",
4697                    mode & 2 ? "ACT ": "",
4698                    mode & 0x10 ? "SYN ": "",
4699                    mode & 0x20 ? "LNK ": "",
4700                    mode & 0x40 ? "LEAP ": "",
4701                    mode & 0x80 ? "PRIV ": "",
4702                    mode & 0x100 ? "KEY ": "",
4703                    mode & 0x200 ? "WEP ": "",
4704                    mode & 0x8000 ? "ERR ": "");
4705	sprintf(data->rbuffer+i, "Mode: %x\n"
4706		 "Signal Strength: %d\n"
4707		 "Signal Quality: %d\n"
4708		 "SSID: %-.*s\n"
4709		 "AP: %-.16s\n"
4710		 "Freq: %d\n"
4711		 "BitRate: %dmbs\n"
4712		 "Driver Version: %s\n"
4713		 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4714		 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4715		 "Software Version: %x\nSoftware Subversion: %x\n"
4716		 "Boot block version: %x\n",
4717		 le16_to_cpu(status_rid.mode),
4718		 le16_to_cpu(status_rid.normalizedSignalStrength),
4719		 le16_to_cpu(status_rid.signalQuality),
4720		 le16_to_cpu(status_rid.SSIDlen),
4721		 status_rid.SSID,
4722		 status_rid.apName,
4723		 le16_to_cpu(status_rid.channel),
4724		 le16_to_cpu(status_rid.currentXmitRate) / 2,
4725		 version,
4726		 cap_rid.prodName,
4727		 cap_rid.manName,
4728		 cap_rid.prodVer,
4729		 le16_to_cpu(cap_rid.radioType),
4730		 le16_to_cpu(cap_rid.country),
4731		 le16_to_cpu(cap_rid.hardVer),
4732		 le16_to_cpu(cap_rid.softVer),
4733		 le16_to_cpu(cap_rid.softSubVer),
4734		 le16_to_cpu(cap_rid.bootBlockVer));
4735	data->readlen = strlen(data->rbuffer);
4736	return 0;
4737}
4738
4739static int proc_stats_rid_open(struct inode*, struct file*, u16);
4740static int proc_statsdelta_open(struct inode *inode,
4741				 struct file *file)
4742{
4743	if (file->f_mode&FMODE_WRITE) {
4744		return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4745	}
4746	return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4747}
4748
4749static int proc_stats_open(struct inode *inode, struct file *file)
4750{
4751	return proc_stats_rid_open(inode, file, RID_STATS);
4752}
4753
4754static int proc_stats_rid_open(struct inode *inode,
4755				struct file *file,
4756				u16 rid)
4757{
4758	struct proc_data *data;
4759	struct net_device *dev = pde_data(inode);
4760	struct airo_info *apriv = dev->ml_priv;
4761	StatsRid stats;
4762	int i, j;
4763	__le32 *vals = stats.vals;
4764	int len;
4765
4766	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
4767		return -ENOMEM;
4768	data = file->private_data;
4769	if ((data->rbuffer = kmalloc(4096, GFP_KERNEL)) == NULL) {
4770		kfree (file->private_data);
4771		return -ENOMEM;
4772	}
4773
4774	readStatsRid(apriv, &stats, rid, 1);
4775	len = le16_to_cpu(stats.len);
4776
4777        j = 0;
4778	for (i = 0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
4779		if (!statsLabels[i]) continue;
4780		if (j+strlen(statsLabels[i])+16>4096) {
4781			airo_print_warn(apriv->dev->name,
4782			       "Potentially disastrous buffer overflow averted!");
4783			break;
4784		}
4785		j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
4786				le32_to_cpu(vals[i]));
4787	}
4788	if (i*4 >= len) {
4789		airo_print_warn(apriv->dev->name, "Got a short rid");
4790	}
4791	data->readlen = j;
4792	return 0;
4793}
4794
4795static int get_dec_u16(char *buffer, int *start, int limit)
4796{
4797	u16 value;
4798	int valid = 0;
4799	for (value = 0; *start < limit && buffer[*start] >= '0' &&
4800			buffer[*start] <= '9'; (*start)++) {
4801		valid = 1;
4802		value *= 10;
4803		value += buffer[*start] - '0';
4804	}
4805	if (!valid) return -1;
4806	return value;
4807}
4808
4809static int airo_config_commit(struct net_device *dev,
4810			      struct iw_request_info *info,
4811			      union iwreq_data *wrqu,
4812			      char *extra);
4813
4814static inline int sniffing_mode(struct airo_info *ai)
4815{
4816	return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
4817		le16_to_cpu(RXMODE_RFMON);
4818}
4819
4820static void proc_config_on_close(struct inode *inode, struct file *file)
4821{
4822	struct proc_data *data = file->private_data;
4823	struct net_device *dev = pde_data(inode);
4824	struct airo_info *ai = dev->ml_priv;
4825	char *line;
4826
4827	if (!data->writelen) return;
4828
4829	readConfigRid(ai, 1);
4830	set_bit (FLAG_COMMIT, &ai->flags);
4831
4832	line = data->wbuffer;
4833	while (line[0]) {
4834/*** Mode processing */
4835		if (!strncmp(line, "Mode: ", 6)) {
4836			line += 6;
4837			if (sniffing_mode(ai))
4838				set_bit (FLAG_RESET, &ai->flags);
4839			ai->config.rmode &= ~RXMODE_FULL_MASK;
4840			clear_bit (FLAG_802_11, &ai->flags);
4841			ai->config.opmode &= ~MODE_CFG_MASK;
4842			ai->config.scanMode = SCANMODE_ACTIVE;
4843			if (line[0] == 'a') {
4844				ai->config.opmode |= MODE_STA_IBSS;
4845			} else {
4846				ai->config.opmode |= MODE_STA_ESS;
4847				if (line[0] == 'r') {
4848					ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4849					ai->config.scanMode = SCANMODE_PASSIVE;
4850					set_bit (FLAG_802_11, &ai->flags);
4851				} else if (line[0] == 'y') {
4852					ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4853					ai->config.scanMode = SCANMODE_PASSIVE;
4854					set_bit (FLAG_802_11, &ai->flags);
4855				} else if (line[0] == 'l')
4856					ai->config.rmode |= RXMODE_LANMON;
4857			}
4858			set_bit (FLAG_COMMIT, &ai->flags);
4859		}
4860
4861/*** Radio status */
4862		else if (!strncmp(line,"Radio: ", 7)) {
4863			line += 7;
4864			if (!strncmp(line,"off", 3)) {
4865				set_bit (FLAG_RADIO_OFF, &ai->flags);
4866			} else {
4867				clear_bit (FLAG_RADIO_OFF, &ai->flags);
4868			}
4869		}
4870/*** NodeName processing */
4871		else if (!strncmp(line, "NodeName: ", 10)) {
4872			int j;
4873
4874			line += 10;
4875			memset(ai->config.nodeName, 0, 16);
4876/* Do the name, assume a space between the mode and node name */
4877			for (j = 0; j < 16 && line[j] != '\n'; j++) {
4878				ai->config.nodeName[j] = line[j];
4879			}
4880			set_bit (FLAG_COMMIT, &ai->flags);
4881		}
4882
4883/*** PowerMode processing */
4884		else if (!strncmp(line, "PowerMode: ", 11)) {
4885			line += 11;
4886			if (!strncmp(line, "PSPCAM", 6)) {
4887				ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4888				set_bit (FLAG_COMMIT, &ai->flags);
4889			} else if (!strncmp(line, "PSP", 3)) {
4890				ai->config.powerSaveMode = POWERSAVE_PSP;
4891				set_bit (FLAG_COMMIT, &ai->flags);
4892			} else {
4893				ai->config.powerSaveMode = POWERSAVE_CAM;
4894				set_bit (FLAG_COMMIT, &ai->flags);
4895			}
4896		} else if (!strncmp(line, "DataRates: ", 11)) {
4897			int v, i = 0, k = 0; /* i is index into line,
4898						k is index to rates */
4899
4900			line += 11;
4901			while ((v = get_dec_u16(line, &i, 3))!=-1) {
4902				ai->config.rates[k++] = (u8)v;
4903				line += i + 1;
4904				i = 0;
4905			}
4906			set_bit (FLAG_COMMIT, &ai->flags);
4907		} else if (!strncmp(line, "Channel: ", 9)) {
4908			int v, i = 0;
4909			line += 9;
4910			v = get_dec_u16(line, &i, i+3);
4911			if (v != -1) {
4912				ai->config.channelSet = cpu_to_le16(v);
4913				set_bit (FLAG_COMMIT, &ai->flags);
4914			}
4915		} else if (!strncmp(line, "XmitPower: ", 11)) {
4916			int v, i = 0;
4917			line += 11;
4918			v = get_dec_u16(line, &i, i+3);
4919			if (v != -1) {
4920				ai->config.txPower = cpu_to_le16(v);
4921				set_bit (FLAG_COMMIT, &ai->flags);
4922			}
4923		} else if (!strncmp(line, "WEP: ", 5)) {
4924			line += 5;
4925			switch(line[0]) {
4926			case 's':
4927				set_auth_type(ai, AUTH_SHAREDKEY);
4928				break;
4929			case 'e':
4930				set_auth_type(ai, AUTH_ENCRYPT);
4931				break;
4932			default:
4933				set_auth_type(ai, AUTH_OPEN);
4934				break;
4935			}
4936			set_bit (FLAG_COMMIT, &ai->flags);
4937		} else if (!strncmp(line, "LongRetryLimit: ", 16)) {
4938			int v, i = 0;
4939
4940			line += 16;
4941			v = get_dec_u16(line, &i, 3);
4942			v = (v<0) ? 0 : ((v>255) ? 255 : v);
4943			ai->config.longRetryLimit = cpu_to_le16(v);
4944			set_bit (FLAG_COMMIT, &ai->flags);
4945		} else if (!strncmp(line, "ShortRetryLimit: ", 17)) {
4946			int v, i = 0;
4947
4948			line += 17;
4949			v = get_dec_u16(line, &i, 3);
4950			v = (v<0) ? 0 : ((v>255) ? 255 : v);
4951			ai->config.shortRetryLimit = cpu_to_le16(v);
4952			set_bit (FLAG_COMMIT, &ai->flags);
4953		} else if (!strncmp(line, "RTSThreshold: ", 14)) {
4954			int v, i = 0;
4955
4956			line += 14;
4957			v = get_dec_u16(line, &i, 4);
4958			v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4959			ai->config.rtsThres = cpu_to_le16(v);
4960			set_bit (FLAG_COMMIT, &ai->flags);
4961		} else if (!strncmp(line, "TXMSDULifetime: ", 16)) {
4962			int v, i = 0;
4963
4964			line += 16;
4965			v = get_dec_u16(line, &i, 5);
4966			v = (v<0) ? 0 : v;
4967			ai->config.txLifetime = cpu_to_le16(v);
4968			set_bit (FLAG_COMMIT, &ai->flags);
4969		} else if (!strncmp(line, "RXMSDULifetime: ", 16)) {
4970			int v, i = 0;
4971
4972			line += 16;
4973			v = get_dec_u16(line, &i, 5);
4974			v = (v<0) ? 0 : v;
4975			ai->config.rxLifetime = cpu_to_le16(v);
4976			set_bit (FLAG_COMMIT, &ai->flags);
4977		} else if (!strncmp(line, "TXDiversity: ", 13)) {
4978			ai->config.txDiversity =
4979				(line[13]=='l') ? 1 :
4980				((line[13]=='r')? 2: 3);
4981			set_bit (FLAG_COMMIT, &ai->flags);
4982		} else if (!strncmp(line, "RXDiversity: ", 13)) {
4983			ai->config.rxDiversity =
4984				(line[13]=='l') ? 1 :
4985				((line[13]=='r')? 2: 3);
4986			set_bit (FLAG_COMMIT, &ai->flags);
4987		} else if (!strncmp(line, "FragThreshold: ", 15)) {
4988			int v, i = 0;
4989
4990			line += 15;
4991			v = get_dec_u16(line, &i, 4);
4992			v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4993			v = v & 0xfffe; /* Make sure its even */
4994			ai->config.fragThresh = cpu_to_le16(v);
4995			set_bit (FLAG_COMMIT, &ai->flags);
4996		} else if (!strncmp(line, "Modulation: ", 12)) {
4997			line += 12;
4998			switch(*line) {
4999			case 'd':  ai->config.modulation = MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
5000			case 'c':  ai->config.modulation = MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
5001			case 'm':  ai->config.modulation = MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
5002			default: airo_print_warn(ai->dev->name, "Unknown modulation");
5003			}
5004		} else if (!strncmp(line, "Preamble: ", 10)) {
5005			line += 10;
5006			switch(*line) {
5007			case 'a': ai->config.preamble = PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
5008			case 'l': ai->config.preamble = PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
5009			case 's': ai->config.preamble = PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
5010			default: airo_print_warn(ai->dev->name, "Unknown preamble");
5011			}
5012		} else {
5013			airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
5014		}
5015		while (line[0] && line[0] != '\n') line++;
5016		if (line[0]) line++;
5017	}
5018	airo_config_commit(dev, NULL, NULL, NULL);
5019}
5020
5021static const char *get_rmode(__le16 mode)
5022{
5023        switch(mode & RXMODE_MASK) {
5024        case RXMODE_RFMON:  return "rfmon";
5025        case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
5026        case RXMODE_LANMON:  return "lanmon";
5027        }
5028        return "ESS";
5029}
5030
5031static int proc_config_open(struct inode *inode, struct file *file)
5032{
5033	struct proc_data *data;
5034	struct net_device *dev = pde_data(inode);
5035	struct airo_info *ai = dev->ml_priv;
5036	int i;
5037	__le16 mode;
5038
5039	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5040		return -ENOMEM;
5041	data = file->private_data;
5042	if ((data->rbuffer = kmalloc(2048, GFP_KERNEL)) == NULL) {
5043		kfree (file->private_data);
5044		return -ENOMEM;
5045	}
5046	if ((data->wbuffer = kzalloc(2048, GFP_KERNEL)) == NULL) {
5047		kfree (data->rbuffer);
5048		kfree (file->private_data);
5049		return -ENOMEM;
5050	}
5051	data->maxwritelen = 2048;
5052	data->on_close = proc_config_on_close;
5053
5054	readConfigRid(ai, 1);
5055
5056	mode = ai->config.opmode & MODE_CFG_MASK;
5057	i = sprintf(data->rbuffer,
5058		     "Mode: %s\n"
5059		     "Radio: %s\n"
5060		     "NodeName: %-16s\n"
5061		     "PowerMode: %s\n"
5062		     "DataRates: %d %d %d %d %d %d %d %d\n"
5063		     "Channel: %d\n"
5064		     "XmitPower: %d\n",
5065		     mode == MODE_STA_IBSS ? "adhoc" :
5066		     mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
5067		     mode == MODE_AP ? "AP" :
5068		     mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
5069		     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
5070		     ai->config.nodeName,
5071		     ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
5072		     ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
5073		     ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
5074		     "Error",
5075		     (int)ai->config.rates[0],
5076		     (int)ai->config.rates[1],
5077		     (int)ai->config.rates[2],
5078		     (int)ai->config.rates[3],
5079		     (int)ai->config.rates[4],
5080		     (int)ai->config.rates[5],
5081		     (int)ai->config.rates[6],
5082		     (int)ai->config.rates[7],
5083		     le16_to_cpu(ai->config.channelSet),
5084		     le16_to_cpu(ai->config.txPower)
5085		);
5086	sprintf(data->rbuffer + i,
5087		 "LongRetryLimit: %d\n"
5088		 "ShortRetryLimit: %d\n"
5089		 "RTSThreshold: %d\n"
5090		 "TXMSDULifetime: %d\n"
5091		 "RXMSDULifetime: %d\n"
5092		 "TXDiversity: %s\n"
5093		 "RXDiversity: %s\n"
5094		 "FragThreshold: %d\n"
5095		 "WEP: %s\n"
5096		 "Modulation: %s\n"
5097		 "Preamble: %s\n",
5098		 le16_to_cpu(ai->config.longRetryLimit),
5099		 le16_to_cpu(ai->config.shortRetryLimit),
5100		 le16_to_cpu(ai->config.rtsThres),
5101		 le16_to_cpu(ai->config.txLifetime),
5102		 le16_to_cpu(ai->config.rxLifetime),
5103		 ai->config.txDiversity == 1 ? "left" :
5104		 ai->config.txDiversity == 2 ? "right" : "both",
5105		 ai->config.rxDiversity == 1 ? "left" :
5106		 ai->config.rxDiversity == 2 ? "right" : "both",
5107		 le16_to_cpu(ai->config.fragThresh),
5108		 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
5109		 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
5110		 ai->config.modulation == MOD_DEFAULT ? "default" :
5111		 ai->config.modulation == MOD_CCK ? "cck" :
5112		 ai->config.modulation == MOD_MOK ? "mok" : "error",
5113		 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
5114		 ai->config.preamble == PREAMBLE_LONG ? "long" :
5115		 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
5116		);
5117	data->readlen = strlen(data->rbuffer);
5118	return 0;
5119}
5120
5121static void proc_SSID_on_close(struct inode *inode, struct file *file)
5122{
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	SsidRid SSID_rid;
5127	int i;
5128	char *p = data->wbuffer;
5129	char *end = p + data->writelen;
5130
5131	if (!data->writelen)
5132		return;
5133
5134	*end = '\n'; /* sentinel; we have space for it */
5135
5136	memset(&SSID_rid, 0, sizeof(SSID_rid));
5137
5138	for (i = 0; i < 3 && p < end; i++) {
5139		int j = 0;
5140		/* copy up to 32 characters from this line */
5141		while (*p != '\n' && j < 32)
5142			SSID_rid.ssids[i].ssid[j++] = *p++;
5143		if (j == 0)
5144			break;
5145		SSID_rid.ssids[i].len = cpu_to_le16(j);
5146		/* skip to the beginning of the next line */
5147		while (*p++ != '\n')
5148			;
5149	}
5150	if (i)
5151		SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5152	disable_MAC(ai, 1);
5153	writeSsidRid(ai, &SSID_rid, 1);
5154	enable_MAC(ai, 1);
5155}
5156
5157static void proc_APList_on_close(struct inode *inode, struct file *file)
5158{
5159	struct proc_data *data = file->private_data;
5160	struct net_device *dev = pde_data(inode);
5161	struct airo_info *ai = dev->ml_priv;
5162	APListRid *APList_rid = &ai->APList;
5163	int i;
5164
5165	if (!data->writelen) return;
5166
5167	memset(APList_rid, 0, sizeof(*APList_rid));
5168	APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
5169
5170	for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
5171		mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
5172
5173	disable_MAC(ai, 1);
5174	writeAPListRid(ai, APList_rid, 1);
5175	enable_MAC(ai, 1);
5176}
5177
5178/* This function wraps PC4500_writerid with a MAC disable */
5179static int do_writerid(struct airo_info *ai, u16 rid, const void *rid_data,
5180			int len, int dummy)
5181{
5182	int rc;
5183
5184	disable_MAC(ai, 1);
5185	rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5186	enable_MAC(ai, 1);
5187	return rc;
5188}
5189
5190/* Returns the WEP key at the specified index, or -1 if that key does
5191 * not exist.  The buffer is assumed to be at least 16 bytes in length.
5192 */
5193static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
5194{
5195	WepKeyRid wkr;
5196	int rc;
5197	__le16 lastindex;
5198
5199	rc = readWepKeyRid(ai, &wkr, 1, 1);
5200	if (rc != SUCCESS)
5201		return -1;
5202	do {
5203		lastindex = wkr.kindex;
5204		if (le16_to_cpu(wkr.kindex) == index) {
5205			int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
5206			memcpy(buf, wkr.key, klen);
5207			return klen;
5208		}
5209		rc = readWepKeyRid(ai, &wkr, 0, 1);
5210		if (rc != SUCCESS)
5211			return -1;
5212	} while (lastindex != wkr.kindex);
5213	return -1;
5214}
5215
5216static int get_wep_tx_idx(struct airo_info *ai)
5217{
5218	WepKeyRid wkr;
5219	int rc;
5220	__le16 lastindex;
5221
5222	rc = readWepKeyRid(ai, &wkr, 1, 1);
5223	if (rc != SUCCESS)
5224		return -1;
5225	do {
5226		lastindex = wkr.kindex;
5227		if (wkr.kindex == cpu_to_le16(0xffff))
5228			return wkr.mac[0];
5229		rc = readWepKeyRid(ai, &wkr, 0, 1);
5230		if (rc != SUCCESS)
5231			return -1;
5232	} while (lastindex != wkr.kindex);
5233	return -1;
5234}
5235
5236static int set_wep_key(struct airo_info *ai, u16 index, const u8 *key,
5237		       u16 keylen, int perm, int lock)
5238{
5239	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5240	WepKeyRid wkr;
5241	int rc;
5242
5243	if (WARN_ON(keylen == 0))
5244		return -1;
5245
5246	memset(&wkr, 0, sizeof(wkr));
5247	wkr.len = cpu_to_le16(sizeof(wkr));
5248	wkr.kindex = cpu_to_le16(index);
5249	wkr.klen = cpu_to_le16(keylen);
5250	memcpy(wkr.key, key, keylen);
5251	memcpy(wkr.mac, macaddr, ETH_ALEN);
5252
5253	if (perm) disable_MAC(ai, lock);
5254	rc = writeWepKeyRid(ai, &wkr, perm, lock);
5255	if (perm) enable_MAC(ai, lock);
5256	return rc;
5257}
5258
5259static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
5260{
5261	WepKeyRid wkr;
5262	int rc;
5263
5264	memset(&wkr, 0, sizeof(wkr));
5265	wkr.len = cpu_to_le16(sizeof(wkr));
5266	wkr.kindex = cpu_to_le16(0xffff);
5267	wkr.mac[0] = (char)index;
5268
5269	if (perm) {
5270		ai->defindex = (char)index;
5271		disable_MAC(ai, lock);
5272	}
5273
5274	rc = writeWepKeyRid(ai, &wkr, perm, lock);
5275
5276	if (perm)
5277		enable_MAC(ai, lock);
5278	return rc;
5279}
5280
5281static void proc_wepkey_on_close(struct inode *inode, struct file *file)
5282{
5283	struct proc_data *data;
5284	struct net_device *dev = pde_data(inode);
5285	struct airo_info *ai = dev->ml_priv;
5286	int i, rc;
5287	u8 key[16];
5288	u16 index = 0;
5289	int j = 0;
5290
5291	memset(key, 0, sizeof(key));
5292
5293	data = file->private_data;
5294	if (!data->writelen) return;
5295
5296	if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5297	    (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5298		index = data->wbuffer[0] - '0';
5299		if (data->wbuffer[1] == '\n') {
5300			rc = set_wep_tx_idx(ai, index, 1, 1);
5301			if (rc < 0) {
5302				airo_print_err(ai->dev->name, "failed to set "
5303				               "WEP transmit index to %d: %d.",
5304				               index, rc);
5305			}
5306			return;
5307		}
5308		j = 2;
5309	} else {
5310		airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5311		return;
5312	}
5313
5314	for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) {
5315		int val;
5316
5317		if (i % 3 == 2)
5318			continue;
5319
5320		val = hex_to_bin(data->wbuffer[i+j]);
5321		if (val < 0) {
5322			airo_print_err(ai->dev->name, "WebKey passed invalid key hex");
5323			return;
5324		}
5325		switch(i%3) {
5326		case 0:
5327			key[i/3] = (u8)val << 4;
5328			break;
5329		case 1:
5330			key[i/3] |= (u8)val;
5331			break;
5332		}
5333	}
5334
5335	rc = set_wep_key(ai, index, key, i/3, 1, 1);
5336	if (rc < 0) {
5337		airo_print_err(ai->dev->name, "failed to set WEP key at index "
5338		               "%d: %d.", index, rc);
5339	}
5340}
5341
5342static int proc_wepkey_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	char *ptr;
5348	WepKeyRid wkr;
5349	__le16 lastindex;
5350	int j = 0;
5351	int rc;
5352
5353	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5354		return -ENOMEM;
5355	memset(&wkr, 0, sizeof(wkr));
5356	data = file->private_data;
5357	if ((data->rbuffer = kzalloc(180, GFP_KERNEL)) == NULL) {
5358		kfree (file->private_data);
5359		return -ENOMEM;
5360	}
5361	data->writelen = 0;
5362	data->maxwritelen = 80;
5363	if ((data->wbuffer = kzalloc(80, GFP_KERNEL)) == NULL) {
5364		kfree (data->rbuffer);
5365		kfree (file->private_data);
5366		return -ENOMEM;
5367	}
5368	data->on_close = proc_wepkey_on_close;
5369
5370	ptr = data->rbuffer;
5371	strcpy(ptr, "No wep keys\n");
5372	rc = readWepKeyRid(ai, &wkr, 1, 1);
5373	if (rc == SUCCESS) do {
5374		lastindex = wkr.kindex;
5375		if (wkr.kindex == cpu_to_le16(0xffff)) {
5376			j += sprintf(ptr+j, "Tx key = %d\n",
5377				     (int)wkr.mac[0]);
5378		} else {
5379			j += sprintf(ptr+j, "Key %d set with length = %d\n",
5380				     le16_to_cpu(wkr.kindex),
5381				     le16_to_cpu(wkr.klen));
5382		}
5383		readWepKeyRid(ai, &wkr, 0, 1);
5384	} while ((lastindex != wkr.kindex) && (j < 180-30));
5385
5386	data->readlen = strlen(data->rbuffer);
5387	return 0;
5388}
5389
5390static int proc_SSID_open(struct inode *inode, struct file *file)
5391{
5392	struct proc_data *data;
5393	struct net_device *dev = pde_data(inode);
5394	struct airo_info *ai = dev->ml_priv;
5395	int i;
5396	char *ptr;
5397	SsidRid SSID_rid;
5398
5399	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5400		return -ENOMEM;
5401	data = file->private_data;
5402	if ((data->rbuffer = kmalloc(104, GFP_KERNEL)) == NULL) {
5403		kfree (file->private_data);
5404		return -ENOMEM;
5405	}
5406	data->writelen = 0;
5407	data->maxwritelen = 33*3;
5408	/* allocate maxwritelen + 1; we'll want a sentinel */
5409	if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
5410		kfree (data->rbuffer);
5411		kfree (file->private_data);
5412		return -ENOMEM;
5413	}
5414	data->on_close = proc_SSID_on_close;
5415
5416	readSsidRid(ai, &SSID_rid);
5417	ptr = data->rbuffer;
5418	for (i = 0; i < 3; i++) {
5419		int j;
5420		size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
5421		if (!len)
5422			break;
5423		if (len > 32)
5424			len = 32;
5425		for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
5426			*ptr++ = SSID_rid.ssids[i].ssid[j];
5427		*ptr++ = '\n';
5428	}
5429	*ptr = '\0';
5430	data->readlen = strlen(data->rbuffer);
5431	return 0;
5432}
5433
5434static int proc_APList_open(struct inode *inode, struct file *file)
5435{
5436	struct proc_data *data;
5437	struct net_device *dev = pde_data(inode);
5438	struct airo_info *ai = dev->ml_priv;
5439	int i;
5440	char *ptr;
5441	APListRid *APList_rid = &ai->APList;
5442
5443	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5444		return -ENOMEM;
5445	data = file->private_data;
5446	if ((data->rbuffer = kmalloc(104, GFP_KERNEL)) == NULL) {
5447		kfree (file->private_data);
5448		return -ENOMEM;
5449	}
5450	data->writelen = 0;
5451	data->maxwritelen = 4*6*3;
5452	if ((data->wbuffer = kzalloc(data->maxwritelen, GFP_KERNEL)) == NULL) {
5453		kfree (data->rbuffer);
5454		kfree (file->private_data);
5455		return -ENOMEM;
5456	}
5457	data->on_close = proc_APList_on_close;
5458
5459	ptr = data->rbuffer;
5460	for (i = 0; i < 4; i++) {
5461// We end when we find a zero MAC
5462		if (!*(int*)APList_rid->ap[i] &&
5463		     !*(int*)&APList_rid->ap[i][2]) break;
5464		ptr += sprintf(ptr, "%pM\n", APList_rid->ap[i]);
5465	}
5466	if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5467
5468	*ptr = '\0';
5469	data->readlen = strlen(data->rbuffer);
5470	return 0;
5471}
5472
5473static int proc_BSSList_open(struct inode *inode, struct file *file)
5474{
5475	struct proc_data *data;
5476	struct net_device *dev = pde_data(inode);
5477	struct airo_info *ai = dev->ml_priv;
5478	char *ptr;
5479	BSSListRid BSSList_rid;
5480	int rc;
5481	/* If doLoseSync is not 1, we won't do a Lose Sync */
5482	int doLoseSync = -1;
5483
5484	if ((file->private_data = kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL)
5485		return -ENOMEM;
5486	data = file->private_data;
5487	if ((data->rbuffer = kmalloc(1024, GFP_KERNEL)) == NULL) {
5488		kfree (file->private_data);
5489		return -ENOMEM;
5490	}
5491	data->writelen = 0;
5492	data->maxwritelen = 0;
5493	data->wbuffer = NULL;
5494	data->on_close = NULL;
5495
5496	if (file->f_mode & FMODE_WRITE) {
5497		if (!(file->f_mode & FMODE_READ)) {
5498			Cmd cmd;
5499			Resp rsp;
5500
5501			if (ai->flags & FLAG_RADIO_MASK) {
5502				kfree(data->rbuffer);
5503				kfree(file->private_data);
5504				return -ENETDOWN;
5505			}
5506			memset(&cmd, 0, sizeof(cmd));
5507			cmd.cmd = CMD_LISTBSS;
5508			if (down_interruptible(&ai->sem)) {
5509				kfree(data->rbuffer);
5510				kfree(file->private_data);
5511				return -ERESTARTSYS;
5512			}
5513			issuecommand(ai, &cmd, &rsp, true);
5514			up(&ai->sem);
5515			data->readlen = 0;
5516			return 0;
5517		}
5518		doLoseSync = 1;
5519	}
5520	ptr = data->rbuffer;
5521	/* There is a race condition here if there are concurrent opens.
5522           Since it is a rare condition, we'll just live with it, otherwise
5523           we have to add a spin lock... */
5524	rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5525	while (rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
5526		ptr += sprintf(ptr, "%pM %.*s rssi = %d",
5527			       BSSList_rid.bssid,
5528				(int)BSSList_rid.ssidLen,
5529				BSSList_rid.ssid,
5530				le16_to_cpu(BSSList_rid.dBm));
5531		ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5532				le16_to_cpu(BSSList_rid.dsChannel),
5533				BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5534				BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5535				BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5536				BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5537		rc = readBSSListRid(ai, 0, &BSSList_rid);
5538	}
5539	*ptr = '\0';
5540	data->readlen = strlen(data->rbuffer);
5541	return 0;
5542}
5543
5544static int proc_close(struct inode *inode, struct file *file)
5545{
5546	struct proc_data *data = file->private_data;
5547
5548	if (data->on_close != NULL)
5549		data->on_close(inode, file);
5550	kfree(data->rbuffer);
5551	kfree(data->wbuffer);
5552	kfree(data);
5553	return 0;
5554}
5555
5556/* Since the card doesn't automatically switch to the right WEP mode,
5557   we will make it do it.  If the card isn't associated, every secs we
5558   will switch WEP modes to see if that will help.  If the card is
5559   associated we will check every minute to see if anything has
5560   changed. */
5561static void timer_func(struct net_device *dev)
5562{
5563	struct airo_info *apriv = dev->ml_priv;
5564
5565/* We don't have a link so try changing the authtype */
5566	readConfigRid(apriv, 0);
5567	disable_MAC(apriv, 0);
5568	switch(apriv->config.authType) {
5569		case AUTH_ENCRYPT:
5570/* So drop to OPEN */
5571			apriv->config.authType = AUTH_OPEN;
5572			break;
5573		case AUTH_SHAREDKEY:
5574			if (apriv->keyindex < auto_wep) {
5575				set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
5576				apriv->config.authType = AUTH_SHAREDKEY;
5577				apriv->keyindex++;
5578			} else {
5579			        /* Drop to ENCRYPT */
5580				apriv->keyindex = 0;
5581				set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
5582				apriv->config.authType = AUTH_ENCRYPT;
5583			}
5584			break;
5585		default:  /* We'll escalate to SHAREDKEY */
5586			apriv->config.authType = AUTH_SHAREDKEY;
5587	}
5588	set_bit (FLAG_COMMIT, &apriv->flags);
5589	writeConfigRid(apriv, 0);
5590	enable_MAC(apriv, 0);
5591	up(&apriv->sem);
5592
5593/* Schedule check to see if the change worked */
5594	clear_bit(JOB_AUTOWEP, &apriv->jobs);
5595	apriv->expires = RUN_AT(HZ*3);
5596}
5597
5598#ifdef CONFIG_PCI
5599static int airo_pci_probe(struct pci_dev *pdev,
5600				    const struct pci_device_id *pent)
5601{
5602	struct net_device *dev;
5603
5604	if (pci_enable_device(pdev))
5605		return -ENODEV;
5606	pci_set_master(pdev);
5607
5608	if (pdev->device == 0x5000 || pdev->device == 0xa504)
5609			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5610	else
5611			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5612	if (!dev) {
5613		pci_disable_device(pdev);
5614		return -ENODEV;
5615	}
5616
5617	pci_set_drvdata(pdev, dev);
5618	return 0;
5619}
5620
5621static void airo_pci_remove(struct pci_dev *pdev)
5622{
5623	struct net_device *dev = pci_get_drvdata(pdev);
5624
5625	airo_print_info(dev->name, "Unregistering...");
5626	stop_airo_card(dev, 1);
5627	pci_disable_device(pdev);
5628}
5629
5630static int __maybe_unused airo_pci_suspend(struct device *dev_d)
5631{
5632	struct net_device *dev = dev_get_drvdata(dev_d);
5633	struct airo_info *ai = dev->ml_priv;
5634	Cmd cmd;
5635	Resp rsp;
5636
5637	if (!ai->SSID)
5638		ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
5639	if (!ai->SSID)
5640		return -ENOMEM;
5641	readSsidRid(ai, ai->SSID);
5642	memset(&cmd, 0, sizeof(cmd));
5643	/* the lock will be released at the end of the resume callback */
5644	if (down_interruptible(&ai->sem))
5645		return -EAGAIN;
5646	disable_MAC(ai, 0);
5647	netif_device_detach(dev);
5648	ai->power = PMSG_SUSPEND;
5649	cmd.cmd = HOSTSLEEP;
5650	issuecommand(ai, &cmd, &rsp, true);
5651
5652	device_wakeup_enable(dev_d);
 
 
5653	return 0;
5654}
5655
5656static int __maybe_unused airo_pci_resume(struct device *dev_d)
5657{
5658	struct net_device *dev = dev_get_drvdata(dev_d);
5659	struct airo_info *ai = dev->ml_priv;
5660	pci_power_t prev_state = to_pci_dev(dev_d)->current_state;
5661
5662	device_wakeup_disable(dev_d);
 
 
5663
5664	if (prev_state != PCI_D1) {
5665		reset_card(dev, 0);
5666		mpi_init_descriptors(ai);
5667		setup_card(ai, dev, 0);
5668		clear_bit(FLAG_RADIO_OFF, &ai->flags);
5669		clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5670	} else {
5671		OUT4500(ai, EVACK, EV_AWAKEN);
5672		OUT4500(ai, EVACK, EV_AWAKEN);
5673		msleep(100);
5674	}
5675
5676	set_bit(FLAG_COMMIT, &ai->flags);
5677	disable_MAC(ai, 0);
5678        msleep(200);
5679	if (ai->SSID) {
5680		writeSsidRid(ai, ai->SSID, 0);
5681		kfree(ai->SSID);
5682		ai->SSID = NULL;
5683	}
5684	writeAPListRid(ai, &ai->APList, 0);
5685	writeConfigRid(ai, 0);
5686	enable_MAC(ai, 0);
5687	ai->power = PMSG_ON;
5688	netif_device_attach(dev);
5689	netif_wake_queue(dev);
5690	enable_interrupts(ai);
5691	up(&ai->sem);
5692	return 0;
5693}
5694#endif
5695
5696static int __init airo_init_module(void)
5697{
5698	int i;
5699
5700	proc_kuid = make_kuid(&init_user_ns, proc_uid);
5701	proc_kgid = make_kgid(&init_user_ns, proc_gid);
5702	if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
5703		return -EINVAL;
5704
5705	airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
5706
5707	if (airo_entry)
5708		proc_set_user(airo_entry, proc_kuid, proc_kgid);
5709
5710	for (i = 0; i < 4 && io[i] && irq[i]; i++) {
5711		airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5712			"io = 0x%x", irq[i], io[i]);
5713		if (init_airo_card(irq[i], io[i], 0, NULL)) {
5714			/* do nothing */ ;
5715		}
5716	}
5717
5718#ifdef CONFIG_PCI
5719	airo_print_info("", "Probing for PCI adapters");
5720	i = pci_register_driver(&airo_driver);
5721	airo_print_info("", "Finished probing for PCI adapters");
5722
5723	if (i) {
5724		remove_proc_entry("driver/aironet", NULL);
5725		return i;
5726	}
5727#endif
5728
5729	/* Always exit with success, as we are a library module
5730	 * as well as a driver module
5731	 */
5732	return 0;
5733}
5734
5735static void __exit airo_cleanup_module(void)
5736{
5737	struct airo_info *ai;
5738	while (!list_empty(&airo_devices)) {
5739		ai = list_entry(airo_devices.next, struct airo_info, dev_list);
5740		airo_print_info(ai->dev->name, "Unregistering...");
5741		stop_airo_card(ai->dev, 1);
5742	}
5743#ifdef CONFIG_PCI
5744	pci_unregister_driver(&airo_driver);
5745#endif
5746	remove_proc_entry("driver/aironet", NULL);
5747}
5748
5749/*
5750 * Initial Wireless Extension code for Aironet driver by :
5751 *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5752 * Conversion to new driver API by :
5753 *	Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5754 * Javier also did a good amount of work here, adding some new extensions
5755 * and fixing my code. Let's just say that without him this code just
5756 * would not work at all... - Jean II
5757 */
5758
5759static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
5760{
5761	if (!rssi_rid)
5762		return 0;
5763
5764	return (0x100 - rssi_rid[rssi].rssidBm);
5765}
5766
5767static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
5768{
5769	int i;
5770
5771	if (!rssi_rid)
5772		return 0;
5773
5774	for (i = 0; i < 256; i++)
5775		if (rssi_rid[i].rssidBm == dbm)
5776			return rssi_rid[i].rssipct;
5777
5778	return 0;
5779}
5780
5781
5782static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5783{
5784	int quality = 0;
5785	u16 sq;
5786
5787	if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
5788		return 0;
5789
5790	if (!(cap_rid->hardCap & cpu_to_le16(8)))
5791		return 0;
5792
5793	sq = le16_to_cpu(status_rid->signalQuality);
5794	if (memcmp(cap_rid->prodName, "350", 3))
5795		if (sq > 0x20)
5796			quality = 0;
5797		else
5798			quality = 0x20 - sq;
5799	else
5800		if (sq > 0xb0)
5801			quality = 0;
5802		else if (sq < 0x10)
5803			quality = 0xa0;
5804		else
5805			quality = 0xb0 - sq;
5806	return quality;
5807}
5808
5809#define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5810#define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50)
5811
5812/*------------------------------------------------------------------*/
5813/*
5814 * Wireless Handler : get protocol name
5815 */
5816static int airo_get_name(struct net_device *dev,
5817			 struct iw_request_info *info,
5818			 union iwreq_data *cwrq,
5819			 char *extra)
5820{
5821	strcpy(cwrq->name, "IEEE 802.11-DS");
5822	return 0;
5823}
5824
5825/*------------------------------------------------------------------*/
5826/*
5827 * Wireless Handler : set frequency
5828 */
5829static int airo_set_freq(struct net_device *dev,
5830			 struct iw_request_info *info,
5831			 union iwreq_data *wrqu,
5832			 char *extra)
5833{
5834	struct iw_freq *fwrq = &wrqu->freq;
5835	struct airo_info *local = dev->ml_priv;
5836	int rc = -EINPROGRESS;		/* Call commit handler */
5837
5838	/* If setting by frequency, convert to a channel */
5839	if (fwrq->e == 1) {
5840		int f = fwrq->m / 100000;
5841
5842		/* Hack to fall through... */
5843		fwrq->e = 0;
5844		fwrq->m = ieee80211_frequency_to_channel(f);
5845	}
5846	/* Setting by channel number */
5847	if (fwrq->m < 0 || fwrq->m > 1000 || fwrq->e > 0)
5848		rc = -EOPNOTSUPP;
5849	else {
5850		int channel = fwrq->m;
5851		/* We should do a better check than that,
5852		 * based on the card capability !!! */
5853		if ((channel < 1) || (channel > 14)) {
5854			airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5855				fwrq->m);
5856			rc = -EINVAL;
5857		} else {
5858			readConfigRid(local, 1);
5859			/* Yes ! We can set it !!! */
5860			local->config.channelSet = cpu_to_le16(channel);
5861			set_bit (FLAG_COMMIT, &local->flags);
5862		}
5863	}
5864	return rc;
5865}
5866
5867/*------------------------------------------------------------------*/
5868/*
5869 * Wireless Handler : get frequency
5870 */
5871static int airo_get_freq(struct net_device *dev,
5872			 struct iw_request_info *info,
5873			 union iwreq_data *wrqu,
5874			 char *extra)
5875{
5876	struct iw_freq *fwrq = &wrqu->freq;
5877	struct airo_info *local = dev->ml_priv;
5878	StatusRid status_rid;		/* Card status info */
5879	int ch;
5880
5881	readConfigRid(local, 1);
5882	if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
5883		status_rid.channel = local->config.channelSet;
5884	else
5885		readStatusRid(local, &status_rid, 1);
5886
5887	ch = le16_to_cpu(status_rid.channel);
5888	if ((ch > 0) && (ch < 15)) {
5889		fwrq->m = 100000 *
5890			ieee80211_channel_to_frequency(ch, NL80211_BAND_2GHZ);
5891		fwrq->e = 1;
5892	} else {
5893		fwrq->m = ch;
5894		fwrq->e = 0;
5895	}
5896
5897	return 0;
5898}
5899
5900/*------------------------------------------------------------------*/
5901/*
5902 * Wireless Handler : set ESSID
5903 */
5904static int airo_set_essid(struct net_device *dev,
5905			  struct iw_request_info *info,
5906			  union iwreq_data *wrqu,
5907			  char *extra)
5908{
5909	struct iw_point *dwrq = &wrqu->essid;
5910	struct airo_info *local = dev->ml_priv;
5911	SsidRid SSID_rid;		/* SSIDs */
5912
5913	/* Reload the list of current SSID */
5914	readSsidRid(local, &SSID_rid);
5915
5916	/* Check if we asked for `any' */
5917	if (dwrq->flags == 0) {
5918		/* Just send an empty SSID list */
5919		memset(&SSID_rid, 0, sizeof(SSID_rid));
5920	} else {
5921		unsigned index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5922
5923		/* Check the size of the string */
5924		if (dwrq->length > IW_ESSID_MAX_SIZE)
5925			return -E2BIG ;
5926
5927		/* Check if index is valid */
5928		if (index >= ARRAY_SIZE(SSID_rid.ssids))
5929			return -EINVAL;
5930
5931		/* Set the SSID */
5932		memset(SSID_rid.ssids[index].ssid, 0,
5933		       sizeof(SSID_rid.ssids[index].ssid));
5934		memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5935		SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
5936	}
5937	SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
5938	/* Write it to the card */
5939	disable_MAC(local, 1);
5940	writeSsidRid(local, &SSID_rid, 1);
5941	enable_MAC(local, 1);
5942
5943	return 0;
5944}
5945
5946/*------------------------------------------------------------------*/
5947/*
5948 * Wireless Handler : get ESSID
5949 */
5950static int airo_get_essid(struct net_device *dev,
5951			  struct iw_request_info *info,
5952			  union iwreq_data *wrqu,
5953			  char *extra)
5954{
5955	struct iw_point *dwrq = &wrqu->essid;
5956	struct airo_info *local = dev->ml_priv;
5957	StatusRid status_rid;		/* Card status info */
5958
5959	readStatusRid(local, &status_rid, 1);
5960
5961	/* Note : if dwrq->flags != 0, we should
5962	 * get the relevant SSID from the SSID list... */
5963
5964	/* Get the current SSID */
5965	memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
5966	/* If none, we may want to get the one that was set */
5967
5968	/* Push it out ! */
5969	dwrq->length = le16_to_cpu(status_rid.SSIDlen);
5970	dwrq->flags = 1; /* active */
5971
5972	return 0;
5973}
5974
5975/*------------------------------------------------------------------*/
5976/*
5977 * Wireless Handler : set AP address
5978 */
5979static int airo_set_wap(struct net_device *dev,
5980			struct iw_request_info *info,
5981			union iwreq_data *wrqu,
5982			char *extra)
5983{
5984	struct sockaddr *awrq = &wrqu->ap_addr;
5985	struct airo_info *local = dev->ml_priv;
5986	Cmd cmd;
5987	Resp rsp;
5988	APListRid *APList_rid = &local->APList;
5989
5990	if (awrq->sa_family != ARPHRD_ETHER)
5991		return -EINVAL;
5992	else if (is_broadcast_ether_addr(awrq->sa_data) ||
5993		 is_zero_ether_addr(awrq->sa_data)) {
5994		memset(&cmd, 0, sizeof(cmd));
5995		cmd.cmd = CMD_LOSE_SYNC;
5996		if (down_interruptible(&local->sem))
5997			return -ERESTARTSYS;
5998		issuecommand(local, &cmd, &rsp, true);
5999		up(&local->sem);
6000	} else {
6001		memset(APList_rid, 0, sizeof(*APList_rid));
6002		APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
6003		memcpy(APList_rid->ap[0], awrq->sa_data, ETH_ALEN);
6004		disable_MAC(local, 1);
6005		writeAPListRid(local, APList_rid, 1);
6006		enable_MAC(local, 1);
6007	}
6008	return 0;
6009}
6010
6011/*------------------------------------------------------------------*/
6012/*
6013 * Wireless Handler : get AP address
6014 */
6015static int airo_get_wap(struct net_device *dev,
6016			struct iw_request_info *info,
6017			union iwreq_data *wrqu,
6018			char *extra)
6019{
6020	struct sockaddr *awrq = &wrqu->ap_addr;
6021	struct airo_info *local = dev->ml_priv;
6022	StatusRid status_rid;		/* Card status info */
6023
6024	readStatusRid(local, &status_rid, 1);
6025
6026	/* Tentative. This seems to work, wow, I'm lucky !!! */
6027	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
6028	awrq->sa_family = ARPHRD_ETHER;
6029
6030	return 0;
6031}
6032
6033/*------------------------------------------------------------------*/
6034/*
6035 * Wireless Handler : set Nickname
6036 */
6037static int airo_set_nick(struct net_device *dev,
6038			 struct iw_request_info *info,
6039			 union iwreq_data *wrqu,
6040			 char *extra)
6041{
6042	struct iw_point *dwrq = &wrqu->data;
6043	struct airo_info *local = dev->ml_priv;
6044
6045	/* Check the size of the string */
6046	if (dwrq->length > 16) {
6047		return -E2BIG;
6048	}
6049	readConfigRid(local, 1);
6050	memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
6051	memcpy(local->config.nodeName, extra, dwrq->length);
6052	set_bit (FLAG_COMMIT, &local->flags);
6053
6054	return -EINPROGRESS;		/* Call commit handler */
6055}
6056
6057/*------------------------------------------------------------------*/
6058/*
6059 * Wireless Handler : get Nickname
6060 */
6061static int airo_get_nick(struct net_device *dev,
6062			 struct iw_request_info *info,
6063			 union iwreq_data *wrqu,
6064			 char *extra)
6065{
6066	struct iw_point *dwrq = &wrqu->data;
6067	struct airo_info *local = dev->ml_priv;
6068
6069	readConfigRid(local, 1);
6070	strncpy(extra, local->config.nodeName, 16);
6071	extra[16] = '\0';
6072	dwrq->length = strlen(extra);
6073
6074	return 0;
6075}
6076
6077/*------------------------------------------------------------------*/
6078/*
6079 * Wireless Handler : set Bit-Rate
6080 */
6081static int airo_set_rate(struct net_device *dev,
6082			 struct iw_request_info *info,
6083			 union iwreq_data *wrqu,
6084			 char *extra)
6085{
6086	struct iw_param *vwrq = &wrqu->bitrate;
6087	struct airo_info *local = dev->ml_priv;
6088	CapabilityRid cap_rid;		/* Card capability info */
6089	u8	brate = 0;
6090	int	i;
6091
6092	/* First : get a valid bit rate value */
6093	readCapabilityRid(local, &cap_rid, 1);
6094
6095	/* Which type of value ? */
6096	if ((vwrq->value < 8) && (vwrq->value >= 0)) {
6097		/* Setting by rate index */
6098		/* Find value in the magic rate table */
6099		brate = cap_rid.supportedRates[vwrq->value];
6100	} else {
6101		/* Setting by frequency value */
6102		u8	normvalue = (u8) (vwrq->value/500000);
6103
6104		/* Check if rate is valid */
6105		for (i = 0 ; i < 8 ; i++) {
6106			if (normvalue == cap_rid.supportedRates[i]) {
6107				brate = normvalue;
6108				break;
6109			}
6110		}
6111	}
6112	/* -1 designed the max rate (mostly auto mode) */
6113	if (vwrq->value == -1) {
6114		/* Get the highest available rate */
6115		for (i = 0 ; i < 8 ; i++) {
6116			if (cap_rid.supportedRates[i] == 0)
6117				break;
6118		}
6119		if (i != 0)
6120			brate = cap_rid.supportedRates[i - 1];
6121	}
6122	/* Check that it is valid */
6123	if (brate == 0) {
6124		return -EINVAL;
6125	}
6126
6127	readConfigRid(local, 1);
6128	/* Now, check if we want a fixed or auto value */
6129	if (vwrq->fixed == 0) {
6130		/* Fill all the rates up to this max rate */
6131		memset(local->config.rates, 0, 8);
6132		for (i = 0 ; i < 8 ; i++) {
6133			local->config.rates[i] = cap_rid.supportedRates[i];
6134			if (local->config.rates[i] == brate)
6135				break;
6136		}
6137	} else {
6138		/* Fixed mode */
6139		/* One rate, fixed */
6140		memset(local->config.rates, 0, 8);
6141		local->config.rates[0] = brate;
6142	}
6143	set_bit (FLAG_COMMIT, &local->flags);
6144
6145	return -EINPROGRESS;		/* Call commit handler */
6146}
6147
6148/*------------------------------------------------------------------*/
6149/*
6150 * Wireless Handler : get Bit-Rate
6151 */
6152static int airo_get_rate(struct net_device *dev,
6153			 struct iw_request_info *info,
6154			 union iwreq_data *wrqu,
6155			 char *extra)
6156{
6157	struct iw_param *vwrq = &wrqu->bitrate;
6158	struct airo_info *local = dev->ml_priv;
6159	StatusRid status_rid;		/* Card status info */
6160
6161	readStatusRid(local, &status_rid, 1);
6162
6163	vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
6164	/* If more than one rate, set auto */
6165	readConfigRid(local, 1);
6166	vwrq->fixed = (local->config.rates[1] == 0);
6167
6168	return 0;
6169}
6170
6171/*------------------------------------------------------------------*/
6172/*
6173 * Wireless Handler : set RTS threshold
6174 */
6175static int airo_set_rts(struct net_device *dev,
6176			struct iw_request_info *info,
6177			union iwreq_data *wrqu,
6178			char *extra)
6179{
6180	struct iw_param *vwrq = &wrqu->rts;
6181	struct airo_info *local = dev->ml_priv;
6182	int rthr = vwrq->value;
6183
6184	if (vwrq->disabled)
6185		rthr = AIRO_DEF_MTU;
6186	if ((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
6187		return -EINVAL;
6188	}
6189	readConfigRid(local, 1);
6190	local->config.rtsThres = cpu_to_le16(rthr);
6191	set_bit (FLAG_COMMIT, &local->flags);
6192
6193	return -EINPROGRESS;		/* Call commit handler */
6194}
6195
6196/*------------------------------------------------------------------*/
6197/*
6198 * Wireless Handler : get RTS threshold
6199 */
6200static int airo_get_rts(struct net_device *dev,
6201			struct iw_request_info *info,
6202			union iwreq_data *wrqu,
6203			char *extra)
6204{
6205	struct iw_param *vwrq = &wrqu->rts;
6206	struct airo_info *local = dev->ml_priv;
6207
6208	readConfigRid(local, 1);
6209	vwrq->value = le16_to_cpu(local->config.rtsThres);
6210	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6211	vwrq->fixed = 1;
6212
6213	return 0;
6214}
6215
6216/*------------------------------------------------------------------*/
6217/*
6218 * Wireless Handler : set Fragmentation threshold
6219 */
6220static int airo_set_frag(struct net_device *dev,
6221			 struct iw_request_info *info,
6222			 union iwreq_data *wrqu, char *extra)
 
6223{
6224	struct iw_param *vwrq = &wrqu->frag;
6225	struct airo_info *local = dev->ml_priv;
6226	int fthr = vwrq->value;
6227
6228	if (vwrq->disabled)
6229		fthr = AIRO_DEF_MTU;
6230	if ((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
6231		return -EINVAL;
6232	}
6233	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
6234	readConfigRid(local, 1);
6235	local->config.fragThresh = cpu_to_le16(fthr);
6236	set_bit (FLAG_COMMIT, &local->flags);
6237
6238	return -EINPROGRESS;		/* Call commit handler */
6239}
6240
6241/*------------------------------------------------------------------*/
6242/*
6243 * Wireless Handler : get Fragmentation threshold
6244 */
6245static int airo_get_frag(struct net_device *dev,
6246			 struct iw_request_info *info,
6247			 union iwreq_data *wrqu,
6248			 char *extra)
6249{
6250	struct iw_param *vwrq = &wrqu->frag;
6251	struct airo_info *local = dev->ml_priv;
6252
6253	readConfigRid(local, 1);
6254	vwrq->value = le16_to_cpu(local->config.fragThresh);
6255	vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6256	vwrq->fixed = 1;
6257
6258	return 0;
6259}
6260
6261/*------------------------------------------------------------------*/
6262/*
6263 * Wireless Handler : set Mode of Operation
6264 */
6265static int airo_set_mode(struct net_device *dev,
6266			 struct iw_request_info *info,
6267			 union iwreq_data *uwrq,
6268			 char *extra)
6269{
6270	__u32 mode = uwrq->mode;
6271	struct airo_info *local = dev->ml_priv;
6272	int reset = 0;
6273
6274	readConfigRid(local, 1);
6275	if (sniffing_mode(local))
6276		reset = 1;
6277
6278	switch (mode) {
6279		case IW_MODE_ADHOC:
6280			local->config.opmode &= ~MODE_CFG_MASK;
6281			local->config.opmode |= MODE_STA_IBSS;
6282			local->config.rmode &= ~RXMODE_FULL_MASK;
6283			local->config.scanMode = SCANMODE_ACTIVE;
6284			clear_bit (FLAG_802_11, &local->flags);
6285			break;
6286		case IW_MODE_INFRA:
6287			local->config.opmode &= ~MODE_CFG_MASK;
6288			local->config.opmode |= MODE_STA_ESS;
6289			local->config.rmode &= ~RXMODE_FULL_MASK;
6290			local->config.scanMode = SCANMODE_ACTIVE;
6291			clear_bit (FLAG_802_11, &local->flags);
6292			break;
6293		case IW_MODE_MASTER:
6294			local->config.opmode &= ~MODE_CFG_MASK;
6295			local->config.opmode |= MODE_AP;
6296			local->config.rmode &= ~RXMODE_FULL_MASK;
6297			local->config.scanMode = SCANMODE_ACTIVE;
6298			clear_bit (FLAG_802_11, &local->flags);
6299			break;
6300		case IW_MODE_REPEAT:
6301			local->config.opmode &= ~MODE_CFG_MASK;
6302			local->config.opmode |= MODE_AP_RPTR;
6303			local->config.rmode &= ~RXMODE_FULL_MASK;
6304			local->config.scanMode = SCANMODE_ACTIVE;
6305			clear_bit (FLAG_802_11, &local->flags);
6306			break;
6307		case IW_MODE_MONITOR:
6308			local->config.opmode &= ~MODE_CFG_MASK;
6309			local->config.opmode |= MODE_STA_ESS;
6310			local->config.rmode &= ~RXMODE_FULL_MASK;
6311			local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6312			local->config.scanMode = SCANMODE_PASSIVE;
6313			set_bit (FLAG_802_11, &local->flags);
6314			break;
6315		default:
6316			return -EINVAL;
6317	}
6318	if (reset)
6319		set_bit (FLAG_RESET, &local->flags);
6320	set_bit (FLAG_COMMIT, &local->flags);
6321
6322	return -EINPROGRESS;		/* Call commit handler */
6323}
6324
6325/*------------------------------------------------------------------*/
6326/*
6327 * Wireless Handler : get Mode of Operation
6328 */
6329static int airo_get_mode(struct net_device *dev,
6330			 struct iw_request_info *info,
6331			 union iwreq_data *uwrq,
6332			 char *extra)
6333{
6334	struct airo_info *local = dev->ml_priv;
6335
6336	readConfigRid(local, 1);
6337	/* If not managed, assume it's ad-hoc */
6338	switch (local->config.opmode & MODE_CFG_MASK) {
6339		case MODE_STA_ESS:
6340			uwrq->mode = IW_MODE_INFRA;
6341			break;
6342		case MODE_AP:
6343			uwrq->mode = IW_MODE_MASTER;
6344			break;
6345		case MODE_AP_RPTR:
6346			uwrq->mode = IW_MODE_REPEAT;
6347			break;
6348		default:
6349			uwrq->mode = IW_MODE_ADHOC;
6350	}
6351
6352	return 0;
6353}
6354
6355static inline int valid_index(struct airo_info *ai, int index)
6356{
6357	return (index >= 0) && (index <= ai->max_wep_idx);
6358}
6359
6360/*------------------------------------------------------------------*/
6361/*
6362 * Wireless Handler : set Encryption Key
6363 */
6364static int airo_set_encode(struct net_device *dev,
6365			   struct iw_request_info *info,
6366			   union iwreq_data *wrqu,
6367			   char *extra)
6368{
6369	struct iw_point *dwrq = &wrqu->encoding;
6370	struct airo_info *local = dev->ml_priv;
6371	int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
6372	__le16 currentAuthType = local->config.authType;
6373	int rc = 0;
6374
6375	if (!local->wep_capable)
6376		return -EOPNOTSUPP;
6377
6378	readConfigRid(local, 1);
6379
6380	/* Basic checking: do we have a key to set ?
6381	 * Note : with the new API, it's impossible to get a NULL pointer.
6382	 * Therefore, we need to check a key size == 0 instead.
6383	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6384	 * when no key is present (only change flags), but older versions
6385	 * don't do it. - Jean II */
6386	if (dwrq->length > 0) {
6387		wep_key_t key;
6388		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6389		int current_index;
6390
6391		/* Check the size of the key */
6392		if (dwrq->length > MAX_KEY_SIZE) {
6393			return -EINVAL;
6394		}
6395
6396		current_index = get_wep_tx_idx(local);
6397		if (current_index < 0)
6398			current_index = 0;
6399
6400		/* Check the index (none -> use current) */
6401		if (!valid_index(local, index))
6402			index = current_index;
6403
6404		/* Set the length */
6405		if (dwrq->length > MIN_KEY_SIZE)
6406			key.len = MAX_KEY_SIZE;
6407		else
6408			key.len = MIN_KEY_SIZE;
6409		/* Check if the key is not marked as invalid */
6410		if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
6411			/* Cleanup */
6412			memset(key.key, 0, MAX_KEY_SIZE);
6413			/* Copy the key in the driver */
6414			memcpy(key.key, extra, dwrq->length);
6415			/* Send the key to the card */
6416			rc = set_wep_key(local, index, key.key, key.len, perm, 1);
6417			if (rc < 0) {
6418				airo_print_err(local->dev->name, "failed to set"
6419				               " WEP key at index %d: %d.",
6420				               index, rc);
6421				return rc;
6422			}
6423		}
6424		/* WE specify that if a valid key is set, encryption
6425		 * should be enabled (user may turn it off later)
6426		 * This is also how "iwconfig ethX key on" works */
6427		if ((index == current_index) && (key.len > 0) &&
6428		   (local->config.authType == AUTH_OPEN))
6429			set_auth_type(local, AUTH_ENCRYPT);
6430	} else {
6431		/* Do we want to just set the transmit key index ? */
6432		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6433		if (valid_index(local, index)) {
6434			rc = set_wep_tx_idx(local, index, perm, 1);
6435			if (rc < 0) {
6436				airo_print_err(local->dev->name, "failed to set"
6437				               " WEP transmit index to %d: %d.",
6438				               index, rc);
6439				return rc;
6440			}
6441		} else {
6442			/* Don't complain if only change the mode */
6443			if (!(dwrq->flags & IW_ENCODE_MODE))
6444				return -EINVAL;
6445		}
6446	}
6447	/* Read the flags */
6448	if (dwrq->flags & IW_ENCODE_DISABLED)
6449		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
6450	if (dwrq->flags & IW_ENCODE_RESTRICTED)
6451		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
6452	if (dwrq->flags & IW_ENCODE_OPEN)
6453		set_auth_type(local, AUTH_ENCRYPT);	/* Only Wep */
6454	/* Commit the changes to flags if needed */
6455	if (local->config.authType != currentAuthType)
6456		set_bit (FLAG_COMMIT, &local->flags);
6457	return -EINPROGRESS;		/* Call commit handler */
6458}
6459
6460/*------------------------------------------------------------------*/
6461/*
6462 * Wireless Handler : get Encryption Key
6463 */
6464static int airo_get_encode(struct net_device *dev,
6465			   struct iw_request_info *info,
6466			   union iwreq_data *wrqu,
6467			   char *extra)
6468{
6469	struct iw_point *dwrq = &wrqu->encoding;
6470	struct airo_info *local = dev->ml_priv;
6471	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6472	int wep_key_len;
6473	u8 buf[16];
6474
6475	if (!local->wep_capable)
6476		return -EOPNOTSUPP;
6477
6478	readConfigRid(local, 1);
6479
6480	/* Check encryption mode */
6481	switch(local->config.authType)	{
6482		case AUTH_ENCRYPT:
6483			dwrq->flags = IW_ENCODE_OPEN;
6484			break;
6485		case AUTH_SHAREDKEY:
6486			dwrq->flags = IW_ENCODE_RESTRICTED;
6487			break;
6488		default:
6489		case AUTH_OPEN:
6490			dwrq->flags = IW_ENCODE_DISABLED;
6491			break;
6492	}
6493	/* We can't return the key, so set the proper flag and return zero */
6494	dwrq->flags |= IW_ENCODE_NOKEY;
6495	memset(extra, 0, 16);
6496
6497	/* Which key do we want ? -1 -> tx index */
6498	if (!valid_index(local, index)) {
6499		index = get_wep_tx_idx(local);
6500		if (index < 0)
6501			index = 0;
6502	}
6503	dwrq->flags |= index + 1;
6504
6505	/* Copy the key to the user buffer */
6506	wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
6507	if (wep_key_len < 0) {
6508		dwrq->length = 0;
6509	} else {
6510		dwrq->length = wep_key_len;
6511		memcpy(extra, buf, dwrq->length);
6512	}
6513
6514	return 0;
6515}
6516
6517/*------------------------------------------------------------------*/
6518/*
6519 * Wireless Handler : set extended Encryption parameters
6520 */
6521static int airo_set_encodeext(struct net_device *dev,
6522			   struct iw_request_info *info,
6523			    union iwreq_data *wrqu,
6524			    char *extra)
6525{
6526	struct airo_info *local = dev->ml_priv;
6527	struct iw_point *encoding = &wrqu->encoding;
6528	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6529	int perm = (encoding->flags & IW_ENCODE_TEMP ? 0 : 1);
6530	__le16 currentAuthType = local->config.authType;
6531	int idx, key_len, alg = ext->alg, set_key = 1, rc;
6532	wep_key_t key;
6533
6534	if (!local->wep_capable)
6535		return -EOPNOTSUPP;
6536
6537	readConfigRid(local, 1);
6538
6539	/* Determine and validate the key index */
6540	idx = encoding->flags & IW_ENCODE_INDEX;
6541	if (idx) {
6542		if (!valid_index(local, idx - 1))
6543			return -EINVAL;
6544		idx--;
6545	} else {
6546		idx = get_wep_tx_idx(local);
6547		if (idx < 0)
6548			idx = 0;
6549	}
6550
6551	if (encoding->flags & IW_ENCODE_DISABLED)
6552		alg = IW_ENCODE_ALG_NONE;
6553
6554	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
6555		/* Only set transmit key index here, actual
6556		 * key is set below if needed.
6557		 */
6558		rc = set_wep_tx_idx(local, idx, perm, 1);
6559		if (rc < 0) {
6560			airo_print_err(local->dev->name, "failed to set "
6561			               "WEP transmit index to %d: %d.",
6562			               idx, rc);
6563			return rc;
6564		}
6565		set_key = ext->key_len > 0 ? 1 : 0;
6566	}
6567
6568	if (set_key) {
6569		/* Set the requested key first */
6570		memset(key.key, 0, MAX_KEY_SIZE);
6571		switch (alg) {
6572		case IW_ENCODE_ALG_NONE:
6573			key.len = 0;
6574			break;
6575		case IW_ENCODE_ALG_WEP:
6576			if (ext->key_len > MIN_KEY_SIZE) {
6577				key.len = MAX_KEY_SIZE;
6578			} else if (ext->key_len > 0) {
6579				key.len = MIN_KEY_SIZE;
6580			} else {
6581				return -EINVAL;
6582			}
6583			key_len = min (ext->key_len, key.len);
6584			memcpy(key.key, ext->key, key_len);
6585			break;
6586		default:
6587			return -EINVAL;
6588		}
6589		if (key.len == 0) {
6590			rc = set_wep_tx_idx(local, idx, perm, 1);
6591			if (rc < 0) {
6592				airo_print_err(local->dev->name,
6593					       "failed to set WEP transmit index to %d: %d.",
6594					       idx, rc);
6595				return rc;
6596			}
6597		} else {
6598			rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6599			if (rc < 0) {
6600				airo_print_err(local->dev->name,
6601					       "failed to set WEP key at index %d: %d.",
6602					       idx, rc);
6603				return rc;
6604			}
6605		}
6606	}
6607
6608	/* Read the flags */
6609	if (encoding->flags & IW_ENCODE_DISABLED)
6610		set_auth_type(local, AUTH_OPEN);	/* disable encryption */
6611	if (encoding->flags & IW_ENCODE_RESTRICTED)
6612		set_auth_type(local, AUTH_SHAREDKEY);	/* Only Both */
6613	if (encoding->flags & IW_ENCODE_OPEN)
6614		set_auth_type(local, AUTH_ENCRYPT);
6615	/* Commit the changes to flags if needed */
6616	if (local->config.authType != currentAuthType)
6617		set_bit (FLAG_COMMIT, &local->flags);
6618
6619	return -EINPROGRESS;
6620}
6621
6622
6623/*------------------------------------------------------------------*/
6624/*
6625 * Wireless Handler : get extended Encryption parameters
6626 */
6627static int airo_get_encodeext(struct net_device *dev,
6628			    struct iw_request_info *info,
6629			    union iwreq_data *wrqu,
6630			    char *extra)
6631{
6632	struct airo_info *local = dev->ml_priv;
6633	struct iw_point *encoding = &wrqu->encoding;
6634	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6635	int idx, max_key_len, wep_key_len;
6636	u8 buf[16];
6637
6638	if (!local->wep_capable)
6639		return -EOPNOTSUPP;
6640
6641	readConfigRid(local, 1);
6642
6643	max_key_len = encoding->length - sizeof(*ext);
6644	if (max_key_len < 0)
6645		return -EINVAL;
6646
6647	idx = encoding->flags & IW_ENCODE_INDEX;
6648	if (idx) {
6649		if (!valid_index(local, idx - 1))
6650			return -EINVAL;
6651		idx--;
6652	} else {
6653		idx = get_wep_tx_idx(local);
6654		if (idx < 0)
6655			idx = 0;
6656	}
6657
6658	encoding->flags = idx + 1;
6659	memset(ext, 0, sizeof(*ext));
6660
6661	/* Check encryption mode */
6662	switch(local->config.authType) {
6663		case AUTH_ENCRYPT:
6664			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6665			break;
6666		case AUTH_SHAREDKEY:
6667			encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED;
6668			break;
6669		default:
6670		case AUTH_OPEN:
6671			encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED;
6672			break;
6673	}
6674	/* We can't return the key, so set the proper flag and return zero */
6675	encoding->flags |= IW_ENCODE_NOKEY;
6676	memset(extra, 0, 16);
6677
6678	/* Copy the key to the user buffer */
6679	wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
6680	if (wep_key_len < 0) {
6681		ext->key_len = 0;
6682	} else {
6683		ext->key_len = wep_key_len;
6684		memcpy(extra, buf, ext->key_len);
6685	}
6686
6687	return 0;
6688}
6689
6690
6691/*------------------------------------------------------------------*/
6692/*
6693 * Wireless Handler : set extended authentication parameters
6694 */
6695static int airo_set_auth(struct net_device *dev,
6696			       struct iw_request_info *info,
6697			       union iwreq_data *wrqu, char *extra)
6698{
6699	struct airo_info *local = dev->ml_priv;
6700	struct iw_param *param = &wrqu->param;
6701	__le16 currentAuthType = local->config.authType;
6702
6703	switch (param->flags & IW_AUTH_INDEX) {
6704	case IW_AUTH_WPA_VERSION:
6705	case IW_AUTH_CIPHER_PAIRWISE:
6706	case IW_AUTH_CIPHER_GROUP:
6707	case IW_AUTH_KEY_MGMT:
6708	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6709	case IW_AUTH_PRIVACY_INVOKED:
6710		/*
6711		 * airo does not use these parameters
6712		 */
6713		break;
6714
6715	case IW_AUTH_DROP_UNENCRYPTED:
6716		if (param->value) {
6717			/* Only change auth type if unencrypted */
6718			if (currentAuthType == AUTH_OPEN)
6719				set_auth_type(local, AUTH_ENCRYPT);
6720		} else {
6721			set_auth_type(local, AUTH_OPEN);
6722		}
6723
6724		/* Commit the changes to flags if needed */
6725		if (local->config.authType != currentAuthType)
6726			set_bit (FLAG_COMMIT, &local->flags);
6727		break;
6728
6729	case IW_AUTH_80211_AUTH_ALG: {
6730			if (param->value & IW_AUTH_ALG_SHARED_KEY) {
6731				set_auth_type(local, AUTH_SHAREDKEY);
6732			} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
6733				/* We don't know here if WEP open system or
6734				 * unencrypted mode was requested - so use the
6735				 * last mode (of these two) used last time
6736				 */
6737				set_auth_type(local, local->last_auth);
6738			} else
6739				return -EINVAL;
6740
6741			/* Commit the changes to flags if needed */
6742			if (local->config.authType != currentAuthType)
6743				set_bit (FLAG_COMMIT, &local->flags);
6744			break;
6745		}
6746
6747	case IW_AUTH_WPA_ENABLED:
6748		/* Silently accept disable of WPA */
6749		if (param->value > 0)
6750			return -EOPNOTSUPP;
6751		break;
6752
6753	default:
6754		return -EOPNOTSUPP;
6755	}
6756	return -EINPROGRESS;
6757}
6758
6759
6760/*------------------------------------------------------------------*/
6761/*
6762 * Wireless Handler : get extended authentication parameters
6763 */
6764static int airo_get_auth(struct net_device *dev,
6765			       struct iw_request_info *info,
6766			       union iwreq_data *wrqu, char *extra)
6767{
6768	struct airo_info *local = dev->ml_priv;
6769	struct iw_param *param = &wrqu->param;
6770	__le16 currentAuthType = local->config.authType;
6771
6772	switch (param->flags & IW_AUTH_INDEX) {
6773	case IW_AUTH_DROP_UNENCRYPTED:
6774		switch (currentAuthType) {
6775		case AUTH_SHAREDKEY:
6776		case AUTH_ENCRYPT:
6777			param->value = 1;
6778			break;
6779		default:
6780			param->value = 0;
6781			break;
6782		}
6783		break;
6784
6785	case IW_AUTH_80211_AUTH_ALG:
6786		switch (currentAuthType) {
6787		case AUTH_SHAREDKEY:
6788			param->value = IW_AUTH_ALG_SHARED_KEY;
6789			break;
6790		case AUTH_ENCRYPT:
6791		default:
6792			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
6793			break;
6794		}
6795		break;
6796
6797	case IW_AUTH_WPA_ENABLED:
6798		param->value = 0;
6799		break;
6800
6801	default:
6802		return -EOPNOTSUPP;
6803	}
6804	return 0;
6805}
6806
6807
6808/*------------------------------------------------------------------*/
6809/*
6810 * Wireless Handler : set Tx-Power
6811 */
6812static int airo_set_txpow(struct net_device *dev,
6813			  struct iw_request_info *info,
6814			  union iwreq_data *wrqu,
6815			  char *extra)
6816{
6817	struct iw_param *vwrq = &wrqu->txpower;
6818	struct airo_info *local = dev->ml_priv;
6819	CapabilityRid cap_rid;		/* Card capability info */
6820	int i;
6821	int rc = -EINVAL;
6822	__le16 v = cpu_to_le16(vwrq->value);
6823
6824	readCapabilityRid(local, &cap_rid, 1);
6825
6826	if (vwrq->disabled) {
6827		set_bit (FLAG_RADIO_OFF, &local->flags);
6828		set_bit (FLAG_COMMIT, &local->flags);
6829		return -EINPROGRESS;		/* Call commit handler */
6830	}
6831	if (vwrq->flags != IW_TXPOW_MWATT) {
6832		return -EINVAL;
6833	}
6834	clear_bit (FLAG_RADIO_OFF, &local->flags);
6835	for (i = 0; i < 8 && cap_rid.txPowerLevels[i]; i++)
6836		if (v == cap_rid.txPowerLevels[i]) {
6837			readConfigRid(local, 1);
6838			local->config.txPower = v;
6839			set_bit (FLAG_COMMIT, &local->flags);
6840			rc = -EINPROGRESS;	/* Call commit handler */
6841			break;
6842		}
6843	return rc;
6844}
6845
6846/*------------------------------------------------------------------*/
6847/*
6848 * Wireless Handler : get Tx-Power
6849 */
6850static int airo_get_txpow(struct net_device *dev,
6851			  struct iw_request_info *info,
6852			  union iwreq_data *wrqu,
6853			  char *extra)
6854{
6855	struct iw_param *vwrq = &wrqu->txpower;
6856	struct airo_info *local = dev->ml_priv;
6857
6858	readConfigRid(local, 1);
6859	vwrq->value = le16_to_cpu(local->config.txPower);
6860	vwrq->fixed = 1;	/* No power control */
6861	vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6862	vwrq->flags = IW_TXPOW_MWATT;
6863
6864	return 0;
6865}
6866
6867/*------------------------------------------------------------------*/
6868/*
6869 * Wireless Handler : set Retry limits
6870 */
6871static int airo_set_retry(struct net_device *dev,
6872			  struct iw_request_info *info,
6873			  union iwreq_data *wrqu,
6874			  char *extra)
6875{
6876	struct iw_param *vwrq = &wrqu->retry;
6877	struct airo_info *local = dev->ml_priv;
6878	int rc = -EINVAL;
6879
6880	if (vwrq->disabled) {
6881		return -EINVAL;
6882	}
6883	readConfigRid(local, 1);
6884	if (vwrq->flags & IW_RETRY_LIMIT) {
6885		__le16 v = cpu_to_le16(vwrq->value);
6886		if (vwrq->flags & IW_RETRY_LONG)
6887			local->config.longRetryLimit = v;
6888		else if (vwrq->flags & IW_RETRY_SHORT)
6889			local->config.shortRetryLimit = v;
6890		else {
6891			/* No modifier : set both */
6892			local->config.longRetryLimit = v;
6893			local->config.shortRetryLimit = v;
6894		}
6895		set_bit (FLAG_COMMIT, &local->flags);
6896		rc = -EINPROGRESS;		/* Call commit handler */
6897	}
6898	if (vwrq->flags & IW_RETRY_LIFETIME) {
6899		local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
6900		set_bit (FLAG_COMMIT, &local->flags);
6901		rc = -EINPROGRESS;		/* Call commit handler */
6902	}
6903	return rc;
6904}
6905
6906/*------------------------------------------------------------------*/
6907/*
6908 * Wireless Handler : get Retry limits
6909 */
6910static int airo_get_retry(struct net_device *dev,
6911			  struct iw_request_info *info,
6912			  union iwreq_data *wrqu,
6913			  char *extra)
6914{
6915	struct iw_param *vwrq = &wrqu->retry;
6916	struct airo_info *local = dev->ml_priv;
6917
6918	vwrq->disabled = 0;      /* Can't be disabled */
6919
6920	readConfigRid(local, 1);
6921	/* Note : by default, display the min retry number */
6922	if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6923		vwrq->flags = IW_RETRY_LIFETIME;
6924		vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
6925	} else if ((vwrq->flags & IW_RETRY_LONG)) {
6926		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
6927		vwrq->value = le16_to_cpu(local->config.longRetryLimit);
6928	} else {
6929		vwrq->flags = IW_RETRY_LIMIT;
6930		vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
6931		if (local->config.shortRetryLimit != local->config.longRetryLimit)
6932			vwrq->flags |= IW_RETRY_SHORT;
6933	}
6934
6935	return 0;
6936}
6937
6938/*------------------------------------------------------------------*/
6939/*
6940 * Wireless Handler : get range info
6941 */
6942static int airo_get_range(struct net_device *dev,
6943			  struct iw_request_info *info,
6944			  union iwreq_data *wrqu,
6945			  char *extra)
6946{
6947	struct iw_point *dwrq = &wrqu->data;
6948	struct airo_info *local = dev->ml_priv;
6949	struct iw_range *range = (struct iw_range *) extra;
6950	CapabilityRid cap_rid;		/* Card capability info */
6951	int		i;
6952	int		k;
6953
6954	readCapabilityRid(local, &cap_rid, 1);
6955
6956	dwrq->length = sizeof(struct iw_range);
6957	memset(range, 0, sizeof(*range));
6958	range->min_nwid = 0x0000;
6959	range->max_nwid = 0x0000;
6960	range->num_channels = 14;
6961	/* Should be based on cap_rid.country to give only
6962	 * what the current card support */
6963	k = 0;
6964	for (i = 0; i < 14; i++) {
6965		range->freq[k].i = i + 1; /* List index */
6966		range->freq[k].m = 100000 *
6967		     ieee80211_channel_to_frequency(i + 1, NL80211_BAND_2GHZ);
6968		range->freq[k++].e = 1;	/* Values in MHz -> * 10^5 * 10 */
6969	}
6970	range->num_frequency = k;
6971
6972	range->sensitivity = 65535;
6973
6974	/* Hum... Should put the right values there */
6975	if (local->rssi)
6976		range->max_qual.qual = 100;	/* % */
6977	else
6978		range->max_qual.qual = airo_get_max_quality(&cap_rid);
6979	range->max_qual.level = 0x100 - 120;	/* -120 dBm */
6980	range->max_qual.noise = 0x100 - 120;	/* -120 dBm */
6981
6982	/* Experimental measurements - boundary 11/5.5 Mb/s */
6983	/* Note : with or without the (local->rssi), results
6984	 * are somewhat different. - Jean II */
6985	if (local->rssi) {
6986		range->avg_qual.qual = 50;		/* % */
6987		range->avg_qual.level = 0x100 - 70;	/* -70 dBm */
6988	} else {
6989		range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6990		range->avg_qual.level = 0x100 - 80;	/* -80 dBm */
6991	}
6992	range->avg_qual.noise = 0x100 - 85;		/* -85 dBm */
6993
6994	for (i = 0 ; i < 8 ; i++) {
6995		range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6996		if (range->bitrate[i] == 0)
6997			break;
6998	}
6999	range->num_bitrates = i;
7000
7001	/* Set an indication of the max TCP throughput
7002	 * in bit/s that we can expect using this interface.
7003	 * May be use for QoS stuff... Jean II */
7004	if (i > 2)
7005		range->throughput = 5000 * 1000;
7006	else
7007		range->throughput = 1500 * 1000;
7008
7009	range->min_rts = 0;
7010	range->max_rts = AIRO_DEF_MTU;
7011	range->min_frag = 256;
7012	range->max_frag = AIRO_DEF_MTU;
7013
7014	if (cap_rid.softCap & cpu_to_le16(2)) {
7015		// WEP: RC4 40 bits
7016		range->encoding_size[0] = 5;
7017		// RC4 ~128 bits
7018		if (cap_rid.softCap & cpu_to_le16(0x100)) {
7019			range->encoding_size[1] = 13;
7020			range->num_encoding_sizes = 2;
7021		} else
7022			range->num_encoding_sizes = 1;
7023		range->max_encoding_tokens =
7024			cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
7025	} else {
7026		range->num_encoding_sizes = 0;
7027		range->max_encoding_tokens = 0;
7028	}
7029	range->min_pmp = 0;
7030	range->max_pmp = 5000000;	/* 5 secs */
7031	range->min_pmt = 0;
7032	range->max_pmt = 65535 * 1024;	/* ??? */
7033	range->pmp_flags = IW_POWER_PERIOD;
7034	range->pmt_flags = IW_POWER_TIMEOUT;
7035	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
7036
7037	/* Transmit Power - values are in mW */
7038	for (i = 0 ; i < 8 ; i++) {
7039		range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
7040		if (range->txpower[i] == 0)
7041			break;
7042	}
7043	range->num_txpower = i;
7044	range->txpower_capa = IW_TXPOW_MWATT;
7045	range->we_version_source = 19;
7046	range->we_version_compiled = WIRELESS_EXT;
7047	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
7048	range->retry_flags = IW_RETRY_LIMIT;
7049	range->r_time_flags = IW_RETRY_LIFETIME;
7050	range->min_retry = 1;
7051	range->max_retry = 65535;
7052	range->min_r_time = 1024;
7053	range->max_r_time = 65535 * 1024;
7054
7055	/* Event capability (kernel + driver) */
7056	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
7057				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
7058				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
7059				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
7060	range->event_capa[1] = IW_EVENT_CAPA_K_1;
7061	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
7062	return 0;
7063}
7064
7065/*------------------------------------------------------------------*/
7066/*
7067 * Wireless Handler : set Power Management
7068 */
7069static int airo_set_power(struct net_device *dev,
7070			  struct iw_request_info *info,
7071			  union iwreq_data *wrqu, char *extra)
 
7072{
7073	struct iw_param *vwrq = &wrqu->power;
7074	struct airo_info *local = dev->ml_priv;
7075
7076	readConfigRid(local, 1);
7077	if (vwrq->disabled) {
7078		if (sniffing_mode(local))
7079			return -EINVAL;
7080		local->config.powerSaveMode = POWERSAVE_CAM;
7081		local->config.rmode &= ~RXMODE_MASK;
7082		local->config.rmode |= RXMODE_BC_MC_ADDR;
7083		set_bit (FLAG_COMMIT, &local->flags);
7084		return -EINPROGRESS;		/* Call commit handler */
7085	}
7086	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7087		local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
7088		local->config.powerSaveMode = POWERSAVE_PSPCAM;
7089		set_bit (FLAG_COMMIT, &local->flags);
7090	} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
7091		local->config.fastListenInterval =
7092		local->config.listenInterval =
7093			cpu_to_le16((vwrq->value + 500) / 1024);
7094		local->config.powerSaveMode = POWERSAVE_PSPCAM;
7095		set_bit (FLAG_COMMIT, &local->flags);
7096	}
7097	switch (vwrq->flags & IW_POWER_MODE) {
7098		case IW_POWER_UNICAST_R:
7099			if (sniffing_mode(local))
7100				return -EINVAL;
7101			local->config.rmode &= ~RXMODE_MASK;
7102			local->config.rmode |= RXMODE_ADDR;
7103			set_bit (FLAG_COMMIT, &local->flags);
7104			break;
7105		case IW_POWER_ALL_R:
7106			if (sniffing_mode(local))
7107				return -EINVAL;
7108			local->config.rmode &= ~RXMODE_MASK;
7109			local->config.rmode |= RXMODE_BC_MC_ADDR;
7110			set_bit (FLAG_COMMIT, &local->flags);
7111			break;
7112		case IW_POWER_ON:
7113			/* This is broken, fixme ;-) */
7114			break;
7115		default:
7116			return -EINVAL;
7117	}
7118	// Note : we may want to factor local->need_commit here
7119	// Note2 : may also want to factor RXMODE_RFMON test
7120	return -EINPROGRESS;		/* Call commit handler */
7121}
7122
7123/*------------------------------------------------------------------*/
7124/*
7125 * Wireless Handler : get Power Management
7126 */
7127static int airo_get_power(struct net_device *dev,
7128			  struct iw_request_info *info,
7129			  union iwreq_data *wrqu,
7130			  char *extra)
7131{
7132	struct iw_param *vwrq = &wrqu->power;
7133	struct airo_info *local = dev->ml_priv;
7134	__le16 mode;
7135
7136	readConfigRid(local, 1);
7137	mode = local->config.powerSaveMode;
7138	if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
7139		return 0;
7140	if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
7141		vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
7142		vwrq->flags = IW_POWER_TIMEOUT;
7143	} else {
7144		vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
7145		vwrq->flags = IW_POWER_PERIOD;
7146	}
7147	if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
7148		vwrq->flags |= IW_POWER_UNICAST_R;
7149	else
7150		vwrq->flags |= IW_POWER_ALL_R;
7151
7152	return 0;
7153}
7154
7155/*------------------------------------------------------------------*/
7156/*
7157 * Wireless Handler : set Sensitivity
7158 */
7159static int airo_set_sens(struct net_device *dev,
7160			 struct iw_request_info *info,
7161			 union iwreq_data *wrqu,
7162			 char *extra)
7163{
7164	struct iw_param *vwrq = &wrqu->sens;
7165	struct airo_info *local = dev->ml_priv;
7166
7167	readConfigRid(local, 1);
7168	local->config.rssiThreshold =
7169		cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
7170	set_bit (FLAG_COMMIT, &local->flags);
7171
7172	return -EINPROGRESS;		/* Call commit handler */
7173}
7174
7175/*------------------------------------------------------------------*/
7176/*
7177 * Wireless Handler : get Sensitivity
7178 */
7179static int airo_get_sens(struct net_device *dev,
7180			 struct iw_request_info *info,
7181			 union iwreq_data *wrqu,
7182			 char *extra)
7183{
7184	struct iw_param *vwrq = &wrqu->sens;
7185	struct airo_info *local = dev->ml_priv;
7186
7187	readConfigRid(local, 1);
7188	vwrq->value = le16_to_cpu(local->config.rssiThreshold);
7189	vwrq->disabled = (vwrq->value == 0);
7190	vwrq->fixed = 1;
7191
7192	return 0;
7193}
7194
7195/*------------------------------------------------------------------*/
7196/*
7197 * Wireless Handler : get AP List
7198 * Note : this is deprecated in favor of IWSCAN
7199 */
7200static int airo_get_aplist(struct net_device *dev,
7201			   struct iw_request_info *info,
7202			   union iwreq_data *wrqu,
7203			   char *extra)
7204{
7205	struct iw_point *dwrq = &wrqu->data;
7206	struct airo_info *local = dev->ml_priv;
7207	struct sockaddr *address = (struct sockaddr *) extra;
7208	struct iw_quality *qual;
7209	BSSListRid BSSList;
7210	int i;
7211	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
7212
7213	qual = kmalloc_array(IW_MAX_AP, sizeof(*qual), GFP_KERNEL);
7214	if (!qual)
7215		return -ENOMEM;
7216
7217	for (i = 0; i < IW_MAX_AP; i++) {
7218		u16 dBm;
7219		if (readBSSListRid(local, loseSync, &BSSList))
7220			break;
7221		loseSync = 0;
7222		memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
7223		address[i].sa_family = ARPHRD_ETHER;
7224		dBm = le16_to_cpu(BSSList.dBm);
7225		if (local->rssi) {
7226			qual[i].level = 0x100 - dBm;
7227			qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
7228			qual[i].updated = IW_QUAL_QUAL_UPDATED
7229					| IW_QUAL_LEVEL_UPDATED
7230					| IW_QUAL_DBM;
7231		} else {
7232			qual[i].level = (dBm + 321) / 2;
7233			qual[i].qual = 0;
7234			qual[i].updated = IW_QUAL_QUAL_INVALID
7235					| IW_QUAL_LEVEL_UPDATED
7236					| IW_QUAL_DBM;
7237		}
7238		qual[i].noise = local->wstats.qual.noise;
7239		if (BSSList.index == cpu_to_le16(0xffff))
7240			break;
7241	}
7242	if (!i) {
7243		StatusRid status_rid;		/* Card status info */
7244		readStatusRid(local, &status_rid, 1);
7245		for (i = 0;
7246		     i < min(IW_MAX_AP, 4) &&
7247			     (status_rid.bssid[i][0]
7248			      & status_rid.bssid[i][1]
7249			      & status_rid.bssid[i][2]
7250			      & status_rid.bssid[i][3]
7251			      & status_rid.bssid[i][4]
7252			      & status_rid.bssid[i][5])!=0xff &&
7253			     (status_rid.bssid[i][0]
7254			      | status_rid.bssid[i][1]
7255			      | status_rid.bssid[i][2]
7256			      | status_rid.bssid[i][3]
7257			      | status_rid.bssid[i][4]
7258			      | status_rid.bssid[i][5]);
7259		     i++) {
7260			memcpy(address[i].sa_data,
7261			       status_rid.bssid[i], ETH_ALEN);
7262			address[i].sa_family = ARPHRD_ETHER;
7263		}
7264	} else {
7265		dwrq->flags = 1; /* Should be define'd */
7266		memcpy(extra + sizeof(struct sockaddr) * i, qual,
7267		       sizeof(struct iw_quality) * i);
7268	}
7269	dwrq->length = i;
7270
7271	kfree(qual);
7272	return 0;
7273}
7274
7275/*------------------------------------------------------------------*/
7276/*
7277 * Wireless Handler : Initiate Scan
7278 */
7279static int airo_set_scan(struct net_device *dev,
7280			 struct iw_request_info *info,
7281			 union iwreq_data *wrqu,
7282			 char *extra)
7283{
7284	struct airo_info *ai = dev->ml_priv;
7285	Cmd cmd;
7286	Resp rsp;
7287	int wake = 0;
7288	APListRid APList_rid_empty;
7289
7290	/* Note : you may have realised that, as this is a SET operation,
7291	 * this is privileged and therefore a normal user can't
7292	 * perform scanning.
7293	 * This is not an error, while the device perform scanning,
7294	 * traffic doesn't flow, so it's a perfect DoS...
7295	 * Jean II */
7296	if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
7297
7298	if (down_interruptible(&ai->sem))
7299		return -ERESTARTSYS;
7300
7301	/* If there's already a scan in progress, don't
7302	 * trigger another one. */
7303	if (ai->scan_timeout > 0)
7304		goto out;
7305
7306	/* Clear APList as it affects scan results */
7307	memset(&APList_rid_empty, 0, sizeof(APList_rid_empty));
7308	APList_rid_empty.len = cpu_to_le16(sizeof(APList_rid_empty));
7309	disable_MAC(ai, 2);
7310	writeAPListRid(ai, &APList_rid_empty, 0);
7311	enable_MAC(ai, 0);
7312
7313	/* Initiate a scan command */
7314	ai->scan_timeout = RUN_AT(3*HZ);
7315	memset(&cmd, 0, sizeof(cmd));
7316	cmd.cmd = CMD_LISTBSS;
7317	issuecommand(ai, &cmd, &rsp, true);
7318	wake = 1;
7319
7320out:
7321	up(&ai->sem);
7322	if (wake)
7323		wake_up_interruptible(&ai->thr_wait);
7324	return 0;
7325}
7326
7327/*------------------------------------------------------------------*/
7328/*
7329 * Translate scan data returned from the card to a card independent
7330 * format that the Wireless Tools will understand - Jean II
7331 */
7332static inline char *airo_translate_scan(struct net_device *dev,
7333					struct iw_request_info *info,
7334					char *current_ev,
7335					char *end_buf,
7336					BSSListRid *bss)
7337{
7338	struct airo_info *ai = dev->ml_priv;
7339	struct iw_event		iwe;		/* Temporary buffer */
7340	__le16			capabilities;
7341	char *			current_val;	/* For rates */
7342	int			i;
7343	char *		buf;
7344	u16 dBm;
7345
7346	/* First entry *MUST* be the AP MAC address */
7347	iwe.cmd = SIOCGIWAP;
7348	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7349	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7350	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7351					  &iwe, IW_EV_ADDR_LEN);
7352
7353	/* Other entries will be displayed in the order we give them */
7354
7355	/* Add the ESSID */
7356	iwe.u.data.length = bss->ssidLen;
7357	if (iwe.u.data.length > 32)
7358		iwe.u.data.length = 32;
7359	iwe.cmd = SIOCGIWESSID;
7360	iwe.u.data.flags = 1;
7361	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7362					  &iwe, bss->ssid);
7363
7364	/* Add mode */
7365	iwe.cmd = SIOCGIWMODE;
7366	capabilities = bss->cap;
7367	if (capabilities & (CAP_ESS | CAP_IBSS)) {
7368		if (capabilities & CAP_ESS)
7369			iwe.u.mode = IW_MODE_MASTER;
7370		else
7371			iwe.u.mode = IW_MODE_ADHOC;
7372		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7373						  &iwe, IW_EV_UINT_LEN);
7374	}
7375
7376	/* Add frequency */
7377	iwe.cmd = SIOCGIWFREQ;
7378	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
7379	iwe.u.freq.m = 100000 *
7380	      ieee80211_channel_to_frequency(iwe.u.freq.m, NL80211_BAND_2GHZ);
7381	iwe.u.freq.e = 1;
7382	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7383					  &iwe, IW_EV_FREQ_LEN);
7384
7385	dBm = le16_to_cpu(bss->dBm);
7386
7387	/* Add quality statistics */
7388	iwe.cmd = IWEVQUAL;
7389	if (ai->rssi) {
7390		iwe.u.qual.level = 0x100 - dBm;
7391		iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
7392		iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
7393				| IW_QUAL_LEVEL_UPDATED
7394				| IW_QUAL_DBM;
7395	} else {
7396		iwe.u.qual.level = (dBm + 321) / 2;
7397		iwe.u.qual.qual = 0;
7398		iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
7399				| IW_QUAL_LEVEL_UPDATED
7400				| IW_QUAL_DBM;
7401	}
7402	iwe.u.qual.noise = ai->wstats.qual.noise;
7403	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7404					  &iwe, IW_EV_QUAL_LEN);
7405
7406	/* Add encryption capability */
7407	iwe.cmd = SIOCGIWENCODE;
7408	if (capabilities & CAP_PRIVACY)
7409		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
7410	else
7411		iwe.u.data.flags = IW_ENCODE_DISABLED;
7412	iwe.u.data.length = 0;
7413	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7414					  &iwe, bss->ssid);
7415
7416	/* Rate : stuffing multiple values in a single event require a bit
7417	 * more of magic - Jean II */
7418	current_val = current_ev + iwe_stream_lcp_len(info);
7419
7420	iwe.cmd = SIOCGIWRATE;
7421	/* Those two flags are ignored... */
7422	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
7423	/* Max 8 values */
7424	for (i = 0 ; i < 8 ; i++) {
7425		/* NULL terminated */
7426		if (bss->rates[i] == 0)
7427			break;
7428		/* Bit rate given in 500 kb/s units (+ 0x80) */
7429		iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7430		/* Add new value to event */
7431		current_val = iwe_stream_add_value(info, current_ev,
7432						   current_val, end_buf,
7433						   &iwe, IW_EV_PARAM_LEN);
7434	}
7435	/* Check if we added any event */
7436	if ((current_val - current_ev) > iwe_stream_lcp_len(info))
7437		current_ev = current_val;
7438
7439	/* Beacon interval */
7440	buf = kmalloc(30, GFP_KERNEL);
7441	if (buf) {
7442		iwe.cmd = IWEVCUSTOM;
7443		sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7444		iwe.u.data.length = strlen(buf);
7445		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7446						  &iwe, buf);
7447		kfree(buf);
7448	}
7449
7450	/* Put WPA/RSN Information Elements into the event stream */
7451	if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
7452		unsigned int num_null_ies = 0;
7453		u16 length = sizeof (bss->extra.iep);
7454		u8 *ie = (void *)&bss->extra.iep;
7455
7456		while ((length >= 2) && (num_null_ies < 2)) {
7457			if (2 + ie[1] > length) {
7458				/* Invalid element, don't continue parsing IE */
7459				break;
7460			}
7461
7462			switch (ie[0]) {
7463			case WLAN_EID_SSID:
7464				/* Two zero-length SSID elements
7465				 * mean we're done parsing elements */
7466				if (!ie[1])
7467					num_null_ies++;
7468				break;
7469
7470			case WLAN_EID_VENDOR_SPECIFIC:
7471				if (ie[1] >= 4 &&
7472				    ie[2] == 0x00 &&
7473				    ie[3] == 0x50 &&
7474				    ie[4] == 0xf2 &&
7475				    ie[5] == 0x01) {
7476					iwe.cmd = IWEVGENIE;
7477					/* 64 is an arbitrary cut-off */
7478					iwe.u.data.length = min(ie[1] + 2,
7479								64);
7480					current_ev = iwe_stream_add_point(
7481							info, current_ev,
7482							end_buf, &iwe, ie);
7483				}
7484				break;
7485
7486			case WLAN_EID_RSN:
7487				iwe.cmd = IWEVGENIE;
7488				/* 64 is an arbitrary cut-off */
7489				iwe.u.data.length = min(ie[1] + 2, 64);
7490				current_ev = iwe_stream_add_point(
7491					info, current_ev, end_buf,
7492					&iwe, ie);
7493				break;
7494
7495			default:
7496				break;
7497			}
7498
7499			length -= 2 + ie[1];
7500			ie += 2 + ie[1];
7501		}
7502	}
7503	return current_ev;
7504}
7505
7506/*------------------------------------------------------------------*/
7507/*
7508 * Wireless Handler : Read Scan Results
7509 */
7510static int airo_get_scan(struct net_device *dev,
7511			 struct iw_request_info *info,
7512			 union iwreq_data *wrqu,
7513			 char *extra)
7514{
7515	struct iw_point *dwrq = &wrqu->data;
7516	struct airo_info *ai = dev->ml_priv;
7517	BSSListElement *net;
7518	int err = 0;
7519	char *current_ev = extra;
7520
7521	/* If a scan is in-progress, return -EAGAIN */
7522	if (ai->scan_timeout > 0)
7523		return -EAGAIN;
7524
7525	if (down_interruptible(&ai->sem))
7526		return -EAGAIN;
7527
7528	list_for_each_entry (net, &ai->network_list, list) {
7529		/* Translate to WE format this entry */
7530		current_ev = airo_translate_scan(dev, info, current_ev,
7531						 extra + dwrq->length,
7532						 &net->bss);
7533
7534		/* Check if there is space for one more entry */
7535		if ((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7536			/* Ask user space to try again with a bigger buffer */
7537			err = -E2BIG;
7538			goto out;
7539		}
7540	}
7541
7542	/* Length of data */
7543	dwrq->length = (current_ev - extra);
7544	dwrq->flags = 0;	/* todo */
7545
7546out:
7547	up(&ai->sem);
7548	return err;
7549}
7550
7551/*------------------------------------------------------------------*/
7552/*
7553 * Commit handler : called after a bunch of SET operations
7554 */
7555static int airo_config_commit(struct net_device *dev,
7556			      struct iw_request_info *info,	/* NULL */
7557			      union iwreq_data *wrqu,		/* NULL */
7558			      char *extra)			/* NULL */
7559{
7560	struct airo_info *local = dev->ml_priv;
7561
7562	if (!test_bit (FLAG_COMMIT, &local->flags))
7563		return 0;
7564
7565	/* Some of the "SET" function may have modified some of the
7566	 * parameters. It's now time to commit them in the card */
7567	disable_MAC(local, 1);
7568	if (test_bit (FLAG_RESET, &local->flags)) {
7569		SsidRid SSID_rid;
7570
7571		readSsidRid(local, &SSID_rid);
7572		if (test_bit(FLAG_MPI,&local->flags))
7573			setup_card(local, dev, 1);
7574		else
7575			reset_airo_card(dev);
7576		disable_MAC(local, 1);
7577		writeSsidRid(local, &SSID_rid, 1);
7578		writeAPListRid(local, &local->APList, 1);
7579	}
7580	if (down_interruptible(&local->sem))
7581		return -ERESTARTSYS;
7582	writeConfigRid(local, 0);
7583	enable_MAC(local, 0);
7584	if (test_bit (FLAG_RESET, &local->flags))
7585		airo_set_promisc(local, true);
7586	else
7587		up(&local->sem);
7588
7589	return 0;
7590}
7591
7592/*------------------------------------------------------------------*/
7593/*
7594 * Structures to export the Wireless Handlers
7595 */
7596
7597static const struct iw_priv_args airo_private_args[] = {
7598/*{ cmd,         set_args,                            get_args, name } */
7599  { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7600    IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
7601  { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
7602    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
7603};
7604
7605static const iw_handler		airo_handler[] =
7606{
7607	IW_HANDLER(SIOCSIWCOMMIT,	airo_config_commit),
7608	IW_HANDLER(SIOCGIWNAME,		airo_get_name),
7609	IW_HANDLER(SIOCSIWFREQ,		airo_set_freq),
7610	IW_HANDLER(SIOCGIWFREQ,		airo_get_freq),
7611	IW_HANDLER(SIOCSIWMODE,		airo_set_mode),
7612	IW_HANDLER(SIOCGIWMODE,		airo_get_mode),
7613	IW_HANDLER(SIOCSIWSENS,		airo_set_sens),
7614	IW_HANDLER(SIOCGIWSENS,		airo_get_sens),
7615	IW_HANDLER(SIOCGIWRANGE,	airo_get_range),
7616	IW_HANDLER(SIOCSIWSPY,		iw_handler_set_spy),
7617	IW_HANDLER(SIOCGIWSPY,		iw_handler_get_spy),
7618	IW_HANDLER(SIOCSIWTHRSPY,	iw_handler_set_thrspy),
7619	IW_HANDLER(SIOCGIWTHRSPY,	iw_handler_get_thrspy),
7620	IW_HANDLER(SIOCSIWAP,		airo_set_wap),
7621	IW_HANDLER(SIOCGIWAP,		airo_get_wap),
7622	IW_HANDLER(SIOCGIWAPLIST,	airo_get_aplist),
7623	IW_HANDLER(SIOCSIWSCAN,		airo_set_scan),
7624	IW_HANDLER(SIOCGIWSCAN,		airo_get_scan),
7625	IW_HANDLER(SIOCSIWESSID,	airo_set_essid),
7626	IW_HANDLER(SIOCGIWESSID,	airo_get_essid),
7627	IW_HANDLER(SIOCSIWNICKN,	airo_set_nick),
7628	IW_HANDLER(SIOCGIWNICKN,	airo_get_nick),
7629	IW_HANDLER(SIOCSIWRATE,		airo_set_rate),
7630	IW_HANDLER(SIOCGIWRATE,		airo_get_rate),
7631	IW_HANDLER(SIOCSIWRTS,		airo_set_rts),
7632	IW_HANDLER(SIOCGIWRTS,		airo_get_rts),
7633	IW_HANDLER(SIOCSIWFRAG,		airo_set_frag),
7634	IW_HANDLER(SIOCGIWFRAG,		airo_get_frag),
7635	IW_HANDLER(SIOCSIWTXPOW,	airo_set_txpow),
7636	IW_HANDLER(SIOCGIWTXPOW,	airo_get_txpow),
7637	IW_HANDLER(SIOCSIWRETRY,	airo_set_retry),
7638	IW_HANDLER(SIOCGIWRETRY,	airo_get_retry),
7639	IW_HANDLER(SIOCSIWENCODE,	airo_set_encode),
7640	IW_HANDLER(SIOCGIWENCODE,	airo_get_encode),
7641	IW_HANDLER(SIOCSIWPOWER,	airo_set_power),
7642	IW_HANDLER(SIOCGIWPOWER,	airo_get_power),
7643	IW_HANDLER(SIOCSIWAUTH,		airo_set_auth),
7644	IW_HANDLER(SIOCGIWAUTH,		airo_get_auth),
7645	IW_HANDLER(SIOCSIWENCODEEXT,	airo_set_encodeext),
7646	IW_HANDLER(SIOCGIWENCODEEXT,	airo_get_encodeext),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7647};
7648
7649/* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7650 * We want to force the use of the ioctl code, because those can't be
7651 * won't work the iw_handler code (because they simultaneously read
7652 * and write data and iw_handler can't do that).
7653 * Note that it's perfectly legal to read/write on a single ioctl command,
7654 * you just can't use iwpriv and need to force it via the ioctl handler.
7655 * Jean II */
7656static const iw_handler		airo_private_handler[] =
7657{
7658	NULL,				/* SIOCIWFIRSTPRIV */
7659};
7660
7661static const struct iw_handler_def	airo_handler_def =
7662{
7663	.num_standard	= ARRAY_SIZE(airo_handler),
7664	.num_private	= ARRAY_SIZE(airo_private_handler),
7665	.num_private_args = ARRAY_SIZE(airo_private_args),
7666	.standard	= airo_handler,
7667	.private	= airo_private_handler,
7668	.private_args	= airo_private_args,
7669	.get_wireless_stats = airo_get_wireless_stats,
7670};
7671
7672/*
7673 * This defines the configuration part of the Wireless Extensions
7674 * Note : irq and spinlock protection will occur in the subroutines
7675 *
7676 * TODO :
7677 *	o Check input value more carefully and fill correct values in range
7678 *	o Test and shakeout the bugs (if any)
7679 *
7680 * Jean II
7681 *
7682 * Javier Achirica did a great job of merging code from the unnamed CISCO
7683 * developer that added support for flashing the card.
7684 */
7685static int airo_siocdevprivate(struct net_device *dev, struct ifreq *rq,
7686			       void __user *data, int cmd)
7687{
7688	int rc = 0;
7689	struct airo_info *ai = dev->ml_priv;
7690
7691	if (ai->power.event)
7692		return 0;
7693
7694	switch (cmd) {
7695#ifdef CISCO_EXT
7696	case AIROIDIFC:
7697#ifdef AIROOLDIDIFC
7698	case AIROOLDIDIFC:
7699#endif
7700	{
7701		int val = AIROMAGIC;
7702		aironet_ioctl com;
7703		if (copy_from_user(&com, data, sizeof(com)))
7704			rc = -EFAULT;
7705		else if (copy_to_user(com.data, (char *)&val, sizeof(val)))
7706			rc = -EFAULT;
7707	}
7708	break;
7709
7710	case AIROIOCTL:
7711#ifdef AIROOLDIOCTL
7712	case AIROOLDIOCTL:
7713#endif
7714		/* Get the command struct and hand it off for evaluation by
7715		 * the proper subfunction
7716		 */
7717	{
7718		aironet_ioctl com;
7719		if (copy_from_user(&com, data, sizeof(com))) {
7720			rc = -EFAULT;
7721			break;
7722		}
7723
7724		/* Separate R/W functions bracket legality here
7725		 */
7726		if (com.command == AIRORSWVERSION) {
7727			if (copy_to_user(com.data, swversion, sizeof(swversion)))
7728				rc = -EFAULT;
7729			else
7730				rc = 0;
7731		}
7732		else if (com.command <= AIRORRID)
7733			rc = readrids(dev,&com);
7734		else if (com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2))
7735			rc = writerids(dev,&com);
7736		else if (com.command >= AIROFLSHRST && com.command <= AIRORESTART)
7737			rc = flashcard(dev,&com);
7738		else
7739			rc = -EINVAL;      /* Bad command in ioctl */
7740	}
7741	break;
7742#endif /* CISCO_EXT */
7743
7744	// All other calls are currently unsupported
7745	default:
7746		rc = -EOPNOTSUPP;
7747	}
7748	return rc;
7749}
7750
7751/*
7752 * Get the Wireless stats out of the driver
7753 * Note : irq and spinlock protection will occur in the subroutines
7754 *
7755 * TODO :
7756 *	o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7757 *
7758 * Jean
7759 */
7760static void airo_read_wireless_stats(struct airo_info *local)
7761{
7762	StatusRid status_rid;
7763	StatsRid stats_rid;
7764	CapabilityRid cap_rid;
7765	__le32 *vals = stats_rid.vals;
7766
7767	/* Get stats out of the card */
7768	if (local->power.event)
 
 
7769		return;
7770
7771	readCapabilityRid(local, &cap_rid, 0);
7772	readStatusRid(local, &status_rid, 0);
7773	readStatsRid(local, &stats_rid, RID_STATS, 0);
 
7774
7775	/* The status */
7776	local->wstats.status = le16_to_cpu(status_rid.mode);
7777
7778	/* Signal quality and co */
7779	if (local->rssi) {
7780		local->wstats.qual.level =
7781			airo_rssi_to_dbm(local->rssi,
7782					 le16_to_cpu(status_rid.sigQuality));
7783		/* normalizedSignalStrength appears to be a percentage */
7784		local->wstats.qual.qual =
7785			le16_to_cpu(status_rid.normalizedSignalStrength);
7786	} else {
7787		local->wstats.qual.level =
7788			(le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
7789		local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7790	}
7791	if (le16_to_cpu(status_rid.len) >= 124) {
7792		local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
7793		local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
7794	} else {
7795		local->wstats.qual.noise = 0;
7796		local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
7797	}
7798
7799	/* Packets discarded in the wireless adapter due to wireless
7800	 * specific problems */
7801	local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
7802				     le32_to_cpu(vals[57]) +
7803				     le32_to_cpu(vals[58]); /* SSID Mismatch */
7804	local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
7805	local->wstats.discard.fragment = le32_to_cpu(vals[30]);
7806	local->wstats.discard.retries = le32_to_cpu(vals[10]);
7807	local->wstats.discard.misc = le32_to_cpu(vals[1]) +
7808				     le32_to_cpu(vals[32]);
7809	local->wstats.miss.beacon = le32_to_cpu(vals[34]);
7810}
7811
7812static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7813{
7814	struct airo_info *local =  dev->ml_priv;
7815
7816	if (!down_interruptible(&local->sem)) {
7817		airo_read_wireless_stats(local);
7818		up(&local->sem);
 
 
 
 
7819	}
 
7820	return &local->wstats;
7821}
7822
7823#ifdef CISCO_EXT
7824/*
7825 * This just translates from driver IOCTL codes to the command codes to
7826 * feed to the radio's host interface. Things can be added/deleted
7827 * as needed.  This represents the READ side of control I/O to
7828 * the card
7829 */
7830static int readrids(struct net_device *dev, aironet_ioctl *comp)
7831{
7832	unsigned short ridcode;
7833	unsigned char *iobuf;
7834	int len;
7835	struct airo_info *ai = dev->ml_priv;
7836
7837	if (test_bit(FLAG_FLASHING, &ai->flags))
7838		return -EIO;
7839
7840	switch(comp->command)
7841	{
7842	case AIROGCAP:      ridcode = RID_CAPABILITIES; break;
7843	case AIROGCFG:      ridcode = RID_CONFIG;
7844		if (test_bit(FLAG_COMMIT, &ai->flags)) {
7845			disable_MAC (ai, 1);
7846			writeConfigRid (ai, 1);
7847			enable_MAC(ai, 1);
7848		}
7849		break;
7850	case AIROGSLIST:    ridcode = RID_SSID;         break;
7851	case AIROGVLIST:    ridcode = RID_APLIST;       break;
7852	case AIROGDRVNAM:   ridcode = RID_DRVNAME;      break;
7853	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
7854	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;	break;
7855	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;	break;
 
 
 
 
 
 
 
 
7856	case AIROGSTAT:     ridcode = RID_STATUS;       break;
7857	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
7858	case AIROGSTATSC32: ridcode = RID_STATS;        break;
7859	case AIROGMICSTATS:
7860		if (copy_to_user(comp->data, &ai->micstats,
7861				 min((int)comp->len, (int)sizeof(ai->micstats))))
7862			return -EFAULT;
7863		return 0;
7864	case AIRORRID:      ridcode = comp->ridnum;     break;
7865	default:
7866		return -EINVAL;
7867	}
7868
7869	if (ridcode == RID_WEP_TEMP || ridcode == RID_WEP_PERM) {
7870		/* Only super-user can read WEP keys */
7871		if (!capable(CAP_NET_ADMIN))
7872			return -EPERM;
7873	}
7874
7875	if ((iobuf = kzalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7876		return -ENOMEM;
7877
7878	PC4500_readrid(ai, ridcode, iobuf, RIDSIZE, 1);
7879	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
7880	 * then return it to the user
7881	 * 9/22/2000 Honor user given length
7882	 */
7883	len = comp->len;
7884
7885	if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7886		kfree (iobuf);
7887		return -EFAULT;
7888	}
7889	kfree (iobuf);
7890	return 0;
7891}
7892
7893/*
7894 * Danger Will Robinson write the rids here
7895 */
7896
7897static int writerids(struct net_device *dev, aironet_ioctl *comp)
7898{
7899	struct airo_info *ai = dev->ml_priv;
7900	int  ridcode;
7901        int  enabled;
7902	int (*writer)(struct airo_info *, u16 rid, const void *, int, int);
7903	unsigned char *iobuf;
7904
7905	/* Only super-user can write RIDs */
7906	if (!capable(CAP_NET_ADMIN))
7907		return -EPERM;
7908
7909	if (test_bit(FLAG_FLASHING, &ai->flags))
7910		return -EIO;
7911
7912	ridcode = 0;
7913	writer = do_writerid;
7914
7915	switch(comp->command)
7916	{
7917	case AIROPSIDS:     ridcode = RID_SSID;         break;
7918	case AIROPCAP:      ridcode = RID_CAPABILITIES; break;
7919	case AIROPAPLIST:   ridcode = RID_APLIST;       break;
7920	case AIROPCFG: ai->config.len = 0;
7921			    clear_bit(FLAG_COMMIT, &ai->flags);
7922			    ridcode = RID_CONFIG;       break;
7923	case AIROPWEPKEYNV: ridcode = RID_WEP_PERM;     break;
7924	case AIROPLEAPUSR:  ridcode = RID_LEAPUSERNAME; break;
7925	case AIROPLEAPPWD:  ridcode = RID_LEAPPASSWORD; break;
7926	case AIROPWEPKEY:   ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7927		break;
7928	case AIROPLEAPUSR+1: ridcode = 0xFF2A;          break;
7929	case AIROPLEAPUSR+2: ridcode = 0xFF2B;          break;
7930
7931		/* this is not really a rid but a command given to the card
7932		 * same with MAC off
7933		 */
7934	case AIROPMACON:
7935		if (enable_MAC(ai, 1) != 0)
7936			return -EIO;
7937		return 0;
7938
7939		/*
7940		 * Evidently this code in the airo driver does not get a symbol
7941		 * as disable_MAC. it's probably so short the compiler does not gen one.
7942		 */
7943	case AIROPMACOFF:
7944		disable_MAC(ai, 1);
7945		return 0;
7946
7947		/* This command merely clears the counts does not actually store any data
7948		 * only reads rid. But as it changes the cards state, I put it in the
7949		 * writerid routines.
7950		 */
7951	case AIROPSTCLR:
7952		if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7953			return -ENOMEM;
7954
7955		PC4500_readrid(ai, RID_STATSDELTACLEAR, iobuf, RIDSIZE, 1);
7956
7957		enabled = ai->micstats.enabled;
7958		memset(&ai->micstats, 0, sizeof(ai->micstats));
7959		ai->micstats.enabled = enabled;
7960
7961		if (copy_to_user(comp->data, iobuf,
7962				 min((int)comp->len, (int)RIDSIZE))) {
7963			kfree (iobuf);
7964			return -EFAULT;
7965		}
7966		kfree (iobuf);
7967		return 0;
7968
7969	default:
7970		return -EOPNOTSUPP;	/* Blarg! */
7971	}
7972	if (comp->len > RIDSIZE)
7973		return -EINVAL;
7974
7975	if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7976		return -ENOMEM;
7977
7978	if (copy_from_user(iobuf, comp->data, comp->len)) {
7979		kfree (iobuf);
7980		return -EFAULT;
7981	}
7982
7983	if (comp->command == AIROPCFG) {
7984		ConfigRid *cfg = (ConfigRid *)iobuf;
7985
7986		if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7987			cfg->opmode |= MODE_MIC;
7988
7989		if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
7990			set_bit (FLAG_ADHOC, &ai->flags);
7991		else
7992			clear_bit (FLAG_ADHOC, &ai->flags);
7993	}
7994
7995	if ((*writer)(ai, ridcode, iobuf, comp->len, 1)) {
7996		kfree (iobuf);
7997		return -EIO;
7998	}
7999	kfree (iobuf);
8000	return 0;
8001}
8002
8003/*****************************************************************************
8004 * Ancillary flash / mod functions much black magic lurkes here              *
8005 *****************************************************************************
8006 */
8007
8008/*
8009 * Flash command switch table
8010 */
8011
8012static int flashcard(struct net_device *dev, aironet_ioctl *comp)
8013{
8014	int z;
8015
8016	/* Only super-user can modify flash */
8017	if (!capable(CAP_NET_ADMIN))
8018		return -EPERM;
8019
8020	switch(comp->command)
8021	{
8022	case AIROFLSHRST:
8023		return cmdreset((struct airo_info *)dev->ml_priv);
8024
8025	case AIROFLSHSTFL:
8026		if (!AIRO_FLASH(dev) &&
8027		    (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
8028			return -ENOMEM;
8029		return setflashmode((struct airo_info *)dev->ml_priv);
8030
8031	case AIROFLSHGCHR: /* Get char from aux */
8032		if (comp->len != sizeof(int))
8033			return -EINVAL;
8034		if (copy_from_user(&z, comp->data, comp->len))
8035			return -EFAULT;
8036		return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
8037
8038	case AIROFLSHPCHR: /* Send char to card. */
8039		if (comp->len != sizeof(int))
8040			return -EINVAL;
8041		if (copy_from_user(&z, comp->data, comp->len))
8042			return -EFAULT;
8043		return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
8044
8045	case AIROFLPUTBUF: /* Send 32k to card */
8046		if (!AIRO_FLASH(dev))
8047			return -ENOMEM;
8048		if (comp->len > FLASHSIZE)
8049			return -EINVAL;
8050		if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
8051			return -EFAULT;
8052
8053		flashputbuf((struct airo_info *)dev->ml_priv);
8054		return 0;
8055
8056	case AIRORESTART:
8057		if (flashrestart((struct airo_info *)dev->ml_priv, dev))
8058			return -EIO;
8059		return 0;
8060	}
8061	return -EINVAL;
8062}
8063
8064#define FLASH_COMMAND  0x7e7e
8065
8066/*
8067 * STEP 1)
8068 * Disable MAC and do soft reset on
8069 * card.
8070 */
8071
8072static int cmdreset(struct airo_info *ai)
8073{
8074	disable_MAC(ai, 1);
8075
8076	if (!waitbusy (ai)) {
8077		airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
8078		return -EBUSY;
8079	}
8080
8081	OUT4500(ai, COMMAND, CMD_SOFTRESET);
8082
8083	ssleep(1);			/* WAS 600 12/7/00 */
8084
8085	if (!waitbusy (ai)) {
8086		airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
8087		return -EBUSY;
8088	}
8089	return 0;
8090}
8091
8092/* STEP 2)
8093 * Put the card in legendary flash
8094 * mode
8095 */
8096
8097static int setflashmode (struct airo_info *ai)
8098{
8099	set_bit (FLAG_FLASHING, &ai->flags);
8100
8101	OUT4500(ai, SWS0, FLASH_COMMAND);
8102	OUT4500(ai, SWS1, FLASH_COMMAND);
8103	if (probe) {
8104		OUT4500(ai, SWS0, FLASH_COMMAND);
8105		OUT4500(ai, COMMAND, 0x10);
8106	} else {
8107		OUT4500(ai, SWS2, FLASH_COMMAND);
8108		OUT4500(ai, SWS3, FLASH_COMMAND);
8109		OUT4500(ai, COMMAND, 0);
8110	}
8111	msleep(500);		/* 500ms delay */
8112
8113	if (!waitbusy(ai)) {
8114		clear_bit (FLAG_FLASHING, &ai->flags);
8115		airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
8116		return -EIO;
8117	}
8118	return 0;
8119}
8120
8121/* Put character to SWS0 wait for dwelltime
8122 * x 50us for  echo .
8123 */
8124
8125static int flashpchar(struct airo_info *ai, int byte, int dwelltime)
8126{
8127	int echo;
8128	int waittime;
8129
8130	byte |= 0x8000;
8131
8132	if (dwelltime == 0)
8133		dwelltime = 200;
8134
8135	waittime = dwelltime;
8136
8137	/* Wait for busy bit d15 to go false indicating buffer empty */
8138	while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
8139		udelay (50);
8140		waittime -= 50;
8141	}
8142
8143	/* timeout for busy clear wait */
8144	if (waittime <= 0) {
8145		airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
8146		return -EBUSY;
8147	}
8148
8149	/* Port is clear now write byte and wait for it to echo back */
8150	do {
8151		OUT4500(ai, SWS0, byte);
8152		udelay(50);
8153		dwelltime -= 50;
8154		echo = IN4500(ai, SWS1);
8155	} while (dwelltime >= 0 && echo != byte);
8156
8157	OUT4500(ai, SWS1, 0);
8158
8159	return (echo == byte) ? 0 : -EIO;
8160}
8161
8162/*
8163 * Get a character from the card matching matchbyte
8164 * Step 3)
8165 */
8166static int flashgchar(struct airo_info *ai, int matchbyte, int dwelltime)
8167{
8168	int           rchar;
8169	unsigned char rbyte = 0;
8170
8171	do {
8172		rchar = IN4500(ai, SWS1);
8173
8174		if (dwelltime && !(0x8000 & rchar)) {
8175			dwelltime -= 10;
8176			mdelay(10);
8177			continue;
8178		}
8179		rbyte = 0xff & rchar;
8180
8181		if ((rbyte == matchbyte) && (0x8000 & rchar)) {
8182			OUT4500(ai, SWS1, 0);
8183			return 0;
8184		}
8185		if (rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
8186			break;
8187		OUT4500(ai, SWS1, 0);
8188
8189	} while (dwelltime > 0);
8190	return -EIO;
8191}
8192
8193/*
8194 * Transfer 32k of firmware data from user buffer to our buffer and
8195 * send to the card
8196 */
8197
8198static int flashputbuf(struct airo_info *ai)
8199{
8200	int            nwords;
8201
8202	/* Write stuff */
8203	if (test_bit(FLAG_MPI,&ai->flags))
8204		memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
8205	else {
8206		OUT4500(ai, AUXPAGE, 0x100);
8207		OUT4500(ai, AUXOFF, 0);
8208
8209		for (nwords = 0; nwords != FLASHSIZE / 2; nwords++) {
8210			OUT4500(ai, AUXDATA, ai->flash[nwords] & 0xffff);
8211		}
8212	}
8213	OUT4500(ai, SWS0, 0x8000);
8214
8215	return 0;
8216}
8217
8218/*
8219 *
8220 */
8221static int flashrestart(struct airo_info *ai, struct net_device *dev)
8222{
8223	int    i, status;
8224
8225	ssleep(1);			/* Added 12/7/00 */
8226	clear_bit (FLAG_FLASHING, &ai->flags);
8227	if (test_bit(FLAG_MPI, &ai->flags)) {
8228		status = mpi_init_descriptors(ai);
8229		if (status != SUCCESS)
8230			return status;
8231	}
8232	status = setup_card(ai, dev, 1);
8233
8234	if (!test_bit(FLAG_MPI,&ai->flags))
8235		for (i = 0; i < MAX_FIDS; i++) {
8236			ai->fids[i] = transmit_allocate
8237				(ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2);
8238		}
8239
8240	ssleep(1);			/* Added 12/7/00 */
8241	return status;
8242}
8243#endif /* CISCO_EXT */
8244
8245/*
8246    This program is free software; you can redistribute it and/or
8247    modify it under the terms of the GNU General Public License
8248    as published by the Free Software Foundation; either version 2
8249    of the License, or (at your option) any later version.
8250
8251    This program is distributed in the hope that it will be useful,
8252    but WITHOUT ANY WARRANTY; without even the implied warranty of
8253    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8254    GNU General Public License for more details.
8255
8256    In addition:
8257
8258    Redistribution and use in source and binary forms, with or without
8259    modification, are permitted provided that the following conditions
8260    are met:
8261
8262    1. Redistributions of source code must retain the above copyright
8263       notice, this list of conditions and the following disclaimer.
8264    2. Redistributions in binary form must reproduce the above copyright
8265       notice, this list of conditions and the following disclaimer in the
8266       documentation and/or other materials provided with the distribution.
8267    3. The name of the author may not be used to endorse or promote
8268       products derived from this software without specific prior written
8269       permission.
8270
8271    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8272    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8273    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8274    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
8275    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8276    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
8277    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8278    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8279    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
8280    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8281    POSSIBILITY OF SUCH DAMAGE.
8282*/
8283
8284module_init(airo_init_module);
8285module_exit(airo_cleanup_module);