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.4 (Berkeley) 05/26/88 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 ((struct dedevice *)ui->ui_addr)->pcsr0 = PCSR0_RSET; 238 (void)dewait(ui, "reset"); 239 deinit(unit); 240 } 241 242 /* 243 * Initialization of interface; clear recorded pending 244 * operations, and reinitialize UNIBUS usage. 245 */ 246 deinit(unit) 247 int unit; 248 { 249 register struct de_softc *ds = &de_softc[unit]; 250 register struct uba_device *ui = deinfo[unit]; 251 register struct dedevice *addr; 252 register struct ifrw *ifrw; 253 register struct ifxmt *ifxp; 254 struct ifnet *ifp = &ds->ds_if; 255 int s; 256 struct de_ring *rp; 257 int incaddr; 258 259 /* not yet, if address still unknown */ 260 if (ifp->if_addrlist == (struct ifaddr *)0) 261 return; 262 263 if (ds->ds_flags & DSF_RUNNING) 264 return; 265 if ((ifp->if_flags & IFF_RUNNING) == 0) { 266 if (if_ubaminit(&ds->ds_deuba, ui->ui_ubanum, 267 sizeof (struct ether_header), (int)btoc(ETHERMTU), 268 ds->ds_ifr, NRCV, ds->ds_ifw, NXMT) == 0) { 269 printf("de%d: can't initialize\n", unit); 270 ds->ds_if.if_flags &= ~IFF_UP; 271 return; 272 } 273 ds->ds_ubaddr = uballoc(ui->ui_ubanum, INCORE_BASE(ds), 274 INCORE_SIZE, 0); 275 } 276 addr = (struct dedevice *)ui->ui_addr; 277 278 /* set the pcbb block address */ 279 incaddr = ds->ds_ubaddr + PCBB_OFFSET; 280 addr->pcsr2 = incaddr & 0xffff; 281 addr->pcsr3 = (incaddr >> 16) & 0x3; 282 addr->pclow = 0; /* reset INTE */ 283 DELAY(100); 284 addr->pclow = CMD_GETPCBB; 285 (void)dewait(ui, "pcbb"); 286 287 /* set the transmit and receive ring header addresses */ 288 incaddr = ds->ds_ubaddr + UDBBUF_OFFSET; 289 ds->ds_pcbb.pcbb0 = FC_WTRING; 290 ds->ds_pcbb.pcbb2 = incaddr & 0xffff; 291 ds->ds_pcbb.pcbb4 = (incaddr >> 16) & 0x3; 292 293 incaddr = ds->ds_ubaddr + XRENT_OFFSET; 294 ds->ds_udbbuf.b_tdrbl = incaddr & 0xffff; 295 ds->ds_udbbuf.b_tdrbh = (incaddr >> 16) & 0x3; 296 ds->ds_udbbuf.b_telen = sizeof (struct de_ring) / sizeof (short); 297 ds->ds_udbbuf.b_trlen = NXMT; 298 incaddr = ds->ds_ubaddr + RRENT_OFFSET; 299 ds->ds_udbbuf.b_rdrbl = incaddr & 0xffff; 300 ds->ds_udbbuf.b_rdrbh = (incaddr >> 16) & 0x3; 301 ds->ds_udbbuf.b_relen = sizeof (struct de_ring) / sizeof (short); 302 ds->ds_udbbuf.b_rrlen = NRCV; 303 304 addr->pclow = CMD_GETCMD; 305 (void)dewait(ui, "wtring"); 306 307 /* initialize the mode - enable hardware padding */ 308 ds->ds_pcbb.pcbb0 = FC_WTMODE; 309 /* let hardware do padding - set MTCH bit on broadcast */ 310 ds->ds_pcbb.pcbb2 = MOD_TPAD|MOD_HDX; 311 addr->pclow = CMD_GETCMD; 312 (void)dewait(ui, "wtmode"); 313 314 /* set up the receive and transmit ring entries */ 315 ifxp = &ds->ds_ifw[0]; 316 for (rp = &ds->ds_xrent[0]; rp < &ds->ds_xrent[NXMT]; rp++) { 317 rp->r_segbl = ifxp->ifw_info & 0xffff; 318 rp->r_segbh = (ifxp->ifw_info >> 16) & 0x3; 319 rp->r_flags = 0; 320 ifxp++; 321 } 322 ifrw = &ds->ds_ifr[0]; 323 for (rp = &ds->ds_rrent[0]; rp < &ds->ds_rrent[NRCV]; rp++) { 324 rp->r_slen = sizeof (struct de_buf); 325 rp->r_segbl = ifrw->ifrw_info & 0xffff; 326 rp->r_segbh = (ifrw->ifrw_info >> 16) & 0x3; 327 rp->r_flags = RFLG_OWN; /* hang receive */ 328 ifrw++; 329 } 330 331 /* start up the board (rah rah) */ 332 s = splimp(); 333 ds->ds_rindex = ds->ds_xindex = ds->ds_xfree = ds->ds_nxmit = 0; 334 ds->ds_if.if_flags |= IFF_RUNNING; 335 addr->pclow = PCSR0_INTE; /* avoid interlock */ 336 destart(unit); /* queue output packets */ 337 ds->ds_flags |= DSF_RUNNING; /* need before de_setaddr */ 338 if (ds->ds_flags & DSF_SETADDR) 339 de_setaddr(ds->ds_addr, unit); 340 addr->pclow = CMD_START | PCSR0_INTE; 341 splx(s); 342 } 343 344 /* 345 * Setup output on interface. 346 * Get another datagram to send off of the interface queue, 347 * and map it to the interface before starting the output. 348 */ 349 destart(unit) 350 int unit; 351 { 352 int len; 353 struct uba_device *ui = deinfo[unit]; 354 struct dedevice *addr = (struct dedevice *)ui->ui_addr; 355 register struct de_softc *ds = &de_softc[unit]; 356 register struct de_ring *rp; 357 struct mbuf *m; 358 register int nxmit; 359 360 /* 361 * the following test is necessary, since 362 * the code is not reentrant and we have 363 * multiple transmission buffers. 364 */ 365 if (ds->ds_flags & DSF_LOCK) 366 return; 367 for (nxmit = ds->ds_nxmit; nxmit < NXMT; nxmit++) { 368 IF_DEQUEUE(&ds->ds_if.if_snd, m); 369 if (m == 0) 370 break; 371 rp = &ds->ds_xrent[ds->ds_xfree]; 372 if (rp->r_flags & XFLG_OWN) 373 panic("deuna xmit in progress"); 374 len = if_ubaput(&ds->ds_deuba, &ds->ds_ifw[ds->ds_xfree], m); 375 if (ds->ds_deuba.iff_flags & UBA_NEEDBDP) 376 UBAPURGE(ds->ds_deuba.iff_uba, 377 ds->ds_ifw[ds->ds_xfree].ifw_bdp); 378 rp->r_slen = len; 379 rp->r_tdrerr = 0; 380 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN; 381 382 ds->ds_xfree++; 383 if (ds->ds_xfree == NXMT) 384 ds->ds_xfree = 0; 385 } 386 if (ds->ds_nxmit != nxmit) { 387 ds->ds_nxmit = nxmit; 388 if (ds->ds_flags & DSF_RUNNING) 389 addr->pclow = PCSR0_INTE|CMD_PDMD; 390 } 391 } 392 393 /* 394 * Command done interrupt. 395 */ 396 deintr(unit) 397 int unit; 398 { 399 struct uba_device *ui = deinfo[unit]; 400 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 401 register struct de_softc *ds = &de_softc[unit]; 402 register struct de_ring *rp; 403 register struct ifxmt *ifxp; 404 short csr0; 405 406 /* save flags right away - clear out interrupt bits */ 407 csr0 = addr->pcsr0; 408 addr->pchigh = csr0 >> 8; 409 410 411 ds->ds_flags |= DSF_LOCK; /* prevent entering destart */ 412 /* 413 * if receive, put receive buffer on mbuf 414 * and hang the request again 415 */ 416 derecv(unit); 417 418 /* 419 * Poll transmit ring and check status. 420 * Be careful about loopback requests. 421 * Then free buffer space and check for 422 * more transmit requests. 423 */ 424 for ( ; ds->ds_nxmit > 0; ds->ds_nxmit--) { 425 rp = &ds->ds_xrent[ds->ds_xindex]; 426 if (rp->r_flags & XFLG_OWN) 427 break; 428 ds->ds_if.if_opackets++; 429 ifxp = &ds->ds_ifw[ds->ds_xindex]; 430 /* check for unusual conditions */ 431 if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) { 432 if (rp->r_flags & XFLG_ERRS) { 433 /* output error */ 434 ds->ds_if.if_oerrors++; 435 if (dedebug) 436 printf("de%d: oerror, flags=%b tdrerr=%b (len=%d)\n", 437 unit, rp->r_flags, XFLG_BITS, 438 rp->r_tdrerr, XERR_BITS, rp->r_slen); 439 } else if (rp->r_flags & XFLG_ONE) { 440 /* one collision */ 441 ds->ds_if.if_collisions++; 442 } else if (rp->r_flags & XFLG_MORE) { 443 /* more than one collision */ 444 ds->ds_if.if_collisions += 2; /* guess */ 445 } else if (rp->r_flags & XFLG_MTCH) { 446 /* received our own packet */ 447 ds->ds_if.if_ipackets++; 448 deread(ds, &ifxp->ifrw, 449 rp->r_slen - sizeof (struct ether_header)); 450 } 451 } 452 if (ifxp->ifw_xtofree) { 453 m_freem(ifxp->ifw_xtofree); 454 ifxp->ifw_xtofree = 0; 455 } 456 /* check if next transmit buffer also finished */ 457 ds->ds_xindex++; 458 if (ds->ds_xindex == NXMT) 459 ds->ds_xindex = 0; 460 } 461 ds->ds_flags &= ~DSF_LOCK; 462 destart(unit); 463 464 if (csr0 & PCSR0_RCBI) { 465 if (dedebug) 466 log(LOG_WARNING, "de%d: buffer unavailable\n", unit); 467 addr->pclow = PCSR0_INTE|CMD_PDMD; 468 } 469 } 470 471 /* 472 * Ethernet interface receiver interface. 473 * If input error just drop packet. 474 * Otherwise purge input buffered data path and examine 475 * packet to determine type. If can't determine length 476 * from type, then have to drop packet. Othewise decapsulate 477 * packet based on type and pass to type specific higher-level 478 * input routine. 479 */ 480 derecv(unit) 481 int unit; 482 { 483 register struct de_softc *ds = &de_softc[unit]; 484 register struct de_ring *rp; 485 int len; 486 487 rp = &ds->ds_rrent[ds->ds_rindex]; 488 while ((rp->r_flags & RFLG_OWN) == 0) { 489 ds->ds_if.if_ipackets++; 490 if (ds->ds_deuba.iff_flags & UBA_NEEDBDP) 491 UBAPURGE(ds->ds_deuba.iff_uba, 492 ds->ds_ifr[ds->ds_rindex].ifrw_bdp); 493 len = (rp->r_lenerr&RERR_MLEN) - sizeof (struct ether_header) 494 - 4; /* don't forget checksum! */ 495 /* check for errors */ 496 if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) || 497 (rp->r_flags&(RFLG_STP|RFLG_ENP)) != (RFLG_STP|RFLG_ENP) || 498 (rp->r_lenerr & (RERR_BUFL|RERR_UBTO|RERR_NCHN)) || 499 len < ETHERMIN || len > ETHERMTU) { 500 ds->ds_if.if_ierrors++; 501 if (dedebug) 502 printf("de%d: ierror, flags=%b lenerr=%b (len=%d)\n", 503 unit, rp->r_flags, RFLG_BITS, rp->r_lenerr, 504 RERR_BITS, len); 505 } else 506 deread(ds, &ds->ds_ifr[ds->ds_rindex], len); 507 508 /* hang the receive buffer again */ 509 rp->r_lenerr = 0; 510 rp->r_flags = RFLG_OWN; 511 512 /* check next receive buffer */ 513 ds->ds_rindex++; 514 if (ds->ds_rindex == NRCV) 515 ds->ds_rindex = 0; 516 rp = &ds->ds_rrent[ds->ds_rindex]; 517 } 518 } 519 520 /* 521 * Pass a packet to the higher levels. 522 * We deal with the trailer protocol here. 523 */ 524 deread(ds, ifrw, len) 525 register struct de_softc *ds; 526 struct ifrw *ifrw; 527 int len; 528 { 529 struct ether_header *eh; 530 struct mbuf *m; 531 int off, resid; 532 int s; 533 register struct ifqueue *inq; 534 535 /* 536 * Deal with trailer protocol: if type is trailer type 537 * get true type from first 16-bit word past data. 538 * Remember that type was trailer by setting off. 539 */ 540 eh = (struct ether_header *)ifrw->ifrw_addr; 541 eh->ether_type = ntohs((u_short)eh->ether_type); 542 #define dedataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) 543 if (eh->ether_type >= ETHERTYPE_TRAIL && 544 eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 545 off = (eh->ether_type - ETHERTYPE_TRAIL) * 512; 546 if (off >= ETHERMTU) 547 return; /* sanity */ 548 eh->ether_type = ntohs(*dedataaddr(eh, off, u_short *)); 549 resid = ntohs(*(dedataaddr(eh, off+2, u_short *))); 550 if (off + resid > len) 551 return; /* sanity */ 552 len = off + resid; 553 } else 554 off = 0; 555 if (len == 0) 556 return; 557 558 /* 559 * Pull packet off interface. Off is nonzero if packet 560 * has trailing header; if_ubaget will then force this header 561 * information to be at the front, but we still have to drop 562 * the type and length which are at the front of any trailer data. 563 */ 564 m = if_ubaget(&ds->ds_deuba, ifrw, len, off, &ds->ds_if); 565 if (m == 0) 566 return; 567 if (off) { 568 struct ifnet *ifp; 569 570 ifp = *(mtod(m, struct ifnet **)); 571 m->m_off += 2 * sizeof (u_short); 572 m->m_len -= 2 * sizeof (u_short); 573 *(mtod(m, struct ifnet **)) = ifp; 574 } 575 switch (eh->ether_type) { 576 577 #ifdef INET 578 case ETHERTYPE_IP: 579 schednetisr(NETISR_IP); 580 inq = &ipintrq; 581 break; 582 583 case ETHERTYPE_ARP: 584 arpinput(&ds->ds_ac, m); 585 return; 586 #endif 587 #ifdef NS 588 case ETHERTYPE_NS: 589 schednetisr(NETISR_NS); 590 inq = &nsintrq; 591 break; 592 593 #endif 594 default: 595 m_freem(m); 596 return; 597 } 598 599 s = splimp(); 600 if (IF_QFULL(inq)) { 601 IF_DROP(inq); 602 splx(s); 603 m_freem(m); 604 return; 605 } 606 IF_ENQUEUE(inq, m); 607 splx(s); 608 } 609 610 /* 611 * Ethernet output routine. 612 * Encapsulate a packet of type family for the local net. 613 * Use trailer local net encapsulation if enough data in first 614 * packet leaves a multiple of 512 bytes of data in remainder. 615 */ 616 deoutput(ifp, m0, dst) 617 struct ifnet *ifp; 618 struct mbuf *m0; 619 struct sockaddr *dst; 620 { 621 int type, s, error; 622 u_char edst[6]; 623 struct in_addr idst; 624 register struct de_softc *ds = &de_softc[ifp->if_unit]; 625 register struct mbuf *m = m0; 626 register struct ether_header *eh; 627 register int off; 628 int usetrailers; 629 630 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { 631 error = ENETDOWN; 632 goto bad; 633 } 634 switch (dst->sa_family) { 635 636 #ifdef INET 637 case AF_INET: 638 idst = ((struct sockaddr_in *)dst)->sin_addr; 639 if (!arpresolve(&ds->ds_ac, m, &idst, edst, &usetrailers)) 640 return (0); /* if not yet resolved */ 641 off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; 642 if (usetrailers && off > 0 && (off & 0x1ff) == 0 && 643 m->m_off >= MMINOFF + 2 * sizeof (u_short)) { 644 type = ETHERTYPE_TRAIL + (off>>9); 645 m->m_off -= 2 * sizeof (u_short); 646 m->m_len += 2 * sizeof (u_short); 647 *mtod(m, u_short *) = htons((u_short)ETHERTYPE_IP); 648 *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len); 649 goto gottrailertype; 650 } 651 type = ETHERTYPE_IP; 652 off = 0; 653 goto gottype; 654 #endif 655 #ifdef NS 656 case AF_NS: 657 type = ETHERTYPE_NS; 658 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 659 (caddr_t)edst, sizeof (edst)); 660 off = 0; 661 goto gottype; 662 #endif 663 664 case AF_UNSPEC: 665 eh = (struct ether_header *)dst->sa_data; 666 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 667 type = eh->ether_type; 668 goto gottype; 669 670 default: 671 printf("de%d: can't handle af%d\n", ifp->if_unit, 672 dst->sa_family); 673 error = EAFNOSUPPORT; 674 goto bad; 675 } 676 677 gottrailertype: 678 /* 679 * Packet to be sent as trailer: move first packet 680 * (control information) to end of chain. 681 */ 682 while (m->m_next) 683 m = m->m_next; 684 m->m_next = m0; 685 m = m0->m_next; 686 m0->m_next = 0; 687 m0 = m; 688 689 gottype: 690 /* 691 * Add local net header. If no space in first mbuf, 692 * allocate another. 693 */ 694 if (m->m_off > MMAXOFF || 695 MMINOFF + sizeof (struct ether_header) > m->m_off) { 696 m = m_get(M_DONTWAIT, MT_HEADER); 697 if (m == 0) { 698 error = ENOBUFS; 699 goto bad; 700 } 701 m->m_next = m0; 702 m->m_off = MMINOFF; 703 m->m_len = sizeof (struct ether_header); 704 } else { 705 m->m_off -= sizeof (struct ether_header); 706 m->m_len += sizeof (struct ether_header); 707 } 708 eh = mtod(m, struct ether_header *); 709 eh->ether_type = htons((u_short)type); 710 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 711 /* DEUNA fills in source address */ 712 713 /* 714 * Queue message on interface, and start output if interface 715 * not yet active. 716 */ 717 s = splimp(); 718 if (IF_QFULL(&ifp->if_snd)) { 719 IF_DROP(&ifp->if_snd); 720 splx(s); 721 m_freem(m); 722 return (ENOBUFS); 723 } 724 IF_ENQUEUE(&ifp->if_snd, m); 725 destart(ifp->if_unit); 726 splx(s); 727 return (0); 728 729 bad: 730 m_freem(m0); 731 return (error); 732 } 733 734 /* 735 * Process an ioctl request. 736 */ 737 deioctl(ifp, cmd, data) 738 register struct ifnet *ifp; 739 int cmd; 740 caddr_t data; 741 { 742 register struct ifaddr *ifa = (struct ifaddr *)data; 743 register struct de_softc *ds = &de_softc[ifp->if_unit]; 744 int s = splimp(), error = 0; 745 746 switch (cmd) { 747 748 case SIOCSIFADDR: 749 ifp->if_flags |= IFF_UP; 750 deinit(ifp->if_unit); 751 752 switch (ifa->ifa_addr.sa_family) { 753 #ifdef INET 754 case AF_INET: 755 ((struct arpcom *)ifp)->ac_ipaddr = 756 IA_SIN(ifa)->sin_addr; 757 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 758 break; 759 #endif 760 #ifdef NS 761 case AF_NS: 762 { 763 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 764 765 if (ns_nullhost(*ina)) 766 ina->x_host = *(union ns_host *)(ds->ds_addr); 767 else 768 de_setaddr(ina->x_host.c_host,ifp->if_unit); 769 break; 770 } 771 #endif 772 } 773 break; 774 775 case SIOCSIFFLAGS: 776 if ((ifp->if_flags & IFF_UP) == 0 && 777 ds->ds_flags & DSF_RUNNING) { 778 ((struct dedevice *) 779 (deinfo[ifp->if_unit]->ui_addr))->pclow = 0; 780 DELAY(100); 781 ((struct dedevice *) 782 (deinfo[ifp->if_unit]->ui_addr))->pclow = PCSR0_RSET; 783 ds->ds_flags &= ~(DSF_LOCK | DSF_RUNNING); 784 } else if (ifp->if_flags & IFF_UP && 785 (ds->ds_flags & DSF_RUNNING) == 0) 786 deinit(ifp->if_unit); 787 break; 788 789 default: 790 error = EINVAL; 791 } 792 splx(s); 793 return (error); 794 } 795 796 /* 797 * set ethernet address for unit 798 */ 799 de_setaddr(physaddr, unit) 800 u_char *physaddr; 801 int unit; 802 { 803 register struct de_softc *ds = &de_softc[unit]; 804 struct uba_device *ui = deinfo[unit]; 805 register struct dedevice *addr= (struct dedevice *)ui->ui_addr; 806 807 if (! (ds->ds_flags & DSF_RUNNING)) 808 return; 809 810 bcopy((caddr_t) physaddr, (caddr_t) &ds->ds_pcbb.pcbb2, 6); 811 ds->ds_pcbb.pcbb0 = FC_WTPHYAD; 812 addr->pclow = PCSR0_INTE|CMD_GETCMD; 813 if (dewait(ui, "address change") == 0) { 814 ds->ds_flags |= DSF_SETADDR; 815 bcopy((caddr_t) physaddr, (caddr_t) ds->ds_addr, 6); 816 } 817 } 818 819 /* 820 * Await completion of the named function 821 * and check for errors. 822 */ 823 dewait(ui, fn) 824 register struct uba_device *ui; 825 char *fn; 826 { 827 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 828 register csr0; 829 830 while ((addr->pcsr0 & PCSR0_INTR) == 0) 831 ; 832 csr0 = addr->pcsr0; 833 addr->pchigh = csr0 >> 8; 834 if (csr0 & PCSR0_PCEI) 835 printf("de%d: %s failed, csr0=%b csr1=%b\n", 836 ui->ui_unit, fn, csr0, PCSR0_BITS, 837 addr->pcsr1, PCSR1_BITS); 838 return (csr0 & PCSR0_PCEI); 839 } 840 #endif 841