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