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