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