1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)if_de.c 7.12 (Berkeley) 12/16/90 8 */ 9 10 #include "de.h" 11 #if NDE > 0 12 13 /* 14 * DEC DEUNA interface 15 * 16 * Lou Salkind 17 * New York University 18 * 19 * TODO: 20 * timeout routine (get statistics) 21 */ 22 #include "../include/pte.h" 23 24 #include "sys/param.h" 25 #include "sys/systm.h" 26 #include "sys/mbuf.h" 27 #include "sys/buf.h" 28 #include "sys/protosw.h" 29 #include "sys/socket.h" 30 #include "sys/vmmac.h" 31 #include "sys/ioctl.h" 32 #include "sys/errno.h" 33 #include "sys/syslog.h" 34 35 #include "net/if.h" 36 #include "net/netisr.h" 37 #include "net/route.h" 38 39 #ifdef INET 40 #include "netinet/in.h" 41 #include "netinet/in_systm.h" 42 #include "netinet/in_var.h" 43 #include "netinet/ip.h" 44 #include "netinet/if_ether.h" 45 #endif 46 47 #ifdef NS 48 #include "netns/ns.h" 49 #include "netns/ns_if.h" 50 #endif 51 52 #ifdef ISO 53 #include "netiso/iso.h" 54 #include "netiso/iso_var.h" 55 extern char all_es_snpa[], all_is_snpa[]; 56 #endif 57 58 #include "../include/cpu.h" 59 #include "../include/mtpr.h" 60 #include "if_dereg.h" 61 #include "if_uba.h" 62 #include "../uba/ubareg.h" 63 #include "../uba/ubavar.h" 64 65 #define NXMT 3 /* number of transmit buffers */ 66 #define NRCV 7 /* number of receive buffers (must be > 1) */ 67 68 int dedebug = 0; 69 70 int deprobe(), deattach(), deintr(); 71 struct uba_device *deinfo[NDE]; 72 u_short destd[] = { 0 }; 73 struct uba_driver dedriver = 74 { deprobe, 0, deattach, 0, destd, "de", deinfo }; 75 int deinit(),ether_output(),deioctl(),dereset(),destart(); 76 77 78 /* 79 * Ethernet software status per interface. 80 * 81 * Each interface is referenced by a network interface structure, 82 * ds_if, which the routing code uses to locate the interface. 83 * This structure contains the output queue for the interface, its address, ... 84 * We also have, for each interface, a UBA interface structure, which 85 * contains information about the UNIBUS resources held by the interface: 86 * map registers, buffered data paths, etc. Information is cached in this 87 * structure for use by the if_uba.c routines in running the interface 88 * efficiently. 89 */ 90 struct de_softc { 91 struct arpcom ds_ac; /* Ethernet common part */ 92 #define ds_if ds_ac.ac_if /* network-visible interface */ 93 #define ds_addr ds_ac.ac_enaddr /* hardware Ethernet address */ 94 int ds_flags; 95 #define DSF_RUNNING 2 /* board is enabled */ 96 #define DSF_SETADDR 4 /* physical address is changed */ 97 int ds_ubaddr; /* map info for incore structs */ 98 struct ifubinfo ds_deuba; /* unibus resource structure */ 99 struct ifrw ds_ifr[NRCV]; /* unibus receive maps */ 100 struct ifxmt ds_ifw[NXMT]; /* unibus xmt maps */ 101 /* the following structures are always mapped in */ 102 struct de_pcbb ds_pcbb; /* port control block */ 103 struct de_ring ds_xrent[NXMT]; /* transmit ring entrys */ 104 struct de_ring ds_rrent[NRCV]; /* receive ring entrys */ 105 struct de_udbbuf ds_udbbuf; /* UNIBUS data buffer */ 106 /* end mapped area */ 107 #define INCORE_BASE(p) ((char *)&(p)->ds_pcbb) 108 #define RVAL_OFF(n) ((char *)&de_softc[0].n - INCORE_BASE(&de_softc[0])) 109 #define LVAL_OFF(n) ((char *)de_softc[0].n - INCORE_BASE(&de_softc[0])) 110 #define PCBB_OFFSET RVAL_OFF(ds_pcbb) 111 #define XRENT_OFFSET LVAL_OFF(ds_xrent) 112 #define RRENT_OFFSET LVAL_OFF(ds_rrent) 113 #define UDBBUF_OFFSET RVAL_OFF(ds_udbbuf) 114 #define INCORE_SIZE RVAL_OFF(ds_xindex) 115 int ds_xindex; /* UNA index into transmit chain */ 116 int ds_rindex; /* UNA index into receive chain */ 117 int ds_xfree; /* index for next transmit buffer */ 118 int ds_nxmit; /* # of transmits in progress */ 119 } de_softc[NDE]; 120 121 deprobe(reg) 122 caddr_t reg; 123 { 124 register int br, cvec; /* r11, r10 value-result */ 125 register struct dedevice *addr = (struct dedevice *)reg; 126 register i; 127 128 #ifdef lint 129 br = 0; cvec = br; br = cvec; 130 i = 0; derint(i); deintr(i); 131 #endif 132 133 /* 134 * Make sure self-test is finished before we screw with the board. 135 * Self-test on a DELUA can take 15 seconds (argh). 136 */ 137 for (i = 0; 138 i < 160 && 139 (addr->pcsr0 & PCSR0_FATI) == 0 && 140 (addr->pcsr1 & PCSR1_STMASK) == STAT_RESET; 141 ++i) 142 DELAY(100000); 143 if ((addr->pcsr0 & PCSR0_FATI) != 0 || 144 (addr->pcsr1 & PCSR1_STMASK) != STAT_READY) 145 return(0); 146 147 addr->pcsr0 = 0; 148 DELAY(100); 149 addr->pcsr0 = PCSR0_RSET; 150 while ((addr->pcsr0 & PCSR0_INTR) == 0) 151 ; 152 /* make board interrupt by executing a GETPCBB command */ 153 addr->pcsr0 = PCSR0_INTE; 154 addr->pcsr2 = 0; 155 addr->pcsr3 = 0; 156 addr->pcsr0 = PCSR0_INTE|CMD_GETPCBB; 157 DELAY(100000); 158 return(1); 159 } 160 161 /* 162 * Interface exists: make available by filling in network interface 163 * record. System will initialize the interface when it is ready 164 * to accept packets. We get the ethernet address here. 165 */ 166 deattach(ui) 167 struct uba_device *ui; 168 { 169 register struct de_softc *ds = &de_softc[ui->ui_unit]; 170 register struct ifnet *ifp = &ds->ds_if; 171 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 172 int csr1; 173 174 ifp->if_unit = ui->ui_unit; 175 ifp->if_name = "de"; 176 ifp->if_mtu = ETHERMTU; 177 ifp->if_flags = IFF_BROADCAST; 178 179 /* 180 * What kind of a board is this? 181 * The error bits 4-6 in pcsr1 are a device id as long as 182 * the high byte is zero. 183 */ 184 csr1 = addr->pcsr1; 185 if (csr1 & 0xff60) 186 printf("de%d: broken\n", ui->ui_unit); 187 else if (csr1 & 0x10) 188 printf("de%d: delua\n", ui->ui_unit); 189 else 190 printf("de%d: deuna\n", ui->ui_unit); 191 192 /* 193 * Reset the board and temporarily map 194 * the pcbb buffer onto the Unibus. 195 */ 196 addr->pcsr0 = 0; /* reset INTE */ 197 DELAY(100); 198 addr->pcsr0 = PCSR0_RSET; 199 (void)dewait(ui, "reset"); 200 201 ds->ds_ubaddr = uballoc(ui->ui_ubanum, (char *)&ds->ds_pcbb, 202 sizeof (struct de_pcbb), 0); 203 addr->pcsr2 = ds->ds_ubaddr & 0xffff; 204 addr->pcsr3 = (ds->ds_ubaddr >> 16) & 0x3; 205 addr->pclow = CMD_GETPCBB; 206 (void)dewait(ui, "pcbb"); 207 208 ds->ds_pcbb.pcbb0 = FC_RDPHYAD; 209 addr->pclow = CMD_GETCMD; 210 (void)dewait(ui, "read addr "); 211 212 ubarelse(ui->ui_ubanum, &ds->ds_ubaddr); 213 bcopy((caddr_t)&ds->ds_pcbb.pcbb2, (caddr_t)ds->ds_addr, 214 sizeof (ds->ds_addr)); 215 printf("de%d: hardware address %s\n", ui->ui_unit, 216 ether_sprintf(ds->ds_addr)); 217 ifp->if_init = deinit; 218 ifp->if_output = ether_output; 219 ifp->if_ioctl = deioctl; 220 ifp->if_reset = dereset; 221 ifp->if_start = destart; 222 ds->ds_deuba.iff_flags = UBA_CANTWAIT; 223 #ifdef notdef 224 /* CAN WE USE BDP's ??? */ 225 ds->ds_deuba.iff_flags |= UBA_NEEDBDP; 226 #endif 227 if_attach(ifp); 228 } 229 230 /* 231 * Reset of interface after UNIBUS reset. 232 * If interface is on specified uba, reset its state. 233 */ 234 dereset(unit, uban) 235 int unit, uban; 236 { 237 register struct uba_device *ui; 238 239 if (unit >= NDE || (ui = deinfo[unit]) == 0 || ui->ui_alive == 0 || 240 ui->ui_ubanum != uban) 241 return; 242 printf(" de%d", unit); 243 de_softc[unit].ds_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 244 de_softc[unit].ds_flags &= ~DSF_RUNNING; 245 ((struct dedevice *)ui->ui_addr)->pcsr0 = PCSR0_RSET; 246 (void)dewait(ui, "reset"); 247 deinit(unit); 248 } 249 250 /* 251 * Initialization of interface; clear recorded pending 252 * operations, and reinitialize UNIBUS usage. 253 */ 254 deinit(unit) 255 int unit; 256 { 257 register struct de_softc *ds = &de_softc[unit]; 258 register struct uba_device *ui = deinfo[unit]; 259 register struct dedevice *addr; 260 register struct ifrw *ifrw; 261 register struct ifxmt *ifxp; 262 struct ifnet *ifp = &ds->ds_if; 263 int s; 264 struct de_ring *rp; 265 int incaddr; 266 267 /* not yet, if address still unknown */ 268 if (ifp->if_addrlist == (struct ifaddr *)0) 269 return; 270 271 if (ds->ds_flags & DSF_RUNNING) 272 return; 273 if ((ifp->if_flags & IFF_RUNNING) == 0) { 274 if (if_ubaminit(&ds->ds_deuba, ui->ui_ubanum, 275 sizeof (struct ether_header), (int)btoc(ETHERMTU), 276 ds->ds_ifr, NRCV, ds->ds_ifw, NXMT) == 0) { 277 printf("de%d: can't initialize\n", unit); 278 ds->ds_if.if_flags &= ~IFF_UP; 279 return; 280 } 281 ds->ds_ubaddr = uballoc(ui->ui_ubanum, INCORE_BASE(ds), 282 INCORE_SIZE, 0); 283 } 284 addr = (struct dedevice *)ui->ui_addr; 285 286 /* set the pcbb block address */ 287 incaddr = ds->ds_ubaddr + PCBB_OFFSET; 288 addr->pcsr2 = incaddr & 0xffff; 289 addr->pcsr3 = (incaddr >> 16) & 0x3; 290 addr->pclow = 0; /* reset INTE */ 291 DELAY(100); 292 addr->pclow = CMD_GETPCBB; 293 (void)dewait(ui, "pcbb"); 294 295 /* set the transmit and receive ring header addresses */ 296 incaddr = ds->ds_ubaddr + UDBBUF_OFFSET; 297 ds->ds_pcbb.pcbb0 = FC_WTRING; 298 ds->ds_pcbb.pcbb2 = incaddr & 0xffff; 299 ds->ds_pcbb.pcbb4 = (incaddr >> 16) & 0x3; 300 301 incaddr = ds->ds_ubaddr + XRENT_OFFSET; 302 ds->ds_udbbuf.b_tdrbl = incaddr & 0xffff; 303 ds->ds_udbbuf.b_tdrbh = (incaddr >> 16) & 0x3; 304 ds->ds_udbbuf.b_telen = sizeof (struct de_ring) / sizeof (short); 305 ds->ds_udbbuf.b_trlen = NXMT; 306 incaddr = ds->ds_ubaddr + RRENT_OFFSET; 307 ds->ds_udbbuf.b_rdrbl = incaddr & 0xffff; 308 ds->ds_udbbuf.b_rdrbh = (incaddr >> 16) & 0x3; 309 ds->ds_udbbuf.b_relen = sizeof (struct de_ring) / sizeof (short); 310 ds->ds_udbbuf.b_rrlen = NRCV; 311 312 addr->pclow = CMD_GETCMD; 313 (void)dewait(ui, "wtring"); 314 315 /* initialize the mode - enable hardware padding */ 316 ds->ds_pcbb.pcbb0 = FC_WTMODE; 317 /* let hardware do padding - set MTCH bit on broadcast */ 318 ds->ds_pcbb.pcbb2 = MOD_TPAD|MOD_HDX; 319 addr->pclow = CMD_GETCMD; 320 (void)dewait(ui, "wtmode"); 321 322 /* set up the receive and transmit ring entries */ 323 ifxp = &ds->ds_ifw[0]; 324 for (rp = &ds->ds_xrent[0]; rp < &ds->ds_xrent[NXMT]; rp++) { 325 rp->r_segbl = ifxp->ifw_info & 0xffff; 326 rp->r_segbh = (ifxp->ifw_info >> 16) & 0x3; 327 rp->r_flags = 0; 328 ifxp++; 329 } 330 ifrw = &ds->ds_ifr[0]; 331 for (rp = &ds->ds_rrent[0]; rp < &ds->ds_rrent[NRCV]; rp++) { 332 rp->r_slen = sizeof (struct de_buf); 333 rp->r_segbl = ifrw->ifrw_info & 0xffff; 334 rp->r_segbh = (ifrw->ifrw_info >> 16) & 0x3; 335 rp->r_flags = RFLG_OWN; /* hang receive */ 336 ifrw++; 337 } 338 339 /* start up the board (rah rah) */ 340 s = splimp(); 341 ds->ds_rindex = ds->ds_xindex = ds->ds_xfree = ds->ds_nxmit = 0; 342 ds->ds_if.if_flags |= IFF_RUNNING; 343 addr->pclow = PCSR0_INTE; /* avoid interlock */ 344 destart(&ds->ds_if); /* queue output packets */ 345 ds->ds_flags |= DSF_RUNNING; /* need before de_setaddr */ 346 if (ds->ds_flags & DSF_SETADDR) 347 de_setaddr(ds->ds_addr, unit); 348 addr->pclow = CMD_START | PCSR0_INTE; 349 splx(s); 350 } 351 352 /* 353 * Setup output on interface. 354 * Get another datagram to send off of the interface queue, 355 * and map it to the interface before starting the output. 356 * Must be called from ipl >= our interrupt level. 357 */ 358 destart(ifp) 359 struct ifnet *ifp; 360 { 361 int len; 362 int unit = ifp->if_unit; 363 struct uba_device *ui = deinfo[unit]; 364 struct dedevice *addr = (struct dedevice *)ui->ui_addr; 365 register struct de_softc *ds = &de_softc[unit]; 366 register struct de_ring *rp; 367 struct mbuf *m; 368 register int nxmit; 369 370 /* 371 * the following test is necessary, since 372 * the code is not reentrant and we have 373 * multiple transmission buffers. 374 */ 375 if (ds->ds_if.if_flags & IFF_OACTIVE) 376 return; 377 for (nxmit = ds->ds_nxmit; nxmit < NXMT; nxmit++) { 378 IF_DEQUEUE(&ds->ds_if.if_snd, m); 379 if (m == 0) 380 break; 381 rp = &ds->ds_xrent[ds->ds_xfree]; 382 if (rp->r_flags & XFLG_OWN) 383 panic("deuna xmit in progress"); 384 len = if_ubaput(&ds->ds_deuba, &ds->ds_ifw[ds->ds_xfree], m); 385 if (ds->ds_deuba.iff_flags & UBA_NEEDBDP) 386 UBAPURGE(ds->ds_deuba.iff_uba, 387 ds->ds_ifw[ds->ds_xfree].ifw_bdp); 388 rp->r_slen = len; 389 rp->r_tdrerr = 0; 390 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN; 391 392 ds->ds_xfree++; 393 if (ds->ds_xfree == NXMT) 394 ds->ds_xfree = 0; 395 } 396 if (ds->ds_nxmit != nxmit) { 397 ds->ds_nxmit = nxmit; 398 if (ds->ds_flags & DSF_RUNNING) 399 addr->pclow = PCSR0_INTE|CMD_PDMD; 400 } 401 } 402 403 /* 404 * Command done interrupt. 405 */ 406 deintr(unit) 407 int unit; 408 { 409 struct uba_device *ui = deinfo[unit]; 410 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 411 register struct de_softc *ds = &de_softc[unit]; 412 register struct de_ring *rp; 413 register struct ifxmt *ifxp; 414 short csr0; 415 416 /* save flags right away - clear out interrupt bits */ 417 csr0 = addr->pcsr0; 418 addr->pchigh = csr0 >> 8; 419 420 421 ds->ds_if.if_flags |= IFF_OACTIVE; /* prevent entering destart */ 422 /* 423 * if receive, put receive buffer on mbuf 424 * and hang the request again 425 */ 426 derecv(unit); 427 428 /* 429 * Poll transmit ring and check status. 430 * Be careful about loopback requests. 431 * Then free buffer space and check for 432 * more transmit requests. 433 */ 434 for ( ; ds->ds_nxmit > 0; ds->ds_nxmit--) { 435 rp = &ds->ds_xrent[ds->ds_xindex]; 436 if (rp->r_flags & XFLG_OWN) 437 break; 438 ds->ds_if.if_opackets++; 439 ifxp = &ds->ds_ifw[ds->ds_xindex]; 440 /* check for unusual conditions */ 441 if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) { 442 if (rp->r_flags & XFLG_ERRS) { 443 /* output error */ 444 ds->ds_if.if_oerrors++; 445 if (dedebug) 446 printf("de%d: oerror, flags=%b tdrerr=%b (len=%d)\n", 447 unit, rp->r_flags, XFLG_BITS, 448 rp->r_tdrerr, XERR_BITS, rp->r_slen); 449 } else if (rp->r_flags & XFLG_ONE) { 450 /* one collision */ 451 ds->ds_if.if_collisions++; 452 } else if (rp->r_flags & XFLG_MORE) { 453 /* more than one collision */ 454 ds->ds_if.if_collisions += 2; /* guess */ 455 } else if (rp->r_flags & XFLG_MTCH) { 456 /* received our own packet */ 457 ds->ds_if.if_ipackets++; 458 deread(ds, &ifxp->ifrw, 459 rp->r_slen - sizeof (struct ether_header)); 460 } 461 } 462 if (ifxp->ifw_xtofree) { 463 m_freem(ifxp->ifw_xtofree); 464 ifxp->ifw_xtofree = 0; 465 } 466 /* check if next transmit buffer also finished */ 467 ds->ds_xindex++; 468 if (ds->ds_xindex == NXMT) 469 ds->ds_xindex = 0; 470 } 471 ds->ds_if.if_flags &= ~IFF_OACTIVE; 472 destart(&ds->ds_if); 473 474 if (csr0 & PCSR0_RCBI) { 475 if (dedebug) 476 log(LOG_WARNING, "de%d: buffer unavailable\n", unit); 477 addr->pclow = PCSR0_INTE|CMD_PDMD; 478 } 479 } 480 481 /* 482 * Ethernet interface receiver interface. 483 * If input error just drop packet. 484 * Otherwise purge input buffered data path and examine 485 * packet to determine type. If can't determine length 486 * from type, then have to drop packet. Othewise decapsulate 487 * packet based on type and pass to type specific higher-level 488 * input routine. 489 */ 490 derecv(unit) 491 int unit; 492 { 493 register struct de_softc *ds = &de_softc[unit]; 494 register struct de_ring *rp; 495 int len; 496 497 rp = &ds->ds_rrent[ds->ds_rindex]; 498 while ((rp->r_flags & RFLG_OWN) == 0) { 499 ds->ds_if.if_ipackets++; 500 if (ds->ds_deuba.iff_flags & UBA_NEEDBDP) 501 UBAPURGE(ds->ds_deuba.iff_uba, 502 ds->ds_ifr[ds->ds_rindex].ifrw_bdp); 503 len = (rp->r_lenerr&RERR_MLEN) - sizeof (struct ether_header) 504 - 4; /* don't forget checksum! */ 505 /* check for errors */ 506 if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) || 507 (rp->r_flags&(RFLG_STP|RFLG_ENP)) != (RFLG_STP|RFLG_ENP) || 508 (rp->r_lenerr & (RERR_BUFL|RERR_UBTO|RERR_NCHN)) || 509 len < ETHERMIN || len > ETHERMTU) { 510 ds->ds_if.if_ierrors++; 511 if (dedebug) 512 printf("de%d: ierror, flags=%b lenerr=%b (len=%d)\n", 513 unit, rp->r_flags, RFLG_BITS, rp->r_lenerr, 514 RERR_BITS, len); 515 } else 516 deread(ds, &ds->ds_ifr[ds->ds_rindex], len); 517 518 /* hang the receive buffer again */ 519 rp->r_lenerr = 0; 520 rp->r_flags = RFLG_OWN; 521 522 /* check next receive buffer */ 523 ds->ds_rindex++; 524 if (ds->ds_rindex == NRCV) 525 ds->ds_rindex = 0; 526 rp = &ds->ds_rrent[ds->ds_rindex]; 527 } 528 } 529 530 /* 531 * Pass a packet to the higher levels. 532 * We deal with the trailer protocol here. 533 */ 534 deread(ds, ifrw, len) 535 register struct de_softc *ds; 536 struct ifrw *ifrw; 537 int len; 538 { 539 struct ether_header *eh; 540 struct mbuf *m; 541 int off, resid; 542 int s; 543 register struct ifqueue *inq; 544 545 /* 546 * Deal with trailer protocol: if type is trailer type 547 * get true type from first 16-bit word past data. 548 * Remember that type was trailer by setting off. 549 */ 550 eh = (struct ether_header *)ifrw->ifrw_addr; 551 eh->ether_type = ntohs((u_short)eh->ether_type); 552 #define dedataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) 553 if (eh->ether_type >= ETHERTYPE_TRAIL && 554 eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 555 off = (eh->ether_type - ETHERTYPE_TRAIL) * 512; 556 if (off >= ETHERMTU) 557 return; /* sanity */ 558 eh->ether_type = ntohs(*dedataaddr(eh, off, u_short *)); 559 resid = ntohs(*(dedataaddr(eh, off+2, u_short *))); 560 if (off + resid > len) 561 return; /* sanity */ 562 len = off + resid; 563 } else 564 off = 0; 565 if (len == 0) 566 return; 567 568 /* 569 * Pull packet off interface. Off is nonzero if packet 570 * has trailing header; if_ubaget will then force this header 571 * information to be at the front. 572 */ 573 m = if_ubaget(&ds->ds_deuba, ifrw, len, off, &ds->ds_if); 574 if (m) 575 ether_input(&ds->ds_if, eh, m); 576 } 577 /* 578 * Process an ioctl request. 579 */ 580 deioctl(ifp, cmd, data) 581 register struct ifnet *ifp; 582 int cmd; 583 caddr_t data; 584 { 585 register struct ifaddr *ifa = (struct ifaddr *)data; 586 register struct de_softc *ds = &de_softc[ifp->if_unit]; 587 int s = splimp(), error = 0; 588 589 switch (cmd) { 590 591 case SIOCSIFADDR: 592 ifp->if_flags |= IFF_UP; 593 deinit(ifp->if_unit); 594 595 switch (ifa->ifa_addr->sa_family) { 596 #ifdef INET 597 case AF_INET: 598 ((struct arpcom *)ifp)->ac_ipaddr = 599 IA_SIN(ifa)->sin_addr; 600 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 601 break; 602 #endif 603 #ifdef NS 604 case AF_NS: 605 { 606 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 607 608 if (ns_nullhost(*ina)) 609 ina->x_host = *(union ns_host *)(ds->ds_addr); 610 else 611 de_setaddr(ina->x_host.c_host,ifp->if_unit); 612 break; 613 } 614 #endif 615 } 616 break; 617 618 case SIOCSIFFLAGS: 619 if ((ifp->if_flags & IFF_UP) == 0 && 620 ds->ds_flags & DSF_RUNNING) { 621 ((struct dedevice *) 622 (deinfo[ifp->if_unit]->ui_addr))->pclow = 0; 623 DELAY(100); 624 ((struct dedevice *) 625 (deinfo[ifp->if_unit]->ui_addr))->pclow = PCSR0_RSET; 626 ds->ds_flags &= ~DSF_RUNNING; 627 ds->ds_if.if_flags &= ~IFF_OACTIVE; 628 } else if (ifp->if_flags & IFF_UP && 629 (ds->ds_flags & DSF_RUNNING) == 0) 630 deinit(ifp->if_unit); 631 break; 632 633 default: 634 error = EINVAL; 635 } 636 splx(s); 637 return (error); 638 } 639 640 /* 641 * set ethernet address for unit 642 */ 643 de_setaddr(physaddr, unit) 644 u_char *physaddr; 645 int unit; 646 { 647 register struct de_softc *ds = &de_softc[unit]; 648 struct uba_device *ui = deinfo[unit]; 649 register struct dedevice *addr= (struct dedevice *)ui->ui_addr; 650 651 if (! (ds->ds_flags & DSF_RUNNING)) 652 return; 653 654 bcopy((caddr_t) physaddr, (caddr_t) &ds->ds_pcbb.pcbb2, 6); 655 ds->ds_pcbb.pcbb0 = FC_WTPHYAD; 656 addr->pclow = PCSR0_INTE|CMD_GETCMD; 657 if (dewait(ui, "address change") == 0) { 658 ds->ds_flags |= DSF_SETADDR; 659 bcopy((caddr_t) physaddr, (caddr_t) ds->ds_addr, 6); 660 } 661 } 662 663 /* 664 * Await completion of the named function 665 * and check for errors. 666 */ 667 dewait(ui, fn) 668 register struct uba_device *ui; 669 char *fn; 670 { 671 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 672 register csr0; 673 674 while ((addr->pcsr0 & PCSR0_INTR) == 0) 675 ; 676 csr0 = addr->pcsr0; 677 addr->pchigh = csr0 >> 8; 678 if (csr0 & PCSR0_PCEI) 679 printf("de%d: %s failed, csr0=%b csr1=%b\n", 680 ui->ui_unit, fn, csr0, PCSR0_BITS, 681 addr->pcsr1, PCSR1_BITS); 682 return (csr0 & PCSR0_PCEI); 683 } 684 #endif 685