This source file includes following definitions.
- ie_setup_config
- ie_ack
- ieprobe
- sl_probe
- el_probe
- ee16_probe
- ieattach
- iewatchdog
- ieintr
- ierint
- ietint
- ether_equal
- check_eh
- ie_buflen
- ie_packet_len
- iexmit
- ieget
- ie_readframe
- ie_drop_packet_buffer
- iestart
- check_ie_present
- ie_find_mem_size
- el_reset_586
- sl_reset_586
- ee16_reset_586
- el_chan_attn
- sl_chan_attn
- ee16_chan_attn
- ee16_read_eeprom
- ee16_eeprom_outbits
- ee16_eeprom_inbits
- ee16_eeprom_clock
- ee16_interrupt_enable
- slel_get_address
- iereset
- command_and_wait
- run_tdr
- iememinit
- mc_setup
- ieinit
- iestop
- ieioctl
- mc_reset
- print_rbd
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 #include "bpfilter.h"
110
111 #include <sys/param.h>
112 #include <sys/systm.h>
113 #include <sys/mbuf.h>
114 #include <sys/buf.h>
115 #include <sys/protosw.h>
116 #include <sys/socket.h>
117 #include <sys/ioctl.h>
118 #include <sys/errno.h>
119 #include <sys/syslog.h>
120 #include <sys/device.h>
121 #include <sys/timeout.h>
122
123 #include <net/if.h>
124 #include <net/if_types.h>
125 #include <net/if_dl.h>
126 #include <net/netisr.h>
127 #include <net/route.h>
128
129 #if NBPFILTER > 0
130 #include <net/bpf.h>
131 #endif
132
133 #ifdef INET
134 #include <netinet/in.h>
135 #include <netinet/in_systm.h>
136 #include <netinet/in_var.h>
137 #include <netinet/ip.h>
138 #include <netinet/if_ether.h>
139 #endif
140
141 #include <machine/cpu.h>
142 #include <machine/bus.h>
143 #include <machine/intr.h>
144
145 #include <dev/isa/isareg.h>
146 #include <dev/isa/isavar.h>
147 #include <i386/isa/isa_machdep.h>
148 #include <dev/ic/i82586reg.h>
149 #include <dev/isa/if_ieatt.h>
150 #include <dev/isa/if_ie507.h>
151 #include <dev/isa/if_iee16.h>
152 #include <dev/isa/elink.h>
153
154 #define IED_RINT 0x01
155 #define IED_TINT 0x02
156 #define IED_RNR 0x04
157 #define IED_CNA 0x08
158 #define IED_READFRAME 0x10
159 #define IED_ENQ 0x20
160 #define IED_XMIT 0x40
161 #define IED_ALL 0x7f
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 #define NFRAMES 16
188 #define NRXBUF 48
189 #define IE_RBUF_SIZE 256
190
191 #define NTXBUF 2
192 #define IE_TBUF_SIZE ETHER_MAX_LEN
193
194
195 enum ie_hardware {
196 IE_STARLAN10,
197 IE_EN100,
198 IE_SLFIBER,
199 IE_3C507,
200 IE_EE16,
201 IE_UNKNOWN
202 };
203
204 const char *ie_hardware_names[] = {
205 "StarLAN 10",
206 "EN100",
207 "StarLAN Fiber",
208 "3C507",
209 "EtherExpress 16",
210 "Unknown"
211 };
212
213
214
215
216 struct ie_softc {
217 struct device sc_dev;
218 void *sc_ih;
219
220 int sc_iobase;
221 caddr_t sc_maddr;
222 u_int sc_msize;
223
224 struct arpcom sc_arpcom;
225
226 void (*reset_586)(struct ie_softc *);
227 void (*chan_attn)(struct ie_softc *);
228
229 enum ie_hardware hard_type;
230 int hard_vers;
231
232 int want_mcsetup;
233 int promisc;
234 volatile struct ie_int_sys_conf_ptr *iscp;
235 volatile struct ie_sys_ctl_block *scb;
236
237 int rfhead, rftail, rbhead, rbtail;
238 volatile struct ie_recv_frame_desc *rframes[NFRAMES];
239 volatile struct ie_recv_buf_desc *rbuffs[NRXBUF];
240 volatile char *cbuffs[NRXBUF];
241
242 int xmit_busy;
243 int xchead, xctail;
244 volatile struct ie_xmit_cmd *xmit_cmds[NTXBUF];
245 volatile struct ie_xmit_buf *xmit_buffs[NTXBUF];
246 u_char *xmit_cbuffs[NTXBUF];
247
248 struct ie_en_addr mcast_addrs[MAXMCAST + 1];
249 int mcast_count;
250
251 u_short irq_encoded;
252
253 #ifdef IEDEBUG
254 int sc_debug;
255 #endif
256 };
257
258 void iewatchdog(struct ifnet *);
259 int ieintr(void *);
260 void iestop(struct ie_softc *);
261 int ieinit(struct ie_softc *);
262 int ieioctl(struct ifnet *, u_long, caddr_t);
263 void iestart(struct ifnet *);
264 static void el_reset_586(struct ie_softc *);
265 static void sl_reset_586(struct ie_softc *);
266 static void el_chan_attn(struct ie_softc *);
267 static void sl_chan_attn(struct ie_softc *);
268 static void slel_get_address(struct ie_softc *);
269
270 static void ee16_reset_586(struct ie_softc *);
271 static void ee16_chan_attn(struct ie_softc *);
272 static void ee16_interrupt_enable(struct ie_softc *);
273 void ee16_eeprom_outbits(struct ie_softc *, int, int);
274 void ee16_eeprom_clock(struct ie_softc *, int);
275 u_short ee16_read_eeprom(struct ie_softc *, int);
276 int ee16_eeprom_inbits(struct ie_softc *);
277
278 void iereset(struct ie_softc *);
279 void ie_readframe(struct ie_softc *, int);
280 void ie_drop_packet_buffer(struct ie_softc *);
281 void ie_find_mem_size(struct ie_softc *);
282 static int command_and_wait(struct ie_softc *, int,
283 void volatile *, int);
284 void ierint(struct ie_softc *);
285 void ietint(struct ie_softc *);
286 void iexmit(struct ie_softc *);
287 struct mbuf *ieget(struct ie_softc *,
288 struct ether_header *, int *);
289 void iememinit(void *, struct ie_softc *);
290 static int mc_setup(struct ie_softc *, void *);
291 static void mc_reset(struct ie_softc *);
292
293 #ifdef IEDEBUG
294 void print_rbd(volatile struct ie_recv_buf_desc *);
295
296 int in_ierint = 0;
297 int in_ietint = 0;
298 #endif
299
300 int ieprobe(struct device *, void *, void *);
301 void ieattach(struct device *, struct device *, void *);
302 int sl_probe(struct ie_softc *, struct isa_attach_args *);
303 int el_probe(struct ie_softc *, struct isa_attach_args *);
304 int ee16_probe(struct ie_softc *, struct isa_attach_args *);
305 int check_ie_present(struct ie_softc *, caddr_t, u_int);
306
307 static __inline void ie_setup_config(volatile struct ie_config_cmd *,
308 int, int);
309 static __inline void ie_ack(struct ie_softc *, u_int);
310 static __inline int ether_equal(u_char *, u_char *);
311 static __inline int check_eh(struct ie_softc *, struct ether_header *,
312 int *);
313 static __inline int ie_buflen(struct ie_softc *, int);
314 static __inline int ie_packet_len(struct ie_softc *);
315
316 static void run_tdr(struct ie_softc *, struct ie_tdr_cmd *);
317
318 struct cfattach ie_isa_ca = {
319 sizeof(struct ie_softc), ieprobe, ieattach
320 };
321
322 struct cfdriver ie_cd = {
323 NULL, "ie", DV_IFNET
324 };
325
326 #define MK_24(base, ptr) ((caddr_t)((u_long)ptr - (u_long)base))
327 #define MK_16(base, ptr) ((u_short)(u_long)MK_24(base, ptr))
328
329 #define PORT sc->sc_iobase
330 #define MEM sc->sc_maddr
331
332
333
334
335
336 static __inline void
337 ie_setup_config(cmd, promiscuous, manchester)
338 volatile struct ie_config_cmd *cmd;
339 int promiscuous, manchester;
340 {
341
342 cmd->ie_config_count = 0x0c;
343 cmd->ie_fifo = 8;
344 cmd->ie_save_bad = 0x40;
345 cmd->ie_addr_len = 0x2e;
346 cmd->ie_priority = 0;
347 cmd->ie_ifs = 0x60;
348 cmd->ie_slot_low = 0;
349 cmd->ie_slot_high = 0xf2;
350 cmd->ie_promisc = promiscuous | manchester << 2;
351 cmd->ie_crs_cdt = 0;
352 cmd->ie_min_len = 64;
353 cmd->ie_junk = 0xff;
354 }
355
356 static __inline void
357 ie_ack(sc, mask)
358 struct ie_softc *sc;
359 u_int mask;
360 {
361 volatile struct ie_sys_ctl_block *scb = sc->scb;
362
363 scb->ie_command = scb->ie_status & mask;
364 (sc->chan_attn)(sc);
365
366 while (scb->ie_command)
367 ;
368 }
369
370 int
371 ieprobe(parent, match, aux)
372 struct device *parent;
373 void *match, *aux;
374 {
375 struct ie_softc *sc = match;
376 struct isa_attach_args *ia = aux;
377
378 if (sl_probe(sc, ia))
379 return 1;
380 if (el_probe(sc, ia))
381 return 1;
382 if (ee16_probe(sc, ia))
383 return 1;
384 return 0;
385 }
386
387 int
388 sl_probe(sc, ia)
389 struct ie_softc *sc;
390 struct isa_attach_args *ia;
391 {
392 u_char c;
393
394 sc->sc_iobase = ia->ia_iobase;
395
396
397 sc->reset_586 = sl_reset_586;
398 sc->chan_attn = sl_chan_attn;
399
400 c = inb(PORT + IEATT_REVISION);
401 switch (SL_BOARD(c)) {
402 case SL10_BOARD:
403 sc->hard_type = IE_STARLAN10;
404 break;
405 case EN100_BOARD:
406 sc->hard_type = IE_EN100;
407 break;
408 case SLFIBER_BOARD:
409 sc->hard_type = IE_SLFIBER;
410 break;
411
412 default:
413
414 #if 0
415 printf("%s: unknown AT&T board type code %d\n",
416 sc->sc_dev.dv_xname, SL_BOARD(c));
417 #endif
418 return 0;
419 }
420
421 sc->hard_vers = SL_REV(c);
422
423 if (ia->ia_irq == IRQUNK || ia->ia_maddr == MADDRUNK) {
424 printf("%s: %s does not have soft configuration\n",
425 sc->sc_dev.dv_xname, ie_hardware_names[sc->hard_type]);
426 return 0;
427 }
428
429
430
431
432 sc->sc_maddr = ISA_HOLE_VADDR(ia->ia_maddr);
433 ie_find_mem_size(sc);
434
435 if (!sc->sc_msize) {
436 printf("%s: can't find shared memory\n", sc->sc_dev.dv_xname);
437 return 0;
438 }
439
440 if (!ia->ia_msize)
441 ia->ia_msize = sc->sc_msize;
442 else if (ia->ia_msize != sc->sc_msize) {
443 printf("%s: msize mismatch; kernel configured %d != board configured %d\n",
444 sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
445 return 0;
446 }
447
448 slel_get_address(sc);
449
450 ia->ia_iosize = 16;
451 return 1;
452 }
453
454 int
455 el_probe(sc, ia)
456 struct ie_softc *sc;
457 struct isa_attach_args *ia;
458 {
459 bus_space_tag_t iot = ia->ia_iot;
460 bus_space_handle_t ioh;
461 u_char c;
462 int i, rval = 0;
463 u_char signature[] = "*3COM*";
464
465 sc->sc_iobase = ia->ia_iobase;
466
467
468 sc->reset_586 = el_reset_586;
469 sc->chan_attn = el_chan_attn;
470
471
472
473
474 if (bus_space_map(iot, ELINK_ID_PORT, 1, 0, &ioh)) {
475 printf("3c507 probe: can't map Etherlink ID port\n");
476 return 0;
477 }
478
479
480
481
482
483 elink_reset(iot, ioh, sc->sc_dev.dv_parent->dv_unit);
484 elink_idseq(iot, ioh, ELINK_507_POLY);
485 elink_idseq(iot, ioh, ELINK_507_POLY);
486 outb(ELINK_ID_PORT, 0xff);
487
488
489 outb(PORT + IE507_CTRL, inb(PORT + IE507_CTRL) & 0xfc);
490 for (i = 0; i < 6; i++)
491 if (inb(PORT + i) != signature[i])
492 goto out;
493
494 c = inb(PORT + IE507_MADDR);
495 if (c & 0x20) {
496 printf("%s: can't map 3C507 RAM in high memory\n",
497 sc->sc_dev.dv_xname);
498 goto out;
499 }
500
501
502 outb(ELINK_ID_PORT, 0x00);
503 elink_idseq(iot, ioh, ELINK_507_POLY);
504 outb(ELINK_ID_PORT, 0x00);
505
506
507 outb(PORT + IE507_CTRL, EL_CTRL_NRST | EL_CTRL_BNK2);
508 i = inb(PORT + 3);
509
510 sc->hard_type = IE_3C507;
511 sc->hard_vers = 10*(i / 16) + (i % 16) - 1;
512
513 i = inb(PORT + IE507_IRQ) & 0x0f;
514
515 if (ia->ia_irq != IRQUNK) {
516 if (ia->ia_irq != i) {
517 printf("%s: irq mismatch; kernel configured %d != board configured %d\n",
518 sc->sc_dev.dv_xname, ia->ia_irq, i);
519 goto out;
520 }
521 } else
522 ia->ia_irq = i;
523
524 i = ((inb(PORT + IE507_MADDR) & 0x1c) << 12) + 0xc0000;
525
526 if (ia->ia_maddr != MADDRUNK) {
527 if (ia->ia_maddr != i) {
528 printf("%s: maddr mismatch; kernel configured %x != board configured %x\n",
529 sc->sc_dev.dv_xname, ia->ia_maddr, i);
530 goto out;
531 }
532 } else
533 ia->ia_maddr = i;
534
535 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
536
537
538
539
540 sc->sc_maddr = ISA_HOLE_VADDR(ia->ia_maddr);
541 ie_find_mem_size(sc);
542
543 if (!sc->sc_msize) {
544 printf("%s: can't find shared memory\n", sc->sc_dev.dv_xname);
545 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
546 goto out;
547 }
548
549 if (!ia->ia_msize)
550 ia->ia_msize = sc->sc_msize;
551 else if (ia->ia_msize != sc->sc_msize) {
552 printf("%s: msize mismatch; kernel configured %d != board configured %d\n",
553 sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
554 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
555 goto out;
556 }
557
558 slel_get_address(sc);
559
560
561 outb(PORT + IE507_ICTRL, 1);
562
563 ia->ia_iosize = 16;
564 rval = 1;
565
566 out:
567 bus_space_unmap(iot, ioh, 1);
568 return rval;
569 }
570
571
572
573 int
574 ee16_probe(sc, ia)
575 struct ie_softc *sc;
576 struct isa_attach_args *ia;
577 {
578 int i;
579 u_short board_id, id_var1, id_var2, checksum = 0;
580 u_short eaddrtemp, irq;
581 u_short pg, adjust, decode, edecode;
582 u_char bart_config;
583
584 short irq_translate[] = {0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0};
585
586
587 sc->reset_586 = ee16_reset_586;
588 sc->chan_attn = ee16_chan_attn;
589
590
591 outb(ia->ia_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
592 outb(ia->ia_iobase + IEE16_ECTRL, 0);
593 delay(240);
594
595
596 board_id = id_var1 = id_var2 = 0;
597 for (i=0; i<4 ; i++) {
598 id_var1 = inb(ia->ia_iobase + IEE16_ID_PORT);
599 id_var2 = ((id_var1 & 0x03) << 2);
600 board_id |= (( id_var1 >> 4) << id_var2);
601 }
602
603 if (board_id != IEE16_ID)
604 return 0;
605
606
607 sc->sc_iobase = ia->ia_iobase;
608 sc->hard_type = IE_EE16;
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631 if ((ia->ia_maddr == MADDRUNK) || (ia->ia_msize == 0)) {
632 i = (ee16_read_eeprom(sc, 6) & 0x00ff ) >> 3;
633 switch(i) {
634 case 0x03:
635 ia->ia_maddr = 0xCC000;
636 break;
637 case 0x06:
638 ia->ia_maddr = 0xD0000;
639 break;
640 case 0x0c:
641 ia->ia_maddr = 0xD4000;
642 break;
643 case 0x18:
644 ia->ia_maddr = 0xD8000;
645 break;
646 default:
647 return 0 ;
648 break;
649 }
650 ia->ia_msize = 0x8000;
651 }
652
653
654 sc->sc_maddr = ISA_HOLE_VADDR(ia->ia_maddr);
655 sc->sc_msize = ia->ia_msize;
656
657
658 outb( PORT + IEE16_ECTRL, IEE16_RESET_586);
659
660
661 for(i=0 ; i< 0x40 ; i++)
662 checksum += ee16_read_eeprom(sc, i);
663
664 if (checksum != IEE16_ID)
665 return 0;
666
667
668
669
670
671
672
673
674
675
676 switch (ia->ia_msize) {
677 case 65536:
678 case 32768:
679 break;
680 case 16384:
681 case 49512:
682 default:
683 printf("ieprobe mapped memory size out of range\n");
684 return 0;
685 break;
686 }
687
688 if ((kvtop(sc->sc_maddr) < 0xC0000) ||
689 (kvtop(sc->sc_maddr) + sc->sc_msize > 0xF0000)) {
690 printf("ieprobe mapped memory address out of range\n");
691 return 0;
692 }
693
694 pg = (kvtop(sc->sc_maddr) & 0x3C000) >> 14;
695 adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
696 decode = ((1 << (sc->sc_msize / 16384)) - 1) << pg;
697 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
698
699
700 outb(PORT + IEE16_MEMDEC, decode & 0xFF);
701
702 outb(PORT + IEE16_MCTRL, adjust);
703
704 outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
705
706 outb(PORT + IEE16_MECTRL, edecode);
707
708
709
710
711
712 bzero(sc->sc_maddr, 32);
713 bzero(sc->sc_maddr, sc->sc_msize);
714
715
716
717
718
719
720
721 irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
722 irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
723 sc->irq_encoded = irq;
724 irq = irq_translate[irq];
725 if (ia->ia_irq != IRQUNK) {
726 if (irq != ia->ia_irq) {
727 #ifdef DIAGNOSTIC
728 printf("\nie%d: fatal: board IRQ %d does not match kernel\n", sc->sc_dev.dv_unit, irq);
729 #endif
730 return 0;
731 }
732 } else
733 ia->ia_irq = irq;
734
735
736
737
738
739 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
740 sc->sc_arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
741 sc->sc_arpcom.ac_enaddr[0] = eaddrtemp >> 8;
742 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
743 sc->sc_arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
744 sc->sc_arpcom.ac_enaddr[2] = eaddrtemp >> 8;
745 eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
746 sc->sc_arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
747 sc->sc_arpcom.ac_enaddr[4] = eaddrtemp >> 8;
748
749
750 outb(PORT + IEE16_IRQ, sc->irq_encoded);
751
752
753 if(sc->hard_type == IE_EE16) {
754 bart_config = inb(PORT + IEE16_CONFIG);
755 bart_config |= IEE16_BART_LOOPBACK;
756 bart_config |= IEE16_BART_MCS16_TEST;
757 outb(PORT + IEE16_CONFIG, bart_config);
758 bart_config = inb(PORT + IEE16_CONFIG);
759 }
760
761 outb(PORT + IEE16_ECTRL, 0);
762 delay(100);
763 if (!check_ie_present(sc, sc->sc_maddr, sc->sc_msize))
764 return 0;
765
766 ia->ia_iosize = 16;
767 return 1;
768 }
769
770
771
772
773 void
774 ieattach(parent, self, aux)
775 struct device *parent, *self;
776 void *aux;
777 {
778 struct ie_softc *sc = (void *)self;
779 struct isa_attach_args *ia = aux;
780 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
781
782 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
783 ifp->if_softc = sc;
784 ifp->if_start = iestart;
785 ifp->if_ioctl = ieioctl;
786 ifp->if_watchdog = iewatchdog;
787 ifp->if_flags =
788 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
789 IFQ_SET_READY(&ifp->if_snd);
790
791
792 if_attach(ifp);
793 ether_ifattach(ifp);
794
795 printf(": address %s, type %s R%d\n",
796 ether_sprintf(sc->sc_arpcom.ac_enaddr),
797 ie_hardware_names[sc->hard_type], sc->hard_vers + 1);
798
799 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
800 IPL_NET, ieintr, sc, sc->sc_dev.dv_xname);
801 }
802
803
804
805
806
807 void
808 iewatchdog(ifp)
809 struct ifnet *ifp;
810 {
811 struct ie_softc *sc = ifp->if_softc;
812
813 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
814 ++sc->sc_arpcom.ac_if.if_oerrors;
815 iereset(sc);
816 }
817
818
819
820
821 int
822 ieintr(arg)
823 void *arg;
824 {
825 struct ie_softc *sc = arg;
826 register u_short status;
827
828
829 if (sc->hard_type == IE_3C507)
830 outb(PORT + IE507_ICTRL, 1);
831
832
833 if (sc->hard_type == IE_EE16)
834 outb(PORT + IEE16_IRQ, sc->irq_encoded);
835
836 status = sc->scb->ie_status & IE_ST_WHENCE;
837 if (status == 0)
838 return 0;
839
840 loop:
841
842 ie_ack(sc, status);
843
844 if (status & (IE_ST_FR | IE_ST_RNR)) {
845 #ifdef IEDEBUG
846 in_ierint++;
847 if (sc->sc_debug & IED_RINT)
848 printf("%s: rint\n", sc->sc_dev.dv_xname);
849 #endif
850 ierint(sc);
851 #ifdef IEDEBUG
852 in_ierint--;
853 #endif
854 }
855
856 if (status & IE_ST_CX) {
857 #ifdef IEDEBUG
858 in_ietint++;
859 if (sc->sc_debug & IED_TINT)
860 printf("%s: tint\n", sc->sc_dev.dv_xname);
861 #endif
862 ietint(sc);
863 #ifdef IEDEBUG
864 in_ietint--;
865 #endif
866 }
867
868 if (status & IE_ST_RNR) {
869 printf("%s: receiver not ready\n", sc->sc_dev.dv_xname);
870 sc->sc_arpcom.ac_if.if_ierrors++;
871 iereset(sc);
872 }
873
874 #ifdef IEDEBUG
875 if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
876 printf("%s: cna\n", sc->sc_dev.dv_xname);
877 #endif
878
879
880 if (sc->hard_type == IE_3C507)
881 outb(PORT + IE507_ICTRL, 1);
882
883 status = sc->scb->ie_status & IE_ST_WHENCE;
884 if (status == 0) {
885
886 if (sc->hard_type == IE_EE16)
887 outb(PORT + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
888 return 1;
889 }
890
891 goto loop;
892 }
893
894
895
896
897 void
898 ierint(sc)
899 struct ie_softc *sc;
900 {
901 volatile struct ie_sys_ctl_block *scb = sc->scb;
902 int i, status;
903 static int timesthru = 1024;
904
905 i = sc->rfhead;
906 for (;;) {
907 status = sc->rframes[i]->ie_fd_status;
908
909 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
910 if (!--timesthru) {
911 sc->sc_arpcom.ac_if.if_ierrors +=
912 scb->ie_err_crc + scb->ie_err_align +
913 scb->ie_err_resource + scb->ie_err_overrun;
914 scb->ie_err_crc = scb->ie_err_align =
915 scb->ie_err_resource = scb->ie_err_overrun =
916 0;
917 timesthru = 1024;
918 }
919 ie_readframe(sc, i);
920 } else {
921 if ((status & IE_FD_RNR) != 0 &&
922 (scb->ie_status & IE_RU_READY) == 0) {
923 sc->rframes[0]->ie_fd_buf_desc =
924 MK_16(MEM, sc->rbuffs[0]);
925 scb->ie_recv_list = MK_16(MEM, sc->rframes[0]);
926 command_and_wait(sc, IE_RU_START, 0, 0);
927 }
928 break;
929 }
930 i = (i + 1) % NFRAMES;
931 }
932 }
933
934
935
936
937
938
939 void
940 ietint(sc)
941 struct ie_softc *sc;
942 {
943 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
944 int status;
945
946 ifp->if_timer = 0;
947 ifp->if_flags &= ~IFF_OACTIVE;
948
949 status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
950
951 if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
952 printf("ietint: command still busy!\n");
953
954 if (status & IE_STAT_OK) {
955 ifp->if_opackets++;
956 ifp->if_collisions += status & IE_XS_MAXCOLL;
957 } else {
958 ifp->if_oerrors++;
959
960
961
962
963
964 if (status & IE_STAT_ABORT)
965 printf("%s: send aborted\n", sc->sc_dev.dv_xname);
966 else if (status & IE_XS_LATECOLL)
967 printf("%s: late collision\n", sc->sc_dev.dv_xname);
968 else if (status & IE_XS_NOCARRIER)
969 printf("%s: no carrier\n", sc->sc_dev.dv_xname);
970 else if (status & IE_XS_LOSTCTS)
971 printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
972 else if (status & IE_XS_UNDERRUN)
973 printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
974 else if (status & IE_XS_EXCMAX) {
975 printf("%s: too many collisions\n", sc->sc_dev.dv_xname);
976 ifp->if_collisions += 16;
977 }
978 }
979
980
981
982
983
984
985 if (sc->want_mcsetup) {
986 mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
987 sc->want_mcsetup = 0;
988 }
989
990
991 sc->xmit_busy--;
992 sc->xctail = (sc->xctail + 1) % NTXBUF;
993
994
995 if (sc->xmit_busy > 0)
996 iexmit(sc);
997
998 iestart(ifp);
999 }
1000
1001
1002
1003
1004
1005 static __inline int
1006 ether_equal(one, two)
1007 u_char *one, *two;
1008 {
1009
1010 if (one[0] != two[0] || one[1] != two[1] || one[2] != two[2] ||
1011 one[3] != two[3] || one[4] != two[4] || one[5] != two[5])
1012 return 0;
1013 return 1;
1014 }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 static __inline int
1029 check_eh(sc, eh, to_bpf)
1030 struct ie_softc *sc;
1031 struct ether_header *eh;
1032 int *to_bpf;
1033 {
1034 int i;
1035
1036 switch (sc->promisc) {
1037 case IFF_ALLMULTI:
1038
1039
1040
1041
1042 #if NBPFILTER > 0
1043 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
1044 #endif
1045 if (eh->ether_dhost[0] & 1)
1046 return 1;
1047 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
1048 return 1;
1049 return 0;
1050
1051 case IFF_PROMISC:
1052
1053
1054
1055 #if NBPFILTER > 0
1056 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) ||
1057 (sc->sc_arpcom.ac_if.if_bridge != NULL);
1058 #else
1059 *to_bpf = (sc->sc_arpcom.ac_if.if_bridge != NULL);
1060 #endif
1061
1062 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
1063 return 1;
1064
1065 #if NBPFILTER > 0
1066 if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge == NULL)
1067 *to_bpf = 2;
1068 #endif
1069
1070
1071
1072
1073 if (!(eh->ether_dhost[0] & 1))
1074 return 1;
1075
1076
1077
1078
1079
1080 for (i = 0; i < sc->mcast_count; i++) {
1081 if (ether_equal(eh->ether_dhost, (u_char *)&sc->mcast_addrs[i])) {
1082 #if NBPFILTER > 0
1083 if (*to_bpf)
1084 *to_bpf = 1;
1085 #endif
1086 return 1;
1087 }
1088 }
1089 return 1;
1090
1091 case IFF_ALLMULTI | IFF_PROMISC:
1092
1093
1094
1095
1096 #if NBPFILTER > 0
1097 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) ||
1098 (sc->sc_arpcom.ac_if.if_bridge != NULL);
1099 #else
1100 *to_bpf = (sc->sc_arpcom.ac_if.if_bridge != NULL);
1101 #endif
1102
1103 if (eh->ether_dhost[0] & 1)
1104 return 1;
1105
1106
1107 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
1108 return 1;
1109
1110
1111 #if NBPFILTER > 0
1112 if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge == NULL)
1113 *to_bpf = 2;
1114 #endif
1115 return 1;
1116
1117 case 0:
1118
1119
1120
1121
1122
1123
1124
1125
1126 #if NBPFILTER > 0
1127 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
1128 #endif
1129 return 1;
1130 }
1131
1132 #ifdef DIAGNOSTIC
1133 panic("check_eh: impossible");
1134 #endif
1135 return 0;
1136 }
1137
1138
1139
1140
1141
1142
1143 static __inline int
1144 ie_buflen(sc, head)
1145 struct ie_softc *sc;
1146 int head;
1147 {
1148
1149 return (sc->rbuffs[head]->ie_rbd_actual
1150 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
1151 }
1152
1153 static __inline int
1154 ie_packet_len(sc)
1155 struct ie_softc *sc;
1156 {
1157 int i;
1158 int head = sc->rbhead;
1159 int acc = 0;
1160
1161 do {
1162 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED))
1163 return -1;
1164
1165 i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
1166
1167 acc += ie_buflen(sc, head);
1168 head = (head + 1) % NRXBUF;
1169 } while (!i);
1170
1171 return acc;
1172 }
1173
1174
1175
1176
1177
1178
1179 void
1180 iexmit(sc)
1181 struct ie_softc *sc;
1182 {
1183
1184 #ifdef IEDEBUG
1185 if (sc->sc_debug & IED_XMIT)
1186 printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname,
1187 sc->xctail);
1188 #endif
1189
1190 #if NBPFILTER > 0
1191
1192
1193
1194
1195 if (sc->sc_arpcom.ac_if.if_bpf)
1196 bpf_tap(sc->sc_arpcom.ac_if.if_bpf,
1197 sc->xmit_cbuffs[sc->xctail],
1198 sc->xmit_buffs[sc->xctail]->ie_xmit_flags,
1199 BPF_DIRECTION_OUT);
1200 #endif
1201
1202 sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
1203 sc->xmit_buffs[sc->xctail]->ie_xmit_next = 0xffff;
1204 sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
1205 MK_24(MEM, sc->xmit_cbuffs[sc->xctail]);
1206
1207 sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = 0xffff;
1208 sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
1209 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
1210
1211 sc->xmit_cmds[sc->xctail]->ie_xmit_status = 0;
1212 sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
1213 MK_16(MEM, sc->xmit_buffs[sc->xctail]);
1214
1215 sc->scb->ie_command_list = MK_16(MEM, sc->xmit_cmds[sc->xctail]);
1216 command_and_wait(sc, IE_CU_START, 0, 0);
1217
1218 sc->sc_arpcom.ac_if.if_timer = 5;
1219 }
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231 struct mbuf *
1232 ieget(sc, ehp, to_bpf)
1233 struct ie_softc *sc;
1234 struct ether_header *ehp;
1235 int *to_bpf;
1236 {
1237 struct mbuf *top, **mp, *m;
1238 int len, totlen, resid;
1239 int thisrboff, thismboff;
1240 int head;
1241
1242 resid = totlen = ie_packet_len(sc);
1243 if (totlen <= 0)
1244 return 0;
1245
1246 head = sc->rbhead;
1247
1248
1249
1250
1251 bcopy((caddr_t)sc->cbuffs[head], (caddr_t)ehp, sizeof *ehp);
1252
1253
1254
1255
1256
1257
1258
1259
1260 if (!check_eh(sc, ehp, to_bpf)) {
1261 sc->sc_arpcom.ac_if.if_ierrors--;
1262 return 0;
1263 }
1264
1265 MGETHDR(m, M_DONTWAIT, MT_DATA);
1266 if (m == 0)
1267 return 0;
1268 m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
1269 m->m_pkthdr.len = totlen;
1270 len = MHLEN;
1271 top = 0;
1272 mp = ⊤
1273
1274
1275
1276
1277
1278 while (totlen > 0) {
1279 if (top) {
1280 MGET(m, M_DONTWAIT, MT_DATA);
1281 if (m == 0) {
1282 m_freem(top);
1283 return 0;
1284 }
1285 len = MLEN;
1286 }
1287 if (totlen >= MINCLSIZE) {
1288 MCLGET(m, M_DONTWAIT);
1289 if (m->m_flags & M_EXT)
1290 len = MCLBYTES;
1291 }
1292 m->m_len = len = min(totlen, len);
1293 totlen -= len;
1294 *mp = m;
1295 mp = &m->m_next;
1296 }
1297
1298 m = top;
1299 thisrboff = 0;
1300 thismboff = 0;
1301
1302
1303
1304
1305
1306
1307 while (resid > 0) {
1308 int thisrblen = ie_buflen(sc, head) - thisrboff,
1309 thismblen = m->m_len - thismboff;
1310 len = min(thisrblen, thismblen);
1311
1312 bcopy((caddr_t)(sc->cbuffs[head] + thisrboff),
1313 mtod(m, caddr_t) + thismboff, (u_int)len);
1314 resid -= len;
1315
1316 if (len == thismblen) {
1317 m = m->m_next;
1318 thismboff = 0;
1319 } else
1320 thismboff += len;
1321
1322 if (len == thisrblen) {
1323 head = (head + 1) % NRXBUF;
1324 thisrboff = 0;
1325 } else
1326 thisrboff += len;
1327 }
1328
1329
1330
1331
1332
1333
1334 return top;
1335 }
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346 void
1347 ie_readframe(sc, num)
1348 struct ie_softc *sc;
1349 int num;
1350 {
1351 int status;
1352 struct mbuf *m = 0;
1353 struct ether_header eh;
1354 #if NBPFILTER > 0
1355 int bpf_gets_it = 0;
1356 #endif
1357
1358 status = sc->rframes[num]->ie_fd_status;
1359
1360
1361 sc->rframes[num]->ie_fd_status = 0;
1362 sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
1363 sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
1364 sc->rftail = (sc->rftail + 1) % NFRAMES;
1365 sc->rfhead = (sc->rfhead + 1) % NFRAMES;
1366
1367 if (status & IE_FD_OK) {
1368 #if NBPFILTER > 0
1369 m = ieget(sc, &eh, &bpf_gets_it);
1370 #else
1371 m = ieget(sc, &eh, 0);
1372 #endif
1373 ie_drop_packet_buffer(sc);
1374 }
1375 if (m == 0) {
1376 sc->sc_arpcom.ac_if.if_ierrors++;
1377 return;
1378 }
1379
1380 #ifdef IEDEBUG
1381 if (sc->sc_debug & IED_READFRAME)
1382 printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
1383 ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
1384 #endif
1385
1386 #if NBPFILTER > 0
1387
1388 if (bpf_gets_it) {
1389
1390 bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, m, BPF_DIRECTION_IN);
1391
1392
1393
1394
1395
1396
1397
1398 if (bpf_gets_it == 2) {
1399 m_freem(m);
1400 return;
1401 }
1402 }
1403 #endif
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416 ether_input_mbuf(&sc->sc_arpcom.ac_if, m);
1417 sc->sc_arpcom.ac_if.if_ipackets++;
1418 }
1419
1420 void
1421 ie_drop_packet_buffer(sc)
1422 struct ie_softc *sc;
1423 {
1424 int i;
1425
1426 do {
1427
1428
1429
1430
1431 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
1432 #ifdef IEDEBUG
1433 print_rbd(sc->rbuffs[sc->rbhead]);
1434 #endif
1435 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
1436 sc->sc_dev.dv_xname, sc->rbhead);
1437 iereset(sc);
1438 return;
1439 }
1440
1441 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
1442
1443 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
1444 sc->rbuffs[sc->rbhead]->ie_rbd_actual = 0;
1445 sc->rbhead = (sc->rbhead + 1) % NRXBUF;
1446 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
1447 sc->rbtail = (sc->rbtail + 1) % NRXBUF;
1448 } while (!i);
1449 }
1450
1451
1452
1453
1454 void
1455 iestart(ifp)
1456 struct ifnet *ifp;
1457 {
1458 struct ie_softc *sc = ifp->if_softc;
1459 struct mbuf *m0, *m;
1460 u_char *buffer;
1461 u_short len;
1462
1463 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1464 return;
1465
1466 for (;;) {
1467 if (sc->xmit_busy == NTXBUF) {
1468 ifp->if_flags |= IFF_OACTIVE;
1469 break;
1470 }
1471
1472 IFQ_DEQUEUE(&ifp->if_snd, m0);
1473 if (m0 == 0)
1474 break;
1475
1476
1477 if ((m0->m_flags & M_PKTHDR) == 0)
1478 panic("iestart: no header mbuf");
1479
1480 #if NBPFILTER > 0
1481
1482 if (ifp->if_bpf)
1483 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1484 #endif
1485
1486 #ifdef IEDEBUG
1487 if (sc->sc_debug & IED_ENQ)
1488 printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
1489 sc->xchead);
1490 #endif
1491
1492 len = 0;
1493 buffer = sc->xmit_cbuffs[sc->xchead];
1494
1495 for (m = m0; m != NULL && (len + m->m_len) < IE_TBUF_SIZE;
1496 m = m->m_next) {
1497 bcopy(mtod(m, caddr_t), buffer, m->m_len);
1498 buffer += m->m_len;
1499 len += m->m_len;
1500 }
1501 if (m != NULL)
1502 printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
1503
1504 m_freem(m0);
1505
1506 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1507 bzero(buffer, ETHER_MIN_LEN - ETHER_CRC_LEN - len);
1508 len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1509 buffer += ETHER_MIN_LEN - ETHER_CRC_LEN;
1510 }
1511
1512 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = len;
1513
1514
1515 if (sc->xmit_busy == 0)
1516 iexmit(sc);
1517
1518 sc->xchead = (sc->xchead + 1) % NTXBUF;
1519 sc->xmit_busy++;
1520 }
1521 }
1522
1523
1524
1525
1526 int
1527 check_ie_present(sc, where, size)
1528 struct ie_softc *sc;
1529 caddr_t where;
1530 u_int size;
1531 {
1532 volatile struct ie_sys_conf_ptr *scp;
1533 volatile struct ie_int_sys_conf_ptr *iscp;
1534 volatile struct ie_sys_ctl_block *scb;
1535 u_long realbase;
1536 int s;
1537
1538 s = splnet();
1539
1540 realbase = (u_long)where + size - (1 << 24);
1541
1542 scp = (volatile struct ie_sys_conf_ptr *)(realbase + IE_SCP_ADDR);
1543 bzero((char *)scp, sizeof *scp);
1544
1545
1546
1547
1548
1549
1550
1551 iscp = (volatile struct ie_int_sys_conf_ptr *)where;
1552 bzero((char *)iscp, sizeof *iscp);
1553
1554 scb = (volatile struct ie_sys_ctl_block *)where;
1555 bzero((char *)scb, sizeof *scb);
1556
1557 scp->ie_bus_use = 0;
1558 scp->ie_iscp_ptr = (caddr_t)((volatile caddr_t)iscp -
1559 (volatile caddr_t)realbase);
1560
1561 iscp->ie_busy = 1;
1562 iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
1563
1564 (sc->reset_586)(sc);
1565 (sc->chan_attn)(sc);
1566
1567 delay(100);
1568
1569 if (iscp->ie_busy) {
1570 splx(s);
1571 return 0;
1572 }
1573
1574
1575
1576
1577
1578 iscp = (void *)ALIGN(realbase + IE_SCP_ADDR - sizeof(*iscp));
1579 bzero((char *)iscp, sizeof *iscp);
1580
1581 scp->ie_iscp_ptr = (caddr_t)((caddr_t)iscp - (caddr_t)realbase);
1582
1583 iscp->ie_busy = 1;
1584 iscp->ie_scb_offset = MK_16(realbase, scb);
1585
1586 (sc->reset_586)(sc);
1587 (sc->chan_attn)(sc);
1588
1589 delay(100);
1590
1591 if (iscp->ie_busy) {
1592 splx(s);
1593 return 0;
1594 }
1595
1596 sc->sc_msize = size;
1597 sc->sc_maddr = (caddr_t)realbase;
1598
1599 sc->iscp = iscp;
1600 sc->scb = scb;
1601
1602
1603
1604
1605 ie_ack(sc, IE_ST_WHENCE);
1606 splx(s);
1607
1608 return 1;
1609 }
1610
1611
1612
1613
1614
1615 void
1616 ie_find_mem_size(sc)
1617 struct ie_softc *sc;
1618 {
1619 u_int size;
1620
1621 sc->sc_msize = 0;
1622
1623 for (size = 65536; size >= 16384; size -= 16384)
1624 if (check_ie_present(sc, sc->sc_maddr, size))
1625 return;
1626
1627 return;
1628 }
1629
1630 void
1631 el_reset_586(sc)
1632 struct ie_softc *sc;
1633 {
1634
1635 outb(PORT + IE507_CTRL, EL_CTRL_RESET);
1636 delay(100);
1637 outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
1638 delay(100);
1639 }
1640
1641 void
1642 sl_reset_586(sc)
1643 struct ie_softc *sc;
1644 {
1645
1646 outb(PORT + IEATT_RESET, 0);
1647 }
1648
1649 void
1650 ee16_reset_586(sc)
1651 struct ie_softc *sc;
1652 {
1653
1654 outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
1655 delay(100);
1656 outb(PORT + IEE16_ECTRL, 0);
1657 delay(100);
1658 }
1659
1660 void
1661 el_chan_attn(sc)
1662 struct ie_softc *sc;
1663 {
1664
1665 outb(PORT + IE507_ATTN, 1);
1666 }
1667
1668 void
1669 sl_chan_attn(sc)
1670 struct ie_softc *sc;
1671 {
1672
1673 outb(PORT + IEATT_ATTN, 0);
1674 }
1675
1676 void
1677 ee16_chan_attn(sc)
1678 struct ie_softc *sc;
1679 {
1680 outb(PORT + IEE16_ATTN, 0);
1681 }
1682
1683 u_short
1684 ee16_read_eeprom(sc, location)
1685 struct ie_softc *sc;
1686 int location;
1687 {
1688 int ectrl, edata;
1689
1690 ectrl = inb(PORT + IEE16_ECTRL);
1691 ectrl &= IEE16_ECTRL_MASK;
1692 ectrl |= IEE16_ECTRL_EECS;
1693 outb(PORT + IEE16_ECTRL, ectrl);
1694
1695 ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
1696 ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
1697 edata = ee16_eeprom_inbits(sc);
1698 ectrl = inb(PORT + IEE16_ECTRL);
1699 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
1700 outb(PORT + IEE16_ECTRL, ectrl);
1701 ee16_eeprom_clock(sc, 1);
1702 ee16_eeprom_clock(sc, 0);
1703 return edata;
1704 }
1705
1706 void
1707 ee16_eeprom_outbits(sc, edata, count)
1708 struct ie_softc *sc;
1709 int edata, count;
1710 {
1711 int ectrl, i;
1712
1713 ectrl = inb(PORT + IEE16_ECTRL);
1714 ectrl &= ~IEE16_RESET_ASIC;
1715 for (i = count - 1; i >= 0; i--) {
1716 ectrl &= ~IEE16_ECTRL_EEDI;
1717 if (edata & (1 << i)) {
1718 ectrl |= IEE16_ECTRL_EEDI;
1719 }
1720 outb(PORT + IEE16_ECTRL, ectrl);
1721 delay(1);
1722 ee16_eeprom_clock(sc, 1);
1723 ee16_eeprom_clock(sc, 0);
1724 }
1725 ectrl &= ~IEE16_ECTRL_EEDI;
1726 outb(PORT + IEE16_ECTRL, ectrl);
1727 delay(1);
1728 }
1729
1730 int
1731 ee16_eeprom_inbits(sc)
1732 struct ie_softc *sc;
1733 {
1734 int ectrl, edata, i;
1735
1736 ectrl = inb(PORT + IEE16_ECTRL);
1737 ectrl &= ~IEE16_RESET_ASIC;
1738 for (edata = 0, i = 0; i < 16; i++) {
1739 edata = edata << 1;
1740 ee16_eeprom_clock(sc, 1);
1741 ectrl = inb(PORT + IEE16_ECTRL);
1742 if (ectrl & IEE16_ECTRL_EEDO) {
1743 edata |= 1;
1744 }
1745 ee16_eeprom_clock(sc, 0);
1746 }
1747 return (edata);
1748 }
1749
1750 void
1751 ee16_eeprom_clock(sc, state)
1752 struct ie_softc *sc;
1753 int state;
1754 {
1755 int ectrl;
1756
1757 ectrl = inb(PORT + IEE16_ECTRL);
1758 ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
1759 if (state) {
1760 ectrl |= IEE16_ECTRL_EESK;
1761 }
1762 outb(PORT + IEE16_ECTRL, ectrl);
1763 delay(9);
1764 }
1765
1766 static inline void
1767 ee16_interrupt_enable(sc)
1768 struct ie_softc *sc;
1769 {
1770 delay(100);
1771 outb(PORT + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
1772 delay(100);
1773 }
1774 void
1775 slel_get_address(sc)
1776 struct ie_softc *sc;
1777 {
1778 u_char *addr = sc->sc_arpcom.ac_enaddr;
1779 int i;
1780
1781 for (i = 0; i < ETHER_ADDR_LEN; i++)
1782 addr[i] = inb(PORT + i);
1783 }
1784
1785 void
1786 iereset(sc)
1787 struct ie_softc *sc;
1788 {
1789 int s = splnet();
1790
1791 iestop(sc);
1792
1793
1794
1795
1796 if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
1797 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
1798
1799 if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
1800 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
1801
1802 ieinit(sc);
1803
1804 splx(s);
1805 }
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815 static int
1816 command_and_wait(sc, cmd, pcmd, mask)
1817 struct ie_softc *sc;
1818 int cmd;
1819 volatile void *pcmd;
1820 int mask;
1821 {
1822 volatile struct ie_cmd_common *cc = pcmd;
1823 volatile struct ie_sys_ctl_block *scb = sc->scb;
1824 int i;
1825
1826 scb->ie_command = (u_short)cmd;
1827
1828 if (IE_ACTION_COMMAND(cmd) && pcmd) {
1829 (sc->chan_attn)(sc);
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841 for (i = 36900; i--; DELAY(10))
1842 if ((cc->ie_cmd_status & mask))
1843 break;
1844
1845 return i < 0;
1846 } else {
1847
1848
1849
1850 (sc->chan_attn)(sc);
1851
1852 while (scb->ie_command)
1853 ;
1854
1855 return 0;
1856 }
1857 }
1858
1859
1860
1861
1862 static void
1863 run_tdr(sc, cmd)
1864 struct ie_softc *sc;
1865 struct ie_tdr_cmd *cmd;
1866 {
1867 int result;
1868
1869 cmd->com.ie_cmd_status = 0;
1870 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
1871 cmd->com.ie_cmd_link = 0xffff;
1872
1873 sc->scb->ie_command_list = MK_16(MEM, cmd);
1874 cmd->ie_tdr_time = 0;
1875
1876 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
1877 !(cmd->com.ie_cmd_status & IE_STAT_OK))
1878 result = 0x10000;
1879 else
1880 result = cmd->ie_tdr_time;
1881
1882 ie_ack(sc, IE_ST_WHENCE);
1883
1884 if (result & IE_TDR_SUCCESS)
1885 return;
1886
1887 if (result & 0x10000)
1888 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
1889 else if (result & IE_TDR_XCVR)
1890 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
1891 else if (result & IE_TDR_OPEN)
1892 printf("%s: TDR detected an open %d clocks away\n",
1893 sc->sc_dev.dv_xname, result & IE_TDR_TIME);
1894 else if (result & IE_TDR_SHORT)
1895 printf("%s: TDR detected a short %d clocks away\n",
1896 sc->sc_dev.dv_xname, result & IE_TDR_TIME);
1897 else
1898 printf("%s: TDR returned unknown status %x\n",
1899 sc->sc_dev.dv_xname, result);
1900 }
1901
1902 #define _ALLOC(p, n) (bzero(p, n), p += n, p - n)
1903 #define ALLOC(p, n) _ALLOC(p, ALIGN(n))
1904
1905
1906
1907
1908 void
1909 iememinit(ptr, sc)
1910 void *ptr;
1911 struct ie_softc *sc;
1912 {
1913 int i;
1914
1915
1916 for (i = 0; i < NFRAMES; i++)
1917 sc->rframes[i] = ALLOC(ptr, sizeof(*sc->rframes[i]));
1918
1919
1920 for (i = 0; i < NFRAMES; i++)
1921 sc->rframes[i]->ie_fd_next =
1922 MK_16(MEM, sc->rframes[(i + 1) % NFRAMES]);
1923
1924
1925 sc->rframes[NFRAMES - 1]->ie_fd_last |= IE_FD_LAST;
1926
1927
1928
1929
1930
1931
1932 for (i = 0; i < NRXBUF; i++) {
1933 sc->rbuffs[i] = ALLOC(ptr, sizeof(*sc->rbuffs[i]));
1934 sc->rbuffs[i]->ie_rbd_length = IE_RBUF_SIZE;
1935 sc->rbuffs[i]->ie_rbd_buffer = MK_24(MEM, ptr);
1936 sc->cbuffs[i] = ALLOC(ptr, IE_RBUF_SIZE);
1937 }
1938
1939
1940 for (i = 0; i < NRXBUF; i++)
1941 sc->rbuffs[i]->ie_rbd_next =
1942 MK_16(MEM, sc->rbuffs[(i + 1) % NRXBUF]);
1943
1944
1945 sc->rbuffs[NRXBUF - 1]->ie_rbd_length |= IE_RBD_LAST;
1946
1947
1948
1949
1950
1951 sc->rfhead = 0;
1952 sc->rftail = NFRAMES - 1;
1953 sc->rbhead = 0;
1954 sc->rbtail = NRXBUF - 1;
1955
1956 sc->scb->ie_recv_list = MK_16(MEM, sc->rframes[0]);
1957 sc->rframes[0]->ie_fd_buf_desc = MK_16(MEM, sc->rbuffs[0]);
1958
1959
1960
1961
1962
1963 for (i = 0; i < NTXBUF; i++) {
1964 sc->xmit_cmds[i] = ALLOC(ptr, sizeof(*sc->xmit_cmds[i]));
1965 sc->xmit_buffs[i] = ALLOC(ptr, sizeof(*sc->xmit_buffs[i]));
1966 }
1967
1968 for (i = 0; i < NTXBUF; i++)
1969 sc->xmit_cbuffs[i] = ALLOC(ptr, IE_TBUF_SIZE);
1970
1971
1972 sc->xchead = sc->xctail = 0;
1973
1974
1975 sc->xmit_busy = 0;
1976 }
1977
1978
1979
1980
1981
1982 static int
1983 mc_setup(sc, ptr)
1984 struct ie_softc *sc;
1985 void *ptr;
1986 {
1987 volatile struct ie_mcast_cmd *cmd = ptr;
1988
1989 cmd->com.ie_cmd_status = 0;
1990 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
1991 cmd->com.ie_cmd_link = 0xffff;
1992
1993 bcopy((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
1994 sc->mcast_count * sizeof *sc->mcast_addrs);
1995
1996 cmd->ie_mcast_bytes = sc->mcast_count * ETHER_ADDR_LEN;
1997
1998 sc->scb->ie_command_list = MK_16(MEM, cmd);
1999 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
2000 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2001 printf("%s: multicast address setup command failed\n",
2002 sc->sc_dev.dv_xname);
2003 return 0;
2004 }
2005 return 1;
2006 }
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016 int
2017 ieinit(sc)
2018 struct ie_softc *sc;
2019 {
2020 volatile struct ie_sys_ctl_block *scb = sc->scb;
2021 void *ptr;
2022
2023 ptr = (void *)ALIGN(scb + 1);
2024
2025
2026
2027
2028 {
2029 volatile struct ie_config_cmd *cmd = ptr;
2030
2031 scb->ie_command_list = MK_16(MEM, cmd);
2032 cmd->com.ie_cmd_status = 0;
2033 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
2034 cmd->com.ie_cmd_link = 0xffff;
2035
2036 ie_setup_config(cmd, sc->promisc != 0,
2037 sc->hard_type == IE_STARLAN10);
2038
2039 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
2040 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2041 printf("%s: configure command failed\n",
2042 sc->sc_dev.dv_xname);
2043 return 0;
2044 }
2045 }
2046
2047
2048
2049
2050 {
2051 volatile struct ie_iasetup_cmd *cmd = ptr;
2052
2053 scb->ie_command_list = MK_16(MEM, cmd);
2054 cmd->com.ie_cmd_status = 0;
2055 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
2056 cmd->com.ie_cmd_link = 0xffff;
2057
2058 bcopy(sc->sc_arpcom.ac_enaddr, (caddr_t)&cmd->ie_address,
2059 sizeof cmd->ie_address);
2060
2061 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
2062 !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
2063 printf("%s: individual address setup command failed\n",
2064 sc->sc_dev.dv_xname);
2065 return 0;
2066 }
2067 }
2068
2069
2070
2071
2072 run_tdr(sc, ptr);
2073
2074
2075
2076
2077 ie_ack(sc, IE_ST_WHENCE);
2078
2079
2080
2081
2082 iememinit(ptr, sc);
2083
2084 sc->sc_arpcom.ac_if.if_flags |= IFF_RUNNING;
2085 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
2086
2087 sc->scb->ie_recv_list = MK_16(MEM, sc->rframes[0]);
2088 command_and_wait(sc, IE_RU_START, 0, 0);
2089
2090 ie_ack(sc, IE_ST_WHENCE);
2091
2092
2093 {
2094 u_char bart_config;
2095
2096 if(sc->hard_type == IE_EE16) {
2097 bart_config = inb(PORT + IEE16_CONFIG);
2098 bart_config &= ~IEE16_BART_LOOPBACK;
2099 bart_config |= IEE16_BART_MCS16_TEST;
2100 outb(PORT + IEE16_CONFIG, bart_config);
2101 ee16_interrupt_enable(sc);
2102 ee16_chan_attn(sc);
2103 }
2104 }
2105 return 0;
2106 }
2107
2108 void
2109 iestop(sc)
2110 struct ie_softc *sc;
2111 {
2112
2113 command_and_wait(sc, IE_RU_DISABLE, 0, 0);
2114 }
2115
2116 int
2117 ieioctl(ifp, cmd, data)
2118 register struct ifnet *ifp;
2119 u_long cmd;
2120 caddr_t data;
2121 {
2122 struct ie_softc *sc = ifp->if_softc;
2123 struct ifaddr *ifa = (struct ifaddr *)data;
2124 struct ifreq *ifr = (struct ifreq *)data;
2125 int s, error = 0;
2126
2127 s = splnet();
2128
2129 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
2130 splx(s);
2131 return error;
2132 }
2133
2134 switch (cmd) {
2135
2136 case SIOCSIFADDR:
2137 ifp->if_flags |= IFF_UP;
2138
2139 switch (ifa->ifa_addr->sa_family) {
2140 #ifdef INET
2141 case AF_INET:
2142 ieinit(sc);
2143 arp_ifinit(&sc->sc_arpcom, ifa);
2144 break;
2145 #endif
2146 default:
2147 ieinit(sc);
2148 break;
2149 }
2150 break;
2151
2152 case SIOCSIFFLAGS:
2153 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
2154 if ((ifp->if_flags & IFF_UP) == 0 &&
2155 (ifp->if_flags & IFF_RUNNING) != 0) {
2156
2157
2158
2159
2160 iestop(sc);
2161 ifp->if_flags &= ~IFF_RUNNING;
2162 } else if ((ifp->if_flags & IFF_UP) != 0 &&
2163 (ifp->if_flags & IFF_RUNNING) == 0) {
2164
2165
2166
2167
2168 ieinit(sc);
2169 } else {
2170
2171
2172
2173
2174 iestop(sc);
2175 ieinit(sc);
2176 }
2177 #ifdef IEDEBUG
2178 if (ifp->if_flags & IFF_DEBUG)
2179 sc->sc_debug = IED_ALL;
2180 else
2181 sc->sc_debug = 0;
2182 #endif
2183 break;
2184
2185 case SIOCADDMULTI:
2186 case SIOCDELMULTI:
2187 error = (cmd == SIOCADDMULTI) ?
2188 ether_addmulti(ifr, &sc->sc_arpcom):
2189 ether_delmulti(ifr, &sc->sc_arpcom);
2190
2191 if (error == ENETRESET) {
2192
2193
2194
2195
2196 if (ifp->if_flags & IFF_RUNNING)
2197 mc_reset(sc);
2198 error = 0;
2199 }
2200 break;
2201
2202 default:
2203 error = EINVAL;
2204 }
2205 splx(s);
2206 return error;
2207 }
2208
2209 static void
2210 mc_reset(sc)
2211 struct ie_softc *sc;
2212 {
2213 struct ether_multi *enm;
2214 struct ether_multistep step;
2215
2216
2217
2218
2219 sc->mcast_count = 0;
2220 ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
2221 while (enm) {
2222 if (sc->mcast_count >= MAXMCAST ||
2223 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
2224 sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
2225 ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, (void *)0);
2226 goto setflag;
2227 }
2228
2229 bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
2230 sc->mcast_count++;
2231 ETHER_NEXT_MULTI(step, enm);
2232 }
2233 setflag:
2234 sc->want_mcsetup = 1;
2235 }
2236
2237 #ifdef IEDEBUG
2238 void
2239 print_rbd(rbd)
2240 volatile struct ie_recv_buf_desc *rbd;
2241 {
2242
2243 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
2244 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
2245 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
2246 rbd->mbz);
2247 }
2248 #endif
2249