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