if_ae.c revision 1.19 1 /* $NetBSD: if_ae.c,v 1.19 1995/04/08 13:17:55 briggs Exp $ */
2
3 /*
4 * Device driver for National Semiconductor DS8390 based ethernet adapters.
5 *
6 * Based on original ISA bus driver by David Greenman, 29-April-1993
7 *
8 * Copyright (C) 1993, David Greenman. This software may be used, modified,
9 * copied, distributed, and sold, in both source and binary form provided
10 * that the above copyright and these terms are retained. Under no
11 * circumstances is the author responsible for the proper functioning
12 * of this software, nor does the author assume any responsibility
13 * for damages incurred with its use.
14 *
15 * Adapted for MacBSD by Brad Parker <brad (at) fcr.com>
16 *
17 * Currently supports:
18 * Apples NB Ethernet card
19 * Interlan A310 Nubus Ethernet card
20 * Cayman Systems GatorCard
21 * Asante MacCon II/E
22 */
23
24 /*
25 * $Id: if_ae.c,v 1.19 1995/04/08 13:17:55 briggs Exp $
26 */
27
28 #include "ae.h"
29 /* bpfilter included here in case it is needed in future net includes */
30 #include "bpfilter.h"
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/errno.h>
35 #include <sys/ioctl.h>
36 #include <sys/mbuf.h>
37 #include <sys/socket.h>
38 #include <sys/syslog.h>
39
40 #include <net/if.h>
41 #include <net/if_dl.h>
42 #include <net/if_types.h>
43 #include <net/netisr.h>
44
45 #ifdef INET
46 #include <netinet/in.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/in_var.h>
49 #include <netinet/ip.h>
50 #include <netinet/if_ether.h>
51 #endif
52
53 #ifdef NS
54 #include <netns/ns.h>
55 #include <netns/ns_if.h>
56 #endif
57
58 #if NBPFILTER > 0
59 #include <net/bpf.h>
60 #include <net/bpfdesc.h>
61 #endif
62
63 #include <sys/device.h>
64 #include "../mac68k/via.h"
65 #include "nubus.h"
66 #include "if_aereg.h"
67
68 struct ae_device {
69 struct device ae_dev;
70 /* struct nubusdev ae_nu;
71 struct intrhand ae_ih; */
72 };
73
74 /*
75 * ae_softc: per line info and status
76 */
77 struct ae_softc {
78 struct ae_device *sc_ae;
79
80 struct arpcom arpcom; /* ethernet common */
81
82 char *type_str; /* pointer to type string */
83 u_char vendor; /* interface vendor */
84 u_char type; /* interface type code */
85 u_char regs_rev; /* registers are reversed */
86
87 #define REG_MAP(sc, reg) ((sc)->regs_rev ? (0x0f-(reg))<<2 : (reg)<<2)
88 #define NIC_GET(sc, reg) ((sc)->nic_addr[REG_MAP(sc, reg)])
89 #define NIC_PUT(sc, reg, val) ((sc)->nic_addr[REG_MAP(sc, reg)] = (val))
90 volatile caddr_t nic_addr; /* NIC (DS8390) I/O bus address */
91 caddr_t rom_addr; /* on board prom address */
92 caddr_t smem_start; /* shared memory start address */
93 caddr_t smem_end; /* shared memory end address */
94 u_long smem_size; /* total shared memory size */
95 u_char smem_wr_short; /* card memory requires int16 writes */
96 caddr_t smem_ring; /* start of RX ring-buffer (in smem) */
97
98 caddr_t bpf; /* BPF "magic cookie" */
99
100 u_char xmit_busy; /* transmitter is busy */
101 u_char txb_cnt; /* Number of transmit buffers */
102 u_char txb_next; /* Pointer to next buffer ready to xmit */
103 u_short txb_next_len; /* next xmit buffer length */
104 u_char data_buffered; /* data has been buffered in interface mem */
105 u_char tx_page_start; /* first page of TX buffer area */
106
107 u_char rec_page_start; /* first page of RX ring-buffer */
108 u_char rec_page_stop; /* last page of RX ring-buffer */
109 u_char next_packet; /* pointer to next unread RX packet */
110 } ae_softc[NAE];
111
112 void ae_find(), ae_attach();
113 int ae_init(), ae_ioctl(), ae_probe(),
114 ae_start(), ae_reset(), ae_watchdog(), aeintr();
115
116 struct cfdriver aecd =
117 { NULL, "ae", ae_probe, ae_attach, DV_IFNET, sizeof(struct ae_device), NULL, 0 };
118
119 static void ae_stop();
120 static inline void ae_rint();
121 static inline void ae_xmit();
122 static inline char *ae_ring_copy();
123
124 extern int ether_output();
125
126 #define ETHER_MIN_LEN 64
127 #define ETHER_MAX_LEN 1518
128 #define ETHER_ADDR_LEN 6
129 #define ETHER_HDR_SIZE 14
130
131 char ae_name[] = "8390 Nubus Ethernet card";
132 static char zero = 0;
133 static u_char ones = 0xff;
134
135 struct vendor_S {
136 char *manu;
137 int len;
138 int vendor;
139 } vend[] = {
140 { "Apple", 5, AE_VENDOR_APPLE },
141 { "3Com", 4, AE_VENDOR_APPLE },
142 { "Dayna", 5, AE_VENDOR_DAYNA },
143 { "Inter", 5, AE_VENDOR_INTERLAN },
144 { "Asant", 5, AE_VENDOR_ASANTE },
145 };
146
147 static int numvend = sizeof(vend)/sizeof(vend[0]);
148
149 /*
150 * XXX These two should be moved to locore, and maybe changed to use shorts
151 * instead of bytes. The reason for these is that bcopy and bzero use longs,
152 * which the ethernet cards can't handle.
153 */
154
155 void
156 bszero (u_short *addr, int len)
157 {
158 while (len--) {
159 *addr++ = 0;
160 }
161 }
162
163 void
164 bbcopy (char *src, char *dest, int len)
165 {
166 while (len--) {
167 *dest++ = *src++;
168 }
169 }
170
171 /*
172 short copy; assume destination is always aligned
173 and last byte of odd length copy is not important
174 */
175
176 void
177 bscopy (char *src, char *dest, int len)
178 {
179 u_short *d = (u_short *)dest;
180 u_short *s = (u_short *)src;
181 char b1, b2;
182
183 /* odd case, src addr is unaligned */
184 if ( ((u_long)src) & 1 ) {
185 while (len > 0) {
186 b1 = *src++;
187 b2 = len > 1 ? *src++ : (*d & 0xff);
188 *d++ = (b1 << 8) | b2;
189 len -= 2;
190 }
191 return;
192 }
193
194 /* normal case, aligned src & dst */
195 while (len > 0) {
196 *d++ = *s++;
197 len -= 2;
198 }
199 }
200
201 void
202 ae_id_card(nu, sc)
203 struct nubus_hw *nu;
204 struct ae_softc *sc;
205 {
206 int i;
207
208 /*
209 * Try to determine what type of card this is...
210 */
211 sc->vendor = AE_VENDOR_UNKNOWN;
212 for (i=0 ; i<numvend ; i++) {
213 if (!strncmp(nu->Slot.manufacturer, vend[i].manu, vend[i].len))
214 {
215 sc->vendor = vend[i].vendor;
216 break;
217 }
218 }
219 sc->type_str = (char *) (nu->Slot.manufacturer);
220
221 }
222
223 int
224 ae_size_card_memory(sc)
225 struct ae_softc *sc;
226 {
227 u_short *p;
228 u_short i1, i2, i3, i4;
229 int size;
230
231 p = (u_short *)sc->smem_start;
232
233 /*
234 * very simple size memory, assuming it's installed in 8k
235 * banks; also assume it will generally mirror in upper banks
236 * if not installed.
237 */
238 i1 = (8192*0)/2;
239 i2 = (8192*1)/2;
240 i3 = (8192*2)/2;
241 i4 = (8192*3)/2;
242
243 p[i1] = 0x1111;
244 p[i2] = 0x2222;
245 p[i3] = 0x3333;
246 p[i4] = 0x4444;
247
248 size = 0;
249 if (p[i1] == 0x1111 && p[i2] == 0x2222 &&
250 p[i3] == 0x3333 && p[i4] == 0x4444)
251 size = 8192*4;
252 else
253 if ((p[i1] == 0x1111 && p[i2] == 0x2222) ||
254 (p[i1] == 0x3333 && p[i2] == 0x4444))
255 size = 8192*2;
256 else
257 if (p[i1] == 0x1111 || p[i1] == 0x4444)
258 size = 8192;
259
260 if (size == 0)
261 return 0;
262
263 return size;
264 }
265
266 int
267 ae_probe(parent, cf, aux)
268 struct cfdriver *parent;
269 struct cfdata *cf;
270 void *aux;
271 {
272 register struct nubus_hw *nu = (struct nubus_hw *) aux;
273 struct ae_softc *sc = &ae_softc[cf->cf_unit];
274 int i, memsize;
275 int flags = 0;
276
277 if (nu->Slot.type != NUBUS_NETWORK)
278 return 0;
279
280 ae_id_card(nu, sc);
281
282 sc->regs_rev = 0;
283 sc->smem_wr_short = 0;
284
285 switch (sc->vendor) {
286 case AE_VENDOR_INTERLAN:
287 sc->nic_addr = nu->addr + GC_NIC_OFFSET;
288 sc->rom_addr = nu->addr + GC_ROM_OFFSET;
289 sc->smem_start = nu->addr + GC_DATA_OFFSET;
290 if ((memsize = ae_size_card_memory(sc)) == 0)
291 return 0;
292
293 /* reset the NIC chip */
294 *((caddr_t)nu->addr + GC_RESET_OFFSET) = (char)zero;
295
296 /* Get station address from on-board ROM */
297 for (i = 0; i < ETHER_ADDR_LEN; ++i)
298 sc->arpcom.ac_enaddr[i] = *(sc->rom_addr + i*4);
299 break;
300
301 case AE_VENDOR_ASANTE:
302 /* memory writes require *(u_short *) */
303 sc->smem_wr_short = 1;
304 /* otherwise, pretend to be an apple card (fall through) */
305
306 case AE_VENDOR_APPLE:
307 sc->regs_rev = 1;
308 sc->nic_addr = nu->addr + AE_NIC_OFFSET;
309 sc->rom_addr = nu->addr + AE_ROM_OFFSET;
310 sc->smem_start = nu->addr + AE_DATA_OFFSET;
311 if ((memsize = ae_size_card_memory(sc)) == 0)
312 return 0;
313
314 /* Get station address from on-board ROM */
315 for (i = 0; i < ETHER_ADDR_LEN; ++i)
316 sc->arpcom.ac_enaddr[i] = *(sc->rom_addr + i*2);
317 break;
318
319 case AE_VENDOR_DAYNA:
320 printf("We think we are a Dayna card, but ");
321 sc->nic_addr = nu->addr + DP_NIC_OFFSET;
322 sc->rom_addr = nu->addr + DP_ROM_OFFSET;
323 sc->smem_start = nu->addr + DP_DATA_OFFSET;
324 memsize = 8192;
325
326 /* Get station address from on-board ROM */
327 for (i = 0; i < ETHER_ADDR_LEN; ++i)
328 sc->arpcom.ac_enaddr[i] = *(sc->rom_addr + i*2);
329 printf("it is dangerous to continue.\n");
330 return 0; /* Since we don't work yet... */
331 break;
332
333 default:
334 return 0;
335 break;
336 }
337
338 /*
339 * allocate one xmit buffer if < 16k, two buffers otherwise
340 */
341 if ((memsize < 16384) || (flags & AE_FLAGS_NO_DOUBLE_BUFFERING)) {
342 sc->smem_ring =
343 sc->smem_start + (AE_PAGE_SIZE * AE_TXBUF_SIZE);
344 sc->txb_cnt = 1;
345 sc->rec_page_start = AE_TXBUF_SIZE;
346 } else {
347 sc->smem_ring =
348 sc->smem_start + (AE_PAGE_SIZE * AE_TXBUF_SIZE * 2);
349 sc->txb_cnt = 2;
350 sc->rec_page_start = AE_TXBUF_SIZE * 2;
351 }
352
353 sc->smem_size = memsize;
354 sc->smem_end = sc->smem_start + memsize;
355 sc->rec_page_stop = memsize / AE_PAGE_SIZE;
356 sc->tx_page_start = 0;
357
358 /*
359 * Now zero memory and verify that it is clear
360 */
361 bszero((u_short *)sc->smem_start, memsize / 2);
362
363 for (i = 0; i < memsize; ++i)
364 if (sc->smem_start[i]) {
365 printf("ae: failed to clear shared memory at %x\n",
366 sc->smem_start + i);
367
368 return(0);
369 }
370
371 #ifdef DEBUG_PRINT
372 printf("nic_addr %x, rom_addr %x\n",
373 sc->nic_addr, sc->rom_addr);
374 printf("smem_size %d\n", sc->smem_size);
375 printf("smem_start %x, smem_ring %x, smem_end %x\n",
376 sc->smem_start, sc->smem_ring, sc->smem_end);
377 printf("phys address %02x:%02x:%02x:%02x:%02x:%02x\n",
378 sc->arpcom.ac_enaddr[0],
379 sc->arpcom.ac_enaddr[1],
380 sc->arpcom.ac_enaddr[2],
381 sc->arpcom.ac_enaddr[3],
382 sc->arpcom.ac_enaddr[4],
383 sc->arpcom.ac_enaddr[5]);
384 #endif
385
386 return(1);
387 }
388
389 /*
390 * Install interface into kernel networking data structures
391 */
392 void
393 ae_attach(parent, self, aux)
394 struct cfdriver *parent, *self;
395 void *aux;
396 {
397 struct nubus_hw *nu = aux;
398 struct ae_device *ae = (struct ae_device *) self;
399 struct ae_softc *sc = &ae_softc[ae->ae_dev.dv_unit];
400 struct cfdata *cf = ae->ae_dev.dv_cfdata;
401 struct ifnet *ifp = &sc->arpcom.ac_if;
402 struct ifaddr *ifa;
403 struct sockaddr_dl *sdl;
404
405 sc->sc_ae = ae;
406
407 /*
408 * Set interface to stopped condition (reset)
409 */
410 ae_stop(sc);
411
412 /*
413 * Initialize ifnet structure
414 */
415 ifp->if_unit = ae->ae_dev.dv_unit;
416 ifp->if_name = aecd.cd_name;
417 ifp->if_mtu = ETHERMTU;
418 ifp->if_output = ether_output;
419 ifp->if_start = ae_start;
420 ifp->if_ioctl = ae_ioctl;
421 ifp->if_reset = ae_reset;
422 ifp->if_watchdog = ae_watchdog;
423 ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);
424
425 #if 0
426 /*
427 * Set default state for ALTPHYS flag (used to disable the transceiver
428 * for AUI operation), based on compile-time config option.
429 */
430 if (cf->cf_flags & AE_FLAGS_DISABLE_TRANSCEIVER)
431 ifp->if_flags |= IFF_ALTPHYS;
432 #endif
433
434 /*
435 * Attach the interface
436 */
437 if_attach(ifp);
438
439 /*
440 * Search down the ifa address list looking for the AF_LINK type entry
441 */
442 ifa = ifp->if_addrlist;
443 while ((ifa != 0) && (ifa->ifa_addr != 0) &&
444 (ifa->ifa_addr->sa_family != AF_LINK))
445 ifa = ifa->ifa_next;
446 /*
447 * If we find an AF_LINK type entry we fill in the hardware address.
448 * This is useful for netstat(1) to keep track of which interface
449 * is which.
450 */
451 if ((ifa != 0) && (ifa->ifa_addr != 0)) {
452 /*
453 * Fill in the link-level address for this interface
454 */
455 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
456 sdl->sdl_type = IFT_ETHER;
457 sdl->sdl_alen = ETHER_ADDR_LEN;
458 sdl->sdl_slen = 0;
459 bbcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
460 }
461
462 /*
463 * Print additional info when attached
464 */
465 printf(": address %s, ", ether_sprintf(sc->arpcom.ac_enaddr));
466
467 if (sc->type_str && (*sc->type_str != 0))
468 printf("type %s", sc->type_str);
469 else
470 printf("type unknown (0x%x)", sc->type);
471
472 printf(", %dk mem", sc->smem_size / 1024);
473
474 printf("\n");
475
476 /*
477 * If BPF is in the kernel, call the attach for it
478 */
479 #if NBPFILTER > 0
480 bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
481 #endif
482 }
483
484 /*
485 * Reset interface.
486 */
487 int
488 ae_reset(sc)
489 struct ae_softc *sc;
490 {
491 int s;
492
493 s = splnet();
494
495 /*
496 * Stop interface and re-initialize.
497 */
498 ae_stop(sc);
499 ae_init(sc);
500
501 (void) splx(s);
502 }
503
504 /*
505 * Take interface offline.
506 */
507 void
508 ae_stop(sc)
509 struct ae_softc *sc;
510 {
511 int n = 5000;
512
513 /*
514 * Stop everything on the interface, and select page 0 registers.
515 */
516 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_STP);
517
518 /*
519 * Wait for interface to enter stopped state, but limit # of checks
520 * to 'n' (about 5ms). It shouldn't even take 5us on modern
521 * DS8390's, but just in case it's an old one.
522 */
523 while (((NIC_GET(sc, AE_P0_ISR) & AE_ISR_RST) == 0) && --n);
524 }
525
526 /*
527 * Device timeout/watchdog routine. Entered if the device neglects to
528 * generate an interrupt after a transmit has been started on it.
529 */
530 static int aeintr_ctr=0;
531 int
532 ae_watchdog(unit)
533 short unit;
534 {
535 struct ae_softc *sc = &ae_softc[unit];
536
537 #if 1
538 /*
539 * This is a kludge! The via code seems to miss slot interrupts
540 * sometimes. This kludges around that by calling the handler
541 * by hand if the watchdog is activated. -- XXX (akb)
542 */
543 int i;
544
545 i = aeintr_ctr;
546
547 (*via2itab[1])(1);
548
549 if (i != aeintr_ctr) {
550 log(LOG_ERR, "ae%d: device timeout, recovered\n", unit);
551 return;
552 }
553 #endif
554
555 log(LOG_ERR, "ae%d: device timeout\n", unit);
556 ae_reset(sc);
557 }
558
559 /*
560 * Initialize device.
561 */
562 ae_init(sc)
563 struct ae_softc *sc;
564 {
565 struct ifnet *ifp = &sc->arpcom.ac_if;
566 int i, s;
567 u_char command;
568
569 /* address not known */
570 if (ifp->if_addrlist == (struct ifaddr *)0) return;
571
572 /*
573 * Initialize the NIC in the exact order outlined in the NS manual.
574 * This init procedure is "mandatory"...don't change what or when
575 * things happen.
576 */
577 s = splnet();
578
579 /* reset transmitter flags */
580 sc->data_buffered = 0;
581 sc->xmit_busy = 0;
582 sc->arpcom.ac_if.if_timer = 0;
583
584 sc->txb_next = 0;
585
586 /* This variable is used below - don't move this assignment */
587 sc->next_packet = sc->rec_page_start + 1;
588
589 #ifdef DEBUG_PRINT
590 printf("page_start %d, page_stop %d, next %d\n",
591 sc->rec_page_start, sc->rec_page_stop, sc->next_packet);
592 #endif
593
594 /*
595 * Set interface for page 0, Remote DMA complete, Stopped
596 */
597 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_STP);
598
599 /*
600 * Set FIFO threshold to 4, No auto-init Remote DMA, Burst mode,
601 * byte order=80x86, word-wide DMA xfers,
602 */
603 NIC_PUT(sc, AE_P0_DCR, AE_DCR_FT1|AE_DCR_BMS|AE_DCR_WTS);
604
605 /*
606 * Clear Remote Byte Count Registers
607 */
608 NIC_PUT(sc, AE_P0_RBCR0, zero);
609 NIC_PUT(sc, AE_P0_RBCR1, zero);
610
611 /*
612 * Enable reception of broadcast packets
613 */
614 NIC_PUT(sc, AE_P0_RCR, AE_RCR_AB);
615
616 /*
617 * Place NIC in internal loopback mode
618 */
619 NIC_PUT(sc, AE_P0_TCR, AE_TCR_LB0);
620
621 /*
622 * Initialize transmit/receive (ring-buffer) Page Start
623 */
624 NIC_PUT(sc, AE_P0_TPSR, sc->tx_page_start);
625 NIC_PUT(sc, AE_P0_PSTART, sc->rec_page_start);
626
627 /*
628 * Initialize Receiver (ring-buffer) Page Stop and Boundry
629 */
630 NIC_PUT(sc, AE_P0_PSTOP, sc->rec_page_stop);
631 NIC_PUT(sc, AE_P0_BNRY, sc->rec_page_start);
632
633 /*
634 * Clear all interrupts. A '1' in each bit position clears the
635 * corresponding flag.
636 */
637 NIC_PUT(sc, AE_P0_ISR, ones);
638
639 /* make sure interrupts are vectored to us */
640 add_nubus_intr((int)sc->rom_addr & 0xFF000000, aeintr, sc - ae_softc);
641
642 /*
643 * Enable the following interrupts: receive/transmit complete,
644 * receive/transmit error, and Receiver OverWrite.
645 *
646 * Counter overflow and Remote DMA complete are *not* enabled.
647 */
648 NIC_PUT(sc, AE_P0_IMR,
649 AE_IMR_PRXE|AE_IMR_PTXE|AE_IMR_RXEE|AE_IMR_TXEE|AE_IMR_OVWE);
650
651 /*
652 * Program Command Register for page 1
653 */
654 NIC_PUT(sc, AE_P0_CR, AE_CR_PAGE_1|AE_CR_RD2|AE_CR_STP);
655
656 /*
657 * Copy out our station address
658 */
659 for (i = 0; i < ETHER_ADDR_LEN; ++i)
660 NIC_PUT(sc, AE_P1_PAR0 + i, sc->arpcom.ac_enaddr[i]);
661
662 #if NBPFILTER > 0
663 /*
664 * Initialize multicast address hashing registers to accept
665 * all multicasts (only used when in promiscuous mode)
666 */
667 for (i = 0; i < 8; ++i)
668 NIC_PUT(sc, AE_P1_MAR0 + i, 0xff);
669 #endif
670
671 /*
672 * Set Current Page pointer to next_packet (initialized above)
673 */
674 NIC_PUT(sc, AE_P1_CURR, sc->next_packet);
675
676 /*
677 * Set Command Register for page 0, Remote DMA complete,
678 * and interface Start.
679 */
680 NIC_PUT(sc, AE_P1_CR, AE_CR_RD2|AE_CR_STA);
681
682 /*
683 * Take interface out of loopback
684 */
685 NIC_PUT(sc, AE_P0_TCR, zero);
686
687 /*
688 * Set 'running' flag, and clear output active flag.
689 */
690 ifp->if_flags |= IFF_RUNNING;
691 ifp->if_flags &= ~IFF_OACTIVE;
692
693 /*
694 * ...and attempt to start output
695 */
696 ae_start(ifp);
697
698 (void) splx(s);
699 }
700
701 /*
702 * This routine actually starts the transmission on the interface
703 */
704 static inline void ae_xmit(ifp)
705 struct ifnet *ifp;
706 {
707 struct ae_softc *sc = &ae_softc[ifp->if_unit];
708 u_short len = sc->txb_next_len;
709
710 /*
711 * Set NIC for page 0 register access
712 */
713 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_STA);
714
715 /*
716 * Set TX buffer start page
717 */
718 NIC_PUT(sc, AE_P0_TPSR, sc->tx_page_start +
719 sc->txb_next * AE_TXBUF_SIZE);
720
721 /*
722 * Set TX length
723 */
724 NIC_PUT(sc, AE_P0_TBCR0, len & 0xff);
725 NIC_PUT(sc, AE_P0_TBCR1, len >> 8);
726
727 /*
728 * Set page 0, Remote DMA complete, Transmit Packet, and *Start*
729 */
730 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_TXP|AE_CR_STA);
731
732 sc->xmit_busy = 1;
733 sc->data_buffered = 0;
734
735 /*
736 * Switch buffers if we are doing double-buffered transmits
737 */
738 if ((sc->txb_next == 0) && (sc->txb_cnt > 1))
739 sc->txb_next = 1;
740 else
741 sc->txb_next = 0;
742
743 /*
744 * Set a timer just in case we never hear from the board again
745 */
746 ifp->if_timer = 2;
747 }
748
749 /*
750 * Start output on interface.
751 * We make two assumptions here:
752 * 1) that the current priority is set to splnet _before_ this code
753 * is called *and* is returned to the appropriate priority after
754 * return
755 * 2) that the IFF_OACTIVE flag is checked before this code is called
756 * (i.e. that the output part of the interface is idle)
757 */
758 int
759 ae_start(ifp)
760 struct ifnet *ifp;
761 {
762 struct ae_softc *sc = &ae_softc[ifp->if_unit];
763 struct mbuf *m0, *m;
764 caddr_t buffer;
765 int len;
766
767 outloop:
768 /*
769 * See if there is room to send more data (i.e. one or both of the
770 * buffers is empty).
771 */
772 if (sc->data_buffered)
773 if (sc->xmit_busy) {
774 /*
775 * No room. Indicate this to the outside world
776 * and exit.
777 */
778 ifp->if_flags |= IFF_OACTIVE;
779 return;
780 } else {
781 /*
782 * Data is buffered, but we're not transmitting, so
783 * start the xmit on the buffered data.
784 * Note that ae_xmit() resets the data_buffered flag
785 * before returning.
786 */
787 ae_xmit(ifp);
788 }
789
790 IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
791 if (m == 0) {
792 /*
793 * The following isn't pretty; we are using the !OACTIVE flag to
794 * indicate to the outside world that we can accept an additional
795 * packet rather than that the transmitter is _actually_
796 * active. Indeed, the transmitter may be active, but if we haven't
797 * filled the secondary buffer with data then we still want to
798 * accept more.
799 * Note that it isn't necessary to test the data_buffered flag -
800 * we wouldn't have tried to de-queue the packet in the first place
801 * if it was set.
802 */
803 ifp->if_flags &= ~IFF_OACTIVE;
804 return;
805 }
806
807 /*
808 * Copy the mbuf chain into the transmit buffer
809 */
810 buffer = sc->smem_start + (sc->txb_next * AE_TXBUF_SIZE * AE_PAGE_SIZE);
811 len = 0;
812 for (m0 = m; m != 0; m = m->m_next) {
813 /*printf("ae: copy %d bytes @ %x\n", m->m_len, buffer);*/
814 bscopy(mtod(m, caddr_t), buffer, m->m_len);
815 buffer += m->m_len;
816 len += m->m_len;
817 }
818 if (len & 1) len++;
819
820 sc->txb_next_len = max(len, ETHER_MIN_LEN);
821
822 if (sc->txb_cnt > 1)
823 /*
824 * only set 'buffered' flag if doing multiple buffers
825 */
826 sc->data_buffered = 1;
827
828 if (sc->xmit_busy == 0)
829 ae_xmit(ifp);
830 /*
831 * If there is BPF support in the configuration, tap off here.
832 * The following has support for converting trailer packets
833 * back to normal.
834 */
835 #if NBPFILTER > 0
836 if (sc->bpf) {
837 u_short etype;
838 int off, datasize, resid;
839 struct ether_header *eh;
840 struct trailer_header {
841 u_short ether_type;
842 u_short ether_residual;
843 } trailer_header;
844 char ether_packet[ETHER_MAX_LEN];
845 char *ep;
846
847 ep = ether_packet;
848
849 /*
850 * We handle trailers below:
851 * Copy ether header first, then residual data,
852 * then data. Put all this in a temporary buffer
853 * 'ether_packet' and send off to bpf. Since the
854 * system has generated this packet, we assume
855 * that all of the offsets in the packet are
856 * correct; if they're not, the system will almost
857 * certainly crash in m_copydata.
858 * We make no assumptions about how the data is
859 * arranged in the mbuf chain (i.e. how much
860 * data is in each mbuf, if mbuf clusters are
861 * used, etc.), which is why we use m_copydata
862 * to get the ether header rather than assume
863 * that this is located in the first mbuf.
864 */
865 /* copy ether header */
866 m_copydata(m0, 0, sizeof(struct ether_header), ep);
867 eh = (struct ether_header *) ep;
868 ep += sizeof(struct ether_header);
869 etype = ntohs(eh->ether_type);
870 if (etype >= ETHERTYPE_TRAIL &&
871 etype < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
872 datasize = ((etype - ETHERTYPE_TRAIL) << 9);
873 off = datasize + sizeof(struct ether_header);
874
875 /* copy trailer_header into a data structure */
876 m_copydata(m0, off, sizeof(struct trailer_header),
877 &trailer_header.ether_type);
878
879 /* copy residual data */
880 m_copydata(m0, off+sizeof(struct trailer_header),
881 resid = ntohs(trailer_header.ether_residual) -
882 sizeof(struct trailer_header), ep);
883 ep += resid;
884
885 /* copy data */
886 m_copydata(m0, sizeof(struct ether_header),
887 datasize, ep);
888 ep += datasize;
889
890 /* restore original ether packet type */
891 eh->ether_type = trailer_header.ether_type;
892
893 bpf_tap(sc->bpf, ether_packet, ep - ether_packet);
894 } else
895 bpf_mtap(sc->bpf, m0);
896 }
897 #endif
898
899 m_freem(m0);
900
901 /*
902 * If we are doing double-buffering, a buffer might be free to
903 * fill with another packet, so loop back to the top.
904 */
905 if (sc->txb_cnt > 1)
906 goto outloop;
907 else {
908 ifp->if_flags |= IFF_OACTIVE;
909 return;
910 }
911 }
912
913 /*
914 * Ethernet interface receiver interrupt.
915 */
916 static inline void
917 ae_rint(unit)
918 int unit;
919 {
920 register struct ae_softc *sc = &ae_softc[unit];
921 u_char boundry, current;
922 u_short len;
923 struct ae_ring *packet_ptr;
924
925 /*
926 * Set NIC to page 1 registers to get 'current' pointer
927 */
928 NIC_PUT(sc, AE_P0_CR, AE_CR_PAGE_1|AE_CR_RD2|AE_CR_STA);
929
930 /*
931 * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
932 * it points to where new data has been buffered. The 'CURR'
933 * (current) register points to the logical end of the ring-buffer
934 * - i.e. it points to where additional new data will be added.
935 * We loop here until the logical beginning equals the logical
936 * end (or in other words, until the ring-buffer is empty).
937 */
938 while (sc->next_packet != NIC_GET(sc, AE_P1_CURR)) {
939
940 /* get pointer to this buffer header structure */
941 packet_ptr = (struct ae_ring *)(sc->smem_ring +
942 (sc->next_packet - sc->rec_page_start) * AE_PAGE_SIZE);
943
944 /*
945 * The byte count includes the FCS - Frame Check Sequence (a
946 * 32 bit CRC).
947 */
948 len = packet_ptr->count[0] | (packet_ptr->count[1] << 8);
949 if ((len >= ETHER_MIN_LEN) && (len <= ETHER_MAX_LEN)) {
950 /*
951 * Go get packet. len - 4 removes CRC from length.
952 * (packet_ptr + 1) points to data just after the
953 * packet ring header (+4 bytes)
954 */
955 ae_get_packet(sc, (caddr_t)(packet_ptr + 1), len - 4);
956 ++sc->arpcom.ac_if.if_ipackets;
957 } else {
958 /*
959 * Really BAD...probably indicates that the ring
960 * pointers are corrupted. Also seen on early rev
961 * chips under high load - the byte order of the
962 * length gets switched.
963 */
964 log(LOG_ERR,
965 "ae%d: shared memory corrupt - invalid packet length %d\n",
966 unit, len);
967 ae_reset(sc);
968 return;
969 }
970
971 /*
972 * Update next packet pointer
973 */
974 sc->next_packet = packet_ptr->next_packet;
975
976 /*
977 * Update NIC boundry pointer - being careful to keep it
978 * one buffer behind. (as recommended by NS databook)
979 */
980 boundry = sc->next_packet - 1;
981 if (boundry < sc->rec_page_start)
982 boundry = sc->rec_page_stop - 1;
983
984 /*
985 * Set NIC to page 0 registers to update boundry register
986 */
987 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_STA);
988
989 NIC_PUT(sc, AE_P0_BNRY, boundry);
990
991 /*
992 * Set NIC to page 1 registers before looping to top
993 * (prepare to get 'CURR' current pointer)
994 */
995 NIC_PUT(sc, AE_P0_CR, AE_CR_PAGE_1|AE_CR_RD2|AE_CR_STA);
996 }
997 }
998
999 /*
1000 * Ethernet interface interrupt processor
1001 */
1002 int
1003 aeintr(unit)
1004 int unit;
1005 {
1006 struct ae_softc *sc = &ae_softc[unit];
1007 u_char isr;
1008
1009 aeintr_ctr++;
1010 /*
1011 * Set NIC to page 0 registers
1012 */
1013 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_STA);
1014
1015 /*
1016 * loop until there are no more new interrupts
1017 */
1018 while (isr = NIC_GET(sc, AE_P0_ISR)) {
1019
1020 /*
1021 * reset all the bits that we are 'acknowledging'
1022 * by writing a '1' to each bit position that was set
1023 * (writing a '1' *clears* the bit)
1024 */
1025 NIC_PUT(sc, AE_P0_ISR, isr);
1026
1027 /*
1028 * Handle transmitter interrupts. Handle these first
1029 * because the receiver will reset the board under
1030 * some conditions.
1031 */
1032 if (isr & (AE_ISR_PTX|AE_ISR_TXE)) {
1033 u_char collisions = NIC_GET(sc, AE_P0_NCR);
1034
1035 /*
1036 * Check for transmit error. If a TX completed with an
1037 * error, we end up throwing the packet away. Really
1038 * the only error that is possible is excessive
1039 * collisions, and in this case it is best to allow the
1040 * automatic mechanisms of TCP to backoff the flow. Of
1041 * course, with UDP we're screwed, but this is expected
1042 * when a network is heavily loaded.
1043 */
1044 if (isr & AE_ISR_TXE) {
1045
1046 /*
1047 * Excessive collisions (16)
1048 */
1049 if ((NIC_GET(sc, AE_P0_TSR) & AE_TSR_ABT)
1050 && (collisions == 0)) {
1051 /*
1052 * When collisions total 16, the
1053 * P0_NCR will indicate 0, and the
1054 * TSR_ABT is set.
1055 */
1056 collisions = 16;
1057 }
1058
1059 /*
1060 * update output errors counter
1061 */
1062 ++sc->arpcom.ac_if.if_oerrors;
1063 } else {
1064 /*
1065 * Update total number of successfully
1066 * transmitted packets.
1067 */
1068 ++sc->arpcom.ac_if.if_opackets;
1069 }
1070
1071 /*
1072 * reset tx busy and output active flags
1073 */
1074 sc->xmit_busy = 0;
1075 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
1076
1077 /*
1078 * clear watchdog timer
1079 */
1080 sc->arpcom.ac_if.if_timer = 0;
1081
1082 /*
1083 * Add in total number of collisions on last
1084 * transmission.
1085 */
1086 sc->arpcom.ac_if.if_collisions += collisions;
1087
1088 /*
1089 * If data is ready to transmit, start it transmitting,
1090 * otherwise defer until after handling receiver
1091 */
1092 if (sc->data_buffered)
1093 ae_xmit(&sc->arpcom.ac_if);
1094 }
1095
1096 /*
1097 * Handle receiver interrupts
1098 */
1099 if (isr & (AE_ISR_PRX|AE_ISR_RXE|AE_ISR_OVW)) {
1100 /*
1101 * Overwrite warning. In order to make sure that a lockup
1102 * of the local DMA hasn't occurred, we reset and
1103 * re-init the NIC. The NSC manual suggests only a
1104 * partial reset/re-init is necessary - but some
1105 * chips seem to want more. The DMA lockup has been
1106 * seen only with early rev chips - Methinks this
1107 * bug was fixed in later revs. -DG
1108 */
1109 if (isr & AE_ISR_OVW) {
1110 ++sc->arpcom.ac_if.if_ierrors;
1111 log(LOG_WARNING,
1112 "ae%d: warning - receiver ring buffer overrun\n",
1113 unit);
1114 /*
1115 * Stop/reset/re-init NIC
1116 */
1117 ae_reset(sc);
1118 } else {
1119
1120 /*
1121 * Receiver Error. One or more of: CRC error, frame
1122 * alignment error FIFO overrun, or missed packet.
1123 */
1124 if (isr & AE_ISR_RXE) {
1125 ++sc->arpcom.ac_if.if_ierrors;
1126 #ifdef AE_DEBUG
1127 printf("ae%d: receive error %x\n", unit,
1128 NIC_GET(sc, AE_P0_RSR));
1129 #endif
1130 }
1131
1132 /*
1133 * Go get the packet(s)
1134 * XXX - Doing this on an error is dubious
1135 * because there shouldn't be any data to
1136 * get (we've configured the interface to
1137 * not accept packets with errors).
1138 */
1139 ae_rint (unit);
1140 }
1141 }
1142
1143 /*
1144 * If it looks like the transmitter can take more data,
1145 * attempt to start output on the interface.
1146 * This is done after handling the receiver to
1147 * give the receiver priority.
1148 */
1149 if ((sc->arpcom.ac_if.if_flags & IFF_OACTIVE) == 0)
1150 ae_start(&sc->arpcom.ac_if);
1151
1152 /*
1153 * return NIC CR to standard state: page 0, remote DMA complete,
1154 * start (toggling the TXP bit off, even if was just set
1155 * in the transmit routine, is *okay* - it is 'edge'
1156 * triggered from low to high)
1157 */
1158 NIC_PUT(sc, AE_P0_CR, AE_CR_RD2|AE_CR_STA);
1159
1160 /*
1161 * If the Network Talley Counters overflow, read them to
1162 * reset them. It appears that old 8390's won't
1163 * clear the ISR flag otherwise - resulting in an
1164 * infinite loop.
1165 */
1166 if (isr & AE_ISR_CNT) {
1167 (void) NIC_GET(sc, AE_P0_CNTR0);
1168 (void) NIC_GET(sc, AE_P0_CNTR1);
1169 (void) NIC_GET(sc, AE_P0_CNTR2);
1170 }
1171 }
1172 return 0;
1173 }
1174
1175 /*
1176 * Process an ioctl request. This code needs some work - it looks
1177 * pretty ugly.
1178 */
1179 int
1180 ae_ioctl(ifp, command, data)
1181 register struct ifnet *ifp;
1182 int command;
1183 caddr_t data;
1184 {
1185 register struct ifaddr *ifa = (struct ifaddr *)data;
1186 struct ae_softc *sc = &ae_softc[ifp->if_unit];
1187 struct ifreq *ifr = (struct ifreq *)data;
1188 int s, error = 0;
1189
1190 s = splnet();
1191
1192 switch (command) {
1193
1194 case SIOCSIFADDR:
1195 ifp->if_flags |= IFF_UP;
1196
1197 switch (ifa->ifa_addr->sa_family) {
1198 #ifdef INET
1199 case AF_INET:
1200 ae_init(sc); /* before arpwhohas */
1201 /*
1202 * See if another station has *our* IP address.
1203 * i.e.: There is an address conflict! If a
1204 * conflict exists, a message is sent to the
1205 * console.
1206 */
1207 ((struct arpcom *)ifp)->ac_ipaddr =
1208 IA_SIN(ifa)->sin_addr;
1209 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
1210 break;
1211 #endif
1212 #ifdef NS
1213 /*
1214 * XXX - This code is probably wrong
1215 */
1216 case AF_NS:
1217 {
1218 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
1219
1220 if (ns_nullhost(*ina))
1221 ina->x_host =
1222 *(union ns_host *)(sc->arpcom.ac_enaddr);
1223 else {
1224 /*
1225 *
1226 */
1227 bbcopy((caddr_t)ina->x_host.c_host,
1228 (caddr_t)sc->arpcom.ac_enaddr,
1229 sizeof(sc->arpcom.ac_enaddr));
1230 }
1231 /*
1232 * Set new address
1233 */
1234 ae_init(sc);
1235 break;
1236 }
1237 #endif
1238 default:
1239 ae_init(sc);
1240 break;
1241 }
1242 break;
1243
1244 case SIOCSIFFLAGS:
1245 /*
1246 * If interface is marked down and it is running, then stop it
1247 */
1248 if (((ifp->if_flags & IFF_UP) == 0) &&
1249 (ifp->if_flags & IFF_RUNNING)) {
1250 ae_stop(sc);
1251 ifp->if_flags &= ~IFF_RUNNING;
1252 } else {
1253 /*
1254 * If interface is marked up and it is stopped, then start it
1255 */
1256 if ((ifp->if_flags & IFF_UP) &&
1257 ((ifp->if_flags & IFF_RUNNING) == 0))
1258 ae_init(sc);
1259 }
1260 #if NBPFILTER > 0
1261 if (ifp->if_flags & IFF_PROMISC) {
1262 /*
1263 * Set promiscuous mode on interface.
1264 * XXX - for multicasts to work, we would need to
1265 * write 1's in all bits of multicast
1266 * hashing array. For now we assume that
1267 * this was done in ae_init().
1268 */
1269 NIC_PUT(sc, AE_P0_RCR,
1270 AE_RCR_PRO|AE_RCR_AM|AE_RCR_AB);
1271 } else {
1272 /*
1273 * XXX - for multicasts to work, we would need to
1274 * rewrite the multicast hashing array with the
1275 * proper hash (would have been destroyed above).
1276 */
1277 NIC_PUT(sc, AE_P0_RCR, AE_RCR_AB);
1278 }
1279 #endif
1280 break;
1281
1282 default:
1283 error = EINVAL;
1284 }
1285 (void) splx(s);
1286 return (error);
1287 }
1288
1289 /*
1290 * Macro to calculate a new address within shared memory when given an offset
1291 * from an address, taking into account ring-wrap.
1292 */
1293 #define ringoffset(sc, start, off, type) \
1294 ((type)( ((caddr_t)(start)+(off) >= (sc)->smem_end) ? \
1295 (((caddr_t)(start)+(off))) - (sc)->smem_end \
1296 + (sc)->smem_ring: \
1297 ((caddr_t)(start)+(off)) ))
1298
1299 /*
1300 * Retreive packet from shared memory and send to the next level up via
1301 * ether_input(). If there is a BPF listener, give a copy to BPF, too.
1302 */
1303 ae_get_packet(sc, buf, len)
1304 struct ae_softc *sc;
1305 char *buf;
1306 u_short len;
1307 {
1308 struct ether_header *eh;
1309 struct mbuf *m, *head, *ae_ring_to_mbuf();
1310 u_short off;
1311 int resid;
1312 u_short etype;
1313 struct trailer_header {
1314 u_short trail_type;
1315 u_short trail_residual;
1316 } trailer_header;
1317
1318 /* Allocate a header mbuf */
1319 MGETHDR(m, M_DONTWAIT, MT_DATA);
1320 if (m == 0)
1321 goto bad;
1322 m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
1323 m->m_pkthdr.len = len;
1324 m->m_len = 0;
1325 head = m;
1326
1327 eh = (struct ether_header *)buf;
1328
1329 /* The following sillines is to make NFS happy */
1330 #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
1331 #define EOFF (EROUND - sizeof(struct ether_header))
1332
1333 /*
1334 * The following assumes there is room for
1335 * the ether header in the header mbuf
1336 */
1337 head->m_data += EOFF;
1338 bbcopy(buf, mtod(head, caddr_t), sizeof(struct ether_header));
1339 buf += sizeof(struct ether_header);
1340 head->m_len += sizeof(struct ether_header);
1341 len -= sizeof(struct ether_header);
1342
1343 etype = ntohs((u_short)eh->ether_type);
1344
1345 /*
1346 * Deal with trailer protocol:
1347 * If trailer protocol, calculate the datasize as 'off',
1348 * which is also the offset to the trailer header.
1349 * Set resid to the amount of packet data following the
1350 * trailer header.
1351 * Finally, copy residual data into mbuf chain.
1352 */
1353 if (etype >= ETHERTYPE_TRAIL &&
1354 etype < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
1355
1356 off = (etype - ETHERTYPE_TRAIL) << 9;
1357 if ((off + sizeof(struct trailer_header)) > len)
1358 goto bad; /* insanity */
1359
1360 eh->ether_type = *ringoffset(sc, buf, off, u_short *);
1361 resid = ntohs(*ringoffset(sc, buf, off+2, u_short *));
1362
1363 if ((off + resid) > len) goto bad; /* insanity */
1364
1365 resid -= sizeof(struct trailer_header);
1366 if (resid < 0) goto bad; /* insanity */
1367
1368 m = ae_ring_to_mbuf(sc, ringoffset(sc, buf, off+4, char *),
1369 head, resid);
1370 if (m == 0) goto bad;
1371
1372 len = off;
1373 head->m_pkthdr.len -= 4; /* subtract trailer header */
1374 }
1375
1376 /*
1377 * Pull packet off interface. Or if this was a trailer packet,
1378 * the data portion is appended.
1379 */
1380 m = ae_ring_to_mbuf(sc, buf, m, len);
1381 if (m == 0) goto bad;
1382
1383 #if NBPFILTER > 0
1384 /*
1385 * Check if there's a BPF listener on this interface.
1386 * If so, hand off the raw packet to bpf.
1387 */
1388 if (sc->bpf) {
1389 bpf_mtap(sc->bpf, head);
1390
1391 /*
1392 * Note that the interface cannot be in promiscuous mode if
1393 * there are no BPF listeners. And if we are in promiscuous
1394 * mode, we have to check if this packet is really ours.
1395 *
1396 * XXX This test does not support multicasts.
1397 */
1398 if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
1399 bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
1400 sizeof(eh->ether_dhost)) != 0 &&
1401 bcmp(eh->ether_dhost, etherbroadcastaddr,
1402 sizeof(eh->ether_dhost)) != 0) {
1403
1404 m_freem(head);
1405 return;
1406 }
1407 }
1408 #endif
1409
1410 /*
1411 * Fix up data start offset in mbuf to point past ether header
1412 */
1413 m_adj(head, sizeof(struct ether_header));
1414
1415 ether_input(&sc->arpcom.ac_if, eh, head);
1416 return;
1417
1418 bad: if (head)
1419 m_freem(head);
1420 return;
1421 }
1422
1423 /*
1424 * Supporting routines
1425 */
1426
1427 /*
1428 * Given a source and destination address, copy 'amount' of a packet from
1429 * the ring buffer into a linear destination buffer. Takes into account
1430 * ring-wrap.
1431 */
1432 static inline char *
1433 ae_ring_copy(sc,src,dst,amount)
1434 struct ae_softc *sc;
1435 char *src;
1436 char *dst;
1437 u_short amount;
1438 {
1439 u_short tmp_amount;
1440
1441 /* does copy wrap to lower addr in ring buffer? */
1442 if (src + amount > sc->smem_end) {
1443 tmp_amount = sc->smem_end - src;
1444 /* copy amount up to end of smem */
1445 bbcopy(src, dst, tmp_amount);
1446 amount -= tmp_amount;
1447 src = sc->smem_ring;
1448 dst += tmp_amount;
1449 }
1450
1451 bbcopy(src, dst, amount);
1452
1453 return(src + amount);
1454 }
1455
1456 /*
1457 * Copy data from receive buffer to end of mbuf chain
1458 * allocate additional mbufs as needed. return pointer
1459 * to last mbuf in chain.
1460 * sc = ed info (softc)
1461 * src = pointer in ed ring buffer
1462 * dst = pointer to last mbuf in mbuf chain to copy to
1463 * amount = amount of data to copy
1464 */
1465 struct mbuf *
1466 ae_ring_to_mbuf(sc,src,dst,total_len)
1467 struct ae_softc *sc;
1468 char *src;
1469 struct mbuf *dst;
1470 u_short total_len;
1471 {
1472 register struct mbuf *m = dst;
1473
1474 while (total_len) {
1475 register u_short amount = min(total_len, M_TRAILINGSPACE(m));
1476
1477 if (amount == 0) {
1478 /* no more data in this mbuf, alloc another */
1479 /*
1480 * If there is enough data for an mbuf cluster, attempt
1481 * to allocate one of those, otherwise, a regular
1482 * mbuf will do.
1483 * Note that a regular mbuf is always required, even if
1484 * we get a cluster - getting a cluster does not
1485 * allocate any mbufs, and one is needed to assign
1486 * the cluster to. The mbuf that has a cluster
1487 * extension can not be used to contain data -
1488 * only the cluster can contain data.
1489 */
1490 dst = m;
1491 MGET(m, M_DONTWAIT, MT_DATA);
1492 if (m == 0)
1493 return (0);
1494
1495 if (total_len >= MINCLSIZE)
1496 MCLGET(m, M_DONTWAIT);
1497
1498 m->m_len = 0;
1499 dst->m_next = m;
1500 amount = min(total_len, M_TRAILINGSPACE(m));
1501 }
1502
1503 src = ae_ring_copy(sc, src, mtod(m, caddr_t) + m->m_len,
1504 amount);
1505
1506 m->m_len += amount;
1507 total_len -= amount;
1508
1509 }
1510 return (m);
1511 }
1512