1139749Simp/*- 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$ 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 */ 121298955Spfg int error; /* set if error occurred */ 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 { 169118208Sharti struct atmio_vcc param; /* traffic parameters */ 170116735Sharti void *rxhand; 171118607Sjhb u_int vflags; 172118208Sharti uint32_t ipackets; 173118208Sharti uint32_t opackets; 174118208Sharti uint32_t ibytes; 175118208Sharti uint32_t obytes; 176116735Sharti}; 177116735Sharti 178116735Sharti#define FATM_VCC_OPEN 0x00010000 /* is open */ 179116735Sharti#define FATM_VCC_TRY_OPEN 0x00020000 /* is currently opening */ 180116735Sharti#define FATM_VCC_TRY_CLOSE 0x00040000 /* is currently closing */ 181116735Sharti#define FATM_VCC_BUSY 0x00070000 /* one of the above */ 182118596Sharti#define FATM_VCC_REOPEN 0x00080000 /* reopening during init */ 183116735Sharti 184116735Sharti/* 185116735Sharti * Finally the softc structure 186116735Sharti */ 187116735Shartistruct fatm_softc { 188147256Sbrooks struct ifnet *ifp; /* common part */ 189116735Sharti struct mtx mtx; /* lock this structure */ 190116735Sharti struct ifmedia media; /* media */ 191199559Sjhb struct callout watchdog_timer; 192116735Sharti 193116735Sharti int init_state; /* initialisation step */ 194116735Sharti int memid; /* resource id for card memory */ 195116735Sharti struct resource *memres; /* resource for card memory */ 196116735Sharti bus_space_handle_t memh; /* handle for card memory */ 197116735Sharti bus_space_tag_t memt; /* tag for card memory */ 198116735Sharti int irqid; /* resource id for interrupt */ 199116735Sharti struct resource *irqres; /* resource for interrupt */ 200116735Sharti void *ih; /* interrupt handler */ 201116735Sharti 202116735Sharti bus_dma_tag_t parent_dmat; /* parent DMA tag */ 203116735Sharti struct fatm_mem stat_mem; /* memory for status blocks */ 204116735Sharti struct fatm_mem txq_mem; /* TX descriptor queue */ 205116735Sharti struct fatm_mem rxq_mem; /* RX descriptor queue */ 206116735Sharti struct fatm_mem s1q_mem; /* Small buffer 1 queue */ 207116735Sharti struct fatm_mem l1q_mem; /* Large buffer 1 queue */ 208116735Sharti struct fatm_mem prom_mem; /* PROM memory */ 209116735Sharti 210116735Sharti struct fqueue txqueue; /* transmission queue */ 211116735Sharti struct fqueue rxqueue; /* receive queue */ 212116735Sharti struct fqueue s1queue; /* SMALL S1 queue */ 213116735Sharti struct fqueue l1queue; /* LARGE S1 queue */ 214116735Sharti struct fqueue cmdqueue; /* command queue */ 215116735Sharti 216116735Sharti /* fields for access to the SUNI registers */ 217116735Sharti struct fatm_mem reg_mem; /* DMAable memory for readregs */ 218116735Sharti struct cv cv_regs; /* to serialize access to reg_mem */ 219116735Sharti 220116735Sharti /* fields for access to statistics */ 221116735Sharti struct fatm_mem sadi_mem; /* sadistics memory */ 222116735Sharti struct cv cv_stat; /* to serialize access to sadi_mem */ 223116735Sharti 224116735Sharti u_int flags; 225116735Sharti#define FATM_STAT_INUSE 0x0001 226116735Sharti#define FATM_REGS_INUSE 0x0002 227116735Sharti u_int txcnt; /* number of used transmit desc */ 228116735Sharti int retry_tx; /* keep mbufs in queue if full */ 229116735Sharti 230118208Sharti struct card_vcc **vccs; /* table of vccs */ 231116735Sharti int open_vccs; /* number of vccs in use */ 232116735Sharti int small_cnt; /* number of buffers owned by card */ 233116735Sharti int large_cnt; /* number of buffers owned by card */ 234118208Sharti uma_zone_t vcc_zone; /* allocator for VCCs */ 235116735Sharti 236116735Sharti /* receiving */ 237116735Sharti struct rbuf *rbufs; /* rbuf array */ 238116735Sharti struct rbuf_list rbuf_free; /* free rbufs list */ 239116735Sharti struct rbuf_list rbuf_used; /* used rbufs list */ 240116735Sharti u_int rbuf_total; /* total number of buffs */ 241116735Sharti bus_dma_tag_t rbuf_tag; /* tag for rbuf mapping */ 242116735Sharti 243116735Sharti /* transmission */ 244116735Sharti bus_dma_tag_t tx_tag; /* transmission tag */ 245116735Sharti 246116735Sharti uint32_t heartbeat; /* last heartbeat */ 247116735Sharti u_int stop_cnt; /* how many times checked */ 248116735Sharti 249116735Sharti struct istats istats; /* internal statistics */ 250116735Sharti 251116735Sharti /* SUNI state */ 252116735Sharti struct utopia utopia; 253116735Sharti 254116735Sharti /* sysctl support */ 255116735Sharti struct sysctl_ctx_list sysctl_ctx; 256116735Sharti struct sysctl_oid *sysctl_tree; 257116735Sharti 258116735Sharti#ifdef FATM_DEBUG 259116735Sharti /* debugging */ 260116735Sharti u_int debug; 261116735Sharti#endif 262116735Sharti}; 263116735Sharti 264116735Sharti#ifndef FATM_DEBUG 265116735Sharti#define FATM_LOCK(SC) mtx_lock(&(SC)->mtx) 266116735Sharti#define FATM_UNLOCK(SC) mtx_unlock(&(SC)->mtx) 267116735Sharti#else 268116735Sharti#define FATM_LOCK(SC) do { \ 269116735Sharti DBG(SC, LOCK, ("locking in line %d", __LINE__)); \ 270116735Sharti mtx_lock(&(SC)->mtx); \ 271116735Sharti } while (0) 272116735Sharti#define FATM_UNLOCK(SC) do { \ 273116735Sharti DBG(SC, LOCK, ("unlocking in line %d", __LINE__)); \ 274116735Sharti mtx_unlock(&(SC)->mtx); \ 275116735Sharti } while (0) 276116735Sharti#endif 277116735Sharti#define FATM_CHECKLOCK(SC) mtx_assert(&sc->mtx, MA_OWNED) 278116735Sharti 279116735Sharti/* 280116735Sharti * Macros to access host memory fields that are also access by the card. 281116735Sharti * These fields need to little-endian always. 282116735Sharti */ 283116735Sharti#define H_GETSTAT(STATP) (le32toh(*(STATP))) 284116735Sharti#define H_SETSTAT(STATP, S) do { *(STATP) = htole32(S); } while (0) 285116735Sharti#define H_SETDESC(DESC, D) do { (DESC) = htole32(D); } while (0) 286116735Sharti 287116735Sharti#ifdef notyet 288116735Sharti#define H_SYNCSTAT_POSTREAD(SC, P) \ 289116735Sharti bus_dmamap_sync_size((SC)->stat_mem.dmat, \ 290116735Sharti (SC)->stat_mem.map, \ 291116735Sharti (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \ 292116735Sharti sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD) 293116735Sharti 294116735Sharti#define H_SYNCSTAT_PREWRITE(SC, P) \ 295116735Sharti bus_dmamap_sync_size((SC)->stat_mem.dmat, \ 296116735Sharti (SC)->stat_mem.map, \ 297116735Sharti (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \ 298116735Sharti sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE) 299116735Sharti 300116735Sharti#define H_SYNCQ_PREWRITE(M, P, SZ) \ 301116735Sharti bus_dmamap_sync_size((M)->dmat, (M)->map, \ 302116735Sharti (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \ 303116735Sharti BUS_DMASYNC_PREWRITE) 304116735Sharti 305116735Sharti#define H_SYNCQ_POSTREAD(M, P, SZ) \ 306116735Sharti bus_dmamap_sync_size((M)->dmat, (M)->map, \ 307116735Sharti (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \ 308116735Sharti BUS_DMASYNC_POSTREAD) 309116735Sharti#else 310116735Sharti#define H_SYNCSTAT_POSTREAD(SC, P) do { } while (0) 311116735Sharti#define H_SYNCSTAT_PREWRITE(SC, P) do { } while (0) 312116735Sharti#define H_SYNCQ_PREWRITE(M, P, SZ) do { } while (0) 313116735Sharti#define H_SYNCQ_POSTREAD(M, P, SZ) do { } while (0) 314116735Sharti#endif 315116735Sharti 316116735Sharti/* 317116735Sharti * Macros to manipulate VPVCs 318116735Sharti */ 319116735Sharti#define MKVPVC(VPI,VCI) (((VPI) << 16) | (VCI)) 320116735Sharti#define GETVPI(VPVC) (((VPVC) >> 16) & 0xff) 321116735Sharti#define GETVCI(VPVC) ((VPVC) & 0xffff) 322116735Sharti 323116735Sharti/* 324116735Sharti * These macros encapsulate the bus_space functions for better readabiliy. 325116735Sharti */ 326116735Sharti#define WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL) 327116735Sharti#define WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL) 328116735Sharti 329116735Sharti#define READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF) 330116735Sharti#define READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF) 331116735Sharti 332116735Sharti#define BARRIER_R(SC) \ 333116735Sharti bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 334116735Sharti BUS_SPACE_BARRIER_READ) 335116735Sharti#define BARRIER_W(SC) \ 336116735Sharti bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 337116735Sharti BUS_SPACE_BARRIER_WRITE) 338116735Sharti#define BARRIER_RW(SC) \ 339116735Sharti bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \ 340116735Sharti BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ) 341116735Sharti 342116735Sharti#ifdef FATM_DEBUG 343116735Sharti#define DBG(SC, FL, PRINT) do { \ 344116735Sharti if ((SC)->debug & DBG_##FL) { \ 345116735Sharti if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \ 346116735Sharti printf PRINT; \ 347116735Sharti printf("\n"); \ 348116735Sharti } \ 349116735Sharti } while (0) 350116735Sharti#define DBGC(SC, FL, PRINT) do { \ 351116735Sharti if ((SC)->debug & DBG_##FL) \ 352116735Sharti printf PRINT; \ 353116735Sharti } while (0) 354116735Sharti 355116735Shartienum { 356116735Sharti DBG_RCV = 0x0001, 357116735Sharti DBG_XMIT = 0x0002, 358116735Sharti DBG_VCC = 0x0004, 359116735Sharti DBG_IOCTL = 0x0008, 360116735Sharti DBG_ATTACH = 0x0010, 361116735Sharti DBG_INIT = 0x0020, 362116735Sharti DBG_DMA = 0x0040, 363116735Sharti DBG_BEAT = 0x0080, 364116735Sharti DBG_UART = 0x0100, 365116735Sharti DBG_LOCK = 0x0200, 366116735Sharti 367116735Sharti DBG_ALL = 0xffff 368116735Sharti}; 369116735Sharti 370116735Sharti#else 371116735Sharti#define DBG(SC, FL, PRINT) 372116735Sharti#define DBGC(SC, FL, PRINT) 373116735Sharti#endif 374116735Sharti 375116735Sharti/* 376116735Sharti * Configuration. 377116735Sharti * 378116735Sharti * This section contains tunable parameters and dependend defines. 379116735Sharti */ 380116735Sharti#define FATM_CMD_QLEN 16 /* command queue length */ 381116735Sharti#ifndef TEST_DMA_SYNC 382116735Sharti#define FATM_TX_QLEN 128 /* transmit queue length */ 383116735Sharti#define FATM_RX_QLEN 64 /* receive queue length */ 384116735Sharti#else 385116735Sharti#define FATM_TX_QLEN 8 /* transmit queue length */ 386116735Sharti#define FATM_RX_QLEN 8 /* receive queue length */ 387116735Sharti#endif 388116735Sharti 389116735Sharti#define SMALL_SUPPLY_QLEN 16 390116735Sharti#define SMALL_POOL_SIZE 256 391116735Sharti#define SMALL_SUPPLY_BLKSIZE 8 392116735Sharti 393116735Sharti#define LARGE_SUPPLY_QLEN 16 394116735Sharti#define LARGE_POOL_SIZE 128 395116735Sharti#define LARGE_SUPPLY_BLKSIZE 8 396