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