Home | History | Annotate | Line # | Download | only in ic
mb86950.c revision 1.14
      1 /*	$NetBSD: mb86950.c,v 1.14 2009/03/14 15:36:17 dsl 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.14 2009/03/14 15:36:17 dsl 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(struct ifnet *, u_long, void *);
    171 void	mb86950_init(struct mb86950_softc *);
    172 void	mb86950_start(struct ifnet *);
    173 void	mb86950_watchdog(struct ifnet *);
    174 void	mb86950_reset(struct mb86950_softc *);
    175 
    176 /* Local functions. */
    177 void	mb86950_stop(struct mb86950_softc *);
    178 void	mb86950_tint(struct mb86950_softc *, u_int8_t);
    179 void	mb86950_rint(struct mb86950_softc *, u_int8_t);
    180 int		mb86950_get_fifo(struct mb86950_softc *, u_int);
    181 ushort	mb86950_put_fifo(struct mb86950_softc *, struct mbuf *);
    182 void	mb86950_drain_fifo(struct mb86950_softc *);
    183 
    184 int		mb86950_mediachange(struct ifnet *);
    185 void	mb86950_mediastatus(struct ifnet *, struct ifmediareq *);
    186 
    187 
    188 #if ESTAR_DEBUG >= 1
    189 void	mb86950_dump(int, struct mb86950_softc *);
    190 #endif
    191 
    192 /********************************************************************/
    193 
    194 void
    195 mb86950_attach(struct mb86950_softc *sc, u_int8_t *myea)
    196 {
    197 
    198 #ifdef DIAGNOSTIC
    199 	if (myea == NULL) {
    200 		printf("%s: ethernet address shouldn't be NULL\n",
    201 		    device_xname(&sc->sc_dev));
    202 		panic("NULL ethernet address");
    203 	}
    204 #endif
    205 
    206 	/* Initialize 86950. */
    207 	mb86950_stop(sc);
    208 
    209 	memcpy(sc->sc_enaddr, myea, sizeof(sc->sc_enaddr));
    210 
    211 	sc->sc_stat |= ESTAR_STAT_ENABLED;
    212 }
    213 
    214 /*
    215  * Stop everything on the interface.
    216  *
    217  * All buffered packets, both transmitting and receiving,
    218  * if any, will be lost by stopping the interface.
    219  */
    220 void
    221 mb86950_stop(struct mb86950_softc *sc)
    222 {
    223 	bus_space_tag_t bst = sc->sc_bst;
    224 	bus_space_handle_t bsh = sc->sc_bsh;
    225 
    226 	/* Stop interface hardware. */
    227 	bus_space_write_1(bst, bsh, DLCR_CONFIG, DISABLE_DLC);
    228 	delay(200);
    229 
    230 	/* Disable interrupts. */
    231 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0);
    232 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0);
    233 
    234 	/* Ack / Clear all interrupt status. */
    235 	bus_space_write_1(bst, bsh, DLCR_TX_STAT, 0xff);
    236 	bus_space_write_1(bst, bsh, DLCR_RX_STAT, 0xff);
    237 
    238 	/* Clear DMA Bit */
    239     bus_space_write_2(bst, bsh, BMPR_DMA, 0);
    240 
    241     /* accept no packets */
    242 	bus_space_write_1(bst, bsh, DLCR_TX_MODE, 0);
    243 	bus_space_write_1(bst, bsh, DLCR_RX_MODE, 0);
    244 
    245     mb86950_drain_fifo(sc);
    246 
    247 }
    248 
    249 void
    250 mb86950_drain_fifo(struct mb86950_softc *sc)
    251 {
    252 	bus_space_tag_t bst = sc->sc_bst;
    253 	bus_space_handle_t bsh = sc->sc_bsh;
    254 
    255 	/* Read data until bus read error (i.e. buffer empty). */
    256 	/* XXX There ought to be a better way, eats CPU and bothers the chip */
    257 	while (!(bus_space_read_1(bst, bsh, DLCR_RX_STAT) & RX_BUS_RD_ERR))
    258 		bus_space_read_2(bst, bsh, BMPR_FIFO);
    259 	/* XXX */
    260 
    261 	/* Clear Bus Rd Error */
    262 	bus_space_write_1(bst, bsh, DLCR_RX_STAT, RX_BUS_RD_ERR);
    263 }
    264 
    265 /*
    266  * Install interface into kernel networking data structures
    267  */
    268 void
    269 mb86950_config(struct mb86950_softc *sc, int *media,
    270     int nmedia, int defmedia)
    271 {
    272 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    273 	bus_space_tag_t bst = sc->sc_bst;
    274 	bus_space_handle_t bsh = sc->sc_bsh;
    275 
    276 	/* Initialize ifnet structure. */
    277 	strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
    278 	ifp->if_softc = sc;
    279 	ifp->if_start = mb86950_start;
    280 	ifp->if_ioctl = mb86950_ioctl;
    281 	ifp->if_watchdog = mb86950_watchdog;
    282 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
    283 
    284 	IFQ_SET_READY(&ifp->if_snd);
    285 
    286 	/* Initialize media goo. */
    287 	/* XXX The Tiara LANCard uses board jumpers to change media.
    288 	 *       This code may have to be changed for other cards.
    289 	 */
    290 	ifmedia_init(&sc->sc_media, 0, mb86950_mediachange, mb86950_mediastatus);
    291 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL);
    292 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL);
    293 
    294 	/* Attach the interface. */
    295 	if_attach(ifp);
    296 
    297 	/* Feed the chip the station address. */
    298 	bus_space_write_region_1(bst, bsh, DLCR_NODE_ID, sc->sc_enaddr, ETHER_ADDR_LEN);
    299 
    300 	ether_ifattach(ifp, sc->sc_enaddr);
    301 
    302 #if NRND > 0
    303 	rnd_attach_source(&sc->rnd_source, device_xname(&sc->sc_dev),
    304 	    RND_TYPE_NET, 0);
    305 #endif
    306 
    307 /* XXX No! This doesn't work - DLCR6 of the mb86950 is different
    308 
    309 	bus_space_write_1(bst, bsh, DLCR_CONFIG, 0x0f);
    310 	buf_config = bus_space_read_1(bst, bsh, DLCR_CONFIG);
    311 
    312 	sc->txb_count = ((buf_config & 0x0c) ? 2 : 1);
    313 	sc->txb_size = 1024 * (2 << ((buf_config & 0x0c) ? (((buf_config & 0x0c) >> 2) - 1) : 0));
    314 	sc->txb_free = (sc->txb_size * sc->txb_count) / 1500;
    315 
    316   	sc->rxb_size = ((8 << (buf_config & 3)) * 1024) - (sc->txb_size * sc->txb_count);
    317 	sc->rxb_max = sc->rxb_size / 64;
    318 
    319 	printf("mb86950: Buffer Size %dKB with %d transmit buffer(s) %dKB each.\n",
    320 		(8 << (buf_config & 3)), sc->txb_count,	(sc->txb_size / 1024));
    321 	printf("         Transmit Buffer Space for %d maximum sized packet(s).\n",sc->txb_free);
    322 	printf("         System Bus Width %d bits, Buffer Memory %d bits.\n",
    323 		((buf_config & 0x20) ? 8 : 16),
    324 		((buf_config & 0x10) ? 8 : 16));
    325 
    326 */
    327 
    328 	/* Set reasonable values for number of packet flow control if not
    329 	 * set elsewhere */
    330 	if (sc->txb_num_pkt == 0) sc->txb_num_pkt = 1;
    331 	if (sc->rxb_num_pkt == 0) sc->rxb_num_pkt = 100;
    332 
    333 	/* Print additional info when attached. */
    334 	printf("%s: Ethernet address %s\n", device_xname(&sc->sc_dev),
    335 	    ether_sprintf(sc->sc_enaddr));
    336 
    337 	/* The attach is successful. */
    338 	sc->sc_stat |= ESTAR_STAT_ATTACHED;
    339 }
    340 
    341 /*
    342  * Media change callback.
    343  */
    344 int
    345 mb86950_mediachange(struct ifnet *ifp)
    346 {
    347 
    348 	struct mb86950_softc *sc = ifp->if_softc;
    349 
    350 	if (sc->sc_mediachange)
    351 		return ((*sc->sc_mediachange)(sc));
    352 
    353 	return (0);
    354 }
    355 
    356 /*
    357  * Media status callback.
    358  */
    359 void
    360 mb86950_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
    361 {
    362 	struct mb86950_softc *sc = ifp->if_softc;
    363 
    364 	if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0) {
    365 		ifmr->ifm_active = IFM_ETHER | IFM_NONE;
    366 		ifmr->ifm_status = 0;
    367 		return;
    368 	}
    369 
    370 	if (sc->sc_mediastatus)
    371 		(*sc->sc_mediastatus)(sc, ifmr);
    372 
    373 }
    374 
    375 /*
    376  * Reset interface.
    377  */
    378 void
    379 mb86950_reset(struct mb86950_softc *sc)
    380 {
    381 	int s;
    382 
    383 	s = splnet();
    384 	log(LOG_ERR, "%s: device reset\n", device_xname(&sc->sc_dev));
    385 	mb86950_stop(sc);
    386 	mb86950_init(sc);
    387 	splx(s);
    388 }
    389 
    390 /*
    391  * Device timeout/watchdog routine. Entered if the device neglects to
    392  * generate an interrupt after a transmit has been started on it.
    393  */
    394 void
    395 mb86950_watchdog(struct ifnet *ifp)
    396 {
    397 	struct mb86950_softc *sc = ifp->if_softc;
    398 	bus_space_tag_t bst = sc->sc_bst;
    399 	bus_space_handle_t bsh = sc->sc_bsh;
    400 	u_int8_t tstat;
    401 
    402 	/* verbose watchdog messages for debugging timeouts */
    403     if ((tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT)) != 0) {
    404 		if (tstat & TX_CR_LOST) {
    405 			if ((tstat & (TX_COL | TX_16COL)) == 0) {
    406 				 log(LOG_ERR, "%s: carrier lost\n",
    407 				    device_xname(&sc->sc_dev));
    408 			} else {
    409 				log(LOG_ERR, "%s: excessive collisions\n",
    410 				    device_xname(&sc->sc_dev));
    411 			}
    412 		}
    413 		else if ((tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) != 0) {
    414 			log(LOG_ERR, "%s: tx fifo underflow/overflow\n",
    415 			    device_xname(&sc->sc_dev));
    416 		} else {
    417 			log(LOG_ERR, "%s: transmit error\n",
    418 			    device_xname(&sc->sc_dev));
    419 		}
    420 	} else {
    421 		log(LOG_ERR, "%s: device timeout\n", device_xname(&sc->sc_dev));
    422 	}
    423 
    424 	/* Don't know how many packets are lost by this accident.
    425 	 *  ... So just errors = errors + 1
    426 	 */
    427 	ifp->if_oerrors++;
    428 
    429 	mb86950_reset(sc);
    430 
    431 }
    432 
    433 /*
    434  ******************** IOCTL
    435  * Process an ioctl request.
    436  */
    437 int
    438 mb86950_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
    439 {
    440 	struct mb86950_softc *sc = ifp->if_softc;
    441 	struct ifaddr *ifa = (struct ifaddr *)data;
    442 	struct ifreq *ifr = (struct ifreq *)data;
    443 
    444 	int s, error = 0;
    445 
    446 	s = splnet();
    447 
    448 	switch (cmd) {
    449 	case SIOCINITIFADDR:
    450 		/* XXX deprecated ? What should I use instead? */
    451 		if ((error = mb86950_enable(sc)) != 0)
    452 			break;
    453 
    454 		ifp->if_flags |= IFF_UP;
    455 
    456 		mb86950_init(sc);
    457 		switch (ifa->ifa_addr->sa_family) {
    458 
    459 #ifdef INET
    460 		case AF_INET:
    461 			arp_ifinit(ifp, ifa);
    462 			break;
    463 #endif
    464 
    465 
    466 		default:
    467 			break;
    468 		}
    469 		break;
    470 
    471 	case SIOCSIFFLAGS:
    472 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
    473 			break;
    474 		/* XXX re-use ether_ioctl() */
    475 		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
    476 		case IFF_RUNNING:
    477 			/*
    478 			 * If interface is marked down and it is running, then
    479 			 * stop it.
    480 			 */
    481 			mb86950_stop(sc);
    482 			ifp->if_flags &= ~IFF_RUNNING;
    483 			mb86950_disable(sc);
    484 			break;
    485 		case IFF_UP:
    486 			/*
    487 			 * If interface is marked up and it is stopped, then
    488 			 * start it.
    489 			 */
    490 			if ((error = mb86950_enable(sc)) != 0)
    491 				break;
    492 			mb86950_init(sc);
    493 			break;
    494 		case IFF_UP|IFF_RUNNING:
    495 			/*
    496 			 * Reset the interface to pick up changes in any other
    497 			 * flags that affect hardware registers.
    498 			 */
    499 #if 0
    500 			/* Setmode not supported */
    501 			mb86950_setmode(sc);
    502 #endif
    503 			break;
    504 		case 0:
    505 			break;
    506 		}
    507 
    508 #if ESTAR_DEBUG >= 1
    509 		/* "ifconfig fe0 debug" to print register dump. */
    510 		if (ifp->if_flags & IFF_DEBUG) {
    511 			log(LOG_INFO, "%s: SIOCSIFFLAGS(DEBUG)\n",
    512 			    device_xname(&sc->sc_dev));
    513 			mb86950_dump(LOG_DEBUG, sc);
    514 		}
    515 #endif
    516 		break;
    517 
    518 	case SIOCGIFMEDIA:
    519 	case SIOCSIFMEDIA:
    520 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
    521 		break;
    522 
    523 	default:
    524 		error = ether_ioctl(ifp, cmd, data);
    525 		break;
    526 	}
    527 
    528 	splx(s);
    529 	return (error);
    530 }
    531 
    532 /*
    533  * Initialize device.
    534  */
    535 void
    536 mb86950_init(struct mb86950_softc *sc)
    537 {
    538 	bus_space_tag_t bst = sc->sc_bst;
    539 	bus_space_handle_t bsh = sc->sc_bsh;
    540 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    541 
    542 	/* Reset transmitter flags. */
    543 	ifp->if_flags &= ~IFF_OACTIVE;
    544 	ifp->if_timer = 0;
    545 	sc->txb_sched = 0;
    546 
    547 	bus_space_write_1(bst, bsh, DLCR_TX_MODE, LBC);
    548 	bus_space_write_1(bst, bsh, DLCR_RX_MODE, NORMAL_MODE);
    549 
    550 	/* Enable interrupts. */
    551 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK);
    552 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK);
    553 
    554 	/* Enable transmitter and receiver. */
    555 	bus_space_write_1(bst, bsh, DLCR_CONFIG, ENABLE_DLC);
    556 	delay(200);
    557 
    558 	/* Set 'running' flag. */
    559 	ifp->if_flags |= IFF_RUNNING;
    560 
    561 	/* ...and attempt to start output. */
    562 	mb86950_start(ifp);
    563 
    564 }
    565 
    566 void
    567 mb86950_start(struct ifnet *ifp)
    568 {
    569 	struct mb86950_softc *sc = ifp->if_softc;
    570     bus_space_tag_t bst = sc->sc_bst;
    571     bus_space_handle_t bsh = sc->sc_bsh;
    572 	struct mbuf *m;
    573 	int len;
    574 
    575 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
    576 		return;
    577 
    578 	IF_DEQUEUE(&ifp->if_snd, m);
    579 	if (m == 0)
    580 		return;
    581 
    582 #if NBPFILTER > 0
    583 	/* Tap off here if there is a BPF listener. */
    584 	if (ifp->if_bpf)
    585 		bpf_mtap(ifp->if_bpf, m);
    586 #endif
    587 
    588 	/* Send the packet to the mb86950 */
    589 	len = mb86950_put_fifo(sc,m);
    590 	m_freem(m);
    591 
    592 	/* XXX bus_space_barrier here ? */
    593 	if (bus_space_read_1(bst, bsh, DLCR_TX_STAT) & (TX_UNDERFLO | TX_BUS_WR_ERR)) {
    594 		log(LOG_ERR, "%s: tx fifo underflow/overflow\n", device_xname(&sc->sc_dev));
    595 	}
    596 
    597 	bus_space_write_2(bst, bsh, BMPR_TX_LENGTH, len | TRANSMIT_START);
    598 
    599 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK);
    600 	/* XXX                          */
    601 	sc->txb_sched++;
    602 
    603 	/* We have space for 'n' transmit packets of size 'mtu. */
    604 	if (sc->txb_sched > sc->txb_num_pkt) {
    605 		ifp->if_flags |= IFF_OACTIVE;
    606 		ifp->if_timer = 2;
    607 	}
    608 }
    609 
    610 /*
    611  * Send packet - copy packet from mbuf to the fifo
    612  */
    613 u_short
    614 mb86950_put_fifo(struct mb86950_softc *sc, struct mbuf *m)
    615 {
    616 	bus_space_tag_t bst = sc->sc_bst;
    617 	bus_space_handle_t bsh = sc->sc_bsh;
    618 	u_short *data;
    619 	u_char savebyte[2];
    620 	int len, len1, wantbyte;
    621 	u_short totlen;
    622 
    623 	memset(savebyte, 0, sizeof(savebyte));	/* XXX gcc */
    624 
    625 	totlen = wantbyte = 0;
    626 
    627 	for (; m != NULL; m = m->m_next) {
    628 		data = mtod(m, u_short *);
    629 		len = m->m_len;
    630 		if (len > 0) {
    631 			totlen += len;
    632 
    633 			/* Finish the last word. */
    634 			if (wantbyte) {
    635 				savebyte[1] = *((u_char *)data);
    636 				bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte);
    637 				data = (u_short *)((u_char *)data + 1);
    638 				len--;
    639 				wantbyte = 0;
    640 			}
    641 			/* Output contiguous words. */
    642 			if (len > 1) {
    643 				len1 = len/2;
    644 				bus_space_write_multi_stream_2(bst, bsh, BMPR_FIFO, data, len1);
    645 				data += len1;
    646 				len &= 1;
    647 			}
    648 			/* Save last byte, if necessary. */
    649 			if (len == 1) {
    650 				savebyte[0] = *((u_char *)data);
    651 				wantbyte = 1;
    652 			}
    653 		}
    654 	}
    655 
    656 	if (wantbyte) {
    657 		savebyte[1] = 0;
    658 		bus_space_write_2(bst, bsh, BMPR_FIFO, *savebyte);
    659 	}
    660 
    661 	if (totlen < (ETHER_MIN_LEN - ETHER_CRC_LEN)) {
    662 
    663 		/* Fill the rest of the packet with zeros. */
    664 		/* XXX Replace this mess with something else, eats CPU */
    665 		/* The zero fill and last byte ought to be combined somehow */
    666 		for(len = totlen + 1; len < (ETHER_MIN_LEN - ETHER_CRC_LEN); len += 2)
    667 	  		bus_space_write_2(bst, bsh, BMPR_FIFO, 0);
    668 		/* XXX                                       */
    669 
    670 		totlen = (ETHER_MIN_LEN - ETHER_CRC_LEN);
    671 	}
    672 
    673 	return (totlen);
    674 }
    675 
    676 /*
    677  * Handle interrupts.
    678  * Ethernet interface interrupt processor
    679  */
    680 int
    681 mb86950_intr(void *arg)
    682 {
    683 	struct mb86950_softc *sc = arg;
    684 	bus_space_tag_t bst = sc->sc_bst;
    685 	bus_space_handle_t bsh = sc->sc_bsh;
    686 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    687 	u_int8_t tstat, rstat;
    688 
    689 	/* Get interrupt status. */
    690 	tstat = bus_space_read_1(bst, bsh, DLCR_TX_STAT);
    691 	rstat = bus_space_read_1(bst, bsh, DLCR_RX_STAT);
    692 
    693 	if (tstat == 0 && rstat == 0) return (0);
    694 
    695 	/* Disable etherstar interrupts so that we won't miss anything. */
    696 	bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, 0);
    697 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, 0);
    698 
    699 	/*
    700 	 * Handle transmitter interrupts. Handle these first because
    701 	 * the receiver will reset the board under some conditions.
    702 	 */
    703 	if (tstat != 0) {
    704 
    705 		mb86950_tint(sc, tstat);
    706 
    707 		/* acknowledge transmit interrupt status. */
    708 		bus_space_write_1(bst, bsh, DLCR_TX_STAT, tstat);
    709 
    710 	}
    711 
    712 	/* Handle receiver interrupts. */
    713 	if (rstat != 0) {
    714 
    715 		mb86950_rint(sc, rstat);
    716 
    717 		/* acknowledge receive interrupt status. */
    718 		bus_space_write_1(bst, bsh, DLCR_RX_STAT, rstat);
    719 
    720 	}
    721 
    722 	/* If tx still pending reset tx interrupt mask */
    723 	if (sc->txb_sched > 0)
    724 		bus_space_write_1(bst, bsh, DLCR_TX_INT_EN, TX_MASK);
    725 
    726 	/*
    727 	 * If it looks like the transmitter can take more data,
    728 	 * attempt to start output on the interface. This is done
    729 	 * after handling the receiver interrupt to give the
    730 	 * receive operation priority.
    731 	 */
    732 
    733 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
    734 		mb86950_start(ifp);
    735 
    736 	/* Set receive interrupts back */
    737 	bus_space_write_1(bst, bsh, DLCR_RX_INT_EN, RX_MASK);
    738 
    739 	return(1);
    740 }
    741 
    742 /* Transmission interrupt handler */
    743 void
    744 mb86950_tint(struct mb86950_softc *sc, u_int8_t tstat)
    745 {
    746 	bus_space_tag_t bst = sc->sc_bst;
    747 	bus_space_handle_t bsh = sc->sc_bsh;
    748 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    749 	int col;
    750 
    751 	if (tstat & (TX_UNDERFLO | TX_BUS_WR_ERR)) {
    752 		/* XXX What do we need to do here? reset ? */
    753 		ifp->if_oerrors++;
    754 	}
    755 
    756 	/* excessive collision */
    757 	if (tstat & TX_16COL) {
    758 		ifp->if_collisions += 16;
    759 		/* 16 collisions means that the packet has been thrown away. */
    760 		if (sc->txb_sched > 0)
    761 			sc->txb_sched--;
    762 	}
    763 
    764 	/* transmission complete. */
    765 	if (tstat & TX_DONE) {
    766 		/* successfully transmitted packets ++. */
    767 		ifp->if_opackets++;
    768 		if (sc->txb_sched > 0)
    769 			sc->txb_sched--;
    770 
    771 		/* Collision count valid only when TX_DONE is set */
    772 		if (tstat & TX_COL) {
    773 			col = (bus_space_read_1(bst, bsh, DLCR_TX_MODE) & COL_MASK) >> 4;
    774 			ifp->if_collisions = ifp->if_collisions + col;
    775 		}
    776 	}
    777 
    778 	if (sc->txb_sched == 0) {
    779 		 /* Reset output active flag and stop timer. */
    780 		 ifp->if_flags &= ~IFF_OACTIVE;
    781 		 ifp->if_timer = 0;
    782 	}
    783 }
    784 
    785 /* receiver interrupt. */
    786 void
    787 mb86950_rint(struct mb86950_softc *sc, u_int8_t rstat)
    788 {
    789 	bus_space_tag_t bst = sc->sc_bst;
    790 	bus_space_handle_t bsh = sc->sc_bsh;
    791 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    792 	u_int status, len;
    793 	int i;
    794 
    795 	 /* Update statistics if this interrupt is caused by an error. */
    796 	 if (rstat & RX_ERR_MASK) {
    797 
    798 		/* tried to read past end of fifo, should be harmless
    799 		 * count everything else
    800 		 */
    801 		if ((rstat & RX_BUS_RD_ERR) == 0) {
    802 			ifp->if_ierrors++;
    803 		}
    804 	}
    805 
    806 	/*
    807 	 * mb86950 has a flag indicating "receive buffer empty."
    808 	 * We just loop checking the flag to pull out all received
    809 	 * packets.
    810 	 *
    811 	 * We limit the number of iterrations to avoid infinite loop.
    812 	 * It can be caused by a very slow CPU (some broken
    813 	 * peripheral may insert incredible number of wait cycles)
    814 	 * or, worse, by a broken mb86950 chip.
    815 	 */
    816 	for (i = 0; i < sc->rxb_num_pkt; i++) {
    817 		/* Stop the iterration if 86950 indicates no packets. */
    818 		if (bus_space_read_1(bst, bsh, DLCR_RX_MODE) & RX_BUF_EMTY)
    819 			break;
    820 
    821 		/* receive packet status */
    822 		status = bus_space_read_2(bst, bsh, BMPR_FIFO);
    823 
    824 		/* bad packet? */
    825 		if ((status & GOOD_PKT) == 0) {
    826 			ifp->if_ierrors++;
    827 			mb86950_drain_fifo(sc);
    828 			continue;
    829 		}
    830 
    831 		/* Length valid ? */
    832 		len = bus_space_read_2(bst, bsh, BMPR_FIFO);
    833 
    834 		if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN) || len < ETHER_HDR_LEN) {
    835 			ifp->if_ierrors++;
    836 			mb86950_drain_fifo(sc);
    837 			continue;
    838 		}
    839 
    840 		if (mb86950_get_fifo(sc, len) != 0) {
    841 			/* No mbufs? Drop packet. */
    842 			ifp->if_ierrors++;
    843 			mb86950_drain_fifo(sc);
    844 			return;
    845 		}
    846 
    847 		/* Successfully received a packet.  Update stat. */
    848 		ifp->if_ipackets++;
    849 	}
    850 }
    851 
    852 /*
    853  * Receive packet.
    854  * Retrieve packet from receive buffer and send to the next level up via
    855  * ether_input(). If there is a BPF listener, give a copy to BPF, too.
    856  * Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
    857  */
    858 int
    859 mb86950_get_fifo(struct mb86950_softc *sc, u_int len)
    860 {
    861 	bus_space_tag_t bst = sc->sc_bst;
    862 	bus_space_handle_t bsh = sc->sc_bsh;
    863 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    864 	struct mbuf *m;
    865 
    866 	/* Allocate a header mbuf. */
    867 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    868 	if (m == 0)
    869 		return (-1);
    870 
    871 	/*
    872 	 * Round len to even value.
    873 	 */
    874 	if (len & 1)
    875 		len++;
    876 
    877 	m->m_pkthdr.rcvif = ifp;
    878 	m->m_pkthdr.len = len;
    879 
    880 	/* The following silliness is to make NFS happy. */
    881 #define	EROUND	((sizeof(struct ether_header) + 3) & ~3)
    882 #define	EOFF	(EROUND - sizeof(struct ether_header))
    883 
    884 	/*
    885 	 * Our strategy has one more problem.  There is a policy on
    886 	 * mbuf cluster allocation.  It says that we must have at
    887 	 * least MINCLSIZE (208 bytes) to allocate a cluster.  For a
    888 	 * packet of a size between (MHLEN - 2) to (MINCLSIZE - 2),
    889 	 * our code violates the rule...
    890 	 * On the other hand, the current code is short, simple,
    891 	 * and fast, however.  It does no harmful thing, just wastes
    892 	 * some memory.  Any comments?  FIXME.
    893 	 */
    894 
    895 	/* Attach a cluster if this packet doesn't fit in a normal mbuf. */
    896 	if (len > MHLEN - EOFF) {
    897 		MCLGET(m, M_DONTWAIT);
    898 		if ((m->m_flags & M_EXT) == 0) {
    899 			m_freem(m);
    900 			return (-1);
    901 		}
    902 	}
    903 
    904 	/*
    905 	 * The following assumes there is room for the ether header in the
    906 	 * header mbuf.
    907 	 */
    908 	m->m_data += EOFF;
    909 
    910 	/* Set the length of this packet. */
    911 	m->m_len = len;
    912 
    913 	/* Get a packet. */
    914 	bus_space_read_multi_stream_2(bst, bsh, BMPR_FIFO, mtod(m, u_int16_t *), (len + 1) >> 1);
    915 
    916 #if NBPFILTER > 0
    917 	/*
    918 	 * Check if there's a BPF listener on this interface.  If so, hand off
    919 	 * the raw packet to bpf.
    920 	 */
    921 	if (ifp->if_bpf)
    922 		bpf_mtap(ifp->if_bpf, m);
    923 #endif
    924 
    925 	(*ifp->if_input)(ifp, m);
    926 	return (0);
    927 }
    928 
    929 /*
    930  * Enable power on the interface.
    931  */
    932 int
    933 mb86950_enable(struct mb86950_softc *sc)
    934 {
    935 
    936 	if ((sc->sc_stat & ESTAR_STAT_ENABLED) == 0 && sc->sc_enable != NULL) {
    937 		if ((*sc->sc_enable)(sc) != 0) {
    938 			aprint_error_dev(&sc->sc_dev, "device enable failed\n");
    939 			return (EIO);
    940 		}
    941 	}
    942 
    943 	sc->sc_stat |= ESTAR_STAT_ENABLED;
    944 	return (0);
    945 }
    946 
    947 /*
    948  * Disable power on the interface.
    949  */
    950 void
    951 mb86950_disable(struct mb86950_softc *sc)
    952 {
    953 
    954 	if ((sc->sc_stat & ESTAR_STAT_ENABLED) != 0 && sc->sc_disable != NULL) {
    955 		(*sc->sc_disable)(sc);
    956 		sc->sc_stat &= ~ESTAR_STAT_ENABLED;
    957 	}
    958 }
    959 
    960 /*
    961  * mbe_activate:
    962  *
    963  *	Handle device activation/deactivation requests.
    964  */
    965 int
    966 mb86950_activate(struct device *self, enum devact act)
    967 {
    968 	struct mb86950_softc *sc = (struct mb86950_softc *)self;
    969 	int rv, s;
    970 
    971 	rv = 0;
    972 	s = splnet();
    973 	switch (act) {
    974 	case DVACT_ACTIVATE:
    975 		rv = EOPNOTSUPP;
    976 		break;
    977 
    978 	case DVACT_DEACTIVATE:
    979 		if_deactivate(&sc->sc_ec.ec_if);
    980 		break;
    981 	}
    982 	splx(s);
    983 	return (rv);
    984 }
    985 
    986 /*
    987  * mb86950_detach:
    988  *
    989  *	Detach a mb86950 interface.
    990  */
    991 int
    992 mb86950_detach(struct mb86950_softc *sc)
    993 {
    994 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    995 
    996 	/* Succeed now if there's no work to do. */
    997 	if ((sc->sc_stat & ESTAR_STAT_ATTACHED) == 0)
    998 		return (0);
    999 
   1000 	/* Delete all media. */
   1001 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
   1002 
   1003 #if NRND > 0
   1004 	/* Unhook the entropy source. */
   1005 	rnd_detach_source(&sc->rnd_source);
   1006 #endif
   1007 	ether_ifdetach(ifp);
   1008 	if_detach(ifp);
   1009 
   1010 	return (0);
   1011 }
   1012 
   1013 #if ESTAR_DEBUG >= 1
   1014 void
   1015 mb86950_dump(int level, struct mb86950_softc *sc)
   1016 {
   1017 	bus_space_tag_t bst = sc->sc_bst;
   1018 	bus_space_handle_t bsh = sc->sc_bsh;
   1019 
   1020 	log(level, "\tDLCR = %02x %02x %02x %02x %02x %02x %02x\n",
   1021 	    bus_space_read_1(bst, bsh, DLCR_TX_STAT),
   1022 	    bus_space_read_1(bst, bsh, DLCR_TX_INT_EN),
   1023 	    bus_space_read_1(bst, bsh, DLCR_RX_STAT),
   1024 	    bus_space_read_1(bst, bsh, DLCR_RX_INT_EN),
   1025 	    bus_space_read_1(bst, bsh, DLCR_TX_MODE),
   1026 	    bus_space_read_1(bst, bsh, DLCR_RX_MODE),
   1027 	    bus_space_read_1(bst, bsh, DLCR_CONFIG));
   1028 
   1029 	/* XXX BMPR2, 4 write only ?
   1030 	log(level, "\tBMPR = xxxx %04x %04x\n",
   1031 		bus_space_read_2(bst, bsh, BMPR_TX_LENGTH),
   1032 		bus_space_read_2(bst, bsh, BMPR_DMA));
   1033 	*/
   1034 }
   1035 #endif
   1036