xref: /csrg-svn/sys/vax/if/if_dp.c (revision 45166)
145163Ssklower /*
245163Ssklower  * Copyright (c) 1990 Regents of the University of California.
345163Ssklower  * All rights reserved.
445163Ssklower  *
545163Ssklower  * %sccs.include.redist.c%
645163Ssklower  *
7*45166Ssklower  *	@(#)if_dp.c	7.2 (Berkeley) 08/30/90
845163Ssklower  */
945163Ssklower 
1045163Ssklower #include "dp.h"
1145163Ssklower #if NDP > 0
1245163Ssklower 
1345163Ssklower /*
1445163Ssklower  * DPV-11 device driver, X.25 version
1545163Ssklower  *
1645163Ssklower  * Derived from dmc-11 driver:
1745163Ssklower  *
1845163Ssklower  *	Bill Nesheim
1945163Ssklower  *	Cornell University
2045163Ssklower  *
2145163Ssklower  *	Lou Salkind
2245163Ssklower  *	New York University
2345163Ssklower  */
2445163Ssklower 
2545163Ssklower /* #define DEBUG	/* for base table dump on fatal error */
2645163Ssklower 
2745163Ssklower #include "machine/pte.h"
2845163Ssklower 
2945163Ssklower #include "param.h"
3045163Ssklower #include "systm.h"
3145163Ssklower #include "mbuf.h"
3245163Ssklower #include "buf.h"
3345163Ssklower #include "ioctl.h"		/* must precede tty.h */
3445163Ssklower #include "protosw.h"
3545163Ssklower #include "socket.h"
3645163Ssklower #include "syslog.h"
3745163Ssklower #include "vmmac.h"
3845163Ssklower #include "errno.h"
3945163Ssklower #include "time.h"
4045163Ssklower #include "kernel.h"
4145163Ssklower 
4245163Ssklower #include "../net/if.h"
4345163Ssklower #include "../net/netisr.h"
4445163Ssklower #include "../net/route.h"
4545163Ssklower 
4645163Ssklower #include "../vax/cpu.h"
4745163Ssklower #include "../vax/mtpr.h"
48*45166Ssklower 
4945163Ssklower #include "../vaxuba/pdma.h"
50*45166Ssklower #include "../vaxuba/ubavar.h"
5145163Ssklower 
52*45166Ssklower #include "../netcitt/x25.h"
53*45166Ssklower 
5445163Ssklower #include "if_dpreg.h"
5545163Ssklower 
5645163Ssklower /*
5745163Ssklower  * Driver information for auto-configuration stuff.
5845163Ssklower  */
5945163Ssklower int	dpprobe(), dpattach(), dpinit(), dpioctl(), dprint(), dpxint();
60*45166Ssklower int	dpoutput(), dpreset(), dptimeout(), dpstart(), x25_ifoutput();
6145163Ssklower 
6245163Ssklower struct	uba_device *dpinfo[NDP];
6345163Ssklower 
6445163Ssklower u_short	dpstd[] = { 0 };
6545163Ssklower struct	uba_driver dpdriver =
6645163Ssklower 	{ dpprobe, 0, dpattach, 0, dpstd, "dp", dpinfo };
6745163Ssklower 
6845163Ssklower /*
6945163Ssklower  * Pdma structures for fast interrupts.
7045163Ssklower  */
7145163Ssklower struct	pdma dppdma[2*NDP];
7245163Ssklower 
7345163Ssklower /* error reporting intervals */
7445163Ssklower #define DPI_RPNBFS	50
7545163Ssklower #define DPI_RPDSC	1
7645163Ssklower #define DPI_RPTMO	10
7745163Ssklower #define DPI_RPDCK	10
7845163Ssklower 
7945163Ssklower 
8045163Ssklower /*
8145163Ssklower  * DP software status per interface.
8245163Ssklower  *
8345163Ssklower  * Each interface is referenced by a network interface structure,
8445163Ssklower  * dp_if, which the routing code uses to locate the interface.
8545163Ssklower  * This structure contains the output queue for the interface, its address, ...
8645163Ssklower  */
8745163Ssklower struct dp_softc {
8845163Ssklower 	struct	ifnet dp_if;		/* network-visible interface */
8945163Ssklower 	short	dp_iused;		/* input buffers given to DP */
9045163Ssklower 	short	dp_flags;		/* flags */
9145163Ssklower 	short	dp_ostate;		/* restarting, etc. */
9245163Ssklower 	short	dp_istate;		/* not sure this is necessary */
9345163Ssklower #define DPS_IDLE	0
9445163Ssklower #define DPS_RESTART	1
9545163Ssklower #define DPS_ACTIVE	2
9645163Ssklower #define DPS_XEM		3		/* transmitting CRC, etc. */
9745163Ssklower /* flags */
9845163Ssklower #define DPF_RUNNING	0x01		/* device initialized */
9945163Ssklower #define DPF_ONLINE	0x02		/* device running (had a RDYO) */
10045163Ssklower #define DPF_RESTART	0x04		/* software restart in progress */
10145163Ssklower #define DPF_FLUSH	0x08		/* had a ROVR, flush ipkt when done */
10245163Ssklower 	int	dp_errors[4];		/* non-fatal error counters */
10345163Ssklower #define dp_datck dp_errors[0]
10445163Ssklower #define dp_timeo dp_errors[1]
10545163Ssklower #define dp_nobuf dp_errors[2]
10645163Ssklower #define dp_disc  dp_errors[3]
10745163Ssklower 	char	dp_obuf[DP_MTU+8];
108*45166Ssklower 	char	dp_ibuf[DP_MTU+8];
10945163Ssklower } dp_softc[NDP];
11045163Ssklower 
11145163Ssklower dpprobe(reg, ui)
11245163Ssklower 	caddr_t reg;
11345163Ssklower 	struct	uba_device *ui;
11445163Ssklower {
11545163Ssklower 	register int br, cvec;
11645163Ssklower 	register struct dpdevice *addr = (struct dpdevice *)reg;
11745163Ssklower 	register int i;
11845163Ssklower 
11945163Ssklower #ifdef lint
12045163Ssklower 	br = 0; cvec = br; br = cvec;
12145163Ssklower 	dprint(0); dpxint(0);
12245163Ssklower #endif
12345163Ssklower 	addr->dpclr = DP_CLR;
12445163Ssklower 	addr->dpclr = DP_XIE|DP_XE;
12545163Ssklower 	DELAY(100000);
12645163Ssklower 	addr->dpclr = 0;
12745163Ssklower 	return (1);
12845163Ssklower }
12945163Ssklower 
13045163Ssklower /*
13145163Ssklower  * Interface exists: make available by filling in network interface
13245163Ssklower  * record.  System will initialize the interface when it is ready
13345163Ssklower  * to accept packets.
13445163Ssklower  */
13545163Ssklower dpattach(ui)
13645163Ssklower 	register struct uba_device *ui;
13745163Ssklower {
13845163Ssklower 	register struct dp_softc *dp = &dp_softc[ui->ui_unit];
13945163Ssklower 	register struct pdma *pdp = &dppdma[ui->ui_unit*2];
14045163Ssklower 
14145163Ssklower 	dp->dp_if.if_unit = ui->ui_unit;
14245163Ssklower 	dp->dp_if.if_name = "dp";
14345163Ssklower 	dp->dp_if.if_mtu = DP_MTU;
14445163Ssklower 	dp->dp_if.if_init = dpinit;
14545163Ssklower 	dp->dp_if.if_output = x25_ifoutput;
14645163Ssklower 	dp->dp_if.if_start = dpstart;
14745163Ssklower 	dp->dp_if.if_ioctl = dpioctl;
14845163Ssklower 	dp->dp_if.if_reset = dpreset;
14945163Ssklower 	dp->dp_if.if_watchdog = dptimeout;
15045163Ssklower 	dp->dp_if.if_flags = IFF_POINTOPOINT;
15145163Ssklower 
15245163Ssklower 
15345163Ssklower 	pdp->p_addr = (struct dzdevice *)ui->ui_addr;
15445163Ssklower 	pdp->p_arg = (int)dp;
15545163Ssklower 	pdp->p_fcn = dpxint;
15645163Ssklower 	pdp->p_mem = pdp->p_end = dp->dp_obuf;
15745163Ssklower 	pdp++;
15845163Ssklower 	pdp->p_addr = (struct dzdevice *)ui->ui_addr;
15945163Ssklower 	pdp->p_arg = (int)dp;
16045163Ssklower 	pdp->p_fcn = dprint;
161*45166Ssklower 	pdp->p_mem = pdp->p_end = dp->dp_ibuf;
16245163Ssklower 
16345163Ssklower 	if_attach(&dp->dp_if);
16445163Ssklower }
16545163Ssklower 
16645163Ssklower /*
16745163Ssklower  * Reset of interface after UNIBUS reset.
16845163Ssklower  * If interface is on specified UBA, reset its state.
16945163Ssklower  */
17045163Ssklower dpreset(unit, uban)
17145163Ssklower 	int unit, uban;
17245163Ssklower {
17345163Ssklower 	register struct uba_device *ui;
17445163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
17545163Ssklower 	register struct dpdevice *addr;
17645163Ssklower 
17745163Ssklower 	if (unit >= NDP || (ui = dpinfo[unit]) == 0 || ui->ui_alive == 0 ||
17845163Ssklower 	    ui->ui_ubanum != uban)
17945163Ssklower 		return;
18045163Ssklower 	printf(" dp%d", unit);
181*45166Ssklower 	dp->dp_flags = 0;
18245163Ssklower 	dp->dp_if.if_flags &= ~IFF_RUNNING;
183*45166Ssklower 	addr = (struct dpdevice *)ui->ui_addr;
18445163Ssklower 	addr->dpclr = DP_CLR;
18545163Ssklower 	addr->dpsar = 0;
18645163Ssklower 	addr->dprcsr = 0;
18745163Ssklower 	dpinit(unit);
18845163Ssklower }
18945163Ssklower 
19045163Ssklower /*
19145163Ssklower  * Initialization of interface.
19245163Ssklower  */
19345163Ssklower dpinit(unit)
19445163Ssklower 	int unit;
19545163Ssklower {
19645163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
19745163Ssklower 	register struct uba_device *ui = dpinfo[unit];
19845163Ssklower 	register struct dpdevice *addr;
19945163Ssklower 	register struct ifnet *ifp = &dp->dp_if;
20045163Ssklower 	struct ifaddr *ifa;
20145163Ssklower 	int base;
20245163Ssklower 	int s;
20345163Ssklower 
20445163Ssklower 	addr = (struct dpdevice *)ui->ui_addr;
20545163Ssklower 
20645163Ssklower 	/*
20745163Ssklower 	 * Check to see that an address has been set.
20845163Ssklower 	 */
20945163Ssklower 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
21045163Ssklower 		if (ifa->ifa_addr->sa_family != AF_LINK)
21145163Ssklower 			break;
21245163Ssklower 	if (ifa == (struct ifaddr *) 0)
21345163Ssklower 		return;
21445163Ssklower 
21545163Ssklower 	s = spl5();
21645163Ssklower 	dp->dp_iused = 0;
21745163Ssklower 	dp->dp_istate = dp->dp_ostate = DPS_IDLE;
21845163Ssklower 	dppdma[2*unit+1].p_end =
219*45166Ssklower 		dppdma[2*unit+1].p_mem = dp->dp_ibuf;
22045163Ssklower 	/* enable receive interrupt; CTS comming up will trigger it also */
22145163Ssklower 	addr->dpsar = DP_CHRM | 0x7E; /* 7E is the flag character */
22245163Ssklower 	addr->dpclr = 0;
22345163Ssklower 	addr->dprcsr = DP_RIE | DP_DTR | DP_RE;
22445163Ssklower 	splx(s);
22545163Ssklower }
22645163Ssklower 
22745163Ssklower /*
22845163Ssklower  * Start output on interface.  Get another datagram
22945163Ssklower  * to send from the interface queue and map it to
23045163Ssklower  * the interface before starting output.
23145163Ssklower  *
23245163Ssklower  */
23345163Ssklower dpstart(ifp)
23445163Ssklower 	struct ifnet *ifp;
23545163Ssklower {
23645163Ssklower 	int s, unit = ifp->if_unit;
23745163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
238*45166Ssklower 	register struct dpdevice *addr =
239*45166Ssklower 				(struct dpdevice *)(dpinfo[unit]->ui_addr);
24045163Ssklower 	register struct mbuf *m;
24145163Ssklower 	register char *cp;
24245163Ssklower 	char *cplim;
24345163Ssklower 
24445163Ssklower 	/*
24545163Ssklower 	 * If already doing output, go away and depend on transmit
24645163Ssklower 	 * complete or error.
24745163Ssklower 	 */
24845163Ssklower 	s = splimp();
24945163Ssklower 	if (dp->dp_if.if_flags & IFF_OACTIVE) {
25045163Ssklower 		splx(s);
25145163Ssklower 		return (0);
25245163Ssklower 	}
25345163Ssklower 	IF_DEQUEUE(&dp->dp_if.if_snd, m);
25445163Ssklower 	if (m == 0)
25545163Ssklower 		return (0);
25645163Ssklower 	if ((m->m_flags | M_PKTHDR) == 0 || m->m_pkthdr.len > DP_MTU)
25745163Ssklower 		return (EINVAL);
25845163Ssklower 	s = spl5();
25945163Ssklower 	dppdma[2*unit].p_mem = cp = dp->dp_obuf;
26045163Ssklower 	while (m) {
26145163Ssklower 		struct mbuf *n;
26245163Ssklower 		bcopy(mtod(m, caddr_t), (caddr_t)cp, m->m_len);
26345163Ssklower 		cp += m->m_len;
26445163Ssklower 		MFREE(m, n); m = n;
26545163Ssklower 	}
26645163Ssklower 	if (cp == dp->dp_obuf)
26745163Ssklower 		return (0);
26845163Ssklower 	dppdma[2*unit].p_end = cp;
26945163Ssklower 	addr->dpclr = DP_XE | DP_XIE;
27045163Ssklower 	addr->dptdsr = DP_XSM;
27145163Ssklower 	dp->dp_if.if_flags |= IFF_OACTIVE;
27245163Ssklower 	dp->dp_ostate = DPS_ACTIVE;
27345163Ssklower 	splx(s);
27445163Ssklower 	return (0);
27545163Ssklower }
27645163Ssklower /*
27745163Ssklower  * Receive done or error interrupt
27845163Ssklower  */
27945163Ssklower dprint(unit, pdma, addr)
28045163Ssklower register struct pdma *pdma;
28145163Ssklower register struct dpdevice *addr;
28245163Ssklower {
283*45166Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
284*45166Ssklower 	short rdsr = addr->dprdsr;
28545163Ssklower 
286*45166Ssklower 	if (rdsr & DP_ROVR) {
28745163Ssklower 		dp->dp_flags |= DPF_FLUSH;
28845163Ssklower 		return;
28945163Ssklower 	}
290*45166Ssklower 	if (rdsr & DP_RSM) { /* Received Start of Message */
291*45166Ssklower 		dp->dp_ibuf[0] = rdsr & DP_RBUF;
29245163Ssklower 		pdma->p_mem = dp->dp_ibuf + 1;
293*45166Ssklower 		dp->dp_flags &= ~DPF_FLUSH;
29445163Ssklower 		return;
29545163Ssklower 	}
296*45166Ssklower 	if (rdsr & DP_REM) { /* Received End of Message */
297*45166Ssklower 		if (rdsr & DP_REC || dp->dp_flags & DPF_FLUSH) {
298*45166Ssklower 			dp->dp_if.if_ierrors++;
29945163Ssklower 			pdma->p_mem = dp->dp_ibuf;
30045163Ssklower 			dp->dp_flags &= ~ DPF_FLUSH;
30145163Ssklower 			return;
30245163Ssklower 		}
30345163Ssklower 		dpinput(dp, pdma->p_mem - dp->dp_ibuf, dp->dp_ibuf);
30445163Ssklower 		return;
30545163Ssklower 	}
30645163Ssklower 	dp->dp_flags |= DPF_FLUSH;
30745163Ssklower 	if (pdma->p_mem != pdma->p_end)
308*45166Ssklower 		log("dp%d: unexplained receiver interrupt\n", unit);
30945163Ssklower }
31045163Ssklower 
31145163Ssklower /*
31245163Ssklower  * Transmit complete or error interrupt
31345163Ssklower  */
31445163Ssklower dpxint(unit, pdma, addr)
31545163Ssklower register struct pdma *pdma;
31645163Ssklower register struct dpdevice *addr;
31745163Ssklower {
318*45166Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
31945163Ssklower 
32045163Ssklower 	if (addr->dptdsr & DP_XERR) {
32145163Ssklower 		log("if_dp%d: data late\n", unit);
32245163Ssklower 	restart:
32345163Ssklower 		pdma->p_mem = dp->dp_obuf;
32445163Ssklower 		addr->dptdsr = DP_XSM;
32545163Ssklower 		return;
32645163Ssklower 	}
32745163Ssklower 	switch (dp->dp_ostate) {
32845163Ssklower 
32945163Ssklower 	case DPS_ACTIVE:
33045163Ssklower 		if (pdma->p_mem != pdma->p_end) {
33145163Ssklower 			log("if_dp%d: misc error in dpxint\n");
33245163Ssklower 			goto restart;
33345163Ssklower 		}
33445163Ssklower 		addr->dptdsr = DP_XEM;
33545163Ssklower 		dp->dp_ostate = DPS_XEM;
33645163Ssklower 		break;
33745163Ssklower 
33845163Ssklower 	case DPS_XEM:
33945163Ssklower 		dp->dp_if.if_flags &= ~IFF_OACTIVE;
34045163Ssklower 		if (dp->dp_if.if_snd.ifq_len)
34145163Ssklower 			dpstart(&dp->dp_if);
34245163Ssklower 		else {
34345163Ssklower 			addr->dpclr = 0;
34445163Ssklower 			dp->dp_ostate = DPS_IDLE;
34545163Ssklower 		}
34645163Ssklower 		break;
34745163Ssklower 
34845163Ssklower 	default:
34945163Ssklower 		log("if_dp%d: impossible state in dpxint\n");
35045163Ssklower 	}
35145163Ssklower }
35245163Ssklower /*
35345163Ssklower  * Routine to copy from device buffer into mbufs.
35445163Ssklower  *
35545163Ssklower  * Warning: This makes the fairly safe assumption that
35645163Ssklower  * mbufs have even lengths.
35745163Ssklower  */
35845163Ssklower struct mbuf *
35945163Ssklower dpget(rxbuf, totlen, off, ifp)
36045163Ssklower 	caddr_t rxbuf;
36145163Ssklower 	int totlen, off;
36245163Ssklower 	struct ifnet *ifp;
36345163Ssklower {
36445163Ssklower 	register caddr_t cp;
36545163Ssklower 	register struct mbuf *m;
36645163Ssklower 	struct mbuf *top = 0, **mp = ⊤
36745163Ssklower 	int len;
36845163Ssklower 	caddr_t packet_end;
36945163Ssklower 
37045163Ssklower 	cp = rxbuf;
37145163Ssklower 	packet_end = cp + totlen;
37245163Ssklower 	if (off) {
37345163Ssklower 		off += 2 * sizeof(u_short);
37445163Ssklower 		totlen -= 2 *sizeof(u_short);
37545163Ssklower 		cp = rxbuf + off;
37645163Ssklower 	}
37745163Ssklower 
37845163Ssklower 	MGETHDR(m, M_DONTWAIT, MT_DATA);
37945163Ssklower 	if (m == 0)
38045163Ssklower 		return (0);
38145163Ssklower 	m->m_pkthdr.rcvif = ifp;
38245163Ssklower 	m->m_pkthdr.len = totlen;
38345163Ssklower 	m->m_len = MHLEN;
38445163Ssklower 
38545163Ssklower 	while (totlen > 0) {
38645163Ssklower 		if (top) {
38745163Ssklower 			MGET(m, M_DONTWAIT, MT_DATA);
38845163Ssklower 			if (m == 0) {
38945163Ssklower 				m_freem(top);
39045163Ssklower 				return (0);
39145163Ssklower 			}
39245163Ssklower 			m->m_len = MLEN;
39345163Ssklower 		}
39445163Ssklower 		len = min(totlen, (packet_end - cp));
39545163Ssklower 		if (len >= MINCLSIZE) {
39645163Ssklower 			MCLGET(m, M_DONTWAIT);
39745163Ssklower 			if (m->m_flags & M_EXT)
39845163Ssklower 				m->m_len = len = min(len, MCLBYTES);
39945163Ssklower 			else
40045163Ssklower 				len = m->m_len;
40145163Ssklower 		} else {
40245163Ssklower 			/*
40345163Ssklower 			 * Place initial small packet/header at end of mbuf.
40445163Ssklower 			 */
40545163Ssklower 			if (len < m->m_len) {
40645163Ssklower 				if (top == 0 && len + max_linkhdr <= m->m_len)
40745163Ssklower 					m->m_data += max_linkhdr;
40845163Ssklower 				m->m_len = len;
40945163Ssklower 			} else
41045163Ssklower 				len = m->m_len;
41145163Ssklower 		}
41245163Ssklower 		bcopy(cp, mtod(m, caddr_t), (u_int)len);
41345163Ssklower 		*mp = m;
41445163Ssklower 		mp = &m->m_next;
41545163Ssklower 		totlen -= len;
41645163Ssklower 		cp += len;
41745163Ssklower 		if (cp == packet_end)
41845163Ssklower 			cp = rxbuf;
41945163Ssklower 	}
42045163Ssklower 	return (top);
42145163Ssklower }
42245163Ssklower 
42345163Ssklower dpinput(dp, len, buffer)
424*45166Ssklower register struct dp_softc *dp;
42545163Ssklower caddr_t buffer;
42645163Ssklower {
42745163Ssklower 	register struct ifnet *ifp = &dp->dp_if;
42845163Ssklower 	register struct ifqueue *inq;
42945163Ssklower 	register struct mbuf *m;
43045163Ssklower 	extern struct ifqueue hdintrq;
43145163Ssklower 
43245163Ssklower 	if(len <= 0 || ifp->if_addrlist == 0)
43345163Ssklower 		return;
43445163Ssklower 
43545163Ssklower 	m = dpget(buffer, len , 0, ifp);
43645163Ssklower 	if (m == 0)
43745163Ssklower 		return;
43845163Ssklower 	ifp->if_ipackets++;
43945163Ssklower 
44045163Ssklower 	/* Only AF_CCITT makes sense at this point */
44145163Ssklower 	inq = &hdintrq;
44245163Ssklower 
44345163Ssklower 	if(IF_QFULL(inq)) {
44445163Ssklower 		IF_DROP(inq);
44545163Ssklower 		m_freem(m);
44645163Ssklower 	} else {
44745163Ssklower 		IF_ENQUEUE(inq, m);
448*45166Ssklower 		schednetisr(NETISR_CCITT);
44945163Ssklower 	}
45045163Ssklower }
45145163Ssklower 
45245163Ssklower /*
45345163Ssklower  * Process an ioctl request.
45445163Ssklower  */
45545163Ssklower dpioctl(ifp, cmd, data)
45645163Ssklower 	register struct ifnet *ifp;
45745163Ssklower 	int cmd;
45845163Ssklower 	caddr_t data;
45945163Ssklower {
46045163Ssklower 	register struct ifaddr *ifa = (struct ifaddr *)data;
46145163Ssklower 	int s = splimp(), error = 0;
462*45166Ssklower 	struct dp_softc *dp = &dp_softc[ifp->if_unit];
46345163Ssklower 
46445163Ssklower 	switch (cmd) {
46545163Ssklower 
46645163Ssklower 	case SIOCSIFADDR:
46745163Ssklower 		ifp->if_flags |= IFF_UP;
46845163Ssklower 		switch (ifa->ifa_addr->sa_family) {
46945163Ssklower #ifdef CCITT
47045163Ssklower 		case AF_CCITT:
471*45166Ssklower 			error = hd_ctlinput(PRC_IFUP, (caddr_t)&ifa->ifa_addr);
47245163Ssklower 			if (error == 0)
47345163Ssklower 				dpinit(ifp->if_unit);
47445163Ssklower 			break;
47545163Ssklower #endif
47645163Ssklower 		case SIOCSIFFLAGS:
47745163Ssklower 			if ((ifp->if_flags & IFF_UP) == 0 &&
47845163Ssklower 			    (dp->dp_flags & DPF_RUNNING))
47945163Ssklower 				dpdown(ifp->if_unit);
48045163Ssklower 			else if (ifp->if_flags & IFF_UP &&
48145163Ssklower 			    (dp->dp_flags & DPF_RUNNING) == 0)
48245163Ssklower 				dpinit(ifp->if_unit);
48345163Ssklower 			break;
48445163Ssklower 
48545163Ssklower 		default:
48645163Ssklower 			dpinit(ifp->if_unit);
48745163Ssklower 			break;
48845163Ssklower 		}
48945163Ssklower 		break;
49045163Ssklower 
49145163Ssklower 	/* case SIOCSIFFLAGS: ... */
49245163Ssklower 
49345163Ssklower 	default:
49445163Ssklower 		error = EINVAL;
49545163Ssklower 	}
49645163Ssklower 	splx(s);
49745163Ssklower 	return (error);
49845163Ssklower }
49945163Ssklower /*
50045163Ssklower  * Reset a device and mark down.
50145163Ssklower  * Flush output queue and drop queue limit.
50245163Ssklower  */
50345163Ssklower dpdown(unit)
50445163Ssklower 	int unit;
50545163Ssklower {
50645163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
50745163Ssklower 	register struct ifxmt *ifxp;
508*45166Ssklower 	register struct dpdevice *addr = (struct dpdevice *)dpinfo[unit]->ui_addr;
50945163Ssklower 
510*45166Ssklower 	dp->dp_flags &= ~(DPF_RUNNING | DPF_ONLINE);
51145163Ssklower 	addr->dpclr = DP_CLR;
51245163Ssklower 	addr->dpclr = 0;
51345163Ssklower 
51445163Ssklower 	if_qflush(&dp->dp_if.if_snd);
51545163Ssklower }
51645163Ssklower 
51745163Ssklower /*
51845163Ssklower  * Watchdog timeout to see that transmitted packets don't
51945163Ssklower  * lose interrupts.  The device has to be online (the first
52045163Ssklower  * transmission may block until the other side comes up).
52145163Ssklower  */
52245163Ssklower dptimeout(unit)
52345163Ssklower 	int unit;
52445163Ssklower {
52545163Ssklower 	register struct dp_softc *dp;
52645163Ssklower 	struct dpdevice *addr;
52745163Ssklower 
52845163Ssklower 	dp = &dp_softc[unit];
529*45166Ssklower 	if (dp->dp_flags & DPF_ONLINE) {
53045163Ssklower 		addr = (struct dpdevice *)(dpinfo[unit]->ui_addr);
53145163Ssklower 		dpstart(unit);
53245163Ssklower 	}
53345163Ssklower }
53445163Ssklower #endif
535