This source file includes following definitions.
- egprintpcb
- egprintstat
- egoutPCB
- egreadPCBstat
- egreadPCBready
- egwritePCB
- egreadPCB
- egprobe
- egattach
- eginit
- egrecv
- egstart
- egintr
- egread
- egget
- egioctl
- egreset
- egwatchdog
- egstop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 #include "bpfilter.h"
42
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/mbuf.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
49 #include <sys/syslog.h>
50 #include <sys/systm.h>
51 #include <sys/selinfo.h>
52 #include <sys/device.h>
53
54 #include <net/if.h>
55 #include <net/if_dl.h>
56 #include <net/if_types.h>
57 #include <net/netisr.h>
58
59 #ifdef INET
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in_var.h>
63 #include <netinet/ip.h>
64 #include <netinet/if_ether.h>
65 #endif
66
67 #if NBPFILTER > 0
68 #include <net/bpf.h>
69 #endif
70
71 #include <machine/cpu.h>
72 #include <machine/intr.h>
73
74 #include <dev/isa/isavar.h>
75 #include <dev/isa/if_egreg.h>
76 #include <dev/isa/elink.h>
77
78
79 #ifdef EGDEBUG
80 #define DPRINTF(x) printf x
81 #else
82 #define DPRINTF(x)
83 #endif
84
85 #define EG_INLEN 10
86 #define EG_BUFLEN 0x0670
87
88
89
90
91 struct eg_softc {
92 struct device sc_dev;
93 void *sc_ih;
94 bus_space_tag_t sc_bst;
95 bus_space_handle_t sc_bsh;
96 struct arpcom sc_arpcom;
97 u_char eg_rom_major;
98 u_char eg_rom_minor;
99 short eg_ram;
100 u_char eg_pcb[64];
101 u_char eg_incount;
102 u_char *eg_inbuf;
103 u_char *eg_outbuf;
104 };
105
106 int egprobe(struct device *, void *, void *);
107 void egattach(struct device *, struct device *, void *);
108
109 struct cfattach eg_ca = {
110 sizeof(struct eg_softc), egprobe, egattach
111 };
112
113 struct cfdriver eg_cd = {
114 NULL, "eg", DV_IFNET
115 };
116
117 int egintr(void *);
118 void eginit(struct eg_softc *);
119 int egioctl(struct ifnet *, u_long, caddr_t);
120 void egrecv(struct eg_softc *);
121 void egstart(struct ifnet *);
122 void egwatchdog(struct ifnet *);
123 void egreset(struct eg_softc *);
124 void egread(struct eg_softc *, caddr_t, int);
125 struct mbuf *egget(struct eg_softc *, caddr_t, int);
126 void egstop(struct eg_softc *);
127
128 static __inline void egprintpcb(struct eg_softc *);
129 static __inline void egprintstat(u_char);
130 static int egoutPCB(struct eg_softc *, u_char);
131 static int egreadPCBstat(struct eg_softc *, u_char);
132 static int egreadPCBready(struct eg_softc *);
133 static int egwritePCB(struct eg_softc *);
134 static int egreadPCB(struct eg_softc *);
135
136
137
138
139
140 static __inline void
141 egprintpcb(sc)
142 struct eg_softc *sc;
143 {
144 int i;
145
146 for (i = 0; i < sc->eg_pcb[1] + 2; i++)
147 DPRINTF(("pcb[%2d] = %x\n", i, sc->eg_pcb[i]));
148 }
149
150
151 static __inline void
152 egprintstat(b)
153 u_char b;
154 {
155 DPRINTF(("%s %s %s %s %s %s %s\n",
156 (b & EG_STAT_HCRE)?"HCRE":"",
157 (b & EG_STAT_ACRF)?"ACRF":"",
158 (b & EG_STAT_DIR )?"DIR ":"",
159 (b & EG_STAT_DONE)?"DONE":"",
160 (b & EG_STAT_ASF3)?"ASF3":"",
161 (b & EG_STAT_ASF2)?"ASF2":"",
162 (b & EG_STAT_ASF1)?"ASF1":""));
163 }
164
165 static int
166 egoutPCB(sc, b)
167 struct eg_softc *sc;
168 u_char b;
169 {
170 bus_space_tag_t bst = sc->sc_bst;
171 bus_space_handle_t bsh = sc->sc_bsh;
172 int i;
173
174 for (i = 0; i < 4000; i++) {
175 if (bus_space_read_1(bst, bsh, EG_STATUS) & EG_STAT_HCRE) {
176 bus_space_write_1(bst, bsh, EG_COMMAND, b);
177 return 0;
178 }
179 delay(10);
180 }
181 DPRINTF(("egoutPCB failed\n"));
182 return (1);
183 }
184
185 static int
186 egreadPCBstat(sc, statb)
187 struct eg_softc *sc;
188 u_char statb;
189 {
190 bus_space_tag_t bst = sc->sc_bst;
191 bus_space_handle_t bsh = sc->sc_bsh;
192 int i;
193
194 for (i=0; i < 5000; i++) {
195 if ((bus_space_read_1(bst, bsh, EG_STATUS) & EG_PCB_STAT) !=
196 EG_PCB_NULL)
197 break;
198 delay(10);
199 }
200 if ((bus_space_read_1(bst, bsh, EG_STATUS) & EG_PCB_STAT) == statb)
201 return (0);
202 return (1);
203 }
204
205 static int
206 egreadPCBready(sc)
207 struct eg_softc *sc;
208 {
209 bus_space_tag_t bst = sc->sc_bst;
210 bus_space_handle_t bsh = sc->sc_bsh;
211 int i;
212
213 for (i=0; i < 10000; i++) {
214 if (bus_space_read_1(bst, bsh, EG_STATUS) & EG_STAT_ACRF)
215 return (0);
216 delay(5);
217 }
218 DPRINTF(("PCB read not ready status %02x\n",
219 bus_space_read_1(bst, bsh, EG_STATUS)));
220 return (1);
221 }
222
223 static int
224 egwritePCB(sc)
225 struct eg_softc *sc;
226 {
227 bus_space_tag_t bst = sc->sc_bst;
228 bus_space_handle_t bsh = sc->sc_bsh;
229 int i;
230 u_char len;
231
232 bus_space_write_1(bst, bsh, EG_CONTROL,
233 (bus_space_read_1(bst, bsh, EG_CONTROL) & ~EG_PCB_STAT) |
234 EG_PCB_NULL);
235
236 len = sc->eg_pcb[1] + 2;
237 for (i = 0; i < len; i++)
238 egoutPCB(sc, sc->eg_pcb[i]);
239
240 for (i=0; i < 4000; i++) {
241 if (bus_space_read_1(bst, bsh, EG_STATUS) & EG_STAT_HCRE)
242 break;
243 delay(10);
244 }
245
246 bus_space_write_1(bst, bsh, EG_CONTROL,
247 (bus_space_read_1(bst, bsh, EG_CONTROL) & ~EG_PCB_STAT) |
248 EG_PCB_DONE);
249
250 egoutPCB(sc, len);
251
252 if (egreadPCBstat(sc, EG_PCB_ACCEPT))
253 return (1);
254 return (0);
255 }
256
257 static int
258 egreadPCB(sc)
259 struct eg_softc *sc;
260 {
261 bus_space_tag_t bst = sc->sc_bst;
262 bus_space_handle_t bsh = sc->sc_bsh;
263 int i;
264 u_char b;
265
266 bus_space_write_1(bst, bsh, EG_CONTROL,
267 (bus_space_read_1(bst, bsh, EG_CONTROL) & ~EG_PCB_STAT) |
268 EG_PCB_NULL);
269
270 bzero(sc->eg_pcb, sizeof(sc->eg_pcb));
271
272 if (egreadPCBready(sc))
273 return (1);
274
275 sc->eg_pcb[0] = bus_space_read_1(bst, bsh, EG_COMMAND);
276
277 if (egreadPCBready(sc))
278 return (1);
279
280 sc->eg_pcb[1] = bus_space_read_1(bst, bsh, EG_COMMAND);
281
282 if (sc->eg_pcb[1] > 62) {
283 DPRINTF(("len %d too large\n", sc->eg_pcb[1]));
284 return (1);
285 }
286
287 for (i = 0; i < sc->eg_pcb[1]; i++) {
288 if (egreadPCBready(sc))
289 return (1);
290 sc->eg_pcb[2+i] = bus_space_read_1(bst, bsh, EG_COMMAND);
291 }
292 if (egreadPCBready(sc))
293 return (1);
294 if (egreadPCBstat(sc, EG_PCB_DONE))
295 return (1);
296 if ((b = bus_space_read_1(bst, bsh, EG_COMMAND)) != sc->eg_pcb[1] + 2) {
297 DPRINTF(("%d != %d\n", b, sc->eg_pcb[1] + 2));
298 return (1);
299 }
300
301 bus_space_write_1(bst, bsh, EG_CONTROL,
302 (bus_space_read_1(bst, bsh, EG_CONTROL) & ~EG_PCB_STAT) |
303 EG_PCB_ACCEPT);
304
305 return (0);
306 }
307
308
309
310
311
312 int
313 egprobe(parent, match, aux)
314 struct device *parent;
315 void *match, *aux;
316 {
317 struct eg_softc *sc = match;
318 struct isa_attach_args *ia = aux;
319 bus_space_tag_t bst = sc->sc_bst = ia->ia_iot;
320 bus_space_handle_t bsh;
321 int i;
322
323 if ((ia->ia_iobase & ~0x07f0) != 0) {
324 DPRINTF(("Weird iobase %x\n", ia->ia_iobase));
325 return (0);
326 }
327
328 if (bus_space_map(bst, ia->ia_iobase, EG_IO_PORTS, 0, &bsh)) {
329 DPRINTF(("%s: can't map I/O space\n", sc->sc_dev.dv_xname));
330 return (0);
331 }
332 sc->sc_bsh = bsh;
333
334
335 bus_space_write_1(bst, bsh, EG_CONTROL, EG_CTL_RESET);
336 bus_space_write_1(bst, bsh, EG_CONTROL, 0);
337 for (i = 0; i < 5000; i++) {
338 delay(1000);
339 if ((bus_space_read_1(bst, bsh, EG_STATUS) & EG_PCB_STAT) ==
340 EG_PCB_NULL)
341 break;
342 }
343 if ((bus_space_read_1(bst, bsh, EG_STATUS) & EG_PCB_STAT) !=
344 EG_PCB_NULL) {
345 DPRINTF(("eg: Reset failed\n"));
346 goto lose;
347 }
348 sc->eg_pcb[0] = EG_CMD_GETINFO;
349 sc->eg_pcb[1] = 0;
350 if (egwritePCB(sc) != 0)
351 goto lose;
352
353 if (egreadPCB(sc) != 0) {
354 egprintpcb(sc);
355 goto lose;
356 }
357
358 if (sc->eg_pcb[0] != EG_RSP_GETINFO ||
359 sc->eg_pcb[1] != 0x0a) {
360 egprintpcb(sc);
361 goto lose;
362 }
363 sc->eg_rom_major = sc->eg_pcb[3];
364 sc->eg_rom_minor = sc->eg_pcb[2];
365 sc->eg_ram = sc->eg_pcb[6] | (sc->eg_pcb[7] << 8);
366
367 ia->ia_iosize = 0x08;
368 ia->ia_msize = 0;
369 bus_space_unmap(bst, bsh, EG_IO_PORTS);
370 return (1);
371
372 lose:
373 bus_space_unmap(bst, bsh, EG_IO_PORTS);
374 return (0);
375 }
376
377 void
378 egattach(parent, self, aux)
379 struct device *parent, *self;
380 void *aux;
381 {
382 struct eg_softc *sc = (void *)self;
383 struct isa_attach_args *ia = aux;
384 bus_space_tag_t bst = sc->sc_bst = ia->ia_iot;
385 bus_space_handle_t bsh;
386 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
387
388 if (bus_space_map(bst, ia->ia_iobase, EG_IO_PORTS, 0, &bsh)) {
389 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
390 return;
391 }
392 sc->sc_bsh = bsh;
393
394 egstop(sc);
395
396 sc->eg_pcb[0] = EG_CMD_GETEADDR;
397 sc->eg_pcb[1] = 0;
398 if (egwritePCB(sc) != 0) {
399 DPRINTF(("write error\n"));
400 return;
401 }
402 if (egreadPCB(sc) != 0) {
403 DPRINTF(("read error\n"));
404 egprintpcb(sc);
405 return;
406 }
407
408
409 if (sc->eg_pcb[0] != EG_RSP_GETEADDR || sc->eg_pcb[1] != 0x06) {
410 DPRINTF(("parse error\n"));
411 egprintpcb(sc);
412 return;
413 }
414 bcopy(&sc->eg_pcb[2], sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
415
416 printf(": ROM v%d.%02d %dk address %s\n",
417 sc->eg_rom_major, sc->eg_rom_minor, sc->eg_ram,
418 ether_sprintf(sc->sc_arpcom.ac_enaddr));
419
420 sc->eg_pcb[0] = EG_CMD_SETEADDR;
421 if (egwritePCB(sc) != 0) {
422 DPRINTF(("write error2\n"));
423 return;
424 }
425 if (egreadPCB(sc) != 0) {
426 DPRINTF(("read error2\n"));
427 egprintpcb(sc);
428 return;
429 }
430 if (sc->eg_pcb[0] != EG_RSP_SETEADDR || sc->eg_pcb[1] != 0x02 ||
431 sc->eg_pcb[2] != 0 || sc->eg_pcb[3] != 0) {
432 DPRINTF(("parse error2\n"));
433 egprintpcb(sc);
434 return;
435 }
436
437
438 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
439 ifp->if_softc = sc;
440 ifp->if_start = egstart;
441 ifp->if_ioctl = egioctl;
442 ifp->if_watchdog = egwatchdog;
443 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
444 IFQ_SET_READY(&ifp->if_snd);
445
446
447 if_attach(ifp);
448 ether_ifattach(ifp);
449
450 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
451 IPL_NET, egintr, sc, sc->sc_dev.dv_xname);
452 }
453
454 void
455 eginit(sc)
456 register struct eg_softc *sc;
457 {
458 bus_space_tag_t bst = sc->sc_bst;
459 bus_space_handle_t bsh = sc->sc_bsh;
460 register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
461
462
463 bus_space_write_1(bst, bsh, EG_CONTROL, EG_CTL_FLSH);
464 delay(100);
465 bus_space_write_1(bst, bsh, EG_CONTROL, EG_CTL_ATTN);
466 delay(100);
467 bus_space_write_1(bst, bsh, EG_CONTROL, 0);
468 delay(200);
469
470 sc->eg_pcb[0] = EG_CMD_CONFIG82586;
471 sc->eg_pcb[1] = 2;
472 sc->eg_pcb[2] = 3;
473 sc->eg_pcb[3] = 0;
474 if (egwritePCB(sc) != 0)
475 DPRINTF(("write error3\n"));
476
477 if (egreadPCB(sc) != 0) {
478 DPRINTF(("read error3\n"));
479 egprintpcb(sc);
480 } else if (sc->eg_pcb[2] != 0 || sc->eg_pcb[3] != 0)
481 printf("%s: configure card command failed\n",
482 sc->sc_dev.dv_xname);
483
484 if (sc->eg_inbuf == 0)
485 sc->eg_inbuf = malloc(EG_BUFLEN, M_TEMP, M_NOWAIT);
486 sc->eg_incount = 0;
487
488 if (sc->eg_outbuf == 0)
489 sc->eg_outbuf = malloc(EG_BUFLEN, M_TEMP, M_NOWAIT);
490
491 bus_space_write_1(bst, bsh, EG_CONTROL, EG_CTL_CMDE);
492
493 sc->eg_incount = 0;
494 egrecv(sc);
495
496
497 ifp->if_flags |= IFF_RUNNING;
498 ifp->if_flags &= ~IFF_OACTIVE;
499
500
501 egstart(ifp);
502 }
503
504 void
505 egrecv(sc)
506 struct eg_softc *sc;
507 {
508
509 while (sc->eg_incount < EG_INLEN) {
510 sc->eg_pcb[0] = EG_CMD_RECVPACKET;
511 sc->eg_pcb[1] = 0x08;
512 sc->eg_pcb[2] = 0;
513 sc->eg_pcb[3] = 0;
514 sc->eg_pcb[4] = 0;
515 sc->eg_pcb[5] = 0;
516 sc->eg_pcb[6] = EG_BUFLEN & 0xff;
517 sc->eg_pcb[7] = (EG_BUFLEN >> 8) & 0xff;
518 sc->eg_pcb[8] = 0;
519 sc->eg_pcb[9] = 0;
520 if (egwritePCB(sc) != 0)
521 break;
522 sc->eg_incount++;
523 }
524 }
525
526 void
527 egstart(ifp)
528 struct ifnet *ifp;
529 {
530 struct eg_softc *sc = ifp->if_softc;
531 bus_space_tag_t bst = sc->sc_bst;
532 bus_space_handle_t bsh = sc->sc_bsh;
533 struct mbuf *m0, *m;
534 caddr_t buffer;
535 int len;
536 u_short *ptr;
537 u_int i;
538
539
540 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
541 return;
542
543 loop:
544
545 IFQ_DEQUEUE(&ifp->if_snd, m0);
546 if (m0 == 0)
547 return;
548
549 ifp->if_flags |= IFF_OACTIVE;
550
551
552 if ((m0->m_flags & M_PKTHDR) == 0)
553 panic("egstart: no header mbuf");
554 len = max(m0->m_pkthdr.len, ETHER_MIN_LEN);
555
556 #if NBPFILTER > 0
557 if (ifp->if_bpf)
558 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
559 #endif
560
561 sc->eg_pcb[0] = EG_CMD_SENDPACKET;
562 sc->eg_pcb[1] = 0x06;
563 sc->eg_pcb[2] = 0;
564 sc->eg_pcb[3] = 0;
565 sc->eg_pcb[4] = 0;
566 sc->eg_pcb[5] = 0;
567 sc->eg_pcb[6] = len;
568 sc->eg_pcb[7] = len >> 8;
569 if (egwritePCB(sc) != 0) {
570 DPRINTF(("egwritePCB in egstart failed\n"));
571 ifp->if_oerrors++;
572 ifp->if_flags &= ~IFF_OACTIVE;
573 m_freem(m0);
574 goto loop;
575 }
576
577 buffer = sc->eg_outbuf;
578 for (m = m0; m != 0; m = m->m_next) {
579 bcopy(mtod(m, caddr_t), buffer, m->m_len);
580 buffer += m->m_len;
581 }
582 if (len > m0->m_pkthdr.len)
583 bzero(buffer, len - m0->m_pkthdr.len);
584
585
586 bus_space_write_1(bst, bsh, EG_CONTROL,
587 bus_space_read_1(bst, bsh, EG_CONTROL) & ~EG_CTL_DIR);
588
589 for (ptr = (u_short *)sc->eg_outbuf; len > 0; len -= 2) {
590 bus_space_write_2(bst, bsh, EG_DATA, *ptr++);
591 for (i = 10000; i != 0; i--) {
592 if (bus_space_read_1(bst, bsh, EG_STATUS) & EG_STAT_HRDY)
593 break;
594 delay(10);
595 }
596 if (i == 0) {
597 printf("%s: start failed\n", sc->sc_dev.dv_xname);
598 break;
599 }
600 }
601
602 m_freem(m0);
603 }
604
605 int
606 egintr(arg)
607 void *arg;
608 {
609 struct eg_softc *sc = arg;
610 bus_space_tag_t bst = sc->sc_bst;
611 bus_space_handle_t bsh = sc->sc_bsh;
612 int ret = 0;
613 int i, len;
614 u_short *ptr;
615
616 while (bus_space_read_1(bst, bsh, EG_STATUS) & EG_STAT_ACRF) {
617 ret = 1;
618 egreadPCB(sc);
619 switch (sc->eg_pcb[0]) {
620 case EG_RSP_RECVPACKET:
621 len = sc->eg_pcb[6] | (sc->eg_pcb[7] << 8);
622
623
624 bus_space_write_1(bst, bsh, EG_CONTROL,
625 bus_space_read_1(bst, bsh, EG_CONTROL) |
626 EG_CTL_DIR);
627
628 for (ptr = (u_short *)sc->eg_inbuf; len > 0; len -= 2) {
629 for (i = 10000; i != 0; i--) {
630 if (bus_space_read_1(bst, bsh, EG_STATUS) & EG_STAT_HRDY)
631 break;
632 delay(10);
633 }
634 if (i == 0) {
635 printf("%s: receive failed\n",
636 sc->sc_dev.dv_xname);
637 break;
638 }
639 *ptr++ = bus_space_read_2(bst, bsh, EG_DATA);
640 }
641
642 if (len <= 0) {
643 len = sc->eg_pcb[8] | (sc->eg_pcb[9] << 8);
644 egread(sc, sc->eg_inbuf, len);
645
646 sc->eg_incount--;
647 egrecv(sc);
648 }
649 break;
650
651 case EG_RSP_SENDPACKET:
652 if (sc->eg_pcb[6] || sc->eg_pcb[7]) {
653 DPRINTF(("packet dropped\n"));
654 sc->sc_arpcom.ac_if.if_oerrors++;
655 } else
656 sc->sc_arpcom.ac_if.if_opackets++;
657 sc->sc_arpcom.ac_if.if_collisions +=
658 sc->eg_pcb[8] & 0xf;
659 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
660 egstart(&sc->sc_arpcom.ac_if);
661 break;
662
663 case EG_RSP_GETSTATS:
664 DPRINTF(("Card Statistics\n"));
665 bcopy(&sc->eg_pcb[2], &i, sizeof(i));
666 DPRINTF(("Receive Packets %d\n", i));
667 bcopy(&sc->eg_pcb[6], &i, sizeof(i));
668 DPRINTF(("Transmit Packets %d\n", i));
669 DPRINTF(("CRC errors %d\n", *(short *)&sc->eg_pcb[10]));
670 DPRINTF(("alignment errors %d\n",
671 *(short *)&sc->eg_pcb[12]));
672 DPRINTF(("no resources errors %d\n",
673 *(short *)&sc->eg_pcb[14]));
674 DPRINTF(("overrun errors %d\n",
675 *(short *)&sc->eg_pcb[16]));
676 break;
677
678 default:
679 DPRINTF(("egintr: Unknown response %x??\n",
680 sc->eg_pcb[0]));
681 egprintpcb(sc);
682 break;
683 }
684 }
685
686 return (ret);
687 }
688
689
690
691
692 void
693 egread(sc, buf, len)
694 struct eg_softc *sc;
695 caddr_t buf;
696 int len;
697 {
698 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
699 struct mbuf *m;
700
701 if (len <= sizeof(struct ether_header) ||
702 len > ETHER_MAX_LEN) {
703 printf("%s: invalid packet size %d; dropping\n",
704 sc->sc_dev.dv_xname, len);
705 ifp->if_ierrors++;
706 return;
707 }
708
709
710 m = egget(sc, buf, len);
711 if (m == 0) {
712 ifp->if_ierrors++;
713 return;
714 }
715
716 ifp->if_ipackets++;
717
718 #if NBPFILTER > 0
719
720
721
722
723 if (ifp->if_bpf)
724 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
725 #endif
726
727 ether_input_mbuf(ifp, m);
728 }
729
730
731
732
733 struct mbuf *
734 egget(sc, buf, totlen)
735 struct eg_softc *sc;
736 caddr_t buf;
737 int totlen;
738 {
739 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
740 struct mbuf *top, **mp, *m;
741 int len;
742
743 MGETHDR(m, M_DONTWAIT, MT_DATA);
744 if (m == 0)
745 return (0);
746 m->m_pkthdr.rcvif = ifp;
747 m->m_pkthdr.len = totlen;
748 len = MHLEN;
749 top = 0;
750 mp = ⊤
751
752 while (totlen > 0) {
753 if (top) {
754 MGET(m, M_DONTWAIT, MT_DATA);
755 if (m == 0) {
756 m_freem(top);
757 return (0);
758 }
759 len = MLEN;
760 }
761 if (totlen >= MINCLSIZE) {
762 MCLGET(m, M_DONTWAIT);
763 if (m->m_flags & M_EXT)
764 len = MCLBYTES;
765 }
766 m->m_len = len = min(totlen, len);
767 bcopy((caddr_t)buf, mtod(m, caddr_t), len);
768 buf += len;
769 totlen -= len;
770 *mp = m;
771 mp = &m->m_next;
772 }
773
774 return (top);
775 }
776
777 int
778 egioctl(ifp, cmd, data)
779 register struct ifnet *ifp;
780 u_long cmd;
781 caddr_t data;
782 {
783 struct eg_softc *sc = ifp->if_softc;
784 struct ifaddr *ifa = (struct ifaddr *)data;
785 int s, error = 0;
786
787 s = splnet();
788
789 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
790 splx(s);
791 return (error);
792 }
793
794 switch (cmd) {
795
796 case SIOCSIFADDR:
797 ifp->if_flags |= IFF_UP;
798
799 switch (ifa->ifa_addr->sa_family) {
800 #ifdef INET
801 case AF_INET:
802 eginit(sc);
803 arp_ifinit(&sc->sc_arpcom, ifa);
804 break;
805 #endif
806 default:
807 eginit(sc);
808 break;
809 }
810 break;
811
812 case SIOCSIFFLAGS:
813 if ((ifp->if_flags & IFF_UP) == 0 &&
814 (ifp->if_flags & IFF_RUNNING) != 0) {
815
816
817
818
819 egstop(sc);
820 ifp->if_flags &= ~IFF_RUNNING;
821 } else if ((ifp->if_flags & IFF_UP) != 0 &&
822 (ifp->if_flags & IFF_RUNNING) == 0) {
823
824
825
826
827 eginit(sc);
828 } else {
829 sc->eg_pcb[0] = EG_CMD_GETSTATS;
830 sc->eg_pcb[1] = 0;
831 if (egwritePCB(sc) != 0)
832 DPRINTF(("write error\n"));
833
834
835
836
837
838 }
839 break;
840
841 default:
842 error = EINVAL;
843 break;
844 }
845
846 splx(s);
847 return (error);
848 }
849
850 void
851 egreset(sc)
852 struct eg_softc *sc;
853 {
854 int s;
855
856 DPRINTF(("egreset()\n"));
857 s = splnet();
858 egstop(sc);
859 eginit(sc);
860 splx(s);
861 }
862
863 void
864 egwatchdog(ifp)
865 struct ifnet *ifp;
866 {
867 struct eg_softc *sc = ifp->if_softc;
868
869 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
870 sc->sc_arpcom.ac_if.if_oerrors++;
871
872 egreset(sc);
873 }
874
875 void
876 egstop(sc)
877 register struct eg_softc *sc;
878 {
879 bus_space_tag_t bst = sc->sc_bst;
880 bus_space_handle_t bsh = sc->sc_bsh;
881
882 bus_space_write_1(bst, bsh, EG_CONTROL, 0);
883 }