xref: /csrg-svn/sys/vax/if/if_dp.c (revision 45163)
1*45163Ssklower /*
2*45163Ssklower  * Copyright (c) 1990 Regents of the University of California.
3*45163Ssklower  * All rights reserved.
4*45163Ssklower  *
5*45163Ssklower  * %sccs.include.redist.c%
6*45163Ssklower  *
7*45163Ssklower  *	@(#)if_dp.c	7.1 (Berkeley) 08/30/90
8*45163Ssklower  */
9*45163Ssklower 
10*45163Ssklower #include "dp.h"
11*45163Ssklower #if NDP > 0
12*45163Ssklower 
13*45163Ssklower /*
14*45163Ssklower  * DPV-11 device driver, X.25 version
15*45163Ssklower  *
16*45163Ssklower  * Derived from dmc-11 driver:
17*45163Ssklower  *
18*45163Ssklower  *	Bill Nesheim
19*45163Ssklower  *	Cornell University
20*45163Ssklower  *
21*45163Ssklower  *	Lou Salkind
22*45163Ssklower  *	New York University
23*45163Ssklower  */
24*45163Ssklower 
25*45163Ssklower /* #define DEBUG	/* for base table dump on fatal error */
26*45163Ssklower 
27*45163Ssklower #include "machine/pte.h"
28*45163Ssklower 
29*45163Ssklower #include "param.h"
30*45163Ssklower #include "systm.h"
31*45163Ssklower #include "mbuf.h"
32*45163Ssklower #include "buf.h"
33*45163Ssklower #include "ioctl.h"		/* must precede tty.h */
34*45163Ssklower #include "protosw.h"
35*45163Ssklower #include "socket.h"
36*45163Ssklower #include "syslog.h"
37*45163Ssklower #include "vmmac.h"
38*45163Ssklower #include "errno.h"
39*45163Ssklower #include "time.h"
40*45163Ssklower #include "kernel.h"
41*45163Ssklower 
42*45163Ssklower #include "../net/if.h"
43*45163Ssklower #include "../net/netisr.h"
44*45163Ssklower #include "../net/route.h"
45*45163Ssklower 
46*45163Ssklower #include "../vax/cpu.h"
47*45163Ssklower #include "../vax/mtpr.h"
48*45163Ssklower #include "../vaxuba/pdma.h"
49*45163Ssklower 
50*45163Ssklower #include "if_dpreg.h"
51*45163Ssklower 
52*45163Ssklower /*
53*45163Ssklower  * Driver information for auto-configuration stuff.
54*45163Ssklower  */
55*45163Ssklower int	dpprobe(), dpattach(), dpinit(), dpioctl(), dprint(), dpxint();
56*45163Ssklower int	dpoutput(), dpreset(), dptimeout(), x25_ifoutput();
57*45163Ssklower 
58*45163Ssklower struct	uba_device *dpinfo[NDP];
59*45163Ssklower 
60*45163Ssklower u_short	dpstd[] = { 0 };
61*45163Ssklower struct	uba_driver dpdriver =
62*45163Ssklower 	{ dpprobe, 0, dpattach, 0, dpstd, "dp", dpinfo };
63*45163Ssklower 
64*45163Ssklower /*
65*45163Ssklower  * Pdma structures for fast interrupts.
66*45163Ssklower  */
67*45163Ssklower struct	pdma dppdma[2*NDP];
68*45163Ssklower 
69*45163Ssklower /* error reporting intervals */
70*45163Ssklower #define DPI_RPNBFS	50
71*45163Ssklower #define DPI_RPDSC	1
72*45163Ssklower #define DPI_RPTMO	10
73*45163Ssklower #define DPI_RPDCK	10
74*45163Ssklower 
75*45163Ssklower 
76*45163Ssklower /*
77*45163Ssklower  * DP software status per interface.
78*45163Ssklower  *
79*45163Ssklower  * Each interface is referenced by a network interface structure,
80*45163Ssklower  * dp_if, which the routing code uses to locate the interface.
81*45163Ssklower  * This structure contains the output queue for the interface, its address, ...
82*45163Ssklower  */
83*45163Ssklower struct dp_softc {
84*45163Ssklower 	struct	ifnet dp_if;		/* network-visible interface */
85*45163Ssklower 	short	dp_iused;		/* input buffers given to DP */
86*45163Ssklower 	short	dp_flags;		/* flags */
87*45163Ssklower 	short	dp_ostate;		/* restarting, etc. */
88*45163Ssklower 	short	dp_istate;		/* not sure this is necessary */
89*45163Ssklower #define DPS_IDLE	0
90*45163Ssklower #define DPS_RESTART	1
91*45163Ssklower #define DPS_ACTIVE	2
92*45163Ssklower #define DPS_XEM		3		/* transmitting CRC, etc. */
93*45163Ssklower /* flags */
94*45163Ssklower #define DPF_RUNNING	0x01		/* device initialized */
95*45163Ssklower #define DPF_ONLINE	0x02		/* device running (had a RDYO) */
96*45163Ssklower #define DPF_RESTART	0x04		/* software restart in progress */
97*45163Ssklower #define DPF_FLUSH	0x08		/* had a ROVR, flush ipkt when done */
98*45163Ssklower 	int	dp_errors[4];		/* non-fatal error counters */
99*45163Ssklower #define dp_datck dp_errors[0]
100*45163Ssklower #define dp_timeo dp_errors[1]
101*45163Ssklower #define dp_nobuf dp_errors[2]
102*45163Ssklower #define dp_disc  dp_errors[3]
103*45163Ssklower 	char	dp_obuf[DP_MTU+8];
104*45163Ssklower 	char	dp_rbuf[DP_MTU+8];
105*45163Ssklower } dp_softc[NDP];
106*45163Ssklower 
107*45163Ssklower dpprobe(reg, ui)
108*45163Ssklower 	caddr_t reg;
109*45163Ssklower 	struct	uba_device *ui;
110*45163Ssklower {
111*45163Ssklower 	register int br, cvec;
112*45163Ssklower 	register struct dpdevice *addr = (struct dpdevice *)reg;
113*45163Ssklower 	register int i;
114*45163Ssklower 
115*45163Ssklower #ifdef lint
116*45163Ssklower 	br = 0; cvec = br; br = cvec;
117*45163Ssklower 	dprint(0); dpxint(0);
118*45163Ssklower #endif
119*45163Ssklower 	addr->dpclr = DP_CLR;
120*45163Ssklower 	addr->dpclr = DP_XIE|DP_XE;
121*45163Ssklower 	DELAY(100000);
122*45163Ssklower 	addr->dpclr = 0;
123*45163Ssklower 	return (1);
124*45163Ssklower }
125*45163Ssklower 
126*45163Ssklower /*
127*45163Ssklower  * Interface exists: make available by filling in network interface
128*45163Ssklower  * record.  System will initialize the interface when it is ready
129*45163Ssklower  * to accept packets.
130*45163Ssklower  */
131*45163Ssklower dpattach(ui)
132*45163Ssklower 	register struct uba_device *ui;
133*45163Ssklower {
134*45163Ssklower 	register struct dp_softc *dp = &dp_softc[ui->ui_unit];
135*45163Ssklower 	register struct pdma *pdp = &dppdma[ui->ui_unit*2];
136*45163Ssklower 
137*45163Ssklower 	dp->dp_if.if_unit = ui->ui_unit;
138*45163Ssklower 	dp->dp_if.if_name = "dp";
139*45163Ssklower 	dp->dp_if.if_mtu = DP_MTU;
140*45163Ssklower 	dp->dp_if.if_init = dpinit;
141*45163Ssklower 	dp->dp_if.if_output = x25_ifoutput;
142*45163Ssklower 	dp->dp_if.if_start = dpstart;
143*45163Ssklower 	dp->dp_if.if_ioctl = dpioctl;
144*45163Ssklower 	dp->dp_if.if_reset = dpreset;
145*45163Ssklower 	dp->dp_if.if_watchdog = dptimeout;
146*45163Ssklower 	dp->dp_if.if_flags = IFF_POINTOPOINT;
147*45163Ssklower 
148*45163Ssklower 
149*45163Ssklower 	pdp->p_addr = (struct dzdevice *)ui->ui_addr;
150*45163Ssklower 	pdp->p_arg = (int)dp;
151*45163Ssklower 	pdp->p_fcn = dpxint;
152*45163Ssklower 	pdp->p_mem = pdp->p_end = dp->dp_obuf;
153*45163Ssklower 	pdp++;
154*45163Ssklower 	pdp->p_addr = (struct dzdevice *)ui->ui_addr;
155*45163Ssklower 	pdp->p_arg = (int)dp;
156*45163Ssklower 	pdp->p_fcn = dprint;
157*45163Ssklower 	pdp->p_mem = pdp->p_end = dp->dp_rbuf;
158*45163Ssklower 
159*45163Ssklower 	if_attach(&dp->dp_if);
160*45163Ssklower }
161*45163Ssklower 
162*45163Ssklower /*
163*45163Ssklower  * Reset of interface after UNIBUS reset.
164*45163Ssklower  * If interface is on specified UBA, reset its state.
165*45163Ssklower  */
166*45163Ssklower dpreset(unit, uban)
167*45163Ssklower 	int unit, uban;
168*45163Ssklower {
169*45163Ssklower 	register struct uba_device *ui;
170*45163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
171*45163Ssklower 	register struct dpdevice *addr;
172*45163Ssklower 
173*45163Ssklower 	if (unit >= NDP || (ui = dpinfo[unit]) == 0 || ui->ui_alive == 0 ||
174*45163Ssklower 	    ui->ui_ubanum != uban)
175*45163Ssklower 		return;
176*45163Ssklower 	printf(" dp%d", unit);
177*45163Ssklower 	dp->dp_flag = 0;
178*45163Ssklower 	dp->dp_if.if_flags &= ~IFF_RUNNING;
179*45163Ssklower 	addr = ui->ui_addr;
180*45163Ssklower 	addr->dpclr = DP_CLR;
181*45163Ssklower 	addr->dpsar = 0;
182*45163Ssklower 	addr->dprcsr = 0;
183*45163Ssklower 	dpinit(unit);
184*45163Ssklower }
185*45163Ssklower 
186*45163Ssklower /*
187*45163Ssklower  * Initialization of interface.
188*45163Ssklower  */
189*45163Ssklower dpinit(unit)
190*45163Ssklower 	int unit;
191*45163Ssklower {
192*45163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
193*45163Ssklower 	register struct uba_device *ui = dpinfo[unit];
194*45163Ssklower 	register struct dpdevice *addr;
195*45163Ssklower 	register struct ifnet *ifp = &dp->dp_if;
196*45163Ssklower 	struct ifaddr *ifa;
197*45163Ssklower 	int base;
198*45163Ssklower 	int s;
199*45163Ssklower 
200*45163Ssklower 	addr = (struct dpdevice *)ui->ui_addr;
201*45163Ssklower 
202*45163Ssklower 	/*
203*45163Ssklower 	 * Check to see that an address has been set.
204*45163Ssklower 	 */
205*45163Ssklower 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
206*45163Ssklower 		if (ifa->ifa_addr->sa_family != AF_LINK)
207*45163Ssklower 			break;
208*45163Ssklower 	if (ifa == (struct ifaddr *) 0)
209*45163Ssklower 		return;
210*45163Ssklower 
211*45163Ssklower 	s = spl5();
212*45163Ssklower 	dp->dp_iused = 0;
213*45163Ssklower 	dp->dp_istate = dp->dp_ostate = DPS_IDLE;
214*45163Ssklower 	dppdma[2*unit+1].p_end =
215*45163Ssklower 		dppdma[2*unit+1].p_mem = = dp->dp_rbuf;
216*45163Ssklower 	/* enable receive interrupt; CTS comming up will trigger it also */
217*45163Ssklower 	addr->dpsar = DP_CHRM | 0x7E; /* 7E is the flag character */
218*45163Ssklower 	addr->dpclr = 0;
219*45163Ssklower 	addr->dprcsr = DP_RIE | DP_DTR | DP_RE;
220*45163Ssklower 	splx(s);
221*45163Ssklower }
222*45163Ssklower 
223*45163Ssklower /*
224*45163Ssklower  * Start output on interface.  Get another datagram
225*45163Ssklower  * to send from the interface queue and map it to
226*45163Ssklower  * the interface before starting output.
227*45163Ssklower  *
228*45163Ssklower  */
229*45163Ssklower dpstart(ifp)
230*45163Ssklower 	struct ifnet *ifp;
231*45163Ssklower {
232*45163Ssklower 	int s, unit = ifp->if_unit;
233*45163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
234*45163Ssklower 	register struct dpdevice *addr = dpinfo[unit].ui_addr;
235*45163Ssklower 	register struct mbuf *m;
236*45163Ssklower 	register char *cp;
237*45163Ssklower 	char *cplim;
238*45163Ssklower 
239*45163Ssklower 	/*
240*45163Ssklower 	 * If already doing output, go away and depend on transmit
241*45163Ssklower 	 * complete or error.
242*45163Ssklower 	 */
243*45163Ssklower 	s = splimp();
244*45163Ssklower 	if (dp->dp_if.if_flags & IFF_OACTIVE) {
245*45163Ssklower 		splx(s);
246*45163Ssklower 		return (0);
247*45163Ssklower 	}
248*45163Ssklower 	IF_DEQUEUE(&dp->dp_if.if_snd, m);
249*45163Ssklower 	if (m == 0)
250*45163Ssklower 		return (0);
251*45163Ssklower 	if ((m->m_flags | M_PKTHDR) == 0 || m->m_pkthdr.len > DP_MTU)
252*45163Ssklower 		return (EINVAL);
253*45163Ssklower 	s = spl5();
254*45163Ssklower 	dppdma[2*unit].p_mem = cp = dp->dp_obuf;
255*45163Ssklower 	while (m) {
256*45163Ssklower 		struct mbuf *n;
257*45163Ssklower 		bcopy(mtod(m, caddr_t), (caddr_t)cp, m->m_len);
258*45163Ssklower 		cp += m->m_len;
259*45163Ssklower 		MFREE(m, n); m = n;
260*45163Ssklower 	}
261*45163Ssklower 	if (cp == dp->dp_obuf)
262*45163Ssklower 		return (0);
263*45163Ssklower 	dppdma[2*unit].p_end = cp;
264*45163Ssklower 	addr->dpclr = DP_XE | DP_XIE;
265*45163Ssklower 	addr->dptdsr = DP_XSM;
266*45163Ssklower 	dp->dp_if.if_flags |= IFF_OACTIVE;
267*45163Ssklower 	dp->dp_ostate = DPS_ACTIVE;
268*45163Ssklower 	splx(s);
269*45163Ssklower 	return (0);
270*45163Ssklower }
271*45163Ssklower /*
272*45163Ssklower  * Receive done or error interrupt
273*45163Ssklower  */
274*45163Ssklower dprint(unit, pdma, addr)
275*45163Ssklower register struct pdma *pdma;
276*45163Ssklower register struct dpdevice *addr;
277*45163Ssklower {
278*45163Ssklower 	register struct dpsoftc *dp = &dpsoftc[unit];
279*45163Ssklower 	unsigned short dprdsr = addr->dprdsr;
280*45163Ssklower 
281*45163Ssklower 	if (dprdsr & DP_ROVR) {
282*45163Ssklower 		dp->dp_flags |= DPF_FLUSH;
283*45163Ssklower 		return;
284*45163Ssklower 	}
285*45163Ssklower 	if (dprdsr & DP_RSM) { /* Received Start of Message */
286*45163Ssklower 		dp->dp_ibuf[0] = dprdsr & DP_RBUF;
287*45163Ssklower 		pdma->p_mem = dp->dp_ibuf + 1;
288*45163Ssklower 		dpflags &= ~DPF_FLUSH;
289*45163Ssklower 		return;
290*45163Ssklower 	}
291*45163Ssklower 	if (dprdsr & DP_REM) { /* Received End of Message */
292*45163Ssklower 		if (dprdsr & DP_REC || dp->dp_flags & DPF_FLUSH) {
293*45163Ssklower 			dp->dp_if.if_errors++;
294*45163Ssklower 			pdma->p_mem = dp->dp_ibuf;
295*45163Ssklower 			dp->dp_flags &= ~ DPF_FLUSH;
296*45163Ssklower 			return;
297*45163Ssklower 		}
298*45163Ssklower 		dpinput(dp, pdma->p_mem - dp->dp_ibuf, dp->dp_ibuf);
299*45163Ssklower 		return;
300*45163Ssklower 	}
301*45163Ssklower 	dp->dp_flags |= DPF_FLUSH;
302*45163Ssklower 	if (pdma->p_mem != pdma->p_end)
303*45163Ssklower 		log(dp%d: unexplained receiver interrupt\n");
304*45163Ssklower }
305*45163Ssklower 
306*45163Ssklower /*
307*45163Ssklower  * Transmit complete or error interrupt
308*45163Ssklower  */
309*45163Ssklower dpxint(unit, pdma, addr)
310*45163Ssklower register struct pdma *pdma;
311*45163Ssklower register struct dpdevice *addr;
312*45163Ssklower {
313*45163Ssklower 	register struct dpsoftc *dp = &dpsoftc[unit];
314*45163Ssklower 
315*45163Ssklower 	if (addr->dptdsr & DP_XERR) {
316*45163Ssklower 		log("if_dp%d: data late\n", unit);
317*45163Ssklower 	restart:
318*45163Ssklower 		pdma->p_mem = dp->dp_obuf;
319*45163Ssklower 		addr->dptdsr = DP_XSM;
320*45163Ssklower 		return;
321*45163Ssklower 	}
322*45163Ssklower 	switch (dp->dp_ostate) {
323*45163Ssklower 
324*45163Ssklower 	case DPS_ACTIVE:
325*45163Ssklower 		if (pdma->p_mem != pdma->p_end) {
326*45163Ssklower 			log("if_dp%d: misc error in dpxint\n");
327*45163Ssklower 			goto restart;
328*45163Ssklower 		}
329*45163Ssklower 		addr->dptdsr = DP_XEM;
330*45163Ssklower 		dp->dp_ostate = DPS_XEM;
331*45163Ssklower 		break;
332*45163Ssklower 
333*45163Ssklower 	case DPS_XEM:
334*45163Ssklower 		dp->dp_if.if_flags &= ~IFF_OACTIVE;
335*45163Ssklower 		if (dp->dp_if.if_snd.ifq_len)
336*45163Ssklower 			dpstart(&dp->dp_if);
337*45163Ssklower 		else {
338*45163Ssklower 			addr->dpclr = 0;
339*45163Ssklower 			dp->dp_ostate = DPS_IDLE;
340*45163Ssklower 		}
341*45163Ssklower 		break;
342*45163Ssklower 
343*45163Ssklower 	default:
344*45163Ssklower 		log("if_dp%d: impossible state in dpxint\n");
345*45163Ssklower 	}
346*45163Ssklower }
347*45163Ssklower /*
348*45163Ssklower  * Routine to copy from device buffer into mbufs.
349*45163Ssklower  *
350*45163Ssklower  * Warning: This makes the fairly safe assumption that
351*45163Ssklower  * mbufs have even lengths.
352*45163Ssklower  */
353*45163Ssklower struct mbuf *
354*45163Ssklower dpget(rxbuf, totlen, off, ifp)
355*45163Ssklower 	caddr_t rxbuf;
356*45163Ssklower 	int totlen, off;
357*45163Ssklower 	struct ifnet *ifp;
358*45163Ssklower {
359*45163Ssklower 	register caddr_t cp;
360*45163Ssklower 	register struct mbuf *m;
361*45163Ssklower 	struct mbuf *top = 0, **mp = ⊤
362*45163Ssklower 	int len;
363*45163Ssklower 	caddr_t packet_end;
364*45163Ssklower 
365*45163Ssklower 	cp = rxbuf;
366*45163Ssklower 	packet_end = cp + totlen;
367*45163Ssklower 	if (off) {
368*45163Ssklower 		off += 2 * sizeof(u_short);
369*45163Ssklower 		totlen -= 2 *sizeof(u_short);
370*45163Ssklower 		cp = rxbuf + off;
371*45163Ssklower 	}
372*45163Ssklower 
373*45163Ssklower 	MGETHDR(m, M_DONTWAIT, MT_DATA);
374*45163Ssklower 	if (m == 0)
375*45163Ssklower 		return (0);
376*45163Ssklower 	m->m_pkthdr.rcvif = ifp;
377*45163Ssklower 	m->m_pkthdr.len = totlen;
378*45163Ssklower 	m->m_len = MHLEN;
379*45163Ssklower 
380*45163Ssklower 	while (totlen > 0) {
381*45163Ssklower 		if (top) {
382*45163Ssklower 			MGET(m, M_DONTWAIT, MT_DATA);
383*45163Ssklower 			if (m == 0) {
384*45163Ssklower 				m_freem(top);
385*45163Ssklower 				return (0);
386*45163Ssklower 			}
387*45163Ssklower 			m->m_len = MLEN;
388*45163Ssklower 		}
389*45163Ssklower 		len = min(totlen, (packet_end - cp));
390*45163Ssklower 		if (len >= MINCLSIZE) {
391*45163Ssklower 			MCLGET(m, M_DONTWAIT);
392*45163Ssklower 			if (m->m_flags & M_EXT)
393*45163Ssklower 				m->m_len = len = min(len, MCLBYTES);
394*45163Ssklower 			else
395*45163Ssklower 				len = m->m_len;
396*45163Ssklower 		} else {
397*45163Ssklower 			/*
398*45163Ssklower 			 * Place initial small packet/header at end of mbuf.
399*45163Ssklower 			 */
400*45163Ssklower 			if (len < m->m_len) {
401*45163Ssklower 				if (top == 0 && len + max_linkhdr <= m->m_len)
402*45163Ssklower 					m->m_data += max_linkhdr;
403*45163Ssklower 				m->m_len = len;
404*45163Ssklower 			} else
405*45163Ssklower 				len = m->m_len;
406*45163Ssklower 		}
407*45163Ssklower 		bcopy(cp, mtod(m, caddr_t), (u_int)len);
408*45163Ssklower 		*mp = m;
409*45163Ssklower 		mp = &m->m_next;
410*45163Ssklower 		totlen -= len;
411*45163Ssklower 		cp += len;
412*45163Ssklower 		if (cp == packet_end)
413*45163Ssklower 			cp = rxbuf;
414*45163Ssklower 	}
415*45163Ssklower 	return (top);
416*45163Ssklower }
417*45163Ssklower 
418*45163Ssklower dpinput(dp, len, buffer)
419*45163Ssklower register struct dpsoftc *dp;
420*45163Ssklower caddr_t buffer;
421*45163Ssklower {
422*45163Ssklower 	register struct ifnet *ifp = &dp->dp_if;
423*45163Ssklower 	register struct ifqueue *inq;
424*45163Ssklower 	register struct mbuf *m;
425*45163Ssklower 	extern struct ifqueue hdintrq;
426*45163Ssklower 
427*45163Ssklower 	if(len <= 0 || ifp->if_addrlist == 0)
428*45163Ssklower 		return;
429*45163Ssklower 
430*45163Ssklower 	m = dpget(buffer, len , 0, ifp);
431*45163Ssklower 	if (m == 0)
432*45163Ssklower 		return;
433*45163Ssklower 	ifp->if_ipackets++;
434*45163Ssklower 
435*45163Ssklower 	/* Only AF_CCITT makes sense at this point */
436*45163Ssklower 	inq = &hdintrq;
437*45163Ssklower 
438*45163Ssklower 	if(IF_QFULL(inq)) {
439*45163Ssklower 		IF_DROP(inq);
440*45163Ssklower 		m_freem(m);
441*45163Ssklower 	} else {
442*45163Ssklower 		IF_ENQUEUE(inq, m);
443*45163Ssklower 		schednetisr(NETISR_HD);
444*45163Ssklower 	}
445*45163Ssklower }
446*45163Ssklower 
447*45163Ssklower /*
448*45163Ssklower  * Process an ioctl request.
449*45163Ssklower  */
450*45163Ssklower dpioctl(ifp, cmd, data)
451*45163Ssklower 	register struct ifnet *ifp;
452*45163Ssklower 	int cmd;
453*45163Ssklower 	caddr_t data;
454*45163Ssklower {
455*45163Ssklower 	register struct ifaddr *ifa = (struct ifaddr *)data;
456*45163Ssklower 	int s = splimp(), error = 0;
457*45163Ssklower 
458*45163Ssklower 	switch (cmd) {
459*45163Ssklower 
460*45163Ssklower 	case SIOCSIFADDR:
461*45163Ssklower 		ifp->if_flags |= IFF_UP;
462*45163Ssklower 		switch (ifa->ifa_addr->sa_family) {
463*45163Ssklower #ifdef CCITT
464*45163Ssklower 		case AF_CCITT:
465*45163Ssklower 			error = hd_ctlinput (PRC_IFUP, (caddr_t)&ifa->ifa_addr);
466*45163Ssklower 			if (error == 0)
467*45163Ssklower 				dpinit(ifp->if_unit);
468*45163Ssklower 			break;
469*45163Ssklower #endif
470*45163Ssklower 		case SIOCSIFFLAGS:
471*45163Ssklower 			if ((ifp->if_flags & IFF_UP) == 0 &&
472*45163Ssklower 			    (dp->dp_flags & DPF_RUNNING))
473*45163Ssklower 				dpdown(ifp->if_unit);
474*45163Ssklower 			else if (ifp->if_flags & IFF_UP &&
475*45163Ssklower 			    (dp->dp_flags & DPF_RUNNING) == 0)
476*45163Ssklower 				dpinit(ifp->if_unit);
477*45163Ssklower 			break;
478*45163Ssklower 
479*45163Ssklower 		default:
480*45163Ssklower 			dpinit(ifp->if_unit);
481*45163Ssklower 			break;
482*45163Ssklower 		}
483*45163Ssklower 		break;
484*45163Ssklower 
485*45163Ssklower 	/* case SIOCSIFFLAGS: ... */
486*45163Ssklower 
487*45163Ssklower 	default:
488*45163Ssklower 		error = EINVAL;
489*45163Ssklower 	}
490*45163Ssklower 	splx(s);
491*45163Ssklower 	return (error);
492*45163Ssklower }
493*45163Ssklower /*
494*45163Ssklower  * Reset a device and mark down.
495*45163Ssklower  * Flush output queue and drop queue limit.
496*45163Ssklower  */
497*45163Ssklower dpdown(unit)
498*45163Ssklower 	int unit;
499*45163Ssklower {
500*45163Ssklower 	register struct dp_softc *dp = &dp_softc[unit];
501*45163Ssklower 	register struct ifxmt *ifxp;
502*45163Ssklower 
503*45163Ssklower 	dp->dp_flags &= ~(DP_RUNNING | DP_ONLINE);
504*45163Ssklower 	addr->dpclr = DP_CLR;
505*45163Ssklower 	addr->dpclr = 0;
506*45163Ssklower 
507*45163Ssklower 	if_qflush(&dp->dp_if.if_snd);
508*45163Ssklower }
509*45163Ssklower 
510*45163Ssklower /*
511*45163Ssklower  * Watchdog timeout to see that transmitted packets don't
512*45163Ssklower  * lose interrupts.  The device has to be online (the first
513*45163Ssklower  * transmission may block until the other side comes up).
514*45163Ssklower  */
515*45163Ssklower dptimeout(unit)
516*45163Ssklower 	int unit;
517*45163Ssklower {
518*45163Ssklower 	register struct dp_softc *dp;
519*45163Ssklower 	struct dpdevice *addr;
520*45163Ssklower 
521*45163Ssklower 	dp = &dp_softc[unit];
522*45163Ssklower 	if (dp->dp_flags & DP_ONLINE) {
523*45163Ssklower 		addr = (struct dpdevice *)(dpinfo[unit]->ui_addr);
524*45163Ssklower 		dpstart(unit);
525*45163Ssklower 	}
526*45163Ssklower }
527*45163Ssklower #endif
528