1 /* $NetBSD: if_admswvar.h,v 1.1 2007/03/20 08:52:02 dyoung Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or 8 * without modification, are permitted provided that the following 9 * conditions are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 3. The names of the authors may not be used to endorse or promote 17 * products derived from this software without specific prior 18 * written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 29 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 * OF SUCH DAMAGE. 32 */ 33 #ifndef _IF_ADMSWVAR_H_ 34 #define _IF_ADMSWVAR_H_ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: if_admswvar.h,v 1.1 2007/03/20 08:52:02 dyoung Exp $"); 38 39 #include "bpfilter.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/callout.h> 44 #include <sys/mbuf.h> 45 #include <sys/malloc.h> 46 #include <sys/kernel.h> 47 #include <sys/socket.h> 48 #include <sys/ioctl.h> 49 #include <sys/errno.h> 50 #include <sys/device.h> 51 #include <sys/queue.h> 52 #include <sys/wdog.h> 53 54 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 55 56 #include <net/if.h> 57 #include <net/if_dl.h> 58 #include <net/if_media.h> 59 #include <net/if_ether.h> 60 61 #if NBPFILTER > 0 62 #include <net/bpf.h> 63 #endif 64 65 #include <machine/bus.h> 66 #include <machine/intr.h> 67 #include <machine/endian.h> 68 69 #include <dev/mii/mii.h> 70 #include <dev/mii/miivar.h> 71 72 #include <dev/sysmon/sysmonvar.h> 73 74 #include <mips/adm5120/include/adm5120reg.h> 75 #include <mips/adm5120/include/adm5120var.h> 76 #include <mips/adm5120/include/adm5120_obiovar.h> 77 78 #include <mips/adm5120/dev/if_admswreg.h> 79 80 #define ADMSW_EVENT_COUNTERS 81 82 #define MAC_BUFLEN 0x07ff 83 84 #define ADMSW_NTXHDESC 4 85 #define ADMSW_NRXHDESC 32 86 #define ADMSW_NTXLDESC 32 87 #define ADMSW_NRXLDESC 32 88 89 #define ADMSW_NTXHDESC_MASK (ADMSW_NTXHDESC - 1) 90 #define ADMSW_NRXHDESC_MASK (ADMSW_NRXHDESC - 1) 91 #define ADMSW_NTXLDESC_MASK (ADMSW_NTXLDESC - 1) 92 #define ADMSW_NRXLDESC_MASK (ADMSW_NRXLDESC - 1) 93 94 #define ADMSW_NEXTTXH(x) (((x) + 1) & ADMSW_NTXHDESC_MASK) 95 #define ADMSW_NEXTRXH(x) (((x) + 1) & ADMSW_NRXHDESC_MASK) 96 #define ADMSW_NEXTTXL(x) (((x) + 1) & ADMSW_NTXLDESC_MASK) 97 #define ADMSW_NEXTRXL(x) (((x) + 1) & ADMSW_NRXLDESC_MASK) 98 99 struct admsw_control_data { 100 /* The transmit descriptors. */ 101 struct admsw_desc acd_txhdescs[ADMSW_NTXHDESC]; 102 103 /* The receive descriptors. */ 104 struct admsw_desc acd_rxhdescs[ADMSW_NRXHDESC]; 105 106 /* The transmit descriptors. */ 107 struct admsw_desc acd_txldescs[ADMSW_NTXLDESC]; 108 109 /* The receive descriptors. */ 110 struct admsw_desc acd_rxldescs[ADMSW_NRXLDESC]; 111 }; 112 113 #define ADMSW_CDOFF(x) offsetof(struct admsw_control_data, x) 114 #define ADMSW_CDTXHOFF(x) ADMSW_CDOFF(acd_txhdescs[(x)]) 115 #define ADMSW_CDTXLOFF(x) ADMSW_CDOFF(acd_txldescs[(x)]) 116 #define ADMSW_CDRXHOFF(x) ADMSW_CDOFF(acd_rxhdescs[(x)]) 117 #define ADMSW_CDRXLOFF(x) ADMSW_CDOFF(acd_rxldescs[(x)]) 118 119 struct admsw_descsoft { 120 struct mbuf *ds_mbuf; 121 bus_dmamap_t ds_dmamap; 122 }; 123 124 /* 125 * Software state per device. 126 */ 127 struct admsw_softc { 128 struct device sc_dev; /* generic device information */ 129 uint8_t sc_enaddr[ETHER_ADDR_LEN]; 130 bus_dma_tag_t sc_dmat; /* bus DMA tag */ 131 bus_space_tag_t sc_st; /* bus space tag */ 132 bus_space_handle_t sc_ioh; /* MAC space handle */ 133 struct sysmon_wdog sc_smw; 134 struct ifmedia sc_ifmedia[SW_DEVS]; 135 int ndevs; /* number of IFF_RUNNING interfaces */ 136 struct ethercom sc_ethercom[SW_DEVS]; /* Ethernet common data */ 137 void *sc_sdhook; /* shutdown hook */ 138 void *sc_ih; /* interrupt cookie */ 139 struct admsw_descsoft sc_txhsoft[ADMSW_NTXHDESC]; 140 struct admsw_descsoft sc_rxhsoft[ADMSW_NRXHDESC]; 141 struct admsw_descsoft sc_txlsoft[ADMSW_NTXLDESC]; 142 struct admsw_descsoft sc_rxlsoft[ADMSW_NRXLDESC]; 143 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 144 #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 145 struct admsw_control_data *sc_control_data; 146 #define sc_txhdescs sc_control_data->acd_txhdescs 147 #define sc_rxhdescs sc_control_data->acd_rxhdescs 148 #define sc_txldescs sc_control_data->acd_txldescs 149 #define sc_rxldescs sc_control_data->acd_rxldescs 150 151 int sc_txfree; /* number of free Tx descriptors */ 152 int sc_txnext; /* next Tx descriptor to use */ 153 int sc_txdirty; /* first dirty Tx descriptor */ 154 155 int sc_rxptr; /* next ready Rx descriptor */ 156 157 #ifdef ADMSW_EVENT_COUNTERS 158 struct evcnt sc_ev_txstall; /* Tx stalled */ 159 struct evcnt sc_ev_rxstall; /* Rx stalled */ 160 struct evcnt sc_ev_txintr; /* Tx interrupts */ 161 struct evcnt sc_ev_rxintr; /* Rx interrupts */ 162 #if 1 163 struct evcnt sc_ev_rxsync; /* Rx syncs */ 164 #endif 165 #endif 166 167 }; 168 169 #define ADMSW_CDTXHADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDTXHOFF((x))) 170 #define ADMSW_CDTXLADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDTXLOFF((x))) 171 #define ADMSW_CDRXHADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDRXHOFF((x))) 172 #define ADMSW_CDRXLADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDRXLOFF((x))) 173 174 #define ADMSW_CDTXHSYNC(sc, x, ops) \ 175 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 176 ADMSW_CDTXHOFF((x)), sizeof(struct admsw_desc), (ops)) 177 178 #define ADMSW_CDTXLSYNC(sc, x, ops) \ 179 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 180 ADMSW_CDTXLOFF((x)), sizeof(struct admsw_desc), (ops)) 181 182 #define ADMSW_CDRXHSYNC(sc, x, ops) \ 183 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 184 ADMSW_CDRXHOFF((x)), sizeof(struct admsw_desc), (ops)) 185 186 #define ADMSW_CDRXLSYNC(sc, x, ops) \ 187 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 188 ADMSW_CDRXLOFF((x)), sizeof(struct admsw_desc), (ops)) 189 190 #define ADMSW_INIT_RXHDESC(sc, x) \ 191 do { \ 192 struct admsw_descsoft *__ds = &(sc)->sc_rxhsoft[(x)]; \ 193 struct admsw_desc *__desc = &(sc)->sc_rxhdescs[(x)]; \ 194 struct mbuf *__m = __ds->ds_mbuf; \ 195 \ 196 __m->m_data = __m->m_ext.ext_buf + 2; \ 197 __desc->data = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \ 198 __desc->cntl = 0; \ 199 __desc->len = min(MCLBYTES - 2, MAC_BUFLEN - 2); \ 200 __desc->status = 0; \ 201 if ((x) == ADMSW_NRXHDESC - 1) \ 202 __desc->data |= ADM5120_DMA_RINGEND; \ 203 __desc->data |= ADM5120_DMA_OWN; \ 204 ADMSW_CDRXHSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 205 } while (0) 206 207 #define ADMSW_INIT_RXLDESC(sc, x) \ 208 do { \ 209 struct admsw_descsoft *__ds = &(sc)->sc_rxlsoft[(x)]; \ 210 struct admsw_desc *__desc = &(sc)->sc_rxldescs[(x)]; \ 211 struct mbuf *__m = __ds->ds_mbuf; \ 212 \ 213 __m->m_data = __m->m_ext.ext_buf + 2; \ 214 __desc->data = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \ 215 __desc->cntl = 0; \ 216 __desc->len = min(MCLBYTES - 2, MAC_BUFLEN - 2); \ 217 __desc->status = 0; \ 218 if ((x) == ADMSW_NRXLDESC - 1) \ 219 __desc->data |= ADM5120_DMA_RINGEND; \ 220 __desc->data |= ADM5120_DMA_OWN; \ 221 ADMSW_CDRXLSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 222 } while (0) 223 224 void admwdog_attach(struct admsw_softc *); 225 226 #endif /* _IF_ADMSWVAR_H_ */ 227