diff options
Diffstat (limited to 'sys/dev/hatm/if_hatmvar.h')
-rw-r--r-- | sys/dev/hatm/if_hatmvar.h | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/sys/dev/hatm/if_hatmvar.h b/sys/dev/hatm/if_hatmvar.h new file mode 100644 index 0000000..92722d0 --- /dev/null +++ b/sys/dev/hatm/if_hatmvar.h @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2001-2003 + * Fraunhofer Institute for Open Communication Systems (FhG Fokus). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Hartmut Brandt <harti@freebsd.org> + * + * $FreeBSD$ + * + * Fore HE driver for NATM + */ + +/* + * Debug statistics of the HE driver + */ +struct istats { + uint32_t tdprq_full; + uint32_t hbuf_error; + uint32_t crc_error; + uint32_t len_error; + uint32_t flow_closed; + uint32_t flow_drop; + uint32_t tpd_no_mem; + uint32_t rx_seg; + uint32_t empty_hbuf; + uint32_t short_aal5; + uint32_t badlen_aal5; + uint32_t bug_bad_isw; + uint32_t bug_no_irq_upd; + uint32_t itype_tbrq; + uint32_t itype_tpd; + uint32_t itype_rbps; + uint32_t itype_rbpl; + uint32_t itype_rbrq; + uint32_t itype_rbrqt; + uint32_t itype_unknown; + uint32_t itype_phys; + uint32_t itype_err; + uint32_t defrag; +}; + +/* Card memory layout parameters */ +#define HE_CONFIG_MEM_LAYOUT { \ + { /* 155 */ \ + 20, /* cells_per_row */ \ + 1024, /* bytes_per_row */ \ + 512, /* r0_numrows */ \ + 1018, /* tx_numrows */ \ + 512, /* r1_numrows */ \ + 6, /* r0_startrow */ \ + 2 /* cells_per_lbuf */ \ + }, { /* 622 */ \ + 40, /* cells_per_row */ \ + 2048, /* bytes_per_row */ \ + 256, /* r0_numrows */ \ + 512, /* tx_numrows */ \ + 256, /* r1_numrows */ \ + 0, /* r0_startrow */ \ + 4 /* cells_per_lbuf */ \ + } \ +} + +/*********************************************************************/ +struct hatm_softc; + +/* + * A chunk of DMA-able memory + */ +struct dmamem { + u_int size; /* in bytes */ + u_int align; /* alignement */ + bus_dma_tag_t tag; /* DMA tag */ + void *base; /* the memory */ + bus_addr_t paddr; /* physical address */ + bus_dmamap_t map; /* the MAP */ +}; + +/* + * RBP (Receive Buffer Pool) queue entry and queue. + */ +struct herbp { + u_int size; /* RBP number of entries (power of two) */ + u_int thresh; /* interrupt treshold */ + uint32_t bsize; /* buffer size in bytes */ + u_int offset; /* free space at start for small bufs */ + uint32_t mask; /* mask for index */ + struct dmamem mem; /* the queue area */ + struct he_rbpen *rbp; + uint32_t head, tail; /* head and tail */ +}; + +/* + * RBRQ (Receive Buffer Return Queue) entry and queue. + */ +struct herbrq { + u_int size; /* number of entries */ + u_int thresh; /* interrupt threshold */ + u_int tout; /* timeout value */ + u_int pcnt; /* packet count threshold */ + struct dmamem mem; /* memory */ + struct he_rbrqen *rbrq; + uint32_t head; /* driver end */ +}; + +/* + * TPDRQ (Transmit Packet Descriptor Ready Queue) entry and queue + */ +struct hetpdrq { + u_int size; /* number of entries */ + struct dmamem mem; /* memory */ + struct he_tpdrqen *tpdrq; + u_int head; /* head (copy of adapter) */ + u_int tail; /* written back to adapter */ +}; + +/* + * TBRQ (Transmit Buffer Return Queue) entry and queue + */ +struct hetbrq { + u_int size; /* number of entries */ + u_int thresh; /* interrupt threshold */ + struct dmamem mem; /* memory */ + struct he_tbrqen *tbrq; + u_int head; /* adapter end */ +}; + +/*==================================================================*/ + +/* + * TPDs are 32 byte and must be aligned on 64 byte boundaries. That means, + * that half of the space is free. We use this space to plug in a link for + * the list of free TPDs. Note, that the m_act member of the mbufs contain + * a pointer to the dmamap. + * + * The maximum number of TDPs is the size of the common transmit packet + * descriptor ready queue plus the sizes of the transmit buffer return queues + * (currently only queue 0). We allocate and map these TPD when initializing + * the card. We also allocate on DMA map for each TPD. Only the map in the + * last TPD of a packets is used when a packet is transmitted. + * This is signalled by having the mbuf member of this TPD non-zero and + * pointing to the mbuf. + */ +#define HE_TPD_SIZE 64 +struct tpd { + struct he_tpd tpd; /* at beginning */ + SLIST_ENTRY(tpd) link; /* free cid list link */ + struct mbuf *mbuf; /* the buf chain */ + bus_dmamap_t map; /* map */ + uint32_t cid; /* CID */ + uint16_t no; /* number of this tpd */ +}; +SLIST_HEAD(tpd_list, tpd); + +#define TPD_SET_USED(SC, I) do { \ + (SC)->tpd_used[(I) / 8] |= (1 << ((I) % 8)); \ + } while (0) + +#define TPD_CLR_USED(SC, I) do { \ + (SC)->tpd_used[(I) / 8] &= ~(1 << ((I) % 8)); \ + } while (0) + +#define TPD_TST_USED(SC, I) ((SC)->tpd_used[(I) / 8] & (1 << ((I) % 8))) + +#define TPD_ADDR(SC, I) ((struct tpd *)((char *)sc->tpds.base + \ + (I) * HE_TPD_SIZE)) + +/*==================================================================*/ + +/* + * External MBUFs. The card needs a lot of mbufs in the pools for high + * performance. The problem with using mbufs directly is that we would need + * a dmamap for each of the mbufs. This can exhaust iommu space on the sparc + * and it eats also a lot of processing time. So we use external mbufs + * for the small buffers and clusters for the large buffers. + * For receive group 0 we use 5 ATM cells, for group 1 one (52 byte) ATM + * cell. The mbuf storage is allocated pagewise and one dmamap is used per + * page. + * + * The handle we give to the card for the small buffers is a word combined + * of the page number and the number of the chunk in the page. This restricts + * the number of chunks per page to 256 (8 bit) and the number of pages to + * 65536 (16 bits). + * + * A chunk may be in one of three states: free, on the card and floating around + * in the system. If it is free, it is on one of the two free lists and + * start with a struct mbufx_free. Each page has a bitmap that tracks where + * its chunks are. + * + * For large buffers we use mbuf clusters. Here we have two problems: we need + * to track the buffers on the card (in the case we want to stop it) and + * we need to map the 64bit mbuf address to a 26bit handle for 64-bit machines. + * The card uses the buffers in the order we give it to the card. Therefor + * we can use a private array holding pointers to the mbufs as a circular + * queue for both tasks. This is done with the lbufs member of softc. The + * handle for these buffer is the lbufs index ored with a flag. + */ +#define MBUF0_SIZE (5 * 48) /* 240 */ +#define MBUF1_SIZE (52) + +#define MBUF0_CHUNK 256 /* 16 free bytes */ +#define MBUF1_CHUNK 96 /* 44 free bytes */ +#ifdef XXX +#define MBUF0_OFFSET (MBUF0_CHUNK - sizeof(struct mbuf_chunk_hdr) \ + - MBUF0_SIZE) +#else +#define MBUF0_OFFSET 0 +#endif +#define MBUF1_OFFSET (MBUF1_CHUNK - sizeof(struct mbuf_chunk_hdr) \ + - MBUF1_SIZE) +#define MBUFL_OFFSET 16 /* two pointers for HARP */ + +#define MBUF_ALLOC_SIZE (PAGE_SIZE) + +/* each allocated page has one of these structures at its very end. */ +struct mbuf_page_hdr { + uint8_t card[32]; /* bitmap for on-card */ + uint8_t used[32]; /* bitmap for used but not on-card */ + uint16_t nchunks; /* chunks on this page */ + bus_dmamap_t map; /* the DMA MAP */ + uint32_t phys; /* physical base address */ + uint32_t hdroff; /* chunk header offset */ + uint32_t chunksize; /* chunk size */ +}; +struct mbuf_page { + char storage[MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)]; + struct mbuf_page_hdr hdr; +}; + +/* numbers per page */ +#define MBUF0_PER_PAGE ((MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)) / \ + MBUF0_CHUNK) +#define MBUF1_PER_PAGE ((MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)) / \ + MBUF1_CHUNK) + +#define MBUF_CLR_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] &= ~(1 << ((BIT) % 8))) +#define MBUF_SET_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] |= (1 << ((BIT) % 8))) +#define MBUF_TST_BIT(ARRAY, BIT) ((ARRAY)[(BIT) / 8] & (1 << ((BIT) % 8))) + +#define MBUF_MAKE_HANDLE(PAGENO, CHUNKNO) \ + (((PAGENO) << 10) | (CHUNKNO)) + +#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do { \ + (CHUNKNO) = (HANDLE) & 0x3ff; \ + (PAGENO) = ((HANDLE) >> 10) & 0x3ff; \ + } while (0) + +#define MBUF_LARGE_FLAG (1 << 20) + +/* chunks have the following structure at the end */ +struct mbuf_chunk_hdr { + struct mbuf *mbuf; + uint16_t pageno; + uint16_t chunkno; +}; + +#define MBUFX_STORAGE_SIZE(X) (MBUF##X##_CHUNK \ + - sizeof(struct mbuf_chunk_hdr)) + +struct mbuf0_chunk { + char storage[MBUFX_STORAGE_SIZE(0)]; + struct mbuf_chunk_hdr hdr; +}; + +struct mbuf1_chunk { + char storage[MBUFX_STORAGE_SIZE(1)]; + struct mbuf_chunk_hdr hdr; +}; + +struct mbufx_free { + SLIST_ENTRY(mbufx_free) link; +}; +SLIST_HEAD(mbufx_free_list, mbufx_free); + +/*==================================================================*/ + +/* + * Interrupt queue + */ +struct heirq { + u_int size; /* number of entries */ + u_int thresh; /* re-interrupt threshold */ + u_int line; /* interrupt line to use */ + struct dmamem mem; /* interrupt queues */ + uint32_t * irq; /* interrupt queue */ + uint32_t head; /* head index */ + uint32_t * tailp; /* pointer to tail */ + struct hatm_softc *sc; /* back pointer */ + u_int group; /* interrupt group */ +}; + +/* + * This structure describes all information for a VCC open on the card. + * The array of these structures is indexed by the compressed connection ID + * (CID). + */ +struct hevcc { + u_int vflags; /* private flags */ + void * rxhand; /* NATM protocol block */ + u_int rc; /* rate control group for CBR */ + struct mbuf * chain; /* partial received PDU */ + struct mbuf * last; /* last mbuf in chain */ + + /* from the OPEN_VCC ioctl */ + struct atmio_vcc param; /* traffic parameters */ + + uint32_t ibytes; + uint32_t ipackets; + uint32_t obytes; + uint32_t opackets; + u_int ntpds; /* number of active TPDs */ +}; +#define HE_VCC_OPEN 0x000f0000 +#define HE_VCC_RX_OPEN 0x00010000 +#define HE_VCC_RX_CLOSING 0x00020000 +#define HE_VCC_TX_OPEN 0x00040000 +#define HE_VCC_TX_CLOSING 0x00080000 +#define HE_VCC_FLOW_CTRL 0x00100000 +#define HE_VCC_ASYNC 0x00200000 + +/* + * CBR rate groups + */ +struct herg { + u_int refcnt; /* how many connections reference this group */ + u_int rate; /* the value */ +}; + +/* + * Softc + */ +struct hatm_softc { + struct ifatm ifatm; /* common ATM stuff */ + struct mtx mtx; /* lock */ + struct ifmedia media; /* media */ + device_t dev; /* device */ + int memid; /* resoure id for memory */ + struct resource * memres; /* memory resource */ + bus_space_handle_t memh; /* handle */ + bus_space_tag_t memt; /* ... and tag */ + bus_dma_tag_t parent_tag; /* global restriction */ + struct cv vcc_cv; /* condition variable */ + int irqid; /* resource id */ + struct resource * irqres; /* resource */ + void * ih; /* interrupt handle */ + struct utopia utopia; /* utopia state */ + + /* rest has to be reset by stop */ + int he622; /* this is a HE622 */ + int pci64; /* 64bit bus */ + char prod_id[HE_EEPROM_PROD_ID_LEN + 1]; + char rev[HE_EEPROM_REV_LEN + 1]; + struct heirq irq_0; /* interrupt queues 0 */ + + /* generic network controller state */ + u_int cells_per_row; + u_int bytes_per_row; + u_int r0_numrows; + u_int tx_numrows; + u_int r1_numrows; + u_int r0_startrow; + u_int tx_startrow; + u_int r1_startrow; + u_int cells_per_lbuf; + u_int r0_numbuffs; + u_int r1_numbuffs; + u_int tx_numbuffs; + + /* HSP */ + struct he_hsp *hsp; + struct dmamem hsp_mem; + + /*** TX ***/ + struct hetbrq tbrq; /* TBRQ 0 */ + struct hetpdrq tpdrq; /* TPDRQ */ + struct tpd_list tpd_free; /* Free TPDs */ + u_int tpd_nfree; /* number of free TPDs */ + u_int tpd_total; /* total TPDs */ + uint8_t *tpd_used; /* bitmap of used TPDs */ + struct dmamem tpds; /* TPD memory */ + bus_dma_tag_t tx_tag; /* DMA tag for all tx mbufs */ + + /*** RX ***/ + /* receive/transmit groups */ + struct herbp rbp_s0; /* RBPS0 */ + struct herbp rbp_l0; /* RBPL0 */ + struct herbp rbp_s1; /* RBPS1 */ + struct herbrq rbrq_0; /* RBRQ0 */ + struct herbrq rbrq_1; /* RBRQ1 */ + + /* list of external mbuf storage */ + bus_dma_tag_t mbuf_tag; + struct mbuf_page **mbuf_pages; + u_int mbuf_npages; + struct mtx mbuf0_mtx; + struct mbufx_free_list mbuf0_list; + struct mtx mbuf1_mtx; + struct mbufx_free_list mbuf1_list; + + /* mbuf cluster tracking and mapping for group 0 */ + struct mbuf **lbufs; /* mbufs */ + bus_dmamap_t *rmaps; /* DMA maps */ + u_int lbufs_size; + u_int lbufs_next; + + /* VCCs */ + struct hevcc *vccs[HE_MAX_VCCS]; + u_int cbr_bw; /* BW allocated to CBR */ + u_int max_tpd; /* per VCC */ + u_int open_vccs; + uma_zone_t vcc_zone; + + /* rate groups */ + struct herg rate_ctrl[HE_REGN_CS_STPER]; + + /* memory offsets */ + u_int tsrb, tsrc, tsrd; + u_int rsrb; + + struct cv cv_rcclose; /* condition variable */ + uint32_t rate_grid[16][16]; /* our copy */ + + /* sysctl support */ + struct sysctl_ctx_list sysctl_ctx; + struct sysctl_oid *sysctl_tree; + + /* internal statistics */ + struct istats istats; + +#ifdef HATM_DEBUG + /* debugging */ + u_int debug; +#endif +}; + +#define READ4(SC,OFF) bus_space_read_4(SC->memt, SC->memh, (OFF)) +#define READ2(SC,OFF) bus_space_read_2(SC->memt, SC->memh, (OFF)) +#define READ1(SC,OFF) bus_space_read_1(SC->memt, SC->memh, (OFF)) + +#define WRITE4(SC,OFF,VAL) bus_space_write_4(SC->memt, SC->memh, (OFF), (VAL)) +#define WRITE2(SC,OFF,VAL) bus_space_write_2(SC->memt, SC->memh, (OFF), (VAL)) +#define WRITE1(SC,OFF,VAL) bus_space_write_1(SC->memt, SC->memh, (OFF), (VAL)) + +#define BARRIER_R(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \ + BUS_SPACE_BARRIER_READ) +#define BARRIER_W(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \ + BUS_SPACE_BARRIER_WRITE) +#define BARRIER_RW(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) + +#define READ_SUNI(SC,OFF) READ4(SC, HE_REGO_SUNI + 4 * (OFF)) +#define WRITE_SUNI(SC,OFF,VAL) WRITE4(SC, HE_REGO_SUNI + 4 * (OFF), (VAL)) + +#define READ_LB4(SC,OFF) \ + ({ \ + WRITE4(SC, HE_REGO_LB_MEM_ADDR, (OFF)); \ + WRITE4(SC, HE_REGO_LB_MEM_ACCESS, \ + (HE_REGM_LB_MEM_HNDSHK | HE_REGM_LB_MEM_READ)); \ + while((READ4(SC, HE_REGO_LB_MEM_ACCESS) & HE_REGM_LB_MEM_HNDSHK))\ + ; \ + READ4(SC, HE_REGO_LB_MEM_DATA); \ + }) +#define WRITE_LB4(SC,OFF,VAL) \ + do { \ + WRITE4(SC, HE_REGO_LB_MEM_ADDR, (OFF)); \ + WRITE4(SC, HE_REGO_LB_MEM_DATA, (VAL)); \ + WRITE4(SC, HE_REGO_LB_MEM_ACCESS, \ + (HE_REGM_LB_MEM_HNDSHK | HE_REGM_LB_MEM_WRITE)); \ + while((READ4(SC, HE_REGO_LB_MEM_ACCESS) & HE_REGM_LB_MEM_HNDSHK))\ + ; \ + } while(0) + +#define WRITE_MEM4(SC,OFF,VAL,SPACE) \ + do { \ + WRITE4(SC, HE_REGO_CON_DAT, (VAL)); \ + WRITE4(SC, HE_REGO_CON_CTL, \ + (SPACE | HE_REGM_CON_WE | HE_REGM_CON_STATUS | (OFF))); \ + while((READ4(SC, HE_REGO_CON_CTL) & HE_REGM_CON_STATUS) != 0) \ + ; \ + } while(0) + +#define READ_MEM4(SC,OFF,SPACE) \ + ({ \ + WRITE4(SC, HE_REGO_CON_CTL, \ + (SPACE | HE_REGM_CON_STATUS | (OFF))); \ + while((READ4(SC, HE_REGO_CON_CTL) & HE_REGM_CON_STATUS) != 0) \ + ; \ + READ4(SC, HE_REGO_CON_DAT); \ + }) + +#define WRITE_TCM4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_TCM) +#define WRITE_RCM4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_RCM) +#define WRITE_MBOX4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_MBOX) + +#define READ_TCM4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_TCM) +#define READ_RCM4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_RCM) +#define READ_MBOX4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_MBOX) + +#define WRITE_TCM(SC,OFF,BYTES,VAL) \ + WRITE_MEM4(SC,(OFF) | ((~(BYTES) & 0xf) << HE_REGS_CON_DIS), \ + (VAL), HE_REGM_CON_TCM) +#define WRITE_RCM(SC,OFF,BYTES,VAL) \ + WRITE_MEM4(SC,(OFF) | ((~(BYTES) & 0xf) << HE_REGS_CON_DIS), \ + (VAL), HE_REGM_CON_RCM) + +#define READ_TSR(SC,CID,NR) \ + ({ \ + uint32_t _v; \ + if((NR) <= 7) { \ + _v = READ_TCM4(SC, HE_REGO_TSRA(0,CID,NR)); \ + } else if((NR) <= 11) { \ + _v = READ_TCM4(SC, HE_REGO_TSRB((SC)->tsrb,CID,(NR-8)));\ + } else if((NR) <= 13) { \ + _v = READ_TCM4(SC, HE_REGO_TSRC((SC)->tsrc,CID,(NR-12)));\ + } else { \ + _v = READ_TCM4(SC, HE_REGO_TSRD((SC)->tsrd,CID)); \ + } \ + _v; \ + }) + +#define WRITE_TSR(SC,CID,NR,BEN,VAL) \ + do { \ + if((NR) <= 7) { \ + WRITE_TCM(SC, HE_REGO_TSRA(0,CID,NR),BEN,VAL); \ + } else if((NR) <= 11) { \ + WRITE_TCM(SC, HE_REGO_TSRB((SC)->tsrb,CID,(NR-8)),BEN,VAL);\ + } else if((NR) <= 13) { \ + WRITE_TCM(SC, HE_REGO_TSRC((SC)->tsrc,CID,(NR-12)),BEN,VAL);\ + } else { \ + WRITE_TCM(SC, HE_REGO_TSRD((SC)->tsrd,CID),BEN,VAL); \ + } \ + } while(0) + +#define READ_RSR(SC,CID,NR) \ + ({ \ + uint32_t _v; \ + if((NR) <= 7) { \ + _v = READ_RCM4(SC, HE_REGO_RSRA(0,CID,NR)); \ + } else { \ + _v = READ_RCM4(SC, HE_REGO_RSRB((SC)->rsrb,CID,(NR-8)));\ + } \ + _v; \ + }) + +#define WRITE_RSR(SC,CID,NR,BEN,VAL) \ + do { \ + if((NR) <= 7) { \ + WRITE_RCM(SC, HE_REGO_RSRA(0,CID,NR),BEN,VAL); \ + } else { \ + WRITE_RCM(SC, HE_REGO_RSRB((SC)->rsrb,CID,(NR-8)),BEN,VAL);\ + } \ + } while(0) + +#ifdef HATM_DEBUG +#define DBG(SC, FL, PRINT) do { \ + if((SC)->debug & DBG_##FL) { \ + if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \ + printf PRINT; \ + printf("\n"); \ + } \ + } while (0) + +enum { + DBG_RX = 0x0001, + DBG_TX = 0x0002, + DBG_VCC = 0x0004, + DBG_IOCTL = 0x0008, + DBG_ATTACH = 0x0010, + DBG_INTR = 0x0020, + DBG_DMA = 0x0040, + DBG_DMAH = 0x0080, + + DBG_ALL = 0x00ff +}; + +#else +#define DBG(SC, FL, PRINT) +#endif + +u_int hatm_cps2atmf(uint32_t); +u_int hatm_atmf2cps(uint32_t); + +void hatm_intr(void *); +int hatm_ioctl(struct ifnet *, u_long, caddr_t); +void hatm_initialize(struct hatm_softc *); +void hatm_stop(struct hatm_softc *sc); +void hatm_start(struct ifnet *); + +void hatm_rx(struct hatm_softc *sc, u_int cid, u_int flags, struct mbuf *m, + u_int len); +void hatm_tx_complete(struct hatm_softc *sc, struct tpd *tpd, uint32_t); + +int hatm_tx_vcc_can_open(struct hatm_softc *sc, u_int cid, struct hevcc *); +void hatm_tx_vcc_open(struct hatm_softc *sc, u_int cid); +void hatm_rx_vcc_open(struct hatm_softc *sc, u_int cid); +void hatm_tx_vcc_close(struct hatm_softc *sc, u_int cid); +void hatm_rx_vcc_close(struct hatm_softc *sc, u_int cid); +void hatm_tx_vcc_closed(struct hatm_softc *sc, u_int cid); +void hatm_vcc_closed(struct hatm_softc *sc, u_int cid); |