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