This source file includes following definitions.
- dp8390_media_init
- dp8390_config
- dp8390_mediachange
- dp8390_mediastatus
- dp8390_reset
- dp8390_stop
- dp8390_watchdog
- dp8390_init
- dp8390_xmit
- dp8390_start
- dp8390_rint
- dp8390_intr
- dp8390_ioctl
- dp8390_read
- dp8390_getmcaf
- dp8390_get
- dp8390_test_mem
- dp8390_read_hdr
- dp8390_ring_copy
- dp8390_write_mbuf
- dp8390_enable
- dp8390_disable
- dp8390_detach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "bpfilter.h"
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <sys/errno.h>
23 #include <sys/ioctl.h>
24 #include <sys/mbuf.h>
25 #include <sys/socket.h>
26 #include <sys/syslog.h>
27
28 #include <net/if.h>
29 #include <net/if_dl.h>
30 #include <net/if_types.h>
31 #include <net/if_media.h>
32
33 #ifdef INET
34 #include <netinet/in.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/in_var.h>
37 #include <netinet/ip.h>
38 #include <netinet/if_ether.h>
39 #endif
40
41 #if NBPFILTER > 0
42 #include <net/bpf.h>
43 #endif
44
45 #include <machine/bus.h>
46
47 #include <dev/ic/dp8390reg.h>
48 #include <dev/ic/dp8390var.h>
49
50 #ifdef DEBUG
51 #define __inline__
52 #endif
53
54 static __inline__ void dp8390_xmit(struct dp8390_softc *);
55
56 static __inline__ void dp8390_read_hdr(struct dp8390_softc *,
57 int, struct dp8390_ring *);
58 static __inline__ int dp8390_ring_copy(struct dp8390_softc *,
59 int, caddr_t, u_short);
60 static __inline__ int dp8390_write_mbuf(struct dp8390_softc *,
61 struct mbuf *, int);
62
63 static int dp8390_test_mem(struct dp8390_softc *);
64
65 int dp8390_enable(struct dp8390_softc *);
66 void dp8390_disable(struct dp8390_softc *);
67
68 #ifdef DEBUG
69 int dp8390_debug = 0;
70 #endif
71
72
73
74
75 void
76 dp8390_media_init(struct dp8390_softc *sc)
77 {
78 ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
79 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
80 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
81 }
82
83
84
85
86 int
87 dp8390_config(struct dp8390_softc *sc)
88 {
89 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
90 int rv;
91
92 rv = 1;
93
94 if (!sc->test_mem)
95 sc->test_mem = dp8390_test_mem;
96
97
98 if ((sc->mem_size < 16384) ||
99 (sc->sc_flags & DP8390_NO_MULTI_BUFFERING))
100 sc->txb_cnt = 1;
101 else if (sc->mem_size < 8192 * 3)
102 sc->txb_cnt = 2;
103 else
104 sc->txb_cnt = 3;
105
106 sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
107 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
108 sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
109 sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT);
110 sc->mem_end = sc->mem_start + sc->mem_size;
111
112
113 if ((*sc->test_mem)(sc))
114 goto out;
115
116
117 dp8390_stop(sc);
118
119
120 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
121 ifp->if_softc = sc;
122 ifp->if_start = dp8390_start;
123 ifp->if_ioctl = dp8390_ioctl;
124 if (!ifp->if_watchdog)
125 ifp->if_watchdog = dp8390_watchdog;
126 ifp->if_flags =
127 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
128 IFQ_SET_READY(&ifp->if_snd);
129
130 ifp->if_capabilities = IFCAP_VLAN_MTU;
131
132
133 printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
134
135
136 (*sc->sc_media_init)(sc);
137
138
139 if_attach(ifp);
140 ether_ifattach(ifp);
141
142 rv = 0;
143 out:
144 return (rv);
145 }
146
147
148
149
150 int
151 dp8390_mediachange(struct ifnet *ifp)
152 {
153 struct dp8390_softc *sc = ifp->if_softc;
154
155 if (sc->sc_mediachange)
156 return ((*sc->sc_mediachange)(sc));
157
158 return (0);
159 }
160
161
162
163
164 void
165 dp8390_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
166 {
167 struct dp8390_softc *sc = ifp->if_softc;
168
169 if (sc->sc_enabled == 0) {
170 ifmr->ifm_active = IFM_ETHER | IFM_NONE;
171 ifmr->ifm_status = 0;
172 return;
173 }
174
175 if (sc->sc_mediastatus)
176 (*sc->sc_mediastatus)(sc, ifmr);
177 }
178
179
180
181
182 void
183 dp8390_reset(struct dp8390_softc *sc)
184 {
185 int s;
186
187 s = splnet();
188 dp8390_stop(sc);
189 dp8390_init(sc);
190 splx(s);
191 }
192
193
194
195
196 void
197 dp8390_stop(struct dp8390_softc *sc)
198 {
199 bus_space_tag_t regt = sc->sc_regt;
200 bus_space_handle_t regh = sc->sc_regh;
201 int n = 5000;
202
203
204 NIC_BARRIER(regt, regh);
205 NIC_PUT(regt, regh, ED_P0_CR,
206 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
207 NIC_BARRIER(regt, regh);
208
209
210
211
212
213
214 while (((NIC_GET(regt, regh,
215 ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
216 DELAY(1);
217
218 if (sc->stop_card != NULL)
219 (*sc->stop_card)(sc);
220 }
221
222
223
224
225
226
227 void
228 dp8390_watchdog(struct ifnet *ifp)
229 {
230 struct dp8390_softc *sc = ifp->if_softc;
231
232 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
233 ++sc->sc_arpcom.ac_if.if_oerrors;
234
235 dp8390_reset(sc);
236 }
237
238
239
240
241 void
242 dp8390_init(struct dp8390_softc *sc)
243 {
244 bus_space_tag_t regt = sc->sc_regt;
245 bus_space_handle_t regh = sc->sc_regh;
246 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
247 u_int8_t mcaf[8];
248 int i;
249
250
251
252
253
254
255
256
257 ifp->if_timer = 0;
258
259 sc->txb_inuse = 0;
260 sc->txb_new = 0;
261 sc->txb_next_tx = 0;
262
263
264 NIC_BARRIER(regt, regh);
265 NIC_PUT(regt, regh, ED_P0_CR,
266 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
267 NIC_BARRIER(regt, regh);
268
269 if (sc->dcr_reg & ED_DCR_LS) {
270 NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
271 } else {
272
273
274
275
276 NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
277 }
278
279
280 NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
281 NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
282
283
284 NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
285
286
287 NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
288
289
290 if (sc->is790)
291 NIC_PUT(regt, regh, 0x09, 0);
292
293
294 NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
295 NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
296 NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
297
298
299
300
301
302
303
304 NIC_PUT(regt, regh, ED_P0_IMR,
305 ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE |
306 ED_IMR_OVWE);
307
308
309
310
311
312 NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
313
314
315 NIC_BARRIER(regt, regh);
316 NIC_PUT(regt, regh, ED_P0_CR,
317 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
318 NIC_BARRIER(regt, regh);
319
320
321 for (i = 0; i < ETHER_ADDR_LEN; ++i)
322 NIC_PUT(regt, regh, ED_P1_PAR0 + i,
323 sc->sc_arpcom.ac_enaddr[i]);
324
325
326 dp8390_getmcaf(&sc->sc_arpcom, mcaf);
327 for (i = 0; i < 8; i++)
328 NIC_PUT(regt, regh, ED_P1_MAR0 + i, mcaf[i]);
329
330
331
332
333
334 sc->next_packet = sc->rec_page_start + 1;
335 NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
336
337
338 NIC_BARRIER(regt, regh);
339 NIC_PUT(regt, regh, ED_P1_CR,
340 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
341 NIC_BARRIER(regt, regh);
342
343
344 i = ED_RCR_AB | ED_RCR_AM | sc->rcr_proto;
345 if (ifp->if_flags & IFF_PROMISC) {
346
347
348
349
350 i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP;
351 }
352 NIC_PUT(regt, regh, ED_P0_RCR, i);
353
354
355 NIC_PUT(regt, regh, ED_P0_TCR, 0);
356
357
358 if (sc->init_card)
359 (*sc->init_card)(sc);
360
361
362 NIC_BARRIER(regt, regh);
363 NIC_PUT(regt, regh, ED_P0_CR,
364 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
365
366
367 ifp->if_flags |= IFF_RUNNING;
368 ifp->if_flags &= ~IFF_OACTIVE;
369
370
371 dp8390_start(ifp);
372 }
373
374
375
376
377 static __inline__ void
378 dp8390_xmit(struct dp8390_softc *sc)
379 {
380 bus_space_tag_t regt = sc->sc_regt;
381 bus_space_handle_t regh = sc->sc_regh;
382 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
383 u_short len;
384
385 #ifdef DIAGNOSTIC
386 if ((sc->txb_next_tx + sc->txb_inuse) % sc->txb_cnt != sc->txb_new)
387 panic("dp8390_xmit: desync, next_tx=%d inuse=%d cnt=%d new=%d",
388 sc->txb_next_tx, sc->txb_inuse, sc->txb_cnt, sc->txb_new);
389
390 if (sc->txb_inuse == 0)
391 panic("dp8390_xmit: no packets to xmit");
392 #endif
393
394 len = sc->txb_len[sc->txb_next_tx];
395
396
397 NIC_BARRIER(regt, regh);
398 NIC_PUT(regt, regh, ED_P0_CR,
399 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
400 NIC_BARRIER(regt, regh);
401
402
403 NIC_PUT(regt, regh, ED_P0_TPSR, sc->tx_page_start +
404 sc->txb_next_tx * ED_TXBUF_SIZE);
405
406
407 NIC_PUT(regt, regh, ED_P0_TBCR0, len);
408 NIC_PUT(regt, regh, ED_P0_TBCR1, len >> 8);
409
410
411 NIC_BARRIER(regt, regh);
412 NIC_PUT(regt, regh, ED_P0_CR,
413 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
414
415
416 if (++sc->txb_next_tx == sc->txb_cnt)
417 sc->txb_next_tx = 0;
418
419
420 ifp->if_timer = 2;
421 }
422
423
424
425
426
427
428
429
430
431
432 void
433 dp8390_start(struct ifnet *ifp)
434 {
435 struct dp8390_softc *sc = ifp->if_softc;
436 struct mbuf *m0;
437 int buffer;
438 int len;
439
440 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
441 return;
442
443 outloop:
444
445 if (sc->txb_inuse == sc->txb_cnt) {
446
447 ifp->if_flags |= IFF_OACTIVE;
448 return;
449 }
450 IFQ_DEQUEUE(&ifp->if_snd, m0);
451 if (m0 == 0)
452 return;
453
454
455 if ((m0->m_flags & M_PKTHDR) == 0)
456 panic("dp8390_start: no header mbuf");
457
458 #if NBPFILTER > 0
459
460 if (ifp->if_bpf)
461 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
462 #endif
463
464
465 buffer = sc->mem_start +
466 ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
467
468 if (sc->write_mbuf)
469 len = (*sc->write_mbuf)(sc, m0, buffer);
470 else
471 len = dp8390_write_mbuf(sc, m0, buffer);
472
473 m_freem(m0);
474 sc->txb_len[sc->txb_new] = max(len, ETHER_MIN_LEN - ETHER_CRC_LEN);
475
476
477 if (++sc->txb_new == sc->txb_cnt)
478 sc->txb_new = 0;
479
480
481 if (sc->txb_inuse++ == 0)
482 dp8390_xmit(sc);
483
484
485 goto outloop;
486 }
487
488
489
490
491 void
492 dp8390_rint(struct dp8390_softc *sc)
493 {
494 bus_space_tag_t regt = sc->sc_regt;
495 bus_space_handle_t regh = sc->sc_regh;
496 struct dp8390_ring packet_hdr;
497 int packet_ptr;
498 u_short len;
499 u_char boundary, current;
500 u_char nlen;
501
502 loop:
503
504 NIC_BARRIER(regt, regh);
505 NIC_PUT(regt, regh, ED_P0_CR,
506 sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
507 NIC_BARRIER(regt, regh);
508
509
510
511
512
513
514
515
516
517 current = NIC_GET(regt, regh, ED_P1_CURR);
518 if (sc->next_packet == current)
519 return;
520
521
522 NIC_BARRIER(regt, regh);
523 NIC_PUT(regt, regh, ED_P1_CR,
524 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
525 NIC_BARRIER(regt, regh);
526
527 do {
528
529 packet_ptr = sc->mem_ring +
530 ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
531
532 if (sc->read_hdr)
533 (*sc->read_hdr)(sc, packet_ptr, &packet_hdr);
534 else
535 dp8390_read_hdr(sc, packet_ptr, &packet_hdr);
536 len = packet_hdr.count;
537
538
539
540
541
542
543
544
545
546 if (packet_hdr.next_packet >= sc->next_packet)
547 nlen = (packet_hdr.next_packet - sc->next_packet);
548 else
549 nlen = ((packet_hdr.next_packet - sc->rec_page_start) +
550 (sc->rec_page_stop - sc->next_packet));
551 --nlen;
552 if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
553 --nlen;
554 len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
555 #ifdef DIAGNOSTIC
556 if (len != packet_hdr.count) {
557 printf("%s: length does not match "
558 "next packet pointer\n", sc->sc_dev.dv_xname);
559 printf("%s: len %04x nlen %04x start %02x "
560 "first %02x curr %02x next %02x stop %02x\n",
561 sc->sc_dev.dv_xname, packet_hdr.count, len,
562 sc->rec_page_start, sc->next_packet, current,
563 packet_hdr.next_packet, sc->rec_page_stop);
564 }
565 #endif
566
567
568
569
570
571
572
573
574
575 if (len <= MCLBYTES &&
576 packet_hdr.next_packet >= sc->rec_page_start &&
577 packet_hdr.next_packet < sc->rec_page_stop) {
578
579 dp8390_read(sc,
580 packet_ptr + sizeof(struct dp8390_ring),
581 len - sizeof(struct dp8390_ring));
582 } else {
583
584 log(LOG_ERR, "%s: NIC memory corrupt - "
585 "invalid packet length %d\n",
586 sc->sc_dev.dv_xname, len);
587 ++sc->sc_arpcom.ac_if.if_ierrors;
588 dp8390_reset(sc);
589 return;
590 }
591
592
593 sc->next_packet = packet_hdr.next_packet;
594
595
596
597
598
599 boundary = sc->next_packet - 1;
600 if (boundary < sc->rec_page_start)
601 boundary = sc->rec_page_stop - 1;
602 NIC_PUT(regt, regh, ED_P0_BNRY, boundary);
603 } while (sc->next_packet != current);
604
605 goto loop;
606 }
607
608
609 int
610 dp8390_intr(void *arg)
611 {
612 struct dp8390_softc *sc = (struct dp8390_softc *)arg;
613 bus_space_tag_t regt = sc->sc_regt;
614 bus_space_handle_t regh = sc->sc_regh;
615 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
616 u_char isr;
617
618 if (sc->sc_enabled == 0)
619 return (0);
620
621
622 NIC_BARRIER(regt, regh);
623 NIC_PUT(regt, regh, ED_P0_CR,
624 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
625 NIC_BARRIER(regt, regh);
626
627 isr = NIC_GET(regt, regh, ED_P0_ISR);
628 if (!isr)
629 return (0);
630
631
632 for (;;) {
633
634
635
636
637
638 NIC_PUT(regt, regh, ED_P0_ISR, isr);
639
640
641 if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0)
642 while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) {
643 NIC_PUT(regt, regh, ED_P0_ISR, 0);
644 NIC_PUT(regt, regh, ED_P0_ISR, isr);
645 }
646
647
648
649
650
651
652
653
654
655 if (isr & (ED_ISR_PTX | ED_ISR_TXE) &&
656 sc->txb_inuse != 0) {
657 u_char collisions =
658 NIC_GET(regt, regh, ED_P0_NCR) & 0x0f;
659
660
661
662
663
664
665
666
667
668
669 if (isr & ED_ISR_TXE) {
670
671
672
673 if ((NIC_GET(regt, regh, ED_P0_TSR)
674 & ED_TSR_ABT) && (collisions == 0)) {
675
676
677
678
679
680 collisions = 16;
681 }
682
683
684 ++ifp->if_oerrors;
685 } else {
686
687
688
689
690
691
692
693 (void)NIC_GET(regt, regh, ED_P0_TSR);
694
695
696
697
698
699 ++ifp->if_opackets;
700 }
701
702
703 ifp->if_timer = 0;
704 ifp->if_flags &= ~IFF_OACTIVE;
705
706
707
708
709
710 ifp->if_collisions += collisions;
711
712
713
714
715
716
717
718
719 if (--sc->txb_inuse != 0)
720 dp8390_xmit(sc);
721 }
722
723
724 if (isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) {
725
726
727
728
729
730
731
732
733
734 if (isr & ED_ISR_OVW) {
735 ++ifp->if_ierrors;
736 #ifdef DEBUG
737 log(LOG_WARNING, "%s: warning - receiver "
738 "ring buffer overrun\n",
739 sc->sc_dev.dv_xname);
740 #endif
741
742 dp8390_reset(sc);
743 } else {
744
745
746
747
748
749 if (isr & ED_ISR_RXE) {
750 ++ifp->if_ierrors;
751 #ifdef DEBUG
752 if (dp8390_debug) {
753 printf("%s: receive error %x\n",
754 sc->sc_dev.dv_xname,
755 NIC_GET(regt, regh,
756 ED_P0_RSR));
757 }
758 #endif
759 }
760
761
762
763
764
765
766
767
768 if (sc->recv_int)
769 (*sc->recv_int)(sc);
770 else
771 dp8390_rint(sc);
772 }
773 }
774
775
776
777
778
779
780 dp8390_start(ifp);
781
782
783
784
785
786
787
788 NIC_BARRIER(regt, regh);
789 NIC_PUT(regt, regh, ED_P0_CR,
790 sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
791 NIC_BARRIER(regt, regh);
792
793
794
795
796
797
798 if (isr & ED_ISR_CNT) {
799 (void)NIC_GET(regt, regh, ED_P0_CNTR0);
800 (void)NIC_GET(regt, regh, ED_P0_CNTR1);
801 (void)NIC_GET(regt, regh, ED_P0_CNTR2);
802 }
803
804 isr = NIC_GET(regt, regh, ED_P0_ISR);
805 if (!isr)
806 return (1);
807 }
808 }
809
810
811
812
813 int
814 dp8390_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
815 {
816 struct dp8390_softc *sc = ifp->if_softc;
817 struct ifaddr *ifa = (struct ifaddr *) data;
818 struct ifreq *ifr = (struct ifreq *) data;
819 int s, error = 0;
820
821 s = splnet();
822
823 switch (cmd) {
824
825 case SIOCSIFADDR:
826 if ((error = dp8390_enable(sc)) != 0)
827 break;
828 ifp->if_flags |= IFF_UP;
829
830 switch (ifa->ifa_addr->sa_family) {
831 #ifdef INET
832 case AF_INET:
833 dp8390_init(sc);
834 arp_ifinit(&sc->sc_arpcom, ifa);
835 break;
836 #endif
837 default:
838 dp8390_init(sc);
839 break;
840 }
841 break;
842
843 case SIOCSIFMTU:
844 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
845 error = EINVAL;
846 } else if (ifp->if_mtu != ifr->ifr_mtu) {
847 ifp->if_mtu = ifr->ifr_mtu;
848 }
849 break;
850
851 case SIOCSIFFLAGS:
852 if ((ifp->if_flags & IFF_UP) == 0 &&
853 (ifp->if_flags & IFF_RUNNING) != 0) {
854
855
856
857
858 dp8390_stop(sc);
859 ifp->if_flags &= ~IFF_RUNNING;
860 dp8390_disable(sc);
861 } else if ((ifp->if_flags & IFF_UP) != 0 &&
862 (ifp->if_flags & IFF_RUNNING) == 0) {
863
864
865
866
867 if ((error = dp8390_enable(sc)) != 0)
868 break;
869 dp8390_init(sc);
870 } else if ((ifp->if_flags & IFF_UP) != 0) {
871
872
873
874
875 dp8390_stop(sc);
876 dp8390_init(sc);
877 }
878 break;
879
880 case SIOCADDMULTI:
881 case SIOCDELMULTI:
882 if (sc->sc_enabled == 0) {
883 error = EIO;
884 break;
885 }
886
887
888 error = (cmd == SIOCADDMULTI) ?
889 ether_addmulti(ifr, &sc->sc_arpcom) :
890 ether_delmulti(ifr, &sc->sc_arpcom);
891
892 if (error == ENETRESET) {
893
894
895
896
897 if (ifp->if_flags & IFF_RUNNING) {
898 dp8390_stop(sc);
899 dp8390_init(sc);
900 }
901 error = 0;
902 }
903 break;
904
905 case SIOCGIFMEDIA:
906 case SIOCSIFMEDIA:
907 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
908 break;
909
910 default:
911 error = EINVAL;
912 break;
913 }
914
915 splx(s);
916 return (error);
917 }
918
919
920
921
922
923 void
924 dp8390_read(struct dp8390_softc *sc, int buf, u_short len)
925 {
926 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
927 struct mbuf *m;
928
929
930 m = dp8390_get(sc, buf, len);
931 if (m == 0) {
932 ifp->if_ierrors++;
933 return;
934 }
935
936 ifp->if_ipackets++;
937
938 #if NBPFILTER > 0
939
940
941
942
943 if (ifp->if_bpf)
944 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
945 #endif
946
947 ether_input_mbuf(ifp, m);
948 }
949
950
951
952
953
954
955
956
957
958
959 void
960 dp8390_getmcaf(struct arpcom *ac, u_int8_t *af)
961 {
962 struct ifnet *ifp = &ac->ac_if;
963 struct ether_multi *enm;
964 u_int32_t crc;
965 int i;
966 struct ether_multistep step;
967
968
969
970
971
972
973
974
975
976 if (ifp->if_flags & IFF_PROMISC) {
977 ifp->if_flags |= IFF_ALLMULTI;
978 for (i = 0; i < 8; i++)
979 af[i] = 0xff;
980 return;
981 }
982 for (i = 0; i < 8; i++)
983 af[i] = 0;
984 ETHER_FIRST_MULTI(step, ac, enm);
985 while (enm != NULL) {
986 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
987 sizeof(enm->enm_addrlo)) != 0) {
988
989
990
991
992
993
994
995
996 ifp->if_flags |= IFF_ALLMULTI;
997 for (i = 0; i < 8; i++)
998 af[i] = 0xff;
999 return;
1000 }
1001
1002
1003 crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
1004
1005
1006 af[crc >> 3] |= 1 << (crc & 0x7);
1007
1008 ETHER_NEXT_MULTI(step, enm);
1009 }
1010 ifp->if_flags &= ~IFF_ALLMULTI;
1011 }
1012
1013
1014
1015
1016
1017
1018
1019
1020 struct mbuf *
1021 dp8390_get(struct dp8390_softc *sc, int src, u_short total_len)
1022 {
1023 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1024 struct mbuf *m, *m0, *newm;
1025 u_short len;
1026
1027 MGETHDR(m0, M_DONTWAIT, MT_DATA);
1028 if (m0 == NULL)
1029 return (0);
1030 m0->m_pkthdr.rcvif = ifp;
1031 m0->m_pkthdr.len = total_len;
1032 len = MHLEN;
1033 m = m0;
1034
1035 while (total_len > 0) {
1036 if (total_len >= MINCLSIZE) {
1037 MCLGET(m, M_DONTWAIT);
1038 if (!(m->m_flags & M_EXT))
1039 goto bad;
1040 len = MCLBYTES;
1041 }
1042
1043
1044
1045
1046 if (m == m0) {
1047 caddr_t newdata = (caddr_t)
1048 ALIGN(m->m_data + sizeof(struct ether_header)) -
1049 sizeof(struct ether_header);
1050 len -= newdata - m->m_data;
1051 m->m_data = newdata;
1052 }
1053
1054 m->m_len = len = min(total_len, len);
1055 if (sc->ring_copy)
1056 src = (*sc->ring_copy)(sc, src, mtod(m, caddr_t), len);
1057 else
1058 src = dp8390_ring_copy(sc, src, mtod(m, caddr_t), len);
1059
1060 total_len -= len;
1061 if (total_len > 0) {
1062 MGET(newm, M_DONTWAIT, MT_DATA);
1063 if (newm == NULL)
1064 goto bad;
1065 len = MLEN;
1066 m = m->m_next = newm;
1067 }
1068 }
1069
1070 return (m0);
1071
1072 bad:
1073 m_freem(m0);
1074 return (0);
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 static int
1087 dp8390_test_mem(struct dp8390_softc *sc)
1088 {
1089 bus_space_tag_t buft = sc->sc_buft;
1090 bus_space_handle_t bufh = sc->sc_bufh;
1091 int i;
1092
1093 bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size);
1094
1095 for (i = 0; i < sc->mem_size; ++i) {
1096 if (bus_space_read_1(buft, bufh, sc->mem_start + i)) {
1097 printf(": failed to clear NIC buffer at offset %x - "
1098 "check configuration\n", (sc->mem_start + i));
1099 return 1;
1100 }
1101 }
1102
1103 return 0;
1104 }
1105
1106
1107
1108
1109 static __inline__ void
1110 dp8390_read_hdr(struct dp8390_softc *sc, int src, struct dp8390_ring *hdrp)
1111 {
1112 bus_space_tag_t buft = sc->sc_buft;
1113 bus_space_handle_t bufh = sc->sc_bufh;
1114
1115
1116
1117
1118
1119 hdrp->rsr = bus_space_read_1(buft, bufh, src);
1120 hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1);
1121 hdrp->count = bus_space_read_1(buft, bufh, src + 2) |
1122 (bus_space_read_1(buft, bufh, src + 3) << 8);
1123 }
1124
1125
1126
1127
1128
1129
1130 static __inline__ int
1131 dp8390_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst, u_short amount)
1132 {
1133 bus_space_tag_t buft = sc->sc_buft;
1134 bus_space_handle_t bufh = sc->sc_bufh;
1135 u_short tmp_amount;
1136
1137
1138 if (src + amount > sc->mem_end) {
1139 tmp_amount = sc->mem_end - src;
1140
1141
1142 bus_space_read_region_1(buft, bufh, src, dst, tmp_amount);
1143
1144 amount -= tmp_amount;
1145 src = sc->mem_ring;
1146 dst += tmp_amount;
1147 }
1148 bus_space_read_region_1(buft, bufh, src, dst, amount);
1149
1150 return (src + amount);
1151 }
1152
1153
1154
1155
1156
1157
1158
1159 static __inline__ int
1160 dp8390_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
1161 {
1162 bus_space_tag_t buft = sc->sc_buft;
1163 bus_space_handle_t bufh = sc->sc_bufh;
1164 u_char *data;
1165 int len, totlen = 0;
1166
1167 for (; m ; m = m->m_next) {
1168 data = mtod(m, u_char *);
1169 len = m->m_len;
1170 if (len > 0) {
1171 bus_space_write_region_1(buft, bufh, buf, data, len);
1172 totlen += len;
1173 buf += len;
1174 }
1175 }
1176
1177 return (totlen);
1178 }
1179
1180
1181
1182
1183 int
1184 dp8390_enable(struct dp8390_softc *sc)
1185 {
1186
1187 if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
1188 if ((*sc->sc_enable)(sc) != 0) {
1189 printf("%s: device enable failed\n",
1190 sc->sc_dev.dv_xname);
1191 return (EIO);
1192 }
1193 }
1194
1195 sc->sc_enabled = 1;
1196 return (0);
1197 }
1198
1199
1200
1201
1202 void
1203 dp8390_disable(struct dp8390_softc *sc)
1204 {
1205 if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
1206 (*sc->sc_disable)(sc);
1207 sc->sc_enabled = 0;
1208 }
1209 }
1210
1211 int
1212 dp8390_detach(struct dp8390_softc *sc, int flags)
1213 {
1214 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1215
1216
1217 dp8390_disable(sc);
1218
1219 if (sc->sc_media_fini != NULL)
1220 (*sc->sc_media_fini)(sc);
1221
1222
1223 ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
1224
1225 ether_ifdetach(ifp);
1226 if_detach(ifp);
1227
1228 return (0);
1229 }