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