Home | History | Annotate | Line # | Download | only in ic
smc83c170.c revision 1.29
      1  1.29   thorpej /*	$NetBSD: smc83c170.c,v 1.29 2000/03/23 07:01:32 thorpej Exp $	*/
      2   1.1   thorpej 
      3   1.1   thorpej /*-
      4  1.10   thorpej  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
      5   1.1   thorpej  * All rights reserved.
      6   1.1   thorpej  *
      7   1.1   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1   thorpej  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9   1.1   thorpej  * NASA Ames Research Center.
     10   1.1   thorpej  *
     11   1.1   thorpej  * Redistribution and use in source and binary forms, with or without
     12   1.1   thorpej  * modification, are permitted provided that the following conditions
     13   1.1   thorpej  * are met:
     14   1.1   thorpej  * 1. Redistributions of source code must retain the above copyright
     15   1.1   thorpej  *    notice, this list of conditions and the following disclaimer.
     16   1.1   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     17   1.1   thorpej  *    notice, this list of conditions and the following disclaimer in the
     18   1.1   thorpej  *    documentation and/or other materials provided with the distribution.
     19   1.1   thorpej  * 3. All advertising materials mentioning features or use of this software
     20   1.1   thorpej  *    must display the following acknowledgement:
     21   1.1   thorpej  *	This product includes software developed by the NetBSD
     22   1.1   thorpej  *	Foundation, Inc. and its contributors.
     23   1.1   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24   1.1   thorpej  *    contributors may be used to endorse or promote products derived
     25   1.1   thorpej  *    from this software without specific prior written permission.
     26   1.1   thorpej  *
     27   1.1   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28   1.1   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29   1.1   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30   1.1   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31   1.1   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32   1.1   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33   1.1   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34   1.1   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35   1.1   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36   1.1   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37   1.1   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     38   1.1   thorpej  */
     39   1.1   thorpej 
     40   1.1   thorpej /*
     41   1.1   thorpej  * Device driver for the Standard Microsystems Corp. 83C170
     42   1.1   thorpej  * Ethernet PCI Integrated Controller (EPIC/100).
     43   1.1   thorpej  */
     44   1.1   thorpej 
     45   1.2  jonathan #include "opt_inet.h"
     46   1.3  jonathan #include "opt_ns.h"
     47   1.1   thorpej #include "bpfilter.h"
     48   1.1   thorpej 
     49   1.1   thorpej #include <sys/param.h>
     50   1.1   thorpej #include <sys/systm.h>
     51  1.29   thorpej #include <sys/callout.h>
     52   1.1   thorpej #include <sys/mbuf.h>
     53   1.1   thorpej #include <sys/malloc.h>
     54   1.1   thorpej #include <sys/kernel.h>
     55   1.1   thorpej #include <sys/socket.h>
     56   1.1   thorpej #include <sys/ioctl.h>
     57   1.1   thorpej #include <sys/errno.h>
     58   1.1   thorpej #include <sys/device.h>
     59   1.1   thorpej 
     60   1.1   thorpej #include <net/if.h>
     61   1.1   thorpej #include <net/if_dl.h>
     62   1.1   thorpej #include <net/if_media.h>
     63   1.1   thorpej #include <net/if_ether.h>
     64   1.1   thorpej 
     65   1.1   thorpej #if NBPFILTER > 0
     66   1.1   thorpej #include <net/bpf.h>
     67   1.1   thorpej #endif
     68   1.1   thorpej 
     69   1.1   thorpej #ifdef INET
     70   1.1   thorpej #include <netinet/in.h>
     71   1.1   thorpej #include <netinet/if_inarp.h>
     72   1.1   thorpej #endif
     73   1.1   thorpej 
     74   1.1   thorpej #ifdef NS
     75   1.1   thorpej #include <netns/ns.h>
     76   1.1   thorpej #include <netns/ns_if.h>
     77   1.1   thorpej #endif
     78   1.1   thorpej 
     79   1.1   thorpej #include <machine/bus.h>
     80   1.1   thorpej #include <machine/intr.h>
     81   1.1   thorpej 
     82   1.8   thorpej #include <dev/mii/miivar.h>
     83   1.8   thorpej 
     84   1.1   thorpej #include <dev/ic/smc83c170reg.h>
     85   1.1   thorpej #include <dev/ic/smc83c170var.h>
     86   1.1   thorpej 
     87   1.1   thorpej void	epic_start __P((struct ifnet *));
     88   1.1   thorpej void	epic_watchdog __P((struct ifnet *));
     89   1.1   thorpej int	epic_ioctl __P((struct ifnet *, u_long, caddr_t));
     90   1.1   thorpej 
     91   1.1   thorpej void	epic_shutdown __P((void *));
     92   1.1   thorpej 
     93   1.1   thorpej void	epic_reset __P((struct epic_softc *));
     94  1.19   thorpej int	epic_init __P((struct epic_softc *));
     95  1.19   thorpej void	epic_rxdrain __P((struct epic_softc *));
     96  1.19   thorpej void	epic_stop __P((struct epic_softc *, int));
     97   1.1   thorpej int	epic_add_rxbuf __P((struct epic_softc *, int));
     98   1.1   thorpej void	epic_read_eeprom __P((struct epic_softc *, int, int, u_int16_t *));
     99   1.1   thorpej void	epic_set_mchash __P((struct epic_softc *));
    100   1.6   thorpej void	epic_fixup_clock_source __P((struct epic_softc *));
    101   1.8   thorpej int	epic_mii_read __P((struct device *, int, int));
    102   1.8   thorpej void	epic_mii_write __P((struct device *, int, int, int));
    103   1.8   thorpej int	epic_mii_wait __P((struct epic_softc *, u_int32_t));
    104   1.8   thorpej void	epic_tick __P((void *));
    105   1.8   thorpej 
    106   1.8   thorpej void	epic_statchg __P((struct device *));
    107   1.8   thorpej int	epic_mediachange __P((struct ifnet *));
    108   1.8   thorpej void	epic_mediastatus __P((struct ifnet *, struct ifmediareq *));
    109   1.1   thorpej 
    110   1.1   thorpej #define	INTMASK	(INTSTAT_FATAL_INT | INTSTAT_TXU | \
    111  1.21   thorpej 	    INTSTAT_TXC | INTSTAT_RXE | INTSTAT_RQE | INTSTAT_RCC)
    112   1.1   thorpej 
    113  1.19   thorpej int	epic_copy_small = 0;
    114  1.19   thorpej 
    115   1.1   thorpej /*
    116   1.1   thorpej  * Attach an EPIC interface to the system.
    117   1.1   thorpej  */
    118   1.1   thorpej void
    119   1.1   thorpej epic_attach(sc)
    120   1.1   thorpej 	struct epic_softc *sc;
    121   1.1   thorpej {
    122   1.1   thorpej 	bus_space_tag_t st = sc->sc_st;
    123   1.1   thorpej 	bus_space_handle_t sh = sc->sc_sh;
    124   1.1   thorpej 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    125  1.14   thorpej 	int i, rseg, error;
    126   1.1   thorpej 	bus_dma_segment_t seg;
    127   1.1   thorpej 	u_int8_t enaddr[ETHER_ADDR_LEN], devname[12 + 1];
    128   1.1   thorpej 	u_int16_t myea[ETHER_ADDR_LEN / 2], mydevname[6];
    129   1.1   thorpej 
    130  1.29   thorpej 	callout_init(&sc->sc_mii_callout);
    131  1.29   thorpej 
    132   1.1   thorpej 	/*
    133   1.1   thorpej 	 * Allocate the control data structures, and create and load the
    134   1.1   thorpej 	 * DMA map for it.
    135   1.1   thorpej 	 */
    136   1.1   thorpej 	if ((error = bus_dmamem_alloc(sc->sc_dmat,
    137   1.1   thorpej 	    sizeof(struct epic_control_data), NBPG, 0, &seg, 1, &rseg,
    138   1.1   thorpej 	    BUS_DMA_NOWAIT)) != 0) {
    139   1.1   thorpej 		printf("%s: unable to allocate control data, error = %d\n",
    140   1.1   thorpej 		    sc->sc_dev.dv_xname, error);
    141  1.14   thorpej 		goto fail_0;
    142   1.1   thorpej 	}
    143   1.1   thorpej 
    144   1.1   thorpej 	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
    145   1.1   thorpej 	    sizeof(struct epic_control_data), (caddr_t *)&sc->sc_control_data,
    146   1.1   thorpej 	    BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
    147   1.1   thorpej 		printf("%s: unable to map control data, error = %d\n",
    148   1.1   thorpej 		    sc->sc_dev.dv_xname, error);
    149  1.14   thorpej 		goto fail_1;
    150   1.1   thorpej 	}
    151   1.1   thorpej 
    152   1.1   thorpej 	if ((error = bus_dmamap_create(sc->sc_dmat,
    153   1.1   thorpej 	    sizeof(struct epic_control_data), 1,
    154   1.1   thorpej 	    sizeof(struct epic_control_data), 0, BUS_DMA_NOWAIT,
    155   1.1   thorpej 	    &sc->sc_cddmamap)) != 0) {
    156   1.1   thorpej 		printf("%s: unable to create control data DMA map, "
    157   1.1   thorpej 		    "error = %d\n", sc->sc_dev.dv_xname, error);
    158  1.14   thorpej 		goto fail_2;
    159   1.1   thorpej 	}
    160   1.1   thorpej 
    161   1.1   thorpej 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
    162   1.1   thorpej 	    sc->sc_control_data, sizeof(struct epic_control_data), NULL,
    163   1.1   thorpej 	    BUS_DMA_NOWAIT)) != 0) {
    164   1.1   thorpej 		printf("%s: unable to load control data DMA map, error = %d\n",
    165   1.1   thorpej 		    sc->sc_dev.dv_xname, error);
    166  1.14   thorpej 		goto fail_3;
    167   1.1   thorpej 	}
    168   1.1   thorpej 
    169   1.1   thorpej 	/*
    170   1.1   thorpej 	 * Create the transmit buffer DMA maps.
    171   1.1   thorpej 	 */
    172   1.1   thorpej 	for (i = 0; i < EPIC_NTXDESC; i++) {
    173   1.1   thorpej 		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
    174   1.1   thorpej 		    EPIC_NFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
    175  1.10   thorpej 		    &EPIC_DSTX(sc, i)->ds_dmamap)) != 0) {
    176   1.1   thorpej 			printf("%s: unable to create tx DMA map %d, "
    177   1.1   thorpej 			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
    178  1.14   thorpej 			goto fail_4;
    179   1.1   thorpej 		}
    180   1.1   thorpej 	}
    181   1.1   thorpej 
    182   1.1   thorpej 	/*
    183   1.1   thorpej 	 * Create the recieve buffer DMA maps.
    184   1.1   thorpej 	 */
    185   1.1   thorpej 	for (i = 0; i < EPIC_NRXDESC; i++) {
    186   1.1   thorpej 		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
    187   1.1   thorpej 		    MCLBYTES, 0, BUS_DMA_NOWAIT,
    188  1.10   thorpej 		    &EPIC_DSRX(sc, i)->ds_dmamap)) != 0) {
    189   1.1   thorpej 			printf("%s: unable to create rx DMA map %d, "
    190   1.1   thorpej 			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
    191  1.14   thorpej 			goto fail_5;
    192   1.1   thorpej 		}
    193  1.19   thorpej 		EPIC_DSRX(sc, i)->ds_mbuf = NULL;
    194   1.1   thorpej 	}
    195   1.1   thorpej 
    196   1.1   thorpej 
    197   1.1   thorpej 	/*
    198   1.1   thorpej 	 * Bring the chip out of low-power mode and reset it to a known state.
    199   1.1   thorpej 	 */
    200   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_GENCTL, 0);
    201   1.1   thorpej 	epic_reset(sc);
    202   1.1   thorpej 
    203   1.1   thorpej 	/*
    204   1.1   thorpej 	 * Read the Ethernet address from the EEPROM.
    205   1.1   thorpej 	 */
    206   1.1   thorpej 	epic_read_eeprom(sc, 0, (sizeof(myea) / sizeof(myea[0])), myea);
    207   1.1   thorpej 	bcopy(myea, enaddr, sizeof(myea));
    208   1.1   thorpej 
    209   1.1   thorpej 	/*
    210   1.1   thorpej 	 * ...and the device name.
    211   1.1   thorpej 	 */
    212   1.1   thorpej 	epic_read_eeprom(sc, 0x2c, (sizeof(mydevname) / sizeof(mydevname[0])),
    213   1.1   thorpej 	    mydevname);
    214   1.1   thorpej 	bcopy(mydevname, devname, sizeof(mydevname));
    215   1.1   thorpej 	devname[sizeof(mydevname)] = '\0';
    216   1.1   thorpej 	for (i = sizeof(mydevname) - 1; i >= 0; i--) {
    217   1.1   thorpej 		if (devname[i] == ' ')
    218   1.1   thorpej 			devname[i] = '\0';
    219   1.1   thorpej 		else
    220   1.1   thorpej 			break;
    221   1.1   thorpej 	}
    222   1.1   thorpej 
    223   1.1   thorpej 	printf("%s: %s, Ethernet address %s\n", sc->sc_dev.dv_xname,
    224   1.1   thorpej 	    devname, ether_sprintf(enaddr));
    225   1.1   thorpej 
    226   1.8   thorpej 	/*
    227   1.8   thorpej 	 * Initialize our media structures and probe the MII.
    228   1.8   thorpej 	 */
    229   1.8   thorpej 	sc->sc_mii.mii_ifp = ifp;
    230   1.8   thorpej 	sc->sc_mii.mii_readreg = epic_mii_read;
    231   1.8   thorpej 	sc->sc_mii.mii_writereg = epic_mii_write;
    232   1.8   thorpej 	sc->sc_mii.mii_statchg = epic_statchg;
    233   1.8   thorpej 	ifmedia_init(&sc->sc_mii.mii_media, 0, epic_mediachange,
    234   1.8   thorpej 	    epic_mediastatus);
    235  1.24   thorpej 	mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
    236  1.25   thorpej 	    MII_OFFSET_ANY, 0);
    237   1.8   thorpej 	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
    238   1.8   thorpej 		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
    239   1.8   thorpej 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
    240   1.8   thorpej 	} else
    241   1.8   thorpej 		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
    242   1.8   thorpej 
    243   1.1   thorpej 	strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
    244   1.1   thorpej 	ifp->if_softc = sc;
    245   1.1   thorpej 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    246   1.1   thorpej 	ifp->if_ioctl = epic_ioctl;
    247   1.1   thorpej 	ifp->if_start = epic_start;
    248   1.1   thorpej 	ifp->if_watchdog = epic_watchdog;
    249   1.1   thorpej 
    250   1.1   thorpej 	/*
    251   1.1   thorpej 	 * Attach the interface.
    252   1.1   thorpej 	 */
    253   1.1   thorpej 	if_attach(ifp);
    254   1.1   thorpej 	ether_ifattach(ifp, enaddr);
    255   1.1   thorpej #if NBPFILTER > 0
    256   1.1   thorpej 	bpfattach(&sc->sc_ethercom.ec_if.if_bpf, ifp, DLT_EN10MB,
    257   1.1   thorpej 	    sizeof(struct ether_header));
    258   1.1   thorpej #endif
    259   1.1   thorpej 
    260   1.1   thorpej 	/*
    261   1.1   thorpej 	 * Make sure the interface is shutdown during reboot.
    262   1.1   thorpej 	 */
    263   1.1   thorpej 	sc->sc_sdhook = shutdownhook_establish(epic_shutdown, sc);
    264   1.1   thorpej 	if (sc->sc_sdhook == NULL)
    265   1.1   thorpej 		printf("%s: WARNING: unable to establish shutdown hook\n",
    266   1.1   thorpej 		    sc->sc_dev.dv_xname);
    267   1.1   thorpej 	return;
    268   1.1   thorpej 
    269   1.1   thorpej 	/*
    270   1.1   thorpej 	 * Free any resources we've allocated during the failed attach
    271   1.1   thorpej 	 * attempt.  Do this in reverse order and fall through.
    272   1.1   thorpej 	 */
    273  1.14   thorpej  fail_5:
    274  1.14   thorpej 	for (i = 0; i < EPIC_NRXDESC; i++) {
    275  1.14   thorpej 		if (EPIC_DSRX(sc, i)->ds_dmamap != NULL)
    276   1.1   thorpej 			bus_dmamap_destroy(sc->sc_dmat,
    277  1.10   thorpej 			    EPIC_DSRX(sc, i)->ds_dmamap);
    278  1.14   thorpej 	}
    279  1.14   thorpej  fail_4:
    280  1.14   thorpej 	for (i = 0; i < EPIC_NTXDESC; i++) {
    281  1.14   thorpej 		if (EPIC_DSTX(sc, i)->ds_dmamap != NULL)
    282   1.1   thorpej 			bus_dmamap_destroy(sc->sc_dmat,
    283  1.10   thorpej 			    EPIC_DSTX(sc, i)->ds_dmamap);
    284   1.1   thorpej 	}
    285  1.14   thorpej 	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
    286  1.14   thorpej  fail_3:
    287  1.14   thorpej 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
    288  1.14   thorpej  fail_2:
    289  1.14   thorpej 	bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
    290  1.14   thorpej 	    sizeof(struct epic_control_data));
    291  1.14   thorpej  fail_1:
    292  1.14   thorpej 	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
    293  1.14   thorpej  fail_0:
    294  1.14   thorpej 	return;
    295   1.1   thorpej }
    296   1.1   thorpej 
    297   1.1   thorpej /*
    298   1.1   thorpej  * Shutdown hook.  Make sure the interface is stopped at reboot.
    299   1.1   thorpej  */
    300   1.1   thorpej void
    301   1.1   thorpej epic_shutdown(arg)
    302   1.1   thorpej 	void *arg;
    303   1.1   thorpej {
    304   1.1   thorpej 	struct epic_softc *sc = arg;
    305   1.1   thorpej 
    306  1.19   thorpej 	epic_stop(sc, 1);
    307   1.1   thorpej }
    308   1.1   thorpej 
    309   1.1   thorpej /*
    310   1.1   thorpej  * Start packet transmission on the interface.
    311   1.1   thorpej  * [ifnet interface function]
    312   1.1   thorpej  */
    313   1.1   thorpej void
    314   1.1   thorpej epic_start(ifp)
    315   1.1   thorpej 	struct ifnet *ifp;
    316   1.1   thorpej {
    317   1.1   thorpej 	struct epic_softc *sc = ifp->if_softc;
    318  1.10   thorpej 	struct mbuf *m0, *m;
    319   1.1   thorpej 	struct epic_txdesc *txd;
    320   1.1   thorpej 	struct epic_descsoft *ds;
    321   1.1   thorpej 	struct epic_fraglist *fr;
    322   1.1   thorpej 	bus_dmamap_t dmamap;
    323  1.10   thorpej 	int error, firsttx, nexttx, opending, seg;
    324   1.1   thorpej 
    325  1.10   thorpej 	/*
    326  1.10   thorpej 	 * Remember the previous txpending and the first transmit
    327  1.10   thorpej 	 * descriptor we use.
    328  1.10   thorpej 	 */
    329  1.10   thorpej 	opending = sc->sc_txpending;
    330  1.10   thorpej 	firsttx = EPIC_NEXTTX(sc->sc_txlast);
    331   1.1   thorpej 
    332   1.1   thorpej 	/*
    333   1.1   thorpej 	 * Loop through the send queue, setting up transmit descriptors
    334   1.1   thorpej 	 * until we drain the queue, or use up all available transmit
    335   1.1   thorpej 	 * descriptors.
    336   1.1   thorpej 	 */
    337  1.10   thorpej 	while (sc->sc_txpending < EPIC_NTXDESC) {
    338   1.1   thorpej 		/*
    339   1.1   thorpej 		 * Grab a packet off the queue.
    340   1.1   thorpej 		 */
    341   1.1   thorpej 		IF_DEQUEUE(&ifp->if_snd, m0);
    342  1.10   thorpej 		if (m0 == NULL)
    343  1.10   thorpej 			break;
    344   1.1   thorpej 
    345   1.1   thorpej 		/*
    346   1.1   thorpej 		 * Get the last and next available transmit descriptor.
    347   1.1   thorpej 		 */
    348   1.1   thorpej 		nexttx = EPIC_NEXTTX(sc->sc_txlast);
    349  1.10   thorpej 		txd = EPIC_CDTX(sc, nexttx);
    350  1.10   thorpej 		fr = EPIC_CDFL(sc, nexttx);
    351  1.10   thorpej 		ds = EPIC_DSTX(sc, nexttx);
    352   1.1   thorpej 		dmamap = ds->ds_dmamap;
    353   1.1   thorpej 
    354   1.1   thorpej 		/*
    355  1.10   thorpej 		 * Load the DMA map.  If this fails, the packet either
    356  1.10   thorpej 		 * didn't fit in the alloted number of frags, or we were
    357  1.10   thorpej 		 * short on resources.  In this case, we'll copy and try
    358  1.10   thorpej 		 * again.
    359   1.1   thorpej 		 */
    360  1.10   thorpej 		if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
    361  1.10   thorpej 		    BUS_DMA_NOWAIT) != 0) {
    362  1.10   thorpej 			MGETHDR(m, M_DONTWAIT, MT_DATA);
    363  1.10   thorpej 			if (m == NULL) {
    364  1.10   thorpej 				printf("%s: unable to allocate Tx mbuf\n",
    365  1.10   thorpej 				    sc->sc_dev.dv_xname);
    366  1.10   thorpej 				IF_PREPEND(&ifp->if_snd, m0);
    367  1.10   thorpej 				break;
    368   1.1   thorpej 			}
    369   1.1   thorpej 			if (m0->m_pkthdr.len > MHLEN) {
    370  1.10   thorpej 				MCLGET(m, M_DONTWAIT);
    371  1.10   thorpej 				if ((m->m_flags & M_EXT) == 0) {
    372  1.10   thorpej 					printf("%s: unable to allocate Tx "
    373  1.10   thorpej 					    "cluster\n", sc->sc_dev.dv_xname);
    374  1.10   thorpej 					m_freem(m);
    375  1.10   thorpej 					IF_PREPEND(&ifp->if_snd, m0);
    376  1.10   thorpej 					break;
    377   1.1   thorpej 				}
    378   1.1   thorpej 			}
    379  1.10   thorpej 			m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
    380  1.10   thorpej 			m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
    381   1.1   thorpej 			m_freem(m0);
    382  1.10   thorpej 			m0 = m;
    383  1.10   thorpej 			error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
    384  1.10   thorpej 			    m0, BUS_DMA_NOWAIT);
    385  1.10   thorpej 			if (error) {
    386  1.10   thorpej 				printf("%s: unable to load Tx buffer, "
    387  1.10   thorpej 				    "error = %d\n", sc->sc_dev.dv_xname, error);
    388  1.10   thorpej 				IF_PREPEND(&ifp->if_snd, m0);
    389  1.10   thorpej 				break;
    390  1.10   thorpej 			}
    391   1.1   thorpej 		}
    392   1.1   thorpej 
    393  1.10   thorpej 		/* Initialize the fraglist. */
    394   1.1   thorpej 		fr->ef_nfrags = dmamap->dm_nsegs;
    395   1.1   thorpej 		for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
    396   1.1   thorpej 			fr->ef_frags[seg].ef_addr =
    397   1.1   thorpej 			    dmamap->dm_segs[seg].ds_addr;
    398   1.1   thorpej 			fr->ef_frags[seg].ef_length =
    399   1.1   thorpej 			    dmamap->dm_segs[seg].ds_len;
    400   1.1   thorpej 		}
    401   1.1   thorpej 
    402  1.10   thorpej 		EPIC_CDFLSYNC(sc, nexttx, BUS_DMASYNC_PREWRITE);
    403  1.10   thorpej 
    404  1.10   thorpej 		/* Sync the DMA map. */
    405   1.1   thorpej 		bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
    406   1.1   thorpej 		    BUS_DMASYNC_PREWRITE);
    407   1.1   thorpej 
    408   1.1   thorpej 		/*
    409   1.1   thorpej 		 * Store a pointer to the packet so we can free it later.
    410   1.1   thorpej 		 */
    411   1.1   thorpej 		ds->ds_mbuf = m0;
    412   1.1   thorpej 
    413   1.1   thorpej 		/*
    414  1.10   thorpej 		 * Fill in the transmit descriptor.  The EPIC doesn't
    415  1.10   thorpej 		 * auto-pad, so we have to do this ourselves.
    416   1.1   thorpej 		 */
    417  1.10   thorpej 		txd->et_control = ET_TXCTL_LASTDESC | ET_TXCTL_FRAGLIST;
    418  1.20   thorpej 		txd->et_txlength = max(m0->m_pkthdr.len,
    419  1.20   thorpej 		    ETHER_MIN_LEN - ETHER_CRC_LEN);
    420   1.1   thorpej 
    421   1.1   thorpej 		/*
    422  1.10   thorpej 		 * If this is the first descriptor we're enqueueing,
    423  1.10   thorpej 		 * don't give it to the EPIC yet.  That could cause
    424  1.10   thorpej 		 * a race condition.  We'll do it below.
    425   1.1   thorpej 		 */
    426  1.10   thorpej 		if (nexttx == firsttx)
    427  1.10   thorpej 			txd->et_txstatus = 0;
    428  1.10   thorpej 		else
    429  1.10   thorpej 			txd->et_txstatus = ET_TXSTAT_OWNER;
    430  1.10   thorpej 
    431  1.10   thorpej 		EPIC_CDTXSYNC(sc, nexttx,
    432  1.10   thorpej 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    433   1.1   thorpej 
    434  1.10   thorpej 		/* Advance the tx pointer. */
    435   1.1   thorpej 		sc->sc_txpending++;
    436  1.10   thorpej 		sc->sc_txlast = nexttx;
    437   1.1   thorpej 
    438   1.1   thorpej #if NBPFILTER > 0
    439   1.1   thorpej 		/*
    440   1.1   thorpej 		 * Pass the packet to any BPF listeners.
    441   1.1   thorpej 		 */
    442   1.1   thorpej 		if (ifp->if_bpf)
    443   1.1   thorpej 			bpf_mtap(ifp->if_bpf, m0);
    444   1.1   thorpej #endif
    445   1.1   thorpej 	}
    446   1.1   thorpej 
    447  1.10   thorpej 	if (sc->sc_txpending == EPIC_NTXDESC) {
    448  1.10   thorpej 		/* No more slots left; notify upper layer. */
    449  1.10   thorpej 		ifp->if_flags |= IFF_OACTIVE;
    450  1.10   thorpej 	}
    451  1.10   thorpej 
    452  1.10   thorpej 	if (sc->sc_txpending != opending) {
    453  1.10   thorpej 		/*
    454  1.10   thorpej 		 * We enqueued packets.  If the transmitter was idle,
    455  1.10   thorpej 		 * reset the txdirty pointer.
    456  1.10   thorpej 		 */
    457  1.10   thorpej 		if (opending == 0)
    458  1.10   thorpej 			sc->sc_txdirty = firsttx;
    459  1.10   thorpej 
    460  1.10   thorpej 		/*
    461  1.10   thorpej 		 * Cause a transmit interrupt to happen on the
    462  1.10   thorpej 		 * last packet we enqueued.
    463  1.10   thorpej 		 */
    464  1.10   thorpej 		EPIC_CDTX(sc, sc->sc_txlast)->et_control |= ET_TXCTL_IAF;
    465  1.10   thorpej 		EPIC_CDTXSYNC(sc, sc->sc_txlast,
    466  1.10   thorpej 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    467  1.10   thorpej 
    468  1.10   thorpej 		/*
    469  1.10   thorpej 		 * The entire packet chain is set up.  Give the
    470  1.10   thorpej 		 * first descriptor to the EPIC now.
    471  1.10   thorpej 		 */
    472  1.10   thorpej 		EPIC_CDTX(sc, firsttx)->et_txstatus = ET_TXSTAT_OWNER;
    473  1.10   thorpej 		EPIC_CDTXSYNC(sc, firsttx,
    474  1.10   thorpej 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    475  1.10   thorpej 
    476  1.10   thorpej 		/* Start the transmitter. */
    477   1.1   thorpej 		bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_COMMAND,
    478   1.1   thorpej 		    COMMAND_TXQUEUED);
    479   1.1   thorpej 
    480  1.10   thorpej 		/* Set a watchdog timer in case the chip flakes out. */
    481   1.1   thorpej 		ifp->if_timer = 5;
    482   1.1   thorpej 	}
    483   1.1   thorpej }
    484   1.1   thorpej 
    485   1.1   thorpej /*
    486   1.1   thorpej  * Watchdog timer handler.
    487   1.1   thorpej  * [ifnet interface function]
    488   1.1   thorpej  */
    489   1.1   thorpej void
    490   1.1   thorpej epic_watchdog(ifp)
    491   1.1   thorpej 	struct ifnet *ifp;
    492   1.1   thorpej {
    493   1.1   thorpej 	struct epic_softc *sc = ifp->if_softc;
    494   1.1   thorpej 
    495   1.1   thorpej 	printf("%s: device timeout\n", sc->sc_dev.dv_xname);
    496   1.1   thorpej 	ifp->if_oerrors++;
    497   1.1   thorpej 
    498  1.19   thorpej 	(void) epic_init(sc);
    499   1.1   thorpej }
    500   1.1   thorpej 
    501   1.1   thorpej /*
    502   1.1   thorpej  * Handle control requests from the operator.
    503   1.1   thorpej  * [ifnet interface function]
    504   1.1   thorpej  */
    505   1.1   thorpej int
    506   1.1   thorpej epic_ioctl(ifp, cmd, data)
    507   1.1   thorpej 	struct ifnet *ifp;
    508   1.1   thorpej 	u_long cmd;
    509   1.1   thorpej 	caddr_t data;
    510   1.1   thorpej {
    511   1.1   thorpej 	struct epic_softc *sc = ifp->if_softc;
    512   1.1   thorpej 	struct ifreq *ifr = (struct ifreq *)data;
    513   1.1   thorpej 	struct ifaddr *ifa = (struct ifaddr *)data;
    514   1.1   thorpej 	int s, error = 0;
    515   1.1   thorpej 
    516   1.7   mycroft 	s = splnet();
    517   1.1   thorpej 
    518   1.1   thorpej 	switch (cmd) {
    519   1.1   thorpej 	case SIOCSIFADDR:
    520   1.1   thorpej 		ifp->if_flags |= IFF_UP;
    521   1.1   thorpej 
    522   1.1   thorpej 		switch (ifa->ifa_addr->sa_family) {
    523   1.1   thorpej #ifdef INET
    524   1.1   thorpej 		case AF_INET:
    525  1.19   thorpej 			if ((error = epic_init(sc)) != 0)
    526  1.19   thorpej 				break;
    527   1.1   thorpej 			arp_ifinit(ifp, ifa);
    528   1.1   thorpej 			break;
    529   1.1   thorpej #endif /* INET */
    530   1.1   thorpej #ifdef NS
    531   1.1   thorpej 		case AF_NS:
    532   1.1   thorpej 		    {
    533   1.1   thorpej 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
    534   1.1   thorpej 
    535   1.1   thorpej 			if (ns_nullhost(*ina))
    536   1.1   thorpej 				ina->x_host = *(union ns_host *)
    537   1.1   thorpej 				    LLADDR(ifp->if_sadl);
    538   1.1   thorpej 			else
    539   1.1   thorpej 				bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
    540   1.1   thorpej 				    ifp->if_addrlen);
    541   1.1   thorpej 			/* Set new address. */
    542  1.19   thorpej 			error = epic_init(sc);
    543   1.1   thorpej 			break;
    544   1.1   thorpej 		    }
    545   1.1   thorpej #endif /* NS */
    546   1.1   thorpej 		default:
    547  1.19   thorpej 			error = epic_init(sc);
    548   1.1   thorpej 			break;
    549   1.1   thorpej 		}
    550   1.1   thorpej 		break;
    551   1.1   thorpej 
    552   1.1   thorpej 	case SIOCSIFMTU:
    553   1.1   thorpej 		if (ifr->ifr_mtu > ETHERMTU)
    554   1.1   thorpej 			error = EINVAL;
    555   1.1   thorpej 		else
    556   1.1   thorpej 			ifp->if_mtu = ifr->ifr_mtu;
    557   1.1   thorpej 		break;
    558   1.1   thorpej 
    559   1.1   thorpej 	case SIOCSIFFLAGS:
    560   1.1   thorpej 		if ((ifp->if_flags & IFF_UP) == 0 &&
    561   1.1   thorpej 		    (ifp->if_flags & IFF_RUNNING) != 0) {
    562   1.1   thorpej 			/*
    563   1.1   thorpej 			 * If interface is marked down and it is running, then
    564   1.1   thorpej 			 * stop it.
    565   1.1   thorpej 			 */
    566  1.19   thorpej 			epic_stop(sc, 1);
    567   1.1   thorpej 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
    568   1.1   thorpej 			   (ifp->if_flags & IFF_RUNNING) == 0) {
    569   1.1   thorpej 			/*
    570   1.1   thorpej 			 * If interfase it marked up and it is stopped, then
    571   1.1   thorpej 			 * start it.
    572   1.1   thorpej 			 */
    573  1.19   thorpej 			error = epic_init(sc);
    574  1.10   thorpej 		} else if ((ifp->if_flags & IFF_UP) != 0) {
    575   1.1   thorpej 			/*
    576   1.1   thorpej 			 * Reset the interface to pick up changes in any other
    577   1.1   thorpej 			 * flags that affect the hardware state.
    578   1.1   thorpej 			 */
    579  1.19   thorpej 			error = epic_init(sc);
    580   1.1   thorpej 		}
    581   1.1   thorpej 		break;
    582   1.1   thorpej 
    583   1.1   thorpej 	case SIOCADDMULTI:
    584   1.1   thorpej 	case SIOCDELMULTI:
    585   1.1   thorpej 		error = (cmd == SIOCADDMULTI) ?
    586   1.1   thorpej 		    ether_addmulti(ifr, &sc->sc_ethercom) :
    587   1.1   thorpej 		    ether_delmulti(ifr, &sc->sc_ethercom);
    588   1.1   thorpej 
    589   1.1   thorpej 		if (error == ENETRESET) {
    590   1.1   thorpej 			/*
    591   1.1   thorpej 			 * Multicast list has changed; set the hardware filter
    592  1.13   thorpej 			 * accordingly.  Update our idea of the current media;
    593  1.13   thorpej 			 * epic_set_mchash() needs to know what it is.
    594   1.1   thorpej 			 */
    595  1.13   thorpej 			mii_pollstat(&sc->sc_mii);
    596  1.13   thorpej 			epic_set_mchash(sc);
    597   1.1   thorpej 			error = 0;
    598   1.1   thorpej 		}
    599   1.1   thorpej 		break;
    600   1.1   thorpej 
    601   1.8   thorpej 	case SIOCSIFMEDIA:
    602   1.8   thorpej 	case SIOCGIFMEDIA:
    603   1.8   thorpej 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
    604   1.8   thorpej 		break;
    605   1.8   thorpej 
    606   1.1   thorpej 	default:
    607   1.1   thorpej 		error = EINVAL;
    608   1.1   thorpej 		break;
    609   1.1   thorpej 	}
    610   1.1   thorpej 
    611   1.1   thorpej 	splx(s);
    612   1.1   thorpej 	return (error);
    613   1.1   thorpej }
    614   1.1   thorpej 
    615   1.1   thorpej /*
    616   1.1   thorpej  * Interrupt handler.
    617   1.1   thorpej  */
    618   1.1   thorpej int
    619   1.1   thorpej epic_intr(arg)
    620   1.1   thorpej 	void *arg;
    621   1.1   thorpej {
    622   1.1   thorpej 	struct epic_softc *sc = arg;
    623   1.1   thorpej 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    624   1.1   thorpej 	struct ether_header *eh;
    625   1.1   thorpej 	struct epic_rxdesc *rxd;
    626   1.1   thorpej 	struct epic_txdesc *txd;
    627   1.1   thorpej 	struct epic_descsoft *ds;
    628   1.1   thorpej 	struct mbuf *m;
    629   1.1   thorpej 	u_int32_t intstat;
    630  1.10   thorpej 	int i, len, claimed = 0;
    631   1.1   thorpej 
    632   1.1   thorpej  top:
    633   1.1   thorpej 	/*
    634   1.1   thorpej 	 * Get the interrupt status from the EPIC.
    635   1.1   thorpej 	 */
    636   1.1   thorpej 	intstat = bus_space_read_4(sc->sc_st, sc->sc_sh, EPIC_INTSTAT);
    637   1.1   thorpej 	if ((intstat & INTSTAT_INT_ACTV) == 0)
    638   1.1   thorpej 		return (claimed);
    639   1.1   thorpej 
    640   1.1   thorpej 	claimed = 1;
    641   1.1   thorpej 
    642   1.1   thorpej 	/*
    643   1.1   thorpej 	 * Acknowledge the interrupt.
    644   1.1   thorpej 	 */
    645   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_INTSTAT,
    646   1.1   thorpej 	    intstat & INTMASK);
    647   1.1   thorpej 
    648   1.1   thorpej 	/*
    649   1.1   thorpej 	 * Check for receive interrupts.
    650   1.1   thorpej 	 */
    651  1.21   thorpej 	if (intstat & (INTSTAT_RCC | INTSTAT_RXE | INTSTAT_RQE)) {
    652   1.1   thorpej 		for (i = sc->sc_rxptr;; i = EPIC_NEXTRX(i)) {
    653  1.10   thorpej 			rxd = EPIC_CDRX(sc, i);
    654  1.10   thorpej 			ds = EPIC_DSRX(sc, i);
    655  1.10   thorpej 
    656  1.10   thorpej 			EPIC_CDRXSYNC(sc, i,
    657  1.10   thorpej 			    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    658   1.1   thorpej 
    659   1.1   thorpej 			if (rxd->er_rxstatus & ER_RXSTAT_OWNER) {
    660   1.1   thorpej 				/*
    661   1.1   thorpej 				 * We have processed all of the
    662   1.1   thorpej 				 * receive buffers.
    663   1.1   thorpej 				 */
    664   1.1   thorpej 				break;
    665   1.1   thorpej 			}
    666   1.1   thorpej 
    667   1.1   thorpej 			/*
    668  1.10   thorpej 			 * Make sure the packet arrived intact.  If an error
    669  1.10   thorpej 			 * occurred, update stats and reset the descriptor.
    670  1.10   thorpej 			 * The buffer will be reused the next time the
    671  1.10   thorpej 			 * descriptor comes up in the ring.
    672   1.1   thorpej 			 */
    673   1.1   thorpej 			if ((rxd->er_rxstatus & ER_RXSTAT_PKTINTACT) == 0) {
    674   1.1   thorpej 				if (rxd->er_rxstatus & ER_RXSTAT_CRCERROR)
    675   1.1   thorpej 					printf("%s: CRC error\n",
    676   1.1   thorpej 					    sc->sc_dev.dv_xname);
    677   1.1   thorpej 				if (rxd->er_rxstatus & ER_RXSTAT_ALIGNERROR)
    678   1.1   thorpej 					printf("%s: alignment error\n",
    679   1.1   thorpej 					    sc->sc_dev.dv_xname);
    680   1.1   thorpej 				ifp->if_ierrors++;
    681  1.10   thorpej 				EPIC_INIT_RXDESC(sc, i);
    682  1.10   thorpej 				continue;
    683   1.1   thorpej 			}
    684   1.1   thorpej 
    685  1.10   thorpej 			bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
    686  1.10   thorpej 			    ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
    687  1.10   thorpej 
    688  1.21   thorpej 			/*
    689  1.21   thorpej 			 * The EPIC includes the CRC with every packet;
    690  1.21   thorpej 			 * trim it.
    691  1.21   thorpej 			 */
    692  1.21   thorpej 			len = rxd->er_rxlength - ETHER_CRC_LEN;
    693  1.21   thorpej 
    694  1.19   thorpej 			if (len < sizeof(struct ether_header)) {
    695  1.19   thorpej 				/*
    696  1.19   thorpej 				 * Runt packet; drop it now.
    697  1.19   thorpej 				 */
    698  1.10   thorpej 				ifp->if_ierrors++;
    699  1.10   thorpej 				EPIC_INIT_RXDESC(sc, i);
    700  1.10   thorpej 				bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
    701  1.10   thorpej 				    ds->ds_dmamap->dm_mapsize,
    702  1.10   thorpej 				    BUS_DMASYNC_PREREAD);
    703  1.10   thorpej 				continue;
    704  1.10   thorpej 			}
    705  1.10   thorpej 
    706  1.19   thorpej 			/*
    707  1.19   thorpej 			 * If the packet is small enough to fit in a
    708  1.19   thorpej 			 * single header mbuf, allocate one and copy
    709  1.19   thorpej 			 * the data into it.  This greatly reduces
    710  1.19   thorpej 			 * memory consumption when we receive lots
    711  1.19   thorpej 			 * of small packets.
    712  1.19   thorpej 			 *
    713  1.19   thorpej 			 * Otherwise, we add a new buffer to the receive
    714  1.19   thorpej 			 * chain.  If this fails, we drop the packet and
    715  1.19   thorpej 			 * recycle the old buffer.
    716  1.19   thorpej 			 */
    717  1.19   thorpej 			if (epic_copy_small != 0 && len <= MHLEN) {
    718  1.19   thorpej 				MGETHDR(m, M_DONTWAIT, MT_DATA);
    719  1.19   thorpej 				if (m == NULL)
    720  1.19   thorpej 					goto dropit;
    721  1.19   thorpej 				memcpy(mtod(m, caddr_t),
    722  1.19   thorpej 				    mtod(ds->ds_mbuf, caddr_t), len);
    723  1.19   thorpej 				EPIC_INIT_RXDESC(sc, i);
    724  1.19   thorpej 				bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
    725  1.19   thorpej 				    ds->ds_dmamap->dm_mapsize,
    726  1.19   thorpej 				    BUS_DMASYNC_PREREAD);
    727  1.19   thorpej 			} else {
    728  1.19   thorpej 				m = ds->ds_mbuf;
    729  1.19   thorpej 				if (epic_add_rxbuf(sc, i) != 0) {
    730  1.19   thorpej  dropit:
    731  1.19   thorpej 					ifp->if_ierrors++;
    732  1.19   thorpej 					EPIC_INIT_RXDESC(sc, i);
    733  1.19   thorpej 					bus_dmamap_sync(sc->sc_dmat,
    734  1.19   thorpej 					    ds->ds_dmamap, 0,
    735  1.19   thorpej 					    ds->ds_dmamap->dm_mapsize,
    736  1.19   thorpej 					    BUS_DMASYNC_PREREAD);
    737  1.19   thorpej 					continue;
    738  1.19   thorpej 				}
    739  1.10   thorpej 			}
    740  1.10   thorpej 
    741  1.10   thorpej 			m->m_pkthdr.rcvif = ifp;
    742  1.10   thorpej 			m->m_pkthdr.len = m->m_len = len;
    743  1.10   thorpej 			eh = mtod(m, struct ether_header *);
    744   1.1   thorpej 
    745  1.10   thorpej #if NBPFILTER > 0
    746  1.10   thorpej 			/*
    747  1.10   thorpej 			 * Pass this up to any BPF listeners, but only
    748  1.10   thorpej 			 * pass it up the stack if its for us.
    749  1.10   thorpej 			 */
    750  1.10   thorpej 			if (ifp->if_bpf) {
    751  1.10   thorpej 				bpf_mtap(ifp->if_bpf, m);
    752  1.10   thorpej 				if ((ifp->if_flags & IFF_PROMISC) != 0 &&
    753  1.26   thorpej 				    memcmp(LLADDR(ifp->if_sadl),
    754  1.26   thorpej 				           eh->ether_dhost,
    755  1.26   thorpej 				           ETHER_ADDR_LEN) != 0 &&
    756  1.26   thorpej 				    ETHER_IS_MULTICAST(eh->ether_dhost) == 0) {
    757   1.1   thorpej 					m_freem(m);
    758   1.1   thorpej 					continue;
    759   1.1   thorpej 				}
    760  1.10   thorpej 			}
    761   1.1   thorpej #endif /* NPBFILTER > 0 */
    762  1.10   thorpej 
    763  1.16   thorpej 			/* Pass it on. */
    764  1.16   thorpej 			(*ifp->if_input)(ifp, m);
    765  1.17   thorpej 			ifp->if_ipackets++;
    766   1.1   thorpej 		}
    767  1.10   thorpej 
    768  1.10   thorpej 		/* Update the recieve pointer. */
    769   1.1   thorpej 		sc->sc_rxptr = i;
    770   1.1   thorpej 
    771   1.1   thorpej 		/*
    772   1.1   thorpej 		 * Check for receive queue underflow.
    773   1.1   thorpej 		 */
    774   1.1   thorpej 		if (intstat & INTSTAT_RQE) {
    775   1.1   thorpej 			printf("%s: receiver queue empty\n",
    776   1.1   thorpej 			    sc->sc_dev.dv_xname);
    777   1.1   thorpej 			/*
    778   1.1   thorpej 			 * Ring is already built; just restart the
    779   1.1   thorpej 			 * receiver.
    780   1.1   thorpej 			 */
    781   1.1   thorpej 			bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_PRCDAR,
    782  1.10   thorpej 			    EPIC_CDRXADDR(sc, sc->sc_rxptr));
    783   1.1   thorpej 			bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_COMMAND,
    784   1.1   thorpej 			    COMMAND_RXQUEUED | COMMAND_START_RX);
    785   1.1   thorpej 		}
    786   1.1   thorpej 	}
    787   1.1   thorpej 
    788   1.1   thorpej 	/*
    789   1.1   thorpej 	 * Check for transmission complete interrupts.
    790   1.1   thorpej 	 */
    791   1.1   thorpej 	if (intstat & (INTSTAT_TXC | INTSTAT_TXU)) {
    792  1.10   thorpej 		ifp->if_flags &= ~IFF_OACTIVE;
    793  1.10   thorpej 		for (i = sc->sc_txdirty; sc->sc_txpending != 0;
    794  1.10   thorpej 		     i = EPIC_NEXTTX(i), sc->sc_txpending--) {
    795  1.10   thorpej 			txd = EPIC_CDTX(sc, i);
    796  1.10   thorpej 			ds = EPIC_DSTX(sc, i);
    797   1.1   thorpej 
    798  1.10   thorpej 			EPIC_CDTXSYNC(sc, i,
    799  1.10   thorpej 			    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    800  1.10   thorpej 
    801  1.10   thorpej 			if (txd->et_txstatus & ET_TXSTAT_OWNER)
    802   1.1   thorpej 				break;
    803   1.1   thorpej 
    804  1.10   thorpej 			EPIC_CDFLSYNC(sc, i, BUS_DMASYNC_POSTWRITE);
    805  1.10   thorpej 
    806  1.10   thorpej 			bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap,
    807  1.10   thorpej 			    0, ds->ds_dmamap->dm_mapsize,
    808  1.10   thorpej 			    BUS_DMASYNC_POSTWRITE);
    809  1.10   thorpej 			bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
    810  1.10   thorpej 			m_freem(ds->ds_mbuf);
    811  1.10   thorpej 			ds->ds_mbuf = NULL;
    812   1.1   thorpej 
    813   1.1   thorpej 			/*
    814   1.1   thorpej 			 * Check for errors and collisions.
    815   1.1   thorpej 			 */
    816   1.1   thorpej 			if ((txd->et_txstatus & ET_TXSTAT_PACKETTX) == 0)
    817   1.1   thorpej 				ifp->if_oerrors++;
    818  1.10   thorpej 			else
    819  1.10   thorpej 				ifp->if_opackets++;
    820   1.1   thorpej 			ifp->if_collisions +=
    821   1.1   thorpej 			    TXSTAT_COLLISIONS(txd->et_txstatus);
    822  1.10   thorpej 			if (txd->et_txstatus & ET_TXSTAT_CARSENSELOST)
    823   1.1   thorpej 				printf("%s: lost carrier\n",
    824   1.1   thorpej 				    sc->sc_dev.dv_xname);
    825   1.1   thorpej 		}
    826   1.1   thorpej 
    827  1.10   thorpej 		/* Update the dirty transmit buffer pointer. */
    828   1.1   thorpej 		sc->sc_txdirty = i;
    829   1.1   thorpej 
    830   1.1   thorpej 		/*
    831   1.1   thorpej 		 * Cancel the watchdog timer if there are no pending
    832   1.1   thorpej 		 * transmissions.
    833   1.1   thorpej 		 */
    834   1.1   thorpej 		if (sc->sc_txpending == 0)
    835   1.1   thorpej 			ifp->if_timer = 0;
    836   1.1   thorpej 
    837   1.1   thorpej 		/*
    838   1.1   thorpej 		 * Kick the transmitter after a DMA underrun.
    839   1.1   thorpej 		 */
    840   1.1   thorpej 		if (intstat & INTSTAT_TXU) {
    841   1.1   thorpej 			printf("%s: transmit underrun\n", sc->sc_dev.dv_xname);
    842   1.1   thorpej 			bus_space_write_4(sc->sc_st, sc->sc_sh,
    843   1.1   thorpej 			    EPIC_COMMAND, COMMAND_TXUGO);
    844   1.1   thorpej 			if (sc->sc_txpending)
    845   1.1   thorpej 				bus_space_write_4(sc->sc_st, sc->sc_sh,
    846   1.1   thorpej 				    EPIC_COMMAND, COMMAND_TXQUEUED);
    847   1.1   thorpej 		}
    848   1.1   thorpej 
    849   1.1   thorpej 		/*
    850   1.1   thorpej 		 * Try to get more packets going.
    851   1.1   thorpej 		 */
    852   1.1   thorpej 		epic_start(ifp);
    853   1.1   thorpej 	}
    854   1.1   thorpej 
    855   1.1   thorpej 	/*
    856   1.1   thorpej 	 * Check for fatal interrupts.
    857   1.1   thorpej 	 */
    858   1.1   thorpej 	if (intstat & INTSTAT_FATAL_INT) {
    859  1.21   thorpej 		if (intstat & INTSTAT_PTA)
    860  1.21   thorpej 			printf("%s: PCI target abort error\n",
    861  1.21   thorpej 			    sc->sc_dev.dv_xname);
    862  1.21   thorpej 		else if (intstat & INTSTAT_PMA)
    863  1.21   thorpej 			printf("%s: PCI master abort error\n",
    864  1.21   thorpej 			    sc->sc_dev.dv_xname);
    865  1.21   thorpej 		else if (intstat & INTSTAT_APE)
    866  1.21   thorpej 			printf("%s: PCI address parity error\n",
    867  1.21   thorpej 			    sc->sc_dev.dv_xname);
    868  1.21   thorpej 		else if (intstat & INTSTAT_DPE)
    869  1.21   thorpej 			printf("%s: PCI data parity error\n",
    870  1.21   thorpej 			    sc->sc_dev.dv_xname);
    871  1.21   thorpej 		else
    872  1.21   thorpej 			printf("%s: unknown fatal error\n",
    873  1.21   thorpej 			    sc->sc_dev.dv_xname);
    874  1.19   thorpej 		(void) epic_init(sc);
    875   1.1   thorpej 	}
    876   1.1   thorpej 
    877   1.1   thorpej 	/*
    878   1.1   thorpej 	 * Check for more interrupts.
    879   1.1   thorpej 	 */
    880   1.1   thorpej 	goto top;
    881   1.1   thorpej }
    882   1.1   thorpej 
    883   1.1   thorpej /*
    884   1.8   thorpej  * One second timer, used to tick the MII.
    885   1.8   thorpej  */
    886   1.8   thorpej void
    887   1.8   thorpej epic_tick(arg)
    888   1.8   thorpej 	void *arg;
    889   1.8   thorpej {
    890   1.8   thorpej 	struct epic_softc *sc = arg;
    891   1.8   thorpej 	int s;
    892   1.8   thorpej 
    893  1.12   thorpej 	s = splnet();
    894   1.8   thorpej 	mii_tick(&sc->sc_mii);
    895   1.8   thorpej 	splx(s);
    896   1.8   thorpej 
    897  1.29   thorpej 	callout_reset(&sc->sc_mii_callout, hz, epic_tick, sc);
    898   1.8   thorpej }
    899   1.8   thorpej 
    900   1.8   thorpej /*
    901   1.6   thorpej  * Fixup the clock source on the EPIC.
    902   1.6   thorpej  */
    903   1.6   thorpej void
    904   1.6   thorpej epic_fixup_clock_source(sc)
    905   1.6   thorpej 	struct epic_softc *sc;
    906   1.6   thorpej {
    907   1.6   thorpej 	int i;
    908   1.6   thorpej 
    909   1.6   thorpej 	/*
    910   1.6   thorpej 	 * According to SMC Application Note 7-15, the EPIC's clock
    911   1.6   thorpej 	 * source is incorrect following a reset.  This manifests itself
    912   1.6   thorpej 	 * as failure to recognize when host software has written to
    913   1.6   thorpej 	 * a register on the EPIC.  The appnote recommends issuing at
    914   1.6   thorpej 	 * least 16 consecutive writes to the CLOCK TEST bit to correctly
    915   1.6   thorpej 	 * configure the clock source.
    916   1.6   thorpej 	 */
    917   1.6   thorpej 	for (i = 0; i < 16; i++)
    918   1.6   thorpej 		bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_TEST,
    919   1.6   thorpej 		    TEST_CLOCKTEST);
    920   1.6   thorpej }
    921   1.6   thorpej 
    922   1.6   thorpej /*
    923   1.1   thorpej  * Perform a soft reset on the EPIC.
    924   1.1   thorpej  */
    925   1.1   thorpej void
    926   1.1   thorpej epic_reset(sc)
    927   1.1   thorpej 	struct epic_softc *sc;
    928   1.1   thorpej {
    929   1.1   thorpej 
    930   1.6   thorpej 	epic_fixup_clock_source(sc);
    931   1.6   thorpej 
    932   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_GENCTL, 0);
    933   1.1   thorpej 	delay(100);
    934   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_GENCTL, GENCTL_SOFTRESET);
    935   1.1   thorpej 	delay(100);
    936   1.6   thorpej 
    937   1.6   thorpej 	epic_fixup_clock_source(sc);
    938   1.1   thorpej }
    939   1.1   thorpej 
    940   1.1   thorpej /*
    941   1.7   mycroft  * Initialize the interface.  Must be called at splnet().
    942   1.1   thorpej  */
    943  1.19   thorpej int
    944   1.1   thorpej epic_init(sc)
    945   1.1   thorpej 	struct epic_softc *sc;
    946   1.1   thorpej {
    947   1.1   thorpej 	bus_space_tag_t st = sc->sc_st;
    948   1.1   thorpej 	bus_space_handle_t sh = sc->sc_sh;
    949   1.1   thorpej 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    950   1.1   thorpej 	u_int8_t *enaddr = LLADDR(ifp->if_sadl);
    951   1.1   thorpej 	struct epic_txdesc *txd;
    952  1.19   thorpej 	struct epic_descsoft *ds;
    953   1.1   thorpej 	u_int32_t genctl, reg0;
    954  1.19   thorpej 	int i, error = 0;
    955   1.1   thorpej 
    956   1.1   thorpej 	/*
    957   1.1   thorpej 	 * Cancel any pending I/O.
    958   1.1   thorpej 	 */
    959  1.19   thorpej 	epic_stop(sc, 0);
    960   1.1   thorpej 
    961   1.1   thorpej 	/*
    962   1.1   thorpej 	 * Reset the EPIC to a known state.
    963   1.1   thorpej 	 */
    964   1.1   thorpej 	epic_reset(sc);
    965   1.1   thorpej 
    966   1.1   thorpej 	/*
    967   1.1   thorpej 	 * Magical mystery initialization.
    968   1.1   thorpej 	 */
    969   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_TXTEST, 0);
    970   1.1   thorpej 
    971   1.1   thorpej 	/*
    972   1.1   thorpej 	 * Initialize the EPIC genctl register:
    973   1.1   thorpej 	 *
    974   1.1   thorpej 	 *	- 64 byte receive FIFO threshold
    975   1.1   thorpej 	 *	- automatic advance to next receive frame
    976   1.1   thorpej 	 */
    977   1.1   thorpej 	genctl = GENCTL_RX_FIFO_THRESH0 | GENCTL_ONECOPY;
    978  1.18   thorpej #if BYTE_ORDER == BIG_ENDIAN
    979  1.18   thorpej 	genctl |= GENCTL_BIG_ENDIAN;
    980  1.18   thorpej #endif
    981   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_GENCTL, genctl);
    982   1.1   thorpej 
    983   1.1   thorpej 	/*
    984   1.1   thorpej 	 * Reset the MII bus and PHY.
    985   1.1   thorpej 	 */
    986   1.1   thorpej 	reg0 = bus_space_read_4(st, sh, EPIC_NVCTL);
    987   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_NVCTL, reg0 | NVCTL_GPIO1 | NVCTL_GPOE1);
    988   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_MIICFG, MIICFG_ENASER);
    989   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_GENCTL, genctl | GENCTL_RESET_PHY);
    990   1.1   thorpej 	delay(100);
    991   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_GENCTL, genctl);
    992   1.1   thorpej 	delay(100);
    993   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_NVCTL, reg0);
    994   1.1   thorpej 
    995   1.1   thorpej 	/*
    996   1.1   thorpej 	 * Initialize Ethernet address.
    997   1.1   thorpej 	 */
    998   1.1   thorpej 	reg0 = enaddr[1] << 8 | enaddr[0];
    999   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_LAN0, reg0);
   1000   1.1   thorpej 	reg0 = enaddr[3] << 8 | enaddr[2];
   1001   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_LAN1, reg0);
   1002   1.1   thorpej 	reg0 = enaddr[5] << 8 | enaddr[4];
   1003   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_LAN2, reg0);
   1004   1.1   thorpej 
   1005   1.1   thorpej 	/*
   1006   1.1   thorpej 	 * Initialize receive control.  Remember the external buffer
   1007   1.1   thorpej 	 * size setting.
   1008   1.1   thorpej 	 */
   1009   1.1   thorpej 	reg0 = bus_space_read_4(st, sh, EPIC_RXCON) &
   1010   1.1   thorpej 	    (RXCON_EXTBUFSIZESEL1 | RXCON_EXTBUFSIZESEL0);
   1011   1.1   thorpej 	reg0 |= (RXCON_RXMULTICAST | RXCON_RXBROADCAST);
   1012   1.1   thorpej 	if (ifp->if_flags & IFF_PROMISC)
   1013   1.1   thorpej 		reg0 |= RXCON_PROMISCMODE;
   1014   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_RXCON, reg0);
   1015   1.1   thorpej 
   1016  1.13   thorpej 	/* Set the current media. */
   1017   1.8   thorpej 	mii_mediachg(&sc->sc_mii);
   1018   1.1   thorpej 
   1019  1.13   thorpej 	/* Set up the multicast hash table. */
   1020  1.13   thorpej 	epic_set_mchash(sc);
   1021  1.13   thorpej 
   1022   1.1   thorpej 	/*
   1023  1.10   thorpej 	 * Initialize the transmit descriptor ring.  txlast is initialized
   1024  1.10   thorpej 	 * to the end of the list so that it will wrap around to the first
   1025  1.10   thorpej 	 * descriptor when the first packet is transmitted.
   1026   1.1   thorpej 	 */
   1027   1.1   thorpej 	for (i = 0; i < EPIC_NTXDESC; i++) {
   1028  1.10   thorpej 		txd = EPIC_CDTX(sc, i);
   1029  1.10   thorpej 		memset(txd, 0, sizeof(struct epic_txdesc));
   1030  1.10   thorpej 		txd->et_bufaddr = EPIC_CDFLADDR(sc, i);
   1031  1.10   thorpej 		txd->et_nextdesc = EPIC_CDTXADDR(sc, EPIC_NEXTTX(i));
   1032  1.10   thorpej 		EPIC_CDTXSYNC(sc, i, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1033   1.1   thorpej 	}
   1034  1.10   thorpej 	sc->sc_txpending = 0;
   1035  1.10   thorpej 	sc->sc_txdirty = 0;
   1036  1.10   thorpej 	sc->sc_txlast = EPIC_NTXDESC - 1;
   1037   1.1   thorpej 
   1038   1.1   thorpej 	/*
   1039  1.19   thorpej 	 * Initialize the receive descriptor ring.
   1040   1.1   thorpej 	 */
   1041  1.19   thorpej 	for (i = 0; i < EPIC_NRXDESC; i++) {
   1042  1.19   thorpej 		ds = EPIC_DSRX(sc, i);
   1043  1.19   thorpej 		if (ds->ds_mbuf == NULL) {
   1044  1.19   thorpej 			if ((error = epic_add_rxbuf(sc, i)) != 0) {
   1045  1.19   thorpej 				printf("%s: unable to allocate or map rx "
   1046  1.19   thorpej 				    "buffer %d error = %d\n",
   1047  1.19   thorpej 				    sc->sc_dev.dv_xname, i, error);
   1048  1.19   thorpej 				/*
   1049  1.19   thorpej 				 * XXX Should attempt to run with fewer receive
   1050  1.19   thorpej 				 * XXX buffers instead of just failing.
   1051  1.19   thorpej 				 */
   1052  1.19   thorpej 				epic_rxdrain(sc);
   1053  1.19   thorpej 				goto out;
   1054  1.19   thorpej 			}
   1055  1.19   thorpej 		}
   1056  1.19   thorpej 	}
   1057  1.10   thorpej 	sc->sc_rxptr = 0;
   1058   1.1   thorpej 
   1059   1.1   thorpej 	/*
   1060   1.1   thorpej 	 * Initialize the interrupt mask and enable interrupts.
   1061   1.1   thorpej 	 */
   1062   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_INTMASK, INTMASK);
   1063   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_GENCTL, genctl | GENCTL_INTENA);
   1064   1.1   thorpej 
   1065   1.1   thorpej 	/*
   1066   1.1   thorpej 	 * Give the transmit and receive rings to the EPIC.
   1067   1.1   thorpej 	 */
   1068   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_PTCDAR,
   1069  1.10   thorpej 	    EPIC_CDTXADDR(sc, EPIC_NEXTTX(sc->sc_txlast)));
   1070   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_PRCDAR,
   1071  1.10   thorpej 	    EPIC_CDRXADDR(sc, sc->sc_rxptr));
   1072   1.1   thorpej 
   1073   1.1   thorpej 	/*
   1074   1.1   thorpej 	 * Set the EPIC in motion.
   1075   1.1   thorpej 	 */
   1076   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_COMMAND,
   1077   1.1   thorpej 	    COMMAND_RXQUEUED | COMMAND_START_RX);
   1078   1.1   thorpej 
   1079   1.1   thorpej 	/*
   1080   1.1   thorpej 	 * ...all done!
   1081   1.1   thorpej 	 */
   1082   1.1   thorpej 	ifp->if_flags |= IFF_RUNNING;
   1083   1.1   thorpej 	ifp->if_flags &= ~IFF_OACTIVE;
   1084   1.8   thorpej 
   1085   1.8   thorpej 	/*
   1086   1.8   thorpej 	 * Start the one second clock.
   1087   1.8   thorpej 	 */
   1088  1.29   thorpej 	callout_reset(&sc->sc_mii_callout, hz, epic_tick, sc);
   1089   1.9   thorpej 
   1090   1.9   thorpej 	/*
   1091   1.9   thorpej 	 * Attempt to start output on the interface.
   1092   1.9   thorpej 	 */
   1093   1.9   thorpej 	epic_start(ifp);
   1094  1.19   thorpej 
   1095  1.19   thorpej  out:
   1096  1.19   thorpej 	if (error)
   1097  1.19   thorpej 		printf("%s: interface not running\n", sc->sc_dev.dv_xname);
   1098  1.19   thorpej 	return (error);
   1099  1.19   thorpej }
   1100  1.19   thorpej 
   1101  1.19   thorpej /*
   1102  1.19   thorpej  * Drain the receive queue.
   1103  1.19   thorpej  */
   1104  1.19   thorpej void
   1105  1.19   thorpej epic_rxdrain(sc)
   1106  1.19   thorpej 	struct epic_softc *sc;
   1107  1.19   thorpej {
   1108  1.19   thorpej 	struct epic_descsoft *ds;
   1109  1.19   thorpej 	int i;
   1110  1.19   thorpej 
   1111  1.19   thorpej 	for (i = 0; i < EPIC_NRXDESC; i++) {
   1112  1.19   thorpej 		ds = EPIC_DSRX(sc, i);
   1113  1.19   thorpej 		if (ds->ds_mbuf != NULL) {
   1114  1.19   thorpej 			bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
   1115  1.19   thorpej 			m_freem(ds->ds_mbuf);
   1116  1.19   thorpej 			ds->ds_mbuf = NULL;
   1117  1.19   thorpej 		}
   1118  1.19   thorpej 	}
   1119   1.1   thorpej }
   1120   1.1   thorpej 
   1121   1.1   thorpej /*
   1122   1.1   thorpej  * Stop transmission on the interface.
   1123   1.1   thorpej  */
   1124   1.1   thorpej void
   1125  1.19   thorpej epic_stop(sc, drain)
   1126   1.1   thorpej 	struct epic_softc *sc;
   1127  1.19   thorpej 	int drain;
   1128   1.1   thorpej {
   1129   1.1   thorpej 	bus_space_tag_t st = sc->sc_st;
   1130   1.1   thorpej 	bus_space_handle_t sh = sc->sc_sh;
   1131   1.1   thorpej 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1132   1.1   thorpej 	struct epic_descsoft *ds;
   1133   1.1   thorpej 	u_int32_t reg;
   1134   1.1   thorpej 	int i;
   1135   1.6   thorpej 
   1136   1.8   thorpej 	/*
   1137   1.8   thorpej 	 * Stop the one second clock.
   1138   1.8   thorpej 	 */
   1139  1.29   thorpej 	callout_stop(&sc->sc_mii_callout);
   1140  1.23   thorpej 
   1141  1.23   thorpej 	/* Down the MII. */
   1142  1.23   thorpej 	mii_down(&sc->sc_mii);
   1143   1.8   thorpej 
   1144   1.6   thorpej 	/* Paranoia... */
   1145   1.6   thorpej 	epic_fixup_clock_source(sc);
   1146   1.1   thorpej 
   1147   1.1   thorpej 	/*
   1148   1.1   thorpej 	 * Disable interrupts.
   1149   1.1   thorpej 	 */
   1150   1.1   thorpej 	reg = bus_space_read_4(st, sh, EPIC_GENCTL);
   1151   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_GENCTL, reg & ~GENCTL_INTENA);
   1152   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_INTMASK, 0);
   1153   1.1   thorpej 
   1154   1.1   thorpej 	/*
   1155   1.1   thorpej 	 * Stop the DMA engine and take the receiver off-line.
   1156   1.1   thorpej 	 */
   1157   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_COMMAND, COMMAND_STOP_RDMA |
   1158   1.1   thorpej 	    COMMAND_STOP_TDMA | COMMAND_STOP_RX);
   1159   1.1   thorpej 
   1160   1.1   thorpej 	/*
   1161   1.1   thorpej 	 * Release any queued transmit buffers.
   1162   1.1   thorpej 	 */
   1163   1.1   thorpej 	for (i = 0; i < EPIC_NTXDESC; i++) {
   1164  1.10   thorpej 		ds = EPIC_DSTX(sc, i);
   1165   1.1   thorpej 		if (ds->ds_mbuf != NULL) {
   1166   1.1   thorpej 			bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
   1167   1.1   thorpej 			m_freem(ds->ds_mbuf);
   1168   1.1   thorpej 			ds->ds_mbuf = NULL;
   1169   1.1   thorpej 		}
   1170  1.19   thorpej 	}
   1171  1.19   thorpej 
   1172  1.19   thorpej 	if (drain) {
   1173  1.19   thorpej 		/*
   1174  1.19   thorpej 		 * Release the receive buffers.
   1175  1.19   thorpej 		 */
   1176  1.19   thorpej 		epic_rxdrain(sc);
   1177   1.1   thorpej 	}
   1178   1.1   thorpej 
   1179   1.1   thorpej 	/*
   1180   1.1   thorpej 	 * Mark the interface down and cancel the watchdog timer.
   1181   1.1   thorpej 	 */
   1182   1.1   thorpej 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   1183   1.1   thorpej 	ifp->if_timer = 0;
   1184   1.1   thorpej }
   1185   1.1   thorpej 
   1186   1.1   thorpej /*
   1187   1.1   thorpej  * Read the EPIC Serial EEPROM.
   1188   1.1   thorpej  */
   1189   1.1   thorpej void
   1190   1.1   thorpej epic_read_eeprom(sc, word, wordcnt, data)
   1191   1.1   thorpej 	struct epic_softc *sc;
   1192   1.1   thorpej 	int word, wordcnt;
   1193   1.1   thorpej 	u_int16_t *data;
   1194   1.1   thorpej {
   1195   1.1   thorpej 	bus_space_tag_t st = sc->sc_st;
   1196   1.1   thorpej 	bus_space_handle_t sh = sc->sc_sh;
   1197   1.1   thorpej 	u_int16_t reg;
   1198   1.1   thorpej 	int i, x;
   1199   1.1   thorpej 
   1200   1.1   thorpej #define	EEPROM_WAIT_READY(st, sh) \
   1201   1.1   thorpej 	while ((bus_space_read_4((st), (sh), EPIC_EECTL) & EECTL_EERDY) == 0) \
   1202   1.1   thorpej 		/* nothing */
   1203   1.1   thorpej 
   1204   1.1   thorpej 	/*
   1205   1.1   thorpej 	 * Enable the EEPROM.
   1206   1.1   thorpej 	 */
   1207   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_EECTL, EECTL_ENABLE);
   1208   1.1   thorpej 	EEPROM_WAIT_READY(st, sh);
   1209   1.1   thorpej 
   1210   1.1   thorpej 	for (i = 0; i < wordcnt; i++) {
   1211   1.1   thorpej 		/* Send CHIP SELECT for one clock tick. */
   1212   1.1   thorpej 		bus_space_write_4(st, sh, EPIC_EECTL, EECTL_ENABLE|EECTL_EECS);
   1213   1.1   thorpej 		EEPROM_WAIT_READY(st, sh);
   1214   1.1   thorpej 
   1215   1.1   thorpej 		/* Shift in the READ opcode. */
   1216   1.1   thorpej 		for (x = 3; x > 0; x--) {
   1217   1.1   thorpej 			reg = EECTL_ENABLE|EECTL_EECS;
   1218   1.1   thorpej 			if (EPIC_EEPROM_OPC_READ & (1 << (x - 1)))
   1219   1.1   thorpej 				reg |= EECTL_EEDI;
   1220   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg);
   1221   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1222   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg|EECTL_EESK);
   1223   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1224   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg);
   1225   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1226   1.1   thorpej 		}
   1227   1.1   thorpej 
   1228   1.1   thorpej 		/* Shift in address. */
   1229   1.1   thorpej 		for (x = 6; x > 0; x--) {
   1230   1.1   thorpej 			reg = EECTL_ENABLE|EECTL_EECS;
   1231   1.1   thorpej 			if ((word + i) & (1 << (x - 1)))
   1232   1.1   thorpej 				reg |= EECTL_EEDI;
   1233   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg);
   1234   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1235   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg|EECTL_EESK);
   1236   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1237   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg);
   1238   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1239   1.1   thorpej 		}
   1240   1.1   thorpej 
   1241   1.1   thorpej 		/* Shift out data. */
   1242   1.1   thorpej 		reg = EECTL_ENABLE|EECTL_EECS;
   1243   1.1   thorpej 		data[i] = 0;
   1244   1.1   thorpej 		for (x = 16; x > 0; x--) {
   1245   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg|EECTL_EESK);
   1246   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1247   1.1   thorpej 			if (bus_space_read_4(st, sh, EPIC_EECTL) & EECTL_EEDO)
   1248   1.1   thorpej 				data[i] |= (1 << (x - 1));
   1249   1.1   thorpej 			bus_space_write_4(st, sh, EPIC_EECTL, reg);
   1250   1.1   thorpej 			EEPROM_WAIT_READY(st, sh);
   1251   1.1   thorpej 		}
   1252   1.1   thorpej 
   1253   1.1   thorpej 		/* Clear CHIP SELECT. */
   1254   1.1   thorpej 		bus_space_write_4(st, sh, EPIC_EECTL, EECTL_ENABLE);
   1255   1.1   thorpej 		EEPROM_WAIT_READY(st, sh);
   1256   1.1   thorpej 	}
   1257   1.1   thorpej 
   1258   1.1   thorpej 	/*
   1259   1.1   thorpej 	 * Disable the EEPROM.
   1260   1.1   thorpej 	 */
   1261   1.1   thorpej 	bus_space_write_4(st, sh, EPIC_EECTL, 0);
   1262   1.1   thorpej 
   1263   1.1   thorpej #undef EEPROM_WAIT_READY
   1264   1.1   thorpej }
   1265   1.1   thorpej 
   1266   1.1   thorpej /*
   1267   1.1   thorpej  * Add a receive buffer to the indicated descriptor.
   1268   1.1   thorpej  */
   1269   1.1   thorpej int
   1270   1.1   thorpej epic_add_rxbuf(sc, idx)
   1271   1.1   thorpej 	struct epic_softc *sc;
   1272   1.1   thorpej 	int idx;
   1273   1.1   thorpej {
   1274  1.10   thorpej 	struct epic_descsoft *ds = EPIC_DSRX(sc, idx);
   1275  1.10   thorpej 	struct mbuf *m;
   1276  1.10   thorpej 	int error;
   1277   1.1   thorpej 
   1278  1.10   thorpej 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1279  1.10   thorpej 	if (m == NULL)
   1280  1.10   thorpej 		return (ENOBUFS);
   1281   1.1   thorpej 
   1282  1.10   thorpej 	MCLGET(m, M_DONTWAIT);
   1283  1.10   thorpej 	if ((m->m_flags & M_EXT) == 0) {
   1284  1.10   thorpej 		m_freem(m);
   1285  1.10   thorpej 		return (ENOBUFS);
   1286   1.1   thorpej 	}
   1287   1.1   thorpej 
   1288  1.10   thorpej 	if (ds->ds_mbuf != NULL)
   1289  1.10   thorpej 		bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
   1290  1.10   thorpej 
   1291   1.1   thorpej 	ds->ds_mbuf = m;
   1292   1.1   thorpej 
   1293  1.10   thorpej 	error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap,
   1294  1.10   thorpej 	    m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
   1295  1.10   thorpej 	if (error) {
   1296  1.10   thorpej 		printf("%s: can't load rx DMA map %d, error = %d\n",
   1297  1.10   thorpej 		    sc->sc_dev.dv_xname, idx, error);
   1298  1.10   thorpej 		panic("epic_add_rxbuf");	/* XXX */
   1299   1.1   thorpej 	}
   1300   1.1   thorpej 
   1301   1.1   thorpej 	bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
   1302   1.1   thorpej 	    ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
   1303   1.1   thorpej 
   1304  1.10   thorpej 	EPIC_INIT_RXDESC(sc, idx);
   1305   1.1   thorpej 
   1306  1.10   thorpej 	return (0);
   1307   1.1   thorpej }
   1308   1.1   thorpej 
   1309   1.1   thorpej /*
   1310   1.1   thorpej  * Set the EPIC multicast hash table.
   1311  1.13   thorpej  *
   1312  1.13   thorpej  * NOTE: We rely on a recently-updated mii_media_active here!
   1313   1.1   thorpej  */
   1314   1.1   thorpej void
   1315   1.1   thorpej epic_set_mchash(sc)
   1316   1.1   thorpej 	struct epic_softc *sc;
   1317   1.1   thorpej {
   1318   1.1   thorpej 	struct ethercom *ec = &sc->sc_ethercom;
   1319   1.1   thorpej 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1320   1.1   thorpej 	struct ether_multi *enm;
   1321   1.1   thorpej 	struct ether_multistep step;
   1322   1.1   thorpej 	u_int8_t *cp;
   1323   1.1   thorpej 	u_int32_t crc, mchash[4];
   1324   1.1   thorpej 	int len;
   1325   1.1   thorpej 	static const u_int32_t crctab[] = {
   1326   1.1   thorpej 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
   1327   1.1   thorpej 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
   1328   1.1   thorpej 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
   1329   1.1   thorpej 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
   1330   1.1   thorpej 	};
   1331   1.1   thorpej 
   1332   1.1   thorpej 	/*
   1333   1.1   thorpej 	 * Set up the multicast address filter by passing all multicast
   1334   1.1   thorpej 	 * addresses through a CRC generator, and then using the high-order
   1335   1.1   thorpej 	 * 6 bits as an index into the 64 bit multicast hash table (only
   1336   1.1   thorpej 	 * the lower 16 bits of each 32 bit multicast hash register are
   1337   1.1   thorpej 	 * valid).  The high order bit selects the register, while the
   1338   1.1   thorpej 	 * rest of the bits select the bit within the register.
   1339   1.1   thorpej 	 */
   1340   1.1   thorpej 
   1341   1.1   thorpej 	if (ifp->if_flags & IFF_PROMISC)
   1342   1.1   thorpej 		goto allmulti;
   1343   1.1   thorpej 
   1344  1.13   thorpej 	if (IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_10_T) {
   1345  1.13   thorpej 		/* XXX hardware bug in 10Mbps mode. */
   1346  1.13   thorpej 		goto allmulti;
   1347  1.13   thorpej 	}
   1348   1.1   thorpej 
   1349   1.1   thorpej 	mchash[0] = mchash[1] = mchash[2] = mchash[3] = 0;
   1350   1.1   thorpej 
   1351   1.1   thorpej 	ETHER_FIRST_MULTI(step, ec, enm);
   1352   1.1   thorpej 	while (enm != NULL) {
   1353   1.1   thorpej 		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
   1354   1.1   thorpej 			/*
   1355   1.1   thorpej 			 * We must listen to a range of multicast addresses.
   1356   1.1   thorpej 			 * For now, just accept all multicasts, rather than
   1357   1.1   thorpej 			 * trying to set only those filter bits needed to match
   1358   1.1   thorpej 			 * the range.  (At this time, the only use of address
   1359   1.1   thorpej 			 * ranges is for IP multicast routing, for which the
   1360   1.1   thorpej 			 * range is big enough to require all bits set.)
   1361   1.1   thorpej 			 */
   1362   1.1   thorpej 			goto allmulti;
   1363   1.1   thorpej 		}
   1364   1.1   thorpej 
   1365   1.1   thorpej 		cp = enm->enm_addrlo;
   1366   1.1   thorpej 		crc = 0xffffffff;
   1367   1.1   thorpej 		for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
   1368   1.1   thorpej 			crc ^= *cp++;
   1369   1.1   thorpej 			crc = (crc >> 4) ^ crctab[crc & 0xf];
   1370   1.1   thorpej 			crc = (crc >> 4) ^ crctab[crc & 0xf];
   1371   1.1   thorpej 		}
   1372   1.1   thorpej 		/* Just want the 6 most significant bits. */
   1373   1.1   thorpej 		crc >>= 26;
   1374   1.1   thorpej 
   1375   1.1   thorpej 		/* Set the corresponding bit in the hash table. */
   1376   1.1   thorpej 		mchash[crc >> 4] |= 1 << (crc & 0xf);
   1377   1.1   thorpej 
   1378   1.1   thorpej 		ETHER_NEXT_MULTI(step, enm);
   1379   1.1   thorpej 	}
   1380   1.1   thorpej 
   1381   1.1   thorpej 	ifp->if_flags &= ~IFF_ALLMULTI;
   1382   1.1   thorpej 	goto sethash;
   1383   1.1   thorpej 
   1384   1.1   thorpej  allmulti:
   1385   1.1   thorpej 	ifp->if_flags |= IFF_ALLMULTI;
   1386   1.1   thorpej 	mchash[0] = mchash[1] = mchash[2] = mchash[3] = 0xffff;
   1387   1.1   thorpej 
   1388   1.1   thorpej  sethash:
   1389   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC0, mchash[0]);
   1390   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC1, mchash[1]);
   1391   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC2, mchash[2]);
   1392   1.1   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC3, mchash[3]);
   1393   1.8   thorpej }
   1394   1.8   thorpej 
   1395   1.8   thorpej /*
   1396   1.8   thorpej  * Wait for the MII to become ready.
   1397   1.8   thorpej  */
   1398   1.8   thorpej int
   1399   1.8   thorpej epic_mii_wait(sc, rw)
   1400   1.8   thorpej 	struct epic_softc *sc;
   1401   1.8   thorpej 	u_int32_t rw;
   1402   1.8   thorpej {
   1403   1.8   thorpej 	int i;
   1404   1.8   thorpej 
   1405   1.8   thorpej 	for (i = 0; i < 50; i++) {
   1406   1.8   thorpej 		if ((bus_space_read_4(sc->sc_st, sc->sc_sh, EPIC_MMCTL) & rw)
   1407   1.8   thorpej 		    == 0)
   1408   1.8   thorpej 			break;
   1409   1.8   thorpej 		delay(2);
   1410   1.8   thorpej 	}
   1411   1.8   thorpej 	if (i == 50) {
   1412   1.8   thorpej 		printf("%s: MII timed out\n", sc->sc_dev.dv_xname);
   1413   1.8   thorpej 		return (1);
   1414   1.8   thorpej 	}
   1415   1.8   thorpej 
   1416   1.8   thorpej 	return (0);
   1417   1.8   thorpej }
   1418   1.8   thorpej 
   1419   1.8   thorpej /*
   1420   1.8   thorpej  * Read from the MII.
   1421   1.8   thorpej  */
   1422   1.8   thorpej int
   1423   1.8   thorpej epic_mii_read(self, phy, reg)
   1424   1.8   thorpej 	struct device *self;
   1425   1.8   thorpej 	int phy, reg;
   1426   1.8   thorpej {
   1427   1.8   thorpej 	struct epic_softc *sc = (struct epic_softc *)self;
   1428   1.8   thorpej 
   1429   1.8   thorpej 	if (epic_mii_wait(sc, MMCTL_WRITE))
   1430   1.8   thorpej 		return (0);
   1431   1.8   thorpej 
   1432   1.8   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MMCTL,
   1433   1.8   thorpej 	    MMCTL_ARG(phy, reg, MMCTL_READ));
   1434   1.8   thorpej 
   1435   1.8   thorpej 	if (epic_mii_wait(sc, MMCTL_READ))
   1436   1.8   thorpej 		return (0);
   1437   1.8   thorpej 
   1438   1.8   thorpej 	return (bus_space_read_4(sc->sc_st, sc->sc_sh, EPIC_MMDATA) &
   1439   1.8   thorpej 	    MMDATA_MASK);
   1440   1.8   thorpej }
   1441   1.8   thorpej 
   1442   1.8   thorpej /*
   1443   1.8   thorpej  * Write to the MII.
   1444   1.8   thorpej  */
   1445   1.8   thorpej void
   1446   1.8   thorpej epic_mii_write(self, phy, reg, val)
   1447   1.8   thorpej 	struct device *self;
   1448   1.8   thorpej 	int phy, reg, val;
   1449   1.8   thorpej {
   1450   1.8   thorpej 	struct epic_softc *sc = (struct epic_softc *)self;
   1451   1.8   thorpej 
   1452   1.8   thorpej 	if (epic_mii_wait(sc, MMCTL_WRITE))
   1453   1.8   thorpej 		return;
   1454   1.8   thorpej 
   1455   1.8   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MMDATA, val);
   1456   1.8   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MMCTL,
   1457   1.8   thorpej 	    MMCTL_ARG(phy, reg, MMCTL_WRITE));
   1458   1.8   thorpej }
   1459   1.8   thorpej 
   1460   1.8   thorpej /*
   1461   1.8   thorpej  * Callback from PHY when media changes.
   1462   1.8   thorpej  */
   1463   1.8   thorpej void
   1464   1.8   thorpej epic_statchg(self)
   1465   1.8   thorpej 	struct device *self;
   1466   1.8   thorpej {
   1467  1.11   thorpej 	struct epic_softc *sc = (struct epic_softc *)self;
   1468  1.11   thorpej 	u_int32_t txcon;
   1469  1.11   thorpej 
   1470  1.11   thorpej 	/*
   1471  1.11   thorpej 	 * Update loopback bits in TXCON to reflect duplex mode.
   1472  1.11   thorpej 	 */
   1473  1.11   thorpej 	txcon = bus_space_read_4(sc->sc_st, sc->sc_sh, EPIC_TXCON);
   1474  1.11   thorpej 	if (sc->sc_mii.mii_media_active & IFM_FDX)
   1475  1.11   thorpej 		txcon |= (TXCON_LOOPBACK_D1|TXCON_LOOPBACK_D2);
   1476  1.11   thorpej 	else
   1477  1.11   thorpej 		txcon &= ~(TXCON_LOOPBACK_D1|TXCON_LOOPBACK_D2);
   1478  1.11   thorpej 	bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_TXCON, txcon);
   1479  1.13   thorpej 
   1480  1.13   thorpej 	/*
   1481  1.13   thorpej 	 * There is a multicast filter bug in 10Mbps mode.  Kick the
   1482  1.13   thorpej 	 * multicast filter in case the speed changed.
   1483  1.13   thorpej 	 */
   1484  1.13   thorpej 	epic_set_mchash(sc);
   1485   1.8   thorpej }
   1486   1.8   thorpej 
   1487   1.8   thorpej /*
   1488   1.8   thorpej  * Callback from ifmedia to request current media status.
   1489   1.8   thorpej  */
   1490   1.8   thorpej void
   1491   1.8   thorpej epic_mediastatus(ifp, ifmr)
   1492   1.8   thorpej 	struct ifnet *ifp;
   1493   1.8   thorpej 	struct ifmediareq *ifmr;
   1494   1.8   thorpej {
   1495   1.8   thorpej 	struct epic_softc *sc = ifp->if_softc;
   1496   1.8   thorpej 
   1497   1.8   thorpej 	mii_pollstat(&sc->sc_mii);
   1498   1.8   thorpej 	ifmr->ifm_status = sc->sc_mii.mii_media_status;
   1499   1.8   thorpej 	ifmr->ifm_active = sc->sc_mii.mii_media_active;
   1500   1.8   thorpej }
   1501   1.8   thorpej 
   1502   1.8   thorpej /*
   1503   1.8   thorpej  * Callback from ifmedia to request new media setting.
   1504   1.8   thorpej  */
   1505   1.8   thorpej int
   1506   1.8   thorpej epic_mediachange(ifp)
   1507   1.8   thorpej 	struct ifnet *ifp;
   1508   1.8   thorpej {
   1509  1.11   thorpej 	struct epic_softc *sc = ifp->if_softc;
   1510   1.8   thorpej 
   1511   1.8   thorpej 	if (ifp->if_flags & IFF_UP)
   1512  1.11   thorpej 		mii_mediachg(&sc->sc_mii);
   1513   1.8   thorpej 	return (0);
   1514   1.1   thorpej }
   1515