1 /* $NetBSD: if_cemac.c,v 1.46 2025/10/12 23:30:13 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Genetec Corporation. All rights reserved. 5 * Written by Hashimoto Kenichi for Genetec Corporation. 6 * 7 * Based on arch/arm/at91/at91emac.c 8 * 9 * Copyright (c) 2007 Embedtronics Oy 10 * All rights reserved. 11 * 12 * Copyright (c) 2004 Jesse Off 13 * All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 /* 38 * Cadence EMAC/GEM ethernet controller IP driver 39 * used by arm/at91, arm/zynq SoC 40 */ 41 42 /* 43 * Lock order: 44 * 45 * IFNET_LOCK -> sc_mcast_lock 46 * IFNET_LOCK -> sc_intr_lock 47 */ 48 49 50 #include <sys/cdefs.h> 51 __KERNEL_RCSID(0, "$NetBSD: if_cemac.c,v 1.46 2025/10/12 23:30:13 thorpej Exp $"); 52 53 #include <sys/param.h> 54 #include <sys/types.h> 55 56 #include <sys/bus.h> 57 #include <sys/device.h> 58 #include <sys/kernel.h> 59 #include <sys/proc.h> 60 #include <sys/systm.h> 61 #include <sys/time.h> 62 63 #include <net/if.h> 64 #include <net/if_dl.h> 65 #include <net/if_types.h> 66 #include <net/if_media.h> 67 #include <net/if_ether.h> 68 #include <net/bpf.h> 69 70 #include <dev/mii/mii.h> 71 #include <dev/mii/miivar.h> 72 73 #ifdef INET 74 #include <netinet/in.h> 75 #include <netinet/in_systm.h> 76 #include <netinet/in_var.h> 77 #include <netinet/ip.h> 78 #include <netinet/if_inarp.h> 79 #endif 80 81 #include <dev/cadence/cemacreg.h> 82 #include <dev/cadence/if_cemacvar.h> 83 84 #ifndef CEMAC_WATCHDOG_TIMEOUT 85 #define CEMAC_WATCHDOG_TIMEOUT 5 86 #endif 87 static int cemac_watchdog_timeout = CEMAC_WATCHDOG_TIMEOUT; 88 89 #define DEFAULT_MDCDIV 32 90 91 #define CEMAC_READ(x) \ 92 bus_space_read_4(sc->sc_iot, sc->sc_ioh, (x)) 93 #define CEMAC_WRITE(x, y) \ 94 bus_space_write_4(sc->sc_iot, sc->sc_ioh, (x), (y)) 95 #define CEMAC_GEM_WRITE(x, y) \ 96 do { \ 97 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) \ 98 bus_space_write_4(sc->sc_iot, sc->sc_ioh, (GEM_##x), (y)); \ 99 else \ 100 bus_space_write_4(sc->sc_iot, sc->sc_ioh, (ETH_##x), (y)); \ 101 } while(0) 102 103 static void cemac_init(struct cemac_softc *); 104 static int cemac_gctx(struct cemac_softc *); 105 static int cemac_mediachange(struct ifnet *); 106 static void cemac_mediastatus(struct ifnet *, struct ifmediareq *); 107 static int cemac_mii_readreg(device_t, int, int, uint16_t *); 108 static int cemac_mii_writereg(device_t, int, int, uint16_t); 109 static void cemac_statchg(struct ifnet *); 110 static void cemac_tick(void *); 111 static int cemac_ifioctl(struct ifnet *, u_long, void *); 112 static void cemac_ifstart(struct ifnet *); 113 static void cemac_ifstart_locked(struct ifnet *); 114 static void cemac_ifwatchdog(struct ifnet *); 115 static int cemac_ifinit(struct ifnet *); 116 static void cemac_ifstop(struct ifnet *, int); 117 static void cemac_setaddr(struct ifnet *); 118 119 #ifdef CEMAC_DEBUG 120 int cemac_debug = CEMAC_DEBUG; 121 #define DPRINTFN(n, fmt) if (cemac_debug >= (n)) printf fmt 122 #else 123 #define DPRINTFN(n, fmt) 124 #endif 125 126 /* 127 * Perform an interface watchdog reset. 128 */ 129 static void 130 cemac_handle_reset_work(struct work *work, void *arg) 131 { 132 struct cemac_softc * const sc = arg; 133 struct ifnet * const ifp = &sc->sc_ethercom.ec_if; 134 135 printf("%s: watchdog timeout -- resetting\n", ifp->if_xname); 136 137 /* Don't want ioctl operations to happen */ 138 IFNET_LOCK(ifp); 139 140 /* reset the interface. */ 141 cemac_ifinit(ifp); 142 143 IFNET_UNLOCK(ifp); 144 145 /* 146 * There are still some upper layer processing which call 147 * ifp->if_start(). e.g. ALTQ or one CPU system 148 */ 149 /* Try to get more packets going. */ 150 ifp->if_start(ifp); 151 152 atomic_store_relaxed(&sc->sc_reset_pending, 0); 153 } 154 155 156 void 157 cemac_attach_common(struct cemac_softc *sc) 158 { 159 uint32_t u; 160 161 aprint_naive("\n"); 162 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 163 aprint_normal(": Cadence Gigabit Ethernet Controller\n"); 164 else 165 aprint_normal(": Cadence Ethernet Controller\n"); 166 167 /* configure emac: */ 168 CEMAC_WRITE(ETH_CTL, 0); // disable everything 169 CEMAC_WRITE(ETH_IDR, -1); // disable interrupts 170 CEMAC_WRITE(ETH_RBQP, 0); // clear receive 171 CEMAC_WRITE(ETH_TBQP, 0); // clear transmit 172 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 173 CEMAC_WRITE(ETH_CFG, 174 GEM_CFG_CLK_64 | GEM_CFG_GEN | ETH_CFG_SPD | ETH_CFG_FD); 175 else 176 CEMAC_WRITE(ETH_CFG, 177 ETH_CFG_CLK_32 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG); 178 //CEMAC_WRITE(ETH_TCR, 0); // send nothing 179 //(void)CEMAC_READ(ETH_ISR); 180 u = CEMAC_READ(ETH_TSR); 181 CEMAC_WRITE(ETH_TSR, (u & (ETH_TSR_UND | ETH_TSR_COMP | ETH_TSR_BNQ 182 | ETH_TSR_IDLE | ETH_TSR_RLE 183 | ETH_TSR_COL | ETH_TSR_OVR))); 184 u = CEMAC_READ(ETH_RSR); 185 CEMAC_WRITE(ETH_RSR, (u & (ETH_RSR_OVR | ETH_RSR_REC | ETH_RSR_BNA))); 186 187 /* Fetch the Ethernet address from property if set. */ 188 if (! ether_getaddr(sc->sc_dev, sc->sc_enaddr)) { 189 static const uint8_t hardcoded[ETHER_ADDR_LEN] = { 190 0x00, 0x0d, 0x10, 0x81, 0x0c, 0x94 191 }; 192 memcpy(sc->sc_enaddr, hardcoded, ETHER_ADDR_LEN); 193 } 194 195 cemac_init(sc); 196 } 197 198 static int 199 cemac_gctx(struct cemac_softc *sc) 200 { 201 uint32_t tsr; 202 203 tsr = CEMAC_READ(ETH_TSR); 204 if (!ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) { 205 // no space left 206 if (!(tsr & ETH_TSR_BNQ)) 207 return 0; 208 } else { 209 if (tsr & GEM_TSR_TXGO) 210 return 0; 211 } 212 CEMAC_WRITE(ETH_TSR, tsr); 213 214 // free sent frames 215 while (sc->txqc > (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM) ? 0 : 216 (tsr & ETH_TSR_IDLE ? 0 : 1))) { 217 int bi = sc->txqi % TX_QLEN; 218 219 DPRINTFN(3,("%s: TDSC[%i].Addr 0x%08x\n", 220 __FUNCTION__, bi, sc->TDSC[bi].Addr)); 221 DPRINTFN(3,("%s: TDSC[%i].Info 0x%08x\n", 222 __FUNCTION__, bi, sc->TDSC[bi].Info)); 223 224 bus_dmamap_sync(sc->sc_dmat, sc->txq[bi].m_dmamap, 0, 225 sc->txq[bi].m->m_pkthdr.len, BUS_DMASYNC_POSTWRITE); 226 bus_dmamap_unload(sc->sc_dmat, sc->txq[bi].m_dmamap); 227 m_freem(sc->txq[bi].m); 228 DPRINTFN(2,("%s: freed idx #%i mbuf %p (txqc=%i)\n", 229 __FUNCTION__, bi, sc->txq[bi].m, sc->txqc)); 230 sc->txq[bi].m = NULL; 231 sc->txqi = (bi + 1) % TX_QLEN; 232 sc->txqc--; 233 } 234 235 // mark we're free 236 if (sc->sc_txbusy) { 237 sc->sc_txbusy = false; 238 /* Disable transmit-buffer-free interrupt */ 239 /*CEMAC_WRITE(ETH_IDR, ETH_ISR_TBRE);*/ 240 } 241 242 return 1; 243 } 244 245 int 246 cemac_intr(void *arg) 247 { 248 struct cemac_softc * const sc = arg; 249 struct ifnet * const ifp = &sc->sc_ethercom.ec_if; 250 uint32_t imr, isr, ctl; 251 #ifdef CEMAC_DEBUG 252 uint32_t rsr; 253 #endif 254 int bi; 255 256 mutex_enter(sc->sc_intr_lock); 257 if (sc->sc_stopping) { 258 mutex_exit(sc->sc_intr_lock); 259 return 0; 260 } 261 262 imr = ~CEMAC_READ(ETH_IMR); 263 if (!(imr & (ETH_ISR_RCOM | ETH_ISR_TBRE | ETH_ISR_TIDLE | 264 ETH_ISR_RBNA | ETH_ISR_ROVR | ETH_ISR_TCOM))) { 265 // interrupt not enabled, can't be us 266 mutex_exit(sc->sc_intr_lock); 267 return 0; 268 } 269 270 isr = CEMAC_READ(ETH_ISR); 271 CEMAC_WRITE(ETH_ISR, isr); 272 isr &= imr; 273 274 if (isr == 0) { 275 mutex_exit(sc->sc_intr_lock); 276 return 0; 277 } 278 279 #ifdef CEMAC_DEBUG 280 rsr = CEMAC_READ(ETH_RSR); // get receive status register 281 #endif 282 DPRINTFN(2, ("%s: isr=0x%08X rsr=0x%08X imr=0x%08X\n", __FUNCTION__, 283 isr, rsr, imr)); 284 285 net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 286 // out of receive buffers 287 if (isr & ETH_ISR_RBNA) { 288 // clear interrupt 289 CEMAC_WRITE(ETH_RSR, ETH_RSR_BNA); 290 291 ctl = CEMAC_READ(ETH_CTL); 292 // disable receiver 293 CEMAC_WRITE(ETH_CTL, ctl & ~ETH_CTL_RE); 294 // clear BNA bit 295 CEMAC_WRITE(ETH_RSR, ETH_RSR_BNA); 296 // re-enable receiver 297 CEMAC_WRITE(ETH_CTL, ctl | ETH_CTL_RE); 298 299 if_statinc_ref(ifp, nsr, if_ierrors); 300 if_statinc_ref(ifp, nsr, if_ipackets); 301 DPRINTFN(1,("%s: out of receive buffers\n", __FUNCTION__)); 302 } 303 if (isr & ETH_ISR_ROVR) { 304 // clear interrupt 305 CEMAC_WRITE(ETH_RSR, ETH_RSR_OVR); 306 if_statinc_ref(ifp, nsr, if_ierrors); 307 if_statinc_ref(ifp, nsr, if_ipackets); 308 DPRINTFN(1,("%s: receive overrun\n", __FUNCTION__)); 309 } 310 311 // packet has been received! 312 if (isr & ETH_ISR_RCOM) { 313 uint32_t nfo; 314 DPRINTFN(2,("#2 RDSC[%i].INFO=0x%08X\n", sc->rxqi % RX_QLEN, 315 sc->RDSC[sc->rxqi % RX_QLEN].Info)); 316 while (sc->RDSC[(bi = sc->rxqi % RX_QLEN)].Addr & ETH_RDSC_F_USED) { 317 int fl, csum; 318 struct mbuf *m; 319 320 nfo = sc->RDSC[bi].Info; 321 fl = (nfo & ETH_RDSC_I_LEN) - 4; 322 DPRINTFN(2,("## nfo=0x%08X\n", nfo)); 323 324 MGETHDR(m, M_DONTWAIT, MT_DATA); 325 if (m != NULL) 326 MCLGET(m, M_DONTWAIT); 327 if (m != NULL && (m->m_flags & M_EXT)) { 328 bus_dmamap_sync(sc->sc_dmat, 329 sc->rxq[bi].m_dmamap, 0, MCLBYTES, 330 BUS_DMASYNC_POSTREAD); 331 bus_dmamap_unload(sc->sc_dmat, 332 sc->rxq[bi].m_dmamap); 333 m_set_rcvif(sc->rxq[bi].m, ifp); 334 sc->rxq[bi].m->m_pkthdr.len = 335 sc->rxq[bi].m->m_len = fl; 336 switch (nfo & ETH_RDSC_I_CHKSUM) { 337 case ETH_RDSC_I_CHKSUM_IP: 338 csum = M_CSUM_IPv4; 339 break; 340 case ETH_RDSC_I_CHKSUM_UDP: 341 csum = M_CSUM_IPv4 | M_CSUM_UDPv4 | 342 M_CSUM_UDPv6; 343 break; 344 case ETH_RDSC_I_CHKSUM_TCP: 345 csum = M_CSUM_IPv4 | M_CSUM_TCPv4 | 346 M_CSUM_TCPv6; 347 break; 348 default: 349 csum = 0; 350 break; 351 } 352 sc->rxq[bi].m->m_pkthdr.csum_flags = csum; 353 DPRINTFN(2,("received %u bytes packet\n", fl)); 354 if_percpuq_enqueue(ifp->if_percpuq, 355 sc->rxq[bi].m); 356 if (mtod(m, intptr_t) & 3) 357 m_adj(m, mtod(m, intptr_t) & 3); 358 sc->rxq[bi].m = m; 359 bus_dmamap_load(sc->sc_dmat, 360 sc->rxq[bi].m_dmamap, m->m_ext.ext_buf, 361 MCLBYTES, NULL, BUS_DMA_NOWAIT); 362 bus_dmamap_sync(sc->sc_dmat, 363 sc->rxq[bi].m_dmamap, 0, MCLBYTES, 364 BUS_DMASYNC_PREREAD); 365 sc->RDSC[bi].Info = 0; 366 sc->RDSC[bi].Addr = 367 sc->rxq[bi].m_dmamap->dm_segs[0].ds_addr 368 | (bi == (RX_QLEN-1) ? ETH_RDSC_F_WRAP : 0); 369 } else { 370 /* Drop packets until we can get replacement 371 * empty mbufs for the RXDQ. 372 */ 373 m_freem(m); 374 if_statinc_ref(ifp, nsr, if_ierrors); 375 } 376 sc->rxqi++; 377 } 378 } 379 380 IF_STAT_PUTREF(ifp); 381 382 if (cemac_gctx(sc) > 0) 383 if_schedule_deferred_start(ifp); 384 #if 0 // reloop 385 irq = CEMAC_READ(IntStsC); 386 if ((irq & (IntSts_RxSQ | IntSts_ECI)) != 0) 387 goto begin; 388 #endif 389 390 mutex_exit(sc->sc_intr_lock); 391 392 return 1; 393 } 394 395 396 static int 397 cemac_ifflags_cb(struct ethercom *ec) 398 { 399 struct ifnet * const ifp = &ec->ec_if; 400 struct cemac_softc * const sc = ifp->if_softc; 401 int ret = 0; 402 403 KASSERT(IFNET_LOCKED(ifp)); 404 mutex_enter(sc->sc_mcast_lock); 405 406 u_short change = ifp->if_flags ^ sc->sc_if_flags; 407 sc->sc_if_flags = ifp->if_flags; 408 409 if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) { 410 ret = ENETRESET; 411 } else if ((change & IFF_PROMISC) != 0) { 412 if ((sc->sc_if_flags & IFF_RUNNING) != 0) 413 cemac_setaddr(ifp); 414 } 415 mutex_exit(sc->sc_mcast_lock); 416 417 return ret; 418 } 419 420 static void 421 cemac_init(struct cemac_softc *sc) 422 { 423 bus_dma_segment_t segs; 424 int rsegs, err, i; 425 struct ifnet * const ifp = &sc->sc_ethercom.ec_if; 426 struct mii_data * const mii = &sc->sc_mii; 427 uint32_t u; 428 #if 0 429 int mdcdiv = DEFAULT_MDCDIV; 430 #endif 431 432 callout_init(&sc->cemac_tick_ch, CALLOUT_MPSAFE); 433 callout_setfunc(&sc->cemac_tick_ch, cemac_tick, sc); 434 435 // ok... 436 CEMAC_WRITE(ETH_CTL, ETH_CTL_MPE); // disable everything 437 CEMAC_WRITE(ETH_IDR, -1); // disable interrupts 438 CEMAC_WRITE(ETH_RBQP, 0); // clear receive 439 CEMAC_WRITE(ETH_TBQP, 0); // clear transmit 440 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 441 CEMAC_WRITE(ETH_CFG, 442 GEM_CFG_CLK_64 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG); 443 else 444 CEMAC_WRITE(ETH_CFG, 445 ETH_CFG_CLK_32 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG); 446 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) { 447 CEMAC_WRITE(GEM_DMA_CFG, 448 __SHIFTIN((MCLBYTES + 63) / 64, GEM_DMA_CFG_RX_BUF_SIZE) | 449 __SHIFTIN(3, GEM_DMA_CFG_RX_PKTBUF_MEMSZ_SEL) | 450 GEM_DMA_CFG_TX_PKTBUF_MEMSZ_SEL | 451 __SHIFTIN(16, GEM_DMA_CFG_AHB_FIXED_BURST_LEN) | 452 GEM_DMA_CFG_DISC_WHEN_NO_AHB); 453 } 454 // CEMAC_WRITE(ETH_TCR, 0); // send nothing 455 // (void)CEMAC_READ(ETH_ISR); 456 u = CEMAC_READ(ETH_TSR); 457 CEMAC_WRITE(ETH_TSR, (u & (ETH_TSR_UND | ETH_TSR_COMP | ETH_TSR_BNQ 458 | ETH_TSR_IDLE | ETH_TSR_RLE 459 | ETH_TSR_COL | ETH_TSR_OVR))); 460 u = CEMAC_READ(ETH_RSR); 461 CEMAC_WRITE(ETH_RSR, (u & (ETH_RSR_OVR | ETH_RSR_REC | ETH_RSR_BNA))); 462 463 #if 0 464 if (device_cfdata(sc->sc_dev)->cf_flags) 465 mdcdiv = device_cfdata(sc->sc_dev)->cf_flags; 466 #endif 467 /* set ethernet address */ 468 CEMAC_GEM_WRITE(SA1L, (sc->sc_enaddr[3] << 24) 469 | (sc->sc_enaddr[2] << 16) | (sc->sc_enaddr[1] << 8) 470 | (sc->sc_enaddr[0])); 471 CEMAC_GEM_WRITE(SA1H, (sc->sc_enaddr[5] << 8) 472 | (sc->sc_enaddr[4])); 473 CEMAC_GEM_WRITE(SA2L, 0); 474 CEMAC_GEM_WRITE(SA2H, 0); 475 CEMAC_GEM_WRITE(SA3L, 0); 476 CEMAC_GEM_WRITE(SA3H, 0); 477 CEMAC_GEM_WRITE(SA4L, 0); 478 CEMAC_GEM_WRITE(SA4H, 0); 479 480 char wqname[MAXCOMLEN]; 481 snprintf(wqname, sizeof(wqname), "%sReset", device_xname(sc->sc_dev)); 482 int error = workqueue_create(&sc->sc_reset_wq, wqname, 483 cemac_handle_reset_work, sc, PRI_NONE, IPL_SOFTCLOCK, 484 WQ_MPSAFE); 485 if (error) { 486 aprint_error_dev(sc->sc_dev, 487 "unable to create reset workqueue\n"); 488 return; 489 } 490 491 /* Allocate memory for receive queue descriptors */ 492 sc->rbqlen = roundup(ETH_DSC_SIZE * (RX_QLEN + 1) * 2, PAGE_SIZE); 493 DPRINTFN(1,("%s: rbqlen=%i\n", __FUNCTION__, sc->rbqlen)); 494 495 // see EMAC errata why forced to 16384 byte boundary 496 err = bus_dmamem_alloc(sc->sc_dmat, sc->rbqlen, 0, 497 MAX(16384, PAGE_SIZE), &segs, 1, &rsegs, BUS_DMA_WAITOK); 498 if (err == 0) { 499 DPRINTFN(1,("%s: -> bus_dmamem_map\n", __FUNCTION__)); 500 err = bus_dmamem_map(sc->sc_dmat, &segs, 1, sc->rbqlen, 501 &sc->rbqpage, (BUS_DMA_WAITOK | BUS_DMA_COHERENT)); 502 } 503 if (err == 0) { 504 DPRINTFN(1,("%s: -> bus_dmamap_create\n", __FUNCTION__)); 505 err = bus_dmamap_create(sc->sc_dmat, sc->rbqlen, 1, 506 sc->rbqlen, MAX(16384, PAGE_SIZE), BUS_DMA_WAITOK, 507 &sc->rbqpage_dmamap); 508 } 509 if (err == 0) { 510 DPRINTFN(1,("%s: -> bus_dmamap_load\n", __FUNCTION__)); 511 err = bus_dmamap_load(sc->sc_dmat, sc->rbqpage_dmamap, 512 sc->rbqpage, sc->rbqlen, NULL, BUS_DMA_WAITOK); 513 } 514 if (err != 0) 515 panic("%s: Cannot get DMA memory", device_xname(sc->sc_dev)); 516 517 sc->rbqpage_dsaddr = sc->rbqpage_dmamap->dm_segs[0].ds_addr; 518 memset(sc->rbqpage, 0, sc->rbqlen); 519 520 /* Allocate memory for transmit queue descriptors */ 521 sc->tbqlen = roundup(ETH_DSC_SIZE * (TX_QLEN + 1) * 2, PAGE_SIZE); 522 DPRINTFN(1,("%s: tbqlen=%i\n", __FUNCTION__, sc->tbqlen)); 523 524 // see EMAC errata why forced to 16384 byte boundary 525 err = bus_dmamem_alloc(sc->sc_dmat, sc->tbqlen, 0, 526 MAX(16384, PAGE_SIZE), &segs, 1, &rsegs, BUS_DMA_WAITOK); 527 if (err == 0) { 528 DPRINTFN(1,("%s: -> bus_dmamem_map\n", __FUNCTION__)); 529 err = bus_dmamem_map(sc->sc_dmat, &segs, 1, sc->tbqlen, 530 &sc->tbqpage, (BUS_DMA_WAITOK | BUS_DMA_COHERENT)); 531 } 532 if (err == 0) { 533 DPRINTFN(1,("%s: -> bus_dmamap_create\n", __FUNCTION__)); 534 err = bus_dmamap_create(sc->sc_dmat, sc->tbqlen, 1, 535 sc->tbqlen, MAX(16384, PAGE_SIZE), BUS_DMA_WAITOK, 536 &sc->tbqpage_dmamap); 537 } 538 if (err == 0) { 539 DPRINTFN(1,("%s: -> bus_dmamap_load\n", __FUNCTION__)); 540 err = bus_dmamap_load(sc->sc_dmat, sc->tbqpage_dmamap, 541 sc->tbqpage, sc->tbqlen, NULL, BUS_DMA_WAITOK); 542 } 543 if (err != 0) 544 panic("%s: Cannot get DMA memory", device_xname(sc->sc_dev)); 545 546 sc->tbqpage_dsaddr = sc->tbqpage_dmamap->dm_segs[0].ds_addr; 547 memset(sc->tbqpage, 0, sc->tbqlen); 548 549 /* Set up pointers to start of each queue in kernel addr space. 550 * Each descriptor queue or status queue entry uses 2 words 551 */ 552 sc->RDSC = (void *)sc->rbqpage; 553 sc->TDSC = (void *)sc->tbqpage; 554 555 /* init TX queue */ 556 for (i = 0; i < TX_QLEN; i++) { 557 sc->TDSC[i].Addr = 0; 558 sc->TDSC[i].Info = ETH_TDSC_I_USED | 559 (i == (TX_QLEN - 1) ? ETH_TDSC_I_WRAP : 0); 560 } 561 562 /* Populate the RXQ with mbufs */ 563 sc->rxqi = 0; 564 for (i = 0; i < RX_QLEN; i++) { 565 struct mbuf *m; 566 567 err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 568 PAGE_SIZE, BUS_DMA_WAITOK, &sc->rxq[i].m_dmamap); 569 if (err) { 570 panic("%s: dmamap_create failed: %i\n", __FUNCTION__, 571 err); 572 } 573 MGETHDR(m, M_WAIT, MT_DATA); 574 MCLGET(m, M_WAIT); 575 sc->rxq[i].m = m; 576 if (mtod(m, intptr_t) & 3) { 577 m_adj(m, mtod(m, intptr_t) & 3); 578 } 579 err = bus_dmamap_load(sc->sc_dmat, sc->rxq[i].m_dmamap, 580 m->m_ext.ext_buf, MCLBYTES, NULL, 581 BUS_DMA_WAITOK); 582 if (err) { 583 panic("%s: dmamap_load failed: %i\n", __FUNCTION__, err); 584 } 585 sc->RDSC[i].Addr = sc->rxq[i].m_dmamap->dm_segs[0].ds_addr 586 | (i == (RX_QLEN-1) ? ETH_RDSC_F_WRAP : 0); 587 sc->RDSC[i].Info = 0; 588 bus_dmamap_sync(sc->sc_dmat, sc->rxq[i].m_dmamap, 0, 589 MCLBYTES, BUS_DMASYNC_PREREAD); 590 } 591 592 /* prepare transmit queue */ 593 for (i = 0; i < TX_QLEN; i++) { 594 err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 595 (BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW), 596 &sc->txq[i].m_dmamap); 597 if (err) 598 panic("ARGH #1"); 599 sc->txq[i].m = NULL; 600 } 601 602 /* Program each queue's start addr, cur addr, and len registers 603 * with the physical addresses. 604 */ 605 CEMAC_WRITE(ETH_RBQP, (uint32_t)sc->rbqpage_dsaddr); 606 CEMAC_WRITE(ETH_TBQP, (uint32_t)sc->tbqpage_dsaddr); 607 608 sc->sc_mcast_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); 609 sc->sc_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); 610 611 /* Divide HCLK by 32 for MDC clock */ 612 sc->sc_ethercom.ec_mii = mii; 613 mii->mii_ifp = ifp; 614 mii->mii_readreg = cemac_mii_readreg; 615 mii->mii_writereg = cemac_mii_writereg; 616 mii->mii_statchg = cemac_statchg; 617 ifmedia_init(&mii->mii_media, IFM_IMASK, cemac_mediachange, 618 cemac_mediastatus); 619 mii_attach(sc->sc_dev, mii, 0xffffffff, sc->sc_phyno, MII_OFFSET_ANY, 0); 620 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 621 622 #if 0 623 // enable / disable interrupts 624 CEMAC_WRITE(ETH_IDR, -1); 625 CEMAC_WRITE(ETH_IER, ETH_ISR_RCOM | ETH_ISR_TBRE | ETH_ISR_TIDLE 626 | ETH_ISR_RBNA | ETH_ISR_ROVR | ETH_ISR_TCOM); 627 // (void)CEMAC_READ(ETH_ISR); // why 628 629 // enable transmitter / receiver 630 CEMAC_WRITE(ETH_CTL, ETH_CTL_TE | ETH_CTL_RE | ETH_CTL_ISR 631 | ETH_CTL_CSR | ETH_CTL_MPE); 632 #endif 633 /* 634 * We can support hardware checksumming. 635 */ 636 ifp->if_capabilities |= 637 IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx | 638 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 639 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx | 640 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx | 641 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx; 642 643 /* 644 * We can support 802.1Q VLAN-sized frames. 645 */ 646 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 647 648 strcpy(ifp->if_xname, device_xname(sc->sc_dev)); 649 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 650 ifp->if_extflags = IFEF_MPSAFE; 651 ifp->if_ioctl = cemac_ifioctl; 652 ifp->if_start = cemac_ifstart; 653 ifp->if_watchdog = cemac_ifwatchdog; 654 ifp->if_init = cemac_ifinit; 655 ifp->if_stop = cemac_ifstop; 656 ifp->if_softc = sc; 657 IFQ_SET_READY(&ifp->if_snd); 658 if_attach(ifp); 659 if_deferred_start_init(ifp, NULL); 660 ether_ifattach(ifp, (sc)->sc_enaddr); 661 ether_set_ifflags_cb(&sc->sc_ethercom, cemac_ifflags_cb); 662 } 663 664 static int 665 cemac_mediachange(struct ifnet *ifp) 666 { 667 if (ifp->if_flags & IFF_UP) 668 cemac_ifinit(ifp); 669 return 0; 670 } 671 672 static void 673 cemac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 674 { 675 struct cemac_softc * const sc = ifp->if_softc; 676 677 mii_pollstat(&sc->sc_mii); 678 ifmr->ifm_active = sc->sc_mii.mii_media_active; 679 ifmr->ifm_status = sc->sc_mii.mii_media_status; 680 } 681 682 683 static int 684 cemac_mii_readreg(device_t self, int phy, int reg, uint16_t *val) 685 { 686 struct cemac_softc * const sc = device_private(self); 687 688 CEMAC_WRITE(ETH_MAN, (ETH_MAN_HIGH | ETH_MAN_RW_RD 689 | ((phy << ETH_MAN_PHYA_SHIFT) & ETH_MAN_PHYA) 690 | ((reg << ETH_MAN_REGA_SHIFT) & ETH_MAN_REGA) 691 | ETH_MAN_CODE_IEEE802_3)); 692 while (!(CEMAC_READ(ETH_SR) & ETH_SR_IDLE)) 693 ; 694 695 *val = CEMAC_READ(ETH_MAN) & ETH_MAN_DATA; 696 return 0; 697 } 698 699 static int 700 cemac_mii_writereg(device_t self, int phy, int reg, uint16_t val) 701 { 702 struct cemac_softc * const sc = device_private(self); 703 704 CEMAC_WRITE(ETH_MAN, (ETH_MAN_HIGH | ETH_MAN_RW_WR 705 | ((phy << ETH_MAN_PHYA_SHIFT) & ETH_MAN_PHYA) 706 | ((reg << ETH_MAN_REGA_SHIFT) & ETH_MAN_REGA) 707 | ETH_MAN_CODE_IEEE802_3 708 | (val & ETH_MAN_DATA))); 709 while (!(CEMAC_READ(ETH_SR) & ETH_SR_IDLE)) 710 ; 711 712 return 0; 713 } 714 715 716 static void 717 cemac_statchg(struct ifnet *ifp) 718 { 719 struct cemac_softc * const sc = ifp->if_softc; 720 struct mii_data *mii = &sc->sc_mii; 721 uint32_t reg; 722 723 /* 724 * We must keep the MAC and the PHY in sync as 725 * to the status of full-duplex! 726 */ 727 reg = CEMAC_READ(ETH_CFG); 728 reg &= ~ETH_CFG_FD; 729 if (sc->sc_mii.mii_media_active & IFM_FDX) 730 reg |= ETH_CFG_FD; 731 732 reg &= ~ETH_CFG_SPD; 733 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 734 reg &= ~GEM_CFG_GEN; 735 switch (IFM_SUBTYPE(mii->mii_media_active)) { 736 case IFM_10_T: 737 break; 738 case IFM_100_TX: 739 reg |= ETH_CFG_SPD; 740 break; 741 case IFM_1000_T: 742 reg |= ETH_CFG_SPD | GEM_CFG_GEN; 743 break; 744 default: 745 break; 746 } 747 CEMAC_WRITE(ETH_CFG, reg); 748 } 749 750 static bool 751 cemac_watchdog_check(struct cemac_softc * const sc) 752 { 753 754 KASSERT(mutex_owned(sc->sc_intr_lock)); 755 756 if (!sc->sc_tx_sending) 757 return true; 758 759 if (time_uptime - sc->sc_tx_lastsent <= cemac_watchdog_timeout) 760 return true; 761 762 return false; 763 } 764 765 static bool 766 cemac_watchdog_tick(struct ifnet *ifp) 767 { 768 struct cemac_softc * const sc = ifp->if_softc; 769 770 KASSERT(mutex_owned(sc->sc_intr_lock)); 771 772 if (!sc->sc_trigger_reset && cemac_watchdog_check(sc)) 773 return true; 774 775 if (atomic_swap_uint(&sc->sc_reset_pending, 1) == 0) 776 workqueue_enqueue(sc->sc_reset_wq, &sc->sc_reset_work, NULL); 777 778 return false; 779 } 780 781 782 static void 783 cemac_tick(void *arg) 784 { 785 struct cemac_softc * const sc = arg; 786 struct ifnet * const ifp = &sc->sc_ethercom.ec_if; 787 788 mutex_enter(sc->sc_intr_lock); 789 if (sc->sc_stopping) { 790 mutex_exit(sc->sc_intr_lock); 791 return; 792 } 793 794 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 795 if_statadd(ifp, if_collisions, 796 CEMAC_READ(GEM_SCOL) + CEMAC_READ(GEM_MCOL)); 797 else 798 if_statadd(ifp, if_collisions, 799 CEMAC_READ(ETH_SCOL) + CEMAC_READ(ETH_MCOL)); 800 801 /* These misses are ok, they will happen if the RAM/CPU can't keep up */ 802 if (!ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) { 803 uint32_t misses = CEMAC_READ(ETH_DRFC); 804 if (misses > 0) 805 aprint_normal_ifnet(ifp, "%d rx misses\n", misses); 806 } 807 808 mii_tick(&sc->sc_mii); 809 810 const bool ok = cemac_watchdog_tick(ifp); 811 if (ok) 812 callout_schedule(&sc->cemac_tick_ch, hz); 813 814 mutex_exit(sc->sc_intr_lock); 815 } 816 817 818 static int 819 cemac_ifioctl(struct ifnet *ifp, u_long cmd, void *data) 820 { 821 struct cemac_softc * const sc = ifp->if_softc; 822 int error; 823 824 switch (cmd) { 825 case SIOCADDMULTI: 826 case SIOCDELMULTI: 827 break; 828 default: 829 KASSERT(IFNET_LOCKED(ifp)); 830 } 831 832 const int s = splnet(); 833 error = ether_ioctl(ifp, cmd, data); 834 splx(s); 835 836 if (error == ENETRESET) { 837 error = 0; 838 839 if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) { 840 mutex_enter(sc->sc_mcast_lock); 841 if ((sc->sc_if_flags & IFF_RUNNING) != 0) 842 cemac_setaddr(ifp); 843 844 mutex_exit(sc->sc_mcast_lock); 845 } 846 } 847 848 return error; 849 } 850 851 852 853 static void 854 cemac_ifstart(struct ifnet *ifp) 855 { 856 struct cemac_softc * const sc = ifp->if_softc; 857 KASSERT(if_is_mpsafe(ifp)); 858 859 mutex_enter(sc->sc_intr_lock); 860 if (!sc->sc_stopping) { 861 cemac_ifstart_locked(ifp); 862 } 863 mutex_exit(sc->sc_intr_lock); 864 } 865 866 static void 867 cemac_ifstart_locked(struct ifnet *ifp) 868 { 869 struct cemac_softc * const sc = ifp->if_softc; 870 struct mbuf *m; 871 bus_dma_segment_t *segs; 872 int bi, err, nsegs; 873 874 KASSERT(mutex_owned(sc->sc_intr_lock)); 875 876 start: 877 if (cemac_gctx(sc) == 0) { 878 /* Enable transmit-buffer-free interrupt */ 879 CEMAC_WRITE(ETH_IER, ETH_ISR_TBRE); 880 sc->sc_txbusy = true; 881 return; 882 } 883 884 IFQ_POLL(&ifp->if_snd, m); 885 if (m == NULL) { 886 return; 887 } 888 889 bi = (sc->txqi + sc->txqc) % TX_QLEN; 890 if ((err = bus_dmamap_load_mbuf(sc->sc_dmat, sc->txq[bi].m_dmamap, m, 891 BUS_DMA_NOWAIT)) || 892 sc->txq[bi].m_dmamap->dm_segs[0].ds_addr & 0x3 || 893 sc->txq[bi].m_dmamap->dm_nsegs > 1) { 894 /* Copy entire mbuf chain to new single */ 895 struct mbuf *mn; 896 897 if (err == 0) 898 bus_dmamap_unload(sc->sc_dmat, sc->txq[bi].m_dmamap); 899 900 MGETHDR(mn, M_DONTWAIT, MT_DATA); 901 if (mn == NULL) 902 return; 903 if (m->m_pkthdr.len > MHLEN) { 904 MCLGET(mn, M_DONTWAIT); 905 if ((mn->m_flags & M_EXT) == 0) { 906 m_freem(mn); 907 return; 908 } 909 } 910 m_copydata(m, 0, m->m_pkthdr.len, mtod(mn, void *)); 911 mn->m_pkthdr.len = mn->m_len = m->m_pkthdr.len; 912 IFQ_DEQUEUE(&ifp->if_snd, m); 913 m_freem(m); 914 m = mn; 915 bus_dmamap_load_mbuf(sc->sc_dmat, sc->txq[bi].m_dmamap, m, 916 BUS_DMA_NOWAIT); 917 } else { 918 IFQ_DEQUEUE(&ifp->if_snd, m); 919 } 920 921 bpf_mtap(ifp, m, BPF_D_OUT); 922 923 nsegs = sc->txq[bi].m_dmamap->dm_nsegs; 924 segs = sc->txq[bi].m_dmamap->dm_segs; 925 if (nsegs > 1) 926 panic("#### ARGH #2"); 927 928 sc->txq[bi].m = m; 929 sc->txqc++; 930 931 DPRINTFN(2,("%s: start sending idx #%i mbuf %p (txqc=%i, phys %p), " 932 "len=%u\n", __FUNCTION__, bi, sc->txq[bi].m, sc->txqc, 933 (void *)segs->ds_addr, (unsigned)m->m_pkthdr.len)); 934 #ifdef DIAGNOSTIC 935 if (sc->txqc > TX_QLEN) 936 panic("%s: txqc %i > %i", __FUNCTION__, sc->txqc, TX_QLEN); 937 #endif 938 939 bus_dmamap_sync(sc->sc_dmat, sc->txq[bi].m_dmamap, 0, 940 sc->txq[bi].m_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE); 941 942 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) { 943 sc->TDSC[bi].Addr = segs->ds_addr; 944 sc->TDSC[bi].Info = 945 __SHIFTIN(m->m_pkthdr.len, ETH_TDSC_I_LEN) | 946 ETH_TDSC_I_LAST_BUF | 947 (bi == (TX_QLEN - 1) ? ETH_TDSC_I_WRAP : 0); 948 949 DPRINTFN(3,("%s: TDSC[%i].Addr 0x%08x\n", 950 __FUNCTION__, bi, sc->TDSC[bi].Addr)); 951 DPRINTFN(3,("%s: TDSC[%i].Info 0x%08x\n", 952 __FUNCTION__, bi, sc->TDSC[bi].Info)); 953 954 uint32_t ctl = CEMAC_READ(ETH_CTL) | GEM_CTL_STARTTX; 955 CEMAC_WRITE(ETH_CTL, ctl); 956 DPRINTFN(3,("%s: ETH_CTL 0x%08x\n", __FUNCTION__, 957 CEMAC_READ(ETH_CTL))); 958 } else { 959 CEMAC_WRITE(ETH_TAR, segs->ds_addr); 960 CEMAC_WRITE(ETH_TCR, m->m_pkthdr.len); 961 } 962 sc->sc_tx_lastsent = time_uptime; 963 964 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 965 goto start; 966 967 return; 968 } 969 970 static void 971 cemac_ifwatchdog(struct ifnet *ifp) 972 { 973 struct cemac_softc * const sc = ifp->if_softc; 974 975 if ((ifp->if_flags & IFF_RUNNING) == 0) 976 return; 977 aprint_error_ifnet(ifp, "device timeout, CTL = 0x%08x, CFG = 0x%08x\n", 978 CEMAC_READ(ETH_CTL), CEMAC_READ(ETH_CFG)); 979 } 980 981 static int 982 cemac_ifinit(struct ifnet *ifp) 983 { 984 struct cemac_softc * const sc = ifp->if_softc; 985 uint32_t dma, cfg; 986 987 ASSERT_SLEEPABLE(); 988 KASSERT(IFNET_LOCKED(ifp)); 989 990 /* Cancel pending I/O and flush buffers. */ 991 cemac_ifstop(ifp, 0); 992 993 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) { 994 995 if (ifp->if_capenable & 996 (IFCAP_CSUM_IPv4_Tx | 997 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx | 998 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx)) { 999 dma = CEMAC_READ(GEM_DMA_CFG); 1000 dma |= GEM_DMA_CFG_CHKSUM_GEN_OFFLOAD_EN; 1001 CEMAC_WRITE(GEM_DMA_CFG, dma); 1002 } 1003 if (ifp->if_capenable & 1004 (IFCAP_CSUM_IPv4_Rx | 1005 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | 1006 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx)) { 1007 cfg = CEMAC_READ(ETH_CFG); 1008 cfg |= GEM_CFG_RXCOEN; 1009 CEMAC_WRITE(ETH_CFG, cfg); 1010 } 1011 } 1012 1013 // enable interrupts 1014 CEMAC_WRITE(ETH_IDR, -1); 1015 CEMAC_WRITE(ETH_IER, ETH_ISR_RCOM | ETH_ISR_TBRE | ETH_ISR_TIDLE 1016 | ETH_ISR_RBNA | ETH_ISR_ROVR | ETH_ISR_TCOM); 1017 1018 // enable transmitter / receiver 1019 CEMAC_WRITE(ETH_CTL, ETH_CTL_TE | ETH_CTL_RE | ETH_CTL_ISR 1020 | ETH_CTL_CSR | ETH_CTL_MPE); 1021 1022 mii_mediachg(&sc->sc_mii); 1023 callout_reset(&sc->cemac_tick_ch, hz, cemac_tick, sc); 1024 ifp->if_flags |= IFF_RUNNING; 1025 1026 mutex_enter(sc->sc_intr_lock); 1027 sc->sc_stopping = false; 1028 mutex_exit(sc->sc_intr_lock); 1029 1030 return 0; 1031 } 1032 1033 static void 1034 cemac_ifstop(struct ifnet *ifp, int disable) 1035 { 1036 // uint32_t u; 1037 struct cemac_softc * const sc = ifp->if_softc; 1038 1039 ASSERT_SLEEPABLE(); 1040 KASSERT(IFNET_LOCKED(ifp)); 1041 1042 ifp->if_flags &= ~IFF_RUNNING; 1043 1044 mutex_enter(sc->sc_mcast_lock); 1045 sc->sc_if_flags = ifp->if_flags; 1046 mutex_exit(sc->sc_mcast_lock); 1047 1048 mutex_enter(sc->sc_intr_lock); 1049 sc->sc_stopping = true; 1050 mutex_exit(sc->sc_intr_lock); 1051 1052 #if 0 1053 CEMAC_WRITE(ETH_CTL, ETH_CTL_MPE); // disable everything 1054 CEMAC_WRITE(ETH_IDR, -1); // disable interrupts 1055 // CEMAC_WRITE(ETH_RBQP, 0); // clear receive 1056 if (ISSET(sc->cemac_flags, CEMAC_FLAG_GEM)) 1057 CEMAC_WRITE(ETH_CFG, 1058 GEM_CFG_CLK_64 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG); 1059 else 1060 CEMAC_WRITE(ETH_CFG, 1061 ETH_CFG_CLK_32 | ETH_CFG_SPD | ETH_CFG_FD | ETH_CFG_BIG); 1062 // CEMAC_WRITE(ETH_TCR, 0); // send nothing 1063 // (void)CEMAC_READ(ETH_ISR); 1064 u = CEMAC_READ(ETH_TSR); 1065 CEMAC_WRITE(ETH_TSR, (u & (ETH_TSR_UND | ETH_TSR_COMP | ETH_TSR_BNQ 1066 | ETH_TSR_IDLE | ETH_TSR_RLE 1067 | ETH_TSR_COL | ETH_TSR_OVR))); 1068 u = CEMAC_READ(ETH_RSR); 1069 CEMAC_WRITE(ETH_RSR, (u & (ETH_RSR_OVR | ETH_RSR_REC | ETH_RSR_BNA))); 1070 #endif 1071 callout_halt(&sc->cemac_tick_ch, NULL); 1072 1073 /* Down the MII. */ 1074 mii_down(&sc->sc_mii); 1075 1076 ifp->if_flags &= ~IFF_RUNNING; 1077 sc->sc_txbusy = false; 1078 sc->sc_mii.mii_media_status &= ~IFM_ACTIVE; 1079 } 1080 1081 static void 1082 cemac_setaddr(struct ifnet *ifp) 1083 { 1084 struct cemac_softc * const sc = ifp->if_softc; 1085 struct ethercom *ec = &sc->sc_ethercom; 1086 struct ether_multi *enm; 1087 struct ether_multistep step; 1088 uint8_t ias[3][ETHER_ADDR_LEN]; 1089 uint32_t h, nma = 0, hashes[2] = { 0, 0 }; 1090 uint32_t ctl = CEMAC_READ(ETH_CTL); 1091 uint32_t cfg = CEMAC_READ(ETH_CFG); 1092 1093 KASSERT(mutex_owned(sc->sc_mcast_lock)); 1094 1095 /* disable receiver temporarily */ 1096 CEMAC_WRITE(ETH_CTL, ctl & ~ETH_CTL_RE); 1097 1098 cfg &= ~(ETH_CFG_MTI | ETH_CFG_UNI | ETH_CFG_CAF | ETH_CFG_UNI); 1099 1100 if (sc->sc_if_flags & IFF_PROMISC) { 1101 cfg |= ETH_CFG_CAF; 1102 } else { 1103 cfg &= ~ETH_CFG_CAF; 1104 } 1105 1106 // ETH_CFG_BIG? 1107 1108 ETHER_LOCK(ec); 1109 ec->ec_flags &= ~ETHER_F_ALLMULTI; 1110 1111 ETHER_FIRST_MULTI(step, ec, enm); 1112 while (enm != NULL) { 1113 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 1114 /* 1115 * We must listen to a range of multicast addresses. 1116 * For now, just accept all multicasts, rather than 1117 * trying to set only those filter bits needed to match 1118 * the range. (At this time, the only use of address 1119 * ranges is for IP multicast routing, for which the 1120 * range is big enough to require all bits set.) 1121 */ 1122 cfg |= ETH_CFG_MTI; 1123 hashes[0] = 0xffffffffUL; 1124 hashes[1] = 0xffffffffUL; 1125 nma = 0; 1126 ec->ec_flags |= ETHER_F_ALLMULTI; 1127 break; 1128 } 1129 1130 if (nma < 3) { 1131 /* We can program 3 perfect address filters for mcast */ 1132 memcpy(ias[nma], enm->enm_addrlo, ETHER_ADDR_LEN); 1133 } else { 1134 /* 1135 * XXX: Datasheet is not very clear here, I'm not sure 1136 * if I'm doing this right. --joff 1137 */ 1138 h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); 1139 1140 /* Just want the 6 most-significant bits. */ 1141 h = h >> 26; 1142 #if 0 1143 hashes[h / 32] |= (1 << (h % 32)); 1144 #else 1145 hashes[0] = 0xffffffffUL; 1146 hashes[1] = 0xffffffffUL; 1147 #endif 1148 cfg |= ETH_CFG_MTI; 1149 } 1150 ETHER_NEXT_MULTI(step, enm); 1151 nma++; 1152 } 1153 ETHER_UNLOCK(ec); 1154 1155 // program... 1156 DPRINTFN(1,("%s: en0 %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, 1157 sc->sc_enaddr[0], sc->sc_enaddr[1], sc->sc_enaddr[2], 1158 sc->sc_enaddr[3], sc->sc_enaddr[4], sc->sc_enaddr[5])); 1159 CEMAC_GEM_WRITE(SA1L, (sc->sc_enaddr[3] << 24) 1160 | (sc->sc_enaddr[2] << 16) | (sc->sc_enaddr[1] << 8) 1161 | (sc->sc_enaddr[0])); 1162 CEMAC_GEM_WRITE(SA1H, (sc->sc_enaddr[5] << 8) 1163 | (sc->sc_enaddr[4])); 1164 if (nma > 0) { 1165 DPRINTFN(1,("%s: en1 %02x:%02x:%02x:%02x:%02x:%02x\n", 1166 __FUNCTION__, 1167 ias[0][0], ias[0][1], ias[0][2], 1168 ias[0][3], ias[0][4], ias[0][5])); 1169 CEMAC_WRITE(ETH_SA2L, (ias[0][3] << 24) 1170 | (ias[0][2] << 16) | (ias[0][1] << 8) 1171 | (ias[0][0])); 1172 CEMAC_WRITE(ETH_SA2H, (ias[0][4] << 8) 1173 | (ias[0][5])); 1174 } 1175 if (nma > 1) { 1176 DPRINTFN(1,("%s: en2 %02x:%02x:%02x:%02x:%02x:%02x\n", 1177 __FUNCTION__, 1178 ias[1][0], ias[1][1], ias[1][2], 1179 ias[1][3], ias[1][4], ias[1][5])); 1180 CEMAC_WRITE(ETH_SA3L, (ias[1][3] << 24) 1181 | (ias[1][2] << 16) | (ias[1][1] << 8) 1182 | (ias[1][0])); 1183 CEMAC_WRITE(ETH_SA3H, (ias[1][4] << 8) 1184 | (ias[1][5])); 1185 } 1186 if (nma > 2) { 1187 DPRINTFN(1,("%s: en3 %02x:%02x:%02x:%02x:%02x:%02x\n", 1188 __FUNCTION__, 1189 ias[2][0], ias[2][1], ias[2][2], 1190 ias[2][3], ias[2][4], ias[2][5])); 1191 CEMAC_WRITE(ETH_SA4L, (ias[2][3] << 24) 1192 | (ias[2][2] << 16) | (ias[2][1] << 8) 1193 | (ias[2][0])); 1194 CEMAC_WRITE(ETH_SA4H, (ias[2][4] << 8) 1195 | (ias[2][5])); 1196 } 1197 CEMAC_GEM_WRITE(HSH, hashes[0]); 1198 CEMAC_GEM_WRITE(HSL, hashes[1]); 1199 CEMAC_WRITE(ETH_CFG, cfg); 1200 CEMAC_WRITE(ETH_CTL, ctl | ETH_CTL_RE); 1201 } 1202