if_casvar.h revision 194904
1139823Simp/*- 275374Sbp * Copyright (C) 2001 Eduardo Horvath. 375374Sbp * Copyright (c) 2008 Marius Strobl <marius@FreeBSD.org> 475374Sbp * All rights reserved. 575374Sbp * 675374Sbp * Redistribution and use in source and binary forms, with or without 775374Sbp * modification, are permitted provided that the following conditions 875374Sbp * are met: 975374Sbp * 1. Redistributions of source code must retain the above copyright 1075374Sbp * notice, this list of conditions and the following disclaimer. 1175374Sbp * 2. Redistributions in binary form must reproduce the above copyright 1275374Sbp * notice, this list of conditions and the following disclaimer in the 1375374Sbp * documentation and/or other materials provided with the distribution. 1475374Sbp * 1575374Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 1675374Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1775374Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1875374Sbp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 1975374Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2075374Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2175374Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2275374Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2375374Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2475374Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2575374Sbp * SUCH DAMAGE. 2675374Sbp * 2775374Sbp * from: NetBSD: gemvar.h,v 1.8 2002/05/15 02:36:12 matt Exp 2875374Sbp * from: FreeBSD: if_gemvar.h 177560 2008-03-24 17:23:53Z marius 2975374Sbp * 3075374Sbp * $FreeBSD: head/sys/dev/cas/if_casvar.h 194904 2009-06-24 20:56:06Z marius $ 3175374Sbp */ 3275374Sbp 3375374Sbp#ifndef _IF_CASVAR_H 3475374Sbp#define _IF_CASVAR_H 3575374Sbp 3675374Sbp/* 3775374Sbp * The page size is configurable, but needs to be at least 8k (the 3875374Sbp * default) in order to also support jumbo buffers. 3975374Sbp */ 4075374Sbp#define CAS_PAGE_SIZE 8192 4175374Sbp 4275374Sbp/* 4375374Sbp * Transmit descriptor ring size - this is arbitrary, but allocate 4475374Sbp * enough descriptors for 64 pending transmissions and 16 segments 4587599Sobrien * per packet. This limit is not actually enforced (packets with 4687599Sobrien * more segments can be sent, depending on the busdma backend); it 4775374Sbp * is however used as an estimate for the TX window size. 4875374Sbp */ 4987599Sobrien#define CAS_NTXSEGS 16 5075374Sbp 5175374Sbp#define CAS_TXQUEUELEN 64 5275374Sbp#define CAS_NTXDESC (CAS_TXQUEUELEN * CAS_NTXSEGS) 5375374Sbp#define CAS_MAXTXFREE (CAS_NTXDESC - 1) 5475374Sbp#define CAS_NTXDESC_MASK (CAS_NTXDESC - 1) 5587599Sobrien#define CAS_NEXTTX(x) ((x + 1) & CAS_NTXDESC_MASK) 5675374Sbp 5775374Sbp/* 5875374Sbp * Receive completion ring size - we have one completion per 5975374Sbp * incoming packet (though the opposite isn't necesarrily true), 6075374Sbp * so this logic is a little simpler. 6175374Sbp */ 6275374Sbp#define CAS_NRXCOMP 4096 6375374Sbp#define CAS_NRXCOMP_MASK (CAS_NRXCOMP - 1) 6475374Sbp#define CAS_NEXTRXCOMP(x) ((x + 1) & CAS_NRXCOMP_MASK) 6575374Sbp 6675374Sbp/* 6775374Sbp * Receive descriptor ring sizes - for Cassini+ and Saturn both 6875374Sbp * rings must be at least initialized. 6975374Sbp */ 7075374Sbp#define CAS_NRXDESC 1024 7193593Sjhb#define CAS_NRXDESC_MASK (CAS_NRXDESC - 1) 7275374Sbp#define CAS_NEXTRXDESC(x) ((x + 1) & CAS_NRXDESC_MASK) 7375374Sbp#define CAS_NRXDESC2 32 7475374Sbp#define CAS_NRXDESC2_MASK (CAS_NRXDESC2 - 1) 7575374Sbp#define CAS_NEXTRXDESC2(x) ((x + 1) & CAS_NRXDESC2_MASK) 7675374Sbp 77102481Sbde/* 7875374Sbp * How many ticks to wait until to retry on a RX descriptor that is 7975374Sbp * still owned by the hardware. 8075374Sbp */ 8193818Sjhb#define CAS_RXOWN_TICKS (hz / 50) 8275374Sbp 8375374Sbp/* 8475374Sbp * Control structures are DMA'd to the chip. We allocate them 8575374Sbp * in a single clump that maps to a single DMA segment to make 8675374Sbp * several things easier. 8775374Sbp */ 8875374Sbpstruct cas_control_data { 8975374Sbp struct cas_desc ccd_txdescs[CAS_NTXDESC]; /* TX descriptors */ 9075374Sbp struct cas_rx_comp ccd_rxcomps[CAS_NRXCOMP]; /* RX completions */ 9175374Sbp struct cas_desc ccd_rxdescs[CAS_NRXDESC]; /* RX descriptors */ 9275374Sbp struct cas_desc ccd_rxdescs2[CAS_NRXDESC2]; /* RX descriptors 2 */ 9375374Sbp}; 9475374Sbp 9575374Sbp#define CAS_CDOFF(x) offsetof(struct cas_control_data, x) 9687192Sbp#define CAS_CDTXDOFF(x) CAS_CDOFF(ccd_txdescs[(x)]) 9775374Sbp#define CAS_CDRXCOFF(x) CAS_CDOFF(ccd_rxcomps[(x)]) 9875374Sbp#define CAS_CDRXDOFF(x) CAS_CDOFF(ccd_rxdescs[(x)]) 9975374Sbp#define CAS_CDRXD2OFF(x) CAS_CDOFF(ccd_rxdescs2[(x)]) 10075374Sbp 10175374Sbp/* 10275374Sbp * software state for transmit job mbufs (may be elements of mbuf chains) 10375374Sbp */ 10475374Sbpstruct cas_txsoft { 10575374Sbp struct mbuf *txs_mbuf; /* head of our mbuf chain */ 10687192Sbp bus_dmamap_t txs_dmamap; /* our DMA map */ 107112888Sjeff u_int txs_firstdesc; /* first descriptor in packet */ 10875374Sbp u_int txs_lastdesc; /* last descriptor in packet */ 10975374Sbp u_int txs_ndescs; /* number of descriptors */ 11075374Sbp STAILQ_ENTRY(cas_txsoft) txs_q; 11175374Sbp}; 11275374Sbp 11375374SbpSTAILQ_HEAD(cas_txsq, cas_txsoft); 11475374Sbp 11575374Sbp/* 11675374Sbp * software state for receive descriptors 117124087Stjr */ 11875374Sbpstruct cas_rxdsoft { 11975374Sbp void *rxds_buf; /* receive buffer */ 12075374Sbp bus_dmamap_t rxds_dmamap; /* our DMA map */ 12175374Sbp bus_addr_t rxds_paddr; /* physical address of the segment */ 12275374Sbp#if __FreeBSD_version < 800016 12375374Sbp struct cas_softc *rxds_sc; /* softc pointer */ 12475374Sbp u_int rxds_idx; /* our index */ 12575374Sbp#endif 12675374Sbp u_int rxds_refcount; /* hardware + mbuf references */ 127124087Stjr}; 128124087Stjr 12975374Sbp/* 13075374Sbp * software state per device 131 */ 132struct cas_softc { 133 struct ifnet *sc_ifp; 134 struct mtx sc_mtx; 135 device_t sc_miibus; 136 struct mii_data *sc_mii; /* MII media control */ 137 device_t sc_dev; /* generic device information */ 138 u_char sc_enaddr[ETHER_ADDR_LEN]; 139 struct callout sc_tick_ch; /* tick callout */ 140 struct callout sc_rx_ch; /* delayed RX callout */ 141 struct task sc_intr_task; 142 struct task sc_tx_task; 143 struct taskqueue *sc_tq; 144 u_int sc_wdog_timer; /* watchdog timer */ 145 146 void *sc_ih; 147 struct resource *sc_res[2]; 148#define CAS_RES_INTR 0 149#define CAS_RES_MEM 1 150 151 bus_dma_tag_t sc_pdmatag; /* parent bus DMA tag */ 152 bus_dma_tag_t sc_rdmatag; /* RX bus DMA tag */ 153 bus_dma_tag_t sc_tdmatag; /* TX bus DMA tag */ 154 bus_dma_tag_t sc_cdmatag; /* control data bus DMA tag */ 155 bus_dmamap_t sc_dmamap; /* bus DMA handle */ 156 157 u_int sc_phyad; /* PHY to use or -1 for any */ 158 159 u_int sc_variant; 160#define CAS_UNKNOWN 0 /* don't know */ 161#define CAS_CAS 1 /* Sun Cassini */ 162#define CAS_CASPLUS 2 /* Sun Cassini+ */ 163#define CAS_SATURN 3 /* National Semiconductor Saturn */ 164 165 u_int sc_flags; 166#define CAS_INITED (1 << 0) /* reset persistent regs init'ed */ 167#define CAS_NO_CSUM (1 << 1) /* don't use hardware checksumming */ 168#define CAS_LINK (1 << 2) /* link is up */ 169#define CAS_REG_PLUS (1 << 3) /* has Cassini+ registers */ 170#define CAS_SERDES (1 << 4) /* use the SERDES */ 171#define CAS_TABORT (1 << 5) /* has target abort issues */ 172 173 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 174 bus_addr_t sc_cddma; 175 176 /* 177 * software state for transmit and receive descriptors 178 */ 179 struct cas_txsoft sc_txsoft[CAS_TXQUEUELEN]; 180 struct cas_rxdsoft sc_rxdsoft[CAS_NRXDESC]; 181 182 /* 183 * control data structures 184 */ 185 struct cas_control_data *sc_control_data; 186#define sc_txdescs sc_control_data->ccd_txdescs 187#define sc_rxcomps sc_control_data->ccd_rxcomps 188#define sc_rxdescs sc_control_data->ccd_rxdescs 189#define sc_rxdescs2 sc_control_data->ccd_rxdescs2 190 191 u_int sc_txfree; /* number of free TX descriptors */ 192 u_int sc_txnext; /* next ready TX descriptor */ 193 u_int sc_txwin; /* TX desc. since last TX intr. */ 194 195 struct cas_txsq sc_txfreeq; /* free software TX descriptors */ 196 struct cas_txsq sc_txdirtyq; /* dirty software TX descriptors */ 197 198 u_int sc_rxcptr; /* next ready RX completion */ 199 u_int sc_rxdptr; /* next ready RX descriptor */ 200 201 int sc_ifflags; 202}; 203 204#define CAS_BARRIER(sc, offs, len, flags) \ 205 bus_barrier((sc)->sc_res[CAS_RES_MEM], (offs), (len), (flags)) 206 207#define CAS_READ_N(n, sc, offs) \ 208 bus_read_ ## n((sc)->sc_res[CAS_RES_MEM], (offs)) 209#define CAS_READ_1(sc, offs) CAS_READ_N(1, (sc), (offs)) 210#define CAS_READ_2(sc, offs) CAS_READ_N(2, (sc), (offs)) 211#define CAS_READ_4(sc, offs) CAS_READ_N(4, (sc), (offs)) 212 213#define CAS_WRITE_N(n, sc, offs, v) \ 214 bus_write_ ## n((sc)->sc_res[CAS_RES_MEM], (offs), (v)) 215#define CAS_WRITE_1(sc, offs, v) CAS_WRITE_N(1, (sc), (offs), (v)) 216#define CAS_WRITE_2(sc, offs, v) CAS_WRITE_N(2, (sc), (offs), (v)) 217#define CAS_WRITE_4(sc, offs, v) CAS_WRITE_N(4, (sc), (offs), (v)) 218 219#define CAS_CDTXDADDR(sc, x) ((sc)->sc_cddma + CAS_CDTXDOFF((x))) 220#define CAS_CDRXCADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXCOFF((x))) 221#define CAS_CDRXDADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXDOFF((x))) 222#define CAS_CDRXD2ADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXD2OFF((x))) 223 224#define CAS_CDSYNC(sc, ops) \ 225 bus_dmamap_sync((sc)->sc_cdmatag, (sc)->sc_cddmamap, (ops)); 226 227#define __CAS_UPDATE_RXDESC(rxd, rxds, s) \ 228do { \ 229 \ 230 refcount_init(&(rxds)->rxds_refcount, 1); \ 231 (rxd)->cd_buf_ptr = htole64((rxds)->rxds_paddr); \ 232 KASSERT((s) < CAS_RD_BUF_INDEX_MASK >> CAS_RD_BUF_INDEX_SHFT, \ 233 ("%s: RX buffer index too large!", __func__)); \ 234 (rxd)->cd_flags = \ 235 htole64((uint64_t)((s) << CAS_RD_BUF_INDEX_SHFT)); \ 236} while (0) 237 238#define CAS_UPDATE_RXDESC(sc, d, s) \ 239 __CAS_UPDATE_RXDESC(&(sc)->sc_rxdescs[(d)], \ 240 &(sc)->sc_rxdsoft[(s)], (s)) 241 242#if __FreeBSD_version < 800016 243#define CAS_INIT_RXDESC(sc, d, s) \ 244do { \ 245 struct cas_rxdsoft *__rxds = &(sc)->sc_rxdsoft[(s)]; \ 246 \ 247 __rxds->rxds_sc = (sc); \ 248 __rxds->rxds_idx = (s); \ 249 __CAS_UPDATE_RXDESC(&(sc)->sc_rxdescs[(d)], __rxds, (s)); \ 250} while (0) 251#else 252#define CAS_INIT_RXDESC(sc, d, s) CAS_UPDATE_RXDESC(sc, d, s) 253#endif 254 255#define CAS_LOCK_INIT(_sc, _name) \ 256 mtx_init(&(_sc)->sc_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) 257#define CAS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 258#define CAS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 259#define CAS_LOCK_ASSERT(_sc, _what) mtx_assert(&(_sc)->sc_mtx, (_what)) 260#define CAS_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 261#define CAS_LOCK_OWNED(_sc) mtx_owned(&(_sc)->sc_mtx) 262 263#endif 264