if_patmvar.h revision 147256
1183840Sraj/*- 2183840Sraj * Copyright (c) 2003 3183840Sraj * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4183840Sraj * All rights reserved. 5183840Sraj * 6183840Sraj * Redistribution and use in source and binary forms, with or without 7183840Sraj * modification, are permitted provided that the following conditions 8183840Sraj * are met: 9183840Sraj * 1. Redistributions of source code must retain the above copyright 10183840Sraj * notice, this list of conditions and the following disclaimer. 11183840Sraj * 2. Redistributions in binary form must reproduce the above copyright 12183840Sraj * notice, this list of conditions and the following disclaimer in the 13183840Sraj * documentation and/or other materials provided with the distribution. 14183840Sraj * 15183840Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16183840Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17183840Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18183840Sraj * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19183840Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20183840Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21183840Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22183840Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23183840Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24183840Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25183840Sraj * SUCH DAMAGE. 26183840Sraj * 27183840Sraj * Author: Hartmut Brandt <harti@freebsd.org> 28183840Sraj * 29183840Sraj * $FreeBSD: head/sys/dev/patm/if_patmvar.h 147256 2005-06-10 16:49:24Z brooks $ 30183840Sraj * 31183840Sraj * Driver for IDT77252 (ABR) based cards like ProSum's. 32183840Sraj */ 33183840Sraj 34183840Sraj/* legal values are 0, 1, 2 and 8 */ 35183840Sraj#define PATM_VPI_BITS 2 36183840Sraj#define PATM_CFG_VPI IDT_CFG_VP2 37183840Sraj 38218427Smarcel/* receive status queue size */ 39183840Sraj#define PATM_RSQ_SIZE 512 40183840Sraj#define PATM_CFQ_RSQ_SIZE IDT_CFG_RXQ512 41183840Sraj 42183840Sraj/* alignment for SQ memory */ 43183840Sraj#define PATM_SQ_ALIGNMENT 8192 44209131Sraj 45209131Sraj#define PATM_PROATM_NAME_OFFSET 060 46209131Sraj#define PATM_PROATM_NAME "PROATM" 47183840Sraj#define PATM_PROATM_MAC_OFFSET 044 48183840Sraj#define PATM_IDT_MAC_OFFSET 0154 49183840Sraj 50183840Sraj/* maximum number of packets on UBR queue */ 51183840Sraj#define PATM_DLFT_MAXQ 1000 52183840Sraj 53183840Sraj/* maximum number of packets on other queues. This should depend on the 54183840Sraj * traffic contract. */ 55183840Sraj#define PATM_TX_IFQLEN 100 56183840Sraj 57183840Sraj/* 58183840Sraj * Maximum number of DMA maps we allocate. This is the minimum that can be 59183840Sraj * set larger via a sysctl. 60183840Sraj * Starting number of DMA maps. 61183840Sraj * Step for growing. 62183840Sraj */ 63183840Sraj#define PATM_CFG_TXMAPS_MAX 1024 64183840Sraj#define PATM_CFG_TXMAPS_INIT 128 65183840Sraj#define PATM_CFG_TXMAPS_STEP 128 66183840Sraj 67183840Sraj/* percents of TST slots to keep for non-CBR traffic */ 68183840Sraj#define PATM_TST_RESERVE 2 69183840Sraj 70183840Sraj/* 71183840Sraj * Structure to hold TX DMA maps 72183840Sraj */ 73183840Srajstruct patm_txmap { 74183840Sraj SLIST_ENTRY(patm_txmap) link; 75183840Sraj bus_dmamap_t map; 76183840Sraj}; 77183840Sraj 78183840Sraj/* 79183840Sraj * Receive buffers. 80183840Sraj * 81183840Sraj * We manage our own external mbufs for small receive buffers for two reasons: 82183840Sraj * the card may consume a rather large number of buffers. Mapping each buffer 83261410Sian * would consume a lot of iospace on sparc64. Also the card allows us to set 84261410Sian * a 32-bit handle for identification of the buffers. On a 64-bit system this 85261410Sian * requires us to use a mapping between buffers and handles. 86209131Sraj * 87209131Sraj * For large buffers we use mbuf clusters directly. We track these by using 88209131Sraj * an array of pointers (lbufs) to special structs and a free list of these 89183840Sraj * structs. 90183840Sraj * 91183840Sraj * For AAL0 cell we use FBQ2 and make the 1 cell long. 92183840Sraj */ 93183840Sraj/* 94183840Sraj * Define the small buffer chunk so that we have at least 16 byte free 95183840Sraj * at the end of the chunk and that there is an integral number of chunks 96183840Sraj * in a page. 97183840Sraj */ 98183840Sraj#define SMBUF_PAGE_SIZE 16384 /* 16k pages */ 99183840Sraj#define SMBUF_MAX_PAGES 64 /* maximum number of pages */ 100183840Sraj#define SMBUF_CHUNK_SIZE 256 /* 256 bytes per chunk */ 101183840Sraj#define SMBUF_CELLS 5 102183840Sraj#define SMBUF_SIZE (SMBUF_CELLS * 48) 103183840Sraj#define SMBUF_THRESHOLD 9 /* 9/16 of queue size */ 104183840Sraj#define SMBUF_NI_THRESH 3 105183840Sraj#define SMBUF_CI_THRESH 1 106183840Sraj 107183840Sraj#define VMBUF_PAGE_SIZE 16384 /* 16k pages */ 108183840Sraj#define VMBUF_MAX_PAGES 16 /* maximum number of pages */ 109183840Sraj#define VMBUF_CHUNK_SIZE 64 /* 64 bytes per chunk */ 110183840Sraj#define VMBUF_CELLS 1 111238873Shrs#define VMBUF_SIZE (VMBUF_CELLS * 48) 112238873Shrs#define VMBUF_THRESHOLD 15 /* 15/16 of size */ 113238873Shrs 114191140Sraj#define SMBUF_OFFSET (SMBUF_CHUNK_SIZE - 8 - SMBUF_SIZE) 115183840Sraj#define VMBUF_OFFSET 0 116183840Sraj 117191140Sraj#define MBUF_SHANDLE 0x00000000 118183840Sraj#define MBUF_LHANDLE 0x80000000 119183840Sraj#define MBUF_VHANDLE 0x40000000 120183840Sraj#define MBUF_HMASK 0x3fffffff 121183840Sraj 122183840Sraj/* 123183840Sraj * Large buffers 124183840Sraj * 125183840Sraj * The problem with these is the maximum count. When the card assembles 126183840Sraj * a AAL5 pdu it moves a buffer from the FBQ to the VC. This frees space 127183840Sraj * in the FBQ, put the buffer may pend on the card for an unlimited amount 128183840Sraj * of time (we don't idle connections). This means that the upper limit 129183840Sraj * on buffers on the card may be (no-of-open-vcs + FBQ_SIZE). Because 130183840Sraj * this is far too much, make this a tuneable. We could also make 131183840Sraj * this dynamic by allocating pages of several lbufs at once during run time. 132183840Sraj */ 133183840Sraj#define LMBUF_MAX (IDT_FBQ_SIZE * 2) 134183840Sraj#define LMBUF_CELLS (MCLBYTES / 48) /* 42 cells = 2048 byte */ 135183840Sraj#define LMBUF_SIZE (LMBUF_CELLS * 48) 136183840Sraj#define LMBUF_THRESHOLD 9 /* 9/16 of queue size */ 137183840Sraj#define LMBUF_OFFSET (MCLBYTES - LMBUF_SIZE) 138183840Sraj#define LMBUF_NI_THRESH 3 139183840Sraj#define LMBUF_CI_THRESH 1 140183840Sraj 141183840Sraj#define LMBUF_HANDLE 0x80000000 142183840Sraj 143183840Srajstruct lmbuf { 144183840Sraj SLIST_ENTRY(lmbuf) link; /* free list link */ 145183840Sraj bus_dmamap_t map; /* DMA map */ 146183840Sraj u_int handle; /* this is the handle index */ 147183840Sraj struct mbuf *m; /* the current mbuf */ 148183840Sraj bus_addr_t phy; /* phy addr */ 149209131Sraj}; 150183840Sraj 151183840Sraj#define PATM_CID(SC, VPI, VCI) \ 152218427Smarcel (((VPI) << IFP2IFATM((SC)->ifp)->mib.vci_bits) | (VCI)) 153183840Sraj 154218427Smarcel/* 155218427Smarcel * Internal driver statistics 156183840Sraj */ 157218427Smarcelstruct patm_stats { 158183840Sraj uint32_t raw_cells; 159218427Smarcel uint32_t raw_no_vcc; 160218427Smarcel uint32_t raw_no_buf; 161218427Smarcel uint32_t tx_qfull; 162218427Smarcel uint32_t tx_out_of_tbds; 163183840Sraj uint32_t tx_out_of_maps; 164218427Smarcel uint32_t tx_load_err; 165183840Sraj}; 166218427Smarcel 167218427Smarcel/* 168218427Smarcel * These are allocated as DMA able memory 169218427Smarcel */ 170183840Srajstruct patm_scd { 171183840Sraj struct idt_tbd scq[IDT_SCQ_SIZE]; 172218427Smarcel LIST_ENTRY(patm_scd) link; /* all active SCDs */ 173183840Sraj uint32_t sram; /* SRAM address */ 174218427Smarcel bus_addr_t phy; /* physical address */ 175218427Smarcel bus_dmamap_t map; /* DMA map */ 176218427Smarcel u_int tail; /* next free entry for host */ 177218427Smarcel int space; /* number of free entries (minus one) */ 178183840Sraj u_int slots; /* CBR slots allocated */ 179218427Smarcel uint8_t tag; /* next tag for TSI */ 180183840Sraj uint8_t last_tag; /* last tag checked in interrupt */ 181218427Smarcel uint8_t num_on_card; /* number of PDUs on tx queue */ 182218427Smarcel uint8_t lacr; /* LogACR value */ 183218427Smarcel uint8_t init_er; /* LogER value */ 184183840Sraj struct ifqueue q; /* queue of packets */ 185183840Sraj struct mbuf *on_card[IDT_TSQE_TAG_SPACE]; 186183840Sraj}; 187183840Sraj 188183840Sraj/* 189183840Sraj * Per-VCC data 190183840Sraj */ 191183840Srajstruct patm_vcc { 192183840Sraj struct atmio_vcc vcc; /* caller's parameters */ 193183840Sraj void *rxhand; /* NATM handle */ 194183840Sraj u_int vflags; /* open and other flags */ 195183840Sraj uint32_t ipackets; /* packets received */ 196183840Sraj uint32_t opackets; /* packets sent */ 197183840Sraj uint64_t ibytes; /* bytes received */ 198183840Sraj uint64_t obytes; /* bytes sent */ 199183840Sraj 200183840Sraj struct mbuf *chain; /* currently received chain */ 201183840Sraj struct mbuf *last; /* end of chain */ 202183840Sraj u_int cid; /* index */ 203183840Sraj u_int cps; /* last ABR cps */ 204183840Sraj struct patm_scd *scd; 205183840Sraj}; 206183840Sraj#define PATM_VCC_TX_OPEN 0x0001 207183840Sraj#define PATM_VCC_RX_OPEN 0x0002 208183840Sraj#define PATM_VCC_TX_CLOSING 0x0004 209183840Sraj#define PATM_VCC_RX_CLOSING 0x0008 210183840Sraj#define PATM_VCC_OPEN 0x000f /* all the above */ 211183840Sraj 212183840Sraj#define PATM_RAW_CELL 0x0000 /* 53 byte cells */ 213183840Sraj#define PATM_RAW_NOHEC 0x0100 /* 52 byte cells */ 214183840Sraj#define PATM_RAW_CS 0x0200 /* 64 byte cell stream */ 215183840Sraj#define PATM_RAW_FORMAT 0x0300 /* format mask */ 216183840Sraj 217183840Sraj/* 218183840Sraj * Per adapter data 219183840Sraj */ 220183840Srajstruct patm_softc { 221183840Sraj struct ifnet *ifp; /* common ATM stuff */ 222183840Sraj struct mtx mtx; /* lock */ 223183840Sraj struct ifmedia media; /* media */ 224183840Sraj device_t dev; /* device */ 225183840Sraj struct resource * memres; /* memory resource */ 226183840Sraj bus_space_handle_t memh; /* handle */ 227183840Sraj bus_space_tag_t memt; /* ... and tag */ 228183840Sraj int irqid; /* resource id */ 229183840Sraj struct resource * irqres; /* resource */ 230183840Sraj void * ih; /* interrupt handle */ 231183840Sraj struct utopia utopia; /* phy state */ 232183840Sraj const struct idt_mmap *mmap; /* SRAM memory map */ 233183840Sraj u_int flags; /* see below */ 234183840Sraj u_int revision; /* chip revision */ 235183840Sraj 236183840Sraj /* DMAable status queue memory */ 237183840Sraj size_t sq_size; /* size of memory area */ 238183840Sraj bus_dma_tag_t sq_tag; /* DMA tag */ 239183840Sraj bus_dmamap_t sq_map; /* map */ 240183840Sraj 241183840Sraj bus_addr_t tsq_phy; /* phys addr. */ 242183840Sraj struct idt_tsqe *tsq; /* transmit status queue */ 243183840Sraj struct idt_tsqe *tsq_next; /* last processed entry */ 244183840Sraj struct idt_rsqe *rsq; /* receive status queue */ 245183840Sraj bus_addr_t rsq_phy; /* phys addr. */ 246183840Sraj u_int rsq_last; /* last processed entry */ 247183840Sraj struct idt_rawhnd *rawhnd; /* raw cell handle */ 248183840Sraj bus_addr_t rawhnd_phy; /* phys addr. */ 249183840Sraj 250183840Sraj /* TST */ 251183840Sraj u_int tst_state; /* active TST and others */ 252183840Sraj u_int tst_jump[2]; /* address of the jumps */ 253183840Sraj u_int tst_base[2]; /* base address of TST */ 254183840Sraj u_int *tst_soft; /* soft TST */ 255183840Sraj struct mtx tst_lock; 256183840Sraj struct callout tst_callout; 257183840Sraj u_int tst_free; /* free slots */ 258183840Sraj u_int tst_reserve; /* non-CBR reserve */ 259183840Sraj u_int bwrem; /* remaining bandwith */ 260183840Sraj 261183840Sraj /* sysctl support */ 262183840Sraj struct sysctl_ctx_list sysctl_ctx; 263183840Sraj struct sysctl_oid *sysctl_tree; 264183840Sraj 265183840Sraj /* EEPROM contents */ 266183840Sraj uint8_t eeprom[256]; 267183840Sraj 268183840Sraj /* large buffer mapping */ 269183840Sraj bus_dma_tag_t lbuf_tag; /* DMA tag */ 270183840Sraj u_int lbuf_max; /* maximum number */ 271183840Sraj struct lmbuf *lbufs; /* array for indexing */ 272183840Sraj SLIST_HEAD(,lmbuf) lbuf_free_list; /* free list */ 273183840Sraj 274183840Sraj /* small buffer handling */ 275183840Sraj bus_dma_tag_t sbuf_tag; /* DMA tag */ 276183840Sraj struct mbpool *sbuf_pool; /* pool */ 277183840Sraj struct mbpool *vbuf_pool; /* pool */ 278183840Sraj 279183840Sraj /* raw cell queue */ 280183840Sraj struct lmbuf *rawh; /* current header buf */ 281183840Sraj u_int rawi; /* cell index into buffer */ 282183840Sraj 283183840Sraj /* statistics */ 284183840Sraj struct patm_stats stats; /* statistics */ 285183840Sraj 286183840Sraj /* Vccs */ 287183840Sraj struct patm_vcc **vccs; /* channel pointer array */ 288183840Sraj u_int vccs_open; /* number of open channels */ 289183840Sraj uma_zone_t vcc_zone; 290183840Sraj struct cv vcc_cv; 291183840Sraj 292183840Sraj /* SCDs */ 293183840Sraj uint32_t scd_free; /* SRAM of first free SCD */ 294183840Sraj bus_dma_tag_t scd_tag; 295183840Sraj struct patm_scd *scd0; 296183840Sraj LIST_HEAD(, patm_scd) scd_list; /* list of all active SCDs */ 297183840Sraj 298183840Sraj /* Tx */ 299183840Sraj bus_dma_tag_t tx_tag; /* for transmission */ 300183840Sraj SLIST_HEAD(, patm_txmap) tx_maps_free; /* free maps */ 301183840Sraj u_int tx_nmaps; /* allocated maps */ 302183840Sraj u_int tx_maxmaps; /* maximum number */ 303183840Sraj struct uma_zone *tx_mapzone; /* zone for maps */ 304183840Sraj 305183840Sraj#ifdef PATM_DEBUG 306183840Sraj /* debugging */ 307183840Sraj u_int debug; 308183840Sraj#endif 309183840Sraj}; 310183840Sraj 311183840Sraj/* flags */ 312183840Sraj#define PATM_25M 0x0001 /* 25MBit card */ 313183840Sraj#define PATM_SBUFW 0x0002 /* warned */ 314#define PATM_VBUFW 0x0004 /* warned */ 315#define PATM_UNASS 0x0010 /* unassigned cells */ 316 317#define PATM_CLR 0x0007 /* clear on stop */ 318 319/* tst - uses unused fields */ 320#define TST_BOTH 0x03000000 321#define TST_CH0 0x01000000 322#define TST_CH1 0x02000000 323/* tst_state */ 324#define TST_ACT1 0x0001 /* active TST */ 325#define TST_PENDING 0x0002 /* need update */ 326#define TST_WAIT 0x0004 /* wait fo jump */ 327 328#define patm_printf(SC, ...) if_printf((SC)->ifp, __VA_ARGS__); 329 330#ifdef PATM_DEBUG 331/* 332 * Debugging 333 */ 334enum { 335 DBG_ATTACH = 0x0001, /* attaching the card */ 336 DBG_INTR = 0x0002, /* interrupts */ 337 DBG_REG = 0x0004, /* register access */ 338 DBG_SRAM = 0x0008, /* SRAM access */ 339 DBG_PHY = 0x0010, /* PHY access */ 340 DBG_IOCTL = 0x0020, /* ioctl */ 341 DBG_FREEQ = 0x0040, /* free bufq supply */ 342 DBG_VCC = 0x0080, /* open/close */ 343 DBG_TX = 0x0100, /* transmission */ 344 DBG_TST = 0x0200, /* TST */ 345 346 DBG_ALL = 0xffff 347}; 348 349#define patm_debug(SC, FLAG, ...) do { \ 350 if((SC)->debug & DBG_##FLAG) { \ 351 if_printf((SC)->ifp, "%s: ", __func__); \ 352 printf(__VA_ARGS__); \ 353 printf("\n"); \ 354 } \ 355 } while (0) 356#else 357 358#define patm_debug(SC, FLAG, ...) do { } while (0) 359 360#endif 361 362/* start output */ 363void patm_start(struct ifnet *); 364 365/* ioctl handler */ 366int patm_ioctl(struct ifnet *, u_long, caddr_t); 367 368/* start the interface */ 369void patm_init(void *); 370 371/* start the interface with the lock held */ 372void patm_initialize(struct patm_softc *); 373 374/* stop the interface */ 375void patm_stop(struct patm_softc *); 376 377/* software reset of interface */ 378void patm_reset(struct patm_softc *); 379 380/* interrupt handler */ 381void patm_intr(void *); 382 383/* check RSQ */ 384void patm_intr_rsq(struct patm_softc *sc); 385 386/* enable the vcc */ 387void patm_load_vc(struct patm_softc *sc, struct patm_vcc *vcc, int reload); 388 389/* close the given vcc for transmission */ 390void patm_tx_vcc_close(struct patm_softc *, struct patm_vcc *); 391 392/* close the given vcc for receive */ 393void patm_rx_vcc_close(struct patm_softc *, struct patm_vcc *); 394 395/* transmission side finally closed */ 396void patm_tx_vcc_closed(struct patm_softc *, struct patm_vcc *); 397 398/* receive side finally closed */ 399void patm_rx_vcc_closed(struct patm_softc *, struct patm_vcc *); 400 401/* vcc closed */ 402void patm_vcc_closed(struct patm_softc *, struct patm_vcc *); 403 404/* check if we can open this one */ 405int patm_tx_vcc_can_open(struct patm_softc *, struct patm_vcc *); 406 407/* check if we can open this one */ 408int patm_rx_vcc_can_open(struct patm_softc *, struct patm_vcc *); 409 410/* open it */ 411void patm_tx_vcc_open(struct patm_softc *, struct patm_vcc *); 412 413/* open it */ 414void patm_rx_vcc_open(struct patm_softc *, struct patm_vcc *); 415 416/* receive packet */ 417void patm_rx(struct patm_softc *, struct idt_rsqe *); 418 419/* packet transmitted */ 420void patm_tx(struct patm_softc *, u_int, u_int); 421 422/* VBR connection went idle */ 423void patm_tx_idle(struct patm_softc *, u_int); 424 425/* allocate an SCQ */ 426struct patm_scd *patm_scd_alloc(struct patm_softc *); 427 428/* free an SCD */ 429void patm_scd_free(struct patm_softc *sc, struct patm_scd *scd); 430 431/* setup SCD in SRAM */ 432void patm_scd_setup(struct patm_softc *sc, struct patm_scd *scd); 433 434/* setup TCT entry in SRAM */ 435void patm_tct_setup(struct patm_softc *, struct patm_scd *, struct patm_vcc *); 436 437/* free a large buffer */ 438void patm_lbuf_free(struct patm_softc *sc, struct lmbuf *b); 439 440/* Process the raw cell at the given address */ 441void patm_rx_raw(struct patm_softc *sc, u_char *cell); 442 443/* load a one segment DMA map */ 444void patm_load_callback(void *, bus_dma_segment_t *, int, int); 445 446/* network operation register access */ 447static __inline uint32_t 448patm_nor_read(struct patm_softc *sc, u_int reg) 449{ 450 uint32_t val; 451 452 val = bus_space_read_4(sc->memt, sc->memh, reg); 453 patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val); 454 return (val); 455} 456static __inline void 457patm_nor_write(struct patm_softc *sc, u_int reg, uint32_t val) 458{ 459 460 patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val); 461 bus_space_write_4(sc->memt, sc->memh, reg, val); 462} 463 464/* Execute command */ 465static __inline void 466patm_cmd_wait(struct patm_softc *sc) 467{ 468 while (patm_nor_read(sc, IDT_NOR_STAT) & IDT_STAT_CMDBZ) 469 ; 470} 471static __inline void 472patm_cmd_exec(struct patm_softc *sc, uint32_t cmd) 473{ 474 patm_cmd_wait(sc); 475 patm_nor_write(sc, IDT_NOR_CMD, cmd); 476} 477 478/* Read/write SRAM at the given word address. */ 479static __inline uint32_t 480patm_sram_read(struct patm_softc *sc, u_int addr) 481{ 482 uint32_t val; 483 484 patm_cmd_exec(sc, IDT_MKCMD_RSRAM(addr)); 485 patm_cmd_wait(sc); 486 val = patm_nor_read(sc, IDT_NOR_D0); 487 patm_debug(sc, SRAM, "read %04x=%08x", addr, val); 488 return (val); 489} 490static __inline void 491patm_sram_write(struct patm_softc *sc, u_int addr, uint32_t val) 492{ 493 patm_debug(sc, SRAM, "write %04x=%08x", addr, val); 494 patm_cmd_wait(sc); 495 patm_nor_write(sc, IDT_NOR_D0, val); 496 patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 0)); 497} 498static __inline void 499patm_sram_write4(struct patm_softc *sc, u_int addr, uint32_t v0, uint32_t v1, 500 uint32_t v2, uint32_t v3) 501{ 502 patm_debug(sc, SRAM, "write %04x=%08x,%08x,%08x,%08x", 503 addr, v0, v1, v2, v3); 504 patm_cmd_wait(sc); 505 patm_nor_write(sc, IDT_NOR_D0, v0); 506 patm_nor_write(sc, IDT_NOR_D1, v1); 507 patm_nor_write(sc, IDT_NOR_D2, v2); 508 patm_nor_write(sc, IDT_NOR_D3, v3); 509 patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 3)); 510} 511 512#define LEGAL_VPI(SC, VPI) \ 513 (((VPI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vpi_bits) - 1)) == 0) 514#define LEGAL_VCI(SC, VCI) \ 515 (((VCI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vci_bits) - 1)) == 0) 516 517extern const uint32_t patm_rtables155[]; 518extern const uint32_t patm_rtables25[]; 519extern const u_int patm_rtables_size; 520extern const u_int patm_rtables_ntab; 521