Home | History | Annotate | Line # | Download | only in dev
if_sn.c revision 1.6
      1 /*	$NetBSD: if_sn.c,v 1.6 1997/03/17 13:11:24 briggs Exp $	*/
      2 
      3 /*
      4  * National Semiconductor  SONIC Driver
      5  * Copyright (c) 1991   Algorithmics Ltd (http://www.algor.co.uk)
      6  * You may use, copy, and modify this program so long as you retain the
      7  * copyright line.
      8  *
      9  * This driver has been substantially modified since Algorithmics donated
     10  * it.
     11  *
     12  *   Denton Gentry <denny1 (at) home.com>
     13  * and also
     14  *   Yanagisawa Takeshi <yanagisw (at) aa.ap.titech.ac.jp>
     15  * did the work to get this running on the Macintosh.
     16  */
     17 
     18 #include <sys/param.h>
     19 #include <sys/systm.h>
     20 #include <sys/mbuf.h>
     21 #include <sys/buf.h>
     22 #include <sys/protosw.h>
     23 #include <sys/socket.h>
     24 #include <sys/syslog.h>
     25 #include <sys/ioctl.h>
     26 #include <sys/errno.h>
     27 #include <sys/device.h>
     28 
     29 #include <net/if.h>
     30 #include <net/if_ether.h>
     31 
     32 #ifdef INET
     33 #include <netinet/in.h>
     34 #include <netinet/in_systm.h>
     35 #include <netinet/in_var.h>
     36 #include <netinet/ip.h>
     37 #include <netinet/if_inarp.h>
     38 #endif
     39 
     40 #include <vm/vm.h>
     41 
     42 extern int kvtop(caddr_t addr);
     43 
     44 #include "bpfilter.h"
     45 #if NBPFILTER > 0
     46 #include <net/bpf.h>
     47 #include <net/bpfdesc.h>
     48 #endif
     49 
     50 typedef unsigned char uchar;
     51 
     52 #include <machine/bus.h>
     53 #include <machine/cpu.h>
     54 #include <machine/viareg.h>
     55 #include <mac68k/dev/if_snreg.h>
     56 #include <mac68k/dev/if_snvar.h>
     57 
     58 #include	"nubus.h"
     59 
     60 /*
     61  * Register access macros:
     62  * SWR is "Sonic Write Register"
     63  * SRD is "Sonic Read Register"
     64  */
     65 #define SWR(a, x) 	(a) = (x)
     66 #define SRD(a)		((a) & 0xffff)
     67 
     68 #define wbflush()
     69 
     70 static void snwatchdog __P((struct ifnet *));
     71 static int sninit __P((struct sn_softc *sc));
     72 static int snstop __P((struct sn_softc *sc));
     73 static int sonicput __P((struct sn_softc *sc, struct mbuf *m0));
     74 static void snintr __P((void *, int));
     75 static int snioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data));
     76 static void snstart __P((struct ifnet *ifp));
     77 static void snreset __P((struct sn_softc *sc));
     78 
     79 void camdump __P((struct sn_softc *sc));
     80 
     81 struct cfdriver sn_cd = {
     82 	NULL, "sn", DV_IFNET
     83 };
     84 
     85 #undef assert
     86 #undef _assert
     87 
     88 #ifdef NDEBUG
     89 #define	assert(e)	((void)0)
     90 #define	_assert(e)	((void)0)
     91 #else
     92 #define	_assert(e)	assert(e)
     93 #ifdef __STDC__
     94 #define	assert(e)	((e) ? (void)0 : __assert("sn ", __FILE__, __LINE__, #e))
     95 #else	/* PCC */
     96 #define	assert(e)	((e) ? (void)0 : __assert("sn "__FILE__, __LINE__, "e"))
     97 #endif
     98 #endif
     99 
    100 int ethdebug = 0;
    101 
    102 /*
    103  * SONIC buffers need to be aligned 16 or 32 bit aligned.
    104  * These macros calculate and verify alignment.
    105  */
    106 #define	ROUNDUP(p, N)	(((int) p + N - 1) & ~(N - 1))
    107 
    108 #define SOALIGN(m, array)	(m ? (ROUNDUP(array, 4)) : (ROUNDUP(array, 2)))
    109 
    110 #define LOWER(x) ((unsigned)(x) & 0xffff)
    111 #define UPPER(x) ((unsigned)(x) >> 16)
    112 
    113 /*
    114  * Interface exists: make available by filling in network interface
    115  * record.  System will initialize the interface when it is ready
    116  * to accept packets.
    117  */
    118 void
    119 snsetup(sc, lladdr)
    120 	struct sn_softc	*sc;
    121 	u_int8_t *lladdr;
    122 {
    123 	struct ifnet	*ifp = &sc->sc_if;
    124 	unsigned char	*p;
    125 	unsigned char	*pp;
    126 	int		i;
    127 
    128 	sc->sc_csr = (struct sonic_reg *) sc->sc_regh;
    129 
    130 /*
    131  * Disable caching on the SONIC's data space.
    132  */
    133 	physaccess((caddr_t) sc->space, (caddr_t) kvtop((caddr_t) sc->space),
    134 		sizeof(sc->space), PG_V | PG_RW | PG_CI);
    135 
    136 /*
    137  * Put the pup in reset mode (sninit() will fix it later)
    138  * and clear any interrupts.
    139  */
    140 	sc->sc_csr->s_cr = CR_RST;
    141 	wbflush();
    142 	sc->sc_csr->s_isr = 0x7fff;
    143 	wbflush();
    144 
    145 /*
    146  * because the SONIC is basically 16bit device it 'concatenates'
    147  * a higher buffer address to a 16 bit offset--this will cause wrap
    148  * around problems near the end of 64k !!
    149  */
    150 	p = &sc->space[0];
    151 	pp = (unsigned char *)ROUNDUP ((int)p, NBPG);
    152 	p = pp;
    153 
    154 	for (i = 0; i < NRRA; i++) {
    155 		sc->p_rra[i] = (void *)p;
    156 		sc->v_rra[i] = kvtop(p);
    157 		p += RXRSRC_SIZE(sc);
    158 	}
    159 	sc->v_rea = kvtop(p);
    160 
    161 	p = (unsigned char *)SOALIGN(sc, p);
    162 
    163 	sc->p_cda = (void *) (p);
    164 	sc->v_cda = kvtop(p);
    165 	p += CDA_SIZE(sc);
    166 
    167 	p = (unsigned char *)SOALIGN(sc, p);
    168 
    169 	for (i = 0; i < NRDA; i++) {
    170 		sc->p_rda[i] = (void *) p;
    171 		sc->v_rda[i] = kvtop(p);
    172 		p += RXPKT_SIZE(sc);
    173 	}
    174 
    175 	p = (unsigned char *)SOALIGN(sc, p);
    176 
    177 	for (i = 0; i < NTDA; i++) {
    178 		struct mtd *mtdp = &sc->mtda[i];
    179 		mtdp->mtd_txp = (void *)p;
    180 		mtdp->mtd_vtxp = kvtop(p);
    181 		p += TXP_SIZE(sc);
    182 	}
    183 
    184 	p = (unsigned char *)SOALIGN(sc, p);
    185 
    186 	if ((p - pp) > NBPG) {
    187 		printf ("sn: sizeof RRA (%ld) + CDA (%ld) +"
    188 			"RDA (%ld) + TDA (%ld) > NBPG (%d). Punt!\n",
    189 			(ulong)sc->p_cda - (ulong)sc->p_rra[0],
    190 			(ulong)sc->p_rda[0] - (ulong)sc->p_cda,
    191 			(ulong)sc->mtda[0].mtd_txp - (ulong)sc->p_rda[0],
    192 			(ulong)p - (ulong)sc->mtda[0].mtd_txp,
    193 			NBPG);
    194 		return;
    195 	}
    196 
    197 	p = pp + NBPG;
    198 
    199 	for (i = 0; i < NRBA; i+=2) {
    200 		sc->rbuf[i] = (caddr_t) p;
    201 		sc->rbuf[i+1] = (caddr_t)(p + (NBPG/2));
    202 		p += NBPG;
    203 	}
    204 
    205 	for (i = 0; i < NTXB; i+=2) {
    206 		sc->tbuf[i] = (caddr_t) p;
    207 		sc->tbuf[i+1] = (caddr_t)(p + (NBPG/2));
    208 		sc->vtbuf[i] = kvtop(sc->tbuf[i]);
    209 		sc->vtbuf[i+1] = kvtop(sc->tbuf[i+1]);
    210 		p += NBPG;
    211 	}
    212 
    213 #if 0
    214 	camdump(sc);
    215 #endif
    216 	printf(" address %s\n", ether_sprintf(lladdr));
    217 
    218 #if 0
    219 printf("sonic buffers: rra=%p cda=0x%x rda=0x%x tda=0x%x\n",
    220 	sc->p_rra[0], sc->p_cda, sc->p_rda[0], sc->mtda[0].mtd_txp);
    221 #endif
    222 
    223 	bcopy(lladdr, sc->sc_enaddr, 6);
    224 
    225 	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
    226 	ifp->if_softc = sc;
    227 	ifp->if_ioctl = snioctl;
    228 	ifp->if_start = snstart;
    229 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    230 	ifp->if_watchdog = snwatchdog;
    231 #if NBPFILTER > 0
    232 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
    233 #endif
    234 	if_attach(ifp);
    235 	ether_ifattach(ifp, lladdr);
    236 
    237 	add_nubus_intr(sc->slotno, snintr, (void *) sc);
    238 }
    239 
    240 static int
    241 snioctl(ifp, cmd, data)
    242 	struct ifnet *ifp;
    243 	u_long cmd;
    244 	caddr_t data;
    245 {
    246 	struct ifaddr *ifa;
    247 	struct sn_softc *sc = ifp->if_softc;
    248 	int     s = splnet(), err = 0;
    249 	int	temp;
    250 
    251 	switch (cmd) {
    252 
    253 	case SIOCSIFADDR:
    254 		ifa = (struct ifaddr *)data;
    255 		ifp->if_flags |= IFF_UP;
    256 		switch (ifa->ifa_addr->sa_family) {
    257 #ifdef INET
    258 		case AF_INET:
    259 			(void)sninit(ifp->if_softc);
    260 			arp_ifinit(ifp, ifa);
    261 			break;
    262 #endif
    263 		default:
    264 			(void)sninit(ifp->if_softc);
    265 			break;
    266 		}
    267 		break;
    268 
    269 	case SIOCSIFFLAGS:
    270 		if ((ifp->if_flags & IFF_UP) == 0 &&
    271 		    ifp->if_flags & IFF_RUNNING) {
    272 			snstop(ifp->if_softc);
    273 			ifp->if_flags &= ~IFF_RUNNING;
    274 		} else if (ifp->if_flags & IFF_UP &&
    275 		    (ifp->if_flags & IFF_RUNNING) == 0)
    276 			(void)sninit(ifp->if_softc);
    277 		/*
    278 		 * If the state of the promiscuous bit changes, the interface
    279 		 * must be reset to effect the change.
    280 		 */
    281 		if (((ifp->if_flags ^ sc->sc_iflags) & IFF_PROMISC) &&
    282 		    (ifp->if_flags & IFF_RUNNING)) {
    283 			sc->sc_iflags = ifp->if_flags;
    284 			printf("change in flags\n");
    285 			temp = sc->sc_if.if_flags & IFF_UP;
    286 			snreset(sc);
    287 			sc->sc_if.if_flags |= temp;
    288 			snstart(ifp);
    289 		}
    290 		break;
    291 
    292 	case SIOCADDMULTI:
    293 	case SIOCDELMULTI:
    294 		if(cmd == SIOCADDMULTI)
    295 			err = ether_addmulti((struct ifreq *)data,
    296 						&sc->sc_ethercom);
    297 		else
    298 			err = ether_delmulti((struct ifreq *)data,
    299 						&sc->sc_ethercom);
    300 
    301 		if (err == ENETRESET) {
    302 			/*
    303 			 * Multicast list has changed; set the hardware
    304 			 * filter accordingly. But remember UP flag!
    305 			 */
    306 			temp = sc->sc_if.if_flags & IFF_UP;
    307 			snreset(sc);
    308 			sc->sc_if.if_flags |= temp;
    309 			err = 0;
    310 		}
    311 		break;
    312 	default:
    313 		err = EINVAL;
    314 	}
    315 	splx(s);
    316 	return (err);
    317 }
    318 
    319 /*
    320  * Encapsulate a packet of type family for the local net.
    321  * Use trailer local net encapsulation if enough data in first
    322  * packet leaves a multiple of 512 bytes of data in remainder.
    323  */
    324 static void
    325 snstart(ifp)
    326 	struct ifnet *ifp;
    327 {
    328 	struct sn_softc *sc = ifp->if_softc;
    329 	struct mbuf *m;
    330 	int	len;
    331 
    332 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
    333 		return;
    334 
    335 outloop:
    336 	/* Check for room in the xmit buffer. */
    337 	if (sc->txb_inuse == sc->txb_cnt) {
    338 		ifp->if_flags |= IFF_OACTIVE;
    339 		return;
    340 	}
    341 
    342 	IF_DEQUEUE(&ifp->if_snd, m);
    343 	if (m == 0)
    344 		return;
    345 
    346 	/* We need the header for m_pkthdr.len. */
    347 	if ((m->m_flags & M_PKTHDR) == 0)
    348 		panic("snstart: no header mbuf");
    349 
    350 #if NBPFILTER > 0
    351 	/*
    352 	 * If bpf is listening on this interface, let it
    353 	 * see the packet before we commit it to the wire.
    354 	 */
    355 	if (ifp->if_bpf)
    356 		bpf_mtap(ifp->if_bpf, m);
    357 #endif
    358 
    359 	/*
    360 	 * If there is nothing in the o/p queue, and there is room in
    361 	 * the Tx ring, then send the packet directly.  Otherwise append
    362 	 * it to the o/p queue.
    363 	 */
    364 	if ((len = sonicput(sc, m)) > 0) {
    365 		len = m->m_pkthdr.len;
    366 		m_freem(m);
    367 	} else {
    368 		IF_PREPEND(&ifp->if_snd, m);
    369 		return;
    370 	}
    371 
    372 	/* Point to next buffer slot and wrap if necessary. */
    373 	if (++sc->txb_new == sc->txb_cnt)
    374 		sc->txb_new = 0;
    375 
    376 	sc->txb_inuse++;
    377 
    378 	ifp->if_opackets++;		/* # of pkts */
    379 	sc->sc_sum.ls_opacks++;		/* # of pkts */
    380 
    381 	/* Jump back for possibly more punishment. */
    382 	goto outloop;
    383 }
    384 
    385 /*
    386  * This is called from sonicioctl() when /etc/ifconfig is run to set
    387  * the address or switch the i/f on.
    388  */
    389 void caminitialise __P((struct sn_softc *));
    390 void camentry __P((struct sn_softc *, int, unsigned char *ea));
    391 void camprogram __P((struct sn_softc *));
    392 void initialise_tda __P((struct sn_softc *));
    393 void initialise_rda __P((struct sn_softc *));
    394 void initialise_rra __P((struct sn_softc *));
    395 void initialise_tba __P((struct sn_softc *));
    396 
    397 /*
    398  * reset and restart the SONIC.  Called in case of fatal
    399  * hardware/software errors.
    400  */
    401 static void
    402 snreset(sc)
    403 	struct sn_softc *sc;
    404 {
    405 	printf("snreset\n");
    406 	snstop(sc);
    407 	sninit(sc);
    408 }
    409 
    410 static int
    411 sninit(sc)
    412 	struct sn_softc *sc;
    413 {
    414 	struct sonic_reg *csr = sc->sc_csr;
    415 	int s;
    416 
    417 	if (sc->sc_if.if_flags & IFF_RUNNING)
    418 		/* already running */
    419 		return (0);
    420 
    421 	s = splnet();
    422 
    423 	csr->s_cr = CR_RST;	/* s_dcr only accessable reset mode! */
    424 
    425 	/* config it */
    426 	csr->s_dcr = sc->s_dcr | (sc->bitmode ? DCR_DW32 : DCR_DW16);
    427 	csr->s_rcr = RCR_BRD | RCR_LBNONE;
    428 	csr->s_imr = IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN;
    429 
    430 	/* clear pending interrupts */
    431 	csr->s_isr = 0x7fff;
    432 
    433 	/* clear tally counters */
    434 	csr->s_crct = -1;
    435 	csr->s_faet = -1;
    436 	csr->s_mpt = -1;
    437 
    438 	initialise_tda(sc);
    439 	initialise_rda(sc);
    440 	initialise_rra(sc);
    441 	initialise_tba(sc);
    442 
    443 	/* enable the chip */
    444 	csr->s_cr = 0;
    445 	wbflush();
    446 
    447 	/* program the CAM with our address */
    448 	caminitialise(sc);
    449 	camentry(sc, 0, sc->sc_enaddr);
    450 	camprogram(sc);
    451 
    452 	/* get it to read resource descriptors */
    453 	csr->s_cr = CR_RRRA;
    454 	wbflush();
    455 	while (csr->s_cr & CR_RRRA)
    456 		continue;
    457 
    458 	/* enable rx */
    459 	csr->s_cr = CR_RXEN;
    460 	wbflush();
    461 
    462 	/* flag interface as "running" */
    463 	sc->sc_if.if_flags |= IFF_RUNNING;
    464 
    465 	splx(s);
    466 	return (0);
    467 }
    468 
    469 /*
    470  * close down an interface and free its buffers
    471  * Called on final close of device, or if sninit() fails
    472  * part way through.
    473  */
    474 static int
    475 snstop(sc)
    476 	struct sn_softc *sc;
    477 {
    478 	struct mtd *mtd;
    479 	int s = splnet();
    480 
    481 	/* stick chip in reset */
    482 	sc->sc_csr->s_cr = CR_RST;
    483 	wbflush();
    484 
    485 	/* free all receive buffers (currently static so nothing to do) */
    486 
    487 	/* free all pending transmit mbufs */
    488 	while (sc->mtd_hw != sc->mtd_free) {
    489 		mtd = &sc->mtda[sc->mtd_hw];
    490 		mtd->mtd_buf = 0;
    491 		if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0;
    492 	}
    493 	sc->txb_inuse = 0;
    494 
    495 	sc->sc_if.if_timer = 0;
    496 	sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_UP);
    497 
    498 	splx(s);
    499 	return (0);
    500 }
    501 
    502 /*
    503  * Called if any Tx packets remain unsent after 5 seconds,
    504  * In all cases we just reset the chip, and any retransmission
    505  * will be handled by higher level protocol timeouts.
    506  */
    507 static void
    508 snwatchdog(ifp)
    509 	struct ifnet *ifp;
    510 {
    511 	struct sn_softc *sc = ifp->if_softc;
    512 	struct mtd	*mtd;
    513 	int		temp;
    514 
    515 	if (sc->mtd_hw != sc->mtd_free) {
    516 		/* something still pending for transmit */
    517 		mtd = &sc->mtda[sc->mtd_hw];
    518 		if (SRO(sc->bitmode, mtd->mtd_txp, TXP_STATUS) == 0)
    519 			log(LOG_ERR, "%s: Tx - timeout\n",
    520 				sc->sc_dev.dv_xname);
    521 		else
    522 			log(LOG_ERR, "%s: Tx - lost interrupt\n",
    523 			   	 sc->sc_dev.dv_xname);
    524 		temp = ifp->if_flags & IFF_UP;
    525 		snreset(sc);
    526 		ifp->if_flags |= temp;
    527 	}
    528 }
    529 
    530 /*
    531  * stuff packet into sonic (at splnet)
    532  */
    533 static int
    534 sonicput(sc, m0)
    535 	struct sn_softc *sc;
    536 	struct mbuf *m0;
    537 {
    538 	struct sonic_reg	*csr = sc->sc_csr;
    539 	unsigned char		*buff, *buffer;
    540 	void			*txp;
    541 	struct mtd		*mtdp;
    542 	struct mbuf		*m;
    543 	unsigned int		len = 0;
    544 	unsigned int		totlen = 0;
    545 	int			mtd_free = sc->mtd_free;
    546 	int			mtd_next;
    547 	int			txb_new = sc->txb_new;
    548 
    549 	if (sc->sc_csr->s_cr & CR_TXP) {
    550 		return (0);
    551 	}
    552 
    553 	/* grab the replacement mtd */
    554 	mtdp = &sc->mtda[mtd_free];
    555 
    556 	if ((mtd_next = mtd_free + 1) == NTDA)
    557 		mtd_next = 0;
    558 
    559 	if (mtd_next == sc->mtd_hw) {
    560 		return (0);
    561 	}
    562 
    563 	/* We are guaranteed, if we get here, that the xmit buffer is free. */
    564 	buff = buffer = sc->tbuf[txb_new];
    565 
    566 	/* this packet goes to mtdnext fill in the TDA */
    567 	mtdp->mtd_buf = buffer;
    568 	txp = mtdp->mtd_txp;
    569 	SWO(sc->bitmode, txp, TXP_CONFIG, 0);
    570 
    571 	for (m = m0; m; m = m->m_next) {
    572 		unsigned char *data = mtod(m, u_char *);
    573 		len = m->m_len;
    574 		totlen += len;
    575 		bcopy(data, buff, len);
    576 		buff += len;
    577 	}
    578 	if (totlen >= TXBSIZE) {
    579 		panic("packet overflow in sonicput.");
    580 	}
    581 	SWO(sc->bitmode, txp, TXP_FRAGOFF+(0*TXP_FRAGSIZE)+TXP_FPTRLO,
    582 		LOWER(sc->vtbuf[txb_new]));
    583 	SWO(sc->bitmode, txp, TXP_FRAGOFF+(0*TXP_FRAGSIZE)+TXP_FPTRHI,
    584 		UPPER(sc->vtbuf[txb_new]));
    585 
    586 	if (totlen < ETHERMIN + sizeof(struct ether_header)) {
    587 		int pad = ETHERMIN + sizeof(struct ether_header) - totlen;
    588 		bzero(buffer + totlen, pad);
    589 		totlen = ETHERMIN + sizeof(struct ether_header);
    590 	}
    591 
    592 	SWO(sc->bitmode, txp, TXP_FRAGOFF+(0*TXP_FRAGSIZE)+TXP_FSIZE,
    593 		totlen);
    594 	SWO(sc->bitmode, txp, TXP_FRAGCNT, 1);
    595 	SWO(sc->bitmode, txp, TXP_PKTSIZE, totlen);
    596 
    597 	/* link onto the next mtd that will be used */
    598 	SWO(sc->bitmode, txp, TXP_FRAGOFF+(1*TXP_FRAGSIZE)+TXP_FPTRLO,
    599 		LOWER(sc->mtda[mtd_next].mtd_vtxp) | EOL);
    600 
    601 	/*
    602 	 * The previous txp.tlink currently contains a pointer to
    603 	 * our txp | EOL. Want to clear the EOL, so write our
    604 	 * pointer to the previous txp.
    605 	 */
    606 	SWO(sc->bitmode, sc->mtda[sc->mtd_prev].mtd_txp, sc->mtd_tlinko,
    607 		LOWER(mtdp->mtd_vtxp));
    608 
    609 	sc->mtd_prev = mtd_free;
    610 	sc->mtd_free = mtd_next;
    611 
    612 	/* make sure chip is running */
    613 	wbflush();
    614 	csr->s_cr = CR_TXP;
    615 	wbflush();
    616 	sc->sc_if.if_timer = 5;	/* 5 seconds to watch for failing to transmit */
    617 
    618 	return (totlen);
    619 }
    620 
    621 void sonictxint __P((struct sn_softc *));
    622 void sonicrxint __P((struct sn_softc *));
    623 
    624 int sonic_read __P((struct sn_softc *, caddr_t, int));
    625 struct mbuf *sonic_get __P((struct sn_softc *, struct ether_header *, int));
    626 
    627 /*
    628  * CAM support
    629  */
    630 void
    631 caminitialise(sc)
    632 	struct sn_softc *sc;
    633 {
    634 	int    	i;
    635 	void	*p_cda = sc->p_cda;
    636 	int	bitmode = sc->bitmode;
    637 
    638 	for (i = 0; i < MAXCAM; i++)
    639 		SWO(bitmode, p_cda, (CDA_CAMDESC * i + CDA_CAMEP), i);
    640 	SWO(bitmode, p_cda, CDA_ENABLE, 0);
    641 }
    642 
    643 void
    644 camentry(sc, entry, ea)
    645 	int entry;
    646 	unsigned char *ea;
    647 	struct sn_softc *sc;
    648 {
    649 	int	bitmode = sc->bitmode;
    650 	void	*p_cda = sc->p_cda;
    651 	int		camoffset = entry * CDA_CAMDESC;
    652 
    653 	SWO(bitmode, p_cda, camoffset + CDA_CAMEP, entry);
    654 	SWO(bitmode, p_cda, camoffset + CDA_CAMAP2, (ea[5] << 8) | ea[4]);
    655 	SWO(bitmode, p_cda, camoffset + CDA_CAMAP1, (ea[3] << 8) | ea[2]);
    656 	SWO(bitmode, p_cda, camoffset + CDA_CAMAP0, (ea[1] << 8) | ea[0]);
    657 	SWO(bitmode, p_cda, CDA_ENABLE, (1 << entry));
    658 }
    659 
    660 void
    661 camprogram(sc)
    662 	struct sn_softc *sc;
    663 {
    664 	struct sonic_reg *csr;
    665 	int     timeout;
    666 
    667 	csr = sc->sc_csr;
    668 	csr->s_cdp = LOWER(sc->v_cda);
    669 	csr->s_cdc = MAXCAM;
    670 	csr->s_cr = CR_LCAM;
    671 	wbflush();
    672 
    673 	timeout = 10000;
    674 	while (csr->s_cr & CR_LCAM && timeout--)
    675 		continue;
    676 	if (timeout == 0) {
    677 		/* XXX */
    678 		panic("sonic: CAM initialisation failed\n");
    679 	}
    680 	timeout = 10000;
    681 	while ((csr->s_isr & ISR_LCD) == 0 && timeout--)
    682 		continue;
    683 
    684 	if (csr->s_isr & ISR_LCD)
    685 		csr->s_isr = ISR_LCD;
    686 	else
    687 		printf("sonic: CAM initialisation without interrupt\n");
    688 }
    689 
    690 #if 0
    691 void
    692 camdump(sc)
    693 	struct sn_softc *sc;
    694 {
    695 	struct sonic_reg *csr = sc->sc_csr;
    696 	int i;
    697 
    698 	printf("CAM entries:\n");
    699 	csr->s_cr = CR_RST;
    700 	wbflush();
    701 
    702 	for (i = 0; i < 16; i++) {
    703 		ushort  ap2, ap1, ap0;
    704 		csr->s_cep = i;
    705 		wbflush();
    706 		ap2 = csr->s_cap2;
    707 		ap1 = csr->s_cap1;
    708 		ap0 = csr->s_cap0;
    709 		printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0);
    710 	}
    711 	printf("CAM enable 0x%lx\n", csr->s_cep);
    712 
    713 	csr->s_cr = 0;
    714 	wbflush();
    715 }
    716 #endif
    717 
    718 void
    719 initialise_tda(sc)
    720 	struct sn_softc *sc;
    721 {
    722 	struct sonic_reg *csr;
    723 	struct mtd *mtd;
    724 	int     i;
    725 
    726 	csr = sc->sc_csr;
    727 
    728 	for (i = 0; i < NTDA; i++) {
    729 		mtd = &sc->mtda[i];
    730 		mtd->mtd_buf = 0;
    731 	}
    732 
    733 	sc->mtd_hw = 0;
    734 	sc->mtd_prev = NTDA-1;
    735 	sc->mtd_free = 0;
    736 	sc->mtd_tlinko = TXP_FRAGOFF + 1*TXP_FRAGSIZE + TXP_FPTRLO;
    737 
    738 	csr->s_utda = UPPER(sc->mtda[0].mtd_vtxp);
    739 	csr->s_ctda = LOWER(sc->mtda[0].mtd_vtxp);
    740 }
    741 
    742 void
    743 initialise_rda(sc)
    744 	struct sn_softc *sc;
    745 {
    746 	struct sonic_reg *csr;
    747 	int	bitmode = sc->bitmode;
    748 	int     i;
    749 
    750 	csr = sc->sc_csr;
    751 
    752 	/* link the RDA's together into a circular list */
    753 	for (i = 0; i < (NRDA - 1); i++) {
    754 		SWO(bitmode, sc->p_rda[i], RXPKT_RLINK, LOWER(sc->v_rda[i+1]));
    755 		SWO(bitmode, sc->p_rda[i], RXPKT_INUSE, 1);
    756 	}
    757 	SWO(bitmode, sc->p_rda[NRDA - 1], RXPKT_RLINK, LOWER(sc->v_rda[0]) | EOL);
    758 	SWO(bitmode, sc->p_rda[NRDA - 1], RXPKT_INUSE, 1);
    759 
    760 	/* mark end of receive descriptor list */
    761 	sc->sc_rdamark = NRDA - 1;
    762 
    763 	sc->sc_rxmark = 0;
    764 
    765 	SWR(csr->s_urda, UPPER(sc->v_rda[0]));
    766 	SWR(csr->s_crda, LOWER(sc->v_rda[0]));
    767 	wbflush();
    768 }
    769 
    770 void
    771 initialise_rra(sc)
    772 	struct sn_softc *sc;
    773 {
    774 	struct sonic_reg *csr;
    775 	int     	i;
    776 	unsigned int	v;
    777 	int		bitmode = sc->bitmode;
    778 
    779 	csr = sc->sc_csr;
    780 
    781 	if (bitmode)
    782 		csr->s_eobc = RBASIZE(sc) / 2 - 2; /* must be >= MAXETHERPKT */
    783 	else
    784 		csr->s_eobc = RBASIZE(sc) / 2 - 1; /* must be >= MAXETHERPKT */
    785 	csr->s_urra = UPPER(sc->v_rra[0]);
    786 	csr->s_rsa = LOWER(sc->v_rra[0]);
    787 	/* rea must point just past the end of the rra space */
    788 	csr->s_rea = LOWER(sc->v_rea);
    789 	csr->s_rrp = LOWER(sc->v_rra[0]);
    790 
    791 	/* fill up SOME of the rra with buffers */
    792 	for (i = 0; i < NRBA; i++) {
    793 		v = kvtop(sc->rbuf[i]);
    794 		SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v));
    795 		SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v));
    796 		SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(RBASIZE(sc) / 2));
    797 		SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(RBASIZE(sc) / 2));
    798 	}
    799 	sc->sc_rramark = NRBA;
    800 	csr->s_rwp = LOWER(sc->v_rra[sc->sc_rramark]);
    801 	wbflush();
    802 }
    803 
    804 void
    805 initialise_tba(sc)
    806 	struct sn_softc *sc;
    807 {
    808 	sc->txb_cnt = NTXB;
    809 	sc->txb_inuse = 0;
    810 	sc->txb_new = 0;
    811 }
    812 
    813 static void
    814 snintr(arg, slot)
    815 	void	*arg;
    816 	int	slot;
    817 {
    818 	struct sn_softc	*sc = (struct sn_softc *)arg;
    819 	struct sonic_reg *csr = sc->sc_csr;
    820 	int	isr;
    821 
    822 	while ((isr = (csr->s_isr & ISR_ALL)) != 0) {
    823 		/* scrub the interrupts that we are going to service */
    824 		csr->s_isr = isr;
    825 		wbflush();
    826 
    827 		if (isr & (ISR_BR | ISR_LCD | ISR_PINT | ISR_TC))
    828 			printf("sonic: unexpected interrupt status 0x%x\n", isr);
    829 
    830 		if (isr & (ISR_TXDN | ISR_TXER))
    831 			sonictxint(sc);
    832 
    833 		if (isr & ISR_PKTRX)
    834 			sonicrxint(sc);
    835 
    836 		if (isr & (ISR_HBL | ISR_RDE | ISR_RBE | ISR_RBAE | ISR_RFO)) {
    837 			if (isr & ISR_HBL)
    838 				/*
    839 				 * The repeater is not providing a heartbeat.
    840 				 * In itself this isn't harmful, lots of the
    841 				 * cheap repeater hubs don't supply a heartbeat.
    842 				 * So ignore the lack of heartbeat. Its only
    843 				 * if we can't detect a carrier that we have a
    844 				 * problem.
    845 				 */
    846 			if (isr & ISR_RDE)
    847 				printf("sonic: receive descriptors exhausted\n");
    848 			if (isr & ISR_RBE)
    849 				printf("sonic: receive buffers exhausted\n");
    850 			if (isr & ISR_RBAE)
    851 				printf("sonic: receive buffer area exhausted\n");
    852 			if (isr & ISR_RFO)
    853 				printf("sonic: receive FIFO overrun\n");
    854 		}
    855 		if (isr & (ISR_CRC | ISR_FAE | ISR_MP)) {
    856 #ifdef notdef
    857 			if (isr & ISR_CRC)
    858 				sc->sc_crctally++;
    859 			if (isr & ISR_FAE)
    860 				sc->sc_faetally++;
    861 			if (isr & ISR_MP)
    862 				sc->sc_mptally++;
    863 #endif
    864 		}
    865 		snstart(&sc->sc_if);
    866 	}
    867 	return;
    868 }
    869 
    870 /*
    871  * Transmit interrupt routine
    872  */
    873 void
    874 sonictxint(sc)
    875 	struct sn_softc *sc;
    876 {
    877 	void		*txp;
    878 	struct sonic_reg *csr;
    879 	struct mtd	*mtd;
    880 	/* XXX DG make mtd_hw a local var */
    881 
    882 	if (sc->mtd_hw == sc->mtd_free)
    883 		return;
    884 
    885 	csr = sc->sc_csr;
    886 
    887 	while (sc->mtd_hw != sc->mtd_free) {
    888 		mtd = &sc->mtda[sc->mtd_hw];
    889 		if (mtd->mtd_buf == 0)
    890 			break;
    891 
    892 		txp = mtd->mtd_txp;
    893 
    894 		if (SRO(sc->bitmode, txp, TXP_STATUS) == 0)
    895 			return; /* it hasn't really gone yet */
    896 
    897 		if (ethdebug) {
    898 			struct ether_header *eh;
    899 
    900 			eh = (struct ether_header *) mtd->mtd_buf;
    901 			printf("xmit status=0x%x len=%d type=0x%x from %s",
    902 			    SRO(sc->bitmode, txp, TXP_STATUS),
    903 			    SRO(sc->bitmode, txp, TXP_PKTSIZE),
    904 			    htons(eh->ether_type),
    905 			    ether_sprintf(eh->ether_shost));
    906 			printf(" (to %s)\n", ether_sprintf(eh->ether_dhost));
    907 		}
    908 		sc->txb_inuse--;
    909 		mtd->mtd_buf = 0;
    910 		if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0;
    911 
    912 		/* XXX - Do stats here. */
    913 
    914 		if ((SRO(sc->bitmode, txp, TXP_STATUS) & TCR_PTX) == 0) {
    915 			printf("sonic: Tx packet status=0x%x\n",
    916 				SRO(sc->bitmode, txp, TXP_STATUS));
    917 
    918 			/* XXX - DG This looks bogus */
    919 			if (sc->mtd_hw != sc->mtd_free) {
    920 				printf("resubmitting remaining packets\n");
    921 				mtd = &sc->mtda[sc->mtd_hw];
    922 				csr->s_ctda = LOWER(mtd->mtd_vtxp);
    923 				csr->s_cr = CR_TXP;
    924 				wbflush();
    925 				return;
    926 			}
    927 		}
    928 	}
    929 }
    930 
    931 /*
    932  * Receive interrupt routine
    933  */
    934 void
    935 sonicrxint(sc)
    936 	struct sn_softc *sc;
    937 {
    938 	struct sonic_reg	*csr = sc->sc_csr;
    939 	void			*rda;
    940 	int     		orra;
    941 	int			len;
    942 	int			rramark;
    943 	int			rdamark;
    944 	int			bitmode = sc->bitmode;
    945 	void			*tmp1;
    946 	void			*tmp2;
    947 
    948 	rda = sc->p_rda[sc->sc_rxmark];
    949 
    950 	while (SRO(bitmode, rda, RXPKT_INUSE) == 0) {
    951 		unsigned status = SRO(bitmode, rda, RXPKT_STATUS);
    952 		if ((status & RCR_LPKT) == 0)
    953 			printf("sonic: more than one packet in RBA!\n");
    954 
    955 		orra = RBASEQ(SRO(bitmode, rda, RXPKT_SEQNO)) & RRAMASK;
    956 		len = SRO(bitmode, rda, RXPKT_BYTEC) -
    957 			sizeof(struct ether_header) - FCSSIZE;
    958 		if (status & RCR_PRX) {
    959 			if (sonic_read(sc, sc->rbuf[orra & RBAMASK], len)) {
    960 				sc->sc_if.if_ipackets++;
    961 				sc->sc_sum.ls_ipacks++;
    962 				sc->sc_missed = 0;
    963 			}
    964 		} else
    965 			sc->sc_if.if_ierrors++;
    966 
    967 		/*
    968 		 * give receive buffer area back to chip.
    969 		 *
    970 		 * orra is now empty of packets and can be freed if
    971 		 * sonic read didnt copy it out then we would have to
    972 		 * wait !!
    973 		 * (dont bother add it back in again straight away)
    974 		 *
    975 		 * Really, we're doing p_rra[rramark] = p_rra[orra] but
    976 		 * we have to use the macros because SONIC might be in
    977 		 * 16 or 32 bit mode.
    978 		 */
    979 		rramark = sc->sc_rramark;
    980 		tmp1 = sc->p_rra[rramark];
    981 		tmp2 = sc->p_rra[orra];
    982 		SWO(bitmode, tmp1, RXRSRC_PTRLO,
    983 			SRO(bitmode, tmp2, RXRSRC_PTRLO));
    984 		SWO(bitmode, tmp1, RXRSRC_PTRHI,
    985 			SRO(bitmode, tmp2, RXRSRC_PTRHI));
    986 		SWO(bitmode, tmp1, RXRSRC_WCLO,
    987 			SRO(bitmode, tmp2, RXRSRC_WCLO));
    988 		SWO(bitmode, tmp1, RXRSRC_WCHI,
    989 			SRO(bitmode, tmp2, RXRSRC_WCHI));
    990 
    991 		/* zap old rra for fun */
    992 		SWO(bitmode, tmp2, RXRSRC_WCHI, 0);
    993 		SWO(bitmode, tmp2, RXRSRC_WCLO, 0);
    994 
    995 		sc->sc_rramark = (++rramark) & RRAMASK;
    996 		csr->s_rwp = LOWER(sc->v_rra[rramark]);
    997 		wbflush();
    998 
    999 		/*
   1000 		 * give receive descriptor back to chip simple
   1001 		 * list is circular
   1002 		 */
   1003 		rdamark = sc->sc_rdamark;
   1004 		SWO(bitmode, rda, RXPKT_INUSE, 1);
   1005 		SWO(bitmode, rda, RXPKT_RLINK,
   1006 			SRO(bitmode, rda, RXPKT_RLINK) | EOL);
   1007 		SWO(bitmode, sc->p_rda[rdamark], RXPKT_RLINK,
   1008 			SRO(bitmode, sc->p_rda[rdamark], RXPKT_RLINK) & ~EOL);
   1009 		sc->sc_rdamark = sc->sc_rxmark;
   1010 
   1011 		if (++sc->sc_rxmark >= NRDA)
   1012 			sc->sc_rxmark = 0;
   1013 		rda = sc->p_rda[sc->sc_rxmark];
   1014 	}
   1015 }
   1016 
   1017 /*
   1018  * sonic_read -- pull packet off interface and forward to
   1019  * appropriate protocol handler
   1020  */
   1021 int
   1022 sonic_read(sc, pkt, len)
   1023 	struct sn_softc *sc;
   1024 	caddr_t pkt;
   1025 	int len;
   1026 {
   1027 	struct ifnet *ifp = &sc->sc_if;
   1028 	struct ether_header *et;
   1029 	struct mbuf *m;
   1030 
   1031 	/*
   1032          * Get pointer to ethernet header (in input buffer).
   1033          * Deal with trailer protocol: if type is PUP trailer
   1034          * get true type from first 16-bit word past data.
   1035          * Remember that type was trailer by setting off.
   1036          */
   1037 	et = (struct ether_header *)pkt;
   1038 
   1039 	if (ethdebug) {
   1040 		printf("rcvd 0x%p len=%d type=0x%x from %s",
   1041 		    et, len, htons(et->ether_type),
   1042 		    ether_sprintf(et->ether_shost));
   1043 		printf(" (to %s)\n", ether_sprintf(et->ether_dhost));
   1044 	}
   1045 	if (len < ETHERMIN || len > ETHERMTU) {
   1046 		printf("sonic: invalid packet length %d bytes\n", len);
   1047 		return (0);
   1048 	}
   1049 
   1050 #if NBPFILTER > 0
   1051 	/*
   1052 	 * Check if there's a bpf filter listening on this interface.
   1053 	 * If so, hand off the raw packet to enet, then discard things
   1054 	 * not destined for us (but be sure to keep broadcast/multicast).
   1055 	 */
   1056 	if (sc->sc_if.if_bpf) {
   1057 		bpf_tap(sc->sc_if.if_bpf, pkt,
   1058 		    len + sizeof(struct ether_header));
   1059 		if ((ifp->if_flags & IFF_PROMISC) != 0 &&
   1060 		    (et->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
   1061 		    bcmp(et->ether_dhost, sc->sc_enaddr,
   1062 			    sizeof(et->ether_dhost)) != 0)
   1063 			return (0);
   1064 	}
   1065 #endif
   1066 	m = sonic_get(sc, et, len);
   1067 	if (m == NULL)
   1068 		return (0);
   1069 	ether_input(ifp, et, m);
   1070 	return(1);
   1071 }
   1072 
   1073 #define sonicdataaddr(eh, off, type)       ((type)(((caddr_t)((eh)+1)+(off))))
   1074 
   1075 /*
   1076  * munge the received packet into an mbuf chain
   1077  * because we are using stupid buffer management this
   1078  * is slow.
   1079  */
   1080 struct mbuf *
   1081 sonic_get(sc, eh, datalen)
   1082 	struct sn_softc *sc;
   1083 	struct ether_header *eh;
   1084 	int datalen;
   1085 {
   1086 	struct mbuf *m;
   1087 	struct mbuf *top = 0, **mp = &top;
   1088 	int	len;
   1089 	char   *spkt = sonicdataaddr(eh, 0, caddr_t);
   1090 	char   *epkt = spkt + datalen;
   1091 	char *cp = spkt;
   1092 
   1093 	epkt = cp + datalen;
   1094 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1095 	if (m == 0)
   1096 		return (0);
   1097 	m->m_pkthdr.rcvif = &sc->sc_if;
   1098 	m->m_pkthdr.len = datalen;
   1099 	m->m_len = MHLEN;
   1100 
   1101 	while (datalen > 0) {
   1102 		if (top) {
   1103 			MGET(m, M_DONTWAIT, MT_DATA);
   1104 			if (m == 0) {
   1105 				m_freem(top);
   1106 				return (0);
   1107 			}
   1108 			m->m_len = MLEN;
   1109 		}
   1110 		len = min(datalen, epkt - cp);
   1111 		if (len >= MINCLSIZE) {
   1112 			MCLGET(m, M_DONTWAIT);
   1113 			if (m->m_flags & M_EXT)
   1114 				m->m_len = len = min(len, MCLBYTES);
   1115 			else
   1116 				len = m->m_len;
   1117 		} else {
   1118 			/*
   1119 		         * Place initial small packet/header at end of mbuf.
   1120 		         */
   1121 			if (len < m->m_len) {
   1122 				if (top == 0 && len + max_linkhdr <= m->m_len)
   1123 					m->m_data += max_linkhdr;
   1124 				m->m_len = len;
   1125 			} else
   1126 				len = m->m_len;
   1127 		}
   1128 		bcopy(cp, mtod(m, caddr_t), (unsigned) len);
   1129 		cp += len;
   1130 		*mp = m;
   1131 		mp = &m->m_next;
   1132 		datalen -= len;
   1133 		if (cp == epkt)
   1134 			cp = spkt;
   1135 	}
   1136 	return (top);
   1137 }
   1138