1/* $NetBSD: aevar.h,v 1.8 2019/09/13 07:55:06 msaitoh Exp $ */ 2 3/*- 4 * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#ifndef _MIPS_ATHEROS_DEV_AEVAR_H_ 34#define _MIPS_ATHEROS_DEV_AEVAR_H_ 35 36#include <sys/queue.h> 37#include <sys/callout.h> 38 39#include <sys/rndsource.h> 40 41/* 42 * Misc. definitions for the Digital Semiconductor ``Tulip'' (21x4x) 43 * Ethernet controller family driver. 44 */ 45 46/* 47 * Transmit descriptor list size. This is arbitrary, but allocate 48 * enough descriptors for 64 pending transmissions and 16 segments 49 * per packet. Since a descriptor holds 2 buffer addresses, that's 50 * 8 descriptors per packet. This MUST work out to a power of 2. 51 */ 52#define AE_NTXSEGS 16 53 54#define AE_TXQUEUELEN 64 55#define AE_NTXDESC (AE_TXQUEUELEN * AE_NTXSEGS) 56#define AE_NTXDESC_MASK (AE_NTXDESC - 1) 57#define AE_NEXTTX(x) ((x + 1) & AE_NTXDESC_MASK) 58 59/* 60 * Receive descriptor list size. We have one Rx buffer per incoming 61 * packet, so this logic is a little simpler. 62 */ 63#define AE_NRXDESC 64 64#define AE_NRXDESC_MASK (AE_NRXDESC - 1) 65#define AE_NEXTRX(x) ((x + 1) & AE_NRXDESC_MASK) 66 67/* 68 * Control structures are DMA'd to the TULIP chip. We allocate them in 69 * a single clump that maps to a single DMA segment to make several things 70 * easier. 71 */ 72struct ae_control_data { 73 /* 74 * The transmit descriptors. 75 */ 76 struct ae_desc acd_txdescs[AE_NTXDESC]; 77 78 /* 79 * The receive descriptors. 80 */ 81 struct ae_desc acd_rxdescs[AE_NRXDESC]; 82}; 83 84#define AE_CDOFF(x) offsetof(struct ae_control_data, x) 85#define AE_CDTXOFF(x) AE_CDOFF(acd_txdescs[(x)]) 86#define AE_CDRXOFF(x) AE_CDOFF(acd_rxdescs[(x)]) 87 88/* 89 * Software state for transmit jobs. 90 */ 91struct ae_txsoft { 92 struct mbuf *txs_mbuf; /* head of our mbuf chain */ 93 bus_dmamap_t txs_dmamap; /* our DMA map */ 94 int txs_firstdesc; /* first descriptor in packet */ 95 int txs_lastdesc; /* last descriptor in packet */ 96 int txs_ndescs; /* number of descriptors */ 97 SIMPLEQ_ENTRY(ae_txsoft) txs_q; 98}; 99 100SIMPLEQ_HEAD(ae_txsq, ae_txsoft); 101 102/* 103 * Software state for receive jobs. 104 */ 105struct ae_rxsoft { 106 struct mbuf *rxs_mbuf; /* head of our mbuf chain */ 107 bus_dmamap_t rxs_dmamap; /* our DMA map */ 108}; 109 110struct ae_softc; 111 112/* 113 * Some misc. statics, useful for debugging. 114 */ 115struct ae_stats { 116 u_long ts_tx_uf; /* transmit underflow errors */ 117 u_long ts_tx_to; /* transmit jabber timeouts */ 118 u_long ts_tx_ec; /* excessive collision count */ 119 u_long ts_tx_lc; /* late collision count */ 120}; 121 122#ifndef _STANDALONE 123/* 124 * Software state per device. 125 */ 126struct ae_softc { 127 device_t sc_dev; /* generic device information */ 128 bus_space_tag_t sc_st; /* bus space tag */ 129 bus_space_handle_t sc_sh; /* bus space handle */ 130 bus_size_t sc_size; /* bus space size */ 131 bus_dma_tag_t sc_dmat; /* bus DMA tag */ 132 void *sc_ih; /* interrupt handle */ 133 int sc_cirq; /* interrupt request line (cpu) */ 134 int sc_mirq; /* interrupt request line (misc) */ 135 struct ethercom sc_ethercom; /* ethernet common data */ 136 void *sc_sdhook; /* shutdown hook */ 137 void *sc_powerhook; /* power management hook */ 138 139 struct ae_stats sc_stats; /* debugging stats */ 140 141 int sc_flags; /* misc flags. */ 142 143 struct mii_data sc_mii; /* MII/media information */ 144 145 int sc_txthresh; /* current transmit threshold */ 146 147 /* Media tick function. */ 148 void (*sc_tick)(void *); 149 struct callout sc_tick_callout; 150 151 u_int32_t sc_inten; /* copy of CSR_INTEN */ 152 153 u_int32_t sc_rxint_mask; /* mask of Rx interrupts we want */ 154 u_int32_t sc_txint_mask; /* mask of Tx interrupts we want */ 155 156 bus_dma_segment_t sc_cdseg; /* control data memory */ 157 int sc_cdnseg; /* number of segments */ 158 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 159#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 160 161 /* 162 * Software state for transmit and receive descriptors. 163 */ 164 struct ae_txsoft sc_txsoft[AE_TXQUEUELEN]; 165 struct ae_rxsoft sc_rxsoft[AE_NRXDESC]; 166 167 /* 168 * Control data structures. 169 */ 170 struct ae_control_data *sc_control_data; 171#define sc_txdescs sc_control_data->acd_txdescs 172#define sc_rxdescs sc_control_data->acd_rxdescs 173#define sc_setup_desc sc_control_data->acd_setup_desc 174 175 int sc_txfree; /* number of free Tx descriptors */ 176 int sc_txnext; /* next ready Tx descriptor */ 177 178 struct ae_txsq sc_txfreeq; /* free Tx descsofts */ 179 struct ae_txsq sc_txdirtyq; /* dirty Tx descsofts */ 180 181 u_short sc_if_flags; 182 183 int sc_rxptr; /* next ready RX descriptor/descsoft */ 184 185 krndsource_t sc_rnd_source; /* random source */ 186}; 187#endif 188 189/* sc_flags */ 190#define AE_ATTACHED 0x00000800 /* attach has succeeded */ 191#define AE_ENABLED 0x00001000 /* chip is enabled */ 192 193#define AE_IS_ENABLED(sc) ((sc)->sc_flags & AE_ENABLED) 194 195/* 196 * This macro returns the current media entry. 197 */ 198#define AE_CURRENT_MEDIA(sc) ((sc)->sc_mii.mii_media.ifm_cur) 199 200/* 201 * This macro determines if a change to media-related OPMODE bits requires 202 * a chip reset. 203 */ 204#define TULIP_MEDIA_NEEDSRESET(sc, newbits) \ 205 (((sc)->sc_opmode & OPMODE_MEDIA_BITS) != \ 206 ((newbits) & OPMODE_MEDIA_BITS)) 207 208#define AE_CDTXADDR(sc, x) ((sc)->sc_cddma + AE_CDTXOFF((x))) 209#define AE_CDRXADDR(sc, x) ((sc)->sc_cddma + AE_CDRXOFF((x))) 210 211#define AE_CDTXSYNC(sc, x, n, ops) \ 212do { \ 213 int __x, __n; \ 214 \ 215 __x = (x); \ 216 __n = (n); \ 217 \ 218 /* If it will wrap around, sync to the end of the ring. */ \ 219 if ((__x + __n) > AE_NTXDESC) { \ 220 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 221 AE_CDTXOFF(__x), sizeof(struct ae_desc) * \ 222 (AE_NTXDESC - __x), (ops)); \ 223 __n -= (AE_NTXDESC - __x); \ 224 __x = 0; \ 225 } \ 226 \ 227 /* Now sync whatever is left. */ \ 228 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 229 AE_CDTXOFF(__x), sizeof(struct ae_desc) * __n, (ops)); \ 230} while (0) 231 232#define AE_CDRXSYNC(sc, x, ops) \ 233 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 234 AE_CDRXOFF((x)), sizeof(struct ae_desc), (ops)) 235 236/* 237 * Note we rely on MCLBYTES being a power of two. Because the `length' 238 * field is only 11 bits, we must subtract 1 from the length to avoid 239 * having it truncated to 0! 240 */ 241#define AE_INIT_RXDESC(sc, x) \ 242do { \ 243 struct ae_rxsoft *__rxs = &sc->sc_rxsoft[(x)]; \ 244 struct ae_desc *__rxd = &sc->sc_rxdescs[(x)]; \ 245 struct mbuf *__m = __rxs->rxs_mbuf; \ 246 \ 247 __m->m_data = __m->m_ext.ext_buf; \ 248 __rxd->ad_bufaddr1 = \ 249 (__rxs->rxs_dmamap->dm_segs[0].ds_addr); \ 250 __rxd->ad_bufaddr2 = \ 251 AE_CDRXADDR((sc), AE_NEXTRX((x))); \ 252 __rxd->ad_ctl = \ 253 ((((__m->m_ext.ext_size - 1) & ~0x3U) \ 254 << ADCTL_SIZE1_SHIFT) | \ 255 ((x) == (AE_NRXDESC - 1) ? ADCTL_ER : 0)); \ 256 __rxd->ad_status = ADSTAT_OWN|ADSTAT_Rx_FS|ADSTAT_Rx_LS; \ 257 AE_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 258} while (0) 259 260/* CSR access */ 261 262#define AE_READ(sc, reg) \ 263 bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) 264 265#define AE_WRITE(sc, reg, val) \ 266 bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) 267 268#define AE_SET(sc, reg, mask) \ 269 AE_WRITE((sc), (reg), AE_READ((sc), (reg)) | (mask)) 270 271#define AE_CLR(sc, reg, mask) \ 272 AE_WRITE((sc), (reg), AE_READ((sc), (reg)) & ~(mask)) 273 274#define AE_ISSET(sc, reg, mask) \ 275 (AE_READ((sc), (reg)) & (mask)) 276 277#define AE_BARRIER(sc) \ 278 bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_size, \ 279 BUS_SPACE_BARRIER_WRITE) 280 281#endif /* _MIPS_ATHEROS_DEV_AEVAR_H_ */ 282