1139749Simp/*- 2117632Sharti * Copyright (c) 2003 3117632Sharti * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4117632Sharti * All rights reserved. 5117632Sharti * 6117632Sharti * Redistribution and use in source and binary forms, with or without 7117632Sharti * modification, are permitted provided that the following conditions 8117632Sharti * are met: 9117632Sharti * 1. Redistributions of source code must retain the above copyright 10117632Sharti * notice, this list of conditions and the following disclaimer. 11117632Sharti * 2. Redistributions in binary form must reproduce the above copyright 12117632Sharti * notice, this list of conditions and the following disclaimer in the 13117632Sharti * documentation and/or other materials provided with the distribution. 14117632Sharti * 15117632Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16117632Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17117632Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18117632Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19117632Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20117632Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21117632Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22117632Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23117632Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24117632Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25117632Sharti * SUCH DAMAGE. 26117632Sharti * 27117632Sharti * Author: Hartmut Brandt <harti@freebsd.org> 28117632Sharti * 29117632Sharti * $FreeBSD$ 30117632Sharti * 31117632Sharti * Driver for IDT77252 (ABR) based cards like ProSum's. 32117632Sharti */ 33117632Sharti 34117632Sharti/* legal values are 0, 1, 2 and 8 */ 35117632Sharti#define PATM_VPI_BITS 2 36117632Sharti#define PATM_CFG_VPI IDT_CFG_VP2 37117632Sharti 38117632Sharti/* receive status queue size */ 39117632Sharti#define PATM_RSQ_SIZE 512 40117632Sharti#define PATM_CFQ_RSQ_SIZE IDT_CFG_RXQ512 41117632Sharti 42117632Sharti/* alignment for SQ memory */ 43117632Sharti#define PATM_SQ_ALIGNMENT 8192 44117632Sharti 45117632Sharti#define PATM_PROATM_NAME_OFFSET 060 46117632Sharti#define PATM_PROATM_NAME "PROATM" 47117632Sharti#define PATM_PROATM_MAC_OFFSET 044 48117632Sharti#define PATM_IDT_MAC_OFFSET 0154 49117632Sharti 50117632Sharti/* maximum number of packets on UBR queue */ 51117632Sharti#define PATM_DLFT_MAXQ 1000 52117632Sharti 53117632Sharti/* maximum number of packets on other queues. This should depend on the 54117632Sharti * traffic contract. */ 55117632Sharti#define PATM_TX_IFQLEN 100 56117632Sharti 57117632Sharti/* 58117632Sharti * Maximum number of DMA maps we allocate. This is the minimum that can be 59117632Sharti * set larger via a sysctl. 60117632Sharti * Starting number of DMA maps. 61117632Sharti * Step for growing. 62117632Sharti */ 63117632Sharti#define PATM_CFG_TXMAPS_MAX 1024 64117632Sharti#define PATM_CFG_TXMAPS_INIT 128 65117632Sharti#define PATM_CFG_TXMAPS_STEP 128 66117632Sharti 67117632Sharti/* percents of TST slots to keep for non-CBR traffic */ 68117632Sharti#define PATM_TST_RESERVE 2 69117632Sharti 70117632Sharti/* 71117632Sharti * Structure to hold TX DMA maps 72117632Sharti */ 73117632Shartistruct patm_txmap { 74117632Sharti SLIST_ENTRY(patm_txmap) link; 75117632Sharti bus_dmamap_t map; 76117632Sharti}; 77117632Sharti 78117632Sharti/* 79117632Sharti * Receive buffers. 80117632Sharti * 81117632Sharti * We manage our own external mbufs for small receive buffers for two reasons: 82117632Sharti * the card may consume a rather large number of buffers. Mapping each buffer 83117632Sharti * would consume a lot of iospace on sparc64. Also the card allows us to set 84117632Sharti * a 32-bit handle for identification of the buffers. On a 64-bit system this 85117632Sharti * requires us to use a mapping between buffers and handles. 86117632Sharti * 87117632Sharti * For large buffers we use mbuf clusters directly. We track these by using 88117632Sharti * an array of pointers (lbufs) to special structs and a free list of these 89117632Sharti * structs. 90117632Sharti * 91117632Sharti * For AAL0 cell we use FBQ2 and make the 1 cell long. 92117632Sharti */ 93117632Sharti/* 94117632Sharti * Define the small buffer chunk so that we have at least 16 byte free 95117632Sharti * at the end of the chunk and that there is an integral number of chunks 96117632Sharti * in a page. 97117632Sharti */ 98117632Sharti#define SMBUF_PAGE_SIZE 16384 /* 16k pages */ 99117632Sharti#define SMBUF_MAX_PAGES 64 /* maximum number of pages */ 100117632Sharti#define SMBUF_CHUNK_SIZE 256 /* 256 bytes per chunk */ 101117632Sharti#define SMBUF_CELLS 5 102117632Sharti#define SMBUF_SIZE (SMBUF_CELLS * 48) 103117632Sharti#define SMBUF_THRESHOLD 9 /* 9/16 of queue size */ 104117632Sharti#define SMBUF_NI_THRESH 3 105117632Sharti#define SMBUF_CI_THRESH 1 106117632Sharti 107117632Sharti#define VMBUF_PAGE_SIZE 16384 /* 16k pages */ 108117632Sharti#define VMBUF_MAX_PAGES 16 /* maximum number of pages */ 109117632Sharti#define VMBUF_CHUNK_SIZE 64 /* 64 bytes per chunk */ 110117632Sharti#define VMBUF_CELLS 1 111117632Sharti#define VMBUF_SIZE (VMBUF_CELLS * 48) 112117632Sharti#define VMBUF_THRESHOLD 15 /* 15/16 of size */ 113117632Sharti 114117632Sharti#define SMBUF_OFFSET (SMBUF_CHUNK_SIZE - 8 - SMBUF_SIZE) 115117632Sharti#define VMBUF_OFFSET 0 116117632Sharti 117117632Sharti#define MBUF_SHANDLE 0x00000000 118117632Sharti#define MBUF_LHANDLE 0x80000000 119117632Sharti#define MBUF_VHANDLE 0x40000000 120117632Sharti#define MBUF_HMASK 0x3fffffff 121117632Sharti 122117632Sharti/* 123117632Sharti * Large buffers 124117632Sharti * 125117632Sharti * The problem with these is the maximum count. When the card assembles 126117632Sharti * a AAL5 pdu it moves a buffer from the FBQ to the VC. This frees space 127117632Sharti * in the FBQ, put the buffer may pend on the card for an unlimited amount 128117632Sharti * of time (we don't idle connections). This means that the upper limit 129117632Sharti * on buffers on the card may be (no-of-open-vcs + FBQ_SIZE). Because 130117632Sharti * this is far too much, make this a tuneable. We could also make 131117632Sharti * this dynamic by allocating pages of several lbufs at once during run time. 132117632Sharti */ 133117632Sharti#define LMBUF_MAX (IDT_FBQ_SIZE * 2) 134117632Sharti#define LMBUF_CELLS (MCLBYTES / 48) /* 42 cells = 2048 byte */ 135117632Sharti#define LMBUF_SIZE (LMBUF_CELLS * 48) 136117632Sharti#define LMBUF_THRESHOLD 9 /* 9/16 of queue size */ 137117632Sharti#define LMBUF_OFFSET (MCLBYTES - LMBUF_SIZE) 138117632Sharti#define LMBUF_NI_THRESH 3 139117632Sharti#define LMBUF_CI_THRESH 1 140117632Sharti 141117632Sharti#define LMBUF_HANDLE 0x80000000 142117632Sharti 143117632Shartistruct lmbuf { 144117632Sharti SLIST_ENTRY(lmbuf) link; /* free list link */ 145117632Sharti bus_dmamap_t map; /* DMA map */ 146117632Sharti u_int handle; /* this is the handle index */ 147117632Sharti struct mbuf *m; /* the current mbuf */ 148117632Sharti bus_addr_t phy; /* phy addr */ 149117632Sharti}; 150117632Sharti 151117632Sharti#define PATM_CID(SC, VPI, VCI) \ 152147256Sbrooks (((VPI) << IFP2IFATM((SC)->ifp)->mib.vci_bits) | (VCI)) 153117632Sharti 154117632Sharti/* 155117632Sharti * Internal driver statistics 156117632Sharti */ 157117632Shartistruct patm_stats { 158117632Sharti uint32_t raw_cells; 159117632Sharti uint32_t raw_no_vcc; 160117632Sharti uint32_t raw_no_buf; 161117632Sharti uint32_t tx_qfull; 162117632Sharti uint32_t tx_out_of_tbds; 163117632Sharti uint32_t tx_out_of_maps; 164117632Sharti uint32_t tx_load_err; 165117632Sharti}; 166117632Sharti 167117632Sharti/* 168117632Sharti * These are allocated as DMA able memory 169117632Sharti */ 170117632Shartistruct patm_scd { 171117632Sharti struct idt_tbd scq[IDT_SCQ_SIZE]; 172117632Sharti LIST_ENTRY(patm_scd) link; /* all active SCDs */ 173117632Sharti uint32_t sram; /* SRAM address */ 174117632Sharti bus_addr_t phy; /* physical address */ 175117632Sharti bus_dmamap_t map; /* DMA map */ 176117632Sharti u_int tail; /* next free entry for host */ 177117632Sharti int space; /* number of free entries (minus one) */ 178117632Sharti u_int slots; /* CBR slots allocated */ 179117632Sharti uint8_t tag; /* next tag for TSI */ 180117632Sharti uint8_t last_tag; /* last tag checked in interrupt */ 181117632Sharti uint8_t num_on_card; /* number of PDUs on tx queue */ 182117632Sharti uint8_t lacr; /* LogACR value */ 183117632Sharti uint8_t init_er; /* LogER value */ 184117632Sharti struct ifqueue q; /* queue of packets */ 185117632Sharti struct mbuf *on_card[IDT_TSQE_TAG_SPACE]; 186117632Sharti}; 187117632Sharti 188117632Sharti/* 189117632Sharti * Per-VCC data 190117632Sharti */ 191117632Shartistruct patm_vcc { 192117632Sharti struct atmio_vcc vcc; /* caller's parameters */ 193117632Sharti void *rxhand; /* NATM handle */ 194117632Sharti u_int vflags; /* open and other flags */ 195117632Sharti uint32_t ipackets; /* packets received */ 196117632Sharti uint32_t opackets; /* packets sent */ 197117632Sharti uint64_t ibytes; /* bytes received */ 198117632Sharti uint64_t obytes; /* bytes sent */ 199118601Sharti 200117632Sharti struct mbuf *chain; /* currently received chain */ 201117632Sharti struct mbuf *last; /* end of chain */ 202117632Sharti u_int cid; /* index */ 203117632Sharti u_int cps; /* last ABR cps */ 204117632Sharti struct patm_scd *scd; 205117632Sharti}; 206117632Sharti#define PATM_VCC_TX_OPEN 0x0001 207117632Sharti#define PATM_VCC_RX_OPEN 0x0002 208117632Sharti#define PATM_VCC_TX_CLOSING 0x0004 209117632Sharti#define PATM_VCC_RX_CLOSING 0x0008 210117632Sharti#define PATM_VCC_OPEN 0x000f /* all the above */ 211117632Sharti 212117632Sharti#define PATM_RAW_CELL 0x0000 /* 53 byte cells */ 213117632Sharti#define PATM_RAW_NOHEC 0x0100 /* 52 byte cells */ 214117632Sharti#define PATM_RAW_CS 0x0200 /* 64 byte cell stream */ 215117632Sharti#define PATM_RAW_FORMAT 0x0300 /* format mask */ 216117632Sharti 217117632Sharti/* 218117632Sharti * Per adapter data 219117632Sharti */ 220117632Shartistruct patm_softc { 221147256Sbrooks struct ifnet *ifp; /* common ATM stuff */ 222117632Sharti struct mtx mtx; /* lock */ 223117632Sharti struct ifmedia media; /* media */ 224117632Sharti device_t dev; /* device */ 225117632Sharti struct resource * memres; /* memory resource */ 226117632Sharti bus_space_handle_t memh; /* handle */ 227117632Sharti bus_space_tag_t memt; /* ... and tag */ 228117632Sharti int irqid; /* resource id */ 229117632Sharti struct resource * irqres; /* resource */ 230117632Sharti void * ih; /* interrupt handle */ 231117632Sharti struct utopia utopia; /* phy state */ 232117632Sharti const struct idt_mmap *mmap; /* SRAM memory map */ 233117632Sharti u_int flags; /* see below */ 234117632Sharti u_int revision; /* chip revision */ 235117632Sharti 236117632Sharti /* DMAable status queue memory */ 237117632Sharti size_t sq_size; /* size of memory area */ 238117632Sharti bus_dma_tag_t sq_tag; /* DMA tag */ 239117632Sharti bus_dmamap_t sq_map; /* map */ 240117632Sharti 241117632Sharti bus_addr_t tsq_phy; /* phys addr. */ 242117632Sharti struct idt_tsqe *tsq; /* transmit status queue */ 243117632Sharti struct idt_tsqe *tsq_next; /* last processed entry */ 244117632Sharti struct idt_rsqe *rsq; /* receive status queue */ 245117632Sharti bus_addr_t rsq_phy; /* phys addr. */ 246117632Sharti u_int rsq_last; /* last processed entry */ 247117632Sharti struct idt_rawhnd *rawhnd; /* raw cell handle */ 248117632Sharti bus_addr_t rawhnd_phy; /* phys addr. */ 249117632Sharti 250117632Sharti /* TST */ 251117632Sharti u_int tst_state; /* active TST and others */ 252117632Sharti u_int tst_jump[2]; /* address of the jumps */ 253117632Sharti u_int tst_base[2]; /* base address of TST */ 254117632Sharti u_int *tst_soft; /* soft TST */ 255117632Sharti struct mtx tst_lock; 256117632Sharti struct callout tst_callout; 257117632Sharti u_int tst_free; /* free slots */ 258117632Sharti u_int tst_reserve; /* non-CBR reserve */ 259117632Sharti u_int bwrem; /* remaining bandwith */ 260117632Sharti 261117632Sharti /* sysctl support */ 262117632Sharti struct sysctl_ctx_list sysctl_ctx; 263117632Sharti struct sysctl_oid *sysctl_tree; 264117632Sharti 265117632Sharti /* EEPROM contents */ 266117632Sharti uint8_t eeprom[256]; 267117632Sharti 268117632Sharti /* large buffer mapping */ 269117632Sharti bus_dma_tag_t lbuf_tag; /* DMA tag */ 270117632Sharti u_int lbuf_max; /* maximum number */ 271117632Sharti struct lmbuf *lbufs; /* array for indexing */ 272117632Sharti SLIST_HEAD(,lmbuf) lbuf_free_list; /* free list */ 273117632Sharti 274117632Sharti /* small buffer handling */ 275117632Sharti bus_dma_tag_t sbuf_tag; /* DMA tag */ 276117632Sharti struct mbpool *sbuf_pool; /* pool */ 277117632Sharti struct mbpool *vbuf_pool; /* pool */ 278117632Sharti 279117632Sharti /* raw cell queue */ 280117632Sharti struct lmbuf *rawh; /* current header buf */ 281117632Sharti u_int rawi; /* cell index into buffer */ 282117632Sharti 283117632Sharti /* statistics */ 284117632Sharti struct patm_stats stats; /* statistics */ 285117632Sharti 286117632Sharti /* Vccs */ 287117632Sharti struct patm_vcc **vccs; /* channel pointer array */ 288117632Sharti u_int vccs_open; /* number of open channels */ 289117632Sharti uma_zone_t vcc_zone; 290117632Sharti struct cv vcc_cv; 291117632Sharti 292117632Sharti /* SCDs */ 293117632Sharti uint32_t scd_free; /* SRAM of first free SCD */ 294117632Sharti bus_dma_tag_t scd_tag; 295117632Sharti struct patm_scd *scd0; 296117632Sharti LIST_HEAD(, patm_scd) scd_list; /* list of all active SCDs */ 297117632Sharti 298117632Sharti /* Tx */ 299117632Sharti bus_dma_tag_t tx_tag; /* for transmission */ 300117632Sharti SLIST_HEAD(, patm_txmap) tx_maps_free; /* free maps */ 301117632Sharti u_int tx_nmaps; /* allocated maps */ 302117632Sharti u_int tx_maxmaps; /* maximum number */ 303117632Sharti struct uma_zone *tx_mapzone; /* zone for maps */ 304117632Sharti 305117632Sharti#ifdef PATM_DEBUG 306117632Sharti /* debugging */ 307117632Sharti u_int debug; 308117632Sharti#endif 309117632Sharti}; 310117632Sharti 311117632Sharti/* flags */ 312117632Sharti#define PATM_25M 0x0001 /* 25MBit card */ 313117632Sharti#define PATM_SBUFW 0x0002 /* warned */ 314117632Sharti#define PATM_VBUFW 0x0004 /* warned */ 315117632Sharti#define PATM_UNASS 0x0010 /* unassigned cells */ 316117632Sharti 317117632Sharti#define PATM_CLR 0x0007 /* clear on stop */ 318117632Sharti 319117632Sharti/* tst - uses unused fields */ 320117632Sharti#define TST_BOTH 0x03000000 321117632Sharti#define TST_CH0 0x01000000 322117632Sharti#define TST_CH1 0x02000000 323117632Sharti/* tst_state */ 324117632Sharti#define TST_ACT1 0x0001 /* active TST */ 325117632Sharti#define TST_PENDING 0x0002 /* need update */ 326117632Sharti#define TST_WAIT 0x0004 /* wait fo jump */ 327117632Sharti 328147256Sbrooks#define patm_printf(SC, ...) if_printf((SC)->ifp, __VA_ARGS__); 329117632Sharti 330117632Sharti#ifdef PATM_DEBUG 331117632Sharti/* 332117632Sharti * Debugging 333117632Sharti */ 334117632Shartienum { 335117632Sharti DBG_ATTACH = 0x0001, /* attaching the card */ 336117632Sharti DBG_INTR = 0x0002, /* interrupts */ 337117632Sharti DBG_REG = 0x0004, /* register access */ 338117632Sharti DBG_SRAM = 0x0008, /* SRAM access */ 339117632Sharti DBG_PHY = 0x0010, /* PHY access */ 340117632Sharti DBG_IOCTL = 0x0020, /* ioctl */ 341117632Sharti DBG_FREEQ = 0x0040, /* free bufq supply */ 342117632Sharti DBG_VCC = 0x0080, /* open/close */ 343117632Sharti DBG_TX = 0x0100, /* transmission */ 344117632Sharti DBG_TST = 0x0200, /* TST */ 345117632Sharti 346117632Sharti DBG_ALL = 0xffff 347117632Sharti}; 348117632Sharti 349117632Sharti#define patm_debug(SC, FLAG, ...) do { \ 350117632Sharti if((SC)->debug & DBG_##FLAG) { \ 351147256Sbrooks if_printf((SC)->ifp, "%s: ", __func__); \ 352117632Sharti printf(__VA_ARGS__); \ 353117632Sharti printf("\n"); \ 354117632Sharti } \ 355117632Sharti } while (0) 356117632Sharti#else 357117632Sharti 358117632Sharti#define patm_debug(SC, FLAG, ...) do { } while (0) 359117632Sharti 360117632Sharti#endif 361117632Sharti 362117632Sharti/* start output */ 363117632Shartivoid patm_start(struct ifnet *); 364117632Sharti 365117632Sharti/* ioctl handler */ 366117632Shartiint patm_ioctl(struct ifnet *, u_long, caddr_t); 367117632Sharti 368117632Sharti/* start the interface */ 369117632Shartivoid patm_init(void *); 370117632Sharti 371117632Sharti/* start the interface with the lock held */ 372117632Shartivoid patm_initialize(struct patm_softc *); 373117632Sharti 374117632Sharti/* stop the interface */ 375117632Shartivoid patm_stop(struct patm_softc *); 376117632Sharti 377117632Sharti/* software reset of interface */ 378117632Shartivoid patm_reset(struct patm_softc *); 379117632Sharti 380117632Sharti/* interrupt handler */ 381117632Shartivoid patm_intr(void *); 382117632Sharti 383117632Sharti/* check RSQ */ 384117632Shartivoid patm_intr_rsq(struct patm_softc *sc); 385117632Sharti 386118601Sharti/* enable the vcc */ 387118601Shartivoid patm_load_vc(struct patm_softc *sc, struct patm_vcc *vcc, int reload); 388118601Sharti 389117632Sharti/* close the given vcc for transmission */ 390117632Shartivoid patm_tx_vcc_close(struct patm_softc *, struct patm_vcc *); 391117632Sharti 392117632Sharti/* close the given vcc for receive */ 393117632Shartivoid patm_rx_vcc_close(struct patm_softc *, struct patm_vcc *); 394117632Sharti 395117632Sharti/* transmission side finally closed */ 396117632Shartivoid patm_tx_vcc_closed(struct patm_softc *, struct patm_vcc *); 397117632Sharti 398117632Sharti/* receive side finally closed */ 399117632Shartivoid patm_rx_vcc_closed(struct patm_softc *, struct patm_vcc *); 400117632Sharti 401117632Sharti/* vcc closed */ 402117632Shartivoid patm_vcc_closed(struct patm_softc *, struct patm_vcc *); 403117632Sharti 404117632Sharti/* check if we can open this one */ 405117632Shartiint patm_tx_vcc_can_open(struct patm_softc *, struct patm_vcc *); 406117632Sharti 407117632Sharti/* check if we can open this one */ 408117632Shartiint patm_rx_vcc_can_open(struct patm_softc *, struct patm_vcc *); 409117632Sharti 410117632Sharti/* open it */ 411117632Shartivoid patm_tx_vcc_open(struct patm_softc *, struct patm_vcc *); 412117632Sharti 413117632Sharti/* open it */ 414117632Shartivoid patm_rx_vcc_open(struct patm_softc *, struct patm_vcc *); 415117632Sharti 416117632Sharti/* receive packet */ 417117632Shartivoid patm_rx(struct patm_softc *, struct idt_rsqe *); 418117632Sharti 419117632Sharti/* packet transmitted */ 420117632Shartivoid patm_tx(struct patm_softc *, u_int, u_int); 421117632Sharti 422117632Sharti/* VBR connection went idle */ 423117632Shartivoid patm_tx_idle(struct patm_softc *, u_int); 424117632Sharti 425117632Sharti/* allocate an SCQ */ 426117632Shartistruct patm_scd *patm_scd_alloc(struct patm_softc *); 427117632Sharti 428117632Sharti/* free an SCD */ 429117632Shartivoid patm_scd_free(struct patm_softc *sc, struct patm_scd *scd); 430117632Sharti 431117632Sharti/* setup SCD in SRAM */ 432117632Shartivoid patm_scd_setup(struct patm_softc *sc, struct patm_scd *scd); 433117632Sharti 434117632Sharti/* setup TCT entry in SRAM */ 435117632Shartivoid patm_tct_setup(struct patm_softc *, struct patm_scd *, struct patm_vcc *); 436117632Sharti 437117632Sharti/* free a large buffer */ 438117632Shartivoid patm_lbuf_free(struct patm_softc *sc, struct lmbuf *b); 439117632Sharti 440117632Sharti/* Process the raw cell at the given address */ 441117632Shartivoid patm_rx_raw(struct patm_softc *sc, u_char *cell); 442117632Sharti 443117632Sharti/* load a one segment DMA map */ 444117632Shartivoid patm_load_callback(void *, bus_dma_segment_t *, int, int); 445117632Sharti 446117632Sharti/* network operation register access */ 447117632Shartistatic __inline uint32_t 448117632Shartipatm_nor_read(struct patm_softc *sc, u_int reg) 449117632Sharti{ 450117632Sharti uint32_t val; 451117632Sharti 452117632Sharti val = bus_space_read_4(sc->memt, sc->memh, reg); 453117632Sharti patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val); 454117632Sharti return (val); 455117632Sharti} 456117632Shartistatic __inline void 457117632Shartipatm_nor_write(struct patm_softc *sc, u_int reg, uint32_t val) 458117632Sharti{ 459117632Sharti 460117632Sharti patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val); 461117632Sharti bus_space_write_4(sc->memt, sc->memh, reg, val); 462117632Sharti} 463117632Sharti 464117632Sharti/* Execute command */ 465117632Shartistatic __inline void 466117632Shartipatm_cmd_wait(struct patm_softc *sc) 467117632Sharti{ 468117632Sharti while (patm_nor_read(sc, IDT_NOR_STAT) & IDT_STAT_CMDBZ) 469117632Sharti ; 470117632Sharti} 471117632Shartistatic __inline void 472117632Shartipatm_cmd_exec(struct patm_softc *sc, uint32_t cmd) 473117632Sharti{ 474117632Sharti patm_cmd_wait(sc); 475117632Sharti patm_nor_write(sc, IDT_NOR_CMD, cmd); 476117632Sharti} 477117632Sharti 478117632Sharti/* Read/write SRAM at the given word address. */ 479117632Shartistatic __inline uint32_t 480117632Shartipatm_sram_read(struct patm_softc *sc, u_int addr) 481117632Sharti{ 482117632Sharti uint32_t val; 483117632Sharti 484117632Sharti patm_cmd_exec(sc, IDT_MKCMD_RSRAM(addr)); 485117632Sharti patm_cmd_wait(sc); 486117632Sharti val = patm_nor_read(sc, IDT_NOR_D0); 487117632Sharti patm_debug(sc, SRAM, "read %04x=%08x", addr, val); 488117632Sharti return (val); 489117632Sharti} 490117632Shartistatic __inline void 491117632Shartipatm_sram_write(struct patm_softc *sc, u_int addr, uint32_t val) 492117632Sharti{ 493117632Sharti patm_debug(sc, SRAM, "write %04x=%08x", addr, val); 494117632Sharti patm_cmd_wait(sc); 495117632Sharti patm_nor_write(sc, IDT_NOR_D0, val); 496117632Sharti patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 0)); 497117632Sharti} 498117632Shartistatic __inline void 499117632Shartipatm_sram_write4(struct patm_softc *sc, u_int addr, uint32_t v0, uint32_t v1, 500117632Sharti uint32_t v2, uint32_t v3) 501117632Sharti{ 502117632Sharti patm_debug(sc, SRAM, "write %04x=%08x,%08x,%08x,%08x", 503117632Sharti addr, v0, v1, v2, v3); 504117632Sharti patm_cmd_wait(sc); 505117632Sharti patm_nor_write(sc, IDT_NOR_D0, v0); 506117632Sharti patm_nor_write(sc, IDT_NOR_D1, v1); 507117632Sharti patm_nor_write(sc, IDT_NOR_D2, v2); 508117632Sharti patm_nor_write(sc, IDT_NOR_D3, v3); 509117632Sharti patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 3)); 510117632Sharti} 511117632Sharti 512117632Sharti#define LEGAL_VPI(SC, VPI) \ 513147256Sbrooks (((VPI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vpi_bits) - 1)) == 0) 514117632Sharti#define LEGAL_VCI(SC, VCI) \ 515147256Sbrooks (((VCI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vci_bits) - 1)) == 0) 516117632Sharti 517117632Shartiextern const uint32_t patm_rtables155[]; 518117632Shartiextern const uint32_t patm_rtables25[]; 519117632Shartiextern const u_int patm_rtables_size; 520117632Shartiextern const u_int patm_rtables_ntab; 521