|
|
1.1 root 1: /*
2: * Device driver for National Semiconductor DS8390 based ethernet
3: * adapters. By David Greenman, 29-April-1993
4: *
5: * Copyright (C) 1993, David Greenman. This software may be used, modified,
6: * copied, distributed, and sold, in both source and binary form provided
7: * that the above copyright and these terms are retained. Under no
8: * circumstances is the author responsible for the proper functioning
9: * of this software, nor does the author assume any responsibility
10: * for damages incurred with its use.
11: *
12: * Currently supports the Western Digital/SMC 8003 and 8013 series
13: * and the 3Com 3c503
14: */
15:
16: /*
17: * if_ed.c,v 1.2.2.5 1993/07/27 06:00:45 cgd Exp
18: */
19:
20: #include "ed.h"
21: #if NED > 0
22: #include "bpfilter.h"
23:
24: #include "param.h"
25: #include "systm.h"
26: #include "select.h"
27: #include "errno.h"
28: #include "ioctl.h"
29: #include "mbuf.h"
30: #include "socket.h"
31: #include "syslog.h"
32:
33: #include "net/if.h"
34: #include "net/if_dl.h"
35: #include "net/if_types.h"
36: #include "net/netisr.h"
37:
38: #ifdef INET
39: #include "netinet/in.h"
40: #include "netinet/in_systm.h"
41: #include "netinet/in_var.h"
42: #include "netinet/ip.h"
43: #include "netinet/if_ether.h"
44: #endif
45:
46: #ifdef NS
47: #include "netns/ns.h"
48: #include "netns/ns_if.h"
49: #endif
50:
51: #if NBPFILTER > 0
52: #include "net/bpf.h"
53: #include "net/bpfdesc.h"
54: #endif
55:
56: #include "i386/isa/isa.h"
57: #include "i386/isa/isa_device.h"
58: #include "i386/isa/icu.h"
59: #include "i386/isa/if_edreg.h"
60:
61: #include "i386/include/pio.h"
62:
63:
64: /*
65: * ed_softc: per line info and status
66: */
67: struct ed_softc {
68: struct arpcom arpcom; /* ethernet common */
69:
70: char *type_str; /* pointer to type string */
71: u_char vendor; /* interface vendor */
72: u_char type; /* interface type code */
73:
74: u_short vector; /* interrupt vector */
75: u_short asic_addr; /* ASIC I/O bus address */
76: u_short nic_addr; /* NIC (DS8390) I/O bus address */
77:
78: caddr_t smem_start; /* shared memory start address */
79: caddr_t smem_end; /* shared memory end address */
80: u_long smem_size; /* total shared memory size */
81: caddr_t smem_ring; /* start of RX ring-buffer (in smem) */
82:
83: caddr_t bpf; /* BPF "magic cookie" */
84:
85: u_char memwidth; /* width of access to card mem 8 or 16 */
86: u_char xmit_busy; /* transmitter is busy */
87: u_char txb_cnt; /* Number of transmit buffers */
88: u_char txb_next; /* Pointer to next buffer ready to xmit */
89: u_short txb_next_len; /* next xmit buffer length */
90: u_char data_buffered; /* data has been buffered in interface memory */
91: u_char tx_page_start; /* first page of TX buffer area */
92:
93: u_char rec_page_start; /* first page of RX ring-buffer */
94: u_char rec_page_stop; /* last page of RX ring-buffer */
95: u_char next_packet; /* pointer to next unread RX packet */
96: } ed_softc[NED];
97:
98: int ed_attach(), ed_init(), edintr(), ed_ioctl(), ed_probe(),
99: ed_start(), ed_reset(), ed_watchdog();
100:
101: static void ed_stop();
102:
103: static inline void ed_rint();
104: static inline void ed_xmit();
105: static inline char *ed_ring_copy();
106:
107: extern int ether_output();
108:
109: struct isa_driver eddriver = {
110: ed_probe,
111: ed_attach,
112: "ed"
113: };
114: /*
115: * Interrupt conversion table for WD/SMC ASIC
116: * (IRQ* are defined in icu.h)
117: */
118: static unsigned short ed_intr_mask[] = {
119: IRQ9,
120: IRQ3,
121: IRQ5,
122: IRQ7,
123: IRQ10,
124: IRQ11,
125: IRQ15,
126: IRQ4
127: };
128:
129: #define ETHER_MIN_LEN 64
130: #define ETHER_MAX_LEN 1518
131: #define ETHER_ADDR_LEN 6
132: #define ETHER_HDR_SIZE 14
133:
134: /*
135: * Determine if the device is present
136: *
137: * on entry:
138: * a pointer to an isa_device struct
139: * on exit:
140: * NULL if device not found
141: * or # of i/o addresses used (if found)
142: */
143: int
144: ed_probe(isa_dev)
145: struct isa_device *isa_dev;
146: {
147: struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
148: int i, x;
149: u_int memsize;
150: u_char iptr, memwidth, sum, tmp;
151:
152: /*
153: * Setup initial i/o address for ASIC and NIC
154: */
155: sc->asic_addr = isa_dev->id_iobase;
156: sc->vector = isa_dev->id_irq;
157: sc->smem_start = (caddr_t)isa_dev->id_maddr;
158:
159: /*
160: * Attempt to do a checksum over the station address PROM.
161: * This is mapped differently on the WD80x3 and 3C503, so if
162: * it fails, it might be a 3C503. There is a problem with
163: * this, though: some clone WD boards don't pass the
164: * checksum test. Danpex boards for one. We need to do
165: * additional checking for this case.
166: */
167: for (sum = 0, i = 0; i < 8; ++i) {
168: sum += inb(sc->asic_addr + ED_WD_PROM + i);
169: }
170:
171: if (sum == ED_WD_ROM_CHECKSUM_TOTAL) {
172: goto type_WD80x3;
173: } else {
174: /*
175: * Do additional checking to make sure its a 3Com and
176: * not a broken WD clone
177: */
178: goto type_3Com;
179: }
180:
181: type_WD80x3:
182: /*
183: * Looks like a WD/SMC board
184: */
185:
186: sc->vendor = ED_VENDOR_WD_SMC;
187: sc->type = inb(sc->asic_addr + ED_WD_CARD_ID);
188:
189: sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
190:
191: /* reset card to force it into a known state. */
192: outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
193: DELAY(100);
194: outb(sc->asic_addr + ED_WD_MSR, inb(sc->asic_addr + ED_WD_MSR) & ~ED_WD_MSR_RST);
195: /* wait in the case this card is reading it's EEROM */
196: DELAY(5000);
197:
198: /*
199: * Set initial values for width/size.
200: */
201: switch (sc->type) {
202: case ED_TYPE_WD8003S:
203: sc->type_str = "WD8003S";
204: memsize = 8192;
205: memwidth = 8;
206: break;
207: case ED_TYPE_WD8003E:
208: sc->type_str = "WD8003E";
209: memsize = 8192;
210: memwidth = 8;
211: break;
212: case ED_TYPE_WD8013EBT:
213: sc->type_str = "WD8013EBT";
214: memsize = 16384;
215: memwidth = 16;
216: break;
217: case ED_TYPE_WD8013EB: /* also WD8003EP */
218: if (inb(sc->asic_addr + ED_WD_ICR)
219: & ED_WD_ICR_16BIT) {
220: memwidth = 16;
221: memsize = 16384;
222: sc->type_str = "WD8013EB";
223: } else {
224: sc->type_str = "WD8003EP";
225: memsize = 8192;
226: memwidth = 8;
227: }
228: break;
229: case ED_TYPE_WD8013EBP:
230: sc->type_str = "WD8013EBP";
231: memsize = 16384;
232: memwidth = 16;
233: break;
234: case ED_TYPE_WD8013EPC:
235: sc->type_str = "WD8013EPC";
236: memsize = 16384;
237: memwidth = 16;
238: break;
239: default:
240: sc->type_str = "unknown";
241: memsize = 8192;
242: memwidth = 8;
243: break;
244: }
245: /*
246: * Make some adjustments to initial values depending on what is
247: * found in the ICR.
248: */
249: if ((memwidth==16)
250: && ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
251: memwidth = 8;
252: memsize = 8192;
253: }
254: if (inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_MSZ) {
255: memsize = 32768;
256: }
257:
258: #if ED_DEBUG
259: printf("type=%s memwidth=%d memsize=%d id_msize=%d\n",
260: sc->type_str,memwidth,memsize,isa_dev->id_msize);
261: for (i=0; i<8; i++)
262: printf("%x -> %x\n", i, inb(sc->asic_addr + i));
263: #endif
264: /*
265: * Allow the user to override the autoconfiguration
266: */
267: if (isa_dev->id_msize)
268: memsize = isa_dev->id_msize;
269: /*
270: * (note that if the user specifies both of the following flags
271: * that '8bit' mode intentionally has precedence)
272: */
273: if (isa_dev->id_flags & ED_FLAGS_FORCE_16BIT_MODE)
274: memwidth = 16;
275: if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE)
276: memwidth = 8;
277:
278: /*
279: * Check 83C584 interrupt configuration register if this board has one
280: * XXX - we could also check the IO address register. But why
281: * bother...if we get past this, it *has* to be correct.
282: */
283: if (sc->type & ED_WD_SOFTCONFIG) {
284: /*
285: * Assemble together the encoded interrupt number.
286: */
287: iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
288: ((inb(isa_dev->id_iobase + ED_WD_IRR) &
289: (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
290: /*
291: * Translate it using translation table, and check for correctness.
292: */
293: if (ed_intr_mask[iptr] != isa_dev->id_irq) {
294: printf("ed%d: kernel configured irq doesn't match board configured irq\n",
295: isa_dev->id_unit);
296: return(0);
297: }
298: /*
299: * Enable the interrupt.
300: */
301: outb(isa_dev->id_iobase + ED_WD_IRR,
302: inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
303: }
304:
305: sc->memwidth = memwidth;
306: /*
307: * allocate one xmit buffer if < 16k, two buffers otherwise
308: */
309: if ((memsize < 16384) || (isa_dev->id_msize & ED_FLAGS_NO_DOUBLE_BUFFERING)) {
310: sc->smem_ring = sc->smem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
311: sc->txb_cnt = 1;
312: sc->rec_page_start = ED_TXBUF_SIZE;
313: } else {
314: sc->smem_ring = sc->smem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE * 2);
315: sc->txb_cnt = 2;
316: sc->rec_page_start = ED_TXBUF_SIZE * 2;
317: }
318: sc->smem_size = memsize;
319: sc->smem_end = sc->smem_start + memsize;
320: sc->rec_page_stop = memsize / ED_PAGE_SIZE;
321: sc->tx_page_start = ED_WD_PAGE_OFFSET;
322:
323: /*
324: * Get station address from on-board ROM
325: */
326: for (i = 0; i < ETHER_ADDR_LEN; ++i)
327: sc->arpcom.ac_enaddr[i] = inb(sc->asic_addr + ED_WD_PROM + i);
328:
329: /*
330: * Set address and enable interface shared memory.
331: */
332: outb(sc->asic_addr + ED_WD_MSR, ((kvtop(sc->smem_start) >> 13) &
333: ED_WD_MSR_ADDR) | ED_WD_MSR_MENB);
334:
335: /*
336: * Set upper address bits and 8/16 bit access to shared memory
337: */
338: if (sc->type & ED_WD_SOFTCONFIG) {
339: if (memwidth == 8) {
340: outb(sc->asic_addr + ED_WD_LAAR,
341: ((kvtop(sc->smem_start) >> 19) & ED_WD_LAAR_ADDRHI));
342: } else {
343: outb(sc->asic_addr + ED_WD_LAAR,
344: ED_WD_LAAR_L16EN | ED_WD_LAAR_M16EN |
345: ((kvtop(sc->smem_start) >> 19) & ED_WD_LAAR_ADDRHI));
346: }
347: }
348:
349: /*
350: * Now zero memory and verify that it is clear
351: */
352: bzero(sc->smem_start, memsize);
353:
354: for (i = 0; i < memsize; ++i)
355: if (sc->smem_start[i]) {
356: printf("ed%d: failed to clear shared memory at %x - check configuration\n",
357: isa_dev->id_unit, sc->smem_start + i);
358:
359: /*
360: * Disable 16 bit access to shared memory
361: */
362: if (memwidth == 16)
363: outb(sc->asic_addr + ED_WD_LAAR,
364: inb(sc->asic_addr + ED_WD_LAAR)
365: & ~ED_WD_LAAR_M16EN);
366:
367: return(0);
368: }
369:
370: /*
371: * Disable 16bit access to shared memory - we leave it disabled so
372: * that 1) machines reboot properly when the board is set
373: * 16 bit mode and there are conflicting 8bit devices/ROMS
374: * in the same 128k address space as this boards shared
375: * memory. and 2) so that other 8 bit devices with shared
376: * memory can be used in this 128k region, too.
377: */
378: if (memwidth == 16)
379: outb(sc->asic_addr + ED_WD_LAAR, inb(sc->asic_addr + ED_WD_LAAR)
380: & ~ED_WD_LAAR_M16EN);
381:
382: isa_dev->id_msize = memsize;
383: return (ED_WD_IO_PORTS);
384:
385: type_3Com:
386: /*
387: * Looks like a 3Com board
388: */
389:
390: sc->vendor = ED_VENDOR_3COM;
391: sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET;
392: sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET;
393:
394: sc->type_str = "3c503";
395:
396: memsize = 8192;
397:
398: /*
399: * Verify that the kernel configured I/O address matches the board
400: * configured address
401: */
402: switch (inb(sc->asic_addr + ED_3COM_BCFR)) {
403: case ED_3COM_BCFR_300:
404: if (isa_dev->id_iobase != 0x300)
405: return(0);
406: break;
407: case ED_3COM_BCFR_310:
408: if (isa_dev->id_iobase != 0x310)
409: return(0);
410: break;
411: case ED_3COM_BCFR_330:
412: if (isa_dev->id_iobase != 0x330)
413: return(0);
414: break;
415: case ED_3COM_BCFR_350:
416: if (isa_dev->id_iobase != 0x350)
417: return(0);
418: break;
419: case ED_3COM_BCFR_250:
420: if (isa_dev->id_iobase != 0x250)
421: return(0);
422: break;
423: case ED_3COM_BCFR_280:
424: if (isa_dev->id_iobase != 0x280)
425: return(0);
426: break;
427: case ED_3COM_BCFR_2A0:
428: if (isa_dev->id_iobase != 0x2a0)
429: return(0);
430: break;
431: case ED_3COM_BCFR_2E0:
432: if (isa_dev->id_iobase != 0x2e0)
433: return(0);
434: break;
435: default:
436: return(0);
437: }
438:
439: /*
440: * Verify that the kernel shared memory address matches the
441: * board configured address.
442: */
443: switch (inb(sc->asic_addr + ED_3COM_PCFR)) {
444: case ED_3COM_PCFR_DC000:
445: if (kvtop(isa_dev->id_maddr) != 0xdc000)
446: return(0);
447: break;
448: case ED_3COM_PCFR_D8000:
449: if (kvtop(isa_dev->id_maddr) != 0xd8000)
450: return(0);
451: break;
452: case ED_3COM_PCFR_CC000:
453: if (kvtop(isa_dev->id_maddr) != 0xcc000)
454: return(0);
455: break;
456: case ED_3COM_PCFR_C8000:
457: if (kvtop(isa_dev->id_maddr) != 0xc8000)
458: return(0);
459: break;
460: default:
461: return(0);
462: }
463:
464: /*
465: * Reset NIC and ASIC
466: */
467: outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST);
468: /*
469: * Wait for a while, then un-reset it
470: */
471: DELAY(5000);
472: outb(sc->asic_addr + ED_3COM_CR, 0);
473:
474: /*
475: * Wait a bit for the NIC to recover from the reset
476: */
477: DELAY(5000);
478:
479: /*
480: * The 3Com ASIC defaults to rather strange settings for the CR after
481: * a reset - it's important to set it so that the NIC I/O
482: * registers are mapped. The above setting of it to '0' only
483: * resets the reset condition - the CR is *not* set to zeros.
484: */
485: outb(sc->asic_addr + ED_3COM_CR, 0);
486:
487: /*
488: * Determine if this is an 8bit or 16bit board
489: */
490:
491: /*
492: * select page 0 registers
493: */
494: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
495:
496: /*
497: * Attempt to clear WTS bit. If it doesn't clear, then this is a
498: * 16bit board.
499: */
500: outb(sc->nic_addr + ED_P0_DCR, 0);
501:
502: /*
503: * select page 2 registers
504: */
505: outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_2|ED_CR_RD2|ED_CR_STP);
506:
507: /*
508: * The 3c503 forces the WTS bit to a one if this is a 16bit board
509: */
510: if (inb(sc->nic_addr + ED_P2_DCR) & ED_DCR_WTS)
511: memwidth = 16;
512: else
513: memwidth = 8;
514:
515: /*
516: * select page 0 registers
517: */
518: outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2|ED_CR_STP);
519:
520: sc->txb_cnt = 1;
521:
522: sc->tx_page_start = ED_3COM_PAGE_OFFSET;
523: sc->rec_page_start = ED_TXBUF_SIZE + ED_3COM_PAGE_OFFSET;
524: sc->rec_page_stop = memsize / ED_PAGE_SIZE + ED_3COM_PAGE_OFFSET;
525:
526: sc->smem_size = memsize;
527: sc->smem_end = sc->smem_start + memsize;
528: sc->smem_ring = sc->smem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
529:
530: sc->memwidth = memwidth;
531:
532: /*
533: * Initialize GA page start/stop registers. Probably only needed
534: * if doing DMA, but what the hell.
535: */
536: outb(sc->asic_addr + ED_3COM_PSTR, sc->rec_page_start);
537: outb(sc->asic_addr + ED_3COM_PSPR, sc->rec_page_stop);
538:
539: /*
540: * Set IRQ. 3c503 only allows a choice of irq 2-5.
541: */
542: switch (isa_dev->id_irq) {
543: case IRQ2:
544: outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2);
545: break;
546: case IRQ3:
547: outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3);
548: break;
549: case IRQ4:
550: outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4);
551: break;
552: case IRQ5:
553: outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
554: break;
555: default:
556: printf("ed%d: Invalid irq configuration\n", isa_dev->id_unit);
557: return(0);
558: }
559:
560: /*
561: * Initialize GA configuration register. Set bank and enable smem.
562: */
563: outb(sc->asic_addr + ED_3COM_GACFR, ED_3COM_GACFR_RSEL |
564: ED_3COM_GACFR_MBS0);
565:
566: /*
567: * Initialize "Vector Pointer" registers. These gawd-awful things
568: * are compared to 20 bits of the address on ISA, and if they
569: * match, the shared memory is disabled. We set them to
570: * 0xffff0...allegedly the reset vector.
571: */
572: outb(sc->asic_addr + ED_3COM_VPTR2, 0xff);
573: outb(sc->asic_addr + ED_3COM_VPTR1, 0xff);
574: outb(sc->asic_addr + ED_3COM_VPTR0, 0x00);
575:
576: /*
577: * Get station address from on-board ROM
578: */
579: /*
580: * First, map ethernet address PROM over the top of where the NIC
581: * registers normally appear.
582: */
583: outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_EALO);
584:
585: for (i = 0; i < ETHER_ADDR_LEN; ++i)
586: sc->arpcom.ac_enaddr[i] = inb(sc->nic_addr + i);
587:
588: /*
589: * Unmap PROM - select NIC registers. Tranceiver remains disabled at
590: * this point. It's enabled in ed_init so that the attach code
591: * is given a chance to set the default based on a compile-time
592: * config option
593: */
594: outb(sc->asic_addr + ED_3COM_CR, 0);
595:
596: #if 0
597: printf("Starting write\n");
598: for (i = 0; i < 8192; ++i)
599: bzero(sc->smem_start, 8192);
600: printf("Done.\n");
601: #endif
602: #if 0
603: { char test_buf[1024];
604: printf("starting write\n");
605: for (i = 0; i < 8*8192; ++i)
606: bcopy(test_buf, sc->smem_start, 1024);
607: printf("starting read\n");
608: for (i = 0; i < 8*8192; ++i)
609: bcopy(sc->smem_start, test_buf, 1024);
610: printf("done.\n");
611: }
612: #endif
613:
614: /*
615: * Zero memory and verify that it is clear
616: */
617: bzero(sc->smem_start, memsize);
618:
619: for (i = 0; i < memsize; ++i)
620: if (sc->smem_start[i]) {
621: printf("ed%d: failed to clear shared memory at %x - check configuration\n",
622: isa_dev->id_unit, sc->smem_start + i);
623: return(0);
624: }
625:
626: isa_dev->id_msize = memsize;
627: return(ED_3COM_IO_PORTS);
628: }
629:
630: /*
631: * Install interface into kernel networking data structures
632: */
633: int
634: ed_attach(isa_dev)
635: struct isa_device *isa_dev;
636: {
637: struct ed_softc *sc = &ed_softc[isa_dev->id_unit];
638: struct ifnet *ifp = &sc->arpcom.ac_if;
639: struct ifaddr *ifa;
640: struct sockaddr_dl *sdl;
641:
642: /*
643: * Set interface to stopped condition (reset)
644: */
645: ed_stop(isa_dev->id_unit);
646:
647: /*
648: * Initialize ifnet structure
649: */
650: ifp->if_unit = isa_dev->id_unit;
651: ifp->if_name = "ed" ;
652: ifp->if_mtu = ETHERMTU;
653: ifp->if_init = ed_init;
654: ifp->if_output = ether_output;
655: ifp->if_start = ed_start;
656: ifp->if_ioctl = ed_ioctl;
657: ifp->if_reset = ed_reset;
658: ifp->if_watchdog = ed_watchdog;
659:
660: /*
661: * Set default state for LLC0 flag (used to disable the tranceiver
662: * for AUI operation), based on compile-time config option.
663: */
664: if (isa_dev->id_flags & ED_FLAGS_DISABLE_TRANCEIVER)
665: ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS
666: | IFF_LLC0);
667: else
668: ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS);
669:
670: /*
671: * Attach the interface
672: */
673: if_attach(ifp);
674:
675: /*
676: * Search down the ifa address list looking for the AF_LINK type entry
677: */
678: ifa = ifp->if_addrlist;
679: while ((ifa != 0) && (ifa->ifa_addr != 0) &&
680: (ifa->ifa_addr->sa_family != AF_LINK))
681: ifa = ifa->ifa_next;
682: /*
683: * If we find an AF_LINK type entry we fill in the hardware address.
684: * This is useful for netstat(1) to keep track of which interface
685: * is which.
686: */
687: if ((ifa != 0) && (ifa->ifa_addr != 0)) {
688: /*
689: * Fill in the link-level address for this interface
690: */
691: sdl = (struct sockaddr_dl *)ifa->ifa_addr;
692: sdl->sdl_type = IFT_ETHER;
693: sdl->sdl_alen = ETHER_ADDR_LEN;
694: sdl->sdl_slen = 0;
695: bcopy(sc->arpcom.ac_enaddr, LLADDR(sdl), ETHER_ADDR_LEN);
696: }
697:
698: /*
699: * Print additional info when attached
700: */
701: printf("ed%d: address %s, type %s (%dbit) %s\n", isa_dev->id_unit,
702: ether_sprintf(sc->arpcom.ac_enaddr), sc->type_str,
703: sc->memwidth, ((sc->vendor == ED_VENDOR_3COM) &&
704: (ifp->if_flags & IFF_LLC0)) ? "tranceiver disabled" : "");
705:
706: /*
707: * If BPF is in the kernel, call the attach for it
708: */
709: #if NBPFILTER > 0
710: bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
711: #endif
712:
713: }
714:
715: /*
716: * Reset interface.
717: */
718: int
719: ed_reset(unit)
720: int unit;
721: {
722: int s;
723:
724: s = splnet();
725:
726: /*
727: * Stop interface and re-initialize.
728: */
729: ed_stop(unit);
730: ed_init(unit);
731:
732: s = splx(s);
733: }
734:
735: /*
736: * Take interface offline.
737: */
738: void
739: ed_stop(unit)
740: int unit;
741: {
742: struct ed_softc *sc = &ed_softc[unit];
743: int n = 5000;
744:
745: /*
746: * Stop everything on the interface, and select page 0 registers.
747: */
748: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
749:
750: /*
751: * Wait for interface to enter stopped state, but limit # of checks
752: * to 'n' (about 5ms). It shouldn't even take 5us on modern
753: * DS8390's, but just in case it's an old one.
754: */
755: while (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
756:
757: }
758:
759: /*
760: * Device timeout/watchdog routine. Entered if the device neglects to
761: * generate an interrupt after a transmit has been started on it.
762: */
763: int
764: ed_watchdog(unit)
765: int unit;
766: {
767: log(LOG_ERR, "ed%d: device timeout\n", unit);
768:
769: ed_reset(unit);
770: }
771:
772: /*
773: * Initialize device.
774: */
775: ed_init(unit)
776: int unit;
777: {
778: struct ed_softc *sc = &ed_softc[unit];
779: struct ifnet *ifp = &sc->arpcom.ac_if;
780: int i, s;
781: u_char command;
782:
783:
784: /* address not known */
785: if (ifp->if_addrlist == (struct ifaddr *)0) return;
786:
787: /*
788: * Initialize the NIC in the exact order outlined in the NS manual.
789: * This init procedure is "mandatory"...don't change what or when
790: * things happen.
791: */
792: s = splnet();
793:
794: /* reset transmitter flags */
795: sc->data_buffered = 0;
796: sc->xmit_busy = 0;
797: sc->arpcom.ac_if.if_timer = 0;
798:
799: sc->txb_next = 0;
800:
801: /* This variable is used below - don't move this assignment */
802: sc->next_packet = sc->rec_page_start + 1;
803:
804: /*
805: * Set interface for page 0, Remote DMA complete, Stopped
806: */
807: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
808:
809: if (sc->memwidth == 16) {
810: /*
811: * Set FIFO threshold to 8, No auto-init Remote DMA,
812: * byte order=80x86, word-wide DMA xfers
813: */
814: outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1|ED_DCR_WTS);
815: } else {
816: /*
817: * Same as above, but byte-wide DMA xfers
818: */
819: outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1);
820: }
821:
822: /*
823: * Clear Remote Byte Count Registers
824: */
825: outb(sc->nic_addr + ED_P0_RBCR0, 0);
826: outb(sc->nic_addr + ED_P0_RBCR1, 0);
827:
828: /*
829: * Enable reception of broadcast packets
830: */
831: outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
832:
833: /*
834: * Place NIC in internal loopback mode
835: */
836: outb(sc->nic_addr + ED_P0_TCR, ED_TCR_LB0);
837:
838: /*
839: * Initialize transmit/receive (ring-buffer) Page Start
840: */
841: outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
842: outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
843:
844: /*
845: * Initialize Receiver (ring-buffer) Page Stop and Boundry
846: */
847: outb(sc->nic_addr + ED_P0_PSTOP, sc->rec_page_stop);
848: outb(sc->nic_addr + ED_P0_BNRY, sc->rec_page_start);
849:
850: /*
851: * Clear all interrupts. A '1' in each bit position clears the
852: * corresponding flag.
853: */
854: outb(sc->nic_addr + ED_P0_ISR, 0xff);
855:
856: /*
857: * Enable the following interrupts: receive/transmit complete,
858: * receive/transmit error, and Receiver OverWrite.
859: *
860: * Counter overflow and Remote DMA complete are *not* enabled.
861: */
862: outb(sc->nic_addr + ED_P0_IMR,
863: ED_IMR_PRXE|ED_IMR_PTXE|ED_IMR_RXEE|ED_IMR_TXEE|ED_IMR_OVWE);
864:
865: /*
866: * Program Command Register for page 1
867: */
868: outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
869:
870: /*
871: * Copy out our station address
872: */
873: for (i = 0; i < ETHER_ADDR_LEN; ++i)
874: outb(sc->nic_addr + ED_P1_PAR0 + i, sc->arpcom.ac_enaddr[i]);
875:
876: #if NBPFILTER > 0
877: /*
878: * Initialize multicast address hashing registers to accept
879: * all multicasts (only used when in promiscuous mode)
880: */
881: for (i = 0; i < 8; ++i)
882: outb(sc->nic_addr + ED_P1_MAR0 + i, 0xff);
883: #endif
884:
885: /*
886: * Set Current Page pointer to next_packet (initialized above)
887: */
888: outb(sc->nic_addr + ED_P1_CURR, sc->next_packet);
889:
890: /*
891: * Set Command Register for page 0, Remote DMA complete,
892: * and interface Start.
893: */
894: outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
895:
896: /*
897: * Take interface out of loopback
898: */
899: outb(sc->nic_addr + ED_P0_TCR, 0);
900:
901: /*
902: * If this is a 3Com board, the tranceiver must be software enabled
903: * (there is no settable hardware default).
904: */
905: if (sc->vendor == ED_VENDOR_3COM) {
906: if (ifp->if_flags & IFF_LLC0) {
907: outb(sc->asic_addr + ED_3COM_CR, 0);
908: } else {
909: outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
910: }
911: }
912:
913: /*
914: * Set 'running' flag, and clear output active flag.
915: */
916: ifp->if_flags |= IFF_RUNNING;
917: ifp->if_flags &= ~IFF_OACTIVE;
918:
919: /*
920: * ...and attempt to start output
921: */
922: ed_start(ifp);
923:
924: (void) splx(s);
925: }
926:
927: /*
928: * This routine actually starts the transmission on the interface
929: */
930: static inline void ed_xmit(ifp)
931: struct ifnet *ifp;
932: {
933: struct ed_softc *sc = &ed_softc[ifp->if_unit];
934: u_short len = sc->txb_next_len;
935:
936: /*
937: * Set NIC for page 0 register access
938: */
939: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
940:
941: /*
942: * Set TX buffer start page
943: */
944: outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start +
945: sc->txb_next * ED_TXBUF_SIZE);
946:
947: /*
948: * Set TX length
949: */
950: outb(sc->nic_addr + ED_P0_TBCR0, len & 0xff);
951: outb(sc->nic_addr + ED_P0_TBCR1, len >> 8);
952:
953: /*
954: * Set page 0, Remote DMA complete, Transmit Packet, and *Start*
955: */
956: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
957:
958: sc->xmit_busy = 1;
959: sc->data_buffered = 0;
960:
961: /*
962: * Switch buffers if we are doing double-buffered transmits
963: */
964: if ((sc->txb_next == 0) && (sc->txb_cnt > 1))
965: sc->txb_next = 1;
966: else
967: sc->txb_next = 0;
968:
969: /*
970: * Set a timer just in case we never hear from the board again
971: */
972: ifp->if_timer = 2;
973: }
974:
975: /*
976: * Start output on interface.
977: * We make two assumptions here:
978: * 1) that the current priority is set to splnet _before_ this code
979: * is called *and* is returned to the appropriate priority after
980: * return
981: * 2) that the IFF_OACTIVE flag is checked before this code is called
982: * (i.e. that the output part of the interface is idle)
983: */
984: int
985: ed_start(ifp)
986: struct ifnet *ifp;
987: {
988: struct ed_softc *sc = &ed_softc[ifp->if_unit];
989: struct mbuf *m0, *m;
990: caddr_t buffer;
991: int len;
992: u_char laar_tmp;
993:
994: outloop:
995: /*
996: * See if there is room to send more data (i.e. one or both of the
997: * buffers is empty).
998: */
999: if (sc->data_buffered)
1000: if (sc->xmit_busy) {
1001: /*
1002: * No room. Indicate this to the outside world
1003: * and exit.
1004: */
1005: ifp->if_flags |= IFF_OACTIVE;
1006: return;
1007: } else {
1008: /*
1009: * Data is buffered, but we're not transmitting, so
1010: * start the xmit on the buffered data.
1011: * Note that ed_xmit() resets the data_buffered flag
1012: * before returning.
1013: */
1014: ed_xmit(ifp);
1015: }
1016:
1017: IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
1018: if (m == 0) {
1019: /*
1020: * The following isn't pretty; we are using the !OACTIVE flag to
1021: * indicate to the outside world that we can accept an additional
1022: * packet rather than that the transmitter is _actually_
1023: * active. Indeed, the transmitter may be active, but if we haven't
1024: * filled the secondary buffer with data then we still want to
1025: * accept more.
1026: * Note that it isn't necessary to test the data_buffered flag -
1027: * we wouldn't have tried to de-queue the packet in the first place
1028: * if it was set.
1029: */
1030: ifp->if_flags &= ~IFF_OACTIVE;
1031: return;
1032: }
1033:
1034: /*
1035: * Copy the mbuf chain into the transmit buffer
1036: */
1037: /*
1038: * Enable 16bit access to shared memory on WD/SMC boards
1039: */
1040: if (sc->memwidth == 16)
1041: if (sc->vendor == ED_VENDOR_WD_SMC) {
1042: laar_tmp = inb(sc->asic_addr + ED_WD_LAAR);
1043: outb(sc->asic_addr + ED_WD_LAAR, laar_tmp | ED_WD_LAAR_M16EN);
1044: }
1045:
1046: buffer = sc->smem_start + (sc->txb_next * ED_TXBUF_SIZE * ED_PAGE_SIZE);
1047: len = 0;
1048: for (m0 = m; m != 0; m = m->m_next) {
1049: bcopy(mtod(m, caddr_t), buffer, m->m_len);
1050: buffer += m->m_len;
1051: len += m->m_len;
1052: }
1053:
1054: /*
1055: * Restore previous shared mem access type
1056: */
1057: if (sc->memwidth == 16)
1058: if (sc->vendor == ED_VENDOR_WD_SMC) {
1059: outb(sc->asic_addr + ED_WD_LAAR, laar_tmp);
1060: }
1061:
1062: sc->txb_next_len = MAX(len, ETHER_MIN_LEN);
1063:
1064: if (sc->txb_cnt > 1)
1065: /*
1066: * only set 'buffered' flag if doing multiple buffers
1067: */
1068: sc->data_buffered = 1;
1069:
1070: if (sc->xmit_busy == 0)
1071: ed_xmit(ifp);
1072: /*
1073: * If there is BPF support in the configuration, tap off here.
1074: * The following has support for converting trailer packets
1075: * back to normal.
1076: */
1077: #if NBPFILTER > 0
1078: if (sc->bpf) {
1079: u_short etype;
1080: int off, datasize, resid;
1081: struct ether_header *eh;
1082: struct trailer_header {
1083: u_short ether_type;
1084: u_short ether_residual;
1085: } trailer_header;
1086: char ether_packet[ETHER_MAX_LEN];
1087: char *ep;
1088:
1089: ep = ether_packet;
1090:
1091: /*
1092: * We handle trailers below:
1093: * Copy ether header first, then residual data,
1094: * then data. Put all this in a temporary buffer
1095: * 'ether_packet' and send off to bpf. Since the
1096: * system has generated this packet, we assume
1097: * that all of the offsets in the packet are
1098: * correct; if they're not, the system will almost
1099: * certainly crash in m_copydata.
1100: * We make no assumptions about how the data is
1101: * arranged in the mbuf chain (i.e. how much
1102: * data is in each mbuf, if mbuf clusters are
1103: * used, etc.), which is why we use m_copydata
1104: * to get the ether header rather than assume
1105: * that this is located in the first mbuf.
1106: */
1107: /* copy ether header */
1108: m_copydata(m0, 0, sizeof(struct ether_header), ep);
1109: eh = (struct ether_header *) ep;
1110: ep += sizeof(struct ether_header);
1111: etype = ntohs(eh->ether_type);
1112: if (etype >= ETHERTYPE_TRAIL &&
1113: etype < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
1114: datasize = ((etype - ETHERTYPE_TRAIL) << 9);
1115: off = datasize + sizeof(struct ether_header);
1116:
1117: /* copy trailer_header into a data structure */
1118: m_copydata(m0, off, sizeof(struct trailer_header),
1119: &trailer_header.ether_type);
1120:
1121: /* copy residual data */
1122: m_copydata(m0, off+sizeof(struct trailer_header),
1123: resid = ntohs(trailer_header.ether_residual) -
1124: sizeof(struct trailer_header), ep);
1125: ep += resid;
1126:
1127: /* copy data */
1128: m_copydata(m0, sizeof(struct ether_header),
1129: datasize, ep);
1130: ep += datasize;
1131:
1132: /* restore original ether packet type */
1133: eh->ether_type = trailer_header.ether_type;
1134:
1135: bpf_tap(sc->bpf, ether_packet, ep - ether_packet);
1136: } else
1137: bpf_mtap(sc->bpf, m0);
1138: }
1139: #endif
1140:
1141: m_freem(m0);
1142:
1143: /*
1144: * If we are doing double-buffering, a buffer might be free to
1145: * fill with another packet, so loop back to the top.
1146: */
1147: if (sc->txb_cnt > 1)
1148: goto outloop;
1149: else {
1150: ifp->if_flags |= IFF_OACTIVE;
1151: return;
1152: }
1153: }
1154:
1155: /*
1156: * Ethernet interface receiver interrupt.
1157: */
1158: static inline void /* only called from one place, so may as well integrate */
1159: ed_rint(unit)
1160: int unit;
1161: {
1162: register struct ed_softc *sc = &ed_softc[unit];
1163: u_char boundry, current;
1164: u_short len;
1165: struct ed_ring *packet_ptr;
1166:
1167: /*
1168: * Set NIC to page 1 registers to get 'current' pointer
1169: */
1170: outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
1171:
1172: /*
1173: * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
1174: * it points to where new data has been buffered. The 'CURR'
1175: * (current) register points to the logical end of the ring-buffer
1176: * - i.e. it points to where additional new data will be added.
1177: * We loop here until the logical beginning equals the logical
1178: * end (or in other words, until the ring-buffer is empty).
1179: */
1180: while (sc->next_packet != inb(sc->nic_addr + ED_P1_CURR)) {
1181:
1182: /* get pointer to this buffer header structure */
1183: packet_ptr = (struct ed_ring *)(sc->smem_ring +
1184: (sc->next_packet - sc->rec_page_start) * ED_PAGE_SIZE);
1185:
1186: /*
1187: * The byte count includes the FCS - Frame Check Sequence (a
1188: * 32 bit CRC).
1189: */
1190: len = packet_ptr->count;
1191: if ((len >= ETHER_MIN_LEN) && (len <= ETHER_MAX_LEN)) {
1192: /*
1193: * Go get packet. len - 4 removes CRC from length.
1194: * (packet_ptr + 1) points to data just after the packet ring
1195: * header (+4 bytes)
1196: */
1197: ed_get_packet(sc, (caddr_t)(packet_ptr + 1), len - 4);
1198: ++sc->arpcom.ac_if.if_ipackets;
1199: } else {
1200: /*
1201: * Really BAD...probably indicates that the ring pointers
1202: * are corrupted. Also seen on early rev chips under
1203: * high load - the byte order of the length gets switched.
1204: */
1205: log(LOG_ERR,
1206: "ed%d: shared memory corrupt - invalid packet length %d\n",
1207: unit, len);
1208: ed_reset(unit);
1209: return;
1210: }
1211:
1212: /*
1213: * Update next packet pointer
1214: */
1215: sc->next_packet = packet_ptr->next_packet;
1216:
1217: /*
1218: * Update NIC boundry pointer - being careful to keep it
1219: * one buffer behind. (as recommended by NS databook)
1220: */
1221: boundry = sc->next_packet - 1;
1222: if (boundry < sc->rec_page_start)
1223: boundry = sc->rec_page_stop - 1;
1224:
1225: /*
1226: * Set NIC to page 0 registers to update boundry register
1227: */
1228: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1229:
1230: outb(sc->nic_addr + ED_P0_BNRY, boundry);
1231:
1232: /*
1233: * Set NIC to page 1 registers before looping to top (prepare to
1234: * get 'CURR' current pointer)
1235: */
1236: outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
1237: }
1238: }
1239:
1240: /*
1241: * Ethernet interface interrupt processor
1242: */
1243: int
1244: edintr(unit)
1245: int unit;
1246: {
1247: struct ed_softc *sc = &ed_softc[unit];
1248: u_char isr;
1249:
1250: /*
1251: * Set NIC to page 0 registers
1252: */
1253: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1254:
1255: /*
1256: * loop until there are no more new interrupts
1257: */
1258: while (isr = inb(sc->nic_addr + ED_P0_ISR)) {
1259:
1260: /*
1261: * reset all the bits that we are 'acknowleging'
1262: * by writing a '1' to each bit position that was set
1263: * (writing a '1' *clears* the bit)
1264: */
1265: outb(sc->nic_addr + ED_P0_ISR, isr);
1266:
1267: /*
1268: * Transmit error. If a TX completed with an error, we end up
1269: * throwing the packet away. Really the only error that is
1270: * possible is excessive collisions, and in this case it is
1271: * best to allow the automatic mechanisms of TCP to backoff
1272: * the flow. Of course, with UDP we're screwed, but this is
1273: * expected when a network is heavily loaded.
1274: */
1275: if (isr & ED_ISR_TXE) {
1276: u_char tsr = inb(sc->nic_addr + ED_P0_TSR);
1277: u_char ncr = inb(sc->nic_addr + ED_P0_NCR);
1278:
1279: /*
1280: * Excessive collisions (16)
1281: */
1282: if ((tsr & ED_TSR_ABT) && (ncr == 0)) {
1283: /*
1284: * When collisions total 16, the P0_NCR will
1285: * indicate 0, and the TSR_ABT is set.
1286: */
1287: sc->arpcom.ac_if.if_collisions += 16;
1288: } else
1289: sc->arpcom.ac_if.if_collisions += ncr;
1290:
1291: /*
1292: * update output errors counter
1293: */
1294: ++sc->arpcom.ac_if.if_oerrors;
1295:
1296: /*
1297: * reset tx busy and output active flags
1298: */
1299: sc->xmit_busy = 0;
1300: sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
1301:
1302: /*
1303: * clear watchdog timer
1304: */
1305: sc->arpcom.ac_if.if_timer = 0;
1306: }
1307:
1308:
1309: /*
1310: * Receiver Error. One or more of: CRC error, frame alignment error
1311: * FIFO overrun, or missed packet.
1312: */
1313: if (isr & ED_ISR_RXE) {
1314: ++sc->arpcom.ac_if.if_ierrors;
1315: #ifdef ED_DEBUG
1316: printf("ed%d: receive error %x\n", unit,
1317: inb(sc->nic_addr + ED_P0_RSR));
1318: #endif
1319: }
1320:
1321: /*
1322: * Overwrite warning. In order to make sure that a lockup
1323: * of the local DMA hasn't occurred, we reset and
1324: * re-init the NIC. The NSC manual suggests only a
1325: * partial reset/re-init is necessary - but some
1326: * chips seem to want more. The DMA lockup has been
1327: * seen only with early rev chips - Methinks this
1328: * bug was fixed in later revs. -DG
1329: */
1330: if (isr & ED_ISR_OVW) {
1331: ++sc->arpcom.ac_if.if_ierrors;
1332: log(LOG_WARNING,
1333: "ed%d: warning - receiver ring buffer overrun\n",
1334: unit);
1335: /*
1336: * Stop/reset/re-init NIC
1337: */
1338: ed_reset(unit);
1339: }
1340:
1341: /*
1342: * Transmission completed normally.
1343: */
1344: if (isr & ED_ISR_PTX) {
1345:
1346: /*
1347: * reset tx busy and output active flags
1348: */
1349: sc->xmit_busy = 0;
1350: sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
1351:
1352: /*
1353: * clear watchdog timer
1354: */
1355: sc->arpcom.ac_if.if_timer = 0;
1356:
1357: /*
1358: * Update total number of successfully transmitted
1359: * packets.
1360: */
1361: ++sc->arpcom.ac_if.if_opackets;
1362:
1363: /*
1364: * Add in total number of collisions on last
1365: * transmission.
1366: */
1367: sc->arpcom.ac_if.if_collisions += inb(sc->nic_addr +
1368: ED_P0_TBCR0);
1369: }
1370:
1371: /*
1372: * Receive Completion. Go and get the packet.
1373: * XXX - Doing this on an error is dubious because there
1374: * shouldn't be any data to get (we've configured the
1375: * interface to not accept packets with errors).
1376: */
1377: if (isr & (ED_ISR_PRX|ED_ISR_RXE)) {
1378: /*
1379: * Enable access to shared memory on WD/SMC boards
1380: */
1381: if (sc->memwidth == 16)
1382: if (sc->vendor == ED_VENDOR_WD_SMC) {
1383: outb(sc->asic_addr + ED_WD_LAAR,
1384: inb(sc->asic_addr + ED_WD_LAAR)
1385: | ED_WD_LAAR_M16EN);
1386: }
1387:
1388: ed_rint (unit);
1389:
1390: /*
1391: * Disable access to shared memory
1392: */
1393: if (sc->memwidth == 16)
1394: if (sc->vendor == ED_VENDOR_WD_SMC) {
1395: outb(sc->asic_addr + ED_WD_LAAR,
1396: inb(sc->asic_addr + ED_WD_LAAR)
1397: & ~ED_WD_LAAR_M16EN);
1398: }
1399: }
1400:
1401: /*
1402: * If it looks like the transmitter can take more data,
1403: * attempt to start output on the interface. If data is
1404: * already buffered and ready to go, send it first.
1405: */
1406: if ((sc->arpcom.ac_if.if_flags & IFF_OACTIVE) == 0) {
1407: if (sc->data_buffered)
1408: ed_xmit(&sc->arpcom.ac_if);
1409: ed_start(&sc->arpcom.ac_if);
1410: }
1411:
1412: /*
1413: * return NIC CR to standard state: page 0, remote DMA complete,
1414: * start (toggling the TXP bit off, even if was just set
1415: * in the transmit routine, is *okay* - it is 'edge'
1416: * triggered from low to high)
1417: */
1418: outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
1419:
1420: /*
1421: * If the Network Talley Counters overflow, read them to
1422: * reset them. It appears that old 8390's won't
1423: * clear the ISR flag otherwise - resulting in an
1424: * infinite loop.
1425: */
1426: if (isr & ED_ISR_CNT) {
1427: (void) inb(sc->nic_addr + ED_P0_CNTR0);
1428: (void) inb(sc->nic_addr + ED_P0_CNTR1);
1429: (void) inb(sc->nic_addr + ED_P0_CNTR2);
1430: }
1431: }
1432: }
1433:
1434: /*
1435: * Process an ioctl request. This code needs some work - it looks
1436: * pretty ugly.
1437: */
1438: int
1439: ed_ioctl(ifp, command, data)
1440: register struct ifnet *ifp;
1441: int command;
1442: caddr_t data;
1443: {
1444: register struct ifaddr *ifa = (struct ifaddr *)data;
1445: struct ed_softc *sc = &ed_softc[ifp->if_unit];
1446: struct ifreq *ifr = (struct ifreq *)data;
1447: int s, error = 0;
1448:
1449: s = splnet();
1450:
1451: switch (command) {
1452:
1453: case SIOCSIFADDR:
1454: ifp->if_flags |= IFF_UP;
1455:
1456: switch (ifa->ifa_addr->sa_family) {
1457: #ifdef INET
1458: case AF_INET:
1459: ed_init(ifp->if_unit); /* before arpwhohas */
1460: /*
1461: * See if another station has *our* IP address.
1462: * i.e.: There is an address conflict! If a
1463: * conflict exists, a message is sent to the
1464: * console.
1465: */
1466: ((struct arpcom *)ifp)->ac_ipaddr =
1467: IA_SIN(ifa)->sin_addr;
1468: arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
1469: break;
1470: #endif
1471: #ifdef NS
1472: /*
1473: * XXX - This code is probably wrong
1474: */
1475: case AF_NS:
1476: {
1477: register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
1478:
1479: if (ns_nullhost(*ina))
1480: ina->x_host =
1481: *(union ns_host *)(sc->arpcom.ac_enaddr);
1482: else {
1483: /*
1484: *
1485: */
1486: bcopy((caddr_t)ina->x_host.c_host,
1487: (caddr_t)sc->arpcom.ac_enaddr,
1488: sizeof(sc->arpcom.ac_enaddr));
1489: }
1490: /*
1491: * Set new address
1492: */
1493: ed_init(ifp->if_unit);
1494: break;
1495: }
1496: #endif
1497: default:
1498: ed_init(ifp->if_unit);
1499: break;
1500: }
1501: break;
1502:
1503: case SIOCSIFFLAGS:
1504: /*
1505: * If interface is marked down and it is running, then stop it
1506: */
1507: if (((ifp->if_flags & IFF_UP) == 0) &&
1508: (ifp->if_flags & IFF_RUNNING)) {
1509: ed_stop(ifp->if_unit);
1510: ifp->if_flags &= ~IFF_RUNNING;
1511: } else {
1512: /*
1513: * If interface is marked up and it is stopped, then start it
1514: */
1515: if ((ifp->if_flags & IFF_UP) &&
1516: ((ifp->if_flags & IFF_RUNNING) == 0))
1517: ed_init(ifp->if_unit);
1518: }
1519: #if NBPFILTER > 0
1520: if (ifp->if_flags & IFF_PROMISC) {
1521: /*
1522: * Set promiscuous mode on interface.
1523: * XXX - for multicasts to work, we would need to
1524: * write 1's in all bits of multicast
1525: * hashing array. For now we assume that
1526: * this was done in ed_init().
1527: */
1528: outb(sc->nic_addr + ED_P0_RCR,
1529: ED_RCR_PRO|ED_RCR_AM|ED_RCR_AB);
1530: } else {
1531: /*
1532: * XXX - for multicasts to work, we would need to
1533: * rewrite the multicast hashing array with the
1534: * proper hash (would have been destroyed above).
1535: */
1536: outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
1537: }
1538: #endif
1539: /*
1540: * An unfortunate hack to provide the (required) software control
1541: * of the tranceiver for 3Com boards. The LLC0 flag disables
1542: * the tranceiver if set.
1543: */
1544: if (sc->vendor == ED_VENDOR_3COM) {
1545: if (ifp->if_flags & IFF_LLC0) {
1546: outb(sc->asic_addr + ED_3COM_CR, 0);
1547: } else {
1548: outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
1549: }
1550: }
1551:
1552: break;
1553:
1554: default:
1555: error = EINVAL;
1556: }
1557: (void) splx(s);
1558: return (error);
1559: }
1560:
1561: /*
1562: * Macro to calculate a new address within shared memory when given an offset
1563: * from an address, taking into account ring-wrap.
1564: */
1565: #define ringoffset(sc, start, off, type) \
1566: ((type)( ((caddr_t)(start)+(off) >= (sc)->smem_end) ? \
1567: (((caddr_t)(start)+(off))) - (sc)->smem_end \
1568: + (sc)->smem_ring: \
1569: ((caddr_t)(start)+(off)) ))
1570:
1571: /*
1572: * Retreive packet from shared memory and send to the next level up via
1573: * ether_input(). If there is a BPF listener, give a copy to BPF, too.
1574: */
1575: ed_get_packet(sc, buf, len)
1576: struct ed_softc *sc;
1577: char *buf;
1578: u_short len;
1579: {
1580: struct ether_header *eh;
1581: struct mbuf *m, *head, *ed_ring_to_mbuf();
1582: u_short off;
1583: int resid;
1584: u_short etype;
1585: struct trailer_header {
1586: u_short trail_type;
1587: u_short trail_residual;
1588: } trailer_header;
1589:
1590: /* Allocate a header mbuf */
1591: MGETHDR(m, M_DONTWAIT, MT_DATA);
1592: if (m == 0)
1593: goto bad;
1594: m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
1595: m->m_pkthdr.len = len;
1596: m->m_len = 0;
1597: head = m;
1598:
1599: eh = (struct ether_header *)buf;
1600:
1601: /* The following sillines is to make NFS happy */
1602: #define EROUND ((sizeof(struct ether_header) + 3) & ~3)
1603: #define EOFF (EROUND - sizeof(struct ether_header))
1604:
1605: /*
1606: * The following assumes there is room for
1607: * the ether header in the header mbuf
1608: */
1609: head->m_data += EOFF;
1610: bcopy(buf, mtod(head, caddr_t), sizeof(struct ether_header));
1611: buf += sizeof(struct ether_header);
1612: head->m_len += sizeof(struct ether_header);
1613: len -= sizeof(struct ether_header);
1614:
1615: etype = ntohs((u_short)eh->ether_type);
1616:
1617: /*
1618: * Deal with trailer protocol:
1619: * If trailer protocol, calculate the datasize as 'off',
1620: * which is also the offset to the trailer header.
1621: * Set resid to the amount of packet data following the
1622: * trailer header.
1623: * Finally, copy residual data into mbuf chain.
1624: */
1625: if (etype >= ETHERTYPE_TRAIL &&
1626: etype < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
1627:
1628: off = (etype - ETHERTYPE_TRAIL) << 9;
1629: if ((off + sizeof(struct trailer_header)) > len)
1630: goto bad; /* insanity */
1631:
1632: eh->ether_type = *ringoffset(sc, buf, off, u_short *);
1633: resid = ntohs(*ringoffset(sc, buf, off+2, u_short *));
1634:
1635: if ((off + resid) > len) goto bad; /* insanity */
1636:
1637: resid -= sizeof(struct trailer_header);
1638: if (resid < 0) goto bad; /* insanity */
1639:
1640: m = ed_ring_to_mbuf(sc, ringoffset(sc, buf, off+4, char *), head, resid);
1641: if (m == 0) goto bad;
1642:
1643: len = off;
1644: head->m_pkthdr.len -= 4; /* subtract trailer header */
1645: }
1646:
1647: /*
1648: * Pull packet off interface. Or if this was a trailer packet,
1649: * the data portion is appended.
1650: */
1651: m = ed_ring_to_mbuf(sc, buf, m, len);
1652: if (m == 0) goto bad;
1653:
1654: #if NBPFILTER > 0
1655: /*
1656: * Check if there's a BPF listener on this interface.
1657: * If so, hand off the raw packet to bpf.
1658: */
1659: if (sc->bpf) {
1660: bpf_mtap(sc->bpf, head);
1661:
1662: /*
1663: * Note that the interface cannot be in promiscuous mode if
1664: * there are no BPF listeners. And if we are in promiscuous
1665: * mode, we have to check if this packet is really ours.
1666: *
1667: * XXX This test does not support multicasts.
1668: */
1669: if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
1670: bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
1671: sizeof(eh->ether_dhost)) != 0 &&
1672: bcmp(eh->ether_dhost, etherbroadcastaddr,
1673: sizeof(eh->ether_dhost)) != 0) {
1674:
1675: m_freem(head);
1676: return;
1677: }
1678: }
1679: #endif
1680:
1681: /*
1682: * Fix up data start offset in mbuf to point past ether header
1683: */
1684: m_adj(head, sizeof(struct ether_header));
1685:
1686: /*
1687: * silly ether_input routine needs 'type' in host byte order
1688: */
1689: eh->ether_type = ntohs(eh->ether_type);
1690:
1691: ether_input(&sc->arpcom.ac_if, eh, head);
1692: return;
1693:
1694: bad: if (head)
1695: m_freem(head);
1696: return;
1697: }
1698:
1699: /*
1700: * Supporting routines
1701: */
1702:
1703: /*
1704: * Given a source and destination address, copy 'amount' of a packet from
1705: * the ring buffer into a linear destination buffer. Takes into account
1706: * ring-wrap.
1707: */
1708: static inline char *
1709: ed_ring_copy(sc,src,dst,amount)
1710: struct ed_softc *sc;
1711: char *src;
1712: char *dst;
1713: u_short amount;
1714: {
1715: u_short tmp_amount;
1716:
1717: /* does copy wrap to lower addr in ring buffer? */
1718: if (src + amount > sc->smem_end) {
1719: tmp_amount = sc->smem_end - src;
1720: bcopy(src,dst,tmp_amount); /* copy amount up to end of smem */
1721: amount -= tmp_amount;
1722: src = sc->smem_ring;
1723: dst += tmp_amount;
1724: }
1725:
1726: bcopy(src, dst, amount);
1727:
1728: return(src + amount);
1729: }
1730:
1731: /*
1732: * Copy data from receive buffer to end of mbuf chain
1733: * allocate additional mbufs as needed. return pointer
1734: * to last mbuf in chain.
1735: * sc = ed info (softc)
1736: * src = pointer in ed ring buffer
1737: * dst = pointer to last mbuf in mbuf chain to copy to
1738: * amount = amount of data to copy
1739: */
1740: struct mbuf *
1741: ed_ring_to_mbuf(sc,src,dst,total_len)
1742: struct ed_softc *sc;
1743: char *src;
1744: struct mbuf *dst;
1745: u_short total_len;
1746: {
1747: register struct mbuf *m = dst;
1748:
1749: while (total_len) {
1750: register u_short amount = min(total_len, M_TRAILINGSPACE(m));
1751:
1752: if (amount == 0) { /* no more data in this mbuf, alloc another */
1753: /*
1754: * If there is enough data for an mbuf cluster, attempt
1755: * to allocate one of those, otherwise, a regular
1756: * mbuf will do.
1757: * Note that a regular mbuf is always required, even if
1758: * we get a cluster - getting a cluster does not
1759: * allocate any mbufs, and one is needed to assign
1760: * the cluster to. The mbuf that has a cluster
1761: * extension can not be used to contain data - only
1762: * the cluster can contain data.
1763: */
1764: dst = m;
1765: MGET(m, M_DONTWAIT, MT_DATA);
1766: if (m == 0)
1767: return (0);
1768:
1769: if (total_len >= MINCLSIZE)
1770: MCLGET(m, M_DONTWAIT);
1771:
1772: m->m_len = 0;
1773: dst->m_next = m;
1774: amount = min(total_len, M_TRAILINGSPACE(m));
1775: }
1776:
1777: src = ed_ring_copy(sc, src, mtod(m, caddr_t) + m->m_len, amount);
1778:
1779: m->m_len += amount;
1780: total_len -= amount;
1781:
1782: }
1783: return (m);
1784: }
1785: #endif
1786:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.