1 1.51 rin /* $NetBSD: epe.c,v 1.51 2024/07/05 04:31:49 rin Exp $ */ 2 1.1 joff 3 1.1 joff /* 4 1.1 joff * Copyright (c) 2004 Jesse Off 5 1.1 joff * All rights reserved. 6 1.1 joff * 7 1.1 joff * Redistribution and use in source and binary forms, with or without 8 1.1 joff * modification, are permitted provided that the following conditions 9 1.1 joff * are met: 10 1.1 joff * 1. Redistributions of source code must retain the above copyright 11 1.1 joff * notice, this list of conditions and the following disclaimer. 12 1.1 joff * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 joff * notice, this list of conditions and the following disclaimer in the 14 1.1 joff * documentation and/or other materials provided with the distribution. 15 1.1 joff * 16 1.1 joff * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 1.1 joff * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 1.1 joff * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 1.1 joff * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 1.1 joff * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 1.1 joff * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 1.1 joff * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 1.1 joff * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 1.1 joff * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 1.1 joff * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 1.1 joff * POSSIBILITY OF SUCH DAMAGE. 27 1.1 joff */ 28 1.1 joff 29 1.1 joff #include <sys/cdefs.h> 30 1.51 rin __KERNEL_RCSID(0, "$NetBSD: epe.c,v 1.51 2024/07/05 04:31:49 rin Exp $"); 31 1.1 joff 32 1.1 joff #include <sys/types.h> 33 1.1 joff #include <sys/param.h> 34 1.1 joff #include <sys/systm.h> 35 1.1 joff #include <sys/ioctl.h> 36 1.1 joff #include <sys/kernel.h> 37 1.1 joff #include <sys/proc.h> 38 1.1 joff #include <sys/time.h> 39 1.1 joff #include <sys/device.h> 40 1.1 joff #include <uvm/uvm_extern.h> 41 1.1 joff 42 1.26 dyoung #include <sys/bus.h> 43 1.1 joff #include <machine/intr.h> 44 1.1 joff 45 1.1 joff #include <arm/cpufunc.h> 46 1.1 joff 47 1.41 msaitoh #include <arm/ep93xx/epsocvar.h> 48 1.1 joff #include <arm/ep93xx/ep93xxvar.h> 49 1.1 joff 50 1.1 joff #include <net/if.h> 51 1.1 joff #include <net/if_dl.h> 52 1.1 joff #include <net/if_types.h> 53 1.1 joff #include <net/if_media.h> 54 1.1 joff #include <net/if_ether.h> 55 1.37 msaitoh #include <net/bpf.h> 56 1.1 joff 57 1.1 joff #include <dev/mii/mii.h> 58 1.1 joff #include <dev/mii/miivar.h> 59 1.1 joff 60 1.1 joff #ifdef INET 61 1.1 joff #include <netinet/in.h> 62 1.1 joff #include <netinet/in_systm.h> 63 1.1 joff #include <netinet/in_var.h> 64 1.1 joff #include <netinet/ip.h> 65 1.1 joff #include <netinet/if_inarp.h> 66 1.1 joff #endif 67 1.1 joff 68 1.2 joff #include <arm/ep93xx/ep93xxreg.h> 69 1.41 msaitoh #include <arm/ep93xx/epereg.h> 70 1.41 msaitoh #include <arm/ep93xx/epevar.h> 71 1.1 joff 72 1.4 hamajima #define DEFAULT_MDCDIV 32 73 1.4 hamajima 74 1.2 joff #ifndef EPE_FAST 75 1.2 joff #define EPE_FAST 76 1.2 joff #endif 77 1.1 joff 78 1.2 joff #ifndef EPE_FAST 79 1.1 joff #define EPE_READ(x) \ 80 1.1 joff bus_space_read_4(sc->sc_iot, sc->sc_ioh, (EPE_ ## x)) 81 1.1 joff #define EPE_WRITE(x, y) \ 82 1.1 joff bus_space_write_4(sc->sc_iot, sc->sc_ioh, (EPE_ ## x), (y)) 83 1.2 joff #define CTRLPAGE_DMASYNC(x, y, z) \ 84 1.2 joff bus_dmamap_sync(sc->sc_dmat, sc->ctrlpage_dmamap, (x), (y), (z)) 85 1.2 joff #else 86 1.29 skrll #define EPE_READ(x) *(volatile uint32_t *) \ 87 1.2 joff (EP93XX_AHB_VBASE + EP93XX_AHB_EPE + (EPE_ ## x)) 88 1.29 skrll #define EPE_WRITE(x, y) *(volatile uint32_t *) \ 89 1.2 joff (EP93XX_AHB_VBASE + EP93XX_AHB_EPE + (EPE_ ## x)) = y 90 1.2 joff #define CTRLPAGE_DMASYNC(x, y, z) 91 1.2 joff #endif /* ! EPE_FAST */ 92 1.1 joff 93 1.27 matt static int epe_match(device_t , cfdata_t, void *); 94 1.27 matt static void epe_attach(device_t, device_t, void *); 95 1.1 joff static void epe_init(struct epe_softc *); 96 1.42 msaitoh static int epe_intr(void* arg); 97 1.2 joff static int epe_gctx(struct epe_softc *); 98 1.39 msaitoh int epe_mii_readreg (device_t, int, int, uint16_t *); 99 1.39 msaitoh int epe_mii_writereg (device_t, int, int, uint16_t); 100 1.27 matt void epe_statchg (struct ifnet *); 101 1.1 joff void epe_tick (void *); 102 1.10 christos static int epe_ifioctl (struct ifnet *, u_long, void *); 103 1.1 joff static void epe_ifstart (struct ifnet *); 104 1.1 joff static void epe_ifwatchdog (struct ifnet *); 105 1.1 joff static int epe_ifinit (struct ifnet *); 106 1.1 joff static void epe_ifstop (struct ifnet *, int); 107 1.1 joff static void epe_setaddr (struct ifnet *); 108 1.1 joff 109 1.28 chs CFATTACH_DECL_NEW(epe, sizeof(struct epe_softc), 110 1.1 joff epe_match, epe_attach, NULL, NULL); 111 1.1 joff 112 1.1 joff static int 113 1.27 matt epe_match(device_t parent, cfdata_t match, void *aux) 114 1.1 joff { 115 1.1 joff return 2; 116 1.1 joff } 117 1.1 joff 118 1.1 joff static void 119 1.27 matt epe_attach(device_t parent, device_t self, void *aux) 120 1.1 joff { 121 1.27 matt struct epe_softc *sc = device_private(self); 122 1.1 joff struct epsoc_attach_args *sa; 123 1.8 thorpej prop_data_t enaddr; 124 1.1 joff 125 1.27 matt aprint_normal("\n"); 126 1.1 joff sa = aux; 127 1.27 matt sc->sc_dev = self; 128 1.1 joff sc->sc_iot = sa->sa_iot; 129 1.1 joff sc->sc_intr = sa->sa_intr; 130 1.1 joff sc->sc_dmat = sa->sa_dmat; 131 1.1 joff 132 1.41 msaitoh if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 133 1.1 joff 0, &sc->sc_ioh)) 134 1.28 chs panic("%s: Cannot map registers", device_xname(self)); 135 1.1 joff 136 1.4 hamajima /* Fetch the Ethernet address from property if set. */ 137 1.24 martin enaddr = prop_dictionary_get(device_properties(self), "mac-address"); 138 1.8 thorpej if (enaddr != NULL) { 139 1.8 thorpej KASSERT(prop_object_type(enaddr) == PROP_TYPE_DATA); 140 1.8 thorpej KASSERT(prop_data_size(enaddr) == ETHER_ADDR_LEN); 141 1.8 thorpej memcpy(sc->sc_enaddr, prop_data_data_nocopy(enaddr), 142 1.8 thorpej ETHER_ADDR_LEN); 143 1.4 hamajima bus_space_write_4(sc->sc_iot, sc->sc_ioh, EPE_AFP, 0); 144 1.4 hamajima bus_space_write_region_1(sc->sc_iot, sc->sc_ioh, EPE_IndAd, 145 1.4 hamajima sc->sc_enaddr, ETHER_ADDR_LEN); 146 1.4 hamajima } 147 1.4 hamajima 148 1.42 msaitoh ep93xx_intr_establish(sc->sc_intr, IPL_NET, epe_intr, sc); 149 1.1 joff epe_init(sc); 150 1.1 joff } 151 1.1 joff 152 1.1 joff static int 153 1.2 joff epe_gctx(struct epe_softc *sc) 154 1.2 joff { 155 1.2 joff struct ifnet * ifp = &sc->sc_ec.ec_if; 156 1.29 skrll uint32_t *cur, ndq = 0; 157 1.2 joff 158 1.2 joff /* Handle transmit completions */ 159 1.29 skrll cur = (uint32_t *)(EPE_READ(TXStsQCurAdd) - 160 1.11 he sc->ctrlpage_dsaddr + (char*)sc->ctrlpage); 161 1.2 joff 162 1.41 msaitoh if (sc->TXStsQ_cur != cur) { 163 1.41 msaitoh CTRLPAGE_DMASYNC(TX_QLEN * 2 * sizeof(uint32_t), 164 1.29 skrll TX_QLEN * sizeof(uint32_t), BUS_DMASYNC_PREREAD); 165 1.41 msaitoh } else 166 1.2 joff return 0; 167 1.2 joff 168 1.2 joff do { 169 1.29 skrll uint32_t tbi = *sc->TXStsQ_cur & 0x7fff; 170 1.2 joff struct mbuf *m = sc->txq[tbi].m; 171 1.2 joff 172 1.41 msaitoh if ((*sc->TXStsQ_cur & TXStsQ_TxWE) == 0) 173 1.46 skrll if_statinc(ifp, if_oerrors); 174 1.41 msaitoh 175 1.2 joff bus_dmamap_unload(sc->sc_dmat, sc->txq[tbi].m_dmamap); 176 1.2 joff m_freem(m); 177 1.2 joff do { 178 1.2 joff sc->txq[tbi].m = NULL; 179 1.2 joff ndq++; 180 1.2 joff tbi = (tbi + 1) % TX_QLEN; 181 1.2 joff } while (sc->txq[tbi].m == m); 182 1.2 joff 183 1.46 skrll if_statinc(ifp, if_opackets); 184 1.2 joff sc->TXStsQ_cur++; 185 1.2 joff if (sc->TXStsQ_cur >= sc->TXStsQ + TX_QLEN) { 186 1.2 joff sc->TXStsQ_cur = sc->TXStsQ; 187 1.2 joff } 188 1.41 msaitoh } while (sc->TXStsQ_cur != cur); 189 1.2 joff 190 1.2 joff sc->TXDQ_avail += ndq; 191 1.49 thorpej if (sc->tx_busy) { 192 1.49 thorpej sc->tx_busy = false; 193 1.2 joff /* Disable end-of-tx-chain interrupt */ 194 1.2 joff EPE_WRITE(IntEn, IntEn_REOFIE); 195 1.2 joff } 196 1.2 joff return ndq; 197 1.2 joff } 198 1.2 joff 199 1.2 joff static int 200 1.1 joff epe_intr(void *arg) 201 1.1 joff { 202 1.1 joff struct epe_softc *sc = (struct epe_softc *)arg; 203 1.1 joff struct ifnet * ifp = &sc->sc_ec.ec_if; 204 1.29 skrll uint32_t ndq = 0, irq, *cur; 205 1.1 joff 206 1.1 joff irq = EPE_READ(IntStsC); 207 1.1 joff begin: 208 1.29 skrll cur = (uint32_t *)(EPE_READ(RXStsQCurAdd) - 209 1.11 he sc->ctrlpage_dsaddr + (char*)sc->ctrlpage); 210 1.29 skrll CTRLPAGE_DMASYNC(TX_QLEN * 3 * sizeof(uint32_t), 211 1.41 msaitoh RX_QLEN * 4 * sizeof(uint32_t), 212 1.1 joff BUS_DMASYNC_PREREAD); 213 1.1 joff while (sc->RXStsQ_cur != cur) { 214 1.41 msaitoh if ((sc->RXStsQ_cur[0] & (RXStsQ_RWE | RXStsQ_RFP |RXStsQ_EOB)) 215 1.41 msaitoh == (RXStsQ_RWE | RXStsQ_RFP | RXStsQ_EOB)) { 216 1.29 skrll uint32_t bi = (sc->RXStsQ_cur[1] >> 16) & 0x7fff; 217 1.29 skrll uint32_t fl = sc->RXStsQ_cur[1] & 0xffff; 218 1.1 joff struct mbuf *m; 219 1.1 joff 220 1.1 joff MGETHDR(m, M_DONTWAIT, MT_DATA); 221 1.1 joff if (m != NULL) MCLGET(m, M_DONTWAIT); 222 1.1 joff if (m != NULL && (m->m_flags & M_EXT)) { 223 1.41 msaitoh bus_dmamap_unload(sc->sc_dmat, 224 1.1 joff sc->rxq[bi].m_dmamap); 225 1.34 ozaki m_set_rcvif(sc->rxq[bi].m, ifp); 226 1.41 msaitoh sc->rxq[bi].m->m_pkthdr.len = 227 1.1 joff sc->rxq[bi].m->m_len = fl; 228 1.33 ozaki if_percpuq_enqueue(ifp->if_percpuq, 229 1.33 ozaki sc->rxq[bi].m); 230 1.1 joff sc->rxq[bi].m = m; 231 1.41 msaitoh bus_dmamap_load(sc->sc_dmat, 232 1.41 msaitoh sc->rxq[bi].m_dmamap, 233 1.1 joff m->m_ext.ext_buf, MCLBYTES, 234 1.1 joff NULL, BUS_DMA_NOWAIT); 235 1.41 msaitoh sc->RXDQ[bi * 2] = 236 1.1 joff sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr; 237 1.1 joff } else { 238 1.1 joff /* Drop packets until we can get replacement 239 1.1 joff * empty mbufs for the RXDQ. 240 1.1 joff */ 241 1.51 rin m_freem(m); 242 1.41 msaitoh 243 1.46 skrll if_statinc(ifp, if_ierrors); 244 1.41 msaitoh } 245 1.41 msaitoh } else 246 1.46 skrll if_statinc(ifp, if_ierrors); 247 1.1 joff 248 1.1 joff ndq++; 249 1.1 joff 250 1.1 joff sc->RXStsQ_cur += 2; 251 1.41 msaitoh if (sc->RXStsQ_cur >= sc->RXStsQ + (RX_QLEN * 2)) 252 1.1 joff sc->RXStsQ_cur = sc->RXStsQ; 253 1.1 joff } 254 1.1 joff 255 1.1 joff if (ndq > 0) { 256 1.29 skrll CTRLPAGE_DMASYNC(TX_QLEN * 3 * sizeof(uint32_t), 257 1.42 msaitoh RX_QLEN * 4 * sizeof(uint32_t), 258 1.41 msaitoh BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 259 1.1 joff EPE_WRITE(RXStsEnq, ndq); 260 1.1 joff EPE_WRITE(RXDEnq, ndq); 261 1.1 joff ndq = 0; 262 1.1 joff } 263 1.1 joff 264 1.2 joff if (epe_gctx(sc) > 0 && IFQ_IS_EMPTY(&ifp->if_snd) == 0) { 265 1.36 nonaka if_schedule_deferred_start(ifp); 266 1.41 msaitoh } 267 1.1 joff 268 1.1 joff irq = EPE_READ(IntStsC); 269 1.41 msaitoh if ((irq & (IntSts_RxSQ | IntSts_ECI)) != 0) 270 1.1 joff goto begin; 271 1.2 joff 272 1.41 msaitoh return 1; 273 1.1 joff } 274 1.1 joff 275 1.1 joff 276 1.1 joff static void 277 1.1 joff epe_init(struct epe_softc *sc) 278 1.1 joff { 279 1.1 joff bus_dma_segment_t segs; 280 1.11 he char *addr; 281 1.1 joff int rsegs, err, i; 282 1.1 joff struct ifnet * ifp = &sc->sc_ec.ec_if; 283 1.44 msaitoh struct mii_data *mii = &sc->sc_mii; 284 1.4 hamajima int mdcdiv = DEFAULT_MDCDIV; 285 1.1 joff 286 1.12 ad callout_init(&sc->epe_tick_ch, 0); 287 1.1 joff 288 1.1 joff /* Select primary Individual Address in Address Filter Pointer */ 289 1.1 joff EPE_WRITE(AFP, 0); 290 1.1 joff /* Read ethernet MAC, should already be set by bootrom */ 291 1.1 joff bus_space_read_region_1(sc->sc_iot, sc->sc_ioh, EPE_IndAd, 292 1.1 joff sc->sc_enaddr, ETHER_ADDR_LEN); 293 1.41 msaitoh aprint_normal_dev(sc->sc_dev, "MAC address %s\n", 294 1.1 joff ether_sprintf(sc->sc_enaddr)); 295 1.1 joff 296 1.1 joff /* Soft Reset the MAC */ 297 1.1 joff EPE_WRITE(SelfCtl, SelfCtl_RESET); 298 1.41 msaitoh while (EPE_READ(SelfCtl) & SelfCtl_RESET) 299 1.41 msaitoh ; 300 1.1 joff 301 1.1 joff /* suggested magic initialization values from datasheet */ 302 1.1 joff EPE_WRITE(RXBufThrshld, 0x800040); 303 1.1 joff EPE_WRITE(TXBufThrshld, 0x200010); 304 1.1 joff EPE_WRITE(RXStsThrshld, 0x40002); 305 1.1 joff EPE_WRITE(TXStsThrshld, 0x40002); 306 1.1 joff EPE_WRITE(RXDThrshld, 0x40002); 307 1.1 joff EPE_WRITE(TXDThrshld, 0x40002); 308 1.1 joff 309 1.1 joff /* Allocate a page of memory for descriptor and status queues */ 310 1.41 msaitoh err = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, 0, PAGE_SIZE, 311 1.1 joff &segs, 1, &rsegs, BUS_DMA_WAITOK); 312 1.1 joff if (err == 0) { 313 1.41 msaitoh err = bus_dmamem_map(sc->sc_dmat, &segs, 1, PAGE_SIZE, 314 1.41 msaitoh &sc->ctrlpage, (BUS_DMA_WAITOK | BUS_DMA_COHERENT)); 315 1.1 joff } 316 1.1 joff if (err == 0) { 317 1.1 joff err = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 318 1.1 joff 0, BUS_DMA_WAITOK, &sc->ctrlpage_dmamap); 319 1.1 joff } 320 1.1 joff if (err == 0) { 321 1.1 joff err = bus_dmamap_load(sc->sc_dmat, sc->ctrlpage_dmamap, 322 1.1 joff sc->ctrlpage, PAGE_SIZE, NULL, BUS_DMA_WAITOK); 323 1.1 joff } 324 1.1 joff if (err != 0) { 325 1.27 matt panic("%s: Cannot get DMA memory", device_xname(sc->sc_dev)); 326 1.1 joff } 327 1.2 joff sc->ctrlpage_dsaddr = sc->ctrlpage_dmamap->dm_segs[0].ds_addr; 328 1.21 cegger memset(sc->ctrlpage, 0, PAGE_SIZE); 329 1.41 msaitoh 330 1.1 joff /* Set up pointers to start of each queue in kernel addr space. 331 1.1 joff * Each descriptor queue or status queue entry uses 2 words 332 1.1 joff */ 333 1.29 skrll sc->TXDQ = (uint32_t *)sc->ctrlpage; 334 1.1 joff sc->TXDQ_cur = sc->TXDQ; 335 1.1 joff sc->TXDQ_avail = TX_QLEN - 1; 336 1.1 joff sc->TXStsQ = &sc->TXDQ[TX_QLEN * 2]; 337 1.1 joff sc->TXStsQ_cur = sc->TXStsQ; 338 1.1 joff sc->RXDQ = &sc->TXStsQ[TX_QLEN]; 339 1.1 joff sc->RXStsQ = &sc->RXDQ[RX_QLEN * 2]; 340 1.1 joff sc->RXStsQ_cur = sc->RXStsQ; 341 1.1 joff 342 1.1 joff /* Program each queue's start addr, cur addr, and len registers 343 1.41 msaitoh * with the physical addresses. 344 1.1 joff */ 345 1.11 he addr = (char *)sc->ctrlpage_dmamap->dm_segs[0].ds_addr; 346 1.29 skrll EPE_WRITE(TXDQBAdd, (uint32_t)addr); 347 1.29 skrll EPE_WRITE(TXDQCurAdd, (uint32_t)addr); 348 1.41 msaitoh EPE_WRITE(TXDQBLen, TX_QLEN * 2 * sizeof(uint32_t)); 349 1.29 skrll 350 1.29 skrll addr += (sc->TXStsQ - sc->TXDQ) * sizeof(uint32_t); 351 1.29 skrll EPE_WRITE(TXStsQBAdd, (uint32_t)addr); 352 1.29 skrll EPE_WRITE(TXStsQCurAdd, (uint32_t)addr); 353 1.29 skrll EPE_WRITE(TXStsQBLen, TX_QLEN * sizeof(uint32_t)); 354 1.29 skrll 355 1.29 skrll addr += (sc->RXDQ - sc->TXStsQ) * sizeof(uint32_t); 356 1.29 skrll EPE_WRITE(RXDQBAdd, (uint32_t)addr); 357 1.29 skrll EPE_WRITE(RXDCurAdd, (uint32_t)addr); 358 1.29 skrll EPE_WRITE(RXDQBLen, RX_QLEN * 2 * sizeof(uint32_t)); 359 1.41 msaitoh 360 1.29 skrll addr += (sc->RXStsQ - sc->RXDQ) * sizeof(uint32_t); 361 1.29 skrll EPE_WRITE(RXStsQBAdd, (uint32_t)addr); 362 1.29 skrll EPE_WRITE(RXStsQCurAdd, (uint32_t)addr); 363 1.29 skrll EPE_WRITE(RXStsQBLen, RX_QLEN * 2 * sizeof(uint32_t)); 364 1.1 joff 365 1.1 joff /* Populate the RXDQ with mbufs */ 366 1.41 msaitoh for (i = 0; i < RX_QLEN; i++) { 367 1.1 joff struct mbuf *m; 368 1.1 joff 369 1.41 msaitoh bus_dmamap_create(sc->sc_dmat, MCLBYTES, TX_QLEN/4, MCLBYTES, 370 1.41 msaitoh 0, BUS_DMA_WAITOK, &sc->rxq[i].m_dmamap); 371 1.1 joff MGETHDR(m, M_WAIT, MT_DATA); 372 1.1 joff MCLGET(m, M_WAIT); 373 1.1 joff sc->rxq[i].m = m; 374 1.41 msaitoh bus_dmamap_load(sc->sc_dmat, sc->rxq[i].m_dmamap, 375 1.41 msaitoh m->m_ext.ext_buf, MCLBYTES, NULL, BUS_DMA_WAITOK); 376 1.1 joff 377 1.1 joff sc->RXDQ[i * 2] = sc->rxq[i].m_dmamap->dm_segs[0].ds_addr; 378 1.1 joff sc->RXDQ[i * 2 + 1] = (i << 16) | MCLBYTES; 379 1.1 joff bus_dmamap_sync(sc->sc_dmat, sc->rxq[i].m_dmamap, 0, 380 1.1 joff MCLBYTES, BUS_DMASYNC_PREREAD); 381 1.1 joff } 382 1.1 joff 383 1.41 msaitoh for (i = 0; i < TX_QLEN; i++) { 384 1.1 joff bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 385 1.41 msaitoh (BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW), 386 1.1 joff &sc->txq[i].m_dmamap); 387 1.1 joff sc->txq[i].m = NULL; 388 1.1 joff sc->TXDQ[i * 2 + 1] = (i << 16); 389 1.1 joff } 390 1.1 joff 391 1.1 joff /* Divide HCLK by 32 for MDC clock */ 392 1.27 matt if (device_cfdata(sc->sc_dev)->cf_flags) 393 1.27 matt mdcdiv = device_cfdata(sc->sc_dev)->cf_flags; 394 1.41 msaitoh EPE_WRITE(SelfCtl, (SelfCtl_MDCDIV(mdcdiv) | SelfCtl_PSPRS)); 395 1.1 joff 396 1.44 msaitoh mii->mii_ifp = ifp; 397 1.44 msaitoh mii->mii_readreg = epe_mii_readreg; 398 1.44 msaitoh mii->mii_writereg = epe_mii_writereg; 399 1.44 msaitoh mii->mii_statchg = epe_statchg; 400 1.44 msaitoh sc->sc_ec.ec_mii = mii; 401 1.48 thorpej ifmedia_init(&mii->mii_media, IFM_IMASK, ether_mediachange, 402 1.15 dyoung ether_mediastatus); 403 1.44 msaitoh mii_attach(sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, 404 1.44 msaitoh MII_OFFSET_ANY, 0); 405 1.44 msaitoh ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 406 1.1 joff 407 1.41 msaitoh EPE_WRITE(BMCtl, BMCtl_RxEn | BMCtl_TxEn); 408 1.2 joff EPE_WRITE(IntEn, IntEn_REOFIE); 409 1.1 joff /* maximum valid max frame length */ 410 1.41 msaitoh EPE_WRITE(MaxFrmLen, (0x7ff << 16) | MHLEN); 411 1.1 joff /* wait for receiver ready */ 412 1.41 msaitoh while ((EPE_READ(BMSts) & BMSts_RxAct) == 0) 413 1.30 joerg continue; 414 1.1 joff /* enqueue the entries in RXStsQ and RXDQ */ 415 1.41 msaitoh CTRLPAGE_DMASYNC(0, sc->ctrlpage_dmamap->dm_mapsize, 416 1.41 msaitoh BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 417 1.1 joff EPE_WRITE(RXDEnq, RX_QLEN - 1); 418 1.1 joff EPE_WRITE(RXStsEnq, RX_QLEN - 1); 419 1.1 joff 420 1.1 joff /* 421 1.1 joff * We can support 802.1Q VLAN-sized frames. 422 1.1 joff */ 423 1.1 joff sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 424 1.1 joff 425 1.42 msaitoh strcpy(ifp->if_xname, device_xname(sc->sc_dev)); 426 1.42 msaitoh ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 427 1.42 msaitoh ifp->if_ioctl = epe_ifioctl; 428 1.42 msaitoh ifp->if_start = epe_ifstart; 429 1.42 msaitoh ifp->if_watchdog = epe_ifwatchdog; 430 1.42 msaitoh ifp->if_init = epe_ifinit; 431 1.42 msaitoh ifp->if_stop = epe_ifstop; 432 1.42 msaitoh ifp->if_timer = 0; 433 1.1 joff ifp->if_softc = sc; 434 1.42 msaitoh IFQ_SET_READY(&ifp->if_snd); 435 1.42 msaitoh if_attach(ifp); 436 1.36 nonaka if_deferred_start_init(ifp, NULL); 437 1.42 msaitoh ether_ifattach(ifp, (sc)->sc_enaddr); 438 1.1 joff } 439 1.1 joff 440 1.1 joff int 441 1.39 msaitoh epe_mii_readreg(device_t self, int phy, int reg, uint16_t *val) 442 1.1 joff { 443 1.39 msaitoh uint32_t d; 444 1.1 joff 445 1.1 joff d = EPE_READ(SelfCtl); 446 1.1 joff EPE_WRITE(SelfCtl, d & ~SelfCtl_PSPRS); /* no preamble suppress */ 447 1.1 joff EPE_WRITE(MIICmd, (MIICmd_READ | (phy << 5) | reg)); 448 1.41 msaitoh while (EPE_READ(MIISts) & MIISts_BUSY) 449 1.41 msaitoh ; 450 1.39 msaitoh *val = EPE_READ(MIIData) & 0xffff; 451 1.1 joff EPE_WRITE(SelfCtl, d); /* restore old value */ 452 1.39 msaitoh return 0; 453 1.1 joff } 454 1.1 joff 455 1.39 msaitoh int 456 1.39 msaitoh epe_mii_writereg(device_t self, int phy, int reg, uint16_t val) 457 1.1 joff { 458 1.29 skrll uint32_t d; 459 1.1 joff 460 1.1 joff d = EPE_READ(SelfCtl); 461 1.1 joff EPE_WRITE(SelfCtl, d & ~SelfCtl_PSPRS); /* no preamble suppress */ 462 1.3 hamajima EPE_WRITE(MIIData, val); 463 1.1 joff EPE_WRITE(MIICmd, (MIICmd_WRITE | (phy << 5) | reg)); 464 1.41 msaitoh while (EPE_READ(MIISts) & MIISts_BUSY) 465 1.41 msaitoh ; 466 1.1 joff EPE_WRITE(SelfCtl, d); /* restore old value */ 467 1.39 msaitoh 468 1.39 msaitoh return 0; 469 1.1 joff } 470 1.1 joff 471 1.1 joff void 472 1.27 matt epe_statchg(struct ifnet *ifp) 473 1.1 joff { 474 1.42 msaitoh struct epe_softc *sc = ifp->if_softc; 475 1.42 msaitoh uint32_t reg; 476 1.1 joff 477 1.42 msaitoh /* 478 1.42 msaitoh * We must keep the MAC and the PHY in sync as 479 1.42 msaitoh * to the status of full-duplex! 480 1.42 msaitoh */ 481 1.42 msaitoh reg = EPE_READ(TestCtl); 482 1.42 msaitoh if (sc->sc_mii.mii_media_active & IFM_FDX) 483 1.42 msaitoh reg |= TestCtl_MFDX; 484 1.42 msaitoh else 485 1.42 msaitoh reg &= ~TestCtl_MFDX; 486 1.1 joff EPE_WRITE(TestCtl, reg); 487 1.1 joff } 488 1.1 joff 489 1.1 joff void 490 1.19 dsl epe_tick(void *arg) 491 1.1 joff { 492 1.1 joff struct epe_softc* sc = (struct epe_softc *)arg; 493 1.1 joff struct ifnet * ifp = &sc->sc_ec.ec_if; 494 1.2 joff int s; 495 1.29 skrll uint32_t misses; 496 1.1 joff 497 1.47 skrll if_statadd(ifp, if_collisions, EPE_READ(TXCollCnt)); 498 1.1 joff /* These misses are ok, they will happen if the RAM/CPU can't keep up */ 499 1.1 joff misses = EPE_READ(RXMissCnt); 500 1.41 msaitoh if (misses > 0) 501 1.27 matt printf("%s: %d rx misses\n", device_xname(sc->sc_dev), misses); 502 1.41 msaitoh 503 1.2 joff s = splnet(); 504 1.2 joff if (epe_gctx(sc) > 0 && IFQ_IS_EMPTY(&ifp->if_snd) == 0) { 505 1.2 joff epe_ifstart(ifp); 506 1.2 joff } 507 1.2 joff splx(s); 508 1.2 joff 509 1.1 joff mii_tick(&sc->sc_mii); 510 1.1 joff callout_reset(&sc->epe_tick_ch, hz, epe_tick, sc); 511 1.1 joff } 512 1.1 joff 513 1.1 joff 514 1.1 joff static int 515 1.19 dsl epe_ifioctl(struct ifnet *ifp, u_long cmd, void *data) 516 1.1 joff { 517 1.1 joff int s, error; 518 1.1 joff 519 1.1 joff s = splnet(); 520 1.15 dyoung error = ether_ioctl(ifp, cmd, data); 521 1.15 dyoung if (error == ENETRESET) { 522 1.15 dyoung if (ifp->if_flags & IFF_RUNNING) 523 1.15 dyoung epe_setaddr(ifp); 524 1.15 dyoung error = 0; 525 1.1 joff } 526 1.1 joff splx(s); 527 1.1 joff return error; 528 1.1 joff } 529 1.1 joff 530 1.1 joff static void 531 1.19 dsl epe_ifstart(struct ifnet *ifp) 532 1.1 joff { 533 1.1 joff struct epe_softc *sc = (struct epe_softc *)ifp->if_softc; 534 1.1 joff struct mbuf *m; 535 1.1 joff bus_dma_segment_t *segs; 536 1.2 joff int s, bi, err, nsegs, ndq; 537 1.2 joff 538 1.41 msaitoh s = splnet(); 539 1.2 joff start: 540 1.2 joff ndq = 0; 541 1.1 joff if (sc->TXDQ_avail == 0) { 542 1.2 joff if (epe_gctx(sc) == 0) { 543 1.2 joff /* Enable End-Of-TX-Chain interrupt */ 544 1.41 msaitoh EPE_WRITE(IntEn, IntEn_REOFIE | IntEn_ECIE); 545 1.49 thorpej sc->tx_busy = true; 546 1.2 joff ifp->if_timer = 10; 547 1.2 joff splx(s); 548 1.2 joff return; 549 1.2 joff } 550 1.41 msaitoh } 551 1.2 joff 552 1.41 msaitoh bi = sc->TXDQ_cur - sc->TXDQ; 553 1.1 joff 554 1.1 joff IFQ_POLL(&ifp->if_snd, m); 555 1.1 joff if (m == NULL) { 556 1.1 joff splx(s); 557 1.1 joff return; 558 1.1 joff } 559 1.2 joff more: 560 1.1 joff if ((err = bus_dmamap_load_mbuf(sc->sc_dmat, sc->txq[bi].m_dmamap, m, 561 1.41 msaitoh BUS_DMA_NOWAIT)) || 562 1.1 joff sc->txq[bi].m_dmamap->dm_segs[0].ds_addr & 0x3 || 563 1.1 joff sc->txq[bi].m_dmamap->dm_nsegs > (sc->TXDQ_avail - ndq)) { 564 1.1 joff /* Copy entire mbuf chain to new and 32-bit aligned storage */ 565 1.1 joff struct mbuf *mn; 566 1.1 joff 567 1.41 msaitoh if (err == 0) 568 1.1 joff bus_dmamap_unload(sc->sc_dmat, sc->txq[bi].m_dmamap); 569 1.1 joff 570 1.1 joff MGETHDR(mn, M_DONTWAIT, MT_DATA); 571 1.1 joff if (mn == NULL) goto stop; 572 1.1 joff if (m->m_pkthdr.len > (MHLEN & (~0x3))) { 573 1.1 joff MCLGET(mn, M_DONTWAIT); 574 1.1 joff if ((mn->m_flags & M_EXT) == 0) { 575 1.1 joff m_freem(mn); 576 1.1 joff goto stop; 577 1.1 joff } 578 1.1 joff } 579 1.41 msaitoh mn->m_data = (void *)(((uint32_t)mn->m_data + 0x3) & (~0x3)); 580 1.10 christos m_copydata(m, 0, m->m_pkthdr.len, mtod(mn, void *)); 581 1.1 joff mn->m_pkthdr.len = mn->m_len = m->m_pkthdr.len; 582 1.1 joff IFQ_DEQUEUE(&ifp->if_snd, m); 583 1.1 joff m_freem(m); 584 1.1 joff m = mn; 585 1.1 joff bus_dmamap_load_mbuf(sc->sc_dmat, sc->txq[bi].m_dmamap, m, 586 1.1 joff BUS_DMA_NOWAIT); 587 1.1 joff } else { 588 1.1 joff IFQ_DEQUEUE(&ifp->if_snd, m); 589 1.1 joff } 590 1.1 joff 591 1.38 msaitoh bpf_mtap(ifp, m, BPF_D_OUT); 592 1.1 joff 593 1.1 joff nsegs = sc->txq[bi].m_dmamap->dm_nsegs; 594 1.1 joff segs = sc->txq[bi].m_dmamap->dm_segs; 595 1.41 msaitoh bus_dmamap_sync(sc->sc_dmat, sc->txq[bi].m_dmamap, 0, 596 1.41 msaitoh sc->txq[bi].m_dmamap->dm_mapsize, 597 1.41 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 598 1.1 joff 599 1.1 joff /* XXX: This driver hasn't been tested w/nsegs > 1 */ 600 1.1 joff while (nsegs > 0) { 601 1.1 joff nsegs--; 602 1.1 joff sc->txq[bi].m = m; 603 1.1 joff sc->TXDQ[bi * 2] = segs->ds_addr; 604 1.1 joff if (nsegs == 0) 605 1.1 joff sc->TXDQ[bi * 2 + 1] = segs->ds_len | (bi << 16) | 606 1.1 joff (1 << 31); 607 1.1 joff else 608 1.1 joff sc->TXDQ[bi * 2 + 1] = segs->ds_len | (bi << 16); 609 1.1 joff segs++; 610 1.1 joff bi = (bi + 1) % TX_QLEN; 611 1.1 joff ndq++; 612 1.1 joff } 613 1.1 joff 614 1.1 joff 615 1.2 joff /* 616 1.2 joff * Enqueue another. Don't do more than half the available 617 1.2 joff * descriptors before telling the MAC about them 618 1.2 joff */ 619 1.2 joff if ((sc->TXDQ_avail - ndq) > 0 && ndq < TX_QLEN / 2) { 620 1.1 joff IFQ_POLL(&ifp->if_snd, m); 621 1.41 msaitoh if (m != NULL) 622 1.2 joff goto more; 623 1.41 msaitoh } 624 1.1 joff stop: 625 1.1 joff if (ndq > 0) { 626 1.1 joff sc->TXDQ_avail -= ndq; 627 1.1 joff sc->TXDQ_cur = &sc->TXDQ[bi]; 628 1.29 skrll CTRLPAGE_DMASYNC(0, TX_QLEN * 2 * sizeof(uint32_t), 629 1.41 msaitoh BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 630 1.1 joff EPE_WRITE(TXDEnq, ndq); 631 1.1 joff } 632 1.2 joff 633 1.2 joff if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 634 1.2 joff goto start; 635 1.2 joff 636 1.1 joff splx(s); 637 1.1 joff return; 638 1.1 joff } 639 1.1 joff 640 1.1 joff static void 641 1.19 dsl epe_ifwatchdog(struct ifnet *ifp) 642 1.1 joff { 643 1.1 joff struct epe_softc *sc = (struct epe_softc *)ifp->if_softc; 644 1.1 joff 645 1.1 joff if ((ifp->if_flags & IFF_RUNNING) == 0) 646 1.1 joff return; 647 1.42 msaitoh printf("%s: device timeout, BMCtl = 0x%08x, BMSts = 0x%08x\n", 648 1.27 matt device_xname(sc->sc_dev), EPE_READ(BMCtl), EPE_READ(BMSts)); 649 1.1 joff } 650 1.1 joff 651 1.1 joff static int 652 1.19 dsl epe_ifinit(struct ifnet *ifp) 653 1.1 joff { 654 1.1 joff struct epe_softc *sc = ifp->if_softc; 655 1.15 dyoung int rc, s = splnet(); 656 1.1 joff 657 1.1 joff callout_stop(&sc->epe_tick_ch); 658 1.41 msaitoh EPE_WRITE(RXCtl, RXCtl_IA0 | RXCtl_BA | RXCtl_RCRCA | RXCtl_SRxON); 659 1.1 joff EPE_WRITE(TXCtl, TXCtl_STxON); 660 1.1 joff EPE_WRITE(GIIntMsk, GIIntMsk_INT); /* start interrupting */ 661 1.15 dyoung 662 1.15 dyoung if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO) 663 1.15 dyoung rc = 0; 664 1.15 dyoung else if (rc != 0) 665 1.15 dyoung goto out; 666 1.15 dyoung 667 1.1 joff callout_reset(&sc->epe_tick_ch, hz, epe_tick, sc); 668 1.42 msaitoh ifp->if_flags |= IFF_RUNNING; 669 1.15 dyoung out: 670 1.1 joff splx(s); 671 1.1 joff return 0; 672 1.1 joff } 673 1.1 joff 674 1.1 joff static void 675 1.19 dsl epe_ifstop(struct ifnet *ifp, int disable) 676 1.1 joff { 677 1.1 joff struct epe_softc *sc = ifp->if_softc; 678 1.1 joff 679 1.1 joff 680 1.1 joff EPE_WRITE(RXCtl, 0); 681 1.1 joff EPE_WRITE(TXCtl, 0); 682 1.1 joff EPE_WRITE(GIIntMsk, 0); 683 1.1 joff callout_stop(&sc->epe_tick_ch); 684 1.1 joff 685 1.1 joff /* Down the MII. */ 686 1.1 joff mii_down(&sc->sc_mii); 687 1.1 joff 688 1.49 thorpej ifp->if_flags &= ~IFF_RUNNING; 689 1.1 joff ifp->if_timer = 0; 690 1.1 joff sc->sc_mii.mii_media_status &= ~IFM_ACTIVE; 691 1.1 joff } 692 1.1 joff 693 1.1 joff static void 694 1.19 dsl epe_setaddr(struct ifnet *ifp) 695 1.1 joff { 696 1.1 joff struct epe_softc *sc = ifp->if_softc; 697 1.41 msaitoh struct ethercom *ec = &sc->sc_ec; 698 1.1 joff struct ether_multi *enm; 699 1.1 joff struct ether_multistep step; 700 1.29 skrll uint8_t ias[2][ETHER_ADDR_LEN]; 701 1.29 skrll uint32_t h, nma = 0, hashes[2] = { 0, 0 }; 702 1.29 skrll uint32_t rxctl = EPE_READ(RXCtl); 703 1.1 joff 704 1.1 joff /* disable receiver temporarily */ 705 1.1 joff EPE_WRITE(RXCtl, rxctl & ~RXCtl_SRxON); 706 1.1 joff 707 1.41 msaitoh rxctl &= ~(RXCtl_MA | RXCtl_PA | RXCtl_IA2 | RXCtl_IA3); 708 1.41 msaitoh 709 1.41 msaitoh if (ifp->if_flags & IFF_PROMISC) 710 1.1 joff rxctl |= RXCtl_PA; 711 1.1 joff 712 1.1 joff ifp->if_flags &= ~IFF_ALLMULTI; 713 1.1 joff 714 1.43 msaitoh ETHER_LOCK(ec); 715 1.41 msaitoh ETHER_FIRST_MULTI(step, ec, enm); 716 1.1 joff while (enm != NULL) { 717 1.1 joff if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 718 1.1 joff /* 719 1.1 joff * We must listen to a range of multicast addresses. 720 1.1 joff * For now, just accept all multicasts, rather than 721 1.1 joff * trying to set only those filter bits needed to match 722 1.1 joff * the range. (At this time, the only use of address 723 1.1 joff * ranges is for IP multicast routing, for which the 724 1.1 joff * range is big enough to require all bits set.) 725 1.1 joff */ 726 1.41 msaitoh rxctl &= ~(RXCtl_IA2 | RXCtl_IA3); 727 1.1 joff rxctl |= RXCtl_MA; 728 1.1 joff hashes[0] = 0xffffffffUL; 729 1.1 joff hashes[1] = 0xffffffffUL; 730 1.1 joff ifp->if_flags |= IFF_ALLMULTI; 731 1.1 joff break; 732 1.1 joff } 733 1.1 joff 734 1.1 joff if (nma < 2) { 735 1.1 joff /* We can program 2 perfect address filters for mcast */ 736 1.41 msaitoh memcpy(ias[nma], enm->enm_addrlo, ETHER_ADDR_LEN); 737 1.1 joff rxctl |= (1 << (nma + 2)); 738 1.1 joff } else { 739 1.1 joff /* 740 1.1 joff * XXX: Datasheet is not very clear here, I'm not sure 741 1.1 joff * if I'm doing this right. --joff 742 1.1 joff */ 743 1.1 joff h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); 744 1.1 joff 745 1.1 joff /* Just want the 6 most-significant bits. */ 746 1.1 joff h = h >> 26; 747 1.1 joff 748 1.1 joff hashes[ h / 32 ] |= (1 << (h % 32)); 749 1.1 joff rxctl |= RXCtl_MA; 750 1.1 joff } 751 1.1 joff ETHER_NEXT_MULTI(step, enm); 752 1.1 joff nma++; 753 1.1 joff } 754 1.43 msaitoh ETHER_UNLOCK(ec); 755 1.41 msaitoh 756 1.1 joff EPE_WRITE(AFP, 0); 757 1.41 msaitoh bus_space_write_region_1(sc->sc_iot, sc->sc_ioh, EPE_IndAd, 758 1.1 joff sc->sc_enaddr, ETHER_ADDR_LEN); 759 1.1 joff if (rxctl & RXCtl_IA2) { 760 1.1 joff EPE_WRITE(AFP, 2); 761 1.1 joff bus_space_write_region_1(sc->sc_iot, sc->sc_ioh, EPE_IndAd, 762 1.1 joff ias[0], ETHER_ADDR_LEN); 763 1.1 joff } 764 1.1 joff if (rxctl & RXCtl_IA3) { 765 1.1 joff EPE_WRITE(AFP, 3); 766 1.1 joff bus_space_write_region_1(sc->sc_iot, sc->sc_ioh, EPE_IndAd, 767 1.1 joff ias[1], ETHER_ADDR_LEN); 768 1.1 joff } 769 1.1 joff if (hashes[0] != 0 && hashes[1] != 0) { 770 1.1 joff EPE_WRITE(AFP, 7); 771 1.1 joff EPE_WRITE(HashTbl, hashes[0]); 772 1.1 joff EPE_WRITE(HashTbl + 4, hashes[1]); 773 1.1 joff } 774 1.1 joff EPE_WRITE(RXCtl, rxctl); 775 1.1 joff } 776