1 /* if_en.c 6.3 84/05/18 */ 2 3 #include "en.h" 4 5 /* 6 * Xerox prototype (3 Mb) Ethernet interface driver. 7 */ 8 #include "../machine/pte.h" 9 10 #include "../h/param.h" 11 #include "../h/systm.h" 12 #include "../h/mbuf.h" 13 #include "../h/buf.h" 14 #include "../h/protosw.h" 15 #include "../h/socket.h" 16 #include "../h/vmmac.h" 17 #include "../h/errno.h" 18 #include "../h/ioctl.h" 19 20 #include "../net/if.h" 21 #include "../net/netisr.h" 22 #include "../net/route.h" 23 #include "../netinet/in.h" 24 #include "../netinet/in_systm.h" 25 #include "../netinet/ip.h" 26 #include "../netinet/ip_var.h" 27 #include "../netpup/pup.h" 28 #include "../netpup/ether.h" 29 30 #include "../vax/cpu.h" 31 #include "../vax/mtpr.h" 32 #include "../vaxif/if_en.h" 33 #include "../vaxif/if_enreg.h" 34 #include "../vaxif/if_uba.h" 35 #include "../vaxuba/ubareg.h" 36 #include "../vaxuba/ubavar.h" 37 38 #define ENMTU (1024+512) 39 #define ENMRU (1024+512+16) /* 16 is enough to receive trailer */ 40 41 int enprobe(), enattach(), enrint(), enxint(), encollide(); 42 struct uba_device *eninfo[NEN]; 43 u_short enstd[] = { 0 }; 44 struct uba_driver endriver = 45 { enprobe, 0, enattach, 0, enstd, "en", eninfo }; 46 #define ENUNIT(x) minor(x) 47 48 int eninit(),enoutput(),enreset(),enioctl(); 49 50 #ifdef notdef 51 /* 52 * If you need to byte swap IP's in the system, define 53 * this and do a SIOCSIFFLAGS at boot time. 54 */ 55 #define ENF_SWABIPS 0x100 56 #endif 57 58 /* 59 * Ethernet software status per interface. 60 * 61 * Each interface is referenced by a network interface structure, 62 * es_if, which the routing code uses to locate the interface. 63 * This structure contains the output queue for the interface, its address, ... 64 * We also have, for each interface, a UBA interface structure, which 65 * contains information about the UNIBUS resources held by the interface: 66 * map registers, buffered data paths, etc. Information is cached in this 67 * structure for use by the if_uba.c routines in running the interface 68 * efficiently. 69 */ 70 struct en_softc { 71 struct ifnet es_if; /* network-visible interface */ 72 struct ifuba es_ifuba; /* UNIBUS resources */ 73 short es_host; /* hardware host number */ 74 short es_delay; /* current output delay */ 75 short es_mask; /* mask for current output delay */ 76 short es_lastx; /* host last transmitted to */ 77 short es_oactive; /* is output active? */ 78 short es_olen; /* length of last output */ 79 } en_softc[NEN]; 80 81 /* 82 * Do output DMA to determine interface presence and 83 * interrupt vector. DMA is too short to disturb other hosts. 84 */ 85 enprobe(reg) 86 caddr_t reg; 87 { 88 register int br, cvec; /* r11, r10 value-result */ 89 register struct endevice *addr = (struct endevice *)reg; 90 91 #ifdef lint 92 br = 0; cvec = br; br = cvec; 93 enrint(0); enxint(0); encollide(0); 94 #endif 95 addr->en_istat = 0; 96 addr->en_owc = -1; 97 addr->en_oba = 0; 98 addr->en_ostat = EN_IEN|EN_GO; 99 DELAY(100000); 100 addr->en_ostat = 0; 101 return (1); 102 } 103 104 /* 105 * Interface exists: make available by filling in network interface 106 * record. System will initialize the interface when it is ready 107 * to accept packets. 108 */ 109 enattach(ui) 110 struct uba_device *ui; 111 { 112 register struct en_softc *es = &en_softc[ui->ui_unit]; 113 114 es->es_if.if_unit = ui->ui_unit; 115 es->es_if.if_name = "en"; 116 es->es_if.if_mtu = ENMTU; 117 es->es_if.if_init = eninit; 118 es->es_if.if_output = enoutput; 119 es->es_if.if_ioctl = enioctl; 120 es->es_if.if_reset = enreset; 121 es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16 | UBA_CANTWAIT; 122 #if defined(VAX750) 123 /* don't chew up 750 bdp's */ 124 if (cpu == VAX_750 && ui->ui_unit > 0) 125 es->es_ifuba.ifu_flags &= ~UBA_NEEDBDP; 126 #endif 127 if_attach(&es->es_if); 128 } 129 130 /* 131 * Reset of interface after UNIBUS reset. 132 * If interface is on specified uba, reset its state. 133 */ 134 enreset(unit, uban) 135 int unit, uban; 136 { 137 register struct uba_device *ui; 138 139 if (unit >= NEN || (ui = eninfo[unit]) == 0 || ui->ui_alive == 0 || 140 ui->ui_ubanum != uban) 141 return; 142 printf(" en%d", unit); 143 eninit(unit); 144 } 145 146 /* 147 * Initialization of interface; clear recorded pending 148 * operations, and reinitialize UNIBUS usage. 149 */ 150 eninit(unit) 151 int unit; 152 { 153 register struct en_softc *es = &en_softc[unit]; 154 register struct uba_device *ui = eninfo[unit]; 155 register struct endevice *addr; 156 struct sockaddr_in *sin = (struct sockaddr_in *)&es->es_if.if_addr; 157 int s; 158 159 if (in_netof(sin->sin_addr) == 0) 160 return; 161 if (if_ubainit(&es->es_ifuba, ui->ui_ubanum, 162 sizeof (struct en_header), (int)btoc(ENMRU)) == 0) { 163 printf("en%d: can't initialize\n", unit); 164 es->es_if.if_flags &= ~IFF_UP; 165 return; 166 } 167 addr = (struct endevice *)ui->ui_addr; 168 addr->en_istat = addr->en_ostat = 0; 169 170 /* 171 * Hang a receive and start any 172 * pending writes by faking a transmit complete. 173 */ 174 s = splimp(); 175 addr->en_iba = es->es_ifuba.ifu_r.ifrw_info; 176 addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1; 177 addr->en_istat = EN_IEN|EN_GO; 178 es->es_oactive = 1; 179 es->es_if.if_flags |= IFF_UP|IFF_RUNNING; 180 enxint(unit); 181 splx(s); 182 if_rtinit(&es->es_if, RTF_UP); 183 } 184 185 int enalldelay = 0; 186 int enlastdel = 50; 187 int enlastmask = (~0) << 5; 188 189 /* 190 * Start or restart output on interface. 191 * If interface is already active, then this is a retransmit 192 * after a collision, and just restuff registers and delay. 193 * If interface is not already active, get another datagram 194 * to send off of the interface queue, and map it to the interface 195 * before starting the output. 196 */ 197 enstart(dev) 198 dev_t dev; 199 { 200 int unit = ENUNIT(dev); 201 struct uba_device *ui = eninfo[unit]; 202 register struct en_softc *es = &en_softc[unit]; 203 register struct endevice *addr; 204 register struct en_header *en; 205 struct mbuf *m; 206 int dest; 207 208 if (es->es_oactive) 209 goto restart; 210 211 /* 212 * Not already active: dequeue another request 213 * and map it to the UNIBUS. If no more requests, 214 * just return. 215 */ 216 IF_DEQUEUE(&es->es_if.if_snd, m); 217 if (m == 0) { 218 es->es_oactive = 0; 219 return; 220 } 221 en = mtod(m, struct en_header *); 222 dest = en->en_dhost; 223 en->en_shost = es->es_host; 224 es->es_olen = if_wubaput(&es->es_ifuba, m); 225 #ifdef ENF_SWABIPS 226 /* 227 * The Xerox interface does word at a time DMA, so 228 * someone must do byte swapping of user data if high 229 * and low ender machines are to communicate. It doesn't 230 * belong here, but certain people depend on it, so... 231 * 232 * Should swab everybody, but this is a kludge anyway. 233 */ 234 if (es->es_if.if_flags & ENF_SWABIPS) { 235 en = (struct en_header *)es->es_ifuba.ifu_w.ifrw_addr; 236 if (en->en_type == ENTYPE_IP) 237 enswab((caddr_t)(en + 1), (caddr_t)(en + 1), 238 es->es_olen - sizeof (struct en_header) + 1); 239 } 240 #endif 241 242 /* 243 * Ethernet cannot take back-to-back packets (no 244 * buffering in interface. To help avoid overrunning 245 * receivers, enforce a small delay (about 1ms) in interface: 246 * * between all packets when enalldelay 247 * * whenever last packet was broadcast 248 * * whenever this packet is to same host as last packet 249 */ 250 if (enalldelay || es->es_lastx == 0 || es->es_lastx == dest) { 251 es->es_delay = enlastdel; 252 es->es_mask = enlastmask; 253 } 254 es->es_lastx = dest; 255 256 restart: 257 /* 258 * Have request mapped to UNIBUS for transmission. 259 * Purge any stale data from this BDP, and start the otput. 260 */ 261 if (es->es_ifuba.ifu_flags & UBA_NEEDBDP) 262 UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_w.ifrw_bdp); 263 addr = (struct endevice *)ui->ui_addr; 264 addr->en_oba = (int)es->es_ifuba.ifu_w.ifrw_info; 265 addr->en_odelay = es->es_delay; 266 addr->en_owc = -((es->es_olen + 1) >> 1); 267 addr->en_ostat = EN_IEN|EN_GO; 268 es->es_oactive = 1; 269 } 270 271 /* 272 * Ethernet interface transmitter interrupt. 273 * Start another output if more data to send. 274 */ 275 enxint(unit) 276 int unit; 277 { 278 register struct uba_device *ui = eninfo[unit]; 279 register struct en_softc *es = &en_softc[unit]; 280 register struct endevice *addr = (struct endevice *)ui->ui_addr; 281 282 if (es->es_oactive == 0) 283 return; 284 if (es->es_mask && (addr->en_ostat&EN_OERROR)) { 285 es->es_if.if_oerrors++; 286 endocoll(unit); 287 return; 288 } 289 es->es_if.if_opackets++; 290 es->es_oactive = 0; 291 es->es_delay = 0; 292 es->es_mask = ~0; 293 if (es->es_ifuba.ifu_xtofree) { 294 m_freem(es->es_ifuba.ifu_xtofree); 295 es->es_ifuba.ifu_xtofree = 0; 296 } 297 if (es->es_if.if_snd.ifq_head == 0) { 298 es->es_lastx = 256; /* putatively illegal */ 299 return; 300 } 301 enstart(unit); 302 } 303 304 /* 305 * Collision on ethernet interface. Do exponential 306 * backoff, and retransmit. If have backed off all 307 * the way print warning diagnostic, and drop packet. 308 */ 309 encollide(unit) 310 int unit; 311 { 312 struct en_softc *es = &en_softc[unit]; 313 314 es->es_if.if_collisions++; 315 if (es->es_oactive == 0) 316 return; 317 endocoll(unit); 318 } 319 320 endocoll(unit) 321 int unit; 322 { 323 register struct en_softc *es = &en_softc[unit]; 324 325 /* 326 * Es_mask is a 16 bit number with n low zero bits, with 327 * n the number of backoffs. When es_mask is 0 we have 328 * backed off 16 times, and give up. 329 */ 330 if (es->es_mask == 0) { 331 printf("en%d: send error\n", unit); 332 enxint(unit); 333 return; 334 } 335 /* 336 * Another backoff. Restart with delay based on n low bits 337 * of the interval timer. 338 */ 339 es->es_mask <<= 1; 340 es->es_delay = mfpr(ICR) &~ es->es_mask; 341 enstart(unit); 342 } 343 344 #ifdef notdef 345 struct sockproto enproto = { AF_ETHERLINK }; 346 struct sockaddr_en endst = { AF_ETHERLINK }; 347 struct sockaddr_en ensrc = { AF_ETHERLINK }; 348 #endif 349 /* 350 * Ethernet interface receiver interrupt. 351 * If input error just drop packet. 352 * Otherwise purge input buffered data path and examine 353 * packet to determine type. If can't determine length 354 * from type, then have to drop packet. Othewise decapsulate 355 * packet based on type and pass to type specific higher-level 356 * input routine. 357 */ 358 enrint(unit) 359 int unit; 360 { 361 register struct en_softc *es = &en_softc[unit]; 362 struct endevice *addr = (struct endevice *)eninfo[unit]->ui_addr; 363 register struct en_header *en; 364 struct mbuf *m; 365 int len; short resid; 366 register struct ifqueue *inq; 367 int off, s; 368 369 es->es_if.if_ipackets++; 370 371 /* 372 * Purge BDP; drop if input error indicated. 373 */ 374 if (es->es_ifuba.ifu_flags & UBA_NEEDBDP) 375 UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp); 376 if (addr->en_istat&EN_IERROR) { 377 es->es_if.if_ierrors++; 378 goto setup; 379 } 380 381 /* 382 * Calculate input data length. 383 * Get pointer to ethernet header (in input buffer). 384 * Deal with trailer protocol: if type is PUP trailer 385 * get true type from first 16-bit word past data. 386 * Remember that type was trailer by setting off. 387 */ 388 resid = addr->en_iwc; 389 if (resid) 390 resid |= 0176000; 391 len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1; 392 len -= sizeof (struct en_header); 393 if (len > ENMRU) 394 goto setup; /* sanity */ 395 en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr); 396 en->en_type = ntohs(en->en_type); 397 #define endataaddr(en, off, type) ((type)(((caddr_t)((en)+1)+(off)))) 398 if (en->en_type >= ENTYPE_TRAIL && 399 en->en_type < ENTYPE_TRAIL+ENTYPE_NTRAILER) { 400 off = (en->en_type - ENTYPE_TRAIL) * 512; 401 if (off > ENMTU) 402 goto setup; /* sanity */ 403 en->en_type = ntohs(*endataaddr(en, off, u_short *)); 404 resid = ntohs(*(endataaddr(en, off+2, u_short *))); 405 if (off + resid > len) 406 goto setup; /* sanity */ 407 len = off + resid; 408 } else 409 off = 0; 410 if (len == 0) 411 goto setup; 412 #ifdef ENF_SWABIPS 413 if (es->es_if.if_flags & ENF_SWABIPS && en->en_type == ENTYPE_IP) 414 enswab((caddr_t)(en + 1), (caddr_t)(en + 1), len); 415 #endif 416 /* 417 * Pull packet off interface. Off is nonzero if packet 418 * has trailing header; if_rubaget will then force this header 419 * information to be at the front, but we still have to drop 420 * the type and length which are at the front of any trailer data. 421 */ 422 m = if_rubaget(&es->es_ifuba, len, off); 423 if (m == 0) 424 goto setup; 425 if (off) { 426 m->m_off += 2 * sizeof (u_short); 427 m->m_len -= 2 * sizeof (u_short); 428 } 429 switch (en->en_type) { 430 431 #ifdef INET 432 case ENTYPE_IP: 433 schednetisr(NETISR_IP); 434 inq = &ipintrq; 435 break; 436 #endif 437 #ifdef PUP 438 case ENTYPE_PUP: 439 rpup_input(m); 440 goto setup; 441 #endif 442 default: 443 #ifdef notdef 444 enproto.sp_protocol = en->en_type; 445 endst.sen_host = en->en_dhost; 446 endst.sen_net = ensrc.sen_net = es->es_if.if_net; 447 ensrc.sen_host = en->en_shost; 448 raw_input(m, &enproto, 449 (struct sockaddr *)&ensrc, (struct sockaddr *)&endst); 450 #else 451 m_freem(m); 452 #endif 453 goto setup; 454 } 455 456 s = splimp(); 457 if (IF_QFULL(inq)) { 458 IF_DROP(inq); 459 m_freem(m); 460 } else 461 IF_ENQUEUE(inq, m); 462 splx(s); 463 464 setup: 465 /* 466 * Reset for next packet. 467 */ 468 addr->en_iba = es->es_ifuba.ifu_r.ifrw_info; 469 addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1; 470 addr->en_istat = EN_IEN|EN_GO; 471 } 472 473 /* 474 * Ethernet output routine. 475 * Encapsulate a packet of type family for the local net. 476 * Use trailer local net encapsulation if enough data in first 477 * packet leaves a multiple of 512 bytes of data in remainder. 478 */ 479 enoutput(ifp, m0, dst) 480 struct ifnet *ifp; 481 struct mbuf *m0; 482 struct sockaddr *dst; 483 { 484 int type, dest, s, error; 485 register struct mbuf *m = m0; 486 register struct en_header *en; 487 register int off; 488 489 switch (dst->sa_family) { 490 491 #ifdef INET 492 case AF_INET: 493 dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr; 494 if (in_lnaof(*((struct in_addr *)&dest)) >= 0x100) { 495 error = EPERM; /* ??? */ 496 goto bad; 497 } 498 dest = (dest >> 24) & 0xff; 499 off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; 500 /* need per host negotiation */ 501 if ((ifp->if_flags & IFF_NOTRAILERS) == 0) 502 if (off > 0 && (off & 0x1ff) == 0 && 503 m->m_off >= MMINOFF + 2 * sizeof (u_short)) { 504 type = ENTYPE_TRAIL + (off>>9); 505 m->m_off -= 2 * sizeof (u_short); 506 m->m_len += 2 * sizeof (u_short); 507 *mtod(m, u_short *) = htons((u_short)ENTYPE_IP); 508 *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len); 509 goto gottrailertype; 510 } 511 type = ENTYPE_IP; 512 off = 0; 513 goto gottype; 514 #endif 515 #ifdef PUP 516 case AF_PUP: 517 dest = ((struct sockaddr_pup *)dst)->spup_host; 518 type = ENTYPE_PUP; 519 off = 0; 520 goto gottype; 521 #endif 522 523 #ifdef notdef 524 case AF_ETHERLINK: 525 goto gotheader; 526 #endif 527 528 default: 529 printf("en%d: can't handle af%d\n", ifp->if_unit, 530 dst->sa_family); 531 error = EAFNOSUPPORT; 532 goto bad; 533 } 534 535 gottrailertype: 536 /* 537 * Packet to be sent as trailer: move first packet 538 * (control information) to end of chain. 539 */ 540 while (m->m_next) 541 m = m->m_next; 542 m->m_next = m0; 543 m = m0->m_next; 544 m0->m_next = 0; 545 m0 = m; 546 547 gottype: 548 /* 549 * Add local net header. If no space in first mbuf, 550 * allocate another. 551 */ 552 if (m->m_off > MMAXOFF || 553 MMINOFF + sizeof (struct en_header) > m->m_off) { 554 m = m_get(M_DONTWAIT, MT_HEADER); 555 if (m == 0) { 556 error = ENOBUFS; 557 goto bad; 558 } 559 m->m_next = m0; 560 m->m_off = MMINOFF; 561 m->m_len = sizeof (struct en_header); 562 } else { 563 m->m_off -= sizeof (struct en_header); 564 m->m_len += sizeof (struct en_header); 565 } 566 en = mtod(m, struct en_header *); 567 /* add en_shost later */ 568 en->en_dhost = dest; 569 en->en_type = htons((u_short)type); 570 571 gotheader: 572 /* 573 * Queue message on interface, and start output if interface 574 * not yet active. 575 */ 576 s = splimp(); 577 if (IF_QFULL(&ifp->if_snd)) { 578 IF_DROP(&ifp->if_snd); 579 error = ENOBUFS; 580 goto qfull; 581 } 582 IF_ENQUEUE(&ifp->if_snd, m); 583 if (en_softc[ifp->if_unit].es_oactive == 0) 584 enstart(ifp->if_unit); 585 splx(s); 586 return (0); 587 qfull: 588 m0 = m; 589 splx(s); 590 bad: 591 m_freem(m0); 592 return (error); 593 } 594 595 /* 596 * Process an ioctl request. 597 */ 598 enioctl(ifp, cmd, data) 599 register struct ifnet *ifp; 600 int cmd; 601 caddr_t data; 602 { 603 struct ifreq *ifr = (struct ifreq *)data; 604 int s = splimp(), error = 0; 605 606 switch (cmd) { 607 608 case SIOCSIFADDR: 609 if (ifp->if_flags & IFF_RUNNING) 610 if_rtinit(ifp, -1); /* delete previous route */ 611 ensetaddr(ifp, (struct sockaddr_in *)&ifr->ifr_addr); 612 if (ifp->if_flags & IFF_RUNNING) 613 if_rtinit(ifp, RTF_UP); 614 else 615 eninit(ifp->if_unit); 616 break; 617 618 default: 619 error = EINVAL; 620 } 621 splx(s); 622 return (error); 623 } 624 625 ensetaddr(ifp, sin) 626 register struct ifnet *ifp; 627 register struct sockaddr_in *sin; 628 { 629 struct endevice *enaddr; 630 631 /* set address once for in_netof, so subnets will be recognized */ 632 ifp->if_addr = *(struct sockaddr *)sin; 633 ifp->if_net = in_netof(sin->sin_addr); 634 enaddr = (struct endevice *)eninfo[ifp->if_unit]->ui_addr; 635 ((struct en_softc *) ifp)->es_host = (~enaddr->en_addr) & 0xff; 636 sin = (struct sockaddr_in *)&ifp->if_addr; 637 sin->sin_family = AF_INET; 638 sin->sin_addr = if_makeaddr(ifp->if_net, 639 ((struct en_softc *)ifp)->es_host); 640 sin = (struct sockaddr_in *)&ifp->if_broadaddr; 641 sin->sin_family = AF_INET; 642 sin->sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); 643 ifp->if_flags |= IFF_BROADCAST; 644 } 645 646 #ifdef ENF_SWABIPS 647 /* 648 * Swab bytes 649 * Jeffrey Mogul, Stanford 650 */ 651 enswab(from, to, n) 652 register caddr_t *from, *to; 653 register int n; 654 { 655 register unsigned long temp; 656 657 n >>= 1; n++; 658 #define STEP temp = *from++,*to++ = *from++,*to++ = temp 659 /* round to multiple of 8 */ 660 while ((--n) & 07) 661 STEP; 662 n >>= 3; 663 while (--n >= 0) { 664 STEP; STEP; STEP; STEP; 665 STEP; STEP; STEP; STEP; 666 } 667 } 668 #endif 669