1 /* if_ec.c 4.18 82/06/17 */ 2 3 #include "ec.h" 4 5 /* 6 * 3Com Ethernet Controller interface 7 */ 8 9 #include "../h/param.h" 10 #include "../h/systm.h" 11 #include "../h/mbuf.h" 12 #include "../h/pte.h" 13 #include "../h/buf.h" 14 #include "../h/protosw.h" 15 #include "../h/socket.h" 16 #include "../h/ubareg.h" 17 #include "../h/ubavar.h" 18 #include "../h/ecreg.h" 19 #include "../h/cpu.h" 20 #include "../h/mtpr.h" 21 #include "../h/vmmac.h" 22 #include "../net/in.h" 23 #include "../net/in_systm.h" 24 #include "../net/if.h" 25 #include "../net/if_ec.h" 26 #include "../net/if_uba.h" 27 #include "../net/ip.h" 28 #include "../net/ip_var.h" 29 #include "../net/pup.h" 30 #include "../net/route.h" 31 #include <errno.h> 32 33 #define ECMTU 1500 34 35 int ecprobe(), ecattach(), ecrint(), ecxint(), eccollide(); 36 struct uba_device *ecinfo[NEC]; 37 u_short ecstd[] = { 0 }; 38 struct uba_driver ecdriver = 39 { ecprobe, 0, ecattach, 0, ecstd, "ec", ecinfo }; 40 u_char ec_iltop[3] = { 0x02, 0x07, 0x01 }; 41 #define ECUNIT(x) minor(x) 42 43 int ecinit(),ecoutput(),ecreset(); 44 struct mbuf *ecget(); 45 46 extern struct ifnet loif; 47 48 /* 49 * Ethernet software status per interface. 50 * 51 * Each interface is referenced by a network interface structure, 52 * es_if, which the routing code uses to locate the interface. 53 * This structure contains the output queue for the interface, its address, ... 54 * We also have, for each interface, a UBA interface structure, which 55 * contains information about the UNIBUS resources held by the interface: 56 * map registers, buffered data paths, etc. Information is cached in this 57 * structure for use by the if_uba.c routines in running the interface 58 * efficiently. 59 */ 60 struct ec_softc { 61 struct ifnet es_if; /* network-visible interface */ 62 struct ifuba es_ifuba; /* UNIBUS resources */ 63 short es_mask; /* mask for current output delay */ 64 short es_oactive; /* is output active? */ 65 caddr_t es_buf[16]; /* virtual addresses of buffers */ 66 u_char es_enaddr[6]; /* board's ethernet address */ 67 } ec_softc[NEC]; 68 69 /* 70 * Do output DMA to determine interface presence and 71 * interrupt vector. DMA is too short to disturb other hosts. 72 */ 73 ecprobe(reg) 74 caddr_t reg; 75 { 76 register int br, cvec; /* r11, r10 value-result */ 77 register struct ecdevice *addr = (struct ecdevice *)reg; 78 register caddr_t ecbuf = (caddr_t) &umem[0][0600000]; 79 80 COUNT(ECPROBE); 81 #ifdef lint 82 br = 0; cvec = br; br = cvec; 83 ecrint(0); ecxint(0); eccollide(0); 84 #endif 85 /* 86 * Make sure memory is turned on 87 */ 88 addr->ec_rcr = EC_AROM; 89 /* 90 * Check for existence of buffers on Unibus. 91 * This won't work on a 780 until more work is done. 92 */ 93 if (badaddr((caddr_t) ecbuf, 2)) { 94 printf("ec: buffer mem not found"); 95 return (0); 96 } 97 98 /* 99 * Tell the system that the board has memory here, so it won't 100 * attempt to allocate the addresses later. 101 */ 102 ubamem(0, 0600000, 32*2); 103 104 /* 105 * Make a one byte packet in what should be buffer #0. 106 * Submit it for sending. This whould cause an xmit interrupt. 107 * The xmit interrupt vector is 8 bytes after the receive vector, 108 * so adjust for this before returning. 109 */ 110 *(u_short *)ecbuf = (u_short) 03777; 111 ecbuf[03777] = '\0'; 112 addr->ec_xcr = EC_XINTEN|EC_XWBN; 113 DELAY(100000); 114 addr->ec_xcr = EC_XCLR; 115 if (cvec > 0 && cvec != 0x200) { 116 cvec -= 010; 117 br += 2; /* rcv is xmit + 2 */ 118 } 119 return (1); 120 } 121 122 /* 123 * Interface exists: make available by filling in network interface 124 * record. System will initialize the interface when it is ready 125 * to accept packets. 126 */ 127 ecattach(ui) 128 struct uba_device *ui; 129 { 130 struct ec_softc *es = &ec_softc[ui->ui_unit]; 131 register struct ifnet *ifp = &es->es_if; 132 register struct ecdevice *addr = (struct ecdevice *)ui->ui_addr; 133 struct sockaddr_in *sin; 134 int i, j; 135 u_char *cp; 136 COUNT(ECATTACH); 137 138 ifp->if_unit = ui->ui_unit; 139 ifp->if_name = "ec"; 140 ifp->if_mtu = ECMTU; 141 ifp->if_net = ui->ui_flags; 142 143 /* 144 * Read the ethernet address off the board, one nibble at a time. 145 */ 146 addr->ec_xcr = EC_UECLR; 147 addr->ec_rcr = EC_AROM; 148 cp = es->es_enaddr; 149 #define NEXTBIT addr->ec_rcr = EC_AROM|EC_ASTEP; addr->ec_rcr = EC_AROM 150 for (i=0; i<6; i++) { 151 *cp = 0; 152 for (j=0; j<=4; j+=4) { 153 *cp |= ((addr->ec_rcr >> 8) & 0xf) << j; 154 NEXTBIT; NEXTBIT; NEXTBIT; NEXTBIT; 155 } 156 cp++; 157 } 158 #ifdef notdef 159 printf("ec%d: addr=%x:%x:%x:%x:%x:%x\n", ui->ui_unit, 160 es->es_enaddr[0]&0xff, es->es_enaddr[1]&0xff, 161 es->es_enaddr[2]&0xff, es->es_enaddr[3]&0xff, 162 es->es_enaddr[4]&0xff, es->es_enaddr[5]&0xff); 163 #endif 164 ifp->if_host[0] = ((es->es_enaddr[3]&0xff)<<16) | 165 ((es->es_enaddr[4]&0xff)<<8) | (es->es_enaddr[5]&0xff); 166 sin = (struct sockaddr_in *)&es->es_if.if_addr; 167 sin->sin_family = AF_INET; 168 sin->sin_addr = if_makeaddr(ifp->if_net, ifp->if_host[0]); 169 170 sin = (struct sockaddr_in *)&ifp->if_broadaddr; 171 sin->sin_family = AF_INET; 172 sin->sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); 173 ifp->if_flags = IFF_BROADCAST; 174 175 ifp->if_init = ecinit; 176 ifp->if_output = ecoutput; 177 ifp->if_ubareset = ecreset; 178 for (i=0; i<16; i++) 179 es->es_buf[i] = &umem[ui->ui_ubanum][0600000+2048*i]; 180 if_attach(ifp); 181 } 182 183 /* 184 * Reset of interface after UNIBUS reset. 185 * If interface is on specified uba, reset its state. 186 */ 187 ecreset(unit, uban) 188 int unit, uban; 189 { 190 register struct uba_device *ui; 191 COUNT(ECRESET); 192 193 if (unit >= NEC || (ui = ecinfo[unit]) == 0 || ui->ui_alive == 0 || 194 ui->ui_ubanum != uban) 195 return; 196 printf(" ec%d", unit); 197 ecinit(unit); 198 } 199 200 /* 201 * Initialization of interface; clear recorded pending 202 * operations, and reinitialize UNIBUS usage. 203 */ 204 ecinit(unit) 205 int unit; 206 { 207 struct ec_softc *es = &ec_softc[unit]; 208 struct ecdevice *addr; 209 int i, s; 210 211 /* 212 * Hang receive buffers and start any pending writes. 213 * Writing into the rcr also makes sure the memory 214 * is turned on. 215 */ 216 addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 217 s = splimp(); 218 for (i=ECRHBF; i>=ECRLBF; i--) 219 addr->ec_rcr = EC_READ|i; 220 es->es_oactive = 0; 221 es->es_mask = ~0; 222 es->es_if.if_flags |= IFF_UP; 223 if (es->es_if.if_snd.ifq_head) 224 ecstart(unit); 225 splx(s); 226 if_rtinit(&es->es_if, RTF_UP); 227 } 228 229 /* 230 * Start or restart output on interface. 231 * If interface is already active, then this is a retransmit 232 * after a collision, and just restuff registers. 233 * If interface is not already active, get another datagram 234 * to send off of the interface queue, and map it to the interface 235 * before starting the output. 236 */ 237 ecstart(dev) 238 dev_t dev; 239 { 240 int unit = ECUNIT(dev), dest; 241 struct ec_softc *es = &ec_softc[unit]; 242 struct ecdevice *addr; 243 struct mbuf *m; 244 caddr_t ecbuf; 245 COUNT(ECSTART); 246 247 if (es->es_oactive) 248 goto restart; 249 250 IF_DEQUEUE(&es->es_if.if_snd, m); 251 if (m == 0) { 252 es->es_oactive = 0; 253 return; 254 } 255 ecput(es->es_buf[ECTBF], m); 256 257 restart: 258 addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 259 addr->ec_xcr = EC_WRITE|ECTBF; 260 es->es_oactive = 1; 261 } 262 263 /* 264 * Ethernet interface transmitter interrupt. 265 * Start another output if more data to send. 266 */ 267 ecxint(unit) 268 int unit; 269 { 270 register struct ec_softc *es = &ec_softc[unit]; 271 register struct ecdevice *addr = 272 (struct ecdevice *)ecinfo[unit]->ui_addr; 273 COUNT(ECXINT); 274 275 if (es->es_oactive == 0) 276 return; 277 if ((addr->ec_xcr&EC_XDONE) == 0 || (addr->ec_xcr&EC_XBN) != ECTBF) { 278 printf("ec%d: stray xmit interrupt, xcr=%b\n", unit, 279 addr->ec_xcr, EC_XBITS); 280 es->es_oactive = 0; 281 addr->ec_xcr = EC_XCLR; 282 return; 283 } 284 es->es_if.if_opackets++; 285 es->es_oactive = 0; 286 es->es_mask = ~0; 287 addr->ec_xcr = EC_XCLR; 288 /* 289 * There shouldn't ever be any mbuf's to free, but just in case... 290 */ 291 if (es->es_ifuba.ifu_xtofree) { 292 m_freem(es->es_ifuba.ifu_xtofree); 293 es->es_ifuba.ifu_xtofree = 0; 294 } 295 if (es->es_if.if_snd.ifq_head) 296 ecstart(unit); 297 } 298 299 /* 300 * Collision on ethernet interface. Do exponential 301 * backoff, and retransmit. If have backed off all 302 * the way print warning diagnostic, and drop packet. 303 */ 304 eccollide(unit) 305 int unit; 306 { 307 struct ec_softc *es = &ec_softc[unit]; 308 COUNT(ECCOLLIDE); 309 310 printf("ec%d: collision\n", unit); 311 es->es_if.if_collisions++; 312 if (es->es_oactive) 313 ecdocoll(unit); 314 } 315 316 ecdocoll(unit) 317 int unit; 318 { 319 register struct ec_softc *es = &ec_softc[unit]; 320 register struct ecdevice *addr = 321 (struct ecdevice *)ecinfo[unit]->ui_addr; 322 register i; 323 int delay; 324 325 /* 326 * Es_mask is a 16 bit number with n low zero bits, with 327 * n the number of backoffs. When es_mask is 0 we have 328 * backed off 16 times, and give up. 329 */ 330 if (es->es_mask == 0) { 331 es->es_if.if_oerrors++; 332 printf("ec%d: send error\n", unit); 333 /* 334 * Reset interface, then requeue rcv buffers. 335 * Some incoming packets may be lost, but that 336 * can't be helped. 337 */ 338 addr->ec_xcr = EC_UECLR; 339 for (i=ECRHBF; i>=ECRLBF; i--) 340 addr->ec_rcr = EC_READ|i; 341 /* 342 * Reset and transmit next packet (if any). 343 */ 344 es->es_oactive = 0; 345 es->es_mask = ~0; 346 if (es->es_if.if_snd.ifq_head) 347 ecstart(unit); 348 return; 349 } 350 /* 351 * Do exponential backoff. Compute delay based on low bits 352 * of the interval timer. Then delay for that number of 353 * slot times. A slot time is 51.2 microseconds (rounded to 51). 354 * This does not take into account the time already used to 355 * process the interrupt. 356 */ 357 es->es_mask <<= 1; 358 delay = mfpr(ICR) &~ es->es_mask; 359 DELAY(delay * 51); 360 /* 361 * Clear the controller's collision flag, thus enabling retransmit. 362 */ 363 addr->ec_xcr = EC_JINTEN|EC_XINTEN|EC_JCLR; 364 } 365 366 /* 367 * Ethernet interface receiver interrupt. 368 * If input error just drop packet. 369 * Otherwise purge input buffered data path and examine 370 * packet to determine type. If can't determine length 371 * from type, then have to drop packet. Othewise decapsulate 372 * packet based on type and pass to type specific higher-level 373 * input routine. 374 */ 375 ecrint(unit) 376 int unit; 377 { 378 struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 379 COUNT(ECRINT); 380 381 while (addr->ec_rcr & EC_RDONE) 382 ecread(unit); 383 } 384 385 ecread(unit) 386 int unit; 387 { 388 register struct ec_softc *es = &ec_softc[unit]; 389 struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr; 390 register struct ec_header *ec; 391 struct mbuf *m; 392 int len, off, resid, ecoff, buf; 393 register struct ifqueue *inq; 394 caddr_t ecbuf; 395 COUNT(ECREAD); 396 397 es->es_if.if_ipackets++; 398 buf = addr->ec_rcr & EC_RBN; 399 if (buf < ECRLBF || buf > ECRHBF) 400 panic("ecrint"); 401 ecbuf = es->es_buf[buf]; 402 ecoff = *(short *)ecbuf; 403 if (ecoff <= ECRDOFF || ecoff > 2046) { 404 es->es_if.if_ierrors++; 405 #ifdef notdef 406 if (es->es_if.if_ierrors % 100 == 0) 407 printf("ec%d: += 100 input errors\n", unit); 408 #endif 409 printf("ec%d: input error (offset=%d)\n", unit, ecoff); 410 goto setup; 411 } 412 413 /* 414 * Get input data length. 415 * Get pointer to ethernet header (in input buffer). 416 * Deal with trailer protocol: if type is PUP trailer 417 * get true type from first 16-bit word past data. 418 * Remember that type was trailer by setting off. 419 */ 420 len = ecoff - ECRDOFF - sizeof (struct ec_header); 421 ec = (struct ec_header *)(ecbuf + ECRDOFF); 422 #define ecdataaddr(ec, off, type) ((type)(((caddr_t)((ec)+1)+(off)))) 423 if (ec->ec_type >= ECPUP_TRAIL && 424 ec->ec_type < ECPUP_TRAIL+ECPUP_NTRAILER) { 425 off = (ec->ec_type - ECPUP_TRAIL) * 512; 426 if (off >= ECMTU) 427 goto setup; /* sanity */ 428 ec->ec_type = *ecdataaddr(ec, off, u_short *); 429 resid = *(ecdataaddr(ec, off+2, u_short *)); 430 if (off + resid > len) 431 goto setup; /* sanity */ 432 len = off + resid; 433 } else 434 off = 0; 435 if (len == 0) 436 goto setup; 437 438 /* 439 * Pull packet off interface. Off is nonzero if packet 440 * has trailing header; ecget will then force this header 441 * information to be at the front, but we still have to drop 442 * the type and length which are at the front of any trailer data. 443 */ 444 m = ecget(ecbuf, len, off); 445 if (m == 0) 446 goto setup; 447 if (off) { 448 m->m_off += 2 * sizeof (u_short); 449 m->m_len -= 2 * sizeof (u_short); 450 } 451 switch (ec->ec_type) { 452 453 #ifdef INET 454 case ECPUP_IPTYPE: 455 schednetisr(NETISR_IP); 456 inq = &ipintrq; 457 break; 458 #endif 459 default: 460 m_freem(m); 461 goto setup; 462 } 463 464 if (IF_QFULL(inq)) { 465 IF_DROP(inq); 466 m_freem(m); 467 goto setup; 468 } 469 IF_ENQUEUE(inq, m); 470 471 setup: 472 /* 473 * Reset for next packet. 474 */ 475 addr->ec_rcr = EC_READ|EC_RCLR|buf; 476 } 477 478 /* 479 * Ethernet output routine. 480 * Encapsulate a packet of type family for the local net. 481 * Use trailer local net encapsulation if enough data in first 482 * packet leaves a multiple of 512 bytes of data in remainder. 483 * If destination is this address or broadcast, send packet to 484 * loop device to kludge around the fact that 3com interfaces can't 485 * talk to themselves. 486 */ 487 ecoutput(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 ec_softc *es = &ec_softc[ifp->if_unit]; 494 register struct mbuf *m = m0; 495 register struct ec_header *ec; 496 register int off, i; 497 struct mbuf *mcopy = (struct mbuf *) 0; /* Null */ 498 499 COUNT(ECOUTPUT); 500 switch (dst->sa_family) { 501 502 #ifdef INET 503 case AF_INET: 504 dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr; 505 if ((dest &~ 0xff) == 0) 506 mcopy = m_copy(m, 0, M_COPYALL); 507 else if (dest == ((struct sockaddr_in *)&es->es_if.if_addr)-> 508 sin_addr.s_addr) { 509 mcopy = m; 510 goto gotlocal; 511 } 512 off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; 513 if (off > 0 && (off & 0x1ff) == 0 && 514 m->m_off >= MMINOFF + 2 * sizeof (u_short)) { 515 type = ECPUP_TRAIL + (off>>9); 516 m->m_off -= 2 * sizeof (u_short); 517 m->m_len += 2 * sizeof (u_short); 518 *mtod(m, u_short *) = ECPUP_IPTYPE; 519 *(mtod(m, u_short *) + 1) = m->m_len; 520 goto gottrailertype; 521 } 522 type = ECPUP_IPTYPE; 523 off = 0; 524 goto gottype; 525 #endif 526 527 default: 528 printf("ec%d: can't handle af%d\n", ifp->if_unit, 529 dst->sa_family); 530 error = EAFNOSUPPORT; 531 goto bad; 532 } 533 534 gottrailertype: 535 /* 536 * Packet to be sent as trailer: move first packet 537 * (control information) to end of chain. 538 */ 539 while (m->m_next) 540 m = m->m_next; 541 m->m_next = m0; 542 m = m0->m_next; 543 m0->m_next = 0; 544 m0 = m; 545 546 gottype: 547 /* 548 * Add local net header. If no space in first mbuf, 549 * allocate another. 550 */ 551 if (m->m_off > MMAXOFF || 552 MMINOFF + sizeof (struct ec_header) > m->m_off) { 553 m = m_get(M_DONTWAIT); 554 if (m == 0) { 555 error = ENOBUFS; 556 goto bad; 557 } 558 m->m_next = m0; 559 m->m_off = MMINOFF; 560 m->m_len = sizeof (struct ec_header); 561 } else { 562 m->m_off -= sizeof (struct ec_header); 563 m->m_len += sizeof (struct ec_header); 564 } 565 ec = mtod(m, struct ec_header *); 566 for (i=0; i<6; i++) 567 ec->ec_shost[i] = es->es_enaddr[i]; 568 if ((dest &~ 0xff) == 0) 569 /* broadcast address */ 570 for (i=0; i<6; i++) 571 ec->ec_dhost[i] = 0xff; 572 else { 573 if (dest & 0x8000) { 574 ec->ec_dhost[0] = ec_iltop[0]; 575 ec->ec_dhost[1] = ec_iltop[1]; 576 ec->ec_dhost[2] = ec_iltop[2]; 577 } else { 578 ec->ec_dhost[0] = es->es_enaddr[0]; 579 ec->ec_dhost[1] = es->es_enaddr[1]; 580 ec->ec_dhost[2] = es->es_enaddr[2]; 581 } 582 ec->ec_dhost[3] = (dest>>8) & 0x7f; 583 ec->ec_dhost[4] = (dest>>16) & 0xff; 584 ec->ec_dhost[5] = (dest>>24) & 0xff; 585 } 586 ec->ec_type = type; 587 588 /* 589 * Queue message on interface, and start output if interface 590 * not yet active. 591 */ 592 s = splimp(); 593 if (IF_QFULL(&ifp->if_snd)) { 594 IF_DROP(&ifp->if_snd); 595 error = ENOBUFS; 596 goto qfull; 597 } 598 IF_ENQUEUE(&ifp->if_snd, m); 599 if (es->es_oactive == 0) 600 ecstart(ifp->if_unit); 601 splx(s); 602 603 gotlocal: 604 return(mcopy ? looutput(&loif, mcopy, dst) : 0); 605 606 qfull: 607 m0 = m; 608 splx(s); 609 bad: 610 m_freem(m0); 611 return(error); 612 } 613 614 /* 615 * Routine to copy from mbuf chain to transmitter 616 * buffer in UNIBUS memory. 617 */ 618 ecput(ecbuf, m) 619 u_char *ecbuf; 620 struct mbuf *m; 621 { 622 register struct mbuf *mp; 623 register u_char *bp; 624 register int off; 625 626 COUNT(ECPUT); 627 for (off = 2048, mp = m; mp; mp = mp->m_next) 628 off -= mp->m_len; 629 *(u_short *)ecbuf = off; 630 bp = (u_char *)(ecbuf + off); 631 for (mp = m; mp; mp = m_free(mp)) { 632 register unsigned len; 633 register u_char *mcp; 634 635 len = mp->m_len; 636 if (len == 0) 637 continue; 638 mcp = mtod(mp, u_char *); 639 if ((unsigned)bp & 01) { 640 *bp++ = *mcp++; 641 len--; 642 } 643 for (; len > 1; len -= sizeof (u_short)) { 644 *(u_short *)bp = *(u_short *)mcp; 645 bp += sizeof (u_short); 646 mcp += sizeof (u_short); 647 } 648 if (len) 649 *bp++ = *mcp++; 650 } 651 #ifdef notdef 652 if (bp - ecbuf != 2048) 653 printf("ec: bad ecput, diff=%d\n", bp-ecbuf); 654 #endif 655 } 656 657 /* 658 * Routine to copy from UNIBUS memory into mbufs. 659 * Similar in spirit to if_rubaget. 660 * 661 * Warning: This makes the fairly safe assumption that 662 * mbufs have even lengths. 663 */ 664 struct mbuf * 665 ecget(ecbuf, totlen, off0) 666 char *ecbuf; 667 int totlen, off0; 668 { 669 struct mbuf *top, **mp, *m; 670 int off = off0, len; 671 register char *cp, *mcp; 672 register int i; 673 674 COUNT(ECGET); 675 top = 0; 676 mp = ⊤ 677 cp = ecbuf + ECRDOFF + sizeof (struct ec_header); 678 while (totlen > 0) { 679 MGET(m, 0); 680 if (m == 0) 681 goto bad; 682 if (off) { 683 len = totlen - off; 684 cp = ecbuf + ECRDOFF + sizeof (struct ec_header) + off; 685 } else 686 len = totlen; 687 if (len >= CLBYTES) { 688 struct mbuf *p; 689 690 MCLGET(p, 1); 691 if (p != 0) { 692 m->m_len = len = CLBYTES; 693 m->m_off = (int)p - (int)m; 694 } else { 695 m->m_len = len = MIN(MLEN, len); 696 m->m_off = MMINOFF; 697 } 698 } else { 699 m->m_len = len = MIN(MLEN, len); 700 m->m_off = MMINOFF; 701 } 702 mcp = mtod(m, char *); 703 for (i = 0; i < len; i += sizeof (short)) { 704 *(short *)mcp = *(short *)cp; 705 mcp += sizeof (short); 706 cp += sizeof (short); 707 } 708 if (len & 01) 709 *mcp++ = *cp++; 710 *mp = m; 711 mp = &m->m_next; 712 if (off) { 713 off += len; 714 if (off == totlen) { 715 cp = ecbuf + ECRDOFF + 716 sizeof (struct ec_header); 717 off = 0; 718 totlen = off0; 719 } 720 } else 721 totlen -= len; 722 } 723 return (top); 724 bad: 725 m_freem(top); 726 return (0); 727 } 728