This source file includes following definitions.
- elprobe
- elattach
- elreset
- elstop
- el_hardreset
- elinit
- elstart
- el_xmit
- elintr
- elread
- elget
- elioctl
- elwatchdog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include "bpfilter.h"
23
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/errno.h>
27 #include <sys/ioctl.h>
28 #include <sys/mbuf.h>
29 #include <sys/socket.h>
30 #include <sys/syslog.h>
31 #include <sys/device.h>
32
33 #include <net/if.h>
34 #include <net/if_dl.h>
35 #include <net/if_types.h>
36
37 #ifdef INET
38 #include <netinet/in.h>
39 #include <netinet/in_systm.h>
40 #include <netinet/in_var.h>
41 #include <netinet/ip.h>
42 #include <netinet/if_ether.h>
43 #endif
44
45 #if NBPFILTER > 0
46 #include <net/bpf.h>
47 #endif
48
49 #include <machine/cpu.h>
50 #include <machine/intr.h>
51 #include <machine/pio.h>
52
53 #include <dev/isa/isavar.h>
54 #include <dev/isa/if_elreg.h>
55
56
57 #ifdef EL_DEBUG
58 #define dprintf(x) printf x
59 #else
60 #define dprintf(x)
61 #endif
62
63
64
65
66 struct el_softc {
67 struct device sc_dev;
68 void *sc_ih;
69
70 struct arpcom sc_arpcom;
71 int sc_iobase;
72 };
73
74
75
76
77 int elintr(void *);
78 void elinit(struct el_softc *);
79 int elioctl(struct ifnet *, u_long, caddr_t);
80 void elstart(struct ifnet *);
81 void elwatchdog(struct ifnet *);
82 void elreset(struct el_softc *);
83 void elstop(struct el_softc *);
84 static int el_xmit(struct el_softc *);
85 void elread(struct el_softc *, int);
86 struct mbuf *elget(struct el_softc *sc, int);
87 static inline void el_hardreset(struct el_softc *);
88
89 int elprobe(struct device *, void *, void *);
90 void elattach(struct device *, struct device *, void *);
91
92 struct cfattach el_ca = {
93 sizeof(struct el_softc), elprobe, elattach
94 };
95
96 struct cfdriver el_cd = {
97 NULL, "el", DV_IFNET
98 };
99
100
101
102
103
104
105
106 int
107 elprobe(parent, match, aux)
108 struct device *parent;
109 void *match, *aux;
110 {
111 struct el_softc *sc = match;
112 struct isa_attach_args *ia = aux;
113 int iobase = ia->ia_iobase;
114 u_char station_addr[ETHER_ADDR_LEN];
115 int i;
116
117
118 if (iobase < 0x280 || iobase > 0x3f0)
119 return 0;
120
121
122 sc->sc_iobase = iobase;
123
124
125
126
127
128 dprintf(("Probing 3c501 at 0x%x...\n", iobase));
129
130
131 dprintf(("Resetting board...\n"));
132 outb(iobase+EL_AC, EL_AC_RESET);
133 delay(5);
134 outb(iobase+EL_AC, 0);
135
136
137 dprintf(("Reading station address...\n"));
138 for (i = 0; i < ETHER_ADDR_LEN; i++) {
139 outb(iobase+EL_GPBL, i);
140 station_addr[i] = inb(iobase+EL_EAW);
141 }
142 dprintf(("Address is %s\n", ether_sprintf(station_addr)));
143
144
145
146
147
148 if (station_addr[0] != 0x02 || station_addr[1] != 0x60 ||
149 station_addr[2] != 0x8c) {
150 dprintf(("Bad vendor code.\n"));
151 return 0;
152 }
153
154 dprintf(("Vendor code ok.\n"));
155
156 bcopy(station_addr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
157
158 ia->ia_iosize = 4;
159 ia->ia_msize = 0;
160 return 1;
161 }
162
163
164
165
166
167
168 void
169 elattach(parent, self, aux)
170 struct device *parent, *self;
171 void *aux;
172 {
173 struct el_softc *sc = (void *)self;
174 struct isa_attach_args *ia = aux;
175 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
176
177 dprintf(("Attaching %s...\n", sc->sc_dev.dv_xname));
178
179
180 elstop(sc);
181
182
183 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
184 ifp->if_softc = sc;
185 ifp->if_start = elstart;
186 ifp->if_ioctl = elioctl;
187 ifp->if_watchdog = elwatchdog;
188 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
189 IFQ_SET_READY(&ifp->if_snd);
190
191
192 dprintf(("Attaching interface...\n"));
193 if_attach(ifp);
194 ether_ifattach(ifp);
195
196
197 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
198
199 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
200 IPL_NET, elintr, sc, sc->sc_dev.dv_xname);
201
202 dprintf(("elattach() finished.\n"));
203 }
204
205
206
207
208 void
209 elreset(sc)
210 struct el_softc *sc;
211 {
212 int s;
213
214 dprintf(("elreset()\n"));
215 s = splnet();
216 elstop(sc);
217 elinit(sc);
218 splx(s);
219 }
220
221
222
223
224 void
225 elstop(sc)
226 struct el_softc *sc;
227 {
228
229 outb(sc->sc_iobase+EL_AC, 0);
230 }
231
232
233
234
235
236 static inline void
237 el_hardreset(sc)
238 struct el_softc *sc;
239 {
240 int iobase = sc->sc_iobase;
241 int i;
242
243 outb(iobase+EL_AC, EL_AC_RESET);
244 delay(5);
245 outb(iobase+EL_AC, 0);
246
247 for (i = 0; i < ETHER_ADDR_LEN; i++)
248 outb(iobase+i, sc->sc_arpcom.ac_enaddr[i]);
249 }
250
251
252
253
254 void
255 elinit(sc)
256 struct el_softc *sc;
257 {
258 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
259 int iobase = sc->sc_iobase;
260
261
262 el_hardreset(sc);
263
264
265 dprintf(("Configuring rx...\n"));
266 if (ifp->if_flags & IFF_PROMISC)
267 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC);
268 else
269 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD);
270 outb(iobase+EL_RBC, 0);
271
272
273 dprintf(("Configuring tx...\n"));
274 outb(iobase+EL_TXC, 0);
275
276
277 dprintf(("Starting reception...\n"));
278 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
279
280
281 ifp->if_flags |= IFF_RUNNING;
282 ifp->if_flags &= ~IFF_OACTIVE;
283
284
285 elstart(ifp);
286 }
287
288
289
290
291
292
293 void
294 elstart(ifp)
295 struct ifnet *ifp;
296 {
297 struct el_softc *sc = ifp->if_softc;
298 int iobase = sc->sc_iobase;
299 struct mbuf *m, *m0;
300 int s, i, off, retries;
301
302 dprintf(("elstart()...\n"));
303 s = splnet();
304
305
306 if ((ifp->if_flags & IFF_OACTIVE) != 0) {
307 splx(s);
308 return;
309 }
310
311 ifp->if_flags |= IFF_OACTIVE;
312
313
314
315
316
317 for (;;) {
318
319 IFQ_DEQUEUE(&ifp->if_snd, m0);
320
321
322 if (m0 == 0)
323 break;
324
325 #if NBPFILTER > 0
326
327 if (ifp->if_bpf)
328 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
329 #endif
330
331
332 outb(iobase+EL_AC, EL_AC_HOST);
333 outb(iobase+EL_RBC, 0);
334
335
336 dprintf(("el: xfr pkt length=%d...\n", m0->m_pkthdr.len));
337 off = EL_BUFSIZ - max(m0->m_pkthdr.len, ETHER_MIN_LEN);
338 outb(iobase+EL_GPBL, off);
339 outb(iobase+EL_GPBH, off >> 8);
340
341
342 for (m = m0; m != 0; m = m->m_next)
343 outsb(iobase+EL_BUF, mtod(m, caddr_t), m->m_len);
344 for (i = 0;
345 i < ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len; i++)
346 outb(iobase+EL_BUF, 0);
347
348 m_freem(m0);
349
350
351 retries = 0;
352 for (;;) {
353 outb(iobase+EL_GPBL, off);
354 outb(iobase+EL_GPBH, off >> 8);
355 if (el_xmit(sc)) {
356 ifp->if_oerrors++;
357 break;
358 }
359
360 i = inb(iobase+EL_TXS);
361 dprintf(("tx status=0x%x\n", i));
362 if ((i & EL_TXS_READY) == 0) {
363 dprintf(("el: err txs=%x\n", i));
364 if (i & (EL_TXS_COLL | EL_TXS_COLL16)) {
365 ifp->if_collisions++;
366 if ((i & EL_TXC_DCOLL16) == 0 &&
367 retries < 15) {
368 retries++;
369 outb(iobase+EL_AC, EL_AC_HOST);
370 }
371 } else {
372 ifp->if_oerrors++;
373 break;
374 }
375 } else {
376 ifp->if_opackets++;
377 break;
378 }
379 }
380
381
382
383
384
385 (void)inb(iobase+EL_AS);
386 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
387 splx(s);
388
389 s = splnet();
390 }
391
392 (void)inb(iobase+EL_AS);
393 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
394 ifp->if_flags &= ~IFF_OACTIVE;
395 splx(s);
396 }
397
398
399
400
401
402
403 static int
404 el_xmit(sc)
405 struct el_softc *sc;
406 {
407 int iobase = sc->sc_iobase;
408 int i;
409
410
411
412
413
414
415
416 dprintf(("el: xmit..."));
417 outb(iobase+EL_AC, EL_AC_TXFRX);
418 i = 20000;
419 while ((inb(iobase+EL_AS) & EL_AS_TXBUSY) && (i > 0))
420 i--;
421 if (i == 0) {
422 dprintf(("tx not ready\n"));
423 return -1;
424 }
425 dprintf(("%d cycles.\n", 20000 - i));
426 return 0;
427 }
428
429
430
431
432 int
433 elintr(arg)
434 void *arg;
435 {
436 register struct el_softc *sc = arg;
437 int iobase = sc->sc_iobase;
438 int rxstat, len;
439
440 dprintf(("elintr: "));
441
442
443 if ((inb(iobase+EL_AS) & EL_AS_RXBUSY) != 0) {
444 (void)inb(iobase+EL_RXC);
445 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
446 return 0;
447 }
448
449 for (;;) {
450 rxstat = inb(iobase+EL_RXS);
451 if (rxstat & EL_RXS_STALE)
452 break;
453
454
455 if ((rxstat & EL_RXS_NOFLOW) == 0) {
456 dprintf(("overflow.\n"));
457 el_hardreset(sc);
458
459 if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC)
460 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_PROMISC);
461 else
462 outb(iobase+EL_RXC, EL_RXC_AGF | EL_RXC_DSHORT | EL_RXC_DDRIB | EL_RXC_DOFLOW | EL_RXC_ABROAD);
463 (void)inb(iobase+EL_AS);
464 outb(iobase+EL_RBC, 0);
465 break;
466 }
467
468
469 len = inb(iobase+EL_RBL);
470 len |= inb(iobase+EL_RBH) << 8;
471 dprintf(("receive len=%d rxstat=%x ", len, rxstat));
472 outb(iobase+EL_AC, EL_AC_HOST);
473
474
475 elread(sc, len);
476
477
478 if ((inb(iobase+EL_AS) & EL_AS_RXBUSY) != 0)
479 break;
480
481 dprintf(("<rescan> "));
482 }
483
484 (void)inb(iobase+EL_RXC);
485 outb(iobase+EL_AC, EL_AC_IRQE | EL_AC_RX);
486 return 1;
487 }
488
489
490
491
492 void
493 elread(sc, len)
494 register struct el_softc *sc;
495 int len;
496 {
497 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
498 struct mbuf *m;
499
500 if (len <= sizeof(struct ether_header) ||
501 len > ETHER_MAX_LEN) {
502 printf("%s: invalid packet size %d; dropping\n",
503 sc->sc_dev.dv_xname, len);
504 ifp->if_ierrors++;
505 return;
506 }
507
508
509 m = elget(sc, len);
510 if (m == 0) {
511 ifp->if_ierrors++;
512 return;
513 }
514
515 ifp->if_ipackets++;
516
517 #if NBPFILTER > 0
518
519
520
521
522 if (ifp->if_bpf)
523 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
524 #endif
525
526 ether_input_mbuf(ifp, m);
527 }
528
529
530
531
532
533
534 struct mbuf *
535 elget(sc, totlen)
536 struct el_softc *sc;
537 int totlen;
538 {
539 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
540 int iobase = sc->sc_iobase;
541 struct mbuf *top, **mp, *m;
542 int len;
543
544 MGETHDR(m, M_DONTWAIT, MT_DATA);
545 if (m == 0)
546 return 0;
547 m->m_pkthdr.rcvif = ifp;
548 m->m_pkthdr.len = totlen;
549 len = MHLEN;
550 top = 0;
551 mp = ⊤
552
553 outb(iobase+EL_GPBL, 0);
554 outb(iobase+EL_GPBH, 0);
555
556 while (totlen > 0) {
557 if (top) {
558 MGET(m, M_DONTWAIT, MT_DATA);
559 if (m == 0) {
560 m_freem(top);
561 return 0;
562 }
563 len = MLEN;
564 }
565 if (totlen >= MINCLSIZE) {
566 MCLGET(m, M_DONTWAIT);
567 if (m->m_flags & M_EXT)
568 len = MCLBYTES;
569 }
570 m->m_len = len = min(totlen, len);
571 insb(iobase+EL_BUF, mtod(m, caddr_t), len);
572 totlen -= len;
573 *mp = m;
574 mp = &m->m_next;
575 }
576
577 outb(iobase+EL_RBC, 0);
578 outb(iobase+EL_AC, EL_AC_RX);
579
580 return top;
581 }
582
583
584
585
586 int
587 elioctl(ifp, cmd, data)
588 register struct ifnet *ifp;
589 u_long cmd;
590 caddr_t data;
591 {
592 struct el_softc *sc = ifp->if_softc;
593 struct ifaddr *ifa = (struct ifaddr *)data;
594 int s, error = 0;
595
596 s = splnet();
597
598 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
599 splx(s);
600 return error;
601 }
602
603 switch (cmd) {
604
605 case SIOCSIFADDR:
606 ifp->if_flags |= IFF_UP;
607
608 switch (ifa->ifa_addr->sa_family) {
609 #ifdef INET
610 case AF_INET:
611 elinit(sc);
612 arp_ifinit(&sc->sc_arpcom, ifa);
613 break;
614 #endif
615 default:
616 elinit(sc);
617 break;
618 }
619 break;
620
621 case SIOCSIFFLAGS:
622 if ((ifp->if_flags & IFF_UP) == 0 &&
623 (ifp->if_flags & IFF_RUNNING) != 0) {
624
625
626
627
628 elstop(sc);
629 ifp->if_flags &= ~IFF_RUNNING;
630 } else if ((ifp->if_flags & IFF_UP) != 0 &&
631 (ifp->if_flags & IFF_RUNNING) == 0) {
632
633
634
635
636 elinit(sc);
637 } else {
638
639
640
641
642 elreset(sc);
643 }
644 break;
645
646 default:
647 error = EINVAL;
648 break;
649 }
650
651 splx(s);
652 return error;
653 }
654
655
656
657
658 void
659 elwatchdog(ifp)
660 struct ifnet *ifp;
661 {
662 struct el_softc *sc = ifp->if_softc;
663
664 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
665 sc->sc_arpcom.ac_if.if_oerrors++;
666
667 elreset(sc);
668 }