if_hatmvar.h revision 118169
1/* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Author: Hartmut Brandt <harti@freebsd.org> 28 * 29 * $FreeBSD: head/sys/dev/hatm/if_hatmvar.h 118169 2003-07-29 14:05:45Z harti $ 30 * 31 * Fore HE driver for NATM 32 */ 33 34/* 35 * Debug statistics of the HE driver 36 */ 37struct istats { 38 uint32_t tdprq_full; 39 uint32_t hbuf_error; 40 uint32_t crc_error; 41 uint32_t len_error; 42 uint32_t flow_closed; 43 uint32_t flow_drop; 44 uint32_t tpd_no_mem; 45 uint32_t rx_seg; 46 uint32_t empty_hbuf; 47 uint32_t short_aal5; 48 uint32_t badlen_aal5; 49 uint32_t bug_bad_isw; 50 uint32_t bug_no_irq_upd; 51 uint32_t itype_tbrq; 52 uint32_t itype_tpd; 53 uint32_t itype_rbps; 54 uint32_t itype_rbpl; 55 uint32_t itype_rbrq; 56 uint32_t itype_rbrqt; 57 uint32_t itype_unknown; 58 uint32_t itype_phys; 59 uint32_t itype_err; 60 uint32_t defrag; 61 uint32_t mcc; 62 uint32_t oec; 63 uint32_t dcc; 64 uint32_t cec; 65}; 66 67/* Card memory layout parameters */ 68#define HE_CONFIG_MEM_LAYOUT { \ 69 { /* 155 */ \ 70 20, /* cells_per_row */ \ 71 1024, /* bytes_per_row */ \ 72 512, /* r0_numrows */ \ 73 1018, /* tx_numrows */ \ 74 512, /* r1_numrows */ \ 75 6, /* r0_startrow */ \ 76 2 /* cells_per_lbuf */ \ 77 }, { /* 622 */ \ 78 40, /* cells_per_row */ \ 79 2048, /* bytes_per_row */ \ 80 256, /* r0_numrows */ \ 81 512, /* tx_numrows */ \ 82 256, /* r1_numrows */ \ 83 0, /* r0_startrow */ \ 84 4 /* cells_per_lbuf */ \ 85 } \ 86} 87 88/*********************************************************************/ 89struct hatm_softc; 90 91/* 92 * A chunk of DMA-able memory 93 */ 94struct dmamem { 95 u_int size; /* in bytes */ 96 u_int align; /* alignement */ 97 bus_dma_tag_t tag; /* DMA tag */ 98 void *base; /* the memory */ 99 bus_addr_t paddr; /* physical address */ 100 bus_dmamap_t map; /* the MAP */ 101}; 102 103/* 104 * RBP (Receive Buffer Pool) queue entry and queue. 105 */ 106struct herbp { 107 u_int size; /* RBP number of entries (power of two) */ 108 u_int thresh; /* interrupt treshold */ 109 uint32_t bsize; /* buffer size in bytes */ 110 u_int offset; /* free space at start for small bufs */ 111 uint32_t mask; /* mask for index */ 112 struct dmamem mem; /* the queue area */ 113 struct he_rbpen *rbp; 114 uint32_t head, tail; /* head and tail */ 115}; 116 117/* 118 * RBRQ (Receive Buffer Return Queue) entry and queue. 119 */ 120struct herbrq { 121 u_int size; /* number of entries */ 122 u_int thresh; /* interrupt threshold */ 123 u_int tout; /* timeout value */ 124 u_int pcnt; /* packet count threshold */ 125 struct dmamem mem; /* memory */ 126 struct he_rbrqen *rbrq; 127 uint32_t head; /* driver end */ 128}; 129 130/* 131 * TPDRQ (Transmit Packet Descriptor Ready Queue) entry and queue 132 */ 133struct hetpdrq { 134 u_int size; /* number of entries */ 135 struct dmamem mem; /* memory */ 136 struct he_tpdrqen *tpdrq; 137 u_int head; /* head (copy of adapter) */ 138 u_int tail; /* written back to adapter */ 139}; 140 141/* 142 * TBRQ (Transmit Buffer Return Queue) entry and queue 143 */ 144struct hetbrq { 145 u_int size; /* number of entries */ 146 u_int thresh; /* interrupt threshold */ 147 struct dmamem mem; /* memory */ 148 struct he_tbrqen *tbrq; 149 u_int head; /* adapter end */ 150}; 151 152/*==================================================================*/ 153 154/* 155 * TPDs are 32 byte and must be aligned on 64 byte boundaries. That means, 156 * that half of the space is free. We use this space to plug in a link for 157 * the list of free TPDs. Note, that the m_act member of the mbufs contain 158 * a pointer to the dmamap. 159 * 160 * The maximum number of TDPs is the size of the common transmit packet 161 * descriptor ready queue plus the sizes of the transmit buffer return queues 162 * (currently only queue 0). We allocate and map these TPD when initializing 163 * the card. We also allocate on DMA map for each TPD. Only the map in the 164 * last TPD of a packets is used when a packet is transmitted. 165 * This is signalled by having the mbuf member of this TPD non-zero and 166 * pointing to the mbuf. 167 */ 168#define HE_TPD_SIZE 64 169struct tpd { 170 struct he_tpd tpd; /* at beginning */ 171 SLIST_ENTRY(tpd) link; /* free cid list link */ 172 struct mbuf *mbuf; /* the buf chain */ 173 bus_dmamap_t map; /* map */ 174 uint32_t cid; /* CID */ 175 uint16_t no; /* number of this tpd */ 176}; 177SLIST_HEAD(tpd_list, tpd); 178 179#define TPD_SET_USED(SC, I) do { \ 180 (SC)->tpd_used[(I) / 8] |= (1 << ((I) % 8)); \ 181 } while (0) 182 183#define TPD_CLR_USED(SC, I) do { \ 184 (SC)->tpd_used[(I) / 8] &= ~(1 << ((I) % 8)); \ 185 } while (0) 186 187#define TPD_TST_USED(SC, I) ((SC)->tpd_used[(I) / 8] & (1 << ((I) % 8))) 188 189#define TPD_ADDR(SC, I) ((struct tpd *)((char *)sc->tpds.base + \ 190 (I) * HE_TPD_SIZE)) 191 192/*==================================================================*/ 193 194/* 195 * External MBUFs. The card needs a lot of mbufs in the pools for high 196 * performance. The problem with using mbufs directly is that we would need 197 * a dmamap for each of the mbufs. This can exhaust iommu space on the sparc 198 * and it eats also a lot of processing time. So we use external mbufs 199 * for the small buffers and clusters for the large buffers. 200 * For receive group 0 we use 5 ATM cells, for group 1 one (52 byte) ATM 201 * cell. The mbuf storage is allocated pagewise and one dmamap is used per 202 * page. 203 * 204 * The handle we give to the card for the small buffers is a word combined 205 * of the page number and the number of the chunk in the page. This restricts 206 * the number of chunks per page to 256 (8 bit) and the number of pages to 207 * 65536 (16 bits). 208 * 209 * A chunk may be in one of three states: free, on the card and floating around 210 * in the system. If it is free, it is on one of the two free lists and 211 * start with a struct mbufx_free. Each page has a bitmap that tracks where 212 * its chunks are. 213 * 214 * For large buffers we use mbuf clusters. Here we have two problems: we need 215 * to track the buffers on the card (in the case we want to stop it) and 216 * we need to map the 64bit mbuf address to a 26bit handle for 64-bit machines. 217 * The card uses the buffers in the order we give it to the card. Therefor 218 * we can use a private array holding pointers to the mbufs as a circular 219 * queue for both tasks. This is done with the lbufs member of softc. The 220 * handle for these buffer is the lbufs index ored with a flag. 221 */ 222#define MBUF0_SIZE (5 * 48) /* 240 */ 223#define MBUF1_SIZE (52) 224 225#define MBUF0_CHUNK 256 /* 16 free bytes */ 226#define MBUF1_CHUNK 96 /* 44 free bytes */ 227#ifdef XXX 228#define MBUF0_OFFSET (MBUF0_CHUNK - sizeof(struct mbuf_chunk_hdr) \ 229 - MBUF0_SIZE) 230#else 231#define MBUF0_OFFSET 0 232#endif 233#define MBUF1_OFFSET (MBUF1_CHUNK - sizeof(struct mbuf_chunk_hdr) \ 234 - MBUF1_SIZE) 235#define MBUFL_OFFSET 16 /* two pointers for HARP */ 236 237#define MBUF_ALLOC_SIZE (PAGE_SIZE) 238 239/* each allocated page has one of these structures at its very end. */ 240struct mbuf_page_hdr { 241 uint8_t card[32]; /* bitmap for on-card */ 242 uint8_t used[32]; /* bitmap for used but not on-card */ 243 uint16_t nchunks; /* chunks on this page */ 244 bus_dmamap_t map; /* the DMA MAP */ 245 uint32_t phys; /* physical base address */ 246 uint32_t hdroff; /* chunk header offset */ 247 uint32_t chunksize; /* chunk size */ 248}; 249struct mbuf_page { 250 char storage[MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)]; 251 struct mbuf_page_hdr hdr; 252}; 253 254/* numbers per page */ 255#define MBUF0_PER_PAGE ((MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)) / \ 256 MBUF0_CHUNK) 257#define MBUF1_PER_PAGE ((MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)) / \ 258 MBUF1_CHUNK) 259 260#define MBUF_CLR_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] &= ~(1 << ((BIT) % 8))) 261#define MBUF_SET_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] |= (1 << ((BIT) % 8))) 262#define MBUF_TST_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] & (1 << ((BIT) % 8))) 263 264#define MBUF_MAKE_HANDLE(PAGENO, CHUNKNO) \ 265 (((PAGENO) << 10) | (CHUNKNO)) 266 267#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do { \ 268 (CHUNKNO) = (HANDLE) & 0x3ff; \ 269 (PAGENO) = ((HANDLE) >> 10) & 0x3ff; \ 270 } while (0) 271 272#define MBUF_LARGE_FLAG (1 << 20) 273 274/* chunks have the following structure at the end */ 275struct mbuf_chunk_hdr { 276 struct mbuf *mbuf; 277 uint16_t pageno; 278 uint16_t chunkno; 279}; 280 281#define MBUFX_STORAGE_SIZE(X) (MBUF##X##_CHUNK \ 282 - sizeof(struct mbuf_chunk_hdr)) 283 284struct mbuf0_chunk { 285 char storage[MBUFX_STORAGE_SIZE(0)]; 286 struct mbuf_chunk_hdr hdr; 287}; 288 289struct mbuf1_chunk { 290 char storage[MBUFX_STORAGE_SIZE(1)]; 291 struct mbuf_chunk_hdr hdr; 292}; 293 294struct mbufx_free { 295 SLIST_ENTRY(mbufx_free) link; 296}; 297SLIST_HEAD(mbufx_free_list, mbufx_free); 298 299/*==================================================================*/ 300 301/* 302 * Interrupt queue 303 */ 304struct heirq { 305 u_int size; /* number of entries */ 306 u_int thresh; /* re-interrupt threshold */ 307 u_int line; /* interrupt line to use */ 308 struct dmamem mem; /* interrupt queues */ 309 uint32_t * irq; /* interrupt queue */ 310 uint32_t head; /* head index */ 311 uint32_t * tailp; /* pointer to tail */ 312 struct hatm_softc *sc; /* back pointer */ 313 u_int group; /* interrupt group */ 314}; 315 316/* 317 * This structure describes all information for a VCC open on the card. 318 * The array of these structures is indexed by the compressed connection ID 319 * (CID). 320 */ 321struct hevcc { 322 u_int vflags; /* private flags */ 323 void * rxhand; /* NATM protocol block */ 324 u_int rc; /* rate control group for CBR */ 325 struct mbuf * chain; /* partial received PDU */ 326 struct mbuf * last; /* last mbuf in chain */ 327 328 /* from the OPEN_VCC ioctl */ 329 struct atmio_vcc param; /* traffic parameters */ 330 331 uint32_t ibytes; 332 uint32_t ipackets; 333 uint32_t obytes; 334 uint32_t opackets; 335 u_int ntpds; /* number of active TPDs */ 336}; 337#define HE_VCC_OPEN 0x000f0000 338#define HE_VCC_RX_OPEN 0x00010000 339#define HE_VCC_RX_CLOSING 0x00020000 340#define HE_VCC_TX_OPEN 0x00040000 341#define HE_VCC_TX_CLOSING 0x00080000 342#define HE_VCC_FLOW_CTRL 0x00100000 343#define HE_VCC_ASYNC 0x00200000 344 345/* 346 * CBR rate groups 347 */ 348struct herg { 349 u_int refcnt; /* how many connections reference this group */ 350 u_int rate; /* the value */ 351}; 352 353/* 354 * Softc 355 */ 356struct hatm_softc { 357 struct ifatm ifatm; /* common ATM stuff */ 358 struct mtx mtx; /* lock */ 359 struct ifmedia media; /* media */ 360 device_t dev; /* device */ 361 int memid; /* resoure id for memory */ 362 struct resource * memres; /* memory resource */ 363 bus_space_handle_t memh; /* handle */ 364 bus_space_tag_t memt; /* ... and tag */ 365 bus_dma_tag_t parent_tag; /* global restriction */ 366 struct cv vcc_cv; /* condition variable */ 367 int irqid; /* resource id */ 368 struct resource * irqres; /* resource */ 369 void * ih; /* interrupt handle */ 370 struct utopia utopia; /* utopia state */ 371 372 /* rest has to be reset by stop */ 373 int he622; /* this is a HE622 */ 374 int pci64; /* 64bit bus */ 375 char prod_id[HE_EEPROM_PROD_ID_LEN + 1]; 376 char rev[HE_EEPROM_REV_LEN + 1]; 377 struct heirq irq_0; /* interrupt queues 0 */ 378 379 /* generic network controller state */ 380 u_int cells_per_row; 381 u_int bytes_per_row; 382 u_int r0_numrows; 383 u_int tx_numrows; 384 u_int r1_numrows; 385 u_int r0_startrow; 386 u_int tx_startrow; 387 u_int r1_startrow; 388 u_int cells_per_lbuf; 389 u_int r0_numbuffs; 390 u_int r1_numbuffs; 391 u_int tx_numbuffs; 392 393 /* HSP */ 394 struct he_hsp *hsp; 395 struct dmamem hsp_mem; 396 397 /*** TX ***/ 398 struct hetbrq tbrq; /* TBRQ 0 */ 399 struct hetpdrq tpdrq; /* TPDRQ */ 400 struct tpd_list tpd_free; /* Free TPDs */ 401 u_int tpd_nfree; /* number of free TPDs */ 402 u_int tpd_total; /* total TPDs */ 403 uint8_t *tpd_used; /* bitmap of used TPDs */ 404 struct dmamem tpds; /* TPD memory */ 405 bus_dma_tag_t tx_tag; /* DMA tag for all tx mbufs */ 406 407 /*** RX ***/ 408 /* receive/transmit groups */ 409 struct herbp rbp_s0; /* RBPS0 */ 410 struct herbp rbp_l0; /* RBPL0 */ 411 struct herbp rbp_s1; /* RBPS1 */ 412 struct herbrq rbrq_0; /* RBRQ0 */ 413 struct herbrq rbrq_1; /* RBRQ1 */ 414 415 /* list of external mbuf storage */ 416 bus_dma_tag_t mbuf_tag; 417 struct mbuf_page **mbuf_pages; 418 u_int mbuf_npages; 419 struct mtx mbuf0_mtx; 420 struct mbufx_free_list mbuf0_list; 421 struct mtx mbuf1_mtx; 422 struct mbufx_free_list mbuf1_list; 423 424 /* mbuf cluster tracking and mapping for group 0 */ 425 struct mbuf **lbufs; /* mbufs */ 426 bus_dmamap_t *rmaps; /* DMA maps */ 427 u_int lbufs_size; 428 u_int lbufs_next; 429 430 /* VCCs */ 431 struct hevcc *vccs[HE_MAX_VCCS]; 432 u_int cbr_bw; /* BW allocated to CBR */ 433 u_int max_tpd; /* per VCC */ 434 u_int open_vccs; 435 uma_zone_t vcc_zone; 436 437 /* rate groups */ 438 struct herg rate_ctrl[HE_REGN_CS_STPER]; 439 440 /* memory offsets */ 441 u_int tsrb, tsrc, tsrd; 442 u_int rsrb; 443 444 struct cv cv_rcclose; /* condition variable */ 445 uint32_t rate_grid[16][16]; /* our copy */ 446 447 /* sysctl support */ 448 struct sysctl_ctx_list sysctl_ctx; 449 struct sysctl_oid *sysctl_tree; 450 451 /* internal statistics */ 452 struct istats istats; 453 454#ifdef HATM_DEBUG 455 /* debugging */ 456 u_int debug; 457#endif 458}; 459 460#define READ4(SC,OFF) bus_space_read_4(SC->memt, SC->memh, (OFF)) 461#define READ2(SC,OFF) bus_space_read_2(SC->memt, SC->memh, (OFF)) 462#define READ1(SC,OFF) bus_space_read_1(SC->memt, SC->memh, (OFF)) 463 464#define WRITE4(SC,OFF,VAL) bus_space_write_4(SC->memt, SC->memh, (OFF), (VAL)) 465#define WRITE2(SC,OFF,VAL) bus_space_write_2(SC->memt, SC->memh, (OFF), (VAL)) 466#define WRITE1(SC,OFF,VAL) bus_space_write_1(SC->memt, SC->memh, (OFF), (VAL)) 467 468#define BARRIER_R(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \ 469 BUS_SPACE_BARRIER_READ) 470#define BARRIER_W(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \ 471 BUS_SPACE_BARRIER_WRITE) 472#define BARRIER_RW(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \ 473 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) 474 475#define READ_SUNI(SC,OFF) READ4(SC, HE_REGO_SUNI + 4 * (OFF)) 476#define WRITE_SUNI(SC,OFF,VAL) WRITE4(SC, HE_REGO_SUNI + 4 * (OFF), (VAL)) 477 478#define READ_LB4(SC,OFF) \ 479 ({ \ 480 WRITE4(SC, HE_REGO_LB_MEM_ADDR, (OFF)); \ 481 WRITE4(SC, HE_REGO_LB_MEM_ACCESS, \ 482 (HE_REGM_LB_MEM_HNDSHK | HE_REGM_LB_MEM_READ)); \ 483 while((READ4(SC, HE_REGO_LB_MEM_ACCESS) & HE_REGM_LB_MEM_HNDSHK))\ 484 ; \ 485 READ4(SC, HE_REGO_LB_MEM_DATA); \ 486 }) 487#define WRITE_LB4(SC,OFF,VAL) \ 488 do { \ 489 WRITE4(SC, HE_REGO_LB_MEM_ADDR, (OFF)); \ 490 WRITE4(SC, HE_REGO_LB_MEM_DATA, (VAL)); \ 491 WRITE4(SC, HE_REGO_LB_MEM_ACCESS, \ 492 (HE_REGM_LB_MEM_HNDSHK | HE_REGM_LB_MEM_WRITE)); \ 493 while((READ4(SC, HE_REGO_LB_MEM_ACCESS) & HE_REGM_LB_MEM_HNDSHK))\ 494 ; \ 495 } while(0) 496 497#define WRITE_MEM4(SC,OFF,VAL,SPACE) \ 498 do { \ 499 WRITE4(SC, HE_REGO_CON_DAT, (VAL)); \ 500 WRITE4(SC, HE_REGO_CON_CTL, \ 501 (SPACE | HE_REGM_CON_WE | HE_REGM_CON_STATUS | (OFF))); \ 502 while((READ4(SC, HE_REGO_CON_CTL) & HE_REGM_CON_STATUS) != 0) \ 503 ; \ 504 } while(0) 505 506#define READ_MEM4(SC,OFF,SPACE) \ 507 ({ \ 508 WRITE4(SC, HE_REGO_CON_CTL, \ 509 (SPACE | HE_REGM_CON_STATUS | (OFF))); \ 510 while((READ4(SC, HE_REGO_CON_CTL) & HE_REGM_CON_STATUS) != 0) \ 511 ; \ 512 READ4(SC, HE_REGO_CON_DAT); \ 513 }) 514 515#define WRITE_TCM4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_TCM) 516#define WRITE_RCM4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_RCM) 517#define WRITE_MBOX4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_MBOX) 518 519#define READ_TCM4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_TCM) 520#define READ_RCM4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_RCM) 521#define READ_MBOX4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_MBOX) 522 523#define WRITE_TCM(SC,OFF,BYTES,VAL) \ 524 WRITE_MEM4(SC,(OFF) | ((~(BYTES) & 0xf) << HE_REGS_CON_DIS), \ 525 (VAL), HE_REGM_CON_TCM) 526#define WRITE_RCM(SC,OFF,BYTES,VAL) \ 527 WRITE_MEM4(SC,(OFF) | ((~(BYTES) & 0xf) << HE_REGS_CON_DIS), \ 528 (VAL), HE_REGM_CON_RCM) 529 530#define READ_TSR(SC,CID,NR) \ 531 ({ \ 532 uint32_t _v; \ 533 if((NR) <= 7) { \ 534 _v = READ_TCM4(SC, HE_REGO_TSRA(0,CID,NR)); \ 535 } else if((NR) <= 11) { \ 536 _v = READ_TCM4(SC, HE_REGO_TSRB((SC)->tsrb,CID,(NR-8)));\ 537 } else if((NR) <= 13) { \ 538 _v = READ_TCM4(SC, HE_REGO_TSRC((SC)->tsrc,CID,(NR-12)));\ 539 } else { \ 540 _v = READ_TCM4(SC, HE_REGO_TSRD((SC)->tsrd,CID)); \ 541 } \ 542 _v; \ 543 }) 544 545#define WRITE_TSR(SC,CID,NR,BEN,VAL) \ 546 do { \ 547 if((NR) <= 7) { \ 548 WRITE_TCM(SC, HE_REGO_TSRA(0,CID,NR),BEN,VAL); \ 549 } else if((NR) <= 11) { \ 550 WRITE_TCM(SC, HE_REGO_TSRB((SC)->tsrb,CID,(NR-8)),BEN,VAL);\ 551 } else if((NR) <= 13) { \ 552 WRITE_TCM(SC, HE_REGO_TSRC((SC)->tsrc,CID,(NR-12)),BEN,VAL);\ 553 } else { \ 554 WRITE_TCM(SC, HE_REGO_TSRD((SC)->tsrd,CID),BEN,VAL); \ 555 } \ 556 } while(0) 557 558#define READ_RSR(SC,CID,NR) \ 559 ({ \ 560 uint32_t _v; \ 561 if((NR) <= 7) { \ 562 _v = READ_RCM4(SC, HE_REGO_RSRA(0,CID,NR)); \ 563 } else { \ 564 _v = READ_RCM4(SC, HE_REGO_RSRB((SC)->rsrb,CID,(NR-8)));\ 565 } \ 566 _v; \ 567 }) 568 569#define WRITE_RSR(SC,CID,NR,BEN,VAL) \ 570 do { \ 571 if((NR) <= 7) { \ 572 WRITE_RCM(SC, HE_REGO_RSRA(0,CID,NR),BEN,VAL); \ 573 } else { \ 574 WRITE_RCM(SC, HE_REGO_RSRB((SC)->rsrb,CID,(NR-8)),BEN,VAL);\ 575 } \ 576 } while(0) 577 578#ifdef HATM_DEBUG 579#define DBG(SC, FL, PRINT) do { \ 580 if((SC)->debug & DBG_##FL) { \ 581 if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \ 582 printf PRINT; \ 583 printf("\n"); \ 584 } \ 585 } while (0) 586 587enum { 588 DBG_RX = 0x0001, 589 DBG_TX = 0x0002, 590 DBG_VCC = 0x0004, 591 DBG_IOCTL = 0x0008, 592 DBG_ATTACH = 0x0010, 593 DBG_INTR = 0x0020, 594 DBG_DMA = 0x0040, 595 DBG_DMAH = 0x0080, 596 597 DBG_ALL = 0x00ff 598}; 599 600#else 601#define DBG(SC, FL, PRINT) 602#endif 603 604u_int hatm_cps2atmf(uint32_t); 605u_int hatm_atmf2cps(uint32_t); 606 607void hatm_intr(void *); 608int hatm_ioctl(struct ifnet *, u_long, caddr_t); 609void hatm_initialize(struct hatm_softc *); 610void hatm_stop(struct hatm_softc *sc); 611void hatm_start(struct ifnet *); 612 613void hatm_rx(struct hatm_softc *sc, u_int cid, u_int flags, struct mbuf *m, 614 u_int len); 615void hatm_tx_complete(struct hatm_softc *sc, struct tpd *tpd, uint32_t); 616 617int hatm_tx_vcc_can_open(struct hatm_softc *sc, u_int cid, struct hevcc *); 618void hatm_tx_vcc_open(struct hatm_softc *sc, u_int cid); 619void hatm_rx_vcc_open(struct hatm_softc *sc, u_int cid); 620void hatm_tx_vcc_close(struct hatm_softc *sc, u_int cid); 621void hatm_rx_vcc_close(struct hatm_softc *sc, u_int cid); 622void hatm_tx_vcc_closed(struct hatm_softc *sc, u_int cid); 623void hatm_vcc_closed(struct hatm_softc *sc, u_int cid); 624