From: briggs Date: Fri, 14 Mar 1997 14:11:34 +0000 (+0000) Subject: Updates from Yanagisawa and Denny. This seems to work. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=609bed02f941b91747d5e03b234124b519352001;p=openbsd Updates from Yanagisawa and Denny. This seems to work. --- diff --git a/sys/arch/mac68k/dev/if_sn.c b/sys/arch/mac68k/dev/if_sn.c index 03e112348e2..d7e79846194 100644 --- a/sys/arch/mac68k/dev/if_sn.c +++ b/sys/arch/mac68k/dev/if_sn.c @@ -1,5 +1,4 @@ -/* $OpenBSD: if_sn.c,v 1.9 1997/03/12 13:20:31 briggs Exp $ -*/ +/* $OpenBSD: if_sn.c,v 1.10 1997/03/14 14:11:34 briggs Exp $ */ /* * National Semiconductor SONIC Driver @@ -54,75 +53,64 @@ typedef unsigned char uchar; #include "nubus.h" -#define SWR(a, x) (a) = (x) -#define SRD(a) ((a) & 0xffff) +/* + * 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 sonicput32 __P((struct sn_softc *sc, struct mbuf *m0)); -static int sonicput16 __P((struct sn_softc *sc, struct mbuf *m0)); +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)); -static void sntxint16 __P((struct sn_softc *)); -static void sntxint32 __P((struct sn_softc *)); -static void snrxint16 __P((struct sn_softc *)); -static void snrxint32 __P((struct sn_softc *)); - void camdump __P((struct sn_softc *sc)); +struct cfdriver sn_cd = { + NULL, "sn", DV_IFNET +}; + #undef assert #undef _assert #ifdef NDEBUG -#define assert(e) ((void)0) -#define _assert(e) ((void)0) +#define assert(e) ((void)0) +#define _assert(e) ((void)0) #else -#define _assert(e) assert(e) +#define _assert(e) assert(e) #ifdef __STDC__ -#define assert(e) ((e) ? (void)0 : __assert("sn ", __FILE__, __LINE__, #e)) -#else /* PCC */ -#define assert(e) ((e) ? (void)0 : __assert("sn "__FILE__, __LINE__, "e")) +#define assert(e) ((e) ? (void)0 : __assert("sn ", __FILE__, __LINE__, #e)) +#else /* PCC */ +#define assert(e) ((e) ? (void)0 : __assert("sn "__FILE__, __LINE__, "e")) #endif #endif int ethdebug = 0; -#define ROUNDUP(p, N) (((int) p + N - 1) & ~(N - 1)) +/* + * SONIC buffers need to be aligned 16 or 32 bit aligned. + * These macros calculate and verify alignment. + */ +#define ROUNDUP(p, N) (((int) p + N - 1) & ~(N - 1)) + +#define SOALIGN(m, array) (m ? (ROUNDUP(array, 4)) : (ROUNDUP(array, 2))) #define LOWER(x) ((unsigned)(x) & 0xffff) #define UPPER(x) ((unsigned)(x) >> 16) /* - * Nicely aligned pointers into the SONIC buffers - * p_ points at physical (K1_SEG) addresses. + * Interface exists: make available by filling in network interface + * record. System will initialize the interface when it is ready + * to accept packets. */ - -/* Meta transmit descriptors */ -struct mtd { - struct mtd *mtd_link; - void *mtd_txp; - int mtd_vtxp; - unsigned char *mtd_buf; -} mtda[NTDA]; - -struct mtd *mtdfree; /* list of free meta transmit descriptors */ -struct mtd *mtdhead; /* head of descriptors assigned to chip */ -struct mtd *mtdtail; /* tail of descriptors assigned to chip */ -struct mtd *mtdnext; /* next descriptor to give to chip */ - -void mtd_free __P((struct mtd *)); -struct mtd *mtd_alloc __P((void)); - -struct cfdriver sn_cd = { - NULL, "sn", DV_IFNET -}; - void snsetup(sc) struct sn_softc *sc; @@ -159,30 +147,50 @@ snsetup(sc) */ p = &sc->space[0]; pp = (unsigned char *)ROUNDUP ((int)p, NBPG); + p = pp; - if ((RRASIZE + CDASIZE + RDASIZE + TDASIZE) > NBPG) { - printf ("sn: sizeof RRA (%d) + CDA (%d) + " - "RDA (%d) + TDA (%d) > NBPG (%d). Punt!\n", - RRASIZE, CDASIZE, RDASIZE, TDASIZE, NBPG); - return; + for (i = 0; i < NRRA; i++) { + sc->p_rra[i] = (void *)p; + sc->v_rra[i] = kvtop(p); + p += RXRSRC_SIZE(sc); } + sc->v_rea = kvtop(p); - p = pp; - sc->p_rra = (void *) p; - sc->v_rra = kvtop((caddr_t) sc->p_rra); - p += RRASIZE; + p = (unsigned char *)SOALIGN(sc, p); sc->p_cda = (void *) (p); - sc->v_cda = kvtop((caddr_t) sc->p_cda); - p += CDASIZE; + sc->v_cda = kvtop(p); + p += CDA_SIZE(sc); - sc->p_rda = (void *) p; - sc->v_rda = kvtop((caddr_t) sc->p_rda); - p += RDASIZE; + p = (unsigned char *)SOALIGN(sc, p); + + for (i = 0; i < NRDA; i++) { + sc->p_rda[i] = (void *) p; + sc->v_rda[i] = kvtop(p); + p += RXPKT_SIZE(sc); + } + + p = (unsigned char *)SOALIGN(sc, p); + + for (i = 0; i < NTDA; i++) { + struct mtd *mtdp = &sc->mtda[i]; + mtdp->mtd_txp = (void *)p; + mtdp->mtd_vtxp = kvtop(p); + p += TXP_SIZE(sc); + } - sc->p_tda = (void *) p; - sc->v_tda = kvtop((caddr_t) sc->p_tda); - p += TDASIZE; + p = (unsigned char *)SOALIGN(sc, p); + + if ((p - pp) > NBPG) { + printf ("sn: sizeof RRA (%ld) + CDA (%ld) +" + "RDA (%ld) + TDA (%ld) > NBPG (%d). Punt!\n", + (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; + } p = pp + NBPG; @@ -206,8 +214,8 @@ snsetup(sc) printf(" address %s\n", ether_sprintf(sc->sc_enaddr)); #if 0 -printf("sonic buffers: rra=0x%x cda=0x%x rda=0x%x tda=0x%x\n", - sc->p_rra, sc->p_cda, sc->p_rda, sc->p_tda); +printf("sonic buffers: rra=%p cda=0x%x rda=0x%x tda=0x%x\n", + sc->p_rra[0], sc->p_cda, sc->p_rda[0], sc->mtda[0].mtd_txp); #endif bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); @@ -216,21 +224,12 @@ printf("sonic buffers: rra=0x%x cda=0x%x rda=0x%x tda=0x%x\n", ifp->if_start = snstart; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_watchdog = snwatchdog; - #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif - if_attach(ifp); ether_ifattach(ifp); - if (sc->sc_is16) { - sc->rxint = snrxint16; - sc->txint = sntxint16; - } else { - sc->rxint = snrxint32; - sc->txint = sntxint32; - } add_nubus_intr(sc->slotno, snintr, (void *) sc); } @@ -243,7 +242,7 @@ snioctl(ifp, cmd, data) struct ifaddr *ifa; struct sn_softc *sc = ifp->if_softc; int s = splnet(), err = 0; - int temp; + int temp; switch (cmd) { @@ -272,8 +271,7 @@ snioctl(ifp, cmd, data) (ifp->if_flags & IFF_RUNNING) == 0) (void)sninit(ifp->if_softc); /* - * If the state of the promiscuous bit changes, the -interface + * If the state of the promiscuous bit changes, the interface * must be reset to effect the change. */ if (((ifp->if_flags ^ sc->sc_iflags) & IFF_PROMISC) && @@ -325,7 +323,7 @@ snstart(ifp) { struct sn_softc *sc = ifp->if_softc; struct mbuf *m; - int len; + int len; if ((sc->sc_if.if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) return; @@ -337,6 +335,10 @@ outloop: return; } + if (sc->sc_csr->s_cr & CR_TXP) { + return; + } + IF_DEQUEUE(&sc->sc_if.if_snd, m); if (m == 0) return; @@ -359,11 +361,7 @@ outloop: * the Tx ring, then send the packet directly. Otherwise append * it to the o/p queue. */ - if (sc->sc_is16) { - len = sonicput16(sc, m); - } else { - len = sonicput32(sc, m); - } + len = sonicput(sc, m); #if 0 if (len != m->m_pkthdr.len) { printf("snstart: len %d != m->m_pkthdr.len %d.\n", @@ -381,7 +379,7 @@ outloop: sc->txb_inuse++; sc->sc_if.if_opackets++; /* # of pkts */ - sc->sc_sum.ls_opacks++; /* # of pkts */ + sc->sc_sum.ls_opacks++; /* # of pkts */ /* Jump back for possibly more punishment. */ goto outloop; @@ -392,7 +390,7 @@ outloop: * the address or switch the i/f on. */ void caminitialise __P((struct sn_softc *)); -void camentry __P((struct sn_softc *, int, unsigned char *)); +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 *)); @@ -425,10 +423,10 @@ sninit(sc) s = splnet(); - csr->s_cr = CR_RST; /* s_dcr only accessable reset mode! */ + csr->s_cr = CR_RST; /* s_dcr only accessable reset mode! */ /* config it */ - csr->s_dcr = sc->s_dcr; + 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; @@ -490,12 +488,11 @@ snstop(sc) /* free all receive buffers (currently static so nothing to do) */ /* free all pending transmit mbufs */ - while ((mtd = mtdhead) != NULL) { - mtdhead = mtdhead->mtd_link; + while (sc->mtd_hw != sc->mtd_free) { + mtd = &sc->mtda[sc->mtd_hw]; mtd->mtd_buf = 0; - mtd_free(mtd); + if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0; } - mtdnext = mtd_alloc(); sc->txb_inuse = 0; sc->sc_if.if_timer = 0; @@ -515,23 +512,18 @@ snwatchdog(ifp) struct ifnet *ifp; { struct sn_softc *sc = ifp->if_softc; - int temp; - u_long status; + struct mtd *mtd; + int temp; - if (mtdhead && mtdhead->mtd_buf) { + if (sc->mtd_hw != sc->mtd_free) { /* something still pending for transmit */ - if (sc->sc_is16) { - status = ((struct _short_TXpkt *) - mtdhead->mtd_txp)->status; - } else { - status = ((struct TXpkt *) mtdhead->mtd_txp)->status; - } - if (status == 0) + mtd = &sc->mtda[sc->mtd_hw]; + if (SRO(sc->bitmode, mtd->mtd_txp, TXP_STATUS) == 0) log(LOG_ERR, "%s: Tx - timeout\n", sc->sc_dev.dv_xname); else log(LOG_ERR, "%s: Tx - lost interrupt\n", - sc->sc_dev.dv_xname); + sc->sc_dev.dv_xname); temp = sc->sc_if.if_flags & IFF_UP; snreset(sc); sc->sc_if.if_flags |= temp; @@ -539,117 +531,44 @@ snwatchdog(ifp) } /* - * stuff packet into sonic (at splnet) (16-bit) + * stuff packet into sonic (at splnet) */ static int -sonicput16(sc, m0) +sonicput(sc, m0) struct sn_softc *sc; struct mbuf *m0; { - struct sonic_reg *csr = sc->sc_csr; - unsigned char *buff, *buffer, *data; - struct _short_TXpkt *txp; - struct mtd *mtdnew; - struct mbuf *m; - unsigned int len = 0; - unsigned int totlen = 0; + struct sonic_reg *csr = sc->sc_csr; + unsigned char *buff, *buffer; + void *txp; + struct mtd *mtdp; + struct mbuf *m; + unsigned int len = 0; + unsigned int totlen = 0; + int mtd_free = sc->mtd_free; + int mtd_next; + int txb_new = sc->txb_new; /* grab the replacement mtd */ - if ((mtdnew = mtd_alloc()) == 0) - return (0); - - /* We are guaranteed, if we get here, that the xmit buffer is free. */ - buff = buffer = sc->tbuf[sc->txb_new]; - - /* this packet goes to mdtnext fill in the TDA */ - mtdnext->mtd_buf = buffer; - txp = mtdnext->mtd_txp; - SWR(txp->config, 0); - - for (m = m0; m; m = m->m_next) { - data = mtod(m, u_char *); - len = m->m_len; - totlen += len; - bcopy(data, buff, len); - buff += len; - } - if (totlen >= TXBSIZE) { - panic("packet overflow in sonicput."); - } - SWR(txp->u[0].frag_ptrlo, LOWER(sc->vtbuf[sc->txb_new])); - SWR(txp->u[0].frag_ptrhi, UPPER(sc->vtbuf[sc->txb_new])); - SWR(txp->u[0].frag_size, totlen); - - if (totlen < ETHERMIN + sizeof(struct ether_header)) { - int pad = ETHERMIN + sizeof(struct ether_header) - totlen; - bzero(buffer + totlen, pad); - SWR(txp->u[0].frag_size, pad + SRD(txp->u[0].frag_size)); - totlen = ETHERMIN + sizeof(struct ether_header); - } - SWR(txp->frag_count, 1); - SWR(txp->pkt_size, totlen); + mtdp = &sc->mtda[mtd_free]; - /* link onto the next mtd that will be used */ - SWR(txp->u[1].tlink, LOWER(mtdnew->mtd_vtxp) | EOL); - - if (mtdhead == 0) { - /* no current transmit list start with this one */ - mtdtail = mtdhead = mtdnext; - csr->s_ctda = LOWER(mtdnext->mtd_vtxp); - } else { - /* - * have a transmit list append it to end note - * mtdnext is already physicaly linked to mtdtail in - * mtdtail->mtd_txp->u[mtdtail->mtd_txp->frag_count].tlink - */ - struct _short_TXpkt *tp; + if ((mtd_next = mtd_free + 1) == NTDA) + mtd_next = 0; - tp = (struct _short_TXpkt *) mtdtail->mtd_txp; - SWR(tp->u[tp->frag_count].tlink, - SRD(tp->u[tp->frag_count].tlink) & ~EOL); - mtdtail = mtdnext; - } - mtdnext->mtd_link = mtdnew; - mtdnext = mtdnew; - - /* make sure chip is running */ - wbflush(); - csr->s_cr = CR_TXP; - wbflush(); - sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */ - return (totlen); -} - -/* - * 32-bit version of sonicput - */ -static int -sonicput32(sc, m0) - struct sn_softc *sc; - struct mbuf *m0; -{ - struct sonic_reg *csr = sc->sc_csr; - unsigned char *buff, *buffer, *data; - struct TXpkt *txp; - struct mtd *mtdnew; - struct mbuf *m; - unsigned int len = 0; - unsigned int totlen = 0; - - /* grab the replacement mtd */ - if ((mtdnew = mtd_alloc()) == 0) + if (mtd_next == sc->mtd_hw) { return (0); + } /* We are guaranteed, if we get here, that the xmit buffer is free. */ - buff = buffer = sc->tbuf[sc->txb_new]; + buff = buffer = sc->tbuf[txb_new]; - /* this packet goes to mdtnext fill in the TDA */ - mtdnext->mtd_buf = buffer; - txp = mtdnext->mtd_txp; - SWR(txp->config, 0); + /* this packet goes to mtdnext fill in the TDA */ + mtdp->mtd_buf = buffer; + txp = mtdp->mtd_txp; + SWO(sc->bitmode, txp, TXP_CONFIG, 0); for (m = m0; m; m = m->m_next) { - data = mtod(m, u_char *); + unsigned char *data = mtod(m, u_char *); len = m->m_len; totlen += len; bcopy(data, buff, len); @@ -658,73 +577,52 @@ sonicput32(sc, m0) if (totlen >= TXBSIZE) { panic("packet overflow in sonicput."); } - SWR(txp->u[0].frag_ptrlo, LOWER(sc->vtbuf[sc->txb_new])); - SWR(txp->u[0].frag_ptrhi, UPPER(sc->vtbuf[sc->txb_new])); - SWR(txp->u[0].frag_size, totlen); + SWO(sc->bitmode, txp, TXP_FRAGOFF+(0*TXP_FRAGSIZE)+TXP_FPTRLO, + LOWER(sc->vtbuf[txb_new])); + SWO(sc->bitmode, txp, TXP_FRAGOFF+(0*TXP_FRAGSIZE)+TXP_FPTRHI, + UPPER(sc->vtbuf[txb_new])); if (totlen < ETHERMIN + sizeof(struct ether_header)) { int pad = ETHERMIN + sizeof(struct ether_header) - totlen; bzero(buffer + totlen, pad); - SWR(txp->u[0].frag_size, pad + SRD(txp->u[0].frag_size)); totlen = ETHERMIN + sizeof(struct ether_header); } - SWR(txp->frag_count, 1); - SWR(txp->pkt_size, totlen); + + SWO(sc->bitmode, txp, TXP_FRAGOFF+(0*TXP_FRAGSIZE)+TXP_FSIZE, + totlen); + SWO(sc->bitmode, txp, TXP_FRAGCNT, 1); + SWO(sc->bitmode, txp, TXP_PKTSIZE, totlen); /* link onto the next mtd that will be used */ - SWR(txp->u[1].tlink, LOWER(mtdnew->mtd_vtxp) | EOL); + SWO(sc->bitmode, txp, TXP_FRAGOFF+(1*TXP_FRAGSIZE)+TXP_FPTRLO, + LOWER(sc->mtda[mtd_next].mtd_vtxp) | EOL); - if (mtdhead == 0) { - /* no current transmit list start with this one */ - mtdtail = mtdhead = mtdnext; - csr->s_ctda = LOWER(mtdnext->mtd_vtxp); - } else { - /* - * have a transmit list append it to end note - * mtdnext is already physicaly linked to mtdtail in - * mtdtail->mtd_txp->u[mtdtail->mtd_txp->frag_count].tlink - */ - struct TXpkt *tp; + /* + * The previous txp.tlink currently contains a pointer to + * our txp | EOL. Want to clear the EOL, so write our + * pointer to the previous txp. + */ + SWO(sc->bitmode, sc->mtda[sc->mtd_prev].mtd_txp, sc->mtd_tlinko, + LOWER(mtdp->mtd_vtxp)); - tp = (struct TXpkt *) mtdtail->mtd_txp; - SWR(tp->u[tp->frag_count].tlink, - SRD(tp->u[tp->frag_count].tlink) & ~EOL); - mtdtail = mtdnext; - } - mtdnext->mtd_link = mtdnew; - mtdnext = mtdnew; + sc->mtd_prev = mtd_free; + sc->mtd_free = mtd_next; /* make sure chip is running */ wbflush(); csr->s_cr = CR_TXP; wbflush(); - sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */ + 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 *)); + int sonic_read __P((struct sn_softc *, caddr_t, int)); struct mbuf *sonic_get __P((struct sn_softc *, struct ether_header *, int)); -void -mtd_free(mtd) - struct mtd *mtd; -{ - mtd->mtd_link = mtdfree; - mtdfree = mtd; -} - -struct mtd * -mtd_alloc() -{ - struct mtd *mtd = mtdfree; - - if (mtd) { - mtdfree = mtd->mtd_link; - mtd->mtd_link = 0; - } - return (mtd); -} - /* * CAM support */ @@ -732,50 +630,30 @@ void caminitialise(sc) struct sn_softc *sc; { - int i; + int i; + void *p_cda = sc->p_cda; + int bitmode = sc->bitmode; - if (sc->sc_is16) { - struct _short_CDA *p_cda; - - p_cda = (struct _short_CDA *) sc->p_cda; - for (i = 0; i < MAXCAM; i++) - SWR(p_cda->desc[i].cam_ep, i); - SWR(p_cda->enable, 0); - } else { - struct CDA *p_cda; - - p_cda = (struct CDA *) sc->p_cda; - for (i = 0; i < MAXCAM; i++) - SWR(p_cda->desc[i].cam_ep, i); - SWR(p_cda->enable, 0); - } + for (i = 0; i < MAXCAM; i++) + SWO(bitmode, p_cda, (CDA_CAMDESC * i + CDA_CAMEP), i); + SWO(bitmode, p_cda, CDA_ENABLE, 0); } void camentry(sc, entry, ea) - struct sn_softc *sc; int entry; unsigned char *ea; + struct sn_softc *sc; { - if (sc->sc_is16) { - struct _short_CDA *p_cda; - - p_cda = (struct _short_CDA *) sc->p_cda; - SWR(p_cda->desc[entry].cam_ep, entry); - SWR(p_cda->desc[entry].cam_ap2, (ea[5] << 8) | ea[4]); - SWR(p_cda->desc[entry].cam_ap1, (ea[3] << 8) | ea[2]); - SWR(p_cda->desc[entry].cam_ap0, (ea[1] << 8) | ea[0]); - SWR(p_cda->enable, SRD(p_cda->enable) | (1 << entry)); - } else { - struct CDA *p_cda; - - p_cda = (struct CDA *) sc->p_cda; - SWR(p_cda->desc[entry].cam_ep, entry); - SWR(p_cda->desc[entry].cam_ap2, (ea[5] << 8) | ea[4]); - SWR(p_cda->desc[entry].cam_ap1, (ea[3] << 8) | ea[2]); - SWR(p_cda->desc[entry].cam_ap0, (ea[1] << 8) | ea[0]); - SWR(p_cda->enable, SRD(p_cda->enable) | (1 << entry)); - } + int bitmode = sc->bitmode; + void *p_cda = sc->p_cda; + 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)); } void @@ -842,28 +720,22 @@ initialise_tda(sc) { struct sonic_reg *csr; struct mtd *mtd; - int i, psize; - u_long p; + int i; csr = sc->sc_csr; - mtdfree = mtdhead = mtdtail = (struct mtd *) 0; - - p = (u_long) sc->p_tda; - psize = (sc->sc_is16 ? - sizeof(struct _short_TXpkt) : sizeof(struct TXpkt)); - for (i = 0; i < NTDA; i++) { - mtd = &mtda[i]; - mtd->mtd_txp = (struct TXpkt *) p; - mtd->mtd_vtxp = kvtop((caddr_t) mtd->mtd_txp); + mtd = &sc->mtda[i]; mtd->mtd_buf = 0; - mtd_free(mtd); - p += psize; } - mtdnext = mtd_alloc(); - csr->s_utda = UPPER(sc->v_tda); + sc->mtd_hw = 0; + sc->mtd_prev = NTDA-1; + 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); } void @@ -871,48 +743,26 @@ 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 */ - if (sc->sc_is16) { - int v_rda; - struct _short_RXpkt *p_rda; - - p_rda = (struct _short_RXpkt *) sc->p_rda; - for (i = 0; i < (NRDA - 1); i++) { - SWR(p_rda[i].rlink, - LOWER(v_rda + (i + 1) * sizeof(struct _short_RXpkt))); - SWR(p_rda[i].in_use, 1); - } - SWR(p_rda[NRDA - 1].rlink, LOWER(v_rda) | EOL); - SWR(p_rda[NRDA - 1].in_use, 1); - - /* mark end of receive descriptor list */ - sc->sc_lrxp = &p_rda[NRDA - 1]; - } else { - int v_rda; - struct RXpkt *p_rda; - - v_rda = sc->v_rda; - p_rda = (struct RXpkt *) sc->p_rda; - for (i = 0; i < (NRDA - 1); i++) { - SWR(p_rda[i].rlink, - LOWER(v_rda + (i + 1) * sizeof(struct RXpkt))); - SWR(p_rda[i].in_use, 1); - } - SWR(p_rda[NRDA - 1].rlink, LOWER(v_rda) | EOL); - SWR(p_rda[NRDA - 1].in_use, 1); - - /* mark end of receive descriptor list */ - sc->sc_lrxp = &p_rda[NRDA - 1]; + for (i = 0; i < (NRDA - 1); i++) { + SWO(bitmode, sc->p_rda[i], RXPKT_RLINK, LOWER(sc->v_rda[i+1])); + SWO(bitmode, sc->p_rda[i], RXPKT_INUSE, 1); } + SWO(bitmode, sc->p_rda[NRDA - 1], RXPKT_RLINK, LOWER(sc->v_rda[0]) | EOL); + SWO(bitmode, sc->p_rda[NRDA - 1], RXPKT_INUSE, 1); + + /* mark end of receive descriptor list */ + sc->sc_rdamark = NRDA - 1; sc->sc_rxmark = 0; - csr->s_urda = UPPER(sc->v_rda); - csr->s_crda = LOWER(sc->v_rda); + SWR(csr->s_urda, UPPER(sc->v_rda[0])); + SWR(csr->s_crda, LOWER(sc->v_rda[0])); wbflush(); } @@ -921,47 +771,32 @@ initialise_rra(sc) struct sn_softc *sc; { struct sonic_reg *csr; - int i; - int rr_size; + int i; + unsigned int v; + int bitmode = sc->bitmode; csr = sc->sc_csr; - if (sc->sc_is16) { - rr_size = sizeof(struct _short_RXrsrc); - csr->s_eobc = RBASIZE(sc) / 2 - 1; /* must be >= MAXETHERPKT */ - } else { - rr_size = sizeof(struct RXrsrc); - csr->s_eobc = RBASIZE(sc) / 2 - 2; /* must be >= MAXETHERPKT */ - } - csr->s_urra = UPPER(sc->v_rra); - csr->s_rsa = LOWER(sc->v_rra); - csr->s_rea = LOWER(sc->v_rra + (NRRA * rr_size)); - csr->s_rrp = LOWER(sc->v_rra); + if (bitmode) + csr->s_eobc = RBASIZE(sc) / 2 - 2; /* must be >= MAXETHERPKT */ + 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]); + /* 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]); /* fill up SOME of the rra with buffers */ - if (sc->sc_is16) { - struct _short_RXrsrc *p_rra; - - p_rra = (struct _short_RXrsrc *) sc->p_rra; - for (i = 0; i < NRBA; i++) { - SWR(p_rra[i].buff_ptrhi, UPPER(kvtop(sc->rbuf[i]))); - SWR(p_rra[i].buff_ptrlo, LOWER(kvtop(sc->rbuf[i]))); - SWR(p_rra[i].buff_wchi, UPPER(RBASIZE(sc) / 2)); - SWR(p_rra[i].buff_wclo, LOWER(RBASIZE(sc) / 2)); - } - } else { - struct RXrsrc *p_rra; - - p_rra = (struct RXrsrc *) sc->p_rra; - for (i = 0; i < NRBA; i++) { - SWR(p_rra[i].buff_ptrhi, UPPER(kvtop(sc->rbuf[i]))); - SWR(p_rra[i].buff_ptrlo, LOWER(kvtop(sc->rbuf[i]))); - SWR(p_rra[i].buff_wchi, UPPER(RBASIZE(sc) / 2)); - SWR(p_rra[i].buff_wclo, LOWER(RBASIZE(sc) / 2)); - } + for (i = 0; i < NRBA; i++) { + v = kvtop(sc->rbuf[i]); + SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v)); + SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v)); + SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(RBASIZE(sc) / 2)); + 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 * rr_size)); + csr->s_rwp = LOWER(sc->v_rra[sc->sc_rramark]); wbflush(); } @@ -976,12 +811,12 @@ initialise_tba(sc) static void snintr(arg, slot) - void *arg; - int slot; + void *arg; + int slot; { - struct sn_softc *sc = (struct sn_softc *)arg; + struct sn_softc *sc = (struct sn_softc *)arg; struct sonic_reg *csr = sc->sc_csr; - int isr; + int isr; while ((isr = (csr->s_isr & ISR_ALL)) != 0) { /* scrub the interrupts that we are going to service */ @@ -992,10 +827,10 @@ snintr(arg, slot) printf("sonic: unexpected interrupt status 0x%x\n", isr); if (isr & (ISR_TXDN | ISR_TXER)) - (*sc->txint)(sc); + sonictxint(sc); if (isr & ISR_PKTRX) - (*sc->rxint)(sc); + sonicrxint(sc); if (isr & (ISR_HBL | ISR_RDE | ISR_RBE | ISR_RBAE | ISR_RFO)) { if (isr & ISR_HBL) @@ -1032,152 +867,93 @@ snintr(arg, slot) } /* - * Transmit interrupt routine (16-bit) - */ -static void -sntxint16(sc) - struct sn_softc *sc; -{ - struct _short_TXpkt *txp; - struct sonic_reg *csr; - struct mtd *mtd; - - if (mtdhead == (struct mtd *) 0) - return; - - csr = sc->sc_csr; - - while ((mtd = mtdhead) != NULL) { - if (mtd->mtd_buf == 0) - break; - - txp = (struct _short_TXpkt *) mtd->mtd_txp; - - if (SRD(txp->status) == 0) /* it hasn't really gone yet */ - return; - - if (ethdebug) { - struct ether_header *eh; - - eh = (struct ether_header *) mtd->mtd_buf; - printf("xmit status=0x%x len=%d type=0x%x from %s", - txp->status, - txp->pkt_size, - htons(eh->ether_type), - ether_sprintf(eh->ether_shost)); - printf(" (to %s)\n", ether_sprintf(eh->ether_dhost)); - } - sc->txb_inuse--; - mtd->mtd_buf = 0; - mtdhead = mtd->mtd_link; - - mtd_free(mtd); - - /* XXX - Do stats here. */ - - if ((SRD(txp->status) & TCR_PTX) == 0) { - printf("sonic: Tx packet status=0x%x\n", txp->status); - - /* XXX - DG This looks bogus */ - if (mtdhead != mtdnext) { - printf("resubmitting remaining packets\n"); - csr->s_ctda = LOWER(mtdhead->mtd_vtxp); - csr->s_cr = CR_TXP; - wbflush(); - return; - } - } - } - /* mtdhead should be at mtdnext (go) */ - mtdhead = 0; -} - -/* - * Transmit interrupt routine (32-bit) + * Transmit interrupt routine */ -static void -sntxint32(sc) +void +sonictxint(sc) struct sn_softc *sc; { - struct TXpkt *txp; + void *txp; struct sonic_reg *csr; - struct mtd *mtd; + struct mtd *mtd; + /* XXX DG make mtd_hw a local var */ - if (mtdhead == (struct mtd *) 0) + if (sc->mtd_hw == sc->mtd_free) return; csr = sc->sc_csr; - while ((mtd = mtdhead) != NULL) { + while (sc->mtd_hw != sc->mtd_free) { + mtd = &sc->mtda[sc->mtd_hw]; if (mtd->mtd_buf == 0) break; txp = mtd->mtd_txp; - if (SRD(txp->status) == 0) /* it hasn't really gone yet */ - return; + if (SRO(sc->bitmode, txp, TXP_STATUS) == 0) + return; /* it hasn't really gone yet */ if (ethdebug) { struct ether_header *eh; eh = (struct ether_header *) mtd->mtd_buf; - printf("xmit status=0x%lx len=%ld type=0x%x from %s", - txp->status, - txp->pkt_size, + printf("xmit status=0x%x len=%d type=0x%x from %s", + SRO(sc->bitmode, txp, TXP_STATUS), + SRO(sc->bitmode, txp, TXP_PKTSIZE), htons(eh->ether_type), ether_sprintf(eh->ether_shost)); printf(" (to %s)\n", ether_sprintf(eh->ether_dhost)); } sc->txb_inuse--; mtd->mtd_buf = 0; - mtdhead = mtd->mtd_link; - - mtd_free(mtd); + if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0; /* XXX - Do stats here. */ - if ((SRD(txp->status) & TCR_PTX) == 0) { - printf("sonic: Tx packet status=0x%lx\n", txp->status); + if ((SRO(sc->bitmode, txp, TXP_STATUS) & TCR_PTX) == 0) { + printf("sonic: Tx packet status=0x%x\n", + SRO(sc->bitmode, txp, TXP_STATUS)); /* XXX - DG This looks bogus */ - if (mtdhead != mtdnext) { + if (sc->mtd_hw != sc->mtd_free) { printf("resubmitting remaining packets\n"); - csr->s_ctda = LOWER(mtdhead->mtd_vtxp); + mtd = &sc->mtda[sc->mtd_hw]; + csr->s_ctda = LOWER(mtd->mtd_vtxp); csr->s_cr = CR_TXP; wbflush(); return; } } } - /* mtdhead should be at mtdnext (go) */ - mtdhead = 0; } /* - * Receive interrupt routine (16-bit) + * Receive interrupt routine */ -static void -snrxint16(sc) +void +sonicrxint(sc) struct sn_softc *sc; { struct sonic_reg *csr = sc->sc_csr; - struct _short_RXpkt *rxp, *p_rda; - struct _short_RXrsrc *p_rra; - int orra; + void *rda; + int orra; int len; + int rramark; + int rdamark; + int bitmode = sc->bitmode; + void *tmp1; + void *tmp2; - p_rra = (struct _short_RXrsrc *) sc->p_rra; - p_rda = (struct _short_RXpkt *) sc->p_rda; - rxp = &p_rda[sc->sc_rxmark]; + rda = sc->p_rda[sc->sc_rxmark]; - while (SRD(rxp->in_use) == 0) { - unsigned status = SRD(rxp->status); + while (SRO(bitmode, rda, RXPKT_INUSE) == 0) { + unsigned status = SRO(bitmode, rda, RXPKT_STATUS); if ((status & RCR_LPKT) == 0) printf("sonic: more than one packet in RBA!\n"); - orra = RBASEQ(SRD(rxp->seq_no)) & RRAMASK; - len = SRD(rxp->byte_count) - - sizeof(struct ether_header) - FCSSIZE; + orra = RBASEQ(SRO(bitmode, rda, RXPKT_SEQNO)) & RRAMASK; + len = SRO(bitmode, rda, RXPKT_BYTEC) - + sizeof(struct ether_header) - FCSSIZE; if (status & RCR_PRX) { if (sonic_read(sc, sc->rbuf[orra & RBAMASK], len)) { sc->sc_if.if_ipackets++; @@ -1194,100 +970,46 @@ snrxint16(sc) * sonic read didnt copy it out then we would have to * wait !! * (dont bother add it back in again straight away) - */ - p_rra[sc->sc_rramark] = p_rra[orra]; - - /* zap old rra for fun */ - p_rra[orra].buff_wchi = 0; - p_rra[orra].buff_wclo = 0; - - sc->sc_rramark = (sc->sc_rramark + 1) & RRAMASK; - csr->s_rwp = LOWER(sc->v_rra + - (sc->sc_rramark * sizeof(struct _short_RXrsrc))); - wbflush(); - - /* - * give receive descriptor back to chip simple - * list is circular - */ - SWR(rxp->in_use, 1); - SWR(rxp->rlink, SRD(rxp->rlink) | EOL); - SWR(((struct _short_RXpkt *) sc->sc_lrxp)->rlink, - SRD(((struct _short_RXpkt *) sc->sc_lrxp)->rlink) & ~EOL); - sc->sc_lrxp = (void *) rxp; - - if (++sc->sc_rxmark >= NRDA) - sc->sc_rxmark = 0; - rxp = &p_rda[sc->sc_rxmark]; - } -} - -/* - * Receive interrupt routine (normal 32-bit) - */ -static void -snrxint32(sc) - struct sn_softc *sc; -{ - struct sonic_reg *csr = sc->sc_csr; - struct RXpkt *rxp, *p_rda; - struct RXrsrc *p_rra; - int orra; - int len; - - p_rra = (struct RXrsrc *) sc->p_rra; - p_rda = (struct RXpkt *) sc->p_rda; - rxp = &p_rda[sc->sc_rxmark]; - - while (SRD(rxp->in_use) == 0) { - unsigned status = SRD(rxp->status); - if ((status & RCR_LPKT) == 0) - printf("sonic: more than one packet in RBA!\n"); - - orra = RBASEQ(SRD(rxp->seq_no)) & RRAMASK; - len = SRD(rxp->byte_count) - - sizeof(struct ether_header) - FCSSIZE; - if (status & RCR_PRX) { - if (sonic_read(sc, sc->rbuf[orra & RBAMASK], len)) { - sc->sc_if.if_ipackets++; - sc->sc_sum.ls_ipacks++; - sc->sc_missed = 0; - } - } else - sc->sc_if.if_ierrors++; - - /* - * give receive buffer area back to chip. * - * orra is now empty of packets and can be freed if - * sonic read didnt copy it out then we would have to - * wait !! - * (dont bother add it back in again straight away) + * Really, we're doing p_rra[rramark] = p_rra[orra] but + * we have to use the macros because SONIC might be in + * 16 or 32 bit mode. */ - p_rra[sc->sc_rramark] = p_rra[orra]; + rramark = sc->sc_rramark; + tmp1 = sc->p_rra[rramark]; + tmp2 = sc->p_rra[orra]; + SWO(bitmode, tmp1, RXRSRC_PTRLO, + SRO(bitmode, tmp2, RXRSRC_PTRLO)); + SWO(bitmode, tmp1, RXRSRC_PTRHI, + SRO(bitmode, tmp2, RXRSRC_PTRHI)); + SWO(bitmode, tmp1, RXRSRC_WCLO, + SRO(bitmode, tmp2, RXRSRC_WCLO)); + SWO(bitmode, tmp1, RXRSRC_WCHI, + SRO(bitmode, tmp2, RXRSRC_WCHI)); /* zap old rra for fun */ - p_rra[orra].buff_wchi = 0; - p_rra[orra].buff_wclo = 0; + SWO(bitmode, tmp2, RXRSRC_WCHI, 0); + SWO(bitmode, tmp2, RXRSRC_WCLO, 0); - sc->sc_rramark = (sc->sc_rramark + 1) & RRAMASK; - csr->s_rwp = LOWER(sc->v_rra + - (sc->sc_rramark * sizeof(struct RXrsrc))); + sc->sc_rramark = (++rramark) & RRAMASK; + csr->s_rwp = LOWER(sc->v_rra[rramark]); wbflush(); /* * give receive descriptor back to chip simple * list is circular */ - SWR(rxp->in_use, 1); - SWR(rxp->rlink, SRD(rxp->rlink) | EOL); - SWR(((struct RXpkt *) sc->sc_lrxp)->rlink, - SRD(((struct RXpkt *) sc->sc_lrxp)->rlink) & ~EOL); - sc->sc_lrxp = (void *) rxp; + rdamark = sc->sc_rdamark; + SWO(bitmode, rda, RXPKT_INUSE, 1); + SWO(bitmode, rda, RXPKT_RLINK, + SRO(bitmode, rda, RXPKT_RLINK) | EOL); + SWO(bitmode, sc->p_rda[rdamark], RXPKT_RLINK, + SRO(bitmode, sc->p_rda[rdamark], RXPKT_RLINK) & ~EOL); + sc->sc_rdamark = sc->sc_rxmark; if (++sc->sc_rxmark >= NRDA) sc->sc_rxmark = 0; - rxp = &p_rda[sc->sc_rxmark]; + rda = sc->p_rda[sc->sc_rxmark]; } } @@ -1306,11 +1028,11 @@ sonic_read(sc, pkt, len) struct mbuf *m; /* - * 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. - */ + * 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; if (ethdebug) { @@ -1328,8 +1050,7 @@ sonic_read(sc, pkt, len) /* * Check if there's a bpf filter listening on this interface. * If so, hand off the raw packet to enet, then discard things - * not destined for us (but be sure to keep -broadcast/multicast). + * not destined for us (but be sure to keep broadcast/multicast). */ if (sc->sc_if.if_bpf) { bpf_tap(sc->sc_if.if_bpf, pkt, @@ -1348,7 +1069,7 @@ broadcast/multicast). return(1); } -#define sonicdataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) +#define sonicdataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) /* * munge the received packet into an mbuf chain @@ -1364,9 +1085,9 @@ sonic_get(sc, eh, datalen) struct mbuf *m; struct mbuf *top = 0, **mp = ⊤ int len; - char *spkt = sonicdataaddr(eh, 0, caddr_t); - char *epkt = spkt + datalen; - char *cp = spkt; + char *spkt = sonicdataaddr(eh, 0, caddr_t); + char *epkt = spkt + datalen; + char *cp = spkt; epkt = cp + datalen; MGETHDR(m, M_DONTWAIT, MT_DATA); @@ -1394,8 +1115,8 @@ sonic_get(sc, eh, datalen) len = m->m_len; } else { /* - * Place initial small packet/header at end of mbuf. - */ + * Place initial small packet/header at end of mbuf. + */ if (len < m->m_len) { if (top == 0 && len + max_linkhdr <= m->m_len) m->m_data += max_linkhdr; diff --git a/sys/arch/mac68k/dev/if_sn_nubus.c b/sys/arch/mac68k/dev/if_sn_nubus.c index 3303306940e..832b16e8aaf 100644 --- a/sys/arch/mac68k/dev/if_sn_nubus.c +++ b/sys/arch/mac68k/dev/if_sn_nubus.c @@ -1,5 +1,5 @@ /* $NetBSD$ */ -/* $OpenBSD: if_sn_nubus.c,v 1.1 1997/03/12 13:20:32 briggs Exp $ */ +/* $OpenBSD: if_sn_nubus.c,v 1.2 1997/03/14 14:11:35 briggs Exp $ */ /* * Copyright (C) 1997 Allen Briggs @@ -120,10 +120,13 @@ sn_nubus_attach(parent, self, aux) } sc->sc_regt = bst; - sc->sc_is16 = 0; + sc->bitmode = 1; success = 0; + sc->bitmode = 1; /* 32-bit card */ + sc->slotno = na->slot; + switch (sn_nb_card_vendor(na)) { case AE_VENDOR_DAYNA: sc->s_dcr = DCR_ASYNC | DCR_WAIT0 | DCR_USR1 | @@ -148,7 +151,6 @@ sn_nubus_attach(parent, self, aux) sc->sc_arpcom.ac_enaddr[i] = bus_space_read_1(bst, tmp_bsh, i); - sc->slotno = na->slot; success = 1; break; diff --git a/sys/arch/mac68k/dev/if_sn_obio.c b/sys/arch/mac68k/dev/if_sn_obio.c index 4ecef27780c..0b4d381c564 100644 --- a/sys/arch/mac68k/dev/if_sn_obio.c +++ b/sys/arch/mac68k/dev/if_sn_obio.c @@ -1,5 +1,5 @@ /* $NetBSD$ */ -/* $OpenBSD: if_sn_obio.c,v 1.1 1997/03/12 13:20:32 briggs Exp $ */ +/* $OpenBSD: if_sn_obio.c,v 1.2 1997/03/14 14:11:35 briggs Exp $ */ /* * Copyright (C) 1997 Allen Briggs @@ -96,12 +96,12 @@ sn_obio_attach(parent, self, aux) case MACH_CLASSQ: case MACH_CLASSQ2: sc->s_dcr |= DCR_DW32; - sc->sc_is16 = 0; + sc->bitmode = 1; break; case MACH_CLASSPB: sc->s_dcr |= DCR_DW16; - sc->sc_is16 = 1; + sc->bitmode = 0; return; default: diff --git a/sys/arch/mac68k/dev/if_snvar.h b/sys/arch/mac68k/dev/if_snvar.h index 4fffbb71bbb..e89d0f50966 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.1 1997/03/12 13:20:33 briggs Exp $ */ +/* $OpenBSD: if_snvar.h,v 1.2 1997/03/14 14:11:36 briggs Exp $ */ /* * Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk) @@ -10,6 +10,17 @@ * if_sonic.h -- National Semiconductor DP83932BVF (SONIC) */ +/* + * Memory access macros. Since we handle SONIC in 16 bit mode (PB5X0) + * and 32 bit mode (everything else) using a single GENERIC kernel + * binary, all structures have to be accessed using macros which can + * adjust the offsets appropriately. + */ +#define SWO(m, a, o, x) (m ? (*(u_int32_t *)((u_int32_t *)a + o) = (x)) : \ + (*(u_int16_t *)((u_int16_t *)a + o) = (x))) +#define SRO(m, a, o) (m ? (*(u_int32_t *)((u_int32_t *)a + o) & 0xffff) : \ + (*(u_int16_t *)((u_int16_t *)a + o) & 0xffff)) + /* * buffer sizes in 32 bit mode * 1 TXpkt is 4 hdr words + (3 * FRAGMAX) + 1 link word @@ -19,18 +30,12 @@ * 1 Rda is 4 words == 16 bytes */ -#define NRRA 32 /* # receive resource descriptors */ -#define RRAMASK 0x1f /* the reason why it must be power of two */ - #define NRBA 16 /* # receive buffers < NRRA */ #define RBAMASK 0x0f -#define NRDA NRBA /* # receive descriptors */ +#define NRDA NRBA #define NTDA 4 /* # transmit descriptors */ - -#define CDASIZE sizeof(struct CDA) -#define RRASIZE (NRRA*sizeof(struct RXrsrc)) -#define RDASIZE (NRDA*sizeof(struct RXpkt)) -#define TDASIZE (NTDA*sizeof(struct TXpkt)) +#define NRRA 32 /* # receive resource descriptors */ +#define RRAMASK 0x1f /* the reason why it must be power of two */ #define FCSSIZE 4 /* size of FCS appended to packets */ @@ -38,9 +43,8 @@ * maximum receive packet size plus 2 byte pad to make each * one aligned. 4 byte slop (required for eobc) */ -#define RBASIZE(sc) \ - (sizeof(struct ether_header) + ETHERMTU + FCSSIZE + \ - ((sc)->sc_is16 ? 2 : 6)) +#define RBASIZE(sc) (sizeof(struct ether_header) + ETHERMTU + FCSSIZE + \ + ((sc)->bitmode ? 6 : 2)) /* * transmit buffer area @@ -77,60 +81,70 @@ struct sn_stats { int ls_maxslots; /* max ring slots on transmit */ }; +typedef struct mtd { + void *mtd_txp; + int mtd_vtxp; + unsigned char *mtd_buf; +} mtd_t; + /* * The sn_softc for Mac68k if_sn. */ typedef struct sn_softc { - struct device sc_dev; - struct arpcom sc_arpcom; -#define sc_if sc_arpcom.ac_if /* network visible interface */ -#define sc_enaddr sc_arpcom.ac_enaddr /* hardware ethernet address */ + struct device sc_dev; + struct arpcom sc_arpcom; +#define sc_if sc_arpcom.ac_if /* network visible interface */ +#define sc_enaddr sc_arpcom.ac_enaddr /* hardware ethernet address */ bus_space_tag_t sc_regt; bus_space_handle_t sc_regh; - int sc_is16; - - unsigned int s_dcr; /* DCR for this instance */ - int slotno; + struct sn_stats sc_sum; + short sc_iflags; + unsigned short bitmode; /* 32 bit mode == 1, 16 == 0 */ - struct sonic_reg *sc_csr; /* hardware pointer */ + unsigned int s_dcr; /* DCR 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 bufs */ + 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 */ + int v_rea; /* ptr to the end of the rra space */ - int sc_rramark; /* index into rra of wp */ + int sc_rdamark; + void *p_rda[NRDA]; + int v_rda[NRDA]; - int sc_txhead; /* index of first TDA passed to chip */ - int sc_missed; /* missed packet counter */ + caddr_t rbuf[NRBA]; - int txb_cnt; /* total number of xmit buffers */ - int txb_inuse; /* number of active xmit buffers */ - int txb_new; /* index of next open slot. */ + int sc_txhead; /*XXX idx of first TDA passed to chip */ + int sc_missed; /* missed packet counter */ - void *sc_lrxp; /* last RDA available to chip */ + int txb_cnt; /* total number of xmit buffers */ + int txb_inuse; /* number of active xmit buffers */ + int txb_new; /* index of next open slot. */ - struct sn_stats sc_sum; - short sc_iflags; + struct mtd mtda[NTDA]; + int mtd_hw; /* idx of first mtd given to hw */ + int mtd_prev; /* idx of last mtd given to hardware */ + int mtd_free; /* next free mtd to use */ + int mtd_tlinko; /* + * offset of tlink of last txp given + * to SONIC. Need to clear EOL on + * this word to add a desc. + */ - void *p_rra; /* struct RXrsrc: receiver resource descriptors */ - int v_rra; /* DMA address of rra */ - void *p_rda; /* struct RXpkt: receiver desriptors */ - int v_rda; - void *p_tda; /* struct TXpkt: transmitter descriptors */ - int v_tda; - void *p_cda; /* struct CDA: CAM descriptors */ - int v_cda; /* DMA address of CDA */ + caddr_t tbuf[NTXB]; + int vtbuf[NTXB]; /* DMA address of tbuf */ - void (*rxint) __P((struct sn_softc *)); - void (*txint) __P((struct sn_softc *)); + void *p_cda; + int v_cda; - caddr_t rbuf[NRBA]; - caddr_t tbuf[NTXB]; - int vtbuf[NTXB]; - unsigned char space[(1 + 1 + 8 + 5) * NBPG]; + unsigned char space[(1 + 1 + 8 + 5) * NBPG]; } sn_softc_t; - /* * Accessing SONIC data structures and registers as 32 bit values * makes code endianess independent. The SONIC is however always in @@ -144,41 +158,26 @@ typedef struct sn_softc { * will be received. Note that more than one packet may be * packed into a single buffer if constraints permit. */ -struct RXrsrc { - u_long buff_ptrlo; /* buffer address LO */ - u_long buff_ptrhi; /* buffer address HI */ - u_long buff_wclo; /* buffer size (16bit words) LO */ - u_long buff_wchi; /* buffer size (16bit words) HI */ -}; -struct _short_RXrsrc { - u_short buff_ptrlo; /* buffer address LO */ - u_short buff_ptrhi; /* buffer address HI */ - u_short buff_wclo; /* buffer size (16bit words) LO */ - u_short buff_wchi; /* buffer size (16bit words) HI */ -}; +#define RXRSRC_PTRLO 0 /* buffer address LO */ +#define RXRSRC_PTRHI 1 /* buffer address HI */ +#define RXRSRC_WCLO 2 /* buffer size (16bit words) LO */ +#define RXRSRC_WCHI 3 /* buffer size (16bit words) HI */ + +#define RXRSRC_SIZE(sc) (sc->bitmode ? (4 * 4) : (4 * 2)) /* * Receive Descriptor * This structure holds information about packets received. */ -struct RXpkt { - u_long status; /* + receive status */ - u_long byte_count; /* + packet byte count (including FCS) */ - u_long pkt_ptrlo; /* + packet data LO (in RBA) */ - u_long pkt_ptrhi; /* + packet data HI (in RBA) */ - u_long seq_no; /* + RBA sequence numbers */ - u_long rlink; /* link to next receive descriptor */ - u_long in_use; /* + packet available to SONIC */ -}; -struct _short_RXpkt { - u_short status; /* + receive status */ - u_short byte_count; /* + packet byte count (including FCS) */ - u_short pkt_ptrlo; /* + packet data LO (in RBA) */ - u_short pkt_ptrhi; /* + packet data HI (in RBA) */ - u_short seq_no; /* + RBA sequence numbers */ - u_short rlink; /* link to next receive descriptor */ - u_short in_use; /* + packet available to SONIC */ -}; +#define RXPKT_STATUS 0 +#define RXPKT_BYTEC 1 +#define RXPKT_PTRLO 2 +#define RXPKT_PTRHI 3 +#define RXPKT_SEQNO 4 +#define RXPKT_RLINK 5 +#define RXPKT_INUSE 6 +#define RXPKT_SIZE(sc) (sc->bitmode ? (7 * 4) : (7 * 2)) + #define RBASEQ(x) (((x)>>8)&0xff) #define PSNSEQ(x) ((x) & 0xff) @@ -186,54 +185,36 @@ struct _short_RXpkt { * Transmit Descriptor * This structure holds information about packets to be transmitted. */ -#define FRAGMAX 16 /* maximum number of fragments in a packet */ -struct TXpkt { - u_long status; /* + transmitted packet status */ - u_long config; /* transmission configuration */ - u_long pkt_size; /* entire packet size in bytes */ - u_long frag_count; /* # fragments in packet */ - struct { - u_long frag_ptrlo; /* pointer to packet fragment LO */ - u_long frag_ptrhi; /* pointer to packet fragment HI */ - u_long frag_size; /* fragment size */ - } u[FRAGMAX]; - u_long :32; /* This makes tcp->u[FRAGMAX].u_link.link valid! */ -}; -struct _short_TXpkt { - u_short status; /* + transmitted packet status */ - u_short config; /* transmission configuration */ - u_short pkt_size; /* entire packet size in bytes */ - u_short frag_count; /* # fragments in packet */ - struct { - u_short frag_ptrlo; /* pointer to packet fragment LO */ - u_short frag_ptrhi; /* pointer to packet fragment HI */ - u_short frag_size; /* fragment size */ - } u[FRAGMAX]; - u_short :16; /* This makes tcp->u[FRAGMAX].u_link.link valid! */ -}; +#define FRAGMAX 16 /* maximum number of fragments in a packet */ -#define tlink frag_ptrlo +#define TXP_STATUS 0 /* + transmitted packet status */ +#define TXP_CONFIG 1 /* transmission configuration */ +#define TXP_PKTSIZE 2 /* entire packet size in bytes */ +#define TXP_FRAGCNT 3 /* # fragments in packet */ -#define EOL 0x0001 /* end of list marker for link fields */ +#define TXP_FRAGOFF 4 /* offset to first fragment */ +#define TXP_FRAGSIZE 3 /* size of each fragment desc */ +#define TXP_FPTRLO 0 /* ptr to packet fragment LO */ +#define TXP_FPTRHI 1 /* ptr to packet fragment HI */ +#define TXP_FSIZE 2 /* fragment size */ -#define MAXCAM 16 /* number of user entries in CAM */ -struct CDA { - struct { - u_long cam_ep; /* CAM Entry Pointer */ - u_long cam_ap0; /* CAM Address Port 0 xx-xx-xx-xx-YY-YY */ - u_long cam_ap1; /* CAM Address Port 1 xx-xx-YY-YY-xxxx */ - u_long cam_ap2; /* CAM Address Port 2 YY-YY-xx-xx-xx-xx */ - } desc[MAXCAM]; - u_long enable; /* mask enabling CAM entries */ -}; -struct _short_CDA { - struct { - u_short cam_ep; /* CAM Entry Pointer */ - u_short cam_ap0; /* CAM Address Port 0 xx-xx-xx-xx-YY-YY */ - u_short cam_ap1; /* CAM Address Port 1 xx-xx-YY-YY-xxxx */ - u_short cam_ap2; /* CAM Address Port 2 YY-YY-xx-xx-xx-xx */ - } desc[MAXCAM]; - u_short enable; /* mask enabling CAM entries */ -}; +#define TXP_WORDS TXP_FRAGOFF + FRAGMAX*TXP_FSIZE + 1 /* 1 for tlink */ +#define TXP_SIZE(sc) ((sc->bitmode) ? (TXP_WORDS*4) : (TXP_WORDS*2)) + +#define EOL 0x0001 /* end of list marker for link fields */ + +/* + * CDA, the CAM descriptor area. The SONIC has a 16 entry CAM to + * match incoming addresses against. It is programmed via DMA + * from a memory region. + */ +#define MAXCAM 16 /* number of user entries in CAM */ +#define CDA_CAMDESC 4 /* # words i na descriptor */ +#define CDA_CAMEP 0 /* CAM Address Port 0 xx-xx-xx-xx-YY-YY */ +#define CDA_CAMAP0 1 /* CAM Address Port 1 xx-xx-YY-YY-xx-xx */ +#define CDA_CAMAP1 2 /* CAM Address Port 2 YY-YY-xx-xx-xx-xx */ +#define CDA_CAMAP2 3 +#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));