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