This source file includes following definitions.
- ec_probe
- ec_attach
- ec_fake_test_mem
- ec_test_mem
- ec_readmem
- ec_write_mbuf
- ec_ring_copy
- ec_read_hdr
- ec_media_init
- ec_mediachange
- ec_mediastatus
- ec_init_card
- ec_set_media
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 #include "bpfilter.h"
59
60 #include <sys/param.h>
61 #include <sys/systm.h>
62 #include <sys/device.h>
63 #include <sys/socket.h>
64 #include <sys/mbuf.h>
65 #include <sys/syslog.h>
66
67 #include <net/if.h>
68 #include <net/if_dl.h>
69 #include <net/if_types.h>
70 #include <net/if_media.h>
71
72 #ifdef INET
73 #include <netinet/in.h>
74 #include <netinet/in_systm.h>
75 #include <netinet/in_var.h>
76 #include <netinet/ip.h>
77 #include <netinet/if_ether.h>
78 #endif
79
80 #if NBPFILTER > 0
81 #include <net/bpf.h>
82 #endif
83
84 #include <machine/bus.h>
85 #include <machine/intr.h>
86
87 #include <dev/isa/isareg.h>
88 #include <dev/isa/isavar.h>
89
90 #include <dev/ic/dp8390reg.h>
91 #include <dev/ic/dp8390var.h>
92
93 #include <dev/isa/if_ecreg.h>
94
95 struct ec_softc {
96 struct dp8390_softc sc_dp8390;
97
98 bus_space_tag_t sc_asict;
99 bus_space_handle_t sc_asich;
100
101 int sc_16bitp;
102
103 void *sc_ih;
104 };
105
106 int ec_probe(struct device *, void *, void *);
107 void ec_attach(struct device *, struct device *, void *);
108
109 struct cfattach ec_ca = {
110 sizeof(struct ec_softc), ec_probe, ec_attach
111 };
112
113 int ec_set_media(struct ec_softc *, int);
114
115 void ec_media_init(struct dp8390_softc *);
116
117 int ec_mediachange(struct dp8390_softc *);
118 void ec_mediastatus(struct dp8390_softc *, struct ifmediareq *);
119
120 void ec_init_card(struct dp8390_softc *);
121 int ec_write_mbuf(struct dp8390_softc *, struct mbuf *, int);
122 int ec_ring_copy(struct dp8390_softc *, int, caddr_t, u_short);
123 void ec_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *);
124 int ec_fake_test_mem(struct dp8390_softc *);
125 int ec_test_mem(struct dp8390_softc *);
126
127 __inline void ec_readmem(struct ec_softc *, int, u_int8_t *, int);
128
129 static const int ec_iobase[] = {
130 0x2e0, 0x2a0, 0x280, 0x250, 0x350, 0x330, 0x310, 0x300,
131 };
132 #define NEC_IOBASE (sizeof(ec_iobase) / sizeof(ec_iobase[0]))
133
134 static const int ec_membase[] = {
135 MADDRUNK, MADDRUNK, MADDRUNK, MADDRUNK, 0xc8000, 0xcc000,
136 0xd8000, 0xdc000,
137 };
138 #define NEC_MEMBASE (sizeof(ec_membase) / sizeof(ec_membase[0]))
139
140 struct cfdriver ec_cd = {
141 NULL, "ec", DV_IFNET
142 };
143
144 int
145 ec_probe(struct device *parent, void *match, void *aux)
146 {
147 struct isa_attach_args *ia = aux;
148 bus_space_tag_t nict, asict, memt;
149 bus_space_handle_t nich, asich, memh;
150 bus_size_t memsize;
151 int nich_valid, asich_valid, memh_valid;
152 int i, rv = 0;
153 u_int8_t x;
154
155 nict = asict = ia->ia_iot;
156 memt = ia->ia_memt;
157
158 nich_valid = asich_valid = memh_valid = 0;
159
160
161
162
163
164 memsize = 8192;
165
166
167 if (ia->ia_iobase == -1 )
168 return (0);
169
170
171 if (ia->ia_maddr == -1 )
172 return (0);
173
174
175 for (i = 0; i < NEC_IOBASE; i++)
176 if (ia->ia_iobase == ec_iobase[i])
177 break;
178 if (i == NEC_IOBASE)
179 return (0);
180
181
182 for (i = 0; i < NEC_MEMBASE; i++) {
183 if (ec_membase[i] == MADDRUNK)
184 continue;
185 if (ia->ia_maddr == ec_membase[i])
186 break;
187 }
188 if (i == NEC_MEMBASE)
189 return (0);
190
191
192 if (bus_space_map(nict, ia->ia_iobase + ELINK2_NIC_OFFSET,
193 ELINK2_NIC_PORTS, 0, &nich))
194 goto out;
195 nich_valid = 1;
196
197
198 if (bus_space_map(asict, ia->ia_iobase + ELINK2_ASIC_OFFSET,
199 ELINK2_ASIC_PORTS, 0, &asich))
200 goto out;
201 asich_valid = 1;
202
203
204 if (bus_space_map(memt, ia->ia_maddr, memsize, 0, &memh))
205 goto out;
206 memh_valid = 1;
207
208
209
210
211
212
213
214
215
216 x = bus_space_read_1(asict, asich, ELINK2_BCFR);
217 if (x == 0 || (x & (x - 1)) != 0)
218 goto out;
219 i = ffs(x) - 1;
220 if (ia->ia_iobase != ec_iobase[i])
221 goto out;
222
223
224
225
226
227 x = bus_space_read_1(asict, asich, ELINK2_PCFR);
228 if (x == 0 || (x & (x - 1)) != 0)
229 goto out;
230 i = ffs(x) - 1;
231 if (ia->ia_maddr != ec_membase[i])
232 goto out;
233
234
235 ia->ia_iosize = ELINK2_NIC_PORTS;
236 ia->ia_msize = memsize;
237 rv = 1;
238
239 out:
240 if (nich_valid)
241 bus_space_unmap(nict, nich, ELINK2_NIC_PORTS);
242 if (asich_valid)
243 bus_space_unmap(asict, asich, ELINK2_ASIC_PORTS);
244 if (memh_valid)
245 bus_space_unmap(memt, memh, memsize);
246 return (rv);
247 }
248
249 void
250 ec_attach(struct device *parent, struct device *self, void *aux)
251 {
252 struct ec_softc *esc = (struct ec_softc *)self;
253 struct dp8390_softc *sc = &esc->sc_dp8390;
254 struct isa_attach_args *ia = aux;
255 bus_space_tag_t nict, asict, memt;
256 bus_space_handle_t nich, asich, memh;
257 bus_size_t memsize;
258 u_int8_t tmp;
259 int i;
260
261 printf("\n");
262
263 nict = asict = ia->ia_iot;
264 memt = ia->ia_memt;
265
266
267
268
269
270 memsize = 8192;
271
272
273 if (bus_space_map(nict, ia->ia_iobase + ELINK2_NIC_OFFSET,
274 ELINK2_NIC_PORTS, 0, &nich)) {
275 printf("%s: can't map nic i/o space\n",
276 sc->sc_dev.dv_xname);
277 return;
278 }
279
280
281 if (bus_space_map(asict, ia->ia_iobase + ELINK2_ASIC_OFFSET,
282 ELINK2_ASIC_PORTS, 0, &asich)) {
283 printf("%s: can't map asic i/o space\n",
284 sc->sc_dev.dv_xname);
285 return;
286 }
287
288
289 if (bus_space_map(memt, ia->ia_maddr, memsize, 0, &memh)) {
290 printf("%s: can't map shared memory\n",
291 sc->sc_dev.dv_xname);
292 return;
293 }
294
295 esc->sc_asict = asict;
296 esc->sc_asich = asich;
297
298 sc->sc_regt = nict;
299 sc->sc_regh = nich;
300
301 sc->sc_buft = memt;
302 sc->sc_bufh = memh;
303
304
305 sc->sc_enabled = 1;
306
307
308 for (i = 0; i < 16; i++)
309 sc->sc_reg_map[i] = i;
310
311
312
313
314
315
316
317
318 bus_space_write_1(asict, asich, ELINK2_CR,
319 ELINK2_CR_RST | ELINK2_CR_XSEL);
320
321
322 delay(50);
323
324
325
326
327
328
329 bus_space_write_1(asict, asich, ELINK2_CR, ELINK2_CR_XSEL);
330
331
332 delay(5000);
333
334
335
336
337
338
339
340 bus_space_write_1(asict, asich, ELINK2_CR,
341 ELINK2_CR_XSEL | ELINK2_CR_EALO);
342
343 for (i = 0; i < ETHER_ADDR_LEN; i++)
344 sc->sc_arpcom.ac_enaddr[i] = NIC_GET(nict, nich, i);
345
346
347
348
349
350 bus_space_write_1(asict, asich, ELINK2_CR, ELINK2_CR_XSEL);
351
352
353
354
355 NIC_PUT(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
356
357
358
359
360
361 NIC_PUT(nict, nich, ED_P0_DCR, 0);
362
363
364 NIC_PUT(nict, nich, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_2 | ED_CR_STP);
365
366
367 if (NIC_GET(nict, nich, ED_P2_DCR) & ED_DCR_WTS)
368 esc->sc_16bitp = 1;
369 else
370 esc->sc_16bitp = 0;
371
372 printf("%s: 3Com 3c503 Ethernet (%s-bit)",
373 sc->sc_dev.dv_xname, esc->sc_16bitp ? "16" : "8");
374
375
376 NIC_PUT(nict, nich, ED_P2_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
377
378 sc->cr_proto = ED_CR_RD2;
379
380
381
382
383
384
385
386
387
388 sc->dcr_reg = ED_DCR_FT1 | ED_DCR_LS |
389 (esc->sc_16bitp ? ED_DCR_WTS : 0);
390
391 sc->test_mem = ec_fake_test_mem;
392 sc->ring_copy = ec_ring_copy;
393 sc->write_mbuf = ec_write_mbuf;
394 sc->read_hdr = ec_read_hdr;
395
396 sc->sc_media_init = ec_media_init;
397
398 sc->sc_mediachange = ec_mediachange;
399 sc->sc_mediastatus = ec_mediastatus;
400
401 sc->mem_start = 0;
402 sc->mem_size = memsize;
403
404
405 if (dp8390_config(sc)) {
406 printf(": configuration failed\n");
407 return;
408 }
409
410
411
412
413
414
415
416
417
418
419
420
421
422 if (esc->sc_16bitp) {
423 if (sc->sc_dev.dv_cfdata->cf_flags & DP8390_NO_MULTI_BUFFERING)
424 sc->txb_cnt = 1;
425 else
426 sc->txb_cnt = 2;
427
428 sc->tx_page_start = ELINK2_TX_PAGE_OFFSET_16BIT;
429 sc->rec_page_start = ELINK2_RX_PAGE_OFFSET_16BIT;
430 sc->rec_page_stop = (memsize >> ED_PAGE_SHIFT) +
431 sc->rec_page_start;
432 sc->mem_ring = sc->mem_start;
433 } else {
434 sc->txb_cnt = 1;
435 sc->tx_page_start = ELINK2_TX_PAGE_OFFSET_8BIT;
436 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE;
437 sc->rec_page_stop = (memsize >> ED_PAGE_SHIFT) +
438 sc->tx_page_start;
439 sc->mem_ring = sc->mem_start +
440 (ED_TXBUF_SIZE << ED_PAGE_SHIFT);
441 }
442
443
444
445
446
447 bus_space_write_1(asict, asich, ELINK2_PSTR, sc->rec_page_start);
448 bus_space_write_1(asict, asich, ELINK2_PSPR, sc->rec_page_stop);
449
450
451
452
453 switch (ia->ia_irq) {
454 case 9: tmp = ELINK2_IDCFR_IRQ2; break;
455 case 3: tmp = ELINK2_IDCFR_IRQ3; break;
456 case 4: tmp = ELINK2_IDCFR_IRQ4; break;
457 case 5: tmp = ELINK2_IDCFR_IRQ5; break;
458 break;
459
460 case IRQUNK:
461 printf("%s: wildcarded IRQ is not allowed\n",
462 sc->sc_dev.dv_xname);
463 return;
464
465 default:
466 printf("%s: invalid IRQ %d, must be 3, 4, 5, or 9\n",
467 sc->sc_dev.dv_xname, ia->ia_irq);
468 return;
469 }
470
471 bus_space_write_1(asict, asich, ELINK2_IDCFR, tmp);
472
473
474
475
476
477 bus_space_write_1(asict, asich, ELINK2_GACFR,
478 ELINK2_GACFR_RSEL | ELINK2_GACFR_MBS0);
479
480
481
482
483
484
485
486 bus_space_write_1(asict, asich, ELINK2_VPTR2, 0xff);
487 bus_space_write_1(asict, asich, ELINK2_VPTR1, 0xff);
488 bus_space_write_1(asict, asich, ELINK2_VPTR0, 0x00);
489
490
491
492
493 if (ec_test_mem(sc)) {
494 printf("%s: memory test failed\n", sc->sc_dev.dv_xname);
495 return;
496 }
497
498
499 esc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
500 IPL_NET, dp8390_intr, sc, sc->sc_dev.dv_xname);
501 if (esc->sc_ih == NULL)
502 printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
503 }
504
505 int
506 ec_fake_test_mem(struct dp8390_softc *sc)
507 {
508
509
510
511
512
513
514 return (0);
515 }
516
517 int
518 ec_test_mem(struct dp8390_softc *sc)
519 {
520 struct ec_softc *esc = (struct ec_softc *)sc;
521 bus_space_tag_t memt = sc->sc_buft;
522 bus_space_handle_t memh = sc->sc_bufh;
523 bus_size_t memsize = sc->mem_size;
524 int i;
525
526 if (esc->sc_16bitp)
527 bus_space_set_region_2(memt, memh, 0, 0, memsize >> 1);
528 else
529 bus_space_set_region_1(memt, memh, 0, 0, memsize);
530
531 if (esc->sc_16bitp) {
532 for (i = 0; i < memsize; i += 2) {
533 if (bus_space_read_2(memt, memh, i) != 0)
534 goto fail;
535 }
536 } else {
537 for (i = 0; i < memsize; i++) {
538 if (bus_space_read_1(memt, memh, i) != 0)
539 goto fail;
540 }
541 }
542
543 return (0);
544
545 fail:
546 printf("%s: failed to clear shared memory at offset 0x%x\n",
547 sc->sc_dev.dv_xname, i);
548 return (1);
549 }
550
551
552
553
554
555
556 __inline void
557 ec_readmem(struct ec_softc *esc, int from, u_int8_t *to, int len)
558 {
559 bus_space_tag_t memt = esc->sc_dp8390.sc_buft;
560 bus_space_handle_t memh = esc->sc_dp8390.sc_bufh;
561
562 if (len & 1)
563 ++len;
564
565 if (esc->sc_16bitp)
566 bus_space_read_region_2(memt, memh, from, (u_int16_t *)to,
567 len >> 1);
568 else
569 bus_space_read_region_1(memt, memh, from, to, len);
570 }
571
572 int
573 ec_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
574 {
575 struct ec_softc *esc = (struct ec_softc *)sc;
576 bus_space_tag_t asict = esc->sc_asict;
577 bus_space_handle_t asich = esc->sc_asich;
578 bus_space_tag_t memt = esc->sc_dp8390.sc_buft;
579 bus_space_handle_t memh = esc->sc_dp8390.sc_bufh;
580 u_int8_t *data, savebyte[2];
581 int savelen, len, leftover;
582 #ifdef DIAGNOSTIC
583 u_int8_t *lim;
584 #endif
585
586 savelen = m->m_pkthdr.len;
587
588
589
590
591
592 if (esc->sc_16bitp == 0) {
593 for (; m != NULL; buf += m->m_len, m = m->m_next)
594 bus_space_write_region_1(memt, memh, buf,
595 mtod(m, u_int8_t *), m->m_len);
596 return (savelen);
597 }
598
599
600
601
602
603 if (esc->sc_16bitp)
604 bus_space_write_1(asict, asich, ELINK2_GACFR,
605 ELINK2_GACFR_RSEL);
606
607
608 leftover = 0;
609 savebyte[0] = savebyte[1] = 0;
610
611 for (; m != NULL; m = m->m_next) {
612 len = m->m_len;
613 if (len == 0)
614 continue;
615 data = mtod(m, u_int8_t *);
616 #ifdef DIAGNOSTIC
617 lim = data + len;
618 #endif
619 while (len > 0) {
620 if (leftover) {
621
622
623
624
625
626 savebyte[1] = *data++;
627 len--;
628 bus_space_write_2(memt, memh, buf,
629 *(u_int16_t *)savebyte);
630 buf += 2;
631 leftover = 0;
632 } else if (ALIGNED_POINTER(data, u_int16_t) == 0) {
633
634
635
636 savebyte[0] = *data++;
637 len--;
638 leftover = 1;
639 } else {
640
641
642
643
644
645 leftover = len & 1;
646 len &= ~1;
647 bus_space_write_region_2(memt, memh, buf,
648 (u_int16_t *)data, len >> 1);
649 data += len;
650 buf += len;
651 if (leftover)
652 savebyte[0] = *data++;
653 len = 0;
654 }
655 }
656 if (len < 0)
657 panic("ec_write_mbuf: negative len");
658 #ifdef DIAGNOSTIC
659 if (data != lim)
660 panic("ec_write_mbuf: data != lim");
661 #endif
662 }
663 if (leftover) {
664 savebyte[1] = 0;
665 bus_space_write_2(memt, memh, buf, *(u_int16_t *)savebyte);
666 }
667
668
669
670
671 if (esc->sc_16bitp)
672 bus_space_write_1(asict, asich, ELINK2_GACFR,
673 ELINK2_GACFR_RSEL | ELINK2_GACFR_MBS0);
674
675 return (savelen);
676 }
677
678 int
679 ec_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst,
680 u_short amount)
681 {
682 struct ec_softc *esc = (struct ec_softc *)sc;
683 u_short tmp_amount;
684
685
686 if (src + amount > sc->mem_end) {
687 tmp_amount = sc->mem_end - src;
688
689
690 ec_readmem(esc, src, dst, tmp_amount);
691
692 amount -= tmp_amount;
693 src = sc->mem_ring;
694 dst += tmp_amount;
695 }
696
697 ec_readmem(esc, src, dst, amount);
698
699 return (src + amount);
700 }
701
702 void
703 ec_read_hdr(struct dp8390_softc *sc, int packet_ptr,
704 struct dp8390_ring *packet_hdrp)
705 {
706 struct ec_softc *esc = (struct ec_softc *)sc;
707
708 ec_readmem(esc, packet_ptr, (u_int8_t *)packet_hdrp,
709 sizeof(struct dp8390_ring));
710 #if BYTE_ORDER == BIG_ENDIAN
711 packet_hdrp->count = swap16(packet_hdrp->count);
712 #endif
713 }
714
715 void
716 ec_media_init(struct dp8390_softc *sc)
717 {
718 ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
719 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_2, 0, NULL);
720 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_5, 0, NULL);
721 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_2);
722 }
723
724 int
725 ec_mediachange(struct dp8390_softc *sc)
726 {
727 struct ec_softc *esc = (struct ec_softc *)sc;
728 struct ifmedia *ifm = &sc->sc_media;
729
730 return (ec_set_media(esc, ifm->ifm_media));
731 }
732
733 void
734 ec_mediastatus(struct dp8390_softc *sc, struct ifmediareq *ifmr)
735 {
736 struct ifmedia *ifm = &sc->sc_media;
737
738
739
740
741 ifmr->ifm_active = ifm->ifm_cur->ifm_media;
742 }
743
744 void
745 ec_init_card(struct dp8390_softc *sc)
746 {
747 struct ec_softc *esc = (struct ec_softc *)sc;
748 struct ifmedia *ifm = &sc->sc_media;
749
750 (void) ec_set_media(esc, ifm->ifm_cur->ifm_media);
751 }
752
753 int
754 ec_set_media(struct ec_softc *esc, int media)
755 {
756 u_int8_t new;
757
758 if (IFM_TYPE(media) != IFM_ETHER)
759 return (EINVAL);
760
761 switch (IFM_SUBTYPE(media)) {
762 case IFM_10_2:
763 new = ELINK2_CR_XSEL;
764 break;
765
766 case IFM_10_5:
767 new = 0;
768 break;
769
770 default:
771 return (EINVAL);
772 }
773
774 bus_space_write_1(esc->sc_asict, esc->sc_asich, ELINK2_CR, new);
775 return (0);
776 }