if_fatmvar.h revision 116735
1116735Sharti/* 2116735Sharti * Copyright (c) 2001-2003 3116735Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4116735Sharti * All rights reserved. 5116735Sharti * 6116735Sharti * Redistribution and use in source and binary forms, with or without 7116735Sharti * modification, are permitted provided that the following conditions 8116735Sharti * are met: 9116735Sharti * 1. Redistributions of source code must retain the above copyright 10116735Sharti * notice, this list of conditions and the following disclaimer. 11116735Sharti * 2. Redistributions in binary form must reproduce the above copyright 12116735Sharti * notice, this list of conditions and the following disclaimer in the 13116735Sharti * documentation and/or other materials provided with the distribution. 14116735Sharti * 15116735Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16116735Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17116735Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18116735Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19116735Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20116735Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21116735Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22116735Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23116735Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24116735Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25116735Sharti * SUCH DAMAGE. 26116735Sharti * 27116735Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28116735Sharti * 29116735Sharti * $FreeBSD: head/sys/dev/fatm/if_fatmvar.h 116735 2003-06-23 14:46:12Z harti $ 30116735Sharti * 31116735Sharti * Fore PCA200E driver definitions. 32116735Sharti */ 33116735Sharti/* 34116735Sharti * Debug statistics of the PCA200 driver 35116735Sharti */ 36116735Shartistruct istats { 37116735Sharti uint32_t cmd_queue_full; 38116735Sharti uint32_t get_stat_errors; 39116735Sharti uint32_t clr_stat_errors; 40116735Sharti uint32_t get_prom_errors; 41116735Sharti uint32_t suni_reg_errors; 42116735Sharti uint32_t tx_queue_full; 43116735Sharti uint32_t tx_queue_almost_full; 44116735Sharti uint32_t tx_pdu2big; 45116735Sharti uint32_t tx_too_many_segs; 46116735Sharti uint32_t tx_retry; 47116735Sharti uint32_t fix_empty; 48116735Sharti uint32_t fix_addr_copy; 49116735Sharti uint32_t fix_addr_noext; 50116735Sharti uint32_t fix_addr_ext; 51116735Sharti uint32_t fix_len_noext; 52116735Sharti uint32_t fix_len_copy; 53116735Sharti uint32_t fix_len; 54116735Sharti uint32_t rx_badvc; 55116735Sharti uint32_t rx_closed; 56116735Sharti}; 57116735Sharti 58116735Sharti/* 59116735Sharti * Addresses on the on-board RAM are expressed as offsets to the 60116735Sharti * start of that RAM. 61116735Sharti */ 62116735Shartitypedef uint32_t cardoff_t; 63116735Sharti 64116735Sharti/* 65116735Sharti * The card uses a number of queues for communication with the host. 66116735Sharti * Parts of the queue are located on the card (pointers to the status 67116735Sharti * word and the ioblk and the command blocks), the rest in host memory. 68116735Sharti * Each of these queues forms a ring, where the head and tail pointers are 69116735Sharti * managed * either by the card or the host. For the receive queue the 70116735Sharti * head is managed by the card (and not used altogether by the host) and the 71116735Sharti * tail by the host - for all other queues its the other way around. 72116735Sharti * The host resident parts of the queue entries contain pointers to 73116735Sharti * the host resident status and the host resident ioblk (the latter not for 74116735Sharti * the command queue) as well as DMA addresses for supply to the card. 75116735Sharti */ 76116735Shartistruct fqelem { 77116735Sharti cardoff_t card; /* corresponding element on card */ 78116735Sharti bus_addr_t card_ioblk; /* ioblk address to supply to card */ 79116735Sharti volatile uint32_t *statp; /* host status pointer */ 80116735Sharti void *ioblk; /* host ioblk (not for commands) */ 81116735Sharti}; 82116735Sharti 83116735Shartistruct fqueue { 84116735Sharti struct fqelem *chunk; /* pointer to the element array */ 85116735Sharti int head; /* queue head */ 86116735Sharti int tail; /* queue tail */ 87116735Sharti}; 88116735Sharti 89116735Sharti/* 90116735Sharti * Queue manipulation macros 91116735Sharti */ 92116735Sharti#define NEXT_QUEUE_ENTRY(HEAD,LEN) ((HEAD) = ((HEAD) + 1) % LEN) 93116735Sharti#define GET_QUEUE(Q,TYPE,IDX) (&((TYPE *)(Q).chunk)[(IDX)]) 94116735Sharti 95116735Sharti/* 96116735Sharti * Now define structures for the different queues. Each of these structures 97116735Sharti * must start with a struct fqelem. 98116735Sharti */ 99116735Shartistruct txqueue { /* transmit queue element */ 100116735Sharti struct fqelem q; 101116735Sharti struct mbuf *m; /* the chain we are transmitting */ 102116735Sharti bus_dmamap_t map; /* map for the packet */ 103116735Sharti}; 104116735Sharti 105116735Shartistruct rxqueue { /* receive queue element */ 106116735Sharti struct fqelem q; 107116735Sharti}; 108116735Sharti 109116735Shartistruct supqueue { /* supply queue element */ 110116735Sharti struct fqelem q; 111116735Sharti}; 112116735Sharti 113116735Shartistruct cmdqueue; 114116735Shartistruct fatm_softc; 115116735Sharti 116116735Shartitypedef void (*completion_cb)(struct fatm_softc *, struct cmdqueue *); 117116735Sharti 118116735Shartistruct cmdqueue { /* command queue element */ 119116735Sharti struct fqelem q; 120116735Sharti completion_cb cb; /* call on command completion */ 121116735Sharti int error; /* set if error occured */ 122116735Sharti}; 123116735Sharti 124116735Sharti/* 125116735Sharti * Card-DMA-able memory is managed by means of the bus_dma* functions. 126116735Sharti * To allocate a chunk of memory with a specific size and alignment one 127116735Sharti * has to: 128116735Sharti * 1. create a DMA tag 129116735Sharti * 2. allocate the memory 130116735Sharti * 3. load the memory into a map. 131116735Sharti * This finally gives the physical address that can be given to the card. 132116735Sharti * The card can DMA the entire 32-bit space without boundaries. We assume, 133116735Sharti * that all the allocations can be mapped in one contiguous segment. This 134116735Sharti * may be wrong in the future if we have more than 32 bit addresses. 135116735Sharti * Allocation is done at attach time and managed by the following structure. 136116735Sharti * 137116735Sharti * This could be done easier with the NetBSD bus_dma* functions. They appear 138116735Sharti * to be more useful and consistent. 139116735Sharti */ 140116735Shartistruct fatm_mem { 141116735Sharti u_int size; /* size */ 142116735Sharti u_int align; /* alignment */ 143116735Sharti bus_dma_tag_t dmat; /* DMA tag */ 144116735Sharti void *mem; /* memory block */ 145116735Sharti bus_addr_t paddr; /* pysical address */ 146116735Sharti bus_dmamap_t map; /* map */ 147116735Sharti}; 148116735Sharti 149116735Sharti/* 150116735Sharti * Each of these structures describes one receive buffer while the buffer 151116735Sharti * is on the card or in the receive return queue. These structures are 152116735Sharti * allocated at initialisation time together with the DMA maps. The handle that 153116735Sharti * is given to the card is the index into the array of these structures. 154116735Sharti */ 155116735Shartistruct rbuf { 156116735Sharti struct mbuf *m; /* the mbuf while we are on the card */ 157116735Sharti bus_dmamap_t map; /* the map */ 158116735Sharti LIST_ENTRY(rbuf) link; /* the free list link */ 159116735Sharti}; 160116735ShartiLIST_HEAD(rbuf_list, rbuf); 161116735Sharti 162116735Sharti/* 163116735Sharti * The driver maintains a list of all open VCCs. Because we 164116735Sharti * use only VPI=0 and a maximum VCI of 1024, the list is rather an array 165116735Sharti * than a list. We also store the atm pseudoheader flags here and the 166116735Sharti * rxhand (aka. protocol block). 167116735Sharti */ 168116735Shartistruct card_vcc { 169116735Sharti void *rxhand; 170116735Sharti uint32_t pcr; 171116735Sharti uint32_t flags; 172116735Sharti uint8_t aal; 173116735Sharti uint8_t traffic; 174116735Sharti}; 175116735Sharti 176116735Sharti#define FATM_VCC_OPEN 0x00010000 /* is open */ 177116735Sharti#define FATM_VCC_TRY_OPEN 0x00020000 /* is currently opening */ 178116735Sharti#define FATM_VCC_TRY_CLOSE 0x00040000 /* is currently closing */ 179116735Sharti#define FATM_VCC_BUSY 0x00070000 /* one of the above */ 180116735Sharti 181116735Sharti/* 182116735Sharti * Finally the softc structure 183116735Sharti */ 184116735Shartistruct fatm_softc { 185116735Sharti struct ifatm ifatm; /* common part */ 186116735Sharti struct mtx mtx; /* lock this structure */ 187116735Sharti struct ifmedia media; /* media */ 188116735Sharti 189116735Sharti int init_state; /* initialisation step */ 190116735Sharti int memid; /* resource id for card memory */ 191116735Sharti struct resource *memres; /* resource for card memory */ 192116735Sharti bus_space_handle_t memh; /* handle for card memory */ 193116735Sharti bus_space_tag_t memt; /* tag for card memory */ 194116735Sharti int irqid; /* resource id for interrupt */ 195116735Sharti struct resource *irqres; /* resource for interrupt */ 196116735Sharti void *ih; /* interrupt handler */ 197116735Sharti 198116735Sharti bus_dma_tag_t parent_dmat; /* parent DMA tag */ 199116735Sharti struct fatm_mem stat_mem; /* memory for status blocks */ 200116735Sharti struct fatm_mem txq_mem; /* TX descriptor queue */ 201116735Sharti struct fatm_mem rxq_mem; /* RX descriptor queue */ 202116735Sharti struct fatm_mem s1q_mem; /* Small buffer 1 queue */ 203116735Sharti struct fatm_mem l1q_mem; /* Large buffer 1 queue */ 204116735Sharti struct fatm_mem prom_mem; /* PROM memory */ 205116735Sharti 206116735Sharti struct fqueue txqueue; /* transmission queue */ 207116735Sharti struct fqueue rxqueue; /* receive queue */ 208116735Sharti struct fqueue s1queue; /* SMALL S1 queue */ 209116735Sharti struct fqueue l1queue; /* LARGE S1 queue */ 210116735Sharti struct fqueue cmdqueue; /* command queue */ 211116735Sharti 212116735Sharti /* fields for access to the SUNI registers */ 213116735Sharti struct fatm_mem reg_mem; /* DMAable memory for readregs */ 214116735Sharti struct cv cv_regs; /* to serialize access to reg_mem */ 215116735Sharti 216116735Sharti /* fields for access to statistics */ 217116735Sharti struct fatm_mem sadi_mem; /* sadistics memory */ 218116735Sharti struct cv cv_stat; /* to serialize access to sadi_mem */ 219116735Sharti 220116735Sharti u_int flags; 221116735Sharti#define FATM_STAT_INUSE 0x0001 222116735Sharti#define FATM_REGS_INUSE 0x0002 223116735Sharti u_int txcnt; /* number of used transmit desc */ 224116735Sharti int retry_tx; /* keep mbufs in queue if full */ 225116735Sharti 226116735Sharti struct card_vcc *vccs; /* table of vccs */ 227116735Sharti int open_vccs; /* number of vccs in use */ 228116735Sharti int small_cnt; /* number of buffers owned by card */ 229116735Sharti int large_cnt; /* number of buffers owned by card */ 230116735Sharti 231116735Sharti /* receiving */ 232116735Sharti struct rbuf *rbufs; /* rbuf array */ 233116735Sharti struct rbuf_list rbuf_free; /* free rbufs list */ 234116735Sharti struct rbuf_list rbuf_used; /* used rbufs list */ 235116735Sharti u_int rbuf_total; /* total number of buffs */ 236116735Sharti bus_dma_tag_t rbuf_tag; /* tag for rbuf mapping */ 237116735Sharti 238116735Sharti /* transmission */ 239116735Sharti bus_dma_tag_t tx_tag; /* transmission tag */ 240116735Sharti 241116735Sharti uint32_t heartbeat; /* last heartbeat */ 242116735Sharti u_int stop_cnt; /* how many times checked */ 243116735Sharti 244116735Sharti struct istats istats; /* internal statistics */ 245116735Sharti 246116735Sharti /* SUNI state */ 247116735Sharti struct utopia utopia; 248116735Sharti 249116735Sharti /* sysctl support */ 250116735Sharti struct sysctl_ctx_list sysctl_ctx; 251116735Sharti struct sysctl_oid *sysctl_tree; 252116735Sharti 253116735Sharti#ifdef FATM_DEBUG 254116735Sharti /* debugging */ 255116735Sharti u_int debug; 256116735Sharti#endif 257116735Sharti}; 258116735Sharti 259116735Sharti#ifndef FATM_DEBUG 260116735Sharti#define FATM_LOCK(SC) mtx_lock(&(SC)->mtx) 261116735Sharti#define FATM_UNLOCK(SC) mtx_unlock(&(SC)->mtx) 262116735Sharti#else 263116735Sharti#define FATM_LOCK(SC) do { \ 264116735Sharti DBG(SC, LOCK, ("locking in line %d", __LINE__)); \ 265116735Sharti mtx_lock(&(SC)->mtx); \ 266116735Sharti } while (0) 267116735Sharti#define FATM_UNLOCK(SC) do { \ 268116735Sharti DBG(SC, LOCK, ("unlocking in line %d", __LINE__)); \ 269116735Sharti mtx_unlock(&(SC)->mtx); \ 270116735Sharti } while (0) 271116735Sharti#endif 272116735Sharti#define FATM_CHECKLOCK(SC) mtx_assert(&sc->mtx, MA_OWNED) 273116735Sharti 274116735Sharti/* 275116735Sharti * Macros to access host memory fields that are also access by the card. 276116735Sharti * These fields need to little-endian always. 277116735Sharti */ 278116735Sharti#define H_GETSTAT(STATP) (le32toh(*(STATP))) 279116735Sharti#define H_SETSTAT(STATP, S) do { *(STATP) = htole32(S); } while (0) 280116735Sharti#define H_SETDESC(DESC, D) do { (DESC) = htole32(D); } while (0) 281116735Sharti 282116735Sharti#ifdef notyet 283116735Sharti#define H_SYNCSTAT_POSTREAD(SC, P) \ 284116735Sharti bus_dmamap_sync_size((SC)->stat_mem.dmat, \ 285116735Sharti (SC)->stat_mem.map, \ 286116735Sharti (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \ 287116735Sharti sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD) 288116735Sharti 289116735Sharti#define H_SYNCSTAT_PREWRITE(SC, P) \ 290116735Sharti bus_dmamap_sync_size((SC)->stat_mem.dmat, \ 291116735Sharti (SC)->stat_mem.map, \ 292116735Sharti (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \ 293116735Sharti sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE) 294116735Sharti 295116735Sharti#define H_SYNCQ_PREWRITE(M, P, SZ) \ 296116735Sharti bus_dmamap_sync_size((M)->dmat, (M)->map, \ 297116735Sharti (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \ 298116735Sharti BUS_DMASYNC_PREWRITE) 299116735Sharti 300116735Sharti#define H_SYNCQ_POSTREAD(M, P, SZ) \ 301116735Sharti bus_dmamap_sync_size((M)->dmat, (M)->map, \ 302116735Sharti (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \ 303116735Sharti BUS_DMASYNC_POSTREAD) 304116735Sharti#else 305116735Sharti#define H_SYNCSTAT_POSTREAD(SC, P) do { } while (0) 306116735Sharti#define H_SYNCSTAT_PREWRITE(SC, P) do { } while (0) 307116735Sharti#define H_SYNCQ_PREWRITE(M, P, SZ) do { } while (0) 308116735Sharti#define H_SYNCQ_POSTREAD(M, P, SZ) do { } while (0) 309116735Sharti#endif 310116735Sharti 311116735Sharti/* 312116735Sharti * Macros to manipulate VPVCs 313116735Sharti */ 314116735Sharti#define MKVPVC(VPI,VCI) (((VPI) << 16) | (VCI)) 315116735Sharti#define GETVPI(VPVC) (((VPVC) >> 16) & 0xff) 316116735Sharti#define GETVCI(VPVC) ((VPVC) & 0xffff) 317116735Sharti 318116735Sharti/* 319116735Sharti * These macros encapsulate the bus_space functions for better readabiliy. 320116735Sharti */ 321116735Sharti#define WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL) 322116735Sharti#define WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL) 323116735Sharti 324116735Sharti#define READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF) 325116735Sharti#define READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF) 326116735Sharti 327116735Sharti#define BARRIER_R(SC) \ 328116735Sharti bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 329116735Sharti BUS_SPACE_BARRIER_READ) 330116735Sharti#define BARRIER_W(SC) \ 331116735Sharti bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 332116735Sharti BUS_SPACE_BARRIER_WRITE) 333116735Sharti#define BARRIER_RW(SC) \ 334116735Sharti bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 335116735Sharti BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ) 336116735Sharti 337116735Sharti#ifdef FATM_DEBUG 338116735Sharti#define DBG(SC, FL, PRINT) do { \ 339116735Sharti if ((SC)->debug & DBG_##FL) { \ 340116735Sharti if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \ 341116735Sharti printf PRINT; \ 342116735Sharti printf("\n"); \ 343116735Sharti } \ 344116735Sharti } while (0) 345116735Sharti#define DBGC(SC, FL, PRINT) do { \ 346116735Sharti if ((SC)->debug & DBG_##FL) \ 347116735Sharti printf PRINT; \ 348116735Sharti } while (0) 349116735Sharti 350116735Shartienum { 351116735Sharti DBG_RCV = 0x0001, 352116735Sharti DBG_XMIT = 0x0002, 353116735Sharti DBG_VCC = 0x0004, 354116735Sharti DBG_IOCTL = 0x0008, 355116735Sharti DBG_ATTACH = 0x0010, 356116735Sharti DBG_INIT = 0x0020, 357116735Sharti DBG_DMA = 0x0040, 358116735Sharti DBG_BEAT = 0x0080, 359116735Sharti DBG_UART = 0x0100, 360116735Sharti DBG_LOCK = 0x0200, 361116735Sharti 362116735Sharti DBG_ALL = 0xffff 363116735Sharti}; 364116735Sharti 365116735Sharti#else 366116735Sharti#define DBG(SC, FL, PRINT) 367116735Sharti#define DBGC(SC, FL, PRINT) 368116735Sharti#endif 369116735Sharti 370116735Sharti/* 371116735Sharti * Configuration. 372116735Sharti * 373116735Sharti * This section contains tunable parameters and dependend defines. 374116735Sharti */ 375116735Sharti#define FATM_CMD_QLEN 16 /* command queue length */ 376116735Sharti#ifndef TEST_DMA_SYNC 377116735Sharti#define FATM_TX_QLEN 128 /* transmit queue length */ 378116735Sharti#define FATM_RX_QLEN 64 /* receive queue length */ 379116735Sharti#else 380116735Sharti#define FATM_TX_QLEN 8 /* transmit queue length */ 381116735Sharti#define FATM_RX_QLEN 8 /* receive queue length */ 382116735Sharti#endif 383116735Sharti 384116735Sharti#define SMALL_SUPPLY_QLEN 16 385116735Sharti#define SMALL_POOL_SIZE 256 386116735Sharti#define SMALL_SUPPLY_BLKSIZE 8 387116735Sharti 388116735Sharti#define LARGE_SUPPLY_QLEN 16 389116735Sharti#define LARGE_POOL_SIZE 128 390116735Sharti#define LARGE_SUPPLY_BLKSIZE 8 391