Share ring buffer code and data structure for `be' and `qe' in
the QEC module. Adapt the QEC interrupt establish code to suit the needs of the `qe' device.
This commit is contained in:
parent
58fa0024a5
commit
fb846bde24
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: be.c,v 1.1 1999/01/16 12:43:09 pk Exp $ */
|
||||
/* $NetBSD: be.c,v 1.2 1999/01/17 20:47:50 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -141,24 +141,8 @@ struct be_softc {
|
|||
int sc_burst;
|
||||
int sc_conf;
|
||||
#define BE_CONF_MII 1
|
||||
int sc_nticks; /* negotiation ticks */
|
||||
|
||||
/* Ring Descriptors */
|
||||
caddr_t sc_membase;
|
||||
bus_addr_t sc_dmabase;
|
||||
struct qec_xd *sc_txd; /* Transmit descriptors */
|
||||
bus_addr_t sc_txddma; /* DMA address of same */
|
||||
struct qec_xd *sc_rxd; /* Receive descriptors */
|
||||
bus_addr_t sc_rxddma; /* DMA address of same */
|
||||
caddr_t sc_txbuf; /* Transmit buffers */
|
||||
caddr_t sc_rxbuf; /* Receive buffers */
|
||||
int sc_ntbuf; /* # of transmit buffers */
|
||||
int sc_nrbuf; /* # of receive buffers */
|
||||
|
||||
/* Ring Descriptor state */
|
||||
int sc_tdhead, sc_tdtail;
|
||||
int sc_rdtail;
|
||||
int sc_td_nbusy;
|
||||
struct qec_ring sc_rb; /* Packet Ring Buffer */
|
||||
|
||||
/* MAC address */
|
||||
u_int8_t sc_enaddr[6];
|
||||
|
@ -168,7 +152,6 @@ int bematch __P((struct device *, struct cfdata *, void *));
|
|||
void beattach __P((struct device *, struct device *, void *));
|
||||
|
||||
void beinit __P((struct be_softc *));
|
||||
void bememinit __P((struct be_softc *));
|
||||
void bestart __P((struct ifnet *));
|
||||
void bestop __P((struct be_softc *));
|
||||
void bewatchdog __P((struct ifnet *));
|
||||
|
@ -190,6 +173,7 @@ void be_tcvr_init __P((struct be_softc *));
|
|||
/* ifmedia callbacks */
|
||||
void be_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
|
||||
int be_ifmedia_upd __P((struct ifnet *));
|
||||
|
||||
void be_mcreset __P((struct be_softc *));
|
||||
|
||||
/* MII methods & callbacks */
|
||||
|
@ -300,13 +284,15 @@ beattach(parent, self, aux)
|
|||
/*
|
||||
* Allocate descriptor ring and buffers.
|
||||
*/
|
||||
sc->sc_ntbuf = QEC_XD_RING_MAXSIZE; /* for now, allocate as many bufs */
|
||||
sc->sc_nrbuf = QEC_XD_RING_MAXSIZE; /* as there are ring descriptors */
|
||||
|
||||
/* for now, allocate as many bufs as there are ring descriptors */
|
||||
sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE;
|
||||
sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE;
|
||||
|
||||
size = QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
|
||||
QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) +
|
||||
sc->sc_ntbuf * BE_PKT_BUF_SZ +
|
||||
sc->sc_nrbuf * BE_PKT_BUF_SZ;
|
||||
sc->sc_rb.rb_ntbuf * BE_PKT_BUF_SZ +
|
||||
sc->sc_rb.rb_nrbuf * BE_PKT_BUF_SZ;
|
||||
if ((error = bus_dmamem_alloc(sa->sa_dmatag, size,
|
||||
NBPG, 0,
|
||||
&seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
|
||||
|
@ -314,10 +300,10 @@ beattach(parent, self, aux)
|
|||
self->dv_xname, error);
|
||||
return;
|
||||
}
|
||||
sc->sc_dmabase = seg.ds_addr;
|
||||
sc->sc_rb.rb_dmabase = seg.ds_addr;
|
||||
|
||||
if ((error = bus_dmamem_map(sa->sa_dmatag, &seg, rseg, size,
|
||||
&sc->sc_membase,
|
||||
&sc->sc_rb.rb_membase,
|
||||
BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
|
||||
printf("%s: DMA buffer map error %d\n",
|
||||
self->dv_xname, error);
|
||||
|
@ -432,7 +418,9 @@ be_put(sc, idx, m)
|
|||
{
|
||||
struct mbuf *n;
|
||||
int len, tlen = 0, boff = 0;
|
||||
caddr_t bp = sc->sc_txbuf + (idx % sc->sc_ntbuf) * BE_PKT_BUF_SZ;
|
||||
caddr_t bp;
|
||||
|
||||
bp = sc->sc_rb.rb_txbuf + (idx % sc->sc_rb.rb_ntbuf) * BE_PKT_BUF_SZ;
|
||||
|
||||
for (; m; m = n) {
|
||||
len = m->m_len;
|
||||
|
@ -463,7 +451,9 @@ be_get(sc, idx, totlen)
|
|||
struct mbuf *m;
|
||||
struct mbuf *top, **mp;
|
||||
int len, pad, boff = 0;
|
||||
caddr_t bp = sc->sc_rxbuf + (idx % sc->sc_nrbuf) * BE_PKT_BUF_SZ;
|
||||
caddr_t bp;
|
||||
|
||||
bp = sc->sc_rb.rb_rxbuf + (idx % sc->sc_rb.rb_nrbuf) * BE_PKT_BUF_SZ;
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
|
@ -564,15 +554,15 @@ bestart(ifp)
|
|||
struct ifnet *ifp;
|
||||
{
|
||||
struct be_softc *sc = (struct be_softc *)ifp->if_softc;
|
||||
struct qec_xd *txd = sc->sc_txd;
|
||||
struct qec_xd *txd = sc->sc_rb.rb_txd;
|
||||
struct mbuf *m;
|
||||
unsigned int bix, len;
|
||||
unsigned int ntbuf = sc->sc_ntbuf;
|
||||
unsigned int ntbuf = sc->sc_rb.rb_ntbuf;
|
||||
|
||||
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
|
||||
return;
|
||||
|
||||
bix = sc->sc_tdhead;
|
||||
bix = sc->sc_rb.rb_tdhead;
|
||||
|
||||
for (;;) {
|
||||
IF_DEQUEUE(&ifp->if_snd, m);
|
||||
|
@ -604,13 +594,13 @@ bestart(ifp)
|
|||
if (++bix == QEC_XD_RING_MAXSIZE)
|
||||
bix = 0;
|
||||
|
||||
if (++sc->sc_td_nbusy == ntbuf) {
|
||||
if (++sc->sc_rb.rb_td_nbusy == ntbuf) {
|
||||
ifp->if_flags |= IFF_OACTIVE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sc->sc_tdhead = bix;
|
||||
sc->sc_rb.rb_tdhead = bix;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -844,13 +834,13 @@ betint(sc)
|
|||
bus_space_write_4(t, br, BE_BRI_EXCNT, 0);
|
||||
bus_space_write_4(t, br, BE_BRI_LTCNT, 0);
|
||||
|
||||
bix = sc->sc_tdtail;
|
||||
bix = sc->sc_rb.rb_tdtail;
|
||||
|
||||
for (;;) {
|
||||
if (sc->sc_td_nbusy <= 0)
|
||||
if (sc->sc_rb.rb_td_nbusy <= 0)
|
||||
break;
|
||||
|
||||
txflags = sc->sc_txd[bix].xd_flags;
|
||||
txflags = sc->sc_rb.rb_txd[bix].xd_flags;
|
||||
|
||||
if (txflags & QEC_XD_OWN)
|
||||
break;
|
||||
|
@ -861,14 +851,14 @@ betint(sc)
|
|||
if (++bix == QEC_XD_RING_MAXSIZE)
|
||||
bix = 0;
|
||||
|
||||
--sc->sc_td_nbusy;
|
||||
--sc->sc_rb.rb_td_nbusy;
|
||||
}
|
||||
|
||||
sc->sc_tdtail = bix;
|
||||
sc->sc_rb.rb_tdtail = bix;
|
||||
|
||||
bestart(ifp);
|
||||
|
||||
if (sc->sc_td_nbusy == 0)
|
||||
if (sc->sc_rb.rb_td_nbusy == 0)
|
||||
ifp->if_timer = 0;
|
||||
|
||||
return (1);
|
||||
|
@ -881,11 +871,11 @@ int
|
|||
berint(sc)
|
||||
struct be_softc *sc;
|
||||
{
|
||||
struct qec_xd *xd = sc->sc_rxd;
|
||||
struct qec_xd *xd = sc->sc_rb.rb_rxd;
|
||||
unsigned int bix, len;
|
||||
unsigned int nrbuf = sc->sc_nrbuf;
|
||||
unsigned int nrbuf = sc->sc_rb.rb_nrbuf;
|
||||
|
||||
bix = sc->sc_rdtail;
|
||||
bix = sc->sc_rb.rb_rdtail;
|
||||
|
||||
/*
|
||||
* Process all buffers with valid data.
|
||||
|
@ -906,7 +896,7 @@ berint(sc)
|
|||
bix = 0;
|
||||
}
|
||||
|
||||
sc->sc_rdtail = bix;
|
||||
sc->sc_rb.rb_rdtail = bix;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
@ -984,7 +974,7 @@ beioctl(ifp, cmd, data)
|
|||
}
|
||||
#ifdef BEDEBUG
|
||||
if (ifp->if_flags & IFF_DEBUG)
|
||||
sc->sc_debug = BE_XXX;
|
||||
sc->sc_debug = 1;
|
||||
else
|
||||
sc->sc_debug = 0;
|
||||
#endif
|
||||
|
@ -1017,97 +1007,23 @@ beioctl(ifp, cmd, data)
|
|||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
bememinit(sc)
|
||||
struct be_softc *sc;
|
||||
{
|
||||
bus_addr_t txbufdma, rxbufdma;
|
||||
bus_addr_t dma;
|
||||
caddr_t p;
|
||||
unsigned int ntbuf, nrbuf, i;
|
||||
|
||||
p = sc->sc_membase;
|
||||
dma = sc->sc_dmabase;
|
||||
|
||||
ntbuf = sc->sc_ntbuf;
|
||||
nrbuf = sc->sc_nrbuf;
|
||||
|
||||
/*
|
||||
* Allocate transmit descriptors
|
||||
*/
|
||||
sc->sc_txd = (struct qec_xd *)p;
|
||||
sc->sc_txddma = dma;
|
||||
p += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
dma += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
|
||||
/*
|
||||
* Allocate receive descriptors
|
||||
*/
|
||||
sc->sc_rxd = (struct qec_xd *)p;
|
||||
sc->sc_rxddma = dma;
|
||||
p += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
dma += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
|
||||
|
||||
/*
|
||||
* Allocate transmit buffers
|
||||
*/
|
||||
sc->sc_txbuf = p;
|
||||
txbufdma = dma;
|
||||
p += ntbuf * BE_PKT_BUF_SZ;
|
||||
dma += ntbuf * BE_PKT_BUF_SZ;
|
||||
|
||||
/*
|
||||
* Allocate receive buffers
|
||||
*/
|
||||
sc->sc_rxbuf = p;
|
||||
rxbufdma = dma;
|
||||
p += nrbuf * BE_PKT_BUF_SZ;
|
||||
dma += nrbuf * BE_PKT_BUF_SZ;
|
||||
|
||||
/*
|
||||
* Initialize transmit buffer descriptors
|
||||
*/
|
||||
for (i = 0; i < QEC_XD_RING_MAXSIZE; i++) {
|
||||
sc->sc_txd[i].xd_addr = (u_int32_t)
|
||||
(txbufdma + (i % ntbuf) * BE_PKT_BUF_SZ);
|
||||
sc->sc_txd[i].xd_flags = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize receive buffer descriptors
|
||||
*/
|
||||
for (i = 0; i < QEC_XD_RING_MAXSIZE; i++) {
|
||||
sc->sc_rxd[i].xd_addr = (u_int32_t)
|
||||
(rxbufdma + (i % nrbuf) * BE_PKT_BUF_SZ);
|
||||
sc->sc_rxd[i].xd_flags = (i < nrbuf)
|
||||
? QEC_XD_OWN | (BE_PKT_BUF_SZ & QEC_XD_LENGTH)
|
||||
: 0;
|
||||
}
|
||||
|
||||
sc->sc_tdhead = sc->sc_tdtail = 0;
|
||||
sc->sc_td_nbusy = 0;
|
||||
sc->sc_rdtail = 0;
|
||||
}
|
||||
|
||||
void
|
||||
beinit(sc)
|
||||
struct be_softc *sc;
|
||||
{
|
||||
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
||||
bus_space_tag_t t = sc->sc_bustag;
|
||||
bus_space_handle_t br = sc->sc_br;
|
||||
bus_space_handle_t cr = sc->sc_cr;
|
||||
struct qec_softc *qec = sc->sc_qec;
|
||||
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
||||
u_int32_t qecaddr;
|
||||
u_int8_t *ea;
|
||||
int s;
|
||||
|
||||
s = splimp();
|
||||
|
||||
sc->sc_nticks = 0;
|
||||
|
||||
bememinit(sc);
|
||||
qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ);
|
||||
be_tcvr_init(sc);
|
||||
|
||||
be_ifmedia_upd(ifp);
|
||||
|
@ -1152,8 +1068,8 @@ beinit(sc)
|
|||
BE_BR_IMASK_DTIMEXP);
|
||||
|
||||
/* Channel registers: */
|
||||
bus_space_write_4(t, cr, BE_CRI_RXDS, (u_int32_t)sc->sc_rxddma);
|
||||
bus_space_write_4(t, cr, BE_CRI_TXDS, (u_int32_t)sc->sc_txddma);
|
||||
bus_space_write_4(t, cr, BE_CRI_RXDS, (u_int32_t)sc->sc_rb.rb_rxddma);
|
||||
bus_space_write_4(t, cr, BE_CRI_TXDS, (u_int32_t)sc->sc_rb.rb_txddma);
|
||||
|
||||
qecaddr = sc->sc_channel * qec->sc_msize;
|
||||
bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr);
|
||||
|
@ -1187,7 +1103,7 @@ void
|
|||
be_mcreset(sc)
|
||||
struct be_softc *sc;
|
||||
{
|
||||
struct ethercom *ac = &sc->sc_ethercom;
|
||||
struct ethercom *ec = &sc->sc_ethercom;
|
||||
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
|
||||
bus_space_tag_t t = sc->sc_bustag;
|
||||
bus_space_handle_t br = sc->sc_br;
|
||||
|
@ -1217,7 +1133,7 @@ be_mcreset(sc)
|
|||
|
||||
hash[3] = hash[2] = hash[1] = hash[0] = 0;
|
||||
|
||||
ETHER_FIRST_MULTI(step, ac, enm);
|
||||
ETHER_FIRST_MULTI(step, ec, enm);
|
||||
while (enm != NULL) {
|
||||
if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
|
||||
/*
|
||||
|
@ -1321,14 +1237,14 @@ be_tcvr_init(sc)
|
|||
DELAY(200);
|
||||
|
||||
v = bus_space_read_4(t, tr, BE_TRI_MGMTPAL);
|
||||
#ifdef DEBUG
|
||||
if (bedebug) {
|
||||
#ifdef BEDEBUG
|
||||
if (sc->sc_debug != 0) {
|
||||
char bits[64];
|
||||
printf("be_tcvr_init: MGMTPAL=%s\n",
|
||||
bitmask_snprintf(v, MGMT_PAL_BITS, bits, sizeof(bits)));
|
||||
}
|
||||
#endif
|
||||
if (v & MGMT_PAL_EXT_MDIO) {
|
||||
if ((v & MGMT_PAL_EXT_MDIO) != 0) {
|
||||
sc->sc_conf |= BE_CONF_MII;
|
||||
/*sc->sc_tcvr_type = BE_TCVR_EXTERNAL;*/
|
||||
bus_space_write_4(t, tr, BE_TRI_TCVRPAL,
|
||||
|
@ -1336,15 +1252,13 @@ be_tcvr_init(sc)
|
|||
TCVR_PAL_LTENABLE));
|
||||
|
||||
(void)bus_space_read_4(t, tr, BE_TRI_TCVRPAL);
|
||||
}
|
||||
else if (v & MGMT_PAL_INT_MDIO) {
|
||||
} else if ((v & MGMT_PAL_INT_MDIO) != 0) {
|
||||
/*sc->sc_tcvr_type = BE_TCVR_INTERNAL;*/
|
||||
bus_space_write_4(t, tr, BE_TRI_TCVRPAL,
|
||||
~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE |
|
||||
TCVR_PAL_LTENABLE | TCVR_PAL_SERIAL));
|
||||
(void)bus_space_read_4(t, tr, BE_TRI_TCVRPAL);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("%s: no internal or external transceiver found.\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bereg.h,v 1.1 1999/01/16 13:19:11 pk Exp $ */
|
||||
/* $NetBSD: bereg.h,v 1.2 1999/01/17 20:47:50 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -158,6 +158,12 @@ struct be_bregs {
|
|||
#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 */
|
||||
#define BE_BR_STAT_BITS "\177\020" \
|
||||
"b\0GOTFRAME\0b\1RCNTEXP\0b\2ACNTEXP\0" \
|
||||
"b\3CCNTEXP\0b\5LCNTEXP\0b\6RFIFOVF\0" \
|
||||
"b\7CVCNTEXP\0b\10SENTFRAME\0b\11TFIFO_UND\0" \
|
||||
"b\12MAXPKTERR\0b\13NCNTEXP\0b\14ECNTEXP\0" \
|
||||
"b\15LCCNTEXP\0b\16FCNTEXP\0b\17DTIMEXP\0\0"
|
||||
|
||||
/* be_bregs.imask: interrupt mask. */
|
||||
#define BE_BR_IMASK_GOTFRAME 0x00000001 /* received a frame */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: qec.c,v 1.7 1999/01/16 12:46:08 pk Exp $ */
|
||||
/* $NetBSD: qec.c,v 1.8 1999/01/17 20:47:50 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -64,6 +64,12 @@ static int qec_bus_map __P((
|
|||
int, /*flags*/
|
||||
vaddr_t, /*preferred virtual address */
|
||||
bus_space_handle_t *));
|
||||
static void *qec_intr_establish __P((
|
||||
bus_space_tag_t,
|
||||
int, /*level*/
|
||||
int, /*flags*/
|
||||
int (*) __P((void *)), /*handler*/
|
||||
void *)); /*arg*/
|
||||
|
||||
struct cfattach qec_ca = {
|
||||
sizeof(struct qec_softc), qecmatch, qecattach
|
||||
|
@ -202,6 +208,18 @@ qecattach(parent, self, aux)
|
|||
sbt->cookie = sc;
|
||||
sbt->parent = sc->sc_bustag;
|
||||
sbt->sparc_bus_map = qec_bus_map;
|
||||
sbt->sparc_intr_establish = qec_intr_establish;
|
||||
|
||||
/*
|
||||
* Save interrupt information for use in our qec_intr_establish()
|
||||
* function below. Apparently, the intr level for the quad
|
||||
* ethernet board (qe) is stored in the QEC node rather then
|
||||
* separately in each of the QE nodes.
|
||||
*
|
||||
* XXX - qe.c should call bus_intr_establish() with `level = 0'..
|
||||
* XXX - maybe we should have our own attach args for all that.
|
||||
*/
|
||||
sc->sc_intr = sa->sa_intr;
|
||||
|
||||
printf(": %dK memory\n", sc->sc_bufsiz / 1024);
|
||||
|
||||
|
@ -248,6 +266,32 @@ qec_bus_map(t, btype, offset, size, flags, vaddr, hp)
|
|||
return (EINVAL);
|
||||
}
|
||||
|
||||
void *
|
||||
qec_intr_establish(t, level, flags, handler, arg)
|
||||
bus_space_tag_t t;
|
||||
int level;
|
||||
int flags;
|
||||
int (*handler) __P((void *));
|
||||
void *arg;
|
||||
{
|
||||
struct qec_softc *sc = t->cookie;
|
||||
|
||||
if (level == 0) {
|
||||
/*
|
||||
* qe.c calls bus_intr_establish() with `level = 0'
|
||||
* XXX - see also comment in qec_attach().
|
||||
*/
|
||||
if (sc->sc_intr == NULL) {
|
||||
printf("%s: warning: no interrupts\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return (NULL);
|
||||
}
|
||||
level = sc->sc_intr->sbi_pri;
|
||||
}
|
||||
|
||||
return (bus_intr_establish(t->parent, level, flags, handler, arg));
|
||||
}
|
||||
|
||||
void
|
||||
qec_init(sc)
|
||||
struct qec_softc *sc;
|
||||
|
@ -280,3 +324,81 @@ qec_init(sc)
|
|||
v = (v & QEC_CTRL_MODEMASK) | burst;
|
||||
bus_space_write_4(t, qr, QEC_QRI_CTRL, v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common routine to initialize the QEC packet ring buffer.
|
||||
* Called from be & qe drivers.
|
||||
*/
|
||||
void
|
||||
qec_meminit(qr, pktbufsz)
|
||||
struct qec_ring *qr;
|
||||
unsigned int pktbufsz;
|
||||
{
|
||||
bus_addr_t txbufdma, rxbufdma;
|
||||
bus_addr_t dma;
|
||||
caddr_t p;
|
||||
unsigned int ntbuf, nrbuf, i;
|
||||
|
||||
p = qr->rb_membase;
|
||||
dma = qr->rb_dmabase;
|
||||
|
||||
ntbuf = qr->rb_ntbuf;
|
||||
nrbuf = qr->rb_nrbuf;
|
||||
|
||||
/*
|
||||
* Allocate transmit descriptors
|
||||
*/
|
||||
qr->rb_txd = (struct qec_xd *)p;
|
||||
qr->rb_txddma = dma;
|
||||
p += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
dma += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
|
||||
/*
|
||||
* Allocate receive descriptors
|
||||
*/
|
||||
qr->rb_rxd = (struct qec_xd *)p;
|
||||
qr->rb_rxddma = dma;
|
||||
p += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
dma += QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd);
|
||||
|
||||
|
||||
/*
|
||||
* Allocate transmit buffers
|
||||
*/
|
||||
qr->rb_txbuf = p;
|
||||
txbufdma = dma;
|
||||
p += ntbuf * pktbufsz;
|
||||
dma += ntbuf * pktbufsz;
|
||||
|
||||
/*
|
||||
* Allocate receive buffers
|
||||
*/
|
||||
qr->rb_rxbuf = p;
|
||||
rxbufdma = dma;
|
||||
p += nrbuf * pktbufsz;
|
||||
dma += nrbuf * pktbufsz;
|
||||
|
||||
/*
|
||||
* Initialize transmit buffer descriptors
|
||||
*/
|
||||
for (i = 0; i < QEC_XD_RING_MAXSIZE; i++) {
|
||||
qr->rb_txd[i].xd_addr = (u_int32_t)
|
||||
(txbufdma + (i % ntbuf) * pktbufsz);
|
||||
qr->rb_txd[i].xd_flags = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize receive buffer descriptors
|
||||
*/
|
||||
for (i = 0; i < QEC_XD_RING_MAXSIZE; i++) {
|
||||
qr->rb_rxd[i].xd_addr = (u_int32_t)
|
||||
(rxbufdma + (i % nrbuf) * pktbufsz);
|
||||
qr->rb_rxd[i].xd_flags = (i < nrbuf)
|
||||
? QEC_XD_OWN | (pktbufsz & QEC_XD_LENGTH)
|
||||
: 0;
|
||||
}
|
||||
|
||||
qr->rb_tdhead = qr->rb_tdtail = 0;
|
||||
qr->rb_td_nbusy = 0;
|
||||
qr->rb_rdtail = 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: qecvar.h,v 1.3 1999/01/16 12:46:08 pk Exp $ */
|
||||
/* $NetBSD: qecvar.h,v 1.4 1999/01/17 20:47:50 pk Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -43,6 +43,7 @@ struct qec_softc {
|
|||
bus_dma_tag_t sc_dmatag;
|
||||
struct sbus_range *sc_range; /* PROM ranges */
|
||||
int sc_nrange; /* */
|
||||
struct sbus_intr *sc_intr; /* interrupt info */
|
||||
|
||||
bus_space_handle_t sc_regs; /* QEC registers */
|
||||
int sc_nchannels; /* # of channels on board */
|
||||
|
@ -53,3 +54,24 @@ struct qec_softc {
|
|||
u_int sc_msize; /* QEC buffer offset per channel */
|
||||
u_int sc_rsize; /* QEC buffer size for receive */
|
||||
};
|
||||
|
||||
struct qec_ring {
|
||||
/* Ring Descriptors */
|
||||
caddr_t rb_membase; /* Packet buffer: CPU address */
|
||||
bus_addr_t rb_dmabase; /* Packet buffer: DMA address */
|
||||
struct qec_xd *rb_txd; /* Transmit descriptors */
|
||||
bus_addr_t rb_txddma; /* DMA address of same */
|
||||
struct qec_xd *rb_rxd; /* Receive descriptors */
|
||||
bus_addr_t rb_rxddma; /* DMA address of same */
|
||||
caddr_t rb_txbuf; /* Transmit buffers */
|
||||
caddr_t rb_rxbuf; /* Receive buffers */
|
||||
int rb_ntbuf; /* # of transmit buffers */
|
||||
int rb_nrbuf; /* # of receive buffers */
|
||||
|
||||
/* Ring Descriptor state */
|
||||
int rb_tdhead, rb_tdtail;
|
||||
int rb_rdtail;
|
||||
int rb_td_nbusy;
|
||||
};
|
||||
|
||||
void qec_meminit __P((struct qec_ring *, unsigned int));
|
||||
|
|
Loading…
Reference in New Issue