/* ih.h */ /* Copyright (c) 2000 James M. Westall, Dept of Computer Science, * Clemson University, Clemson SC 29634 USA * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * To obtain a copy of the GNU General Public License write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This software is derived from software developed by the Interphase * corporation and released by them in September 2000. The software * released by Interphase carried the following copyright notice: * * * Copyright (C) 1993 * Interphase Corporation, Dallas, TX 75234 * All Rights Reserved * * This code contains confidential information and trade secrets of * Interphase Corporation which shall not be reproduced or transferred * to other programs or disclosed to others or used for manufacturing * or any other purpose without prior written permission of Interphase * Corporation. Use of copyright notice is precautionary and does not * imply publication or intent thereof. */ /*H * FILE: ia.h * * DESCRIPTION: * This file contains all the general driver data structures * and defines. * * FUNCTIONS: * EXPORTED: * * STATIC: * * GLOBAL DATA: * */ #ifndef _IA_H #define _IA_H #define Vol volatile typedef char i8; typedef char I8; typedef char S8; typedef unsigned char U8; typedef short i16; typedef short I16; typedef short S16; typedef unsigned short U16; typedef int i32; typedef int I32; typedef int S32; typedef unsigned int U32; /* * General defines */ #define IA_SUCCESS 0 #define IA_FAIL -1 #ifndef PCI_VENDOR_ID_IPHASE #define PCI_VENDOR_ID_IPHASE 0x107e #endif #ifndef PCI_DEVICE_ID_IPHASE_5575 #define PCI_DEVICE_ID_IPHASE_5575 0x0008 #endif #ifndef PCI_DEVICE_ID_IPHASE_5515 #define PCI_DEVICE_ID_IPHASE_5515 0x0001 #endif #define IADEV_MASK 0x80 #define ROUND_UP(x, to) (((u_int)x+(to-1)) & ~(to-1)) /* * Addgen ring numbers */ #define NUM_LIST 2 /* Flipper lists */ #define TX_LIST 0 /* Packet trasnmit list */ #define RX_LIST 1 /* Packet receive list */ /* * MTU and queue watermarks */ #define IA_MTU (9*1024) #define IAUHIWAT (RX_BUF_SIZE * 5) #define IAULOWAT (RX_BUF_SIZE * 1) /* * VC Status byte */ #define VC_ACTIVE 0x01 #define VC_ABR 0x02 #define VC_UBR 0x04 #define NUM_VCCS 128 /* * Linux ATM vcc */ typedef struct { struct sk_buff_head tx_backlog; /* -> backlog queue */ int tx_pending; /* # of elements in queue */ int tx_active; /* # of elements active */ int tx_txed; /* Packets sent */ int rx_rcvd; /* Packets received */ } ia_lnx_vcc_t; /* * State of addgen ring */ typedef struct { DLE *list_start; /* Start of DMA list */ DLE *list_end; /* End of DMA list */ DLE *list_read; /* List read pointer */ DLE *list_write; /* List write pointer */ } ia_dle_list_t; typedef int Tout_t; /* Timeout element */ /* * Tx buffer control structure */ typedef struct { caddr_t *mp; /* System data buffer header */ caddr_t addr; /* Host Buffer address */ caddr_t baddr; /* Controller buffer address */ off_t offset; /* To make ddi_dma_sync easy */ f_buf_desc *desc; /* Buffer descriptor pointer */ int cnt; /* Number of DVMA mappings */ caddr_t daddr[MAX_SGE]; /* Dma segment phys addr */ size_t dlen[MAX_SGE]; /* Dma segment length */ struct sk_buff *skb; /* Pointer to socket buffer */ struct atm_vcc *vcc; /* Pointer to vcc */ } ia_tx_buf_t; /* * Rx buffer control structure */ typedef struct ia_rx_buf { struct ia_rx_buf *next; /* Next element in the link list */ caddr_t *mp; /* Driver data buffer */ caddr_t addr; /* Buffer address */ off_t offset; /* To make ddi_dma_sync easy */ int index; /* Index of the array */ void *softc; /* State structure */ size_t len; /* CS PDU length */ r_buf_desc *desc; /* Descriptor pointer */ caddr_t daddr[MAX_SGE]; /* Dma segment phys addr */ size_t dlen[MAX_SGE]; /* Dma segment length */ struct sk_buff *skb; /* Pointer to socket buffer */ } ia_rx_buf_t; #define NUM_PVCS 64 typedef struct { #if LINUX_VERSION_CODE >= 0x20303 wait_queue_head_t input_wait; #else struct wait_queue *input_wait; #endif ia_rx_buf_t *rdybufhead; ia_rx_buf_t *rdybuftail; } ia_pvc_desc_t; /* * Board registers */ typedef struct { ffred_t *ffred; /* F FRED (Pre-Atlantic) */ rfred_t *rfred; /* R FRED (Pre-Atlantic) */ U32 *ctrl; /* Control Register (pre-Atlantic) */ ia_suni_t *suni; /* SUNI */ suni_pm7345_t *suni_pm7345; /* DS3 PHY */ ia_flip_t *flipper; /* Flipper */ fl_config_t *config; /* Configuration Registers */ U32 *tx_tc; /* Tx transection count */ U32 *rx_tc; /* Tx transection count */ caddr_t ffred_mem; /* F FRED control memory */ caddr_t rfred_mem; /* R FRED control memory */ } ia_brd_regs_t; /* * Board registers (Physical address relative to the board) * These are the needed physical address of the device on * the controller. */ typedef struct { u_int buf_mem; /* Buffer memory */ u_int ffred_mem; /* F FRED control memory */ u_int rfred_mem; /* R FRED control memory */ } ia_brd_regs_ph_t; /* * Board registers (Local copy) * This structure keeps a copy of the rfred and ffred registers. * This helps in reducing the the number of slave accesses to the * board. Only registers that do not change after initialization * or registers owned by the host are maintained. */ typedef struct { /* Pre-Atlantic */ ffred_t ffred; /* F FRED */ rfred_t rfred; /* R FRED */ } ia_brd_regs_ll_t; /* * FFRED map */ typedef struct ia_ffred_map { u_int f_num_vc; /* Size of Tx VC table */ u_int f_abr_tbl; /* Size of ABR table */ u_int f_abr_wq; /* Size of ABR wait queue */ u_int f_ubr_tbl; /* Size of UBR table */ u_int f_ubr_wq; /* Size of UBR wait queue */ u_int f_tcq_start; /* Transmit complete queue start*/ u_int f_prq_start; /* Packet ready queue start */ u_int f_abr_tbl_start;/* ABR table start */ u_int f_ubr_tbl_start;/* UBR table start */ u_int f_abr_wq_start; /* ABR Work Queue */ u_int f_ubr_wq_start; /* UBR Work Queue */ u_int f_evc_start; /* Extended VC table start */ u_int f_vc_start; /* VC table start */ } ia_ffred_map_t; /* * RFRED map */ typedef struct ia_rfred_map { u_int r_num_vc; /* Size of Rx VC table */ u_int r_reassm_size; /* Entries in reassembly table */ u_int r_lfq_start; /* Large buffer free queue start*/ u_int r_pcq_start; /* Packet complete queue start */ u_int r_excp_start; /* Exception queue start */ u_int r_reassm_start; /* Reassembly table start */ u_int r_vc_start; /* VC table start */ u_int r_abr_vc_start; /* ABR VC table start */ } ia_rfred_map_t; /* * This structure manages a dma-able buffer pool. */ typedef struct { caddr_t taddr; /* Unaligned true address */ caddr_t addr; /* Aligned address */ size_t len; /* Requested Length of memory */ size_t real_len; /* Length of aligned memory */ int alloc_handle_done; int mem_alloc_done; } ia_dma_t; /* * Rate Q control elements * Only used for PVC driver * (Pre-Atlantic only) */ typedef struct { u_long lbolt; /* Last time this RQ was used */ u_int rq_info; /* Bits 0-7 RQ_PRELOAD, 8-9 PRESCALER */ } ia_rq_cntl_t; #define NUM_RATE_Q 4 /* Number of settable rate Qs */ /* for ABR software workaround */ typedef struct testTable { u_short lastTime; u_short fract; } testTable_t; /* Driver statistics */ typedef struct { int interrupts; /* Number of interrupts */ int rfred_intr; /* Rfred ints */ int tfred_intr; /* Tfred ints */ int addgen_intr; /* Recvd packet DLE int */ int suni_intr; /* SUNI ints */ int rx_buf_on_dma_q; /* Rx buf queued for DMA */ int tcq_empty; int tx_packets; int tx_bytes; int tx_drops; int tx_waits; int rx_packets; int rx_bytes; int tx_skb_consumed; int tx_skb_returned; } ia_driver_stat_t; /* Ffred statistics */ typedef struct { int cc_flush; int ce_delink; } ia_ffred_stat_t; /* Rfred statistics */ typedef struct { int drop_rxpkt; /* Dropped packet counter */ int drop_cell; /* Dropped cell counter */ int drop_cbr; /* Dropped cbr cells */ int rx_cell; /* Received cells */ int large_freeqmt; /* LFQ Empty count */ int small_freeqmt; /* SFQ Empty count */ int excp_full; /* ExceptionQ empty count */ int cf; int cce; int cse; int sqe; int eof; int pte; int cer; int ofl; int pep; int cng; int baddesc; int rx_no_host_buf; int oos_com; int oos_eom; int nsld; int nld; int last_inv_vc; int invalid_vc; int last_inv_vp; int invalid_vp; } ia_rfred_stat_t; #ifdef __SNMP__ #define LI_ADDRL (6) #define LLC_ADDRL (sizeof (u_short) + LI_ADDRL) #define NUM_INTERFACE 3 #define ATM_INTERFACE 0 #define SONETLINE_INTERFACE 1 #define SONETPATH_INTERFACE 2 #endif __SNMP__ /* * The entire state of each device. */ typedef struct ia_softc { struct atm_dev *atmdev; /* Link to linux atm stack */ int instance; /* controller number */ int atlantic; /* ATLANTIC ? */ uchar_t mac_addr[6]; /* Our mac address */ struct pci_dev *ia_dev; /* PCI control structure */ struct timeval *tod; /* -> xtime */ struct timeval tv; /* -> xtime */ int irq; /* Interrupt number */ ulong_t real_base; caddr_t pci_base_v; /* Our physical PCI base vir */ int pci_map_size; ia_dle_list_t list[NUM_LIST]; /* Flipper DMA list */ ia_dma_t tx_list_dma; /* Tx DMA control */ ia_dma_t rx_list_dma; /* Rx DMA control */ ia_brd_regs_t brd_regs; /* Board registers */ ia_brd_regs_ph_t brd_regs_ph; /* Board regs, Phy addr */ ia_brd_regs_ll_t brd_regs_ll; /* Board regs, local copy */ ia_dma_t tx_dma; /* TX DMA control */ ia_tx_buf_t tx_buf[NUM_TX_BUFS]; /* Tx buffer control */ ia_dma_t rx_dma; /* Rx DMA control */ ia_rx_buf_t rx_buf[NUM_RX_BUFS]; /* Rx buffer control */ ia_rx_buf_t *rx_buf_free; /* Rx free buffer list */ ia_rx_buf_t *rx_buf_freetail; /* Rx free buffer list tail */ ia_rx_buf_t *rx_buf_dmahead; /* Rx buf list on addgen */ ia_rx_buf_t *rx_buf_dmatail; /* Rx buf list on addgen */ u_int rx_state; /* Receive side state */ spinlock_t ia_misc_mutex; /* Driver misc. mutex */ spinlock_t xramlock; /* Driver Control mutex */ spinlock_t xmitlock; /* Driver Tx mutex */ spinlock_t recvlock; /* Driver Rx Mutex */ int attach_flags; /* See below */ ia_ffred_stat_t ffred_stat; /* F-Fred/FE stats */ ia_rfred_stat_t rfred_stat; /* R-Fred stats */ ia_driver_stat_t driver_stat; /* Driver stats */ /* ia_suni_stat_t suni_stat; SUNI stats */ ia_ffred_map_t ffred_map; /* FFRED map */ ia_rfred_map_t rfred_map; /* RFRED map */ Tout_t led_timeout; /* LED timeout */ Tout_t suni_timeout; /* SUNI timeout */ int suni_carrier; /* SUNI carrier */ int phy_type; /* PHY type */ u_int line_crs; /* LINE Cell Rate */ ia_rq_cntl_t ia_rq_cntl[4]; /* Rate q info */ freg_t last_tcq_wr_ptr; /* Used to free SKBs */ int tx_delay; /* Delay when no Tx resources */ int tx_retries; /* Number of retries */ int tx_low_water; int tx_high_water; int num_tx_desc; int num_rx_desc; int num_tx_bufs; int ram_size; int rx_packet_ram; u_char vc_status[F_NUM_VC]; /* each VC status on this card*/ u_int sum_mcr; u_int n_abr; #ifdef __SNMP__ u_int ia_rbytes[NUM_INTERFACE]; u_int ia_obytes[NUM_INTERFACE]; u_int ia_norcvbuf[NUM_INTERFACE]; u_int ia_noxmtbuf[NUM_INTERFACE]; u_int ia_ierrors[NUM_INTERFACE]; u_int ia_oerrors[NUM_INTERFACE]; u_int ia_ipackets[NUM_INTERFACE]; u_int ia_opackets[NUM_INTERFACE]; u_int ia_brdcstrcv[NUM_INTERFACE]; u_int ia_brdcstxmt[NUM_INTERFACE]; u_int ia_multircv[NUM_INTERFACE]; u_int ia_multixmt[NUM_INTERFACE]; #endif __SNMP__ u_int tx_backlog; u_int last_tx_vcc; /* Used for fair queueing */ ia_lnx_vcc_t vcctab[NUM_VCCS]; ia_pvc_desc_t pvctab[NUM_PVCS]; int logtx; int logrx; struct timeval lastrx; } ia_softc_t; typedef struct vcstatus { u_char active: 1; u_char abr: 1; u_char ubr: 1; u_char cnt: 5; } vcstatus_t; /* * Rx state flags */ #define RX_BLOCKED 0x01 /* Receive blocked canput failed */ #define RX_NO_BUFS 0x02 /* No free host receive buffers */ /* * Attach flags */ #define INTERRUPT_ADDED 0x01 #define MUTEX_ADDED 0x02 #define PCI_CONFIG_ADDED 0x04 /* * Stream private data structure */ #ifdef __SNMP__ struct ia_addr{ u_char medaddr[LI_ADDRL]; }; struct iadladdr{ struct ia_addr dl_phys; u_short dl_sap; }; #endif __SNMP__ /* * Front End Control Register Bits * (Pre-Atlantic only). */ #define FECR_LED 0x04 /* 0 = LED On */ #define FECR_RESET 0x02 /* 0 = Reset active */ #define FECR_MLT 0x01 /* 1 = MLT */ #define swaps(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) #define MIN(x, y) ((x) < (y)) ? (x) : (y) /* ** ABR Parameter limits and etc.. */ #define LINE_CELL_RATE_155 352768 /* 155 Mb/sec = ((155.52*1024*1024)/(8))*(1/53)*(26/27) = 370365 cells/sec ( 26/27 = Sonet overhead) But, per Les Zshohar the value that fits the Float respresentation is 352768 155 Mb/sec = 352768 cells/sec */ #define LINE_CELL_RATE_25 59200 #define LINE_CELL_RATE_T3_ADM 104269 #define LINE_CELL_RATE_T3_PLCP 96000 #define LINE_CELL_RATE_E3_832_ADM 80000 #define LINE_CELL_RATE_E3_751_ADM 79698 #define LINE_CELL_RATE_E3_751_PLCP 72000 #define MAX_TBE 16777215 /* ((2**24) -1) */ #define MIN_TBE 1 #define MAX_FRTT 16777215 /* ((2**24) -1) */ #define MIN_FRTT 1 #define MAX_NRM 7 /* Encoded NRM */ #define MAX_TRM 7 /* Encoded TRM */ #define MAX_ADTF 1023 /* Encoded ADTF */ #define MIN_ADTF 1 /* Encoded ADTF */ #define MAX_CDF 7 /* Encoded CDF */ #define MAX_RIF 15 /* Encoded RIF */ #define MAX_RDF 15 /* Encoded RDF */ #define MRM 0x3 #define swap32(x) (((x & 0xff) << 24) | ((x & 0xff00) << 8) | \ ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24)) #define swap(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) #if 1 #define swaps_be(x) swap(x) #define swaps_le(x) (x) #define swapl_be(x) swap32(x) #define swapl_le(x) (x) #define swap32_be(x) swap32(x) #define swap32_le(x) (x) #else /* SPARC */ #define swaps_be(x) (x) #define swaps_le(x) swaps(x) #define swapl_be(x) (x) #define swapl_le(x) swapL(x) #define swap32_be(x) (x) #define swap32_le(x) swap32(x) #endif /* SPARC */ /* * Short IO macros */ #define ia_getw(addr) readw((u16 *)addr) #define ia_putw(addr, val) writew(val, (u16 *)addr) #define ia_orw(addr, val) { \ ushort_t s; \ s = ia_getw(addr); \ s |= val; \ ia_putw(addr, s); \ } #define ia_andw(addr, val) { \ ushort_t s; \ s = ia_getw(addr); \ s &= val; \ ia_putw(addr, s); \ } /* * Long IO macros */ #define ia_get32(addr) readl((u32 *)addr) #define ia_put32(addr, val) writel(val, (u32 *)addr) #define ia_or32(addr, val) { \ ulong_t l; \ l = ia_get32(addr); \ l |= val; \ ia_put32(addr, l); \ } #define ia_and32(addr, val) { \ ulong_t l; \ l = ia_get32(addr); \ l &= val; \ ia_put32(addr, l); \ } #define ia_getl(addr) readl((u32 *)addr) #define ia_putl(addr, val) writel(val, (u32*)addr) #define ia_orl(addr, val) { \ ulong_t l; \ l = ia_getl(addr); \ l |= val; \ ia_putl(addr, l); \ } #define ia_andl(addr, val) { \ ulong_t l; \ l = ia_getl(addr); \ l &= val; \ ia_putl(addr, l); \ } #define pci_config_putl(a, b) \ pci_write_config_dword(softc->ia_dev, a, b) #define pci_config_getl(a, b) \ pci_read_config_dword(softc->ia_dev, a, b) #endif /* _IA_H */