summaryrefslogtreecommitdiff
path: root/sys/arch/vax
diff options
context:
space:
mode:
authorHugh Graham <hugh@cvs.openbsd.org>2003-02-04 02:03:52 +0000
committerHugh Graham <hugh@cvs.openbsd.org>2003-02-04 02:03:52 +0000
commit4f999461359bf6c2fc14ff56a57aacd615e696c4 (patch)
tree5c4c80abe5c7127e16874e3283989e73405f271f /sys/arch/vax
parentaad7713bf64acff8508aebd07cbb07e4383ccbbf (diff)
Bring qe closer to NetBSD and make it compile. As yet untested.
Diffstat (limited to 'sys/arch/vax')
-rw-r--r--sys/arch/vax/if/if_qe.c179
-rw-r--r--sys/arch/vax/if/if_qereg.h8
2 files changed, 76 insertions, 111 deletions
diff --git a/sys/arch/vax/if/if_qe.c b/sys/arch/vax/if/if_qe.c
index 8b2088a5b6e..d662fec4ec1 100644
--- a/sys/arch/vax/if/if_qe.c
+++ b/sys/arch/vax/if/if_qe.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_qe.c,v 1.14 2002/10/12 01:09:44 krw Exp $ */
-/* $NetBSD: if_qe.c,v 1.39 2000/01/24 02:40:29 matt Exp $ */
+/* $OpenBSD: if_qe.c,v 1.15 2003/02/04 02:03:51 hugh Exp $ */
+/* $NetBSD: if_qe.c,v 1.51 2002/06/08 12:28:37 ragge Exp $ */
/*
* Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
*
@@ -33,7 +33,6 @@
/*
* Driver for DEQNA/DELQA ethernet cards.
* Things that is still to do:
- * Have a timeout check for hang transmit logic.
* Handle ubaresets. Does not work at all right now.
* Fix ALLMULTI reception. But someone must tell me how...
* Collect statistics.
@@ -50,6 +49,7 @@
#include <net/if.h>
#include <net/if_dl.h>
+
#include <netinet/in.h>
#include <netinet/if_ether.h>
@@ -61,11 +61,10 @@
#include <machine/bus.h>
#include <arch/vax/qbus/ubavar.h>
-#include <arch/vax/qbus/if_qereg.h>
+#include <arch/vax/if/if_qereg.h>
#define RXDESCS 30 /* # of receive descriptors */
#define TXDESCS 60 /* # transmit descs */
-#define ETHER_MINLEN 64 /* min frame + crc */
/*
* Structure containing the elements that must be in DMA-safe memory.
@@ -78,6 +77,7 @@ struct qe_cdata {
struct qe_softc {
struct device sc_dev; /* Configuration common part */
+ struct evcnt sc_intrcnt; /* Interrupt counting */
struct arpcom sc_ac; /* Ethernet common part */
#define sc_if sc_ac.ac_if /* network-visible interface */
bus_space_tag_t sc_iot;
@@ -85,11 +85,11 @@ struct qe_softc {
bus_dma_tag_t sc_dmat;
struct qe_cdata *sc_qedata; /* Descriptor struct */
struct qe_cdata *sc_pqedata; /* Unibus address of above */
- bus_dmamap_t sc_cmap; /* Map for control structures */
struct mbuf* sc_txmbuf[TXDESCS];
struct mbuf* sc_rxmbuf[RXDESCS];
bus_dmamap_t sc_xmtmap[TXDESCS];
bus_dmamap_t sc_rcvmap[RXDESCS];
+ struct ubinfo sc_ui;
int sc_intvec; /* Interrupt vector */
int sc_nexttx;
int sc_inq;
@@ -112,6 +112,10 @@ struct cfattach qe_ca = {
sizeof(struct qe_softc), (cfmatch_t)qematch, qeattach
};
+struct cfdriver qe_cd = {
+ NULL, "qe", DV_IFNET
+};
+
#define QE_WCSR(csr, val) \
bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
#define QE_RCSR(csr) \
@@ -125,22 +129,20 @@ struct cfattach qe_ca = {
* and wait for interrupt.
*/
int
-qematch(parent, cf, aux)
- struct device *parent;
- struct cfdata *cf;
- void *aux;
+qematch(struct device *parent, struct cfdata *cf, void *aux)
{
- bus_dmamap_t cmap;
struct qe_softc ssc;
struct qe_softc *sc = &ssc;
struct uba_attach_args *ua = aux;
struct uba_softc *ubasc = (struct uba_softc *)parent;
+ struct ubinfo ui;
-#define PROBESIZE (sizeof(struct qe_ring) * 4 + 128)
- struct qe_ring ring[15]; /* For diag purposes only */
+#define PROBESIZE 4096
+ struct qe_ring *ring;
struct qe_ring *rp;
int error;
+ ring = malloc(PROBESIZE, M_TEMP, M_WAITOK);
bzero(sc, sizeof(struct qe_softc));
bzero(ring, PROBESIZE);
sc->sc_iot = ua->ua_iot;
@@ -156,32 +158,25 @@ qematch(parent, cf, aux)
* send and receive a internal packet; some junk is loopbacked
* so that the DEQNA has a reason to interrupt.
*/
- if ((error = bus_dmamap_create(sc->sc_dmat, PROBESIZE, 1, PROBESIZE, 0,
- BUS_DMA_NOWAIT, &cmap))) {
- printf("qematch: bus_dmamap_create failed = %d\n", error);
- return 0;
- }
- if ((error = bus_dmamap_load(sc->sc_dmat, cmap, ring, PROBESIZE, 0,
- BUS_DMA_NOWAIT))) {
- printf("qematch: bus_dmamap_load failed = %d\n", error);
- bus_dmamap_destroy(sc->sc_dmat, cmap);
+ ui.ui_size = PROBESIZE;
+ ui.ui_vaddr = (caddr_t)&ring[0];
+ if ((error = uballoc((void *)parent, &ui, UBA_CANTWAIT)))
return 0;
- }
/*
* Init a simple "fake" receive and transmit descriptor that
* points to some unused area. Send a fake setup packet.
*/
- rp = (void *)cmap->dm_segs[0].ds_addr;
+ rp = (void *)ui.ui_baddr;
ring[0].qe_flag = ring[0].qe_status1 = QE_NOTYET;
ring[0].qe_addr_lo = LOWORD(&rp[4]);
ring[0].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID | QE_EOMSG | QE_SETUP;
- ring[0].qe_buf_len = 128;
+ ring[0].qe_buf_len = -64;
ring[2].qe_flag = ring[2].qe_status1 = QE_NOTYET;
ring[2].qe_addr_lo = LOWORD(&rp[4]);
ring[2].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID;
- ring[2].qe_buf_len = 128;
+ ring[2].qe_buf_len = -(1500/2);
QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET);
DELAY(1000);
@@ -199,8 +194,8 @@ qematch(parent, cf, aux)
/*
* All done with the bus resources.
*/
- bus_dmamap_unload(sc->sc_dmat, cmap);
- bus_dmamap_destroy(sc->sc_dmat, cmap);
+ ubfree((void *)parent, &ui);
+ free(ring, M_TEMP);
return 1;
}
@@ -210,9 +205,7 @@ qematch(parent, cf, aux)
* to accept packets.
*/
void
-qeattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
+qeattach(struct device *parent, struct device *self, void *aux)
{
struct uba_attach_args *ua = aux;
struct uba_softc *ubasc = (struct uba_softc *)parent;
@@ -220,8 +213,7 @@ qeattach(parent, self, aux)
struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
struct qe_ring *rp;
u_int8_t enaddr[ETHER_ADDR_LEN];
- bus_dma_segment_t seg;
- int i, rseg, error;
+ int i, error;
sc->sc_iot = ua->ua_iot;
sc->sc_ioh = ua->ua_ioh;
@@ -230,37 +222,14 @@ qeattach(parent, self, aux)
/*
* Allocate DMA safe memory for descriptors and setup memory.
*/
- if ((error = bus_dmamem_alloc(sc->sc_dmat,
- sizeof(struct qe_cdata), NBPG, 0, &seg, 1, &rseg,
- BUS_DMA_NOWAIT)) != 0) {
- printf(": unable to allocate control data, error = %d\n",
- error);
- goto fail_0;
- }
-
- if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
- sizeof(struct qe_cdata), (caddr_t *)&sc->sc_qedata,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
- printf(": unable to map control data, error = %d\n", error);
- goto fail_1;
- }
-
- if ((error = bus_dmamap_create(sc->sc_dmat,
- sizeof(struct qe_cdata), 1,
- sizeof(struct qe_cdata), 0, BUS_DMA_NOWAIT,
- &sc->sc_cmap)) != 0) {
- printf(": unable to create control data DMA map, error = %d\n",
- error);
- goto fail_2;
- }
- if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
- sc->sc_qedata, sizeof(struct qe_cdata), NULL,
- BUS_DMA_NOWAIT)) != 0) {
- printf(": unable to load control data DMA map, error = %d\n",
- error);
- goto fail_3;
+ sc->sc_ui.ui_size = sizeof(struct qe_cdata);
+ if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) {
+ printf(": unable to ubmemalloc(), error = %d\n", error);
+ return;
}
+ sc->sc_pqedata = (struct qe_cdata *)sc->sc_ui.ui_baddr;
+ sc->sc_qedata = (struct qe_cdata *)sc->sc_ui.ui_vaddr;
/*
* Zero the newly allocated memory.
@@ -309,7 +278,6 @@ qeattach(parent, self, aux)
* Create ring loops of the buffer chains.
* This is only done once.
*/
- sc->sc_pqedata = (struct qe_cdata *)sc->sc_cmap->dm_segs[0].ds_addr;
rp = sc->sc_qedata->qc_recv;
rp[RXDESCS].qe_addr_lo = LOWORD(&sc->sc_pqedata->qc_recv[0]);
@@ -344,7 +312,9 @@ qeattach(parent, self, aux)
QE_WCSR(QE_CSR_VECTOR, QE_RCSR(QE_CSR_VECTOR) & ~1); /* ??? */
- uba_intr_establish(ua->ua_icookie, ua->ua_cvec, qeintr, sc);
+ uba_intr_establish(ua->ua_icookie, ua->ua_cvec, qeintr,
+ sc, &sc->sc_intrcnt);
+ evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
ifp->if_softc = sc;
@@ -352,12 +322,14 @@ qeattach(parent, self, aux)
ifp->if_start = qestart;
ifp->if_ioctl = qeioctl;
ifp->if_watchdog = qetimeout;
+ IFQ_SET_READY(&ifp->if_snd);
/*
* Attach the interface.
*/
if_attach(ifp);
ether_ifattach(ifp);
+
return;
/*
@@ -381,24 +353,13 @@ qeattach(parent, self, aux)
if (sc->sc_rcvmap[i] != NULL)
bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
}
- bus_dmamap_unload(sc->sc_dmat, sc->sc_cmap);
- fail_3:
- bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
- fail_2:
- bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_qedata,
- sizeof(struct qe_cdata));
- fail_1:
- bus_dmamem_free(sc->sc_dmat, &seg, rseg);
- fail_0:
- return;
}
/*
* Initialization of interface.
*/
void
-qeinit(sc)
- struct qe_softc *sc;
+qeinit(struct qe_softc *sc)
{
struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
struct qe_cdata *qc = sc->sc_qedata;
@@ -458,20 +419,19 @@ qeinit(sc)
* Start output on interface.
*/
void
-qestart(ifp)
- struct ifnet *ifp;
+qestart(struct ifnet *ifp)
{
struct qe_softc *sc = ifp->if_softc;
struct qe_cdata *qc = sc->sc_qedata;
paddr_t buffer;
struct mbuf *m, *m0;
int idx, len, s, i, totlen, error;
- short orword;
+ short orword, csr;
if ((QE_RCSR(QE_CSR_CSR) & QE_RCV_ENABLE) == 0)
return;
- s = splimp();
+ s = splnet();
while (sc->sc_inq < (TXDESCS - 1)) {
if (sc->sc_setup) {
@@ -479,7 +439,7 @@ qestart(ifp)
continue;
}
idx = sc->sc_nexttx;
- IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ IFQ_POLL(&ifp->if_snd, m);
if (m == 0)
goto out;
/*
@@ -494,11 +454,12 @@ qestart(ifp)
panic("qestart");
if ((i + sc->sc_inq) >= (TXDESCS - 1)) {
- IF_PREPEND(&sc->sc_if.if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
goto out;
}
-
+
+ IFQ_DEQUEUE(&ifp->if_snd, m);
+
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap(ifp->if_bpf, m);
@@ -520,8 +481,8 @@ qestart(ifp)
/* Word alignment calc */
orword = 0;
if (totlen == m->m_pkthdr.len) {
- if (totlen < ETHER_MINLEN)
- len += (ETHER_MINLEN - totlen);
+ if (totlen < ETHER_MIN_LEN)
+ len += (ETHER_MIN_LEN - totlen);
orword |= QE_EOMSG;
sc->sc_txmbuf[idx] = m;
}
@@ -549,7 +510,8 @@ qestart(ifp)
/*
* Kick off the transmit logic, if it is stopped.
*/
- if (QE_RCSR(QE_CSR_CSR) & QE_XL_INVALID) {
+ csr = QE_RCSR(QE_CSR_CSR);
+ if (csr & QE_XL_INVALID) {
QE_WCSR(QE_CSR_XMTL,
LOWORD(&sc->sc_pqedata->qc_xmit[sc->sc_nexttx]));
QE_WCSR(QE_CSR_XMTH,
@@ -566,8 +528,7 @@ out: if (sc->sc_inq)
}
static void
-qeintr(arg)
- void *arg;
+qeintr(void *arg)
{
struct qe_softc *sc = arg;
struct qe_cdata *qc = sc->sc_qedata;
@@ -585,6 +546,7 @@ qeintr(arg)
while (qc->qc_recv[sc->sc_nextrx].qe_status1 != QE_NOTYET) {
status1 = qc->qc_recv[sc->sc_nextrx].qe_status1;
status2 = qc->qc_recv[sc->sc_nextrx].qe_status2;
+
m = sc->sc_rxmbuf[sc->sc_nextrx];
len = ((status1 & QE_RBL_HI) |
(status2 & QE_RBL_LO)) + 60;
@@ -598,7 +560,7 @@ qeintr(arg)
if (ifp->if_bpf) {
bpf_mtap(ifp->if_bpf, m);
if ((ifp->if_flags & IFF_PROMISC) != 0 &&
- bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
+ bcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,
ETHER_ADDR_LEN) != 0 &&
((eh->ether_dhost[0] & 1) == 0)) {
m_freem(m);
@@ -611,15 +573,21 @@ qeintr(arg)
*/
if ((ifp->if_flags & IFF_ALLMULTI) &&
((eh->ether_dhost[0] & 1) == 0) &&
- bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
+ bcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,
ETHER_ADDR_LEN)) {
m_freem(m);
continue;
}
- ether_input(ifp, eh, m);
+
+ if ((status1 & QE_ESETUP) == 0) {
+ /* m_adj() the ethernet header out of the way and pass up */
+ m_adj(m, sizeof(struct ether_header));
+ ether_input(ifp, eh, m);
+ } else
+ m_freem(m);
}
- if (csr & QE_XMIT_INT) {
+ if (csr & (QE_XMIT_INT|QE_XL_INVALID)) {
while (qc->qc_xmit[sc->sc_lastack].qe_status1 != QE_NOTYET) {
int idx = sc->sc_lastack;
@@ -661,10 +629,7 @@ qeintr(arg)
* Process an ioctl request.
*/
int
-qeioctl(ifp, cmd, data)
- register struct ifnet *ifp;
- u_long cmd;
- caddr_t data;
+qeioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct qe_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
@@ -742,9 +707,7 @@ qeioctl(ifp, cmd, data)
* Add a receive buffer to the indicated descriptor.
*/
int
-qe_add_rxbuf(sc, i)
- struct qe_softc *sc;
- int i;
+qe_add_rxbuf(struct qe_softc *sc, int i)
{
struct mbuf *m;
struct qe_ring *rp;
@@ -793,17 +756,16 @@ qe_add_rxbuf(sc, i)
* Create a setup packet and put in queue for sending.
*/
void
-qe_setup(sc)
- struct qe_softc *sc;
+qe_setup(struct qe_softc *sc)
{
struct ether_multi *enm;
struct ether_multistep step;
struct qe_cdata *qc = sc->sc_qedata;
struct ifnet *ifp = &sc->sc_if;
- u_int8_t *enaddr = sc->sc_ac.ac_enaddr;
+ u_int8_t *enaddr = LLADDR(ifp->if_sadl);
int i, j, k, idx, s;
- s = splimp();
+ s = splnet();
if (sc->sc_inq == (TXDESCS - 1)) {
sc->sc_setup = 1;
splx(s);
@@ -825,7 +787,7 @@ qe_setup(sc)
ifp->if_flags &= ~IFF_ALLMULTI;
ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
while (enm != NULL) {
- if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) {
+ if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) {
ifp->if_flags |= IFF_ALLMULTI;
break;
}
@@ -849,7 +811,11 @@ qe_setup(sc)
* Until someone tells me, fall back to PROMISC when more than
* 12 ethernet addresses.
*/
- if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI))
+ if (ifp->if_flags & IFF_ALLMULTI)
+ ifp->if_flags |= IFF_PROMISC;
+ else if (ifp->if_pcount == 0)
+ ifp->if_flags &= ~IFF_PROMISC;
+ if (ifp->if_flags & IFF_PROMISC)
qc->qc_xmit[idx].qe_buf_len = -65;
qc->qc_xmit[idx].qe_addr_lo = LOWORD(sc->sc_pqedata->qc_setup);
@@ -875,8 +841,7 @@ qe_setup(sc)
* Check for dead transmit logic. Not uncommon.
*/
void
-qetimeout(ifp)
- struct ifnet *ifp;
+qetimeout(struct ifnet *ifp)
{
struct qe_softc *sc = ifp->if_softc;
diff --git a/sys/arch/vax/if/if_qereg.h b/sys/arch/vax/if/if_qereg.h
index d341d0ce157..dbf83d21e95 100644
--- a/sys/arch/vax/if/if_qereg.h
+++ b/sys/arch/vax/if/if_qereg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_qereg.h,v 1.5 2002/06/03 20:01:36 deraadt Exp $ */
-/* $NetBSD: if_qereg.h,v 1.5 1999/06/20 00:04:47 ragge Exp $ */
+/* $OpenBSD: if_qereg.h,v 1.6 2003/02/04 02:03:51 hugh Exp $ */
+/* $NetBSD: if_qereg.h,v 1.6 2001/06/19 13:42:18 wiz Exp $ */
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
@@ -105,7 +105,7 @@ struct qedevice {
*/
#define QE_RCV_ENABLE 0x0001 /* Receiver enable */
#define QE_RESET 0x0002 /* Software reset */
-#define QE_NEX_MEM_INT 0x0004 /* Non existant mem interrupt */
+#define QE_NEX_MEM_INT 0x0004 /* Non existent mem interrupt */
#define QE_LOAD_ROM 0x0008 /* Load boot/diag from rom */
#define QE_XL_INVALID 0x0010 /* Transmit list invalid */
#define QE_RL_INVALID 0x0020 /* Receive list invalid */
@@ -114,7 +114,7 @@ struct qedevice {
#define QE_ILOOP 0x0100 /* Internal loopback */
#define QE_ELOOP 0x0200 /* External loopback */
#define QE_STIM_ENABLE 0x0400 /* Sanity timer enable */
-#define QE_POWERUP 0x1000 /* Transceiver power on */
+#define QE_POWERUP 0x1000 /* Tranceiver power on */
#define QE_CARRIER 0x2000 /* Carrier detect */
#define QE_RCV_INT 0x8000 /* Receiver interrupt */