diff options
-rw-r--r-- | sys/arch/sparc/conf/files.sparc | 5 | ||||
-rw-r--r-- | sys/arch/sparc/dev/be.c | 769 | ||||
-rw-r--r-- | sys/arch/sparc/dev/bereg.h | 415 | ||||
-rw-r--r-- | sys/arch/sparc/dev/bevar.h | 26 |
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 = ⊤ + + 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; }; |