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