1 /* $NetBSD: if_aumac.c,v 1.2 2002/07/29 16:25:03 simonb Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Device driver for Alchemy Semiconductor Au1x00 Ethernet Media 40 * Access Controller. 41 * 42 * TODO: 43 * 44 * Better Rx buffer management; we want to get new Rx buffers 45 * to the chip more quickly than we currently do. 46 */ 47 48 #include <sys/cdefs.h> 49 __KERNEL_RCSID(0, "$NetBSD: if_aumac.c,v 1.2 2002/07/29 16:25:03 simonb Exp $"); 50 51 #include "bpfilter.h" 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/callout.h> 56 #include <sys/mbuf.h> 57 #include <sys/malloc.h> 58 #include <sys/kernel.h> 59 #include <sys/socket.h> 60 #include <sys/ioctl.h> 61 #include <sys/errno.h> 62 #include <sys/device.h> 63 #include <sys/queue.h> 64 65 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 66 67 #include <net/if.h> 68 #include <net/if_dl.h> 69 #include <net/if_media.h> 70 #include <net/if_ether.h> 71 72 #if NBPFILTER > 0 73 #include <net/bpf.h> 74 #endif 75 76 #include <machine/bus.h> 77 #include <machine/intr.h> 78 #include <machine/endian.h> 79 80 #include <dev/mii/mii.h> 81 #include <dev/mii/miivar.h> 82 83 #include <mips/alchemy/include/aureg.h> 84 #include <mips/alchemy/include/auvar.h> 85 #include <mips/alchemy/include/aubusvar.h> 86 #include <mips/alchemy/dev/if_aumacreg.h> 87 88 /* 89 * The Au1X00 MAC has 4 transmit and receive descriptors. Each buffer 90 * must consist of a single DMA segment, and must be aligned to a 2K 91 * boundary. Therefore, this driver does not perform DMA directly 92 * to/from mbufs. Instead, we copy the data to/from buffers allocated 93 * at device attach time. 94 * 95 * We also skip the bus_dma dance. The MAC is built in to the CPU, so 96 * there's little point in not making assumptions based on the CPU type. 97 * We also program the Au1X00 cache to be DMA coherent, so the buffers 98 * are accessed via KSEG0 addresses. 99 */ 100 #define AUMAC_NTXDESC 4 101 #define AUMAC_NTXDESC_MASK (AUMAC_NTXDESC - 1) 102 103 #define AUMAC_NRXDESC 4 104 #define AUMAC_NRXDESC_MASK (AUMAC_NRXDESC - 1) 105 106 #define AUMAC_NEXTTX(x) (((x) + 1) & AUMAC_NTXDESC_MASK) 107 #define AUMAC_NEXTRX(x) (((x) + 1) & AUMAC_NRXDESC_MASK) 108 109 #define AUMAC_TXBUF_OFFSET 0 110 #define AUMAC_RXBUF_OFFSET (MAC_BUFLEN * AUMAC_NTXDESC) 111 #define AUMAC_BUFSIZE (MAC_BUFLEN * (AUMAC_NTXDESC + AUMAC_NRXDESC)) 112 113 struct aumac_buf { 114 caddr_t buf_vaddr; /* virtual address of buffer */ 115 bus_addr_t buf_paddr; /* DMA address of buffer */ 116 }; 117 118 /* 119 * Software state per device. 120 */ 121 struct aumac_softc { 122 struct device sc_dev; /* generic device information */ 123 bus_space_tag_t sc_st; /* bus space tag */ 124 bus_space_handle_t sc_mac_sh; /* MAC space handle */ 125 bus_space_handle_t sc_macen_sh; /* MAC enable space handle */ 126 bus_space_handle_t sc_dma_sh; /* DMA space handle */ 127 struct ethercom sc_ethercom; /* Ethernet common data */ 128 void *sc_sdhook; /* shutdown hook */ 129 130 void *sc_ih; /* interrupt cookie */ 131 132 struct mii_data sc_mii; /* MII/media information */ 133 134 struct callout sc_tick_ch; /* tick callout */ 135 136 /* Transmit and receive buffers */ 137 struct aumac_buf sc_txbufs[AUMAC_NTXDESC]; 138 struct aumac_buf sc_rxbufs[AUMAC_NRXDESC]; 139 caddr_t sc_bufaddr; 140 141 int sc_txfree; /* number of free Tx descriptors */ 142 int sc_txnext; /* next Tx descriptor to use */ 143 int sc_txdirty; /* first dirty Tx descriptor */ 144 145 int sc_rxptr; /* next ready Rx descriptor */ 146 147 #ifdef AUMAC_EVENT_COUNTERS 148 struct evcnt sc_ev_txstall; /* Tx stalled */ 149 struct evcnt sc_ev_rxstall; /* Rx stalled */ 150 struct evcnt sc_ev_txintr; /* Tx interrupts */ 151 struct evcnt sc_ev_rxintr; /* Rx interrupts */ 152 #endif 153 154 uint32_t sc_control; /* MAC_CONTROL contents */ 155 uint32_t sc_flowctrl; /* MAC_FLOWCTRL contents */ 156 }; 157 158 #ifdef AUMAC_EVENT_COUNTERS 159 #define AUMAC_EVCNT_INCR(ev) (ev)->ev_count++ 160 #endif 161 162 #define AUMAC_INIT_RXDESC(sc, x) \ 163 do { \ 164 bus_space_write_4((sc)->sc_st, (sc)->sc_dma_sh, \ 165 MACDMA_RX_STAT((x)), 0); \ 166 bus_space_write_4((sc)->sc_st, (sc)->sc_dma_sh, \ 167 MACDMA_RX_ADDR((x)), \ 168 (sc)->sc_rxbufs[(x)].buf_paddr | RX_ADDR_EN); \ 169 } while (/*CONSTCOND*/0) 170 171 static void aumac_start(struct ifnet *); 172 static void aumac_watchdog(struct ifnet *); 173 static int aumac_ioctl(struct ifnet *, u_long, caddr_t); 174 static int aumac_init(struct ifnet *); 175 static void aumac_stop(struct ifnet *, int); 176 177 static void aumac_shutdown(void *); 178 179 static void aumac_tick(void *); 180 181 static void aumac_set_filter(struct aumac_softc *); 182 183 static void aumac_powerup(struct aumac_softc *); 184 static void aumac_powerdown(struct aumac_softc *); 185 186 static int aumac_intr(void *); 187 static void aumac_txintr(struct aumac_softc *); 188 static void aumac_rxintr(struct aumac_softc *); 189 190 static int aumac_mii_readreg(struct device *, int, int); 191 static void aumac_mii_writereg(struct device *, int, int, int); 192 static void aumac_mii_statchg(struct device *); 193 static int aumac_mii_wait(struct aumac_softc *, const char *); 194 195 static int aumac_mediachange(struct ifnet *); 196 static void aumac_mediastatus(struct ifnet *, struct ifmediareq *); 197 198 static int aumac_match(struct device *, struct cfdata *, void *); 199 static void aumac_attach(struct device *, struct device *, void *); 200 201 int aumac_copy_small = 0; 202 203 struct cfattach aumac_ca = { 204 sizeof(struct aumac_softc), aumac_match, aumac_attach, 205 }; 206 207 static const struct { 208 bus_addr_t mac_base; 209 bus_addr_t macen_base; 210 bus_addr_t macdma_base; 211 } regmap[] = { 212 { MAC0_BASE, MAC0_ENABLE, MAC0_DMA_BASE }, 213 { MAC1_BASE, MAC1_ENABLE, MAC1_DMA_BASE }, 214 }; 215 216 static int 217 aumac_match(struct device *parent, struct cfdata *cf, void *aux) 218 { 219 struct aubus_attach_args *aa = aux; 220 221 if (strcmp(aa->aa_name, cf->cf_driver->cd_name) == 0) 222 return (1); 223 224 return (0); 225 } 226 227 static void 228 aumac_attach(struct device *parent, struct device *self, void *aux) 229 { 230 char prop_name[sizeof("0xffffffff:mac-addr") + 1]; 231 uint8_t enaddr[ETHER_ADDR_LEN]; 232 struct aumac_softc *sc = (void *) self; 233 struct aubus_attach_args *aa = aux; 234 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 235 struct pglist pglist; 236 paddr_t bufaddr; 237 caddr_t vbufaddr; 238 int i; 239 240 callout_init(&sc->sc_tick_ch); 241 242 printf(": Au1X00 10/100 Ethernet\n"); 243 244 sc->sc_st = aa->aa_st; 245 246 /* Get the MAC address. */ 247 snprintf(prop_name, sizeof(prop_name), "%p:mac-addr", self); 248 if (alchemy_info_get(prop_name, enaddr, sizeof(enaddr)) == -1) { 249 printf("%s: unable to determine MAC address\n", 250 sc->sc_dev.dv_xname); 251 return; 252 } 253 254 printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, 255 ether_sprintf(enaddr)); 256 257 /* Map the device. */ 258 if (bus_space_map(sc->sc_st, aa->aa_addrs[AA_MAC_BASE], 259 MACx_SIZE, 0, &sc->sc_mac_sh) != 0) { 260 printf("%s: unable to map MAC registers\n", 261 sc->sc_dev.dv_xname); 262 return; 263 } 264 if (bus_space_map(sc->sc_st, aa->aa_addrs[AA_MAC_ENABLE], 265 MACENx_SIZE, 0, &sc->sc_macen_sh) != 0) { 266 printf("%s: unable to map MACEN registers\n", 267 sc->sc_dev.dv_xname); 268 return; 269 } 270 if (bus_space_map(sc->sc_st, aa->aa_addrs[AA_MAC_DMA_BASE], 271 MACx_DMA_SIZE, 0, &sc->sc_dma_sh) != 0) { 272 printf("%s: unable to map MACDMA registers\n", 273 sc->sc_dev.dv_xname); 274 return; 275 } 276 277 /* Make sure the MAC is powered off. */ 278 aumac_powerdown(sc); 279 280 /* Hook up the interrupt handler. */ 281 sc->sc_ih = au_intr_establish(aa->aa_irq[0], 1, IPL_NET, IST_LEVEL, 282 aumac_intr, sc); 283 if (sc->sc_ih == NULL) { 284 printf("%s: unable to register interrupt handler\n", 285 sc->sc_dev.dv_xname); 286 return; 287 } 288 289 /* 290 * Allocate space for the transmit and receive buffers. 291 */ 292 if (uvm_pglistalloc(AUMAC_BUFSIZE, 0, ctob(physmem), PAGE_SIZE, 0, 293 &pglist, 1, 0)) 294 return; 295 296 bufaddr = TAILQ_FIRST(&pglist)->phys_addr; 297 vbufaddr = (void *)MIPS_PHYS_TO_KSEG0(bufaddr); 298 299 for (i = 0; i < AUMAC_NTXDESC; i++) { 300 int offset = AUMAC_TXBUF_OFFSET + (i * MAC_BUFLEN); 301 302 sc->sc_txbufs[i].buf_vaddr = vbufaddr + offset; 303 sc->sc_txbufs[i].buf_paddr = bufaddr + offset; 304 } 305 306 for (i = 0; i < AUMAC_NRXDESC; i++) { 307 int offset = AUMAC_RXBUF_OFFSET + (i * MAC_BUFLEN); 308 309 sc->sc_rxbufs[i].buf_vaddr = vbufaddr + offset; 310 sc->sc_rxbufs[i].buf_paddr = bufaddr + offset; 311 } 312 313 /* 314 * Power up the MAC before accessing any MAC registers (including 315 * MII configuration. 316 */ 317 aumac_powerup(sc); 318 319 /* 320 * Initialize the media structures and probe the MII. 321 */ 322 sc->sc_mii.mii_ifp = ifp; 323 sc->sc_mii.mii_readreg = aumac_mii_readreg; 324 sc->sc_mii.mii_writereg = aumac_mii_writereg; 325 sc->sc_mii.mii_statchg = aumac_mii_statchg; 326 ifmedia_init(&sc->sc_mii.mii_media, 0, aumac_mediachange, 327 aumac_mediastatus); 328 329 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 330 MII_OFFSET_ANY, 0); 331 332 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 333 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); 334 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); 335 } else 336 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 337 338 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 339 ifp->if_softc = sc; 340 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 341 ifp->if_ioctl = aumac_ioctl; 342 ifp->if_start = aumac_start; 343 ifp->if_watchdog = aumac_watchdog; 344 ifp->if_init = aumac_init; 345 ifp->if_stop = aumac_stop; 346 IFQ_SET_READY(&ifp->if_snd); 347 348 /* Attach the interface. */ 349 if_attach(ifp); 350 ether_ifattach(ifp, enaddr); 351 352 #ifdef AUMAC_EVENT_COUNTERS 353 evcnt_attach_dynamic(&sc->sc_ev_txstall, EVCNT_TYPE_MISC, 354 NULL, sc->sc_dev.dv_xname, "txstall"); 355 evcnt_attach_dynamic(&sc->sc_ev_rxstall, EVCNT_TYPE_MISC, 356 NULL, sc->sc_dev.dv_xname, "rxstall"); 357 evcnt_attach_dynamic(&sc->sc_ev_txintr, EVCNT_TYPE_MISC, 358 NULL, sc->sc_dev.dv_xname, "txintr"); 359 evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_MISC, 360 NULL, sc->sc_dev.dv_xname, "txintr"); 361 #endif 362 363 /* Make sure the interface is shutdown during reboot. */ 364 sc->sc_sdhook = shutdownhook_establish(aumac_shutdown, sc); 365 if (sc->sc_sdhook == NULL) 366 printf("%s: WARNING: unable to establish shutdown hook\n", 367 sc->sc_dev.dv_xname); 368 return; 369 } 370 371 /* 372 * aumac_shutdown: 373 * 374 * Make sure the interface is stopped at reboot time. 375 */ 376 static void 377 aumac_shutdown(void *arg) 378 { 379 struct aumac_softc *sc = arg; 380 381 aumac_stop(&sc->sc_ethercom.ec_if, 1); 382 383 /* 384 * XXX aumac_stop leaves device powered up at the moment 385 * XXX but this still isn't enough to keep yamon happy... :-( 386 */ 387 bus_space_write_4(sc->sc_st, sc->sc_macen_sh, 0, 0); 388 } 389 390 /* 391 * aumac_start: [ifnet interface function] 392 * 393 * Start packet transmission on the interface. 394 */ 395 static void 396 aumac_start(struct ifnet *ifp) 397 { 398 struct aumac_softc *sc = ifp->if_softc; 399 struct mbuf *m; 400 int nexttx; 401 402 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 403 return; 404 405 /* 406 * Loop through the send queue, setting up transmit descriptors 407 * unitl we drain the queue, or use up all available transmit 408 * descriptors. 409 */ 410 for (;;) { 411 /* Grab a packet off the queue. */ 412 IFQ_POLL(&ifp->if_snd, m); 413 if (m == NULL) 414 return; 415 416 /* Get a spare descriptor. */ 417 if (sc->sc_txfree == 0) { 418 /* No more slots left; notify upper layer. */ 419 ifp->if_flags |= IFF_OACTIVE; 420 #ifdef AUMAC_EVENT_COUNTERS 421 AUMAC_EVCNT_INCR(&sc->sc_ev_txstall); 422 #endif 423 return; 424 } 425 nexttx = sc->sc_txnext; 426 427 IFQ_DEQUEUE(&ifp->if_snd, m); 428 429 /* 430 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. 431 */ 432 433 m_copydata(m, 0, m->m_pkthdr.len, 434 sc->sc_txbufs[nexttx].buf_vaddr); 435 436 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 437 MACDMA_TX_STAT(nexttx), 0); 438 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 439 MACDMA_TX_LEN(nexttx), 440 m->m_pkthdr.len < (ETHER_MIN_LEN - ETHER_CRC_LEN) ? 441 ETHER_MIN_LEN - ETHER_CRC_LEN : m->m_pkthdr.len); 442 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 443 MACDMA_TX_ADDR(nexttx), 444 sc->sc_txbufs[nexttx].buf_paddr | TX_ADDR_EN); 445 /* XXX - needed?? we should be coherent */ 446 bus_space_barrier(sc->sc_st, sc->sc_dma_sh, 0 /* XXX */, 447 0 /* XXX */, BUS_SPACE_BARRIER_WRITE); 448 449 /* Advance the Tx pointer. */ 450 sc->sc_txfree--; 451 sc->sc_txnext = AUMAC_NEXTTX(nexttx); 452 453 #if NBPFILTER > 0 454 /* Pass the packet to any BPF listeners. */ 455 if (ifp->if_bpf) 456 bpf_mtap(ifp->if_bpf, m); 457 #endif /* NBPFILTER */ 458 459 m_freem(m); 460 461 /* Set a watchdog timer in case the chip flakes out. */ 462 ifp->if_timer = 5; 463 } 464 /* NOTREACHED */ 465 } 466 467 /* 468 * aumac_watchdog: [ifnet interface function] 469 * 470 * Watchdog timer handler. 471 */ 472 static void 473 aumac_watchdog(struct ifnet *ifp) 474 { 475 struct aumac_softc *sc = ifp->if_softc; 476 477 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 478 (void) aumac_init(ifp); 479 480 /* Try to get more packets going. */ 481 aumac_start(ifp); 482 } 483 484 /* 485 * aumac_ioctl: [ifnet interface function] 486 * 487 * Handle control requests from the operator. 488 */ 489 static int 490 aumac_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 491 { 492 struct aumac_softc *sc = ifp->if_softc; 493 struct ifreq *ifr = (struct ifreq *) data; 494 int s, error; 495 496 s = splnet(); 497 498 switch (cmd) { 499 case SIOCSIFMEDIA: 500 case SIOCGIFMEDIA: 501 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd); 502 break; 503 504 default: 505 error = ether_ioctl(ifp, cmd, data); 506 if (error == ENETRESET) { 507 /* 508 * Multicast list has changed; set the hardware filter 509 * accordingly. 510 */ 511 aumac_set_filter(sc); 512 } 513 break; 514 } 515 516 /* Try to get more packets going. */ 517 aumac_start(ifp); 518 519 splx(s); 520 return (error); 521 } 522 523 /* 524 * aumac_intr: 525 * 526 * Interrupt service routine. 527 */ 528 static int 529 aumac_intr(void *arg) 530 { 531 struct aumac_softc *sc = arg; 532 533 /* 534 * There aren't really any interrupt status bits on the 535 * Au1X00 MAC, and each MAC has a dedicated interrupt 536 * in the CPU's built-in interrupt controller. Just 537 * check for new incoming packets, and then Tx completions 538 * (for status updating). 539 */ 540 if ((sc->sc_ethercom.ec_if.if_flags & IFF_RUNNING) == 0) 541 return (0); 542 543 aumac_rxintr(sc); 544 aumac_txintr(sc); 545 546 return (1); 547 } 548 549 /* 550 * aumac_txintr: 551 * 552 * Helper; handle transmit interrupts. 553 */ 554 static void 555 aumac_txintr(struct aumac_softc *sc) 556 { 557 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 558 uint32_t stat; 559 int i; 560 #ifdef AUMAC_EVENT_COUNTERS 561 int gotone = 0; 562 #endif 563 564 for (i = sc->sc_txdirty; sc->sc_txfree != AUMAC_NTXDESC; 565 i = AUMAC_NEXTTX(i)) { 566 if ((bus_space_read_4(sc->sc_st, sc->sc_dma_sh, 567 MACDMA_TX_ADDR(i)) & TX_ADDR_DN) == 0) 568 break; 569 #ifdef AUMAC_EVENT_COUNTERS 570 gotone = 1; 571 #endif 572 573 /* ACK interrupt. */ 574 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 575 MACDMA_TX_ADDR(i), 0); 576 577 stat = bus_space_read_4(sc->sc_st, sc->sc_dma_sh, 578 MACDMA_TX_STAT(i)); 579 580 if (stat & TX_STAT_FA) { 581 /* XXX STATS */ 582 ifp->if_oerrors++; 583 } else 584 ifp->if_opackets++; 585 586 if (stat & TX_STAT_EC) 587 ifp->if_collisions += 16; 588 else 589 ifp->if_collisions += TX_STAT_CC(stat); 590 591 sc->sc_txfree++; 592 ifp->if_flags &= ~IFF_OACTIVE; 593 594 /* Try to queue more packets. */ 595 aumac_start(ifp); 596 } 597 598 #ifdef AUMAC_EVENT_COUNTERS 599 if (gotone) 600 AUMAC_EVCNT_INCR(&sc->sc_ev_txintr); 601 #endif 602 603 /* Update the dirty descriptor pointer. */ 604 sc->sc_txdirty = i; 605 606 /* 607 * If there are no more pending transmissions, cancel the watchdog 608 * timer. 609 */ 610 if (sc->sc_txfree == AUMAC_NTXDESC) 611 ifp->if_timer = 0; 612 } 613 614 /* 615 * aumac_rxintr: 616 * 617 * Helper; handle receive interrupts. 618 */ 619 static void 620 aumac_rxintr(struct aumac_softc *sc) 621 { 622 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 623 struct mbuf *m; 624 uint32_t stat; 625 int i, len; 626 #ifdef AUMAC_EVENT_COUNTERS 627 int pkts = 0; 628 #endif 629 630 for (i = sc->sc_rxptr;; i = AUMAC_NEXTRX(i)) { 631 if ((bus_space_read_4(sc->sc_st, sc->sc_dma_sh, 632 MACDMA_RX_ADDR(i)) & RX_ADDR_DN) == 0) 633 break; 634 #ifdef AUMAC_EVENT_COUNTERS 635 pkts++; 636 #endif 637 638 stat = bus_space_read_4(sc->sc_st, sc->sc_dma_sh, 639 MACDMA_RX_STAT(i)); 640 641 #define PRINTERR(str) \ 642 do { \ 643 error++; \ 644 printf("%s: %s\n", sc->sc_dev.dv_xname, str); \ 645 } while (0) 646 647 if (stat & RX_STAT_ERRS) { 648 int error = 0; 649 650 if (stat & RX_STAT_MI) 651 PRINTERR("missed frame"); 652 if (stat & RX_STAT_UC) 653 PRINTERR("unknown control frame"); 654 if (stat & RX_STAT_LE) 655 PRINTERR("short frame"); 656 if (stat & RX_STAT_CR) 657 PRINTERR("CRC error"); 658 if (stat & RX_STAT_ME) 659 PRINTERR("medium error"); 660 if (stat & RX_STAT_CS) 661 PRINTERR("late collision"); 662 if (stat & RX_STAT_FL) 663 PRINTERR("frame too big"); 664 if (stat & RX_STAT_RF) 665 PRINTERR("runt frame (collision)"); 666 if (stat & RX_STAT_WT) 667 PRINTERR("watch dog"); 668 if (stat & RX_STAT_DB) { 669 if (stat & (RX_STAT_CS | RX_STAT_RF | 670 RX_STAT_CR)) { 671 if (!error) 672 goto pktok; 673 } else 674 PRINTERR("dribbling bit"); 675 } 676 #undef PRINTERR 677 ifp->if_ierrors++; 678 679 dropit: 680 /* reuse the current descriptor */ 681 AUMAC_INIT_RXDESC(sc, i); 682 continue; 683 } 684 pktok: 685 len = RX_STAT_L(stat); 686 687 /* 688 * The Au1X00 MAC includes the CRC with every packet; 689 * trim it off here. 690 */ 691 len -= ETHER_CRC_LEN; 692 693 /* 694 * Truncate the packet if it's too big to fit in 695 * a single mbuf cluster. 696 */ 697 if (len > MCLBYTES - 2) 698 len = MCLBYTES - 2; 699 700 MGETHDR(m, M_DONTWAIT, MT_DATA); 701 if (m == NULL) { 702 printf("%s: unable to allocate Rx mbuf\n", 703 sc->sc_dev.dv_xname); 704 goto dropit; 705 } 706 if (len > MHLEN - 2) { 707 MCLGET(m, M_DONTWAIT); 708 if ((m->m_flags & M_EXT) == 0) { 709 printf("%s: unable to allocate Rx cluster\n", 710 sc->sc_dev.dv_xname); 711 m_freem(m); 712 goto dropit; 713 } 714 } 715 716 m->m_data += 2; /* align payload */ 717 memcpy(mtod(m, caddr_t), 718 sc->sc_rxbufs[i].buf_vaddr, len); 719 AUMAC_INIT_RXDESC(sc, i); 720 721 m->m_pkthdr.rcvif = ifp; 722 m->m_pkthdr.len = m->m_len = len; 723 724 #if NBPFILTER > 0 725 /* Pass this up to any BPF listeners. */ 726 if (ifp->if_bpf) 727 bpf_mtap(ifp->if_bpf, m); 728 #endif /* NBPFILTER > 0 */ 729 730 /* Pass it on. */ 731 (*ifp->if_input)(ifp, m); 732 ifp->if_ipackets++; 733 } 734 #ifdef AUMAC_EVENT_COUNTERS 735 if (pkts) 736 AUMAC_EVCNT_INCR(&sc->sc_ev_rxintr); 737 if (pkts == AUMAC_NRXDESC) 738 AUMAC_EVCNT_INCR(&sc->sc_ev_rxstall); 739 #endif 740 741 /* Update the receive pointer. */ 742 sc->sc_rxptr = i; 743 } 744 745 /* 746 * aumac_tick: 747 * 748 * One second timer, used to tick the MII. 749 */ 750 static void 751 aumac_tick(void *arg) 752 { 753 struct aumac_softc *sc = arg; 754 int s; 755 756 s = splnet(); 757 mii_tick(&sc->sc_mii); 758 splx(s); 759 760 callout_reset(&sc->sc_tick_ch, hz, aumac_tick, sc); 761 } 762 763 /* 764 * aumac_init: [ifnet interface function] 765 * 766 * Initialize the interface. Must be called at splnet(). 767 */ 768 static int 769 aumac_init(struct ifnet *ifp) 770 { 771 struct aumac_softc *sc = ifp->if_softc; 772 int i, error = 0; 773 774 /* Cancel any pending I/O, reset MAC. */ 775 aumac_stop(ifp, 0); 776 777 /* Set up the transmit ring. */ 778 for (i = 0; i < AUMAC_NTXDESC; i++) { 779 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 780 MACDMA_TX_STAT(i), 0); 781 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 782 MACDMA_TX_LEN(i), 0); 783 bus_space_write_4(sc->sc_st, sc->sc_dma_sh, 784 MACDMA_TX_ADDR(i), sc->sc_txbufs[i].buf_paddr); 785 } 786 sc->sc_txfree = AUMAC_NTXDESC; 787 sc->sc_txnext = TX_ADDR_CB(bus_space_read_4(sc->sc_st, sc->sc_dma_sh, 788 MACDMA_TX_ADDR(0))); 789 sc->sc_txdirty = sc->sc_txnext; 790 791 /* Set up the receive ring. */ 792 for (i = 0; i < AUMAC_NRXDESC; i++) 793 AUMAC_INIT_RXDESC(sc, i); 794 sc->sc_rxptr = RX_ADDR_CB(bus_space_read_4(sc->sc_st, sc->sc_dma_sh, 795 MACDMA_RX_ADDR(0))); 796 797 /* 798 * Power up the MAC. 799 */ 800 aumac_powerup(sc); 801 802 sc->sc_control |= CONTROL_DO | CONTROL_TE | CONTROL_RE; 803 #if _BYTE_ORDER == _BIG_ENDIAN 804 sc->sc_control |= CONTROL_EM; 805 #endif 806 807 /* Set the media. */ 808 aumac_mediachange(ifp); 809 810 /* 811 * Set the receive filter. This will actually start the transmit 812 * and receive processes. 813 */ 814 aumac_set_filter(sc); 815 816 /* Start the one second clock. */ 817 callout_reset(&sc->sc_tick_ch, hz, aumac_tick, sc); 818 819 /* ...all done! */ 820 ifp->if_flags |= IFF_RUNNING; 821 ifp->if_flags &= ~IFF_OACTIVE; 822 823 if (error) 824 printf("%s: interface not running\n", sc->sc_dev.dv_xname); 825 return (error); 826 } 827 828 /* 829 * aumac_stop: [ifnet interface function] 830 * 831 * Stop transmission on the interface. 832 */ 833 static void 834 aumac_stop(struct ifnet *ifp, int disable) 835 { 836 struct aumac_softc *sc = ifp->if_softc; 837 838 /* Stop the one-second clock. */ 839 callout_stop(&sc->sc_tick_ch); 840 841 /* Down the MII. */ 842 mii_down(&sc->sc_mii); 843 844 /* Stop the transmit and receive processes. */ 845 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_CONTROL, 0); 846 847 /* Power down/reset the MAC. */ 848 aumac_powerdown(sc); 849 850 /* Mark the interface as down and cancel the watchdog timer. */ 851 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 852 ifp->if_timer = 0; 853 } 854 855 /* 856 * aumac_powerdown: 857 * 858 * Power down the MAC. 859 */ 860 static void 861 aumac_powerdown(struct aumac_softc *sc) 862 { 863 864 /* Disable the MAC clocks, and place the device in reset. */ 865 // bus_space_write_4(sc->sc_st, sc->sc_macen_sh, 0, MACEN_JP); 866 867 // delay(10000); 868 } 869 870 /* 871 * aumac_powerup: 872 * 873 * Bring the device out of reset. 874 */ 875 static void 876 aumac_powerup(struct aumac_softc *sc) 877 { 878 879 /* Enable clocks to the MAC. */ 880 bus_space_write_4(sc->sc_st, sc->sc_macen_sh, 0, MACEN_JP|MACEN_CE); 881 882 /* Enable MAC, coherent transactions, pass only valid frames. */ 883 bus_space_write_4(sc->sc_st, sc->sc_macen_sh, 0, 884 MACEN_E2|MACEN_E1|MACEN_E0|MACEN_CE); 885 886 delay(20000); 887 } 888 889 /* 890 * aumac_set_filter: 891 * 892 * Set up the receive filter. 893 */ 894 static void 895 aumac_set_filter(struct aumac_softc *sc) 896 { 897 struct ethercom *ec = &sc->sc_ethercom; 898 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 899 struct ether_multi *enm; 900 struct ether_multistep step; 901 const uint8_t *enaddr = LLADDR(ifp->if_sadl); 902 uint32_t mchash[2], crc; 903 904 sc->sc_control &= ~(CONTROL_PM | CONTROL_PR); 905 906 /* Stop the receiver. */ 907 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_CONTROL, 908 sc->sc_control & ~CONTROL_RE); 909 910 if (ifp->if_flags & IFF_PROMISC) { 911 sc->sc_control |= CONTROL_PR; 912 goto allmulti; 913 } 914 915 /* Set the station address. */ 916 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_ADDRHIGH, 917 enaddr[4] | (enaddr[5] << 8)); 918 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_ADDRLOW, 919 enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16) | 920 (enaddr[3] << 24)); 921 922 sc->sc_control |= CONTROL_HP; 923 924 mchash[0] = mchash[1] = 0; 925 926 /* 927 * Set up the multicast address filter by passing all multicast 928 * addresses through a CRC generator, and then using the high 929 * order 6 bits as an index into the 64-bit multicast hash table. 930 * The high order bits select the word, while the rest of the bits 931 * select the bit within the word. 932 */ 933 ETHER_FIRST_MULTI(step, ec, enm); 934 while (enm != NULL) { 935 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 936 /* 937 * We must listen to a range of multicast addresses. 938 * For now, just accept all multicasts, rather than 939 * trying to set only those filter bits needed to match 940 * the range. (At this time, the only use of address 941 * ranges is for IP multicast routing, for which the 942 * range is large enough to require all bits set.) 943 */ 944 goto allmulti; 945 } 946 947 crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 948 949 /* Just want the 6 most significant bits. */ 950 crc >>= 26; 951 952 /* Set the corresponding bit in the filter. */ 953 mchash[crc >> 5] |= 1U << (crc & 0x1f); 954 955 ETHER_NEXT_MULTI(step, enm); 956 } 957 958 ifp->if_flags &= ~IFF_ALLMULTI; 959 960 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_HASHHIGH, 961 mchash[1]); 962 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_HASHLOW, 963 mchash[0]); 964 965 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_CONTROL, 966 sc->sc_control); 967 return; 968 969 allmulti: 970 sc->sc_control |= CONTROL_PM; 971 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_CONTROL, 972 sc->sc_control); 973 } 974 975 /* 976 * aumac_mediastatus: [ifmedia interface function] 977 * 978 * Get the current interface media status. 979 */ 980 static void 981 aumac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 982 { 983 struct aumac_softc *sc = ifp->if_softc; 984 985 mii_pollstat(&sc->sc_mii); 986 ifmr->ifm_status = sc->sc_mii.mii_media_status; 987 ifmr->ifm_active = sc->sc_mii.mii_media_active; 988 } 989 990 /* 991 * aumac_mediachange: [ifmedia interface function] 992 * 993 * Set hardware to newly selected media. 994 */ 995 static int 996 aumac_mediachange(struct ifnet *ifp) 997 { 998 struct aumac_softc *sc = ifp->if_softc; 999 1000 if (ifp->if_flags & IFF_UP) 1001 mii_mediachg(&sc->sc_mii); 1002 return (0); 1003 } 1004 1005 /* 1006 * aumac_mii_wait: 1007 * 1008 * Wait for the MII interface to not be busy. 1009 */ 1010 static int 1011 aumac_mii_wait(struct aumac_softc *sc, const char *msg) 1012 { 1013 int i; 1014 1015 for (i = 0; i < 10000; i++) { 1016 if ((bus_space_read_4(sc->sc_st, sc->sc_mac_sh, 1017 MAC_MIICTRL) & MIICTRL_MB) == 0) 1018 return (0); 1019 delay(10); 1020 } 1021 1022 printf("%s: MII failed to %s\n", sc->sc_dev.dv_xname, msg); 1023 return (1); 1024 } 1025 1026 /* 1027 * aumac_mii_readreg: [mii interface function] 1028 * 1029 * Read a PHY register on the MII. 1030 */ 1031 static int 1032 aumac_mii_readreg(struct device *self, int phy, int reg) 1033 { 1034 struct aumac_softc *sc = (void *) self; 1035 1036 if (aumac_mii_wait(sc, "become ready")) 1037 return (0); 1038 1039 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_MIICTRL, 1040 MIICTRL_PHYADDR(phy) | MIICTRL_MIIREG(reg)); 1041 1042 if (aumac_mii_wait(sc, "complete")) 1043 return (0); 1044 1045 return (bus_space_read_4(sc->sc_st, sc->sc_mac_sh, MAC_MIIDATA) & 1046 MIIDATA_MASK); 1047 } 1048 1049 /* 1050 * aumac_mii_writereg: [mii interface function] 1051 * 1052 * Write a PHY register on the MII. 1053 */ 1054 static void 1055 aumac_mii_writereg(struct device *self, int phy, int reg, int val) 1056 { 1057 struct aumac_softc *sc = (void *) self; 1058 1059 if (aumac_mii_wait(sc, "become ready")) 1060 return; 1061 1062 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_MIIDATA, val); 1063 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_MIICTRL, 1064 MIICTRL_PHYADDR(phy) | MIICTRL_MIIREG(reg) | MIICTRL_MW); 1065 1066 (void) aumac_mii_wait(sc, "complete"); 1067 } 1068 1069 /* 1070 * aumac_mii_statchg: [mii interface function] 1071 * 1072 * Callback from MII layer when media changes. 1073 */ 1074 static void 1075 aumac_mii_statchg(struct device *self) 1076 { 1077 struct aumac_softc *sc = (void *) self; 1078 1079 if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0) 1080 sc->sc_control |= CONTROL_F; 1081 else 1082 sc->sc_control &= ~CONTROL_F; 1083 1084 bus_space_write_4(sc->sc_st, sc->sc_mac_sh, MAC_CONTROL, 1085 sc->sc_control); 1086 } 1087