e902ae382a
compiler. Be carefull about over usage of volatile, it really killed performance in a few areas and there was a better place to make things volatile in almost all cases. The driver can now receive at full speed without RNR errors.
368 lines
16 KiB
C
368 lines
16 KiB
C
/*
|
|
* Copyright (c) 1993, 1994, 1995
|
|
* Rodney W. Grimes, Milwaukie, Oregon 97222. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer as
|
|
* the first lines of this file unmodified.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Rodney W. Grimes.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY RODNEY W. GRIMES ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL RODNEY W. GRIMES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* $Id: if_ixreg.h,v 1.3 1995/02/26 20:13:15 rgrimes Exp $
|
|
*/
|
|
|
|
/*
|
|
* These really belong some place else, but I can't find them right
|
|
* now. I'll look again latter
|
|
*/
|
|
#define ETHER_ADDRESS_LENGTH 6 /* Length of an ethernet address */
|
|
#define ETHER_HEADER_LENGTH 14 /* Length of an ethernet header */
|
|
#define ETHER_DATA_LENGTH ETHERMTU
|
|
#define ETHER_CRC_LENGTH 4
|
|
#define ETHER_MIN_LENGTH 64 /* Minimum length of an ethernet packet */
|
|
#define ETHER_MAX_LENGTH (ETHER_HEADER_LENGTH + \
|
|
ETHERMTU + \
|
|
ETHER_CRC_LENGTH)
|
|
|
|
#define IX_IO_PORTS 16 /* Number of I/O ports used, note
|
|
* this is not true, due to shadow
|
|
* ports at 400X,800X and C00X
|
|
*/
|
|
|
|
#define dxreg 0x00 /* Data transfer register Word R/W */
|
|
#define wrptr 0x02 /* Write address pointer Word R/W */
|
|
#define rdptr 0x04 /* Read address pointer Word R/W */
|
|
#define ca_ctrl 0x06 /* Channel attention control Byte R/W */
|
|
#define sel_irq 0x07 /* IRQ select Byte R/W */
|
|
#define IRQ_ENABLE 0x08 /* Enable board interrupts */
|
|
#define smb_ptr 0x08 /* Shadow memory bank pointer Word R/W */
|
|
#define memdec 0x0A /* Memory address decode Byte W */
|
|
#define memctrl 0x0B /* Memory mapped control Byte R/W */
|
|
#define MEMCTRL_UNUSED 0x83 /* Unused bits */
|
|
#define MEMCTRL_MEMMEG 0x60 /* Which megabyte of memory, 0, E or F */
|
|
#define MEMCTRL_FMCS16 0x10 /* MEMCS16- for F000 */
|
|
#define MEMCTRL_MEMADJ 0xC0 /* memory adjust value */
|
|
#define mempc 0x0C /* MEMCS16- page control Byte R/W */
|
|
#define config 0x0D /* Configuration, test Byte R/W */
|
|
#define BART_LINK 0x01 /* link integrity active, TPE */
|
|
#define BART_LOOPBACK 0x02 /* Loopback, 0=none, 1=loopback */
|
|
#define SLOT_WIDTH 0x04 /* 0 = 8bit, 1 = 16bit */
|
|
#define BART_USEWIDTH 0x08 /* use SLOT_WIDTH for bus size */
|
|
#define BART_IOCHRDY_LATE 0x10 /* iochrdy late control bit */
|
|
#define BART_IO_TEST_EN 0x20 /* enable iochrdy timing test */
|
|
#define BART_IO_RESULT 0x40 /* result of the iochrdy test */
|
|
#define BART_MCS16_TEST 0x80 /* enable memcs16 select test */
|
|
#define ee_ctrl 0x0E /* EEPROM control, reset Byte R/W */
|
|
#define EENORMAL 0x00 /* normal state of ee_ctrl */
|
|
#define EESK 0x01 /* EEPROM clock bit */
|
|
#define EECS 0x02 /* EEPROM chip select */
|
|
#define EEDI 0x04 /* EEPROM data in bit (write EEPROM) */
|
|
#define EEDO 0x08 /* EEPROM data out bit (read EEPROM) */
|
|
#define EEUNUSED 0x30 /* unused bits in ee_ctrl */
|
|
#define GA_RESET 0x40 /* BART ASIC chip reset pin */
|
|
#define I586_RESET 0x80 /* 82586 chip reset pin */
|
|
#define memectrl 0x0F /* Memory control, E000h seg Byte W */
|
|
#define autoid 0x0F /* Auto ID register Byte R */
|
|
|
|
#define BOARDID 0xBABA /* Intel PCED board ID for EtherExpress */
|
|
|
|
#define eeprom_opsize1 0x03 /* Size of opcodes for r/w/e */
|
|
#define eeprom_read_op 0x06 /* EEPROM read op code */
|
|
#define eeprom_write_op 0x05 /* EEPROM write op code */
|
|
#define eeprom_erase_op 0x07 /* EEPROM erase op code */
|
|
#define eeprom_opsize2 0x05 /* Size of opcodes for we/wdr */
|
|
#define eeprom_wenable_op 0x13 /* EEPROM write enable op code */
|
|
#define eeprom_wdisable_op 0x10 /* EEPROM write disable op code */
|
|
|
|
#define eeprom_addr_size 0x06 /* Size of EEPROM address */
|
|
|
|
/* These are the locations in the EEPROM */
|
|
#define eeprom_config1 0x00 /* Configuration register 1 */
|
|
#define CONNECT_BNCTPE 0x1000 /* 0 = AUI, 1 = BNC/TPE */
|
|
#define IRQ 0xE000 /* Encoded IRQ */
|
|
#define IRQ_SHIFT 13 /* To shift IRQ to lower bits */
|
|
#define eeprom_lock_address 0x01 /* contains the lock bit */
|
|
#define EEPROM_LOCKED 0x01 /* means that it is locked */
|
|
#define eeprom_enetaddr_low 0x02 /* Ethernet address, low word */
|
|
#define eeprom_enetaddr_mid 0x03 /* Ethernet address, middle word */
|
|
#define eeprom_enetaddr_high 0x04 /* Ethernet address, high word */
|
|
#define eeprom_config2 0x05 /* Configureation register 2 */
|
|
#define CONNECT_TPE 0x0001 /* 0 = BNC, 1 = TPE */
|
|
|
|
/* this converts a kernal virtual address to a board offset */
|
|
#define KVTOBOARD(addr) ((int)addr - (int)sc->maddr)
|
|
#define BOARDTOKV(addr) ((int)addr + (int)sc->maddr)
|
|
|
|
/* XXX This belongs is ic/i825x6.h, but is here for editing for now */
|
|
|
|
#define INTEL586NULL 0xFFFF /* NULL pointer for 82586 */
|
|
#define INTEL596NULL 0xFFFFFFFF /* NULL pointer for 82596 */
|
|
|
|
/*
|
|
* Layout of memory for the 825x6 chip:
|
|
* Low: Control Blocks
|
|
* Transmit Frame Descriptor(s)
|
|
* Transmit Frame Buffer(s)
|
|
* Receive Frame Descriptors
|
|
* Receive Frames
|
|
* SCB_ADDR System Control Block
|
|
* ISCP_ADDR Intermediate System Configuration Pointer
|
|
* High: SCP_ADDR System Configuration Pointer
|
|
*/
|
|
#define SCP_ADDR (sc->msize - sizeof(scp_t))
|
|
#define ISCP_ADDR (SCP_ADDR - sizeof(iscp_t))
|
|
#define SCB_ADDR (ISCP_ADDR - sizeof(scb_t))
|
|
|
|
#define TB_COUNT 3 /* How many transfer buffers in the TFA */
|
|
#define TB_SIZE (ETHER_MAX_LENGTH) /* size of transmit buffer */
|
|
#define TFA_START 0x0000 /* Start of the TFA */
|
|
#define TFA_SIZE (TB_COUNT * \
|
|
(sizeof(cb_transmit_t) + sizeof(tbd_t) + TB_SIZE))
|
|
|
|
#define RFA_START (TFA_SIZE)
|
|
#define RFA_SIZE (SCP_ADDR - RFA_START)
|
|
#define RB_SIZE (ETHER_MAX_LENGTH) /* size of receive buffer */
|
|
|
|
typedef struct /* System Configuration Pointer */
|
|
{
|
|
u_short unused1; /* should be zeros for 82596 compatibility */
|
|
u_short sysbus; /* width of the 82586 data bus 0=16, 1=8 */
|
|
u_short unused2; /* should be zeros for 82596 compatibility */
|
|
u_short unused3; /* should be zeros for 82596 compatibility */
|
|
u_long iscp; /* iscp address (24bit 586, 32bit 596) */
|
|
} scp_t;
|
|
|
|
typedef struct /* Intermediate System Configuration Pointer */
|
|
{
|
|
volatile
|
|
u_short busy; /* Set to 1 by host before its first CA,
|
|
cleared by 82586 after reading */
|
|
#define ISCP_BUSY 0x01 /* 82586 is busy reading the iscp */
|
|
u_short scb_offset; /* Address of System Control Block */
|
|
u_long scb_base; /* scb base address (24bit 586, 32bit 596) */
|
|
} iscp_t;
|
|
|
|
typedef struct /* System Control Block */
|
|
{
|
|
volatile
|
|
u_short status; /* status bits */
|
|
#define SCB_RUS_MASK 0x0070 /* receive unit status mask */
|
|
#define SCB_RUS_IDLE 0x0000 /* receive unit status idle */
|
|
#define SCB_RUS_SUSP 0x0010 /* receive unit status suspended */
|
|
#define SCB_RUS_NRSC 0x0020 /* receive unit status no resources */
|
|
#define SCB_RUS_READY 0x0040 /* receive unit status ready */
|
|
#define SCB_CUS_MASK 0x0700 /* command unit status mask */
|
|
#define SCB_CUS_IDLE 0x0000 /* command unit status idle */
|
|
#define SCB_CUS_SUSP 0x0100 /* command unit status suspended */
|
|
#define SCB_CUS_ACT 0x0200 /* command unit status active */
|
|
#define SCB_STAT_MASK 0xF000 /* command unit status mask */
|
|
#define SCB_STAT_RNR 0x1000 /* receive unit left the ready state */
|
|
#define SCB_STAT_CNA 0x2000 /* command unit left the active state */
|
|
#define SCB_STAT_FR 0x4000 /* the ru finished receiving a frame */
|
|
#define SCB_STAT_CX 0x8000 /* the cu finished executing a command
|
|
with its I (interrupt) bit set */
|
|
#define SCB_STAT_NULL 0x0000 /* used to clear the status work */
|
|
u_short command; /* command bits */
|
|
#define SCB_RUC_MASK 0x0070 /* receive unit command mask */
|
|
#define SCB_RUC_NOP 0x0000 /* receive unit command nop */
|
|
#define SCB_RUC_START 0x0010 /* receive unit command start */
|
|
#define SCB_RUC_RESUME 0x0020 /* receive unit command resume */
|
|
#define SCB_RUC_SUSP 0x0030 /* receive unit command suspend */
|
|
#define SCB_RUC_ABORT 0x0040 /* receive unit command abort */
|
|
#define SCB_RESET 0x0080 /* reset the chip, same as hardware reset */
|
|
#define SCB_CUC_MASK 0x0700 /* command unit command mask */
|
|
#define SCB_CUC_NOP 0x0000 /* command unit command nop */
|
|
#define SCB_CUC_START 0x0100 /* start execution of the first command */
|
|
#define SCB_CUC_RESUME 0x0200 /* resume execution of the next command */
|
|
#define SCB_CUC_SUSP 0x0300 /* suspend execution after the current command */
|
|
#define SCB_CUC_ABORT 0x0400 /* abort execution of the current command */
|
|
#define SCB_ACK_MASK 0xF000 /* command unit acknowledge mask */
|
|
#define SCB_ACK_RNR 0x1000 /* ack receive unit left the ready state */
|
|
#define SCB_ACK_CNA 0x2000 /* ack command unit left the active state */
|
|
#define SCB_ACK_FR 0x4000 /* ack the ru finished receiving a frame */
|
|
#define SCB_ACK_CX 0x8000 /* ack the cu finished executing a command
|
|
with its I (interrupt) bit set */
|
|
u_short cbl_offset; /* first command block on the cbl */
|
|
u_short rfa_offset; /* receive frame area */
|
|
volatile
|
|
u_short crc_errors; /* frame was aligned, but bad crc */
|
|
volatile
|
|
u_short aln_errors; /* frame was not aligned, and had bad crc */
|
|
volatile
|
|
u_short rsc_errors; /* did not have resources to receive */
|
|
volatile
|
|
u_short ovr_errors; /* system bus was not availiable to receive */
|
|
} scb_t;
|
|
|
|
typedef struct /* command block - nop (also the common part of cb's */
|
|
{
|
|
volatile
|
|
u_short status; /* status bits */
|
|
#define CB_COLLISIONS 0x000F /* the number of collisions that occured */
|
|
#define CB_BIT4 0x0010 /* reserved by intel */
|
|
#define CB_EXCESSCOLL 0x0020 /* the number of collisions > MAX allowed */
|
|
#define CB_HEARTBEAT 0x0040 /* */
|
|
#define CB_DEFER 0x0080 /* had to defer due to trafic */
|
|
#define CB_DMAUNDER 0x0100 /* dma underrun */
|
|
#define CB_NOCTS 0x0200 /* lost clear to send */
|
|
#define CB_NOCS 0x0400 /* lost carrier sense */
|
|
#define CB_LATECOLL 0x0800 /* late collision occured (82596 only) */
|
|
#define CB_ABORT 0x1000 /* command was aborted by CUC abort command */
|
|
#define CB_OK 0x2000 /* command executed without error */
|
|
#define CB_BUSY 0x4000 /* command is being executed */
|
|
#define CB_COMPLETE 0x8000 /* command completed */
|
|
u_short command; /* command bits */
|
|
#define CB_CMD_MASK 0x0007 /* command mask */
|
|
#define CB_CMD_NOP 0x0000 /* nop command */
|
|
#define CB_CMD_IAS 0x0001 /* individual address setup command */
|
|
#define CB_CMD_CONF 0x0002 /* configure command */
|
|
#define CB_CMD_MCAS 0x0003 /* multicast address setup command */
|
|
#define CB_CMD_TRANSMIT 0x0004 /* transmit command */
|
|
#define CB_CMD_TDR 0x0005 /* time domain reflectometry command */
|
|
#define CB_CMD_DUMP 0x0006 /* dump command */
|
|
#define CB_CMD_DIAGNOSE 0x0007 /* diagnose command */
|
|
#define CB_CMD_INT 0x2000 /* interrupt when command completed */
|
|
#define CB_CMD_SUSP 0x4000 /* suspend CU when command completed */
|
|
#define CB_CMD_EL 0x8000 /* end of the command block list */
|
|
u_short next; /* pointer to the next cb */
|
|
} cb_t;
|
|
|
|
typedef struct /* command block - individual address setup command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
u_char source[ETHER_ADDRESS_LENGTH];
|
|
/* ethernet hardware address */
|
|
} cb_ias_t;
|
|
|
|
typedef struct /* command block - configure command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
u_char byte[12]; /* ZZZ this is ugly, but it works */
|
|
} cb_configure_t;
|
|
|
|
typedef struct /* command block - multicast address setup command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
} cb_mcas_t;
|
|
|
|
typedef struct /* command block - transmit command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
u_short tbd_offset; /* transmit buffer descriptor offset */
|
|
u_char destination[ETHER_ADDRESS_LENGTH];
|
|
/* ethernet destination address field */
|
|
u_short length; /* ethernet length field */
|
|
u_char byte[16]; /* XXX stupid fill tell I fix the ixinit
|
|
* code for the special cb's */
|
|
} cb_transmit_t;
|
|
|
|
typedef struct /* command block - tdr command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
} cb_tdr_t;
|
|
|
|
typedef struct /* command block - dump command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
} cb_dump_t;
|
|
|
|
typedef struct /* command block - diagnose command */
|
|
{
|
|
cb_t common; /* common part of all command blocks */
|
|
} cb_diagnose_t;
|
|
|
|
typedef struct /* Transmit Buffer Descriptor */
|
|
{
|
|
volatile
|
|
u_short act_count; /* size of buffer actual count of valid bytes */
|
|
#define TBD_STAT_EOF 0x8000 /* end of frame */
|
|
u_short next; /* pointer to the next tbd */
|
|
u_long buffer; /* transmit buffer address (24bit 586, 32bit 596) */
|
|
} tbd_t;
|
|
|
|
typedef struct /* Receive Frame Descriptor */
|
|
{
|
|
volatile
|
|
u_short status; /* status bits */
|
|
#define RFD_BUSY 0x4000 /* frame is being received */
|
|
#define RFD_COMPLETE 0x8000 /* this frame is complete */
|
|
u_short command; /* command bits */
|
|
#define RFD_CMD_SUSP 0x4000 /* suspend the ru after this rfd is used */
|
|
#define RFD_CMD_EL 0x8000 /* end of the rfd list */
|
|
u_short next; /* pointer to the next rfd */
|
|
u_short rbd_offset; /* pointer to the first rbd for this frame */
|
|
u_char destination[6]; /* ethernet destination address */
|
|
u_char source[6]; /* ethernet source address */
|
|
u_short length; /* ethernet length field */
|
|
} rfd_t;
|
|
|
|
typedef struct /* Receive Buffer Descriptor */
|
|
{
|
|
volatile
|
|
u_short act_count; /* Actual Count (size) and status bits */
|
|
#define RBD_STAT_SIZE 0x3FFF /* size mask */
|
|
#define RBD_STAT_VALID 0x4000 /* act_count field is valid */
|
|
#define RBD_STAT_EOF 0x8000 /* end of frame */
|
|
u_short next; /* pointer to the next rbd */
|
|
u_long buffer; /* receive buffer address */
|
|
u_short size; /* size of buffer in bytes, must be even */
|
|
#define RBD_SIZE_EL 0x8000 /* end of rbd list */
|
|
} rbd_t;
|
|
|
|
/*
|
|
* Ethernet software status per interface.
|
|
*
|
|
* Each interface is referenced by a network interface structure,
|
|
* arpcom.ac_if, which the routing code uses to locate the interface.
|
|
* This structure contains the output queue for the interface, its address, ...
|
|
*/
|
|
typedef struct
|
|
{
|
|
struct arpcom arpcom; /* Ethernet common part see net/if.h */
|
|
int iobase; /* I/O base address for this interface */
|
|
caddr_t maddr; /* Memory base address for this interface */
|
|
int msize; /* Size of memory */
|
|
int flags; /* Software state */
|
|
#define IXF_NONE 0x00000000 /* Clear all flags */
|
|
#define IXF_INITED 0x00000001 /* Device has been inited */
|
|
#define IXF_BPFATTACHED 0x80000000 /* BPF has been attached */
|
|
int connector; /* Type of connector used on board */
|
|
#define AUI 0x00 /* Using AUI connector */
|
|
#define BNC 0x01 /* Using BNC connector */
|
|
#define TPE 0x02 /* Using TPE connector */
|
|
u_short irq_encoded; /* Encoded interrupt for use on bart */
|
|
int width; /* Width of slot the board is in, these
|
|
* constants are defined to match what
|
|
* the 82586/596 wants in scp->sysbus */
|
|
#define WIDTH_8 0x01 /* 8-bit slot */
|
|
#define WIDTH_16 0x00 /* 16-bit slot */
|
|
cb_t *cb_head; /* head of cb list */
|
|
cb_t *cb_tail; /* tail of cb list */
|
|
tbd_t *tbd_head; /* head of the tbd list */
|
|
tbd_t *tbd_tail; /* tail of the tbd list */
|
|
rfd_t *rfd_head; /* head of the rfd list */
|
|
rfd_t *rfd_tail; /* tail of the rfd list */
|
|
rbd_t *rbd_head; /* head of the rbd list */
|
|
rbd_t *rbd_tail; /* tail of the rbd list */
|
|
} ix_softc_t;
|