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