1*4b1a56afSjsg /* $OpenBSD: if_casvar.h,v 1.8 2022/01/09 05:42:50 jsg Exp $ */ 22b3b792eSkettenis 32b3b792eSkettenis /* 42b3b792eSkettenis * 5eeb64880Skettenis * Copyright (C) 2007 Mark Kettenis. 62b3b792eSkettenis * Copyright (C) 2001 Eduardo Horvath. 72b3b792eSkettenis * All rights reserved. 82b3b792eSkettenis * 92b3b792eSkettenis * 102b3b792eSkettenis * Redistribution and use in source and binary forms, with or without 112b3b792eSkettenis * modification, are permitted provided that the following conditions 122b3b792eSkettenis * are met: 132b3b792eSkettenis * 1. Redistributions of source code must retain the above copyright 142b3b792eSkettenis * notice, this list of conditions and the following disclaimer. 152b3b792eSkettenis * 2. Redistributions in binary form must reproduce the above copyright 162b3b792eSkettenis * notice, this list of conditions and the following disclaimer in the 172b3b792eSkettenis * documentation and/or other materials provided with the distribution. 182b3b792eSkettenis * 192b3b792eSkettenis * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 202b3b792eSkettenis * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 212b3b792eSkettenis * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 222b3b792eSkettenis * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 232b3b792eSkettenis * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 242b3b792eSkettenis * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 252b3b792eSkettenis * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 262b3b792eSkettenis * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 272b3b792eSkettenis * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 282b3b792eSkettenis * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 292b3b792eSkettenis * SUCH DAMAGE. 302b3b792eSkettenis * 312b3b792eSkettenis */ 322b3b792eSkettenis 332b3b792eSkettenis #ifndef _IF_CASVAR_H 342b3b792eSkettenis #define _IF_CASVAR_H 352b3b792eSkettenis 362b3b792eSkettenis #include <sys/queue.h> 372b3b792eSkettenis #include <sys/timeout.h> 382b3b792eSkettenis 392b3b792eSkettenis /* 402b3b792eSkettenis * Misc. definitions for Sun Cassini ethernet controllers. 412b3b792eSkettenis */ 422b3b792eSkettenis 432b3b792eSkettenis /* 443597b0ceSkettenis * Preferred page size. Cassini has a configurable page size, but 453597b0ceSkettenis * needs at least 8k to handle jumbo frames. This happens to be the 463597b0ceSkettenis * default anyway. 473597b0ceSkettenis */ 483597b0ceSkettenis #define CAS_PAGE_SIZE 8192 493597b0ceSkettenis 503597b0ceSkettenis /* 51eeb64880Skettenis * Transmit descriptor ring size. This is arbitrary, but allocate 522b3b792eSkettenis * enough descriptors for 64 pending transmissions and 16 segments 532b3b792eSkettenis * per packet. 542b3b792eSkettenis */ 552b3b792eSkettenis #define CAS_NTXSEGS 16 562b3b792eSkettenis 572b3b792eSkettenis #define CAS_TXQUEUELEN 64 582b3b792eSkettenis #define CAS_NTXDESC (CAS_TXQUEUELEN * CAS_NTXSEGS) 592b3b792eSkettenis #define CAS_NTXDESC_MASK (CAS_NTXDESC - 1) 602b3b792eSkettenis #define CAS_NEXTTX(x) ((x + 1) & CAS_NTXDESC_MASK) 612b3b792eSkettenis 622b3b792eSkettenis struct cas_sxd { 632b3b792eSkettenis struct mbuf *sd_mbuf; 642b3b792eSkettenis bus_dmamap_t sd_map; 652b3b792eSkettenis }; 662b3b792eSkettenis 672b3b792eSkettenis /* 68eeb64880Skettenis * Receive descriptor ring size. We have one Rx buffer per incoming 692b3b792eSkettenis * packet, so this logic is a little simpler. 702b3b792eSkettenis */ 712b3b792eSkettenis #define CAS_NRXDESC 128 722b3b792eSkettenis #define CAS_NRXDESC_MASK (CAS_NRXDESC - 1) 732b3b792eSkettenis 742b3b792eSkettenis /* 75eeb64880Skettenis * Receive completion ring size. 76eeb64880Skettenis */ 77eeb64880Skettenis #define CAS_NRXCOMP 256 78eeb64880Skettenis #define CAS_NRXCOMP_MASK (CAS_NRXCOMP - 1) 79eeb64880Skettenis #define CAS_NEXTRX(x) ((x + 1) & CAS_NRXCOMP_MASK) 80eeb64880Skettenis 81eeb64880Skettenis /* 82eeb64880Skettenis * Control structures are DMA'd to the Cassini chip. We allocate them in 832b3b792eSkettenis * a single clump that maps to a single DMA segment to make several things 842b3b792eSkettenis * easier. 852b3b792eSkettenis */ 862b3b792eSkettenis struct cas_control_data { 872b3b792eSkettenis /* 882b3b792eSkettenis * The transmit descriptors. 892b3b792eSkettenis */ 90eeb64880Skettenis struct cas_desc ccd_txdescs[CAS_NTXDESC]; 91eeb64880Skettenis 92eeb64880Skettenis /* 93eeb64880Skettenis * The receive completions. 94eeb64880Skettenis */ 95eeb64880Skettenis struct cas_comp ccd_rxcomps[CAS_NRXCOMP]; 962b3b792eSkettenis 972b3b792eSkettenis /* 982b3b792eSkettenis * The receive descriptors. 992b3b792eSkettenis */ 100eeb64880Skettenis struct cas_desc ccd_rxdescs[CAS_NRXDESC]; 101faf3cde7Skettenis char ccd_unused[CAS_PAGE_SIZE - CAS_NRXDESC * 16]; 102faf3cde7Skettenis struct cas_desc ccd_rxdescs2[CAS_NRXDESC]; 1032b3b792eSkettenis }; 1042b3b792eSkettenis 1052b3b792eSkettenis #define CAS_CDOFF(x) offsetof(struct cas_control_data, x) 106eeb64880Skettenis #define CAS_CDTXOFF(x) CAS_CDOFF(ccd_txdescs[(x)]) 107eeb64880Skettenis #define CAS_CDRXOFF(x) CAS_CDOFF(ccd_rxdescs[(x)]) 108faf3cde7Skettenis #define CAS_CDRXOFF2(x) CAS_CDOFF(ccd_rxdescs2[(x)]) 109eeb64880Skettenis #define CAS_CDRXCOFF(x) CAS_CDOFF(ccd_rxcomps[(x)]) 1102b3b792eSkettenis 1112b3b792eSkettenis /* 1122b3b792eSkettenis * Software state for receive jobs. 1132b3b792eSkettenis */ 1142b3b792eSkettenis struct cas_rxsoft { 1152b3b792eSkettenis bus_dmamap_t rxs_dmamap; /* our DMA map */ 116eeb64880Skettenis bus_dma_segment_t rxs_dmaseg; /* our DMA segment */ 117eeb64880Skettenis caddr_t rxs_kva; 1182b3b792eSkettenis }; 1192b3b792eSkettenis 1202b3b792eSkettenis /* 1212b3b792eSkettenis * Software state per device. 1222b3b792eSkettenis */ 1232b3b792eSkettenis struct cas_softc { 1242b3b792eSkettenis struct device sc_dev; /* generic device information */ 1252b3b792eSkettenis struct arpcom sc_arpcom; /* ethernet common data */ 1262b3b792eSkettenis struct mii_data sc_mii; /* MII media control */ 1272b3b792eSkettenis #define sc_media sc_mii.mii_media/* shorthand */ 1282b3b792eSkettenis struct timeout sc_tick_ch; /* tick callout */ 1292b3b792eSkettenis 1302b3b792eSkettenis bus_space_tag_t sc_memt; 1312b3b792eSkettenis bus_space_handle_t sc_memh; 1322b3b792eSkettenis void *sc_ih; 1332b3b792eSkettenis 1342b3b792eSkettenis bus_dma_tag_t sc_dmatag; /* bus dma tag */ 1352b3b792eSkettenis bus_dmamap_t sc_dmamap; /* bus dma handle */ 1362b3b792eSkettenis int sc_burst; /* DVMA burst size in effect */ 1372b3b792eSkettenis int sc_phys[2]; /* MII instance -> PHY map */ 1382b3b792eSkettenis 1392b3b792eSkettenis int sc_mif_config; /* Selected MII reg setting */ 1402b3b792eSkettenis 1412b3b792eSkettenis /* 1422b3b792eSkettenis * Ring buffer DMA stuff. 1432b3b792eSkettenis */ 1442b3b792eSkettenis bus_dma_segment_t sc_cdseg; /* control data memory */ 1452b3b792eSkettenis int sc_cdnseg; /* number of segments */ 1462b3b792eSkettenis bus_dmamap_t sc_cddmamap; /* control data DMA map */ 1472b3b792eSkettenis #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 1482b3b792eSkettenis 1492b3b792eSkettenis /* 1502b3b792eSkettenis * Software state for transmit and receive descriptors. 1512b3b792eSkettenis */ 1522b3b792eSkettenis struct cas_sxd sc_txd[CAS_NTXDESC]; 1532b3b792eSkettenis u_int32_t sc_tx_cnt, sc_tx_prod, sc_tx_cons; 1542b3b792eSkettenis 1552b3b792eSkettenis struct cas_rxsoft sc_rxsoft[CAS_NRXDESC]; 156faf3cde7Skettenis struct cas_rxsoft sc_rxsoft2[CAS_NRXDESC]; 1572b3b792eSkettenis 1582b3b792eSkettenis /* 1592b3b792eSkettenis * Control data structures. 1602b3b792eSkettenis */ 1612b3b792eSkettenis struct cas_control_data *sc_control_data; 162eeb64880Skettenis #define sc_txdescs sc_control_data->ccd_txdescs 163eeb64880Skettenis #define sc_rxdescs sc_control_data->ccd_rxdescs 164faf3cde7Skettenis #define sc_rxdescs2 sc_control_data->ccd_rxdescs2 165eeb64880Skettenis #define sc_rxcomps sc_control_data->ccd_rxcomps 1662b3b792eSkettenis 1672b3b792eSkettenis int sc_rxptr; /* next ready RX descriptor/descsoft */ 1682b3b792eSkettenis int sc_rxfifosize; 169eeb64880Skettenis int sc_rxdptr; 1702b3b792eSkettenis 171faf3cde7Skettenis int sc_rev; 1722b3b792eSkettenis int sc_inited; 1732b3b792eSkettenis int sc_debug; 1742b3b792eSkettenis }; 1752b3b792eSkettenis 176faf3cde7Skettenis /* 177*4b1a56afSjsg * This macro determines whether we have a Cassini+. 178faf3cde7Skettenis */ 179faf3cde7Skettenis #define CAS_PLUS(sc) (sc->sc_rev > 0x10) 180faf3cde7Skettenis 181eeb64880Skettenis #define CAS_DMA_READ(v) letoh64(v) 182eeb64880Skettenis #define CAS_DMA_WRITE(v) htole64(v) 1832b3b792eSkettenis 1842b3b792eSkettenis #define CAS_CDTXADDR(sc, x) ((sc)->sc_cddma + CAS_CDTXOFF((x))) 1852b3b792eSkettenis #define CAS_CDRXADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXOFF((x))) 186faf3cde7Skettenis #define CAS_CDRXADDR2(sc, x) ((sc)->sc_cddma + CAS_CDRXOFF2((x))) 187eeb64880Skettenis #define CAS_CDRXCADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXCOFF((x))) 1882b3b792eSkettenis 1892b3b792eSkettenis #define CAS_CDTXSYNC(sc, x, n, ops) \ 1902b3b792eSkettenis do { \ 1912b3b792eSkettenis int __x, __n; \ 1922b3b792eSkettenis \ 1932b3b792eSkettenis __x = (x); \ 1942b3b792eSkettenis __n = (n); \ 1952b3b792eSkettenis \ 1962b3b792eSkettenis /* If it will wrap around, sync to the end of the ring. */ \ 1972b3b792eSkettenis if ((__x + __n) > CAS_NTXDESC) { \ 1982b3b792eSkettenis bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \ 1992b3b792eSkettenis CAS_CDTXOFF(__x), sizeof(struct cas_desc) * \ 2002b3b792eSkettenis (CAS_NTXDESC - __x), (ops)); \ 2012b3b792eSkettenis __n -= (CAS_NTXDESC - __x); \ 2022b3b792eSkettenis __x = 0; \ 2032b3b792eSkettenis } \ 2042b3b792eSkettenis \ 2052b3b792eSkettenis /* Now sync whatever is left. */ \ 2062b3b792eSkettenis bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \ 2072b3b792eSkettenis CAS_CDTXOFF(__x), sizeof(struct cas_desc) * __n, (ops)); \ 2082b3b792eSkettenis } while (0) 2092b3b792eSkettenis 2102b3b792eSkettenis #define CAS_CDRXSYNC(sc, x, ops) \ 2112b3b792eSkettenis bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \ 2122b3b792eSkettenis CAS_CDRXOFF((x)), sizeof(struct cas_desc), (ops)) 2132b3b792eSkettenis 214eeb64880Skettenis #define CAS_CDRXCSYNC(sc, x, ops) \ 2152b3b792eSkettenis bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \ 216eeb64880Skettenis CAS_CDRXCOFF((x)), sizeof(struct cas_desc), (ops)) 2172b3b792eSkettenis 218eeb64880Skettenis #define CAS_INIT_RXDESC(sc, d, s) \ 2192b3b792eSkettenis do { \ 220eeb64880Skettenis struct cas_rxsoft *__rxs = &sc->sc_rxsoft[(s)]; \ 221eeb64880Skettenis struct cas_desc *__rxd = &sc->sc_rxdescs[(d)]; \ 2222b3b792eSkettenis \ 223eeb64880Skettenis __rxd->cd_addr = \ 224eeb64880Skettenis CAS_DMA_WRITE(__rxs->rxs_dmamap->dm_segs[0].ds_addr); \ 225eeb64880Skettenis __rxd->cd_flags = \ 226eeb64880Skettenis CAS_DMA_WRITE((s)); \ 227eeb64880Skettenis CAS_CDRXSYNC((sc), (d), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 2282b3b792eSkettenis } while (0) 2292b3b792eSkettenis 2302b3b792eSkettenis #endif 231