source "drivers/staging/samsung-laptop/Kconfig"
 
-source "drivers/staging/wavelan/Kconfig"
-
 source "drivers/staging/netwave/Kconfig"
 
 source "drivers/staging/sm7xx/Kconfig"
 
 obj-$(CONFIG_WLAGS49_H25)      += wlags49_h25/
 obj-$(CONFIG_BATMAN_ADV)       += batman-adv/
 obj-$(CONFIG_SAMSUNG_LAPTOP)   += samsung-laptop/
-obj-$(CONFIG_WAVELAN)          += wavelan/
-obj-$(CONFIG_PCMCIA_WAVELAN)   += wavelan/
 obj-$(CONFIG_PCMCIA_NETWAVE)   += netwave/
 obj-$(CONFIG_FB_SM7XX)         += sm7xx/
 obj-$(CONFIG_DT3155)           += dt3155/
 
+++ /dev/null
-config WAVELAN
-       tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support"
-       depends on ISA && WLAN
-       select WIRELESS_EXT
-       select WEXT_SPY
-       select WEXT_PRIV
-       ---help---
-         The Lucent WaveLAN (formerly NCR and AT&T; or DEC RoamAbout DS) is
-         a Radio LAN (wireless Ethernet-like Local Area Network) using the
-         radio frequencies 900 MHz and 2.4 GHz.
-
-         If you want to use an ISA WaveLAN card under Linux, say Y and read
-         the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>. Some more specific
-         information is contained in
-         <file:Documentation/networking/wavelan.txt> and in the source code
-         <file:drivers/net/wireless/wavelan.p.h>.
-
-         You will also need the wireless tools package available from
-         <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-         Please read the man pages contained therein.
-
-         To compile this driver as a module, choose M here: the module will be
-         called wavelan.
-
-config PCMCIA_WAVELAN
-       tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support"
-       depends on PCMCIA && WLAN
-       select WIRELESS_EXT
-       select WEXT_SPY
-       select WEXT_PRIV
-       help
-         Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
-         (PC-card) wireless Ethernet networking card to your computer.  This
-         driver is for the non-IEEE-802.11 Wavelan cards.
-
-         To compile this driver as a module, choose M here: the module will be
-         called wavelan_cs.  If unsure, say N.
 
+++ /dev/null
-obj-$(CONFIG_WAVELAN)          += wavelan.o
-obj-$(CONFIG_PCMCIA_WAVELAN)   += wavelan_cs.o
 
+++ /dev/null
-TODO:
-       - step up and maintain this driver to ensure that it continues
-         to work.  Having the hardware for this is pretty much a
-         requirement.  If this does not happen, the will be removed in
-         the 2.6.35 kernel release.
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com>.
 
+++ /dev/null
-/*
- * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
- *
- * See:
- *     Intel Microcommunications 1991
- *     p1-1 to p1-37
- *     Intel order No. 231658
- *     ISBN 1-55512-119-5
- *
- *     Unfortunately, the above chapter mentions neither
- * the System Configuration Pointer (SCP) nor the
- * Intermediate System Configuration Pointer (ISCP),
- * so we probably need to look elsewhere for the
- * whole story -- some recommend the "Intel LAN
- * Components manual" but I have neither a copy
- * nor a full reference.  But "elsewhere" may be
- * in the same publication...
- *     The description of a later device, the
- * "82596CA High-Performance 32-Bit Local Area Network
- * Coprocessor", (ibid. p1-38 to p1-109) does mention
- * the SCP and ISCP and also has an i82586 compatibility
- * mode.  Even more useful is "AP-235 An 82586 Data Link
- * Driver" (ibid. p1-337 to p1-417).
- */
-
-#define        I82586_MEMZ     (64 * 1024)
-
-#define        I82586_SCP_ADDR (I82586_MEMZ - sizeof(scp_t))
-
-#define        ADDR_LEN        6
-#define        I82586NULL      0xFFFF
-
-#define        toff(t, p, f)   (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * System Configuration Pointer (SCP).
- */
-typedef struct scp_t   scp_t;
-struct scp_t {
-       unsigned short  scp_sysbus;     /* 82586 bus width:     */
-#define                SCP_SY_16BBUS   (0x0 << 0)      /* 16 bits */
-#define                SCP_SY_8BBUS    (0x1 << 0)      /*  8 bits. */
-       unsigned short  scp_junk[2];    /* Unused */
-       unsigned short  scp_iscpl;      /* lower 16 bits of ISCP_ADDR */
-       unsigned short  scp_iscph;      /* upper 16 bits of ISCP_ADDR */
-};
-
-/*
- * Intermediate System Configuration Pointer (ISCP).
- */
-typedef struct iscp_t  iscp_t;
-struct iscp_t {
-       unsigned short  iscp_busy;      /* set by CPU before first CA,  */
-                                       /* cleared by 82586 after read. */
-       unsigned short  iscp_offset;    /* offset of SCB                */
-       unsigned short  iscp_basel;     /* base of SCB                  */
-       unsigned short  iscp_baseh;     /*  "                           */
-};
-
-/*
- * System Control Block (SCB).
- *     The 82586 writes its status to scb_status and then
- *     raises an interrupt to alert the CPU.
- *     The CPU writes a command to scb_command and
- *     then issues a Channel Attention (CA) to alert the 82586.
- */
-typedef struct scb_t   scb_t;
-struct scb_t {
-       unsigned short  scb_status;     /* Status of 82586              */
-#define                SCB_ST_INT      (0xF << 12)     /* Some of:             */
-#define                SCB_ST_CX       (0x1 << 15)     /* Cmd completed        */
-#define                SCB_ST_FR       (0x1 << 14)     /* Frame received       */
-#define                SCB_ST_CNA      (0x1 << 13)     /* Cmd unit not active  */
-#define                SCB_ST_RNR      (0x1 << 12)     /* Rcv unit not ready   */
-#define                SCB_ST_JUNK0    (0x1 << 11)     /* 0                    */
-#define                SCB_ST_CUS      (0x7 <<  8)     /* Cmd unit status      */
-#define                        SCB_ST_CUS_IDLE (0 << 8)        /* Idle         */
-#define                        SCB_ST_CUS_SUSP (1 << 8)        /* Suspended    */
-#define                        SCB_ST_CUS_ACTV (2 << 8)        /* Active       */
-#define                SCB_ST_JUNK1    (0x1 <<  7)     /* 0                    */
-#define                SCB_ST_RUS      (0x7 <<  4)     /* Rcv unit status      */
-#define                        SCB_ST_RUS_IDLE (0 << 4)        /* Idle         */
-#define                        SCB_ST_RUS_SUSP (1 << 4)        /* Suspended    */
-#define                        SCB_ST_RUS_NRES (2 << 4)        /* No resources */
-#define                        SCB_ST_RUS_RDY  (4 << 4)        /* Ready        */
-       unsigned short  scb_command;    /* Next command                 */
-#define                SCB_CMD_ACK_CX  (0x1 << 15)     /* Ack cmd completion   */
-#define                SCB_CMD_ACK_FR  (0x1 << 14)     /* Ack frame received   */
-#define                SCB_CMD_ACK_CNA (0x1 << 13)     /* Ack CU not active    */
-#define                SCB_CMD_ACK_RNR (0x1 << 12)     /* Ack RU not ready     */
-#define                SCB_CMD_JUNKX   (0x1 << 11)     /* Unused               */
-#define                SCB_CMD_CUC     (0x7 <<  8)     /* Command Unit command */
-#define                        SCB_CMD_CUC_NOP (0 << 8)        /* Nop          */
-#define                        SCB_CMD_CUC_GO  (1 << 8)        /* Start cbl_offset */
-#define                        SCB_CMD_CUC_RES (2 << 8)        /* Resume execution */
-#define                        SCB_CMD_CUC_SUS (3 << 8)        /* Suspend   "  */
-#define                        SCB_CMD_CUC_ABT (4 << 8)        /* Abort     "  */
-#define                SCB_CMD_RESET   (0x1 <<  7)     /* Reset chip (hardware) */
-#define                SCB_CMD_RUC     (0x7 <<  4)     /* Receive Unit command */
-#define                        SCB_CMD_RUC_NOP (0 << 4)        /* Nop          */
-#define                        SCB_CMD_RUC_GO  (1 << 4)        /* Start rfa_offset */
-#define                        SCB_CMD_RUC_RES (2 << 4)        /* Resume reception */
-#define                        SCB_CMD_RUC_SUS (3 << 4)        /* Suspend   "  */
-#define                        SCB_CMD_RUC_ABT (4 << 4)        /* Abort     "  */
-       unsigned short  scb_cbl_offset; /* Offset of first command unit */
-                                       /* Action Command               */
-       unsigned short  scb_rfa_offset; /* Offset of first Receive      */
-                                       /* Frame Descriptor in the      */
-                                       /* Receive Frame Area           */
-       unsigned short  scb_crcerrs;    /* Properly aligned frames      */
-                                       /* received with a CRC error    */
-       unsigned short  scb_alnerrs;    /* Misaligned frames received   */
-                                       /* with a CRC error             */
-       unsigned short  scb_rscerrs;    /* Frames lost due to no space  */
-       unsigned short  scb_ovrnerrs;   /* Frames lost due to slow bus  */
-};
-
-#define        scboff(p, f)    toff(scb_t, p, f)
-
-/*
- * The eight Action Commands.
- */
-typedef enum acmd_e    acmd_e;
-enum acmd_e {
-       acmd_nop        = 0,    /* Do nothing                           */
-       acmd_ia_setup   = 1,    /* Load an (ethernet) address into the  */
-                               /* 82586                                */
-       acmd_configure  = 2,    /* Update the 82586 operating parameters */
-       acmd_mc_setup   = 3,    /* Load a list of (ethernet) multicast  */
-                               /* addresses into the 82586             */
-       acmd_transmit   = 4,    /* Transmit a frame                     */
-       acmd_tdr        = 5,    /* Perform a Time Domain Reflectometer  */
-                               /* test on the serial link              */
-       acmd_dump       = 6,    /* Copy 82586 registers to memory       */
-       acmd_diagnose   = 7,    /* Run an internal self test            */
-};
-
-/*
- * Generic Action Command header.
- */
-typedef struct ach_t   ach_t;
-struct ach_t {
-       unsigned short  ac_status;              /* Command status:      */
-#define                AC_SFLD_C       (0x1 << 15)     /* Command completed    */
-#define                AC_SFLD_B       (0x1 << 14)     /* Busy executing       */
-#define                AC_SFLD_OK      (0x1 << 13)     /* Completed error free */
-#define                AC_SFLD_A       (0x1 << 12)     /* Command aborted      */
-#define                AC_SFLD_FAIL    (0x1 << 11)     /* Selftest failed      */
-#define                AC_SFLD_S10     (0x1 << 10)     /* No carrier sense     */
-                                               /* during transmission  */
-#define                AC_SFLD_S9      (0x1 <<  9)     /* Tx unsuccessful:     */
-                                               /* (stopped) lost CTS   */
-#define                AC_SFLD_S8      (0x1 <<  8)     /* Tx unsuccessful:     */
-                                               /* (stopped) slow DMA   */
-#define                AC_SFLD_S7      (0x1 <<  7)     /* Tx deferred:         */
-                                               /* other link traffic   */
-#define                AC_SFLD_S6      (0x1 <<  6)     /* Heart Beat: collision */
-                                               /* detect after last tx */
-#define                AC_SFLD_S5      (0x1 <<  5)     /* Tx stopped:          */
-                                               /* excessive collisions */
-#define                AC_SFLD_MAXCOL  (0xF <<  0)     /* Collision count      */
-       unsigned short  ac_command;             /* Command specifier:   */
-#define                AC_CFLD_EL      (0x1 << 15)     /* End of command list  */
-#define                AC_CFLD_S       (0x1 << 14)     /* Suspend on completion */
-#define                AC_CFLD_I       (0x1 << 13)     /* Interrupt on completion */
-#define                AC_CFLD_CMD     (0x7 <<  0)     /* acmd_e               */
-       unsigned short  ac_link;                /* Next Action Command  */
-};
-
-#define        acoff(p, f)     toff(ach_t, p, f)
-
-/*
- * The Nop Action Command.
- */
-typedef struct ac_nop_t        ac_nop_t;
-struct ac_nop_t {
-       ach_t   nop_h;
-};
-
-/*
- * The IA-Setup Action Command.
- */
-typedef struct ac_ias_t        ac_ias_t;
-struct ac_ias_t {
-       ach_t           ias_h;
-       unsigned char   ias_addr[ADDR_LEN]; /* The (ethernet) address   */
-};
-
-/*
- * The Configure Action Command.
- */
-typedef struct ac_cfg_t        ac_cfg_t;
-struct ac_cfg_t {
-       ach_t           cfg_h;
-       unsigned char   cfg_byte_cnt;   /* Size foll data: 4-12 */
-#define        AC_CFG_BYTE_CNT(v)      (((v) & 0xF) << 0)
-       unsigned char   cfg_fifolim;    /* FIFO threshold       */
-#define        AC_CFG_FIFOLIM(v)       (((v) & 0xF) << 0)
-       unsigned char   cfg_byte8;
-#define        AC_CFG_SAV_BF(v)        (((v) & 0x1) << 7)      /* Save rxd bad frames  */
-#define        AC_CFG_SRDY(v)          (((v) & 0x1) << 6)      /* SRDY/ARDY pin means  */
-                                                       /* external sync.       */
-       unsigned char   cfg_byte9;
-#define        AC_CFG_ELPBCK(v)        (((v) & 0x1) << 7)      /* External loopback    */
-#define        AC_CFG_ILPBCK(v)        (((v) & 0x1) << 6)      /* Internal loopback    */
-#define        AC_CFG_PRELEN(v)        (((v) & 0x3) << 4)      /* Preamble length      */
-#define                AC_CFG_PLEN_2           0               /*  2 bytes     */
-#define                AC_CFG_PLEN_4           1               /*  4 bytes     */
-#define                AC_CFG_PLEN_8           2               /*  8 bytes     */
-#define                AC_CFG_PLEN_16          3               /* 16 bytes     */
-#define        AC_CFG_ALOC(v)          (((v) & 0x1) << 3)      /* Addr/len data is     */
-                                                       /* explicit in buffers  */
-#define        AC_CFG_ADDRLEN(v)       (((v) & 0x7) << 0)      /* Bytes per address    */
-       unsigned char   cfg_byte10;
-#define        AC_CFG_BOFMET(v)        (((v) & 0x1) << 7)      /* Use alternate expo.  */
-                                                       /* backoff method       */
-#define        AC_CFG_ACR(v)           (((v) & 0x7) << 4)      /* Accelerated cont. res. */
-#define        AC_CFG_LINPRIO(v)       (((v) & 0x7) << 0)      /* Linear priority      */
-       unsigned char   cfg_ifs;        /* Interframe spacing           */
-       unsigned char   cfg_slotl;      /* Slot time (low byte)         */
-       unsigned char   cfg_byte13;
-#define        AC_CFG_RETRYNUM(v)      (((v) & 0xF) << 4)      /* Max. collision retry */
-#define        AC_CFG_SLTTMHI(v)       (((v) & 0x7) << 0)      /* Slot time (high bits) */
-       unsigned char   cfg_byte14;
-#define        AC_CFG_FLGPAD(v)        (((v) & 0x1) << 7)      /* Pad with HDLC flags  */
-#define        AC_CFG_BTSTF(v)         (((v) & 0x1) << 6)      /* Do HDLC bitstuffing  */
-#define        AC_CFG_CRC16(v)         (((v) & 0x1) << 5)      /* 16 bit CCITT CRC     */
-#define        AC_CFG_NCRC(v)          (((v) & 0x1) << 4)      /* Insert no CRC        */
-#define        AC_CFG_TNCRS(v)         (((v) & 0x1) << 3)      /* Tx even if no carrier */
-#define        AC_CFG_MANCH(v)         (((v) & 0x1) << 2)      /* Manchester coding    */
-#define        AC_CFG_BCDIS(v)         (((v) & 0x1) << 1)      /* Disable broadcast    */
-#define        AC_CFG_PRM(v)           (((v) & 0x1) << 0)      /* Promiscuous mode     */
-       unsigned char   cfg_byte15;
-#define        AC_CFG_ICDS(v)          (((v) & 0x1) << 7)      /* Internal collision   */
-                                                       /* detect source        */
-#define        AC_CFG_CDTF(v)          (((v) & 0x7) << 4)      /* Collision detect     */
-                                                       /* filter in bit times  */
-#define        AC_CFG_ICSS(v)          (((v) & 0x1) << 3)      /* Internal carrier     */
-                                                       /* sense source         */
-#define        AC_CFG_CSTF(v)          (((v) & 0x7) << 0)      /* Carrier sense        */
-                                                       /* filter in bit times  */
-       unsigned short  cfg_min_frm_len;
-#define        AC_CFG_MNFRM(v)         (((v) & 0xFF) << 0)     /* Min. bytes/frame (<= 255) */
-};
-
-/*
- * The MC-Setup Action Command.
- */
-typedef struct ac_mcs_t        ac_mcs_t;
-struct ac_mcs_t {
-       ach_t           mcs_h;
-       unsigned short  mcs_cnt;        /* No. of bytes of MC addresses */
-#if 0
-       unsigned char   mcs_data[ADDR_LEN]; /* The first MC address ..  */
-       ...
-#endif
-};
-
-#define I82586_MAX_MULTICAST_ADDRESSES 128     /* Hardware hashed filter */
-
-/*
- * The Transmit Action Command.
- */
-typedef struct ac_tx_t ac_tx_t;
-struct ac_tx_t {
-       ach_t           tx_h;
-       unsigned short  tx_tbd_offset;  /* Address of list of buffers.  */
-#if    0
-Linux packets are passed down with the destination MAC address
-and length/type field already prepended to the data,
-so we do not need to insert it.  Consistent with this
-we must also set the AC_CFG_ALOC(..) flag during the
-ac_cfg_t action command.
-       unsigned char   tx_addr[ADDR_LEN]; /* The frame dest. address   */
-       unsigned short  tx_length;      /* The frame length             */
-#endif /* 0 */
-};
-
-/*
- * The Time Domain Reflectometer Action Command.
- */
-typedef struct ac_tdr_t        ac_tdr_t;
-struct ac_tdr_t {
-       ach_t           tdr_h;
-       unsigned short  tdr_result;     /* Result.      */
-#define                AC_TDR_LNK_OK   (0x1 << 15)     /* No link problem      */
-#define                AC_TDR_XCVR_PRB (0x1 << 14)     /* Txcvr cable problem  */
-#define                AC_TDR_ET_OPN   (0x1 << 13)     /* Open on the link     */
-#define                AC_TDR_ET_SRT   (0x1 << 12)     /* Short on the link    */
-#define                AC_TDR_TIME     (0x7FF << 0)    /* Distance to problem  */
-                                               /* site in transmit     */
-                                               /* clock cycles         */
-};
-
-/*
- * The Dump Action Command.
- */
-typedef struct ac_dmp_t        ac_dmp_t;
-struct ac_dmp_t {
-       ach_t           dmp_h;
-       unsigned short  dmp_offset;     /* Result.      */
-};
-
-/*
- * Size of the result of the dump command.
- */
-#define        DUMPBYTES       170
-
-/*
- * The Diagnose Action Command.
- */
-typedef struct ac_dgn_t        ac_dgn_t;
-struct ac_dgn_t {
-       ach_t           dgn_h;
-};
-
-/*
- * Transmit Buffer Descriptor (TBD).
- */
-typedef struct tbd_t   tbd_t;
-struct tbd_t {
-       unsigned short  tbd_status;             /* Written by the CPU   */
-#define                TBD_STATUS_EOF  (0x1 << 15)     /* This TBD is the      */
-                                               /* last for this frame  */
-#define                TBD_STATUS_ACNT (0x3FFF << 0)   /* Actual count of data */
-                                               /* bytes in this buffer */
-       unsigned short  tbd_next_bd_offset;     /* Next in list         */
-       unsigned short  tbd_bufl;               /* Buffer address (low) */
-       unsigned short  tbd_bufh;               /*    "      "  (high)  */
-};
-
-/*
- * Receive Buffer Descriptor (RBD).
- */
-typedef struct rbd_t   rbd_t;
-struct rbd_t {
-       unsigned short  rbd_status;             /* Written by the 82586 */
-#define                RBD_STATUS_EOF  (0x1 << 15)     /* This RBD is the      */
-                                               /* last for this frame  */
-#define                RBD_STATUS_F    (0x1 << 14)     /* ACNT field is valid  */
-#define                RBD_STATUS_ACNT (0x3FFF << 0)   /* Actual no. of data   */
-                                               /* bytes in this buffer */
-       unsigned short  rbd_next_rbd_offset;    /* Next rbd in list     */
-       unsigned short  rbd_bufl;               /* Data pointer (low)   */
-       unsigned short  rbd_bufh;               /*  "      "    (high)  */
-       unsigned short  rbd_el_size;            /* EL+Data buf. size    */
-#define                RBD_EL  (0x1 << 15)             /* This BD is the       */
-                                               /* last in the list     */
-#define                RBD_SIZE (0x3FFF << 0)          /* No. of bytes the     */
-                                               /* buffer can hold      */
-};
-
-#define        rbdoff(p, f)    toff(rbd_t, p, f)
-
-/*
- * Frame Descriptor (FD).
- */
-typedef struct fd_t    fd_t;
-struct fd_t {
-       unsigned short  fd_status;              /* Written by the 82586 */
-#define                FD_STATUS_C     (0x1 << 15)     /* Completed storing frame */
-#define                FD_STATUS_B     (0x1 << 14)     /* FD was consumed by RU */
-#define                FD_STATUS_OK    (0x1 << 13)     /* Frame rxd successfully */
-#define                FD_STATUS_S11   (0x1 << 11)     /* CRC error            */
-#define                FD_STATUS_S10   (0x1 << 10)     /* Alignment error      */
-#define                FD_STATUS_S9    (0x1 <<  9)     /* Ran out of resources */
-#define                FD_STATUS_S8    (0x1 <<  8)     /* Rx DMA overrun       */
-#define                FD_STATUS_S7    (0x1 <<  7)     /* Frame too short      */
-#define                FD_STATUS_S6    (0x1 <<  6)     /* No EOF flag          */
-       unsigned short  fd_command;             /* Command              */
-#define                FD_COMMAND_EL   (0x1 << 15)     /* Last FD in list      */
-#define                FD_COMMAND_S    (0x1 << 14)     /* Suspend RU after rx  */
-       unsigned short  fd_link_offset;         /* Next FD              */
-       unsigned short  fd_rbd_offset;          /* First RBD (data)     */
-                                               /* Prepared by CPU,     */
-                                               /* updated by 82586     */
-#if    0
-I think the rest is unused since we
-have set AC_CFG_ALOC(..).  However, just
-in case, we leave the space.
-#endif /* 0 */
-       unsigned char   fd_dest[ADDR_LEN];      /* Destination address  */
-                                               /* Written by 82586     */
-       unsigned char   fd_src[ADDR_LEN];       /* Source address       */
-                                               /* Written by 82586     */
-       unsigned short  fd_length;              /* Frame length or type */
-                                               /* Written by 82586     */
-};
-
-#define        fdoff(p, f)     toff(fd_t, p, f)
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU General Public License.
- *
- * For more details, see wavelan.c.
- */
 
+++ /dev/null
-/*
- *     WaveLAN ISA driver
- *
- *             Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follows (also see the end of this file).
- * See wavelan.p.h for details.
- *
- *
- *
- * AT&T GIS (nee NCR) WaveLAN card:
- *     An Ethernet-like radio transceiver
- *     controlled by an Intel 82586 coprocessor.
- */
-
-#include "wavelan.p.h"         /* Private header */
-
-/************************* MISC SUBROUTINES **************************/
-/*
- * Subroutines which won't fit in one of the following category
- * (WaveLAN modem or i82586)
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Translate irq number to PSA irq parameter
- */
-static u8 wv_irq_to_psa(int irq)
-{
-       if (irq < 0 || irq >= ARRAY_SIZE(irqvals))
-               return 0;
-
-       return irqvals[irq];
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Translate PSA irq parameter to irq number
- */
-static int __init wv_psa_to_irq(u8 irqval)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(irqvals); i++)
-               if (irqvals[i] == irqval)
-                       return i;
-
-       return -1;
-}
-
-/********************* HOST ADAPTER SUBROUTINES *********************/
-/*
- * Useful subroutines to manage the WaveLAN ISA interface
- *
- * One major difference with the PCMCIA hardware (except the port mapping)
- * is that we have to keep the state of the Host Control Register
- *because of the interrupt enable & bus size flags.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read from card's Host Adaptor Status Register.
- */
-static inline u16 hasr_read(unsigned long ioaddr)
-{
-       return inw(HASR(ioaddr));
-}                              /* hasr_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register.
- */
-static inline void hacr_write(unsigned long ioaddr, u16 hacr)
-{
-       outw(hacr, HACR(ioaddr));
-}                              /* hacr_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register. Include a delay for
- * those times when it is needed.
- */
-static void hacr_write_slow(unsigned long ioaddr, u16 hacr)
-{
-       hacr_write(ioaddr, hacr);
-       /* delay might only be needed sometimes */
-       mdelay(1);
-}                              /* hacr_write_slow */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the channel attention bit.
- */
-static inline void set_chan_attn(unsigned long ioaddr, u16 hacr)
-{
-       hacr_write(ioaddr, hacr | HACR_CA);
-}                              /* set_chan_attn */
-
-/*------------------------------------------------------------------*/
-/*
- * Reset, and then set host adaptor into default mode.
- */
-static inline void wv_hacr_reset(unsigned long ioaddr)
-{
-       hacr_write_slow(ioaddr, HACR_RESET);
-       hacr_write(ioaddr, HACR_DEFAULT);
-}                              /* wv_hacr_reset */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the I/O transfer over the ISA bus to 8-bit mode
- */
-static inline void wv_16_off(unsigned long ioaddr, u16 hacr)
-{
-       hacr &= ~HACR_16BITS;
-       hacr_write(ioaddr, hacr);
-}                              /* wv_16_off */
-
-/*------------------------------------------------------------------*/
-/*
- * Set the I/O transfer over the ISA bus to 8-bit mode
- */
-static inline void wv_16_on(unsigned long ioaddr, u16 hacr)
-{
-       hacr |= HACR_16BITS;
-       hacr_write(ioaddr, hacr);
-}                              /* wv_16_on */
-
-/*------------------------------------------------------------------*/
-/*
- * Disable interrupts on the WaveLAN hardware.
- * (called by wv_82586_stop())
- */
-static inline void wv_ints_off(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-
-       lp->hacr &= ~HACR_INTRON;
-       hacr_write(ioaddr, lp->hacr);
-}                              /* wv_ints_off */
-
-/*------------------------------------------------------------------*/
-/*
- * Enable interrupts on the WaveLAN hardware.
- * (called by wv_hw_reset())
- */
-static inline void wv_ints_on(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-
-       lp->hacr |= HACR_INTRON;
-       hacr_write(ioaddr, lp->hacr);
-}                              /* wv_ints_on */
-
-/******************* MODEM MANAGEMENT SUBROUTINES *******************/
-/*
- * Useful subroutines to manage the modem of the WaveLAN
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Parameter Storage Area from the WaveLAN card's memory
- */
-/*
- * Read bytes from the PSA.
- */
-static void psa_read(unsigned long ioaddr,
-                       u16 hacr,
-                       int o,  /* offset in PSA */
-                       u8 *b,  /*buffer to fill */
-                       int n)
-{                              /* size to read */
-       wv_16_off(ioaddr, hacr);
-
-       while (n-- > 0) {
-               outw(o, PIOR2(ioaddr));
-               o++;
-               *b++ = inb(PIOP2(ioaddr));
-       }
-
-       wv_16_on(ioaddr, hacr);
-}                              /* psa_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write the Parameter Storage Area to the WaveLAN card's memory.
- */
-static void psa_write(unsigned long ioaddr,
-                       u16 hacr,
-                       int o,  /* Offset in PSA */
-                       u8 *b,  /*buffer in memory */
-                       int n)
-{                              /* Length of buffer */
-       int count = 0;
-
-       wv_16_off(ioaddr, hacr);
-
-       while (n-- > 0) {
-               outw(o, PIOR2(ioaddr));
-               o++;
-
-               outb(*b, PIOP2(ioaddr));
-               b++;
-
-               /* Wait for the memory to finish its write cycle */
-               count = 0;
-               while ((count++ < 100) && (hasr_read(ioaddr) & HASR_PSA_BUSY))
-                       mdelay(1);
-       }
-
-       wv_16_on(ioaddr, hacr);
-}                              /* psa_write */
-
-#ifdef SET_PSA_CRC
-/*------------------------------------------------------------------*/
-/*
- * Calculate the PSA CRC
- * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
- * NOTE: By specifying a length including the CRC position the
- * returned value should be zero. (i.e. a correct checksum in the PSA)
- *
- * The Windows drivers don't use the CRC, but the AP and the PtP tool
- * depend on it.
- */
-static u16 psa_crc(u8 *psa,    /* The PSA */
-                       int size)
-{                              /* Number of short for CRC */
-       int byte_cnt;           /* Loop on the PSA */
-       u16 crc_bytes = 0;      /* Data in the PSA */
-       int bit_cnt;            /* Loop on the bits of the short */
-
-       for (byte_cnt = 0; byte_cnt < size; byte_cnt++) {
-               crc_bytes ^= psa[byte_cnt];     /* Its an xor */
-
-               for (bit_cnt = 1; bit_cnt < 9; bit_cnt++) {
-                       if (crc_bytes & 0x0001)
-                               crc_bytes = (crc_bytes >> 1) ^ 0xA001;
-                       else
-                               crc_bytes >>= 1;
-               }
-       }
-
-       return crc_bytes;
-}                              /* psa_crc */
-#endif                         /* SET_PSA_CRC */
-
-/*------------------------------------------------------------------*/
-/*
- * update the checksum field in the Wavelan's PSA
- */
-static void update_psa_checksum(struct net_device *dev,
-                               unsigned long ioaddr,
-                               u16 hacr)
-{
-#ifdef SET_PSA_CRC
-       psa_t psa;
-       u16 crc;
-
-       /* read the parameter storage area */
-       psa_read(ioaddr, hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
-       /* update the checksum */
-       crc = psa_crc((unsigned char *) &psa,
-                     sizeof(psa) - sizeof(psa.psa_crc[0]) -
-                     sizeof(psa.psa_crc[1])
-                     - sizeof(psa.psa_crc_status));
-
-       psa.psa_crc[0] = crc & 0xFF;
-       psa.psa_crc[1] = (crc & 0xFF00) >> 8;
-
-       /* Write it ! */
-       psa_write(ioaddr, hacr, (char *) &psa.psa_crc - (char *) &psa,
-                 (unsigned char *) &psa.psa_crc, 2);
-
-#ifdef DEBUG_IOCTL_INFO
-       printk(KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
-              dev->name, psa.psa_crc[0], psa.psa_crc[1]);
-
-       /* Check again (luxury !) */
-       crc = psa_crc((unsigned char *) &psa,
-                     sizeof(psa) - sizeof(psa.psa_crc_status));
-
-       if (crc != 0)
-               printk(KERN_WARNING
-                      "%s: update_psa_checksum(): CRC does not \
-                      agree with PSA data (even after recalculating)\n",
-                      dev->name);
-#endif                         /* DEBUG_IOCTL_INFO */
-#endif                         /* SET_PSA_CRC */
-}                              /* update_psa_checksum */
-
-/*------------------------------------------------------------------*/
-/*
- * Write 1 byte to the MMC.
- */
-static void mmc_out(unsigned long ioaddr, u16 o, u8 d)
-{
-       int count = 0;
-
-       /* Wait for MMC to go idle */
-       while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
-               udelay(10);
-
-       outw((u16) (((u16) d << 8) | (o << 1) | 1), MMCR(ioaddr));
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to write bytes to the Modem Management Controller.
- * We start at the end because it is the way it should be!
- */
-static void mmc_write(unsigned long ioaddr, u8 o, u8 *b, int n)
-{
-       o += n;
-       b += n;
-
-       while (n-- > 0)
-               mmc_out(ioaddr, --o, *(--b));
-}                              /* mmc_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Read a byte from the MMC.
- * Optimised version for 1 byte, avoid using memory.
- */
-static u8 mmc_in(unsigned long ioaddr, u16 o)
-{
-       int count = 0;
-
-       while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
-               udelay(10);
-       outw(o << 1, MMCR(ioaddr));
-
-       while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
-               udelay(10);
-       return (u8) (inw(MMCR(ioaddr)) >> 8);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read bytes from the Modem Management Controller.
- * The implementation is complicated by a lack of address lines,
- * which prevents decoding of the low-order bit.
- * (code has just been moved in the above function)
- * We start at the end because it is the way it should be!
- */
-static inline void mmc_read(unsigned long ioaddr, u8 o, u8 *b, int n)
-{
-       o += n;
-       b += n;
-
-       while (n-- > 0)
-               *(--b) = mmc_in(ioaddr, --o);
-}                              /* mmc_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Get the type of encryption available.
- */
-static inline int mmc_encr(unsigned long ioaddr)
-{                              /* I/O port of the card */
-       int temp;
-
-       temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail));
-       if ((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
-               return 0;
-       else
-               return temp;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wait for the frequency EEPROM to complete a command.
- * I hope this one will be optimally inlined.
- */
-static inline void fee_wait(unsigned long ioaddr, /* I/O port of the card */
-                           int delay,  /*base delay to wait for */
-                           int number)
-{                              /* Number of time to wait */
-       int count = 0;          /* Wait only a limited time */
-
-       while ((count++ < number) &&
-              (mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-               MMR_FEE_STATUS_BUSY))
-                       udelay(delay);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the Frequency EEPROM (frequency select cards).
- */
-static void fee_read(unsigned long ioaddr,     /* I/O port of the card */
-                    u16 o,     /* destination offset */
-                    u16 *b,    /* data buffer */
-                    int n)
-{                              /* number of registers */
-       b += n;                 /* Position at the end of the area */
-
-       /* Write the address */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-       /* Loop on all buffer */
-       while (n-- > 0) {
-               /* Write the read command */
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-                       MMW_FEE_CTRL_READ);
-
-               /* Wait until EEPROM is ready (should be quick). */
-               fee_wait(ioaddr, 10, 100);
-
-               /* Read the value. */
-               *--b = ((mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)) << 8) |
-                       mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
-       }
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes from the Frequency EEPROM (frequency select cards).
- * This is a bit complicated, because the frequency EEPROM has to
- *be unprotected and the write enabled.
- * Jean II
- */
-static void fee_write(unsigned long ioaddr,    /* I/O port of the card */
-                     u16 o,    /* destination offset */
-                     u16 *b,   /* data buffer */
-                     int n)
-{                              /* number of registers */
-       b += n;                 /* Position at the end of the area. */
-
-#ifdef EEPROM_IS_PROTECTED     /* disabled */
-#ifdef DOESNT_SEEM_TO_WORK     /* disabled */
-       /* Ask to read the protected register */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
-
-       fee_wait(ioaddr, 10, 100);
-
-       /* Read the protected register. */
-       printk("Protected 2:  %02X-%02X\n",
-              mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)),
-              mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
-#endif                         /* DOESNT_SEEM_TO_WORK */
-
-       /* Enable protected register. */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
-
-       fee_wait(ioaddr, 10, 100);
-
-       /* Unprotect area. */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n);
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-#ifdef DOESNT_SEEM_TO_WORK     /* disabled */
-       /* or use: */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
-#endif                         /* DOESNT_SEEM_TO_WORK */
-
-       fee_wait(ioaddr, 10, 100);
-#endif                         /* EEPROM_IS_PROTECTED */
-
-       /* Write enable. */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
-
-       fee_wait(ioaddr, 10, 100);
-
-       /* Write the EEPROM address. */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-       /* Loop on all buffer */
-       while (n-- > 0) {
-               /* Write the value. */
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
-
-               /* Write the write command. */
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-                       MMW_FEE_CTRL_WRITE);
-
-               /* WaveLAN documentation says to
-               * wait at least 10 ms for EEBUSY = 0
-               */
-               mdelay(10);
-               fee_wait(ioaddr, 10, 100);
-       }
-
-       /* Write disable. */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
-
-       fee_wait(ioaddr, 10, 100);
-
-#ifdef EEPROM_IS_PROTECTED     /* disabled */
-       /* Reprotect EEPROM. */
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00);
-       mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-
-       fee_wait(ioaddr, 10, 100);
-#endif                         /* EEPROM_IS_PROTECTED */
-}
-
-/************************ I82586 SUBROUTINES *************************/
-/*
- * Useful subroutines to manage the Ethernet controller
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the on-board RAM.
- * Why does inlining this function make it fail?
- */
-static /*inline */ void obram_read(unsigned long ioaddr,
-                                  u16 o, u8 *b, int n)
-{
-       outw(o, PIOR1(ioaddr));
-       insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes to the on-board RAM.
- */
-static inline void obram_write(unsigned long ioaddr, u16 o, u8 *b, int n)
-{
-       outw(o, PIOR1(ioaddr));
-       outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Acknowledge the reading of the status issued by the i82586.
- */
-static void wv_ack(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       u16 scb_cs;
-       int i;
-
-       obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
-                  (unsigned char *) &scb_cs, sizeof(scb_cs));
-       scb_cs &= SCB_ST_INT;
-
-       if (scb_cs == 0)
-               return;
-
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-                   (unsigned char *) &scb_cs, sizeof(scb_cs));
-
-       set_chan_attn(ioaddr, lp->hacr);
-
-       for (i = 1000; i > 0; i--) {
-               obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
-                          (unsigned char *) &scb_cs, sizeof(scb_cs));
-               if (scb_cs == 0)
-                       break;
-
-               udelay(10);
-       }
-       udelay(100);
-
-#ifdef DEBUG_CONFIG_ERROR
-       if (i <= 0)
-               printk(KERN_INFO
-                      "%s: wv_ack(): board not accepting command.\n",
-                      dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Set channel attention bit and busy wait until command has
- * completed, then acknowledge completion of the command.
- */
-static int wv_synchronous_cmd(struct net_device *dev, const char *str)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       u16 scb_cmd;
-       ach_t cb;
-       int i;
-
-       scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO;
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-                   (unsigned char *) &scb_cmd, sizeof(scb_cmd));
-
-       set_chan_attn(ioaddr, lp->hacr);
-
-       for (i = 1000; i > 0; i--) {
-               obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb,
-                          sizeof(cb));
-               if (cb.ac_status & AC_SFLD_C)
-                       break;
-
-               udelay(10);
-       }
-       udelay(100);
-
-       if (i <= 0 || !(cb.ac_status & AC_SFLD_OK)) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO "%s: %s failed; status = 0x%x\n",
-                      dev->name, str, cb.ac_status);
-#endif
-#ifdef DEBUG_I82586_SHOW
-               wv_scb_show(ioaddr);
-#endif
-               return -1;
-       }
-
-       /* Ack the status */
-       wv_ack(dev);
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Configuration commands completion interrupt.
- * Check if done, and if OK.
- */
-static int
-wv_config_complete(struct net_device *dev, unsigned long ioaddr, net_local * lp)
-{
-       unsigned short mcs_addr;
-       unsigned short status;
-       int ret;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: ->wv_config_complete()\n", dev->name);
-#endif
-
-       mcs_addr = lp->tx_first_in_use + sizeof(ac_tx_t) + sizeof(ac_nop_t)
-           + sizeof(tbd_t) + sizeof(ac_cfg_t) + sizeof(ac_ias_t);
-
-       /* Read the status of the last command (set mc list). */
-       obram_read(ioaddr, acoff(mcs_addr, ac_status),
-                  (unsigned char *) &status, sizeof(status));
-
-       /* If not completed -> exit */
-       if ((status & AC_SFLD_C) == 0)
-               ret = 0;        /* Not ready to be scrapped */
-       else {
-#ifdef DEBUG_CONFIG_ERROR
-               unsigned short cfg_addr;
-               unsigned short ias_addr;
-
-               /* Check mc_config command */
-               if ((status & AC_SFLD_OK) != AC_SFLD_OK)
-                       printk(KERN_INFO
-                              "%s: wv_config_complete(): \
-                              set_multicast_address failed; status = 0x%x\n",
-                              dev->name, status);
-
-               /* check ia-config command */
-               ias_addr = mcs_addr - sizeof(ac_ias_t);
-               obram_read(ioaddr, acoff(ias_addr, ac_status),
-                          (unsigned char *) &status, sizeof(status));
-               if ((status & AC_SFLD_OK) != AC_SFLD_OK)
-                       printk(KERN_INFO
-                              "%s: wv_config_complete(): set_MAC_address \
-                               failed; status = 0x%x\n",
-                              dev->name, status);
-
-               /* Check config command. */
-               cfg_addr = ias_addr - sizeof(ac_cfg_t);
-               obram_read(ioaddr, acoff(cfg_addr, ac_status),
-                          (unsigned char *) &status, sizeof(status));
-               if ((status & AC_SFLD_OK) != AC_SFLD_OK)
-                       printk(KERN_INFO
-                              "%s: wv_config_complete(): configure failed; \
-                              status = 0x%x\n",
-                              dev->name, status);
-#endif /* DEBUG_CONFIG_ERROR */
-
-               ret = 1;        /* Ready to be scrapped */
-       }
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: <-wv_config_complete() - %d\n", dev->name,
-              ret);
-#endif
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Command completion interrupt.
- * Reclaim as many freed tx buffers as we can.
- * (called in wavelan_interrupt()).
- * Note : the spinlock is already grabbed for us.
- */
-static int wv_complete(struct net_device *dev,
-                       unsigned long ioaddr,
-                       net_local *lp)
-{
-       int nreaped = 0;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: ->wv_complete()\n", dev->name);
-#endif
-
-       /* Loop on all the transmit buffers */
-       while (lp->tx_first_in_use != I82586NULL) {
-               unsigned short tx_status;
-
-               /* Read the first transmit buffer */
-               obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status),
-                          (unsigned char *) &tx_status,
-                          sizeof(tx_status));
-
-               /* If not completed -> exit */
-               if ((tx_status & AC_SFLD_C) == 0)
-                       break;
-
-               /* Hack for reconfiguration */
-               if (tx_status == 0xFFFF)
-                       if (!wv_config_complete(dev, ioaddr, lp))
-                               break;  /* Not completed */
-
-               /* We now remove this buffer */
-               nreaped++;
-               --lp->tx_n_in_use;
-
-/*
-if (lp->tx_n_in_use > 0)
-       printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);
-*/
-
-               /* Was it the last one? */
-               if (lp->tx_n_in_use <= 0)
-                       lp->tx_first_in_use = I82586NULL;
-               else {
-                       /* Next one in the chain */
-                       lp->tx_first_in_use += TXBLOCKZ;
-                       if (lp->tx_first_in_use >=
-                               OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-                               lp->tx_first_in_use -= NTXBLOCKS * TXBLOCKZ;
-               }
-
-               /* Hack for reconfiguration */
-               if (tx_status == 0xFFFF)
-                       continue;
-
-               /* Now, check status of the finished command */
-               if (tx_status & AC_SFLD_OK) {
-                       int ncollisions;
-
-                       dev->stats.tx_packets++;
-                       ncollisions = tx_status & AC_SFLD_MAXCOL;
-                       dev->stats.collisions += ncollisions;
-#ifdef DEBUG_TX_INFO
-                       if (ncollisions > 0)
-                               printk(KERN_DEBUG
-                                      "%s: wv_complete(): tx completed after \
-                                       %d collisions.\n",
-                                      dev->name, ncollisions);
-#endif
-               } else {
-                       dev->stats.tx_errors++;
-                       if (tx_status & AC_SFLD_S10) {
-                               dev->stats.tx_carrier_errors++;
-#ifdef DEBUG_TX_FAIL
-                               printk(KERN_DEBUG
-                                      "%s: wv_complete(): tx error: no CS.\n",
-                                      dev->name);
-#endif
-                       }
-                       if (tx_status & AC_SFLD_S9) {
-                               dev->stats.tx_carrier_errors++;
-#ifdef DEBUG_TX_FAIL
-                               printk(KERN_DEBUG
-                                       "%s: wv_complete(): tx error: \
-                                       lost CTS.\n",
-                                      dev->name);
-#endif
-                       }
-                       if (tx_status & AC_SFLD_S8) {
-                               dev->stats.tx_fifo_errors++;
-#ifdef DEBUG_TX_FAIL
-                               printk(KERN_DEBUG
-                                       "%s: wv_complete(): tx error: \
-                                       slow DMA.\n",
-                                      dev->name);
-#endif
-                       }
-                       if (tx_status & AC_SFLD_S6) {
-                               dev->stats.tx_heartbeat_errors++;
-#ifdef DEBUG_TX_FAIL
-                               printk(KERN_DEBUG
-                                       "%s: wv_complete(): tx error: \
-                                       heart beat.\n",
-                                      dev->name);
-#endif
-                       }
-                       if (tx_status & AC_SFLD_S5) {
-                               dev->stats.tx_aborted_errors++;
-#ifdef DEBUG_TX_FAIL
-                               printk(KERN_DEBUG
-                                       "%s: wv_complete(): tx error: \
-                                       too many collisions.\n",
-                                      dev->name);
-#endif
-                       }
-               }
-
-#ifdef DEBUG_TX_INFO
-               printk(KERN_DEBUG
-                      "%s: wv_complete(): tx completed, tx_status 0x%04x\n",
-                      dev->name, tx_status);
-#endif
-       }
-
-#ifdef DEBUG_INTERRUPT_INFO
-       if (nreaped > 1)
-               printk(KERN_DEBUG "%s: wv_complete(): reaped %d\n",
-                      dev->name, nreaped);
-#endif
-
-       /*
-        * Inform upper layers.
-        */
-       if (lp->tx_n_in_use < NTXBLOCKS - 1)
-               netif_wake_queue(dev);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name);
-#endif
-       return nreaped;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Reconfigure the i82586, or at least ask for it.
- *because wv_82586_config uses a transmission buffer, we must do it
- * when we are sure that there is one left, so we do it now
- * or in wavelan_packet_xmit() (I can't find any better place,
- * wavelan_interrupt is not an option), so you may experience
- * delays sometimes.
- */
-static void wv_82586_reconfig(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-
-       /* Arm the flag, will be cleard in wv_82586_config() */
-       lp->reconfig_82586 = 1;
-
-       /* Check if we can do it now ! */
-       if ((netif_running(dev)) && !(netif_queue_stopped(dev))) {
-               spin_lock_irqsave(&lp->spinlock, flags);
-               /* May fail */
-               wv_82586_config(dev);
-               spin_unlock_irqrestore(&lp->spinlock, flags);
-       } else {
-#ifdef DEBUG_CONFIG_INFO
-               printk(KERN_DEBUG
-                      "%s: wv_82586_reconfig(): delayed (state = %lX)\n",
-                              dev->name, dev->state);
-#endif
-       }
-}
-
-/********************* DEBUG & INFO SUBROUTINES *********************/
-/*
- * This routine is used in the code to show information for debugging.
- * Most of the time, it dumps the contents of hardware structures.
- */
-
-#ifdef DEBUG_PSA_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted contents of the Parameter Storage Area.
- */
-static void wv_psa_show(psa_t *p)
-{
-       printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n");
-       printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
-              p->psa_io_base_addr_1,
-              p->psa_io_base_addr_2,
-              p->psa_io_base_addr_3, p->psa_io_base_addr_4);
-       printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
-              p->psa_rem_boot_addr_1,
-              p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3);
-       printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
-       printk("psa_int_req_no: %d\n", p->psa_int_req_no);
-#ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
-#endif                         /* DEBUG_SHOW_UNUSED */
-       printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
-       printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
-       printk(KERN_DEBUG "psa_univ_local_sel: %d, ",
-              p->psa_univ_local_sel);
-       printk("psa_comp_number: %d, ", p->psa_comp_number);
-       printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
-       printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
-              p->psa_feature_select);
-       printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
-       printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
-       printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
-       printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0],
-              p->psa_nwid[1]);
-       printk("psa_nwid_select: %d\n", p->psa_nwid_select);
-       printk(KERN_DEBUG "psa_encryption_select: %d, ",
-              p->psa_encryption_select);
-       printk
-           ("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-            p->psa_encryption_key[0], p->psa_encryption_key[1],
-            p->psa_encryption_key[2], p->psa_encryption_key[3],
-            p->psa_encryption_key[4], p->psa_encryption_key[5],
-            p->psa_encryption_key[6], p->psa_encryption_key[7]);
-       printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
-       printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
-              p->psa_call_code[0]);
-       printk
-           ("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-            p->psa_call_code[0], p->psa_call_code[1], p->psa_call_code[2],
-            p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5],
-            p->psa_call_code[6], p->psa_call_code[7]);
-#ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
-              p->psa_reserved[0],
-              p->psa_reserved[1]);
-#endif                         /* DEBUG_SHOW_UNUSED */
-       printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
-       printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
-       printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
-}                              /* wv_psa_show */
-#endif                         /* DEBUG_PSA_SHOW */
-
-#ifdef DEBUG_MMC_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the Modem Management Controller.
- * This function needs to be completed.
- */
-static void wv_mmc_show(struct net_device *dev)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       mmr_t m;
-
-       /*basic check */
-       if (hasr_read(ioaddr) & HASR_NO_CLK) {
-               printk(KERN_WARNING
-                      "%s: wv_mmc_show: modem not connected\n",
-                      dev->name);
-               return;
-       }
-
-       /* Read the mmc */
-       mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
-       mmc_read(ioaddr, 0, (u8 *) &m, sizeof(m));
-       mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
-       /* Don't forget to update statistics */
-       lp->wstats.discard.nwid +=
-           (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-
-       printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
-#ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG
-              "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-              m.mmr_unused0[0], m.mmr_unused0[1], m.mmr_unused0[2],
-              m.mmr_unused0[3], m.mmr_unused0[4], m.mmr_unused0[5],
-              m.mmr_unused0[6], m.mmr_unused0[7]);
-#endif                         /* DEBUG_SHOW_UNUSED */
-       printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
-              m.mmr_des_avail, m.mmr_des_status);
-#ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
-              m.mmr_unused1[0],
-              m.mmr_unused1[1],
-              m.mmr_unused1[2], m.mmr_unused1[3], m.mmr_unused1[4]);
-#endif                         /* DEBUG_SHOW_UNUSED */
-       printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
-              m.mmr_dce_status,
-              (m.
-               mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ?
-              "energy detected," : "",
-              (m.
-               mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
-              "loop test indicated," : "",
-              (m.
-               mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ?
-              "transmitter on," : "",
-              (m.
-               mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
-              "jabber timer expired," : "");
-       printk(KERN_DEBUG "Dsp ID: %02X\n", m.mmr_dsp_id);
-#ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
-              m.mmr_unused2[0], m.mmr_unused2[1]);
-#endif                         /* DEBUG_SHOW_UNUSED */
-       printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
-              (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
-              (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
-       printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
-              m.mmr_thr_pre_set & MMR_THR_PRE_SET,
-              (m.
-               mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" :
-              "below");
-       printk(KERN_DEBUG "signal_lvl: %d [%s], ",
-              m.mmr_signal_lvl & MMR_SIGNAL_LVL,
-              (m.
-               mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" :
-              "no new msg");
-       printk("silence_lvl: %d [%s], ",
-              m.mmr_silence_lvl & MMR_SILENCE_LVL,
-              (m.
-               mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" :
-              "no new update");
-       printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
-              (m.
-               mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" :
-              "Antenna 0");
-#ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
-#endif                         /* DEBUG_SHOW_UNUSED */
-}                              /* wv_mmc_show */
-#endif                         /* DEBUG_MMC_SHOW */
-
-#ifdef DEBUG_I82586_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the last block of the i82586 memory.
- */
-static void wv_scb_show(unsigned long ioaddr)
-{
-       scb_t scb;
-
-       obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
-                  sizeof(scb));
-
-       printk(KERN_DEBUG "##### WaveLAN system control block: #####\n");
-
-       printk(KERN_DEBUG "status: ");
-       printk("stat 0x%x[%s%s%s%s] ",
-              (scb.
-               scb_status & (SCB_ST_CX | SCB_ST_FR | SCB_ST_CNA |
-                             SCB_ST_RNR)) >> 12,
-              (scb.
-               scb_status & SCB_ST_CX) ? "command completion interrupt," :
-              "", (scb.scb_status & SCB_ST_FR) ? "frame received," : "",
-              (scb.
-               scb_status & SCB_ST_CNA) ? "command unit not active," : "",
-              (scb.
-               scb_status & SCB_ST_RNR) ? "receiving unit not ready," :
-              "");
-       printk("cus 0x%x[%s%s%s] ", (scb.scb_status & SCB_ST_CUS) >> 8,
-              ((scb.scb_status & SCB_ST_CUS) ==
-               SCB_ST_CUS_IDLE) ? "idle" : "",
-              ((scb.scb_status & SCB_ST_CUS) ==
-               SCB_ST_CUS_SUSP) ? "suspended" : "",
-              ((scb.scb_status & SCB_ST_CUS) ==
-               SCB_ST_CUS_ACTV) ? "active" : "");
-       printk("rus 0x%x[%s%s%s%s]\n", (scb.scb_status & SCB_ST_RUS) >> 4,
-              ((scb.scb_status & SCB_ST_RUS) ==
-               SCB_ST_RUS_IDLE) ? "idle" : "",
-              ((scb.scb_status & SCB_ST_RUS) ==
-               SCB_ST_RUS_SUSP) ? "suspended" : "",
-              ((scb.scb_status & SCB_ST_RUS) ==
-               SCB_ST_RUS_NRES) ? "no resources" : "",
-              ((scb.scb_status & SCB_ST_RUS) ==
-               SCB_ST_RUS_RDY) ? "ready" : "");
-
-       printk(KERN_DEBUG "command: ");
-       printk("ack 0x%x[%s%s%s%s] ",
-              (scb.
-               scb_command & (SCB_CMD_ACK_CX | SCB_CMD_ACK_FR |
-                              SCB_CMD_ACK_CNA | SCB_CMD_ACK_RNR)) >> 12,
-              (scb.
-               scb_command & SCB_CMD_ACK_CX) ? "ack cmd completion," : "",
-              (scb.
-               scb_command & SCB_CMD_ACK_FR) ? "ack frame received," : "",
-              (scb.
-               scb_command & SCB_CMD_ACK_CNA) ? "ack CU not active," : "",
-              (scb.
-               scb_command & SCB_CMD_ACK_RNR) ? "ack RU not ready," : "");
-       printk("cuc 0x%x[%s%s%s%s%s] ",
-              (scb.scb_command & SCB_CMD_CUC) >> 8,
-              ((scb.scb_command & SCB_CMD_CUC) ==
-               SCB_CMD_CUC_NOP) ? "nop" : "",
-              ((scb.scb_command & SCB_CMD_CUC) ==
-               SCB_CMD_CUC_GO) ? "start cbl_offset" : "",
-              ((scb.scb_command & SCB_CMD_CUC) ==
-               SCB_CMD_CUC_RES) ? "resume execution" : "",
-              ((scb.scb_command & SCB_CMD_CUC) ==
-               SCB_CMD_CUC_SUS) ? "suspend execution" : "",
-              ((scb.scb_command & SCB_CMD_CUC) ==
-               SCB_CMD_CUC_ABT) ? "abort execution" : "");
-       printk("ruc 0x%x[%s%s%s%s%s]\n",
-              (scb.scb_command & SCB_CMD_RUC) >> 4,
-              ((scb.scb_command & SCB_CMD_RUC) ==
-               SCB_CMD_RUC_NOP) ? "nop" : "",
-              ((scb.scb_command & SCB_CMD_RUC) ==
-               SCB_CMD_RUC_GO) ? "start rfa_offset" : "",
-              ((scb.scb_command & SCB_CMD_RUC) ==
-               SCB_CMD_RUC_RES) ? "resume reception" : "",
-              ((scb.scb_command & SCB_CMD_RUC) ==
-               SCB_CMD_RUC_SUS) ? "suspend reception" : "",
-              ((scb.scb_command & SCB_CMD_RUC) ==
-               SCB_CMD_RUC_ABT) ? "abort reception" : "");
-
-       printk(KERN_DEBUG "cbl_offset 0x%x ", scb.scb_cbl_offset);
-       printk("rfa_offset 0x%x\n", scb.scb_rfa_offset);
-
-       printk(KERN_DEBUG "crcerrs %d ", scb.scb_crcerrs);
-       printk("alnerrs %d ", scb.scb_alnerrs);
-       printk("rscerrs %d ", scb.scb_rscerrs);
-       printk("ovrnerrs %d\n", scb.scb_ovrnerrs);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the i82586's receive unit.
- */
-static void wv_ru_show(struct net_device *dev)
-{
-       printk(KERN_DEBUG
-              "##### WaveLAN i82586 receiver unit status: #####\n");
-       printk(KERN_DEBUG "ru:");
-       /*
-        * Not implemented yet
-        */
-       printk("\n");
-}                              /* wv_ru_show */
-
-/*------------------------------------------------------------------*/
-/*
- * Display info about one control block of the i82586 memory.
- */
-static void wv_cu_show_one(struct net_device *dev, net_local * lp, int i, u16 p)
-{
-       unsigned long ioaddr;
-       ac_tx_t actx;
-
-       ioaddr = dev->base_addr;
-
-       printk("%d: 0x%x:", i, p);
-
-       obram_read(ioaddr, p, (unsigned char *) &actx, sizeof(actx));
-       printk(" status=0x%x,", actx.tx_h.ac_status);
-       printk(" command=0x%x,", actx.tx_h.ac_command);
-
-       /*
-          {
-          tbd_t      tbd;
-
-          obram_read(ioaddr, actx.tx_tbd_offset, (unsigned char *)&tbd, sizeof(tbd));
-          printk(" tbd_status=0x%x,", tbd.tbd_status);
-          }
-        */
-
-       printk("|");
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Print status of the command unit of the i82586.
- */
-static void wv_cu_show(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned int i;
-       u16 p;
-
-       printk(KERN_DEBUG
-              "##### WaveLAN i82586 command unit status: #####\n");
-
-       printk(KERN_DEBUG);
-       for (i = 0, p = lp->tx_first_in_use; i < NTXBLOCKS; i++) {
-               wv_cu_show_one(dev, lp, i, p);
-
-               p += TXBLOCKZ;
-               if (p >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-                       p -= NTXBLOCKS * TXBLOCKZ;
-       }
-       printk("\n");
-}
-#endif                         /* DEBUG_I82586_SHOW */
-
-#ifdef DEBUG_DEVICE_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver.
- */
-static void wv_dev_show(struct net_device *dev)
-{
-       printk(KERN_DEBUG "dev:");
-       printk(" state=%lX,", dev->state);
-       printk(" trans_start=%ld,", dev->trans_start);
-       printk(" flags=0x%x,", dev->flags);
-       printk("\n");
-}                              /* wv_dev_show */
-
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver's
- * private information.
- */
-static void wv_local_show(struct net_device *dev)
-{
-       net_local *lp;
-
-       lp = netdev_priv(dev);
-
-       printk(KERN_DEBUG "local:");
-       printk(" tx_n_in_use=%d,", lp->tx_n_in_use);
-       printk(" hacr=0x%x,", lp->hacr);
-       printk(" rx_head=0x%x,", lp->rx_head);
-       printk(" rx_last=0x%x,", lp->rx_last);
-       printk(" tx_first_free=0x%x,", lp->tx_first_free);
-       printk(" tx_first_in_use=0x%x,", lp->tx_first_in_use);
-       printk("\n");
-}                              /* wv_local_show */
-#endif                         /* DEBUG_DEVICE_SHOW */
-
-#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
-/*------------------------------------------------------------------*/
-/*
- * Dump packet header (and content if necessary) on the screen
- */
-static inline void wv_packet_info(u8 * p,      /* Packet to dump */
-                                 int length,   /* Length of the packet */
-                                 char *msg1,   /* Name of the device */
-                                 char *msg2)
-{                              /* Name of the function */
-       int i;
-       int maxi;
-
-       printk(KERN_DEBUG
-              "%s: %s(): dest %pM, length %d\n",
-              msg1, msg2, p, length);
-       printk(KERN_DEBUG
-              "%s: %s(): src %pM, type 0x%02X%02X\n",
-              msg1, msg2, &p[6], p[12], p[13]);
-
-#ifdef DEBUG_PACKET_DUMP
-
-       printk(KERN_DEBUG "data=\"");
-
-       if ((maxi = length) > DEBUG_PACKET_DUMP)
-               maxi = DEBUG_PACKET_DUMP;
-       for (i = 14; i < maxi; i++)
-               if (p[i] >= ' ' && p[i] <= '~')
-                       printk(" %c", p[i]);
-               else
-                       printk("%02X", p[i]);
-       if (maxi < length)
-               printk("..");
-       printk("\"\n");
-       printk(KERN_DEBUG "\n");
-#endif                         /* DEBUG_PACKET_DUMP */
-}
-#endif                         /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
-
-/*------------------------------------------------------------------*/
-/*
- * This is the information which is displayed by the driver at startup.
- * There are lots of flags for configuring it to your liking.
- */
-static void wv_init_info(struct net_device *dev)
-{
-       short ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-
-       /* Read the parameter storage area */
-       psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
-#ifdef DEBUG_PSA_SHOW
-       wv_psa_show(&psa);
-#endif
-#ifdef DEBUG_MMC_SHOW
-       wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82586_SHOW
-       wv_cu_show(dev);
-#endif
-
-#ifdef DEBUG_BASIC_SHOW
-       /* Now, let's go for the basic stuff. */
-       printk(KERN_NOTICE "%s: WaveLAN at %#x, %pM, IRQ %d",
-              dev->name, ioaddr, dev->dev_addr, dev->irq);
-
-       /* Print current network ID. */
-       if (psa.psa_nwid_select)
-               printk(", nwid 0x%02X-%02X", psa.psa_nwid[0],
-                      psa.psa_nwid[1]);
-       else
-               printk(", nwid off");
-
-       /* If 2.00 card */
-       if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-               unsigned short freq;
-
-               /* Ask the EEPROM to read the frequency from the first area. */
-               fee_read(ioaddr, 0x00, &freq, 1);
-
-               /* Print frequency */
-               printk(", 2.00, %ld", (freq >> 6) + 2400L);
-
-               /* Hack! */
-               if (freq & 0x20)
-                       printk(".5");
-       } else {
-               printk(", PC");
-               switch (psa.psa_comp_number) {
-               case PSA_COMP_PC_AT_915:
-               case PSA_COMP_PC_AT_2400:
-                       printk("-AT");
-                       break;
-               case PSA_COMP_PC_MC_915:
-               case PSA_COMP_PC_MC_2400:
-                       printk("-MC");
-                       break;
-               case PSA_COMP_PCMCIA_915:
-                       printk("MCIA");
-                       break;
-               default:
-                       printk("?");
-               }
-               printk(", ");
-               switch (psa.psa_subband) {
-               case PSA_SUBBAND_915:
-                       printk("915");
-                       break;
-               case PSA_SUBBAND_2425:
-                       printk("2425");
-                       break;
-               case PSA_SUBBAND_2460:
-                       printk("2460");
-                       break;
-               case PSA_SUBBAND_2484:
-                       printk("2484");
-                       break;
-               case PSA_SUBBAND_2430_5:
-                       printk("2430.5");
-                       break;
-               default:
-                       printk("?");
-               }
-       }
-
-       printk(" MHz\n");
-#endif                         /* DEBUG_BASIC_SHOW */
-
-#ifdef DEBUG_VERSION_SHOW
-       /* Print version information */
-       printk(KERN_NOTICE "%s", version);
-#endif
-}                              /* wv_init_info */
-
-/********************* IOCTL, STATS & RECONFIG *********************/
-/*
- * We found here routines that are called by Linux on different
- * occasions after the configuration and not for transmitting data
- * These may be called when the user use ifconfig, /proc/net/dev
- * or wireless extensions
- */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1     Promiscuous mode, receive all packets
- * num_addrs == 0      Normal mode, clear multicast list
- * num_addrs > 0       Multicast mode, receive normal and MC packets,
- *                     and do best-effort filtering.
- */
-static void wavelan_set_multicast_list(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-
-#ifdef DEBUG_IOCTL_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n",
-              dev->name);
-#endif
-
-#ifdef DEBUG_IOCTL_INFO
-       printk(KERN_DEBUG
-              "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
-              dev->name, dev->flags, netdev_mc_count(dev));
-#endif
-
-       /* Are we asking for promiscuous mode,
-        * or all multicast addresses (we don't have that!)
-        * or too many multicast addresses for the hardware filter? */
-       if ((dev->flags & IFF_PROMISC) ||
-           (dev->flags & IFF_ALLMULTI) ||
-           (netdev_mc_count(dev) > I82586_MAX_MULTICAST_ADDRESSES)) {
-               /*
-                * Enable promiscuous mode: receive all packets.
-                */
-               if (!lp->promiscuous) {
-                       lp->promiscuous = 1;
-                       lp->mc_count = 0;
-
-                       wv_82586_reconfig(dev);
-               }
-       } else
-               /* Are there multicast addresses to send? */
-       if (!netdev_mc_empty(dev)) {
-               /*
-                * Disable promiscuous mode, but receive all packets
-                * in multicast list
-                */
-#ifdef MULTICAST_AVOID
-               if (lp->promiscuous || (netdev_mc_count(dev) != lp->mc_count))
-#endif
-               {
-                       lp->promiscuous = 0;
-                       lp->mc_count = netdev_mc_count(dev);
-
-                       wv_82586_reconfig(dev);
-               }
-       } else {
-               /*
-                * Switch to normal mode: disable promiscuous mode and 
-                * clear the multicast list.
-                */
-               if (lp->promiscuous || lp->mc_count == 0) {
-                       lp->promiscuous = 0;
-                       lp->mc_count = 0;
-
-                       wv_82586_reconfig(dev);
-               }
-       }
-#ifdef DEBUG_IOCTL_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n",
-              dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This function doesn't exist.
- * (Note : it was a nice way to test the reconfigure stuff...)
- */
-#ifdef SET_MAC_ADDRESS
-static int wavelan_set_mac_address(struct net_device *dev, void *addr)
-{
-       struct sockaddr *mac = addr;
-
-       /* Copy the address. */
-       memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
-
-       /* Reconfigure the beast. */
-       wv_82586_reconfig(dev);
-
-       return 0;
-}
-#endif                         /* SET_MAC_ADDRESS */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Frequency setting (for hardware capable of it)
- * It's a bit complicated and you don't really want to look into it.
- * (called in wavelan_ioctl)
- */
-static int wv_set_frequency(unsigned long ioaddr,      /* I/O port of the card */
-                                  iw_freq * frequency)
-{
-       const int BAND_NUM = 10;        /* Number of bands */
-       long freq = 0L;         /* offset to 2.4 GHz in .5 MHz */
-#ifdef DEBUG_IOCTL_INFO
-       int i;
-#endif
-
-       /* Setting by frequency */
-       /* Theoretically, you may set any frequency between
-        * the two limits with a 0.5 MHz precision. In practice,
-        * I don't want you to have trouble with local regulations.
-        */
-       if ((frequency->e == 1) &&
-           (frequency->m >= (int) 2.412e8)
-           && (frequency->m <= (int) 2.487e8)) {
-               freq = ((frequency->m / 10000) - 24000L) / 5;
-       }
-
-       /* Setting by channel (same as wfreqsel) */
-       /* Warning: each channel is 22 MHz wide, so some of the channels
-        * will interfere. */
-       if ((frequency->e == 0) && (frequency->m < BAND_NUM)) {
-               /* Get frequency offset. */
-               freq = channel_bands[frequency->m] >> 1;
-       }
-
-       /* Verify that the frequency is allowed. */
-       if (freq != 0L) {
-               u16 table[10];  /* Authorized frequency table */
-
-               /* Read the frequency table. */
-               fee_read(ioaddr, 0x71, table, 10);
-
-#ifdef DEBUG_IOCTL_INFO
-               printk(KERN_DEBUG "Frequency table: ");
-               for (i = 0; i < 10; i++) {
-                       printk(" %04X", table[i]);
-               }
-               printk("\n");
-#endif
-
-               /* Look in the table to see whether the frequency is allowed. */
-               if (!(table[9 - ((freq - 24) / 16)] &
-                     (1 << ((freq - 24) % 16)))) return -EINVAL;       /* not allowed */
-       } else
-               return -EINVAL;
-
-       /* if we get a usable frequency */
-       if (freq != 0L) {
-               unsigned short area[16];
-               unsigned short dac[2];
-               unsigned short area_verify[16];
-               unsigned short dac_verify[2];
-               /* Corresponding gain (in the power adjust value table)
-                * See AT&T WaveLAN Data Manual, REF 407-024689/E, page 3-8
-                * and WCIN062D.DOC, page 6.2.9. */
-               unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
-               int power_band = 0;     /* Selected band */
-               unsigned short power_adjust;    /* Correct value */
-
-               /* Search for the gain. */
-               power_band = 0;
-               while ((freq > power_limit[power_band]) &&
-                      (power_limit[++power_band] != 0));
-
-               /* Read the first area. */
-               fee_read(ioaddr, 0x00, area, 16);
-
-               /* Read the DAC. */
-               fee_read(ioaddr, 0x60, dac, 2);
-
-               /* Read the new power adjust value. */
-               fee_read(ioaddr, 0x6B - (power_band >> 1), &power_adjust,
-                        1);
-               if (power_band & 0x1)
-                       power_adjust >>= 8;
-               else
-                       power_adjust &= 0xFF;
-
-#ifdef DEBUG_IOCTL_INFO
-               printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");
-               for (i = 0; i < 16; i++) {
-                       printk(" %04X", area[i]);
-               }
-               printk("\n");
-
-               printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",
-                      dac[0], dac[1]);
-#endif
-
-               /* Frequency offset (for info only) */
-               area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
-
-               /* Receiver Principle main divider coefficient */
-               area[3] = (freq >> 1) + 2400L - 352L;
-               area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-               /* Transmitter Main divider coefficient */
-               area[13] = (freq >> 1) + 2400L;
-               area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-               /* Other parts of the area are flags, bit streams or unused. */
-
-               /* Set the value in the DAC. */
-               dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
-               dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
-
-               /* Write the first area. */
-               fee_write(ioaddr, 0x00, area, 16);
-
-               /* Write the DAC. */
-               fee_write(ioaddr, 0x60, dac, 2);
-
-               /* We now should verify here that the writing of the EEPROM went OK. */
-
-               /* Reread the first area. */
-               fee_read(ioaddr, 0x00, area_verify, 16);
-
-               /* Reread the DAC. */
-               fee_read(ioaddr, 0x60, dac_verify, 2);
-
-               /* Compare. */
-               if (memcmp(area, area_verify, 16 * 2) ||
-                   memcmp(dac, dac_verify, 2 * 2)) {
-#ifdef DEBUG_IOCTL_ERROR
-                       printk(KERN_INFO
-                              "WaveLAN: wv_set_frequency: unable to write new frequency to EEPROM(?).\n");
-#endif
-                       return -EOPNOTSUPP;
-               }
-
-               /* We must download the frequency parameters to the
-                * synthesizers (from the EEPROM - area 1)
-                * Note: as the EEPROM is automatically decremented, we set the end
-                * if the area... */
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x0F);
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-                       MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-               /* Wait until the download is finished. */
-               fee_wait(ioaddr, 100, 100);
-
-               /* We must now download the power adjust value (gain) to
-                * the synthesizers (from the EEPROM - area 7 - DAC). */
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x61);
-               mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
-                       MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-               /* Wait for the download to finish. */
-               fee_wait(ioaddr, 100, 100);
-
-#ifdef DEBUG_IOCTL_INFO
-               /* Verification of what we have done */
-
-               printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");
-               for (i = 0; i < 16; i++) {
-                       printk(" %04X", area_verify[i]);
-               }
-               printk("\n");
-
-               printk(KERN_DEBUG "WaveLAN EEPROM DAC:  %04X %04X\n",
-                      dac_verify[0], dac_verify[1]);
-#endif
-
-               return 0;
-       } else
-               return -EINVAL; /*bah, never get there... */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Give the list of available frequencies.
- */
-static int wv_frequency_list(unsigned long ioaddr,     /* I/O port of the card */
-                                   iw_freq * list,     /* List of frequencies to fill */
-                                   int max)
-{                              /* Maximum number of frequencies */
-       u16 table[10];  /* Authorized frequency table */
-       long freq = 0L;         /* offset to 2.4 GHz in .5 MHz + 12 MHz */
-       int i;                  /* index in the table */
-       int c = 0;              /* Channel number */
-
-       /* Read the frequency table. */
-       fee_read(ioaddr, 0x71 /* frequency table */ , table, 10);
-
-       /* Check all frequencies. */
-       i = 0;
-       for (freq = 0; freq < 150; freq++)
-               /* Look in the table if the frequency is allowed */
-               if (table[9 - (freq / 16)] & (1 << (freq % 16))) {
-                       /* Compute approximate channel number */
-                       while ((c < ARRAY_SIZE(channel_bands)) &&
-                               (((channel_bands[c] >> 1) - 24) < freq)) 
-                               c++;
-                       list[i].i = c;  /* Set the list index */
-
-                       /* put in the list */
-                       list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
-                       list[i++].e = 1;
-
-                       /* Check number. */
-                       if (i >= max)
-                               return (i);
-               }
-
-       return (i);
-}
-
-#ifdef IW_WIRELESS_SPY
-/*------------------------------------------------------------------*/
-/*
- * Gather wireless spy statistics:  for each packet, compare the source
- * address with our list, and if they match, get the statistics.
- * Sorry, but this function really needs the wireless extensions.
- */
-static inline void wl_spy_gather(struct net_device *dev,
-                                u8 *   mac,    /* MAC address */
-                                u8 *   stats)  /* Statistics to gather */
-{
-       struct iw_quality wstats;
-
-       wstats.qual = stats[2] & MMR_SGNL_QUAL;
-       wstats.level = stats[0] & MMR_SIGNAL_LVL;
-       wstats.noise = stats[1] & MMR_SILENCE_LVL;
-       wstats.updated = 0x7;
-
-       /* Update spy records */
-       wireless_spy_update(dev, mac, &wstats);
-}
-#endif /* IW_WIRELESS_SPY */
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * This function calculates a histogram of the signal level.
- * As the noise is quite constant, it's like doing it on the SNR.
- * We have defined a set of interval (lp->his_range), and each time
- * the level goes in that interval, we increment the count (lp->his_sum).
- * With this histogram you may detect if one WaveLAN is really weak,
- * or you may also calculate the mean and standard deviation of the level.
- */
-static inline void wl_his_gather(struct net_device *dev, u8 * stats)
-{                              /* Statistics to gather */
-       net_local *lp = netdev_priv(dev);
-       u8 level = stats[0] & MMR_SIGNAL_LVL;
-       int i;
-
-       /* Find the correct interval. */
-       i = 0;
-       while ((i < (lp->his_number - 1))
-              && (level >= lp->his_range[i++]));
-
-       /* Increment interval counter. */
-       (lp->his_sum[i])++;
-}
-#endif /* HISTOGRAM */
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get protocol name
- */
-static int wavelan_get_name(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       strcpy(wrqu->name, "WaveLAN");
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set NWID
- */
-static int wavelan_set_nwid(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       mm_t m;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Set NWID in WaveLAN. */
-       if (!wrqu->nwid.disabled) {
-               /* Set NWID in psa */
-               psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
-               psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
-               psa.psa_nwid_select = 0x01;
-               psa_write(ioaddr, lp->hacr,
-                         (char *) psa.psa_nwid - (char *) &psa,
-                         (unsigned char *) psa.psa_nwid, 3);
-
-               /* Set NWID in mmc. */
-               m.w.mmw_netw_id_l = psa.psa_nwid[1];
-               m.w.mmw_netw_id_h = psa.psa_nwid[0];
-               mmc_write(ioaddr,
-                         (char *) &m.w.mmw_netw_id_l -
-                         (char *) &m,
-                         (unsigned char *) &m.w.mmw_netw_id_l, 2);
-               mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
-       } else {
-               /* Disable NWID in the psa. */
-               psa.psa_nwid_select = 0x00;
-               psa_write(ioaddr, lp->hacr,
-                         (char *) &psa.psa_nwid_select -
-                         (char *) &psa,
-                         (unsigned char *) &psa.psa_nwid_select,
-                         1);
-
-               /* Disable NWID in the mmc (no filtering). */
-               mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel),
-                       MMW_LOOPT_SEL_DIS_NWID);
-       }
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev, ioaddr, lp->hacr);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get NWID 
- */
-static int wavelan_get_nwid(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Read the NWID. */
-       psa_read(ioaddr, lp->hacr,
-                (char *) psa.psa_nwid - (char *) &psa,
-                (unsigned char *) psa.psa_nwid, 3);
-       wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
-       wrqu->nwid.disabled = !(psa.psa_nwid_select);
-       wrqu->nwid.fixed = 1;   /* Superfluous */
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set frequency
- */
-static int wavelan_set_freq(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       unsigned long flags;
-       int ret;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-       if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-               ret = wv_set_frequency(ioaddr, &(wrqu->freq));
-       else
-               ret = -EOPNOTSUPP;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get frequency
- */
-static int wavelan_get_freq(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
-        * Does it work for everybody, especially old cards? */
-       if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-               unsigned short freq;
-
-               /* Ask the EEPROM to read the frequency from the first area. */
-               fee_read(ioaddr, 0x00, &freq, 1);
-               wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
-               wrqu->freq.e = 1;
-       } else {
-               psa_read(ioaddr, lp->hacr,
-                        (char *) &psa.psa_subband - (char *) &psa,
-                        (unsigned char *) &psa.psa_subband, 1);
-
-               if (psa.psa_subband <= 4) {
-                       wrqu->freq.m = fixed_bands[psa.psa_subband];
-                       wrqu->freq.e = (psa.psa_subband != 0);
-               } else
-                       ret = -EOPNOTSUPP;
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set level threshold
- */
-static int wavelan_set_sens(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Set the level threshold. */
-       /* We should complain loudly if wrqu->sens.fixed = 0, because we
-        * can't set auto mode... */
-       psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
-       psa_write(ioaddr, lp->hacr,
-                 (char *) &psa.psa_thr_pre_set - (char *) &psa,
-                 (unsigned char *) &psa.psa_thr_pre_set, 1);
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev, ioaddr, lp->hacr);
-       mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set),
-               psa.psa_thr_pre_set);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get level threshold
- */
-static int wavelan_get_sens(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Read the level threshold. */
-       psa_read(ioaddr, lp->hacr,
-                (char *) &psa.psa_thr_pre_set - (char *) &psa,
-                (unsigned char *) &psa.psa_thr_pre_set, 1);
-       wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
-       wrqu->sens.fixed = 1;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set encryption key
- */
-static int wavelan_set_encode(struct net_device *dev,
-                             struct iw_request_info *info,
-                             union iwreq_data *wrqu,
-                             char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       unsigned long flags;
-       psa_t psa;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-
-       /* Check if capable of encryption */
-       if (!mmc_encr(ioaddr)) {
-               ret = -EOPNOTSUPP;
-       }
-
-       /* Check the size of the key */
-       if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
-               ret = -EINVAL;
-       }
-
-       if(!ret) {
-               /*basic checking... */
-               if (wrqu->encoding.length == 8) {
-                       /* Copy the key in the driver */
-                       memcpy(psa.psa_encryption_key, extra,
-                              wrqu->encoding.length);
-                       psa.psa_encryption_select = 1;
-
-                       psa_write(ioaddr, lp->hacr,
-                                 (char *) &psa.psa_encryption_select -
-                                 (char *) &psa,
-                                 (unsigned char *) &psa.
-                                 psa_encryption_select, 8 + 1);
-
-                       mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
-                               MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
-                       mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
-                                 (unsigned char *) &psa.
-                                 psa_encryption_key, 8);
-               }
-
-               /* disable encryption */
-               if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
-                       psa.psa_encryption_select = 0;
-                       psa_write(ioaddr, lp->hacr,
-                                 (char *) &psa.psa_encryption_select -
-                                 (char *) &psa,
-                                 (unsigned char *) &psa.
-                                 psa_encryption_select, 1);
-
-                       mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
-               }
-               /* update the Wavelan checksum */
-               update_psa_checksum(dev, ioaddr, lp->hacr);
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get encryption key
- */
-static int wavelan_get_encode(struct net_device *dev,
-                             struct iw_request_info *info,
-                             union iwreq_data *wrqu,
-                             char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Check if encryption is available */
-       if (!mmc_encr(ioaddr)) {
-               ret = -EOPNOTSUPP;
-       } else {
-               /* Read the encryption key */
-               psa_read(ioaddr, lp->hacr,
-                        (char *) &psa.psa_encryption_select -
-                        (char *) &psa,
-                        (unsigned char *) &psa.
-                        psa_encryption_select, 1 + 8);
-
-               /* encryption is enabled ? */
-               if (psa.psa_encryption_select)
-                       wrqu->encoding.flags = IW_ENCODE_ENABLED;
-               else
-                       wrqu->encoding.flags = IW_ENCODE_DISABLED;
-               wrqu->encoding.flags |= mmc_encr(ioaddr);
-
-               /* Copy the key to the user buffer */
-               wrqu->encoding.length = 8;
-               memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get range info
- */
-static int wavelan_get_range(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       struct iw_range *range = (struct iw_range *) extra;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Set the length (very important for backward compatibility) */
-       wrqu->data.length = sizeof(struct iw_range);
-
-       /* Set all the info we don't care or don't know about to zero */
-       memset(range, 0, sizeof(struct iw_range));
-
-       /* Set the Wireless Extension versions */
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 9;
-
-       /* Set information in the range struct.  */
-       range->throughput = 1.6 * 1000 * 1000;  /* don't argue on this ! */
-       range->min_nwid = 0x0000;
-       range->max_nwid = 0xFFFF;
-
-       range->sensitivity = 0x3F;
-       range->max_qual.qual = MMR_SGNL_QUAL;
-       range->max_qual.level = MMR_SIGNAL_LVL;
-       range->max_qual.noise = MMR_SILENCE_LVL;
-       range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
-       /* Need to get better values for those two */
-       range->avg_qual.level = 30;
-       range->avg_qual.noise = 8;
-
-       range->num_bitrates = 1;
-       range->bitrate[0] = 2000000;    /* 2 Mb/s */
-
-       /* Event capability (kernel + driver) */
-       range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
-                               IW_EVENT_CAPA_MASK(0x8B04));
-       range->event_capa[1] = IW_EVENT_CAPA_K_1;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-       if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-               range->num_channels = 10;
-               range->num_frequency = wv_frequency_list(ioaddr, range->freq,
-                                                       IW_MAX_FREQUENCIES);
-       } else
-               range->num_channels = range->num_frequency = 0;
-
-       /* Encryption supported ? */
-       if (mmc_encr(ioaddr)) {
-               range->encoding_size[0] = 8;    /* DES = 64 bits key */
-               range->num_encoding_sizes = 1;
-               range->max_encoding_tokens = 1; /* Only one key possible */
-       } else {
-               range->num_encoding_sizes = 0;
-               range->max_encoding_tokens = 0;
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set quality threshold
- */
-static int wavelan_set_qthr(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       psa.psa_quality_thr = *(extra) & 0x0F;
-       psa_write(ioaddr, lp->hacr,
-                 (char *) &psa.psa_quality_thr - (char *) &psa,
-                 (unsigned char *) &psa.psa_quality_thr, 1);
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev, ioaddr, lp->hacr);
-       mmc_out(ioaddr, mmwoff(0, mmw_quality_thr),
-               psa.psa_quality_thr);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get quality threshold
- */
-static int wavelan_get_qthr(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-       psa_t psa;
-       unsigned long flags;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       psa_read(ioaddr, lp->hacr,
-                (char *) &psa.psa_quality_thr - (char *) &psa,
-                (unsigned char *) &psa.psa_quality_thr, 1);
-       *(extra) = psa.psa_quality_thr & 0x0F;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return 0;
-}
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set histogram
- */
-static int wavelan_set_histo(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-
-       /* Check the number of intervals. */
-       if (wrqu->data.length > 16) {
-               return(-E2BIG);
-       }
-
-       /* Disable histo while we copy the addresses.
-        * As we don't disable interrupts, we need to do this */
-       lp->his_number = 0;
-
-       /* Are there ranges to copy? */
-       if (wrqu->data.length > 0) {
-               /* Copy interval ranges to the driver */
-               memcpy(lp->his_range, extra, wrqu->data.length);
-
-               {
-                 int i;
-                 printk(KERN_DEBUG "Histo :");
-                 for(i = 0; i < wrqu->data.length; i++)
-                   printk(" %d", lp->his_range[i]);
-                 printk("\n");
-               }
-
-               /* Reset result structure. */
-               memset(lp->his_sum, 0x00, sizeof(long) * 16);
-       }
-
-       /* Now we can set the number of ranges */
-       lp->his_number = wrqu->data.length;
-
-       return(0);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get histogram
- */
-static int wavelan_get_histo(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       net_local *lp = netdev_priv(dev);       /* lp is not unused */
-
-       /* Set the number of intervals. */
-       wrqu->data.length = lp->his_number;
-
-       /* Give back the distribution statistics */
-       if(lp->his_number > 0)
-               memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
-
-       return(0);
-}
-#endif                 /* HISTOGRAM */
-
-/*------------------------------------------------------------------*/
-/*
- * Structures to export the Wireless Handlers
- */
-
-static const iw_handler                wavelan_handler[] =
-{
-       NULL,                           /* SIOCSIWNAME */
-       wavelan_get_name,               /* SIOCGIWNAME */
-       wavelan_set_nwid,               /* SIOCSIWNWID */
-       wavelan_get_nwid,               /* SIOCGIWNWID */
-       wavelan_set_freq,               /* SIOCSIWFREQ */
-       wavelan_get_freq,               /* SIOCGIWFREQ */
-       NULL,                           /* SIOCSIWMODE */
-       NULL,                           /* SIOCGIWMODE */
-       wavelan_set_sens,               /* SIOCSIWSENS */
-       wavelan_get_sens,               /* SIOCGIWSENS */
-       NULL,                           /* SIOCSIWRANGE */
-       wavelan_get_range,              /* SIOCGIWRANGE */
-       NULL,                           /* SIOCSIWPRIV */
-       NULL,                           /* SIOCGIWPRIV */
-       NULL,                           /* SIOCSIWSTATS */
-       NULL,                           /* SIOCGIWSTATS */
-       iw_handler_set_spy,             /* SIOCSIWSPY */
-       iw_handler_get_spy,             /* SIOCGIWSPY */
-       iw_handler_set_thrspy,          /* SIOCSIWTHRSPY */
-       iw_handler_get_thrspy,          /* SIOCGIWTHRSPY */
-       NULL,                           /* SIOCSIWAP */
-       NULL,                           /* SIOCGIWAP */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCGIWAPLIST */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCSIWESSID */
-       NULL,                           /* SIOCGIWESSID */
-       NULL,                           /* SIOCSIWNICKN */
-       NULL,                           /* SIOCGIWNICKN */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCSIWRATE */
-       NULL,                           /* SIOCGIWRATE */
-       NULL,                           /* SIOCSIWRTS */
-       NULL,                           /* SIOCGIWRTS */
-       NULL,                           /* SIOCSIWFRAG */
-       NULL,                           /* SIOCGIWFRAG */
-       NULL,                           /* SIOCSIWTXPOW */
-       NULL,                           /* SIOCGIWTXPOW */
-       NULL,                           /* SIOCSIWRETRY */
-       NULL,                           /* SIOCGIWRETRY */
-       /*bummer ! Why those are only at the end ??? */
-       wavelan_set_encode,             /* SIOCSIWENCODE */
-       wavelan_get_encode,             /* SIOCGIWENCODE */
-};
-
-static const iw_handler                wavelan_private_handler[] =
-{
-       wavelan_set_qthr,               /* SIOCIWFIRSTPRIV */
-       wavelan_get_qthr,               /* SIOCIWFIRSTPRIV + 1 */
-#ifdef HISTOGRAM
-       wavelan_set_histo,              /* SIOCIWFIRSTPRIV + 2 */
-       wavelan_get_histo,              /* SIOCIWFIRSTPRIV + 3 */
-#endif /* HISTOGRAM */
-};
-
-static const struct iw_priv_args wavelan_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
-  { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
-  { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16,                    0, "sethisto" },
-  { SIOCGIPHISTO, 0,                     IW_PRIV_TYPE_INT | 16, "gethisto" },
-};
-
-static const struct iw_handler_def     wavelan_handler_def =
-{
-       .num_standard   = ARRAY_SIZE(wavelan_handler),
-       .num_private    = ARRAY_SIZE(wavelan_private_handler),
-       .num_private_args = ARRAY_SIZE(wavelan_private_args),
-       .standard       = wavelan_handler,
-       .private        = wavelan_private_handler,
-       .private_args   = wavelan_private_args,
-       .get_wireless_stats = wavelan_get_wireless_stats,
-};
-
-/*------------------------------------------------------------------*/
-/*
- * Get wireless statistics.
- * Called by /proc/net/wireless
- */
-static iw_stats *wavelan_get_wireless_stats(struct net_device *dev)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       mmr_t m;
-       iw_stats *wstats;
-       unsigned long flags;
-
-#ifdef DEBUG_IOCTL_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n",
-              dev->name);
-#endif
-
-       /* Check */
-       if (lp == (net_local *) NULL)
-               return (iw_stats *) NULL;
-       
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       wstats = &lp->wstats;
-
-       /* Get data from the mmc. */
-       mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
-
-       mmc_read(ioaddr, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
-       mmc_read(ioaddr, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l,
-                2);
-       mmc_read(ioaddr, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set,
-                4);
-
-       mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
-       /* Copy data to wireless stuff. */
-       wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
-       wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
-       wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
-       wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
-       wstats->qual.updated = (((m. mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) 
-                       | ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) 
-                       | ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
-       wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-       wstats->discard.code = 0L;
-       wstats->discard.misc = 0L;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_IOCTL_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n",
-              dev->name);
-#endif
-       return &lp->wstats;
-}
-
-/************************* PACKET RECEPTION *************************/
-/*
- * This part deals with receiving the packets.
- * The interrupt handler gets an interrupt when a packet has been
- * successfully received and calls this part.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does the actual copying of data (including the Ethernet
- * header structure) from the WaveLAN card to an sk_buff chain that
- * will be passed up to the network interface layer. NOTE: we
- * currently don't handle trailer protocols (neither does the rest of
- * the network interface), so if that is needed, it will (at least in
- * part) be added here.  The contents of the receive ring buffer are
- * copied to a message chain that is then passed to the kernel.
- *
- * Note: if any errors occur, the packet is "dropped on the floor".
- * (called by wv_packet_rcv())
- */
-static void
-wv_packet_read(struct net_device *dev, u16 buf_off, int sksize)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       struct sk_buff *skb;
-
-#ifdef DEBUG_RX_TRACE
-       printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
-              dev->name, buf_off, sksize);
-#endif
-
-       /* Allocate buffer for the data */
-       if ((skb = dev_alloc_skb(sksize)) == (struct sk_buff *) NULL) {
-#ifdef DEBUG_RX_ERROR
-               printk(KERN_INFO
-                      "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC).\n",
-                      dev->name, sksize);
-#endif
-               dev->stats.rx_dropped++;
-               return;
-       }
-
-       /* Copy the packet to the buffer. */
-       obram_read(ioaddr, buf_off, skb_put(skb, sksize), sksize);
-       skb->protocol = eth_type_trans(skb, dev);
-
-#ifdef DEBUG_RX_INFO
-       wv_packet_info(skb_mac_header(skb), sksize, dev->name,
-                      "wv_packet_read");
-#endif                         /* DEBUG_RX_INFO */
-
-       /* Statistics-gathering and associated stuff.
-        * It seem a bit messy with all the define, but it's really
-        * simple... */
-       if (
-#ifdef IW_WIRELESS_SPY         /* defined in iw_handler.h */
-                  (lp->spy_data.spy_number > 0) ||
-#endif /* IW_WIRELESS_SPY */
-#ifdef HISTOGRAM
-                  (lp->his_number > 0) ||
-#endif /* HISTOGRAM */
-                  0) {
-               u8 stats[3];    /* signal level, noise level, signal quality */
-
-               /* Read signal level, silence level and signal quality bytes */
-               /* Note: in the PCMCIA hardware, these are part of the frame.
-                * It seems that for the ISA hardware, it's nowhere to be
-                * found in the frame, so I'm obliged to do this (it has a
-                * side effect on /proc/net/wireless).
-                * Any ideas?
-                */
-               mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
-               mmc_read(ioaddr, mmroff(0, mmr_signal_lvl), stats, 3);
-               mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
-
-#ifdef DEBUG_RX_INFO
-               printk(KERN_DEBUG
-                      "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
-                      dev->name, stats[0] & 0x3F, stats[1] & 0x3F,
-                      stats[2] & 0x0F);
-#endif
-
-               /* Spying stuff */
-#ifdef IW_WIRELESS_SPY
-               wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE,
-                             stats);
-#endif /* IW_WIRELESS_SPY */
-#ifdef HISTOGRAM
-               wl_his_gather(dev, stats);
-#endif /* HISTOGRAM */
-       }
-
-       /*
-        * Hand the packet to the network module.
-        */
-       netif_rx(skb);
-
-       /* Keep statistics up to date */
-       dev->stats.rx_packets++;
-       dev->stats.rx_bytes += sksize;
-
-#ifdef DEBUG_RX_TRACE
-       printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Transfer as many packets as we can
- * from the device RAM.
- * (called in wavelan_interrupt()).
- * Note : the spinlock is already grabbed for us.
- */
-static void wv_receive(struct net_device *dev)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       fd_t fd;
-       rbd_t rbd;
-       int nreaped = 0;
-
-#ifdef DEBUG_RX_TRACE
-       printk(KERN_DEBUG "%s: ->wv_receive()\n", dev->name);
-#endif
-
-       /* Loop on each received packet. */
-       for (;;) {
-               obram_read(ioaddr, lp->rx_head, (unsigned char *) &fd,
-                          sizeof(fd));
-
-               /* Note about the status :
-                * It start up to be 0 (the value we set). Then, when the RU
-                * grab the buffer to prepare for reception, it sets the
-                * FD_STATUS_B flag. When the RU has finished receiving the
-                * frame, it clears FD_STATUS_B, set FD_STATUS_C to indicate
-                * completion and set the other flags to indicate the eventual
-                * errors. FD_STATUS_OK indicates that the reception was OK.
-                */
-
-               /* If the current frame is not complete, we have reached the end. */
-               if ((fd.fd_status & FD_STATUS_C) != FD_STATUS_C)
-                       break;  /* This is how we exit the loop. */
-
-               nreaped++;
-
-               /* Check whether frame was correctly received. */
-               if ((fd.fd_status & FD_STATUS_OK) == FD_STATUS_OK) {
-                       /* Does the frame contain a pointer to the data?  Let's check. */
-                       if (fd.fd_rbd_offset != I82586NULL) {
-                               /* Read the receive buffer descriptor */
-                               obram_read(ioaddr, fd.fd_rbd_offset,
-                                          (unsigned char *) &rbd,
-                                          sizeof(rbd));
-
-#ifdef DEBUG_RX_ERROR
-                               if ((rbd.rbd_status & RBD_STATUS_EOF) !=
-                                   RBD_STATUS_EOF) printk(KERN_INFO
-                                                          "%s: wv_receive(): missing EOF flag.\n",
-                                                          dev->name);
-
-                               if ((rbd.rbd_status & RBD_STATUS_F) !=
-                                   RBD_STATUS_F) printk(KERN_INFO
-                                                        "%s: wv_receive(): missing F flag.\n",
-                                                        dev->name);
-#endif                         /* DEBUG_RX_ERROR */
-
-                               /* Read the packet and transmit to Linux */
-                               wv_packet_read(dev, rbd.rbd_bufl,
-                                              rbd.
-                                              rbd_status &
-                                              RBD_STATUS_ACNT);
-                       }
-#ifdef DEBUG_RX_ERROR
-                       else    /* if frame has no data */
-                               printk(KERN_INFO
-                                      "%s: wv_receive(): frame has no data.\n",
-                                      dev->name);
-#endif
-               } else {        /* If reception was no successful */
-
-                       dev->stats.rx_errors++;
-
-#ifdef DEBUG_RX_INFO
-                       printk(KERN_DEBUG
-                              "%s: wv_receive(): frame not received successfully (%X).\n",
-                              dev->name, fd.fd_status);
-#endif
-
-#ifdef DEBUG_RX_ERROR
-                       if ((fd.fd_status & FD_STATUS_S6) != 0)
-                               printk(KERN_INFO
-                                      "%s: wv_receive(): no EOF flag.\n",
-                                      dev->name);
-#endif
-
-                       if ((fd.fd_status & FD_STATUS_S7) != 0) {
-                               dev->stats.rx_length_errors++;
-#ifdef DEBUG_RX_FAIL
-                               printk(KERN_DEBUG
-                                      "%s: wv_receive(): frame too short.\n",
-                                      dev->name);
-#endif
-                       }
-
-                       if ((fd.fd_status & FD_STATUS_S8) != 0) {
-                               dev->stats.rx_over_errors++;
-#ifdef DEBUG_RX_FAIL
-                               printk(KERN_DEBUG
-                                      "%s: wv_receive(): rx DMA overrun.\n",
-                                      dev->name);
-#endif
-                       }
-
-                       if ((fd.fd_status & FD_STATUS_S9) != 0) {
-                               dev->stats.rx_fifo_errors++;
-#ifdef DEBUG_RX_FAIL
-                               printk(KERN_DEBUG
-                                      "%s: wv_receive(): ran out of resources.\n",
-                                      dev->name);
-#endif
-                       }
-
-                       if ((fd.fd_status & FD_STATUS_S10) != 0) {
-                               dev->stats.rx_frame_errors++;
-#ifdef DEBUG_RX_FAIL
-                               printk(KERN_DEBUG
-                                      "%s: wv_receive(): alignment error.\n",
-                                      dev->name);
-#endif
-                       }
-
-                       if ((fd.fd_status & FD_STATUS_S11) != 0) {
-                               dev->stats.rx_crc_errors++;
-#ifdef DEBUG_RX_FAIL
-                               printk(KERN_DEBUG
-                                      "%s: wv_receive(): CRC error.\n",
-                                      dev->name);
-#endif
-                       }
-               }
-
-               fd.fd_status = 0;
-               obram_write(ioaddr, fdoff(lp->rx_head, fd_status),
-                           (unsigned char *) &fd.fd_status,
-                           sizeof(fd.fd_status));
-
-               fd.fd_command = FD_COMMAND_EL;
-               obram_write(ioaddr, fdoff(lp->rx_head, fd_command),
-                           (unsigned char *) &fd.fd_command,
-                           sizeof(fd.fd_command));
-
-               fd.fd_command = 0;
-               obram_write(ioaddr, fdoff(lp->rx_last, fd_command),
-                           (unsigned char *) &fd.fd_command,
-                           sizeof(fd.fd_command));
-
-               lp->rx_last = lp->rx_head;
-               lp->rx_head = fd.fd_link_offset;
-       }                       /* for(;;) -> loop on all frames */
-
-#ifdef DEBUG_RX_INFO
-       if (nreaped > 1)
-               printk(KERN_DEBUG "%s: wv_receive(): reaped %d\n",
-                      dev->name, nreaped);
-#endif
-#ifdef DEBUG_RX_TRACE
-       printk(KERN_DEBUG "%s: <-wv_receive()\n", dev->name);
-#endif
-}
-
-/*********************** PACKET TRANSMISSION ***********************/
-/*
- * This part deals with sending packets through the WaveLAN.
- *
- */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine fills in the appropriate registers and memory
- * locations on the WaveLAN card and starts the card off on
- * the transmit.
- *
- * The principle:
- * Each block contains a transmit command, a NOP command,
- * a transmit block descriptor and a buffer.
- * The CU read the transmit block which point to the tbd,
- * read the tbd and the content of the buffer.
- * When it has finish with it, it goes to the next command
- * which in our case is the NOP. The NOP points on itself,
- * so the CU stop here.
- * When we add the next block, we modify the previous nop
- * to make it point on the new tx command.
- * Simple, isn't it ?
- *
- * (called in wavelan_packet_xmit())
- */
-static int wv_packet_write(struct net_device *dev, void *buf, short length)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       unsigned short txblock;
-       unsigned short txpred;
-       unsigned short tx_addr;
-       unsigned short nop_addr;
-       unsigned short tbd_addr;
-       unsigned short buf_addr;
-       ac_tx_t tx;
-       ac_nop_t nop;
-       tbd_t tbd;
-       int clen = length;
-       unsigned long flags;
-
-#ifdef DEBUG_TX_TRACE
-       printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name,
-              length);
-#endif
-
-       spin_lock_irqsave(&lp->spinlock, flags);
-
-       /* Check nothing bad has happened */
-       if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
-#ifdef DEBUG_TX_ERROR
-               printk(KERN_INFO "%s: wv_packet_write(): Tx queue full.\n",
-                      dev->name);
-#endif
-               spin_unlock_irqrestore(&lp->spinlock, flags);
-               return 1;
-       }
-
-       /* Calculate addresses of next block and previous block. */
-       txblock = lp->tx_first_free;
-       txpred = txblock - TXBLOCKZ;
-       if (txpred < OFFSET_CU)
-               txpred += NTXBLOCKS * TXBLOCKZ;
-       lp->tx_first_free += TXBLOCKZ;
-       if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-               lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
-
-       lp->tx_n_in_use++;
-
-       /* Calculate addresses of the different parts of the block. */
-       tx_addr = txblock;
-       nop_addr = tx_addr + sizeof(tx);
-       tbd_addr = nop_addr + sizeof(nop);
-       buf_addr = tbd_addr + sizeof(tbd);
-
-       /*
-        * Transmit command
-        */
-       tx.tx_h.ac_status = 0;
-       obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
-                   (unsigned char *) &tx.tx_h.ac_status,
-                   sizeof(tx.tx_h.ac_status));
-
-       /*
-        * NOP command
-        */
-       nop.nop_h.ac_status = 0;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-                   (unsigned char *) &nop.nop_h.ac_status,
-                   sizeof(nop.nop_h.ac_status));
-       nop.nop_h.ac_link = nop_addr;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-                   (unsigned char *) &nop.nop_h.ac_link,
-                   sizeof(nop.nop_h.ac_link));
-
-       /*
-        * Transmit buffer descriptor
-        */
-       tbd.tbd_status = TBD_STATUS_EOF | (TBD_STATUS_ACNT & clen);
-       tbd.tbd_next_bd_offset = I82586NULL;
-       tbd.tbd_bufl = buf_addr;
-       tbd.tbd_bufh = 0;
-       obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd, sizeof(tbd));
-
-       /*
-        * Data
-        */
-       obram_write(ioaddr, buf_addr, buf, length);
-
-       /*
-        * Overwrite the predecessor NOP link
-        * so that it points to this txblock.
-        */
-       nop_addr = txpred + sizeof(tx);
-       nop.nop_h.ac_status = 0;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-                   (unsigned char *) &nop.nop_h.ac_status,
-                   sizeof(nop.nop_h.ac_status));
-       nop.nop_h.ac_link = txblock;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-                   (unsigned char *) &nop.nop_h.ac_link,
-                   sizeof(nop.nop_h.ac_link));
-
-       /* Make sure the watchdog will keep quiet for a while */
-       dev->trans_start = jiffies;
-
-       /* Keep stats up to date. */
-       dev->stats.tx_bytes += length;
-
-       if (lp->tx_first_in_use == I82586NULL)
-               lp->tx_first_in_use = txblock;
-
-       if (lp->tx_n_in_use < NTXBLOCKS - 1)
-               netif_wake_queue(dev);
-
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-       
-#ifdef DEBUG_TX_INFO
-       wv_packet_info((u8 *) buf, length, dev->name,
-                      "wv_packet_write");
-#endif                         /* DEBUG_TX_INFO */
-
-#ifdef DEBUG_TX_TRACE
-       printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
-#endif
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the harware is ready to accept
- * the packet.  We also prevent reentrance.  Then we call the function
- * to send the packet.
- */
-static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb,
-                                            struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-       char data[ETH_ZLEN];
-
-#ifdef DEBUG_TX_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
-              (unsigned) skb);
-#endif
-
-       /*
-        *block a timer-based transmit from overlapping.
-        * In other words, prevent reentering this routine.
-        */
-       netif_stop_queue(dev);
-
-       /* If somebody has asked to reconfigure the controller, 
-        * we can do it now.
-        */
-       if (lp->reconfig_82586) {
-               spin_lock_irqsave(&lp->spinlock, flags);
-               wv_82586_config(dev);
-               spin_unlock_irqrestore(&lp->spinlock, flags);
-               /* Check that we can continue */
-               if (lp->tx_n_in_use == (NTXBLOCKS - 1))
-                       return NETDEV_TX_BUSY;
-       }
-
-       /* Do we need some padding? */
-       /* Note : on wireless the propagation time is in the order of 1us,
-        * and we don't have the Ethernet specific requirement of beeing
-        * able to detect collisions, therefore in theory we don't really
-        * need to pad. Jean II */
-       if (skb->len < ETH_ZLEN) {
-               memset(data, 0, ETH_ZLEN);
-               skb_copy_from_linear_data(skb, data, skb->len);
-               /* Write packet on the card */
-               if(wv_packet_write(dev, data, ETH_ZLEN))
-                       return NETDEV_TX_BUSY;  /* We failed */
-       }
-       else if(wv_packet_write(dev, skb->data, skb->len))
-               return NETDEV_TX_BUSY;  /* We failed */
-
-
-       dev_kfree_skb(skb);
-
-#ifdef DEBUG_TX_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
-#endif
-       return NETDEV_TX_OK;
-}
-
-/*********************** HARDWARE CONFIGURATION ***********************/
-/*
- * This part does the real job of starting and configuring the hardware.
- */
-
-/*--------------------------------------------------------------------*/
-/*
- * Routine to initialize the Modem Management Controller.
- * (called by wv_hw_reset())
- */
-static int wv_mmc_init(struct net_device *dev)
-{
-       unsigned long ioaddr = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       mmw_t m;
-       int configured;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
-#endif
-
-       /* Read the parameter storage area. */
-       psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
-
-#ifdef USE_PSA_CONFIG
-       configured = psa.psa_conf_status & 1;
-#else
-       configured = 0;
-#endif
-
-       /* Is the PSA is not configured */
-       if (!configured) {
-               /* User will be able to configure NWID later (with iwconfig). */
-               psa.psa_nwid[0] = 0;
-               psa.psa_nwid[1] = 0;
-
-               /* no NWID checking since NWID is not set */
-               psa.psa_nwid_select = 0;
-
-               /* Disable encryption */
-               psa.psa_encryption_select = 0;
-
-               /* Set to standard values:
-                * 0x04 for AT,
-                * 0x01 for MCA,
-                * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document)
-                */
-               if (psa.psa_comp_number & 1)
-                       psa.psa_thr_pre_set = 0x01;
-               else
-                       psa.psa_thr_pre_set = 0x04;
-               psa.psa_quality_thr = 0x03;
-
-               /* It is configured */
-               psa.psa_conf_status |= 1;
-
-#ifdef USE_PSA_CONFIG
-               /* Write the psa. */
-               psa_write(ioaddr, lp->hacr,
-                         (char *) psa.psa_nwid - (char *) &psa,
-                         (unsigned char *) psa.psa_nwid, 4);
-               psa_write(ioaddr, lp->hacr,
-                         (char *) &psa.psa_thr_pre_set - (char *) &psa,
-                         (unsigned char *) &psa.psa_thr_pre_set, 1);
-               psa_write(ioaddr, lp->hacr,
-                         (char *) &psa.psa_quality_thr - (char *) &psa,
-                         (unsigned char *) &psa.psa_quality_thr, 1);
-               psa_write(ioaddr, lp->hacr,
-                         (char *) &psa.psa_conf_status - (char *) &psa,
-                         (unsigned char *) &psa.psa_conf_status, 1);
-               /* update the Wavelan checksum */
-               update_psa_checksum(dev, ioaddr, lp->hacr);
-#endif
-       }
-
-       /* Zero the mmc structure. */
-       memset(&m, 0x00, sizeof(m));
-
-       /* Copy PSA info to the mmc. */
-       m.mmw_netw_id_l = psa.psa_nwid[1];
-       m.mmw_netw_id_h = psa.psa_nwid[0];
-
-       if (psa.psa_nwid_select & 1)
-               m.mmw_loopt_sel = 0x00;
-       else
-               m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
-
-       memcpy(&m.mmw_encr_key, &psa.psa_encryption_key,
-              sizeof(m.mmw_encr_key));
-
-       if (psa.psa_encryption_select)
-               m.mmw_encr_enable =
-                   MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
-       else
-               m.mmw_encr_enable = 0;
-
-       m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
-       m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
-
-       /*
-        * Set default modem control parameters.
-        * See NCR document 407-0024326 Rev. A.
-        */
-       m.mmw_jabber_enable = 0x01;
-       m.mmw_freeze = 0;
-       m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
-       m.mmw_ifs = 0x20;
-       m.mmw_mod_delay = 0x04;
-       m.mmw_jam_time = 0x38;
-
-       m.mmw_des_io_invert = 0;
-       m.mmw_decay_prm = 0;
-       m.mmw_decay_updat_prm = 0;
-
-       /* Write all info to MMC. */
-       mmc_write(ioaddr, 0, (u8 *) & m, sizeof(m));
-
-       /* The following code starts the modem of the 2.00 frequency
-        * selectable cards at power on.  It's not strictly needed for the
-        * following boots.
-        * The original patch was by Joe Finney for the PCMCIA driver, but
-        * I've cleaned it up a bit and added documentation.
-        * Thanks to Loeke Brederveld from Lucent for the info.
-        */
-
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
-        * Does it work for everybody, especially old cards? */
-       /* Note: WFREQSEL verifies that it is able to read a sensible
-        * frequency from EEPROM (address 0x00) and that MMR_FEE_STATUS_ID
-        * is 0xA (Xilinx version) or 0xB (Ariadne version).
-        * My test is more crude but does work. */
-       if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-               /* We must download the frequency parameters to the
-                * synthesizers (from the EEPROM - area 1)
-                * Note: as the EEPROM is automatically decremented, we set the end
-                * if the area... */
-               m.mmw_fee_addr = 0x0F;
-               m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-               mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m,
-                         (unsigned char *) &m.mmw_fee_ctrl, 2);
-
-               /* Wait until the download is finished. */
-               fee_wait(ioaddr, 100, 100);
-
-#ifdef DEBUG_CONFIG_INFO
-               /* The frequency was in the last word downloaded. */
-               mmc_read(ioaddr, (char *) &m.mmw_fee_data_l - (char *) &m,
-                        (unsigned char *) &m.mmw_fee_data_l, 2);
-
-               /* Print some info for the user. */
-               printk(KERN_DEBUG
-                      "%s: WaveLAN 2.00 recognised (frequency select).  Current frequency = %ld\n",
-                      dev->name,
-                      ((m.
-                        mmw_fee_data_h << 4) | (m.mmw_fee_data_l >> 4)) *
-                      5 / 2 + 24000L);
-#endif
-
-               /* We must now download the power adjust value (gain) to
-                * the synthesizers (from the EEPROM - area 7 - DAC). */
-               m.mmw_fee_addr = 0x61;
-               m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-               mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m,
-                         (unsigned char *) &m.mmw_fee_ctrl, 2);
-
-               /* Wait until the download is finished. */
-       }
-       /* if 2.00 card */
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
-#endif
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Construct the fd and rbd structures.
- * Start the receive unit.
- * (called by wv_hw_reset())
- */
-static int wv_ru_start(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       u16 scb_cs;
-       fd_t fd;
-       rbd_t rbd;
-       u16 rx;
-       u16 rx_next;
-       int i;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
-#endif
-
-       obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
-                  (unsigned char *) &scb_cs, sizeof(scb_cs));
-       if ((scb_cs & SCB_ST_RUS) == SCB_ST_RUS_RDY)
-               return 0;
-
-       lp->rx_head = OFFSET_RU;
-
-       for (i = 0, rx = lp->rx_head; i < NRXBLOCKS; i++, rx = rx_next) {
-               rx_next =
-                   (i == NRXBLOCKS - 1) ? lp->rx_head : rx + RXBLOCKZ;
-
-               fd.fd_status = 0;
-               fd.fd_command = (i == NRXBLOCKS - 1) ? FD_COMMAND_EL : 0;
-               fd.fd_link_offset = rx_next;
-               fd.fd_rbd_offset = rx + sizeof(fd);
-               obram_write(ioaddr, rx, (unsigned char *) &fd, sizeof(fd));
-
-               rbd.rbd_status = 0;
-               rbd.rbd_next_rbd_offset = I82586NULL;
-               rbd.rbd_bufl = rx + sizeof(fd) + sizeof(rbd);
-               rbd.rbd_bufh = 0;
-               rbd.rbd_el_size = RBD_EL | (RBD_SIZE & MAXDATAZ);
-               obram_write(ioaddr, rx + sizeof(fd),
-                           (unsigned char *) &rbd, sizeof(rbd));
-
-               lp->rx_last = rx;
-       }
-
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_rfa_offset),
-                   (unsigned char *) &lp->rx_head, sizeof(lp->rx_head));
-
-       scb_cs = SCB_CMD_RUC_GO;
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-                   (unsigned char *) &scb_cs, sizeof(scb_cs));
-
-       set_chan_attn(ioaddr, lp->hacr);
-
-       for (i = 1000; i > 0; i--) {
-               obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
-                          (unsigned char *) &scb_cs, sizeof(scb_cs));
-               if (scb_cs == 0)
-                       break;
-
-               udelay(10);
-       }
-
-       if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_ru_start(): board not accepting command.\n",
-                      dev->name);
-#endif
-               return -1;
-       }
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
-#endif
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Initialise the transmit blocks.
- * Start the command unit executing the NOP
- * self-loop of the first transmit block.
- *
- * Here we create the list of send buffers used to transmit packets
- *between the PC and the command unit. For each buffer, we create a
- *buffer descriptor (pointing on the buffer), a transmit command
- * (pointing to the buffer descriptor) and a NOP command.
- * The transmit command is linked to the NOP, and the NOP to itself.
- * When we will have finished executing the transmit command, we will
- * then loop on the NOP. By releasing the NOP link to a new command,
- * we may send another buffer.
- *
- * (called by wv_hw_reset())
- */
-static int wv_cu_start(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       int i;
-       u16 txblock;
-       u16 first_nop;
-       u16 scb_cs;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_cu_start()\n", dev->name);
-#endif
-
-       lp->tx_first_free = OFFSET_CU;
-       lp->tx_first_in_use = I82586NULL;
-
-       for (i = 0, txblock = OFFSET_CU;
-            i < NTXBLOCKS; i++, txblock += TXBLOCKZ) {
-               ac_tx_t tx;
-               ac_nop_t nop;
-               tbd_t tbd;
-               unsigned short tx_addr;
-               unsigned short nop_addr;
-               unsigned short tbd_addr;
-               unsigned short buf_addr;
-
-               tx_addr = txblock;
-               nop_addr = tx_addr + sizeof(tx);
-               tbd_addr = nop_addr + sizeof(nop);
-               buf_addr = tbd_addr + sizeof(tbd);
-
-               tx.tx_h.ac_status = 0;
-               tx.tx_h.ac_command = acmd_transmit | AC_CFLD_I;
-               tx.tx_h.ac_link = nop_addr;
-               tx.tx_tbd_offset = tbd_addr;
-               obram_write(ioaddr, tx_addr, (unsigned char *) &tx,
-                           sizeof(tx));
-
-               nop.nop_h.ac_status = 0;
-               nop.nop_h.ac_command = acmd_nop;
-               nop.nop_h.ac_link = nop_addr;
-               obram_write(ioaddr, nop_addr, (unsigned char *) &nop,
-                           sizeof(nop));
-
-               tbd.tbd_status = TBD_STATUS_EOF;
-               tbd.tbd_next_bd_offset = I82586NULL;
-               tbd.tbd_bufl = buf_addr;
-               tbd.tbd_bufh = 0;
-               obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd,
-                           sizeof(tbd));
-       }
-
-       first_nop =
-           OFFSET_CU + (NTXBLOCKS - 1) * TXBLOCKZ + sizeof(ac_tx_t);
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_cbl_offset),
-                   (unsigned char *) &first_nop, sizeof(first_nop));
-
-       scb_cs = SCB_CMD_CUC_GO;
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-                   (unsigned char *) &scb_cs, sizeof(scb_cs));
-
-       set_chan_attn(ioaddr, lp->hacr);
-
-       for (i = 1000; i > 0; i--) {
-               obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
-                          (unsigned char *) &scb_cs, sizeof(scb_cs));
-               if (scb_cs == 0)
-                       break;
-
-               udelay(10);
-       }
-
-       if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_cu_start(): board not accepting command.\n",
-                      dev->name);
-#endif
-               return -1;
-       }
-
-       lp->tx_n_in_use = 0;
-       netif_start_queue(dev);
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_cu_start()\n", dev->name);
-#endif
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a standard configuration of the WaveLAN 
- * controller (i82586).
- *
- * It initialises the scp, iscp and scb structure
- * The first two are just pointers to the next.
- * The last one is used for basic configuration and for basic
- * communication (interrupt status).
- *
- * (called by wv_hw_reset())
- */
-static int wv_82586_start(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       scp_t scp;              /* system configuration pointer */
-       iscp_t iscp;            /* intermediate scp */
-       scb_t scb;              /* system control block */
-       ach_t cb;               /* Action command header */
-       u8 zeroes[512];
-       int i;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_82586_start()\n", dev->name);
-#endif
-
-       /*
-        * Clear the onboard RAM.
-        */
-       memset(&zeroes[0], 0x00, sizeof(zeroes));
-       for (i = 0; i < I82586_MEMZ; i += sizeof(zeroes))
-               obram_write(ioaddr, i, &zeroes[0], sizeof(zeroes));
-
-       /*
-        * Construct the command unit structures:
-        * scp, iscp, scb, cb.
-        */
-       memset(&scp, 0x00, sizeof(scp));
-       scp.scp_sysbus = SCP_SY_16BBUS;
-       scp.scp_iscpl = OFFSET_ISCP;
-       obram_write(ioaddr, OFFSET_SCP, (unsigned char *) &scp,
-                   sizeof(scp));
-
-       memset(&iscp, 0x00, sizeof(iscp));
-       iscp.iscp_busy = 1;
-       iscp.iscp_offset = OFFSET_SCB;
-       obram_write(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp,
-                   sizeof(iscp));
-
-       /* Our first command is to reset the i82586. */
-       memset(&scb, 0x00, sizeof(scb));
-       scb.scb_command = SCB_CMD_RESET;
-       scb.scb_cbl_offset = OFFSET_CU;
-       scb.scb_rfa_offset = OFFSET_RU;
-       obram_write(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
-                   sizeof(scb));
-
-       set_chan_attn(ioaddr, lp->hacr);
-
-       /* Wait for command to finish. */
-       for (i = 1000; i > 0; i--) {
-               obram_read(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp,
-                          sizeof(iscp));
-
-               if (iscp.iscp_busy == (unsigned short) 0)
-                       break;
-
-               udelay(10);
-       }
-
-       if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wv_82586_start(): iscp_busy timeout.\n",
-                      dev->name);
-#endif
-               return -1;
-       }
-
-       /* Check command completion. */
-       for (i = 15; i > 0; i--) {
-               obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
-                          sizeof(scb));
-
-               if (scb.scb_status == (SCB_ST_CX | SCB_ST_CNA))
-                       break;
-
-               udelay(10);
-       }
-
-       if (i <= 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wv_82586_start(): status: expected 0x%02x, got 0x%02x.\n",
-                      dev->name, SCB_ST_CX | SCB_ST_CNA, scb.scb_status);
-#endif
-               return -1;
-       }
-
-       wv_ack(dev);
-
-       /* Set the action command header. */
-       memset(&cb, 0x00, sizeof(cb));
-       cb.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_diagnose);
-       cb.ac_link = OFFSET_CU;
-       obram_write(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb));
-
-       if (wv_synchronous_cmd(dev, "diag()") == -1)
-               return -1;
-
-       obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb));
-       if (cb.ac_status & AC_SFLD_FAIL) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wv_82586_start(): i82586 Self Test failed.\n",
-                      dev->name);
-#endif
-               return -1;
-       }
-#ifdef DEBUG_I82586_SHOW
-       wv_scb_show(ioaddr);
-#endif
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_82586_start()\n", dev->name);
-#endif
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a standard configuration of the WaveLAN
- * controller (i82586).
- *
- * This routine is a violent hack. We use the first free transmit block
- * to make our configuration. In the buffer area, we create the three
- * configuration commands (linked). We make the previous NOP point to
- * the beginning of the buffer instead of the tx command. After, we go
- * as usual to the NOP command.
- * Note that only the last command (mc_set) will generate an interrupt.
- *
- * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit())
- */
-static void wv_82586_config(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       unsigned short txblock;
-       unsigned short txpred;
-       unsigned short tx_addr;
-       unsigned short nop_addr;
-       unsigned short tbd_addr;
-       unsigned short cfg_addr;
-       unsigned short ias_addr;
-       unsigned short mcs_addr;
-       ac_tx_t tx;
-       ac_nop_t nop;
-       ac_cfg_t cfg;           /* Configure action */
-       ac_ias_t ias;           /* IA-setup action */
-       ac_mcs_t mcs;           /* Multicast setup */
-       struct dev_mc_list *dmi;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name);
-#endif
-
-       /* Check nothing bad has happened */
-       if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n",
-                      dev->name);
-#endif
-               return;
-       }
-
-       /* Calculate addresses of next block and previous block. */
-       txblock = lp->tx_first_free;
-       txpred = txblock - TXBLOCKZ;
-       if (txpred < OFFSET_CU)
-               txpred += NTXBLOCKS * TXBLOCKZ;
-       lp->tx_first_free += TXBLOCKZ;
-       if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
-               lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
-
-       lp->tx_n_in_use++;
-
-       /* Calculate addresses of the different parts of the block. */
-       tx_addr = txblock;
-       nop_addr = tx_addr + sizeof(tx);
-       tbd_addr = nop_addr + sizeof(nop);
-       cfg_addr = tbd_addr + sizeof(tbd_t);    /*beginning of the buffer */
-       ias_addr = cfg_addr + sizeof(cfg);
-       mcs_addr = ias_addr + sizeof(ias);
-
-       /*
-        * Transmit command
-        */
-       tx.tx_h.ac_status = 0xFFFF;     /* Fake completion value */
-       obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
-                   (unsigned char *) &tx.tx_h.ac_status,
-                   sizeof(tx.tx_h.ac_status));
-
-       /*
-        * NOP command
-        */
-       nop.nop_h.ac_status = 0;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-                   (unsigned char *) &nop.nop_h.ac_status,
-                   sizeof(nop.nop_h.ac_status));
-       nop.nop_h.ac_link = nop_addr;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-                   (unsigned char *) &nop.nop_h.ac_link,
-                   sizeof(nop.nop_h.ac_link));
-
-       /* Create a configure action. */
-       memset(&cfg, 0x00, sizeof(cfg));
-
-       /*
-        * For Linux we invert AC_CFG_ALOC() so as to conform
-        * to the way that net packets reach us from above.
-        * (See also ac_tx_t.)
-        *
-        * Updated from Wavelan Manual WCIN085B
-        */
-       cfg.cfg_byte_cnt =
-           AC_CFG_BYTE_CNT(sizeof(ac_cfg_t) - sizeof(ach_t));
-       cfg.cfg_fifolim = AC_CFG_FIFOLIM(4);
-       cfg.cfg_byte8 = AC_CFG_SAV_BF(1) | AC_CFG_SRDY(0);
-       cfg.cfg_byte9 = AC_CFG_ELPBCK(0) |
-           AC_CFG_ILPBCK(0) |
-           AC_CFG_PRELEN(AC_CFG_PLEN_2) |
-           AC_CFG_ALOC(1) | AC_CFG_ADDRLEN(WAVELAN_ADDR_SIZE);
-       cfg.cfg_byte10 = AC_CFG_BOFMET(1) |
-           AC_CFG_ACR(6) | AC_CFG_LINPRIO(0);
-       cfg.cfg_ifs = 0x20;
-       cfg.cfg_slotl = 0x0C;
-       cfg.cfg_byte13 = AC_CFG_RETRYNUM(15) | AC_CFG_SLTTMHI(0);
-       cfg.cfg_byte14 = AC_CFG_FLGPAD(0) |
-           AC_CFG_BTSTF(0) |
-           AC_CFG_CRC16(0) |
-           AC_CFG_NCRC(0) |
-           AC_CFG_TNCRS(1) |
-           AC_CFG_MANCH(0) |
-           AC_CFG_BCDIS(0) | AC_CFG_PRM(lp->promiscuous);
-       cfg.cfg_byte15 = AC_CFG_ICDS(0) |
-           AC_CFG_CDTF(0) | AC_CFG_ICSS(0) | AC_CFG_CSTF(0);
-/*
-  cfg.cfg_min_frm_len = AC_CFG_MNFRM(64);
-*/
-       cfg.cfg_min_frm_len = AC_CFG_MNFRM(8);
-
-       cfg.cfg_h.ac_command = (AC_CFLD_CMD & acmd_configure);
-       cfg.cfg_h.ac_link = ias_addr;
-       obram_write(ioaddr, cfg_addr, (unsigned char *) &cfg, sizeof(cfg));
-
-       /* Set up the MAC address */
-       memset(&ias, 0x00, sizeof(ias));
-       ias.ias_h.ac_command = (AC_CFLD_CMD & acmd_ia_setup);
-       ias.ias_h.ac_link = mcs_addr;
-       memcpy(&ias.ias_addr[0], (unsigned char *) &dev->dev_addr[0],
-              sizeof(ias.ias_addr));
-       obram_write(ioaddr, ias_addr, (unsigned char *) &ias, sizeof(ias));
-
-       /* Initialize adapter's Ethernet multicast addresses */
-       memset(&mcs, 0x00, sizeof(mcs));
-       mcs.mcs_h.ac_command = AC_CFLD_I | (AC_CFLD_CMD & acmd_mc_setup);
-       mcs.mcs_h.ac_link = nop_addr;
-       mcs.mcs_cnt = WAVELAN_ADDR_SIZE * lp->mc_count;
-       obram_write(ioaddr, mcs_addr, (unsigned char *) &mcs, sizeof(mcs));
-
-       /* Any address to set? */
-       if (lp->mc_count) {
-               netdev_for_each_mc_addr(dmi, dev)
-                       outsw(PIOP1(ioaddr), (u16 *) dmi->dmi_addr,
-                             WAVELAN_ADDR_SIZE >> 1);
-
-#ifdef DEBUG_CONFIG_INFO
-               printk(KERN_DEBUG
-                      "%s: wv_82586_config(): set %d multicast addresses:\n",
-                      dev->name, lp->mc_count);
-               netdev_for_each_mc_addr(dmi, dev)
-                       printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
-#endif
-       }
-
-       /*
-        * Overwrite the predecessor NOP link
-        * so that it points to the configure action.
-        */
-       nop_addr = txpred + sizeof(tx);
-       nop.nop_h.ac_status = 0;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
-                   (unsigned char *) &nop.nop_h.ac_status,
-                   sizeof(nop.nop_h.ac_status));
-       nop.nop_h.ac_link = cfg_addr;
-       obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
-                   (unsigned char *) &nop.nop_h.ac_link,
-                   sizeof(nop.nop_h.ac_link));
-
-       /* Job done, clear the flag */
-       lp->reconfig_82586 = 0;
-
-       if (lp->tx_first_in_use == I82586NULL)
-               lp->tx_first_in_use = txblock;
-
-       if (lp->tx_n_in_use == (NTXBLOCKS - 1))
-               netif_stop_queue(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine, called by wavelan_close(), gracefully stops the 
- * WaveLAN controller (i82586).
- * (called by wavelan_close())
- */
-static void wv_82586_stop(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-       u16 scb_cmd;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_82586_stop()\n", dev->name);
-#endif
-
-       /* Suspend both command unit and receive unit. */
-       scb_cmd =
-           (SCB_CMD_CUC & SCB_CMD_CUC_SUS) | (SCB_CMD_RUC &
-                                              SCB_CMD_RUC_SUS);
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-                   (unsigned char *) &scb_cmd, sizeof(scb_cmd));
-       set_chan_attn(ioaddr, lp->hacr);
-
-       /* No more interrupts */
-       wv_ints_off(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_82586_stop()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Totally reset the WaveLAN and restart it.
- * Performs the following actions:
- *     1. A power reset (reset DMA)
- *     2. Initialize the radio modem (using wv_mmc_init)
- *     3. Reset & Configure LAN controller (using wv_82586_start)
- *     4. Start the LAN controller's command unit
- *     5. Start the LAN controller's receive unit
- * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
- */
-static int wv_hw_reset(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long ioaddr = dev->base_addr;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name,
-              (unsigned int) dev);
-#endif
-
-       /* Increase the number of resets done. */
-       lp->nresets++;
-
-       wv_hacr_reset(ioaddr);
-       lp->hacr = HACR_DEFAULT;
-
-       if ((wv_mmc_init(dev) < 0) || (wv_82586_start(dev) < 0))
-               return -1;
-
-       /* Enable the card to send interrupts. */
-       wv_ints_on(dev);
-
-       /* Start card functions */
-       if (wv_cu_start(dev) < 0)
-               return -1;
-
-       /* Setup the controller and parameters */
-       wv_82586_config(dev);
-
-       /* Finish configuration with the receive unit */
-       if (wv_ru_start(dev) < 0)
-               return -1;
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
-#endif
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Check if there is a WaveLAN at the specific base address.
- * As a side effect, this reads the MAC address.
- * (called in wavelan_probe() and init_module())
- */
-static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
-{
-       int i;                  /* Loop counter */
-
-       /* Check if the base address if available. */
-       if (!request_region(ioaddr, sizeof(ha_t), "wavelan probe"))
-               return -EBUSY;          /* ioaddr already used */
-
-       /* Reset host interface */
-       wv_hacr_reset(ioaddr);
-
-       /* Read the MAC address from the parameter storage area. */
-       psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_univ_mac_addr),
-                mac, 6);
-
-       release_region(ioaddr, sizeof(ha_t));
-
-       /*
-        * Check the first three octets of the address for the manufacturer's code.
-        * Note: if this can't find your WaveLAN card, you've got a
-        * non-NCR/AT&T/Lucent ISA card.  See wavelan.p.h for detail on
-        * how to configure your card.
-        */
-       for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
-               if ((mac[0] == MAC_ADDRESSES[i][0]) &&
-                   (mac[1] == MAC_ADDRESSES[i][1]) &&
-                   (mac[2] == MAC_ADDRESSES[i][2]))
-                       return 0;
-
-#ifdef DEBUG_CONFIG_INFO
-       printk(KERN_WARNING
-              "WaveLAN (0x%3X): your MAC address might be %02X:%02X:%02X.\n",
-              ioaddr, mac[0], mac[1], mac[2]);
-#endif
-       return -ENODEV;
-}
-
-/************************ INTERRUPT HANDLING ************************/
-
-/*
- * This function is the interrupt handler for the WaveLAN card. This
- * routine will be called whenever: 
- */
-static irqreturn_t wavelan_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev;
-       unsigned long ioaddr;
-       net_local *lp;
-       u16 hasr;
-       u16 status;
-       u16 ack_cmd;
-
-       dev = dev_id;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
-#endif
-
-       lp = netdev_priv(dev);
-       ioaddr = dev->base_addr;
-
-#ifdef DEBUG_INTERRUPT_INFO
-       /* Check state of our spinlock */
-       if(spin_is_locked(&lp->spinlock))
-               printk(KERN_DEBUG
-                      "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
-                      dev->name);
-#endif
-
-       /* Prevent reentrancy. We need to do that because we may have
-        * multiple interrupt handler running concurrently.
-        * It is safe because interrupts are disabled before acquiring
-        * the spinlock. */
-       spin_lock(&lp->spinlock);
-
-       /* We always had spurious interrupts at startup, but lately I
-        * saw them comming *between* the request_irq() and the
-        * spin_lock_irqsave() in wavelan_open(), so the spinlock
-        * protection is no enough.
-        * So, we also check lp->hacr that will tell us is we enabled
-        * irqs or not (see wv_ints_on()).
-        * We can't use netif_running(dev) because we depend on the
-        * proper processing of the irq generated during the config. */
-
-       /* Which interrupt it is ? */
-       hasr = hasr_read(ioaddr);
-
-#ifdef DEBUG_INTERRUPT_INFO
-       printk(KERN_INFO
-              "%s: wavelan_interrupt(): hasr 0x%04x; hacr 0x%04x.\n",
-              dev->name, hasr, lp->hacr);
-#endif
-
-       /* Check modem interrupt */
-       if ((hasr & HASR_MMC_INTR) && (lp->hacr & HACR_MMC_INT_ENABLE)) {
-               u8 dce_status;
-
-               /*
-                * Interrupt from the modem management controller.
-                * This will clear it -- ignored for now.
-                */
-               mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status,
-                        sizeof(dce_status));
-
-#ifdef DEBUG_INTERRUPT_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n",
-                      dev->name, dce_status);
-#endif
-       }
-
-       /* Check if not controller interrupt */
-       if (((hasr & HASR_82586_INTR) == 0) ||
-           ((lp->hacr & HACR_82586_INT_ENABLE) == 0)) {
-#ifdef DEBUG_INTERRUPT_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_interrupt(): interrupt not coming from i82586 - hasr 0x%04x.\n",
-                      dev->name, hasr);
-#endif
-               spin_unlock (&lp->spinlock);
-               return IRQ_NONE;
-       }
-
-       /* Read interrupt data. */
-       obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
-                  (unsigned char *) &status, sizeof(status));
-
-       /*
-        * Acknowledge the interrupt(s).
-        */
-       ack_cmd = status & SCB_ST_INT;
-       obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
-                   (unsigned char *) &ack_cmd, sizeof(ack_cmd));
-       set_chan_attn(ioaddr, lp->hacr);
-
-#ifdef DEBUG_INTERRUPT_INFO
-       printk(KERN_DEBUG "%s: wavelan_interrupt(): status 0x%04x.\n",
-              dev->name, status);
-#endif
-
-       /* Command completed. */
-       if ((status & SCB_ST_CX) == SCB_ST_CX) {
-#ifdef DEBUG_INTERRUPT_INFO
-               printk(KERN_DEBUG
-                      "%s: wavelan_interrupt(): command completed.\n",
-                      dev->name);
-#endif
-               wv_complete(dev, ioaddr, lp);
-       }
-
-       /* Frame received. */
-       if ((status & SCB_ST_FR) == SCB_ST_FR) {
-#ifdef DEBUG_INTERRUPT_INFO
-               printk(KERN_DEBUG
-                      "%s: wavelan_interrupt(): received packet.\n",
-                      dev->name);
-#endif
-               wv_receive(dev);
-       }
-
-       /* Check the state of the command unit. */
-       if (((status & SCB_ST_CNA) == SCB_ST_CNA) ||
-           (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) &&
-            (netif_running(dev)))) {
-#ifdef DEBUG_INTERRUPT_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_interrupt(): CU inactive -- restarting\n",
-                      dev->name);
-#endif
-               wv_hw_reset(dev);
-       }
-
-       /* Check the state of the command unit. */
-       if (((status & SCB_ST_RNR) == SCB_ST_RNR) ||
-           (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) &&
-            (netif_running(dev)))) {
-#ifdef DEBUG_INTERRUPT_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_interrupt(): RU not ready -- restarting\n",
-                      dev->name);
-#endif
-               wv_hw_reset(dev);
-       }
-
-       /* Release spinlock */
-       spin_unlock (&lp->spinlock);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
-#endif
-       return IRQ_HANDLED;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Watchdog: when we start a transmission, a timer is set for us in the
- * kernel.  If the transmission completes, this timer is disabled. If
- * the timer expires, we are called and we try to unlock the hardware.
- */
-static void wavelan_watchdog(struct net_device *       dev)
-{
-       net_local *lp = netdev_priv(dev);
-       u_long          ioaddr = dev->base_addr;
-       unsigned long   flags;
-       unsigned int    nreaped;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
-#endif
-
-#ifdef DEBUG_INTERRUPT_ERROR
-       printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
-              dev->name);
-#endif
-
-       /* Check that we came here for something */
-       if (lp->tx_n_in_use <= 0) {
-               return;
-       }
-
-       spin_lock_irqsave(&lp->spinlock, flags);
-
-       /* Try to see if some buffers are not free (in case we missed
-        * an interrupt */
-       nreaped = wv_complete(dev, ioaddr, lp);
-
-#ifdef DEBUG_INTERRUPT_INFO
-       printk(KERN_DEBUG
-              "%s: wavelan_watchdog(): %d reaped, %d remain.\n",
-              dev->name, nreaped, lp->tx_n_in_use);
-#endif
-
-#ifdef DEBUG_PSA_SHOW
-       {
-               psa_t psa;
-               psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-               wv_psa_show(&psa);
-       }
-#endif
-#ifdef DEBUG_MMC_SHOW
-       wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82586_SHOW
-       wv_cu_show(dev);
-#endif
-
-       /* If no buffer has been freed */
-       if (nreaped == 0) {
-#ifdef DEBUG_INTERRUPT_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_watchdog(): cleanup failed, trying reset\n",
-                      dev->name);
-#endif
-               wv_hw_reset(dev);
-       }
-
-       /* At this point, we should have some free Tx buffer ;-) */
-       if (lp->tx_n_in_use < NTXBLOCKS - 1)
-               netif_wake_queue(dev);
-
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-       
-#ifdef DEBUG_INTERRUPT_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
-#endif
-}
-
-/********************* CONFIGURATION CALLBACKS *********************/
-/*
- * Here are the functions called by the Linux networking code (NET3)
- * for initialization, configuration and deinstallations of the 
- * WaveLAN ISA hardware.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Configure and start up the WaveLAN PCMCIA adaptor.
- * Called by NET3 when it "opens" the device.
- */
-static int wavelan_open(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long   flags;
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
-              (unsigned int) dev);
-#endif
-
-       /* Check irq */
-       if (dev->irq == 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_WARNING "%s: wavelan_open(): no IRQ\n",
-                      dev->name);
-#endif
-               return -ENXIO;
-       }
-
-       if (request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", dev) != 0) 
-       {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_WARNING "%s: wavelan_open(): invalid IRQ\n",
-                      dev->name);
-#endif
-               return -EAGAIN;
-       }
-
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       if (wv_hw_reset(dev) != -1) {
-               netif_start_queue(dev);
-       } else {
-               free_irq(dev->irq, dev);
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_open(): impossible to start the card\n",
-                      dev->name);
-#endif
-               spin_unlock_irqrestore(&lp->spinlock, flags);
-               return -EAGAIN;
-       }
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-       
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
-#endif
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Shut down the WaveLAN ISA card.
- * Called by NET3 when it "closes" the device.
- */
-static int wavelan_close(struct net_device *dev)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
-              (unsigned int) dev);
-#endif
-
-       netif_stop_queue(dev);
-
-       /*
-        * Flush the Tx and disable Rx.
-        */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       wv_82586_stop(dev);
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       free_irq(dev->irq, dev);
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
-#endif
-       return 0;
-}
-
-static const struct net_device_ops wavelan_netdev_ops = {
-       .ndo_open               = wavelan_open,
-       .ndo_stop               = wavelan_close,
-       .ndo_start_xmit         = wavelan_packet_xmit,
-       .ndo_set_multicast_list = wavelan_set_multicast_list,
-        .ndo_tx_timeout                = wavelan_watchdog,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_validate_addr      = eth_validate_addr,
-#ifdef SET_MAC_ADDRESS
-       .ndo_set_mac_address    = wavelan_set_mac_address
-#else
-       .ndo_set_mac_address    = eth_mac_addr,
-#endif
-};
-
-
-/*------------------------------------------------------------------*/
-/*
- * Probe an I/O address, and if the WaveLAN is there configure the
- *device structure
- * (called by wavelan_probe() and via init_module()).
- */
-static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
-{
-       u8 irq_mask;
-       int irq;
-       net_local *lp;
-       mac_addr mac;
-       int err;
-
-       if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
-               return -EADDRINUSE;
-
-       err = wv_check_ioaddr(ioaddr, mac);
-       if (err)
-               goto out;
-
-       memcpy(dev->dev_addr, mac, 6);
-
-       dev->base_addr = ioaddr;
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
-              dev->name, (unsigned int) dev, ioaddr);
-#endif
-
-       /* Check IRQ argument on command line. */
-       if (dev->irq != 0) {
-               irq_mask = wv_irq_to_psa(dev->irq);
-
-               if (irq_mask == 0) {
-#ifdef DEBUG_CONFIG_ERROR
-                       printk(KERN_WARNING
-                              "%s: wavelan_config(): invalid IRQ %d ignored.\n",
-                              dev->name, dev->irq);
-#endif
-                       dev->irq = 0;
-               } else {
-#ifdef DEBUG_CONFIG_INFO
-                       printk(KERN_DEBUG
-                              "%s: wavelan_config(): changing IRQ to %d\n",
-                              dev->name, dev->irq);
-#endif
-                       psa_write(ioaddr, HACR_DEFAULT,
-                                 psaoff(0, psa_int_req_no), &irq_mask, 1);
-                       /* update the Wavelan checksum */
-                       update_psa_checksum(dev, ioaddr, HACR_DEFAULT);
-                       wv_hacr_reset(ioaddr);
-               }
-       }
-
-       psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_int_req_no),
-                &irq_mask, 1);
-       if ((irq = wv_psa_to_irq(irq_mask)) == -1) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_INFO
-                      "%s: wavelan_config(): could not wavelan_map_irq(%d).\n",
-                      dev->name, irq_mask);
-#endif
-               err = -EAGAIN;
-               goto out;
-       }
-
-       dev->irq = irq;
-
-       dev->mem_start = 0x0000;
-       dev->mem_end = 0x0000;
-       dev->if_port = 0;
-
-       /* Initialize device structures */
-       memset(netdev_priv(dev), 0, sizeof(net_local));
-       lp = netdev_priv(dev);
-
-       /*back link to the device structure. */
-       lp->dev = dev;
-       /* Add the device at the beginning of the linked list. */
-       lp->next = wavelan_list;
-       wavelan_list = lp;
-
-       lp->hacr = HACR_DEFAULT;
-
-       /* Multicast stuff */
-       lp->promiscuous = 0;
-       lp->mc_count = 0;
-
-       /* Init spinlock */
-       spin_lock_init(&lp->spinlock);
-
-       dev->netdev_ops = &wavelan_netdev_ops;
-       dev->watchdog_timeo = WATCHDOG_JIFFIES;
-       dev->wireless_handlers = &wavelan_handler_def;
-       lp->wireless_data.spy_data = &lp->spy_data;
-       dev->wireless_data = &lp->wireless_data;
-
-       dev->mtu = WAVELAN_MTU;
-
-       /* Display nice information. */
-       wv_init_info(dev);
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG "%s: <-wavelan_config()\n", dev->name);
-#endif
-       return 0;
-out:
-       release_region(ioaddr, sizeof(ha_t));
-       return err;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Check for a network adaptor of this type.  Return '0' iff one 
- * exists.  There seem to be different interpretations of
- * the initial value of dev->base_addr.
- * We follow the example in drivers/net/ne.c.
- * (called in "Space.c")
- */
-struct net_device * __init wavelan_probe(int unit)
-{
-       struct net_device *dev;
-       short base_addr;
-       int def_irq;
-       int i;
-       int r = 0;
-
-       /* compile-time check the sizes of structures */
-       BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
-       BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
-       BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
-       BUILD_BUG_ON(sizeof(ha_t) != HA_SIZE);
-
-       dev = alloc_etherdev(sizeof(net_local));
-       if (!dev)
-               return ERR_PTR(-ENOMEM);
-
-       sprintf(dev->name, "eth%d", unit);
-       netdev_boot_setup_check(dev);
-       base_addr = dev->base_addr;
-       def_irq = dev->irq;
-
-#ifdef DEBUG_CALLBACK_TRACE
-       printk(KERN_DEBUG
-              "%s: ->wavelan_probe(dev=%p (base_addr=0x%x))\n",
-              dev->name, dev, (unsigned int) dev->base_addr);
-#endif
-
-       /* Don't probe at all. */
-       if (base_addr < 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_WARNING
-                      "%s: wavelan_probe(): invalid base address\n",
-                      dev->name);
-#endif
-               r = -ENXIO;
-       } else if (base_addr > 0x100) { /* Check a single specified location. */
-               r = wavelan_config(dev, base_addr);
-#ifdef DEBUG_CONFIG_INFO
-               if (r != 0)
-                       printk(KERN_DEBUG
-                              "%s: wavelan_probe(): no device at specified base address (0x%X) or address already in use\n",
-                              dev->name, base_addr);
-#endif
-
-#ifdef DEBUG_CALLBACK_TRACE
-               printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
-#endif
-       } else { /* Scan all possible addresses of the WaveLAN hardware. */
-               for (i = 0; i < ARRAY_SIZE(iobase); i++) {
-                       dev->irq = def_irq;
-                       if (wavelan_config(dev, iobase[i]) == 0) {
-#ifdef DEBUG_CALLBACK_TRACE
-                               printk(KERN_DEBUG
-                                      "%s: <-wavelan_probe()\n",
-                                      dev->name);
-#endif
-                               break;
-                       }
-               }
-               if (i == ARRAY_SIZE(iobase))
-                       r = -ENODEV;
-       }
-       if (r) 
-               goto out;
-       r = register_netdev(dev);
-       if (r)
-               goto out1;
-       return dev;
-out1:
-       release_region(dev->base_addr, sizeof(ha_t));
-       wavelan_list = wavelan_list->next;
-out:
-       free_netdev(dev);
-       return ERR_PTR(r);
-}
-
-/****************************** MODULE ******************************/
-/*
- * Module entry point: insertion and removal
- */
-
-#ifdef MODULE
-/*------------------------------------------------------------------*/
-/*
- * Insertion of the module
- * I'm now quite proud of the multi-device support.
- */
-int __init init_module(void)
-{
-       int ret = -EIO;         /* Return error if no cards found */
-       int i;
-
-#ifdef DEBUG_MODULE_TRACE
-       printk(KERN_DEBUG "-> init_module()\n");
-#endif
-
-       /* If probing is asked */
-       if (io[0] == 0) {
-#ifdef DEBUG_CONFIG_ERROR
-               printk(KERN_WARNING
-                      "WaveLAN init_module(): doing device probing (bad !)\n");
-               printk(KERN_WARNING
-                      "Specify base addresses while loading module to correct the problem\n");
-#endif
-
-               /* Copy the basic set of address to be probed. */
-               for (i = 0; i < ARRAY_SIZE(iobase); i++)
-                       io[i] = iobase[i];
-       }
-
-
-       /* Loop on all possible base addresses. */
-       for (i = 0; i < ARRAY_SIZE(io) && io[i] != 0; i++) {
-               struct net_device *dev = alloc_etherdev(sizeof(net_local));
-               if (!dev)
-                       break;
-               if (name[i])
-                       strcpy(dev->name, name[i]);     /* Copy name */
-               dev->base_addr = io[i];
-               dev->irq = irq[i];
-
-               /* Check if there is something at this base address. */
-               if (wavelan_config(dev, io[i]) == 0) {
-                       if (register_netdev(dev) != 0) {
-                               release_region(dev->base_addr, sizeof(ha_t));
-                               wavelan_list = wavelan_list->next;
-                       } else {
-                               ret = 0;
-                               continue;
-                       }
-               }
-               free_netdev(dev);
-       }
-
-#ifdef DEBUG_CONFIG_ERROR
-       if (!wavelan_list)
-               printk(KERN_WARNING
-                      "WaveLAN init_module(): no device found\n");
-#endif
-
-#ifdef DEBUG_MODULE_TRACE
-       printk(KERN_DEBUG "<- init_module()\n");
-#endif
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Removal of the module
- */
-void cleanup_module(void)
-{
-#ifdef DEBUG_MODULE_TRACE
-       printk(KERN_DEBUG "-> cleanup_module()\n");
-#endif
-
-       /* Loop on all devices and release them. */
-       while (wavelan_list) {
-               struct net_device *dev = wavelan_list->dev;
-
-#ifdef DEBUG_CONFIG_INFO
-               printk(KERN_DEBUG
-                      "%s: cleanup_module(): removing device at 0x%x\n",
-                      dev->name, (unsigned int) dev);
-#endif
-               unregister_netdev(dev);
-
-               release_region(dev->base_addr, sizeof(ha_t));
-               wavelan_list = wavelan_list->next;
-
-               free_netdev(dev);
-       }
-
-#ifdef DEBUG_MODULE_TRACE
-       printk(KERN_DEBUG "<- cleanup_module()\n");
-#endif
-}
-#endif                         /* MODULE */
-MODULE_LICENSE("GPL");
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU General Public License.
- *
- * This software was developed as a component of the
- * Linux operating system.
- * It is based on other device drivers and information
- * either written or supplied by:
- *     Ajay Bakre (bakre@paul.rutgers.edu),
- *     Donald Becker (becker@scyld.com),
- *     Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com),
- *     Anders Klemets (klemets@it.kth.se),
- *     Vladimir V. Kolpakov (w@stier.koenig.ru),
- *     Marc Meertens (Marc.Meertens@Utrecht.NCR.com),
- *     Pauline Middelink (middelin@polyware.iaf.nl),
- *     Robert Morris (rtm@das.harvard.edu),
- *     Jean Tourrilhes (jt@hplb.hpl.hp.com),
- *     Girish Welling (welling@paul.rutgers.edu),
- *
- * Thanks go also to:
- *     James Ashton (jaa101@syseng.anu.edu.au),
- *     Alan Cox (alan@lxorguk.ukuu.org.uk),
- *     Allan Creighton (allanc@cs.usyd.edu.au),
- *     Matthew Geier (matthew@cs.usyd.edu.au),
- *     Remo di Giovanni (remo@cs.usyd.edu.au),
- *     Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
- *     Vipul Gupta (vgupta@cs.binghamton.edu),
- *     Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
- *     Tim Nicholson (tim@cs.usyd.edu.au),
- *     Ian Parkin (ian@cs.usyd.edu.au),
- *     John Rosenberg (johnr@cs.usyd.edu.au),
- *     George Rossi (george@phm.gov.au),
- *     Arthur Scott (arthur@cs.usyd.edu.au),
- *     Peter Storey,
- * for their assistance and advice.
- *
- * Please send bug reports, updates, comments to:
- *
- *bruce Janson                                    Email:  bruce@cs.usyd.edu.au
- *basser Department of Computer Science           Phone:  +61-2-9351-3423
- * University of Sydney, N.S.W., 2006, AUSTRALIA   Fax:    +61-2-9351-3838
- */
 
+++ /dev/null
-/*
- *     WaveLAN ISA driver
- *
- *             Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follows. See wavelan.p.h for details.
- *
- * This file contains the declarations for the WaveLAN hardware. Note that
- * the WaveLAN ISA includes a i82586 controller (see definitions in
- * file i82586.h).
- *
- * The main difference between the ISA hardware and the PCMCIA one is
- * the Ethernet controller (i82586 instead of i82593).
- * The i82586 allows multiple transmit buffers.  The PSA needs to be accessed
- * through the host interface.
- */
-
-#ifndef _WAVELAN_H
-#define        _WAVELAN_H
-
-/************************** MAGIC NUMBERS ***************************/
-
-/* Detection of the WaveLAN card is done by reading the MAC
- * address from the card and checking it.  If you have a non-AT&T
- * product (OEM, like DEC RoamAbout, Digital Ocean, or Epson),
- * you might need to modify this part to accommodate your hardware.
- */
-static const char      MAC_ADDRESSES[][3] = {
-  { 0x08, 0x00, 0x0E },                /* AT&T WaveLAN (standard) & DEC RoamAbout */
-  { 0x08, 0x00, 0x6A },                /* AT&T WaveLAN (alternate) */
-  { 0x00, 0x00, 0xE1 },                /* Hitachi Wavelan */
-  { 0x00, 0x60, 0x1D }         /* Lucent Wavelan (another one) */
-  /* Add your card here and send me the patch! */
-};
-
-#define WAVELAN_ADDR_SIZE      6       /* Size of a MAC address */
-
-#define WAVELAN_MTU            1500    /* Maximum size of WaveLAN packet */
-
-#define        MAXDATAZ                (WAVELAN_ADDR_SIZE + WAVELAN_ADDR_SIZE + 2 + WAVELAN_MTU)
-
-/*
- * Constants used to convert channels to frequencies
- */
-
-/* Frequency available in the 2.0 modem, in units of 250 kHz
- * (as read in the offset register of the dac area).
- * Used to map channel numbers used by `wfreqsel' to frequencies
- */
-static const short     channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
-                                   0xD0, 0xF0, 0xF8, 0x150 };
-
-/* Frequencies of the 1.0 modem (fixed frequencies).
- * Use to map the PSA `subband' to a frequency
- * Note : all frequencies apart from the first one need to be multiplied by 10
- */
-static const int       fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
-
-
-
-/*************************** PC INTERFACE ****************************/
-
-/*
- * Host Adaptor structure.
- * (base is board port address).
- */
-typedef union hacs_u   hacs_u;
-union hacs_u {
-       unsigned short  hu_command;             /* Command register */
-#define                HACR_RESET              0x0001  /* Reset board */
-#define                HACR_CA                 0x0002  /* Set Channel Attention for 82586 */
-#define                HACR_16BITS             0x0004  /* 16-bit operation (0 => 8bits) */
-#define                HACR_OUT0               0x0008  /* General purpose output pin 0 */
-                                               /* not used - must be 1 */
-#define                HACR_OUT1               0x0010  /* General purpose output pin 1 */
-                                               /* not used - must be 1 */
-#define                HACR_82586_INT_ENABLE   0x0020  /* Enable 82586 interrupts */
-#define                HACR_MMC_INT_ENABLE     0x0040  /* Enable MMC interrupts */
-#define                HACR_INTR_CLR_ENABLE    0x0080  /* Enable interrupt status read/clear */
-       unsigned short  hu_status;              /* Status Register */
-#define                HASR_82586_INTR         0x0001  /* Interrupt request from 82586 */
-#define                HASR_MMC_INTR           0x0002  /* Interrupt request from MMC */
-#define                HASR_MMC_BUSY           0x0004  /* MMC busy indication */
-#define                HASR_PSA_BUSY           0x0008  /* LAN parameter storage area busy */
-} __attribute__ ((packed));
-
-typedef struct ha_t    ha_t;
-struct ha_t {
-       hacs_u          ha_cs;          /* Command and status registers */
-#define                ha_command      ha_cs.hu_command
-#define                ha_status       ha_cs.hu_status
-       unsigned short  ha_mmcr;        /* Modem Management Ctrl Register */
-       unsigned short  ha_pior0;       /* Program I/O Address Register Port 0 */
-       unsigned short  ha_piop0;       /* Program I/O Port 0 */
-       unsigned short  ha_pior1;       /* Program I/O Address Register Port 1 */
-       unsigned short  ha_piop1;       /* Program I/O Port 1 */
-       unsigned short  ha_pior2;       /* Program I/O Address Register Port 2 */
-       unsigned short  ha_piop2;       /* Program I/O Port 2 */
-};
-
-#define HA_SIZE                16
-
-#define        hoff(p, f)      (unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0)
-#define        HACR(p)         hoff(p, ha_command)
-#define        HASR(p)         hoff(p, ha_status)
-#define        MMCR(p)         hoff(p, ha_mmcr)
-#define        PIOR0(p)        hoff(p, ha_pior0)
-#define        PIOP0(p)        hoff(p, ha_piop0)
-#define        PIOR1(p)        hoff(p, ha_pior1)
-#define        PIOP1(p)        hoff(p, ha_piop1)
-#define        PIOR2(p)        hoff(p, ha_pior2)
-#define        PIOP2(p)        hoff(p, ha_piop2)
-
-/*
- * Program I/O Mode Register values.
- */
-#define STATIC_PIO             0       /* Mode 1: static mode */
-                                       /* RAM access ??? */
-#define AUTOINCR_PIO           1       /* Mode 2: auto increment mode */
-                                       /* RAM access ??? */
-#define AUTODECR_PIO           2       /* Mode 3: auto decrement mode */
-                                       /* RAM access ??? */
-#define PARAM_ACCESS_PIO       3       /* Mode 4: LAN parameter access mode */
-                                       /* Parameter access. */
-#define PIO_MASK               3       /* register mask */
-#define PIOM(cmd, piono)               ((u_short)cmd << 10 << (piono * 2))
-
-#define        HACR_DEFAULT            (HACR_OUT0 | HACR_OUT1 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2))
-#define        HACR_INTRON             (HACR_82586_INT_ENABLE | HACR_MMC_INT_ENABLE | HACR_INTR_CLR_ENABLE)
-
-/************************** MEMORY LAYOUT **************************/
-
-/*
- * Onboard 64 k RAM layout.
- * (Offsets from 0x0000.)
- */
-#define OFFSET_RU              0x0000          /* 75% memory */
-#define OFFSET_CU              0xC000          /* 25% memory */
-#define OFFSET_SCB             (OFFSET_ISCP - sizeof(scb_t))
-#define OFFSET_ISCP            (OFFSET_SCP - sizeof(iscp_t))
-#define OFFSET_SCP             I82586_SCP_ADDR
-
-#define        RXBLOCKZ                (sizeof(fd_t) + sizeof(rbd_t) + MAXDATAZ)
-#define        TXBLOCKZ                (sizeof(ac_tx_t) + sizeof(ac_nop_t) + sizeof(tbd_t) + MAXDATAZ)
-
-#define        NRXBLOCKS               ((OFFSET_CU - OFFSET_RU) / RXBLOCKZ)
-#define        NTXBLOCKS               ((OFFSET_SCB - OFFSET_CU) / TXBLOCKZ)
-
-/********************** PARAMETER STORAGE AREA **********************/
-
-/*
- * Parameter Storage Area (PSA).
- */
-typedef struct psa_t   psa_t;
-struct psa_t {
-  unsigned char        psa_io_base_addr_1;     /* [0x00] Base address 1 ??? */
-  unsigned char        psa_io_base_addr_2;     /* [0x01] Base address 2 */
-  unsigned char        psa_io_base_addr_3;     /* [0x02] Base address 3 */
-  unsigned char        psa_io_base_addr_4;     /* [0x03] Base address 4 */
-  unsigned char        psa_rem_boot_addr_1;    /* [0x04] Remote Boot Address 1 */
-  unsigned char        psa_rem_boot_addr_2;    /* [0x05] Remote Boot Address 2 */
-  unsigned char        psa_rem_boot_addr_3;    /* [0x06] Remote Boot Address 3 */
-  unsigned char        psa_holi_params;        /* [0x07] HOst Lan Interface (HOLI) Parameters */
-  unsigned char        psa_int_req_no;         /* [0x08] Interrupt Request Line */
-  unsigned char        psa_unused0[7];         /* [0x09-0x0F] unused */
-
-  unsigned char        psa_univ_mac_addr[WAVELAN_ADDR_SIZE];   /* [0x10-0x15] Universal (factory) MAC Address */
-  unsigned char        psa_local_mac_addr[WAVELAN_ADDR_SIZE];  /* [0x16-1B] Local MAC Address */
-  unsigned char        psa_univ_local_sel;     /* [0x1C] Universal Local Selection */
-#define                PSA_UNIVERSAL   0               /* Universal (factory) */
-#define                PSA_LOCAL       1               /* Local */
-  unsigned char        psa_comp_number;        /* [0x1D] Compatibility Number:  */
-#define                PSA_COMP_PC_AT_915      0       /* PC-AT 915 MHz         */
-#define                PSA_COMP_PC_MC_915      1       /* PC-MC 915 MHz         */
-#define                PSA_COMP_PC_AT_2400     2       /* PC-AT 2.4 GHz         */
-#define                PSA_COMP_PC_MC_2400     3       /* PC-MC 2.4 GHz         */
-#define                PSA_COMP_PCMCIA_915     4       /* PCMCIA 915 MHz or 2.0 */
-  unsigned char        psa_thr_pre_set;        /* [0x1E] Modem Threshold Preset */
-  unsigned char        psa_feature_select;     /* [0x1F] Call code required (1=on) */
-#define                PSA_FEATURE_CALL_CODE   0x01    /* Call code required (Japan) */
-  unsigned char        psa_subband;            /* [0x20] Subband         */
-#define                PSA_SUBBAND_915         0       /* 915 MHz or 2.0 */
-#define                PSA_SUBBAND_2425        1       /* 2425 MHz       */
-#define                PSA_SUBBAND_2460        2       /* 2460 MHz       */
-#define                PSA_SUBBAND_2484        3       /* 2484 MHz       */
-#define                PSA_SUBBAND_2430_5      4       /* 2430.5 MHz     */
-  unsigned char        psa_quality_thr;        /* [0x21] Modem Quality Threshold */
-  unsigned char        psa_mod_delay;          /* [0x22] Modem Delay (?) (reserved) */
-  unsigned char        psa_nwid[2];            /* [0x23-0x24] Network ID */
-  unsigned char        psa_nwid_select;        /* [0x25] Network ID Select On/Off */
-  unsigned char        psa_encryption_select;  /* [0x26] Encryption On/Off */
-  unsigned char        psa_encryption_key[8];  /* [0x27-0x2E] Encryption Key */
-  unsigned char        psa_databus_width;      /* [0x2F] AT bus width select 8/16 */
-  unsigned char        psa_call_code[8];       /* [0x30-0x37] (Japan) Call Code */
-  unsigned char        psa_nwid_prefix[2];     /* [0x38-0x39] Roaming domain */
-  unsigned char        psa_reserved[2];        /* [0x3A-0x3B] Reserved - fixed 00 */
-  unsigned char        psa_conf_status;        /* [0x3C] Conf Status, bit 0=1:config*/
-  unsigned char        psa_crc[2];             /* [0x3D] CRC-16 over PSA */
-  unsigned char        psa_crc_status;         /* [0x3F] CRC Valid Flag */
-};
-
-#define        PSA_SIZE        64
-
-/* Calculate offset of a field in the above structure.
- * Warning:  only even addresses are used. */
-#define        psaoff(p, f)    ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL))
-
-/******************** MODEM MANAGEMENT INTERFACE ********************/
-
-/*
- * Modem Management Controller (MMC) write structure.
- */
-typedef struct mmw_t   mmw_t;
-struct mmw_t {
-  unsigned char        mmw_encr_key[8];        /* encryption key */
-  unsigned char        mmw_encr_enable;        /* Enable or disable encryption. */
-#define        MMW_ENCR_ENABLE_MODE    0x02    /* mode of security option */
-#define        MMW_ENCR_ENABLE_EN      0x01    /* Enable security option. */
-  unsigned char        mmw_unused0[1];         /* unused */
-  unsigned char        mmw_des_io_invert;      /* encryption option */
-#define        MMW_DES_IO_INVERT_RES   0x0F    /* reserved */
-#define        MMW_DES_IO_INVERT_CTRL  0xF0    /* control (?) (set to 0) */
-  unsigned char        mmw_unused1[5];         /* unused */
-  unsigned char        mmw_loopt_sel;          /* looptest selection */
-#define        MMW_LOOPT_SEL_DIS_NWID  0x40    /* Disable NWID filtering. */
-#define        MMW_LOOPT_SEL_INT       0x20    /* Activate Attention Request. */
-#define        MMW_LOOPT_SEL_LS        0x10    /* looptest, no collision avoidance */
-#define MMW_LOOPT_SEL_LT3A     0x08    /* looptest 3a */
-#define        MMW_LOOPT_SEL_LT3B      0x04    /* looptest 3b */
-#define        MMW_LOOPT_SEL_LT3C      0x02    /* looptest 3c */
-#define        MMW_LOOPT_SEL_LT3D      0x01    /* looptest 3d */
-  unsigned char        mmw_jabber_enable;      /* jabber timer enable */
-  /* Abort transmissions > 200 ms */
-  unsigned char        mmw_freeze;             /* freeze or unfreeze signal level */
-  /* 0 : signal level & qual updated for every new message, 1 : frozen */
-  unsigned char        mmw_anten_sel;          /* antenna selection */
-#define MMW_ANTEN_SEL_SEL      0x01    /* direct antenna selection */
-#define        MMW_ANTEN_SEL_ALG_EN    0x02    /* antenna selection algo. enable */
-  unsigned char        mmw_ifs;                /* inter frame spacing */
-  /* min time between transmission in bit periods (.5 us) - bit 0 ignored */
-  unsigned char        mmw_mod_delay;          /* modem delay (synchro) */
-  unsigned char        mmw_jam_time;           /* jamming time (after collision) */
-  unsigned char        mmw_unused2[1];         /* unused */
-  unsigned char        mmw_thr_pre_set;        /* level threshold preset */
-  /* Discard all packet with signal < this value (4) */
-  unsigned char        mmw_decay_prm;          /* decay parameters */
-  unsigned char        mmw_decay_updat_prm;    /* decay update parameters */
-  unsigned char        mmw_quality_thr;        /* quality (z-quotient) threshold */
-  /* Discard all packet with quality < this value (3) */
-  unsigned char        mmw_netw_id_l;          /* NWID low order byte */
-  unsigned char        mmw_netw_id_h;          /* NWID high order byte */
-  /* Network ID or Domain : create virtual net on the air */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char        mmw_mode_select;        /* for analog tests (set to 0) */
-  unsigned char        mmw_unused3[1];         /* unused */
-  unsigned char        mmw_fee_ctrl;           /* frequency EEPROM control */
-#define        MMW_FEE_CTRL_PRE        0x10    /* Enable protected instructions. */
-#define        MMW_FEE_CTRL_DWLD       0x08    /* Download EEPROM to mmc. */
-#define        MMW_FEE_CTRL_CMD        0x07    /* EEPROM commands:  */
-#define        MMW_FEE_CTRL_READ       0x06    /* Read */
-#define        MMW_FEE_CTRL_WREN       0x04    /* Write enable */
-#define        MMW_FEE_CTRL_WRITE      0x05    /* Write data to address. */
-#define        MMW_FEE_CTRL_WRALL      0x04    /* Write data to all addresses. */
-#define        MMW_FEE_CTRL_WDS        0x04    /* Write disable */
-#define        MMW_FEE_CTRL_PRREAD     0x16    /* Read addr from protect register */
-#define        MMW_FEE_CTRL_PREN       0x14    /* Protect register enable */
-#define        MMW_FEE_CTRL_PRCLEAR    0x17    /* Unprotect all registers. */
-#define        MMW_FEE_CTRL_PRWRITE    0x15    /* Write address in protect register */
-#define        MMW_FEE_CTRL_PRDS       0x14    /* Protect register disable */
-  /* Never issue the PRDS command:  it's irreversible! */
-
-  unsigned char        mmw_fee_addr;           /* EEPROM address */
-#define        MMW_FEE_ADDR_CHANNEL    0xF0    /* Select the channel. */
-#define        MMW_FEE_ADDR_OFFSET     0x0F    /* Offset in channel data */
-#define        MMW_FEE_ADDR_EN         0xC0    /* FEE_CTRL enable operations */
-#define        MMW_FEE_ADDR_DS         0x00    /* FEE_CTRL disable operations */
-#define        MMW_FEE_ADDR_ALL        0x40    /* FEE_CTRL all operations */
-#define        MMW_FEE_ADDR_CLEAR      0xFF    /* FEE_CTRL clear operations */
-
-  unsigned char        mmw_fee_data_l;         /* Write data to EEPROM. */
-  unsigned char        mmw_fee_data_h;         /* high octet */
-  unsigned char        mmw_ext_ant;            /* Setting for external antenna */
-#define        MMW_EXT_ANT_EXTANT      0x01    /* Select external antenna */
-#define        MMW_EXT_ANT_POL         0x02    /* Polarity of the antenna */
-#define        MMW_EXT_ANT_INTERNAL    0x00    /* Internal antenna */
-#define        MMW_EXT_ANT_EXTERNAL    0x03    /* External antenna */
-#define        MMW_EXT_ANT_IQ_TEST     0x1C    /* IQ test pattern (set to 0) */
-} __attribute__ ((packed));
-
-#define        MMW_SIZE        37
-
-#define        mmwoff(p, f)    (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * Modem Management Controller (MMC) read structure.
- */
-typedef struct mmr_t   mmr_t;
-struct mmr_t {
-  unsigned char        mmr_unused0[8];         /* unused */
-  unsigned char        mmr_des_status;         /* encryption status */
-  unsigned char        mmr_des_avail;          /* encryption available (0x55 read) */
-#define        MMR_DES_AVAIL_DES       0x55            /* DES available */
-#define        MMR_DES_AVAIL_AES       0x33            /* AES (AT&T) available */
-  unsigned char        mmr_des_io_invert;      /* des I/O invert register */
-  unsigned char        mmr_unused1[5];         /* unused */
-  unsigned char        mmr_dce_status;         /* DCE status */
-#define        MMR_DCE_STATUS_RX_BUSY          0x01    /* receiver busy */
-#define        MMR_DCE_STATUS_LOOPT_IND        0x02    /* loop test indicated */
-#define        MMR_DCE_STATUS_TX_BUSY          0x04    /* transmitter on */
-#define        MMR_DCE_STATUS_JBR_EXPIRED      0x08    /* jabber timer expired */
-#define MMR_DCE_STATUS                 0x0F    /* mask to get the bits */
-  unsigned char        mmr_dsp_id;             /* DSP ID (AA = Daedalus rev A) */
-  unsigned char        mmr_unused2[2];         /* unused */
-  unsigned char        mmr_correct_nwid_l;     /* # of correct NWIDs rxd (low) */
-  unsigned char        mmr_correct_nwid_h;     /* # of correct NWIDs rxd (high) */
-  /* Warning:  read high-order octet first! */
-  unsigned char        mmr_wrong_nwid_l;       /* # of wrong NWIDs rxd (low) */
-  unsigned char        mmr_wrong_nwid_h;       /* # of wrong NWIDs rxd (high) */
-  unsigned char        mmr_thr_pre_set;        /* level threshold preset */
-#define        MMR_THR_PRE_SET         0x3F            /* level threshold preset */
-#define        MMR_THR_PRE_SET_CUR     0x80            /* Current signal above it */
-  unsigned char        mmr_signal_lvl;         /* signal level */
-#define        MMR_SIGNAL_LVL          0x3F            /* signal level */
-#define        MMR_SIGNAL_LVL_VALID    0x80            /* Updated since last read */
-  unsigned char        mmr_silence_lvl;        /* silence level (noise) */
-#define        MMR_SILENCE_LVL         0x3F            /* silence level */
-#define        MMR_SILENCE_LVL_VALID   0x80            /* Updated since last read */
-  unsigned char        mmr_sgnl_qual;          /* signal quality */
-#define        MMR_SGNL_QUAL           0x0F            /* signal quality */
-#define        MMR_SGNL_QUAL_ANT       0x80            /* current antenna used */
-  unsigned char        mmr_netw_id_l;          /* NWID low order byte (?) */
-  unsigned char        mmr_unused3[3];         /* unused */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char        mmr_fee_status;         /* Status of frequency EEPROM */
-#define        MMR_FEE_STATUS_ID       0xF0            /* Modem revision ID */
-#define        MMR_FEE_STATUS_DWLD     0x08            /* Download in progress */
-#define        MMR_FEE_STATUS_BUSY     0x04            /* EEPROM busy */
-  unsigned char        mmr_unused4[1];         /* unused */
-  unsigned char        mmr_fee_data_l;         /* Read data from EEPROM (low) */
-  unsigned char        mmr_fee_data_h;         /* Read data from EEPROM (high) */
-} __attribute__ ((packed));
-
-#define        MMR_SIZE        36
-
-#define        mmroff(p, f)    (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
-
-/* Make the two above structures one */
-typedef union mm_t {
-  struct mmw_t w;      /* Write to the mmc */
-  struct mmr_t r;      /* Read from the mmc */
-} mm_t;
-
-#endif /* _WAVELAN_H */
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU General Public License.
- *
- * For more details, see wavelan.c.
- */
 
+++ /dev/null
-/*
- *     WaveLAN ISA driver
- *
- *             Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- *
- * This file contains all definitions and declarations necessary for the
- * WaveLAN ISA driver.  This file is a private header, so it should
- * be included only in wavelan.c!
- */
-
-#ifndef WAVELAN_P_H
-#define WAVELAN_P_H
-
-/************************** DOCUMENTATION ***************************/
-/*
- * This driver provides a Linux interface to the WaveLAN ISA hardware.
- * The WaveLAN is a product of Lucent (http://www.wavelan.com/).
- * This division was formerly part of NCR and then AT&T.
- * WaveLANs are also distributed by DEC (RoamAbout DS) and Digital Ocean.
- *
- * To learn how to use this driver, read the NET3 HOWTO.
- * If you want to exploit the many other functionalities, read the comments
- * in the code.
- *
- * This driver is the result of the effort of many people (see below).
- */
-
-/* ------------------------ SPECIFIC NOTES ------------------------ */
-/*
- * Web page
- * --------
- *     I try to maintain a web page with the Wireless LAN Howto at :
- *         http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
- *
- * SMP
- * ---
- *     We now are SMP compliant (I eventually fixed the remaining bugs).
- *     The driver has been tested on a dual P6-150 and survived my usual
- *     set of torture tests.
- *     Anyway, I spent enough time chasing interrupt re-entrancy during
- *     errors or reconfigure, and I designed the locked/unlocked sections
- *     of the driver with great care, and with the recent addition of
- *     the spinlock (thanks to the new API), we should be quite close to
- *     the truth.
- *     The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
- *     but better safe than sorry (especially at 2 Mb/s ;-).
- *
- *     I have also looked into disabling only our interrupt on the card
- *     (via HACR) instead of all interrupts in the processor (via cli),
- *     so that other driver are not impacted, and it look like it's
- *     possible, but it's very tricky to do right (full of races). As
- *     the gain would be mostly for SMP systems, it can wait...
- *
- * Debugging and options
- * ---------------------
- *     You will find below a set of '#define" allowing a very fine control
- *     on the driver behaviour and the debug messages printed.
- *     The main options are :
- *     o SET_PSA_CRC, to have your card correctly recognised by
- *       an access point and the Point-to-Point diagnostic tool.
- *     o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
- *       (otherwise we always start afresh with some defaults)
- *
- * wavelan.o is too darned big
- * ---------------------------
- *     That's true!  There is a very simple way to reduce the driver
- *     object by 33%!  Comment out the following line:
- *             #include <linux/wireless.h>
- *     Other compile options can also reduce the size of it...
- *
- * MAC address and hardware detection:
- * -----------------------------------
- *     The detection code for the WaveLAN checks that the first three
- *     octets of the MAC address fit the company code.  This type of
- *     detection works well for AT&T cards (because the AT&T code is
- *     hardcoded in wavelan.h), but of course will fail for other
- *     manufacturers.
- *
- *     If you are sure that your card is derived from the WaveLAN,
- *     here is the way to configure it:
- *     1) Get your MAC address
- *             a) With your card utilities (wfreqsel, instconf, etc.)
- *             b) With the driver:
- *                     o compile the kernel with DEBUG_CONFIG_INFO enabled
- *                     o Boot and look the card messages
- *     2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan.h)
- *     3) Compile and verify
- *     4) Send me the MAC code.  I will include it in the next version.
- *
- */
-
-/* --------------------- WIRELESS EXTENSIONS --------------------- */
-/*
- * This driver is the first to support "wireless extensions".
- * This set of extensions provides a standard way to control the wireless
- * characteristics of the hardware.  Applications such as mobile IP may
- * take advantage of it.
- *
- * It might be a good idea as well to fetch the wireless tools to
- * configure the device and play a bit.
- */
-
-/* ---------------------------- FILES ---------------------------- */
-/*
- * wavelan.c:          actual code for the driver:  C functions
- *
- * wavelan.p.h:                private header:  local types and variables for driver
- *
- * wavelan.h:          description of the hardware interface and structs
- *
- * i82586.h:           description of the Ethernet controller
- */
-
-/* --------------------------- HISTORY --------------------------- */
-/*
- * This is based on information in the drivers' headers. It may not be
- * accurate, and I guarantee only my best effort.
- *
- * The history of the WaveLAN drivers is as complicated as the history of
- * the WaveLAN itself (NCR -> AT&T -> Lucent).
- *
- * It all started with Anders Klemets <klemets@paul.rutgers.edu>
- * writing a WaveLAN ISA driver for the Mach microkernel.  Girish
- * Welling <welling@paul.rutgers.edu> had also worked on it.
- * Keith Moore modified this for the PCMCIA hardware.
- *
- * Robert Morris <rtm@das.harvard.edu> ported these two drivers to BSDI
- * and added specific PCMCIA support (there is currently no equivalent
- * of the PCMCIA package under BSD).
- *
- * Jim Binkley <jrb@cs.pdx.edu> ported both BSDI drivers to FreeBSD.
- *
- * Bruce Janson <bruce@cs.usyd.edu.au> ported the BSDI ISA driver to Linux.
- *
- * Anthony D. Joseph <adj@lcs.mit.edu> started to modify Bruce's driver
- * (with help of the BSDI PCMCIA driver) for PCMCIA.
- * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished this work.
- * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
- * 2.00 cards correctly (2.4 GHz with frequency selection).
- * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
- * PCMCIA package (and bug corrections).
- *
- * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
- * patches to the PCMCIA driver.  Later, I added code in the ISA driver
- * for Wireless Extensions and full support of frequency selection
- * cards.  Then, I did the same to the PCMCIA driver, and did some
- * reorganisation.  Finally, I came back to the ISA driver to
- * upgrade it at the same level as the PCMCIA one and reorganise
- * the code.
- * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
- * much needed information on the WaveLAN hardware.
- */
-
-/* The original copyrights and literature mention others' names and
- * credits.  I don't know what their part in this development was.
- */
-
-/* By the way, for the copyright and legal stuff:
- * almost everybody wrote code under the GNU or BSD license (or similar),
- * and want their original copyright to remain somewhere in the
- * code (for myself, I go with the GPL).
- * Nobody wants to take responsibility for anything, except the fame.
- */
-
-/* --------------------------- CREDITS --------------------------- */
-/*
- * This software was developed as a component of the
- * Linux operating system.
- * It is based on other device drivers and information
- * either written or supplied by:
- *     Ajay Bakre <bakre@paul.rutgers.edu>,
- *     Donald Becker <becker@cesdis.gsfc.nasa.gov>,
- *     Loeke Brederveld <Loeke.Brederveld@Utrecht.NCR.com>,
- *     Brent Elphick <belphick@uwaterloo.ca>,
- *     Anders Klemets <klemets@it.kth.se>,
- *     Vladimir V. Kolpakov <w@stier.koenig.ru>,
- *     Marc Meertens <Marc.Meertens@Utrecht.NCR.com>,
- *     Pauline Middelink <middelin@polyware.iaf.nl>,
- *     Robert Morris <rtm@das.harvard.edu>,
- *     Jean Tourrilhes <jt@hpl.hp.com>,
- *     Girish Welling <welling@paul.rutgers.edu>,
- *     Clark Woodworth <clark@hiway1.exit109.com>
- *     Yongguang Zhang <ygz@isl.hrl.hac.com>
- *
- * Thanks go also to:
- *     James Ashton <jaa101@syseng.anu.edu.au>,
- *     Alan Cox <alan@lxorguk.ukuu.org.uk>,
- *     Allan Creighton <allanc@cs.usyd.edu.au>,
- *     Matthew Geier <matthew@cs.usyd.edu.au>,
- *     Remo di Giovanni <remo@cs.usyd.edu.au>,
- *     Eckhard Grah <grah@wrcs1.urz.uni-wuppertal.de>,
- *     Vipul Gupta <vgupta@cs.binghamton.edu>,
- *     Mark Hagan <mhagan@wtcpost.daytonoh.NCR.COM>,
- *     Tim Nicholson <tim@cs.usyd.edu.au>,
- *     Ian Parkin <ian@cs.usyd.edu.au>,
- *     John Rosenberg <johnr@cs.usyd.edu.au>,
- *     George Rossi <george@phm.gov.au>,
- *     Arthur Scott <arthur@cs.usyd.edu.au>,
- *     Stanislav Sinyagin <stas@isf.ru>
- *     and Peter Storey for their assistance and advice.
- *
- * Additional Credits:
- *
- *     My development has been done initially under Debian 1.1 (Linux 2.0.x)
- *     and now under Debian 2.2, initially with an HP Vectra XP/60, and now
- *     an HP Vectra XP/90.
- *
- */
-
-/* ------------------------- IMPROVEMENTS ------------------------- */
-/*
- * I proudly present:
- *
- * Changes made in first pre-release:
- * ----------------------------------
- *     - reorganisation of the code, function name change
- *     - creation of private header (wavelan.p.h)
- *     - reorganised debug messages
- *     - more comments, history, etc.
- *     - mmc_init:  configure the PSA if not done
- *     - mmc_init:  correct default value of level threshold for PCMCIA
- *     - mmc_init:  2.00 detection better code for 2.00 initialization
- *     - better info at startup
- *     - IRQ setting (note:  this setting is permanent)
- *     - watchdog:  change strategy (and solve module removal problems)
- *     - add wireless extensions (ioctl and get_wireless_stats)
- *       get/set nwid/frequency on fly, info for /proc/net/wireless
- *     - more wireless extensions:  SETSPY and GETSPY
- *     - make wireless extensions optional
- *     - private ioctl to set/get quality and level threshold, histogram
- *     - remove /proc/net/wavelan
- *     - suppress useless stuff from lp (net_local)
- *     - kernel 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
- *     - add message level (debug stuff in /var/adm/debug and errors not
- *       displayed at console and still in /var/adm/messages)
- *     - multi device support
- *     - start fixing the probe (init code)
- *     - more inlines
- *     - man page
- *     - many other minor details and cleanups
- *
- * Changes made in second pre-release:
- * -----------------------------------
- *     - clean up init code (probe and module init)
- *     - better multiple device support (module)
- *     - name assignment (module)
- *
- * Changes made in third pre-release:
- * ----------------------------------
- *     - be more conservative on timers
- *     - preliminary support for multicast (I still lack some details)
- *
- * Changes made in fourth pre-release:
- * -----------------------------------
- *     - multicast (revisited and finished)
- *     - avoid reset in set_multicast_list (a really big hack)
- *       if somebody could apply this code for other i82586 based drivers
- *     - share onboard memory 75% RU and 25% CU (instead of 50/50)
- *
- * Changes made for release in 2.1.15:
- * -----------------------------------
- *     - change the detection code for multi manufacturer code support
- *
- * Changes made for release in 2.1.17:
- * -----------------------------------
- *     - update to wireless extensions changes
- *     - silly bug in card initial configuration (psa_conf_status)
- *
- * Changes made for release in 2.1.27 & 2.0.30:
- * --------------------------------------------
- *     - small bug in debug code (probably not the last one...)
- *     - remove extern keyword for wavelan_probe()
- *     - level threshold is now a standard wireless extension (version 4 !)
- *     - modules parameters types (new module interface)
- *
- * Changes made for release in 2.1.36:
- * -----------------------------------
- *     - byte count stats (courtesy of David Hinds)
- *     - remove dev_tint stuff (courtesy of David Hinds)
- *     - encryption setting from Brent Elphick (thanks a lot!)
- *     - 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
- *
- * Other changes (not by me) :
- * -------------------------
- *     - Spelling and gramar "rectification".
- *
- * Changes made for release in 2.0.37 & 2.2.2 :
- * ------------------------------------------
- *     - Correct status in /proc/net/wireless
- *     - Set PSA CRC to make PtP diagnostic tool happy (Bob Gray)
- *     - Module init code don't fail if we found at least one card in
- *       the address list (Karlis Peisenieks)
- *     - Missing parenthesis (Christopher Peterson)
- *     - Correct i82586 configuration parameters
- *     - Encryption initialisation bug (Robert McCormack)
- *     - New mac addresses detected in the probe
- *     - Increase watchdog for busy environments
- *
- * Changes made for release in 2.0.38 & 2.2.7 :
- * ------------------------------------------
- *     - Correct the reception logic to better report errors and avoid
- *       sending bogus packet up the stack
- *     - Delay RU config to avoid corrupting first received packet
- *     - Change config completion code (to actually check something)
- *     - Avoid reading out of bound in skbuf to transmit
- *     - Rectify a lot of (useless) debugging code
- *     - Change the way to `#ifdef SET_PSA_CRC'
- *
- * Changes made for release in 2.2.11 & 2.3.13 :
- * -------------------------------------------
- *     - Change e-mail and web page addresses
- *     - Watchdog timer is now correctly expressed in HZ, not in jiffies
- *     - Add channel number to the list of frequencies in range
- *     - Add the (short) list of bit-rates in range
- *     - Developp a new sensitivity... (sens.value & sens.fixed)
- *
- * Changes made for release in 2.2.14 & 2.3.23 :
- * -------------------------------------------
- *     - Fix check for root permission (break instead of exit)
- *     - New nwid & encoding setting (Wireless Extension 9)
- *
- * Changes made for release in 2.3.49 :
- * ----------------------------------
- *     - Indentation reformating (Alan)
- *     - Update to new network API (softnet - 2.3.43) :
- *             o replace dev->tbusy (Alan)
- *             o replace dev->tstart (Alan)
- *             o remove dev->interrupt (Alan)
- *             o add SMP locking via spinlock in splxx (me)
- *             o add spinlock in interrupt handler (me)
- *             o use kernel watchdog instead of ours (me)
- *             o increase watchdog timeout (kernel is more sensitive) (me)
- *             o verify that all the changes make sense and work (me)
- *     - Fixup a potential gotcha when reconfiguring and thighten a bit
- *             the interactions with Tx queue.
- *
- * Changes made for release in 2.4.0 :
- * ---------------------------------
- *     - Fix spinlock stupid bugs that I left in. The driver is now SMP
- *             compliant and doesn't lockup at startup.
- *
- * Changes made for release in 2.5.2 :
- * ---------------------------------
- *     - Use new driver API for Wireless Extensions :
- *             o got rid of wavelan_ioctl()
- *             o use a bunch of iw_handler instead
- *
- * Changes made for release in 2.5.35 :
- * ----------------------------------
- *     - Set dev->trans_start to avoid filling the logs
- *     - Handle better spurious/bogus interrupt
- *     - Avoid deadlocks in mmc_out()/mmc_in()
- *
- * Wishes & dreams:
- * ----------------
- *     - roaming (see Pcmcia driver)
- */
-
-/***************************** INCLUDES *****************************/
-
-#include       <linux/module.h>
-
-#include       <linux/kernel.h>
-#include       <linux/sched.h>
-#include       <linux/types.h>
-#include       <linux/fcntl.h>
-#include       <linux/interrupt.h>
-#include       <linux/stat.h>
-#include       <linux/ptrace.h>
-#include       <linux/ioport.h>
-#include       <linux/in.h>
-#include       <linux/string.h>
-#include       <linux/delay.h>
-#include       <linux/bitops.h>
-#include       <asm/system.h>
-#include       <asm/io.h>
-#include       <asm/dma.h>
-#include       <asm/uaccess.h>
-#include       <linux/errno.h>
-#include       <linux/netdevice.h>
-#include       <linux/etherdevice.h>
-#include       <linux/skbuff.h>
-#include       <linux/slab.h>
-#include       <linux/timer.h>
-#include       <linux/init.h>
-
-#include <linux/wireless.h>            /* Wireless extensions */
-#include <net/iw_handler.h>            /* Wireless handlers */
-
-/* WaveLAN declarations */
-#include       "i82586.h"
-#include       "wavelan.h"
-
-/************************** DRIVER OPTIONS **************************/
-/*
- * `#define' or `#undef' the following constant to change the behaviour
- * of the driver...
- */
-#undef SET_PSA_CRC             /* Calculate and set the CRC on PSA (slower) */
-#define USE_PSA_CONFIG         /* Use info from the PSA. */
-#undef EEPROM_IS_PROTECTED     /* doesn't seem to be necessary */
-#define MULTICAST_AVOID                /* Avoid extra multicast (I'm sceptical). */
-#undef SET_MAC_ADDRESS         /* Experimental */
-
-/* Warning:  this stuff will slow down the driver. */
-#define WIRELESS_SPY           /* Enable spying addresses. */
-#undef HISTOGRAM               /* Enable histogram of signal level. */
-
-/****************************** DEBUG ******************************/
-
-#undef DEBUG_MODULE_TRACE      /* module insertion/removal */
-#undef DEBUG_CALLBACK_TRACE    /* calls made by Linux */
-#undef DEBUG_INTERRUPT_TRACE   /* calls to handler */
-#undef DEBUG_INTERRUPT_INFO    /* type of interrupt and so on */
-#define DEBUG_INTERRUPT_ERROR  /* problems */
-#undef DEBUG_CONFIG_TRACE      /* Trace the config functions. */
-#undef DEBUG_CONFIG_INFO       /* what's going on */
-#define DEBUG_CONFIG_ERROR     /* errors on configuration */
-#undef DEBUG_TX_TRACE          /* transmission calls */
-#undef DEBUG_TX_INFO           /* header of the transmitted packet */
-#undef DEBUG_TX_FAIL           /* Normal failure conditions */
-#define DEBUG_TX_ERROR         /* Unexpected conditions */
-#undef DEBUG_RX_TRACE          /* transmission calls */
-#undef DEBUG_RX_INFO           /* header of the received packet */
-#undef DEBUG_RX_FAIL           /* Normal failure conditions */
-#define DEBUG_RX_ERROR         /* Unexpected conditions */
-
-#undef DEBUG_PACKET_DUMP       /* Dump packet on the screen if defined to 32. */
-#undef DEBUG_IOCTL_TRACE       /* misc. call by Linux */
-#undef DEBUG_IOCTL_INFO                /* various debugging info */
-#define DEBUG_IOCTL_ERROR      /* what's going wrong */
-#define DEBUG_BASIC_SHOW       /* Show basic startup info. */
-#undef DEBUG_VERSION_SHOW      /* Print version info. */
-#undef DEBUG_PSA_SHOW          /* Dump PSA to screen. */
-#undef DEBUG_MMC_SHOW          /* Dump mmc to screen. */
-#undef DEBUG_SHOW_UNUSED       /* Show unused fields too. */
-#undef DEBUG_I82586_SHOW       /* Show i82586 status. */
-#undef DEBUG_DEVICE_SHOW       /* Show device parameters. */
-
-/************************ CONSTANTS & MACROS ************************/
-
-#ifdef DEBUG_VERSION_SHOW
-static const char      *version        = "wavelan.c : v24 (SMP + wireless extensions) 11/12/01\n";
-#endif
-
-/* Watchdog temporisation */
-#define        WATCHDOG_JIFFIES        (512*HZ/100)
-
-/* ------------------------ PRIVATE IOCTL ------------------------ */
-
-#define SIOCSIPQTHR    SIOCIWFIRSTPRIV         /* Set quality threshold */
-#define SIOCGIPQTHR    (SIOCIWFIRSTPRIV + 1)   /* Get quality threshold */
-
-#define SIOCSIPHISTO   (SIOCIWFIRSTPRIV + 2)   /* Set histogram ranges */
-#define SIOCGIPHISTO   (SIOCIWFIRSTPRIV + 3)   /* Get histogram values */
-
-/****************************** TYPES ******************************/
-
-/* Shortcuts */
-typedef struct iw_statistics   iw_stats;
-typedef struct iw_quality      iw_qual;
-typedef struct iw_freq         iw_freq;
-typedef struct net_local       net_local;
-typedef struct timer_list      timer_list;
-
-/* Basic types */
-typedef u_char         mac_addr[WAVELAN_ADDR_SIZE];    /* Hardware address */
-
-/*
- * Static specific data for the interface.
- *
- * For each network interface, Linux keeps data in two structures:  "device"
- * keeps the generic data (same format for everybody) and "net_local" keeps
- * additional specific data.
- */
-struct net_local {
-  net_local *next;             /* linked list of the devices */
-  struct net_device *dev;              /* reverse link */
-  spinlock_t   spinlock;       /* Serialize access to the hardware (SMP) */
-  int          nresets;        /* number of hardware resets */
-  u_char       reconfig_82586; /* We need to reconfigure the controller. */
-  u_char       promiscuous;    /* promiscuous mode */
-  int          mc_count;       /* number of multicast addresses */
-  u_short      hacr;           /* current host interface state */
-
-  int          tx_n_in_use;
-  u_short      rx_head;
-  u_short      rx_last;
-  u_short      tx_first_free;
-  u_short      tx_first_in_use;
-
-  iw_stats     wstats;         /* Wireless-specific statistics */
-
-  struct iw_spy_data   spy_data;
-  struct iw_public_data        wireless_data;
-
-#ifdef HISTOGRAM
-  int          his_number;             /* number of intervals */
-  u_char       his_range[16];          /* boundaries of interval ]n-1; n] */
-  u_long       his_sum[16];            /* sum in interval */
-#endif /* HISTOGRAM */
-};
-
-/**************************** PROTOTYPES ****************************/
-
-/* ----------------------- MISC. SUBROUTINES ------------------------ */
-static u_char
-       wv_irq_to_psa(int);
-static int
-       wv_psa_to_irq(u_char);
-/* ------------------- HOST ADAPTER SUBROUTINES ------------------- */
-static inline u_short          /* data */
-       hasr_read(u_long);      /* Read the host interface:  base address */
-static inline void
-       hacr_write(u_long,      /* Write to host interface:  base address */
-                  u_short),    /* data */
-       hacr_write_slow(u_long,
-                  u_short),
-       set_chan_attn(u_long,   /* ioaddr */
-                     u_short), /* hacr   */
-       wv_hacr_reset(u_long),  /* ioaddr */
-       wv_16_off(u_long,       /* ioaddr */
-                 u_short),     /* hacr   */
-       wv_16_on(u_long,        /* ioaddr */
-                u_short),      /* hacr   */
-       wv_ints_off(struct net_device *),
-       wv_ints_on(struct net_device *);
-/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
-static void
-       psa_read(u_long,        /* Read the Parameter Storage Area. */
-                u_short,       /* hacr */
-                int,           /* offset in PSA */
-                u_char *,      /* buffer to fill */
-                int),          /* size to read */
-       psa_write(u_long,       /* Write to the PSA. */
-                 u_short,      /* hacr */
-                 int,          /* offset in PSA */
-                 u_char *,     /* buffer in memory */
-                 int);         /* length of buffer */
-static inline void
-       mmc_out(u_long,         /* Write 1 byte to the Modem Manag Control. */
-               u_short,
-               u_char),
-       mmc_write(u_long,       /* Write n bytes to the MMC. */
-                 u_char,
-                 u_char *,
-                 int);
-static inline u_char           /* Read 1 byte from the MMC. */
-       mmc_in(u_long,
-              u_short);
-static inline void
-       mmc_read(u_long,        /* Read n bytes from the MMC. */
-                u_char,
-                u_char *,
-                int),
-       fee_wait(u_long,        /* Wait for frequency EEPROM:  base address */
-                int,           /* base delay to wait for */
-                int);          /* time to wait */
-static void
-       fee_read(u_long,        /* Read the frequency EEPROM:  base address */
-                u_short,       /* destination offset */
-                u_short *,     /* data buffer */
-                int);          /* number of registers */
-/* ---------------------- I82586 SUBROUTINES ----------------------- */
-static /*inline*/ void
-       obram_read(u_long,      /* ioaddr */
-                  u_short,     /* o */
-                  u_char *,    /* b */
-                  int);        /* n */
-static inline void
-       obram_write(u_long,     /* ioaddr */
-                   u_short,    /* o */
-                   u_char *,   /* b */
-                   int);       /* n */
-static void
-       wv_ack(struct net_device *);
-static inline int
-       wv_synchronous_cmd(struct net_device *,
-                          const char *),
-       wv_config_complete(struct net_device *,
-                          u_long,
-                          net_local *);
-static int
-       wv_complete(struct net_device *,
-                   u_long,
-                   net_local *);
-static inline void
-       wv_82586_reconfig(struct net_device *);
-/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
-#ifdef DEBUG_I82586_SHOW
-static void
-       wv_scb_show(unsigned short);
-#endif
-static inline void
-       wv_init_info(struct net_device *);      /* display startup info */
-/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static iw_stats *
-       wavelan_get_wireless_stats(struct net_device *);
-static void
-       wavelan_set_multicast_list(struct net_device *);
-/* ----------------------- PACKET RECEPTION ----------------------- */
-static inline void
-       wv_packet_read(struct net_device *,     /* Read a packet from a frame. */
-                      u_short,
-                      int),
-       wv_receive(struct net_device *);        /* Read all packets waiting. */
-/* --------------------- PACKET TRANSMISSION --------------------- */
-static inline int
-       wv_packet_write(struct net_device *,    /* Write a packet to the Tx buffer. */
-                       void *,
-                       short);
-static netdev_tx_t
-       wavelan_packet_xmit(struct sk_buff *,   /* Send a packet. */
-                           struct net_device *);
-/* -------------------- HARDWARE CONFIGURATION -------------------- */
-static inline int
-       wv_mmc_init(struct net_device *),       /* Initialize the modem. */
-       wv_ru_start(struct net_device *),       /* Start the i82586 receiver unit. */
-       wv_cu_start(struct net_device *),       /* Start the i82586 command unit. */
-       wv_82586_start(struct net_device *);    /* Start the i82586. */
-static void
-       wv_82586_config(struct net_device *);   /* Configure the i82586. */
-static inline void
-       wv_82586_stop(struct net_device *);
-static int
-       wv_hw_reset(struct net_device *),       /* Reset the WaveLAN hardware. */
-       wv_check_ioaddr(u_long,         /* ioaddr */
-                       u_char *);      /* mac address (read) */
-/* ---------------------- INTERRUPT HANDLING ---------------------- */
-static irqreturn_t
-       wavelan_interrupt(int,          /* interrupt handler */
-                         void *);
-static void
-       wavelan_watchdog(struct net_device *);  /* transmission watchdog */
-/* ------------------- CONFIGURATION CALLBACKS ------------------- */
-static int
-       wavelan_open(struct net_device *),      /* Open the device. */
-       wavelan_close(struct net_device *),     /* Close the device. */
-       wavelan_config(struct net_device *, unsigned short);/* Configure one device. */
-extern struct net_device *wavelan_probe(int unit);     /* See Space.c. */
-
-/**************************** VARIABLES ****************************/
-
-/*
- * This is the root of the linked list of WaveLAN drivers
- * It is use to verify that we don't reuse the same base address
- * for two different drivers and to clean up when removing the module.
- */
-static net_local *     wavelan_list    = (net_local *) NULL;
-
-/*
- * This table is used to translate the PSA value to IRQ number
- * and vice versa.
- */
-static u_char  irqvals[]       = {
-          0,    0,    0, 0x01,
-       0x02, 0x04,    0, 0x08,
-          0,    0, 0x10, 0x20,
-       0x40,    0,    0, 0x80,
-};
-
-/*
- * Table of the available I/O addresses (base addresses) for WaveLAN
- */
-static unsigned short  iobase[]        = {
-#if    0
-  /* Leave out 0x3C0 for now -- seems to clash with some video
-   * controllers.
-   * Leave out the others too -- we will always use 0x390 and leave
-   * 0x300 for the Ethernet device.
-   * Jean II:  0x3E0 is fine as well.
-   */
-  0x300, 0x390, 0x3E0, 0x3C0
-#endif /* 0 */
-  0x390, 0x3E0
-};
-
-#ifdef MODULE
-/* Parameters set by insmod */
-static int     io[4];
-static int     irq[4];
-static char    *name[4];
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(name, charp, NULL, 0);
-
-MODULE_PARM_DESC(io, "WaveLAN I/O base address(es),required");
-MODULE_PARM_DESC(irq, "WaveLAN IRQ number(s)");
-MODULE_PARM_DESC(name, "WaveLAN interface neme(s)");
-#endif /* MODULE */
-
-#endif /* WAVELAN_P_H */
 
+++ /dev/null
-/*
- *     Wavelan Pcmcia driver
- *
- *             Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- * Original copyright follow. See wavelan_cs.p.h for details.
- *
- * This code is derived from Anthony D. Joseph's code and all the changes here
- * are also under the original copyright below.
- *
- * This code supports version 2.00 of WaveLAN/PCMCIA cards (2.4GHz), and
- * can work on Linux 2.0.36 with support of David Hinds' PCMCIA Card Services
- *
- * Joe Finney (joe@comp.lancs.ac.uk) at Lancaster University in UK added
- * critical code in the routine to initialize the Modem Management Controller.
- *
- * Thanks to Alan Cox and Bruce Janson for their advice.
- *
- *     -- Yunzhou Li (scip4166@nus.sg)
- *
-#ifdef WAVELAN_ROAMING 
- * Roaming support added 07/22/98 by Justin Seger (jseger@media.mit.edu)
- * based on patch by Joe Finney from Lancaster University.
-#endif
- *
- * Lucent (formerly AT&T GIS, formerly NCR) WaveLAN PCMCIA card: An
- * Ethernet-like radio transceiver controlled by an Intel 82593 coprocessor.
- *
- *   A non-shared memory PCMCIA ethernet driver for linux
- *
- * ISA version modified to support PCMCIA by Anthony Joseph (adj@lcs.mit.edu)
- *
- *
- * Joseph O'Sullivan & John Langford (josullvn@cs.cmu.edu & jcl@cs.cmu.edu)
- *
- * Apr 2 '98  made changes to bring the i82593 control/int handling in line
- *             with offical specs...
- *
- ****************************************************************************
- *   Copyright 1995
- *   Anthony D. Joseph
- *   Massachusetts Institute of Technology
- *
- *   Permission to use, copy, modify, and distribute this program
- *   for any purpose and without fee is hereby granted, provided
- *   that this copyright and permission notice appear on all copies
- *   and supporting documentation, the name of M.I.T. not be used
- *   in advertising or publicity pertaining to distribution of the
- *   program without specific prior permission, and notice be given
- *   in supporting documentation that copying and distribution is
- *   by permission of M.I.T.  M.I.T. makes no representations about
- *   the suitability of this software for any purpose.  It is pro-
- *   vided "as is" without express or implied warranty.         
- ****************************************************************************
- *
- */
-
-/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
-#include "wavelan_cs.p.h"              /* Private header */
-
-#ifdef WAVELAN_ROAMING
-static void wl_cell_expiry(unsigned long data);
-static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp);
-static void wv_nwid_filter(unsigned char mode, net_local *lp);
-#endif  /*  WAVELAN_ROAMING  */
-
-/************************* MISC SUBROUTINES **************************/
-/*
- * Subroutines which won't fit in one of the following category
- * (wavelan modem or i82593)
- */
-
-/******************* MODEM MANAGEMENT SUBROUTINES *******************/
-/*
- * Useful subroutines to manage the modem of the wavelan
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Read from card's Host Adaptor Status Register.
- */
-static inline u_char
-hasr_read(u_long       base)
-{
-  return(inb(HASR(base)));
-} /* hasr_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register.
- */
-static inline void
-hacr_write(u_long      base,
-          u_char       hacr)
-{
-  outb(hacr, HACR(base));
-} /* hacr_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Write to card's Host Adapter Command Register. Include a delay for
- * those times when it is needed.
- */
-static void
-hacr_write_slow(u_long base,
-               u_char  hacr)
-{
-  hacr_write(base, hacr);
-  /* delay might only be needed sometimes */
-  mdelay(1);
-} /* hacr_write_slow */
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Parameter Storage Area from the WaveLAN card's memory
- */
-static void
-psa_read(struct net_device *   dev,
-        int            o,      /* offset in PSA */
-        u_char *       b,      /* buffer to fill */
-        int            n)      /* size to read */
-{
-  net_local *lp = netdev_priv(dev);
-  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
-
-  while(n-- > 0)
-    {
-      *b++ = readb(ptr);
-      /* Due to a lack of address decode pins, the WaveLAN PCMCIA card
-       * only supports reading even memory addresses. That means the
-       * increment here MUST be two.
-       * Because of that, we can't use memcpy_fromio()...
-       */
-      ptr += 2;
-    }
-} /* psa_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Write the Parameter Storage Area to the WaveLAN card's memory
- */
-static void
-psa_write(struct net_device *  dev,
-         int           o,      /* Offset in psa */
-         u_char *      b,      /* Buffer in memory */
-         int           n)      /* Length of buffer */
-{
-  net_local *lp = netdev_priv(dev);
-  u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
-  int          count = 0;
-  unsigned int base = dev->base_addr;
-  /* As there seem to have no flag PSA_BUSY as in the ISA model, we are
-   * oblige to verify this address to know when the PSA is ready... */
-  volatile u_char __iomem *verify = lp->mem + PSA_ADDR +
-    (psaoff(0, psa_comp_number) << 1);
-
-  /* Authorize writing to PSA */
-  hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN);
-
-  while(n-- > 0)
-    {
-      /* write to PSA */
-      writeb(*b++, ptr);
-      ptr += 2;
-
-      /* I don't have the spec, so I don't know what the correct
-       * sequence to write is. This hack seem to work for me... */
-      count = 0;
-      while((readb(verify) != PSA_COMP_PCMCIA_915) && (count++ < 100))
-       mdelay(1);
-    }
-
-  /* Put the host interface back in standard state */
-  hacr_write(base, HACR_DEFAULT);
-} /* psa_write */
-
-#ifdef SET_PSA_CRC
-/*------------------------------------------------------------------*/
-/*
- * Calculate the PSA CRC
- * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
- * NOTE: By specifying a length including the CRC position the
- * returned value should be zero. (i.e. a correct checksum in the PSA)
- *
- * The Windows drivers don't use the CRC, but the AP and the PtP tool
- * depend on it.
- */
-static u_short
-psa_crc(unsigned char *        psa,    /* The PSA */
-       int             size)   /* Number of short for CRC */
-{
-  int          byte_cnt;       /* Loop on the PSA */
-  u_short      crc_bytes = 0;  /* Data in the PSA */
-  int          bit_cnt;        /* Loop on the bits of the short */
-
-  for(byte_cnt = 0; byte_cnt < size; byte_cnt++ )
-    {
-      crc_bytes ^= psa[byte_cnt];      /* Its an xor */
-
-      for(bit_cnt = 1; bit_cnt < 9; bit_cnt++ )
-       {
-         if(crc_bytes & 0x0001)
-           crc_bytes = (crc_bytes >> 1) ^ 0xA001;
-         else
-           crc_bytes >>= 1 ;
-        }
-    }
-
-  return crc_bytes;
-} /* psa_crc */
-#endif /* SET_PSA_CRC */
-
-/*------------------------------------------------------------------*/
-/*
- * update the checksum field in the Wavelan's PSA
- */
-static void
-update_psa_checksum(struct net_device *        dev)
-{
-#ifdef SET_PSA_CRC
-  psa_t                psa;
-  u_short      crc;
-
-  /* read the parameter storage area */
-  psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-
-  /* update the checksum */
-  crc = psa_crc((unsigned char *) &psa,
-               sizeof(psa) - sizeof(psa.psa_crc[0]) - sizeof(psa.psa_crc[1])
-               - sizeof(psa.psa_crc_status));
-
-  psa.psa_crc[0] = crc & 0xFF;
-  psa.psa_crc[1] = (crc & 0xFF00) >> 8;
-
-  /* Write it ! */
-  psa_write(dev, (char *)&psa.psa_crc - (char *)&psa,
-           (unsigned char *)&psa.psa_crc, 2);
-
-#ifdef DEBUG_IOCTL_INFO
-  printk (KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
-          dev->name, psa.psa_crc[0], psa.psa_crc[1]);
-
-  /* Check again (luxury !) */
-  crc = psa_crc((unsigned char *) &psa,
-                sizeof(psa) - sizeof(psa.psa_crc_status));
-
-  if(crc != 0)
-    printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name);
-#endif /* DEBUG_IOCTL_INFO */
-#endif /* SET_PSA_CRC */
-} /* update_psa_checksum */
-
-/*------------------------------------------------------------------*/
-/*
- * Write 1 byte to the MMC.
- */
-static void
-mmc_out(u_long         base,
-       u_short         o,
-       u_char          d)
-{
-  int count = 0;
-
-  /* Wait for MMC to go idle */
-  while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
-    udelay(10);
-
-  outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base));
-  outb(d, MMD(base));
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to write bytes to the Modem Management Controller.
- * We start by the end because it is the way it should be !
- */
-static void
-mmc_write(u_long       base,
-         u_char        o,
-         u_char *      b,
-         int           n)
-{
-  o += n;
-  b += n;
-
-  while(n-- > 0 )
-    mmc_out(base, --o, *(--b));
-} /* mmc_write */
-
-/*------------------------------------------------------------------*/
-/*
- * Read 1 byte from the MMC.
- * Optimised version for 1 byte, avoid using memory...
- */
-static u_char
-mmc_in(u_long  base,
-       u_short o)
-{
-  int count = 0;
-
-  while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
-    udelay(10);
-  outb(o << 1, MMR(base));             /* Set the read address */
-
-  outb(0, MMD(base));                  /* Required dummy write */
-
-  while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
-    udelay(10);
-  return (u_char) (inb(MMD(base)));    /* Now do the actual read */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read bytes from the Modem Management Controller.
- * The implementation is complicated by a lack of address lines,
- * which prevents decoding of the low-order bit.
- * (code has just been moved in the above function)
- * We start by the end because it is the way it should be !
- */
-static void
-mmc_read(u_long                base,
-        u_char         o,
-        u_char *       b,
-        int            n)
-{
-  o += n;
-  b += n;
-
-  while(n-- > 0)
-    *(--b) = mmc_in(base, --o);
-} /* mmc_read */
-
-/*------------------------------------------------------------------*/
-/*
- * Get the type of encryption available...
- */
-static inline int
-mmc_encr(u_long                base)   /* i/o port of the card */
-{
-  int  temp;
-
-  temp = mmc_in(base, mmroff(0, mmr_des_avail));
-  if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
-    return 0;
-  else
-    return temp;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wait for the frequency EEprom to complete a command...
- */
-static void
-fee_wait(u_long                base,   /* i/o port of the card */
-        int            delay,  /* Base delay to wait for */
-        int            number) /* Number of time to wait */
-{
-  int          count = 0;      /* Wait only a limited time */
-
-  while((count++ < number) &&
-       (mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY))
-    udelay(delay);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read bytes from the Frequency EEprom (frequency select cards).
- */
-static void
-fee_read(u_long                base,   /* i/o port of the card */
-        u_short        o,      /* destination offset */
-        u_short *      b,      /* data buffer */
-        int            n)      /* number of registers */
-{
-  b += n;              /* Position at the end of the area */
-
-  /* Write the address */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-  /* Loop on all buffer */
-  while(n-- > 0)
-    {
-      /* Write the read command */
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ);
-
-      /* Wait until EEprom is ready (should be quick !) */
-      fee_wait(base, 10, 100);
-
-      /* Read the value */
-      *--b = ((mmc_in(base, mmroff(0, mmr_fee_data_h)) << 8) |
-             mmc_in(base, mmroff(0, mmr_fee_data_l)));
-    }
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Write bytes from the Frequency EEprom (frequency select cards).
- * This is a bit complicated, because the frequency eeprom has to
- * be unprotected and the write enabled.
- * Jean II
- */
-static void
-fee_write(u_long       base,   /* i/o port of the card */
-         u_short       o,      /* destination offset */
-         u_short *     b,      /* data buffer */
-         int           n)      /* number of registers */
-{
-  b += n;              /* Position at the end of the area */
-
-#ifdef EEPROM_IS_PROTECTED     /* disabled */
-#ifdef DOESNT_SEEM_TO_WORK     /* disabled */
-  /* Ask to read the protected register */
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
-
-  fee_wait(base, 10, 100);
-
-  /* Read the protected register */
-  printk("Protected 2 : %02X-%02X\n",
-        mmc_in(base, mmroff(0, mmr_fee_data_h)),
-        mmc_in(base, mmroff(0, mmr_fee_data_l)));
-#endif /* DOESNT_SEEM_TO_WORK */
-
-  /* Enable protected register */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
-
-  fee_wait(base, 10, 100);
-
-  /* Unprotect area */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), o + n);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-#ifdef DOESNT_SEEM_TO_WORK     /* disabled */
-  /* Or use : */
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
-#endif /* DOESNT_SEEM_TO_WORK */
-
-  fee_wait(base, 10, 100);
-#endif /* EEPROM_IS_PROTECTED */
-
-  /* Write enable */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
-
-  fee_wait(base, 10, 100);
-
-  /* Write the EEprom address */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
-
-  /* Loop on all buffer */
-  while(n-- > 0)
-    {
-      /* Write the value */
-      mmc_out(base, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
-      mmc_out(base, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
-
-      /* Write the write command */
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE);
-
-      /* Wavelan doc says : wait at least 10 ms for EEBUSY = 0 */
-      mdelay(10);
-      fee_wait(base, 10, 100);
-    }
-
-  /* Write disable */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
-
-  fee_wait(base, 10, 100);
-
-#ifdef EEPROM_IS_PROTECTED     /* disabled */
-  /* Reprotect EEprom */
-  mmc_out(base, mmwoff(0, mmw_fee_addr), 0x00);
-  mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
-
-  fee_wait(base, 10, 100);
-#endif /* EEPROM_IS_PROTECTED */
-}
-
-/******************* WaveLAN Roaming routines... ********************/
-
-#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */
-
-static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00};
-  
-static void wv_roam_init(struct net_device *dev)
-{
-  net_local  *lp= netdev_priv(dev);
-
-  /* Do not remove this unless you have a good reason */
-  printk(KERN_NOTICE "%s: Warning, you have enabled roaming on"
-        " device %s !\n", dev->name, dev->name);
-  printk(KERN_NOTICE "Roaming is currently an experimental unsupported feature"
-        " of the Wavelan driver.\n");
-  printk(KERN_NOTICE "It may work, but may also make the driver behave in"
-        " erratic ways or crash.\n");
-
-  lp->wavepoint_table.head=NULL;           /* Initialise WavePoint table */
-  lp->wavepoint_table.num_wavepoints=0;
-  lp->wavepoint_table.locked=0;
-  lp->curr_point=NULL;                        /* No default WavePoint */
-  lp->cell_search=0;
-  
-  lp->cell_timer.data=(long)lp;               /* Start cell expiry timer */
-  lp->cell_timer.function=wl_cell_expiry;
-  lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
-  add_timer(&lp->cell_timer);
-  
-  wv_nwid_filter(NWID_PROMISC,lp) ;    /* Enter NWID promiscuous mode */
-  /* to build up a good WavePoint */
-                                           /* table... */
-  printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
-}
- 
-static void wv_roam_cleanup(struct net_device *dev)
-{
-  wavepoint_history *ptr,*old_ptr;
-  net_local *lp= netdev_priv(dev);
-  
-  printk(KERN_DEBUG "WaveLAN: Roaming Disabled on device %s\n",dev->name);
-  
-  /* Fixme : maybe we should check that the timer exist before deleting it */
-  del_timer(&lp->cell_timer);          /* Remove cell expiry timer       */
-  ptr=lp->wavepoint_table.head;        /* Clear device's WavePoint table */
-  while(ptr!=NULL)
-    {
-      old_ptr=ptr;
-      ptr=ptr->next;   
-      wl_del_wavepoint(old_ptr,lp);    
-    }
-}
-
-/* Enable/Disable NWID promiscuous mode on a given device */
-static void wv_nwid_filter(unsigned char mode, net_local *lp)
-{
-  mm_t                  m;
-  unsigned long         flags;
-  
-#ifdef WAVELAN_ROAMING_DEBUG
-  printk(KERN_DEBUG "WaveLAN: NWID promisc %s, device %s\n",(mode==NWID_PROMISC) ? "on" : "off", lp->dev->name);
-#endif
-  
-  /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->spinlock, flags);
-  
-  m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
-  mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
-  
-  if(mode==NWID_PROMISC)
-    lp->cell_search=1;
-  else
-    lp->cell_search=0;
-
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-}
-
-/* Find a record in the WavePoint table matching a given NWID */
-static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
-{
-  wavepoint_history    *ptr=lp->wavepoint_table.head;
-  
-  while(ptr!=NULL){
-    if(ptr->nwid==nwid)
-      return ptr;      
-    ptr=ptr->next;
-  }
-  return NULL;
-}
-
-/* Create a new wavepoint table entry */
-static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
-{
-  wavepoint_history *new_wavepoint;
-
-#ifdef WAVELAN_ROAMING_DEBUG   
-  printk(KERN_DEBUG "WaveLAN: New Wavepoint, NWID:%.4X\n",nwid);
-#endif
-  
-  if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
-    return NULL;
-  
-  new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
-  if(new_wavepoint==NULL)
-    return NULL;
-  
-  new_wavepoint->nwid=nwid;                       /* New WavePoints NWID */
-  new_wavepoint->average_fast=0;                    /* Running Averages..*/
-  new_wavepoint->average_slow=0;
-  new_wavepoint->qualptr=0;                       /* Start of ringbuffer */
-  new_wavepoint->last_seq=seq-1;                /* Last sequence no.seen */
-  memset(new_wavepoint->sigqual,0,WAVEPOINT_HISTORY);/* Empty ringbuffer */
-  
-  new_wavepoint->next=lp->wavepoint_table.head;/* Add to wavepoint table */
-  new_wavepoint->prev=NULL;
-  
-  if(lp->wavepoint_table.head!=NULL)
-    lp->wavepoint_table.head->prev=new_wavepoint;
-  
-  lp->wavepoint_table.head=new_wavepoint;
-  
-  lp->wavepoint_table.num_wavepoints++;     /* no. of visible wavepoints */
-  
-  return new_wavepoint;
-}
-
-/* Remove a wavepoint entry from WavePoint table */
-static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
-{
-  if(wavepoint==NULL)
-    return;
-  
-  if(lp->curr_point==wavepoint)
-    lp->curr_point=NULL;
-  
-  if(wavepoint->prev!=NULL)
-    wavepoint->prev->next=wavepoint->next;
-  
-  if(wavepoint->next!=NULL)
-    wavepoint->next->prev=wavepoint->prev;
-  
-  if(lp->wavepoint_table.head==wavepoint)
-    lp->wavepoint_table.head=wavepoint->next;
-  
-  lp->wavepoint_table.num_wavepoints--;
-  kfree(wavepoint);
-}
-
-/* Timer callback function - checks WavePoint table for stale entries */ 
-static void wl_cell_expiry(unsigned long data)
-{
-  net_local *lp=(net_local *)data;
-  wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
-  
-#if WAVELAN_ROAMING_DEBUG > 1
-  printk(KERN_DEBUG "WaveLAN: Wavepoint timeout, dev %s\n",lp->dev->name);
-#endif
-  
-  if(lp->wavepoint_table.locked)
-    {
-#if WAVELAN_ROAMING_DEBUG > 1
-      printk(KERN_DEBUG "WaveLAN: Wavepoint table locked...\n");
-#endif
-      
-      lp->cell_timer.expires=jiffies+1; /* If table in use, come back later */
-      add_timer(&lp->cell_timer);
-      return;
-    }
-  
-  while(wavepoint!=NULL)
-    {
-      if(time_after(jiffies, wavepoint->last_seen + CELL_TIMEOUT))
-       {
-#ifdef WAVELAN_ROAMING_DEBUG
-         printk(KERN_DEBUG "WaveLAN: Bye bye %.4X\n",wavepoint->nwid);
-#endif
-         
-         old_point=wavepoint;
-         wavepoint=wavepoint->next;
-         wl_del_wavepoint(old_point,lp);
-       }
-      else
-       wavepoint=wavepoint->next;
-    }
-  lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
-  add_timer(&lp->cell_timer);
-}
-
-/* Update SNR history of a wavepoint */
-static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)  
-{
-  int i=0,num_missed=0,ptr=0;
-  int average_fast=0,average_slow=0;
-  
-  num_missed=(seq-wavepoint->last_seq)%WAVEPOINT_HISTORY;/* Have we missed
-                                                           any beacons? */
-  if(num_missed)
-    for(i=0;i<num_missed;i++)
-      {
-       wavepoint->sigqual[wavepoint->qualptr++]=0; /* If so, enter them as 0's */
-       wavepoint->qualptr %=WAVEPOINT_HISTORY;    /* in the ringbuffer. */
-      }
-  wavepoint->last_seen=jiffies;                 /* Add beacon to history */
-  wavepoint->last_seq=seq;     
-  wavepoint->sigqual[wavepoint->qualptr++]=sigqual;          
-  wavepoint->qualptr %=WAVEPOINT_HISTORY;
-  ptr=(wavepoint->qualptr-WAVEPOINT_FAST_HISTORY+WAVEPOINT_HISTORY)%WAVEPOINT_HISTORY;
-  
-  for(i=0;i<WAVEPOINT_FAST_HISTORY;i++)       /* Update running averages */
-    {
-      average_fast+=wavepoint->sigqual[ptr++];
-      ptr %=WAVEPOINT_HISTORY;
-    }
-  
-  average_slow=average_fast;
-  for(i=WAVEPOINT_FAST_HISTORY;i<WAVEPOINT_HISTORY;i++)
-    {
-      average_slow+=wavepoint->sigqual[ptr++];
-      ptr %=WAVEPOINT_HISTORY;
-    }
-  
-  wavepoint->average_fast=average_fast/WAVEPOINT_FAST_HISTORY;
-  wavepoint->average_slow=average_slow/WAVEPOINT_HISTORY;      
-}
-
-/* Perform a handover to a new WavePoint */
-static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
-{
-  unsigned int         base = lp->dev->base_addr;
-  mm_t                  m;
-  unsigned long         flags;
-
-  if(wavepoint==lp->curr_point)          /* Sanity check... */
-    {
-      wv_nwid_filter(!NWID_PROMISC,lp);
-      return;
-    }
-  
-#ifdef WAVELAN_ROAMING_DEBUG
-  printk(KERN_DEBUG "WaveLAN: Doing handover to %.4X, dev %s\n",wavepoint->nwid,lp->dev->name);
-#endif
-       
-  /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
-  m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
-  
-  mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
-  
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  wv_nwid_filter(!NWID_PROMISC,lp);
-  lp->curr_point=wavepoint;
-}
-
-/* Called when a WavePoint beacon is received */
-static void wl_roam_gather(struct net_device *  dev,
-                          u_char *  hdr,   /* Beacon header */
-                          u_char *  stats) /* SNR, Signal quality
-                                                     of packet */
-{
-  wavepoint_beacon *beacon= (wavepoint_beacon *)hdr; /* Rcvd. Beacon */
-  unsigned short nwid=ntohs(beacon->nwid);  
-  unsigned short sigqual=stats[2] & MMR_SGNL_QUAL;   /* SNR of beacon */
-  wavepoint_history *wavepoint=NULL;                /* WavePoint table entry */
-  net_local *lp = netdev_priv(dev);              /* Device info */
-
-#ifdef I_NEED_THIS_FEATURE
-  /* Some people don't need this, some other may need it */
-  nwid=nwid^ntohs(beacon->domain_id);
-#endif
-
-#if WAVELAN_ROAMING_DEBUG > 1
-  printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name);
-  printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual);
-#endif
-  
-  lp->wavepoint_table.locked=1;                            /* <Mutex> */
-  
-  wavepoint=wl_roam_check(nwid,lp);            /* Find WavePoint table entry */
-  if(wavepoint==NULL)                    /* If no entry, Create a new one... */
-    {
-      wavepoint=wl_new_wavepoint(nwid,beacon->seq,lp);
-      if(wavepoint==NULL)
-       goto out;
-    }
-  if(lp->curr_point==NULL)             /* If this is the only WavePoint, */
-    wv_roam_handover(wavepoint, lp);            /* Jump on it! */
-  
-  wl_update_history(wavepoint, sigqual, beacon->seq); /* Update SNR history
-                                                        stats. */
-  
-  if(lp->curr_point->average_slow < SEARCH_THRESH_LOW) /* If our current */
-    if(!lp->cell_search)                  /* WavePoint is getting faint, */
-      wv_nwid_filter(NWID_PROMISC,lp);    /* start looking for a new one */
-  
-  if(wavepoint->average_slow > 
-     lp->curr_point->average_slow + WAVELAN_ROAMING_DELTA)
-    wv_roam_handover(wavepoint, lp);   /* Handover to a better WavePoint */
-  
-  if(lp->curr_point->average_slow > SEARCH_THRESH_HIGH) /* If our SNR is */
-    if(lp->cell_search)  /* getting better, drop out of cell search mode */
-      wv_nwid_filter(!NWID_PROMISC,lp);
-  
-out:
-  lp->wavepoint_table.locked=0;                        /* </MUTEX>   :-) */
-}
-
-/* Test this MAC frame a WavePoint beacon */
-static inline int WAVELAN_BEACON(unsigned char *data)
-{
-  wavepoint_beacon *beacon= (wavepoint_beacon *)data;
-  static const wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00};
-  
-  if(memcmp(beacon,&beacon_template,9)==0)
-    return 1;
-  else
-    return 0;
-}
-#endif /* WAVELAN_ROAMING */
-
-/************************ I82593 SUBROUTINES *************************/
-/*
- * Useful subroutines to manage the Ethernet controller
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to synchronously send a command to the i82593 chip. 
- * Should be called with interrupts disabled.
- * (called by wv_packet_write(), wv_ru_stop(), wv_ru_start(),
- *  wv_82593_config() & wv_diag())
- */
-static int
-wv_82593_cmd(struct net_device *       dev,
-            char *     str,
-            int        cmd,
-            int        result)
-{
-  unsigned int base = dev->base_addr;
-  int          status;
-  int          wait_completed;
-  long         spin;
-
-  /* Spin until the chip finishes executing its current command (if any) */
-  spin = 1000;
-  do
-    {
-      /* Time calibration of the loop */
-      udelay(10);
-
-      /* Read the interrupt register */
-      outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-      status = inb(LCSR(base));
-    }
-  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
-
-  /* If the interrupt hasn't been posted */
-  if (spin < 0) {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
-            str, status);
-#endif
-      return(FALSE);
-    }
-
-  /* Issue the command to the controller */
-  outb(cmd, LCCR(base));
-
-  /* If we don't have to check the result of the command
-   * Note : this mean that the irq handler will deal with that */
-  if(result == SR0_NO_RESULT)
-    return(TRUE);
-
-  /* We are waiting for command completion */
-  wait_completed = TRUE;
-
-  /* Busy wait while the LAN controller executes the command. */
-  spin = 1000;
-  do
-    {
-      /* Time calibration of the loop */
-      udelay(10);
-
-      /* Read the interrupt register */
-      outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
-      status = inb(LCSR(base));
-
-      /* Check if there was an interrupt posted */
-      if((status & SR0_INTERRUPT))
-       {
-         /* Acknowledge the interrupt */
-         outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-
-         /* Check if interrupt is a command completion */
-         if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) &&
-            ((status & SR0_BOTH_RX_TX) != 0x0) &&
-            !(status & SR0_RECEPTION))
-           {
-             /* Signal command completion */
-             wait_completed = FALSE;
-           }
-         else
-           {
-             /* Note : Rx interrupts will be handled later, because we can
-              * handle multiple Rx packets at once */
-#ifdef DEBUG_INTERRUPT_INFO
-             printk(KERN_INFO "wv_82593_cmd: not our interrupt\n");
-#endif
-           }
-       }
-    }
-  while(wait_completed && (spin-- > 0));
-
-  /* If the interrupt hasn't be posted */
-  if(wait_completed)
-    {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n",
-            str, status);
-#endif
-      return(FALSE);
-    }
-
-  /* Check the return code returned by the card (see above) against
-   * the expected return code provided by the caller */
-  if((status & SR0_EVENT_MASK) != result)
-    {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n",
-            str, status);
-#endif
-      return(FALSE);
-    }
-
-  return(TRUE);
-} /* wv_82593_cmd */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a 593 op-code number 7, and obtains the diagnose
- * status for the WaveLAN.
- */
-static inline int
-wv_diag(struct net_device *    dev)
-{
-  return(wv_82593_cmd(dev, "wv_diag(): diagnose",
-                     OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED));
-} /* wv_diag */
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to read len bytes from the i82593's ring buffer, starting at
- * chip address addr. The results read from the chip are stored in buf.
- * The return value is the address to use for next the call.
- */
-static int
-read_ringbuf(struct net_device *       dev,
-            int        addr,
-            char *     buf,
-            int        len)
-{
-  unsigned int base = dev->base_addr;
-  int          ring_ptr = addr;
-  int          chunk_len;
-  char *       buf_ptr = buf;
-
-  /* Get all the buffer */
-  while(len > 0)
-    {
-      /* Position the Program I/O Register at the ring buffer pointer */
-      outb(ring_ptr & 0xff, PIORL(base));
-      outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base));
-
-      /* First, determine how much we can read without wrapping around the
-        ring buffer */
-      if((addr + len) < (RX_BASE + RX_SIZE))
-       chunk_len = len;
-      else
-       chunk_len = RX_BASE + RX_SIZE - addr;
-      insb(PIOP(base), buf_ptr, chunk_len);
-      buf_ptr += chunk_len;
-      len -= chunk_len;
-      ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE;
-    }
-  return(ring_ptr);
-} /* read_ringbuf */
-
-/*------------------------------------------------------------------*/
-/*
- * Reconfigure the i82593, or at least ask for it...
- * Because wv_82593_config use the transmission buffer, we must do it
- * when we are sure that there is no transmission, so we do it now
- * or in wavelan_packet_xmit() (I can't find any better place,
- * wavelan_interrupt is not an option...), so you may experience
- * some delay sometime...
- */
-static void
-wv_82593_reconfig(struct net_device *  dev)
-{
-  net_local *          lp = netdev_priv(dev);
-  struct pcmcia_device *               link = lp->link;
-  unsigned long                flags;
-
-  /* Arm the flag, will be cleard in wv_82593_config() */
-  lp->reconfig_82593 = TRUE;
-
-  /* Check if we can do it now ! */
-  if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev)))
-    {
-      spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */
-      wv_82593_config(dev);
-      spin_unlock_irqrestore(&lp->spinlock, flags);    /* Re-enable interrupts */
-    }
-  else
-    {
-#ifdef DEBUG_IOCTL_INFO
-      printk(KERN_DEBUG
-            "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n",
-            dev->name, dev->state, link->open);
-#endif
-    }
-}
-
-/********************* DEBUG & INFO SUBROUTINES *********************/
-/*
- * This routines are used in the code to show debug informations.
- * Most of the time, it dump the content of hardware structures...
- */
-
-#ifdef DEBUG_PSA_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted contents of the Parameter Storage Area.
- */
-static void
-wv_psa_show(psa_t *    p)
-{
-  printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
-  printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
-        p->psa_io_base_addr_1,
-        p->psa_io_base_addr_2,
-        p->psa_io_base_addr_3,
-        p->psa_io_base_addr_4);
-  printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
-        p->psa_rem_boot_addr_1,
-        p->psa_rem_boot_addr_2,
-        p->psa_rem_boot_addr_3);
-  printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
-  printk("psa_int_req_no: %d\n", p->psa_int_req_no);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
-#endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
-  printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
-  printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
-  printk("psa_comp_number: %d, ", p->psa_comp_number);
-  printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
-  printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
-        p->psa_feature_select);
-  printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
-  printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
-  printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
-  printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]);
-  printk("psa_nwid_select: %d\n", p->psa_nwid_select);
-  printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select);
-  printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-        p->psa_encryption_key[0],
-        p->psa_encryption_key[1],
-        p->psa_encryption_key[2],
-        p->psa_encryption_key[3],
-        p->psa_encryption_key[4],
-        p->psa_encryption_key[5],
-        p->psa_encryption_key[6],
-        p->psa_encryption_key[7]);
-  printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
-  printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
-        p->psa_call_code[0]);
-  printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-        p->psa_call_code[0],
-        p->psa_call_code[1],
-        p->psa_call_code[2],
-        p->psa_call_code[3],
-        p->psa_call_code[4],
-        p->psa_call_code[5],
-        p->psa_call_code[6],
-        p->psa_call_code[7]);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n",
-        p->psa_reserved[0],
-        p->psa_reserved[1]);
-#endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
-  printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
-  printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
-} /* wv_psa_show */
-#endif /* DEBUG_PSA_SHOW */
-
-#ifdef DEBUG_MMC_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the Modem Management Controller.
- * This function need to be completed...
- */
-static void
-wv_mmc_show(struct net_device *        dev)
-{
-  unsigned int base = dev->base_addr;
-  net_local *  lp = netdev_priv(dev);
-  mmr_t                m;
-
-  /* Basic check */
-  if(hasr_read(base) & HASR_NO_CLK)
-    {
-      printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n",
-            dev->name);
-      return;
-    }
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Read the mmc */
-  mmc_out(base, mmwoff(0, mmw_freeze), 1);
-  mmc_read(base, 0, (u_char *)&m, sizeof(m));
-  mmc_out(base, mmwoff(0, mmw_freeze), 0);
-
-  /* Don't forget to update statistics */
-  lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-        m.mmr_unused0[0],
-        m.mmr_unused0[1],
-        m.mmr_unused0[2],
-        m.mmr_unused0[3],
-        m.mmr_unused0[4],
-        m.mmr_unused0[5],
-        m.mmr_unused0[6],
-        m.mmr_unused0[7]);
-#endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
-        m.mmr_des_avail, m.mmr_des_status);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
-        m.mmr_unused1[0],
-        m.mmr_unused1[1],
-        m.mmr_unused1[2],
-        m.mmr_unused1[3],
-        m.mmr_unused1[4]);
-#endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
-        m.mmr_dce_status,
-        (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"",
-        (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
-        "loop test indicated," : "",
-        (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "",
-        (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
-        "jabber timer expired," : "");
-  printk(KERN_DEBUG "Dsp ID: %02X\n",
-        m.mmr_dsp_id);
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
-        m.mmr_unused2[0],
-        m.mmr_unused2[1]);
-#endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
-        (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
-        (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
-  printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
-        m.mmr_thr_pre_set & MMR_THR_PRE_SET,
-        (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below");
-  printk(KERN_DEBUG "signal_lvl: %d [%s], ",
-        m.mmr_signal_lvl & MMR_SIGNAL_LVL,
-        (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg");
-  printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL,
-        (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update");
-  printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
-        (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0");
-#ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
-#endif /* DEBUG_SHOW_UNUSED */
-} /* wv_mmc_show */
-#endif /* DEBUG_MMC_SHOW */
-
-#ifdef DEBUG_I82593_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the i82593's receive unit.
- */
-static void
-wv_ru_show(struct net_device * dev)
-{
-  net_local *lp = netdev_priv(dev);
-
-  printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####\n");
-  printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop);
-  /*
-   * Not implemented yet...
-   */
-  printk("\n");
-} /* wv_ru_show */
-#endif /* DEBUG_I82593_SHOW */
-
-#ifdef DEBUG_DEVICE_SHOW
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver.
- */
-static void
-wv_dev_show(struct net_device *        dev)
-{
-  printk(KERN_DEBUG "dev:");
-  printk(" state=%lX,", dev->state);
-  printk(" trans_start=%ld,", dev->trans_start);
-  printk(" flags=0x%x,", dev->flags);
-  printk("\n");
-} /* wv_dev_show */
-
-/*------------------------------------------------------------------*/
-/*
- * Print the formatted status of the WaveLAN PCMCIA device driver's
- * private information.
- */
-static void
-wv_local_show(struct net_device *      dev)
-{
-  net_local *lp = netdev_priv(dev);
-
-  printk(KERN_DEBUG "local:");
-  /*
-   * Not implemented yet...
-   */
-  printk("\n");
-} /* wv_local_show */
-#endif /* DEBUG_DEVICE_SHOW */
-
-#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
-/*------------------------------------------------------------------*/
-/*
- * Dump packet header (and content if necessary) on the screen
- */
-static void
-wv_packet_info(u_char *                p,              /* Packet to dump */
-              int              length,         /* Length of the packet */
-              char *           msg1,           /* Name of the device */
-              char *           msg2)           /* Name of the function */
-{
-  int          i;
-  int          maxi;
-
-  printk(KERN_DEBUG "%s: %s(): dest %pM, length %d\n",
-        msg1, msg2, p, length);
-  printk(KERN_DEBUG "%s: %s(): src %pM, type 0x%02X%02X\n",
-        msg1, msg2, &p[6], p[12], p[13]);
-
-#ifdef DEBUG_PACKET_DUMP
-
-  printk(KERN_DEBUG "data=\"");
-
-  if((maxi = length) > DEBUG_PACKET_DUMP)
-    maxi = DEBUG_PACKET_DUMP;
-  for(i = 14; i < maxi; i++)
-    if(p[i] >= ' ' && p[i] <= '~')
-      printk(" %c", p[i]);
-    else
-      printk("%02X", p[i]);
-  if(maxi < length)
-    printk("..");
-  printk("\"\n");
-  printk(KERN_DEBUG "\n");
-#endif /* DEBUG_PACKET_DUMP */
-}
-#endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
-
-/*------------------------------------------------------------------*/
-/*
- * This is the information which is displayed by the driver at startup
- * There  is a lot of flag to configure it at your will...
- */
-static void
-wv_init_info(struct net_device *       dev)
-{
-  unsigned int base = dev->base_addr;
-  psa_t                psa;
-
-  /* Read the parameter storage area */
-  psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-
-#ifdef DEBUG_PSA_SHOW
-  wv_psa_show(&psa);
-#endif
-#ifdef DEBUG_MMC_SHOW
-  wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82593_SHOW
-  wv_ru_show(dev);
-#endif
-
-#ifdef DEBUG_BASIC_SHOW
-  /* Now, let's go for the basic stuff */
-  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr %pM",
-        dev->name, base, dev->irq, dev->dev_addr);
-
-  /* Print current network id */
-  if(psa.psa_nwid_select)
-    printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]);
-  else
-    printk(", nwid off");
-
-  /* If 2.00 card */
-  if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-       (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-    {
-      unsigned short   freq;
-
-      /* Ask the EEprom to read the frequency from the first area */
-      fee_read(base, 0x00 /* 1st area - frequency... */,
-              &freq, 1);
-
-      /* Print frequency */
-      printk(", 2.00, %ld", (freq >> 6) + 2400L);
-
-      /* Hack !!! */
-      if(freq & 0x20)
-       printk(".5");
-    }
-  else
-    {
-      printk(", PCMCIA, ");
-      switch (psa.psa_subband)
-       {
-       case PSA_SUBBAND_915:
-         printk("915");
-         break;
-       case PSA_SUBBAND_2425:
-         printk("2425");
-         break;
-       case PSA_SUBBAND_2460:
-         printk("2460");
-         break;
-       case PSA_SUBBAND_2484:
-         printk("2484");
-         break;
-       case PSA_SUBBAND_2430_5:
-         printk("2430.5");
-         break;
-       default:
-         printk("unknown");
-       }
-    }
-
-  printk(" MHz\n");
-#endif /* DEBUG_BASIC_SHOW */
-
-#ifdef DEBUG_VERSION_SHOW
-  /* Print version information */
-  printk(KERN_NOTICE "%s", version);
-#endif
-} /* wv_init_info */
-
-/********************* IOCTL, STATS & RECONFIG *********************/
-/*
- * We found here routines that are called by Linux on differents
- * occasions after the configuration and not for transmitting data
- * These may be called when the user use ifconfig, /proc/net/dev
- * or wireless extensions
- */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1     Promiscuous mode, receive all packets
- * num_addrs == 0      Normal mode, clear multicast list
- * num_addrs > 0       Multicast mode, receive normal and MC packets,
- *                     and do best-effort filtering.
- */
-
-static void
-wavelan_set_multicast_list(struct net_device * dev)
-{
-  net_local *  lp = netdev_priv(dev);
-
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", dev->name);
-#endif
-
-#ifdef DEBUG_IOCTL_INFO
-  printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
-        dev->name, dev->flags, netdev_mc_count(dev));
-#endif
-
-  if(dev->flags & IFF_PROMISC)
-    {
-      /*
-       * Enable promiscuous mode: receive all packets.
-       */
-      if(!lp->promiscuous)
-       {
-         lp->promiscuous = 1;
-         lp->allmulticast = 0;
-         lp->mc_count = 0;
-
-         wv_82593_reconfig(dev);
-       }
-    }
-  else
-    /* If all multicast addresses
-     * or too much multicast addresses for the hardware filter */
-    if((dev->flags & IFF_ALLMULTI) ||
-       (netdev_mc_count(dev) > I82593_MAX_MULTICAST_ADDRESSES))
-      {
-       /*
-        * Disable promiscuous mode, but active the all multicast mode
-        */
-       if(!lp->allmulticast)
-         {
-           lp->promiscuous = 0;
-           lp->allmulticast = 1;
-           lp->mc_count = 0;
-
-           wv_82593_reconfig(dev);
-         }
-      }
-    else
-      /* If there is some multicast addresses to send */
-      if (!netdev_mc_empty(dev)) {
-         /*
-          * Disable promiscuous mode, but receive all packets
-          * in multicast list
-          */
-#ifdef MULTICAST_AVOID
-         if(lp->promiscuous || lp->allmulticast ||
-            (netdev_mc_count(dev) != lp->mc_count))
-#endif
-           {
-             lp->promiscuous = 0;
-             lp->allmulticast = 0;
-             lp->mc_count = netdev_mc_count(dev);
-
-             wv_82593_reconfig(dev);
-           }
-       }
-      else
-       {
-         /*
-          * Switch to normal mode: disable promiscuous mode and 
-          * clear the multicast list.
-          */
-         if(lp->promiscuous || lp->mc_count == 0)
-           {
-             lp->promiscuous = 0;
-             lp->allmulticast = 0;
-             lp->mc_count = 0;
-
-             wv_82593_reconfig(dev);
-           }
-       }
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This function doesn't exist...
- * (Note : it was a nice way to test the reconfigure stuff...)
- */
-#ifdef SET_MAC_ADDRESS
-static int
-wavelan_set_mac_address(struct net_device *    dev,
-                       void *          addr)
-{
-  struct sockaddr *    mac = addr;
-
-  /* Copy the address */
-  memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
-
-  /* Reconfig the beast */
-  wv_82593_reconfig(dev);
-
-  return 0;
-}
-#endif /* SET_MAC_ADDRESS */
-
-
-/*------------------------------------------------------------------*/
-/*
- * Frequency setting (for hardware able of it)
- * It's a bit complicated and you don't really want to look into it...
- */
-static int
-wv_set_frequency(u_long                base,   /* i/o port of the card */
-                iw_freq *      frequency)
-{
-  const int    BAND_NUM = 10;  /* Number of bands */
-  long         freq = 0L;      /* offset to 2.4 GHz in .5 MHz */
-#ifdef DEBUG_IOCTL_INFO
-  int          i;
-#endif
-
-  /* Setting by frequency */
-  /* Theoritically, you may set any frequency between
-   * the two limits with a 0.5 MHz precision. In practice,
-   * I don't want you to have trouble with local
-   * regulations... */
-  if((frequency->e == 1) &&
-     (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8))
-    {
-      freq = ((frequency->m / 10000) - 24000L) / 5;
-    }
-
-  /* Setting by channel (same as wfreqsel) */
-  /* Warning : each channel is 22MHz wide, so some of the channels
-   * will interfere... */
-  if((frequency->e == 0) &&
-     (frequency->m >= 0) && (frequency->m < BAND_NUM))
-    {
-      /* Get frequency offset. */
-      freq = channel_bands[frequency->m] >> 1;
-    }
-
-  /* Verify if the frequency is allowed */
-  if(freq != 0L)
-    {
-      u_short  table[10];      /* Authorized frequency table */
-
-      /* Read the frequency table */
-      fee_read(base, 0x71 /* frequency table */,
-              table, 10);
-
-#ifdef DEBUG_IOCTL_INFO
-      printk(KERN_DEBUG "Frequency table :");
-      for(i = 0; i < 10; i++)
-       {
-         printk(" %04X",
-                table[i]);
-       }
-      printk("\n");
-#endif
-
-      /* Look in the table if the frequency is allowed */
-      if(!(table[9 - ((freq - 24) / 16)] &
-          (1 << ((freq - 24) % 16))))
-       return -EINVAL;         /* not allowed */
-    }
-  else
-    return -EINVAL;
-
-  /* If we get a usable frequency */
-  if(freq != 0L)
-    {
-      unsigned short   area[16];
-      unsigned short   dac[2];
-      unsigned short   area_verify[16];
-      unsigned short   dac_verify[2];
-      /* Corresponding gain (in the power adjust value table)
-       * see AT&T Wavelan Data Manual, REF 407-024689/E, page 3-8
-       * & WCIN062D.DOC, page 6.2.9 */
-      unsigned short   power_limit[] = { 40, 80, 120, 160, 0 };
-      int              power_band = 0;         /* Selected band */
-      unsigned short   power_adjust;           /* Correct value */
-
-      /* Search for the gain */
-      power_band = 0;
-      while((freq > power_limit[power_band]) &&
-           (power_limit[++power_band] != 0))
-       ;
-
-      /* Read the first area */
-      fee_read(base, 0x00,
-              area, 16);
-
-      /* Read the DAC */
-      fee_read(base, 0x60,
-              dac, 2);
-
-      /* Read the new power adjust value */
-      fee_read(base, 0x6B - (power_band >> 1),
-              &power_adjust, 1);
-      if(power_band & 0x1)
-       power_adjust >>= 8;
-      else
-       power_adjust &= 0xFF;
-
-#ifdef DEBUG_IOCTL_INFO
-      printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
-      for(i = 0; i < 16; i++)
-       {
-         printk(" %04X",
-                area[i]);
-       }
-      printk("\n");
-
-      printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
-            dac[0], dac[1]);
-#endif
-
-      /* Frequency offset (for info only...) */
-      area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
-
-      /* Receiver Principle main divider coefficient */
-      area[3] = (freq >> 1) + 2400L - 352L;
-      area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-      /* Transmitter Main divider coefficient */
-      area[13] = (freq >> 1) + 2400L;
-      area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
-
-      /* Others part of the area are flags, bit streams or unused... */
-
-      /* Set the value in the DAC */
-      dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
-      dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
-
-      /* Write the first area */
-      fee_write(base, 0x00,
-               area, 16);
-
-      /* Write the DAC */
-      fee_write(base, 0x60,
-               dac, 2);
-
-      /* We now should verify here that the EEprom writing was ok */
-
-      /* ReRead the first area */
-      fee_read(base, 0x00,
-              area_verify, 16);
-
-      /* ReRead the DAC */
-      fee_read(base, 0x60,
-              dac_verify, 2);
-
-      /* Compare */
-      if(memcmp(area, area_verify, 16 * 2) ||
-        memcmp(dac, dac_verify, 2 * 2))
-       {
-#ifdef DEBUG_IOCTL_ERROR
-         printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (?)\n");
-#endif
-         return -EOPNOTSUPP;
-       }
-
-      /* We must download the frequency parameters to the
-       * synthetisers (from the EEprom - area 1)
-       * Note : as the EEprom is auto decremented, we set the end
-       * if the area... */
-      mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F);
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl),
-             MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-      /* Wait until the download is finished */
-      fee_wait(base, 100, 100);
-
-      /* We must now download the power adjust value (gain) to
-       * the synthetisers (from the EEprom - area 7 - DAC) */
-      mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61);
-      mmc_out(base, mmwoff(0, mmw_fee_ctrl),
-             MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
-
-      /* Wait until the download is finished */
-      fee_wait(base, 100, 100);
-
-#ifdef DEBUG_IOCTL_INFO
-      /* Verification of what we have done... */
-
-      printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
-      for(i = 0; i < 16; i++)
-       {
-         printk(" %04X",
-                area_verify[i]);
-       }
-      printk("\n");
-
-      printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
-            dac_verify[0], dac_verify[1]);
-#endif
-
-      return 0;
-    }
-  else
-    return -EINVAL;            /* Bah, never get there... */
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Give the list of available frequencies
- */
-static int
-wv_frequency_list(u_long       base,   /* i/o port of the card */
-                 iw_freq *     list,   /* List of frequency to fill */
-                 int           max)    /* Maximum number of frequencies */
-{
-  u_short      table[10];      /* Authorized frequency table */
-  long         freq = 0L;      /* offset to 2.4 GHz in .5 MHz + 12 MHz */
-  int          i;              /* index in the table */
-  const int    BAND_NUM = 10;  /* Number of bands */
-  int          c = 0;          /* Channel number */
-
-  /* Read the frequency table */
-  fee_read(base, 0x71 /* frequency table */,
-          table, 10);
-
-  /* Look all frequencies */
-  i = 0;
-  for(freq = 0; freq < 150; freq++)
-    /* Look in the table if the frequency is allowed */
-    if(table[9 - (freq / 16)] & (1 << (freq % 16)))
-      {
-       /* Compute approximate channel number */
-       while((((channel_bands[c] >> 1) - 24) < freq) &&
-             (c < BAND_NUM))
-         c++;
-       list[i].i = c;  /* Set the list index */
-
-       /* put in the list */
-       list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
-       list[i++].e = 1;
-
-       /* Check number */
-       if(i >= max)
-         return(i);
-      }
-
-  return(i);
-}
-
-#ifdef IW_WIRELESS_SPY
-/*------------------------------------------------------------------*/
-/*
- * Gather wireless spy statistics : for each packet, compare the source
- * address with out list, and if match, get the stats...
- * Sorry, but this function really need wireless extensions...
- */
-static inline void
-wl_spy_gather(struct net_device *      dev,
-             u_char *  mac,            /* MAC address */
-             u_char *  stats)          /* Statistics to gather */
-{
-  struct iw_quality wstats;
-
-  wstats.qual = stats[2] & MMR_SGNL_QUAL;
-  wstats.level = stats[0] & MMR_SIGNAL_LVL;
-  wstats.noise = stats[1] & MMR_SILENCE_LVL;
-  wstats.updated = 0x7;
-
-  /* Update spy records */
-  wireless_spy_update(dev, mac, &wstats);
-}
-#endif /* IW_WIRELESS_SPY */
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * This function calculate an histogram on the signal level.
- * As the noise is quite constant, it's like doing it on the SNR.
- * We have defined a set of interval (lp->his_range), and each time
- * the level goes in that interval, we increment the count (lp->his_sum).
- * With this histogram you may detect if one wavelan is really weak,
- * or you may also calculate the mean and standard deviation of the level...
- */
-static inline void
-wl_his_gather(struct net_device *      dev,
-             u_char *  stats)          /* Statistics to gather */
-{
-  net_local *  lp = netdev_priv(dev);
-  u_char       level = stats[0] & MMR_SIGNAL_LVL;
-  int          i;
-
-  /* Find the correct interval */
-  i = 0;
-  while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++]))
-    ;
-
-  /* Increment interval counter */
-  (lp->his_sum[i])++;
-}
-#endif /* HISTOGRAM */
-
-static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-       strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1);
-}
-
-static const struct ethtool_ops ops = {
-       .get_drvinfo = wl_get_drvinfo
-};
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get protocol name
- */
-static int wavelan_get_name(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       strcpy(wrqu->name, "WaveLAN");
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set NWID
- */
-static int wavelan_set_nwid(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       mm_t m;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Set NWID in WaveLAN. */
-       if (!wrqu->nwid.disabled) {
-               /* Set NWID in psa */
-               psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
-               psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
-               psa.psa_nwid_select = 0x01;
-               psa_write(dev,
-                         (char *) psa.psa_nwid - (char *) &psa,
-                         (unsigned char *) psa.psa_nwid, 3);
-
-               /* Set NWID in mmc. */
-               m.w.mmw_netw_id_l = psa.psa_nwid[1];
-               m.w.mmw_netw_id_h = psa.psa_nwid[0];
-               mmc_write(base,
-                         (char *) &m.w.mmw_netw_id_l -
-                         (char *) &m,
-                         (unsigned char *) &m.w.mmw_netw_id_l, 2);
-               mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
-       } else {
-               /* Disable NWID in the psa. */
-               psa.psa_nwid_select = 0x00;
-               psa_write(dev,
-                         (char *) &psa.psa_nwid_select -
-                         (char *) &psa,
-                         (unsigned char *) &psa.psa_nwid_select,
-                         1);
-
-               /* Disable NWID in the mmc (no filtering). */
-               mmc_out(base, mmwoff(0, mmw_loopt_sel),
-                       MMW_LOOPT_SEL_DIS_NWID);
-       }
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get NWID 
- */
-static int wavelan_get_nwid(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Read the NWID. */
-       psa_read(dev,
-                (char *) psa.psa_nwid - (char *) &psa,
-                (unsigned char *) psa.psa_nwid, 3);
-       wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
-       wrqu->nwid.disabled = !(psa.psa_nwid_select);
-       wrqu->nwid.fixed = 1;   /* Superfluous */
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set frequency
- */
-static int wavelan_set_freq(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-       int ret;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-       if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-               ret = wv_set_frequency(base, &(wrqu->freq));
-       else
-               ret = -EOPNOTSUPP;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get frequency
- */
-static int wavelan_get_freq(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
-        * Does it work for everybody, especially old cards? */
-       if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-               unsigned short freq;
-
-               /* Ask the EEPROM to read the frequency from the first area. */
-               fee_read(base, 0x00, &freq, 1);
-               wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
-               wrqu->freq.e = 1;
-       } else {
-               psa_read(dev,
-                        (char *) &psa.psa_subband - (char *) &psa,
-                        (unsigned char *) &psa.psa_subband, 1);
-
-               if (psa.psa_subband <= 4) {
-                       wrqu->freq.m = fixed_bands[psa.psa_subband];
-                       wrqu->freq.e = (psa.psa_subband != 0);
-               } else
-                       ret = -EOPNOTSUPP;
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set level threshold
- */
-static int wavelan_set_sens(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Set the level threshold. */
-       /* We should complain loudly if wrqu->sens.fixed = 0, because we
-        * can't set auto mode... */
-       psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
-       psa_write(dev,
-                 (char *) &psa.psa_thr_pre_set - (char *) &psa,
-                 (unsigned char *) &psa.psa_thr_pre_set, 1);
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev);
-       mmc_out(base, mmwoff(0, mmw_thr_pre_set),
-               psa.psa_thr_pre_set);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get level threshold
- */
-static int wavelan_get_sens(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Read the level threshold. */
-       psa_read(dev,
-                (char *) &psa.psa_thr_pre_set - (char *) &psa,
-                (unsigned char *) &psa.psa_thr_pre_set, 1);
-       wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
-       wrqu->sens.fixed = 1;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set encryption key
- */
-static int wavelan_set_encode(struct net_device *dev,
-                             struct iw_request_info *info,
-                             union iwreq_data *wrqu,
-                             char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-       psa_t psa;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-
-       /* Check if capable of encryption */
-       if (!mmc_encr(base)) {
-               ret = -EOPNOTSUPP;
-       }
-
-       /* Check the size of the key */
-       if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
-               ret = -EINVAL;
-       }
-
-       if(!ret) {
-               /* Basic checking... */
-               if (wrqu->encoding.length == 8) {
-                       /* Copy the key in the driver */
-                       memcpy(psa.psa_encryption_key, extra,
-                              wrqu->encoding.length);
-                       psa.psa_encryption_select = 1;
-
-                       psa_write(dev,
-                                 (char *) &psa.psa_encryption_select -
-                                 (char *) &psa,
-                                 (unsigned char *) &psa.
-                                 psa_encryption_select, 8 + 1);
-
-                       mmc_out(base, mmwoff(0, mmw_encr_enable),
-                               MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
-                       mmc_write(base, mmwoff(0, mmw_encr_key),
-                                 (unsigned char *) &psa.
-                                 psa_encryption_key, 8);
-               }
-
-               /* disable encryption */
-               if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
-                       psa.psa_encryption_select = 0;
-                       psa_write(dev,
-                                 (char *) &psa.psa_encryption_select -
-                                 (char *) &psa,
-                                 (unsigned char *) &psa.
-                                 psa_encryption_select, 1);
-
-                       mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
-               }
-               /* update the Wavelan checksum */
-               update_psa_checksum(dev);
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get encryption key
- */
-static int wavelan_get_encode(struct net_device *dev,
-                             struct iw_request_info *info,
-                             union iwreq_data *wrqu,
-                             char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Check if encryption is available */
-       if (!mmc_encr(base)) {
-               ret = -EOPNOTSUPP;
-       } else {
-               /* Read the encryption key */
-               psa_read(dev,
-                        (char *) &psa.psa_encryption_select -
-                        (char *) &psa,
-                        (unsigned char *) &psa.
-                        psa_encryption_select, 1 + 8);
-
-               /* encryption is enabled ? */
-               if (psa.psa_encryption_select)
-                       wrqu->encoding.flags = IW_ENCODE_ENABLED;
-               else
-                       wrqu->encoding.flags = IW_ENCODE_DISABLED;
-               wrqu->encoding.flags |= mmc_encr(base);
-
-               /* Copy the key to the user buffer */
-               wrqu->encoding.length = 8;
-               memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-#ifdef WAVELAN_ROAMING_EXT
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set ESSID (domain)
- */
-static int wavelan_set_essid(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Check if disable */
-       if(wrqu->data.flags == 0)
-               lp->filter_domains = 0;
-       else {
-               char    essid[IW_ESSID_MAX_SIZE + 1];
-               char *  endp;
-
-               /* Terminate the string */
-               memcpy(essid, extra, wrqu->data.length);
-               essid[IW_ESSID_MAX_SIZE] = '\0';
-
-#ifdef DEBUG_IOCTL_INFO
-               printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);
-#endif /* DEBUG_IOCTL_INFO */
-
-               /* Convert to a number (note : Wavelan specific) */
-               lp->domain_id = simple_strtoul(essid, &endp, 16);
-               /* Has it worked  ? */
-               if(endp > essid)
-                       lp->filter_domains = 1;
-               else {
-                       lp->filter_domains = 0;
-                       ret = -EINVAL;
-               }
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get ESSID (domain)
- */
-static int wavelan_get_essid(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-
-       /* Is the domain ID active ? */
-       wrqu->data.flags = lp->filter_domains;
-
-       /* Copy Domain ID into a string (Wavelan specific) */
-       /* Sound crazy, be we can't have a snprintf in the kernel !!! */
-       sprintf(extra, "%lX", lp->domain_id);
-       extra[IW_ESSID_MAX_SIZE] = '\0';
-
-       /* Set the length */
-       wrqu->data.length = strlen(extra);
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set AP address
- */
-static int wavelan_set_wap(struct net_device *dev,
-                          struct iw_request_info *info,
-                          union iwreq_data *wrqu,
-                          char *extra)
-{
-#ifdef DEBUG_IOCTL_INFO
-       printk(KERN_DEBUG "Set AP to : %pM\n", wrqu->ap_addr.sa_data);
-#endif /* DEBUG_IOCTL_INFO */
-
-       return -EOPNOTSUPP;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get AP address
- */
-static int wavelan_get_wap(struct net_device *dev,
-                          struct iw_request_info *info,
-                          union iwreq_data *wrqu,
-                          char *extra)
-{
-       /* Should get the real McCoy instead of own Ethernet address */
-       memcpy(wrqu->ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
-       wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
-       return -EOPNOTSUPP;
-}
-#endif /* WAVELAN_ROAMING_EXT */
-
-#ifdef WAVELAN_ROAMING
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : set mode
- */
-static int wavelan_set_mode(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-       int ret = 0;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-
-       /* Check mode */
-       switch(wrqu->mode) {
-       case IW_MODE_ADHOC:
-               if(do_roaming) {
-                       wv_roam_cleanup(dev);
-                       do_roaming = 0;
-               }
-               break;
-       case IW_MODE_INFRA:
-               if(!do_roaming) {
-                       wv_roam_init(dev);
-                       do_roaming = 1;
-               }
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get mode
- */
-static int wavelan_get_mode(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       if(do_roaming)
-               wrqu->mode = IW_MODE_INFRA;
-       else
-               wrqu->mode = IW_MODE_ADHOC;
-
-       return 0;
-}
-#endif /* WAVELAN_ROAMING */
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Handler : get range info
- */
-static int wavelan_get_range(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       struct iw_range *range = (struct iw_range *) extra;
-       unsigned long flags;
-       int ret = 0;
-
-       /* Set the length (very important for backward compatibility) */
-       wrqu->data.length = sizeof(struct iw_range);
-
-       /* Set all the info we don't care or don't know about to zero */
-       memset(range, 0, sizeof(struct iw_range));
-
-       /* Set the Wireless Extension versions */
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 9;
-
-       /* Set information in the range struct.  */
-       range->throughput = 1.4 * 1000 * 1000;  /* don't argue on this ! */
-       range->min_nwid = 0x0000;
-       range->max_nwid = 0xFFFF;
-
-       range->sensitivity = 0x3F;
-       range->max_qual.qual = MMR_SGNL_QUAL;
-       range->max_qual.level = MMR_SIGNAL_LVL;
-       range->max_qual.noise = MMR_SILENCE_LVL;
-       range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
-       /* Need to get better values for those two */
-       range->avg_qual.level = 30;
-       range->avg_qual.noise = 8;
-
-       range->num_bitrates = 1;
-       range->bitrate[0] = 2000000;    /* 2 Mb/s */
-
-       /* Event capability (kernel + driver) */
-       range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
-                               IW_EVENT_CAPA_MASK(0x8B04) |
-                               IW_EVENT_CAPA_MASK(0x8B06));
-       range->event_capa[1] = IW_EVENT_CAPA_K_1;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
-       if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-             (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
-               range->num_channels = 10;
-               range->num_frequency = wv_frequency_list(base, range->freq,
-                                                       IW_MAX_FREQUENCIES);
-       } else
-               range->num_channels = range->num_frequency = 0;
-
-       /* Encryption supported ? */
-       if (mmc_encr(base)) {
-               range->encoding_size[0] = 8;    /* DES = 64 bits key */
-               range->num_encoding_sizes = 1;
-               range->max_encoding_tokens = 1; /* Only one key possible */
-       } else {
-               range->num_encoding_sizes = 0;
-               range->max_encoding_tokens = 0;
-       }
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return ret;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set quality threshold
- */
-static int wavelan_set_qthr(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       unsigned int base = dev->base_addr;
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       psa.psa_quality_thr = *(extra) & 0x0F;
-       psa_write(dev,
-                 (char *) &psa.psa_quality_thr - (char *) &psa,
-                 (unsigned char *) &psa.psa_quality_thr, 1);
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev);
-       mmc_out(base, mmwoff(0, mmw_quality_thr),
-               psa.psa_quality_thr);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get quality threshold
- */
-static int wavelan_get_qthr(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-       psa_t psa;
-       unsigned long flags;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       psa_read(dev,
-                (char *) &psa.psa_quality_thr - (char *) &psa,
-                (unsigned char *) &psa.psa_quality_thr, 1);
-       *(extra) = psa.psa_quality_thr & 0x0F;
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return 0;
-}
-
-#ifdef WAVELAN_ROAMING
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set roaming
- */
-static int wavelan_set_roam(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-       unsigned long flags;
-
-       /* Disable interrupts and save flags. */
-       spin_lock_irqsave(&lp->spinlock, flags);
-       
-       /* Note : should check if user == root */
-       if(do_roaming && (*extra)==0)
-               wv_roam_cleanup(dev);
-       else if(do_roaming==0 && (*extra)!=0)
-               wv_roam_init(dev);
-
-       do_roaming = (*extra);
-
-       /* Enable interrupts and restore flags. */
-       spin_unlock_irqrestore(&lp->spinlock, flags);
-
-       return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get quality threshold
- */
-static int wavelan_get_roam(struct net_device *dev,
-                           struct iw_request_info *info,
-                           union iwreq_data *wrqu,
-                           char *extra)
-{
-       *(extra) = do_roaming;
-
-       return 0;
-}
-#endif /* WAVELAN_ROAMING */
-
-#ifdef HISTOGRAM
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : set histogram
- */
-static int wavelan_set_histo(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-
-       /* Check the number of intervals. */
-       if (wrqu->data.length > 16) {
-               return(-E2BIG);
-       }
-
-       /* Disable histo while we copy the addresses.
-        * As we don't disable interrupts, we need to do this */
-       lp->his_number = 0;
-
-       /* Are there ranges to copy? */
-       if (wrqu->data.length > 0) {
-               /* Copy interval ranges to the driver */
-               memcpy(lp->his_range, extra, wrqu->data.length);
-
-               {
-                 int i;
-                 printk(KERN_DEBUG "Histo :");
-                 for(i = 0; i < wrqu->data.length; i++)
-                   printk(" %d", lp->his_range[i]);
-                 printk("\n");
-               }
-
-               /* Reset result structure. */
-               memset(lp->his_sum, 0x00, sizeof(long) * 16);
-       }
-
-       /* Now we can set the number of ranges */
-       lp->his_number = wrqu->data.length;
-
-       return(0);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wireless Private Handler : get histogram
- */
-static int wavelan_get_histo(struct net_device *dev,
-                            struct iw_request_info *info,
-                            union iwreq_data *wrqu,
-                            char *extra)
-{
-       net_local *lp = netdev_priv(dev);
-
-       /* Set the number of intervals. */
-       wrqu->data.length = lp->his_number;
-
-       /* Give back the distribution statistics */
-       if(lp->his_number > 0)
-               memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
-
-       return(0);
-}
-#endif                 /* HISTOGRAM */
-
-/*------------------------------------------------------------------*/
-/*
- * Structures to export the Wireless Handlers
- */
-
-static const struct iw_priv_args wavelan_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
-  { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
-  { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setroam" },
-  { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
-  { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16,                    0, "sethisto" },
-  { SIOCGIPHISTO, 0,                     IW_PRIV_TYPE_INT | 16, "gethisto" },
-};
-
-static const iw_handler                wavelan_handler[] =
-{
-       NULL,                           /* SIOCSIWNAME */
-       wavelan_get_name,               /* SIOCGIWNAME */
-       wavelan_set_nwid,               /* SIOCSIWNWID */
-       wavelan_get_nwid,               /* SIOCGIWNWID */
-       wavelan_set_freq,               /* SIOCSIWFREQ */
-       wavelan_get_freq,               /* SIOCGIWFREQ */
-#ifdef WAVELAN_ROAMING
-       wavelan_set_mode,               /* SIOCSIWMODE */
-       wavelan_get_mode,               /* SIOCGIWMODE */
-#else  /* WAVELAN_ROAMING */
-       NULL,                           /* SIOCSIWMODE */
-       NULL,                           /* SIOCGIWMODE */
-#endif /* WAVELAN_ROAMING */
-       wavelan_set_sens,               /* SIOCSIWSENS */
-       wavelan_get_sens,               /* SIOCGIWSENS */
-       NULL,                           /* SIOCSIWRANGE */
-       wavelan_get_range,              /* SIOCGIWRANGE */
-       NULL,                           /* SIOCSIWPRIV */
-       NULL,                           /* SIOCGIWPRIV */
-       NULL,                           /* SIOCSIWSTATS */
-       NULL,                           /* SIOCGIWSTATS */
-       iw_handler_set_spy,             /* SIOCSIWSPY */
-       iw_handler_get_spy,             /* SIOCGIWSPY */
-       iw_handler_set_thrspy,          /* SIOCSIWTHRSPY */
-       iw_handler_get_thrspy,          /* SIOCGIWTHRSPY */
-#ifdef WAVELAN_ROAMING_EXT
-       wavelan_set_wap,                /* SIOCSIWAP */
-       wavelan_get_wap,                /* SIOCGIWAP */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCGIWAPLIST */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* -- hole -- */
-       wavelan_set_essid,              /* SIOCSIWESSID */
-       wavelan_get_essid,              /* SIOCGIWESSID */
-#else  /* WAVELAN_ROAMING_EXT */
-       NULL,                           /* SIOCSIWAP */
-       NULL,                           /* SIOCGIWAP */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCGIWAPLIST */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCSIWESSID */
-       NULL,                           /* SIOCGIWESSID */
-#endif /* WAVELAN_ROAMING_EXT */
-       NULL,                           /* SIOCSIWNICKN */
-       NULL,                           /* SIOCGIWNICKN */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* -- hole -- */
-       NULL,                           /* SIOCSIWRATE */
-       NULL,                           /* SIOCGIWRATE */
-       NULL,                           /* SIOCSIWRTS */
-       NULL,                           /* SIOCGIWRTS */
-       NULL,                           /* SIOCSIWFRAG */
-       NULL,                           /* SIOCGIWFRAG */
-       NULL,                           /* SIOCSIWTXPOW */
-       NULL,                           /* SIOCGIWTXPOW */
-       NULL,                           /* SIOCSIWRETRY */
-       NULL,                           /* SIOCGIWRETRY */
-       wavelan_set_encode,             /* SIOCSIWENCODE */
-       wavelan_get_encode,             /* SIOCGIWENCODE */
-};
-
-static const iw_handler                wavelan_private_handler[] =
-{
-       wavelan_set_qthr,               /* SIOCIWFIRSTPRIV */
-       wavelan_get_qthr,               /* SIOCIWFIRSTPRIV + 1 */
-#ifdef WAVELAN_ROAMING
-       wavelan_set_roam,               /* SIOCIWFIRSTPRIV + 2 */
-       wavelan_get_roam,               /* SIOCIWFIRSTPRIV + 3 */
-#else  /* WAVELAN_ROAMING */
-       NULL,                           /* SIOCIWFIRSTPRIV + 2 */
-       NULL,                           /* SIOCIWFIRSTPRIV + 3 */
-#endif /* WAVELAN_ROAMING */
-#ifdef HISTOGRAM
-       wavelan_set_histo,              /* SIOCIWFIRSTPRIV + 4 */
-       wavelan_get_histo,              /* SIOCIWFIRSTPRIV + 5 */
-#endif /* HISTOGRAM */
-};
-
-static const struct iw_handler_def     wavelan_handler_def =
-{
-       .num_standard   = ARRAY_SIZE(wavelan_handler),
-       .num_private    = ARRAY_SIZE(wavelan_private_handler),
-       .num_private_args = ARRAY_SIZE(wavelan_private_args),
-       .standard       = wavelan_handler,
-       .private        = wavelan_private_handler,
-       .private_args   = wavelan_private_args,
-       .get_wireless_stats = wavelan_get_wireless_stats,
-};
-
-/*------------------------------------------------------------------*/
-/*
- * Get wireless statistics
- * Called by /proc/net/wireless...
- */
-static iw_stats *
-wavelan_get_wireless_stats(struct net_device * dev)
-{
-  unsigned int         base = dev->base_addr;
-  net_local *          lp = netdev_priv(dev);
-  mmr_t                        m;
-  iw_stats *           wstats;
-  unsigned long                flags;
-
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name);
-#endif
-
-  /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  wstats = &lp->wstats;
-
-  /* Get data from the mmc */
-  mmc_out(base, mmwoff(0, mmw_freeze), 1);
-
-  mmc_read(base, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
-  mmc_read(base, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, 2);
-  mmc_read(base, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, 4);
-
-  mmc_out(base, mmwoff(0, mmw_freeze), 0);
-
-  /* Copy data to wireless stuff */
-  wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
-  wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
-  wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
-  wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
-  wstats->qual.updated = (((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) |
-                         ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) |
-                         ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
-  wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-  wstats->discard.code = 0L;
-  wstats->discard.misc = 0L;
-
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_IOCTL_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name);
-#endif
-  return &lp->wstats;
-}
-
-/************************* PACKET RECEPTION *************************/
-/*
- * This part deal with receiving the packets.
- * The interrupt handler get an interrupt when a packet has been
- * successfully received and called this part...
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Calculate the starting address of the frame pointed to by the receive
- * frame pointer and verify that the frame seem correct
- * (called by wv_packet_rcv())
- */
-static int
-wv_start_of_frame(struct net_device *  dev,
-                 int           rfp,    /* end of frame */
-                 int           wrap)   /* start of buffer */
-{
-  unsigned int base = dev->base_addr;
-  int          rp;
-  int          len;
-
-  rp = (rfp - 5 + RX_SIZE) % RX_SIZE;
-  outb(rp & 0xff, PIORL(base));
-  outb(((rp >> 8) & PIORH_MASK), PIORH(base));
-  len = inb(PIOP(base));
-  len |= inb(PIOP(base)) << 8;
-
-  /* Sanity checks on size */
-  /* Frame too big */
-  if(len > MAXDATAZ + 100)
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_start_of_frame: Received frame too large, rfp %d len 0x%x\n",
-            dev->name, rfp, len);
-#endif
-      return(-1);
-    }
-  
-  /* Frame too short */
-  if(len < 7)
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_start_of_frame: Received null frame, rfp %d len 0x%x\n",
-            dev->name, rfp, len);
-#endif
-      return(-1);
-    }
-  
-  /* Wrap around buffer */
-  if(len > ((wrap - (rfp - len) + RX_SIZE) % RX_SIZE)) /* magic formula ! */
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_start_of_frame: wrap around buffer, wrap %d rfp %d len 0x%x\n",
-            dev->name, wrap, rfp, len);
-#endif
-      return(-1);
-    }
-
-  return((rp - len + RX_SIZE) % RX_SIZE);
-} /* wv_start_of_frame */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does the actual copy of data (including the ethernet
- * header structure) from the WaveLAN card to an sk_buff chain that
- * will be passed up to the network interface layer. NOTE: We
- * currently don't handle trailer protocols (neither does the rest of
- * the network interface), so if that is needed, it will (at least in
- * part) be added here.  The contents of the receive ring buffer are
- * copied to a message chain that is then passed to the kernel.
- *
- * Note: if any errors occur, the packet is "dropped on the floor"
- * (called by wv_packet_rcv())
- */
-static void
-wv_packet_read(struct net_device *             dev,
-              int              fd_p,
-              int              sksize)
-{
-  net_local *          lp = netdev_priv(dev);
-  struct sk_buff *     skb;
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
-        dev->name, fd_p, sksize);
-#endif
-
-  /* Allocate some buffer for the new packet */
-  if((skb = dev_alloc_skb(sksize+2)) == (struct sk_buff *) NULL)
-    {
-#ifdef DEBUG_RX_ERROR
-      printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
-            dev->name, sksize);
-#endif
-      dev->stats.rx_dropped++;
-      /*
-       * Not only do we want to return here, but we also need to drop the
-       * packet on the floor to clear the interrupt.
-       */
-      return;
-    }
-
-  skb_reserve(skb, 2);
-  fd_p = read_ringbuf(dev, fd_p, (char *) skb_put(skb, sksize), sksize);
-  skb->protocol = eth_type_trans(skb, dev);
-
-#ifdef DEBUG_RX_INFO
-  wv_packet_info(skb_mac_header(skb), sksize, dev->name, "wv_packet_read");
-#endif /* DEBUG_RX_INFO */
-     
-  /* Statistics gathering & stuff associated.
-   * It seem a bit messy with all the define, but it's really simple... */
-  if(
-#ifdef IW_WIRELESS_SPY
-     (lp->spy_data.spy_number > 0) ||
-#endif /* IW_WIRELESS_SPY */
-#ifdef HISTOGRAM
-     (lp->his_number > 0) ||
-#endif /* HISTOGRAM */
-#ifdef WAVELAN_ROAMING
-     (do_roaming) ||
-#endif /* WAVELAN_ROAMING */
-     0)
-    {
-      u_char   stats[3];       /* Signal level, Noise level, Signal quality */
-
-      /* read signal level, silence level and signal quality bytes */
-      fd_p = read_ringbuf(dev, (fd_p + 4) % RX_SIZE + RX_BASE,
-                         stats, 3);
-#ifdef DEBUG_RX_INFO
-      printk(KERN_DEBUG "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
-            dev->name, stats[0] & 0x3F, stats[1] & 0x3F, stats[2] & 0x0F);
-#endif
-
-#ifdef WAVELAN_ROAMING
-      if(do_roaming)
-       if(WAVELAN_BEACON(skb->data))
-         wl_roam_gather(dev, skb->data, stats);
-#endif /* WAVELAN_ROAMING */
-         
-#ifdef WIRELESS_SPY
-      wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE, stats);
-#endif /* WIRELESS_SPY */
-#ifdef HISTOGRAM
-      wl_his_gather(dev, stats);
-#endif /* HISTOGRAM */
-    }
-
-  /*
-   * Hand the packet to the Network Module
-   */
-  netif_rx(skb);
-
-  /* Keep stats up to date */
-  dev->stats.rx_packets++;
-  dev->stats.rx_bytes += sksize;
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
-#endif
-  return;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine is called by the interrupt handler to initiate a
- * packet transfer from the card to the network interface layer above
- * this driver.  This routine checks if a buffer has been successfully
- * received by the WaveLAN card.  If so, the routine wv_packet_read is
- * called to do the actual transfer of the card's data including the
- * ethernet header into a packet consisting of an sk_buff chain.
- * (called by wavelan_interrupt())
- * Note : the spinlock is already grabbed for us and irq are disabled.
- */
-static void
-wv_packet_rcv(struct net_device *      dev)
-{
-  unsigned int base = dev->base_addr;
-  net_local *  lp = netdev_priv(dev);
-  int          newrfp;
-  int          rp;
-  int          len;
-  int          f_start;
-  int          status;
-  int          i593_rfp;
-  int          stat_ptr;
-  u_char       c[4];
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: ->wv_packet_rcv()\n", dev->name);
-#endif
-
-  /* Get the new receive frame pointer from the i82593 chip */
-  outb(CR0_STATUS_2 | OP0_NOP, LCCR(base));
-  i593_rfp = inb(LCSR(base));
-  i593_rfp |= inb(LCSR(base)) << 8;
-  i593_rfp %= RX_SIZE;
-
-  /* Get the new receive frame pointer from the WaveLAN card.
-   * It is 3 bytes more than the increment of the i82593 receive
-   * frame pointer, for each packet. This is because it includes the
-   * 3 roaming bytes added by the mmc.
-   */
-  newrfp = inb(RPLL(base));
-  newrfp |= inb(RPLH(base)) << 8;
-  newrfp %= RX_SIZE;
-
-#ifdef DEBUG_RX_INFO
-  printk(KERN_DEBUG "%s: wv_packet_rcv(): i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
-        dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
-#endif
-
-#ifdef DEBUG_RX_ERROR
-  /* If no new frame pointer... */
-  if(lp->overrunning || newrfp == lp->rfp)
-    printk(KERN_INFO "%s: wv_packet_rcv(): no new frame: i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
-          dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
-#endif
-
-  /* Read all frames (packets) received */
-  while(newrfp != lp->rfp)
-    {
-      /* A frame is composed of the packet, followed by a status word,
-       * the length of the frame (word) and the mmc info (SNR & qual).
-       * It's because the length is at the end that we can only scan
-       * frames backward. */
-
-      /* Find the first frame by skipping backwards over the frames */
-      rp = newrfp;     /* End of last frame */
-      while(((f_start = wv_start_of_frame(dev, rp, newrfp)) != lp->rfp) &&
-           (f_start != -1))
-         rp = f_start;
-
-      /* If we had a problem */
-      if(f_start == -1)
-       {
-#ifdef DEBUG_RX_ERROR
-         printk(KERN_INFO "wavelan_cs: cannot find start of frame ");
-         printk(" i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
-                i593_rfp, lp->stop, newrfp, lp->rfp);
-#endif
-         lp->rfp = rp;         /* Get to the last usable frame */
-         continue;
-       }
-
-      /* f_start point to the beggining of the first frame received
-       * and rp to the beggining of the next one */
-
-      /* Read status & length of the frame */
-      stat_ptr = (rp - 7 + RX_SIZE) % RX_SIZE;
-      stat_ptr = read_ringbuf(dev, stat_ptr, c, 4);
-      status = c[0] | (c[1] << 8);
-      len = c[2] | (c[3] << 8);
-
-      /* Check status */
-      if((status & RX_RCV_OK) != RX_RCV_OK)
-       {
-         dev->stats.rx_errors++;
-         if(status & RX_NO_SFD)
-           dev->stats.rx_frame_errors++;
-         if(status & RX_CRC_ERR)
-           dev->stats.rx_crc_errors++;
-         if(status & RX_OVRRUN)
-           dev->stats.rx_over_errors++;
-
-#ifdef DEBUG_RX_FAIL
-         printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
-                dev->name, status);
-#endif
-       }
-      else
-       /* Read the packet and transmit to Linux */
-       wv_packet_read(dev, f_start, len - 2);
-
-      /* One frame has been processed, skip it */
-      lp->rfp = rp;
-    }
-
-  /*
-   * Update the frame stop register, but set it to less than
-   * the full 8K to allow space for 3 bytes of signal strength
-   * per packet.
-   */
-  lp->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
-  outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
-  outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
-  outb(OP1_SWIT_TO_PORT_0, LCCR(base));
-
-#ifdef DEBUG_RX_TRACE
-  printk(KERN_DEBUG "%s: <-wv_packet_rcv()\n", dev->name);
-#endif
-}
-
-/*********************** PACKET TRANSMISSION ***********************/
-/*
- * This part deal with sending packet through the wavelan
- * We copy the packet to the send buffer and then issue the send
- * command to the i82593. The result of this operation will be
- * checked in wavelan_interrupt()
- */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine fills in the appropriate registers and memory
- * locations on the WaveLAN card and starts the card off on
- * the transmit.
- * (called in wavelan_packet_xmit())
- */
-static void
-wv_packet_write(struct net_device *    dev,
-               void *          buf,
-               short           length)
-{
-  net_local *          lp = netdev_priv(dev);
-  unsigned int         base = dev->base_addr;
-  unsigned long                flags;
-  int                  clen = length;
-  register u_short     xmtdata_base = TX_BASE;
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length);
-#endif
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Write the length of data buffer followed by the buffer */
-  outb(xmtdata_base & 0xff, PIORL(base));
-  outb(((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-  outb(clen & 0xff, PIOP(base));       /* lsb */
-  outb(clen >> 8, PIOP(base));         /* msb */
-
-  /* Send the data */
-  outsb(PIOP(base), buf, clen);
-
-  /* Indicate end of transmit chain */
-  outb(OP0_NOP, PIOP(base));
-  /* josullvn@cs.cmu.edu: need to send a second NOP for alignment... */
-  outb(OP0_NOP, PIOP(base));
-
-  /* Reset the transmit DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-  /* Send the transmit command */
-  wv_82593_cmd(dev, "wv_packet_write(): transmit",
-              OP0_TRANSMIT, SR0_NO_RESULT);
-
-  /* Make sure the watchdog will keep quiet for a while */
-  dev->trans_start = jiffies;
-
-  /* Keep stats up to date */
-  dev->stats.tx_bytes += length;
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_TX_INFO
-  wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write");
-#endif /* DEBUG_TX_INFO */
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the harware is ready to accept
- * the packet. We also prevent reentrance. Then, we call the function
- * to send the packet...
- */
-static netdev_tx_t
-wavelan_packet_xmit(struct sk_buff *   skb,
-                   struct net_device *         dev)
-{
-  net_local *          lp = netdev_priv(dev);
-  unsigned long                flags;
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
-        (unsigned) skb);
-#endif
-
-  /*
-   * Block a timer-based transmit from overlapping a previous transmit.
-   * In other words, prevent reentering this routine.
-   */
-  netif_stop_queue(dev);
-
-  /* If somebody has asked to reconfigure the controller,
-   * we can do it now */
-  if(lp->reconfig_82593)
-    {
-      spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */
-      wv_82593_config(dev);
-      spin_unlock_irqrestore(&lp->spinlock, flags);    /* Re-enable interrupts */
-      /* Note : the configure procedure was totally synchronous,
-       * so the Tx buffer is now free */
-    }
-
-       /* Check if we need some padding */
-       /* Note : on wireless the propagation time is in the order of 1us,
-        * and we don't have the Ethernet specific requirement of beeing
-        * able to detect collisions, therefore in theory we don't really
-        * need to pad. Jean II */
-       if (skb_padto(skb, ETH_ZLEN))
-               return NETDEV_TX_OK;
-
-  wv_packet_write(dev, skb->data, skb->len);
-
-  dev_kfree_skb(skb);
-
-#ifdef DEBUG_TX_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
-#endif
-  return NETDEV_TX_OK;
-}
-
-/********************** HARDWARE CONFIGURATION **********************/
-/*
- * This part do the real job of starting and configuring the hardware.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to initialize the Modem Management Controller.
- * (called by wv_hw_config())
- */
-static int
-wv_mmc_init(struct net_device *        dev)
-{
-  unsigned int base = dev->base_addr;
-  psa_t                psa;
-  mmw_t                m;
-  int          configured;
-  int          i;              /* Loop counter */
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
-#endif
-
-  /* Read the parameter storage area */
-  psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-
-  /*
-   * Check the first three octets of the MAC addr for the manufacturer's code.
-   * Note: If you get the error message below, you've got a
-   * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on
-   * how to configure your card...
-   */
-  for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
-    if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
-        (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
-        (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
-      break;
-
-  /* If we have not found it... */
-  if (i == ARRAY_SIZE(MAC_ADDRESSES))
-    {
-#ifdef DEBUG_CONFIG_ERRORS
-      printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
-            dev->name, psa.psa_univ_mac_addr[0],
-            psa.psa_univ_mac_addr[1], psa.psa_univ_mac_addr[2]);
-#endif
-      return FALSE;
-    }
-
-  /* Get the MAC address */
-  memcpy(&dev->dev_addr[0], &psa.psa_univ_mac_addr[0], WAVELAN_ADDR_SIZE);
-
-#ifdef USE_PSA_CONFIG
-  configured = psa.psa_conf_status & 1;
-#else
-  configured = 0;
-#endif
-
-  /* Is the PSA is not configured */
-  if(!configured)
-    {
-      /* User will be able to configure NWID after (with iwconfig) */
-      psa.psa_nwid[0] = 0;
-      psa.psa_nwid[1] = 0;
-
-      /* As NWID is not set : no NWID checking */
-      psa.psa_nwid_select = 0;
-
-      /* Disable encryption */
-      psa.psa_encryption_select = 0;
-
-      /* Set to standard values
-       * 0x04 for AT,
-       * 0x01 for MCA,
-       * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document)
-       */
-      if (psa.psa_comp_number & 1)
-       psa.psa_thr_pre_set = 0x01;
-      else
-       psa.psa_thr_pre_set = 0x04;
-      psa.psa_quality_thr = 0x03;
-
-      /* It is configured */
-      psa.psa_conf_status |= 1;
-
-#ifdef USE_PSA_CONFIG
-      /* Write the psa */
-      psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,
-               (unsigned char *)psa.psa_nwid, 4);
-      psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
-               (unsigned char *)&psa.psa_thr_pre_set, 1);
-      psa_write(dev, (char *)&psa.psa_quality_thr - (char *)&psa,
-               (unsigned char *)&psa.psa_quality_thr, 1);
-      psa_write(dev, (char *)&psa.psa_conf_status - (char *)&psa,
-               (unsigned char *)&psa.psa_conf_status, 1);
-      /* update the Wavelan checksum */
-      update_psa_checksum(dev);
-#endif /* USE_PSA_CONFIG */
-    }
-
-  /* Zero the mmc structure */
-  memset(&m, 0x00, sizeof(m));
-
-  /* Copy PSA info to the mmc */
-  m.mmw_netw_id_l = psa.psa_nwid[1];
-  m.mmw_netw_id_h = psa.psa_nwid[0];
-  
-  if(psa.psa_nwid_select & 1)
-    m.mmw_loopt_sel = 0x00;
-  else
-    m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
-
-  memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, 
-        sizeof(m.mmw_encr_key));
-
-  if(psa.psa_encryption_select)
-    m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
-  else
-    m.mmw_encr_enable = 0;
-
-  m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
-  m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
-
-  /*
-   * Set default modem control parameters.
-   * See NCR document 407-0024326 Rev. A.
-   */
-  m.mmw_jabber_enable = 0x01;
-  m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
-  m.mmw_ifs = 0x20;
-  m.mmw_mod_delay = 0x04;
-  m.mmw_jam_time = 0x38;
-
-  m.mmw_des_io_invert = 0;
-  m.mmw_freeze = 0;
-  m.mmw_decay_prm = 0;
-  m.mmw_decay_updat_prm = 0;
-
-  /* Write all info to mmc */
-  mmc_write(base, 0, (u_char *)&m, sizeof(m));
-
-  /* The following code start the modem of the 2.00 frequency
-   * selectable cards at power on. It's not strictly needed for the
-   * following boots...
-   * The original patch was by Joe Finney for the PCMCIA driver, but
-   * I've cleaned it a bit and add documentation.
-   * Thanks to Loeke Brederveld from Lucent for the info.
-   */
-
-  /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
-   * (does it work for everybody ? - especially old cards...) */
-  /* Note : WFREQSEL verify that it is able to read from EEprom
-   * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID
-   * is 0xA (Xilinx version) or 0xB (Ariadne version).
-   * My test is more crude but do work... */
-  if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
-       (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
-    {
-      /* We must download the frequency parameters to the
-       * synthetisers (from the EEprom - area 1)
-       * Note : as the EEprom is auto decremented, we set the end
-       * if the area... */
-      m.mmw_fee_addr = 0x0F;
-      m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-      mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
-               (unsigned char *)&m.mmw_fee_ctrl, 2);
-
-      /* Wait until the download is finished */
-      fee_wait(base, 100, 100);
-
-#ifdef DEBUG_CONFIG_INFO
-      /* The frequency was in the last word downloaded... */
-      mmc_read(base, (char *)&m.mmw_fee_data_l - (char *)&m,
-              (unsigned char *)&m.mmw_fee_data_l, 2);
-
-      /* Print some info for the user */
-      printk(KERN_DEBUG "%s: Wavelan 2.00 recognised (frequency select) : Current frequency = %ld\n",
-            dev->name,
-            ((m.mmw_fee_data_h << 4) |
-             (m.mmw_fee_data_l >> 4)) * 5 / 2 + 24000L);
-#endif
-
-      /* We must now download the power adjust value (gain) to
-       * the synthetisers (from the EEprom - area 7 - DAC) */
-      m.mmw_fee_addr = 0x61;
-      m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
-      mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
-               (unsigned char *)&m.mmw_fee_ctrl, 2);
-
-      /* Wait until the download is finished */
-    }  /* if 2.00 card */
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Routine to gracefully turn off reception, and wait for any commands
- * to complete.
- * (called in wv_ru_start() and wavelan_close() and wavelan_event())
- */
-static int
-wv_ru_stop(struct net_device * dev)
-{
-  unsigned int base = dev->base_addr;
-  net_local *  lp = netdev_priv(dev);
-  unsigned long        flags;
-  int          status;
-  int          spin;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name);
-#endif
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* First, send the LAN controller a stop receive command */
-  wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv",
-              OP0_STOP_RCV, SR0_NO_RESULT);
-
-  /* Then, spin until the receive unit goes idle */
-  spin = 300;
-  do
-    {
-      udelay(10);
-      outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-      status = inb(LCSR(base));
-    }
-  while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0));
-
-  /* Now, spin until the chip finishes executing its current command */
-  do
-    {
-      udelay(10);
-      outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-      status = inb(LCSR(base));
-    }
-  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  /* If there was a problem */
-  if(spin <= 0)
-    {
-#ifdef DEBUG_CONFIG_ERRORS
-      printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
-            dev->name);
-#endif
-      return FALSE;
-    }
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_ru_stop()\n", dev->name);
-#endif
-  return TRUE;
-} /* wv_ru_stop */
-
-/*------------------------------------------------------------------*/
-/*
- * This routine starts the receive unit running.  First, it checks if
- * the card is actually ready. Then the card is instructed to receive
- * packets again.
- * (called in wv_hw_reset() & wavelan_open())
- */
-static int
-wv_ru_start(struct net_device *        dev)
-{
-  unsigned int base = dev->base_addr;
-  net_local *  lp = netdev_priv(dev);
-  unsigned long        flags;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
-#endif
-
-  /*
-   * We need to start from a quiescent state. To do so, we could check
-   * if the card is already running, but instead we just try to shut
-   * it down. First, we disable reception (in case it was already enabled).
-   */
-  if(!wv_ru_stop(dev))
-    return FALSE;
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Now we know that no command is being executed. */
-
-  /* Set the receive frame pointer and stop pointer */
-  lp->rfp = 0;
-  outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
-
-  /* Reset ring management.  This sets the receive frame pointer to 1 */
-  outb(OP1_RESET_RING_MNGMT, LCCR(base));
-
-#if 0
-  /* XXX the i82593 manual page 6-4 seems to indicate that the stop register
-     should be set as below */
-  /* outb(CR1_STOP_REG_UPDATE|((RX_SIZE - 0x40)>> RX_SIZE_SHIFT),LCCR(base));*/
-#elif 0
-  /* but I set it 0 instead */
-  lp->stop = 0;
-#else
-  /* but I set it to 3 bytes per packet less than 8K */
-  lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
-#endif
-  outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
-  outb(OP1_INT_ENABLE, LCCR(base));
-  outb(OP1_SWIT_TO_PORT_0, LCCR(base));
-
-  /* Reset receive DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write_slow(base, HACR_DEFAULT);
-
-  /* Receive DMA on channel 1 */
-  wv_82593_cmd(dev, "wv_ru_start(): rcv-enable",
-              CR0_CHNL | OP0_RCV_ENABLE, SR0_NO_RESULT);
-
-#ifdef DEBUG_I82593_SHOW
-  {
-    int        status;
-    int        opri;
-    int        spin = 10000;
-
-    /* spin until the chip starts receiving */
-    do
-      {
-       outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
-       status = inb(LCSR(base));
-       if(spin-- <= 0)
-         break;
-      }
-    while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) &&
-         ((status & SR3_RCV_STATE_MASK) != SR3_RCV_READY));
-    printk(KERN_DEBUG "rcv status is 0x%x [i:%d]\n",
-          (status & SR3_RCV_STATE_MASK), i);
-  }
-#endif
-
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This routine does a standard config of the WaveLAN controller (i82593).
- * In the ISA driver, this is integrated in wavelan_hardware_reset()
- * (called by wv_hw_config(), wv_82593_reconfig() & wavelan_packet_xmit())
- */
-static int
-wv_82593_config(struct net_device *    dev)
-{
-  unsigned int                 base = dev->base_addr;
-  net_local *                  lp = netdev_priv(dev);
-  struct i82593_conf_block     cfblk;
-  int                          ret = TRUE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name);
-#endif
-
-  /* Create & fill i82593 config block
-   *
-   * Now conform to Wavelan document WCIN085B
-   */
-  memset(&cfblk, 0x00, sizeof(struct i82593_conf_block));
-  cfblk.d6mod = FALSE;         /* Run in i82593 advanced mode */
-  cfblk.fifo_limit = 5;         /* = 56 B rx and 40 B tx fifo thresholds */
-  cfblk.forgnesi = FALSE;       /* 0=82C501, 1=AMD7992B compatibility */
-  cfblk.fifo_32 = 1;
-  cfblk.throttle_enb = FALSE;
-  cfblk.contin = TRUE;          /* enable continuous mode */
-  cfblk.cntrxint = FALSE;       /* enable continuous mode receive interrupts */
-  cfblk.addr_len = WAVELAN_ADDR_SIZE;
-  cfblk.acloc = TRUE;           /* Disable source addr insertion by i82593 */
-  cfblk.preamb_len = 0;         /* 2 bytes preamble (SFD) */
-  cfblk.loopback = FALSE;
-  cfblk.lin_prio = 0;          /* conform to 802.3 backoff algorithm */
-  cfblk.exp_prio = 5;          /* conform to 802.3 backoff algorithm */
-  cfblk.bof_met = 1;           /* conform to 802.3 backoff algorithm */
-  cfblk.ifrm_spc = 0x20 >> 4;  /* 32 bit times interframe spacing */
-  cfblk.slottim_low = 0x20 >> 5;       /* 32 bit times slot time */
-  cfblk.slottim_hi = 0x0;
-  cfblk.max_retr = 15;
-  cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE);    /* Promiscuous mode */
-  cfblk.bc_dis = FALSE;         /* Enable broadcast reception */
-  cfblk.crs_1 = TRUE;          /* Transmit without carrier sense */
-  cfblk.nocrc_ins = FALSE;     /* i82593 generates CRC */      
-  cfblk.crc_1632 = FALSE;      /* 32-bit Autodin-II CRC */
-  cfblk.crs_cdt = FALSE;       /* CD not to be interpreted as CS */
-  cfblk.cs_filter = 0;         /* CS is recognized immediately */
-  cfblk.crs_src = FALSE;       /* External carrier sense */
-  cfblk.cd_filter = 0;         /* CD is recognized immediately */
-  cfblk.min_fr_len = ETH_ZLEN >> 2;     /* Minimum frame length 64 bytes */
-  cfblk.lng_typ = FALSE;       /* Length field > 1500 = type field */
-  cfblk.lng_fld = TRUE;        /* Disable 802.3 length field check */
-  cfblk.rxcrc_xf = TRUE;       /* Don't transfer CRC to memory */
-  cfblk.artx = TRUE;           /* Disable automatic retransmission */
-  cfblk.sarec = TRUE;          /* Disable source addr trig of CD */
-  cfblk.tx_jabber = TRUE;      /* Disable jabber jam sequence */
-  cfblk.hash_1 = FALSE;        /* Use bits 0-5 in mc address hash */
-  cfblk.lbpkpol = TRUE;        /* Loopback pin active high */
-  cfblk.fdx = FALSE;           /* Disable full duplex operation */
-  cfblk.dummy_6 = 0x3f;        /* all ones */
-  cfblk.mult_ia = FALSE;       /* No multiple individual addresses */
-  cfblk.dis_bof = FALSE;       /* Disable the backoff algorithm ?! */
-  cfblk.dummy_1 = TRUE;        /* set to 1 */
-  cfblk.tx_ifs_retrig = 3;     /* Hmm... Disabled */
-#ifdef MULTICAST_ALL
-  cfblk.mc_all = (lp->allmulticast ? TRUE: FALSE);     /* Allow all multicasts */
-#else
-  cfblk.mc_all = FALSE;                /* No multicast all mode */
-#endif
-  cfblk.rcv_mon = 0;           /* Monitor mode disabled */
-  cfblk.frag_acpt = TRUE;      /* Do not accept fragments */
-  cfblk.tstrttrs = FALSE;      /* No start transmission threshold */
-  cfblk.fretx = TRUE;          /* FIFO automatic retransmission */
-  cfblk.syncrqs = FALSE;       /* Synchronous DRQ deassertion... */
-  cfblk.sttlen = TRUE;         /* 6 byte status registers */
-  cfblk.rx_eop = TRUE;         /* Signal EOP on packet reception */
-  cfblk.tx_eop = TRUE;         /* Signal EOP on packet transmission */
-  cfblk.rbuf_size = RX_SIZE>>11;       /* Set receive buffer size */
-  cfblk.rcvstop = TRUE;        /* Enable Receive Stop Register */
-
-#ifdef DEBUG_I82593_SHOW
-  print_hex_dump(KERN_DEBUG, "wavelan_cs: config block: ", DUMP_PREFIX_NONE,
-                16, 1, &cfblk, sizeof(struct i82593_conf_block), false);
-#endif
-
-  /* Copy the config block to the i82593 */
-  outb(TX_BASE & 0xff, PIORL(base));
-  outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-  outb(sizeof(struct i82593_conf_block) & 0xff, PIOP(base));    /* lsb */
-  outb(sizeof(struct i82593_conf_block) >> 8, PIOP(base));     /* msb */
-  outsb(PIOP(base), (char *) &cfblk, sizeof(struct i82593_conf_block));
-
-  /* reset transmit DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-  if(!wv_82593_cmd(dev, "wv_82593_config(): configure",
-                  OP0_CONFIGURE, SR0_CONFIGURE_DONE))
-    ret = FALSE;
-
-  /* Initialize adapter's ethernet MAC address */
-  outb(TX_BASE & 0xff, PIORL(base));
-  outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-  outb(WAVELAN_ADDR_SIZE, PIOP(base)); /* byte count lsb */
-  outb(0, PIOP(base));                 /* byte count msb */
-  outsb(PIOP(base), &dev->dev_addr[0], WAVELAN_ADDR_SIZE);
-
-  /* reset transmit DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-  if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup",
-                  OP0_IA_SETUP, SR0_IA_SETUP_DONE))
-    ret = FALSE;
-
-#ifdef WAVELAN_ROAMING
-    /* If roaming is enabled, join the "Beacon Request" multicast group... */
-    /* But only if it's not in there already! */
-  if(do_roaming)
-    dev_mc_add(dev,WAVELAN_BEACON_ADDRESS, WAVELAN_ADDR_SIZE, 1);
-#endif /* WAVELAN_ROAMING */
-
-  /* If any multicast address to set */
-  if(lp->mc_count)
-    {
-      struct dev_mc_list *dmi;
-      int                      addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
-
-#ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
-            dev->name, lp->mc_count);
-      netdev_for_each_mc_addr(dmi, dev)
-       printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
-#endif
-
-      /* Initialize adapter's ethernet multicast addresses */
-      outb(TX_BASE & 0xff, PIORL(base));
-      outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
-      outb(addrs_len & 0xff, PIOP(base));      /* byte count lsb */
-      outb((addrs_len >> 8), PIOP(base));      /* byte count msb */
-      netdev_for_each_mc_addr(dmi, dev)
-       outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen);
-
-      /* reset transmit DMA pointer */
-      hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
-      hacr_write(base, HACR_DEFAULT);
-      if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup",
-                      OP0_MC_SETUP, SR0_MC_SETUP_DONE))
-       ret = FALSE;
-      /* remember to avoid repeated reset */
-      lp->mc_count = netdev_mc_count(dev);
-    }
-
-  /* Job done, clear the flag */
-  lp->reconfig_82593 = FALSE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name);
-#endif
-  return(ret);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Read the Access Configuration Register, perform a software reset,
- * and then re-enable the card's software.
- *
- * If I understand correctly : reset the pcmcia interface of the
- * wavelan.
- * (called by wv_config())
- */
-static int
-wv_pcmcia_reset(struct net_device *    dev)
-{
-  int          i;
-  conf_reg_t   reg = { 0, CS_READ, CISREG_COR, 0 };
-  struct pcmcia_device *       link = ((net_local *)netdev_priv(dev))->link;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name);
-#endif
-
-  i = pcmcia_access_configuration_register(link, ®);
-  if (i != 0)
-      return FALSE;
-      
-#ifdef DEBUG_CONFIG_INFO
-  printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
-        dev->name, (u_int) reg.Value);
-#endif
-
-  reg.Action = CS_WRITE;
-  reg.Value = reg.Value | COR_SW_RESET;
-  i = pcmcia_access_configuration_register(link, ®);
-  if (i != 0)
-      return FALSE;
-      
-  reg.Action = CS_WRITE;
-  reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
-  i = pcmcia_access_configuration_register(link, ®);
-  if (i != 0)
-      return FALSE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * wavelan_hw_config() is called after a CARD_INSERTION event is
- * received, to configure the wavelan hardware.
- * Note that the reception will be enabled in wavelan->open(), so the
- * device is configured but idle...
- * Performs the following actions:
- *     1. A pcmcia software reset (using wv_pcmcia_reset())
- *     2. A power reset (reset DMA)
- *     3. Reset the LAN controller
- *     4. Initialize the radio modem (using wv_mmc_init)
- *     5. Configure LAN controller (using wv_82593_config)
- *     6. Perform a diagnostic on the LAN controller
- * (called by wavelan_event() & wv_hw_reset())
- */
-static int
-wv_hw_config(struct net_device *       dev)
-{
-  net_local *          lp = netdev_priv(dev);
-  unsigned int         base = dev->base_addr;
-  unsigned long                flags;
-  int                  ret = FALSE;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
-#endif
-
-  /* compile-time check the sizes of structures */
-  BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
-  BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
-  BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
-
-  /* Reset the pcmcia interface */
-  if(wv_pcmcia_reset(dev) == FALSE)
-    return FALSE;
-
-  /* Disable interrupts */
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Disguised goto ;-) */
-  do
-    {
-      /* Power UP the module + reset the modem + reset host adapter
-       * (in fact, reset DMA channels) */
-      hacr_write_slow(base, HACR_RESET);
-      hacr_write(base, HACR_DEFAULT);
-
-      /* Check if the module has been powered up... */
-      if(hasr_read(base) & HASR_NO_CLK)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n",
-                dev->name);
-#endif
-         break;
-       }
-
-      /* initialize the modem */
-      if(wv_mmc_init(dev) == FALSE)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n",
-                dev->name);
-#endif
-         break;
-       }
-
-      /* reset the LAN controller (i82593) */
-      outb(OP0_RESET, LCCR(base));
-      mdelay(1);       /* A bit crude ! */
-
-      /* Initialize the LAN controller */
-      if(wv_82593_config(dev) == FALSE)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n",
-                dev->name);
-#endif
-         break;
-       }
-
-      /* Diagnostic */
-      if(wv_diag(dev) == FALSE)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n",
-                dev->name);
-#endif
-         break;
-       }
-
-      /* 
-       * insert code for loopback test here
-       */
-
-      /* The device is now configured */
-      lp->configured = 1;
-      ret = TRUE;
-    }
-  while(0);
-
-  /* Re-enable interrupts */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name);
-#endif
-  return(ret);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Totally reset the wavelan and restart it.
- * Performs the following actions:
- *     1. Call wv_hw_config()
- *     2. Start the LAN controller's receive unit
- * (called by wavelan_event(), wavelan_watchdog() and wavelan_open())
- */
-static void
-wv_hw_reset(struct net_device *        dev)
-{
-  net_local *  lp = netdev_priv(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name);
-#endif
-
-  lp->nresets++;
-  lp->configured = 0;
-  
-  /* Call wv_hw_config() for most of the reset & init stuff */
-  if(wv_hw_config(dev) == FALSE)
-    return;
-
-  /* start receive unit */
-  wv_ru_start(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
-#endif
-}
-
-/*------------------------------------------------------------------*/
-/*
- * wv_pcmcia_config() is called after a CARD_INSERTION event is
- * received, to configure the PCMCIA socket, and to make the ethernet
- * device available to the system.
- * (called by wavelan_event())
- */
-static int
-wv_pcmcia_config(struct pcmcia_device *        link)
-{
-  struct net_device *  dev = (struct net_device *) link->priv;
-  int                  i;
-  win_req_t            req;
-  memreq_t             mem;
-  net_local *          lp = netdev_priv(dev);
-
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
-#endif
-
-  do
-    {
-      i = pcmcia_request_io(link, &link->io);
-      if (i != 0)
-         break;
-
-      /*
-       * Now allocate an interrupt line.  Note that this does not
-       * actually assign a handler to the interrupt.
-       */
-      i = pcmcia_request_irq(link, &link->irq);
-      if (i != 0)
-         break;
-
-      /*
-       * This actually configures the PCMCIA socket -- setting up
-       * the I/O windows and the interrupt mapping.
-       */
-      link->conf.ConfigIndex = 1;
-      i = pcmcia_request_configuration(link, &link->conf);
-      if (i != 0)
-         break;
-
-      /*
-       * Allocate a small memory window.  Note that the struct pcmcia_device
-       * structure provides space for one window handle -- if your
-       * device needs several windows, you'll need to keep track of
-       * the handles in your private data structure, link->priv.
-       */
-      req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
-      req.Base = req.Size = 0;
-      req.AccessSpeed = mem_speed;
-      i = pcmcia_request_window(link, &req, &link->win);
-      if (i != 0)
-         break;
-
-      lp->mem = ioremap(req.Base, req.Size);
-      dev->mem_start = (u_long)lp->mem;
-      dev->mem_end = dev->mem_start + req.Size;
-
-      mem.CardOffset = 0; mem.Page = 0;
-      i = pcmcia_map_mem_page(link, link->win, &mem);
-      if (i != 0)
-         break;
-
-      /* Feed device with this info... */
-      dev->irq = link->irq.AssignedIRQ;
-      dev->base_addr = link->io.BasePort1;
-      netif_start_queue(dev);
-
-#ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n",
-            lp->mem, dev->irq, (u_int) dev->base_addr);
-#endif
-
-      SET_NETDEV_DEV(dev, &link->dev);
-      i = register_netdev(dev);
-      if(i != 0)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_INFO "wv_pcmcia_config(): register_netdev() failed\n");
-#endif
-         break;
-       }
-    }
-  while(0);            /* Humm... Disguised goto !!! */
-
-  /* If any step failed, release any partially configured state */
-  if(i != 0)
-    {
-      wv_pcmcia_release(link);
-      return FALSE;
-    }
-
-  strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
-  link->dev_node = &((net_local *) netdev_priv(dev))->node;
-
-#ifdef DEBUG_CONFIG_TRACE
-  printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
-#endif
-  return TRUE;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * After a card is removed, wv_pcmcia_release() will unregister the net
- * device, and release the PCMCIA configuration.  If the device is
- * still open, this will be postponed until it is closed.
- */
-static void
-wv_pcmcia_release(struct pcmcia_device *link)
-{
-       struct net_device *     dev = (struct net_device *) link->priv;
-       net_local *             lp = netdev_priv(dev);
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
-#endif
-
-       iounmap(lp->mem);
-       pcmcia_disable_device(link);
-
-#ifdef DEBUG_CONFIG_TRACE
-       printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
-#endif
-}
-
-/************************ INTERRUPT HANDLING ************************/
-
-/*
- * This function is the interrupt handler for the WaveLAN card. This
- * routine will be called whenever: 
- *     1. A packet is received.
- *     2. A packet has successfully been transferred and the unit is
- *        ready to transmit another packet.
- *     3. A command has completed execution.
- */
-static irqreturn_t
-wavelan_interrupt(int          irq,
-                 void *        dev_id)
-{
-  struct net_device *  dev = dev_id;
-  net_local *  lp;
-  unsigned int base;
-  int          status0;
-  u_int                tx_status;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
-#endif
-
-  lp = netdev_priv(dev);
-  base = dev->base_addr;
-
-#ifdef DEBUG_INTERRUPT_INFO
-  /* Check state of our spinlock (it should be cleared) */
-  if(spin_is_locked(&lp->spinlock))
-    printk(KERN_DEBUG
-          "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
-          dev->name);
-#endif
-
-  /* Prevent reentrancy. We need to do that because we may have
-   * multiple interrupt handler running concurrently.
-   * It is safe because interrupts are disabled before aquiring
-   * the spinlock. */
-  spin_lock(&lp->spinlock);
-
-  /* Treat all pending interrupts */
-  while(1)
-    {
-      /* ---------------- INTERRUPT CHECKING ---------------- */
-      /*
-       * Look for the interrupt and verify the validity
-       */
-      outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
-      status0 = inb(LCSR(base));
-
-#ifdef DEBUG_INTERRUPT_INFO
-      printk(KERN_DEBUG "status0 0x%x [%s => 0x%x]", status0, 
-            (status0&SR0_INTERRUPT)?"int":"no int",status0&~SR0_INTERRUPT);
-      if(status0&SR0_INTERRUPT)
-       {
-         printk(" [%s => %d]\n", (status0 & SR0_CHNL) ? "chnl" :
-                ((status0 & SR0_EXECUTION) ? "cmd" :
-                 ((status0 & SR0_RECEPTION) ? "recv" : "unknown")),
-                (status0 & SR0_EVENT_MASK));
-       }
-      else
-       printk("\n");
-#endif
-
-      /* Return if no actual interrupt from i82593 (normal exit) */
-      if(!(status0 & SR0_INTERRUPT))
-       break;
-
-      /* If interrupt is both Rx and Tx or none...
-       * This code in fact is there to catch the spurious interrupt
-       * when you remove the wavelan pcmcia card from the socket */
-      if(((status0 & SR0_BOTH_RX_TX) == SR0_BOTH_RX_TX) ||
-        ((status0 & SR0_BOTH_RX_TX) == 0x0))
-       {
-#ifdef DEBUG_INTERRUPT_INFO
-         printk(KERN_INFO "%s: wv_interrupt(): bogus interrupt (or from dead card) : %X\n",
-                dev->name, status0);
-#endif
-         /* Acknowledge the interrupt */
-         outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-         break;
-       }
-
-      /* ----------------- RECEIVING PACKET ----------------- */
-      /*
-       * When the wavelan signal the reception of a new packet,
-       * we call wv_packet_rcv() to copy if from the buffer and
-       * send it to NET3
-       */
-      if(status0 & SR0_RECEPTION)
-       {
-#ifdef DEBUG_INTERRUPT_INFO
-         printk(KERN_DEBUG "%s: wv_interrupt(): receive\n", dev->name);
-#endif
-
-         if((status0 & SR0_EVENT_MASK) == SR0_STOP_REG_HIT)
-           {
-#ifdef DEBUG_INTERRUPT_ERROR
-             printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
-                    dev->name);
-#endif
-             dev->stats.rx_over_errors++;
-             lp->overrunning = 1;
-           }
-
-         /* Get the packet */
-         wv_packet_rcv(dev);
-         lp->overrunning = 0;
-
-         /* Acknowledge the interrupt */
-         outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-         continue;
-       }
-
-      /* ---------------- COMMAND COMPLETION ---------------- */
-      /*
-       * Interrupts issued when the i82593 has completed a command.
-       * Most likely : transmission done
-       */
-
-      /* If a transmission has been done */
-      if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
-        (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
-        (status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
-       {
-#ifdef DEBUG_TX_ERROR
-         if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
-           printk(KERN_INFO "%s: wv_interrupt(): packet transmitted without CRC.\n",
-                  dev->name);
-#endif
-
-         /* Get transmission status */
-         tx_status = inb(LCSR(base));
-         tx_status |= (inb(LCSR(base)) << 8);
-#ifdef DEBUG_INTERRUPT_INFO
-         printk(KERN_DEBUG "%s: wv_interrupt(): transmission done\n",
-                dev->name);
-         {
-           u_int       rcv_bytes;
-           u_char      status3;
-           rcv_bytes = inb(LCSR(base));
-           rcv_bytes |= (inb(LCSR(base)) << 8);
-           status3 = inb(LCSR(base));
-           printk(KERN_DEBUG "tx_status 0x%02x rcv_bytes 0x%02x status3 0x%x\n",
-                  tx_status, rcv_bytes, (u_int) status3);
-         }
-#endif
-         /* Check for possible errors */
-         if((tx_status & TX_OK) != TX_OK)
-           {
-             dev->stats.tx_errors++;
-
-             if(tx_status & TX_FRTL)
-               {
-#ifdef DEBUG_TX_ERROR
-                 printk(KERN_INFO "%s: wv_interrupt(): frame too long\n",
-                        dev->name);
-#endif
-               }
-             if(tx_status & TX_UND_RUN)
-               {
-#ifdef DEBUG_TX_FAIL
-                 printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
-                        dev->name);
-#endif
-                 dev->stats.tx_aborted_errors++;
-               }
-             if(tx_status & TX_LOST_CTS)
-               {
-#ifdef DEBUG_TX_FAIL
-                 printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name);
-#endif
-                 dev->stats.tx_carrier_errors++;
-               }
-             if(tx_status & TX_LOST_CRS)
-               {
-#ifdef DEBUG_TX_FAIL
-                 printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
-                        dev->name);
-#endif
-                 dev->stats.tx_carrier_errors++;
-               }
-             if(tx_status & TX_HRT_BEAT)
-               {
-#ifdef DEBUG_TX_FAIL
-                 printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name);
-#endif
-                 dev->stats.tx_heartbeat_errors++;
-               }
-             if(tx_status & TX_DEFER)
-               {
-#ifdef DEBUG_TX_FAIL
-                 printk(KERN_DEBUG "%s: wv_interrupt(): channel jammed\n",
-                        dev->name);
-#endif
-               }
-             /* Ignore late collisions since they're more likely to happen
-              * here (the WaveLAN design prevents the LAN controller from
-              * receiving while it is transmitting). We take action only when
-              * the maximum retransmit attempts is exceeded.
-              */
-             if(tx_status & TX_COLL)
-               {
-                 if(tx_status & TX_MAX_COL)
-                   {
-#ifdef DEBUG_TX_FAIL
-                     printk(KERN_DEBUG "%s: wv_interrupt(): channel congestion\n",
-                            dev->name);
-#endif
-                     if(!(tx_status & TX_NCOL_MASK))
-                       {
-                         dev->stats.collisions += 0x10;
-                       }
-                   }
-               }
-           }   /* if(!(tx_status & TX_OK)) */
-
-         dev->stats.collisions += (tx_status & TX_NCOL_MASK);
-         dev->stats.tx_packets++;
-
-         netif_wake_queue(dev);
-         outb(CR0_INT_ACK | OP0_NOP, LCCR(base));      /* Acknowledge the interrupt */
-       } 
-      else     /* if interrupt = transmit done or retransmit done */
-       {
-#ifdef DEBUG_INTERRUPT_ERROR
-         printk(KERN_INFO "wavelan_cs: unknown interrupt, status0 = %02x\n",
-                status0);
-#endif
-         outb(CR0_INT_ACK | OP0_NOP, LCCR(base));      /* Acknowledge the interrupt */
-       }
-    }  /* while(1) */
-
-  spin_unlock(&lp->spinlock);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
-#endif
-
-  /* We always return IRQ_HANDLED, because we will receive empty
-   * interrupts under normal operations. Anyway, it doesn't matter
-   * as we are dealing with an ISA interrupt that can't be shared.
-   *
-   * Explanation : under heavy receive, the following happens :
-   * ->wavelan_interrupt()
-   *    (status0 & SR0_INTERRUPT) != 0
-   *       ->wv_packet_rcv()
-   *    (status0 & SR0_INTERRUPT) != 0
-   *       ->wv_packet_rcv()
-   *    (status0 & SR0_INTERRUPT) == 0 // i.e. no more event
-   * <-wavelan_interrupt()
-   * ->wavelan_interrupt()
-   *    (status0 & SR0_INTERRUPT) == 0 // i.e. empty interrupt
-   * <-wavelan_interrupt()
-   * Jean II */
-  return IRQ_HANDLED;
-} /* wv_interrupt */
-
-/*------------------------------------------------------------------*/
-/*
- * Watchdog: when we start a transmission, a timer is set for us in the
- * kernel.  If the transmission completes, this timer is disabled. If
- * the timer expires, we are called and we try to unlock the hardware.
- *
- * Note : This watchdog is move clever than the one in the ISA driver,
- * because it try to abort the current command before reseting
- * everything...
- * On the other hand, it's a bit simpler, because we don't have to
- * deal with the multiple Tx buffers...
- */
-static void
-wavelan_watchdog(struct net_device *   dev)
-{
-  net_local *          lp = netdev_priv(dev);
-  unsigned int         base = dev->base_addr;
-  unsigned long                flags;
-  int                  aborted = FALSE;
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
-#endif
-
-#ifdef DEBUG_INTERRUPT_ERROR
-  printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
-        dev->name);
-#endif
-
-  spin_lock_irqsave(&lp->spinlock, flags);
-
-  /* Ask to abort the current command */
-  outb(OP0_ABORT, LCCR(base));
-
-  /* Wait for the end of the command (a bit hackish) */
-  if(wv_82593_cmd(dev, "wavelan_watchdog(): abort",
-                 OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED))
-    aborted = TRUE;
-
-  /* Release spinlock here so that wv_hw_reset() can grab it */
-  spin_unlock_irqrestore(&lp->spinlock, flags);
-
-  /* Check if we were successful in aborting it */
-  if(!aborted)
-    {
-      /* It seem that it wasn't enough */
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "%s: wavelan_watchdog: abort failed, trying reset\n",
-            dev->name);
-#endif
-      wv_hw_reset(dev);
-    }
-
-#ifdef DEBUG_PSA_SHOW
-  {
-    psa_t              psa;
-    psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
-    wv_psa_show(&psa);
-  }
-#endif
-#ifdef DEBUG_MMC_SHOW
-  wv_mmc_show(dev);
-#endif
-#ifdef DEBUG_I82593_SHOW
-  wv_ru_show(dev);
-#endif
-
-  /* We are no more waiting for something... */
-  netif_wake_queue(dev);
-
-#ifdef DEBUG_INTERRUPT_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
-#endif
-}
-
-/********************* CONFIGURATION CALLBACKS *********************/
-/*
- * Here are the functions called by the pcmcia package (cardmgr) and
- * linux networking (NET3) for initialization, configuration and
- * deinstallations of the Wavelan Pcmcia Hardware.
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Configure and start up the WaveLAN PCMCIA adaptor.
- * Called by NET3 when it "open" the device.
- */
-static int
-wavelan_open(struct net_device *       dev)
-{
-  net_local *  lp = netdev_priv(dev);
-  struct pcmcia_device *       link = lp->link;
-  unsigned int base = dev->base_addr;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
-        (unsigned int) dev);
-#endif
-
-  /* Check if the modem is powered up (wavelan_close() power it down */
-  if(hasr_read(base) & HASR_NO_CLK)
-    {
-      /* Power up (power up time is 250us) */
-      hacr_write(base, HACR_DEFAULT);
-
-      /* Check if the module has been powered up... */
-      if(hasr_read(base) & HASR_NO_CLK)
-       {
-#ifdef DEBUG_CONFIG_ERRORS
-         printk(KERN_WARNING "%s: wavelan_open(): modem not connected\n",
-                dev->name);
-#endif
-         return FALSE;
-       }
-    }
-
-  /* Start reception and declare the driver ready */
-  if(!lp->configured)
-    return FALSE;
-  if(!wv_ru_start(dev))
-    wv_hw_reset(dev);          /* If problem : reset */
-  netif_start_queue(dev);
-
-  /* Mark the device as used */
-  link->open++;
-
-#ifdef WAVELAN_ROAMING
-  if(do_roaming)
-    wv_roam_init(dev);
-#endif /* WAVELAN_ROAMING */
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
-#endif
-  return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Shutdown the WaveLAN PCMCIA adaptor.
- * Called by NET3 when it "close" the device.
- */
-static int
-wavelan_close(struct net_device *      dev)
-{
-  struct pcmcia_device *       link = ((net_local *)netdev_priv(dev))->link;
-  unsigned int base = dev->base_addr;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
-        (unsigned int) dev);
-#endif
-
-  /* If the device isn't open, then nothing to do */
-  if(!link->open)
-    {
-#ifdef DEBUG_CONFIG_INFO
-      printk(KERN_DEBUG "%s: wavelan_close(): device not open\n", dev->name);
-#endif
-      return 0;
-    }
-
-#ifdef WAVELAN_ROAMING
-  /* Cleanup of roaming stuff... */
-  if(do_roaming)
-    wv_roam_cleanup(dev);
-#endif /* WAVELAN_ROAMING */
-
-  link->open--;
-
-  /* If the card is still present */
-  if(netif_running(dev))
-    {
-      netif_stop_queue(dev);
-
-      /* Stop receiving new messages and wait end of transmission */
-      wv_ru_stop(dev);
-
-      /* Power down the module */
-      hacr_write(base, HACR_DEFAULT & (~HACR_PWR_STAT));
-    }
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
-#endif
-  return 0;
-}
-
-static const struct net_device_ops wavelan_netdev_ops = {
-       .ndo_open               = wavelan_open,
-       .ndo_stop               = wavelan_close,
-       .ndo_start_xmit         = wavelan_packet_xmit,
-       .ndo_set_multicast_list = wavelan_set_multicast_list,
-#ifdef SET_MAC_ADDRESS
-       .ndo_set_mac_address    = wavelan_set_mac_address,
-#endif
-       .ndo_tx_timeout         = wavelan_watchdog,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_validate_addr      = eth_validate_addr,
-};
-
-/*------------------------------------------------------------------*/
-/*
- * wavelan_attach() creates an "instance" of the driver, allocating
- * local data structures for one device (one interface).  The device
- * is registered with Card Services.
- *
- * The dev_link structure is initialized, but we don't actually
- * configure the card at this point -- we wait until we receive a
- * card insertion event.
- */
-static int
-wavelan_probe(struct pcmcia_device *p_dev)
-{
-  struct net_device *  dev;            /* Interface generic data */
-  net_local *  lp;             /* Interface specific data */
-  int ret;
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "-> wavelan_attach()\n");
-#endif
-
-  /* The io structure describes IO port mapping */
-  p_dev->io.NumPorts1 = 8;
-  p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-  p_dev->io.IOAddrLines = 3;
-
-  /* Interrupt setup */
-  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-  p_dev->irq.Handler = wavelan_interrupt;
-
-  /* General socket configuration */
-  p_dev->conf.Attributes = CONF_ENABLE_IRQ;
-  p_dev->conf.IntType = INT_MEMORY_AND_IO;
-
-  /* Allocate the generic data structure */
-  dev = alloc_etherdev(sizeof(net_local));
-  if (!dev)
-      return -ENOMEM;
-
-  p_dev->priv = dev;
-
-  lp = netdev_priv(dev);
-
-  /* Init specific data */
-  lp->configured = 0;
-  lp->reconfig_82593 = FALSE;
-  lp->nresets = 0;
-  /* Multicast stuff */
-  lp->promiscuous = 0;
-  lp->allmulticast = 0;
-  lp->mc_count = 0;
-
-  /* Init spinlock */
-  spin_lock_init(&lp->spinlock);
-
-  /* back links */
-  lp->dev = dev;
-
-  /* wavelan NET3 callbacks */
-  dev->netdev_ops = &wavelan_netdev_ops;
-  dev->watchdog_timeo  = WATCHDOG_JIFFIES;
-  SET_ETHTOOL_OPS(dev, &ops);
-
-  dev->wireless_handlers = &wavelan_handler_def;
-  lp->wireless_data.spy_data = &lp->spy_data;
-  dev->wireless_data = &lp->wireless_data;
-
-  /* Other specific data */
-  dev->mtu = WAVELAN_MTU;
-
-  ret = wv_pcmcia_config(p_dev);
-  if (ret)
-         return ret;
-
-  ret = wv_hw_config(dev);
-  if (ret) {
-         dev->irq = 0;
-         pcmcia_disable_device(p_dev);
-         return ret;
-  }
-
-  wv_init_info(dev);
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<- wavelan_attach()\n");
-#endif
-
-  return 0;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * This deletes a driver "instance".  The device is de-registered with
- * Card Services.  If it has been released, all local data structures
- * are freed.  Otherwise, the structures will be freed when the device
- * is released.
- */
-static void
-wavelan_detach(struct pcmcia_device *link)
-{
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
-#endif
-
-  /* Some others haven't done their job : give them another chance */
-  wv_pcmcia_release(link);
-
-  /* Free pieces */
-  if(link->priv)
-    {
-      struct net_device *      dev = (struct net_device *) link->priv;
-
-      /* Remove ourselves from the kernel list of ethernet devices */
-      /* Warning : can't be called from interrupt, timer or wavelan_close() */
-      if (link->dev_node)
-       unregister_netdev(dev);
-      link->dev_node = NULL;
-      ((net_local *)netdev_priv(dev))->link = NULL;
-      ((net_local *)netdev_priv(dev))->dev = NULL;
-      free_netdev(dev);
-    }
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<- wavelan_detach()\n");
-#endif
-}
-
-static int wavelan_suspend(struct pcmcia_device *link)
-{
-       struct net_device *     dev = (struct net_device *) link->priv;
-
-       /* NB: wavelan_close will be called, but too late, so we are
-        * obliged to close nicely the wavelan here. David, could you
-        * close the device before suspending them ? And, by the way,
-        * could you, on resume, add a "route add -net ..." after the
-        * ifconfig up ? Thanks... */
-
-       /* Stop receiving new messages and wait end of transmission */
-       wv_ru_stop(dev);
-
-       if (link->open)
-               netif_device_detach(dev);
-
-       /* Power down the module */
-       hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
-
-       return 0;
-}
-
-static int wavelan_resume(struct pcmcia_device *link)
-{
-       struct net_device *     dev = (struct net_device *) link->priv;
-
-       if (link->open) {
-               wv_hw_reset(dev);
-               netif_device_attach(dev);
-       }
-
-       return 0;
-}
-
-
-static struct pcmcia_device_id wavelan_ids[] = {
-       PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
-       PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
-       PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/PCMCIA", 0x23eb9949, 0x1bc50975),
-       PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/PCMCIA", 0x24358cd4, 0x1bc50975),
-       PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, wavelan_ids);
-
-static struct pcmcia_driver wavelan_driver = {
-       .owner          = THIS_MODULE,
-       .drv            = {
-               .name   = "wavelan_cs",
-       },
-       .probe          = wavelan_probe,
-       .remove         = wavelan_detach,
-       .id_table       = wavelan_ids,
-       .suspend        = wavelan_suspend,
-       .resume         = wavelan_resume,
-};
-
-static int __init
-init_wavelan_cs(void)
-{
-       return pcmcia_register_driver(&wavelan_driver);
-}
-
-static void __exit
-exit_wavelan_cs(void)
-{
-       pcmcia_unregister_driver(&wavelan_driver);
-}
-
-module_init(init_wavelan_cs);
-module_exit(exit_wavelan_cs);
 
+++ /dev/null
-/*
- *     Wavelan Pcmcia driver
- *
- *             Jean II - HPLB '96
- *
- * Reorganization and extension of the driver.
- * Original copyright follow. See wavelan_cs.h for details.
- *
- * This file contain the declarations of the Wavelan hardware. Note that
- * the Pcmcia Wavelan include a i82593 controller (see definitions in
- * file i82593.h).
- *
- * The main difference between the pcmcia hardware and the ISA one is
- * the Ethernet Controller (i82593 instead of i82586). The i82593 allow
- * only one send buffer. The PSA (Parameter Storage Area : EEprom for
- * permanent storage of various info) is memory mapped, but not the
- * MMI (Modem Management Interface).
- */
-
-/*
- * Definitions for the AT&T GIS (formerly NCR) WaveLAN PCMCIA card:
- *   An Ethernet-like radio transceiver controlled by an Intel 82593
- *   coprocessor.
- *
- *
- ****************************************************************************
- *   Copyright 1995
- *   Anthony D. Joseph
- *   Massachusetts Institute of Technology
- *
- *   Permission to use, copy, modify, and distribute this program
- *   for any purpose and without fee is hereby granted, provided
- *   that this copyright and permission notice appear on all copies
- *   and supporting documentation, the name of M.I.T. not be used
- *   in advertising or publicity pertaining to distribution of the
- *   program without specific prior permission, and notice be given
- *   in supporting documentation that copying and distribution is
- *   by permission of M.I.T.  M.I.T. makes no representations about
- *   the suitability of this software for any purpose.  It is pro-
- *   vided "as is" without express or implied warranty.
- ****************************************************************************
- *
- *
- * Credits:
- *     Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht for
- *       providing extremely useful information about WaveLAN PCMCIA hardware
- *
- *     This driver is based upon several other drivers, in particular:
- *       David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
- *       Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
- *      Anders Klemets' PCMCIA WaveLAN adapter driver
- *       Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
- */
-
-#ifndef _WAVELAN_CS_H
-#define        _WAVELAN_CS_H
-
-/************************** MAGIC NUMBERS ***************************/
-
-/* The detection of the wavelan card is made by reading the MAC address
- * from the card and checking it. If you have a non AT&T product (OEM,
- * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this
- * part to accommodate your hardware...
- */
-static const unsigned char     MAC_ADDRESSES[][3] = {
-  { 0x08, 0x00, 0x0E },                /* AT&T Wavelan (standard) & DEC RoamAbout */
-  { 0x08, 0x00, 0x6A },                /* AT&T Wavelan (alternate) */
-  { 0x00, 0x00, 0xE1 },                /* Hitachi Wavelan */
-  { 0x00, 0x60, 0x1D }         /* Lucent Wavelan (another one) */
-  /* Add your card here and send me the patch ! */
-};
-
-/*
- * Constants used to convert channels to frequencies
- */
-
-/* Frequency available in the 2.0 modem, in units of 250 kHz
- * (as read in the offset register of the dac area).
- * Used to map channel numbers used by `wfreqsel' to frequencies
- */
-static const short     channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
-                                   0xD0, 0xF0, 0xF8, 0x150 };
-
-/* Frequencies of the 1.0 modem (fixed frequencies).
- * Use to map the PSA `subband' to a frequency
- * Note : all frequencies apart from the first one need to be multiplied by 10
- */
-static const int       fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
-
-
-/*************************** PC INTERFACE ****************************/
-
-/* WaveLAN host interface definitions */
-
-#define        LCCR(base)      (base)          /* LAN Controller Command Register */
-#define        LCSR(base)      (base)          /* LAN Controller Status Register */
-#define        HACR(base)      (base+0x1)      /* Host Adapter Command Register */
-#define        HASR(base)      (base+0x1)      /* Host Adapter Status Register */
-#define PIORL(base)    (base+0x2)      /* Program I/O Register Low */
-#define RPLL(base)     (base+0x2)      /* Receive Pointer Latched Low */
-#define PIORH(base)    (base+0x3)      /* Program I/O Register High */
-#define RPLH(base)     (base+0x3)      /* Receive Pointer Latched High */
-#define PIOP(base)     (base+0x4)      /* Program I/O Port */
-#define MMR(base)      (base+0x6)      /* MMI Address Register */
-#define MMD(base)      (base+0x7)      /* MMI Data Register */
-
-/* Host Adaptor Command Register bit definitions */
-
-#define HACR_LOF         (1 << 3)      /* Lock Out Flag, toggle every 250ms */
-#define HACR_PWR_STAT    (1 << 4)      /* Power State, 1=active, 0=sleep */
-#define HACR_TX_DMA_RESET (1 << 5)     /* Reset transmit DMA ptr on high */
-#define HACR_RX_DMA_RESET (1 << 6)     /* Reset receive DMA ptr on high */
-#define HACR_ROM_WEN     (1 << 7)      /* EEPROM write enabled when true */
-
-#define HACR_RESET              (HACR_TX_DMA_RESET | HACR_RX_DMA_RESET)
-#define        HACR_DEFAULT            (HACR_PWR_STAT)
-
-/* Host Adapter Status Register bit definitions */
-
-#define HASR_MMI_BUSY  (1 << 2)        /* MMI is busy when true */
-#define HASR_LOF       (1 << 3)        /* Lock out flag status */
-#define HASR_NO_CLK    (1 << 4)        /* active when modem not connected */
-
-/* Miscellaneous bit definitions */
-
-#define PIORH_SEL_TX   (1 << 5)        /* PIOR points to 0=rx/1=tx buffer */
-#define MMR_MMI_WR     (1 << 0)        /* Next MMI cycle is 0=read, 1=write */
-#define PIORH_MASK     0x1f            /* only low 5 bits are significant */
-#define RPLH_MASK      0x1f            /* only low 5 bits are significant */
-#define MMI_ADDR_MASK  0x7e            /* Bits 1-6 of MMR are significant */
-
-/* Attribute Memory map */
-
-#define CIS_ADDR       0x0000          /* Card Information Status Register */
-#define PSA_ADDR       0x0e00          /* Parameter Storage Area address */
-#define EEPROM_ADDR    0x1000          /* EEPROM address (unused ?) */
-#define COR_ADDR       0x4000          /* Configuration Option Register */
-
-/* Configuration Option Register bit definitions */
-
-#define COR_CONFIG     (1 << 0)        /* Config Index, 0 when unconfigured */
-#define COR_SW_RESET   (1 << 7)        /* Software Reset on true */
-#define COR_LEVEL_IRQ  (1 << 6)        /* Level IRQ */
-
-/* Local Memory map */
-
-#define RX_BASE                0x0000          /* Receive memory, 8 kB */
-#define TX_BASE                0x2000          /* Transmit memory, 2 kB */
-#define UNUSED_BASE    0x2800          /* Unused, 22 kB */
-#define RX_SIZE                (TX_BASE-RX_BASE)       /* Size of receive area */
-#define RX_SIZE_SHIFT  6               /* Bits to shift in stop register */
-
-#define TRUE  1
-#define FALSE 0
-
-#define MOD_ENAL 1
-#define MOD_PROM 2
-
-/* Size of a MAC address */
-#define WAVELAN_ADDR_SIZE      6
-
-/* Maximum size of Wavelan packet */
-#define WAVELAN_MTU    1500
-
-#define        MAXDATAZ                (6 + 6 + 2 + WAVELAN_MTU)
-
-/********************** PARAMETER STORAGE AREA **********************/
-
-/*
- * Parameter Storage Area (PSA).
- */
-typedef struct psa_t   psa_t;
-struct psa_t {
-  /* For the PCMCIA Adapter, locations 0x00-0x0F are unused and fixed at 00 */
-  unsigned char        psa_io_base_addr_1;     /* [0x00] Base address 1 ??? */
-  unsigned char        psa_io_base_addr_2;     /* [0x01] Base address 2 */
-  unsigned char        psa_io_base_addr_3;     /* [0x02] Base address 3 */
-  unsigned char        psa_io_base_addr_4;     /* [0x03] Base address 4 */
-  unsigned char        psa_rem_boot_addr_1;    /* [0x04] Remote Boot Address 1 */
-  unsigned char        psa_rem_boot_addr_2;    /* [0x05] Remote Boot Address 2 */
-  unsigned char        psa_rem_boot_addr_3;    /* [0x06] Remote Boot Address 3 */
-  unsigned char        psa_holi_params;        /* [0x07] HOst Lan Interface (HOLI) Parameters */
-  unsigned char        psa_int_req_no;         /* [0x08] Interrupt Request Line */
-  unsigned char        psa_unused0[7];         /* [0x09-0x0F] unused */
-
-  unsigned char        psa_univ_mac_addr[WAVELAN_ADDR_SIZE];   /* [0x10-0x15] Universal (factory) MAC Address */
-  unsigned char        psa_local_mac_addr[WAVELAN_ADDR_SIZE];  /* [0x16-1B] Local MAC Address */
-  unsigned char        psa_univ_local_sel;     /* [0x1C] Universal Local Selection */
-#define                PSA_UNIVERSAL   0               /* Universal (factory) */
-#define                PSA_LOCAL       1               /* Local */
-  unsigned char        psa_comp_number;        /* [0x1D] Compatability Number: */
-#define                PSA_COMP_PC_AT_915      0       /* PC-AT 915 MHz        */
-#define                PSA_COMP_PC_MC_915      1       /* PC-MC 915 MHz        */
-#define                PSA_COMP_PC_AT_2400     2       /* PC-AT 2.4 GHz        */
-#define                PSA_COMP_PC_MC_2400     3       /* PC-MC 2.4 GHz        */
-#define                PSA_COMP_PCMCIA_915     4       /* PCMCIA 915 MHz or 2.0 */
-  unsigned char        psa_thr_pre_set;        /* [0x1E] Modem Threshold Preset */
-  unsigned char        psa_feature_select;     /* [0x1F] Call code required (1=on) */
-#define                PSA_FEATURE_CALL_CODE   0x01    /* Call code required (Japan) */
-  unsigned char        psa_subband;            /* [0x20] Subband       */
-#define                PSA_SUBBAND_915         0       /* 915 MHz or 2.0 */
-#define                PSA_SUBBAND_2425        1       /* 2425 MHz     */
-#define                PSA_SUBBAND_2460        2       /* 2460 MHz     */
-#define                PSA_SUBBAND_2484        3       /* 2484 MHz     */
-#define                PSA_SUBBAND_2430_5      4       /* 2430.5 MHz   */
-  unsigned char        psa_quality_thr;        /* [0x21] Modem Quality Threshold */
-  unsigned char        psa_mod_delay;          /* [0x22] Modem Delay ??? (reserved) */
-  unsigned char        psa_nwid[2];            /* [0x23-0x24] Network ID */
-  unsigned char        psa_nwid_select;        /* [0x25] Network ID Select On Off */
-  unsigned char        psa_encryption_select;  /* [0x26] Encryption On Off */
-  unsigned char        psa_encryption_key[8];  /* [0x27-0x2E] Encryption Key */
-  unsigned char        psa_databus_width;      /* [0x2F] AT bus width select 8/16 */
-  unsigned char        psa_call_code[8];       /* [0x30-0x37] (Japan) Call Code */
-  unsigned char        psa_nwid_prefix[2];     /* [0x38-0x39] Roaming domain */
-  unsigned char        psa_reserved[2];        /* [0x3A-0x3B] Reserved - fixed 00 */
-  unsigned char        psa_conf_status;        /* [0x3C] Conf Status, bit 0=1:config*/
-  unsigned char        psa_crc[2];             /* [0x3D] CRC-16 over PSA */
-  unsigned char        psa_crc_status;         /* [0x3F] CRC Valid Flag */
-};
-
-/* Size for structure checking (if padding is correct) */
-#define        PSA_SIZE        64
-
-/* Calculate offset of a field in the above structure
- * Warning : only even addresses are used */
-#define        psaoff(p, f)    ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL))
-
-/******************** MODEM MANAGEMENT INTERFACE ********************/
-
-/*
- * Modem Management Controller (MMC) write structure.
- */
-typedef struct mmw_t   mmw_t;
-struct mmw_t {
-  unsigned char        mmw_encr_key[8];        /* encryption key */
-  unsigned char        mmw_encr_enable;        /* enable/disable encryption */
-#define        MMW_ENCR_ENABLE_MODE    0x02    /* Mode of security option */
-#define        MMW_ENCR_ENABLE_EN      0x01    /* Enable security option */
-  unsigned char        mmw_unused0[1];         /* unused */
-  unsigned char        mmw_des_io_invert;      /* Encryption option */
-#define        MMW_DES_IO_INVERT_RES   0x0F    /* Reserved */
-#define        MMW_DES_IO_INVERT_CTRL  0xF0    /* Control ??? (set to 0) */
-  unsigned char        mmw_unused1[5];         /* unused */
-  unsigned char        mmw_loopt_sel;          /* looptest selection */
-#define        MMW_LOOPT_SEL_DIS_NWID  0x40    /* disable NWID filtering */
-#define        MMW_LOOPT_SEL_INT       0x20    /* activate Attention Request */
-#define        MMW_LOOPT_SEL_LS        0x10    /* looptest w/o collision avoidance */
-#define MMW_LOOPT_SEL_LT3A     0x08    /* looptest 3a */
-#define        MMW_LOOPT_SEL_LT3B      0x04    /* looptest 3b */
-#define        MMW_LOOPT_SEL_LT3C      0x02    /* looptest 3c */
-#define        MMW_LOOPT_SEL_LT3D      0x01    /* looptest 3d */
-  unsigned char        mmw_jabber_enable;      /* jabber timer enable */
-  /* Abort transmissions > 200 ms */
-  unsigned char        mmw_freeze;             /* freeze / unfreeeze signal level */
-  /* 0 : signal level & qual updated for every new message, 1 : frozen */
-  unsigned char        mmw_anten_sel;          /* antenna selection */
-#define MMW_ANTEN_SEL_SEL      0x01    /* direct antenna selection */
-#define        MMW_ANTEN_SEL_ALG_EN    0x02    /* antenna selection algo. enable */
-  unsigned char        mmw_ifs;                /* inter frame spacing */
-  /* min time between transmission in bit periods (.5 us) - bit 0 ignored */
-  unsigned char        mmw_mod_delay;          /* modem delay (synchro) */
-  unsigned char        mmw_jam_time;           /* jamming time (after collision) */
-  unsigned char        mmw_unused2[1];         /* unused */
-  unsigned char        mmw_thr_pre_set;        /* level threshold preset */
-  /* Discard all packet with signal < this value (4) */
-  unsigned char        mmw_decay_prm;          /* decay parameters */
-  unsigned char        mmw_decay_updat_prm;    /* decay update parameterz */
-  unsigned char        mmw_quality_thr;        /* quality (z-quotient) threshold */
-  /* Discard all packet with quality < this value (3) */
-  unsigned char        mmw_netw_id_l;          /* NWID low order byte */
-  unsigned char        mmw_netw_id_h;          /* NWID high order byte */
-  /* Network ID or Domain : create virtual net on the air */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char        mmw_mode_select;        /* for analog tests (set to 0) */
-  unsigned char        mmw_unused3[1];         /* unused */
-  unsigned char        mmw_fee_ctrl;           /* frequency eeprom control */
-#define        MMW_FEE_CTRL_PRE        0x10    /* Enable protected instructions */
-#define        MMW_FEE_CTRL_DWLD       0x08    /* Download eeprom to mmc */
-#define        MMW_FEE_CTRL_CMD        0x07    /* EEprom commands : */
-#define        MMW_FEE_CTRL_READ       0x06    /* Read */
-#define        MMW_FEE_CTRL_WREN       0x04    /* Write enable */
-#define        MMW_FEE_CTRL_WRITE      0x05    /* Write data to address */
-#define        MMW_FEE_CTRL_WRALL      0x04    /* Write data to all addresses */
-#define        MMW_FEE_CTRL_WDS        0x04    /* Write disable */
-#define        MMW_FEE_CTRL_PRREAD     0x16    /* Read addr from protect register */
-#define        MMW_FEE_CTRL_PREN       0x14    /* Protect register enable */
-#define        MMW_FEE_CTRL_PRCLEAR    0x17    /* Unprotect all registers */
-#define        MMW_FEE_CTRL_PRWRITE    0x15    /* Write addr in protect register */
-#define        MMW_FEE_CTRL_PRDS       0x14    /* Protect register disable */
-  /* Never issue this command (PRDS) : it's irreversible !!! */
-
-  unsigned char        mmw_fee_addr;           /* EEprom address */
-#define        MMW_FEE_ADDR_CHANNEL    0xF0    /* Select the channel */
-#define        MMW_FEE_ADDR_OFFSET     0x0F    /* Offset in channel data */
-#define        MMW_FEE_ADDR_EN         0xC0    /* FEE_CTRL enable operations */
-#define        MMW_FEE_ADDR_DS         0x00    /* FEE_CTRL disable operations */
-#define        MMW_FEE_ADDR_ALL        0x40    /* FEE_CTRL all operations */
-#define        MMW_FEE_ADDR_CLEAR      0xFF    /* FEE_CTRL clear operations */
-
-  unsigned char        mmw_fee_data_l;         /* Write data to EEprom */
-  unsigned char        mmw_fee_data_h;         /* high octet */
-  unsigned char        mmw_ext_ant;            /* Setting for external antenna */
-#define        MMW_EXT_ANT_EXTANT      0x01    /* Select external antenna */
-#define        MMW_EXT_ANT_POL         0x02    /* Polarity of the antenna */
-#define        MMW_EXT_ANT_INTERNAL    0x00    /* Internal antenna */
-#define        MMW_EXT_ANT_EXTERNAL    0x03    /* External antenna */
-#define        MMW_EXT_ANT_IQ_TEST     0x1C    /* IQ test pattern (set to 0) */
-} __attribute__((packed));
-
-/* Size for structure checking (if padding is correct) */
-#define        MMW_SIZE        37
-
-/* Calculate offset of a field in the above structure */
-#define        mmwoff(p, f)    (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
-
-
-/*
- * Modem Management Controller (MMC) read structure.
- */
-typedef struct mmr_t   mmr_t;
-struct mmr_t {
-  unsigned char        mmr_unused0[8];         /* unused */
-  unsigned char        mmr_des_status;         /* encryption status */
-  unsigned char        mmr_des_avail;          /* encryption available (0x55 read) */
-#define        MMR_DES_AVAIL_DES       0x55            /* DES available */
-#define        MMR_DES_AVAIL_AES       0x33            /* AES (AT&T) available */
-  unsigned char        mmr_des_io_invert;      /* des I/O invert register */
-  unsigned char        mmr_unused1[5];         /* unused */
-  unsigned char        mmr_dce_status;         /* DCE status */
-#define        MMR_DCE_STATUS_RX_BUSY          0x01    /* receiver busy */
-#define        MMR_DCE_STATUS_LOOPT_IND        0x02    /* loop test indicated */
-#define        MMR_DCE_STATUS_TX_BUSY          0x04    /* transmitter on */
-#define        MMR_DCE_STATUS_JBR_EXPIRED      0x08    /* jabber timer expired */
-#define MMR_DCE_STATUS                 0x0F    /* mask to get the bits */
-  unsigned char        mmr_dsp_id;             /* DSP id (AA = Daedalus rev A) */
-  unsigned char        mmr_unused2[2];         /* unused */
-  unsigned char        mmr_correct_nwid_l;     /* # of correct NWID's rxd (low) */
-  unsigned char        mmr_correct_nwid_h;     /* # of correct NWID's rxd (high) */
-  /* Warning : Read high order octet first !!! */
-  unsigned char        mmr_wrong_nwid_l;       /* # of wrong NWID's rxd (low) */
-  unsigned char        mmr_wrong_nwid_h;       /* # of wrong NWID's rxd (high) */
-  unsigned char        mmr_thr_pre_set;        /* level threshold preset */
-#define        MMR_THR_PRE_SET         0x3F            /* level threshold preset */
-#define        MMR_THR_PRE_SET_CUR     0x80            /* Current signal above it */
-  unsigned char        mmr_signal_lvl;         /* signal level */
-#define        MMR_SIGNAL_LVL          0x3F            /* signal level */
-#define        MMR_SIGNAL_LVL_VALID    0x80            /* Updated since last read */
-  unsigned char        mmr_silence_lvl;        /* silence level (noise) */
-#define        MMR_SILENCE_LVL         0x3F            /* silence level */
-#define        MMR_SILENCE_LVL_VALID   0x80            /* Updated since last read */
-  unsigned char        mmr_sgnl_qual;          /* signal quality */
-#define        MMR_SGNL_QUAL           0x0F            /* signal quality */
-#define        MMR_SGNL_QUAL_ANT       0x80            /* current antenna used */
-  unsigned char        mmr_netw_id_l;          /* NWID low order byte ??? */
-  unsigned char        mmr_unused3[3];         /* unused */
-
-  /* 2.0 Hardware extension - frequency selection support */
-  unsigned char        mmr_fee_status;         /* Status of frequency eeprom */
-#define        MMR_FEE_STATUS_ID       0xF0            /* Modem revision id */
-#define        MMR_FEE_STATUS_DWLD     0x08            /* Download in progress */
-#define        MMR_FEE_STATUS_BUSY     0x04            /* EEprom busy */
-  unsigned char        mmr_unused4[1];         /* unused */
-  unsigned char        mmr_fee_data_l;         /* Read data from eeprom (low) */
-  unsigned char        mmr_fee_data_h;         /* Read data from eeprom (high) */
-};
-
-/* Size for structure checking (if padding is correct) */
-#define        MMR_SIZE        36
-
-/* Calculate offset of a field in the above structure */
-#define        mmroff(p, f)    (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
-
-
-/* Make the two above structures one */
-typedef union mm_t {
-  struct mmw_t w;      /* Write to the mmc */
-  struct mmr_t r;      /* Read from the mmc */
-} mm_t;
-
-#endif /* _WAVELAN_CS_H */
 
+++ /dev/null
-/*
- *     Wavelan Pcmcia driver
- *
- *             Jean II - HPLB '96
- *
- * Reorganisation and extension of the driver.
- *
- * This file contain all definition and declarations necessary for the
- * wavelan pcmcia driver. This file is a private header, so it should
- * be included only on wavelan_cs.c !!!
- */
-
-#ifndef WAVELAN_CS_P_H
-#define WAVELAN_CS_P_H
-
-/************************** DOCUMENTATION **************************/
-/*
- * This driver provide a Linux interface to the Wavelan Pcmcia hardware
- * The Wavelan is a product of Lucent (http://www.wavelan.com/).
- * This division was formerly part of NCR and then AT&T.
- * Wavelan are also distributed by DEC (RoamAbout DS)...
- *
- * To know how to use this driver, read the PCMCIA HOWTO.
- * If you want to exploit the many other fonctionalities, look comments
- * in the code...
- *
- * This driver is the result of the effort of many peoples (see below).
- */
-
-/* ------------------------ SPECIFIC NOTES ------------------------ */
-/*
- * Web page
- * --------
- *     I try to maintain a web page with the Wireless LAN Howto at :
- *         http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
- *
- * SMP
- * ---
- *     We now are SMP compliant (I eventually fixed the remaining bugs).
- *     The driver has been tested on a dual P6-150 and survived my usual
- *     set of torture tests.
- *     Anyway, I spent enough time chasing interrupt re-entrancy during
- *     errors or reconfigure, and I designed the locked/unlocked sections
- *     of the driver with great care, and with the recent addition of
- *     the spinlock (thanks to the new API), we should be quite close to
- *     the truth.
- *     The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
- *     but better safe than sorry (especially at 2 Mb/s ;-).
- *
- *     I have also looked into disabling only our interrupt on the card
- *     (via HACR) instead of all interrupts in the processor (via cli),
- *     so that other driver are not impacted, and it look like it's
- *     possible, but it's very tricky to do right (full of races). As
- *     the gain would be mostly for SMP systems, it can wait...
- *
- * Debugging and options
- * ---------------------
- *     You will find below a set of '#define" allowing a very fine control
- *     on the driver behaviour and the debug messages printed.
- *     The main options are :
- *     o WAVELAN_ROAMING, for the experimental roaming support.
- *     o SET_PSA_CRC, to have your card correctly recognised by
- *       an access point and the Point-to-Point diagnostic tool.
- *     o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
- *       (otherwise we always start afresh with some defaults)
- *
- * wavelan_cs.o is darn too big
- * -------------------------
- *     That's true ! There is a very simple way to reduce the driver
- *     object by 33% (yes !). Comment out the following line :
- *             #include <linux/wireless.h>
- *     Other compile options can also reduce the size of it...
- *
- * MAC address and hardware detection :
- * ----------------------------------
- *     The detection code of the wavelan chech that the first 3
- *     octets of the MAC address fit the company code. This type of
- *     detection work well for AT&T cards (because the AT&T code is
- *     hardcoded in wavelan_cs.h), but of course will fail for other
- *     manufacturer.
- *
- *     If you are sure that your card is derived from the wavelan,
- *     here is the way to configure it :
- *     1) Get your MAC address
- *             a) With your card utilities (wfreqsel, instconf, ...)
- *             b) With the driver :
- *                     o compile the kernel with DEBUG_CONFIG_INFO enabled
- *                     o Boot and look the card messages
- *     2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan_cs.h)
- *     3) Compile & verify
- *     4) Send me the MAC code - I will include it in the next version...
- *
- */
-
-/* --------------------- WIRELESS EXTENSIONS --------------------- */
-/*
- * This driver is the first one to support "wireless extensions".
- * This set of extensions provide you some way to control the wireless
- * caracteristics of the hardware in a standard way and support for
- * applications for taking advantage of it (like Mobile IP).
- *
- * It might be a good idea as well to fetch the wireless tools to
- * configure the device and play a bit.
- */
-
-/* ---------------------------- FILES ---------------------------- */
-/*
- * wavelan_cs.c :      The actual code for the driver - C functions
- *
- * wavelan_cs.p.h :    Private header : local types / vars for the driver
- *
- * wavelan_cs.h :      Description of the hardware interface & structs
- *
- * i82593.h :          Description if the Ethernet controller
- */
-
-/* --------------------------- HISTORY --------------------------- */
-/*
- * The history of the Wavelan drivers is as complicated as history of
- * the Wavelan itself (NCR -> AT&T -> Lucent).
- *
- * All started with Anders Klemets <klemets@paul.rutgers.edu>,
- * writing a Wavelan ISA driver for the MACH microkernel. Girish
- * Welling <welling@paul.rutgers.edu> had also worked on it.
- * Keith Moore modify this for the Pcmcia hardware.
- *
- * Robert Morris <rtm@das.harvard.edu> port these two drivers to BSDI
- * and add specific Pcmcia support (there is currently no equivalent
- * of the PCMCIA package under BSD...).
- *
- * Jim Binkley <jrb@cs.pdx.edu> port both BSDI drivers to FreeBSD.
- *
- * Bruce Janson <bruce@cs.usyd.edu.au> port the BSDI ISA driver to Linux.
- *
- * Anthony D. Joseph <adj@lcs.mit.edu> started modify Bruce driver
- * (with help of the BSDI PCMCIA driver) for PCMCIA.
- * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished is work.
- * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
- * correctly 2.00 cards (2.4 GHz with frequency selection).
- * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
- * Pcmcia package (+ bug corrections).
- *
- * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
- * patchs to the Pcmcia driver. After, I added code in the ISA driver
- * for Wireless Extensions and full support of frequency selection
- * cards. Now, I'm doing the same to the Pcmcia driver + some
- * reorganisation.
- * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
- * much needed informations on the Wavelan hardware.
- */
-
-/* By the way : for the copyright & legal stuff :
- * Almost everybody wrote code under GNU or BSD license (or alike),
- * and want that their original copyright remain somewhere in the
- * code (for myself, I go with the GPL).
- * Nobody want to take responsibility for anything, except the fame...
- */
-
-/* --------------------------- CREDITS --------------------------- */
-/*
- * Credits:
- *    Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht and
- *     Loeke Brederveld of Lucent for providing extremely useful
- *     information about WaveLAN PCMCIA hardware
- *
- *    This driver is based upon several other drivers, in particular:
- *     David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
- *     Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
- *     Anders Klemets' PCMCIA WaveLAN adapter driver
- *     Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
- *
- * Additional Credits:
- *
- *    This software was originally developed under Linux 1.2.3
- *     (Slackware 2.0 distribution).
- *    And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+)
- *     with an HP OmniBook 4000 and then a 5500.
- *
- *    It is based on other device drivers and information either written
- *    or supplied by:
- *     James Ashton (jaa101@syseng.anu.edu.au),
- *     Ajay Bakre (bakre@paul.rutgers.edu),
- *     Donald Becker (becker@super.org),
- *     Jim Binkley <jrb@cs.pdx.edu>,
- *     Loeke Brederveld <lbrederv@wavelan.com>,
- *     Allan Creighton (allanc@cs.su.oz.au),
- *     Brent Elphick <belphick@uwaterloo.ca>,
- *     Joe Finney <joe@comp.lancs.ac.uk>,
- *     Matthew Geier (matthew@cs.su.oz.au),
- *     Remo di Giovanni (remo@cs.su.oz.au),
- *     Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
- *     David Hinds <dahinds@users.sourceforge.net>,
- *     Jan Hoogendoorn (c/o marteijn@lucent.com),
- *      Bruce Janson <bruce@cs.usyd.edu.au>,
- *     Anthony D. Joseph <adj@lcs.mit.edu>,
- *     Anders Klemets (klemets@paul.rutgers.edu),
- *     Yunzhou Li <yunzhou@strat.iol.unh.edu>,
- *     Marc Meertens (mmeertens@lucent.com),
- *     Keith Moore,
- *     Robert Morris (rtm@das.harvard.edu),
- *     Ian Parkin (ian@cs.su.oz.au),
- *     John Rosenberg (johnr@cs.su.oz.au),
- *     George Rossi (george@phm.gov.au),
- *     Arthur Scott (arthur@cs.su.oz.au),
- *     Stanislav Sinyagin <stas@isf.ru>
- *     Peter Storey,
- *     Jean Tourrilhes <jt@hpl.hp.com>,
- *     Girish Welling (welling@paul.rutgers.edu)
- *     Clark Woodworth <clark@hiway1.exit109.com>
- *     Yongguang Zhang <ygz@isl.hrl.hac.com>...
- */
-
-/* ------------------------- IMPROVEMENTS ------------------------- */
-/*
- * I proudly present :
- *
- * Changes made in 2.8.22 :
- * ----------------------
- *     - improved wv_set_multicast_list
- *     - catch spurious interrupt
- *     - correct release of the device
- *
- * Changes mades in release :
- * ------------------------
- *     - Reorganisation of the code, function name change
- *     - Creation of private header (wavelan_cs.h)
- *     - Reorganised debug messages
- *     - More comments, history, ...
- *     - Configure earlier (in "insert" instead of "open")
- *        and do things only once
- *     - mmc_init : configure the PSA if not done
- *     - mmc_init : 2.00 detection better code for 2.00 init
- *     - better info at startup
- *     - Correct a HUGE bug (volatile & uncalibrated busy loop)
- *       in wv_82593_cmd => config speedup
- *     - Stop receiving & power down on close (and power up on open)
- *       use "ifconfig down" & "ifconfig up ; route add -net ..."
- *     - Send packets : add watchdog instead of pooling
- *     - Receive : check frame wrap around & try to recover some frames
- *     - wavelan_set_multicast_list : avoid reset
- *     - add wireless extensions (ioctl & get_wireless_stats)
- *       get/set nwid/frequency on fly, info for /proc/net/wireless
- *     - Suppress useless stuff from lp (net_local), but add link
- *     - More inlines
- *     - Lot of others minor details & cleanups
- *
- * Changes made in second release :
- * ------------------------------
- *     - Optimise wv_85893_reconfig stuff, fix potential problems
- *     - Change error values for ioctl
- *     - Non blocking wv_ru_stop() + call wv_reset() in case of problems
- *     - Remove development printk from wavelan_watchdog()
- *     - Remove of the watchdog to wavelan_close instead of wavelan_release
- *       fix potential problems...
- *     - Start debugging suspend stuff (but it's still a bit weird)
- *     - Debug & optimize dump header/packet in Rx & Tx (debug)
- *     - Use "readb" and "writeb" to be kernel 2.1 compliant
- *     - Better handling of bogus interrupts
- *     - Wireless extension : SETSPY and GETSPY
- *     - Remove old stuff (stats - for those needing it, just ask me...)
- *     - Make wireless extensions optional
- *
- * Changes made in third release :
- * -----------------------------
- *     - cleanups & typos
- *     - modif wireless ext (spy -> only one pointer)
- *     - new private ioctl to set/get quality & level threshold
- *     - Init : correct default value of level threshold for pcmcia
- *     - kill watchdog in hw_reset
- *     - more 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
- *     - Add message level (debug stuff in /var/adm/debug & errors not
- *       displayed at console and still in /var/adm/messages)
- *
- * Changes made in fourth release :
- * ------------------------------
- *     - multicast support (yes !) thanks to Yongguang Zhang.
- *
- * Changes made in fifth release (2.9.0) :
- * -------------------------------------
- *     - Revisited multicast code (it was mostly wrong).
- *     - protect code in wv_82593_reconfig with dev->tbusy (oups !)
- *
- * Changes made in sixth release (2.9.1a) :
- * --------------------------------------
- *     - Change the detection code for multi manufacturer code support
- *     - Correct bug (hang kernel) in init when we were "rejecting" a card
- *
- * Changes made in seventh release (2.9.1b) :
- * ----------------------------------------
- *     - Update to wireless extensions changes
- *     - Silly bug in card initial configuration (psa_conf_status)
- *
- * Changes made in eigth release :
- * -----------------------------
- *     - Small bug in debug code (probably not the last one...)
- *     - 1.2.13 support (thanks to Clark Woodworth)
- *
- * Changes made for release in 2.9.2b :
- * ----------------------------------
- *     - Level threshold is now a standard wireless extension (version 4 !)
- *     - modules parameters types for kernel > 2.1.17
- *     - updated man page
- *     - Others cleanup from David Hinds
- *
- * Changes made for release in 2.9.5 :
- * ---------------------------------
- *     - byte count stats (courtesy of David Hinds)
- *     - Remove dev_tint stuff (courtesy of David Hinds)
- *     - Others cleanup from David Hinds
- *     - Encryption setting from Brent Elphick (thanks a lot !)
- *     - 'base' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
- *
- * Changes made for release in 2.9.6 :
- * ---------------------------------
- *     - fix bug : no longuer disable watchdog in case of bogus interrupt
- *     - increase timeout in config code for picky hardware
- *     - mask unused bits in status (Wireless Extensions)
- *
- * Changes integrated by Justin Seger <jseger@MIT.EDU> & David Hinds :
- * -----------------------------------------------------------------
- *     - Roaming "hack" from Joe Finney <joe@comp.lancs.ac.uk>
- *     - PSA CRC code from Bob Gray <rgray@bald.cs.dartmouth.edu>
- *     - Better initialisation of the i82593 controller
- *       from Joseph K. O'Sullivan <josullvn+@cs.cmu.edu>
- *
- * Changes made for release in 3.0.10 :
- * ----------------------------------
- *     - Fix eject "hang" of the driver under 2.2.X :
- *             o create wv_flush_stale_links()
- *             o Rename wavelan_release to wv_pcmcia_release & move up
- *             o move unregister_netdev to wavelan_detach()
- *             o wavelan_release() no longer call wavelan_detach()
- *             o Suppress "release" timer
- *             o Other cleanups & fixes
- *     - New MAC address in the probe
- *     - Reorg PSA_CRC code (endian neutral & cleaner)
- *     - Correct initialisation of the i82593 from Lucent manual
- *     - Put back the watchdog, with larger timeout
- *     - TRANSMIT_NO_CRC is a "normal" error, so recover from it
- *       from Derrick J Brashear <shadow@dementia.org>
- *     - Better handling of TX and RX normal failure conditions
- *     - #ifdef out all the roaming code
- *     - Add ESSID & "AP current address" ioctl stubs
- *     - General cleanup of the code
- *
- * Changes made for release in 3.0.13 :
- * ----------------------------------
- *     - Re-enable compilation of roaming code by default, but with
- *       do_roaming = 0
- *     - Nuke `nwid=nwid^ntohs(beacon->domain_id)' in wl_roam_gather
- *       at the demand of John Carol Langford <jcl@gs176.sp.cs.cmu.edu>
- *     - Introduced WAVELAN_ROAMING_EXT for incomplete ESSID stuff.
- *
- * Changes made for release in 3.0.15 :
- * ----------------------------------
- *     - Change e-mail and web page addresses
- *     - Watchdog timer is now correctly expressed in HZ, not in jiffies
- *     - Add channel number to the list of frequencies in range
- *     - Add the (short) list of bit-rates in range
- *     - Developp a new sensitivity... (sens.value & sens.fixed)
- *
- * Changes made for release in 3.1.2 :
- * ---------------------------------
- *     - Fix check for root permission (break instead of exit)
- *     - New nwid & encoding setting (Wireless Extension 9)
- *
- * Changes made for release in 3.1.12 :
- * ----------------------------------
- *     - reworked wv_82593_cmd to avoid using the IRQ handler and doing
- *       ugly things with interrupts.
- *     - Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog
- *     - Update to new network API (softnet - 2.3.43) :
- *             o replace dev->tbusy (David + me)
- *             o replace dev->tstart (David + me)
- *             o remove dev->interrupt (David)
- *             o add SMP locking via spinlock in splxx (me)
- *             o add spinlock in interrupt handler (me)
- *             o use kernel watchdog instead of ours (me)
- *             o verify that all the changes make sense and work (me)
- *     - Re-sync kernel/pcmcia versions (not much actually)
- *     - A few other cleanups (David & me)...
- *
- * Changes made for release in 3.1.22 :
- * ----------------------------------
- *     - Check that SMP works, remove annoying log message
- *
- * Changes made for release in 3.1.24 :
- * ----------------------------------
- *     - Fix unfrequent card lockup when watchdog was reseting the hardware :
- *             o control first busy loop in wv_82593_cmd()
- *             o Extend spinlock protection in wv_hw_config()
- *
- * Changes made for release in 3.1.33 :
- * ----------------------------------
- *     - Optional use new driver API for Wireless Extensions :
- *             o got rid of wavelan_ioctl()
- *             o use a bunch of iw_handler instead
- *
- * Changes made for release in 3.2.1 :
- * ---------------------------------
- *     - Set dev->trans_start to avoid filling the logs
- *             (and generating useless abort commands)
- *     - Avoid deadlocks in mmc_out()/mmc_in()
- *
- * Wishes & dreams:
- * ----------------
- *     - Cleanup and integrate the roaming code
- *       (std debug, set DomainID, decay avg and co...)
- */
-
-/***************************** INCLUDES *****************************/
-
-/* Linux headers that we need */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/ethtool.h>
-#include <linux/wireless.h>            /* Wireless extensions */
-#include <net/iw_handler.h>            /* New driver API */
-
-/* Pcmcia headers that we need */
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
-/* Wavelan declarations */
-#include <linux/i82593.h>      /* Definitions for the Intel chip */
-
-#include "wavelan_cs.h"        /* Others bits of the hardware */
-
-/************************** DRIVER OPTIONS **************************/
-/*
- * `#define' or `#undef' the following constant to change the behaviour
- * of the driver...
- */
-#define WAVELAN_ROAMING                /* Include experimental roaming code */
-#undef WAVELAN_ROAMING_EXT     /* Enable roaming wireless extensions */
-#undef SET_PSA_CRC             /* Set the CRC in PSA (slower) */
-#define USE_PSA_CONFIG         /* Use info from the PSA */
-#undef EEPROM_IS_PROTECTED     /* Doesn't seem to be necessary */
-#define MULTICAST_AVOID                /* Avoid extra multicast (I'm sceptical) */
-#undef SET_MAC_ADDRESS         /* Experimental */
-
-/* Warning : these stuff will slow down the driver... */
-#define WIRELESS_SPY           /* Enable spying addresses */
-#undef HISTOGRAM               /* Enable histogram of sig level... */
-
-/****************************** DEBUG ******************************/
-
-#undef DEBUG_MODULE_TRACE      /* Module insertion/removal */
-#undef DEBUG_CALLBACK_TRACE    /* Calls made by Linux */
-#undef DEBUG_INTERRUPT_TRACE   /* Calls to handler */
-#undef DEBUG_INTERRUPT_INFO    /* type of interrupt & so on */
-#define DEBUG_INTERRUPT_ERROR  /* problems */
-#undef DEBUG_CONFIG_TRACE      /* Trace the config functions */
-#undef DEBUG_CONFIG_INFO       /* What's going on... */
-#define DEBUG_CONFIG_ERRORS    /* Errors on configuration */
-#undef DEBUG_TX_TRACE          /* Transmission calls */
-#undef DEBUG_TX_INFO           /* Header of the transmitted packet */
-#undef DEBUG_TX_FAIL           /* Normal failure conditions */
-#define DEBUG_TX_ERROR         /* Unexpected conditions */
-#undef DEBUG_RX_TRACE          /* Transmission calls */
-#undef DEBUG_RX_INFO           /* Header of the transmitted packet */
-#undef DEBUG_RX_FAIL           /* Normal failure conditions */
-#define DEBUG_RX_ERROR         /* Unexpected conditions */
-#undef DEBUG_PACKET_DUMP       /* Dump packet on the screen */
-#undef DEBUG_IOCTL_TRACE       /* Misc call by Linux */
-#undef DEBUG_IOCTL_INFO                /* Various debug info */
-#define DEBUG_IOCTL_ERROR      /* What's going wrong */
-#define DEBUG_BASIC_SHOW       /* Show basic startup info */
-#undef DEBUG_VERSION_SHOW      /* Print version info */
-#undef DEBUG_PSA_SHOW          /* Dump psa to screen */
-#undef DEBUG_MMC_SHOW          /* Dump mmc to screen */
-#undef DEBUG_SHOW_UNUSED       /* Show also unused fields */
-#undef DEBUG_I82593_SHOW       /* Show i82593 status */
-#undef DEBUG_DEVICE_SHOW       /* Show device parameters */
-
-/************************ CONSTANTS & MACROS ************************/
-
-#ifdef DEBUG_VERSION_SHOW
-static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/1/02\n";
-#endif
-
-/* Watchdog temporisation */
-#define        WATCHDOG_JIFFIES        (256*HZ/100)
-
-/* Fix a bug in some old wireless extension definitions */
-#ifndef IW_ESSID_MAX_SIZE
-#define IW_ESSID_MAX_SIZE      32
-#endif
-
-/* ------------------------ PRIVATE IOCTL ------------------------ */
-
-#define SIOCSIPQTHR    SIOCIWFIRSTPRIV         /* Set quality threshold */
-#define SIOCGIPQTHR    (SIOCIWFIRSTPRIV + 1)   /* Get quality threshold */
-#define SIOCSIPROAM     (SIOCIWFIRSTPRIV + 2)  /* Set roaming state */
-#define SIOCGIPROAM     (SIOCIWFIRSTPRIV + 3)  /* Get roaming state */
-
-#define SIOCSIPHISTO   (SIOCIWFIRSTPRIV + 4)   /* Set histogram ranges */
-#define SIOCGIPHISTO   (SIOCIWFIRSTPRIV + 5)   /* Get histogram values */
-
-/*************************** WaveLAN Roaming  **************************/
-#ifdef WAVELAN_ROAMING         /* Conditional compile, see above in options */
-
-#define WAVELAN_ROAMING_DEBUG   0      /* 1 = Trace of handover decisions */
-                                       /* 2 = Info on each beacon rcvd... */
-#define MAX_WAVEPOINTS         7       /* Max visible at one time */
-#define WAVEPOINT_HISTORY      5       /* SNR sample history slow search */
-#define WAVEPOINT_FAST_HISTORY 2       /* SNR sample history fast search */
-#define SEARCH_THRESH_LOW      10      /* SNR to enter cell search */
-#define SEARCH_THRESH_HIGH     13      /* SNR to leave cell search */
-#define WAVELAN_ROAMING_DELTA  1       /* Hysteresis value (+/- SNR) */
-#define CELL_TIMEOUT           (2*HZ)  /* in jiffies */
-
-#define FAST_CELL_SEARCH       1       /* Boolean values... */
-#define NWID_PROMISC           1       /* for code clarity. */
-
-typedef struct wavepoint_beacon {
-  unsigned char                dsap,           /* Unused */
-                       ssap,           /* Unused */
-                       ctrl,           /* Unused */
-                       O, U, I,                /* Unused */
-                       spec_id1,       /* Unused */
-                       spec_id2,       /* Unused */
-                       pdu_type,       /* Unused */
-                       seq;            /* WavePoint beacon sequence number */
-  __be16               domain_id,      /* WavePoint Domain ID */
-                       nwid;           /* WavePoint NWID */
-} wavepoint_beacon;
-
-typedef struct wavepoint_history {
-  unsigned short       nwid;           /* WavePoint's NWID */
-  int                  average_slow;   /* SNR running average */
-  int                  average_fast;   /* SNR running average */
-  unsigned char          sigqual[WAVEPOINT_HISTORY]; /* Ringbuffer of recent SNR's */
-  unsigned char                qualptr;        /* Index into ringbuffer */
-  unsigned char                last_seq;       /* Last seq. no seen for WavePoint */
-  struct wavepoint_history *next;      /* Next WavePoint in table */
-  struct wavepoint_history *prev;      /* Previous WavePoint in table */
-  unsigned long                last_seen;      /* Time of last beacon recvd, jiffies */
-} wavepoint_history;
-
-struct wavepoint_table {
-  wavepoint_history    *head;          /* Start of ringbuffer */
-  int                  num_wavepoints; /* No. of WavePoints visible */
-  unsigned char                locked;         /* Table lock */
-};
-
-#endif /* WAVELAN_ROAMING */
-
-/****************************** TYPES ******************************/
-
-/* Shortcuts */
-typedef struct iw_statistics   iw_stats;
-typedef struct iw_quality      iw_qual;
-typedef struct iw_freq         iw_freq;
-typedef struct net_local       net_local;
-typedef struct timer_list      timer_list;
-
-/* Basic types */
-typedef u_char         mac_addr[WAVELAN_ADDR_SIZE];    /* Hardware address */
-
-/*
- * Static specific data for the interface.
- *
- * For each network interface, Linux keep data in two structure. "device"
- * keep the generic data (same format for everybody) and "net_local" keep
- * the additional specific data.
- */
-struct net_local {
-  dev_node_t   node;           /* ???? What is this stuff ???? */
-  struct net_device *dev;              /* Reverse link... */
-  spinlock_t   spinlock;       /* Serialize access to the hardware (SMP) */
-  struct pcmcia_device *link;          /* pcmcia structure */
-  int          nresets;        /* Number of hw resets */
-  u_char       configured;     /* If it is configured */
-  u_char       reconfig_82593; /* Need to reconfigure the controller */
-  u_char       promiscuous;    /* Promiscuous mode */
-  u_char       allmulticast;   /* All Multicast mode */
-  int          mc_count;       /* Number of multicast addresses */
-
-  int          stop;           /* Current i82593 Stop Hit Register */
-  int          rfp;            /* Last DMA machine receive pointer */
-  int          overrunning;    /* Receiver overrun flag */
-
-  iw_stats     wstats;         /* Wireless specific stats */
-
-  struct iw_spy_data   spy_data;
-  struct iw_public_data        wireless_data;
-
-#ifdef HISTOGRAM
-  int          his_number;             /* Number of intervals */
-  u_char       his_range[16];          /* Boundaries of interval ]n-1; n] */
-  u_long       his_sum[16];            /* Sum in interval */
-#endif /* HISTOGRAM */
-#ifdef WAVELAN_ROAMING
-  u_long       domain_id;      /* Domain ID we lock on for roaming */
-  int          filter_domains; /* Check Domain ID of beacon found */
- struct wavepoint_table        wavepoint_table;        /* Table of visible WavePoints*/
-  wavepoint_history *curr_point;               /* Current wavepoint */
-  int                  cell_search;            /* Searching for new cell? */
-  struct timer_list    cell_timer;             /* Garbage collection */
-#endif /* WAVELAN_ROAMING */
-  void __iomem *mem;
-};
-
-/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
-static inline u_char           /* data */
-       hasr_read(u_long);      /* Read the host interface : base address */
-static void
-       hacr_write(u_long,      /* Write to host interface : base address */
-                  u_char),     /* data */
-       hacr_write_slow(u_long,
-                  u_char);
-static void
-       psa_read(struct net_device *,   /* Read the Parameter Storage Area */
-                int,           /* offset in PSA */
-                u_char *,      /* buffer to fill */
-                int),          /* size to read */
-       psa_write(struct net_device *,  /* Write to the PSA */
-                 int,          /* Offset in psa */
-                 u_char *,     /* Buffer in memory */
-                 int);         /* Length of buffer */
-static void
-       mmc_out(u_long,         /* Write 1 byte to the Modem Manag Control */
-               u_short,
-               u_char),
-       mmc_write(u_long,       /* Write n bytes to the MMC */
-                 u_char,
-                 u_char *,
-                 int);
-static u_char                  /* Read 1 byte from the MMC */
-       mmc_in(u_long,
-              u_short);
-static void
-       mmc_read(u_long,        /* Read n bytes from the MMC */
-                u_char,
-                u_char *,
-                int),
-       fee_wait(u_long,        /* Wait for frequency EEprom : base address */
-                int,           /* Base delay to wait for */
-                int);          /* Number of time to wait */
-static void
-       fee_read(u_long,        /* Read the frequency EEprom : base address */
-                u_short,       /* destination offset */
-                u_short *,     /* data buffer */
-                int);          /* number of registers */
-/* ---------------------- I82593 SUBROUTINES ----------------------- */
-static int
-       wv_82593_cmd(struct net_device *,       /* synchronously send a command to i82593 */
-                    char *,
-                    int,
-                    int);
-static inline int
-       wv_diag(struct net_device *);   /* Diagnostique the i82593 */
-static int
-       read_ringbuf(struct net_device *,       /* Read a receive buffer */
-                    int,
-                    char *,
-                    int);
-static void
-       wv_82593_reconfig(struct net_device *); /* Reconfigure the controller */
-/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
-static void
-       wv_init_info(struct net_device *);      /* display startup info */
-/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static iw_stats *
-       wavelan_get_wireless_stats(struct net_device *);
-/* ----------------------- PACKET RECEPTION ----------------------- */
-static int
-       wv_start_of_frame(struct net_device *,  /* Seek beggining of current frame */
-                         int,  /* end of frame */
-                         int); /* start of buffer */
-static void
-       wv_packet_read(struct net_device *,     /* Read a packet from a frame */
-                      int,
-                      int),
-       wv_packet_rcv(struct net_device *);     /* Read all packets waiting */
-/* --------------------- PACKET TRANSMISSION --------------------- */
-static void
-       wv_packet_write(struct net_device *,    /* Write a packet to the Tx buffer */
-                       void *,
-                       short);
-static netdev_tx_t
-       wavelan_packet_xmit(struct sk_buff *,   /* Send a packet */
-                           struct net_device *);
-/* -------------------- HARDWARE CONFIGURATION -------------------- */
-static int
-       wv_mmc_init(struct net_device *);       /* Initialize the modem */
-static int
-       wv_ru_stop(struct net_device *),        /* Stop the i82593 receiver unit */
-       wv_ru_start(struct net_device *);       /* Start the i82593 receiver unit */
-static int
-       wv_82593_config(struct net_device *);   /* Configure the i82593 */
-static int
-       wv_pcmcia_reset(struct net_device *);   /* Reset the pcmcia interface */
-static int
-       wv_hw_config(struct net_device *);      /* Reset & configure the whole hardware */
-static void
-       wv_hw_reset(struct net_device *);       /* Same, + start receiver unit */
-static int
-       wv_pcmcia_config(struct pcmcia_device *);       /* Configure the pcmcia interface */
-static void
-       wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */
-/* ---------------------- INTERRUPT HANDLING ---------------------- */
-static irqreturn_t
-       wavelan_interrupt(int,  /* Interrupt handler */
-                         void *);
-static void
-       wavelan_watchdog(struct net_device *);  /* Transmission watchdog */
-/* ------------------- CONFIGURATION CALLBACKS ------------------- */
-static int
-       wavelan_open(struct net_device *),              /* Open the device */
-       wavelan_close(struct net_device *);     /* Close the device */
-static void
-       wavelan_detach(struct pcmcia_device *p_dev);    /* Destroy a removed device */
-
-/**************************** VARIABLES ****************************/
-
-/*
- * Parameters that can be set with 'insmod'
- * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
- */
-
-/* Shared memory speed, in ns */
-static int     mem_speed;
-
-/* New module interface */
-module_param(mem_speed, int, 0);
-
-#ifdef WAVELAN_ROAMING         /* Conditional compile, see above in options */
-/* Enable roaming mode ? No ! Please keep this to 0 */
-static int     do_roaming;
-module_param(do_roaming, bool, 0);
-#endif /* WAVELAN_ROAMING */
-
-MODULE_LICENSE("GPL");
-
-#endif /* WAVELAN_CS_P_H */
-