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