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_ec.c 7.3 (Berkeley) 08/04/88 18 */ 19 20 #include "ec.h" 21 #if NEC > 0 22 23 /* 24 * 3Com Ethernet Controller interface 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 "syslog.h" 35 #include "vmmac.h" 36 #include "ioctl.h" 37 #include "errno.h" 38 39 #include "../net/if.h" 40 #include "../net/netisr.h" 41 #include "../net/route.h" 42 43 #ifdef INET 44 #include "../netinet/in.h" 45 #include "../netinet/in_systm.h" 46 #include "../netinet/in_var.h" 47 #include "../netinet/ip.h" 48 #include "../netinet/if_ether.h" 49 #endif 50 51 #ifdef NS 52 #include "../netns/ns.h" 53 #include "../netns/ns_if.h" 54 #endif 55 56 #include "../vax/cpu.h" 57 #include "../vax/mtpr.h" 58 #include "if_ecreg.h" 59 #include "if_uba.h" 60 #include "../vaxuba/ubareg.h" 61 #include "../vaxuba/ubavar.h" 62 63 #if CLSIZE == 2 64 #define ECBUFSIZE 32 /* on-board memory, clusters */ 65 #endif 66 67 int ecubamem(), ecprobe(), ecattach(), ecrint(), ecxint(), eccollide(); 68 struct uba_device *ecinfo[NEC]; 69 u_short ecstd[] = { 0 }; 70 struct uba_driver ecdriver = 71 { ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo, 0, 0, 0, 0, ecubamem }; 72 73 int ecinit(),ecioctl(),ecoutput(),ecreset(); 74 struct mbuf *ecget(); 75 76 extern struct ifnet loif; 77 78 /* 79 * Ethernet software status per interface. 80 * 81 * Each interface is referenced by a network interface structure, 82 * es_if, which the routing code uses to locate the interface. 83 * This structure contains the output queue for the interface, its address, ... 84 * We also have, for each interface, a UBA interface structure, which 85 * contains information about the UNIBUS resources held by the interface: 86 * map registers, buffered data paths, etc. Information is cached in this 87 * structure for use by the if_uba.c routines in running the interface 88 * efficiently. 89 */ 90 struct ec_softc { 91 struct arpcom es_ac; /* common Ethernet structures */ 92 #define es_if es_ac.ac_if /* network-visible interface */ 93 #define es_addr es_ac.ac_enaddr /* hardware Ethernet address */ 94 struct ifuba es_ifuba; /* UNIBUS resources */ 95 short es_mask; /* mask for current output delay */ 96 short es_oactive; /* is output active? */ 97 u_char *es_buf[16]; /* virtual addresses of buffers */ 98 } ec_softc[NEC]; 99 100 /* 101 * Configure on-board memory for an interface. 102 * Called from autoconfig and after a uba reset. 103 * The address of the memory on the uba is supplied in the device flags. 104 */ 105 ecubamem(ui, uban) 106 register struct uba_device *ui; 107 { 108 register caddr_t ecbuf = (caddr_t) &umem[uban][ui->ui_flags]; 109 register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr; 110 111 /* 112 * Make sure csr is there (we run before ecprobe). 113 */ 114 if (badaddr((caddr_t)addr, 2)) 115 return (-1); 116 #if VAX780 117 if (cpu == VAX_780 && uba_hd[uban].uh_uba->uba_sr) { 118 uba_hd[uban].uh_uba->uba_sr = uba_hd[uban].uh_uba->uba_sr; 119 return (-1); 120 } 121 #endif 122 /* 123 * Make sure memory is turned on 124 */ 125 addr->ec_rcr = EC_AROM; 126 /* 127 * Tell the system that the board has memory here, so it won't 128 * attempt to allocate the addresses later. 129 */ 130 if (ubamem(uban, ui->ui_flags, ECBUFSIZE*CLSIZE, 1) == 0) { 131 printf("ec%d: cannot reserve uba addresses\n", ui->ui_unit); 132 addr->ec_rcr = EC_MDISAB; /* disable memory */ 133 return (-1); 134 } 135 /* 136 * Check for existence of buffers on Unibus. 137 */ 138 if (badaddr((caddr_t)ecbuf, 2)) { 139 bad: 140 printf("ec%d: buffer mem not found\n", ui->ui_unit); 141 (void) ubamem(uban, ui->ui_flags, ECBUFSIZE*2, 0); 142 addr->ec_rcr = EC_MDISAB; /* disable memory */ 143 return (-1); 144 } 145 #if VAX780 146 if (cpu == VAX_780 && uba_hd[uban].uh_uba->uba_sr) { 147 uba_hd[uban].uh_uba->uba_sr = uba_hd[uban].uh_uba->uba_sr; 148 goto bad; 149 } 150 #endif 151 if (ui->ui_alive == 0) /* Only printf from autoconfig */ 152 printf("ec%d: mem %x-%x\n", ui->ui_unit, 153 ui->ui_flags, ui->ui_flags + ECBUFSIZE*CLBYTES - 1); 154 ui->ui_type = 1; /* Memory on, allocated */ 155 return (0); 156 } 157 158 /* 159 * Do output DMA to determine interface presence and 160 * interrupt vector. DMA is too short to disturb other hosts. 161 */ 162 ecprobe(reg, ui) 163 caddr_t reg; 164 struct uba_device *ui; 165 { 166 register int br, cvec; /* r11, r10 value-result */ 167 register struct ecdevice *addr = (struct ecdevice *)reg; 168 register caddr_t ecbuf = (caddr_t) &umem[ui->ui_ubanum][ui->ui_flags]; 169 170 #ifdef lint 171 br = 0; cvec = br; br = cvec; 172 ecrint(0); ecxint(0); eccollide(0); 173 #endif 174 175 /* 176 * Check that buffer memory was found and enabled. 177 */ 178 if (ui->ui_type == 0) 179 return(0); 180 /* 181 * Make a one byte packet in what should be buffer #0. 182 * Submit it for sending. This should cause an xmit interrupt. 183 * The xmit interrupt vector is 8 bytes after the receive vector, 184 * so adjust for this before returning. 185 */ 186 *(u_short *)ecbuf = (u_short) 03777; 187 ecbuf[03777] = '\0'; 188 addr->ec_xcr = EC_XINTEN|EC_XWBN; 189 DELAY(100000); 190 addr->ec_xcr = EC_XCLR; 191 if (cvec > 0 && cvec != 0x200) { 192 if (cvec & 04) { /* collision interrupt */ 193 cvec -= 04; 194 br += 1; /* rcv is collision + 1 */ 195 } else { /* xmit interrupt */ 196 cvec -= 010; 197 br += 2; /* rcv is xmit + 2 */ 198 } 199 } 200 return (1); 201 } 202 203 /* 204 * Interface exists: make available by filling in network interface 205 * record. System will initialize the interface when it is ready 206 * to accept packets. 207 */ 208 ecattach(ui) 209 struct uba_device *ui; 210 { 211 struct ec_softc *es = &ec_softc[ui->ui_unit]; 212 register struct ifnet *ifp = &es->es_if; 213 register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr; 214 int i, j; 215 u_char *cp; 216 217 ifp->if_unit = ui->ui_unit; 218 ifp->if_name = "ec"; 219 ifp->if_mtu = ETHERMTU; 220 221 /* 222 * Read the ethernet address off the board, one nibble at a time. 223 */ 224 addr->ec_xcr = EC_UECLR; /* zero address pointer */ 225 addr->ec_rcr = EC_AROM; 226 cp = es->es_addr; 227 #define NEXTBIT addr->ec_rcr = EC_AROM|EC_ASTEP; addr->ec_rcr = EC_AROM 228 for (i=0; i < sizeof (es->es_addr); i++) { 229 *cp = 0; 230 for (j=0; j<=4; j+=4) { 231 *cp |= ((addr->ec_rcr >> 8) & 0xf) << j; 232 NEXTBIT; NEXTBIT; NEXTBIT; NEXTBIT; 233 } 234 cp++; 235 } 236 printf("ec%d: hardware address %s\n", ui->ui_unit, 237 ether_sprintf(es->es_addr)); 238 ifp->if_init = ecinit; 239 ifp->if_ioctl = ecioctl; 240 ifp->if_output = ecoutput; 241 ifp->if_reset = ecreset; 242 ifp->if_flags = IFF_BROADCAST; 243 for (i=0; i<16; i++) 244 es->es_buf[i] 245 = (u_char *)&umem[ui->ui_ubanum][ui->ui_flags + 2048*i]; 246 if_attach(ifp); 247 } 248 249 /* 250 * Reset of interface after UNIBUS reset. 251 * If interface is on specified uba, reset its state. 252 */ 253 ecreset(unit, uban) 254 int unit, uban; 255 { 256 register struct uba_device *ui; 257 258 if (unit >= NEC || (ui = ecinfo[unit]) == 0 || ui->ui_alive == 0 || 259 ui->ui_ubanum != uban) 260 return; 261 printf(" ec%d", unit); 262 ec_softc[unit].es_if.if_flags &= ~IFF_RUNNING; 263 ecinit(unit); 264 } 265 266 /* 267 * Initialization of interface; clear recorded pending 268 * operations, and reinitialize UNIBUS usage. 269 */ 270 ecinit(unit) 271 int unit; 272 { 273 struct ec_softc *es = &ec_softc[unit]; 274 struct ecdevice *addr; 275 register struct ifnet *ifp = &es->es_if; 276 int i, s; 277 278 /* not yet, if address still unknown */ 279 if (ifp->if_addrlist == (struct ifaddr *)0) 280 return; 281 282 /* 283 * Hang receive buffers and start any pending writes. 284 * Writing into the rcr also makes sure the memory 285 * is turned on. 286 */ 287 if ((ifp->if_flags & IFF_RUNNING) == 0) { 288 addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 289 s = splimp(); 290 /* 291 * write our ethernet address into the address recognition ROM 292 * so we can always use the same EC_READ bits (referencing ROM), 293 * in case we change the address sometime. 294 * Note that this is safe here as the receiver is NOT armed. 295 */ 296 ec_setaddr(es->es_addr, unit); 297 /* 298 * Arm the receiver 299 */ 300 for (i = ECRHBF; i >= ECRLBF; i--) 301 addr->ec_rcr = EC_READ | i; 302 es->es_oactive = 0; 303 es->es_mask = ~0; 304 es->es_if.if_flags |= IFF_RUNNING; 305 if (es->es_if.if_snd.ifq_head) 306 ecstart(unit); 307 splx(s); 308 } 309 } 310 311 /* 312 * Start output on interface. Get another datagram to send 313 * off of the interface queue, and copy it to the interface 314 * before starting the output. 315 */ 316 ecstart(unit) 317 { 318 register struct ec_softc *es = &ec_softc[unit]; 319 struct ecdevice *addr; 320 struct mbuf *m; 321 322 if ((es->es_if.if_flags & IFF_RUNNING) == 0) 323 return; 324 IF_DEQUEUE(&es->es_if.if_snd, m); 325 if (m == 0) 326 return; 327 ecput(es->es_buf[ECTBF], m); 328 addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 329 addr->ec_xcr = EC_WRITE|ECTBF; 330 es->es_oactive = 1; 331 } 332 333 /* 334 * Ethernet interface transmitter interrupt. 335 * Start another output if more data to send. 336 */ 337 ecxint(unit) 338 int unit; 339 { 340 register struct ec_softc *es = &ec_softc[unit]; 341 register struct ecdevice *addr = 342 (struct ecdevice *)ecinfo[unit]->ui_addr; 343 344 if (es->es_oactive == 0) 345 return; 346 if ((addr->ec_xcr&EC_XDONE) == 0 || (addr->ec_xcr&EC_XBN) != ECTBF) { 347 printf("ec%d: stray xmit interrupt, xcr=%b\n", unit, 348 addr->ec_xcr, EC_XBITS); 349 es->es_oactive = 0; 350 addr->ec_xcr = EC_XCLR; 351 return; 352 } 353 es->es_if.if_opackets++; 354 es->es_oactive = 0; 355 es->es_mask = ~0; 356 addr->ec_xcr = EC_XCLR; 357 if (es->es_if.if_snd.ifq_head) 358 ecstart(unit); 359 } 360 361 /* 362 * Collision on ethernet interface. Do exponential 363 * backoff, and retransmit. If have backed off all 364 * the way print warning diagnostic, and drop packet. 365 */ 366 eccollide(unit) 367 int unit; 368 { 369 register struct ec_softc *es = &ec_softc[unit]; 370 register struct ecdevice *addr = 371 (struct ecdevice *)ecinfo[unit]->ui_addr; 372 register i; 373 int delay; 374 375 es->es_if.if_collisions++; 376 if (es->es_oactive == 0) 377 return; 378 379 /* 380 * Es_mask is a 16 bit number with n low zero bits, with 381 * n the number of backoffs. When es_mask is 0 we have 382 * backed off 16 times, and give up. 383 */ 384 if (es->es_mask == 0) { 385 es->es_if.if_oerrors++; 386 log(LOG_ERR, "ec%d: send error\n", unit); 387 /* 388 * Reset interface, then requeue rcv buffers. 389 * Some incoming packets may be lost, but that 390 * can't be helped. 391 */ 392 addr->ec_xcr = EC_UECLR; 393 for (i=ECRHBF; i>=ECRLBF; i--) 394 addr->ec_rcr = EC_READ|i; 395 /* 396 * Reset and transmit next packet (if any). 397 */ 398 es->es_oactive = 0; 399 es->es_mask = ~0; 400 if (es->es_if.if_snd.ifq_head) 401 ecstart(unit); 402 return; 403 } 404 /* 405 * Do exponential backoff. Compute delay based on low bits 406 * of the interval timer (1 bit for each transmission attempt, 407 * but at most 5 bits). Then delay for that number of 408 * slot times. A slot time is 51.2 microseconds (rounded to 51). 409 * This does not take into account the time already used to 410 * process the interrupt. 411 */ 412 es->es_mask <<= 1; 413 delay = mfpr(ICR) & 0x1f &~ es->es_mask; 414 DELAY(delay * 51); 415 /* 416 * Clear the controller's collision flag, thus enabling retransmit. 417 */ 418 addr->ec_xcr = EC_CLEAR; 419 } 420 421 /* 422 * Ethernet interface receiver interrupt. 423 * If input error just drop packet. 424 * Otherwise examine 425 * packet to determine type. If can't determine length 426 * from type, then have to drop packet. Othewise decapsulate 427 * packet based on type and pass to type specific higher-level 428 * input routine. 429 */ 430 ecrint(unit) 431 int unit; 432 { 433 struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 434 435 while (addr->ec_rcr & EC_RDONE) 436 ecread(unit); 437 } 438 439 ecread(unit) 440 int unit; 441 { 442 register struct ec_softc *es = &ec_softc[unit]; 443 struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 444 register struct ether_header *ec; 445 struct mbuf *m; 446 int len, off, resid, ecoff, rbuf; 447 register struct ifqueue *inq; 448 u_char *ecbuf; 449 450 es->es_if.if_ipackets++; 451 rbuf = addr->ec_rcr & EC_RBN; 452 if (rbuf < ECRLBF || rbuf > ECRHBF) 453 panic("ecrint"); 454 ecbuf = es->es_buf[rbuf]; 455 ecoff = *(short *)ecbuf; 456 if (ecoff <= ECRDOFF || ecoff > 2046) { 457 es->es_if.if_ierrors++; 458 #ifdef notdef 459 if (es->es_if.if_ierrors % 100 == 0) 460 printf("ec%d: += 100 input errors\n", unit); 461 #endif 462 goto setup; 463 } 464 465 /* 466 * Get input data length. 467 * Get pointer to ethernet header (in input buffer). 468 * Deal with trailer protocol: if type is trailer type 469 * get true type from first 16-bit word past data. 470 * Remember that type was trailer by setting off. 471 */ 472 len = ecoff - ECRDOFF - sizeof (struct ether_header); 473 ec = (struct ether_header *)(ecbuf + ECRDOFF); 474 ec->ether_type = ntohs((u_short)ec->ether_type); 475 #define ecdataaddr(ec, off, type) ((type)(((caddr_t)((ec)+1)+(off)))) 476 if (ec->ether_type >= ETHERTYPE_TRAIL && 477 ec->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { 478 off = (ec->ether_type - ETHERTYPE_TRAIL) * 512; 479 if (off >= ETHERMTU) 480 goto setup; /* sanity */ 481 ec->ether_type = ntohs(*ecdataaddr(ec, off, u_short *)); 482 resid = ntohs(*(ecdataaddr(ec, off+2, u_short *))); 483 if (off + resid > len) 484 goto setup; /* sanity */ 485 len = off + resid; 486 } else 487 off = 0; 488 if (len == 0) 489 goto setup; 490 491 /* 492 * Pull packet off interface. Off is nonzero if packet 493 * has trailing header; ecget will then force this header 494 * information to be at the front, but we still have to drop 495 * the type and length which are at the front of any trailer data. 496 */ 497 m = ecget(ecbuf, len, off, &es->es_if); 498 if (m == 0) 499 goto setup; 500 if (off) { 501 struct ifnet *ifp; 502 503 ifp = *(mtod(m, struct ifnet **)); 504 m->m_off += 2 * sizeof (u_short); 505 m->m_len -= 2 * sizeof (u_short); 506 *(mtod(m, struct ifnet **)) = ifp; 507 } 508 switch (ec->ether_type) { 509 510 #ifdef INET 511 case ETHERTYPE_IP: 512 schednetisr(NETISR_IP); 513 inq = &ipintrq; 514 break; 515 516 case ETHERTYPE_ARP: 517 arpinput(&es->es_ac, m); 518 goto setup; 519 #endif 520 #ifdef NS 521 case ETHERTYPE_NS: 522 schednetisr(NETISR_NS); 523 inq = &nsintrq; 524 break; 525 526 #endif 527 default: 528 m_freem(m); 529 goto setup; 530 } 531 532 if (IF_QFULL(inq)) { 533 IF_DROP(inq); 534 m_freem(m); 535 goto setup; 536 } 537 IF_ENQUEUE(inq, m); 538 539 setup: 540 /* 541 * Reset for next packet. 542 */ 543 addr->ec_rcr = EC_READ|EC_RCLR|rbuf; 544 } 545 546 /* 547 * Ethernet output routine. 548 * Encapsulate a packet of type family for the local net. 549 * Use trailer local net encapsulation if enough data in first 550 * packet leaves a multiple of 512 bytes of data in remainder. 551 * If destination is this address or broadcast, send packet to 552 * loop device to kludge around the fact that 3com interfaces can't 553 * talk to themselves. 554 */ 555 ecoutput(ifp, m0, dst) 556 struct ifnet *ifp; 557 struct mbuf *m0; 558 struct sockaddr *dst; 559 { 560 int type, s, error; 561 u_char edst[6]; 562 struct in_addr idst; 563 register struct ec_softc *es = &ec_softc[ifp->if_unit]; 564 register struct mbuf *m = m0; 565 register struct ether_header *ec; 566 register int off; 567 struct mbuf *mcopy = (struct mbuf *)0; 568 int usetrailers; 569 570 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { 571 error = ENETDOWN; 572 goto bad; 573 } 574 switch (dst->sa_family) { 575 576 #ifdef INET 577 case AF_INET: 578 idst = ((struct sockaddr_in *)dst)->sin_addr; 579 if (!arpresolve(&es->es_ac, m, &idst, edst, &usetrailers)) 580 return (0); /* if not yet resolved */ 581 if (!bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr, 582 sizeof(edst))) 583 mcopy = m_copy(m, 0, (int)M_COPYALL); 584 off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; 585 /* need per host negotiation */ 586 if (usetrailers && off > 0 && (off & 0x1ff) == 0 && 587 m->m_off >= MMINOFF + 2 * sizeof (u_short)) { 588 type = ETHERTYPE_TRAIL + (off>>9); 589 m->m_off -= 2 * sizeof (u_short); 590 m->m_len += 2 * sizeof (u_short); 591 *mtod(m, u_short *) = ntohs((u_short)ETHERTYPE_IP); 592 *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len); 593 goto gottrailertype; 594 } 595 type = ETHERTYPE_IP; 596 off = 0; 597 goto gottype; 598 #endif 599 #ifdef NS 600 case AF_NS: 601 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 602 (caddr_t)edst, sizeof (edst)); 603 604 if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, 605 sizeof(edst))) { 606 607 mcopy = m_copy(m, 0, (int)M_COPYALL); 608 } else if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, 609 sizeof(edst))) { 610 611 return(looutput(&loif, m, dst)); 612 } 613 type = ETHERTYPE_NS; 614 off = 0; 615 goto gottype; 616 #endif 617 618 case AF_UNSPEC: 619 ec = (struct ether_header *)dst->sa_data; 620 bcopy((caddr_t)ec->ether_dhost, (caddr_t)edst, sizeof (edst)); 621 type = ec->ether_type; 622 goto gottype; 623 624 default: 625 printf("ec%d: can't handle af%d\n", ifp->if_unit, 626 dst->sa_family); 627 error = EAFNOSUPPORT; 628 goto bad; 629 } 630 631 gottrailertype: 632 /* 633 * Packet to be sent as trailer: move first packet 634 * (control information) to end of chain. 635 */ 636 while (m->m_next) 637 m = m->m_next; 638 m->m_next = m0; 639 m = m0->m_next; 640 m0->m_next = 0; 641 m0 = m; 642 643 gottype: 644 /* 645 * Add local net header. If no space in first mbuf, 646 * allocate another. 647 */ 648 if (m->m_off > MMAXOFF || 649 MMINOFF + sizeof (struct ether_header) > m->m_off) { 650 m = m_get(M_DONTWAIT, MT_HEADER); 651 if (m == 0) { 652 error = ENOBUFS; 653 goto bad; 654 } 655 m->m_next = m0; 656 m->m_off = MMINOFF; 657 m->m_len = sizeof (struct ether_header); 658 } else { 659 m->m_off -= sizeof (struct ether_header); 660 m->m_len += sizeof (struct ether_header); 661 } 662 ec = mtod(m, struct ether_header *); 663 bcopy((caddr_t)edst, (caddr_t)ec->ether_dhost, sizeof (edst)); 664 bcopy((caddr_t)es->es_addr, (caddr_t)ec->ether_shost, 665 sizeof(ec->ether_shost)); 666 ec->ether_type = htons((u_short)type); 667 668 /* 669 * Queue message on interface, and start output if interface 670 * not yet active. 671 */ 672 s = splimp(); 673 if (IF_QFULL(&ifp->if_snd)) { 674 IF_DROP(&ifp->if_snd); 675 error = ENOBUFS; 676 goto qfull; 677 } 678 IF_ENQUEUE(&ifp->if_snd, m); 679 if (es->es_oactive == 0) 680 ecstart(ifp->if_unit); 681 splx(s); 682 return (mcopy ? looutput(&loif, mcopy, dst) : 0); 683 684 qfull: 685 m0 = m; 686 splx(s); 687 bad: 688 m_freem(m0); 689 if (mcopy) 690 m_freem(mcopy); 691 return (error); 692 } 693 694 /* 695 * Routine to copy from mbuf chain to transmit 696 * buffer in UNIBUS memory. 697 * If packet size is less than the minimum legal size, 698 * the buffer is expanded. We probably should zero out the extra 699 * bytes for security, but that would slow things down. 700 */ 701 ecput(ecbuf, m) 702 u_char *ecbuf; 703 struct mbuf *m; 704 { 705 register struct mbuf *mp; 706 register int off; 707 u_char *bp; 708 709 for (off = 2048, mp = m; mp; mp = mp->m_next) 710 off -= mp->m_len; 711 if (2048 - off < ETHERMIN + sizeof (struct ether_header)) 712 off = 2048 - ETHERMIN - sizeof (struct ether_header); 713 *(u_short *)ecbuf = off; 714 bp = (u_char *)(ecbuf + off); 715 for (mp = m; mp; mp = mp->m_next) { 716 register unsigned len = mp->m_len; 717 u_char *mcp; 718 719 if (len == 0) 720 continue; 721 mcp = mtod(mp, u_char *); 722 if ((unsigned)bp & 01) { 723 *bp++ = *mcp++; 724 len--; 725 } 726 if (off = (len >> 1)) { 727 register u_short *to, *from; 728 729 to = (u_short *)bp; 730 from = (u_short *)mcp; 731 do 732 *to++ = *from++; 733 while (--off > 0); 734 bp = (u_char *)to, 735 mcp = (u_char *)from; 736 } 737 if (len & 01) 738 *bp++ = *mcp++; 739 } 740 m_freem(m); 741 } 742 743 /* 744 * Routine to copy from UNIBUS memory into mbufs. 745 * Similar in spirit to if_rubaget. 746 * 747 * Warning: This makes the fairly safe assumption that 748 * mbufs have even lengths. 749 */ 750 struct mbuf * 751 ecget(ecbuf, totlen, off0, ifp) 752 u_char *ecbuf; 753 int totlen, off0; 754 struct ifnet *ifp; 755 { 756 register struct mbuf *m; 757 struct mbuf *top = 0, **mp = ⊤ 758 register int off = off0, len; 759 u_char *cp; 760 761 cp = ecbuf + ECRDOFF + sizeof (struct ether_header); 762 while (totlen > 0) { 763 register int words; 764 u_char *mcp; 765 766 MGET(m, M_DONTWAIT, MT_DATA); 767 if (m == 0) 768 goto bad; 769 if (off) { 770 len = totlen - off; 771 cp = ecbuf + ECRDOFF + 772 sizeof (struct ether_header) + off; 773 } else 774 len = totlen; 775 if (ifp) 776 len += sizeof(ifp); 777 if (len >= NBPG) { 778 MCLGET(m); 779 if (m->m_len == CLBYTES) 780 m->m_len = len = MIN(len, CLBYTES); 781 else 782 m->m_len = len = MIN(MLEN, len); 783 } else { 784 m->m_len = len = MIN(MLEN, len); 785 m->m_off = MMINOFF; 786 } 787 mcp = mtod(m, u_char *); 788 if (ifp) { 789 /* 790 * Prepend interface pointer to first mbuf. 791 */ 792 *(mtod(m, struct ifnet **)) = ifp; 793 mcp += sizeof(ifp); 794 len -= sizeof(ifp); 795 ifp = (struct ifnet *)0; 796 } 797 if (words = (len >> 1)) { 798 register u_short *to, *from; 799 800 to = (u_short *)mcp; 801 from = (u_short *)cp; 802 do 803 *to++ = *from++; 804 while (--words > 0); 805 mcp = (u_char *)to; 806 cp = (u_char *)from; 807 } 808 if (len & 01) 809 *mcp++ = *cp++; 810 *mp = m; 811 mp = &m->m_next; 812 if (off == 0) { 813 totlen -= len; 814 continue; 815 } 816 off += len; 817 if (off == totlen) { 818 cp = ecbuf + ECRDOFF + sizeof (struct ether_header); 819 off = 0; 820 totlen = off0; 821 } 822 } 823 return (top); 824 bad: 825 m_freem(top); 826 return (0); 827 } 828 829 /* 830 * Process an ioctl request. 831 */ 832 ecioctl(ifp, cmd, data) 833 register struct ifnet *ifp; 834 int cmd; 835 caddr_t data; 836 { 837 register struct ifaddr *ifa = (struct ifaddr *)data; 838 struct ec_softc *es = &ec_softc[ifp->if_unit]; 839 struct ecdevice *addr; 840 int s = splimp(), error = 0; 841 842 addr = (struct ecdevice *)(ecinfo[ifp->if_unit]->ui_addr); 843 844 switch (cmd) { 845 846 case SIOCSIFADDR: 847 ifp->if_flags |= IFF_UP; 848 849 switch (ifa->ifa_addr.sa_family) { 850 #ifdef INET 851 case AF_INET: 852 ecinit(ifp->if_unit); /* before arpwhohas */ 853 ((struct arpcom *)ifp)->ac_ipaddr = 854 IA_SIN(ifa)->sin_addr; 855 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 856 break; 857 #endif 858 #ifdef NS 859 case AF_NS: 860 { 861 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 862 863 if (ns_nullhost(*ina)) 864 ina->x_host = *(union ns_host *)(es->es_addr); 865 else { 866 /* 867 * The manual says we can't change the address 868 * while the receiver is armed, 869 * so reset everything 870 */ 871 ifp->if_flags &= ~IFF_RUNNING; 872 bcopy((caddr_t)ina->x_host.c_host, 873 (caddr_t)es->es_addr, sizeof(es->es_addr)); 874 } 875 ecinit(ifp->if_unit); /* does ec_setaddr() */ 876 break; 877 } 878 #endif 879 default: 880 ecinit(ifp->if_unit); 881 break; 882 } 883 break; 884 885 case SIOCSIFFLAGS: 886 if ((ifp->if_flags & IFF_UP) == 0 && 887 ifp->if_flags & IFF_RUNNING) { 888 addr->ec_xcr = EC_UECLR; 889 ifp->if_flags &= ~IFF_RUNNING; 890 } else if (ifp->if_flags & IFF_UP && 891 (ifp->if_flags & IFF_RUNNING) == 0) 892 ecinit(ifp->if_unit); 893 break; 894 895 default: 896 error = EINVAL; 897 } 898 splx(s); 899 return (error); 900 } 901 902 ec_setaddr(physaddr,unit) 903 u_char *physaddr; 904 int unit; 905 { 906 struct ec_softc *es = &ec_softc[unit]; 907 struct uba_device *ui = ecinfo[unit]; 908 register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr; 909 register char nibble; 910 register int i, j; 911 912 /* 913 * Use the ethernet address supplied 914 * Note that we do a UECLR here, so the receive buffers 915 * must be requeued. 916 */ 917 918 #ifdef DEBUG 919 printf("ec_setaddr: setting address for unit %d = %s", 920 unit, ether_sprintf(physaddr)); 921 #endif 922 addr->ec_xcr = EC_UECLR; 923 addr->ec_rcr = 0; 924 /* load requested address */ 925 for (i = 0; i < 6; i++) { /* 6 bytes of address */ 926 es->es_addr[i] = physaddr[i]; 927 nibble = physaddr[i] & 0xf; /* lower nibble */ 928 addr->ec_rcr = (nibble << 8); 929 addr->ec_rcr = (nibble << 8) + EC_AWCLK; /* latch nibble */ 930 addr->ec_rcr = (nibble << 8); 931 for (j=0; j < 4; j++) { 932 addr->ec_rcr = 0; 933 addr->ec_rcr = EC_ASTEP; /* step counter */ 934 addr->ec_rcr = 0; 935 } 936 nibble = (physaddr[i] >> 4) & 0xf; /* upper nibble */ 937 addr->ec_rcr = (nibble << 8); 938 addr->ec_rcr = (nibble << 8) + EC_AWCLK; /* latch nibble */ 939 addr->ec_rcr = (nibble << 8); 940 for (j=0; j < 4; j++) { 941 addr->ec_rcr = 0; 942 addr->ec_rcr = EC_ASTEP; /* step counter */ 943 addr->ec_rcr = 0; 944 } 945 } 946 #ifdef DEBUG 947 /* 948 * Read the ethernet address off the board, one nibble at a time. 949 */ 950 addr->ec_xcr = EC_UECLR; 951 addr->ec_rcr = 0; /* read RAM */ 952 cp = es->es_addr; 953 #undef NEXTBIT 954 #define NEXTBIT addr->ec_rcr = EC_ASTEP; addr->ec_rcr = 0 955 for (i=0; i < sizeof (es->es_addr); i++) { 956 *cp = 0; 957 for (j=0; j<=4; j+=4) { 958 *cp |= ((addr->ec_rcr >> 8) & 0xf) << j; 959 NEXTBIT; NEXTBIT; NEXTBIT; NEXTBIT; 960 } 961 cp++; 962 } 963 printf("ec_setaddr: RAM address for unit %d = %s", 964 unit, ether_sprintf(physaddr)); 965 #endif 966 } 967 #endif 968