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