summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1998-09-01 17:37:02 +0000
committerJason Wright <jason@cvs.openbsd.org>1998-09-01 17:37:02 +0000
commita51ed623750f76b3b40d6ebda689df590b076d70 (patch)
treead3ee132e255eaea203aee2738be9598d13abc96
parent24e373b7dc1e348161e9bdec0b1505a859da1a9a (diff)
o Removed dependence on stp2002 (not sharable with qec+be)
o Added collision counters o Should work on sun4c
-rw-r--r--sys/arch/sparc/conf/files.sparc3
-rw-r--r--sys/arch/sparc/dev/hme.c374
-rw-r--r--sys/arch/sparc/dev/hmereg.h44
-rw-r--r--sys/arch/sparc/dev/hmevar.h8
-rw-r--r--sys/arch/sparc/dev/stp2002base.c383
-rw-r--r--sys/arch/sparc/dev/stp2002var.h92
6 files changed, 374 insertions, 530 deletions
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index a74239ba34d..9775c739b3d 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc,v 1.20 1998/08/26 05:00:49 jason Exp $
+# $OpenBSD: files.sparc,v 1.21 1998/09/01 17:36:58 jason Exp $
# $NetBSD: files.sparc,v 1.44 1997/08/31 21:29:16 pk Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
@@ -117,7 +117,6 @@ file arch/sparc/dev/me.c me
device hme
attach hme at sbus
file arch/sparc/dev/hme.c hme
-file arch/sparc/dev/stp2002base.c hme
device esp: scsi, ncr53c9x
attach esp at sbus, dma, obio
diff --git a/sys/arch/sparc/dev/hme.c b/sys/arch/sparc/dev/hme.c
index 06583bf08e1..317aa69b0f1 100644
--- a/sys/arch/sparc/dev/hme.c
+++ b/sys/arch/sparc/dev/hme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hme.c,v 1.4 1998/07/17 21:33:07 jason Exp $ */
+/* $OpenBSD: hme.c,v 1.5 1998/09/01 17:36:59 jason Exp $ */
/*
* Copyright (c) 1998 Jason L. Wright (jason@thought.net)
@@ -72,7 +72,6 @@
#include <sparc/sparc/cpuvar.h>
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h> /* for SBUS_BURST_* */
-#include <sparc/dev/stp2002var.h>
#include <sparc/dev/hmereg.h>
#include <sparc/dev/hmevar.h>
@@ -85,6 +84,7 @@ void hmereset __P((struct hme_softc *));
void hmestart __P((struct ifnet *));
void hmestop __P((struct hme_softc *));
void hmeinit __P((struct hme_softc *));
+void hme_meminit __P((struct hme_softc *));
static void hme_tcvr_write __P((struct hme_softc *, int reg,
u_short val));
@@ -99,6 +99,8 @@ static int hme_tcvr_reset __P((struct hme_softc *));
static void hme_poll_stop __P((struct hme_softc *sc));
+static int hme_rint __P((struct hme_softc *));
+static int hme_tint __P((struct hme_softc *));
static int hme_mint __P((struct hme_softc *, u_int32_t));
static int hme_eint __P((struct hme_softc *, u_int32_t));
@@ -110,7 +112,10 @@ static void hme_set_initial_advertisement __P((struct hme_softc *));
static void hme_reset_rx __P((struct hme_softc *));
static void hme_reset_tx __P((struct hme_softc *));
-static void hme_tx_dmawakeup __P((void *v));
+
+static struct mbuf * hme_get __P((struct hme_softc *, int, int));
+static void hme_read __P((struct hme_softc *, int, int));
+static int hme_put __P((struct hme_softc *, int, struct mbuf *));
static void hme_mcreset __P((struct hme_softc *));
@@ -145,13 +150,14 @@ hmeattach(parent, self, aux)
{
struct confargs *ca = aux;
struct hme_softc *sc = (struct hme_softc *)self;
- struct ifnet *ifp = &sc->sc_stp.stp_arpcom.ac_if;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
int pri;
/* XXX the following declaration should be elsewhere */
extern void myetheraddr __P((u_char *));
if (ca->ca_ra.ra_nintr != 1) {
- printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
+ printf(": expected 1 interrupt, got %d\n",
+ ca->ca_ra.ra_nintr);
return;
}
pri = ca->ca_ra.ra_intr[0].int_pri;
@@ -184,8 +190,7 @@ hmeattach(parent, self, aux)
sc->sc_burst = ((struct sbus_softc *)parent)->sc_burst;
- sc->sc_stp.stp_tx_dmawakeup = hme_tx_dmawakeup;
- stp2002_meminit(&sc->sc_stp);
+ hme_meminit(sc);
hme_set_initial_advertisement(sc);
@@ -200,8 +205,8 @@ hmeattach(parent, self, aux)
* Otherwise, use the machine's builtin MAC.
*/
if (getprop(ca->ca_ra.ra_node, "local-mac-address",
- sc->sc_stp.stp_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0) {
- myetheraddr(sc->sc_stp.stp_arpcom.ac_enaddr);
+ sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0) {
+ myetheraddr(sc->sc_arpcom.ac_enaddr);
}
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
@@ -220,7 +225,7 @@ hmeattach(parent, self, aux)
sc->sc_an_ticks = 0;
printf(" pri %d: address %s rev %d\n", pri,
- ether_sprintf(sc->sc_stp.stp_arpcom.ac_enaddr), sc->sc_rev);
+ ether_sprintf(sc->sc_arpcom.ac_enaddr), sc->sc_rev);
#if NBPFILTER > 0
bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
@@ -240,18 +245,51 @@ void
hmestart(ifp)
struct ifnet *ifp;
{
- struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;
+ struct hme_softc *sc = ifp->if_softc;
+ struct mbuf *m;
+ int bix, len;
- stp2002_start(&sc->sc_stp);
-}
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+ return;
-void
-hme_tx_dmawakeup(v)
- void *v;
-{
- struct hme_softc *sc = (struct hme_softc *)v;
+ bix = sc->sc_last_td;
+
+ for (;;) {
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (m == 0)
+ break;
+#if NBPFILTER > 0
+ /*
+ * If BPF is listening on this interface, let it see the
+ * packet before we commit it to the wire.
+ */
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m);
+#endif
+
+ /*
+ * Copy the mbuf chain into the transmit buffer.
+ */
+ len = hme_put(sc, bix, m);
+
+ /*
+ * Initialize transmit registers and start transmission.
+ */
+ sc->sc_desc->hme_txd[bix].tx_flags =
+ HME_TXD_OWN | HME_TXD_SOP | HME_TXD_EOP |
+ (len & HME_TXD_SIZE);
+ sc->sc_txr->tx_pnding = TXR_TP_DMAWAKEUP;
+
+ if (++bix == HME_TX_RING_SIZE)
+ bix = 0;
- sc->sc_txr->tx_pnding = TXR_TP_DMAWAKEUP;
+ if (++sc->sc_no_td == HME_TX_RING_SIZE) {
+ ifp->if_flags |= IFF_OACTIVE;
+ break;
+ }
+ }
+
+ sc->sc_last_td = bix;
}
#define MAX_STOP_TRIES 16
@@ -295,7 +333,7 @@ hmewatchdog(ifp)
struct hme_softc *sc = ifp->if_softc;
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
- ++sc->sc_stp.stp_arpcom.ac_if.if_oerrors;
+ ++sc->sc_arpcom.ac_if.if_oerrors;
hmereset(sc);
}
@@ -313,7 +351,7 @@ hmeioctl(ifp, cmd, data)
s = splimp();
- if ((error = ether_ioctl(ifp, &sc->sc_stp.stp_arpcom, cmd, data)) > 0) {
+ if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
splx(s);
return error;
}
@@ -325,7 +363,7 @@ hmeioctl(ifp, cmd, data)
#ifdef INET
case AF_INET:
hmeinit(sc);
- arp_ifinit(&sc->sc_stp.stp_arpcom, ifa);
+ arp_ifinit(&sc->sc_arpcom, ifa);
break;
#endif /* INET */
#ifdef NS
@@ -336,11 +374,11 @@ hmeioctl(ifp, cmd, data)
if (ns_nullhost(*ina))
ina->x_host =
- *(union ns_host *)(sc->sc_stp.stp_arpcom.ac_enaddr);
+ *(union ns_host *)(sc->sc_arpcom.ac_enaddr);
else
bcopy(ina->x_host.c_host,
- sc->sc_stp.stp_arpcom.ac_enaddr,
- sizeof(sc->sc_stp.stp_arpcom.ac_enaddr));
+ sc->sc_arpcom.ac_enaddr,
+ sizeof(sc->sc_arpcom.ac_enaddr));
/* Set new address. */
hmeinit(sc);
break;
@@ -388,8 +426,8 @@ hmeioctl(ifp, cmd, data)
case SIOCADDMULTI:
case SIOCDELMULTI:
error = (cmd == SIOCADDMULTI) ?
- ether_addmulti(ifr, &sc->sc_stp.stp_arpcom):
- ether_delmulti(ifr, &sc->sc_stp.stp_arpcom);
+ ether_addmulti(ifr, &sc->sc_arpcom):
+ ether_delmulti(ifr, &sc->sc_arpcom);
if (error == ENETRESET) {
/*
@@ -408,6 +446,44 @@ hmeioctl(ifp, cmd, data)
}
void
+hme_meminit(sc)
+ struct hme_softc *sc;
+{
+ struct hme_desc *desc;
+ int i;
+
+ if (sc->sc_desc_dva == NULL)
+ sc->sc_desc_dva = (struct hme_desc *) dvma_malloc(
+ sizeof(struct hme_desc), &sc->sc_desc, M_NOWAIT);
+ if (sc->sc_bufs_dva == NULL)
+ sc->sc_bufs_dva = (struct hme_bufs *) dvma_malloc(
+ sizeof(struct hme_bufs), &sc->sc_bufs, M_NOWAIT);
+
+ desc = sc->sc_desc;
+
+ /*
+ * Setup TX descriptors
+ */
+ sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
+ for (i = 0; i < HME_TX_RING_SIZE; i++) {
+ desc->hme_txd[i].tx_addr =
+ (u_int32_t) &sc->sc_bufs_dva->tx_buf[i][0];
+ desc->hme_txd[i].tx_flags = 0;
+ }
+
+ /*
+ * Setup RX descriptors
+ */
+ sc->sc_last_rd = 0;
+ for (i = 0; i < HME_RX_RING_SIZE; i++) {
+ desc->hme_rxd[i].rx_addr =
+ (u_int32_t) &sc->sc_bufs_dva->rx_buf[i][0];
+ desc->hme_rxd[i].rx_flags = HME_RXD_OWN |
+ ((HME_RX_PKT_BUF_SZ - HME_RX_OFFSET) << 16);
+ }
+}
+
+void
hmeinit(sc)
struct hme_softc *sc;
{
@@ -421,7 +497,7 @@ hmeinit(sc)
hme_poll_stop(sc);
hmestop(sc);
- stp2002_meminit(&sc->sc_stp);
+ hme_meminit(sc);
tcvr->int_mask = 0xffff;
@@ -448,14 +524,14 @@ hmeinit(sc)
hme_reset_tx(sc);
hme_reset_rx(sc);
- cr->rand_seed = sc->sc_stp.stp_arpcom.ac_enaddr[5] |
- ((sc->sc_stp.stp_arpcom.ac_enaddr[4] << 8) & 0x3f00);
- cr->mac_addr0 = (sc->sc_stp.stp_arpcom.ac_enaddr[0] << 8) |
- sc->sc_stp.stp_arpcom.ac_enaddr[1];
- cr->mac_addr1 = (sc->sc_stp.stp_arpcom.ac_enaddr[2] << 8) |
- sc->sc_stp.stp_arpcom.ac_enaddr[3];
- cr->mac_addr2 = (sc->sc_stp.stp_arpcom.ac_enaddr[4] << 8) |
- sc->sc_stp.stp_arpcom.ac_enaddr[5];
+ cr->rand_seed = sc->sc_arpcom.ac_enaddr[5] |
+ ((sc->sc_arpcom.ac_enaddr[4] << 8) & 0x3f00);
+ cr->mac_addr0 = (sc->sc_arpcom.ac_enaddr[0] << 8) |
+ sc->sc_arpcom.ac_enaddr[1];
+ cr->mac_addr1 = (sc->sc_arpcom.ac_enaddr[2] << 8) |
+ sc->sc_arpcom.ac_enaddr[3];
+ cr->mac_addr2 = (sc->sc_arpcom.ac_enaddr[4] << 8) |
+ sc->sc_arpcom.ac_enaddr[5];
cr->jsize = HME_DEFAULT_JSIZE;
cr->ipkt_gap1 = HME_DEFAULT_IPKT_GAP1;
@@ -465,8 +541,8 @@ hmeinit(sc)
cr->htable1 = 0;
cr->htable0 = 0;
- rxr->rx_ring = sc->sc_stp.stp_rx_dvma;
- txr->tx_ring = sc->sc_stp.stp_tx_dvma;
+ rxr->rx_ring = (u_int32_t)&sc->sc_desc_dva->hme_rxd[0];
+ txr->tx_ring = (u_int32_t)&sc->sc_desc_dva->hme_txd[0];
if (sc->sc_burst & SBUS_BURST_64)
gr->cfg = GR_CFG_BURST64;
@@ -482,20 +558,20 @@ hmeinit(sc)
gr->imask = GR_IMASK_SENTFRAME | GR_IMASK_TXPERR |
GR_IMASK_GOTFRAME | GR_IMASK_RCNTEXP;
- txr->tx_rsize = (STP_TX_RING_SIZE >> TXR_RSIZE_SHIFT) - 1;
+ txr->tx_rsize = (HME_TX_RING_SIZE >> TXR_RSIZE_SHIFT) - 1;
txr->cfg |= TXR_CFG_DMAENABLE;
- c = RXR_CFG_DMAENABLE | (STP_RX_OFFSET << 3) | (STP_RX_CSUMLOC << 16);
-#if STP_RX_RING_SIZE == 32
+ c = RXR_CFG_DMAENABLE | (HME_RX_OFFSET << 3) | (HME_RX_CSUMLOC << 16);
+#if HME_RX_RING_SIZE == 32
c |= RXR_CFG_RINGSIZE32;
-#elif STP_RX_RING_SIZE == 64
+#elif HME_RX_RING_SIZE == 64
c |= RXR_CFG_RINGSIZE64;
-#elif STP_RX_RING_SIZE == 128
+#elif HME_RX_RING_SIZE == 128
c |= RXR_CFG_RINGSIZE128;
-#elif STP_RX_RING_SIZE == 256
+#elif HME_RX_RING_SIZE == 256
c |= RXR_CFG_RINGSIZE256;
#else
-#error "STP_RX_RING_SIZE must be 32, 64, 128, or 256."
+#error "HME_RX_RING_SIZE must be 32, 64, 128, or 256."
#endif
rxr->cfg = c;
DELAY(20);
@@ -983,7 +1059,7 @@ hme_negotiate_watchdog(arg)
void *arg;
{
struct hme_softc *sc = (struct hme_softc *)arg;
- struct ifnet *ifp = &sc->sc_stp.stp_arpcom.ac_if;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
sc->sc_an_ticks++;
switch (sc->sc_an_state) {
@@ -1096,6 +1172,92 @@ hme_mint(sc, why)
}
/*
+ * transmit interrupt
+ */
+static int
+hme_tint(sc)
+ struct hme_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct hme_cr *cr = sc->sc_cr;
+ int bix;
+ struct hme_txd txd;
+
+ /*
+ * Get collision counters
+ */
+ ifp->if_collisions += cr->ex_ctr + cr->lt_ctr + cr->fc_ctr + cr->nc_ctr;
+ cr->ex_ctr = 0;
+ cr->lt_ctr = 0;
+ cr->fc_ctr = 0;
+ cr->nc_ctr = 0;
+
+ bix = sc->sc_first_td;
+
+ for (;;) {
+ if (sc->sc_no_td <= 0)
+ break;
+
+ bcopy(&sc->sc_desc->hme_txd[bix], &txd, sizeof(txd));
+
+ if (txd.tx_flags & HME_TXD_OWN)
+ break;
+
+ ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_opackets++;
+
+ if (++bix == HME_TX_RING_SIZE)
+ bix = 0;
+
+ --sc->sc_no_td;
+ }
+
+ sc->sc_first_td = bix;
+
+ hmestart(ifp);
+
+ if (sc->sc_no_td == 0)
+ ifp->if_timer = 0;
+
+ return 1;
+}
+
+static int
+hme_rint(sc)
+ struct hme_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int bix, len;
+ struct hme_rxd rxd;
+
+ bix = sc->sc_last_rd;
+
+ for (;;) {
+ bcopy(&sc->sc_desc->hme_rxd[bix], &rxd, sizeof(rxd));
+ len = rxd.rx_flags >> 16;
+
+ if (rxd.rx_flags & HME_RXD_OWN)
+ break;
+
+ if (rxd.rx_flags & HME_RXD_OVERFLOW)
+ ifp->if_ierrors++;
+ else
+ hme_read(sc, bix, len);
+
+ rxd.rx_flags = HME_RXD_OWN |
+ ((HME_RX_PKT_BUF_SZ - HME_RX_OFFSET) << 16);
+ bcopy(&rxd, &sc->sc_desc->hme_rxd[bix], sizeof(rxd));
+
+ if (++bix == HME_RX_RING_SIZE)
+ bix = 0;
+ }
+
+ sc->sc_last_rd = bix;
+
+ return 1;
+}
+
+/*
* error interrupt
*/
static int
@@ -1192,14 +1354,126 @@ hmeintr(v)
r |= hme_mint(sc, why);
if (why & (GR_STAT_TXALL | GR_STAT_HOSTTOTX))
- r |= stp2002_tint(&sc->sc_stp);
+ r |= hme_tint(sc);
if (why & GR_STAT_RXTOHOST)
- r |= stp2002_rint(&sc->sc_stp);
+ r |= hme_rint(sc);
return (r);
}
+static struct mbuf *
+hme_get(sc, idx, totlen)
+ struct hme_softc *sc;
+ int idx, totlen;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct mbuf *m;
+ struct mbuf *top, **mp;
+ int len, pad, boff = 0;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return NULL;
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = totlen;
+ pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
+ m->m_data += pad;
+ len = MHLEN - pad;
+ top = NULL;
+ mp = &top;
+
+ while (totlen > 0) {
+ if (top) {
+ MGET(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ m_freem(top);
+ return NULL;
+ }
+ len = MLEN;
+ }
+ if (top && totlen >= MINCLSIZE) {
+ MCLGET(m, M_DONTWAIT);
+ if (m->m_flags & M_EXT)
+ len = MCLBYTES;
+ }
+ m->m_len = len = min(totlen, len);
+ bcopy(&sc->sc_bufs->rx_buf[idx][boff + HME_RX_OFFSET],
+ mtod(m, caddr_t), len);
+ boff += len;
+ totlen -= len;
+ *mp = m;
+ mp = &m->m_next;
+ }
+
+ return top;
+}
+
+static int
+hme_put(sc, idx, m)
+ struct hme_softc *sc;
+ int idx;
+ struct mbuf *m;
+{
+ struct mbuf *n;
+ int len, tlen = 0, boff = 0;
+
+ for (; m; m = n) {
+ len = m->m_len;
+ if (len == 0) {
+ MFREE(m, n);
+ continue;
+ }
+ bcopy(mtod(m, caddr_t), &sc->sc_bufs->tx_buf[idx][boff], len);
+ boff += len;
+ tlen += len;
+ MFREE(m, n);
+ }
+ return tlen;
+}
+
+static void
+hme_read(sc, idx, len)
+ struct hme_softc *sc;
+ int idx, len;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct ether_header *eh;
+ struct mbuf *m;
+
+ if (len <= sizeof(struct ether_header) ||
+ len > ETHERMTU + sizeof(struct ether_header)) {
+ printf("%s: invalid packet size %d; dropping\n",
+ ifp->if_xname, len);
+ ifp->if_ierrors++;
+ return;
+ }
+
+ /* Pull packet off interface. */
+ m = hme_get(sc, idx, len);
+ if (m == NULL) {
+ ifp->if_ierrors++;
+ return;
+ }
+
+ ifp->if_ipackets++;
+
+ /* We assume that the header fit entirely in one mbuf. */
+ eh = mtod(m, struct ether_header *);
+
+#if NBPFILTER > 0
+ /*
+ * Check if there's a BPF listener on this interface.
+ * If so, hand off the raw packet to BPF.
+ */
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m);
+#endif
+ /* Pass the packet up, with the ether header sort-of removed. */
+ m_adj(m, sizeof(struct ether_header));
+ ether_input(ifp, eh, m);
+}
+
/*
* Program the multicast receive filter.
*/
@@ -1207,8 +1481,8 @@ static void
hme_mcreset(sc)
struct hme_softc *sc;
{
- struct arpcom *ac = &sc->sc_stp.stp_arpcom;
- struct ifnet *ifp = &sc->sc_stp.stp_arpcom.ac_if;
+ struct arpcom *ac = &sc->sc_arpcom;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
struct hme_cr *cr = sc->sc_cr;
struct ether_multi *enm;
struct ether_multistep step;
diff --git a/sys/arch/sparc/dev/hmereg.h b/sys/arch/sparc/dev/hmereg.h
index ac5327dba67..b54a903e407 100644
--- a/sys/arch/sparc/dev/hmereg.h
+++ b/sys/arch/sparc/dev/hmereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hmereg.h,v 1.4 1998/07/17 21:33:08 jason Exp $ */
+/* $OpenBSD: hmereg.h,v 1.5 1998/09/01 17:36:59 jason Exp $ */
/*
* Copyright (c) 1998 Jason L. Wright (jason@thought.net)
@@ -357,6 +357,48 @@ struct hme_swr {
#define HME_TIMER_AUTONEG 1 /* autonegotiating */
#define HME_TIMER_LINKUP 2 /* waiting for link up */
+struct hme_rxd {
+ volatile u_int32_t rx_flags;
+ volatile u_int32_t rx_addr;
+};
+#define HME_RXD_OWN 0x80000000 /* desc owner: 1=hw,0=sw */
+#define HME_RXD_OVERFLOW 0x40000000 /* 1 = buffer over flow */
+#define HME_RXD_SIZE 0x3fff0000 /* desciptor size */
+#define HME_RXD_CSUM 0x0000ffff /* checksum mask */
+
+struct hme_txd {
+ volatile u_int32_t tx_flags;
+ volatile u_int32_t tx_addr;
+};
+#define HME_TXD_OWN 0x80000000 /* desc owner: 1=hw,0=sw */
+#define HME_TXD_SOP 0x40000000 /* 1 = start of pkt */
+#define HME_TXD_EOP 0x20000000 /* 1 = end of pkt */
+#define HME_TXD_CSENABLE 0x10000000 /* 1 = use hw checksums */
+#define HME_TXD_CSLOCATION 0x0ff00000 /* checksum location mask */
+#define HME_TXD_CSBUFBEGIN 0x000fc000 /* checksum begin mask */
+#define HME_TXD_SIZE 0x00003fff /* pkt size mask */
+
+#define HME_RX_RING_SIZE 32 /* Must be 32,64,128, or 256 */
+#define HME_TX_RING_SIZE 32 /* 16<=x<=256 and div by 16 */
+#define HME_RX_RING_MAX 256 /* maximum ring size: rx */
+#define HME_TX_RING_MAX 256 /* maximum ring size: tx */
+#define HME_RX_PKT_BUF_SZ 2048 /* size of a rx buffer */
+#define HME_RX_OFFSET 2 /* packet offset */
+#define HME_RX_CSUMLOC 0x00 /* checksum location */
+#define HME_TX_PKT_BUF_SZ 1546 /* size of a tx buffer */
+#define HME_RX_ALIGN_SIZE 64 /* XXX rx bufs must align 64 */
+#define HME_RX_ALIGN_MASK (~(RX_ALIGN_SIZE - 1))
+
+struct hme_desc {
+ struct hme_rxd hme_rxd[HME_RX_RING_MAX];
+ struct hme_txd hme_txd[HME_TX_RING_MAX];
+};
+
+struct hme_bufs {
+ char rx_buf[HME_RX_RING_SIZE][HME_RX_PKT_BUF_SZ];
+ char tx_buf[HME_TX_RING_SIZE][HME_TX_PKT_BUF_SZ];
+};
+
/*
* National Semiconductor DP83840A chip definitions
* Documentation available from National at:
diff --git a/sys/arch/sparc/dev/hmevar.h b/sys/arch/sparc/dev/hmevar.h
index 8f18d2a76dd..ac597485bbf 100644
--- a/sys/arch/sparc/dev/hmevar.h
+++ b/sys/arch/sparc/dev/hmevar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hmevar.h,v 1.2 1998/07/17 21:33:10 jason Exp $ */
+/* $OpenBSD: hmevar.h,v 1.3 1998/09/01 17:36:59 jason Exp $ */
/*
* Copyright (c) 1998 Jason L. Wright (jason@thought.net)
@@ -36,6 +36,7 @@ struct hme_softc {
struct sbusdev sc_sd; /* sbus device */
struct intrhand sc_ih; /* interrupt vectoring */
int sc_node; /* which sbus node */
+ struct arpcom sc_arpcom;
/*
* Register sets
@@ -60,5 +61,8 @@ struct hme_softc {
/*
* RX/TX ring buffers, descriptors, and counters
*/
- struct stp_base sc_stp;
+ struct hme_desc *sc_desc, *sc_desc_dva; /* ring descriptors */
+ struct hme_bufs *sc_bufs, *sc_bufs_dva; /* packet buffers */
+ int sc_first_td, sc_last_td, sc_no_td; /* tx counters */
+ int sc_last_rd; /* rx counters */
};
diff --git a/sys/arch/sparc/dev/stp2002base.c b/sys/arch/sparc/dev/stp2002base.c
deleted file mode 100644
index 5921d4629f4..00000000000
--- a/sys/arch/sparc/dev/stp2002base.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* $OpenBSD: stp2002base.c,v 1.2 1998/07/22 17:27:15 jason Exp $ */
-
-/*
- * Copyright (c) 1998 Jason L. Wright (jason@thought.net)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jason L. Wright
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Driver for the STP2002QFP chips found in both the hme and qec+be ethernet
- * controllers.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-#include <sys/device.h>
-#include <sys/malloc.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-#include <net/netisr.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#include "bpfilter.h"
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#include <net/bpfdesc.h>
-#endif
-
-#include <sparc/dev/stp2002var.h>
-
-static struct mbuf *stp2002_get __P((struct stp_base *, int, int));
-static int stp2002_put __P((struct stp_base *, int, struct mbuf *));
-static void stp2002_read __P((struct stp_base *, int, int));
-
-/*
- * Allocate and initialize buffers and descriptor rings
- */
-void
-stp2002_meminit(stp)
- struct stp_base *stp;
-{
- struct stp_desc *desc;
- int i;
-
- if (stp->stp_desc_dva == NULL)
- stp->stp_desc_dva = (struct stp_desc *) dvma_malloc(
- sizeof(struct stp_desc), &(stp->stp_desc), M_NOWAIT);
-
- if (stp->stp_bufs_dva == NULL)
- stp->stp_bufs_dva = (struct stp_bufs *) dvma_malloc(
- sizeof(struct stp_bufs) + STP_RX_ALIGN_SIZE,
- &(stp->stp_bufs),
- M_NOWAIT); /* XXX must be aligned on 64 byte boundary */
-
-
- stp->stp_rx_dvma = (u_int32_t)&stp->stp_desc_dva->stp_rxd[0];
- stp->stp_tx_dvma = (u_int32_t)&stp->stp_desc_dva->stp_txd[0];
-
- desc = stp->stp_desc;
-
- /* setup tx descriptors */
- stp->stp_first_td = stp->stp_last_td = stp->stp_no_td = 0;
- for (i = 0; i < STP_TX_RING_SIZE; i++) {
- stp->stp_desc->stp_txd[i].tx_addr =
- (u_int32_t) &stp->stp_bufs_dva->tx_buf[i][0];
- desc->stp_txd[i].tx_flags = 0;
- }
-
- /* setup rx descriptors */
- stp->stp_last_rd = 0;
- for (i = 0; i < STP_RX_RING_SIZE; i++) {
- desc->stp_rxd[i].rx_addr =
- (u_int32_t) &stp->stp_bufs_dva->rx_buf[i][0];
- desc->stp_rxd[i].rx_flags =
- STP_RXFLAG_OWN |
- ((STP_RX_PKT_BUF_SZ - STP_RX_OFFSET) << 16);
- }
-}
-
-/*
- * Pull data off an interface.
- * Len is the length of data, with local net header stripped.
- * We copy the data into mbufs. When full cluster sized units are present,
- * we copy into clusters.
- */
-static struct mbuf *
-stp2002_get(stp, idx, totlen)
- struct stp_base *stp;
- int idx, totlen;
-{
- struct ifnet *ifp = &stp->stp_arpcom.ac_if;
- struct mbuf *m;
- struct mbuf *top, **mp;
- int len, pad, boff = 0;
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (NULL);
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = totlen;
- pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
- m->m_data += pad;
- len = MHLEN - pad;
- top = NULL;
- mp = &top;
-
- while (totlen > 0) {
- if (top) {
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- m_freem(top);
- return NULL;
- }
- len = MLEN;
- }
- if (top && totlen >= MINCLSIZE) {
- MCLGET(m, M_DONTWAIT);
- if (m->m_flags & M_EXT)
- len = MCLBYTES;
- }
- m->m_len = len = min(totlen, len);
- bcopy(&(stp->stp_bufs->rx_buf[idx][boff + STP_RX_OFFSET]),
- mtod(m, caddr_t), len);
- boff += len;
- totlen -= len;
- *mp = m;
- mp = &m->m_next;
- }
-
- return (top);
-}
-
-static int
-stp2002_put(stp, idx, m)
- struct stp_base *stp;
- int idx;
- struct mbuf *m;
-{
- struct mbuf *n;
- int len, tlen = 0, boff = 0;
-
- for (; m; m = n) {
- len = m->m_len;
- if (len == 0) {
- MFREE(m, n);
- continue;
- }
- bcopy(mtod(m, caddr_t), &(stp->stp_bufs->tx_buf[idx][boff]), len);
- boff += len;
- tlen += len;
- MFREE(m, n);
- }
- return tlen;
-}
-
-/*
- * receive interrupt
- */
-int
-stp2002_rint(stp)
- struct stp_base *stp;
-{
- struct ifnet *ifp = &stp->stp_arpcom.ac_if;
- int bix, len;
- struct stp_rxd rxd;
-
- bix = stp->stp_last_rd;
-
- /* Process all buffers with valid data. */
- for (;;) {
- bcopy(&(stp->stp_desc->stp_rxd[bix]), &rxd, sizeof(rxd));
- len = rxd.rx_flags >> 16;
-
- if (rxd.rx_flags & STP_RXFLAG_OWN)
- break;
-
- if (rxd.rx_flags & STP_RXFLAG_OVERFLOW)
- ifp->if_ierrors++;
- else
- stp2002_read(stp, bix, len);
-
- rxd.rx_flags = STP_RXFLAG_OWN |
- ((STP_RX_PKT_BUF_SZ - STP_RX_OFFSET) << 16);
- bcopy(&rxd, &(stp->stp_desc->stp_rxd[bix]), sizeof(rxd));
-
- if (++bix == STP_RX_RING_SIZE)
- bix = 0;
- }
-
- stp->stp_last_rd = bix;
-
- return 1;
-}
-
-/*
- * transmit interrupt
- */
-int
-stp2002_tint(stp)
- struct stp_base *stp;
-{
- struct ifnet *ifp = &stp->stp_arpcom.ac_if;
- int bix;
- struct stp_txd txd;
-
- bix = stp->stp_first_td;
-
- for (;;) {
- if (stp->stp_no_td <= 0)
- break;
-
- bcopy(&(stp->stp_desc->stp_txd[bix]), &txd, sizeof(txd));
-
- if (txd.tx_flags & STP_TXFLAG_OWN)
- break;
-
- ifp->if_flags &= ~IFF_OACTIVE;
- ifp->if_opackets++;
-
- if (++bix == STP_TX_RING_SIZE)
- bix = 0;
-
- --stp->stp_no_td;
- }
-
- stp->stp_first_td = bix;
-
- stp2002_start(stp);
-
- if (stp->stp_no_td == 0)
- ifp->if_timer = 0;
-
- return 1;
-}
-
-/*
- * Start output on interface.
- * We make two assumptions here:
- * 1) that the current priority is set to splnet _before_ this code
- * is called *and* is returned to the appropriate priority after
- * return
- * 2) that the IFF_OACTIVE flag is checked before this code is called
- * (i.e. that the output part of the interface is idle)
- *
- * This function returns 1 if at least one packet has been placed in the
- * descriptor ring, and 0 otherwise. The intent is that upon return, the
- * caller can conditionally wake up the DMA engine.
- */
-void
-stp2002_start(stp)
- struct stp_base *stp;
-{
- struct ifnet *ifp = &stp->stp_arpcom.ac_if;
- struct mbuf *m;
- int bix, len;
-
- if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
- return;
-
- bix = stp->stp_last_td;
-
- for (;;) {
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m == 0)
- break;
-#if NBPFILTER > 0
- /*
- * If BPF is listening on this interface, let it see the
- * packet before we commit it to the wire.
- */
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m);
-#endif
-
- /*
- * Copy the mbuf chain into the transmit buffer.
- */
- len = stp2002_put(stp, bix, m);
-
- /*
- * Initialize transmit registers and start transmission
- */
- stp->stp_desc->stp_txd[bix].tx_flags =
- STP_TXFLAG_OWN | STP_TXFLAG_SOP | STP_TXFLAG_EOP |
- (len & STP_TXFLAG_SIZE);
-
- (*stp->stp_tx_dmawakeup)(ifp->if_softc);
-
- if (++bix == STP_TX_RING_SIZE)
- bix = 0;
-
- if (++stp->stp_no_td == STP_TX_RING_SIZE) {
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
- }
-
- stp->stp_last_td = bix;
-}
-
-static void
-stp2002_read(stp, idx, len)
- struct stp_base *stp;
- int idx, len;
-{
- struct ifnet *ifp = &stp->stp_arpcom.ac_if;
- struct ether_header *eh;
- struct mbuf *m;
-
- if (len <= sizeof(struct ether_header) ||
- len > ETHERMTU + sizeof(struct ether_header)) {
-
- printf("%s: invalid packet size %d; dropping\n",
- ifp->if_xname, len);
-
- ifp->if_ierrors++;
- return;
- }
-
- /* Pull packet off interface. */
- m = stp2002_get(stp, idx, len);
- if (m == NULL) {
- ifp->if_ierrors++;
- return;
- }
-
- ifp->if_ipackets++;
-
- /* We assume that the header fit entirely in one mbuf. */
- eh = mtod(m, struct ether_header *);
-
-#if NBPFILTER > 0
- /*
- * Check if there's a BPF listener on this interface.
- * If so, hand off the raw packet to BPF.
- */
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m);
-#endif
- /* Pass the packet up, with the ether header sort-of removed. */
- m_adj(m, sizeof(struct ether_header));
- ether_input(ifp, eh, m);
-}
diff --git a/sys/arch/sparc/dev/stp2002var.h b/sys/arch/sparc/dev/stp2002var.h
deleted file mode 100644
index 58a98d99875..00000000000
--- a/sys/arch/sparc/dev/stp2002var.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* $OpenBSD: stp2002var.h,v 1.1 1998/07/17 21:33:11 jason Exp $ */
-
-/*
- * Copyright (c) 1998 Jason L. Wright (jason@thought.net)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Jason L. Wright
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-struct stp_rxd {
- volatile u_int32_t rx_flags;
- volatile u_int32_t rx_addr;
-};
-#define STP_RXFLAG_OWN 0x80000000 /* desc owner: 1=hw,0=sw */
-#define STP_RXFLAG_OVERFLOW 0x40000000 /* 1 = buffer over flow */
-#define STP_RXFLAG_SIZE 0x3fff0000 /* desciptor size */
-#define STP_RXFLAG_CSUM 0x0000ffff /* checksum mask */
-
-struct stp_txd {
- volatile u_int32_t tx_flags;
- volatile u_int32_t tx_addr;
-};
-#define STP_TXFLAG_OWN 0x80000000 /* desc owner: 1=hw,0=sw */
-#define STP_TXFLAG_SOP 0x40000000 /* 1 = start of pkt */
-#define STP_TXFLAG_EOP 0x20000000 /* 1 = end of pkt */
-#define STP_TXFLAG_CSENABLE 0x10000000 /* 1 = use hw checksums */
-#define STP_TXFLAG_CSLOCATION 0x0ff00000 /* checksum location mask */
-#define STP_TXFLAG_CSBUFBEGIN 0x000fc000 /* checksum begin mask */
-#define STP_TXFLAG_SIZE 0x00003fff /* pkt size mask */
-
-#define STP_RX_RING_SIZE 32 /* Must be 32, 64, 128, or 256 */
-#define STP_TX_RING_SIZE 32 /* 16<=x<=256 and divisible by 16 */
-#define STP_RX_RING_MAX 256 /* maximum ring size: rx */
-#define STP_TX_RING_MAX 256 /* maximum ring size: tx */
-#define STP_RX_PKT_BUF_SZ 2048 /* size of a rx buffer */
-#define STP_RX_OFFSET 2 /* packet offset */
-#define STP_RX_CSUMLOC 0x00 /* checksum location */
-#define STP_TX_PKT_BUF_SZ 1546 /* size of a tx buffer */
-#define STP_RX_ALIGN_SIZE 64 /* rx buffers must align 64 XXX */
-#define STP_RX_ALIGN_MASK (~(RX_ALIGN_SIZE - 1))
-
-struct stp_desc {
- struct stp_rxd stp_rxd[STP_RX_RING_MAX];
- struct stp_txd stp_txd[STP_TX_RING_MAX];
-};
-
-struct stp_bufs {
- char rx_buf[STP_RX_RING_SIZE][STP_RX_PKT_BUF_SZ];
- char tx_buf[STP_TX_RING_SIZE][STP_TX_PKT_BUF_SZ];
-};
-
-struct stp_base {
- /* public members */
- struct arpcom stp_arpcom; /* ethernet common */
- u_long stp_rx_dvma, stp_tx_dvma; /* ring dva pointers */
- void (*stp_tx_dmawakeup) __P((void *)); /* func to start tx */
-
- /* internal use */
- struct stp_desc *stp_desc, *stp_desc_dva; /* ring descriptors */
- struct stp_bufs *stp_bufs, *stp_bufs_dva; /* packet buffers */
- int stp_first_td, stp_last_td, stp_no_td; /* tx counters */
- int stp_last_rd; /* rx counters */
-};
-
-void stp2002_meminit __P((struct stp_base *));
-int stp2002_rint __P((struct stp_base *));
-int stp2002_tint __P((struct stp_base *));
-void stp2002_start __P((struct stp_base *));