1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (C) 2001 Eduardo Horvath. 5 * Copyright (c) 2008 Marius Strobl <marius@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * from: NetBSD: gemvar.h,v 1.8 2002/05/15 02:36:12 matt Exp 30 * from: FreeBSD: if_gemvar.h 177560 2008-03-24 17:23:53Z marius 31 * 32 * $FreeBSD$ 33 */ 34 35 #ifndef _IF_CASVAR_H 36 #define _IF_CASVAR_H 37 38 /* 39 * The page size is configurable, but needs to be at least 8k (the 40 * default) in order to also support jumbo buffers. 41 */ 42 #define CAS_PAGE_SIZE 8192 43 44 /* 45 * Transmit descriptor ring size - this is arbitrary, but allocate 46 * enough descriptors for 64 pending transmissions and 16 segments 47 * per packet. This limit is not actually enforced (packets with 48 * more segments can be sent, depending on the busdma backend); it 49 * is however used as an estimate for the TX window size. 50 */ 51 #define CAS_NTXSEGS 16 52 53 #define CAS_TXQUEUELEN 64 54 #define CAS_NTXDESC (CAS_TXQUEUELEN * CAS_NTXSEGS) 55 #define CAS_MAXTXFREE (CAS_NTXDESC - 1) 56 #define CAS_NTXDESC_MASK (CAS_NTXDESC - 1) 57 #define CAS_NEXTTX(x) ((x + 1) & CAS_NTXDESC_MASK) 58 59 /* 60 * Receive completion ring size - we have one completion per 61 * incoming packet (though the opposite isn't necessarily true), 62 * so this logic is a little simpler. 63 */ 64 #define CAS_NRXCOMP 4096 65 #define CAS_NRXCOMP_MASK (CAS_NRXCOMP - 1) 66 #define CAS_NEXTRXCOMP(x) ((x + 1) & CAS_NRXCOMP_MASK) 67 68 /* 69 * Receive descriptor ring sizes - for Cassini+ and Saturn both 70 * rings must be at least initialized. 71 */ 72 #define CAS_NRXDESC 1024 73 #define CAS_NRXDESC_MASK (CAS_NRXDESC - 1) 74 #define CAS_NEXTRXDESC(x) ((x + 1) & CAS_NRXDESC_MASK) 75 #define CAS_NRXDESC2 32 76 #define CAS_NRXDESC2_MASK (CAS_NRXDESC2 - 1) 77 #define CAS_NEXTRXDESC2(x) ((x + 1) & CAS_NRXDESC2_MASK) 78 79 /* 80 * How many ticks to wait until to retry on a RX descriptor that is 81 * still owned by the hardware. 82 */ 83 #define CAS_RXOWN_TICKS (hz / 50) 84 85 /* 86 * Control structures are DMA'd to the chip. We allocate them 87 * in a single clump that maps to a single DMA segment to make 88 * several things easier. 89 */ 90 struct cas_control_data { 91 struct cas_desc ccd_txdescs[CAS_NTXDESC]; /* TX descriptors */ 92 struct cas_rx_comp ccd_rxcomps[CAS_NRXCOMP]; /* RX completions */ 93 struct cas_desc ccd_rxdescs[CAS_NRXDESC]; /* RX descriptors */ 94 struct cas_desc ccd_rxdescs2[CAS_NRXDESC2]; /* RX descriptors 2 */ 95 }; 96 97 #define CAS_CDOFF(x) offsetof(struct cas_control_data, x) 98 #define CAS_CDTXDOFF(x) CAS_CDOFF(ccd_txdescs[(x)]) 99 #define CAS_CDRXCOFF(x) CAS_CDOFF(ccd_rxcomps[(x)]) 100 #define CAS_CDRXDOFF(x) CAS_CDOFF(ccd_rxdescs[(x)]) 101 #define CAS_CDRXD2OFF(x) CAS_CDOFF(ccd_rxdescs2[(x)]) 102 103 /* 104 * software state for transmit job mbufs (may be elements of mbuf chains) 105 */ 106 struct cas_txsoft { 107 struct mbuf *txs_mbuf; /* head of our mbuf chain */ 108 bus_dmamap_t txs_dmamap; /* our DMA map */ 109 u_int txs_firstdesc; /* first descriptor in packet */ 110 u_int txs_lastdesc; /* last descriptor in packet */ 111 u_int txs_ndescs; /* number of descriptors */ 112 STAILQ_ENTRY(cas_txsoft) txs_q; 113 }; 114 115 STAILQ_HEAD(cas_txsq, cas_txsoft); 116 117 /* 118 * software state for receive descriptors 119 */ 120 struct cas_rxdsoft { 121 void *rxds_buf; /* receive buffer */ 122 bus_dmamap_t rxds_dmamap; /* our DMA map */ 123 bus_addr_t rxds_paddr; /* physical address of the segment */ 124 u_int rxds_refcount; /* hardware + mbuf references */ 125 }; 126 127 /* 128 * software state per device 129 */ 130 struct cas_softc { 131 if_t sc_ifp; 132 struct mtx sc_mtx; 133 device_t sc_miibus; 134 struct mii_data *sc_mii; /* MII media control */ 135 device_t sc_dev; /* generic device information */ 136 u_char sc_enaddr[ETHER_ADDR_LEN]; 137 struct callout sc_tick_ch; /* tick callout */ 138 struct callout sc_rx_ch; /* delayed RX callout */ 139 struct task sc_intr_task; 140 struct task sc_tx_task; 141 struct taskqueue *sc_tq; 142 u_int sc_wdog_timer; /* watchdog timer */ 143 144 void *sc_ih; 145 struct resource *sc_res[2]; 146 #define CAS_RES_INTR 0 147 #define CAS_RES_MEM 1 148 149 bus_dma_tag_t sc_pdmatag; /* parent bus DMA tag */ 150 bus_dma_tag_t sc_rdmatag; /* RX bus DMA tag */ 151 bus_dma_tag_t sc_tdmatag; /* TX bus DMA tag */ 152 bus_dma_tag_t sc_cdmatag; /* control data bus DMA tag */ 153 bus_dmamap_t sc_dmamap; /* bus DMA handle */ 154 155 u_int sc_variant; 156 #define CAS_UNKNOWN 0 /* don't know */ 157 #define CAS_CAS 1 /* Sun Cassini */ 158 #define CAS_CASPLUS 2 /* Sun Cassini+ */ 159 #define CAS_SATURN 3 /* National Semiconductor Saturn */ 160 161 u_int sc_flags; 162 #define CAS_INITED (1 << 0) /* reset persistent regs init'ed */ 163 #define CAS_NO_CSUM (1 << 1) /* don't use hardware checksumming */ 164 #define CAS_LINK (1 << 2) /* link is up */ 165 #define CAS_REG_PLUS (1 << 3) /* has Cassini+ registers */ 166 #define CAS_SERDES (1 << 4) /* use the SERDES */ 167 #define CAS_TABORT (1 << 5) /* has target abort issues */ 168 169 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 170 bus_addr_t sc_cddma; 171 172 /* 173 * software state for transmit and receive descriptors 174 */ 175 struct cas_txsoft sc_txsoft[CAS_TXQUEUELEN]; 176 struct cas_rxdsoft sc_rxdsoft[CAS_NRXDESC]; 177 178 /* 179 * control data structures 180 */ 181 struct cas_control_data *sc_control_data; 182 #define sc_txdescs sc_control_data->ccd_txdescs 183 #define sc_rxcomps sc_control_data->ccd_rxcomps 184 #define sc_rxdescs sc_control_data->ccd_rxdescs 185 #define sc_rxdescs2 sc_control_data->ccd_rxdescs2 186 187 u_int sc_txfree; /* number of free TX descriptors */ 188 u_int sc_txnext; /* next ready TX descriptor */ 189 u_int sc_txwin; /* TX desc. since last TX intr. */ 190 191 struct cas_txsq sc_txfreeq; /* free software TX descriptors */ 192 struct cas_txsq sc_txdirtyq; /* dirty software TX descriptors */ 193 194 u_int sc_rxcptr; /* next ready RX completion */ 195 u_int sc_rxdptr; /* next ready RX descriptor */ 196 197 uint32_t sc_mac_rxcfg; /* RX MAC conf. % CAS_MAC_RX_CONF_EN */ 198 199 int sc_ifflags; 200 }; 201 202 #define CAS_BARRIER(sc, offs, len, flags) \ 203 bus_barrier((sc)->sc_res[CAS_RES_MEM], (offs), (len), (flags)) 204 205 #define CAS_READ_N(n, sc, offs) \ 206 bus_read_ ## n((sc)->sc_res[CAS_RES_MEM], (offs)) 207 #define CAS_READ_1(sc, offs) CAS_READ_N(1, (sc), (offs)) 208 #define CAS_READ_2(sc, offs) CAS_READ_N(2, (sc), (offs)) 209 #define CAS_READ_4(sc, offs) CAS_READ_N(4, (sc), (offs)) 210 211 #define CAS_WRITE_N(n, sc, offs, v) \ 212 bus_write_ ## n((sc)->sc_res[CAS_RES_MEM], (offs), (v)) 213 #define CAS_WRITE_1(sc, offs, v) CAS_WRITE_N(1, (sc), (offs), (v)) 214 #define CAS_WRITE_2(sc, offs, v) CAS_WRITE_N(2, (sc), (offs), (v)) 215 #define CAS_WRITE_4(sc, offs, v) CAS_WRITE_N(4, (sc), (offs), (v)) 216 217 #define CAS_CDTXDADDR(sc, x) ((sc)->sc_cddma + CAS_CDTXDOFF((x))) 218 #define CAS_CDRXCADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXCOFF((x))) 219 #define CAS_CDRXDADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXDOFF((x))) 220 #define CAS_CDRXD2ADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXD2OFF((x))) 221 222 #define CAS_CDSYNC(sc, ops) \ 223 bus_dmamap_sync((sc)->sc_cdmatag, (sc)->sc_cddmamap, (ops)); 224 225 #define __CAS_UPDATE_RXDESC(rxd, rxds, s) \ 226 do { \ 227 \ 228 refcount_init(&(rxds)->rxds_refcount, 1); \ 229 (rxd)->cd_buf_ptr = htole64((rxds)->rxds_paddr); \ 230 KASSERT((s) < CAS_RD_BUF_INDEX_MASK >> CAS_RD_BUF_INDEX_SHFT, \ 231 ("%s: RX buffer index too large!", __func__)); \ 232 (rxd)->cd_flags = \ 233 htole64((uint64_t)((s) << CAS_RD_BUF_INDEX_SHFT)); \ 234 } while (0) 235 236 #define CAS_UPDATE_RXDESC(sc, d, s) \ 237 __CAS_UPDATE_RXDESC(&(sc)->sc_rxdescs[(d)], \ 238 &(sc)->sc_rxdsoft[(s)], (s)) 239 240 #define CAS_INIT_RXDESC(sc, d, s) CAS_UPDATE_RXDESC(sc, d, s) 241 242 #define CAS_LOCK_INIT(_sc, _name) \ 243 mtx_init(&(_sc)->sc_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) 244 #define CAS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 245 #define CAS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 246 #define CAS_LOCK_ASSERT(_sc, _what) mtx_assert(&(_sc)->sc_mtx, (_what)) 247 #define CAS_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 248 #define CAS_LOCK_OWNED(_sc) mtx_owned(&(_sc)->sc_mtx) 249 250 #endif 251