1 1.15 riastrad /* $NetBSD: sqvar.h,v 1.15 2015/04/13 21:18:42 riastradh Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /* 4 1.1 thorpej * Copyright (c) 2001 Rafal K. Boni 5 1.1 thorpej * All rights reserved. 6 1.3 simonb * 7 1.1 thorpej * Redistribution and use in source and binary forms, with or without 8 1.1 thorpej * modification, are permitted provided that the following conditions 9 1.1 thorpej * are met: 10 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 11 1.1 thorpej * notice, this list of conditions and the following disclaimer. 12 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 14 1.1 thorpej * documentation and/or other materials provided with the distribution. 15 1.1 thorpej * 3. The name of the author may not be used to endorse or promote products 16 1.1 thorpej * derived from this software without specific prior written permission. 17 1.3 simonb * 18 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 thorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 thorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 thorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 thorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 thorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 thorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 thorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 thorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 thorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 thorpej */ 29 1.1 thorpej 30 1.1 thorpej #ifndef _ARCH_SGIMIPS_HPC_SQVAR_H_ 31 1.1 thorpej #define _ARCH_SGIMIPS_HPC_SQVAR_H_ 32 1.1 thorpej 33 1.1 thorpej #include <sys/queue.h> 34 1.1 thorpej #include <sys/callout.h> 35 1.1 thorpej 36 1.15 riastrad #include <sys/rndsource.h> 37 1.1 thorpej 38 1.1 thorpej #include <sgimips/hpc/hpcvar.h> 39 1.1 thorpej #include <sgimips/hpc/hpcreg.h> 40 1.1 thorpej 41 1.1 thorpej /* Note, these must be powers of two for the magic NEXT/PREV macros to work */ 42 1.7 rumble #define SQ_NRXDESC 64 43 1.7 rumble #define SQ_NTXDESC 64 44 1.1 thorpej 45 1.1 thorpej #define SQ_NRXDESC_MASK (SQ_NRXDESC - 1) 46 1.1 thorpej #define SQ_NEXTRX(x) ((x + 1) & SQ_NRXDESC_MASK) 47 1.1 thorpej #define SQ_PREVRX(x) ((x - 1) & SQ_NRXDESC_MASK) 48 1.1 thorpej 49 1.1 thorpej #define SQ_NTXDESC_MASK (SQ_NTXDESC - 1) 50 1.1 thorpej #define SQ_NEXTTX(x) ((x + 1) & SQ_NTXDESC_MASK) 51 1.1 thorpej #define SQ_PREVTX(x) ((x - 1) & SQ_NTXDESC_MASK) 52 1.1 thorpej 53 1.1 thorpej /* 54 1.1 thorpej * We pack all DMA control structures into one container so we can alloc just 55 1.1 thorpej * one chunk of DMA-safe memory and pack them into it. Otherwise, we'd have to 56 1.1 thorpej * allocate a page for each descriptor, since the bus_dmamem_alloc() interface 57 1.1 thorpej * does not allow us to allocate smaller chunks. 58 1.1 thorpej */ 59 1.1 thorpej struct sq_control { 60 1.1 thorpej /* Receive descriptors */ 61 1.1 thorpej struct hpc_dma_desc rx_desc[SQ_NRXDESC]; 62 1.1 thorpej 63 1.1 thorpej /* Transmit descriptors */ 64 1.1 thorpej struct hpc_dma_desc tx_desc[SQ_NTXDESC]; 65 1.1 thorpej }; 66 1.1 thorpej 67 1.1 thorpej #define SQ_CDOFF(x) offsetof(struct sq_control, x) 68 1.1 thorpej #define SQ_CDTXOFF(x) SQ_CDOFF(tx_desc[(x)]) 69 1.1 thorpej #define SQ_CDRXOFF(x) SQ_CDOFF(rx_desc[(x)]) 70 1.1 thorpej 71 1.2 thorpej #define SQ_TYPE_8003 0 72 1.2 thorpej #define SQ_TYPE_80C03 1 73 1.2 thorpej 74 1.6 rumble /* Trace Actions */ 75 1.6 rumble #define SQ_RESET 1 76 1.6 rumble #define SQ_ADD_TO_DMA 2 77 1.6 rumble #define SQ_START_DMA 3 78 1.6 rumble #define SQ_DONE_DMA 4 79 1.6 rumble #define SQ_RESTART_DMA 5 80 1.6 rumble #define SQ_TXINTR_ENTER 6 81 1.6 rumble #define SQ_TXINTR_EXIT 7 82 1.6 rumble #define SQ_TXINTR_BUSY 8 83 1.6 rumble #define SQ_IOCTL 9 84 1.6 rumble #define SQ_ENQUEUE 10 85 1.6 rumble 86 1.6 rumble struct sq_action_trace { 87 1.6 rumble int action; 88 1.6 rumble int line; 89 1.6 rumble int bufno; 90 1.6 rumble int status; 91 1.6 rumble int freebuf; 92 1.6 rumble }; 93 1.6 rumble 94 1.6 rumble #define SQ_TRACEBUF_SIZE 100 95 1.6 rumble 96 1.6 rumble #define SQ_TRACE(act, sc, buf, stat) do { \ 97 1.6 rumble (sc)->sq_trace[(sc)->sq_trace_idx].action = (act); \ 98 1.6 rumble (sc)->sq_trace[(sc)->sq_trace_idx].line = __LINE__; \ 99 1.6 rumble (sc)->sq_trace[(sc)->sq_trace_idx].bufno = (buf); \ 100 1.6 rumble (sc)->sq_trace[(sc)->sq_trace_idx].status = (stat); \ 101 1.6 rumble (sc)->sq_trace[(sc)->sq_trace_idx].freebuf = (sc)->sc_nfreetx; \ 102 1.6 rumble if (++(sc)->sq_trace_idx == SQ_TRACEBUF_SIZE) \ 103 1.6 rumble (sc)->sq_trace_idx = 0; \ 104 1.12 tsutsui } while (/* CONSTCOND */0) 105 1.6 rumble 106 1.1 thorpej struct sq_softc { 107 1.12 tsutsui device_t sc_dev; 108 1.1 thorpej 109 1.1 thorpej /* HPC registers */ 110 1.12 tsutsui bus_space_tag_t sc_hpct; 111 1.12 tsutsui bus_space_handle_t sc_hpch; 112 1.1 thorpej 113 1.3 simonb 114 1.1 thorpej /* HPC external ethernet registers: aka Seeq 8003 registers */ 115 1.12 tsutsui bus_space_tag_t sc_regt; 116 1.12 tsutsui bus_space_handle_t sc_regh; 117 1.1 thorpej 118 1.12 tsutsui bus_dma_tag_t sc_dmat; 119 1.1 thorpej 120 1.12 tsutsui struct ethercom sc_ethercom; 121 1.12 tsutsui uint8_t sc_enaddr[ETHER_ADDR_LEN]; 122 1.1 thorpej 123 1.2 thorpej int sc_type; 124 1.2 thorpej 125 1.1 thorpej struct sq_control* sc_control; 126 1.1 thorpej #define sc_rxdesc sc_control->rx_desc 127 1.1 thorpej #define sc_txdesc sc_control->tx_desc 128 1.1 thorpej 129 1.1 thorpej /* DMA structures for control data (DMA RX/TX descriptors) */ 130 1.1 thorpej int sc_ncdseg; 131 1.1 thorpej bus_dma_segment_t sc_cdseg; 132 1.1 thorpej bus_dmamap_t sc_cdmap; 133 1.1 thorpej #define sc_cddma sc_cdmap->dm_segs[0].ds_addr 134 1.1 thorpej 135 1.1 thorpej int sc_nextrx; 136 1.1 thorpej 137 1.1 thorpej /* DMA structures for RX packet data */ 138 1.1 thorpej bus_dma_segment_t sc_rxseg[SQ_NRXDESC]; 139 1.1 thorpej bus_dmamap_t sc_rxmap[SQ_NRXDESC]; 140 1.1 thorpej struct mbuf* sc_rxmbuf[SQ_NRXDESC]; 141 1.1 thorpej 142 1.1 thorpej int sc_nexttx; 143 1.1 thorpej int sc_prevtx; 144 1.1 thorpej int sc_nfreetx; 145 1.1 thorpej 146 1.1 thorpej /* DMA structures for TX packet data */ 147 1.1 thorpej bus_dma_segment_t sc_txseg[SQ_NTXDESC]; 148 1.1 thorpej bus_dmamap_t sc_txmap[SQ_NTXDESC]; 149 1.1 thorpej struct mbuf* sc_txmbuf[SQ_NTXDESC]; 150 1.2 thorpej 151 1.10 tsutsui uint8_t sc_rxcmd; /* prototype rxcmd */ 152 1.4 rafal 153 1.4 rafal struct evcnt sq_intrcnt; /* count interrupts */ 154 1.1 thorpej 155 1.13 tls krndsource_t rnd_source; /* random source */ 156 1.5 sekiya struct hpc_values *hpc_regs; /* HPC register definitions */ 157 1.6 rumble 158 1.6 rumble int sq_trace_idx; 159 1.6 rumble struct sq_action_trace sq_trace[SQ_TRACEBUF_SIZE]; 160 1.1 thorpej }; 161 1.1 thorpej 162 1.1 thorpej #define SQ_CDTXADDR(sc, x) ((sc)->sc_cddma + SQ_CDTXOFF((x))) 163 1.1 thorpej #define SQ_CDRXADDR(sc, x) ((sc)->sc_cddma + SQ_CDRXOFF((x))) 164 1.1 thorpej 165 1.5 sekiya static inline void 166 1.5 sekiya SQ_CDTXSYNC(struct sq_softc *sc, int __x, int __n, int ops) 167 1.5 sekiya { 168 1.5 sekiya /* If it will wrap around, sync to the end of the ring. */ 169 1.5 sekiya if ((__x + __n) > SQ_NTXDESC) { 170 1.5 sekiya bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cdmap, 171 1.5 sekiya SQ_CDTXOFF(__x), sizeof(struct hpc_dma_desc) * 172 1.5 sekiya (SQ_NTXDESC - __x), (ops)); 173 1.5 sekiya __n -= (SQ_NTXDESC - __x); 174 1.5 sekiya __x = 0; 175 1.5 sekiya } 176 1.5 sekiya 177 1.5 sekiya /* Now sync whatever is left. */ 178 1.5 sekiya bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cdmap, 179 1.5 sekiya SQ_CDTXOFF(__x), sizeof(struct hpc_dma_desc) * __n, (ops)); 180 1.5 sekiya } 181 1.1 thorpej 182 1.1 thorpej #define SQ_CDRXSYNC(sc, x, ops) \ 183 1.1 thorpej bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cdmap, \ 184 1.1 thorpej SQ_CDRXOFF((x)), sizeof(struct hpc_dma_desc), (ops)) 185 1.1 thorpej 186 1.5 sekiya static inline void 187 1.5 sekiya SQ_INIT_RXDESC(struct sq_softc *sc, unsigned int x) 188 1.5 sekiya { 189 1.5 sekiya struct hpc_dma_desc* __rxd = &(sc)->sc_rxdesc[(x)]; 190 1.5 sekiya struct mbuf *__m = (sc)->sc_rxmbuf[(x)]; 191 1.5 sekiya 192 1.5 sekiya __m->m_data = __m->m_ext.ext_buf; 193 1.5 sekiya if (sc->hpc_regs->revision == 3) { 194 1.5 sekiya __rxd->hpc3_hdd_bufptr = 195 1.12 tsutsui (sc)->sc_rxmap[(x)]->dm_segs[0].ds_addr; 196 1.8 rumble __rxd->hpc3_hdd_ctl = __m->m_ext.ext_size | HPC3_HDD_CTL_OWN | 197 1.12 tsutsui HPC3_HDD_CTL_INTR | HPC3_HDD_CTL_EOPACKET | 198 1.12 tsutsui ((x) == (SQ_NRXDESC - 1) ? HPC3_HDD_CTL_EOCHAIN : 0); 199 1.5 sekiya } else { 200 1.12 tsutsui __rxd->hpc1_hdd_bufptr = 201 1.12 tsutsui (sc)->sc_rxmap[(x)]->dm_segs[0].ds_addr | 202 1.12 tsutsui ((x) == (SQ_NRXDESC - 1) ? HPC1_HDD_CTL_EOCHAIN : 0); 203 1.12 tsutsui __rxd->hpc1_hdd_ctl = __m->m_ext.ext_size | HPC1_HDD_CTL_OWN | 204 1.12 tsutsui HPC1_HDD_CTL_INTR | HPC1_HDD_CTL_EOPACKET; 205 1.5 sekiya } 206 1.12 tsutsui __rxd->hdd_descptr = SQ_CDRXADDR((sc), SQ_NEXTRX((x))); 207 1.12 tsutsui SQ_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 208 1.5 sekiya } 209 1.1 thorpej 210 1.1 thorpej #endif /* _ARCH_SGIMIPS_HPC_SQVAR_H_ */ 211