summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/mac68k/dev/if_sn.c318
-rw-r--r--sys/arch/mac68k/dev/if_sn_nubus.c34
-rw-r--r--sys/arch/mac68k/dev/if_sn_obio.c84
-rw-r--r--sys/arch/mac68k/dev/if_snreg.h134
-rw-r--r--sys/arch/mac68k/dev/if_snvar.h36
5 files changed, 368 insertions, 238 deletions
diff --git a/sys/arch/mac68k/dev/if_sn.c b/sys/arch/mac68k/dev/if_sn.c
index 718370a16a9..e54842cdde5 100644
--- a/sys/arch/mac68k/dev/if_sn.c
+++ b/sys/arch/mac68k/dev/if_sn.c
@@ -1,5 +1,5 @@
/* $NetBSD: if_sn.c,v 1.7 1997/03/20 17:47:51 scottr Exp $ */
-/* $OpenBSD: if_sn.c,v 1.16 1997/03/25 05:02:39 briggs Exp $ */
+/* $OpenBSD: if_sn.c,v 1.17 1997/03/29 23:26:48 briggs Exp $ */
/*
* National Semiconductor SONIC Driver
@@ -28,6 +28,7 @@
#include <sys/device.h>
#include <net/if.h>
+#include <net/if_dl.h>
#include <net/netisr.h>
#include <net/route.h>
@@ -57,23 +58,10 @@ typedef unsigned char uchar;
#include <mac68k/dev/if_snreg.h>
#include <mac68k/dev/if_snvar.h>
-#include "nubus.h"
-
-/*
- * Register access macros:
- * SWR is "Sonic Write Register"
- * SRD is "Sonic Read Register"
- */
-#define SWR(a, x) (a) = (x)
-#define SRD(a) ((a) & 0xffff)
-
-#define wbflush()
-
static void snwatchdog __P((struct ifnet *));
static int sninit __P((struct sn_softc *sc));
static int snstop __P((struct sn_softc *sc));
static int sonicput __P((struct sn_softc *sc, struct mbuf *m0));
-static void snintr __P((void *, int));
static int snioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data));
static void snstart __P((struct ifnet *ifp));
static void snreset __P((struct sn_softc *sc));
@@ -117,7 +105,7 @@ int ethdebug = 0;
* record. System will initialize the interface when it is ready
* to accept packets.
*/
-void
+int
snsetup(sc)
struct sn_softc *sc;
{
@@ -126,21 +114,30 @@ snsetup(sc)
unsigned char *pp;
int i;
- sc->sc_csr = (struct sonic_reg *) sc->sc_regh;
/*
- * Disable caching on the SONIC's data space.
+ * XXX if_sn.c is intended to be MI. Should it allocate memory
+ * for its descriptor areas, or expect the MD attach code
+ * to do that?
*/
- physaccess((caddr_t) sc->space, (caddr_t) kvtop((caddr_t) sc->space),
- sizeof(sc->space), PG_V | PG_RW | PG_CI);
+ sc->space = malloc((SN_NPAGES + 1) * NBPG, M_DEVBUF, M_WAITOK);
+ if (sc->space == NULL) {
+ printf ("%s: memory allocation for descriptors failed\n",
+ sc->sc_dev.dv_xname);
+ return (1);
+ }
/*
- * Put the pup in reset mode (sninit() will fix it later)
- * and clear any interrupts.
+ * Put the pup in reset mode (sninit() will fix it later),
+ * stop the timer, disable all interrupts and clear any interrupts.
*/
- sc->sc_csr->s_cr = CR_RST;
+ NIC_PUT(sc, SNR_CR, CR_RST);
+ wbflush();
+ NIC_PUT(sc, SNR_CR, CR_STP);
+ wbflush();
+ NIC_PUT(sc, SNR_IMR, 0);
wbflush();
- sc->sc_csr->s_isr = 0x7fff;
+ NIC_PUT(sc, SNR_ISR, ISR_ALL);
wbflush();
/*
@@ -148,10 +145,22 @@ snsetup(sc)
* a higher buffer address to a 16 bit offset--this will cause wrap
* around problems near the end of 64k !!
*/
- p = &sc->space[0];
+ p = sc->space;
pp = (unsigned char *)ROUNDUP ((int)p, NBPG);
p = pp;
+ /*
+ * Disable caching on the SONIC's data space.
+ * The pages might not be physically contiguous, so set
+ * each page individually.
+ */
+ for (i = 0; i < SN_NPAGES; i++) {
+ physaccess (p, (caddr_t) kvtop(p), NBPG,
+ PG_V | PG_RW | PG_CI);
+ p += NBPG;
+ }
+ p = pp;
+
for (i = 0; i < NRRA; i++) {
sc->p_rra[i] = (void *)p;
sc->v_rra[i] = kvtop(p);
@@ -185,14 +194,15 @@ snsetup(sc)
p = (unsigned char *)SOALIGN(sc, p);
if ((p - pp) > NBPG) {
- printf ("sn: sizeof RRA (%ld) + CDA (%ld) +"
+ printf ("%s: sizeof RRA (%ld) + CDA (%ld) +"
"RDA (%ld) + TDA (%ld) > NBPG (%d). Punt!\n",
+ sc->sc_dev.dv_xname,
(ulong)sc->p_cda - (ulong)sc->p_rra[0],
(ulong)sc->p_rda[0] - (ulong)sc->p_cda,
(ulong)sc->mtda[0].mtd_txp - (ulong)sc->p_rda[0],
(ulong)p - (ulong)sc->mtda[0].mtd_txp,
NBPG);
- return;
+ return(1);
}
p = pp + NBPG;
@@ -225,7 +235,8 @@ printf("sonic buffers: rra=%p cda=0x%x rda=0x%x tda=0x%x\n",
ifp->if_softc = sc;
ifp->if_ioctl = snioctl;
ifp->if_start = snstart;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_flags =
+ IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
ifp->if_watchdog = snwatchdog;
#if NBPFILTER > 0
bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
@@ -233,7 +244,7 @@ printf("sonic buffers: rra=%p cda=0x%x rda=0x%x tda=0x%x\n",
if_attach(ifp);
ether_ifattach(ifp);
- add_nubus_intr(sc->slotno, snintr, (void *) sc);
+ return (0);
}
static int
@@ -242,10 +253,10 @@ snioctl(ifp, cmd, data)
u_long cmd;
caddr_t data;
{
- struct ifaddr *ifa;
- struct sn_softc *sc = ifp->if_softc;
- int s = splnet(), err = 0;
- int temp;
+ struct ifaddr *ifa;
+ struct sn_softc *sc = ifp->if_softc;
+ int s = splnet(), err = 0;
+ int temp;
switch (cmd) {
@@ -317,8 +328,6 @@ snioctl(ifp, cmd, data)
/*
* Encapsulate a packet of type family for the local net.
- * Use trailer local net encapsulation if enough data in first
- * packet leaves a multiple of 512 bytes of data in remainder.
*/
static void
snstart(ifp)
@@ -385,13 +394,13 @@ outloop:
* This is called from sonicioctl() when /etc/ifconfig is run to set
* the address or switch the i/f on.
*/
-void caminitialise __P((struct sn_softc *));
-void camentry __P((struct sn_softc *, int, unsigned char *ea));
-void camprogram __P((struct sn_softc *));
-void initialise_tda __P((struct sn_softc *));
-void initialise_rda __P((struct sn_softc *));
-void initialise_rra __P((struct sn_softc *));
-void initialise_tba __P((struct sn_softc *));
+static void caminitialise __P((struct sn_softc *));
+static void camentry __P((struct sn_softc *, int, unsigned char *ea));
+static void camprogram __P((struct sn_softc *));
+static void initialise_tda __P((struct sn_softc *));
+static void initialise_rda __P((struct sn_softc *));
+static void initialise_rra __P((struct sn_softc *));
+static void initialise_tba __P((struct sn_softc *));
/*
* reset and restart the SONIC. Called in case of fatal
@@ -401,7 +410,6 @@ static void
snreset(sc)
struct sn_softc *sc;
{
- printf("snreset\n");
snstop(sc);
sninit(sc);
}
@@ -410,8 +418,8 @@ static int
sninit(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr = sc->sc_csr;
- int s;
+ int s;
+ unsigned long s_rcr;
if (sc->sc_if.if_flags & IFF_RUNNING)
/* already running */
@@ -419,20 +427,28 @@ sninit(sc)
s = splnet();
- csr->s_cr = CR_RST; /* s_dcr only accessable reset mode! */
+ NIC_PUT(sc, SNR_CR, CR_RST); /* DCR only accessable in reset mode! */
/* config it */
- csr->s_dcr = sc->s_dcr | (sc->bitmode ? DCR_DW32 : DCR_DW16);
- csr->s_rcr = RCR_BRD | RCR_LBNONE;
- csr->s_imr = IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN;
+ NIC_PUT(sc, SNR_DCR, sc->snr_dcr);
+ NIC_PUT(sc, SNR_DCR2, sc->snr_dcr2);
+
+ s_rcr = RCR_BRD | RCR_LBNONE;
+ if (sc->sc_if.if_flags & IFF_PROMISC)
+ s_rcr |= RCR_PRO;
+ if (sc->sc_if.if_flags & IFF_ALLMULTI)
+ s_rcr |= RCR_AMC;
+ NIC_PUT(sc, SNR_RCR, s_rcr);
+
+ NIC_PUT(sc, SNR_IMR, (IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN));
/* clear pending interrupts */
- csr->s_isr = 0x7fff;
+ NIC_PUT(sc, SNR_ISR, ISR_ALL);
/* clear tally counters */
- csr->s_crct = -1;
- csr->s_faet = -1;
- csr->s_mpt = -1;
+ NIC_PUT(sc, SNR_CRCT, -1);
+ NIC_PUT(sc, SNR_FAET, -1);
+ NIC_PUT(sc, SNR_MPT, -1);
initialise_tda(sc);
initialise_rda(sc);
@@ -440,22 +456,20 @@ sninit(sc)
initialise_tba(sc);
/* enable the chip */
- csr->s_cr = 0;
+ NIC_PUT(sc, SNR_CR, 0);
wbflush();
- /* program the CAM with our address */
- caminitialise(sc);
- camentry(sc, 0, sc->sc_enaddr);
+ /* program the CAM */
camprogram(sc);
/* get it to read resource descriptors */
- csr->s_cr = CR_RRRA;
+ NIC_PUT(sc, SNR_CR, CR_RRRA);
wbflush();
- while (csr->s_cr & CR_RRRA)
+ while ((NIC_GET(sc, SNR_CR)) & CR_RRRA)
continue;
/* enable rx */
- csr->s_cr = CR_RXEN;
+ NIC_PUT(sc, SNR_CR, CR_RXEN);
wbflush();
/* flag interface as "running" */
@@ -478,7 +492,7 @@ snstop(sc)
int s = splnet();
/* stick chip in reset */
- sc->sc_csr->s_cr = CR_RST;
+ NIC_PUT(sc, SNR_CR, CR_RST);
wbflush();
/* free all receive buffers (currently static so nothing to do) */
@@ -534,7 +548,6 @@ sonicput(sc, m0)
struct sn_softc *sc;
struct mbuf *m0;
{
- struct sonic_reg *csr = sc->sc_csr;
unsigned char *buff, *buffer;
void *txp;
struct mtd *mtdp;
@@ -545,7 +558,7 @@ sonicput(sc, m0)
int mtd_next;
int txb_new = sc->txb_new;
- if (sc->sc_csr->s_cr & CR_TXP) {
+ if (NIC_GET(sc, SNR_CR) & CR_TXP) {
return (0);
}
@@ -610,36 +623,42 @@ sonicput(sc, m0)
/* make sure chip is running */
wbflush();
- csr->s_cr = CR_TXP;
+ NIC_PUT(sc, SNR_CR, CR_TXP);
wbflush();
sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */
return (totlen);
}
-void sonictxint __P((struct sn_softc *));
-void sonicrxint __P((struct sn_softc *));
+static void sonictxint __P((struct sn_softc *));
+static void sonicrxint __P((struct sn_softc *));
-int sonic_read __P((struct sn_softc *, caddr_t, int));
-struct mbuf *sonic_get __P((struct sn_softc *, struct ether_header *, int));
+static int sonic_read __P((struct sn_softc *, caddr_t, int));
+static struct mbuf *sonic_get __P((struct sn_softc *, struct ether_header *, int));
/*
* CAM support
*/
-void
+static void
caminitialise(sc)
struct sn_softc *sc;
{
int i;
void *p_cda = sc->p_cda;
int bitmode = sc->bitmode;
-
- for (i = 0; i < MAXCAM; i++)
- SWO(bitmode, p_cda, (CDA_CAMDESC * i + CDA_CAMEP), i);
+ int camoffset;
+
+ for (i = 0; i < MAXCAM; i++) {
+ camoffset = i * CDA_CAMDESC;
+ SWO(bitmode, p_cda, (camoffset + CDA_CAMEP), i);
+ SWO(bitmode, p_cda, (camoffset + CDA_CAMAP2), 0);
+ SWO(bitmode, p_cda, (camoffset + CDA_CAMAP1), 0);
+ SWO(bitmode, p_cda, (camoffset + CDA_CAMAP0), 0);
+ }
SWO(bitmode, p_cda, CDA_ENABLE, 0);
}
-void
+static void
camentry(sc, entry, ea)
int entry;
unsigned char *ea;
@@ -647,30 +666,73 @@ camentry(sc, entry, ea)
{
int bitmode = sc->bitmode;
void *p_cda = sc->p_cda;
- int camoffset = entry * CDA_CAMDESC;
+ int camoffset = entry * CDA_CAMDESC;
SWO(bitmode, p_cda, camoffset + CDA_CAMEP, entry);
SWO(bitmode, p_cda, camoffset + CDA_CAMAP2, (ea[5] << 8) | ea[4]);
SWO(bitmode, p_cda, camoffset + CDA_CAMAP1, (ea[3] << 8) | ea[2]);
SWO(bitmode, p_cda, camoffset + CDA_CAMAP0, (ea[1] << 8) | ea[0]);
- SWO(bitmode, p_cda, CDA_ENABLE, (1 << entry));
+ SWO(bitmode, p_cda, CDA_ENABLE,
+ (SRO(bitmode, p_cda, CDA_ENABLE) | (1 << entry)));
}
-void
+static void
camprogram(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr;
- int timeout;
+ int timeout;
+ int mcount = 0;
+ struct ether_multi *enm;
+ struct ether_multistep step;
+ struct ifnet *ifp;
- csr = sc->sc_csr;
- csr->s_cdp = LOWER(sc->v_cda);
- csr->s_cdc = MAXCAM;
- csr->s_cr = CR_LCAM;
+ caminitialise(sc);
+
+ ifp = &sc->sc_if;
+
+ /* Always load our own address first. */
+ camentry (sc, 0, sc->sc_enaddr);
+ mcount++;
+
+ /* Assume we won't need allmulti bit. */
+ ifp->if_flags &= ~IFF_ALLMULTI;
+
+ mcount++;
+ /* Loop through multicast addresses */
+ ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
+ while (enm != NULL) {
+ if (mcount == MAXCAM) {
+ ifp->if_flags |= IFF_ALLMULTI;
+ break;
+ }
+
+ if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
+ sizeof(enm->enm_addrlo)) != 0) {
+ /*
+ * SONIC's CAM is programmed with specific
+ * addresses. It has no way to specify a range.
+ * (Well, thats not exactly true. If the
+ * range is small one could program each addr
+ * within the range as a seperate CAM entry)
+ */
+ ifp->if_flags |= IFF_ALLMULTI;
+ break;
+ }
+
+ /* program the CAM with the specified entry */
+ camentry(sc, mcount, enm->enm_addrlo);
+ mcount++;
+
+ ETHER_NEXT_MULTI(step, enm);
+ }
+
+ NIC_PUT(sc, SNR_CDP, LOWER(sc->v_cda));
+ NIC_PUT(sc, SNR_CDC, MAXCAM);
+ NIC_PUT(sc, SNR_CR, CR_LCAM);
wbflush();
timeout = 10000;
- while (csr->s_cr & CR_LCAM && timeout--)
+ while ((NIC_GET(sc, SNR_CR) & CR_LCAM) && timeout--)
continue;
if (timeout == 0) {
/* XXX */
@@ -678,54 +740,50 @@ camprogram(sc)
sc->sc_dev.dv_xname);
}
timeout = 10000;
- while ((csr->s_isr & ISR_LCD) == 0 && timeout--)
+ while (((NIC_GET(sc, SNR_ISR) & ISR_LCD) == 0) && timeout--)
continue;
- if (csr->s_isr & ISR_LCD)
- csr->s_isr = ISR_LCD;
+ if (NIC_GET(sc, SNR_ISR) & ISR_LCD)
+ NIC_PUT(sc, SNR_ISR, ISR_LCD);
else
printf("%s: CAM initialisation without interrupt\n",
sc->sc_dev.dv_xname);
}
#if 0
-void
+static void
camdump(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr = sc->sc_csr;
int i;
printf("CAM entries:\n");
- csr->s_cr = CR_RST;
+ NIC_PUT(sc, SNR_CR, CR_RST);
wbflush();
for (i = 0; i < 16; i++) {
ushort ap2, ap1, ap0;
- csr->s_cep = i;
+ NIC_PUT(sc, SNR_CEP, i);
wbflush();
- ap2 = csr->s_cap2;
- ap1 = csr->s_cap1;
- ap0 = csr->s_cap0;
+ ap2 = NIC_GET(sc, SNR_CAP2);
+ ap1 = NIC_GET(sc, SNR_CAP1);
+ ap0 = NIC_GET(sc, SNR_CAP0);
printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0);
}
- printf("CAM enable 0x%lx\n", csr->s_cep);
+ printf("CAM enable 0x%x\n", NIC_GET(sc, SNR_CE));
- csr->s_cr = 0;
+ NIC_PUT(sc, SNR_CR, 0);
wbflush();
}
#endif
-void
+static void
initialise_tda(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr;
struct mtd *mtd;
int i;
- csr = sc->sc_csr;
-
for (i = 0; i < NTDA; i++) {
mtd = &sc->mtda[i];
mtd->mtd_buf = 0;
@@ -736,20 +794,17 @@ initialise_tda(sc)
sc->mtd_free = 0;
sc->mtd_tlinko = TXP_FRAGOFF + 1*TXP_FRAGSIZE + TXP_FPTRLO;
- csr->s_utda = UPPER(sc->mtda[0].mtd_vtxp);
- csr->s_ctda = LOWER(sc->mtda[0].mtd_vtxp);
+ NIC_PUT(sc, SNR_UTDA, UPPER(sc->mtda[0].mtd_vtxp));
+ NIC_PUT(sc, SNR_CTDA, LOWER(sc->mtda[0].mtd_vtxp));
}
-void
+static void
initialise_rda(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr;
int bitmode = sc->bitmode;
int i;
- csr = sc->sc_csr;
-
/* link the RDA's together into a circular list */
for (i = 0; i < (NRDA - 1); i++) {
SWO(bitmode, sc->p_rda[i], RXPKT_RLINK, LOWER(sc->v_rda[i+1]));
@@ -763,31 +818,28 @@ initialise_rda(sc)
sc->sc_rxmark = 0;
- SWR(csr->s_urda, UPPER(sc->v_rda[0]));
- SWR(csr->s_crda, LOWER(sc->v_rda[0]));
+ NIC_PUT(sc, SNR_URDA, UPPER(sc->v_rda[0]));
+ NIC_PUT(sc, SNR_CRDA, LOWER(sc->v_rda[0]));
wbflush();
}
-void
+static void
initialise_rra(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr;
int i;
unsigned int v;
int bitmode = sc->bitmode;
- csr = sc->sc_csr;
-
- if (bitmode)
- csr->s_eobc = RBASIZE(sc) / 2 - 2; /* must be >= MAXETHERPKT */
+ if (bitmode) /* eobc must be >= MAXETHERPKT */
+ NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 2);
else
- csr->s_eobc = RBASIZE(sc) / 2 - 1; /* must be >= MAXETHERPKT */
- csr->s_urra = UPPER(sc->v_rra[0]);
- csr->s_rsa = LOWER(sc->v_rra[0]);
+ NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 1);
+ NIC_PUT(sc, SNR_URRA, UPPER(sc->v_rra[0]));
+ NIC_PUT(sc, SNR_RSA, LOWER(sc->v_rra[0]));
/* rea must point just past the end of the rra space */
- csr->s_rea = LOWER(sc->v_rea);
- csr->s_rrp = LOWER(sc->v_rra[0]);
+ NIC_PUT(sc, SNR_REA, LOWER(sc->v_rea));
+ NIC_PUT(sc, SNR_RRP, LOWER(sc->v_rra[0]));
/* fill up SOME of the rra with buffers */
for (i = 0; i < NRBA; i++) {
@@ -798,11 +850,11 @@ initialise_rra(sc)
SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(RBASIZE(sc) / 2));
}
sc->sc_rramark = NRBA;
- csr->s_rwp = LOWER(sc->v_rra[sc->sc_rramark]);
+ NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[sc->sc_rramark]));
wbflush();
}
-void
+static void
initialise_tba(sc)
struct sn_softc *sc;
{
@@ -811,18 +863,17 @@ initialise_tba(sc)
sc->txb_new = 0;
}
-static void
+void
snintr(arg, slot)
void *arg;
int slot;
{
struct sn_softc *sc = (struct sn_softc *)arg;
- struct sonic_reg *csr = sc->sc_csr;
int isr;
- while ((isr = (csr->s_isr & ISR_ALL)) != 0) {
+ while ((isr = (NIC_GET(sc, SNR_ISR) & ISR_ALL)) != 0) {
/* scrub the interrupts that we are going to service */
- csr->s_isr = isr;
+ NIC_PUT(sc, SNR_ISR, isr);
wbflush();
if (isr & (ISR_BR | ISR_LCD | ISR_PINT | ISR_TC))
@@ -877,20 +928,17 @@ snintr(arg, slot)
/*
* Transmit interrupt routine
*/
-void
+static void
sonictxint(sc)
struct sn_softc *sc;
{
void *txp;
- struct sonic_reg *csr;
struct mtd *mtd;
/* XXX DG make mtd_hw a local var */
if (sc->mtd_hw == sc->mtd_free)
return;
- csr = sc->sc_csr;
-
while (sc->mtd_hw != sc->mtd_free) {
mtd = &sc->mtda[sc->mtd_hw];
if (mtd->mtd_buf == 0)
@@ -927,8 +975,8 @@ sonictxint(sc)
if (sc->mtd_hw != sc->mtd_free) {
printf("resubmitting remaining packets\n");
mtd = &sc->mtda[sc->mtd_hw];
- csr->s_ctda = LOWER(mtd->mtd_vtxp);
- csr->s_cr = CR_TXP;
+ NIC_PUT(sc, SNR_CTDA, LOWER(mtd->mtd_vtxp));
+ NIC_PUT(sc, SNR_CR, CR_TXP);
wbflush();
return;
}
@@ -939,11 +987,10 @@ sonictxint(sc)
/*
* Receive interrupt routine
*/
-void
+static void
sonicrxint(sc)
struct sn_softc *sc;
{
- struct sonic_reg *csr = sc->sc_csr;
void *rda;
int orra;
int len;
@@ -1002,7 +1049,7 @@ sonicrxint(sc)
SWO(bitmode, tmp2, RXRSRC_WCLO, 0);
sc->sc_rramark = (++rramark) & RRAMASK;
- csr->s_rwp = LOWER(sc->v_rra[rramark]);
+ NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[rramark]));
wbflush();
/*
@@ -1027,7 +1074,7 @@ sonicrxint(sc)
* sonic_read -- pull packet off interface and forward to
* appropriate protocol handler
*/
-int
+static int
sonic_read(sc, pkt, len)
struct sn_softc *sc;
caddr_t pkt;
@@ -1039,9 +1086,6 @@ sonic_read(sc, pkt, len)
/*
* Get pointer to ethernet header (in input buffer).
- * Deal with trailer protocol: if type is PUP trailer
- * get true type from first 16-bit word past data.
- * Remember that type was trailer by setting off.
*/
et = (struct ether_header *)pkt;
@@ -1087,7 +1131,7 @@ sonic_read(sc, pkt, len)
* because we are using stupid buffer management this
* is slow.
*/
-struct mbuf *
+static struct mbuf *
sonic_get(sc, eh, datalen)
struct sn_softc *sc;
struct ether_header *eh;
diff --git a/sys/arch/mac68k/dev/if_sn_nubus.c b/sys/arch/mac68k/dev/if_sn_nubus.c
index 745309a3b25..977d14ce759 100644
--- a/sys/arch/mac68k/dev/if_sn_nubus.c
+++ b/sys/arch/mac68k/dev/if_sn_nubus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sn_nubus.c,v 1.3 1997/03/17 04:16:59 briggs Exp $ */
+/* $OpenBSD: if_sn_nubus.c,v 1.4 1997/03/29 23:26:49 briggs Exp $ */
/*
* Copyright (C) 1997 Allen Briggs
@@ -124,8 +124,9 @@ sn_nubus_attach(parent, self, aux)
switch (sn_nb_card_vendor(na)) {
case AE_VENDOR_DAYNA:
- sc->s_dcr = DCR_ASYNC | DCR_WAIT0 | DCR_USR1 |
- DCR_DW32 | DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
+ sc->snr_dcr = DCR_ASYNC | DCR_WAIT0 | DCR_DW32 |
+ DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
+ sc->snr_dcr2 = 0;
if (bus_space_subregion(bst, bsh, 0x00180000, SN_REGSIZE,
&sc->sc_regh)) {
@@ -141,6 +142,11 @@ sn_nubus_attach(parent, self, aux)
/*
* Copy out the ethernet address from the card's ROM
+ *
+ * See if_sn_obio.c for a discussion of bit reversal
+ * in Apple's MAC address PROMs. As far as I can tell
+ * Dayna stores their Mac address in ethernet format,
+ * not Token Ring.
*/
for (i = 0; i < ETHER_ADDR_LEN; ++i)
sc->sc_arpcom.ac_enaddr[i] =
@@ -156,8 +162,9 @@ sn_nubus_attach(parent, self, aux)
* for a new card, the following defaults are a
* good starting point.
*/
- sc->s_dcr = DCR_LBR | DCR_SYNC | DCR_WAIT0 |
- DCR_DW32 | DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
+ sc->snr_dcr = DCR_SYNC | DCR_WAIT0 | DCR_DW32 |
+ DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
+ sc->snr_dcr2 = 0;
return;
}
@@ -167,6 +174,20 @@ sn_nubus_attach(parent, self, aux)
}
snsetup(sc);
+ /* Regs are addressed as words, big endian. */
+ for (i = 0; i < SN_NREGS; i++) {
+ sc->sc_reg_map[i] = (bus_size_t)((i * 4) + 2);
+ }
+
+ /* snsetup returns 1 if something fails */
+ if (snsetup(sc)) {
+ bus_space_unmap(bst, bsh, NBMEMSIZE);
+ return;
+ }
+
+ add_nubus_intr(sc->slotno, snintr, (void *)sc);
+
+ return;
}
static int
@@ -205,6 +226,9 @@ sn_nb_card_vendor(na)
break;
}
break;
+ case NUBUS_DRSW_DAYNA:
+ vendor = AE_VENDOR_DAYNA;
+ break;
default:
#ifdef DIAGNOSTIC
printf("Unknown ethernet drsw: %x\n", na->drsw);
diff --git a/sys/arch/mac68k/dev/if_sn_obio.c b/sys/arch/mac68k/dev/if_sn_obio.c
index 358c53415bf..831209f4868 100644
--- a/sys/arch/mac68k/dev/if_sn_obio.c
+++ b/sys/arch/mac68k/dev/if_sn_obio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sn_obio.c,v 1.4 1997/03/29 02:27:11 briggs Exp $ */
+/* $OpenBSD: if_sn_obio.c,v 1.5 1997/03/29 23:26:49 briggs Exp $ */
/*
* Copyright (C) 1997 Allen Briggs
@@ -84,25 +84,33 @@ sn_obio_attach(parent, self, aux)
{
struct obio_attach_args *oa = (struct obio_attach_args *) aux;
struct sn_softc *sc = (void *)self;
+ int i;
- sc->s_dcr = DCR_LBR | DCR_SYNC | DCR_WAIT0 |
- DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
+ sc->snr_dcr = DCR_SYNC | DCR_WAIT0 | DCR_DMABLOCK |
+ DCR_RFT16 | DCR_TFT16;
+ sc->snr_dcr2 = 0;
- switch (current_mac_model->class) {
- case MACH_CLASSQ:
- case MACH_CLASSQ2:
- sc->s_dcr |= DCR_DW32;
+ switch (current_mac_model->machineid) {
+ case MACH_MACQ700: /* only tested on Q700 */
+ case MACH_MACQ900:
+ case MACH_MACQ950:
+ sc->snr_dcr |= DCR_LBR | DCR_DW32;
sc->bitmode = 1;
- break;
-
- case MACH_CLASSPB:
- sc->s_dcr |= DCR_DW16;
- sc->bitmode = 0;
- break;
+ break;
+
+ case MACH_MACQ800:
+ case MACH_MACQ650:
+ case MACH_MACC650:
+ case MACH_MACC610:
+ case MACH_MACQ610:
+ sc->snr_dcr |= DCR_EXBUS | DCR_DW32;
+ sc->bitmode = 1;
+ break;
- default:
- printf("unsupported machine type\n");
- return;
+ case MACH_MACPB500:
+ sc->snr_dcr |= DCR_LBR | DCR_DW16;
+ sc->bitmode = 0;
+ break;
}
sc->sc_regt = oa->oa_tag;
@@ -115,7 +123,18 @@ sn_obio_attach(parent, self, aux)
sn_obio_getaddr(sc);
- snsetup(sc);
+ /* regs are addressed as words, big-endian. */
+ for (i = 0; i < SN_NREGS; i++) {
+ sc->sc_reg_map[i] = (bus_size_t)((i * 4) + 2);
+ }
+
+ /* snsetup returns 1 if something fails */
+ if (snsetup(sc)) {
+ bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
+ return;
+ }
+
+ add_nubus_intr(sc->slotno, snintr, (void *)sc);
}
static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
@@ -134,9 +153,34 @@ sn_obio_getaddr(sc)
}
/*
- * Apparently Apple goofed here. The ethernet MAC address is
- * stored in bit-byte-reversed format. It is rumored that this
- * is only true for some systems.
+ * For reasons known only to Apple, MAC addresses in the ethernet
+ * PROM are stored in Token Ring (IEEE 802.5) format, that is
+ * with all of the bits in each byte reversed (canonical bit format).
+ * When the address is read out it must be reversed to ethernet format
+ * before use.
+ *
+ * Apple has been assigned OUI's 00:08:07 and 00:a0:40. All onboard
+ * ethernet addresses on 68K machines should be in one of these
+ * two ranges.
+ *
+ * Here is where it gets complicated.
+ *
+ * The PMac 7200, 7500, 8500, and 9500 accidentally had the PROM
+ * written in standard ethernet format. The MacOS accounted for this
+ * in these systems, and did not reverse the bytes. Some other
+ * networking utilities were not so forgiving, and got confused.
+ * "Some" of Apple's Nubus ethernet cards also had their bits
+ * burned in ethernet format.
+ *
+ * Apple petitioned the IEEE and was granted the 00:05:02 (bit reversal
+ * of 00:a0:40) as well. As of OpenTransport 1.1.1, Apple removed
+ * their workaround and now reverses the bits regardless of
+ * what kind of machine it is. So PMac systems and the affected
+ * Nubus cards now use 00:05:02, instead of the 00:a0:40 for which they
+ * were intended.
+ *
+ * See Apple Techinfo article TECHINFO-0020552, "OpenTransport 1.1.1
+ * and MacOS System 7.5.3 FAQ (10/96)" for more details.
*/
do_bbr = 0;
b = bus_space_read_1(sc->sc_regt, bsh, 0);
diff --git a/sys/arch/mac68k/dev/if_snreg.h b/sys/arch/mac68k/dev/if_snreg.h
index 3f480d08dfe..8fd0a819e02 100644
--- a/sys/arch/mac68k/dev/if_snreg.h
+++ b/sys/arch/mac68k/dev/if_snreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_snreg.h,v 1.1 1997/03/12 13:20:33 briggs Exp $ */
+/* $OpenBSD: if_snreg.h,v 1.2 1997/03/29 23:26:50 briggs Exp $ */
/*
* Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk)
@@ -13,74 +13,72 @@
/*
* SONIC registers as seen by the processor
*/
-struct sonic_reg {
- volatile u_long s_cr; /* 00: Command */
- volatile u_long s_dcr; /* 01: Data Configuration */
- volatile u_long s_rcr; /* 02: Receive Control */
- volatile u_long s_tcr; /* 03: Transmit Control */
- volatile u_long s_imr; /* 04: Interrupt Mask */
- volatile u_long s_isr; /* 05: Interrupt Status */
- volatile u_long s_utda; /* 06: Upper Transmit Descriptor Address */
- volatile u_long s_ctda; /* 07: Current Transmit Descriptor Address */
- volatile u_long _s_tps; /* 08* Transmit Packet Size */
- volatile u_long _s_tfc; /* 09* Transmit Fragment Count */
- volatile u_long _s_tsa0; /* 0a* Transmit Start Address 0 */
- volatile u_long _s_tsa1; /* 0b* Transmit Start Address 1 */
- volatile u_long _s_tfs; /* 0c* Transmit Fragment Size */
- volatile u_long s_urda; /* 0d: Upper Receive Descriptor Address */
- volatile u_long s_crda; /* 0e: Current Receive Descriptor Address */
- volatile u_long _s_crba0; /* 0f* Current Receive Buffer Address 0 */
- volatile u_long _s_crba1; /* 10* Current Receive Buffer Address 1 */
- volatile u_long _s_rbwc0; /* 11* Remaining Buffer Word Count 0 */
- volatile u_long _s_rbwc1; /* 12* Remaining Buffer Word Count 1 */
- volatile u_long s_eobc; /* 13: End Of Buffer Word Count */
- volatile u_long s_urra; /* 14: Upper Receive Resource Address */
- volatile u_long s_rsa; /* 15: Resource Start Address */
- volatile u_long s_rea; /* 16: Resource End Address */
- volatile u_long s_rrp; /* 17: Resource Read Pointer */
- volatile u_long s_rwp; /* 18: Resource Write Pointer */
- volatile u_long _s_trba0; /* 19* Temporary Receive Buffer Address 0 */
- volatile u_long _s_trba1; /* 1a* Temporary Receive Buffer Address 1 */
- volatile u_long _s_tbwc0; /* 1b* Temporary Buffer Word Count 0 */
- volatile u_long _s_tbwc1; /* 1c* Temporary Buffer Word Count 1 */
- volatile u_long _s_addr0; /* 1d* Address Generator 0 */
- volatile u_long _s_addr1; /* 1e* Address Generator 1 */
- volatile u_long _s_llfa; /* 1f* Last Link Field Address */
- volatile u_long _s_ttda; /* 20* Temp Transmit Descriptor Address */
- volatile u_long s_cep; /* 21: CAM Entry Pointer */
- volatile u_long s_cap2; /* 22: CAM Address Port 2 */
- volatile u_long s_cap1; /* 23: CAM Address Port 1 */
- volatile u_long s_cap0; /* 24: CAM Address Port 0 */
- volatile u_long s_ce; /* 25: CAM Enable */
- volatile u_long s_cdp; /* 26: CAM Descriptor Pointer */
- volatile u_long s_cdc; /* 27: CAM Descriptor Count */
- volatile u_long s_sr; /* 28: Silicon Revision */
- volatile u_long s_wt0; /* 29: Watchdog Timer 0 */
- volatile u_long s_wt1; /* 2a: Watchdog Timer 1 */
- volatile u_long s_rsc; /* 2b: Receive Sequence Counter */
- volatile u_long s_crct; /* 2c: CRC Error Tally */
- volatile u_long s_faet; /* 2d: FAE Tally */
- volatile u_long s_mpt; /* 2e: Missed Packet Tally */
- volatile u_long _s_mdt; /* 2f* Maximum Deferral Timer */
- volatile u_long _s_rtc; /* 30* Receive Test Control */
- volatile u_long _s_ttc; /* 31* Transmit Test Control */
- volatile u_long _s_dtc; /* 32* DMA Test Control */
- volatile u_long _s_cc0; /* 33* CAM Comparison 0 */
- volatile u_long _s_cc1; /* 34* CAM Comparison 1 */
- volatile u_long _s_cc2; /* 35* CAM Comparison 2 */
- volatile u_long _s_cm; /* 36* CAM Match */
- volatile u_long :32; /* 37* reserved */
- volatile u_long :32; /* 38* reserved */
- volatile u_long _s_rbc; /* 39* Receiver Byte Count */
- volatile u_long :32; /* 3a* reserved */
- volatile u_long _s_tbo; /* 3b* Transmitter Backoff Counter */
- volatile u_long _s_trc; /* 3c* Transmitter Random Counter */
- volatile u_long _s_tbm; /* 3d* Transmitter Backoff Mask */
- volatile u_long :32; /* 3e* Reserved */
- volatile u_long s_dcr2; /* 3f Data Configuration 2 (AVF) */
-};
+#define SNR_CR 0x00 /* Command */
+#define SNR_DCR 0x01 /* Data Configuration */
+#define SNR_RCR 0x02 /* Receive Control */
+#define SNR_TCR 0x03 /* Transmit Control */
+#define SNR_IMR 0x04 /* Interrupt Mask */
+#define SNR_ISR 0x05 /* Interrupt Status */
+#define SNR_UTDA 0x06 /* Upper Transmit Descriptor Address */
+#define SNR_CTDA 0x07 /* Current Transmit Descriptor Address */
+#define SNR_TPS 0x08 /* Transmit Packet Size */
+#define SNR_TFC 0x09 /* Transmit Fragment Count */
+#define SNR_TSA0 0x0a /* Transmit Start Address 0 */
+#define SNR_TSA1 0x0b /* Transmit Start Address 1 */
+#define SNR_TFS 0x0c /* Transmit Fragment Size */
+#define SNR_URDA 0x0d /* Upper Receive Descriptor Address */
+#define SNR_CRDA 0x0e /* Current Receive Descriptor Address */
+#define SNR_CRBA0 0x0f /* Current Receive Buffer Address 0 */
+#define SNR_CRBA1 0x10 /* Current Receive Buffer Address 1 */
+#define SNR_RBWC0 0x11 /* Remaining Buffer Word Count 0 */
+#define SNR_RBWC1 0x12 /* Remaining Buffer Word Count 1 */
+#define SNR_EOBC 0x13 /* End Of Buffer Word Count */
+#define SNR_URRA 0x14 /* Upper Receive Resource Address */
+#define SNR_RSA 0x15 /* Resource Start Address */
+#define SNR_REA 0x16 /* Resource End Address */
+#define SNR_RRP 0x17 /* Resource Read Pointer */
+#define SNR_RWP 0x18 /* Resource Write Pointer */
+#define SNR_TRBA0 0x19 /* Temporary Receive Buffer Address 0 */
+#define SNR_TRBA1 0x1a /* Temporary Receive Buffer Address 1 */
+#define SNR_TBWC0 0x1b /* Temporary Buffer Word Count 0 */
+#define SNR_TBWC1 0x1c /* Temporary Buffer Word Count 1 */
+#define SNR_ADDR0 0x1d /* Address Generator 0 */
+#define SNR_ADDR1 0x1e /* Address Generator 1 */
+#define SNR_LLFA 0x1f /* Last Link Field Address */
+#define SNR_TTDA 0x20 /* Temp Transmit Descriptor Address */
+#define SNR_CEP 0x21 /* CAM Entry Pointer */
+#define SNR_CAP2 0x22 /* CAM Address Port 2 */
+#define SNR_CAP1 0x23 /* CAM Address Port 1 */
+#define SNR_CAP0 0x24 /* CAM Address Port 0 */
+#define SNR_CE 0x25 /* CAM Enable */
+#define SNR_CDP 0x26 /* CAM Descriptor Pointer */
+#define SNR_CDC 0x27 /* CAM Descriptor Count */
+#define SNR_SR 0x28 /* Silicon Revision */
+#define SNR_WT0 0x29 /* Watchdog Timer 0 */
+#define SNR_WT1 0x2a /* Watchdog Timer 1 */
+#define SNR_RSC 0x2b /* Receive Sequence Counter */
+#define SNR_CRCT 0x2c /* CRC Error Tally */
+#define SNR_FAET 0x2d /* FAE Tally */
+#define SNR_MPT 0x2e /* Missed Packet Tally */
+#define SNR_MDT 0x2f /* Maximum Deferral Timer */
+#define SNR_RTC 0x30 /* Receive Test Control */
+#define SNR_TTC 0x31 /* Transmit Test Control */
+#define SNR_DTC 0x32 /* DMA Test Control */
+#define SNR_CC0 0x33 /* CAM Comparison 0 */
+#define SNR_CC1 0x34 /* CAM Comparison 1 */
+#define SNR_CC2 0x35 /* CAM Comparison 2 */
+#define SNR_CM 0x36 /* CAM Match */
+#define SNR_RES1 0x37 /* reserved */
+#define SNR_RES2 0x38 /* reserved */
+#define SNR_RBC 0x39 /* Receiver Byte Count */
+#define SNR_RES3 0x3a /* reserved */
+#define SNR_TBO 0x3b /* Transmitter Backoff Counter */
+#define SNR_TRC 0x3c /* Transmitter Random Counter */
+#define SNR_TBM 0x3d /* Transmitter Backoff Mask */
+#define SNR_RES4 0x3e /* Reserved */
+#define SNR_DCR2 0x3f /* Data Configuration 2 (AVF) */
-#define SN_REGSIZE (0x40 * 4)
+#define SN_NREGS 0x40
/*
* Register Interpretations
diff --git a/sys/arch/mac68k/dev/if_snvar.h b/sys/arch/mac68k/dev/if_snvar.h
index e89d0f50966..fa6c3aecc1d 100644
--- a/sys/arch/mac68k/dev/if_snvar.h
+++ b/sys/arch/mac68k/dev/if_snvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_snvar.h,v 1.2 1997/03/14 14:11:36 briggs Exp $ */
+/* $OpenBSD: if_snvar.h,v 1.3 1997/03/29 23:26:50 briggs Exp $ */
/*
* Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk)
@@ -7,7 +7,7 @@
*/
/*
- * if_sonic.h -- National Semiconductor DP83932BVF (SONIC)
+ * if_snvar.h -- National Semiconductor DP83932BVF (SONIC) NetBSD/mac68k vars
*/
/*
@@ -22,6 +22,23 @@
(*(u_int16_t *)((u_int16_t *)a + o) & 0xffff))
/*
+ * Register access macros. We use bus_space_* to talk to the Sonic
+ * registers. A mapping table is used in case a particular configuration
+ * hooked the regs up at non-word offsets.
+ */
+#define NIC_GET(sc, reg) (bus_space_read_2((sc)->sc_regt, \
+ (sc)->sc_regh, \
+ ((sc)->sc_reg_map[reg])))
+#define NIC_PUT(sc, reg, val) (bus_space_write_2((sc)->sc_regt, \
+ (sc)->sc_regh, \
+ ((sc)->sc_reg_map[reg]), \
+ (val)))
+#define SN_REGSIZE SN_NREGS*4
+
+/* mac68k does not have any write buffers to flush... */
+#define wbflush()
+
+/*
* buffer sizes in 32 bit mode
* 1 TXpkt is 4 hdr words + (3 * FRAGMAX) + 1 link word
* FRAGMAX == 16 => 54 words == 216 bytes
@@ -52,6 +69,8 @@
#define NTXB 10 /* Number of xmit buffers */
#define TXBSIZE 1536 /* 6*2^8 -- the same size as the 8390 TXBUF */
+#define SN_NPAGES 1 + 8 + 5
+
/*
* Statistics collected over time
*/
@@ -102,12 +121,13 @@ typedef struct sn_softc {
struct sn_stats sc_sum;
short sc_iflags;
unsigned short bitmode; /* 32 bit mode == 1, 16 == 0 */
+ bus_size_t sc_reg_map[SN_NREGS]; /* register offsets */
- unsigned int s_dcr; /* DCR for this instance */
+ u_int16_t snr_dcr; /* DCR for this instance */
+ u_int16_t snr_dcr2; /* DCR2 for this instance */
int slotno; /* Slot number */
- struct sonic_reg *sc_csr; /* hardware pointer */
- int sc_rxmark; /* pos. in rx ring for reading buffs */
+ int sc_rxmark; /* pos. in rx ring for reading buffs */
int sc_rramark; /* index into p_rra of wp */
void *p_rra[NRRA]; /* RX resource descs */
int v_rra[NRRA]; /* DMA addresses of p_rra */
@@ -119,7 +139,6 @@ typedef struct sn_softc {
caddr_t rbuf[NRBA];
- int sc_txhead; /*XXX idx of first TDA passed to chip */
int sc_missed; /* missed packet counter */
int txb_cnt; /* total number of xmit buffers */
@@ -142,7 +161,7 @@ typedef struct sn_softc {
void *p_cda;
int v_cda;
- unsigned char space[(1 + 1 + 8 + 5) * NBPG];
+ unsigned char *space;
} sn_softc_t;
/*
@@ -217,4 +236,5 @@ typedef struct sn_softc {
#define CDA_ENABLE 64 /* mask enabling CAM entries */
#define CDA_SIZE(sc) ((4*16 + 1) * ((sc->bitmode) ? 4 : 2))
-void snsetup __P((struct sn_softc *sc));
+int snsetup __P((struct sn_softc *sc));
+void snintr __P((void *, int));