Home | History | Annotate | Line # | Download | only in ic
mb86950.c revision 1.12
      1 /*	$NetBSD: mb86950.c,v 1.12 2008/11/07 00:20:02 dyoung Exp $	*/
      2 
      3 /*
      4  * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
      5  *
      6  * This software may be used, modified, copied, distributed, and sold, in
      7  * both source and binary form provided that the above copyright, these
      8  * terms and the following disclaimer are retained.  The name of the author
      9  * and/or the contributor may not be used to endorse or promote products
     10  * derived from this software without specific prior written permission.
     11  *
     12  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
     13  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     14  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     15  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
     16  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     17  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     18  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
     19  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     20  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     21  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     22  * SUCH DAMAGE.
     23  */
     24 
     25 /*
     26  * Portions copyright (C) 1993, David Greenman.  This software may be used,
     27  * modified, copied, distributed, and sold, in both source and binary form
     28  * provided that the above copyright and these terms are retained.  Under no
     29  * circumstances is the author responsible for the proper functioning of this
     30  * software, nor does the author assume any responsibility for damages
     31  * incurred with its use.
     32  */
     33 
     34  /*
     35   * Portions copyright (c) 1995 Mika Kortelainen
     36   * All rights reserved.
     37   *
     38   * Redistribution and use in source and binary forms, with or without
     39   * modification, are permitted provided that the following conditions
     40   * are met:
     41   * 1. Redistributions of source code must retain the above copyright
     42   *    notice, this list of conditions and the following disclaimer.
     43   * 2. Redistributions in binary form must reproduce the above copyright
     44   *    notice, this list of conditions and the following disclaimer in the
     45   *    documentation and/or other materials provided with the distribution.
     46   * 3. All advertising materials mentioning features or use of this software
     47   *    must display the following acknowledgement:
     48   *      This product includes software developed by  Mika Kortelainen
     49   * 4. The name of the author may not be used to endorse or promote products
     50   *    derived from this software without specific prior written permission
     51   *
     52   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     53   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     54   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     55   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     56   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     57   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     58   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     59   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     60   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     61   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     62   */
     63 
     64  /*
     65   * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
     66   * Contributed by M.S. <seki (at) sysrap.cs.fujitsu.co.jp>
     67   */
     68 
     69 #include <sys/cdefs.h>
     70 __KERNEL_RCSID(0, "$NetBSD: mb86950.c,v 1.12 2008/11/07 00:20:02 dyoung Exp $");
     71 
     72 /*
     73  * Device driver for Fujitsu mb86950 based Ethernet cards.
     74  * Adapted by Dave J. Barnes from various Internet sources including
     75  * mb86960.c (NetBSD), if_qn.c (NetBSD/Amiga), DOS Packet Driver (Brian Fisher,
     76  * Queens University), EtherBoot Driver (Ken Yap).
     77  */
     78 
     79 /* XXX There are still rough edges......
     80  *
     81  * (1) There is no watchdog timer for the transmitter. It's doubtful that
     82  *     transmit from the chip could be restarted without a hardware reset
     83  *     though. (Fixed - not fully tested)
     84  *
     85  * (2) The media interface callback goo is broke.  No big deal since to change
     86  *     from aui to bnc on the old Tiara LANCard requires moving 8 board jumpers.
     87  *     Other cards (SMC ?) using the EtherStar chip may support media change
     88  *     via software. (Fixed - tested)
     89  *
     90  * (3) The maximum outstanding transmit packets is set to 4.  What
     91  *     is a good limit of outstanding transmit packets for the EtherStar?
     92  *     Is there a way to tell how many bytes are remaining to be
     93  *     transmitted? [no]
     94 ---
     95 	When the EtherStar was designed, CPU power was a fraction
     96 	of what it is now.  The single EtherStar transmit buffer
     97 	was fine.  It was unlikely that the CPU could outrun the
     98 	EtherStar. However, things in 2004 are quite different.
     99 	sc->txb_size is used to keep the CPU from overrunning the
    100 	EtherStar.  At most allow one packet transmitting and one
    101 	going into the fifo.
    102 
    103 ---
    104     No, that isn't right either :(
    105 
    106  * (4) Multicast isn't supported.  Feel free to add multicast code
    107  *     if you know how to make the EtherStar do multicast.  Otherwise
    108  *     you'd have to use promiscuous mode and do multicast in software. OUCH!
    109  *
    110  * (5) There are no bus_space_barrier calls used. Are they needed? Maybe not.
    111  *
    112  * (6) Access to the fifo assumes word (16 bit) mode.  Cards configured for
    113  *     byte wide fifo access will require driver code changes.
    114  *
    115  * Only the minimum code necessary to make the Tiara LANCard work
    116  * has been tested. Other cards may require more work, especially
    117  * byte mode fifo and if DMA is used.
    118  *
    119  * djb / 2004
    120  */
    121 
    122 #include "opt_inet.h"
    123 #include "bpfilter.h"
    124 #include "rnd.h"
    125 
    126 #include <sys/param.h>
    127 #include <sys/systm.h>
    128 #include <sys/errno.h>
    129 #include <sys/ioctl.h>
    130 #include <sys/mbuf.h>
    131 #include <sys/socket.h>
    132 #include <sys/syslog.h>
    133 #include <sys/device.h>
    134 #if NRND > 0
    135 #include <sys/rnd.h>
    136 #endif
    137 
    138 #include <net/if.h>
    139 #include <net/if_dl.h>
    140 #include <net/if_types.h>
    141 #include <net/if_media.h>
    142 #include <net/if_ether.h>
    143 
    144 #ifdef INET
    145 #include <netinet/in.h>
    146 #include <netinet/in_systm.h>
    147 #include <netinet/in_var.h>
    148 #include <netinet/ip.h>
    149 #include <netinet/if_inarp.h>
    150 #endif
    151 
    152 
    153 #if NBPFILTER > 0
    154 #include <net/bpf.h>
    155 #include <net/bpfdesc.h>
    156 #endif
    157 
    158 #include <sys/bus.h>
    159 
    160 #include <dev/ic/mb86950reg.h>
    161 #include <dev/ic/mb86950var.h>
    162 
    163 #ifndef __BUS_SPACE_HAS_STREAM_METHODS
    164 #define bus_space_write_stream_2	bus_space_write_2
    165 #define bus_space_write_multi_stream_2	bus_space_write_multi_2
    166 #define bus_space_read_multi_stream_2	bus_space_read_multi_2
    167 #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
    168 
    169 /* Standard driver entry points.  These can be static. */
    170 int		mb86950_ioctl	__P((struct ifnet *, u_long, void *));
    171 void	mb86950_init	__P((struct mb86950_softc *));
    172 void	mb86950_start	__P((struct ifnet *));
    173 void	mb86950_watchdog __P((struct ifnet *));
    174 void	mb86950_reset	__P((struct mb86950_softc *));
    175 
    176 /* Local functions. */
    177 void	mb86950_stop __P((struct mb86950_softc *));
    178 void	mb86950_tint __P((struct mb86950_softc *, u_int8_t));
    179 void	mb86950_rint __P((struct mb86950_softc *, u_int8_t));
    180 int		mb86950_get_fifo __P((struct mb86950_softc *, u_int));
    181 ushort	mb86950_put_fifo __P((struct mb86950_softc *, struct mbuf *));
    182 void	mb86950_drain_fifo __P((struct mb86950_softc *));
    183 
    184 int		mb86950_mediachange __P((struct ifnet *));
    185 void	mb86950_mediastatus __P((struct ifnet *, struct ifmediareq *));
    186 
    187 
    188 #if ESTAR_DEBUG >= 1
    189 void	mb86950_dump __P((int, struct mb86950_softc *));
    190 #endif
    191 
    192 /********************************************************************/
    193 
    194 void
    195 mb86950_attach(sc, myea)
    196 	struct mb86950_softc *sc;
    197 	u_int8_t *myea;
    198 {
    199 
    200 #ifdef DIAGNOSTIC
    201 	if (myea == NULL) {
    202 		printf("%s: ethernet address shouldn't be NULL\n",
    203 		    device_xname(&sc->sc_dev));
    204 		panic("NULL ethernet address");
    205 	}
    206 #endif
    207 
    208 	/* Initialize 86950. */
    209 	mb86950_stop(sc);
    210 
    211 	memcpy(sc->sc_enaddr, myea, sizeof(sc->sc_enaddr));
    212 
    213 	sc->sc_stat |= ESTAR_STAT_ENABLED;
    214 }
    215 
    216 /*
    217  * Stop everything on the interface.
    218  *
    219  * All buffered packets, both transmitting and receiving,
    220  * if any, will be lost by stopping the interface.
    221  */
    222 void
    223 mb86950_stop(sc)
    224 	struct mb86950_softc *sc;
    225 {
    226 	bus_space_tag_t bst = sc->sc_bst;
    227 	bus_space_handle_t bsh = sc->sc_bsh;
    228 
    229 	/* Stop interface hardware. */
    230 	bus_space_write_1(bst, bsh, DLCR_CONFIG, DISABLE_DLC);
    231 	delay(200);
    232 
    233 	/* Disable interrupts. */
    234 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0);
    235 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0);
    236 
    237 	/* Ack / Clear all interrupt status. */
    238 	bus_space_write_1(bst, bsh, DLCR_TX_STAT, 0xff);
    239 	bus_space_write_1(bst, bsh, DLCR_RX_STAT, 0xff);
    240 
    241 	/* Clear DMA Bit */
    242     bus_space_write_2(bst, bsh, BMPR_DMA, 0);
    243 
    244     /* accept no packets */
    245 	bus_space_write_1(bst, bsh, DLCR_TX_MODE, 0);
    246 	bus_space_write_1(bst, bsh, DLCR_RX_MODE, 0);
    247 
    248     mb86950_drain_fifo(sc);
    249 
    250 }
    251 
    252 void
    253 mb86950_drain_fifo(sc)
    254 	struct mb86950_softc *sc;
    255 {
    256 	bus_space_tag_t bst = sc->sc_bst;
    257 	bus_space_handle_t bsh = sc->sc_bsh;
    258 
    259 	/* Read data until bus read error (i.e. buffer empty). */
    260 	/* XXX There ought to be a better way, eats CPU and bothers the chip */
    261 	while (!(bus_space_read_1(bst, bsh, DLCR_RX_STAT) & RX_BUS_RD_ERR))
    262 		bus_space_read_2(bst, bsh, BMPR_FIFO);
    263 	/* XXX */
    264 
    265 	/* Clear Bus Rd Error */
    266 	bus_space_write_1(bst, bsh, DLCR_RX_STAT, RX_BUS_RD_ERR);
    267 }
    268 
    269 /*
    270  * Install interface into kernel networking data structures
    271  */
    272 void
    273 mb86950_config(struct mb86950_softc *sc, int *media,
    274     int nmedia, int defmedia)
    275 {
    276 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    277 	bus_space_tag_t bst = sc->sc_bst;
    278 	bus_space_handle_t bsh = sc->sc_bsh;
    279 
    280 	/* Initialize ifnet structure. */
    281 	strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
    282 	ifp->if_softc = sc;
    283 	ifp->if_start = mb86950_start;
    284 	ifp->if_ioctl = mb86950_ioctl;
    285 	ifp->if_watchdog = mb86950_watchdog;
    286 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
    287 
    288 	IFQ_SET_READY(&ifp->if_snd);
    289 
    290 	/* Initialize media goo. */
    291 	/* XXX The Tiara LANCard uses board jumpers to change media.
    292 	 *       This code may have to be changed for other cards.
    293 	 */
    294 	ifmedia_init(&sc->sc_media, 0, mb86950_mediachange, mb86950_mediastatus);
    295 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
    296 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL);
    297 
    298 	/* Attach the interface. */
    299 	if_attach(ifp);
    300 
    301 	/* Feed the chip the station address. */
    302 	bus_space_write_region_1(bst, bsh, DLCR_NODE_ID, sc->sc_enaddr, ETHER_ADDR_LEN);
    303 
    304 	ether_ifattach(ifp, sc->sc_enaddr);
    305 
    306 #if NRND > 0
    307 	rnd_attach_source(&sc->rnd_source, device_xname(&sc->sc_dev),
    308 	    RND_TYPE_NET, 0);
    309 #endif
    310 
    311 /* XXX No! This doesn't work - DLCR6 of the mb86950 is different
    312 
    313 	bus_space_write_1(bst, bsh, DLCR_CONFIG, 0x0f);
    314 	buf_config = bus_space_read_1(bst, bsh, DLCR_CONFIG);
    315 
    316 	sc->txb_count = ((buf_config & 0x0c) ? 2 : 1);
    317 	sc->txb_size = 1024 * (2 << ((buf_config & 0x0c) ? (((buf_config & 0x0c) >> 2) - 1) : 0));
    318 	sc->txb_free = (sc->txb_size * sc->txb_count) / 1500;
    319 
    320   	sc->rxb_size = ((8 << (buf_config & 3)) * 1024) - (sc->txb_size * sc->txb_count);
    321 	sc->rxb_max = sc->rxb_size / 64;
    322 
    323 	printf("mb86950: Buffer Size %dKB with %d transmit buffer(s) %dKB each.\n",
    324 		(8 << (buf_config & 3)), sc->txb_count,	(sc->txb_size / 1024));
    325 	printf("         Transmit Buffer Space for %d maximum sized packet(s).\n",sc->txb_free);
    326 	printf("         System Bus Width %d bits, Buffer Memory %d bits.\n",
    327 		((buf_config & 0x20) ? 8 : 16),
    328 		((buf_config & 0x10) ? 8 : 16));
    329 
    330 */
    331 
    332 	/* Set reasonable values for number of packet flow control if not
    333 	 * set elsewhere */
    334 	if (sc->txb_num_pkt == 0) sc->txb_num_pkt = 1;
    335 	if (sc->rxb_num_pkt == 0) sc->rxb_num_pkt = 100;
    336 
    337 	/* Print additional info when attached. */
    338 	printf("%s: Ethernet address %s\n", device_xname(&sc->sc_dev),
    339 	    ether_sprintf(sc->sc_enaddr));
    340 
    341 	/* The attach is successful. */
    342 	sc->sc_stat |= ESTAR_STAT_ATTACHED;
    343 }
    344 
    345 /*
    346  * Media change callback.
    347  */
    348 int
    349 mb86950_mediachange(ifp)
    350 	struct ifnet *ifp;
    351 {
    352 
    353 	struct mb86950_softc *sc = ifp->if_softc;
    354 
    355 	if (sc->sc_mediachange)
    356 		return ((*sc->sc_mediachange)(sc));
    357 
    358 	return (0);
    359 }
    360 
    361 /*
    362  * Media status callback.
    363  */
    364 void
    365 mb86950_mediastatus(ifp, ifmr)
    366 	struct ifnet *ifp;
    367 	struct ifmediareq *ifmr;
    368 {
    369 	struct mb86950_softc *sc = ifp->if_softc;
    370 
    371 	if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0) {
    372 		ifmr->ifm_active = IFM_ETHER | IFM_NONE;
    373 		ifmr->ifm_status = 0;
    374 		return;
    375 	}
    376 
    377 	if (sc->sc_mediastatus)
    378 		(*sc->sc_mediastatus)(sc, ifmr);
    379 
    380 }
    381 
    382 /*
    383  * Reset interface.
    384  */
    385 void
    386 mb86950_reset(sc)
    387 	struct mb86950_softc *sc;
    388 {
    389 	int s;
    390 
    391 	s = splnet();
    392 	log(LOG_ERR, "%s: device reset\n", device_xname(&sc->sc_dev));
    393 	mb86950_stop(sc);
    394 	mb86950_init(sc);
    395 	splx(s);
    396 }
    397 
    398 /*
    399  * Device timeout/watchdog routine. Entered if the device neglects to
    400  * generate an interrupt after a transmit has been started on it.
    401  */
    402 void
    403 mb86950_watchdog(ifp)
    404 	struct ifnet *ifp;
    405 {
    406 	struct mb86950_softc *sc = ifp->if_softc;
    407 	bus_space_tag_t bst = sc->sc_bst;
    408 	bus_space_handle_t bsh = sc->sc_bsh;
    409 	u_int8_t tstat;
    410 
    411 	/* verbose watchdog messages for debugging timeouts */
    412     if ((tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT)) != 0) {
    413 		if (tstat & TX_CR_LOST) {
    414 			if ((tstat & (TX_COL | TX_16COL)) == 0) {
    415 				 log(LOG_ERR, "%s: carrier lost\n",
    416 				    device_xname(&sc->sc_dev));
    417 			} else {
    418 				log(LOG_ERR, "%s: excessive collisions\n",
    419 				    device_xname(&sc->sc_dev));
    420 			}
    421 		}
    422 		else if ((tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) != 0) {
    423 			log(LOG_ERR, "%s: tx fifo underflow/overflow\n",
    424 			    device_xname(&sc->sc_dev));
    425 		} else {
    426 			log(LOG_ERR, "%s: transmit error\n",
    427 			    device_xname(&sc->sc_dev));
    428 		}
    429 	} else {
    430 		log(LOG_ERR, "%s: device timeout\n", device_xname(&sc->sc_dev));
    431 	}
    432 
    433 	/* Don't know how many packets are lost by this accident.
    434 	 *  ... So just errors = errors + 1
    435 	 */
    436 	ifp->if_oerrors++;
    437 
    438 	mb86950_reset(sc);
    439 
    440 }
    441 
    442 /*
    443  ******************** IOCTL
    444  * Process an ioctl request.
    445  */
    446 int
    447 mb86950_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
    448 {
    449 	struct mb86950_softc *sc = ifp->if_softc;
    450 	struct ifaddr *ifa = (struct ifaddr *)data;
    451 	struct ifreq *ifr = (struct ifreq *)data;
    452 
    453 	int s, error = 0;
    454 
    455 	s = splnet();
    456 
    457 	switch (cmd) {
    458 	case SIOCINITIFADDR:
    459 		/* XXX deprecated ? What should I use instead? */
    460 		if ((error = mb86950_enable(sc)) != 0)
    461 			break;
    462 
    463 		ifp->if_flags |= IFF_UP;
    464 
    465 		mb86950_init(sc);
    466 		switch (ifa->ifa_addr->sa_family) {
    467 
    468 #ifdef INET
    469 		case AF_INET:
    470 			arp_ifinit(ifp, ifa);
    471 			break;
    472 #endif
    473 
    474 
    475 		default:
    476 			break;
    477 		}
    478 		break;
    479 
    480 	case SIOCSIFFLAGS:
    481 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
    482 			break;
    483 		/* XXX re-use ether_ioctl() */
    484 		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
    485 		case IFF_RUNNING:
    486 			/*
    487 			 * If interface is marked down and it is running, then
    488 			 * stop it.
    489 			 */
    490 			mb86950_stop(sc);
    491 			ifp->if_flags &= ~IFF_RUNNING;
    492 			mb86950_disable(sc);
    493 			break;
    494 		case IFF_UP:
    495 			/*
    496 			 * If interface is marked up and it is stopped, then
    497 			 * start it.
    498 			 */
    499 			if ((error = mb86950_enable(sc)) != 0)
    500 				break;
    501 			mb86950_init(sc);
    502 			break;
    503 		case IFF_UP|IFF_RUNNING:
    504 			/*
    505 			 * Reset the interface to pick up changes in any other
    506 			 * flags that affect hardware registers.
    507 			 */
    508 #if 0
    509 			/* Setmode not supported */
    510 			mb86950_setmode(sc);
    511 #endif
    512 			break;
    513 		case 0:
    514 			break;
    515 		}
    516 
    517 #if ESTAR_DEBUG >= 1
    518 		/* "ifconfig fe0 debug" to print register dump. */
    519 		if (ifp->if_flags & IFF_DEBUG) {
    520 			log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n",
    521 			    device_xname(&sc->sc_dev));
    522 			mb86950_dump(LOG_DEBUG, sc);
    523 		}
    524 #endif
    525 		break;
    526 
    527 	case SIOCGIFMEDIA:
    528 	case SIOCSIFMEDIA:
    529 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
    530 		break;
    531 
    532 	default:
    533 		error = ether_ioctl(ifp, cmd, data);
    534 		break;
    535 	}
    536 
    537 	splx(s);
    538 	return (error);
    539 }
    540 
    541 /*
    542  * Initialize device.
    543  */
    544 void
    545 mb86950_init(sc)
    546 	struct mb86950_softc *sc;
    547 {
    548 	bus_space_tag_t bst = sc->sc_bst;
    549 	bus_space_handle_t bsh = sc->sc_bsh;
    550 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    551 
    552 	/* Reset transmitter flags. */
    553 	ifp->if_flags &= ~IFF_OACTIVE;
    554 	ifp->if_timer = 0;
    555 	sc->txb_sched = 0;
    556 
    557 	bus_space_write_1(bst, bsh, DLCR_TX_MODE, LBC);
    558 	bus_space_write_1(bst, bsh, DLCR_RX_MODE, NORMAL_MODE);
    559 
    560 	/* Enable interrupts. */
    561 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK);
    562 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK);
    563 
    564 	/* Enable transmitter and receiver. */
    565 	bus_space_write_1(bst, bsh, DLCR_CONFIG, ENABLE_DLC);
    566 	delay(200);
    567 
    568 	/* Set 'running' flag. */
    569 	ifp->if_flags |= IFF_RUNNING;
    570 
    571 	/* ...and attempt to start output. */
    572 	mb86950_start(ifp);
    573 
    574 }
    575 
    576 void
    577 mb86950_start(ifp)
    578 	struct ifnet *ifp;
    579 {
    580 	struct mb86950_softc *sc = ifp->if_softc;
    581     bus_space_tag_t bst = sc->sc_bst;
    582     bus_space_handle_t bsh = sc->sc_bsh;
    583 	struct mbuf *m;
    584 	int len;
    585 
    586 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
    587 		return;
    588 
    589 	IF_DEQUEUE(&ifp->if_snd, m);
    590 	if (m == 0)
    591 		return;
    592 
    593 #if NBPFILTER > 0
    594 	/* Tap off here if there is a BPF listener. */
    595 	if (ifp->if_bpf)
    596 		bpf_mtap(ifp->if_bpf, m);
    597 #endif
    598 
    599 	/* Send the packet to the mb86950 */
    600 	len = mb86950_put_fifo(sc,m);
    601 	m_freem(m);
    602 
    603 	/* XXX bus_space_barrier here ? */
    604 	if (bus_space_read_1(bst, bsh, DLCR_TX_STAT) & (TX_UNDERFLO | TX_BUS_WR_ERR)) {
    605 		log(LOG_ERR, "%s: tx fifo underflow/overflow\n", device_xname(&sc->sc_dev));
    606 	}
    607 
    608 	bus_space_write_2(bst, bsh, BMPR_TX_LENGTH, len | TRANSMIT_START);
    609 
    610 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK);
    611 	/* XXX                          */
    612 	sc->txb_sched++;
    613 
    614 	/* We have space for 'n' transmit packets of size 'mtu. */
    615 	if (sc->txb_sched > sc->txb_num_pkt) {
    616 		ifp->if_flags |= IFF_OACTIVE;
    617 		ifp->if_timer = 2;
    618 	}
    619 }
    620 
    621 /*
    622  * Send packet - copy packet from mbuf to the fifo
    623  */
    624 u_short
    625 mb86950_put_fifo(sc, m)
    626 	struct mb86950_softc *sc;
    627 	struct mbuf *m;
    628 {
    629 	bus_space_tag_t bst = sc->sc_bst;
    630 	bus_space_handle_t bsh = sc->sc_bsh;
    631 	u_short *data;
    632 	u_char savebyte[2];
    633 	int len, len1, wantbyte;
    634 	u_short totlen;
    635 
    636 	memset(savebyte, 0, sizeof(savebyte));	/* XXX gcc */
    637 
    638 	totlen = wantbyte = 0;
    639 
    640 	for (; m != NULL; m = m->m_next) {
    641 		data = mtod(m, u_short *);
    642 		len = m->m_len;
    643 		if (len > 0) {
    644 			totlen += len;
    645 
    646 			/* Finish the last word. */
    647 			if (wantbyte) {
    648 				savebyte[1] = *((u_char *)data);
    649 				bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte);
    650 				data = (u_short *)((u_char *)data + 1);
    651 				len--;
    652 				wantbyte = 0;
    653 			}
    654 			/* Output contiguous words. */
    655 			if (len > 1) {
    656 				len1 = len/2;
    657 				bus_space_write_multi_stream_2(bst, bsh, BMPR_FIFO, data, len1);
    658 				data += len1;
    659 				len &= 1;
    660 			}
    661 			/* Save last byte, if necessary. */
    662 			if (len == 1) {
    663 				savebyte[0] = *((u_char *)data);
    664 				wantbyte = 1;
    665 			}
    666 		}
    667 	}
    668 
    669 	if (wantbyte) {
    670 		savebyte[1] = 0;
    671 		bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte);
    672 	}
    673 
    674 	if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) {
    675 
    676 		/* Fill the rest of the packet with zeros. */
    677 		/* XXX Replace this mess with something else, eats CPU */
    678 		/* The zero fill and last byte ought to be combined somehow */
    679 		for(len = totlen + 1; len < (ETHER_MIN_LEN - ETHER_CRC_LEN); len += 2)
    680 	  		bus_space_write_2(bst, bsh, BMPR_FIFO, 0);
    681 		/* XXX                                       */
    682 
    683 		totlen = (ETHER_MIN_LEN - ETHER_CRC_LEN);
    684 	}
    685 
    686 	return (totlen);
    687 }
    688 
    689 /*
    690  * Handle interrupts.
    691  * Ethernet interface interrupt processor
    692  */
    693 int
    694 mb86950_intr(arg)
    695 	void *arg;
    696 {
    697 	struct mb86950_softc *sc = arg;
    698 	bus_space_tag_t bst = sc->sc_bst;
    699 	bus_space_handle_t bsh = sc->sc_bsh;
    700 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    701 	u_int8_t tstat, rstat;
    702 
    703 	/* Get interrupt status. */
    704 	tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT);
    705 	rstat = bus_space_read_1(bst, bsh, DLCR_RX_STAT);
    706 
    707 	if (tstat == 0 && rstat == 0) return (0);
    708 
    709 	/* Disable etherstar interrupts so that we won't miss anything. */
    710 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0);
    711 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0);
    712 
    713 	/*
    714 	 * Handle transmitter interrupts. Handle these first because
    715 	 * the receiver will reset the board under some conditions.
    716 	 */
    717 	if (tstat != 0) {
    718 
    719 		mb86950_tint(sc, tstat);
    720 
    721 		/* acknowledge transmit interrupt status. */
    722 		bus_space_write_1(bst, bsh, DLCR_TX_STAT, tstat);
    723 
    724 	}
    725 
    726 	/* Handle receiver interrupts. */
    727 	if (rstat != 0) {
    728 
    729 		mb86950_rint(sc, rstat);
    730 
    731 		/* acknowledge receive interrupt status. */
    732 		bus_space_write_1(bst, bsh, DLCR_RX_STAT, rstat);
    733 
    734 	}
    735 
    736 	/* If tx still pending reset tx interrupt mask */
    737 	if (sc->txb_sched > 0)
    738 		bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK);
    739 
    740 	/*
    741 	 * If it looks like the transmitter can take more data,
    742 	 * attempt to start output on the interface. This is done
    743 	 * after handling the receiver interrupt to give the
    744 	 * receive operation priority.
    745 	 */
    746 
    747 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
    748 		mb86950_start(ifp);
    749 
    750 	/* Set receive interrupts back */
    751 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK);
    752 
    753 	return(1);
    754 }
    755 
    756 /* Transmission interrupt handler */
    757 void
    758 mb86950_tint(sc, tstat)
    759 	struct mb86950_softc *sc;
    760 	u_int8_t tstat;
    761 {
    762 	bus_space_tag_t bst = sc->sc_bst;
    763 	bus_space_handle_t bsh = sc->sc_bsh;
    764 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    765 	int col;
    766 
    767 	if (tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) {
    768 		/* XXX What do we need to do here? reset ? */
    769 		ifp->if_oerrors++;
    770 	}
    771 
    772 	/* excessive collision */
    773 	if (tstat & TX_16COL) {
    774 		ifp->if_collisions += 16;
    775 		/* 16 collisions means that the packet has been thrown away. */
    776 		if (sc->txb_sched > 0)
    777 			sc->txb_sched--;
    778 	}
    779 
    780 	/* transmission complete. */
    781 	if (tstat & TX_DONE) {
    782 		/* successfully transmitted packets ++. */
    783 		ifp->if_opackets++;
    784 		if (sc->txb_sched > 0)
    785 			sc->txb_sched--;
    786 
    787 		/* Collision count valid only when TX_DONE is set */
    788 		if (tstat & TX_COL) {
    789 			col = (bus_space_read_1(bst, bsh, DLCR_TX_MODE) & COL_MASK) >> 4;
    790 			ifp->if_collisions = ifp->if_collisions + col;
    791 		}
    792 	}
    793 
    794 	if (sc->txb_sched == 0) {
    795 		 /* Reset output active flag and stop timer. */
    796 		 ifp->if_flags &= ~IFF_OACTIVE;
    797 		 ifp->if_timer = 0;
    798 	}
    799 }
    800 
    801 /* receiver interrupt. */
    802 void
    803 mb86950_rint(sc, rstat)
    804 	struct mb86950_softc *sc;
    805 	u_int8_t rstat;
    806 {
    807 	bus_space_tag_t bst = sc->sc_bst;
    808 	bus_space_handle_t bsh = sc->sc_bsh;
    809 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    810 	u_int status, len;
    811 	int i;
    812 
    813 	 /* Update statistics if this interrupt is caused by an error. */
    814 	 if (rstat & RX_ERR_MASK) {
    815 
    816 		/* tried to read past end of fifo, should be harmless
    817 		 * count everything else
    818 		 */
    819 		if ((rstat & RX_BUS_RD_ERR) == 0) {
    820 			ifp->if_ierrors++;
    821 		}
    822 	}
    823 
    824 	/*
    825 	 * mb86950 has a flag indicating "receive buffer empty."
    826 	 * We just loop checking the flag to pull out all received
    827 	 * packets.
    828 	 *
    829 	 * We limit the number of iterrations to avoid infinite loop.
    830 	 * It can be caused by a very slow CPU (some broken
    831 	 * peripheral may insert incredible number of wait cycles)
    832 	 * or, worse, by a broken mb86950 chip.
    833 	 */
    834 	for (i = 0; i < sc->rxb_num_pkt; i++) {
    835 		/* Stop the iterration if 86950 indicates no packets. */
    836 		if (bus_space_read_1(bst, bsh, DLCR_RX_MODE) & RX_BUF_EMTY)
    837 			break;
    838 
    839 		/* receive packet status */
    840 		status = bus_space_read_2(bst, bsh, BMPR_FIFO);
    841 
    842 		/* bad packet? */
    843 		if ((status & GOOD_PKT) == 0) {
    844 			ifp->if_ierrors++;
    845 			mb86950_drain_fifo(sc);
    846 			continue;
    847 		}
    848 
    849 		/* Length valid ? */
    850 		len = bus_space_read_2(bst, bsh, BMPR_FIFO);
    851 
    852 		if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN) || len < ETHER_HDR_LEN) {
    853 			ifp->if_ierrors++;
    854 			mb86950_drain_fifo(sc);
    855 			continue;
    856 		}
    857 
    858 		if (mb86950_get_fifo(sc, len) != 0) {
    859 			/* No mbufs? Drop packet. */
    860 			ifp->if_ierrors++;
    861 			mb86950_drain_fifo(sc);
    862 			return;
    863 		}
    864 
    865 		/* Successfully received a packet.  Update stat. */
    866 		ifp->if_ipackets++;
    867 	}
    868 }
    869 
    870 /*
    871  * Receive packet.
    872  * Retrieve packet from receive buffer and send to the next level up via
    873  * ether_input(). If there is a BPF listener, give a copy to BPF, too.
    874  * Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
    875  */
    876 int
    877 mb86950_get_fifo(sc, len)
    878 	struct mb86950_softc *sc;
    879 	u_int len;
    880 {
    881 	bus_space_tag_t bst = sc->sc_bst;
    882 	bus_space_handle_t bsh = sc->sc_bsh;
    883 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    884 	struct mbuf *m;
    885 
    886 	/* Allocate a header mbuf. */
    887 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    888 	if (m == 0)
    889 		return (-1);
    890 
    891 	/*
    892 	 * Round len to even value.
    893 	 */
    894 	if (len & 1)
    895 		len++;
    896 
    897 	m->m_pkthdr.rcvif = ifp;
    898 	m->m_pkthdr.len = len;
    899 
    900 	/* The following silliness is to make NFS happy. */
    901 #define	EROUND	((sizeof(struct ether_header) + 3) & ~3)
    902 #define	EOFF	(EROUND - sizeof(struct ether_header))
    903 
    904 	/*
    905 	 * Our strategy has one more problem.  There is a policy on
    906 	 * mbuf cluster allocation.  It says that we must have at
    907 	 * least MINCLSIZE (208 bytes) to allocate a cluster.  For a
    908 	 * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2),
    909 	 * our code violates the rule...
    910 	 * On the other hand, the current code is short, simple,
    911 	 * and fast, however.  It does no harmful thing, just wastes
    912 	 * some memory.  Any comments?  FIXME.
    913 	 */
    914 
    915 	/* Attach a cluster if this packet doesn't fit in a normal mbuf. */
    916 	if (len > MHLEN - EOFF) {
    917 		MCLGET(m, M_DONTWAIT);
    918 		if ((m->m_flags & M_EXT) == 0) {
    919 			m_freem(m);
    920 			return (-1);
    921 		}
    922 	}
    923 
    924 	/*
    925 	 * The following assumes there is room for the ether header in the
    926 	 * header mbuf.
    927 	 */
    928 	m->m_data += EOFF;
    929 
    930 	/* Set the length of this packet. */
    931 	m->m_len = len;
    932 
    933 	/* Get a packet. */
    934 	bus_space_read_multi_stream_2(bst, bsh, BMPR_FIFO, mtod(m, u_int16_t *), (len + 1) >> 1);
    935 
    936 #if NBPFILTER > 0
    937 	/*
    938 	 * Check if there's a BPF listener on this interface.  If so, hand off
    939 	 * the raw packet to bpf.
    940 	 */
    941 	if (ifp->if_bpf)
    942 		bpf_mtap(ifp->if_bpf, m);
    943 #endif
    944 
    945 	(*ifp->if_input)(ifp, m);
    946 	return (0);
    947 }
    948 
    949 /*
    950  * Enable power on the interface.
    951  */
    952 int
    953 mb86950_enable(sc)
    954 	struct mb86950_softc *sc;
    955 {
    956 
    957 	if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0 && sc->sc_enable != NULL) {
    958 		if ((*sc->sc_enable)(sc) != 0) {
    959 			aprint_error_dev(&sc->sc_dev, "device enable failed\n");
    960 			return (EIO);
    961 		}
    962 	}
    963 
    964 	sc->sc_stat |= ESTAR_STAT_ENABLED;
    965 	return (0);
    966 }
    967 
    968 /*
    969  * Disable power on the interface.
    970  */
    971 void
    972 mb86950_disable(sc)
    973 	struct mb86950_softc *sc;
    974 {
    975 
    976 	if ((sc->sc_stat & ESTAR_STAT_ENABLED) != 0 && sc->sc_disable != NULL) {
    977 		(*sc->sc_disable)(sc);
    978 		sc->sc_stat &= ~ESTAR_STAT_ENABLED;
    979 	}
    980 }
    981 
    982 /*
    983  * mbe_activate:
    984  *
    985  *	Handle device activation/deactivation requests.
    986  */
    987 int
    988 mb86950_activate(self, act)
    989 	struct device *self;
    990 	enum devact act;
    991 {
    992 	struct mb86950_softc *sc = (struct mb86950_softc *)self;
    993 	int rv, s;
    994 
    995 	rv = 0;
    996 	s = splnet();
    997 	switch (act) {
    998 	case DVACT_ACTIVATE:
    999 		rv = EOPNOTSUPP;
   1000 		break;
   1001 
   1002 	case DVACT_DEACTIVATE:
   1003 		if_deactivate(&sc->sc_ec.ec_if);
   1004 		break;
   1005 	}
   1006 	splx(s);
   1007 	return (rv);
   1008 }
   1009 
   1010 /*
   1011  * mb86950_detach:
   1012  *
   1013  *	Detach a mb86950 interface.
   1014  */
   1015 int
   1016 mb86950_detach(sc)
   1017 	struct mb86950_softc *sc;
   1018 {
   1019 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1020 
   1021 	/* Succeed now if there's no work to do. */
   1022 	if ((sc->sc_stat & ESTAR_STAT_ATTACHED) == 0)
   1023 		return (0);
   1024 
   1025 	/* Delete all media. */
   1026 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
   1027 
   1028 #if NRND > 0
   1029 	/* Unhook the entropy source. */
   1030 	rnd_detach_source(&sc->rnd_source);
   1031 #endif
   1032 	ether_ifdetach(ifp);
   1033 	if_detach(ifp);
   1034 
   1035 	return (0);
   1036 }
   1037 
   1038 #if ESTAR_DEBUG >= 1
   1039 void
   1040 mb86950_dump(level, sc)
   1041 	int level;
   1042 	struct mb86950_softc *sc;
   1043 {
   1044 	bus_space_tag_t bst = sc->sc_bst;
   1045 	bus_space_handle_t bsh = sc->sc_bsh;
   1046 
   1047 	log(level, "\tDLCR = %02x %02x %02x %02x %02x %02x %02x\n",
   1048 	    bus_space_read_1(bst, bsh, DLCR_TX_STAT),
   1049 	    bus_space_read_1(bst, bsh, DLCR_TX_INT_EN),
   1050 	    bus_space_read_1(bst, bsh, DLCR_RX_STAT),
   1051 	    bus_space_read_1(bst, bsh, DLCR_RX_INT_EN),
   1052 	    bus_space_read_1(bst, bsh, DLCR_TX_MODE),
   1053 	    bus_space_read_1(bst, bsh, DLCR_RX_MODE),
   1054 	    bus_space_read_1(bst, bsh, DLCR_CONFIG));
   1055 
   1056 	/* XXX BMPR2, 4 write only ?
   1057 	log(level, "\tBMPR = xxxx %04x %04x\n",
   1058 		bus_space_read_2(bst, bsh, BMPR_TX_LENGTH),
   1059 		bus_space_read_2(bst, bsh, BMPR_DMA));
   1060 	*/
   1061 }
   1062 #endif
   1063