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