diff options
Diffstat (limited to 'sys/arch/vax/if/if_qe.c')
-rw-r--r-- | sys/arch/vax/if/if_qe.c | 259 |
1 files changed, 135 insertions, 124 deletions
diff --git a/sys/arch/vax/if/if_qe.c b/sys/arch/vax/if/if_qe.c index fbf584fd09e..a468d3011f4 100644 --- a/sys/arch/vax/if/if_qe.c +++ b/sys/arch/vax/if/if_qe.c @@ -1,4 +1,5 @@ -/* $NetBSD: if_qe.c,v 1.4.2.1 1995/10/15 13:56:26 ragge Exp $ */ +/* $NetBSD: if_qe.c,v 1.7 1995/12/01 19:37:59 ragge Exp $ */ + /* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. @@ -133,8 +134,6 @@ * --------------------------------------------------------------------- */ -#include "qe.h" -#if NQE > 0 /* * Digital Q-BUS to NI Adapter */ @@ -174,19 +173,15 @@ extern char all_es_snpa[], all_is_snpa[], all_l1is_snpa[], all_l2is_snpa[]; #endif -#include "vax/include/pte.h" -#include "vax/include/cpu.h" -#include "vax/include/mtpr.h" +#include "machine/pte.h" +#include "machine/cpu.h" +#include "machine/mtpr.h" #include "if_qereg.h" #include "if_uba.h" #include "vax/uba/ubareg.h" #include "vax/uba/ubavar.h" -#if NQE == 1 && !defined(QNIVERT) #define NRCV 15 /* Receive descriptors */ -#else -#define NRCV 10 /* Receive descriptors */ -#endif #define NXMT 5 /* Transmit descriptors */ #define NTOT (NXMT + NRCV) @@ -205,12 +200,14 @@ void qetimeout(int); * This structure contains the output queue for the interface, its address, ... */ struct qe_softc { + struct device qe_device; /* Configuration common part */ struct arpcom qe_ac; /* Ethernet common part */ #define qe_if qe_ac.ac_if /* network-visible interface */ #define qe_addr qe_ac.ac_enaddr /* hardware Ethernet address */ struct ifubinfo qe_uba; /* Q-bus resources */ - volatile struct ifrw qe_ifr[NRCV]; /* for receive buffers; */ - volatile struct ifxmt qe_ifw[NXMT]; /* for xmit buffers; */ + struct ifrw qe_ifr[NRCV]; /* for receive buffers; */ + struct ifxmt qe_ifw[NXMT]; /* for xmit buffers; */ + struct qedevice *qe_vaddr; int qe_flags; /* software state */ #define QEF_RUNNING 0x01 #define QEF_SETADDR 0x02 @@ -219,30 +216,38 @@ struct qe_softc { int ipl; /* interrupt priority */ struct qe_ring *rringaddr; /* mapping info for rings */ struct qe_ring *tringaddr; /* "" */ - volatile struct qe_ring rring[NRCV+1]; /* Receive ring descriptors */ - volatile struct qe_ring tring[NXMT+1]; /* Xmit ring descriptors */ + struct qe_ring rring[NRCV+1]; /* Receive ring descriptors */ + struct qe_ring tring[NXMT+1]; /* Xmit ring descriptors */ u_char setup_pkt[16][8]; /* Setup packet */ int rindex; /* Receive index */ int tindex; /* Transmit index */ int otindex; /* Old transmit index */ int qe_intvec; /* Interrupt vector */ - volatile struct qedevice *addr; /* device addr */ + struct qedevice *addr; /* device addr */ int setupqueued; /* setup packet queued */ int nxmit; /* Transmits in progress */ int qe_restarts; /* timeouts */ -} qe_softc[NQE]; - -struct uba_device *qeinfo[NQE]; - -extern struct timeval time; - -int qeprobe(), qeattach(), qeintr(); -int qeinit(), qeioctl(), qereset(); -void qestart(); +}; + +int qematch __P((struct device *, void *, void *)); +void qeattach __P((struct device *, struct device *, void *)); +int qereset __P((int)); +void qeinit __P((int)); +void qestart __P((struct ifnet *)); +void qeintr __P((int)); +void qetint __P((int)); +void qerint __P((int)); +int qeioctl __P((struct ifnet *, u_long, caddr_t)); +void qe_setaddr __P((u_char *, int)); +void qeinitdesc __P((struct qe_ring *, caddr_t, int)); +void qesetup __P((struct qe_softc *)); +void qeread __P((struct qe_softc *, struct ifrw *, int)); +void qetimeout __P((int)); +void qerestart __P((struct qe_softc *)); + +struct cfdriver qecd = + { 0, "qe", qematch, qeattach, DV_IFNET, sizeof(struct qe_softc) }; -u_short qestd[] = { 0 }; -struct uba_driver qedriver = - { qeprobe, 0, qeattach, 0, qestd, "qe", qeinfo }; #define QEUNIT(x) minor(x) /* @@ -252,40 +257,39 @@ struct uba_driver qedriver = * size buffers. */ #define MAXPACKETSIZE 2048 /* Should really be ETHERMTU */ + /* * Probe the QNA to see if it's there */ -qeprobe(reg, ui) - caddr_t reg; - struct uba_device *ui; +int +qematch(parent, match, aux) + struct device *parent; + void *match, *aux; { - /* register int br, cvec; r11, r10 value-result */ - register volatile struct qedevice *addr = (struct qedevice *)reg; - register volatile struct qe_ring *rp; - register struct qe_ring *prp; /* physical rp */ - register int i; - register volatile struct qe_softc *sc = &qe_softc[ui->ui_unit]; - -#ifdef lint - br = 0; cvec = br; br = cvec; - qeintr(0); -#endif + struct qe_softc *sc = match; + struct uba_attach_args *ua = aux; + struct uba_softc *ubasc = (struct uba_softc *)parent; + struct qe_ring *rp; + struct qe_ring *prp; /* physical rp */ + volatile struct qedevice *addr = (struct qedevice *)ua->ua_addr; + int i; /* * The QNA interrupts on i/o operations. To do an I/O operation * we have to setup the interface by transmitting a setup packet. */ + addr->qe_csr = QE_RESET; addr->qe_csr &= ~QE_RESET; - addr->qe_vector = (uba_hd[numuba].uh_lastiv -= 4); + addr->qe_vector = (ubasc->uh_lastiv -= 4); /* * Map the communications area and the setup packet. */ sc->setupaddr = - uballoc(0, (caddr_t)sc->setup_pkt, sizeof(sc->setup_pkt), 0); + uballoc(0, (caddr_t)sc->setup_pkt, sizeof(sc->setup_pkt), 0); sc->rringaddr = (struct qe_ring *) uballoc(0, (caddr_t)sc->rring, - sizeof(struct qe_ring) * (NTOT+2), 0); + sizeof(struct qe_ring) * (NTOT+2), 0); prp = (struct qe_ring *)UBAI_ADDR((int)sc->rringaddr); /* @@ -314,10 +318,10 @@ qeprobe(reg, ui) * packet. This code looks strange due to the fact that the address * is placed in the setup packet in col. major order. */ - for( i = 0 ; i < 6 ; i++ ) + for (i = 0; i < 6; i++) sc->setup_pkt[i][1] = addr->qe_sta_addr[i]; - qesetup( sc ); + qesetup(sc); /* * Start the interface and wait for the packet. */ @@ -334,7 +338,9 @@ qeprobe(reg, ui) ubarelse(0, &sc->setupaddr); ubarelse(0, (int *)&sc->rringaddr); sc->ipl = 0x15; - return( sizeof(struct qedevice) ); + ua->ua_ivec = qeintr; + ua->ua_iarg = sc->qe_device.dv_unit; + return 1; } /* @@ -342,15 +348,20 @@ qeprobe(reg, ui) * record. System will initialize the interface when it is ready * to accept packets. */ -qeattach(ui) - struct uba_device *ui; +void +qeattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - struct qe_softc *sc = &qe_softc[ui->ui_unit]; - struct ifnet *ifp = (struct ifnet *)&sc->qe_if; - volatile struct qedevice *addr=(struct qedevice *)ui->ui_addr; + struct uba_attach_args *ua = aux; + struct qe_softc *sc = (struct qe_softc *)self; + struct ifnet *ifp = (struct ifnet *)&sc->qe_if; + struct qedevice *addr =(struct qedevice *)ua->ua_addr; int i; - ifp->if_unit = ui->ui_unit; + printf("\n"); + sc->qe_vaddr = addr; + ifp->if_unit = sc->qe_device.dv_unit; ifp->if_name = "qe"; /* * The Deqna is cable of transmitting broadcasts, but @@ -361,10 +372,11 @@ qeattach(ui) /* * Read the address from the prom and save it. */ - for( i=0 ; i<6 ; i++ ) - sc->setup_pkt[i][1] = sc->qe_addr[i] = addr->qe_sta_addr[i] & 0xff; + for (i = 0; i < 6; i++) + sc->setup_pkt[i][1] = sc->qe_addr[i] = + addr->qe_sta_addr[i] & 0xff; addr->qe_vector |= 1; - printf("qe%d: %s, hardware address %s\n", ui->ui_unit, + printf("qe%d: %s, hardware address %s\n", sc->qe_device.dv_unit, addr->qe_vector&01 ? "delqa":"deqna", ether_sprintf(sc->qe_addr)); addr->qe_vector &= ~1; @@ -387,28 +399,31 @@ qeattach(ui) * Reset of interface after UNIBUS reset. * If interface is on specified uba, reset its state. */ -qereset(unit, uban) - int unit, uban; +qereset(unit) + int unit; { register struct uba_device *ui; + panic("qereset"); +#ifdef notyet if (unit >= NQE || (ui = qeinfo[unit]) == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) return; printf(" qe%d", unit); qe_softc[unit].qe_if.if_flags &= ~IFF_RUNNING; qeinit(unit); +#endif } /* * Initialization of interface. */ +void qeinit(unit) int unit; { - volatile struct qe_softc *sc = &qe_softc[unit]; - struct uba_device *ui = qeinfo[unit]; - volatile struct qedevice *addr=(struct qedevice *)ui->ui_addr; + struct qe_softc *sc = (struct qe_softc *)qecd.cd_devs[unit]; + struct qedevice *addr = sc->qe_vaddr; struct ifnet *ifp = (struct ifnet *)&sc->qe_if; int i; int s; @@ -437,7 +452,7 @@ qeinit(unit) /* * init buffers and maps */ - if (if_ubaminit(&sc->qe_uba, ui->ui_ubanum, + if (if_ubaminit(&sc->qe_uba, sc->qe_device.dv_parent->dv_unit, sizeof (struct ether_header), (int)btoc(MAXPACKETSIZE), sc->qe_ifr, NRCV, sc->qe_ifw, NXMT) == 0) { fail: @@ -504,17 +519,15 @@ qestart(ifp) struct ifnet *ifp; { int unit = ifp->if_unit; - struct uba_device *ui = qeinfo[unit]; - register volatile struct qe_softc *sc = &qe_softc[unit]; - register volatile struct qedevice *addr; - register volatile struct qe_ring *rp; + register struct qe_softc *sc = qecd.cd_devs[ifp->if_unit]; + volatile struct qedevice *addr = sc->qe_vaddr; + register struct qe_ring *rp; register index; struct mbuf *m; int buf_addr, len, s; s = splimp(); - addr = (struct qedevice *)ui->ui_addr; /* * The deqna doesn't look at anything but the valid bit * to determine if it should transmit this packet. If you have @@ -537,7 +550,7 @@ qestart(ifp) sc->setupqueued = 0; } else { IF_DEQUEUE(&sc->qe_if.if_snd, m); - if( m == 0 ){ + if (m == 0) { splx(s); return; } @@ -582,26 +595,31 @@ qestart(ifp) /* * Ethernet interface interrupt processor */ -qeintr(uba, vector, level, unit) +void +qeintr(unit) + int unit; { - register volatile struct qe_softc *sc = &qe_softc[unit]; - volatile struct qedevice *addr = - (struct qedevice *)qeinfo[unit]->ui_addr; + register struct qe_softc *sc; + volatile struct qedevice *addr; int buf_addr, csr; + sc = qecd.cd_devs[unit]; + addr = sc->qe_vaddr; splx(sc->ipl); if (!(sc->qe_flags & QEF_FASTTIMEO)) sc->qe_if.if_timer = QESLOWTIMEOUT; /* Restart timer clock */ csr = addr->qe_csr; - addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | QE_XMIT_INT | QE_RCV_INT | QE_ILOOP; - if( csr & QE_RCV_INT ) - qerint( unit ); - if( csr & QE_XMIT_INT ) - qetint( unit ); - if( csr & QE_NEX_MEM_INT ) + addr->qe_csr = QE_RCV_ENABLE | QE_INT_ENABLE | + QE_XMIT_INT | QE_RCV_INT | QE_ILOOP; + if (csr & QE_RCV_INT) + qerint(unit); + if (csr & QE_XMIT_INT) + qetint(unit ); + if (csr & QE_NEX_MEM_INT) printf("qe%d: Nonexistent memory interrupt\n", unit); - if( addr->qe_csr & QE_RL_INVALID && sc->rring[sc->rindex].qe_status1 == QE_NOTYET ) { + if (addr->qe_csr & QE_RL_INVALID && sc->rring[sc->rindex].qe_status1 == + QE_NOTYET) { buf_addr = (int)&sc->rringaddr[sc->rindex]; addr->qe_rcvlist_lo = (short)buf_addr; addr->qe_rcvlist_hi = (short)(buf_addr >> 16); @@ -611,18 +629,19 @@ qeintr(uba, vector, level, unit) /* * Ethernet interface transmit interrupt. */ - +void qetint(unit) int unit; { - register volatile struct qe_softc *sc = &qe_softc[unit]; - register volatile struct qe_ring *rp; - register volatile struct ifxmt *ifxp; + register struct qe_softc *sc = qecd.cd_devs[unit]; + register struct qe_ring *rp; + register struct ifxmt *ifxp; int status1, setupflag; short len; - while( sc->otindex != sc->tindex && sc->tring[sc->otindex].qe_status1 != QE_NOTYET && sc->nxmit > 0 ) { + while (sc->otindex != sc->tindex && sc->tring[sc->otindex].qe_status1 + != QE_NOTYET && sc->nxmit > 0) { /* * Save the status words from the descriptor so that it can * be released. @@ -657,7 +676,7 @@ qetint(unit) } sc->otindex = ++sc->otindex % NXMT; } - qestart( &sc->qe_if ); + qestart(&sc->qe_if); } /* @@ -666,11 +685,12 @@ qetint(unit) * Othewise decapsulate packet based on type and pass to type specific * higher-level input routine. */ +void qerint(unit) int unit; { - register volatile struct qe_softc *sc = &qe_softc[unit]; - register volatile struct qe_ring *rp; + register struct qe_softc *sc = qecd.cd_devs[unit]; + register struct qe_ring *rp; register int nrcv = 0; int len, status1, status2; int bufaddr; @@ -708,7 +728,8 @@ qerint(unit) log(LOG_ERR, "qe%d: ring overrun, resync'd by skipping %d\n", unit, nrcv); - for( ; sc->rring[sc->rindex].qe_status1 != QE_NOTYET ; sc->rindex = ++sc->rindex % NRCV ){ + for (; sc->rring[sc->rindex].qe_status1 != QE_NOTYET; + sc->rindex = ++sc->rindex % NRCV) { rp = &sc->rring[sc->rindex]; status1 = rp->qe_status1; status2 = rp->qe_status2; @@ -725,7 +746,7 @@ qerint(unit) /* * We don't process setup packets. */ - if( !(status1 & QE_ESETUP) ) + if (!(status1 & QE_ESETUP)) qeread(sc, &sc->qe_ifr[sc->rindex], len - sizeof(struct ether_header)); } @@ -744,12 +765,13 @@ qerint(unit) /* * Process an ioctl request. */ +int qeioctl(ifp, cmd, data) register struct ifnet *ifp; - int cmd; + u_long cmd; caddr_t data; { - struct qe_softc *sc = &qe_softc[ifp->if_unit]; + struct qe_softc *sc = qecd.cd_devs[ifp->if_unit]; struct ifaddr *ifa = (struct ifaddr *)data; int s = splimp(), error = 0; @@ -782,8 +804,7 @@ qeioctl(ifp, cmd, data) case SIOCSIFFLAGS: if ((ifp->if_flags & IFF_UP) == 0 && sc->qe_flags & QEF_RUNNING) { - ((volatile struct qedevice *) - (qeinfo[ifp->if_unit]->ui_addr))->qe_csr = QE_RESET; + sc->qe_vaddr->qe_csr = QE_RESET; sc->qe_flags &= ~QEF_RUNNING; } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING && (sc->qe_flags & QEF_RUNNING) == 0) @@ -801,11 +822,12 @@ qeioctl(ifp, cmd, data) /* * set ethernet address for unit */ +void qe_setaddr(physaddr, unit) u_char *physaddr; int unit; { - register volatile struct qe_softc *sc = &qe_softc[unit]; + register struct qe_softc *sc = qecd.cd_devs[unit]; register int i; for (i = 0; i < 6; i++) @@ -820,8 +842,9 @@ qe_setaddr(physaddr, unit) /* * Initialize a ring descriptor with mbuf allocation side effects */ +void qeinitdesc(rp, addr, len) - register volatile struct qe_ring *rp; + register struct qe_ring *rp; caddr_t addr; /* mapped address */ int len; { @@ -830,7 +853,7 @@ qeinitdesc(rp, addr, len) */ bzero((caddr_t)rp, sizeof(struct qe_ring)); - if( len ) { + if (len) { rp->qe_buf_len = -(len/2); rp->qe_addr_lo = (short)((int)addr); rp->qe_addr_hi = (short)((int)addr >> 16); @@ -840,16 +863,17 @@ qeinitdesc(rp, addr, len) * Build a setup packet - the physical address will already be present * in first column. */ -qesetup( sc ) - volatile struct qe_softc *sc; +void +qesetup(sc) + struct qe_softc *sc; { register i, j; /* * Copy the target address to the rest of the entries in this row. */ - for ( j = 0; j < 6 ; j++ ) - for ( i = 2 ; i < 8 ; i++ ) + for (j = 0; j < 6; j++) + for (i = 2; i < 8; i++) sc->setup_pkt[j][i] = sc->setup_pkt[j][1]; /* * Duplicate the first half. @@ -858,7 +882,7 @@ qesetup( sc ) /* * Fill in the broadcast (and ISO multicast) address(es). */ - for ( i = 0; i < 6 ; i++ ) { + for (i = 0; i < 6; i++) { sc->setup_pkt[i][2] = 0xff; #ifdef ISO sc->setup_pkt[i][3] = all_es_snpa[i]; @@ -874,9 +898,10 @@ qesetup( sc ) * Pass a packet to the higher levels. * We deal with the trailer protocol here. */ +void qeread(sc, ifrw, len) - register volatile struct qe_softc *sc; - volatile struct ifrw *ifrw; + register struct qe_softc *sc; + struct ifrw *ifrw; int len; { struct ether_header *eh; @@ -923,9 +948,9 @@ void qetimeout(unit) int unit; { - register volatile struct qe_softc *sc; + register struct qe_softc *sc; - sc = &qe_softc[unit]; + sc = qecd.cd_devs[unit]; #ifdef notdef log(LOG_ERR, "qe%d: transmit timeout, restarted %d\n", unit, sc->qe_restarts++); @@ -935,17 +960,18 @@ qetimeout(unit) /* * Restart for board lockup problem. */ +void qerestart(sc) - register volatile struct qe_softc *sc; + struct qe_softc *sc; { register struct ifnet *ifp = (struct ifnet *)&sc->qe_if; - register volatile struct qedevice *addr = sc->addr; - register volatile struct qe_ring *rp; + register struct qedevice *addr = sc->addr; + register struct qe_ring *rp; register i; addr->qe_csr = QE_RESET; addr->qe_csr &= ~QE_RESET; - qesetup( sc ); + qesetup(sc); for (i = 0, rp = sc->tring; i < NXMT; rp++, i++) { rp->qe_flag = rp->qe_status1 = QE_NOTYET; rp->qe_valid = 0; @@ -958,18 +984,3 @@ qerestart(sc) sc->qe_flags |= QEF_RUNNING; qestart(ifp); } - -qe_match(){ - printf("qe_match\n"); - return 0; -} - -void -qe_attach(){ - printf("qe_attach\n"); -} - -struct cfdriver qecd = - { 0,"qe",qe_match, qe_attach, DV_IFNET, sizeof(struct uba_driver) }; - -#endif |