diff options
author | Hugh Graham <hugh@cvs.openbsd.org> | 2003-02-04 02:03:52 +0000 |
---|---|---|
committer | Hugh Graham <hugh@cvs.openbsd.org> | 2003-02-04 02:03:52 +0000 |
commit | 4f999461359bf6c2fc14ff56a57aacd615e696c4 (patch) | |
tree | 5c4c80abe5c7127e16874e3283989e73405f271f /sys/arch/vax/if | |
parent | aad7713bf64acff8508aebd07cbb07e4383ccbbf (diff) |
Bring qe closer to NetBSD and make it compile. As yet untested.
Diffstat (limited to 'sys/arch/vax/if')
-rw-r--r-- | sys/arch/vax/if/if_qe.c | 179 | ||||
-rw-r--r-- | sys/arch/vax/if/if_qereg.h | 8 |
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 */ |