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