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