Commit 1d794e3b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Staging: wavelan: delete the driver

It has sat in the staging directory since October of 2009, and no one
has stepped up to take it over, so odds are, no one cares about it
anymore.  So, it is now deleted as scheduled, and documented in the TODO
file.

Cc: John W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent f80a3f62
......@@ -125,8 +125,6 @@ source "drivers/staging/batman-adv/Kconfig"
source "drivers/staging/samsung-laptop/Kconfig"
source "drivers/staging/wavelan/Kconfig"
source "drivers/staging/netwave/Kconfig"
source "drivers/staging/sm7xx/Kconfig"
......
......@@ -43,8 +43,6 @@ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
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/
......
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.
obj-$(CONFIG_WAVELAN) += wavelan.o
obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan_cs.o
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>.
/*
* 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.
*/
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* 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.
*/
/*
* 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 */
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* 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 */
/*
* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment