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