1 /* $NetBSD: if_admswvar.h,v 1.2 2010/01/19 22:06:21 pooka 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.2 2010/01/19 22:06:21 pooka Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/callout.h> 42 #include <sys/mbuf.h> 43 #include <sys/malloc.h> 44 #include <sys/kernel.h> 45 #include <sys/socket.h> 46 #include <sys/ioctl.h> 47 #include <sys/errno.h> 48 #include <sys/device.h> 49 #include <sys/queue.h> 50 #include <sys/wdog.h> 51 52 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 53 54 #include <net/if.h> 55 #include <net/if_dl.h> 56 #include <net/if_media.h> 57 #include <net/if_ether.h> 58 59 #include <machine/bus.h> 60 #include <machine/intr.h> 61 #include <machine/endian.h> 62 63 #include <dev/mii/mii.h> 64 #include <dev/mii/miivar.h> 65 66 #include <dev/sysmon/sysmonvar.h> 67 68 #include <mips/adm5120/include/adm5120reg.h> 69 #include <mips/adm5120/include/adm5120var.h> 70 #include <mips/adm5120/include/adm5120_obiovar.h> 71 72 #include <mips/adm5120/dev/if_admswreg.h> 73 74 #define ADMSW_EVENT_COUNTERS 75 76 #define MAC_BUFLEN 0x07ff 77 78 #define ADMSW_NTXHDESC 4 79 #define ADMSW_NRXHDESC 32 80 #define ADMSW_NTXLDESC 32 81 #define ADMSW_NRXLDESC 32 82 83 #define ADMSW_NTXHDESC_MASK (ADMSW_NTXHDESC - 1) 84 #define ADMSW_NRXHDESC_MASK (ADMSW_NRXHDESC - 1) 85 #define ADMSW_NTXLDESC_MASK (ADMSW_NTXLDESC - 1) 86 #define ADMSW_NRXLDESC_MASK (ADMSW_NRXLDESC - 1) 87 88 #define ADMSW_NEXTTXH(x) (((x) + 1) & ADMSW_NTXHDESC_MASK) 89 #define ADMSW_NEXTRXH(x) (((x) + 1) & ADMSW_NRXHDESC_MASK) 90 #define ADMSW_NEXTTXL(x) (((x) + 1) & ADMSW_NTXLDESC_MASK) 91 #define ADMSW_NEXTRXL(x) (((x) + 1) & ADMSW_NRXLDESC_MASK) 92 93 struct admsw_control_data { 94 /* The transmit descriptors. */ 95 struct admsw_desc acd_txhdescs[ADMSW_NTXHDESC]; 96 97 /* The receive descriptors. */ 98 struct admsw_desc acd_rxhdescs[ADMSW_NRXHDESC]; 99 100 /* The transmit descriptors. */ 101 struct admsw_desc acd_txldescs[ADMSW_NTXLDESC]; 102 103 /* The receive descriptors. */ 104 struct admsw_desc acd_rxldescs[ADMSW_NRXLDESC]; 105 }; 106 107 #define ADMSW_CDOFF(x) offsetof(struct admsw_control_data, x) 108 #define ADMSW_CDTXHOFF(x) ADMSW_CDOFF(acd_txhdescs[(x)]) 109 #define ADMSW_CDTXLOFF(x) ADMSW_CDOFF(acd_txldescs[(x)]) 110 #define ADMSW_CDRXHOFF(x) ADMSW_CDOFF(acd_rxhdescs[(x)]) 111 #define ADMSW_CDRXLOFF(x) ADMSW_CDOFF(acd_rxldescs[(x)]) 112 113 struct admsw_descsoft { 114 struct mbuf *ds_mbuf; 115 bus_dmamap_t ds_dmamap; 116 }; 117 118 /* 119 * Software state per device. 120 */ 121 struct admsw_softc { 122 struct device sc_dev; /* generic device information */ 123 uint8_t sc_enaddr[ETHER_ADDR_LEN]; 124 bus_dma_tag_t sc_dmat; /* bus DMA tag */ 125 bus_space_tag_t sc_st; /* bus space tag */ 126 bus_space_handle_t sc_ioh; /* MAC space handle */ 127 struct sysmon_wdog sc_smw; 128 struct ifmedia sc_ifmedia[SW_DEVS]; 129 int ndevs; /* number of IFF_RUNNING interfaces */ 130 struct ethercom sc_ethercom[SW_DEVS]; /* Ethernet common data */ 131 void *sc_sdhook; /* shutdown hook */ 132 void *sc_ih; /* interrupt cookie */ 133 struct admsw_descsoft sc_txhsoft[ADMSW_NTXHDESC]; 134 struct admsw_descsoft sc_rxhsoft[ADMSW_NRXHDESC]; 135 struct admsw_descsoft sc_txlsoft[ADMSW_NTXLDESC]; 136 struct admsw_descsoft sc_rxlsoft[ADMSW_NRXLDESC]; 137 bus_dmamap_t sc_cddmamap; /* control data DMA map */ 138 #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 139 struct admsw_control_data *sc_control_data; 140 #define sc_txhdescs sc_control_data->acd_txhdescs 141 #define sc_rxhdescs sc_control_data->acd_rxhdescs 142 #define sc_txldescs sc_control_data->acd_txldescs 143 #define sc_rxldescs sc_control_data->acd_rxldescs 144 145 int sc_txfree; /* number of free Tx descriptors */ 146 int sc_txnext; /* next Tx descriptor to use */ 147 int sc_txdirty; /* first dirty Tx descriptor */ 148 149 int sc_rxptr; /* next ready Rx descriptor */ 150 151 #ifdef ADMSW_EVENT_COUNTERS 152 struct evcnt sc_ev_txstall; /* Tx stalled */ 153 struct evcnt sc_ev_rxstall; /* Rx stalled */ 154 struct evcnt sc_ev_txintr; /* Tx interrupts */ 155 struct evcnt sc_ev_rxintr; /* Rx interrupts */ 156 #if 1 157 struct evcnt sc_ev_rxsync; /* Rx syncs */ 158 #endif 159 #endif 160 161 }; 162 163 #define ADMSW_CDTXHADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDTXHOFF((x))) 164 #define ADMSW_CDTXLADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDTXLOFF((x))) 165 #define ADMSW_CDRXHADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDRXHOFF((x))) 166 #define ADMSW_CDRXLADDR(sc, x) ((sc)->sc_cddma + ADMSW_CDRXLOFF((x))) 167 168 #define ADMSW_CDTXHSYNC(sc, x, ops) \ 169 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 170 ADMSW_CDTXHOFF((x)), sizeof(struct admsw_desc), (ops)) 171 172 #define ADMSW_CDTXLSYNC(sc, x, ops) \ 173 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 174 ADMSW_CDTXLOFF((x)), sizeof(struct admsw_desc), (ops)) 175 176 #define ADMSW_CDRXHSYNC(sc, x, ops) \ 177 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 178 ADMSW_CDRXHOFF((x)), sizeof(struct admsw_desc), (ops)) 179 180 #define ADMSW_CDRXLSYNC(sc, x, ops) \ 181 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 182 ADMSW_CDRXLOFF((x)), sizeof(struct admsw_desc), (ops)) 183 184 #define ADMSW_INIT_RXHDESC(sc, x) \ 185 do { \ 186 struct admsw_descsoft *__ds = &(sc)->sc_rxhsoft[(x)]; \ 187 struct admsw_desc *__desc = &(sc)->sc_rxhdescs[(x)]; \ 188 struct mbuf *__m = __ds->ds_mbuf; \ 189 \ 190 __m->m_data = __m->m_ext.ext_buf + 2; \ 191 __desc->data = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \ 192 __desc->cntl = 0; \ 193 __desc->len = min(MCLBYTES - 2, MAC_BUFLEN - 2); \ 194 __desc->status = 0; \ 195 if ((x) == ADMSW_NRXHDESC - 1) \ 196 __desc->data |= ADM5120_DMA_RINGEND; \ 197 __desc->data |= ADM5120_DMA_OWN; \ 198 ADMSW_CDRXHSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 199 } while (0) 200 201 #define ADMSW_INIT_RXLDESC(sc, x) \ 202 do { \ 203 struct admsw_descsoft *__ds = &(sc)->sc_rxlsoft[(x)]; \ 204 struct admsw_desc *__desc = &(sc)->sc_rxldescs[(x)]; \ 205 struct mbuf *__m = __ds->ds_mbuf; \ 206 \ 207 __m->m_data = __m->m_ext.ext_buf + 2; \ 208 __desc->data = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \ 209 __desc->cntl = 0; \ 210 __desc->len = min(MCLBYTES - 2, MAC_BUFLEN - 2); \ 211 __desc->status = 0; \ 212 if ((x) == ADMSW_NRXLDESC - 1) \ 213 __desc->data |= ADM5120_DMA_RINGEND; \ 214 __desc->data |= ADM5120_DMA_OWN; \ 215 ADMSW_CDRXLSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ 216 } while (0) 217 218 void admwdog_attach(struct admsw_softc *); 219 220 #endif /* _IF_ADMSWVAR_H_ */ 221