Home | History | Annotate | Line # | Download | only in dev
if_qn.c revision 1.1
      1 /*	$NetBSD: if_qn.c,v 1.1 1995/10/07 18:04:27 chopps Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1995 Mika Kortelainen
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed by  Mika Kortelainen
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  *
     32  * Thanks for Aspecs Oy (Finland) for the data book for the NIC used
     33  * in this card and also many thanks for the Resource Management Force
     34  * (QuickNet card manufacturer) and especially Daniel Koch for providing
     35  * me with the necessary 'inside' information to write the driver.
     36  *
     37  * This is partly based on other code:
     38  * - if_ed.c: basic function structure for Ethernet driver
     39  *
     40  *	Device driver for National Semiconductor DS8390/WD83C690 based ethernet
     41  *	adapters.
     42  *
     43  *	Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
     44  *
     45  *	Copyright (C) 1993, David Greenman.  This software may be used,
     46  *	modified, copied, distributed, and sold, in both source and binary
     47  *	form provided that the above copyright and these terms are retained.
     48  *	Under no circumstances is the author responsible for the proper
     49  *	functioning of this software, nor does the author assume any
     50  *	responsibility for damages incurred with its use.
     51  *
     52  * - if_es.c: used as an example of -current driver
     53  *
     54  *	Copyright (c) 1995 Michael L. Hitch
     55  *	All rights reserved.
     56  *
     57  *
     58  * TODO:
     59  * - add multicast support
     60  * - try to find out what is the reason for random lock-ups happening
     61  *   when (or after) getting data
     62  */
     63 
     64 #include "qn.h"
     65 #if NQN > 0
     66 
     67 #define QN_DEBUG
     68 
     69 #include "bpfilter.h"
     70 
     71 /*
     72  * Fujitsu MB86950 Ethernet Controller (as used in QuickNet QN2000 Ethernet card)
     73  */
     74 
     75 #include <sys/param.h>
     76 #include <sys/systm.h>
     77 #include <sys/mbuf.h>
     78 #include <sys/buf.h>
     79 #include <sys/device.h>
     80 #include <sys/protosw.h>
     81 #include <sys/socket.h>
     82 #include <sys/syslog.h>
     83 #include <sys/ioctl.h>
     84 #include <sys/errno.h>
     85 
     86 #include <net/if.h>
     87 #include <net/netisr.h>
     88 #include <net/route.h>
     89 
     90 #ifdef INET
     91 #include <netinet/in.h>
     92 #include <netinet/in_systm.h>
     93 #include <netinet/in_var.h>
     94 #include <netinet/ip.h>
     95 #include <netinet/if_ether.h>
     96 #endif
     97 
     98 #ifdef NS
     99 #include <netns/ns.h>
    100 #include <netns/ns_if.h>
    101 #endif
    102 
    103 #include <machine/cpu.h>
    104 #include <machine/mtpr.h>
    105 #include <amiga/amiga/device.h>
    106 #include <amiga/amiga/isr.h>
    107 #include <amiga/dev/zbusvar.h>
    108 #include <amiga/dev/if_qnreg.h>
    109 
    110 
    111 #define ETHER_MIN_LEN 64
    112 #define ETHER_MAX_LEN 1518
    113 #define ETHER_ADDR_LEN 6
    114 
    115 
    116 /*
    117  * Ethernet software status per interface
    118  *
    119  * Each interface is referenced by a network interface structure,
    120  * qn_if, which the routing code uses to locate the interface.
    121  * This structure contains the output queue for the interface, its address, ...
    122  */
    123 struct	qn_softc {
    124 	struct	device sc_dev;
    125 	struct	isr sc_isr;
    126 	struct	arpcom sc_arpcom;	/* Common ethernet structures */
    127 	u_char	volatile *sc_base;
    128 	u_char	volatile *sc_nic_base;
    129 	u_short	volatile *nic_fifo;
    130 	u_short	volatile *nic_r_status;
    131 	u_short	volatile *nic_t_status;
    132 	u_short	volatile *nic_r_mask;
    133 	u_short	volatile *nic_t_mask;
    134 	u_short	volatile *nic_r_mode;
    135 	u_short	volatile *nic_t_mode;
    136 	u_short	volatile *nic_reset;
    137 	u_short	volatile *nic_len;
    138 	u_char	transmit_pending;
    139 #if NBPFILTER > 0
    140 	caddr_t	sc_bpf;
    141 #endif
    142 } qn_softc[NQN];
    143 
    144 #if NBPFILTER > 0
    145 #include <net/bpf.h>
    146 #include <net/bpfdesc.h>
    147 #endif
    148 
    149 
    150 int	qnmatch __P((struct device *, void *, void *));
    151 void	qnattach __P((struct device *, struct device *, void *));
    152 int	qnintr __P((struct qn_softc *sc));
    153 int	qnioctl __P((struct ifnet *, u_long, caddr_t));
    154 void	qnstart __P((struct ifnet *));
    155 void	qnwatchdog __P((int));
    156 void	qnreset __P((struct qn_softc *));
    157 void	qninit __P((struct qn_softc *));
    158 void	qnstop __P((struct qn_softc *));
    159 static	u_short qn_put __P((u_short volatile *, struct mbuf *));
    160 static	void qn_flush __P((struct qn_softc *));
    161 
    162 struct cfdriver qncd = {
    163 	NULL, "qn", qnmatch, qnattach, DV_IFNET, sizeof(struct qn_softc)
    164 };
    165 
    166 int
    167 qnmatch(parent, match, aux)
    168 	struct device *parent;
    169 	void *match, *aux;
    170 {
    171 	struct zbus_args *zap;
    172 
    173 	zap = (struct zbus_args *)aux;
    174 
    175 	/* RMF QuickNet QN2000 EtherNet card */
    176 	if (zap->manid == 2011 && zap->prodid == 2)
    177 		return (1);
    178 
    179 	return (0);
    180 }
    181 
    182 /*
    183  * Interface exists: make available by filling in network interface
    184  * record.  System will initialize the interface when it is ready
    185  * to accept packets.
    186  */
    187 void
    188 qnattach(parent, self, aux)
    189 	struct device *parent, *self;
    190 	void *aux;
    191 {
    192 	struct zbus_args *zap;
    193 	struct qn_softc *sc = (struct qn_softc *)self;
    194 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    195 	int i;
    196 
    197 	zap = (struct zbus_args *)aux;
    198 
    199 	sc->sc_base = zap->va;
    200 	sc->sc_nic_base = sc->sc_base + QUICKNET_NIC_BASE;
    201 	sc->nic_fifo = (u_short volatile *)(sc->sc_nic_base + NIC_BMPR0);
    202 	sc->nic_len = (u_short volatile *)(sc->sc_nic_base + NIC_BMPR2);
    203 	sc->nic_t_status = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR0);
    204 	sc->nic_r_status = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR2);
    205 	sc->nic_t_mask = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR1);
    206 	sc->nic_r_mask = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR3);
    207 	sc->nic_t_mode = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR4);
    208 	sc->nic_r_mode = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR5);
    209 	sc->nic_reset = (u_short volatile *)(sc->sc_nic_base + NIC_DLCR6);
    210 	sc->transmit_pending = 0;
    211 
    212 	/*
    213 	 * The ethernet address of the board (1st three bytes are the vendor
    214 	 * address, the rest is the serial number of the board).
    215 	 */
    216 	sc->sc_arpcom.ac_enaddr[0] = 0x5c;
    217 	sc->sc_arpcom.ac_enaddr[1] = 0x5c;
    218 	sc->sc_arpcom.ac_enaddr[2] = 0x00;
    219 	sc->sc_arpcom.ac_enaddr[3] = (zap->serno >> 16) & 0xff;
    220 	sc->sc_arpcom.ac_enaddr[4] = (zap->serno >> 8) & 0xff;
    221 	sc->sc_arpcom.ac_enaddr[5] = zap->serno & 0xff;
    222 
    223 	/* set interface to stopped condition (reset) */
    224 	qnstop(sc);
    225 
    226 	ifp->if_unit = sc->sc_dev.dv_unit;
    227 	ifp->if_name = qncd.cd_name;
    228 	ifp->if_ioctl = qnioctl;
    229 	ifp->if_watchdog = qnwatchdog;
    230 	ifp->if_output = ether_output;
    231 	ifp->if_start = qnstart;
    232 	/* XXX IFF_MULTICAST */
    233 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
    234 	ifp->if_mtu = ETHERMTU;
    235 
    236 	/* Attach the interface. */
    237 	if_attach(ifp);
    238 	ether_ifattach(ifp);
    239 
    240 #ifdef QN_DEBUG
    241 	printf(": hardware address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
    242 #endif
    243 
    244 #if NBPFILTER > 0
    245 	bpfattach(&sc->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
    246 #endif
    247 
    248 	sc->sc_isr.isr_intr = qnintr;
    249 	sc->sc_isr.isr_arg = sc;
    250 	sc->sc_isr.isr_ipl = 2;
    251 	add_isr(&sc->sc_isr);
    252 }
    253 
    254 /*
    255  * Initialize device
    256  *
    257  */
    258 void
    259 qninit(sc)
    260 	struct qn_softc *sc;
    261 {
    262 	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
    263 	u_short i;
    264 	int s;
    265 
    266 	s = splimp();
    267 
    268 	/* Initialize NIC */
    269 	*sc->nic_reset      = DISABLE_DLC;
    270 	*sc->nic_t_status   = CLEAR_T_ERR;
    271 	*sc->nic_t_mask     = CLEAR_T_MASK;
    272 	*sc->nic_r_status   = CLEAR_R_ERR;
    273 	*sc->nic_r_mask     = R_INT_PKT_RDY;
    274 	*sc->nic_t_mode     = NO_LOOPBACK;
    275 
    276 	/* Turn DMA off */
    277 	*((u_short volatile *)(sc->sc_nic_base + NIC_BMPR4)) = (u_short)0x0000;
    278 
    279 	if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) {
    280 		*sc->nic_r_mode = PROMISCUOUS_MODE;
    281 		log(LOG_INFO, "qn: Promiscuous mode (not tested)\n");
    282 	} else
    283 		*sc->nic_r_mode = NORMAL_MODE;
    284 
    285 	/* Set physical ethernet address. */
    286 	for (i = 0; i < ETHER_ADDR_LEN; i++)
    287 		*((u_short volatile *)(sc->sc_nic_base+QNET_HARDWARE_ADDRESS+2*i)) =
    288 		    ((((u_short)sc->sc_arpcom.ac_enaddr[i]) << 8) |
    289 		    sc->sc_arpcom.ac_enaddr[i]);
    290 
    291 	sc->transmit_pending = 0;
    292 	ifp->if_flags |= IFF_RUNNING;
    293 	ifp->if_flags &= ~IFF_OACTIVE;
    294 
    295 	qn_flush(sc);
    296 
    297 	/* Enable data link controller. */
    298 	*((u_short volatile *)(sc->sc_nic_base + QNET_MAGIC)) = (u_short)0x0000;
    299 	*sc->nic_reset = ENABLE_DLC;
    300 
    301 	/* Attempt to start output, if any. */
    302 	qnstart(ifp);
    303 
    304 	splx(s);
    305 }
    306 
    307 
    308 /*
    309  * Device timeout/watchdog routine.  Entered if the device neglects to
    310  * generate an interrupt after a transmit has been started on it.
    311  */
    312 void
    313 qnwatchdog(unit)
    314 	int unit;
    315 {
    316 	struct qn_softc *sc = qncd.cd_devs[unit];
    317 
    318 	log(LOG_ERR, "%s: device timeout (watchdog)\n", sc->sc_dev.dv_xname);
    319 	++sc->sc_arpcom.ac_if.if_oerrors;
    320 
    321 	qnreset(sc);
    322 }
    323 
    324 
    325 /*
    326  * Flush card's buffer RAM
    327  */
    328 static void
    329 qn_flush(sc)
    330 	struct qn_softc *sc;
    331 {
    332 #ifdef QN_DEBUG1
    333 	int cnt = 0;
    334 #endif
    335 	/* Read data until bus read error (i.e. buffer empty). */
    336 	while (!(*sc->nic_r_status & R_BUS_RD_ERR)) {
    337 		(void)(*sc->nic_fifo);
    338 #ifdef QN_DEBUG1
    339 		cnt++;
    340 #endif
    341 	}
    342 #ifdef QN_DEBUG1
    343 	log(LOG_INFO, "Flushed %d words\n", cnt);
    344 #endif
    345 
    346 	/* Clear bus read error. */
    347 	*sc->nic_r_status = R_BUS_RD_ERR;
    348 }
    349 
    350 
    351 /*
    352  * Reset the interface...
    353  *
    354  */
    355 void
    356 qnreset(sc)
    357 	struct qn_softc *sc;
    358 {
    359 	int s;
    360 
    361 	s = splimp();
    362 	qnstop(sc);
    363 	qninit(sc);
    364 	splx(s);
    365 }
    366 
    367 
    368 /*
    369  * Take interface offline
    370  */
    371 void
    372 qnstop(sc)
    373 	struct qn_softc *sc;
    374 {
    375 
    376 	/* Stop the interface. */
    377 	*sc->nic_reset  = DISABLE_DLC;
    378 
    379 	*sc->nic_t_mask = CLEAR_T_MASK;
    380 	*sc->nic_r_mask = CLEAR_R_MASK;
    381 
    382 	qn_flush(sc);
    383 }
    384 
    385 
    386 /*
    387  * Start output on interface. Get another datagram to send
    388  * off the interface queue, and copy it to the
    389  * interface before starting the output.
    390  *
    391  * This assumes that it is called inside a critical section...
    392  *
    393  */
    394 void
    395 qnstart(ifp)
    396 	struct ifnet *ifp;
    397 {
    398 	struct qn_softc *sc = qncd.cd_devs[ifp->if_unit];
    399 	struct mbuf *m;
    400 	u_short len;
    401 	int timout = 50000;
    402 
    403 	if ((sc->sc_arpcom.ac_if.if_flags & (IFF_RUNNING | IFF_OACTIVE)) !=
    404 	    IFF_RUNNING)
    405 		return;
    406 
    407 	IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m);
    408 	if (m == 0)
    409 		return;
    410 
    411 #if NBPFILTER > 0
    412 	/*
    413 	 * If bpf is listening on this interface, let it
    414 	 * see the packet before we commit it to the wire
    415 	 *
    416 	 * (can't give the copy in QuickNet card RAM to bpf, because
    417 	 * that RAM is not visible to the host but is read from FIFO)
    418 	 *
    419 	 */
    420 	log(LOG_INFO, "NBPFILTER... no-one has tested this with qn.\n");
    421 	if (sc->sc_bpf)
    422 		bpf_mtap(sc->sc_bpf, m);
    423 #endif
    424 	len = qn_put(sc->nic_fifo, m);
    425 
    426 	/*
    427 	 * Really transmit the packet
    428 	 */
    429 
    430 	/* set packet length (byte-swapped) */
    431 	len = ((len >> 8) & 0x0007) | TRANSMIT_START | ((len & 0x00ff) << 8);
    432 	*sc->nic_len = len;
    433 
    434 	/* Wait for the packet to really leave */
    435 	while (!(*sc->nic_t_status & T_TMT_OK) && --timout)
    436 		;
    437 	if (timout == 0)
    438 		/* Maybe we should try to recover from this one? */
    439 		/* But for now on, let's just fall thru and hope the best... */
    440 		log(LOG_INFO, "qn:timout\n");
    441 
    442 	sc->transmit_pending = 1;
    443 	*sc->nic_t_mask = INT_TMT_OK | INT_SIXTEEN_COL;
    444 
    445 	sc->sc_arpcom.ac_if.if_flags |= IFF_OACTIVE;
    446 	ifp->if_timer = 2;
    447 }
    448 
    449 
    450 /*
    451  * Memory copy, copies word at a time
    452  */
    453 static void inline
    454 word_copy_from_card(card, b, len)
    455 	u_short volatile *card;
    456 	u_short *b, len;
    457 {
    458 	register u_short l = len/2;
    459 
    460 	while (l--)
    461 		*b++ = *card;
    462 }
    463 
    464 static void inline
    465 word_copy_to_card(a, card, len)
    466 	u_short *a, len;
    467 	u_short volatile *card;
    468 {
    469 	register u_short l = len/2;
    470 
    471 	while (l--)
    472 		*card = *a++;
    473 }
    474 
    475 
    476 /*
    477  * Copy packet from mbuf to the board memory
    478  *
    479  * Uses an extra buffer/extra memory copy,
    480  * unless the whole packet fits in one mbuf.
    481  *
    482  */
    483 static u_short
    484 qn_put(addr, m)
    485 	u_short volatile *addr;
    486 	struct mbuf *m;
    487 {
    488 	struct mbuf *mp;
    489 	register u_short len, tlen;
    490 	static u_short packet_buf[1536/2];
    491 	register u_char *p;
    492 
    493 	/*
    494 	 * If buffer is bzeroed, we might copy max(60, tlen) bytes and get
    495 	 * rid of extra zero fill-ins.
    496 	 */
    497 	bzero(packet_buf, 1536);
    498 
    499 	/*
    500 	 * The whole packet in one mbuf?
    501 	 */
    502 	if (m->m_next == NULL) {
    503 		tlen = m->m_len;
    504 		bcopy(mtod(m, u_char *), (u_char *)packet_buf, tlen);
    505 		/*word_copy_to_card(mtod(m, u_short *), addr, tlen + 1);*/
    506 		word_copy_to_card(packet_buf,
    507 		    addr,
    508 		    max(tlen + 1, ETHER_MIN_LEN-4));
    509 	} else {
    510 		/* No it wasn't, let's start copying */
    511 		for (p = (u_char *)packet_buf, tlen = 0, mp = m;
    512 		     mp;
    513 		     mp = mp->m_next) {
    514 			if ((len = mp->m_len) == 0)
    515 				continue;
    516 			tlen += len;
    517 			bcopy(mtod(mp, u_char *), p, len);
    518 			p += len;
    519 		}
    520 		/* word_copy_to_card(packet_buf, addr, tlen + 1); */
    521 		word_copy_to_card(packet_buf,
    522 		    addr,
    523 		    max(tlen + 1, ETHER_MIN_LEN-4));
    524 	}
    525 	m_freem(m);
    526 
    527 	if (tlen < ETHER_MIN_LEN - 4)
    528 		/* We have copied ETHER_MIN_LEN-4 bytes. */
    529 		tlen = ETHER_MIN_LEN - 4;
    530 	return (tlen);
    531 }
    532 
    533 /*
    534  * Copy packet from board RAM
    535  *
    536  * Trailers not supported.
    537  *
    538  */
    539 static void
    540 qn_get_packet(sc, len)
    541 	struct qn_softc *sc;
    542 	u_short len;
    543 {
    544 	register u_short volatile *nic_fifo_ptr = sc->nic_fifo;
    545 	struct ether_header *eh;
    546 	struct mbuf *m, *dst, *head = 0;
    547 	register u_short len1;
    548 	u_short amount;
    549 
    550 	/* Allocate header mbuf. */
    551 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    552 	if (m == 0)
    553 		goto bad;
    554 
    555 	m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
    556 	m->m_pkthdr.len = len;
    557 	m->m_len = 0;
    558 	head = m;
    559 
    560 	eh = mtod(head, struct ether_header *);
    561 
    562 	word_copy_from_card(nic_fifo_ptr,
    563 	    mtod(head, u_short *),
    564 	    sizeof(struct ether_header));
    565 
    566 	head->m_len += sizeof(struct ether_header);
    567 	len -= sizeof(struct ether_header);
    568 
    569 	while (len > 0) {
    570 		len1 = len;
    571 
    572 		amount = M_TRAILINGSPACE(m);
    573 		if (amount == 0) {
    574 			/* allocate another mbuf */
    575 			dst = m;
    576 			MGET(m, M_DONTWAIT, MT_DATA);
    577 			if (m == 0)
    578 				goto bad;
    579 
    580 			if (len1 >= MINCLSIZE)
    581 				MCLGET(m, M_DONTWAIT);
    582 
    583 			m->m_len = 0;
    584 			dst->m_next = m;
    585 
    586 			amount = M_TRAILINGSPACE(m);
    587 		}
    588 
    589 		if (amount < len1) {
    590 			if (amount & 1)
    591 				log(LOG_INFO, "Room for odd-length packet\n");
    592 			len1 = amount;
    593 		}
    594 		word_copy_from_card(nic_fifo_ptr,
    595 		    (u_short *)(mtod(m, caddr_t) + m->m_len),
    596 		    len1 + 1);
    597 		m->m_len += len1;
    598 		len -= len1;
    599 	}
    600 
    601 #if NBPFILTER > 0
    602 	log(LOG_INFO, "qn: Beware, an untested code section\n");
    603 	if (sc->sc_bpf) {
    604 		bpf_mtap(sc->sc_bpf, head);
    605 
    606 		/*
    607 		 * The interface cannot be in promiscuous mode if there are
    608 		 * no BPF listeners. And in prom. mode we have to check
    609 		 * if the packet is really ours...
    610 		 */
    611 		if ((sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) &&
    612 		    (eh->ether_dhost[0] & 1) == 0 && /* not bcast or mcast */
    613 		    bcmp(eh->ether_dhost,
    614         	        sc->sc_arpcom.ac_enaddr,
    615 		        ETHER_ADDR_LEN) != 0) {
    616 			m_freem(head);
    617 			return;
    618 		}
    619 	}
    620 #endif
    621 
    622 	m_adj(head, sizeof(struct ether_header));
    623 	ether_input(&sc->sc_arpcom.ac_if, eh, head);
    624 	return;
    625 
    626 bad:
    627 	if (head)
    628 		m_freem(head);
    629 }
    630 
    631 
    632 /*
    633  * Ethernet interface receiver interrupt.
    634  */
    635 static void
    636 qn_rint(sc)
    637 	struct qn_softc *sc;
    638 {
    639 	int i;
    640 	u_short len, status;
    641 
    642 	/*
    643 	 * Read at most 25 packets per interrupt
    644 	 */
    645 	for (i = 0; i < 25; i++) {
    646 		if (*sc->nic_r_mode & RM_BUF_EMP) {
    647 			/*
    648 			 * Buffer empty
    649 			 */
    650 			if ((status = *sc->nic_r_status)) {
    651 				/* It was some error: let's first clear
    652 				 * the register.
    653 				 */
    654 				*sc->nic_r_status = CLEAR_R_ERR;
    655 				if (status & 0x0101) {
    656 #ifdef QN_DEBUG
    657 					log(LOG_INFO, "Overflow\n");
    658 #endif
    659 					++sc->sc_arpcom.ac_if.if_ierrors;
    660 				} else if (status & 0x0202) {
    661 #ifdef QN_DEBUG
    662 					log(LOG_INFO, "CRC Error\n");
    663 #endif
    664 					++sc->sc_arpcom.ac_if.if_ierrors;
    665 				} else if (status & 0x0404) {
    666 #ifdef QN_DEBUG
    667 					log(LOG_INFO, "Alignment error\n");
    668 #endif
    669 					++sc->sc_arpcom.ac_if.if_ierrors;
    670 				} else if (status & 0x0808) {
    671 					/* Short packet (these may occur and are
    672 					 * no reason to worry about - or maybe
    673 					 * they are?).
    674 					 */
    675 #ifdef QN_DEBUG
    676 					log(LOG_INFO, "Short packet\n");
    677 #endif
    678 					++sc->sc_arpcom.ac_if.if_ierrors;
    679 					/* qnreset(sc); */
    680 				} else if (status & 0x4040) {
    681 #ifdef QN_DEBUG
    682 					log(LOG_INFO, "Bus read error\n");
    683 #endif
    684 					++sc->sc_arpcom.ac_if.if_ierrors;
    685 				} else {
    686 					/* There are some registers which are
    687 					 * not meaningful when read, so don't
    688 					 * care...
    689 					 */
    690 				}
    691 			}
    692 			return;
    693 		} else {
    694 			/* At least one valid packet. Clear the whole register. */
    695 			*sc->nic_r_status = CLEAR_R_ERR;
    696 
    697 			/* Read one word of garbage. */
    698 			(void)(*sc->nic_fifo);
    699 
    700 			/* Read packet length. */
    701 			len = *sc->nic_fifo;
    702 			len = ((len << 8) & 0xff00) | ((len >> 8) & 0x00ff);
    703 
    704 			/* Read the packet. */
    705 			qn_get_packet(sc, len);
    706 			++sc->sc_arpcom.ac_if.if_ipackets;
    707 		}
    708 	}
    709 
    710 	if (i == 25)
    711 		log(LOG_INFO, "used all the 25 loops\n");
    712 }
    713 
    714 
    715 /*
    716  * Our interrupt routine
    717  */
    718 int
    719 qnintr(sc)
    720 	struct qn_softc *sc;
    721 {
    722 	u_short tint, rint, tintmask, rintmask;
    723 
    724 	/*
    725 	 * If the driver has not been initialized, just return immediately.
    726 	 * This also happens if there is no QuickNet board present.
    727 	 */
    728 
    729 	if (sc->sc_base == NULL)
    730 		return (0);
    731 
    732 	/* Get interrupt statuses and masks. */
    733 	rint = *sc->nic_r_status;
    734 	tint = *sc->nic_t_status;
    735 	rintmask = *sc->nic_r_mask /* 0x8f8f */;
    736 	tintmask = *sc->nic_t_mask;
    737 	if (!(tint&tintmask) && !(rint&rintmask))
    738 		return (0);
    739 
    740 	/* Disable receive interrupts so that we won't miss anything. */
    741 	*sc->nic_r_mask = CLEAR_R_MASK;
    742 
    743 	/*
    744 	 * Handle transmitter interrupts. Some of them are not asked for
    745 	 * but do happen, anyway.
    746 	 */
    747 	if (tint) {
    748 		*sc->nic_t_mask   = CLEAR_T_MASK;
    749 		*sc->nic_t_status = CLEAR_T_ERR;
    750 		if (sc->transmit_pending && (tint & T_TMT_OK)) {
    751 			sc->transmit_pending = 0;
    752 			/*
    753 			 * Update total number of successfully
    754 			 * transmitted packets.
    755 			 */
    756 			sc->sc_arpcom.ac_if.if_opackets++;
    757 		}
    758 
    759 		if (tint & T_SIXTEEN_COL) {
    760 			/*
    761 			 * 16 collision (i.e., packet lost).
    762 			 */
    763 			log(LOG_INFO, "qn: 16 collision - packet lost\n");
    764 			sc->sc_arpcom.ac_if.if_oerrors++;
    765 			sc->sc_arpcom.ac_if.if_collisions += 16;
    766 			sc->transmit_pending = 0;
    767 		}
    768 
    769 		if (tint & T_COL && !(tint & T_TMT_OK)) {
    770 			/*
    771 			 * Normal collision
    772 			 */
    773 			log(LOG_INFO, "qn:collision (shouldn't hurt)\n");
    774 			sc->transmit_pending = 1;
    775 			sc->sc_arpcom.ac_if.if_oerrors++;
    776 			sc->sc_arpcom.ac_if.if_collisions++;
    777 		}
    778 
    779 		if (tint & BUS_WRITE_ERROR) {
    780 			/* One bus write error occurs at start up, at least on my
    781 			 * card. So I don't care about this one.
    782 			 */
    783 			sc->transmit_pending = 0;
    784 		}
    785 
    786 		if (tint & T_UNDERFLOW) {
    787 			log(LOG_INFO, "qn:underflow\n");
    788 		}
    789 
    790 		if (sc->transmit_pending) {
    791 			log(LOG_INFO, "qn:still pending...\n");
    792 			/* Return transmission interrupt mask. */
    793 			*sc->nic_t_mask = tintmask;
    794 		} else {
    795 			sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
    796 
    797 			/* Clear watchdog timer. */
    798 			sc->sc_arpcom.ac_if.if_timer = 0;
    799 		}
    800 	}
    801 
    802 	/*
    803 	 * Handle receiver interrupts.
    804 	 */
    805 	if (rint & rintmask)
    806 		qn_rint(sc);
    807 
    808 	/* Set receive interrupt mask back. */
    809 	*sc->nic_r_mask = rintmask;
    810 
    811 	if ((sc->sc_arpcom.ac_if.if_flags & IFF_OACTIVE) == 0)
    812 		qnstart(&sc->sc_arpcom.ac_if);
    813 
    814 	return (1);
    815 }
    816 
    817 /*
    818  * Process an ioctl request. This code needs some work - it looks pretty ugly.
    819  * I somehow think that this is quite a common excuse... ;-)
    820  */
    821 int
    822 qnioctl(ifp, command, data)
    823 	register struct ifnet *ifp;
    824 	u_long command;
    825 	caddr_t data;
    826 {
    827 	struct qn_softc *sc = qncd.cd_devs[ifp->if_unit];
    828 	register struct ifaddr *ifa = (struct ifaddr *)data;
    829 #if 0
    830 	struct ifreg *ifr = (struct ifreg *)data;
    831 #endif
    832 	int s, error = 0;
    833 
    834 	s = splimp();
    835 
    836 	switch (command) {
    837 
    838 	case SIOCSIFADDR:
    839 		ifp->if_flags |= IFF_UP;
    840 
    841 		switch (ifa->ifa_addr->sa_family) {
    842 #ifdef INET
    843 		case AF_INET:
    844 			qninit(sc);
    845 			arp_ifinit(&sc->sc_arpcom, ifa);
    846 			break;
    847 #endif
    848 #ifdef NS
    849 		case AF_NS:
    850 		    {
    851 			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
    852 
    853 			if (ns_nullhost(*ina))
    854 				ina->x_host =
    855 				    *(union ns_host *)(sc->sc_arpcom.sc_enaddr);
    856 			else
    857 				bcopy(ina->x_host.c_host,
    858 				    sc->sc_arpcom.ac_enaddr,
    859 				    sizeof(sc->sc_arpcom.ac_enaddr));
    860 			qninit(sc);
    861 			break;
    862 		    }
    863 #endif
    864 		default:
    865 			log(LOG_INFO, "qn:sa_family:default (not tested)\n");
    866 			qninit(sc);
    867 			break;
    868 		}
    869 		break;
    870 
    871 	case SIOCSIFFLAGS:
    872 		/*
    873 		 * If interface is marked down and it is running, then stop it.
    874 		 */
    875 		if ((ifp->if_flags & IFF_UP) == 0 &&
    876 		    (ifp->if_flags & IFF_RUNNING) != 0) {
    877 			/*
    878 			 * If interface is marked down and it is running, then
    879 			 * stop it.
    880 			 */
    881 			qnstop(sc);
    882 			ifp->if_flags &= ~IFF_RUNNING;
    883 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
    884 			   (ifp->if_flags & IFF_RUNNING) == 0)
    885 			/*
    886 			 * If interface is marked up and it is stopped, then
    887 			 * start it.
    888 			 */
    889 			qninit(sc);
    890 		else {
    891 			/*
    892 			 * Something else... we won't do anything so we won't
    893 			 * break anything (hope so).
    894 			 */
    895 		}
    896 		break;
    897 
    898 	case SIOCADDMULTI:
    899 	case SIOCDELMULTI:
    900 		log(LOG_INFO, "qnioctl: multicast not done yet\n");
    901 #if 0
    902 		error = (command == SIOCADDMULTI) ?
    903 		    ether_addmulti(ifr, &sc->sc_arpcom) :
    904 		    ether_delmulti(ifr, &sc->sc_arpcom);
    905 
    906 		if (error == ENETRESET) {
    907 			/*
    908 			 * Multicast list has changed; set the hardware filter
    909 			 * accordingly.
    910 			 */
    911 			log(LOG_INFO, "qnioctl: multicast not done yet\n");
    912 			error = 0;
    913 		}
    914 #else
    915 		error = EINVAL;
    916 #endif
    917 		break;
    918 
    919 	default:
    920 		log(LOG_INFO, "qnioctl: default\n");
    921 		error = EINVAL;
    922 	}
    923 
    924 	(void)splx(s);
    925 	return (error);
    926 }
    927 
    928 #endif /* NQN > 0 */
    929