summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sparc/conf/files.sparc5
-rw-r--r--sys/arch/sparc/dev/be.c769
-rw-r--r--sys/arch/sparc/dev/bereg.h415
-rw-r--r--sys/arch/sparc/dev/bevar.h26
4 files changed, 952 insertions, 263 deletions
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index 66c80577b31..a74239ba34d 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc,v 1.19 1998/07/17 21:33:05 jason Exp $
+# $OpenBSD: files.sparc,v 1.20 1998/08/26 05:00:49 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,8 +117,7 @@ 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 | be
+file arch/sparc/dev/stp2002base.c hme
device esp: scsi, ncr53c9x
attach esp at sbus, dma, obio
diff --git a/sys/arch/sparc/dev/be.c b/sys/arch/sparc/dev/be.c
index b2cafbfafb7..83aaa8453f1 100644
--- a/sys/arch/sparc/dev/be.c
+++ b/sys/arch/sparc/dev/be.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: be.c,v 1.5 1998/07/11 05:47:36 deraadt Exp $ */
+/* $OpenBSD: be.c,v 1.6 1998/08/26 05:00:51 jason Exp $ */
/*
- * Copyright (c) 1998 Theo de Raadt. All rights reserved.
+ * Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,13 +12,13 @@
* 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. The name of the author may not be used to endorse or promote products
+ * 3. The name of the authors 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
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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,
+ * IN NO EVENT SHALL THE AUTHORS 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
@@ -70,19 +71,29 @@ int bematch __P((struct device *, void *, void *));
void beattach __P((struct device *, struct device *, void *));
void beinit __P((struct besoftc *));
-void be_meminit __P((struct besoftc *));
void bestart __P((struct ifnet *));
void bestop __P((struct besoftc *));
void bewatchdog __P((struct ifnet *));
int beioctl __P((struct ifnet *, u_long, caddr_t));
+void bereset __P((struct besoftc *sc));
int beintr __P((void *));
-int betint __P((struct besoftc *));
int berint __P((struct besoftc *));
-int beqint __P((struct besoftc *));
-int beeint __P((struct besoftc *));
+int betint __P((struct besoftc *));
+int beqint __P((struct besoftc *, u_int32_t));
+int beeint __P((struct besoftc *, u_int32_t));
+int be_put __P((struct besoftc *, int, struct mbuf *));
+void be_read __P((struct besoftc *, int, int));
+struct mbuf * be_get __P((struct besoftc *, int, int));
+
+void be_tcvr_idle __P((struct besoftc *sc));
void be_tcvr_init __P((struct besoftc *sc));
void be_tcvr_setspeed __P((struct besoftc *sc));
+void be_tcvr_write __P((struct besoftc *sc, u_int8_t reg, u_int16_t val));
+void be_tcvr_write_bit __P((struct besoftc *sc, int bit));
+int be_tcvr_read_bit1 __P((struct besoftc *sc));
+int be_tcvr_read_bit2 __P((struct besoftc *sc));
+int be_tcvr_read __P((struct besoftc *sc, u_int8_t reg));
struct cfdriver be_cd = {
NULL, "be", DV_IFNET
@@ -125,9 +136,10 @@ beattach(parent, self, aux)
pri = ca->ca_ra.ra_intr[0].int_pri;
sc->sc_rev = getpropint(ca->ca_ra.ra_node, "board-version", -1);
- sc->sc_cr = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct be_cregs));
+ sc->sc_cr = mapiodev(&ca->ca_ra.ra_reg[0], 0, sizeof(struct be_cregs));
sc->sc_br = mapiodev(&ca->ca_ra.ra_reg[1], 0, sizeof(struct be_bregs));
sc->sc_tr = mapiodev(&ca->ca_ra.ra_reg[2], 0, sizeof(struct be_tregs));
+ sc->sc_qec = qec;
sc->sc_qr = qec->sc_regs;
bestop(sc);
@@ -182,11 +194,9 @@ void
bestart(ifp)
struct ifnet *ifp;
{
-printf("start\n");
-#if 0
- struct besoftc *sc = ifp->if_softc;
+ struct besoftc *sc = (struct besoftc *)ifp->if_softc;
struct mbuf *m;
- int bix;
+ int bix, len;
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
return;
@@ -194,11 +204,10 @@ printf("start\n");
bix = sc->sc_last_td;
for (;;) {
- /* XXX TODO: Some magic */
-
IF_DEQUEUE(&ifp->if_snd, m);
if (m == 0)
break;
+
#if NBPFILTER > 0
/*
* If BPF is listening on this interface, let it see the
@@ -208,24 +217,29 @@ printf("start\n");
bpf_mtap(ifp->if_bpf, m);
#endif
- /* XXX TODO
+ /*
* Copy the mbuf chain into the transmit buffer.
*/
- /* XXX TODO
+ len = be_put(sc, bix, m);
+
+ /*
* Initialize transmit registers and start transmission
*/
+ sc->sc_desc->be_txd[bix].tx_flags =
+ BE_TXD_OWN | BE_TXD_SOP | BE_TXD_EOP |
+ (len & BE_TXD_LENGTH);
+ sc->sc_cr->ctrl = BE_CR_CTRL_TWAKEUP;
- if (++bix == TX_RING_SIZE)
+ if (++bix == BE_TX_RING_SIZE)
bix = 0;
- if (++sc->sc_no_td == TX_RING_SIZE) {
+ if (++sc->sc_no_td == BE_TX_RING_SIZE) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
}
sc->sc_last_td = bix;
-#endif
}
void
@@ -245,20 +259,31 @@ bestop(sc)
DELAY(20);
}
+/*
+ * Reset interface.
+ */
+void
+bereset(sc)
+ struct besoftc *sc;
+{
+ int s;
+
+ s = splnet();
+ bestop(sc);
+ beinit(sc);
+ splx(s);
+}
+
void
bewatchdog(ifp)
struct ifnet *ifp;
{
-printf("watchdog\n");
-
-#if 0
struct besoftc *sc = ifp->if_softc;
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
++sc->sc_arpcom.ac_if.if_oerrors;
bereset(sc);
-#endif
}
int
@@ -266,50 +291,227 @@ beintr(v)
void *v;
{
struct besoftc *sc = (struct besoftc *)v;
- u_int32_t why;
+ u_int32_t whyq, whyb, whyc;
int r = 0;
- why = sc->sc_qr->stat;
+ whyq = sc->sc_qr->stat; /* qec status */
+ whyc = sc->sc_cr->stat; /* be channel status */
+ whyb = sc->sc_br->stat; /* be status */
+
+ if (whyq & QEC_STAT_BM)
+ r |= beeint(sc, whyb);
+
+ if (whyq & QEC_STAT_ER)
+ r |= beqint(sc, whyc);
- if (why & QEC_STAT_TX)
+ if (whyq & QEC_STAT_TX && whyc & BE_CR_STAT_TXIRQ)
r |= betint(sc);
- if (why & QEC_STAT_RX)
+
+ if (whyq & QEC_STAT_RX && whyc & BE_CR_STAT_RXIRQ)
r |= berint(sc);
- if (why & QEC_STAT_BM)
- r |= beqint(sc);
- if (why & QEC_STAT_ER)
- r |= beeint(sc);
- if (r)
- printf("%s: intr: why=%08x\n", sc->sc_dev.dv_xname, why);
+
return (r);
}
+/*
+ * QEC Interrupt.
+ */
int
-betint(sc)
+beqint(sc, why)
struct besoftc *sc;
+ u_int32_t why;
{
- return (0);
+ int r = 0, rst = 0;
+
+ if (why & BE_CR_STAT_TXIRQ)
+ r |= 1;
+ if (why & BE_CR_STAT_RXIRQ)
+ r |= 1;
+
+ if (why & BE_CR_STAT_BERROR) {
+ r |= 1;
+ rst = 1;
+ printf("%s: bigmac error\n", sc->sc_dev.dv_xname);
+ }
+
+ if (why & BE_CR_STAT_TXDERR) {
+ r |= 1;
+ rst = 1;
+ printf("%s: bogus tx descriptor\n", sc->sc_dev.dv_xname);
+ }
+
+ if (why & (BE_CR_STAT_TXLERR | BE_CR_STAT_TXPERR | BE_CR_STAT_TXSERR)) {
+ r |= 1;
+ rst = 1;
+ printf("%s: tx dma error ( ", sc->sc_dev.dv_xname);
+ if (why & BE_CR_STAT_TXLERR)
+ printf("Late ");
+ if (why & BE_CR_STAT_TXPERR)
+ printf("Parity ");
+ if (why & BE_CR_STAT_TXSERR)
+ printf("Generic ");
+ printf(")\n");
+ }
+
+ if (why & BE_CR_STAT_RXDROP) {
+ r |= 1;
+ rst = 1;
+ printf("%s: out of rx descriptors\n", sc->sc_dev.dv_xname);
+ }
+
+ if (why & BE_CR_STAT_RXSMALL) {
+ r |= 1;
+ rst = 1;
+ printf("%s: rx descriptor too small\n", sc->sc_dev.dv_xname);
+ }
+
+ if (why & (BE_CR_STAT_RXLERR | BE_CR_STAT_RXPERR | BE_CR_STAT_RXSERR)) {
+ r |= 1;
+ rst = 1;
+ printf("%s: rx dma error ( ", sc->sc_dev.dv_xname);
+ if (why & BE_CR_STAT_RXLERR)
+ printf("Late ");
+ if (why & BE_CR_STAT_RXPERR)
+ printf("Parity ");
+ if (why & BE_CR_STAT_RXSERR)
+ printf("Generic ");
+ printf(")\n");
+ }
+
+ if (!r) {
+ rst = 1;
+ printf("%s: unexpected error interrupt %08x\n",
+ sc->sc_dev.dv_xname, why);
+ }
+
+ if (rst) {
+ printf("%s: resetting\n", sc->sc_dev.dv_xname);
+ bereset(sc);
+ }
+
+ return r;
}
+/*
+ * Error interrupt.
+ */
int
-berint(sc)
+beeint(sc, why)
struct besoftc *sc;
+ u_int32_t why;
{
- return (0);
+ int r = 0, rst = 0;
+
+ if (why & BE_BR_STAT_RFIFOVF) {
+ r |= 1;
+ rst = 1;
+ printf("%s: receive fifo overrun\n", sc->sc_dev.dv_xname);
+ }
+ if (why & BE_BR_STAT_TFIFO_UND) {
+ r |= 1;
+ rst = 1;
+ printf("%s: transmit fifo underrun\n", sc->sc_dev.dv_xname);
+ }
+ if (why & BE_BR_STAT_MAXPKTERR) {
+ r |= 1;
+ rst = 1;
+ printf("%s: max packet size error\n", sc->sc_dev.dv_xname);
+ }
+ if (why & BE_BR_STAT_DTIMEXP) {
+ r |= 1;
+ printf("%s: defer timer expired\n", sc->sc_dev.dv_xname);
+ }
+
+ if (!r) {
+ rst = 1;
+ printf("%s: unexpected error interrupt %08x\n",
+ sc->sc_dev.dv_xname, why);
+ }
+
+ if (rst) {
+ printf("%s: resetting\n", sc->sc_dev.dv_xname);
+ bereset(sc);
+ }
+
+ return r;
}
+/*
+ * Transmit interrupt.
+ */
int
-beqint(sc)
+betint(sc)
struct besoftc *sc;
{
- return (0);
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int bix;
+ struct be_txd txd;
+
+ bix = sc->sc_first_td;
+
+ for (;;) {
+ if (sc->sc_no_td <= 0)
+ break;
+
+ bcopy(&sc->sc_desc->be_txd[bix], &txd, sizeof(txd));
+
+ if (txd.tx_flags & BE_TXD_OWN)
+ break;
+
+ ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_opackets++;
+
+ if (++bix == BE_TX_RING_SIZE)
+ bix = 0;
+
+ --sc->sc_no_td;
+ }
+
+ sc->sc_first_td = bix;
+
+ bestart(ifp);
+
+ if (sc->sc_no_td == 0)
+ ifp->if_timer = 0;
+
+ return 1;
}
+/*
+ * Receive interrupt.
+ */
int
-beeint(sc)
+berint(sc)
struct besoftc *sc;
{
- return (0);
+ int bix, len;
+ struct be_rxd rxd;
+
+ bix = sc->sc_last_rd;
+
+ /*
+ * Process all buffers with valid data.
+ */
+ for (;;) {
+ bcopy(&sc->sc_desc->be_rxd[bix], &rxd, sizeof(rxd));
+
+ if (rxd.rx_flags & BE_RXD_OWN)
+ break;
+
+ len = rxd.rx_flags & BE_RXD_LENGTH;
+ be_read(sc, bix, len);
+
+ rxd.rx_flags = BE_RXD_OWN | (BE_PKT_BUF_SZ & BE_RXD_LENGTH);
+
+ bcopy(&rxd, &sc->sc_desc->be_rxd[bix], sizeof(rxd));
+
+ if (++bix == BE_RX_RING_SIZE)
+ bix = 0;
+ }
+
+ sc->sc_last_rd = bix;
+
+ return 1;
}
int
@@ -422,18 +624,6 @@ beioctl(ifp, cmd, data)
}
void
-be_tcvr_init(sc)
- struct besoftc *sc;
-{
-}
-
-void
-be_tcvr_setspeed(sc)
- struct besoftc *sc;
-{
-}
-
-void
beinit(sc)
struct besoftc *sc;
{
@@ -441,13 +631,15 @@ beinit(sc)
int s = splimp();
int i;
- bestop(sc);
+ qec_reset(sc->sc_qec);
- /* init QEC */
+ /*
+ * init QEC: 'be' specific initializations
+ */
sc->sc_qr->msize = sc->sc_memsize;
sc->sc_qr->rsize = sc->sc_memsize / 2;
sc->sc_qr->tsize = sc->sc_memsize / 2;
- sc->sc_qr->psize = 2048;
+ sc->sc_qr->psize = QEC_PSIZE_2048;
if (sc->sc_burst & SBUS_BURST_64)
i = QEC_CTRL_B64;
else if (sc->sc_burst & SBUS_BURST_32)
@@ -456,28 +648,31 @@ beinit(sc)
i = QEC_CTRL_B16;
sc->sc_qr->ctrl = QEC_CTRL_BMODE | i;
- /* Allocate memory if not done yet */
- if (sc->sc_desc_dva == NULL)
- sc->sc_desc_dva = (struct be_desc *)dvma_malloc(
- sizeof(struct be_desc), &sc->sc_desc, M_NOWAIT);
- if (sc->sc_bufs_dva == NULL)
- sc->sc_bufs_dva = (struct be_bufs *)dvma_malloc(
- sizeof(struct be_bufs), &sc->sc_bufs, M_NOWAIT);
-
- /* chain descriptors into buffers */
- sc->sc_txnew = 0;
- sc->sc_rxnew = 0;
- sc->sc_txold = 0;
- sc->sc_rxold = 0;
- for (i = 0; i < RX_RING_SIZE; i++) {
- sc->sc_desc->be_rxd[i].rx_addr =
- (u_int32_t)&sc->sc_bufs_dva->rx_buf[i][0];
- sc->sc_desc->be_rxd[i].rx_flags = 0;
- }
- for (i = 0; i < TX_RING_SIZE; i++) {
- sc->sc_desc->be_txd[i].tx_addr = 0;
+ /*
+ * Allocate descriptor ring and buffers, if not already done
+ */
+ if (sc->sc_desc == NULL)
+ sc->sc_desc_dva = (struct be_desc *) dvma_malloc(
+ sizeof(struct be_desc), &sc->sc_desc, M_NOWAIT);
+ if (sc->sc_bufs == NULL)
+ sc->sc_bufs_dva = (struct be_bufs *) dvma_malloc(
+ sizeof(struct be_bufs), &sc->sc_bufs, M_NOWAIT);
+
+ for (i = 0; i < BE_TX_RING_SIZE; i++) {
+ sc->sc_desc->be_txd[i].tx_addr =
+ (u_int32_t) &sc->sc_bufs_dva->tx_buf[i][0];
sc->sc_desc->be_txd[i].tx_flags = 0;
}
+ for (i = 0; i < BE_RX_RING_SIZE; i++) {
+ sc->sc_desc->be_rxd[i].rx_addr =
+ (u_int32_t) &sc->sc_bufs_dva->rx_buf[i][0];
+ sc->sc_desc->be_rxd[i].rx_flags =
+ BE_RXD_OWN |
+ (BE_PKT_BUF_SZ & BE_RXD_LENGTH);
+ }
+
+ sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
+ sc->sc_last_rd = 0;
be_tcvr_init(sc);
be_tcvr_setspeed(sc);
@@ -496,23 +691,38 @@ beinit(sc)
sc->sc_br->htable1 = 0;
sc->sc_br->htable0 = 0;
- sc->sc_br->rx_cfg = BE_RXCFG_HENABLE | BE_RXCFG_FIFO;
+ sc->sc_br->rx_cfg = BE_BR_RXCFG_HENABLE | BE_BR_RXCFG_FIFO;
DELAY(20);
- sc->sc_br->tx_cfg = BE_TXCFG_FIFO;
+ sc->sc_br->tx_cfg = BE_BR_TXCFG_FIFO;
sc->sc_br->rand_seed = 0xbd;
- sc->sc_br->xif_cfg = BE_XCFG_ODENABLE | BE_XCFG_RESV;
+ sc->sc_br->xif_cfg = BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV;
- sc->sc_cr->rxds = (u_int32_t)&sc->sc_desc_dva->be_rxd[0];
- sc->sc_cr->txds = (u_int32_t)&sc->sc_desc_dva->be_txd[0];
+ sc->sc_cr->rxds = (u_int32_t) &sc->sc_desc_dva->be_rxd[0];
+ sc->sc_cr->txds = (u_int32_t) &sc->sc_desc_dva->be_txd[0];
sc->sc_cr->rxwbufptr = 0;
sc->sc_cr->rxrbufptr = 0;
- sc->sc_cr->txwbufptr = sc->sc_memsize;
- sc->sc_cr->txrbufptr = sc->sc_memsize;
-
- sc->sc_br->imask = 0;
+ sc->sc_cr->txwbufptr = sc->sc_qr->tsize;
+ sc->sc_cr->txrbufptr = sc->sc_qr->tsize;
+
+ /*
+ * Turn off counter expiration interrupts as well as
+ * 'gotframe' and 'sentframe'
+ */
+ sc->sc_br->imask = BE_BR_IMASK_GOTFRAME |
+ BE_BR_IMASK_RCNTEXP |
+ BE_BR_IMASK_ACNTEXP |
+ BE_BR_IMASK_CCNTEXP |
+ BE_BR_IMASK_LCNTEXP |
+ BE_BR_IMASK_CVCNTEXP |
+ BE_BR_IMASK_NCNTEXP |
+ BE_BR_IMASK_ECNTEXP |
+ BE_BR_IMASK_LCCNTEXP |
+ BE_BR_IMASK_LCNTEXP |
+ BE_BR_IMASK_LCNTEXP |
+ BE_BR_IMASK_SENTFRAME;
sc->sc_cr->rimask = 0;
sc->sc_cr->timask = 0;
@@ -523,10 +733,391 @@ beinit(sc)
sc->sc_cr->ccnt = 0;
- sc->sc_br->tx_cfg |= BE_TXCFG_ENABLE;
- sc->sc_br->rx_cfg |= BE_RXCFG_ENABLE;
+ sc->sc_br->tx_cfg |= BE_BR_TXCFG_ENABLE;
+ sc->sc_br->rx_cfg |= BE_BR_RXCFG_ENABLE;
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
splx(s);
}
+
+void
+be_tcvr_setspeed(sc)
+ struct besoftc *sc;
+{
+ int x;
+
+ be_tcvr_write(sc, PHY_BMCR, 0);
+ x = be_tcvr_read(sc, PHY_BMSR);
+}
+
+/*
+ * Set the tcvr to an idle state
+ */
+void
+be_tcvr_idle(sc)
+ struct besoftc *sc;
+{
+ struct be_tregs *tr = sc->sc_tr;
+ volatile u_int32_t x;
+ int i = 20;
+
+ while (i--) {
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
+ MGMT_PAL_OENAB;
+ x = tr->mgmt_pal;
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO |
+ MGMT_PAL_OENAB | MGMT_PAL_DCLOCK;
+ x = tr->mgmt_pal;
+ }
+}
+
+/*
+ * Initialize the transceiver and figure out whether we're using the
+ * external or internal one.
+ */
+void
+be_tcvr_init(sc)
+ struct besoftc *sc;
+{
+ volatile u_int32_t x;
+ struct be_tregs *tr = sc->sc_tr;
+
+ be_tcvr_idle(sc);
+
+ if (sc->sc_rev != 1) {
+ printf("%s: rev %d PAL not supported.\n",
+ sc->sc_dev.dv_xname,
+ sc->sc_rev);
+ return;
+ }
+
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;
+ x = tr->mgmt_pal;
+
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO;
+ x = tr->mgmt_pal;
+ DELAY(200);
+
+ if (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) {
+ sc->sc_tcvr_type = BE_TCVR_EXTERNAL;
+ tr->tcvr_pal = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |
+ TCVR_PAL_LTENABLE);
+ x = tr->tcvr_pal;
+ }
+ else if (tr->mgmt_pal & MGMT_PAL_INT_MDIO) {
+ sc->sc_tcvr_type = BE_TCVR_INTERNAL;
+ tr->tcvr_pal = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |
+ TCVR_PAL_LTENABLE | TCVR_PAL_SERIAL);
+ x = tr->tcvr_pal;
+ }
+ else {
+ printf("%s: no internal or external transceiver found.\n",
+ sc->sc_dev.dv_xname);
+ }
+}
+
+int
+be_tcvr_read(sc, reg)
+ struct besoftc *sc;
+ u_int8_t reg;
+{
+ int phy, i;
+ u_int32_t ret = 0;
+
+ if (sc->sc_tcvr_type == BE_TCVR_INTERNAL)
+ phy = BE_PHY_INTERNAL;
+ else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL)
+ phy = BE_PHY_EXTERNAL;
+ else {
+ printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
+ return BE_TCVR_READ_INVALID;
+ }
+
+ be_tcvr_idle(sc);
+
+ be_tcvr_write_bit(sc, 0);
+ be_tcvr_write_bit(sc, 1);
+ be_tcvr_write_bit(sc, 1);
+ be_tcvr_write_bit(sc, 0);
+
+ for (i = 4; i >= 0; i--)
+ be_tcvr_write_bit(sc, (phy >> i) & 1);
+
+ for (i = 4; i >= 0; i--)
+ be_tcvr_write_bit(sc, (reg >> i) & 1);
+
+ if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {
+ (void) be_tcvr_read_bit2(sc);
+ (void) be_tcvr_read_bit2(sc);
+
+ for (i = 15; i >= 0; i--) {
+ int b;
+
+ b = be_tcvr_read_bit2(sc);
+ ret |= (b & 1) << i;
+ }
+
+ (void) be_tcvr_read_bit2(sc);
+ (void) be_tcvr_read_bit2(sc);
+ (void) be_tcvr_read_bit2(sc);
+ }
+ else {
+ (void) be_tcvr_read_bit1(sc);
+ (void) be_tcvr_read_bit1(sc);
+
+ for (i = 15; i >= 0; i--) {
+ int b;
+
+ b = be_tcvr_read_bit1(sc);
+ ret |= (b & 1) << i;
+ }
+
+ (void) be_tcvr_read_bit1(sc);
+ (void) be_tcvr_read_bit1(sc);
+ (void) be_tcvr_read_bit1(sc);
+ }
+ return ret;
+}
+
+int
+be_tcvr_read_bit1(sc)
+ struct besoftc *sc;
+{
+ volatile u_int32_t x;
+ struct be_tregs *tr = sc->sc_tr;
+ int ret = 0;
+
+ if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {
+ tr->mgmt_pal = MGMT_PAL_EXT_MDIO;
+ x = tr->mgmt_pal;
+ tr->mgmt_pal = MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;
+ x = tr->mgmt_pal;
+ DELAY(20);
+ ret = (tr->mgmt_pal & MGMT_PAL_INT_MDIO) >> 3;
+ } else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO;
+ x = tr->mgmt_pal;
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK;
+ x = tr->mgmt_pal;
+ DELAY(20);
+ ret = (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) >> 2;
+ } else {
+ printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
+ }
+ return (ret & 1);
+}
+
+int
+be_tcvr_read_bit2(sc)
+ struct besoftc *sc;
+{
+ volatile u_int32_t x;
+ struct be_tregs *tr = sc->sc_tr;
+ int ret = 0;
+
+ if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {
+ tr->mgmt_pal = MGMT_PAL_EXT_MDIO;
+ x = tr->mgmt_pal;
+ DELAY(20);
+ ret = (tr->mgmt_pal & MGMT_PAL_INT_MDIO) >> 3;
+ tr->mgmt_pal = MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK;
+ x = tr->mgmt_pal;
+ } else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL) {
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO;
+ x = tr->mgmt_pal;
+ DELAY(20);
+ ret = (tr->mgmt_pal & MGMT_PAL_EXT_MDIO) >> 2;
+ tr->mgmt_pal = MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK;
+ x = tr->mgmt_pal;
+ } else {
+ printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
+ }
+ return ret;
+}
+
+void
+be_tcvr_write(sc, reg, val)
+ struct besoftc *sc;
+ u_int8_t reg;
+ u_int16_t val;
+{
+ int phy, i;
+
+ if (sc->sc_tcvr_type == BE_TCVR_INTERNAL)
+ phy = BE_PHY_INTERNAL;
+ else if (sc->sc_tcvr_type == BE_TCVR_EXTERNAL)
+ phy = BE_PHY_EXTERNAL;
+ else {
+ printf("%s: invalid tcvr type\n", sc->sc_dev.dv_xname);
+ return;
+ }
+
+ be_tcvr_idle(sc);
+
+ be_tcvr_write_bit(sc, 0);
+ be_tcvr_write_bit(sc, 1);
+ be_tcvr_write_bit(sc, 0);
+ be_tcvr_write_bit(sc, 1);
+
+ for (i = 4; i >= 0; i--)
+ be_tcvr_write_bit(sc, (phy >> i) & 1);
+
+ for (i = 4; i >= 0; i--)
+ be_tcvr_write_bit(sc, (reg >> i) & 1);
+
+ be_tcvr_write_bit(sc, 1);
+ be_tcvr_write_bit(sc, 0);
+
+ for (i = 15; i >= 0; i--)
+ be_tcvr_write_bit(sc, (val >> i) & 1);
+}
+
+void
+be_tcvr_write_bit(sc, bit)
+ struct besoftc *sc;
+ int bit;
+{
+ volatile u_int32_t x;
+
+ if (sc->sc_tcvr_type == BE_TCVR_INTERNAL) {
+ bit = ((bit & 1) << 3) | MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO;
+ sc->sc_tr->mgmt_pal = bit;
+ x = sc->sc_tr->mgmt_pal;
+ sc->sc_tr->mgmt_pal = bit | MGMT_PAL_DCLOCK;
+ x = sc->sc_tr->mgmt_pal;
+ } else {
+ bit = ((bit & 1) << 2) | MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO;
+ sc->sc_tr->mgmt_pal = bit;
+ x = sc->sc_tr->mgmt_pal;
+ sc->sc_tr->mgmt_pal = bit | MGMT_PAL_DCLOCK;
+ x = sc->sc_tr->mgmt_pal;
+ }
+}
+
+/*
+ * Routine to copy from mbuf chain to transmit buffer in
+ * network buffer memory.
+ */
+int
+be_put(sc, idx, m)
+ struct besoftc *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;
+}
+
+/*
+ * Pass a packet to the higher levels.
+ */
+void
+be_read(sc, idx, len)
+ struct besoftc *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 = be_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);
+}
+
+/*
+ * 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.
+ */
+struct mbuf *
+be_get(sc, idx, totlen)
+ struct besoftc *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], mtod(m, caddr_t), len);
+ boff += len;
+ totlen -= len;
+ *mp = m;
+ mp = &m->m_next;
+ }
+
+ return (top);
+}
diff --git a/sys/arch/sparc/dev/bereg.h b/sys/arch/sparc/dev/bereg.h
index 408a1e94407..8097d808bd6 100644
--- a/sys/arch/sparc/dev/bereg.h
+++ b/sys/arch/sparc/dev/bereg.h
@@ -1,7 +1,8 @@
-/* $OpenBSD: bereg.h,v 1.2 1998/07/05 09:25:55 deraadt Exp $ */
+/* $OpenBSD: bereg.h,v 1.3 1998/08/26 05:00:53 jason Exp $ */
/*
- * Copyright (c) 1998 Theo de Raadt. All rights reserved.
+ * Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,13 +12,13 @@
* 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. The name of the author may not be used to endorse or promote products
+ * 3. The name of the authors 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
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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,
+ * IN NO EVENT SHALL THE AUTHORS 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
@@ -26,180 +27,278 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * BE Global registers
+ */
struct be_bregs {
- volatile u_int32_t xif_cfg; /* XIF config register */
- volatile u_int32_t _unused[63]; /* Reserved... */
- volatile u_int32_t status; /* Status register, clear on read */
- volatile u_int32_t imask; /* Interrupt mask register */
- volatile u_int32_t _unused2[64]; /* Reserved... */
- volatile u_int32_t tx_swreset; /* Transmitter software reset */
- volatile u_int32_t tx_cfg; /* Transmitter config register */
- volatile u_int32_t ipkt_gap1; /* Inter-packet gap 1 */
- volatile u_int32_t ipkt_gap2; /* Inter-packet gap 2 */
- volatile u_int32_t attempt_limit; /* Transmit attempt limit */
- volatile u_int32_t stime; /* Transmit slot time */
- volatile u_int32_t preamble_len; /* Size of transmit preamble */
- volatile u_int32_t preamble_pattern; /* Pattern for transmit preamble */
- volatile u_int32_t tx_sframe_delim; /* Transmit delimiter */
- volatile u_int32_t jsize; /* Toe jam... */
- volatile u_int32_t tx_pkt_max; /* Transmit max pkt size */
- volatile u_int32_t tx_pkt_min; /* Transmit min pkt size */
- volatile u_int32_t peak_attempt; /* Count of transmit peak attempts */
- volatile u_int32_t dt_ctr; /* Transmit defer timer */
- volatile u_int32_t nc_ctr; /* Transmit normal-collision counter */
- volatile u_int32_t fc_ctr; /* Transmit first-collision counter */
- volatile u_int32_t ex_ctr; /* Transmit excess-collision counter */
- volatile u_int32_t lt_ctr; /* Transmit late-collision counter */
- volatile u_int32_t rand_seed; /* Transmit random number seed */
- volatile u_int32_t tx_smachine; /* Transmit state machine */
- volatile u_int32_t _unused3[44]; /* Reserved */
- volatile u_int32_t rx_swreset; /* Receiver software reset */
- volatile u_int32_t rx_cfg; /* Receiver config register */
- volatile u_int32_t rx_pkt_max; /* Receive max pkt size */
- volatile u_int32_t rx_pkt_min; /* Receive min pkt size */
- volatile u_int32_t mac_addr2; /* Ether address register 2 */
- volatile u_int32_t mac_addr1; /* Ether address register 1 */
- volatile u_int32_t mac_addr0; /* Ether address register 0 */
- volatile u_int32_t fr_ctr; /* Receive frame receive counter */
- volatile u_int32_t gle_ctr; /* Receive giant-length error counter */
- volatile u_int32_t unale_ctr; /* Receive unaligned error counter */
- volatile u_int32_t rcrce_ctr; /* Receive CRC error counter */
- volatile u_int32_t rx_smachine; /* Receiver state machine */
- volatile u_int32_t rx_cvalid; /* Receiver code violation */
- volatile u_int32_t _unused4; /* Reserved... */
- volatile u_int32_t htable3; /* Hash table 3 */
- volatile u_int32_t htable2; /* Hash table 2 */
- volatile u_int32_t htable1; /* Hash table 1 */
- volatile u_int32_t htable0; /* Hash table 0 */
- volatile u_int32_t afilter2; /* Address filter 2 */
- volatile u_int32_t afilter1; /* Address filter 1 */
- volatile u_int32_t afilter0; /* Address filter 0 */
- volatile u_int32_t afilter_mask; /* Address filter mask */
+ volatile u_int32_t xif_cfg; /* XIF config */
+ volatile u_int32_t _unused[63]; /* reserved */
+ volatile u_int32_t stat; /* status, clear on read */
+ volatile u_int32_t imask; /* interrupt mask */
+ volatile u_int32_t _unused2[64]; /* reserved */
+ volatile u_int32_t tx_swreset; /* tx software reset */
+ volatile u_int32_t tx_cfg; /* tx config */
+ volatile u_int32_t ipkt_gap1; /* inter-packet gap 1 */
+ volatile u_int32_t ipkt_gap2; /* inter-packet gap 2 */
+ volatile u_int32_t attempt_limit; /* tx attempt limit */
+ volatile u_int32_t stime; /* tx slot time */
+ volatile u_int32_t preamble_len; /* size of tx preamble */
+ volatile u_int32_t preamble_pattern; /* pattern for tx preamble */
+ volatile u_int32_t tx_sframe_delim; /* tx delimiter */
+ volatile u_int32_t jsize; /* jam length */
+ volatile u_int32_t tx_pkt_max; /* tx max pkt size */
+ volatile u_int32_t tx_pkt_min; /* tx min pkt size */
+ volatile u_int32_t peak_attempt; /* count of tx peak attempts */
+ volatile u_int32_t dt_ctr; /* tx defer timer */
+ volatile u_int32_t nc_ctr; /* tx normal collision cntr */
+ volatile u_int32_t fc_ctr; /* tx first-collision cntr */
+ volatile u_int32_t ex_ctr; /* tx excess-collision cntr */
+ volatile u_int32_t lt_ctr; /* tx late-collision cntr */
+ volatile u_int32_t rand_seed; /* tx random number seed */
+ volatile u_int32_t tx_smachine; /* tx state machine */
+ volatile u_int32_t _unused3[44]; /* reserved */
+ volatile u_int32_t rx_swreset; /* rx software reset */
+ volatile u_int32_t rx_cfg; /* rx config register */
+ volatile u_int32_t rx_pkt_max; /* rx max pkt size */
+ volatile u_int32_t rx_pkt_min; /* rx min pkt size */
+ volatile u_int32_t mac_addr2; /* ethernet address 2 (MSB) */
+ volatile u_int32_t mac_addr1; /* ethernet address 1 */
+ volatile u_int32_t mac_addr0; /* ethernet address 0 (LSB) */
+ volatile u_int32_t fr_ctr; /* rx frame receive cntr */
+ volatile u_int32_t gle_ctr; /* rx giant-len error cntr */
+ volatile u_int32_t unale_ctr; /* rx unaligned error cntr */
+ volatile u_int32_t rcrce_ctr; /* rx CRC error cntr */
+ volatile u_int32_t rx_smachine; /* rx state machine */
+ volatile u_int32_t rx_cvalid; /* rx code violation */
+ volatile u_int32_t _unused4; /* reserved */
+ volatile u_int32_t htable3; /* hash table 3 */
+ volatile u_int32_t htable2; /* hash table 2 */
+ volatile u_int32_t htable1; /* hash table 1 */
+ volatile u_int32_t htable0; /* hash table 0 */
+ volatile u_int32_t afilter2; /* address filter 2 */
+ volatile u_int32_t afilter1; /* address filter 1 */
+ volatile u_int32_t afilter0; /* address filter 0 */
+ volatile u_int32_t afilter_mask; /* address filter mask */
};
-/* BE XIF config register. */
-#define BE_XCFG_ODENABLE 0x00000001 /* Output driver enable */
-#define BE_XCFG_RESV 0x00000002 /* Reserved, write always as 1 */
-#define BE_XCFG_MLBACK 0x00000004 /* Loopback-mode MII enable */
-#define BE_XCFG_SMODE 0x00000008 /* Enable serial mode */
-
-/* BE status register. */
-#define BE_STAT_GOTFRAME 0x00000001 /* Received a frame */
-#define BE_STAT_RCNTEXP 0x00000002 /* Receive frame counter expired */
-#define BE_STAT_ACNTEXP 0x00000004 /* Align-error counter expired */
-#define BE_STAT_CCNTEXP 0x00000008 /* CRC-error counter expired */
-#define BE_STAT_LCNTEXP 0x00000010 /* Length-error counter expired */
-#define BE_STAT_RFIFOVF 0x00000020 /* Receive FIFO overflow */
-#define BE_STAT_CVCNTEXP 0x00000040 /* Code-violation counter expired */
-#define BE_STAT_SENTFRAME 0x00000100 /* Transmitted a frame */
-#define BE_STAT_TFIFO_UND 0x00000200 /* Transmit FIFO underrun */
-#define BE_STAT_MAXPKTERR 0x00000400 /* Max-packet size error */
-#define BE_STAT_NCNTEXP 0x00000800 /* Normal-collision counter expired */
-#define BE_STAT_ECNTEXP 0x00001000 /* Excess-collision counter expired */
-#define BE_STAT_LCCNTEXP 0x00002000 /* Late-collision counter expired */
-#define BE_STAT_FCNTEXP 0x00004000 /* First-collision counter expired */
-#define BE_STAT_DTIMEXP 0x00008000 /* Defer-timer expired */
-
-/* BE interrupt mask register. */
-#define BE_IMASK_GOTFRAME 0x00000001 /* Received a frame */
-#define BE_IMASK_RCNTEXP 0x00000002 /* Receive frame counter expired */
-#define BE_IMASK_ACNTEXP 0x00000004 /* Align-error counter expired */
-#define BE_IMASK_CCNTEXP 0x00000008 /* CRC-error counter expired */
-#define BE_IMASK_LCNTEXP 0x00000010 /* Length-error counter expired */
-#define BE_IMASK_RFIFOVF 0x00000020 /* Receive FIFO overflow */
-#define BE_IMASK_CVCNTEXP 0x00000040 /* Code-violation counter expired */
-#define BE_IMASK_SENTFRAME 0x00000100 /* Transmitted a frame */
-#define BE_IMASK_TFIFO_UND 0x00000200 /* Transmit FIFO underrun */
-#define BE_IMASK_MAXPKTERR 0x00000400 /* Max-packet size error */
-#define BE_IMASK_NCNTEXP 0x00000800 /* Normal-collision counter expired */
-#define BE_IMASK_ECNTEXP 0x00001000 /* Excess-collision counter expired */
-#define BE_IMASK_LCCNTEXP 0x00002000 /* Late-collision counter expired */
-#define BE_IMASK_FCNTEXP 0x00004000 /* First-collision counter expired */
-#define BE_IMASK_DTIMEXP 0x00008000 /* Defer-timer expired */
-
-/* BE transmit config register. */
-#define BE_TXCFG_ENABLE 0x00000001 /* Enable the transmitter */
-#define BE_TXCFG_FIFO 0x00000010 /* Default tx fthresh... */
-#define BE_TXCFG_SMODE 0x00000020 /* Enable slow transmit mode */
-#define BE_TXCFG_CIGN 0x00000040 /* Ignore transmit collisions */
-#define BE_TXCFG_FCSOFF 0x00000080 /* Do not emit FCS */
-#define BE_TXCFG_DBACKOFF 0x00000100 /* Disable backoff */
-#define BE_TXCFG_FULLDPLX 0x00000200 /* Enable full-duplex */
-
-/* BE receive config register. */
-#define BE_RXCFG_ENABLE 0x00000001 /* Enable the receiver */
-#define BE_RXCFG_FIFO 0x0000000e /* Default rx fthresh... */
-#define BE_RXCFG_PSTRIP 0x00000020 /* Pad byte strip enable */
-#define BE_RXCFG_PMISC 0x00000040 /* Enable promiscous mode */
-#define BE_RXCFG_DERR 0x00000080 /* Disable error checking */
-#define BE_RXCFG_DCRCS 0x00000100 /* Disable CRC stripping */
-#define BE_RXCFG_ME 0x00000200 /* Receive packets addressed to me */
-#define BE_RXCFG_PGRP 0x00000400 /* Enable promisc group mode */
-#define BE_RXCFG_HENABLE 0x00000800 /* Enable the hash filter */
-#define BE_RXCFG_AENABLE 0x00001000 /* Enable the address filter */
+/* be_bregs.xif_cfg: XIF config. */
+#define BE_BR_XCFG_ODENABLE 0x00000001 /* output driver enable */
+#define BE_BR_XCFG_RESV 0x00000002 /* reserved, write as 1 */
+#define BE_BR_XCFG_MLBACK 0x00000004 /* loopback-mode mii enable */
+#define BE_BR_XCFG_SMODE 0x00000008 /* enable serial mode */
+
+/* be_bregs.stat: status, clear on read. */
+#define BE_BR_STAT_GOTFRAME 0x00000001 /* received a frame */
+#define BE_BR_STAT_RCNTEXP 0x00000002 /* rx frame cntr expired */
+#define BE_BR_STAT_ACNTEXP 0x00000004 /* align-error cntr expired */
+#define BE_BR_STAT_CCNTEXP 0x00000008 /* crc-error cntr expired */
+#define BE_BR_STAT_LCNTEXP 0x00000010 /* length-error cntr expired */
+#define BE_BR_STAT_RFIFOVF 0x00000020 /* rx fifo overflow */
+#define BE_BR_STAT_CVCNTEXP 0x00000040 /* code-violation cntr exprd */
+#define BE_BR_STAT_SENTFRAME 0x00000100 /* transmitted a frame */
+#define BE_BR_STAT_TFIFO_UND 0x00000200 /* tx fifo underrun */
+#define BE_BR_STAT_MAXPKTERR 0x00000400 /* max-packet size error */
+#define BE_BR_STAT_NCNTEXP 0x00000800 /* normal-collision cntr exp */
+#define BE_BR_STAT_ECNTEXP 0x00001000 /* excess-collision cntr exp */
+#define BE_BR_STAT_LCCNTEXP 0x00002000 /* late-collision cntr exp */
+#define BE_BR_STAT_FCNTEXP 0x00004000 /* first-collision cntr exp */
+#define BE_BR_STAT_DTIMEXP 0x00008000 /* defer-timer expired */
+
+/* be_bregs.imask: interrupt mask. */
+#define BE_BR_IMASK_GOTFRAME 0x00000001 /* received a frame */
+#define BE_BR_IMASK_RCNTEXP 0x00000002 /* rx frame cntr expired */
+#define BE_BR_IMASK_ACNTEXP 0x00000004 /* align-error cntr expired */
+#define BE_BR_IMASK_CCNTEXP 0x00000008 /* crc-error cntr expired */
+#define BE_BR_IMASK_LCNTEXP 0x00000010 /* length-error cntr expired */
+#define BE_BR_IMASK_RFIFOVF 0x00000020 /* rx fifo overflow */
+#define BE_BR_IMASK_CVCNTEXP 0x00000040 /* code-violation cntr exprd */
+#define BE_BR_IMASK_SENTFRAME 0x00000100 /* transmitted a frame */
+#define BE_BR_IMASK_TFIFO_UND 0x00000200 /* tx fifo underrun */
+#define BE_BR_IMASK_MAXPKTERR 0x00000400 /* max-packet size error */
+#define BE_BR_IMASK_NCNTEXP 0x00000800 /* normal-collision cntr exp */
+#define BE_BR_IMASK_ECNTEXP 0x00001000 /* excess-collision cntr exp */
+#define BE_BR_IMASK_LCCNTEXP 0x00002000 /* late-collision cntr exp */
+#define BE_BR_IMASK_FCNTEXP 0x00004000 /* first-collision cntr exp */
+#define BE_BR_IMASK_DTIMEXP 0x00008000 /* defer-timer expired */
+
+/* be_bregs.tx_cfg: tx config. */
+#define BE_BR_TXCFG_ENABLE 0x00000001 /* enable the transmitter */
+#define BE_BR_TXCFG_FIFO 0x00000010 /* default tx fthresh */
+#define BE_BR_TXCFG_SMODE 0x00000020 /* enable slow transmit mode */
+#define BE_BR_TXCFG_CIGN 0x00000040 /* ignore tx collisions */
+#define BE_BR_TXCFG_FCSOFF 0x00000080 /* do not emit fcs */
+#define BE_BR_TXCFG_DBACKOFF 0x00000100 /* disable backoff */
+#define BE_BR_TXCFG_FULLDPLX 0x00000200 /* enable full-duplex */
+/* be_bregs.rx_cfg: rx config. */
+#define BE_BR_RXCFG_ENABLE 0x00000001 /* enable the receiver */
+#define BE_BR_RXCFG_FIFO 0x0000000e /* default rx fthresh */
+#define BE_BR_RXCFG_PSTRIP 0x00000020 /* pad byte strip enable */
+#define BE_BR_RXCFG_PMISC 0x00000040 /* enable promiscous mode */
+#define BE_BR_RXCFG_DERR 0x00000080 /* disable error checking */
+#define BE_BR_RXCFG_DCRCS 0x00000100 /* disable crc stripping */
+#define BE_BR_RXCFG_ME 0x00000200 /* receive packets for me */
+#define BE_BR_RXCFG_PGRP 0x00000400 /* enable promisc group mode */
+#define BE_BR_RXCFG_HENABLE 0x00000800 /* enable hash filter */
+#define BE_BR_RXCFG_AENABLE 0x00001000 /* enable address filter */
+
+/*
+ * BE Channel registers
+ */
struct be_cregs {
- volatile u_int32_t ctrl; /* Control */
- volatile u_int32_t stat; /* Status */
- volatile u_int32_t rxds; /* RX descriptor ring ptr */
- volatile u_int32_t txds; /* TX descriptor ring ptr */
- volatile u_int32_t rimask; /* RX Interrupt Mask */
- volatile u_int32_t timask; /* TX Interrupt Mask */
- volatile u_int32_t qmask; /* QEC Error Interrupt Mask */
- volatile u_int32_t bmask; /* BE Error Interrupt Mask */
- volatile u_int32_t rxwbufptr; /* Local memory rx write ptr */
- volatile u_int32_t rxrbufptr; /* Local memory rx read ptr */
- volatile u_int32_t txwbufptr; /* Local memory tx write ptr */
- volatile u_int32_t txrbufptr; /* Local memory tx read ptr */
- volatile u_int32_t ccnt; /* Collision Counter */
+ volatile u_int32_t ctrl; /* control */
+ volatile u_int32_t stat; /* status */
+ volatile u_int32_t rxds; /* rx descriptor ring ptr */
+ volatile u_int32_t txds; /* tx descriptor ring ptr */
+ volatile u_int32_t rimask; /* rx interrupt mask */
+ volatile u_int32_t timask; /* tx interrupt mask */
+ volatile u_int32_t qmask; /* qec error interrupt mask */
+ volatile u_int32_t bmask; /* be error interrupt mask */
+ volatile u_int32_t rxwbufptr; /* local memory rx write ptr */
+ volatile u_int32_t rxrbufptr; /* local memory rx read ptr */
+ volatile u_int32_t txwbufptr; /* local memory tx write ptr */
+ volatile u_int32_t txrbufptr; /* local memory tx read ptr */
+ volatile u_int32_t ccnt; /* collision counter */
};
+/* be_cregs.ctrl: control. */
+#define BE_CR_CTRL_TWAKEUP 0x00000001 /* tx dma wakeup */
+
+/* be_cregs.stat: status. */
+#define BE_CR_STAT_BERROR 0x80000000 /* be error */
+#define BE_CR_STAT_TXIRQ 0x00200000 /* tx interrupt */
+#define BE_CR_STAT_TXDERR 0x00080000 /* tx descriptor is bad */
+#define BE_CR_STAT_TXLERR 0x00040000 /* tx late error */
+#define BE_CR_STAT_TXPERR 0x00020000 /* tx parity error */
+#define BE_CR_STAT_TXSERR 0x00010000 /* tx sbus error ack */
+#define BE_CR_STAT_RXIRQ 0x00000020 /* rx interrupt */
+#define BE_CR_STAT_RXDROP 0x00000010 /* rx packet dropped */
+#define BE_CR_STAT_RXSMALL 0x00000008 /* rx buffer too small */
+#define BE_CR_STAT_RXLERR 0x00000004 /* rx late error */
+#define BE_CR_STAT_RXPERR 0x00000002 /* rx parity error */
+#define BE_CR_STAT_RXSERR 0x00000001 /* rx sbus error ack */
+
+/* be_cregs.qmask: qec error interrupt mask. */
+#define BE_CR_QMASK_TXDERR 0x00080000 /* tx descriptor is bad */
+#define BE_CR_QMASK_TXLERR 0x00040000 /* tx late error */
+#define BE_CR_QMASK_TXPERR 0x00020000 /* tx parity error */
+#define BE_CR_QMASK_TXSERR 0x00010000 /* tx sbus error ack */
+#define BE_CR_QMASK_RXDROP 0x00000010 /* rx packet dropped */
+#define BE_CR_QMASK_RXSMALL 0x00000008 /* rx buffer too small */
+#define BE_CR_QMASK_RXLERR 0x00000004 /* rx late error */
+#define BE_CR_QMASK_RXPERR 0x00000002 /* rx parity error */
+#define BE_CR_QMASK_RXSERR 0x00000001 /* rx sbus error ack */
+
+/*
+ * BE Tranceiver registers
+ */
struct be_tregs {
- u_int32_t tcvr_pal;
- u_int32_t mgmt_pal;
+ volatile u_int32_t tcvr_pal; /* tranceiver pal */
+ volatile u_int32_t mgmt_pal; /* management pal */
};
+/* be_tregs.tcvr_pal: tranceiver pal */
+#define TCVR_PAL_SERIAL 0x00000001 /* serial mode enable */
+#define TCVR_PAL_EXTLBACK 0x00000002 /* external loopback */
+#define TCVR_PAL_MSENSE 0x00000004 /* media sense */
+#define TCVR_PAL_LTENABLE 0x00000008 /* link test enable */
+#define TCVR_PAL_LTSTATUS 0x00000010 /* link test status: p1 only */
+
+/* be_tregs.mgmt_pal: management pal */
+#define MGMT_PAL_DCLOCK 0x00000001 /* data clock strobe */
+#define MGMT_PAL_OENAB 0x00000002 /* output enable */
+#define MGMT_PAL_MDIO 0x00000004 /* MDIO data/attached */
+#define MGMT_PAL_EXT_MDIO MGMT_PAL_MDIO /* external mdio */
+#define MGMT_PAL_TIMEO 0x00000008 /* tx enable timeout error */
+#define MGMT_PAL_INT_MDIO MGMT_PAL_TIMEO /* internal mdio */
+
+/*
+ * BE receive descriptor
+ */
struct be_rxd {
- u_int32_t rx_flags;
- u_int32_t rx_addr;
+ volatile u_int32_t rx_flags; /* rx descriptor flags */
+ volatile u_int32_t rx_addr; /* rx buffer address */
};
-#define RXD_OWN 0x80000000 /* Ownership. */
-#define RXD_UPDATE 0x10000000 /* Being Updated? */
-#define RXD_LENGTH 0x000007ff /* Packet Length. */
+#define BE_RXD_OWN 0x80000000 /* ownership: 1=hw, 0=sw */
+#define BE_RXD_UPDATE 0x10000000 /* being updated? */
+#define BE_RXD_LENGTH 0x00001fff /* packet length */
+/*
+ * BE transmit descriptor
+ */
struct be_txd {
- u_int32_t tx_flags;
- u_int32_t tx_addr;
+ volatile u_int32_t tx_flags; /* tx descriptor flags */
+ volatile u_int32_t tx_addr; /* tx buffer address */
};
-#define TXD_OWN 0x80000000 /* Ownership. */
-#define TXD_SOP 0x40000000 /* Start Of Packet */
-#define TXD_EOP 0x20000000 /* End Of Packet */
-#define TXD_UPDATE 0x10000000 /* Being Updated? */
-#define TXD_LENGTH 0x000007ff /* Packet Length. */
+#define BE_TXD_OWN 0x80000000 /* ownership: 1=hw, 0=sw */
+#define BE_TXD_SOP 0x40000000 /* start of packet marker */
+#define BE_TXD_EOP 0x20000000 /* end of packet marker */
+#define BE_TXD_UPDATE 0x10000000 /* being updated? */
+#define BE_TXD_LENGTH 0x00001fff /* packet length */
+/* Buffer and Ring sizes: fixed ring size */
+#define BE_TX_RING_MAXSIZE 256 /* maximum tx ring size */
+#define BE_RX_RING_MAXSIZE 256 /* maximum rx ring size */
+#define BE_TX_RING_SIZE BE_TX_RING_MAXSIZE
+#define BE_RX_RING_SIZE BE_RX_RING_MAXSIZE
+#define BE_PKT_BUF_SZ 2048
-
-
-#define TX_RING_MAXSIZE 256
-#define RX_RING_MAXSIZE 256
-#define TX_RING_SIZE 256
-#define RX_RING_SIZE 256
-
-#define SUN4C_PKT_BUF_SZ 1546
-#define SUN4C_RX_BUFF_SIZE SUN4C_PKT_BUF_SZ
-#define SUN4C_TX_BUFF_SIZE SUN4C_PKT_BUF_SZ
-#define SUN4C_RX_RING_SIZE 16
-#define SUN4C_TX_RING_SIZE 16
-
+/*
+ * BE descriptor rings
+ */
struct be_desc {
- struct be_rxd be_rxd[RX_RING_MAXSIZE];
- struct be_txd be_txd[TX_RING_MAXSIZE];
+ struct be_rxd be_rxd[BE_RX_RING_MAXSIZE];
+ struct be_txd be_txd[BE_TX_RING_MAXSIZE];
};
+/*
+ * BE packet buffers
+ */
struct be_bufs {
- char tx_buf[SUN4C_TX_RING_SIZE][SUN4C_TX_BUFF_SIZE];
- char pad[2];
- char rx_buf[SUN4C_RX_RING_SIZE][SUN4C_RX_BUFF_SIZE];
+ char rx_buf[BE_RX_RING_SIZE][BE_PKT_BUF_SZ];
+ char tx_buf[BE_TX_RING_SIZE][BE_PKT_BUF_SZ];
};
+
+/* PHY addresses */
+#define BE_PHY_EXTERNAL 0
+#define BE_PHY_INTERNAL 1
+
+/* Tranceiver types */
+#define BE_TCVR_NONE 0
+#define BE_TCVR_INTERNAL 1
+#define BE_TCVR_EXTERNAL 2
+
+#define BE_TCVR_READ_INVALID 0xff000000
+
+#define PHY_BMCR 0x00 /* Basic Mode Control Register */
+#define PHY_BMSR 0x01 /* Basic Mode Status Register */
+
+/*
+ * Basic Mode Control Register (BMCR)
+ */
+#define PHY_BMCR_RESET 0x8000 /* Software reset */
+#define PHY_BMCR_LOOPBACK 0x4000 /* Lookback enable */
+#define PHY_BMCR_SPEED 0x2000 /* 1=100Mb, 0=10Mb */
+#define PHY_BMCR_ANE 0x1000 /* Auto-Negiation enable */
+#define PHY_BMCR_PDOWN 0x0800 /* power down the chip */
+#define PHY_BMCR_ISOLATE 0x0400 /* Isolate the chip */
+#define PHY_BMCR_RAN 0x0200 /* Restart autonegotiation */
+#define PHY_BMCR_DUPLEX 0x0100 /* 1=full, 0=half */
+#define PHY_BMCR_COLLISONTEST 0x0080 /* Create collisions on TX */
+
+/*
+ * Basic Mode Status Register (BMSR)
+ */
+#define PHY_BMSR_100BASET4 0x8000 /* 100BaseT4 capable? */
+#define PHY_BMSR_100BASETX_FULL 0x4000 /* 100BaseTX full duplex? */
+#define PHY_BMSR_100BASETX_HALF 0x2000 /* 100BaseTX half duplex? */
+#define PHY_BMSR_10BASET_FULL 0x1000 /* 10BaseT full duplex? */
+#define PHY_BMSR_10BASET_HALF 0x0800 /* 10BaseT half duplex? */
+#define PHY_BMSR_ANCOMPLETE 0x0020 /* auto-negotiation complete? */
+#define PHY_BMSR_REMOTEFAULT 0x0010 /* Fault condition seen? */
+#define PHY_BMSR_ANC 0x0008 /* Can auto-negotiate? */
+#define PHY_BMSR_LINKSTATUS 0x0004 /* Link established? */
+#define PHY_BMSR_JABBER 0x0002 /* Jabber detected? */
+#define PHY_BMSR_EXTENDED 0x0001 /* Extended registers? */
diff --git a/sys/arch/sparc/dev/bevar.h b/sys/arch/sparc/dev/bevar.h
index 9f526f82578..572b642ffba 100644
--- a/sys/arch/sparc/dev/bevar.h
+++ b/sys/arch/sparc/dev/bevar.h
@@ -1,7 +1,8 @@
-/* $OpenBSD: bevar.h,v 1.4 1998/07/05 09:25:56 deraadt Exp $ */
+/* $OpenBSD: bevar.h,v 1.5 1998/08/26 05:00:54 jason Exp $ */
/*
- * Copyright (c) 1998 Theo de Raadt. All rights reserved.
+ * Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,13 +12,13 @@
* 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. The name of the author may not be used to endorse or promote products
+ * 3. The name of the authors 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
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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,
+ * IN NO EVENT SHALL THE AUTHORS 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
@@ -29,11 +30,10 @@
struct besoftc {
struct device sc_dev;
struct sbusdev sc_sd; /* sbus device */
- struct arpcom sc_arpcom;
struct intrhand sc_ih; /* interrupt vectoring */
- struct dma_softc *sc_dma; /* pointer to my dma */
+ struct arpcom sc_arpcom; /* ethernet common */
- u_long sc_laddr; /* DMA address */
+ struct qec_softc *sc_qec; /* QEC parent */
struct qecregs *sc_qr; /* QEC registers */
struct be_bregs *sc_br; /* registers */
struct be_cregs *sc_cr; /* registers */
@@ -41,16 +41,16 @@ struct besoftc {
void *sc_mem;
int sc_memsize;
- long sc_addr;
int sc_conf3;
u_int sc_rev;
int sc_promisc;
int sc_burst;
+ int sc_tcvr_type;
- int sc_txnew, sc_txold;
- int sc_rxnew, sc_rxold;
-
+ struct be_bufs *sc_bufs, *sc_bufs_dva;
struct be_desc *sc_desc, *sc_desc_dva;
- struct be_bufs *sc_bufs, *sc_bufs_dva;
+
+ int sc_no_td, sc_first_td, sc_last_td;
+ int sc_last_rd;
};