/* * * =================================== * HARP | Host ATM Research Platform * =================================== * * * This Host ATM Research Platform ("HARP") file (the "Software") is * made available by Network Computing Services, Inc. ("NetworkCS") * "AS IS". NetworkCS does not provide maintenance, improvements or * support of any kind. * * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. * In no event shall NetworkCS be responsible for any damages, including * but not limited to consequential damages, arising from or relating to * any use of the Software or related support. * * Copyright 1994-1998 Network Computing Services, Inc. * * Copies of this Software may be made, however, the above copyright * notice must be reproduced on all copies. * * @(#) $FreeBSD: src/sys/dev/hea/eni.h,v 1.2 1999/08/28 00:41:43 peter Exp $ */ /* * Efficient ENI Adapter Support * * Protocol and implementation definitions * */ #ifndef _ENI_ENI_H #define _ENI_ENI_H #include #include #include /* * Physical device name - used to configure HARP devices */ #ifndef ENI_DEV_NAME #define ENI_DEV_NAME "hea" /* HARP Efficient ATM */ #endif #define ENI_MAX_UNITS 4 #define ENI_IFF_MTU 9188 #define ENI_MAX_VCI 1023 /* 0 - 1023 */ #define ENI_MAX_VPI 0 #define ENI_IFQ_MAXLEN 1000 /* rx/tx queue lengths */ /* * Size of small and large receive buffers */ #define ENI_SMALL_BSIZE 64 #define ENI_LARGE_BSIZE MCLBYTES /* * ENI memory map offsets IN WORDS, not bytes * * The Efficient Adapter implements a 4 MB address space. The lower * 2 MB are used by bootprom (E)EPROM and by chipset registers such * as the MIDWAY and SUNI chips. The (upto) upper 2 MB is used for * RAM. Of the RAM, the lower 28 KB is used for fixed tables - the * VCI table, the RX and TX DMA queues, and the Service List queue. * Memory above the 28 KB range is available for RX and TX buffers. * * NOTE: Access to anything other then the (E)EPROM MUST be as a 32 bit * access. Also note that Efficient uses both byte addresses and word * addresses when describing offsets. BE CAREFUL or you'll get confused! */ /* * Size of memory space reserved for registers and expansion (e)eprom. */ #define ENI_REG_SIZE 0x200000 /* Two megabytes */ #define SUNI_OFFSET 0x008000 /* SUNI chip registers */ #define MIDWAY_OFFSET 0x010000 /* MIDWAY chip registers */ #define RAM_OFFSET 0x080000 /* Adapter RAM */ #define VCITBL_OFFSET 0x080000 /* VCI Table offset */ #define RXQUEUE_OFFSET 0x081000 /* RX DMA Queue offset */ #define TXQUEUE_OFFSET 0x081400 /* TX DMA Queue offset */ #define SVCLIST_OFFSET 0x081800 /* SVC List Queue offset */ #define SEGBUF_BASE 0x007000 /* Base from start of RAM */ #define DMA_LIST_SIZE 512 /* 1024 words / 2 words per entry */ #define SVC_LIST_SIZE 1024 /* 1024 words / 1 word per entry */ /* * Values for testing size of RAM on adapter * * Efficient has (at least) two different memory sizes available. One * is a client card which has either 128 KB or 512 KB RAM, the other * is a server card which has 2 MB RAM. The driver will size and test * the memory to correctly determine what's available. */ #define MAX_ENI_MEM 0x200000 /* 2 MB - max. mem supported */ #define TEST_STEP 0x000400 /* Look at 1 KB steps */ #define TEST_PAT 0xA5A5A5A5 /* Test pattern */ /* * Values for memory allocator */ #define ENI_BUF_PGSZ 1024 /* Allocation unit of buffers */ #define ENI_BUF_NBIT 8 /* Number of bits to get from */ /* min buffer (1KB) to max (128KB) */ /* * Values for allocating TX buffers */ #define MAX_CLIENT_RAM 512 /* Most RAM a client card will have */ #define TX_SMALL_BSIZE 32 /* Small buffer - 32KB */ #define TX_LARGE_BSIZE 128 /* Large buffer - 128KB */ /* * Values for allocating RX buffers */ #define RX_SIG_BSIZE 4 /* Signalling buffer - 4KB */ #define RX_CLIENT_BSIZE 16 /* Client buffer - 16KB */ #define RX_SERVER_BSIZE 32 /* Server buffer - 32KB */ /* * Adapter bases all addresses off of some power from 1KB. Thus, it * only needs to store the most sigificant bits and can drop the lower * 10 bits. */ #define ENI_LOC_PREDIV 10 /* Bits location is shifted */ /* Location is prescaled by 1KB */ /* before use in various places */ #define MIDWAY_DELAY 10 /* Time to wait for Midway finish */ /* * Define the MIDWAY register offsets and any interesting bits within * the register */ #define MIDWAY_ID 0x00 /* ID/Reset register */ #define MIDWAY_RESET 0 /* iWrite of any value */ #define ID_SHIFT 27 /* Midway ID version */ #define ID_MASK 0x1F /* ID mask */ #define MID_SHIFT 7 /* Mother board ID */ #define MID_MASK 0x7 /* MID mask */ #define DID_SHIFT 0 /* Daughter board ID */ #define DID_MASK 0x1F /* DID mask */ /* * Efficient defines the following IDs for their adapters: * 0x420/0x620 - SONET MMF, client memory size * 0x430/0x630 - SONET MMF, server memory size * 0x424/0x624 - UTP-5, client memory size * 0x434/0x634 - UTP-5, server memory size */ #define MEDIA_MASK 0x04 /* Mask off UTP-5/MMF media */ #define MIDWAY_ISA 0x01 /* Interrupt Status Ack. */ /* Reading this register */ /* also acknowledges the */ /* posted interrupt(s) */ #define MIDWAY_IS 0x02 /* Interrupt Status */ /* Reading this register */ /* does NOT acknowledge the */ /* posted interrupt(s) */ /* Interrupt names */ #define ENI_INT_STAT 0x00000001 #define ENI_INT_SUNI 0x00000002 #define ENI_INT_SERVICE 0x00000004 #define ENI_INT_TX_DMA 0x00000008 #define ENI_INT_RX_DMA 0x00000010 #define ENI_INT_DMA_ERR 0x00000020 #define ENI_INT_DMA_LERR 0x00000040 #define ENI_INT_IDEN 0x00000080 #define ENI_INT_DMA_OVFL 0x00000100 #define ENI_INT_TX_MASK 0x0001FE00 #define MIDWAY_IE 0x03 /* Interrupt Enable register */ /* Interrupt enable bits are the same as the Interrupt names */ #define MIDWAY_MASTER 0x04 /* Master Control */ /* Master control bits */ #define ENI_M_WAIT500 0x00000001 /* Disable interrupts .5 ms */ #define ENI_M_WAIT1 0x00000002 /* Disable interrupts 1 ms */ #define ENI_M_RXENABLE 0x00000004 /* Enable RX engine */ #define ENI_M_TXENABLE 0x00000008 /* Enable TX engine */ #define ENI_M_DMAENABLE 0x00000010 /* Enable DMA */ #define ENI_M_TXLOCK 0x00000020 /* 0: Streaming, 1: Lock */ #define ENI_M_INTSEL 0x000001C0 /* Int Select mask */ #define ENI_ISEL_SHIFT 6 /* Bits to shift ISEL value */ #define MIDWAY_STAT 0x05 /* Statistics register */ #define MIDWAY_SVCWR 0x06 /* Svc List write pointer */ #define SVC_SIZE_MASK 0x3FF /* Valid bits in svc pointer */ #define MIDWAY_DMAADDR 0x07 /* Current virtual DMA addr */ #define MIDWAY_RX_WR 0x08 /* Write ptr to RX DMA queue */ #define MIDWAY_RX_RD 0x09 /* Read ptr to RX DMA queue */ #define MIDWAY_TX_WR 0x0A /* Write ptr to TX DMA queue */ #define MIDWAY_TX_RD 0x0B /* Read ptr to TX DMA queue */ /* * Registers 0x0C - 0x0F are unused */ /* * MIDWAY supports 8 transmit channels. Each channel has 3 registers * to control operation. Each new channel starts on N * 4 set. Thus, * channel 0 uses register 0x10 - 0x13, channel 1 uses 0x14 - 0x17, etc. * Register 0x13 + N * 4 is unused. */ #define MIDWAY_TXPLACE 0x10 /* Channel N TX location */ #define TXSIZE_SHIFT 11 /* Bits to shift size by */ #define TX_PLACE_MASK 0x7FF /* Valid bits in TXPLACE */ #define MIDWAY_RDPTR 0x11 /* Channel N Read ptr */ #define MIDWAY_DESCR 0x12 /* Channel N Descr ptr */ /* * Register 0x30 on up are unused */ /* * Part of PCI configuration registers but not defined in */ #define PCI_CONTROL_REG 0x60 #define ENDIAN_SWAP_DMA 0x80 /* Enable endian swaps on DMA */ /* * The Efficient adapter references adapter RAM through the use of * location and size values. Eight sizes are defined. When allocating * buffers, there size must be rounded up to the next size which will * hold the requested size. Buffers are allocated on 'SIZE' boundaries. * See eni_buffer.c for more info. */ /* * Buffer SIZE definitions - in words, so from 1 KB to 128 KB */ #define SIZE_256 0x00 #define SIZE_512 0x01 #define SIZE_1K 0x02 #define SIZE_2K 0x03 #define SIZE_4K 0x04 #define SIZE_8K 0x05 #define SIZE_16K 0x06 #define SIZE_32K 0x07 /* * Define values for DMA type - DMA descriptors include a type field and a * count field except in the special case of JK (just-kidding). With type JK, * the count field should be set to the address which will be loaded * into the pointer, ie. where the pointer should next point to, since * JK doesn't have a "size" associated with it. JK DMA is used to skip * over descriptor words, and to strip off padding of AAL5 PDUs. The * DMA_nWORDM types will do a n word DMA burst, but the count field * does not have to equal n. Any difference results in garbage filling * the remaining words of the DMA. These types could be used where a * particular burst size yields better DMA performance. */ #define DMA_WORD 0x00 #define DMA_BYTE 0x01 #define DMA_HWORD 0x02 #define DMA_JK 0x03 #define DMA_4WORD 0x04 #define DMA_8WORD 0x05 #define DMA_16WORD 0x06 #define DMA_2WORD 0x07 #define DMA_4WORDM 0x0C #define DMA_8WORDM 0x0D #define DMA_16WORDM 0x0E #define DMA_2WORDM 0x0F /* * Define the size of the local DMA list we'll build before * giving up on the PDU. */ #define TEMP_DMA_SIZE 120 /* Enough for 58/59 buffers */ #define DMA_COUNT_SHIFT 16 /* Number of bits to shift count */ /* in DMA descriptor word */ #define DMA_VCC_SHIFT 6 /* Number of bits to shift RX VCC or */ /* TX channel in DMA descriptor word */ #define DMA_END_BIT 0x20 /* Signal end of DMA list */ /* * Defines for VCI table * * The VCI table is a 1K by 4 word table allowing up to 1024 (0-1023) * VCIs. Entries into the table use the VCI number as the index. */ struct vci_table { u_long vci_control; /* Control word */ u_long vci_descr; /* Descr/ReadPtr */ u_long vci_write; /* WritePtr/State/Cell count */ u_long vci_crc; /* ongoing CRC calculation */ }; typedef volatile struct vci_table VCI_Table; #define VCI_MODE_SHIFT 30 /* Shift to get MODE field */ #define VCI_MODE_MASK 0x3FFFFFFF /* Bits to strip MODE off */ #define VCI_PTI_SHIFT 29 /* Shift to get PTI mode field */ #define VCI_LOC_SHIFT 18 /* Shift to get location field */ #define VCI_LOC_MASK 0x7FF /* Valid bits in location field */ #define VCI_SIZE_SHIFT 15 /* Shift to get size field */ #define VCI_SIZE_MASK 7 /* Valid bits in size field */ #define VCI_IN_SERVICE 1 /* Mask for IN_SERVICE field */ /* * Defines for VC mode */ #define VCI_MODE_TRASH 0x00 /* Trash all cells for this VC */ #define VCI_MODE_AAL0 0x01 /* Reassemble as AAL_0 PDU */ #define VCI_MODE_AAL5 0x02 /* Reassemble as AAL_5 PDU */ /* * Defines for handling cells with PTI(2) set to 1. */ #define PTI_MODE_TRASH 0x00 /* Trash cell */ #define PTI_MODE_PRESV 0x01 /* Send cell to OAM channel */ /* * Current state of VC */ #define VCI_STATE_IDLE 0x00 /* VC is idle */ #define VCI_STATE_REASM 0x01 /* VC is reassembling PDU */ #define VCI_STATE_TRASH 0x03 /* VC is trashing cells */ /* * RX Descriptor word values */ #define DESCR_TRASH_BIT 0x1000 /* VCI was trashing cells */ #define DESCR_CRC_ERR 0x0800 /* PDU has CRC error */ #define DESCR_CELL_COUNT 0x07FF /* Mask to get cell count */ /* * TX Descriptor word values */ #define TX_IDEN_SHIFT 28 /* Unique identifier location */ #define TX_MODE_SHIFT 27 /* AAL5 or AAL0 */ #define TX_VCI_SHIFT 4 /* Bits to shift VCI value */ /* * When setting up descriptor words (at head of segmentation queues), there * is a unique identifier used to help detect sync problems. */ #define MIDWAY_UNQ_ID 0x0B /* * Defines for cell sizes */ #define BYTES_PER_CELL 48 /* Number of data bytes per cell */ #define WORDS_PER_CELL 12 /* Number of data words per cell */ /* * Access to Serial EEPROM [as opposed to expansion (E)PROM]. * * This is a ATMEL AT24C01 serial EEPROM part. * See http://www.atmel.com/atmel/products/prod162.htm for timimg diagrams * for START/STOP/ACK/READ cycles. */ #define SEEPROM PCI_CONTROL_REG /* Serial EEPROM is accessed thru */ /* PCI control register */ #define SEPROM_DATA 0x02 /* SEEPROM DATA line */ #define SEPROM_CLK 0x01 /* SEEPROM CLK line */ #define SEPROM_SIZE 128 /* Size of Serial EEPROM */ #define SEPROM_MAC_OFF 64 /* Offset to MAC address */ #define SEPROM_SN_OFF 112 /* Offset to serial number */ #define SEPROM_DELAY 10 /* Delay when strobing CLK/DATA lines */ /* * Host protocol control blocks * */ /* * Device VCC Entry * * Contains the common and ENI-specific information for each VCC * which is opened through a ENI device. */ struct eni_vcc { struct cmn_vcc ev_cmn; /* Common VCC stuff */ caddr_t ev_rxbuf; /* Receive buffer */ u_long ev_rxpos; /* Adapter buffer read pointer */ }; typedef struct eni_vcc Eni_vcc; #define ev_next ev_cmn.cv_next #define ev_toku ev_cmn.cv_toku #define ev_upper ev_cmn.cv_upper #define ev_connvc ev_cmn.cv_connvc #define ev_state ev_cmn.cv_state typedef volatile unsigned long * Eni_mem; /* * Define the ID's we'll look for in the PCI config * register when deciding if we'll support this device. * The DEV_ID will need to be turned into an array of * ID's in order to support multiple adapters with * the same driver. */ #define EFF_VENDOR_ID 0x111A #define EFF_DEV_ID 0x0002 /* * Memory allocator defines and buffer descriptors */ #define MEM_FREE 0 #define MEM_INUSE 1 typedef struct mbd Mbd; struct mbd { Mbd *prev; Mbd *next; caddr_t base; /* Adapter base address */ int size; /* Size of buffer */ int state; /* INUSE or FREE */ }; /* * We use a hack to allocate a smaller RX buffer for signalling * channels as they tend to have small MTU lengths. */ #define UNI_SIG_VCI 5 /* * Device Unit Structure * * Contains all the information for a single device (adapter). */ struct eni_unit { Cmn_unit eu_cmn; /* Common unit stuff */ pcici_t eu_pcitag; /* PCI tag */ Eni_mem eu_base; /* Adapter memory base */ Eni_mem eu_ram; /* Adapter RAM */ u_long eu_ramsize; Eni_mem eu_suni; /* SUNI registers */ Eni_mem eu_midway; /* MIDWAY registers */ VCI_Table *eu_vcitbl; /* VCI Table */ Eni_mem eu_rxdma; /* Receive DMA queue */ Eni_mem eu_txdma; /* Transmit DMA queue */ Eni_mem eu_svclist; /* Service list */ u_long eu_servread; /* Read pointer into Service list */ caddr_t eu_txbuf; /* One large TX buff for everything */ u_long eu_txsize; /* Size of TX buffer */ u_long eu_txpos; /* Current word being stored in RAM */ u_long eu_txfirst; /* First word of unack'ed data */ u_long eu_trash; u_long eu_ovfl; struct ifqueue eu_txqueue; u_long eu_txdmawr; struct ifqueue eu_rxqueue; u_long eu_rxdmawr; /* DMA list write pointer */ u_char eu_seeprom[SEPROM_SIZE]; /* Serial EEPROM contents */ u_int eu_sevar; /* Unique (per unit) seeprom var. */ Mbd *eu_memmap; /* Adapter RAM memory allocator map */ int eu_memclicks[ENI_BUF_NBIT];/* Count of INUSE buffers */ Eni_stats eu_stats; /* Statistics */ }; typedef struct eni_unit Eni_unit; #define eu_pif eu_cmn.cu_pif #define eu_unit eu_cmn.cu_unit #define eu_flags eu_cmn.cu_flags #define eu_mtu eu_cmn.cu_mtu #define eu_open_vcc eu_cmn.cu_open_vcc #define eu_vcc eu_cmn.cu_vcc #define eu_vcc_pool eu_cmn.cu_vcc_pool #define eu_nif_pool eu_cmn.cu_nif_pool #define eu_ioctl eu_cmn.cu_ioctl #define eu_instvcc eu_cmn.cu_instvcc #define eu_openvcc eu_cmn.cu_openvcc #define eu_closevcc eu_cmn.cu_closevcc #define eu_output eu_cmn.cu_output #define eu_config eu_cmn.cu_config #endif /* _ENI_ENI_H */