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