1 /* $NetBSD: aevar.h,v 1.3 2008/04/28 20:23:28 martin 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 "rnd.h" 37 38 #include <sys/queue.h> 39 #include <sys/callout.h> 40 41 #if NRND > 0 42 #include <sys/rnd.h> 43 #endif 44 45 /* 46 * Misc. definitions for the Digital Semiconductor ``Tulip'' (21x4x) 47 * Ethernet controller family driver. 48 */ 49 50 /* 51 * Transmit descriptor list size. This is arbitrary, but allocate 52 * enough descriptors for 64 pending transmissions and 16 segments 53 * per packet. Since a descriptor holds 2 buffer addresses, that's 54 * 8 descriptors per packet. This MUST work out to a power of 2. 55 */ 56 #define AE_NTXSEGS 16 57 58 #define AE_TXQUEUELEN 64 59 #define AE_NTXDESC (AE_TXQUEUELEN * AE_NTXSEGS) 60 #define AE_NTXDESC_MASK (AE_NTXDESC - 1) 61 #define AE_NEXTTX(x) ((x + 1) & AE_NTXDESC_MASK) 62 63 /* 64 * Receive descriptor list size. We have one Rx buffer per incoming 65 * packet, so this logic is a little simpler. 66 */ 67 #define AE_NRXDESC 64 68 #define AE_NRXDESC_MASK (AE_NRXDESC - 1) 69 #define AE_NEXTRX(x) ((x + 1) & AE_NRXDESC_MASK) 70 71 /* 72 * Control structures are DMA'd to the TULIP chip. We allocate them in 73 * a single clump that maps to a single DMA segment to make several things 74 * easier. 75 */ 76 struct ae_control_data { 77 /* 78 * The transmit descriptors. 79 */ 80 struct ae_desc acd_txdescs[AE_NTXDESC]; 81 82 /* 83 * The receive descriptors. 84 */ 85 struct ae_desc acd_rxdescs[AE_NRXDESC]; 86 }; 87 88 #define AE_CDOFF(x) offsetof(struct ae_control_data, x) 89 #define AE_CDTXOFF(x) AE_CDOFF(acd_txdescs[(x)]) 90 #define AE_CDRXOFF(x) AE_CDOFF(acd_rxdescs[(x)]) 91 92 /* 93 * Software state for transmit jobs. 94 */ 95 struct ae_txsoft { 96 struct mbuf *txs_mbuf; /* head of our mbuf chain */ 97 bus_dmamap_t txs_dmamap; /* our DMA map */ 98 int txs_firstdesc; /* first descriptor in packet */ 99 int txs_lastdesc; /* last descriptor in packet */ 100 int txs_ndescs; /* number of descriptors */ 101 SIMPLEQ_ENTRY(ae_txsoft) txs_q; 102 }; 103 104 SIMPLEQ_HEAD(ae_txsq, ae_txsoft); 105 106 /* 107 * Software state for receive jobs. 108 */ 109 struct ae_rxsoft { 110 struct mbuf *rxs_mbuf; /* head of our mbuf chain */ 111 bus_dmamap_t rxs_dmamap; /* our DMA map */ 112 }; 113 114 struct ae_softc; 115 116 /* 117 * Some misc. statics, useful for debugging. 118 */ 119 struct ae_stats { 120 u_long ts_tx_uf; /* transmit underflow errors */ 121 u_long ts_tx_to; /* transmit jabber timeouts */ 122 u_long ts_tx_ec; /* excessive collision count */ 123 u_long ts_tx_lc; /* late collision count */ 124 }; 125 126 #ifndef _STANDALONE 127 /* 128 * Software state per device. 129 */ 130 struct ae_softc { 131 struct device sc_dev; /* generic device information */ 132 bus_space_tag_t sc_st; /* bus space tag */ 133 bus_space_handle_t sc_sh; /* bus space handle */ 134 bus_size_t sc_size; /* bus space size */ 135 bus_dma_tag_t sc_dmat; /* bus DMA tag */ 136 void *sc_ih; /* interrupt handle */ 137 int sc_cirq; /* interrupt request line (cpu) */ 138 int sc_mirq; /* interrupt request line (misc) */ 139 struct ethercom sc_ethercom; /* ethernet common data */ 140 void *sc_sdhook; /* shutdown hook */ 141 void *sc_powerhook; /* power management hook */ 142 143 struct ae_stats sc_stats; /* debugging stats */ 144 145 int sc_flags; /* misc flags. */ 146 147 struct mii_data sc_mii; /* MII/media information */ 148 149 int sc_txthresh; /* current transmit threshold */ 150 151 /* Media tick function. */ 152 void (*sc_tick)(void *); 153 struct callout sc_tick_callout; 154 155 u_int32_t sc_inten; /* copy of CSR_INTEN */ 156 157 u_int32_t sc_rxint_mask; /* mask of Rx interrupts we want */ 158 u_int32_t sc_txint_mask; /* mask of Tx interrupts we want */ 159 160 bus_dma_segment_t sc_cdseg; /* control data memory */ 161 int sc_cdnseg; /* number of segments */ 162 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 163 #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 164 165 /* 166 * Software state for transmit and receive descriptors. 167 */ 168 struct ae_txsoft sc_txsoft[AE_TXQUEUELEN]; 169 struct ae_rxsoft sc_rxsoft[AE_NRXDESC]; 170 171 /* 172 * Control data structures. 173 */ 174 struct ae_control_data *sc_control_data; 175 #define sc_txdescs sc_control_data->acd_txdescs 176 #define sc_rxdescs sc_control_data->acd_rxdescs 177 #define sc_setup_desc sc_control_data->acd_setup_desc 178 179 int sc_txfree; /* number of free Tx descriptors */ 180 int sc_txnext; /* next ready Tx descriptor */ 181 182 struct ae_txsq sc_txfreeq; /* free Tx descsofts */ 183 struct ae_txsq sc_txdirtyq; /* dirty Tx descsofts */ 184 185 short sc_if_flags; 186 187 int sc_rxptr; /* next ready RX descriptor/descsoft */ 188 189 #if NRND > 0 190 rndsource_element_t sc_rnd_source; /* random source */ 191 #endif 192 }; 193 #endif 194 195 /* sc_flags */ 196 #define AE_ATTACHED 0x00000800 /* attach has succeeded */ 197 #define AE_ENABLED 0x00001000 /* chip is enabled */ 198 199 #define AE_IS_ENABLED(sc) ((sc)->sc_flags & AE_ENABLED) 200 201 /* 202 * This macro returns the current media entry. 203 */ 204 #define AE_CURRENT_MEDIA(sc) ((sc)->sc_mii.mii_media.ifm_cur) 205 206 /* 207 * This macro determines if a change to media-related OPMODE bits requires 208 * a chip reset. 209 */ 210 #define TULIP_MEDIA_NEEDSRESET(sc, newbits) \ 211 (((sc)->sc_opmode & OPMODE_MEDIA_BITS) != \ 212 ((newbits) & OPMODE_MEDIA_BITS)) 213 214 #define AE_CDTXADDR(sc, x) ((sc)->sc_cddma + AE_CDTXOFF((x))) 215 #define AE_CDRXADDR(sc, x) ((sc)->sc_cddma + AE_CDRXOFF((x))) 216 217 #define AE_CDTXSYNC(sc, x, n, ops) \ 218 do { \ 219 int __x, __n; \ 220 \ 221 __x = (x); \ 222 __n = (n); \ 223 \ 224 /* If it will wrap around, sync to the end of the ring. */ \ 225 if ((__x + __n) > AE_NTXDESC) { \ 226 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 227 AE_CDTXOFF(__x), sizeof(struct ae_desc) * \ 228 (AE_NTXDESC - __x), (ops)); \ 229 __n -= (AE_NTXDESC - __x); \ 230 __x = 0; \ 231 } \ 232 \ 233 /* Now sync whatever is left. */ \ 234 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 235 AE_CDTXOFF(__x), sizeof(struct ae_desc) * __n, (ops)); \ 236 } while (0) 237 238 #define AE_CDRXSYNC(sc, x, ops) \ 239 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 240 AE_CDRXOFF((x)), sizeof(struct ae_desc), (ops)) 241 242 /* 243 * Note we rely on MCLBYTES being a power of two. Because the `length' 244 * field is only 11 bits, we must subtract 1 from the length to avoid 245 * having it truncated to 0! 246 */ 247 #define AE_INIT_RXDESC(sc, x) \ 248 do { \ 249 struct ae_rxsoft *__rxs = &sc->sc_rxsoft[(x)]; \ 250 struct ae_desc *__rxd = &sc->sc_rxdescs[(x)]; \ 251 struct mbuf *__m = __rxs->rxs_mbuf; \ 252 \ 253 __m->m_data = __m->m_ext.ext_buf; \ 254 __rxd->ad_bufaddr1 = \ 255 (__rxs->rxs_dmamap->dm_segs[0].ds_addr); \ 256 __rxd->ad_bufaddr2 = \ 257 AE_CDRXADDR((sc), AE_NEXTRX((x))); \ 258 __rxd->ad_ctl = \ 259 ((((__m->m_ext.ext_size - 1) & ~0x3U) \ 260 << ADCTL_SIZE1_SHIFT) | \ 261 ((x) == (AE_NRXDESC - 1) ? ADCTL_ER : 0)); \ 262 __rxd->ad_status = ADSTAT_OWN|ADSTAT_Rx_FS|ADSTAT_Rx_LS; \ 263 AE_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 264 } while (0) 265 266 /* CSR access */ 267 268 #define AE_READ(sc, reg) \ 269 bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) 270 271 #define AE_WRITE(sc, reg, val) \ 272 bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) 273 274 #define AE_SET(sc, reg, mask) \ 275 AE_WRITE((sc), (reg), AE_READ((sc), (reg)) | (mask)) 276 277 #define AE_CLR(sc, reg, mask) \ 278 AE_WRITE((sc), (reg), AE_READ((sc), (reg)) & ~(mask)) 279 280 #define AE_ISSET(sc, reg, mask) \ 281 (AE_READ((sc), (reg)) & (mask)) 282 283 #define AE_BARRIER(sc) \ 284 bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_size, \ 285 BUS_SPACE_BARRIER_WRITE) 286 287 #endif /* _MIPS_ATHEROS_DEV_AEVAR_H_ */ 288