if_fatmvar.h revision 118596
1184902Srwatson/* 2184902Srwatson * Copyright (c) 2001-2003 3293161Sbrueffer * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4293161Sbrueffer * All rights reserved. 5293161Sbrueffer * 6293161Sbrueffer * Redistribution and use in source and binary forms, with or without 7293161Sbrueffer * modification, are permitted provided that the following conditions 8293161Sbrueffer * are met: 9293161Sbrueffer * 1. Redistributions of source code must retain the above copyright 10293161Sbrueffer * notice, this list of conditions and the following disclaimer. 11293161Sbrueffer * 2. Redistributions in binary form must reproduce the above copyright 12293161Sbrueffer * notice, this list of conditions and the following disclaimer in the 13293161Sbrueffer * documentation and/or other materials provided with the distribution. 14244265Srwatson * 15244265Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16244265Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17244265Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18244265Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19244265Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20243750Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21243750Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22243750Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23243750Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24243750Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25243750Srwatson * SUCH DAMAGE. 26243750Srwatson * 27243750Srwatson * Author: Hartmut Brandt <harti@freebsd.org> 28243750Srwatson * 29243750Srwatson * $FreeBSD: head/sys/dev/fatm/if_fatmvar.h 118596 2003-08-07 10:40:24Z harti $ 30243750Srwatson * 31243750Srwatson * Fore PCA200E driver definitions. 32243750Srwatson */ 33243750Srwatson/* 34243750Srwatson * Debug statistics of the PCA200 driver 35243750Srwatson */ 36243750Srwatsonstruct istats { 37243750Srwatson uint32_t cmd_queue_full; 38243750Srwatson uint32_t get_stat_errors; 39243750Srwatson uint32_t clr_stat_errors; 40243750Srwatson uint32_t get_prom_errors; 41243750Srwatson uint32_t suni_reg_errors; 42243750Srwatson uint32_t tx_queue_full; 43243750Srwatson uint32_t tx_queue_almost_full; 44243750Srwatson uint32_t tx_pdu2big; 45196031Srwatson uint32_t tx_too_many_segs; 46196031Srwatson uint32_t tx_retry; 47196031Srwatson uint32_t fix_empty; 48196031Srwatson uint32_t fix_addr_copy; 49196031Srwatson uint32_t fix_addr_noext; 50196031Srwatson uint32_t fix_addr_ext; 51195740Srwatson uint32_t fix_len_noext; 52195740Srwatson uint32_t fix_len_copy; 53195740Srwatson uint32_t fix_len; 54195740Srwatson uint32_t rx_badvc; 55195740Srwatson uint32_t rx_closed; 56195740Srwatson}; 57195740Srwatson 58195740Srwatson/* 59195740Srwatson * Addresses on the on-board RAM are expressed as offsets to the 60191273Srwatson * start of that RAM. 61191273Srwatson */ 62191273Srwatsontypedef uint32_t cardoff_t; 63191273Srwatson 64191273Srwatson/* 65191273Srwatson * The card uses a number of queues for communication with the host. 66191273Srwatson * Parts of the queue are located on the card (pointers to the status 67191273Srwatson * word and the ioblk and the command blocks), the rest in host memory. 68191273Srwatson * Each of these queues forms a ring, where the head and tail pointers are 69191273Srwatson * managed * either by the card or the host. For the receive queue the 70191273Srwatson * head is managed by the card (and not used altogether by the host) and the 71191273Srwatson * tail by the host - for all other queues its the other way around. 72191273Srwatson * The host resident parts of the queue entries contain pointers to 73191273Srwatson * the host resident status and the host resident ioblk (the latter not for 74191273Srwatson * the command queue) as well as DMA addresses for supply to the card. 75191273Srwatson */ 76191273Srwatsonstruct fqelem { 77191273Srwatson cardoff_t card; /* corresponding element on card */ 78189279Srwatson bus_addr_t card_ioblk; /* ioblk address to supply to card */ 79189279Srwatson volatile uint32_t *statp; /* host status pointer */ 80189279Srwatson void *ioblk; /* host ioblk (not for commands) */ 81189279Srwatson}; 82189279Srwatson 83189279Srwatsonstruct fqueue { 84189279Srwatson struct fqelem *chunk; /* pointer to the element array */ 85189279Srwatson int head; /* queue head */ 86189279Srwatson int tail; /* queue tail */ 87189279Srwatson}; 88189279Srwatson 89189279Srwatson/* 90189279Srwatson * Queue manipulation macros 91189279Srwatson */ 92189279Srwatson#define NEXT_QUEUE_ENTRY(HEAD,LEN) ((HEAD) = ((HEAD) + 1) % LEN) 93189279Srwatson#define GET_QUEUE(Q,TYPE,IDX) (&((TYPE *)(Q).chunk)[(IDX)]) 94189279Srwatson 95189279Srwatson/* 96189279Srwatson * Now define structures for the different queues. Each of these structures 97187214Srwatson * must start with a struct fqelem. 98187214Srwatson */ 99187214Srwatsonstruct txqueue { /* transmit queue element */ 100187214Srwatson struct fqelem q; 101187214Srwatson struct mbuf *m; /* the chain we are transmitting */ 102187214Srwatson bus_dmamap_t map; /* map for the packet */ 103187214Srwatson}; 104187214Srwatson 105187214Srwatsonstruct rxqueue { /* receive queue element */ 106187214Srwatson struct fqelem q; 107187214Srwatson}; 108187214Srwatson 109187214Srwatsonstruct supqueue { /* supply queue element */ 110187214Srwatson struct fqelem q; 111187214Srwatson}; 112187214Srwatson 113187214Srwatsonstruct cmdqueue; 114187214Srwatsonstruct fatm_softc; 115187214Srwatson 116186647Srwatsontypedef void (*completion_cb)(struct fatm_softc *, struct cmdqueue *); 117186647Srwatson 118186647Srwatsonstruct cmdqueue { /* command queue element */ 119186647Srwatson struct fqelem q; 120186647Srwatson completion_cb cb; /* call on command completion */ 121186647Srwatson int error; /* set if error occured */ 122186647Srwatson}; 123186647Srwatson 124186647Srwatson/* 125186647Srwatson * Card-DMA-able memory is managed by means of the bus_dma* functions. 126186647Srwatson * To allocate a chunk of memory with a specific size and alignment one 127186647Srwatson * has to: 128186647Srwatson * 1. create a DMA tag 129186647Srwatson * 2. allocate the memory 130186647Srwatson * 3. load the memory into a map. 131186647Srwatson * This finally gives the physical address that can be given to the card. 132186647Srwatson * The card can DMA the entire 32-bit space without boundaries. We assume, 133186647Srwatson * that all the allocations can be mapped in one contiguous segment. This 134186647Srwatson * may be wrong in the future if we have more than 32 bit addresses. 135186647Srwatson * Allocation is done at attach time and managed by the following structure. 136186647Srwatson * 137186647Srwatson * This could be done easier with the NetBSD bus_dma* functions. They appear 138186647Srwatson * to be more useful and consistent. 139186647Srwatson */ 140186647Srwatsonstruct fatm_mem { 141186647Srwatson u_int size; /* size */ 142186647Srwatson u_int align; /* alignment */ 143186647Srwatson bus_dma_tag_t dmat; /* DMA tag */ 144186647Srwatson void *mem; /* memory block */ 145186647Srwatson bus_addr_t paddr; /* pysical address */ 146186647Srwatson bus_dmamap_t map; /* map */ 147186647Srwatson}; 148186647Srwatson 149186647Srwatson/* 150186647Srwatson * Each of these structures describes one receive buffer while the buffer 151186647Srwatson * is on the card or in the receive return queue. These structures are 152186647Srwatson * allocated at initialisation time together with the DMA maps. The handle that 153186647Srwatson * is given to the card is the index into the array of these structures. 154186647Srwatson */ 155186647Srwatsonstruct rbuf { 156186647Srwatson struct mbuf *m; /* the mbuf while we are on the card */ 157186647Srwatson bus_dmamap_t map; /* the map */ 158186647Srwatson LIST_ENTRY(rbuf) link; /* the free list link */ 159186647Srwatson}; 160186647SrwatsonLIST_HEAD(rbuf_list, rbuf); 161184902Srwatson 162184902Srwatson/* 163184902Srwatson * The driver maintains a list of all open VCCs. Because we 164184902Srwatson * use only VPI=0 and a maximum VCI of 1024, the list is rather an array 165184902Srwatson * than a list. We also store the atm pseudoheader flags here and the 166184902Srwatson * rxhand (aka. protocol block). 167184902Srwatson */ 168184902Srwatsonstruct card_vcc { 169184902Srwatson struct atmio_vcc param; /* traffic parameters */ 170184902Srwatson void *rxhand; 171184902Srwatson uint vflags; 172184902Srwatson uint32_t ipackets; 173184902Srwatson uint32_t opackets; 174184902Srwatson uint32_t ibytes; 175184902Srwatson uint32_t obytes; 176184902Srwatson}; 177184902Srwatson 178184902Srwatson#define FATM_VCC_OPEN 0x00010000 /* is open */ 179184902Srwatson#define FATM_VCC_TRY_OPEN 0x00020000 /* is currently opening */ 180184902Srwatson#define FATM_VCC_TRY_CLOSE 0x00040000 /* is currently closing */ 181184902Srwatson#define FATM_VCC_BUSY 0x00070000 /* one of the above */ 182184902Srwatson#define FATM_VCC_REOPEN 0x00080000 /* reopening during init */ 183184902Srwatson 184184902Srwatson/* 185184902Srwatson * Finally the softc structure 186184902Srwatson */ 187184902Srwatsonstruct fatm_softc { 188184902Srwatson struct ifatm ifatm; /* common part */ 189184902Srwatson struct mtx mtx; /* lock this structure */ 190184902Srwatson struct ifmedia media; /* media */ 191184902Srwatson 192184902Srwatson int init_state; /* initialisation step */ 193184902Srwatson int memid; /* resource id for card memory */ 194184902Srwatson struct resource *memres; /* resource for card memory */ 195184902Srwatson bus_space_handle_t memh; /* handle for card memory */ 196184902Srwatson bus_space_tag_t memt; /* tag for card memory */ 197184902Srwatson int irqid; /* resource id for interrupt */ 198184902Srwatson struct resource *irqres; /* resource for interrupt */ 199184902Srwatson void *ih; /* interrupt handler */ 200184902Srwatson 201184902Srwatson bus_dma_tag_t parent_dmat; /* parent DMA tag */ 202184902Srwatson struct fatm_mem stat_mem; /* memory for status blocks */ 203184902Srwatson struct fatm_mem txq_mem; /* TX descriptor queue */ 204184902Srwatson struct fatm_mem rxq_mem; /* RX descriptor queue */ 205184902Srwatson struct fatm_mem s1q_mem; /* Small buffer 1 queue */ 206184902Srwatson struct fatm_mem l1q_mem; /* Large buffer 1 queue */ 207184902Srwatson struct fatm_mem prom_mem; /* PROM memory */ 208184902Srwatson 209184902Srwatson struct fqueue txqueue; /* transmission queue */ 210184902Srwatson struct fqueue rxqueue; /* receive queue */ 211184902Srwatson struct fqueue s1queue; /* SMALL S1 queue */ 212184902Srwatson struct fqueue l1queue; /* LARGE S1 queue */ 213184902Srwatson struct fqueue cmdqueue; /* command queue */ 214184902Srwatson 215184902Srwatson /* fields for access to the SUNI registers */ 216184902Srwatson struct fatm_mem reg_mem; /* DMAable memory for readregs */ 217184902Srwatson struct cv cv_regs; /* to serialize access to reg_mem */ 218184902Srwatson 219184902Srwatson /* fields for access to statistics */ 220184902Srwatson struct fatm_mem sadi_mem; /* sadistics memory */ 221184902Srwatson struct cv cv_stat; /* to serialize access to sadi_mem */ 222184902Srwatson 223184902Srwatson u_int flags; 224184902Srwatson#define FATM_STAT_INUSE 0x0001 225184902Srwatson#define FATM_REGS_INUSE 0x0002 226184902Srwatson u_int txcnt; /* number of used transmit desc */ 227184902Srwatson int retry_tx; /* keep mbufs in queue if full */ 228184902Srwatson 229184902Srwatson struct card_vcc **vccs; /* table of vccs */ 230184902Srwatson int open_vccs; /* number of vccs in use */ 231184902Srwatson int small_cnt; /* number of buffers owned by card */ 232184902Srwatson int large_cnt; /* number of buffers owned by card */ 233184902Srwatson uma_zone_t vcc_zone; /* allocator for VCCs */ 234184902Srwatson 235184902Srwatson /* receiving */ 236184902Srwatson struct rbuf *rbufs; /* rbuf array */ 237184902Srwatson struct rbuf_list rbuf_free; /* free rbufs list */ 238184902Srwatson struct rbuf_list rbuf_used; /* used rbufs list */ 239184902Srwatson u_int rbuf_total; /* total number of buffs */ 240184902Srwatson bus_dma_tag_t rbuf_tag; /* tag for rbuf mapping */ 241184902Srwatson 242184902Srwatson /* transmission */ 243184902Srwatson bus_dma_tag_t tx_tag; /* transmission tag */ 244184902Srwatson 245184902Srwatson uint32_t heartbeat; /* last heartbeat */ 246184902Srwatson u_int stop_cnt; /* how many times checked */ 247184902Srwatson 248184902Srwatson struct istats istats; /* internal statistics */ 249184902Srwatson 250184902Srwatson /* SUNI state */ 251184902Srwatson struct utopia utopia; 252184902Srwatson 253184902Srwatson /* sysctl support */ 254184902Srwatson struct sysctl_ctx_list sysctl_ctx; 255184902Srwatson struct sysctl_oid *sysctl_tree; 256184902Srwatson 257184902Srwatson#ifdef FATM_DEBUG 258184902Srwatson /* debugging */ 259184902Srwatson u_int debug; 260184902Srwatson#endif 261184902Srwatson}; 262184902Srwatson 263184902Srwatson#ifndef FATM_DEBUG 264184902Srwatson#define FATM_LOCK(SC) mtx_lock(&(SC)->mtx) 265184902Srwatson#define FATM_UNLOCK(SC) mtx_unlock(&(SC)->mtx) 266184902Srwatson#else 267184902Srwatson#define FATM_LOCK(SC) do { \ 268184902Srwatson DBG(SC, LOCK, ("locking in line %d", __LINE__)); \ 269184902Srwatson mtx_lock(&(SC)->mtx); \ 270184902Srwatson } while (0) 271184902Srwatson#define FATM_UNLOCK(SC) do { \ 272184902Srwatson DBG(SC, LOCK, ("unlocking in line %d", __LINE__)); \ 273184902Srwatson mtx_unlock(&(SC)->mtx); \ 274184902Srwatson } while (0) 275184902Srwatson#endif 276184902Srwatson#define FATM_CHECKLOCK(SC) mtx_assert(&sc->mtx, MA_OWNED) 277184902Srwatson 278184902Srwatson/* 279184902Srwatson * Macros to access host memory fields that are also access by the card. 280184902Srwatson * These fields need to little-endian always. 281184902Srwatson */ 282184902Srwatson#define H_GETSTAT(STATP) (le32toh(*(STATP))) 283184902Srwatson#define H_SETSTAT(STATP, S) do { *(STATP) = htole32(S); } while (0) 284184902Srwatson#define H_SETDESC(DESC, D) do { (DESC) = htole32(D); } while (0) 285184902Srwatson 286184902Srwatson#ifdef notyet 287184902Srwatson#define H_SYNCSTAT_POSTREAD(SC, P) \ 288184902Srwatson bus_dmamap_sync_size((SC)->stat_mem.dmat, \ 289184902Srwatson (SC)->stat_mem.map, \ 290184902Srwatson (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \ 291184902Srwatson sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD) 292184902Srwatson 293184902Srwatson#define H_SYNCSTAT_PREWRITE(SC, P) \ 294184902Srwatson bus_dmamap_sync_size((SC)->stat_mem.dmat, \ 295184902Srwatson (SC)->stat_mem.map, \ 296184902Srwatson (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \ 297184902Srwatson sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE) 298184902Srwatson 299184902Srwatson#define H_SYNCQ_PREWRITE(M, P, SZ) \ 300184902Srwatson bus_dmamap_sync_size((M)->dmat, (M)->map, \ 301184902Srwatson (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \ 302184902Srwatson BUS_DMASYNC_PREWRITE) 303184902Srwatson 304184902Srwatson#define H_SYNCQ_POSTREAD(M, P, SZ) \ 305184902Srwatson bus_dmamap_sync_size((M)->dmat, (M)->map, \ 306184902Srwatson (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \ 307184902Srwatson BUS_DMASYNC_POSTREAD) 308184902Srwatson#else 309184902Srwatson#define H_SYNCSTAT_POSTREAD(SC, P) do { } while (0) 310184902Srwatson#define H_SYNCSTAT_PREWRITE(SC, P) do { } while (0) 311184902Srwatson#define H_SYNCQ_PREWRITE(M, P, SZ) do { } while (0) 312184902Srwatson#define H_SYNCQ_POSTREAD(M, P, SZ) do { } while (0) 313184902Srwatson#endif 314184902Srwatson 315184902Srwatson/* 316184902Srwatson * Macros to manipulate VPVCs 317184902Srwatson */ 318184902Srwatson#define MKVPVC(VPI,VCI) (((VPI) << 16) | (VCI)) 319184902Srwatson#define GETVPI(VPVC) (((VPVC) >> 16) & 0xff) 320184902Srwatson#define GETVCI(VPVC) ((VPVC) & 0xffff) 321184902Srwatson 322184902Srwatson/* 323184902Srwatson * These macros encapsulate the bus_space functions for better readabiliy. 324184902Srwatson */ 325184902Srwatson#define WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL) 326184902Srwatson#define WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL) 327184902Srwatson 328184902Srwatson#define READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF) 329184902Srwatson#define READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF) 330184902Srwatson 331184902Srwatson#define BARRIER_R(SC) \ 332184902Srwatson bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 333184902Srwatson BUS_SPACE_BARRIER_READ) 334184902Srwatson#define BARRIER_W(SC) \ 335184902Srwatson bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 336184902Srwatson BUS_SPACE_BARRIER_WRITE) 337184902Srwatson#define BARRIER_RW(SC) \ 338184902Srwatson bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 339184902Srwatson BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ) 340184902Srwatson 341184902Srwatson#ifdef FATM_DEBUG 342184902Srwatson#define DBG(SC, FL, PRINT) do { \ 343184902Srwatson if ((SC)->debug & DBG_##FL) { \ 344184902Srwatson if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \ 345184902Srwatson printf PRINT; \ 346184902Srwatson printf("\n"); \ 347184902Srwatson } \ 348184902Srwatson } while (0) 349184902Srwatson#define DBGC(SC, FL, PRINT) do { \ 350184902Srwatson if ((SC)->debug & DBG_##FL) \ 351184902Srwatson printf PRINT; \ 352184902Srwatson } while (0) 353184902Srwatson 354184902Srwatsonenum { 355184902Srwatson DBG_RCV = 0x0001, 356184902Srwatson DBG_XMIT = 0x0002, 357184902Srwatson DBG_VCC = 0x0004, 358184902Srwatson DBG_IOCTL = 0x0008, 359184902Srwatson DBG_ATTACH = 0x0010, 360184902Srwatson DBG_INIT = 0x0020, 361184902Srwatson DBG_DMA = 0x0040, 362184902Srwatson DBG_BEAT = 0x0080, 363184902Srwatson DBG_UART = 0x0100, 364184902Srwatson DBG_LOCK = 0x0200, 365184902Srwatson 366184902Srwatson DBG_ALL = 0xffff 367184902Srwatson}; 368184902Srwatson 369184902Srwatson#else 370184902Srwatson#define DBG(SC, FL, PRINT) 371184902Srwatson#define DBGC(SC, FL, PRINT) 372184902Srwatson#endif 373184902Srwatson 374184902Srwatson/* 375184902Srwatson * Configuration. 376184902Srwatson * 377184902Srwatson * This section contains tunable parameters and dependend defines. 378184902Srwatson */ 379184902Srwatson#define FATM_CMD_QLEN 16 /* command queue length */ 380184902Srwatson#ifndef TEST_DMA_SYNC 381184902Srwatson#define FATM_TX_QLEN 128 /* transmit queue length */ 382184902Srwatson#define FATM_RX_QLEN 64 /* receive queue length */ 383184902Srwatson#else 384184902Srwatson#define FATM_TX_QLEN 8 /* transmit queue length */ 385184902Srwatson#define FATM_RX_QLEN 8 /* receive queue length */ 386184902Srwatson#endif 387184902Srwatson 388184902Srwatson#define SMALL_SUPPLY_QLEN 16 389184902Srwatson#define SMALL_POOL_SIZE 256 390184902Srwatson#define SMALL_SUPPLY_BLKSIZE 8 391184902Srwatson 392184902Srwatson#define LARGE_SUPPLY_QLEN 16 393184902Srwatson#define LARGE_POOL_SIZE 128 394184902Srwatson#define LARGE_SUPPLY_BLKSIZE 8 395184902Srwatson