This source file includes following definitions.
- dc_delay
- dc_eeprom_width
- dc_eeprom_idle
- dc_eeprom_putbyte
- dc_eeprom_getword_pnic
- dc_eeprom_getword_xircom
- dc_eeprom_getword
- dc_read_eeprom
- dc_mii_writebit
- dc_mii_readbit
- dc_mii_sync
- dc_mii_send
- dc_mii_readreg
- dc_mii_writereg
- dc_miibus_readreg
- dc_miibus_writereg
- dc_miibus_statchg
- dc_crc_le
- dc_setfilt_21143
- dc_setfilt_admtek
- dc_setfilt_asix
- dc_setfilt_xircom
- dc_setfilt
- dc_setcfg
- dc_reset
- dc_apply_fixup
- dc_decode_leaf_sia
- dc_decode_leaf_sym
- dc_decode_leaf_mii
- dc_read_srom
- dc_parse_21143_srom
- dc_attach
- dc_list_tx_init
- dc_list_rx_init
- dc_newbuf
- dc_pnic_rx_bug_war
- dc_rx_resync
- dc_rxeof
- dc_txeof
- dc_tick
- dc_tx_underrun
- dc_intr
- dc_encap
- dc_coal
- dc_start
- dc_init
- dc_ifmedia_upd
- dc_ifmedia_sts
- dc_ioctl
- dc_watchdog
- dc_stop
- dc_shutdown
- dc_power
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 #include "bpfilter.h"
93
94 #include <sys/param.h>
95 #include <sys/systm.h>
96 #include <sys/mbuf.h>
97 #include <sys/protosw.h>
98 #include <sys/socket.h>
99 #include <sys/ioctl.h>
100 #include <sys/errno.h>
101 #include <sys/malloc.h>
102 #include <sys/kernel.h>
103 #include <sys/device.h>
104 #include <sys/timeout.h>
105
106 #include <net/if.h>
107 #include <net/if_dl.h>
108 #include <net/if_types.h>
109
110 #ifdef INET
111 #include <netinet/in.h>
112 #include <netinet/in_systm.h>
113 #include <netinet/in_var.h>
114 #include <netinet/ip.h>
115 #include <netinet/if_ether.h>
116 #endif
117
118 #include <net/if_media.h>
119
120 #if NBPFILTER > 0
121 #include <net/bpf.h>
122 #endif
123
124 #include <dev/mii/mii.h>
125 #include <dev/mii/miivar.h>
126
127 #include <machine/bus.h>
128 #include <dev/pci/pcidevs.h>
129
130 #include <dev/ic/dcreg.h>
131
132 int dc_intr(void *);
133 void dc_shutdown(void *);
134 void dc_power(int, void *);
135 struct dc_type *dc_devtype(void *);
136 int dc_newbuf(struct dc_softc *, int, struct mbuf *);
137 int dc_encap(struct dc_softc *, struct mbuf *, u_int32_t *);
138 int dc_coal(struct dc_softc *, struct mbuf **);
139
140 void dc_pnic_rx_bug_war(struct dc_softc *, int);
141 int dc_rx_resync(struct dc_softc *);
142 void dc_rxeof(struct dc_softc *);
143 void dc_txeof(struct dc_softc *);
144 void dc_tick(void *);
145 void dc_tx_underrun(struct dc_softc *);
146 void dc_start(struct ifnet *);
147 int dc_ioctl(struct ifnet *, u_long, caddr_t);
148 void dc_init(void *);
149 void dc_stop(struct dc_softc *);
150 void dc_watchdog(struct ifnet *);
151 int dc_ifmedia_upd(struct ifnet *);
152 void dc_ifmedia_sts(struct ifnet *, struct ifmediareq *);
153
154 void dc_delay(struct dc_softc *);
155 void dc_eeprom_width(struct dc_softc *);
156 void dc_eeprom_idle(struct dc_softc *);
157 void dc_eeprom_putbyte(struct dc_softc *, int);
158 void dc_eeprom_getword(struct dc_softc *, int, u_int16_t *);
159 void dc_eeprom_getword_pnic(struct dc_softc *, int, u_int16_t *);
160 void dc_eeprom_getword_xircom(struct dc_softc *, int, u_int16_t *);
161 void dc_read_eeprom(struct dc_softc *, caddr_t, int, int, int);
162
163 void dc_mii_writebit(struct dc_softc *, int);
164 int dc_mii_readbit(struct dc_softc *);
165 void dc_mii_sync(struct dc_softc *);
166 void dc_mii_send(struct dc_softc *, u_int32_t, int);
167 int dc_mii_readreg(struct dc_softc *, struct dc_mii_frame *);
168 int dc_mii_writereg(struct dc_softc *, struct dc_mii_frame *);
169 int dc_miibus_readreg(struct device *, int, int);
170 void dc_miibus_writereg(struct device *, int, int, int);
171 void dc_miibus_statchg(struct device *);
172
173 void dc_setcfg(struct dc_softc *, int);
174 u_int32_t dc_crc_le(struct dc_softc *, caddr_t);
175 u_int32_t dc_crc_be(caddr_t);
176 void dc_setfilt_21143(struct dc_softc *);
177 void dc_setfilt_asix(struct dc_softc *);
178 void dc_setfilt_admtek(struct dc_softc *);
179 void dc_setfilt_xircom(struct dc_softc *);
180
181 void dc_setfilt(struct dc_softc *);
182
183 void dc_reset(struct dc_softc *);
184 int dc_list_rx_init(struct dc_softc *);
185 int dc_list_tx_init(struct dc_softc *);
186
187 void dc_read_srom(struct dc_softc *, int);
188 void dc_parse_21143_srom(struct dc_softc *);
189 void dc_decode_leaf_sia(struct dc_softc *,
190 struct dc_eblock_sia *);
191 void dc_decode_leaf_mii(struct dc_softc *,
192 struct dc_eblock_mii *);
193 void dc_decode_leaf_sym(struct dc_softc *,
194 struct dc_eblock_sym *);
195 void dc_apply_fixup(struct dc_softc *, int);
196
197 #define DC_SETBIT(sc, reg, x) \
198 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x))
199
200 #define DC_CLRBIT(sc, reg, x) \
201 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(x))
202
203 #define SIO_SET(x) DC_SETBIT(sc, DC_SIO, (x))
204 #define SIO_CLR(x) DC_CLRBIT(sc, DC_SIO, (x))
205
206 void
207 dc_delay(sc)
208 struct dc_softc *sc;
209 {
210 int idx;
211
212 for (idx = (300 / 33) + 1; idx > 0; idx--)
213 CSR_READ_4(sc, DC_BUSCTL);
214 }
215
216 void
217 dc_eeprom_width(sc)
218 struct dc_softc *sc;
219 {
220 int i;
221
222
223 dc_eeprom_idle(sc);
224
225
226 CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
227 dc_delay(sc);
228 DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
229 dc_delay(sc);
230 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
231 dc_delay(sc);
232 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
233 dc_delay(sc);
234
235 for (i = 3; i--;) {
236 if (6 & (1 << i))
237 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
238 else
239 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
240 dc_delay(sc);
241 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
242 dc_delay(sc);
243 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
244 dc_delay(sc);
245 }
246
247 for (i = 1; i <= 12; i++) {
248 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
249 dc_delay(sc);
250 if (!(CSR_READ_4(sc, DC_SIO) & DC_SIO_EE_DATAOUT)) {
251 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
252 dc_delay(sc);
253 break;
254 }
255 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
256 dc_delay(sc);
257 }
258
259
260 dc_eeprom_idle(sc);
261
262 if (i < 4 || i > 12)
263 sc->dc_romwidth = 6;
264 else
265 sc->dc_romwidth = i;
266
267
268 CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
269 dc_delay(sc);
270 DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
271 dc_delay(sc);
272 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
273 dc_delay(sc);
274 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
275 dc_delay(sc);
276
277
278 dc_eeprom_idle(sc);
279 }
280
281 void
282 dc_eeprom_idle(sc)
283 struct dc_softc *sc;
284 {
285 int i;
286
287 CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
288 dc_delay(sc);
289 DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
290 dc_delay(sc);
291 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
292 dc_delay(sc);
293 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
294 dc_delay(sc);
295
296 for (i = 0; i < 25; i++) {
297 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
298 dc_delay(sc);
299 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
300 dc_delay(sc);
301 }
302
303 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
304 dc_delay(sc);
305 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CS);
306 dc_delay(sc);
307 CSR_WRITE_4(sc, DC_SIO, 0x00000000);
308 }
309
310
311
312
313 void
314 dc_eeprom_putbyte(sc, addr)
315 struct dc_softc *sc;
316 int addr;
317 {
318 int d, i;
319
320 d = DC_EECMD_READ >> 6;
321
322 for (i = 3; i--; ) {
323 if (d & (1 << i))
324 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
325 else
326 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
327 dc_delay(sc);
328 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
329 dc_delay(sc);
330 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
331 dc_delay(sc);
332 }
333
334
335
336
337 for (i = sc->dc_romwidth; i--;) {
338 if (addr & (1 << i)) {
339 SIO_SET(DC_SIO_EE_DATAIN);
340 } else {
341 SIO_CLR(DC_SIO_EE_DATAIN);
342 }
343 dc_delay(sc);
344 SIO_SET(DC_SIO_EE_CLK);
345 dc_delay(sc);
346 SIO_CLR(DC_SIO_EE_CLK);
347 dc_delay(sc);
348 }
349 }
350
351
352
353
354
355
356 void
357 dc_eeprom_getword_pnic(sc, addr, dest)
358 struct dc_softc *sc;
359 int addr;
360 u_int16_t *dest;
361 {
362 int i;
363 u_int32_t r;
364
365 CSR_WRITE_4(sc, DC_PN_SIOCTL, DC_PN_EEOPCODE_READ|addr);
366
367 for (i = 0; i < DC_TIMEOUT; i++) {
368 DELAY(1);
369 r = CSR_READ_4(sc, DC_SIO);
370 if (!(r & DC_PN_SIOCTL_BUSY)) {
371 *dest = (u_int16_t)(r & 0xFFFF);
372 return;
373 }
374 }
375 }
376
377
378
379
380
381
382 void
383 dc_eeprom_getword_xircom(struct dc_softc *sc, int addr, u_int16_t *dest)
384 {
385 SIO_SET(DC_SIO_ROMSEL | DC_SIO_ROMCTL_READ);
386
387 addr *= 2;
388 CSR_WRITE_4(sc, DC_ROM, addr | 0x160);
389 *dest = (u_int16_t)CSR_READ_4(sc, DC_SIO) & 0xff;
390 addr += 1;
391 CSR_WRITE_4(sc, DC_ROM, addr | 0x160);
392 *dest |= ((u_int16_t)CSR_READ_4(sc, DC_SIO) & 0xff) << 8;
393
394 SIO_CLR(DC_SIO_ROMSEL | DC_SIO_ROMCTL_READ);
395 }
396
397
398
399
400 void
401 dc_eeprom_getword(sc, addr, dest)
402 struct dc_softc *sc;
403 int addr;
404 u_int16_t *dest;
405 {
406 int i;
407 u_int16_t word = 0;
408
409
410 dc_eeprom_idle(sc);
411
412
413 CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
414 dc_delay(sc);
415 DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
416 dc_delay(sc);
417 DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
418 dc_delay(sc);
419 DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
420 dc_delay(sc);
421
422
423
424
425 dc_eeprom_putbyte(sc, addr);
426
427
428
429
430 for (i = 0x8000; i; i >>= 1) {
431 SIO_SET(DC_SIO_EE_CLK);
432 dc_delay(sc);
433 if (CSR_READ_4(sc, DC_SIO) & DC_SIO_EE_DATAOUT)
434 word |= i;
435 dc_delay(sc);
436 SIO_CLR(DC_SIO_EE_CLK);
437 dc_delay(sc);
438 }
439
440
441 dc_eeprom_idle(sc);
442
443 *dest = word;
444 }
445
446
447
448
449 void dc_read_eeprom(sc, dest, off, cnt, swap)
450 struct dc_softc *sc;
451 caddr_t dest;
452 int off, cnt, swap;
453 {
454 int i;
455 u_int16_t word = 0, *ptr;
456
457 for (i = 0; i < cnt; i++) {
458 if (DC_IS_PNIC(sc))
459 dc_eeprom_getword_pnic(sc, off + i, &word);
460 else if (DC_IS_XIRCOM(sc))
461 dc_eeprom_getword_xircom(sc, off + i, &word);
462 else
463 dc_eeprom_getword(sc, off + i, &word);
464 ptr = (u_int16_t *)(dest + (i * 2));
465 if (swap)
466 *ptr = betoh16(word);
467 else
468 *ptr = letoh16(word);
469 }
470 }
471
472
473
474
475
476
477
478
479 void
480 dc_mii_writebit(sc, bit)
481 struct dc_softc *sc;
482 int bit;
483 {
484 if (bit)
485 CSR_WRITE_4(sc, DC_SIO,
486 DC_SIO_ROMCTL_WRITE|DC_SIO_MII_DATAOUT);
487 else
488 CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_WRITE);
489
490 DC_SETBIT(sc, DC_SIO, DC_SIO_MII_CLK);
491 DC_CLRBIT(sc, DC_SIO, DC_SIO_MII_CLK);
492 }
493
494
495
496
497 int
498 dc_mii_readbit(sc)
499 struct dc_softc *sc;
500 {
501 CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_READ|DC_SIO_MII_DIR);
502 CSR_READ_4(sc, DC_SIO);
503 DC_SETBIT(sc, DC_SIO, DC_SIO_MII_CLK);
504 DC_CLRBIT(sc, DC_SIO, DC_SIO_MII_CLK);
505 if (CSR_READ_4(sc, DC_SIO) & DC_SIO_MII_DATAIN)
506 return (1);
507 return (0);
508 }
509
510
511
512
513 void
514 dc_mii_sync(sc)
515 struct dc_softc *sc;
516 {
517 int i;
518
519 CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_WRITE);
520
521 for (i = 0; i < 32; i++)
522 dc_mii_writebit(sc, 1);
523 }
524
525
526
527
528 void
529 dc_mii_send(sc, bits, cnt)
530 struct dc_softc *sc;
531 u_int32_t bits;
532 int cnt;
533 {
534 int i;
535
536 for (i = (0x1 << (cnt - 1)); i; i >>= 1)
537 dc_mii_writebit(sc, bits & i);
538 }
539
540
541
542
543 int
544 dc_mii_readreg(sc, frame)
545 struct dc_softc *sc;
546 struct dc_mii_frame *frame;
547 {
548 int i, ack, s;
549
550 s = splnet();
551
552
553
554
555 frame->mii_stdelim = DC_MII_STARTDELIM;
556 frame->mii_opcode = DC_MII_READOP;
557 frame->mii_turnaround = 0;
558 frame->mii_data = 0;
559
560
561
562
563 dc_mii_sync(sc);
564
565
566
567
568 dc_mii_send(sc, frame->mii_stdelim, 2);
569 dc_mii_send(sc, frame->mii_opcode, 2);
570 dc_mii_send(sc, frame->mii_phyaddr, 5);
571 dc_mii_send(sc, frame->mii_regaddr, 5);
572
573 #ifdef notdef
574
575 dc_mii_writebit(sc, 1);
576 dc_mii_writebit(sc, 0);
577 #endif
578
579
580 ack = dc_mii_readbit(sc);
581
582
583
584
585
586 if (ack) {
587 for(i = 0; i < 16; i++) {
588 dc_mii_readbit(sc);
589 }
590 goto fail;
591 }
592
593 for (i = 0x8000; i; i >>= 1) {
594 if (!ack) {
595 if (dc_mii_readbit(sc))
596 frame->mii_data |= i;
597 }
598 }
599
600 fail:
601
602 dc_mii_writebit(sc, 0);
603 dc_mii_writebit(sc, 0);
604
605 splx(s);
606
607 if (ack)
608 return (1);
609 return (0);
610 }
611
612
613
614
615 int
616 dc_mii_writereg(sc, frame)
617 struct dc_softc *sc;
618 struct dc_mii_frame *frame;
619 {
620 int s;
621
622 s = splnet();
623
624
625
626
627 frame->mii_stdelim = DC_MII_STARTDELIM;
628 frame->mii_opcode = DC_MII_WRITEOP;
629 frame->mii_turnaround = DC_MII_TURNAROUND;
630
631
632
633
634 dc_mii_sync(sc);
635
636 dc_mii_send(sc, frame->mii_stdelim, 2);
637 dc_mii_send(sc, frame->mii_opcode, 2);
638 dc_mii_send(sc, frame->mii_phyaddr, 5);
639 dc_mii_send(sc, frame->mii_regaddr, 5);
640 dc_mii_send(sc, frame->mii_turnaround, 2);
641 dc_mii_send(sc, frame->mii_data, 16);
642
643
644 dc_mii_writebit(sc, 0);
645 dc_mii_writebit(sc, 0);
646
647 splx(s);
648 return (0);
649 }
650
651 int
652 dc_miibus_readreg(self, phy, reg)
653 struct device *self;
654 int phy, reg;
655 {
656 struct dc_mii_frame frame;
657 struct dc_softc *sc = (struct dc_softc *)self;
658 int i, rval, phy_reg;
659
660
661
662
663
664
665
666
667
668
669 if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR)
670 return (0);
671
672
673
674
675
676
677 if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR)
678 return (0);
679
680 if (sc->dc_pmode != DC_PMODE_MII) {
681 if (phy == (MII_NPHY - 1)) {
682 switch(reg) {
683 case MII_BMSR:
684
685
686
687
688 return (BMSR_MEDIAMASK);
689 break;
690 case MII_PHYIDR1:
691 if (DC_IS_PNIC(sc))
692 return (PCI_VENDOR_LITEON);
693 return (PCI_VENDOR_DEC);
694 break;
695 case MII_PHYIDR2:
696 if (DC_IS_PNIC(sc))
697 return (PCI_PRODUCT_LITEON_PNIC);
698 return (PCI_PRODUCT_DEC_21142);
699 break;
700 default:
701 return (0);
702 break;
703 }
704 } else
705 return (0);
706 }
707
708 if (DC_IS_PNIC(sc)) {
709 CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_READ |
710 (phy << 23) | (reg << 18));
711 for (i = 0; i < DC_TIMEOUT; i++) {
712 DELAY(1);
713 rval = CSR_READ_4(sc, DC_PN_MII);
714 if (!(rval & DC_PN_MII_BUSY)) {
715 rval &= 0xFFFF;
716 return (rval == 0xFFFF ? 0 : rval);
717 }
718 }
719 return (0);
720 }
721
722 if (DC_IS_COMET(sc)) {
723 switch(reg) {
724 case MII_BMCR:
725 phy_reg = DC_AL_BMCR;
726 break;
727 case MII_BMSR:
728 phy_reg = DC_AL_BMSR;
729 break;
730 case MII_PHYIDR1:
731 phy_reg = DC_AL_VENID;
732 break;
733 case MII_PHYIDR2:
734 phy_reg = DC_AL_DEVID;
735 break;
736 case MII_ANAR:
737 phy_reg = DC_AL_ANAR;
738 break;
739 case MII_ANLPAR:
740 phy_reg = DC_AL_LPAR;
741 break;
742 case MII_ANER:
743 phy_reg = DC_AL_ANER;
744 break;
745 default:
746 printf("%s: phy_read: bad phy register %x\n",
747 sc->sc_dev.dv_xname, reg);
748 return (0);
749 break;
750 }
751
752 rval = CSR_READ_4(sc, phy_reg) & 0x0000FFFF;
753
754 if (rval == 0xFFFF)
755 return (0);
756 return (rval);
757 }
758
759 bzero(&frame, sizeof(frame));
760
761 frame.mii_phyaddr = phy;
762 frame.mii_regaddr = reg;
763 if (sc->dc_type == DC_TYPE_98713) {
764 phy_reg = CSR_READ_4(sc, DC_NETCFG);
765 CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL);
766 }
767 dc_mii_readreg(sc, &frame);
768 if (sc->dc_type == DC_TYPE_98713)
769 CSR_WRITE_4(sc, DC_NETCFG, phy_reg);
770
771 return (frame.mii_data);
772 }
773
774 void
775 dc_miibus_writereg(self, phy, reg, data)
776 struct device *self;
777 int phy, reg, data;
778 {
779 struct dc_softc *sc = (struct dc_softc *)self;
780 struct dc_mii_frame frame;
781 int i, phy_reg;
782
783 bzero((char *)&frame, sizeof(frame));
784
785 if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR)
786 return;
787 if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR)
788 return;
789
790 if (DC_IS_PNIC(sc)) {
791 CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE |
792 (phy << 23) | (reg << 10) | data);
793 for (i = 0; i < DC_TIMEOUT; i++) {
794 if (!(CSR_READ_4(sc, DC_PN_MII) & DC_PN_MII_BUSY))
795 break;
796 }
797 return;
798 }
799
800 if (DC_IS_COMET(sc)) {
801 switch(reg) {
802 case MII_BMCR:
803 phy_reg = DC_AL_BMCR;
804 break;
805 case MII_BMSR:
806 phy_reg = DC_AL_BMSR;
807 break;
808 case MII_PHYIDR1:
809 phy_reg = DC_AL_VENID;
810 break;
811 case MII_PHYIDR2:
812 phy_reg = DC_AL_DEVID;
813 break;
814 case MII_ANAR:
815 phy_reg = DC_AL_ANAR;
816 break;
817 case MII_ANLPAR:
818 phy_reg = DC_AL_LPAR;
819 break;
820 case MII_ANER:
821 phy_reg = DC_AL_ANER;
822 break;
823 default:
824 printf("%s: phy_write: bad phy register %x\n",
825 sc->sc_dev.dv_xname, reg);
826 return;
827 break;
828 }
829
830 CSR_WRITE_4(sc, phy_reg, data);
831 return;
832 }
833
834 frame.mii_phyaddr = phy;
835 frame.mii_regaddr = reg;
836 frame.mii_data = data;
837
838 if (sc->dc_type == DC_TYPE_98713) {
839 phy_reg = CSR_READ_4(sc, DC_NETCFG);
840 CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL);
841 }
842 dc_mii_writereg(sc, &frame);
843 if (sc->dc_type == DC_TYPE_98713)
844 CSR_WRITE_4(sc, DC_NETCFG, phy_reg);
845 }
846
847 void
848 dc_miibus_statchg(self)
849 struct device *self;
850 {
851 struct dc_softc *sc = (struct dc_softc *)self;
852 struct mii_data *mii;
853 struct ifmedia *ifm;
854
855 if (DC_IS_ADMTEK(sc))
856 return;
857
858 mii = &sc->sc_mii;
859 ifm = &mii->mii_media;
860 if (DC_IS_DAVICOM(sc) && IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
861 dc_setcfg(sc, ifm->ifm_media);
862 sc->dc_if_media = ifm->ifm_media;
863 } else {
864 dc_setcfg(sc, mii->mii_media_active);
865 sc->dc_if_media = mii->mii_media_active;
866 }
867 }
868
869 #define DC_BITS_512 9
870 #define DC_BITS_128 7
871 #define DC_BITS_64 6
872
873 u_int32_t
874 dc_crc_le(sc, addr)
875 struct dc_softc *sc;
876 caddr_t addr;
877 {
878 u_int32_t crc;
879
880
881 crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
882
883
884
885
886
887 if (sc->dc_flags & DC_128BIT_HASH)
888 return (crc & ((1 << DC_BITS_128) - 1));
889
890
891 if (sc->dc_flags & DC_64BIT_HASH)
892 return (crc & ((1 << DC_BITS_64) - 1));
893
894
895
896 if (DC_IS_XIRCOM(sc)) {
897 if ((crc & 0x180) == 0x180)
898 return (crc & 0x0F) + (crc & 0x70)*3 + (14 << 4);
899 else
900 return (crc & 0x1F) + ((crc>>1) & 0xF0)*3 + (12 << 4);
901 }
902
903 return (crc & ((1 << DC_BITS_512) - 1));
904 }
905
906
907
908
909 #define dc_crc_be(addr) ((ether_crc32_be(addr,ETHER_ADDR_LEN) >> 26) \
910 & 0x0000003F)
911
912
913
914
915
916
917
918
919
920
921
922 void
923 dc_setfilt_21143(sc)
924 struct dc_softc *sc;
925 {
926 struct dc_desc *sframe;
927 u_int32_t h, *sp;
928 struct arpcom *ac = &sc->sc_arpcom;
929 struct ether_multi *enm;
930 struct ether_multistep step;
931 struct ifnet *ifp;
932 int i;
933
934 ifp = &sc->sc_arpcom.ac_if;
935
936 i = sc->dc_cdata.dc_tx_prod;
937 DC_INC(sc->dc_cdata.dc_tx_prod, DC_TX_LIST_CNT);
938 sc->dc_cdata.dc_tx_cnt++;
939 sframe = &sc->dc_ldata->dc_tx_list[i];
940 sp = &sc->dc_ldata->dc_sbuf[0];
941 bzero((char *)sp, DC_SFRAME_LEN);
942
943 sframe->dc_data = htole32(sc->sc_listmap->dm_segs[0].ds_addr +
944 offsetof(struct dc_list_data, dc_sbuf));
945 sframe->dc_ctl = htole32(DC_SFRAME_LEN | DC_TXCTL_SETUP |
946 DC_TXCTL_TLINK | DC_FILTER_HASHPERF | DC_TXCTL_FINT);
947
948 sc->dc_cdata.dc_tx_chain[i].sd_mbuf =
949 (struct mbuf *)&sc->dc_ldata->dc_sbuf[0];
950
951
952 if (ifp->if_flags & IFF_PROMISC)
953 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
954 else
955 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
956
957 allmulti:
958 if (ifp->if_flags & IFF_ALLMULTI)
959 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
960 else {
961 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
962
963 ETHER_FIRST_MULTI(step, ac, enm);
964 while (enm != NULL) {
965 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
966 ETHER_ADDR_LEN)) {
967 ifp->if_flags |= IFF_ALLMULTI;
968 goto allmulti;
969 }
970
971 h = dc_crc_le(sc, enm->enm_addrlo);
972 sp[h >> 4] |= htole32(1 << (h & 0xF));
973 ETHER_NEXT_MULTI(step, enm);
974 }
975 }
976
977 if (ifp->if_flags & IFF_BROADCAST) {
978 h = dc_crc_le(sc, (caddr_t)ðerbroadcastaddr);
979 sp[h >> 4] |= htole32(1 << (h & 0xF));
980 }
981
982
983 sp[39] = DC_SP_FIELD(sc->sc_arpcom.ac_enaddr, 0);
984 sp[40] = DC_SP_FIELD(sc->sc_arpcom.ac_enaddr, 1);
985 sp[41] = DC_SP_FIELD(sc->sc_arpcom.ac_enaddr, 2);
986
987 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
988 offsetof(struct dc_list_data, dc_sbuf[0]),
989 sizeof(struct dc_list_data) -
990 offsetof(struct dc_list_data, dc_sbuf[0]),
991 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
992
993 sframe->dc_status = htole32(DC_TXSTAT_OWN);
994
995 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
996 offsetof(struct dc_list_data, dc_tx_list[i]),
997 sizeof(struct dc_desc), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
998
999 CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
1000
1001
1002
1003
1004
1005
1006
1007 DELAY(10000);
1008
1009 ifp->if_timer = 5;
1010 }
1011
1012 void
1013 dc_setfilt_admtek(sc)
1014 struct dc_softc *sc;
1015 {
1016 struct ifnet *ifp;
1017 struct arpcom *ac = &sc->sc_arpcom;
1018 struct ether_multi *enm;
1019 struct ether_multistep step;
1020 int h = 0;
1021 u_int32_t hashes[2] = { 0, 0 };
1022
1023 ifp = &sc->sc_arpcom.ac_if;
1024
1025
1026 CSR_WRITE_4(sc, DC_AL_PAR0, ac->ac_enaddr[3] << 24 |
1027 ac->ac_enaddr[2] << 16 | ac->ac_enaddr[1] << 8 | ac->ac_enaddr[0]);
1028 CSR_WRITE_4(sc, DC_AL_PAR1, ac->ac_enaddr[5] << 8 | ac->ac_enaddr[4]);
1029
1030
1031 if (ifp->if_flags & IFF_PROMISC)
1032 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
1033 else
1034 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
1035
1036 allmulti:
1037 if (ifp->if_flags & IFF_ALLMULTI)
1038 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
1039 else
1040 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
1041
1042
1043 CSR_WRITE_4(sc, DC_AL_MAR0, 0);
1044 CSR_WRITE_4(sc, DC_AL_MAR1, 0);
1045
1046
1047
1048
1049
1050 if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI))
1051 return;
1052
1053
1054 ETHER_FIRST_MULTI(step, ac, enm);
1055 while (enm != NULL) {
1056 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1057 ifp->if_flags |= IFF_ALLMULTI;
1058 goto allmulti;
1059 }
1060
1061 if (DC_IS_CENTAUR(sc))
1062 h = dc_crc_le(sc, enm->enm_addrlo);
1063 else
1064 h = dc_crc_be(enm->enm_addrlo);
1065 if (h < 32)
1066 hashes[0] |= (1 << h);
1067 else
1068 hashes[1] |= (1 << (h - 32));
1069 ETHER_NEXT_MULTI(step, enm);
1070 }
1071
1072 CSR_WRITE_4(sc, DC_AL_MAR0, hashes[0]);
1073 CSR_WRITE_4(sc, DC_AL_MAR1, hashes[1]);
1074 }
1075
1076 void
1077 dc_setfilt_asix(sc)
1078 struct dc_softc *sc;
1079 {
1080 struct ifnet *ifp;
1081 struct arpcom *ac = &sc->sc_arpcom;
1082 struct ether_multi *enm;
1083 struct ether_multistep step;
1084 int h = 0;
1085 u_int32_t hashes[2] = { 0, 0 };
1086
1087 ifp = &sc->sc_arpcom.ac_if;
1088
1089
1090 CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR0);
1091 CSR_WRITE_4(sc, DC_AX_FILTDATA,
1092 *(u_int32_t *)(&sc->sc_arpcom.ac_enaddr[0]));
1093 CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR1);
1094 CSR_WRITE_4(sc, DC_AX_FILTDATA,
1095 *(u_int32_t *)(&sc->sc_arpcom.ac_enaddr[4]));
1096
1097
1098 if (ifp->if_flags & IFF_PROMISC)
1099 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
1100 else
1101 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
1102
1103 if (ifp->if_flags & IFF_ALLMULTI)
1104 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
1105 else
1106 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
1107
1108
1109
1110
1111
1112 if (ifp->if_flags & IFF_BROADCAST)
1113 DC_SETBIT(sc, DC_NETCFG, DC_AX_NETCFG_RX_BROAD);
1114 else
1115 DC_CLRBIT(sc, DC_NETCFG, DC_AX_NETCFG_RX_BROAD);
1116
1117
1118 CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0);
1119 CSR_WRITE_4(sc, DC_AX_FILTDATA, 0);
1120 CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR1);
1121 CSR_WRITE_4(sc, DC_AX_FILTDATA, 0);
1122
1123
1124
1125
1126
1127 if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI))
1128 return;
1129
1130
1131 ETHER_FIRST_MULTI(step, ac, enm);
1132 while (enm != NULL) {
1133 h = dc_crc_be(enm->enm_addrlo);
1134 if (h < 32)
1135 hashes[0] |= (1 << h);
1136 else
1137 hashes[1] |= (1 << (h - 32));
1138 ETHER_NEXT_MULTI(step, enm);
1139 }
1140
1141 CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0);
1142 CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[0]);
1143 CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR1);
1144 CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[1]);
1145 }
1146
1147 void
1148 dc_setfilt_xircom(sc)
1149 struct dc_softc *sc;
1150 {
1151 struct dc_desc *sframe;
1152 struct arpcom *ac = &sc->sc_arpcom;
1153 struct ether_multi *enm;
1154 struct ether_multistep step;
1155 u_int32_t h, *sp;
1156 struct ifnet *ifp;
1157 int i;
1158
1159 ifp = &sc->sc_arpcom.ac_if;
1160 DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_TX_ON|DC_NETCFG_RX_ON));
1161
1162 i = sc->dc_cdata.dc_tx_prod;
1163 DC_INC(sc->dc_cdata.dc_tx_prod, DC_TX_LIST_CNT);
1164 sc->dc_cdata.dc_tx_cnt++;
1165 sframe = &sc->dc_ldata->dc_tx_list[i];
1166 sp = &sc->dc_ldata->dc_sbuf[0];
1167 bzero((char *)sp, DC_SFRAME_LEN);
1168
1169 sframe->dc_data = htole32(sc->sc_listmap->dm_segs[0].ds_addr +
1170 offsetof(struct dc_list_data, dc_sbuf));
1171 sframe->dc_ctl = htole32(DC_SFRAME_LEN | DC_TXCTL_SETUP |
1172 DC_TXCTL_TLINK | DC_FILTER_HASHPERF | DC_TXCTL_FINT);
1173
1174 sc->dc_cdata.dc_tx_chain[i].sd_mbuf =
1175 (struct mbuf *)&sc->dc_ldata->dc_sbuf[0];
1176
1177
1178 if (ifp->if_flags & IFF_PROMISC)
1179 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
1180 else
1181 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
1182
1183 if (ifp->if_flags & IFF_ALLMULTI)
1184 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
1185 else
1186 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
1187
1188
1189 ETHER_FIRST_MULTI(step, ac, enm);
1190 while (enm != NULL) {
1191 h = dc_crc_le(sc, enm->enm_addrlo);
1192 sp[h >> 4] |= htole32(1 << (h & 0xF));
1193 ETHER_NEXT_MULTI(step, enm);
1194 }
1195
1196 if (ifp->if_flags & IFF_BROADCAST) {
1197 h = dc_crc_le(sc, (caddr_t)ðerbroadcastaddr);
1198 sp[h >> 4] |= htole32(1 << (h & 0xF));
1199 }
1200
1201
1202 sp[0] = DC_SP_FIELD(sc->sc_arpcom.ac_enaddr, 0);
1203 sp[1] = DC_SP_FIELD(sc->sc_arpcom.ac_enaddr, 1);
1204 sp[2] = DC_SP_FIELD(sc->sc_arpcom.ac_enaddr, 2);
1205
1206 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
1207 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ON);
1208 ifp->if_flags |= IFF_RUNNING;
1209 sframe->dc_status = htole32(DC_TXSTAT_OWN);
1210 CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
1211
1212
1213
1214
1215 DELAY(1000);
1216
1217 ifp->if_timer = 5;
1218 }
1219
1220 void
1221 dc_setfilt(sc)
1222 struct dc_softc *sc;
1223 {
1224 if (DC_IS_INTEL(sc) || DC_IS_MACRONIX(sc) || DC_IS_PNIC(sc) ||
1225 DC_IS_PNICII(sc) || DC_IS_DAVICOM(sc) || DC_IS_CONEXANT(sc))
1226 dc_setfilt_21143(sc);
1227
1228 if (DC_IS_ASIX(sc))
1229 dc_setfilt_asix(sc);
1230
1231 if (DC_IS_ADMTEK(sc))
1232 dc_setfilt_admtek(sc);
1233
1234 if (DC_IS_XIRCOM(sc))
1235 dc_setfilt_xircom(sc);
1236 }
1237
1238
1239
1240
1241
1242
1243 void
1244 dc_setcfg(sc, media)
1245 struct dc_softc *sc;
1246 int media;
1247 {
1248 int i, restart = 0;
1249 u_int32_t isr;
1250
1251 if (IFM_SUBTYPE(media) == IFM_NONE)
1252 return;
1253
1254 if (CSR_READ_4(sc, DC_NETCFG) & (DC_NETCFG_TX_ON|DC_NETCFG_RX_ON)) {
1255 restart = 1;
1256 DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_TX_ON|DC_NETCFG_RX_ON));
1257
1258 for (i = 0; i < DC_TIMEOUT; i++) {
1259 isr = CSR_READ_4(sc, DC_ISR);
1260 if (isr & DC_ISR_TX_IDLE &&
1261 ((isr & DC_ISR_RX_STATE) == DC_RXSTATE_STOPPED ||
1262 (isr & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT))
1263 break;
1264 DELAY(10);
1265 }
1266
1267 if (i == DC_TIMEOUT)
1268 printf("%s: failed to force tx and "
1269 "rx to idle state\n", sc->sc_dev.dv_xname);
1270 }
1271
1272 if (IFM_SUBTYPE(media) == IFM_100_TX) {
1273 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_SPEEDSEL);
1274 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_HEARTBEAT);
1275 if (sc->dc_pmode == DC_PMODE_MII) {
1276 int watchdogreg;
1277
1278 if (DC_IS_INTEL(sc)) {
1279
1280 watchdogreg = CSR_READ_4(sc, DC_WATCHDOG);
1281 watchdogreg &= ~DC_WDOG_CTLWREN;
1282 watchdogreg |= DC_WDOG_JABBERDIS;
1283 CSR_WRITE_4(sc, DC_WATCHDOG, watchdogreg);
1284 } else {
1285 DC_SETBIT(sc, DC_WATCHDOG, DC_WDOG_JABBERDIS);
1286 }
1287 DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_PCS|
1288 DC_NETCFG_PORTSEL|DC_NETCFG_SCRAMBLER));
1289 if (sc->dc_type == DC_TYPE_98713)
1290 DC_SETBIT(sc, DC_NETCFG, (DC_NETCFG_PCS|
1291 DC_NETCFG_SCRAMBLER));
1292 if (!DC_IS_DAVICOM(sc))
1293 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
1294 DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
1295 if (DC_IS_INTEL(sc))
1296 dc_apply_fixup(sc, IFM_AUTO);
1297 } else {
1298 if (DC_IS_PNIC(sc)) {
1299 DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_SPEEDSEL);
1300 DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_100TX_LOOP);
1301 DC_SETBIT(sc, DC_PN_NWAY, DC_PN_NWAY_SPEEDSEL);
1302 }
1303 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
1304 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
1305 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER);
1306 if (DC_IS_INTEL(sc))
1307 dc_apply_fixup(sc,
1308 (media & IFM_GMASK) == IFM_FDX ?
1309 IFM_100_TX|IFM_FDX : IFM_100_TX);
1310 }
1311 }
1312
1313 if (IFM_SUBTYPE(media) == IFM_10_T) {
1314 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_SPEEDSEL);
1315 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_HEARTBEAT);
1316 if (sc->dc_pmode == DC_PMODE_MII) {
1317 int watchdogreg;
1318
1319 if (DC_IS_INTEL(sc)) {
1320
1321 watchdogreg = CSR_READ_4(sc, DC_WATCHDOG);
1322 watchdogreg &= ~DC_WDOG_CTLWREN;
1323 watchdogreg |= DC_WDOG_JABBERDIS;
1324 CSR_WRITE_4(sc, DC_WATCHDOG, watchdogreg);
1325 } else {
1326 DC_SETBIT(sc, DC_WATCHDOG, DC_WDOG_JABBERDIS);
1327 }
1328 DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_PCS|
1329 DC_NETCFG_PORTSEL|DC_NETCFG_SCRAMBLER));
1330 if (sc->dc_type == DC_TYPE_98713)
1331 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
1332 if (!DC_IS_DAVICOM(sc))
1333 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
1334 DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
1335 if (DC_IS_INTEL(sc))
1336 dc_apply_fixup(sc, IFM_AUTO);
1337 } else {
1338 if (DC_IS_PNIC(sc)) {
1339 DC_PN_GPIO_CLRBIT(sc, DC_PN_GPIO_SPEEDSEL);
1340 DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_100TX_LOOP);
1341 DC_CLRBIT(sc, DC_PN_NWAY, DC_PN_NWAY_SPEEDSEL);
1342 }
1343 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
1344 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
1345 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER);
1346 if (DC_IS_INTEL(sc)) {
1347 DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET);
1348 DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
1349 if ((media & IFM_GMASK) == IFM_FDX)
1350 DC_SETBIT(sc, DC_10BTCTRL, 0x7F3D);
1351 else
1352 DC_SETBIT(sc, DC_10BTCTRL, 0x7F3F);
1353 DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
1354 DC_CLRBIT(sc, DC_10BTCTRL,
1355 DC_TCTL_AUTONEGENBL);
1356 dc_apply_fixup(sc,
1357 (media & IFM_GMASK) == IFM_FDX ?
1358 IFM_10_T|IFM_FDX : IFM_10_T);
1359 DELAY(20000);
1360 }
1361 }
1362 }
1363
1364
1365
1366
1367
1368
1369 if (DC_IS_DAVICOM(sc)) {
1370 if (IFM_SUBTYPE(media) == IFM_HPNA_1) {
1371 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
1372 sc->dc_link = 1;
1373 } else {
1374 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
1375 }
1376 }
1377
1378 if ((media & IFM_GMASK) == IFM_FDX) {
1379 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
1380 if (sc->dc_pmode == DC_PMODE_SYM && DC_IS_PNIC(sc))
1381 DC_SETBIT(sc, DC_PN_NWAY, DC_PN_NWAY_DUPLEX);
1382 } else {
1383 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
1384 if (sc->dc_pmode == DC_PMODE_SYM && DC_IS_PNIC(sc))
1385 DC_CLRBIT(sc, DC_PN_NWAY, DC_PN_NWAY_DUPLEX);
1386 }
1387
1388 if (restart)
1389 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON|DC_NETCFG_RX_ON);
1390 }
1391
1392 void
1393 dc_reset(sc)
1394 struct dc_softc *sc;
1395 {
1396 int i;
1397
1398 DC_SETBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET);
1399
1400 for (i = 0; i < DC_TIMEOUT; i++) {
1401 DELAY(10);
1402 if (!(CSR_READ_4(sc, DC_BUSCTL) & DC_BUSCTL_RESET))
1403 break;
1404 }
1405
1406 if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_XIRCOM(sc) ||
1407 DC_IS_INTEL(sc) || DC_IS_CONEXANT(sc)) {
1408 DELAY(10000);
1409 DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET);
1410 i = 0;
1411 }
1412
1413 if (i == DC_TIMEOUT)
1414 printf("%s: reset never completed!\n", sc->sc_dev.dv_xname);
1415
1416
1417 DELAY(1000);
1418
1419 CSR_WRITE_4(sc, DC_IMR, 0x00000000);
1420 CSR_WRITE_4(sc, DC_BUSCTL, 0x00000000);
1421 CSR_WRITE_4(sc, DC_NETCFG, 0x00000000);
1422
1423
1424
1425
1426
1427
1428
1429 if (DC_IS_INTEL(sc)) {
1430 DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
1431 CSR_WRITE_4(sc, DC_10BTCTRL, 0);
1432 CSR_WRITE_4(sc, DC_WATCHDOG, 0);
1433 }
1434
1435 if (sc->dc_type == DC_TYPE_21145)
1436 dc_setcfg(sc, IFM_10_T);
1437 }
1438
1439 void
1440 dc_apply_fixup(sc, media)
1441 struct dc_softc *sc;
1442 int media;
1443 {
1444 struct dc_mediainfo *m;
1445 u_int8_t *p;
1446 int i;
1447 u_int32_t reg;
1448
1449 m = sc->dc_mi;
1450
1451 while (m != NULL) {
1452 if (m->dc_media == media)
1453 break;
1454 m = m->dc_next;
1455 }
1456
1457 if (m == NULL)
1458 return;
1459
1460 for (i = 0, p = m->dc_reset_ptr; i < m->dc_reset_len; i++, p += 2) {
1461 reg = (p[0] | (p[1] << 8)) << 16;
1462 CSR_WRITE_4(sc, DC_WATCHDOG, reg);
1463 }
1464
1465 for (i = 0, p = m->dc_gp_ptr; i < m->dc_gp_len; i++, p += 2) {
1466 reg = (p[0] | (p[1] << 8)) << 16;
1467 CSR_WRITE_4(sc, DC_WATCHDOG, reg);
1468 }
1469 }
1470
1471 void
1472 dc_decode_leaf_sia(sc, l)
1473 struct dc_softc *sc;
1474 struct dc_eblock_sia *l;
1475 {
1476 struct dc_mediainfo *m;
1477
1478 m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT);
1479 if (m == NULL)
1480 return;
1481 bzero(m, sizeof(struct dc_mediainfo));
1482 switch (l->dc_sia_code & ~DC_SIA_CODE_EXT) {
1483 case DC_SIA_CODE_10BT:
1484 m->dc_media = IFM_10_T;
1485 break;
1486 case DC_SIA_CODE_10BT_FDX:
1487 m->dc_media = IFM_10_T|IFM_FDX;
1488 break;
1489 case DC_SIA_CODE_10B2:
1490 m->dc_media = IFM_10_2;
1491 break;
1492 case DC_SIA_CODE_10B5:
1493 m->dc_media = IFM_10_5;
1494 break;
1495 default:
1496 break;
1497 }
1498
1499
1500
1501
1502
1503
1504 if (l->dc_sia_code & DC_SIA_CODE_EXT) {
1505 m->dc_gp_len = 2;
1506 m->dc_gp_ptr =
1507 (u_int8_t *)&l->dc_un.dc_sia_ext.dc_sia_gpio_ctl;
1508 } else {
1509 m->dc_gp_len = 2;
1510 m->dc_gp_ptr =
1511 (u_int8_t *)&l->dc_un.dc_sia_noext.dc_sia_gpio_ctl;
1512 }
1513
1514 m->dc_next = sc->dc_mi;
1515 sc->dc_mi = m;
1516
1517 sc->dc_pmode = DC_PMODE_SIA;
1518 }
1519
1520 void
1521 dc_decode_leaf_sym(sc, l)
1522 struct dc_softc *sc;
1523 struct dc_eblock_sym *l;
1524 {
1525 struct dc_mediainfo *m;
1526
1527 m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT);
1528 if (m == NULL)
1529 return;
1530 bzero(m, sizeof(struct dc_mediainfo));
1531 if (l->dc_sym_code == DC_SYM_CODE_100BT)
1532 m->dc_media = IFM_100_TX;
1533
1534 if (l->dc_sym_code == DC_SYM_CODE_100BT_FDX)
1535 m->dc_media = IFM_100_TX|IFM_FDX;
1536
1537 m->dc_gp_len = 2;
1538 m->dc_gp_ptr = (u_int8_t *)&l->dc_sym_gpio_ctl;
1539
1540 m->dc_next = sc->dc_mi;
1541 sc->dc_mi = m;
1542
1543 sc->dc_pmode = DC_PMODE_SYM;
1544 }
1545
1546 void
1547 dc_decode_leaf_mii(sc, l)
1548 struct dc_softc *sc;
1549 struct dc_eblock_mii *l;
1550 {
1551 u_int8_t *p;
1552 struct dc_mediainfo *m;
1553
1554 m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT);
1555 if (m == NULL)
1556 return;
1557 bzero(m, sizeof(struct dc_mediainfo));
1558
1559 m->dc_media = IFM_AUTO;
1560 m->dc_gp_len = l->dc_gpr_len;
1561
1562 p = (u_int8_t *)l;
1563 p += sizeof(struct dc_eblock_mii);
1564 m->dc_gp_ptr = p;
1565 p += 2 * l->dc_gpr_len;
1566 m->dc_reset_len = *p;
1567 p++;
1568 m->dc_reset_ptr = p;
1569
1570 m->dc_next = sc->dc_mi;
1571 sc->dc_mi = m;
1572 }
1573
1574 void
1575 dc_read_srom(sc, bits)
1576 struct dc_softc *sc;
1577 int bits;
1578 {
1579 int size;
1580
1581 size = 2 << bits;
1582 sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT);
1583 if (sc->dc_srom == NULL)
1584 return;
1585 dc_read_eeprom(sc, (caddr_t)sc->dc_srom, 0, (size / 2), 0);
1586 }
1587
1588 void
1589 dc_parse_21143_srom(sc)
1590 struct dc_softc *sc;
1591 {
1592 struct dc_leaf_hdr *lhdr;
1593 struct dc_eblock_hdr *hdr;
1594 int have_mii, i, loff;
1595 char *ptr;
1596
1597 have_mii = 0;
1598 loff = sc->dc_srom[27];
1599 lhdr = (struct dc_leaf_hdr *)&(sc->dc_srom[loff]);
1600
1601 ptr = (char *)lhdr;
1602 ptr += sizeof(struct dc_leaf_hdr) - 1;
1603
1604
1605
1606 for (i = 0; i < lhdr->dc_mcnt; i++) {
1607 hdr = (struct dc_eblock_hdr *)ptr;
1608 if (hdr->dc_type == DC_EBLOCK_MII)
1609 have_mii++;
1610
1611 ptr += (hdr->dc_len & 0x7F);
1612 ptr++;
1613 }
1614
1615
1616
1617
1618
1619 ptr = (char *)lhdr;
1620 ptr += sizeof(struct dc_leaf_hdr) - 1;
1621 for (i = 0; i < lhdr->dc_mcnt; i++) {
1622 hdr = (struct dc_eblock_hdr *)ptr;
1623 switch(hdr->dc_type) {
1624 case DC_EBLOCK_MII:
1625 dc_decode_leaf_mii(sc, (struct dc_eblock_mii *)hdr);
1626 break;
1627 case DC_EBLOCK_SIA:
1628 if (! have_mii)
1629 dc_decode_leaf_sia(sc,
1630 (struct dc_eblock_sia *)hdr);
1631 break;
1632 case DC_EBLOCK_SYM:
1633 if (! have_mii)
1634 dc_decode_leaf_sym(sc,
1635 (struct dc_eblock_sym *)hdr);
1636 break;
1637 default:
1638
1639 break;
1640 }
1641 ptr += (hdr->dc_len & 0x7F);
1642 ptr++;
1643 }
1644 }
1645
1646
1647
1648
1649
1650 void
1651 dc_attach(sc)
1652 struct dc_softc *sc;
1653 {
1654 struct ifnet *ifp;
1655 int mac_offset, tmp, i;
1656 u_int32_t reg;
1657
1658
1659
1660
1661 if (sc->sc_hasmac)
1662 goto hasmac;
1663
1664 switch(sc->dc_type) {
1665 case DC_TYPE_98713:
1666 case DC_TYPE_98713A:
1667 case DC_TYPE_987x5:
1668 case DC_TYPE_PNICII:
1669 dc_read_eeprom(sc, (caddr_t)&mac_offset,
1670 (DC_EE_NODEADDR_OFFSET / 2), 1, 0);
1671 dc_read_eeprom(sc, (caddr_t)&sc->sc_arpcom.ac_enaddr,
1672 (mac_offset / 2), 3, 0);
1673 break;
1674 case DC_TYPE_PNIC:
1675 dc_read_eeprom(sc, (caddr_t)&sc->sc_arpcom.ac_enaddr, 0, 3, 1);
1676 break;
1677 case DC_TYPE_DM9102:
1678 case DC_TYPE_21143:
1679 case DC_TYPE_21145:
1680 case DC_TYPE_ASIX:
1681 dc_read_eeprom(sc, (caddr_t)&sc->sc_arpcom.ac_enaddr,
1682 DC_EE_NODEADDR, 3, 0);
1683 break;
1684 case DC_TYPE_AL981:
1685 case DC_TYPE_AN983:
1686 reg = CSR_READ_4(sc, DC_AL_PAR0);
1687 sc->sc_arpcom.ac_enaddr[0] = (reg & 0xff);
1688 sc->sc_arpcom.ac_enaddr[1] = (reg >> 8) & 0xff;
1689 sc->sc_arpcom.ac_enaddr[2] = (reg >> 16) & 0xff;
1690 sc->sc_arpcom.ac_enaddr[3] = (reg >> 24) & 0xff;
1691 reg = CSR_READ_4(sc, DC_AL_PAR1);
1692 sc->sc_arpcom.ac_enaddr[4] = (reg & 0xff);
1693 sc->sc_arpcom.ac_enaddr[5] = (reg >> 8) & 0xff;
1694 break;
1695 case DC_TYPE_CONEXANT:
1696 bcopy(&sc->dc_srom + DC_CONEXANT_EE_NODEADDR,
1697 &sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
1698 break;
1699 case DC_TYPE_XIRCOM:
1700 break;
1701 default:
1702 dc_read_eeprom(sc, (caddr_t)&sc->sc_arpcom.ac_enaddr,
1703 DC_EE_NODEADDR, 3, 0);
1704 break;
1705 }
1706 hasmac:
1707
1708 if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct dc_list_data),
1709 PAGE_SIZE, 0, sc->sc_listseg, 1, &sc->sc_listnseg,
1710 BUS_DMA_NOWAIT) != 0) {
1711 printf(": can't alloc list mem\n");
1712 goto fail;
1713 }
1714 if (bus_dmamem_map(sc->sc_dmat, sc->sc_listseg, sc->sc_listnseg,
1715 sizeof(struct dc_list_data), &sc->sc_listkva,
1716 BUS_DMA_NOWAIT) != 0) {
1717 printf(": can't map list mem\n");
1718 goto fail;
1719 }
1720 if (bus_dmamap_create(sc->sc_dmat, sizeof(struct dc_list_data), 1,
1721 sizeof(struct dc_list_data), 0, BUS_DMA_NOWAIT,
1722 &sc->sc_listmap) != 0) {
1723 printf(": can't alloc list map\n");
1724 goto fail;
1725 }
1726 if (bus_dmamap_load(sc->sc_dmat, sc->sc_listmap, sc->sc_listkva,
1727 sizeof(struct dc_list_data), NULL, BUS_DMA_NOWAIT) != 0) {
1728 printf(": can't load list map\n");
1729 goto fail;
1730 }
1731 sc->dc_ldata = (struct dc_list_data *)sc->sc_listkva;
1732 bzero(sc->dc_ldata, sizeof(struct dc_list_data));
1733
1734 for (i = 0; i < DC_RX_LIST_CNT; i++) {
1735 if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
1736 0, BUS_DMA_NOWAIT,
1737 &sc->dc_cdata.dc_rx_chain[i].sd_map) != 0) {
1738 printf(": can't create rx map\n");
1739 return;
1740 }
1741 }
1742 if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0,
1743 BUS_DMA_NOWAIT, &sc->sc_rx_sparemap) != 0) {
1744 printf(": can't create rx spare map\n");
1745 return;
1746 }
1747
1748 for (i = 0; i < DC_TX_LIST_CNT; i++) {
1749 if (bus_dmamap_create(sc->sc_dmat, MCLBYTES,
1750 DC_TX_LIST_CNT - 5, MCLBYTES, 0, BUS_DMA_NOWAIT,
1751 &sc->dc_cdata.dc_tx_chain[i].sd_map) != 0) {
1752 printf(": can't create tx map\n");
1753 return;
1754 }
1755 }
1756 if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, DC_TX_LIST_CNT - 5,
1757 MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_tx_sparemap) != 0) {
1758 printf(": can't create tx spare map\n");
1759 return;
1760 }
1761
1762
1763
1764
1765 printf(" address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
1766
1767 ifp = &sc->sc_arpcom.ac_if;
1768 ifp->if_softc = sc;
1769 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1770 ifp->if_ioctl = dc_ioctl;
1771 ifp->if_start = dc_start;
1772 ifp->if_watchdog = dc_watchdog;
1773 ifp->if_baudrate = 10000000;
1774 IFQ_SET_MAXLEN(&ifp->if_snd, DC_TX_LIST_CNT - 1);
1775 IFQ_SET_READY(&ifp->if_snd);
1776 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
1777
1778 ifp->if_capabilities = IFCAP_VLAN_MTU;
1779
1780
1781
1782
1783
1784
1785
1786 if (DC_IS_INTEL(sc)) {
1787 dc_apply_fixup(sc, IFM_AUTO);
1788 tmp = sc->dc_pmode;
1789 sc->dc_pmode = DC_PMODE_MII;
1790 }
1791
1792
1793
1794
1795
1796
1797 if (DC_IS_XIRCOM(sc)) {
1798 CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_WRITE_EN | DC_SIAGP_INT1_EN |
1799 DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT);
1800 DELAY(10);
1801 CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_INT1_EN |
1802 DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT);
1803 DELAY(10);
1804 }
1805
1806 sc->sc_mii.mii_ifp = ifp;
1807 sc->sc_mii.mii_readreg = dc_miibus_readreg;
1808 sc->sc_mii.mii_writereg = dc_miibus_writereg;
1809 sc->sc_mii.mii_statchg = dc_miibus_statchg;
1810 ifmedia_init(&sc->sc_mii.mii_media, 0, dc_ifmedia_upd, dc_ifmedia_sts);
1811 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
1812 MII_OFFSET_ANY, 0);
1813
1814 if (DC_IS_INTEL(sc)) {
1815 if (LIST_EMPTY(&sc->sc_mii.mii_phys)) {
1816 sc->dc_pmode = tmp;
1817 if (sc->dc_pmode != DC_PMODE_SIA)
1818 sc->dc_pmode = DC_PMODE_SYM;
1819 sc->dc_flags |= DC_21143_NWAY;
1820 if (sc->dc_flags & DC_MOMENCO_BOTCH)
1821 sc->dc_pmode = DC_PMODE_MII;
1822 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff,
1823 MII_PHY_ANY, MII_OFFSET_ANY, 0);
1824 } else {
1825
1826 sc->dc_flags &= ~DC_TULIP_LEDS;
1827 }
1828 }
1829
1830 if (LIST_EMPTY(&sc->sc_mii.mii_phys)) {
1831 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
1832 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
1833 printf("%s: MII without any PHY!\n", sc->sc_dev.dv_xname);
1834 } else if (sc->dc_type == DC_TYPE_21145) {
1835 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_10_T);
1836 } else
1837 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
1838
1839 if (DC_IS_DAVICOM(sc) && sc->dc_revision >= DC_REVISION_DM9102A)
1840 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_HPNA_1,0,NULL);
1841
1842 if (DC_IS_ADMTEK(sc)) {
1843
1844
1845
1846 DC_SETBIT(sc, DC_AL_CR, DC_AL_CR_ATUR);
1847 }
1848
1849
1850
1851
1852 if_attach(ifp);
1853 ether_ifattach(ifp);
1854
1855 sc->sc_dhook = shutdownhook_establish(dc_shutdown, sc);
1856 sc->sc_pwrhook = powerhook_establish(dc_power, sc);
1857
1858 fail:
1859 return;
1860 }
1861
1862
1863
1864
1865 int
1866 dc_list_tx_init(sc)
1867 struct dc_softc *sc;
1868 {
1869 struct dc_chain_data *cd;
1870 struct dc_list_data *ld;
1871 int i;
1872 bus_addr_t next;
1873
1874 cd = &sc->dc_cdata;
1875 ld = sc->dc_ldata;
1876 for (i = 0; i < DC_TX_LIST_CNT; i++) {
1877 next = sc->sc_listmap->dm_segs[0].ds_addr;
1878 if (i == (DC_TX_LIST_CNT - 1))
1879 next +=
1880 offsetof(struct dc_list_data, dc_tx_list[0]);
1881 else
1882 next +=
1883 offsetof(struct dc_list_data, dc_tx_list[i + 1]);
1884 cd->dc_tx_chain[i].sd_mbuf = NULL;
1885 ld->dc_tx_list[i].dc_data = htole32(0);
1886 ld->dc_tx_list[i].dc_ctl = htole32(0);
1887 ld->dc_tx_list[i].dc_next = htole32(next);
1888 }
1889
1890 cd->dc_tx_prod = cd->dc_tx_cons = cd->dc_tx_cnt = 0;
1891
1892 return (0);
1893 }
1894
1895
1896
1897
1898
1899
1900
1901 int
1902 dc_list_rx_init(sc)
1903 struct dc_softc *sc;
1904 {
1905 struct dc_chain_data *cd;
1906 struct dc_list_data *ld;
1907 int i;
1908 bus_addr_t next;
1909
1910 cd = &sc->dc_cdata;
1911 ld = sc->dc_ldata;
1912
1913 for (i = 0; i < DC_RX_LIST_CNT; i++) {
1914 if (dc_newbuf(sc, i, NULL) == ENOBUFS)
1915 return (ENOBUFS);
1916 next = sc->sc_listmap->dm_segs[0].ds_addr;
1917 if (i == (DC_RX_LIST_CNT - 1))
1918 next +=
1919 offsetof(struct dc_list_data, dc_rx_list[0]);
1920 else
1921 next +=
1922 offsetof(struct dc_list_data, dc_rx_list[i + 1]);
1923 ld->dc_rx_list[i].dc_next = htole32(next);
1924 }
1925
1926 cd->dc_rx_prod = 0;
1927
1928 return (0);
1929 }
1930
1931
1932
1933
1934 int
1935 dc_newbuf(sc, i, m)
1936 struct dc_softc *sc;
1937 int i;
1938 struct mbuf *m;
1939 {
1940 struct mbuf *m_new = NULL;
1941 struct dc_desc *c;
1942 bus_dmamap_t map;
1943
1944 c = &sc->dc_ldata->dc_rx_list[i];
1945
1946 if (m == NULL) {
1947 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1948 if (m_new == NULL)
1949 return (ENOBUFS);
1950
1951 MCLGET(m_new, M_DONTWAIT);
1952 if (!(m_new->m_flags & M_EXT)) {
1953 m_freem(m_new);
1954 return (ENOBUFS);
1955 }
1956 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1957 if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rx_sparemap,
1958 m_new, BUS_DMA_NOWAIT) != 0) {
1959 m_freem(m_new);
1960 return (ENOBUFS);
1961 }
1962 map = sc->dc_cdata.dc_rx_chain[i].sd_map;
1963 sc->dc_cdata.dc_rx_chain[i].sd_map = sc->sc_rx_sparemap;
1964 sc->sc_rx_sparemap = map;
1965 } else {
1966
1967
1968
1969
1970
1971 m_new = m;
1972 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1973 m_new->m_data = m_new->m_ext.ext_buf;
1974 }
1975
1976 m_adj(m_new, sizeof(u_int64_t));
1977
1978
1979
1980
1981
1982
1983 if (sc->dc_flags & DC_PNIC_RX_BUG_WAR)
1984 bzero((char *)mtod(m_new, char *), m_new->m_len);
1985
1986 bus_dmamap_sync(sc->sc_dmat, sc->dc_cdata.dc_rx_chain[i].sd_map, 0,
1987 sc->dc_cdata.dc_rx_chain[i].sd_map->dm_mapsize,
1988 BUS_DMASYNC_PREREAD);
1989
1990 sc->dc_cdata.dc_rx_chain[i].sd_mbuf = m_new;
1991 c->dc_data = htole32(
1992 sc->dc_cdata.dc_rx_chain[i].sd_map->dm_segs[0].ds_addr +
1993 sizeof(u_int64_t));
1994 c->dc_ctl = htole32(DC_RXCTL_RLINK | ETHER_MAX_DIX_LEN);
1995 c->dc_status = htole32(DC_RXSTAT_OWN);
1996
1997 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
1998 offsetof(struct dc_list_data, dc_rx_list[i]),
1999 sizeof(struct dc_desc),
2000 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2001
2002 return (0);
2003 }
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057 #define DC_WHOLEFRAME (DC_RXSTAT_FIRSTFRAG|DC_RXSTAT_LASTFRAG)
2058 void
2059 dc_pnic_rx_bug_war(sc, idx)
2060 struct dc_softc *sc;
2061 int idx;
2062 {
2063 struct dc_desc *cur_rx;
2064 struct dc_desc *c = NULL;
2065 struct mbuf *m = NULL;
2066 unsigned char *ptr;
2067 int i, total_len;
2068 u_int32_t rxstat = 0;
2069
2070 i = sc->dc_pnic_rx_bug_save;
2071 cur_rx = &sc->dc_ldata->dc_rx_list[idx];
2072 ptr = sc->dc_pnic_rx_buf;
2073 bzero(ptr, ETHER_MAX_DIX_LEN * 5);
2074
2075
2076 while (1) {
2077 c = &sc->dc_ldata->dc_rx_list[i];
2078 rxstat = letoh32(c->dc_status);
2079 m = sc->dc_cdata.dc_rx_chain[i].sd_mbuf;
2080 bcopy(mtod(m, char *), ptr, ETHER_MAX_DIX_LEN);
2081 ptr += ETHER_MAX_DIX_LEN;
2082
2083 if (i == idx || rxstat & DC_RXSTAT_LASTFRAG)
2084 break;
2085 dc_newbuf(sc, i, m);
2086 DC_INC(i, DC_RX_LIST_CNT);
2087 }
2088
2089
2090 total_len = DC_RXBYTES(rxstat);
2091
2092
2093 while(*ptr == 0x00)
2094 ptr--;
2095
2096
2097 if ((unsigned long)(ptr) & 0x3)
2098 ptr -= 1;
2099
2100
2101 ptr -= total_len;
2102 if (ptr < sc->dc_pnic_rx_buf)
2103 ptr = sc->dc_pnic_rx_buf;
2104
2105
2106
2107
2108
2109
2110 dc_newbuf(sc, i, m);
2111 bcopy(ptr, mtod(m, char *), total_len);
2112 cur_rx->dc_status = htole32(rxstat | DC_RXSTAT_FIRSTFRAG);
2113 }
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126 int
2127 dc_rx_resync(sc)
2128 struct dc_softc *sc;
2129 {
2130 u_int32_t stat;
2131 int i, pos, offset;
2132
2133 pos = sc->dc_cdata.dc_rx_prod;
2134
2135 for (i = 0; i < DC_RX_LIST_CNT; i++) {
2136
2137 offset = offsetof(struct dc_list_data, dc_rx_list[pos]);
2138 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
2139 offset, sizeof(struct dc_desc),
2140 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2141
2142 stat = sc->dc_ldata->dc_rx_list[pos].dc_status;
2143 if (!(stat & htole32(DC_RXSTAT_OWN)))
2144 break;
2145 DC_INC(pos, DC_RX_LIST_CNT);
2146 }
2147
2148
2149 if (i == DC_RX_LIST_CNT)
2150 return (0);
2151
2152
2153 sc->dc_cdata.dc_rx_prod = pos;
2154
2155 return (EAGAIN);
2156 }
2157
2158
2159
2160
2161
2162 void
2163 dc_rxeof(sc)
2164 struct dc_softc *sc;
2165 {
2166 struct mbuf *m;
2167 struct ifnet *ifp;
2168 struct dc_desc *cur_rx;
2169 int i, offset, total_len = 0;
2170 u_int32_t rxstat;
2171
2172 ifp = &sc->sc_arpcom.ac_if;
2173 i = sc->dc_cdata.dc_rx_prod;
2174
2175 for(;;) {
2176 struct mbuf *m0 = NULL;
2177
2178 offset = offsetof(struct dc_list_data, dc_rx_list[i]);
2179 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
2180 offset, sizeof(struct dc_desc),
2181 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2182
2183 cur_rx = &sc->dc_ldata->dc_rx_list[i];
2184 rxstat = letoh32(cur_rx->dc_status);
2185 if (rxstat & DC_RXSTAT_OWN)
2186 break;
2187
2188 m = sc->dc_cdata.dc_rx_chain[i].sd_mbuf;
2189 total_len = DC_RXBYTES(rxstat);
2190
2191 bus_dmamap_sync(sc->sc_dmat, sc->dc_cdata.dc_rx_chain[i].sd_map,
2192 0, sc->dc_cdata.dc_rx_chain[i].sd_map->dm_mapsize,
2193 BUS_DMASYNC_POSTREAD);
2194
2195 if (sc->dc_flags & DC_PNIC_RX_BUG_WAR) {
2196 if ((rxstat & DC_WHOLEFRAME) != DC_WHOLEFRAME) {
2197 if (rxstat & DC_RXSTAT_FIRSTFRAG)
2198 sc->dc_pnic_rx_bug_save = i;
2199 if ((rxstat & DC_RXSTAT_LASTFRAG) == 0) {
2200 DC_INC(i, DC_RX_LIST_CNT);
2201 continue;
2202 }
2203 dc_pnic_rx_bug_war(sc, i);
2204 rxstat = letoh32(cur_rx->dc_status);
2205 total_len = DC_RXBYTES(rxstat);
2206 }
2207 }
2208
2209 sc->dc_cdata.dc_rx_chain[i].sd_mbuf = NULL;
2210
2211
2212
2213
2214
2215
2216
2217
2218 if ((rxstat & DC_RXSTAT_RXERR)) {
2219 if (!(rxstat & DC_RXSTAT_GIANT) ||
2220 (rxstat & (DC_RXSTAT_CRCERR | DC_RXSTAT_DRIBBLE |
2221 DC_RXSTAT_MIIERE | DC_RXSTAT_COLLSEEN |
2222 DC_RXSTAT_RUNT | DC_RXSTAT_DE))) {
2223 ifp->if_ierrors++;
2224 if (rxstat & DC_RXSTAT_COLLSEEN)
2225 ifp->if_collisions++;
2226 dc_newbuf(sc, i, m);
2227 if (rxstat & DC_RXSTAT_CRCERR) {
2228 DC_INC(i, DC_RX_LIST_CNT);
2229 continue;
2230 } else {
2231 dc_init(sc);
2232 return;
2233 }
2234 }
2235 }
2236
2237
2238 total_len -= ETHER_CRC_LEN;
2239
2240 m->m_pkthdr.rcvif = ifp;
2241 m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
2242 total_len + ETHER_ALIGN, 0, ifp, NULL);
2243 dc_newbuf(sc, i, m);
2244 DC_INC(i, DC_RX_LIST_CNT);
2245 if (m0 == NULL) {
2246 ifp->if_ierrors++;
2247 continue;
2248 }
2249 m_adj(m0, ETHER_ALIGN);
2250 m = m0;
2251
2252 ifp->if_ipackets++;
2253 #if NBPFILTER > 0
2254 if (ifp->if_bpf)
2255 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
2256 #endif
2257 ether_input_mbuf(ifp, m);
2258 }
2259
2260 sc->dc_cdata.dc_rx_prod = i;
2261 }
2262
2263
2264
2265
2266
2267
2268 void
2269 dc_txeof(sc)
2270 struct dc_softc *sc;
2271 {
2272 struct dc_desc *cur_tx = NULL;
2273 struct ifnet *ifp;
2274 int idx, offset;
2275
2276 ifp = &sc->sc_arpcom.ac_if;
2277
2278
2279
2280
2281
2282 idx = sc->dc_cdata.dc_tx_cons;
2283 while(idx != sc->dc_cdata.dc_tx_prod) {
2284 u_int32_t txstat;
2285
2286 offset = offsetof(struct dc_list_data, dc_tx_list[idx]);
2287 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
2288 offset, sizeof(struct dc_desc),
2289 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2290
2291 cur_tx = &sc->dc_ldata->dc_tx_list[idx];
2292 txstat = letoh32(cur_tx->dc_status);
2293
2294 if (txstat & DC_TXSTAT_OWN)
2295 break;
2296
2297 if (!(cur_tx->dc_ctl & htole32(DC_TXCTL_LASTFRAG)) ||
2298 cur_tx->dc_ctl & htole32(DC_TXCTL_SETUP)) {
2299 if (cur_tx->dc_ctl & htole32(DC_TXCTL_SETUP)) {
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309 if (DC_IS_PNIC(sc)) {
2310 if (txstat & DC_TXSTAT_ERRSUM)
2311 dc_setfilt(sc);
2312 }
2313 sc->dc_cdata.dc_tx_chain[idx].sd_mbuf = NULL;
2314 }
2315 sc->dc_cdata.dc_tx_cnt--;
2316 DC_INC(idx, DC_TX_LIST_CNT);
2317 continue;
2318 }
2319
2320 if (DC_IS_XIRCOM(sc) || DC_IS_CONEXANT(sc)) {
2321
2322
2323
2324
2325
2326
2327
2328
2329 if (
2330 sc->dc_pmode == DC_PMODE_MII &&
2331 ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM|
2332 DC_TXSTAT_NOCARRIER)))
2333 txstat &= ~DC_TXSTAT_ERRSUM;
2334 } else {
2335 if (
2336 sc->dc_pmode == DC_PMODE_MII &&
2337 ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM|
2338 DC_TXSTAT_NOCARRIER|DC_TXSTAT_CARRLOST)))
2339 txstat &= ~DC_TXSTAT_ERRSUM;
2340 }
2341
2342 if (txstat & DC_TXSTAT_ERRSUM) {
2343 ifp->if_oerrors++;
2344 if (txstat & DC_TXSTAT_EXCESSCOLL)
2345 ifp->if_collisions++;
2346 if (txstat & DC_TXSTAT_LATECOLL)
2347 ifp->if_collisions++;
2348 if (!(txstat & DC_TXSTAT_UNDERRUN)) {
2349 dc_init(sc);
2350 return;
2351 }
2352 }
2353
2354 ifp->if_collisions += (txstat & DC_TXSTAT_COLLCNT) >> 3;
2355
2356 ifp->if_opackets++;
2357 if (sc->dc_cdata.dc_tx_chain[idx].sd_map->dm_nsegs != 0) {
2358 bus_dmamap_t map = sc->dc_cdata.dc_tx_chain[idx].sd_map;
2359
2360 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
2361 BUS_DMASYNC_POSTWRITE);
2362 bus_dmamap_unload(sc->sc_dmat, map);
2363 }
2364 if (sc->dc_cdata.dc_tx_chain[idx].sd_mbuf != NULL) {
2365 m_freem(sc->dc_cdata.dc_tx_chain[idx].sd_mbuf);
2366 sc->dc_cdata.dc_tx_chain[idx].sd_mbuf = NULL;
2367 }
2368
2369 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
2370 offset, sizeof(struct dc_desc),
2371 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2372
2373 sc->dc_cdata.dc_tx_cnt--;
2374 DC_INC(idx, DC_TX_LIST_CNT);
2375 }
2376
2377 if (idx != sc->dc_cdata.dc_tx_cons) {
2378
2379 sc->dc_cdata.dc_tx_cons = idx;
2380 ifp->if_flags &= ~IFF_OACTIVE;
2381 }
2382 ifp->if_timer = (sc->dc_cdata.dc_tx_cnt == 0) ? 0 : 5;
2383 }
2384
2385 void
2386 dc_tick(xsc)
2387 void *xsc;
2388 {
2389 struct dc_softc *sc = (struct dc_softc *)xsc;
2390 struct mii_data *mii;
2391 struct ifnet *ifp;
2392 int s;
2393 u_int32_t r;
2394
2395 s = splnet();
2396
2397 ifp = &sc->sc_arpcom.ac_if;
2398 mii = &sc->sc_mii;
2399
2400 if (sc->dc_flags & DC_REDUCED_MII_POLL) {
2401 if (sc->dc_flags & DC_21143_NWAY) {
2402 r = CSR_READ_4(sc, DC_10BTSTAT);
2403 if (IFM_SUBTYPE(mii->mii_media_active) ==
2404 IFM_100_TX && (r & DC_TSTAT_LS100)) {
2405 sc->dc_link = 0;
2406 mii_mediachg(mii);
2407 }
2408 if (IFM_SUBTYPE(mii->mii_media_active) ==
2409 IFM_10_T && (r & DC_TSTAT_LS10)) {
2410 sc->dc_link = 0;
2411 mii_mediachg(mii);
2412 }
2413 if (sc->dc_link == 0)
2414 mii_tick(mii);
2415 } else {
2416 r = CSR_READ_4(sc, DC_ISR);
2417 if ((r & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT &&
2418 sc->dc_cdata.dc_tx_cnt == 0 && !DC_IS_ASIX(sc)) {
2419 mii_tick(mii);
2420 if (!(mii->mii_media_status & IFM_ACTIVE))
2421 sc->dc_link = 0;
2422 }
2423 }
2424 } else
2425 mii_tick(mii);
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446 if (!sc->dc_link && mii->mii_media_status & IFM_ACTIVE &&
2447 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
2448 sc->dc_link++;
2449 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
2450 dc_start(ifp);
2451 }
2452
2453 if (sc->dc_flags & DC_21143_NWAY && !sc->dc_link)
2454 timeout_add(&sc->dc_tick_tmo, hz / 10);
2455 else
2456 timeout_add(&sc->dc_tick_tmo, hz);
2457
2458 splx(s);
2459 }
2460
2461
2462
2463
2464 void
2465 dc_tx_underrun(sc)
2466 struct dc_softc *sc;
2467 {
2468 u_int32_t isr;
2469 int i;
2470
2471 if (DC_IS_DAVICOM(sc))
2472 dc_init(sc);
2473
2474 if (DC_IS_INTEL(sc)) {
2475
2476
2477
2478
2479
2480 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
2481
2482 for (i = 0; i < DC_TIMEOUT; i++) {
2483 isr = CSR_READ_4(sc, DC_ISR);
2484 if (isr & DC_ISR_TX_IDLE)
2485 break;
2486 DELAY(10);
2487 }
2488 if (i == DC_TIMEOUT) {
2489 printf("%s: failed to force tx to idle state\n",
2490 sc->sc_dev.dv_xname);
2491 dc_init(sc);
2492 }
2493 }
2494
2495 sc->dc_txthresh += DC_TXTHRESH_INC;
2496 if (sc->dc_txthresh > DC_TXTHRESH_MAX) {
2497 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
2498 } else {
2499 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_THRESH);
2500 DC_SETBIT(sc, DC_NETCFG, sc->dc_txthresh);
2501 }
2502
2503 if (DC_IS_INTEL(sc))
2504 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
2505
2506 return;
2507 }
2508
2509 int
2510 dc_intr(arg)
2511 void *arg;
2512 {
2513 struct dc_softc *sc;
2514 struct ifnet *ifp;
2515 u_int32_t status;
2516 int claimed = 0;
2517
2518 sc = arg;
2519
2520 ifp = &sc->sc_arpcom.ac_if;
2521
2522 if ((CSR_READ_4(sc, DC_ISR) & DC_INTRS) == 0)
2523 return (claimed);
2524
2525
2526 if (!(ifp->if_flags & IFF_UP)) {
2527 if (CSR_READ_4(sc, DC_ISR) & DC_INTRS)
2528 dc_stop(sc);
2529 return (claimed);
2530 }
2531
2532
2533 CSR_WRITE_4(sc, DC_IMR, 0x00000000);
2534
2535 while (((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) &&
2536 status != 0xFFFFFFFF &&
2537 (ifp->if_flags & IFF_RUNNING)) {
2538
2539 claimed = 1;
2540 CSR_WRITE_4(sc, DC_ISR, status);
2541
2542 if (status & DC_ISR_RX_OK) {
2543 int curpkts;
2544 curpkts = ifp->if_ipackets;
2545 dc_rxeof(sc);
2546 if (curpkts == ifp->if_ipackets) {
2547 while(dc_rx_resync(sc))
2548 dc_rxeof(sc);
2549 }
2550 }
2551
2552 if (status & (DC_ISR_TX_OK|DC_ISR_TX_NOBUF))
2553 dc_txeof(sc);
2554
2555 if (status & DC_ISR_TX_IDLE) {
2556 dc_txeof(sc);
2557 if (sc->dc_cdata.dc_tx_cnt) {
2558 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
2559 CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
2560 }
2561 }
2562
2563 if (status & DC_ISR_TX_UNDERRUN)
2564 dc_tx_underrun(sc);
2565
2566 if ((status & DC_ISR_RX_WATDOGTIMEO)
2567 || (status & DC_ISR_RX_NOBUF)) {
2568 int curpkts;
2569 curpkts = ifp->if_ipackets;
2570 dc_rxeof(sc);
2571 if (curpkts == ifp->if_ipackets) {
2572 while(dc_rx_resync(sc))
2573 dc_rxeof(sc);
2574 }
2575 }
2576
2577 if (status & DC_ISR_BUS_ERR) {
2578 dc_reset(sc);
2579 dc_init(sc);
2580 }
2581 }
2582
2583
2584 CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
2585
2586 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
2587 dc_start(ifp);
2588
2589 return (claimed);
2590 }
2591
2592
2593
2594
2595
2596 int
2597 dc_encap(sc, m_head, txidx)
2598 struct dc_softc *sc;
2599 struct mbuf *m_head;
2600 u_int32_t *txidx;
2601 {
2602 struct dc_desc *f = NULL;
2603 int frag, cur, cnt = 0, i;
2604 bus_dmamap_t map;
2605
2606
2607
2608
2609
2610
2611 map = sc->sc_tx_sparemap;
2612
2613 if (bus_dmamap_load_mbuf(sc->sc_dmat, map,
2614 m_head, BUS_DMA_NOWAIT) != 0)
2615 return (ENOBUFS);
2616
2617 cur = frag = *txidx;
2618
2619 for (i = 0; i < map->dm_nsegs; i++) {
2620 if (sc->dc_flags & DC_TX_ADMTEK_WAR) {
2621 if (*txidx != sc->dc_cdata.dc_tx_prod &&
2622 frag == (DC_TX_LIST_CNT - 1)) {
2623 bus_dmamap_unload(sc->sc_dmat, map);
2624 return (ENOBUFS);
2625 }
2626 }
2627 if ((DC_TX_LIST_CNT -
2628 (sc->dc_cdata.dc_tx_cnt + cnt)) < 5) {
2629 bus_dmamap_unload(sc->sc_dmat, map);
2630 return (ENOBUFS);
2631 }
2632
2633 f = &sc->dc_ldata->dc_tx_list[frag];
2634 f->dc_ctl = htole32(DC_TXCTL_TLINK | map->dm_segs[i].ds_len);
2635 if (cnt == 0) {
2636 f->dc_status = htole32(0);
2637 f->dc_ctl |= htole32(DC_TXCTL_FIRSTFRAG);
2638 } else
2639 f->dc_status = htole32(DC_TXSTAT_OWN);
2640 f->dc_data = htole32(map->dm_segs[i].ds_addr);
2641 cur = frag;
2642 DC_INC(frag, DC_TX_LIST_CNT);
2643 cnt++;
2644 }
2645
2646 sc->dc_cdata.dc_tx_cnt += cnt;
2647 sc->dc_cdata.dc_tx_chain[cur].sd_mbuf = m_head;
2648 sc->sc_tx_sparemap = sc->dc_cdata.dc_tx_chain[cur].sd_map;
2649 sc->dc_cdata.dc_tx_chain[cur].sd_map = map;
2650 sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_LASTFRAG);
2651 if (sc->dc_flags & DC_TX_INTR_FIRSTFRAG)
2652 sc->dc_ldata->dc_tx_list[*txidx].dc_ctl |=
2653 htole32(DC_TXCTL_FINT);
2654 if (sc->dc_flags & DC_TX_INTR_ALWAYS)
2655 sc->dc_ldata->dc_tx_list[cur].dc_ctl |=
2656 htole32(DC_TXCTL_FINT);
2657 if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
2658 sc->dc_ldata->dc_tx_list[cur].dc_ctl |=
2659 htole32(DC_TXCTL_FINT);
2660 else if ((sc->dc_flags & DC_TX_USE_TX_INTR) &&
2661 TBR_IS_ENABLED(&sc->sc_arpcom.ac_if.if_snd))
2662 sc->dc_ldata->dc_tx_list[cur].dc_ctl |=
2663 htole32(DC_TXCTL_FINT);
2664 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
2665 BUS_DMASYNC_PREWRITE);
2666
2667 sc->dc_ldata->dc_tx_list[*txidx].dc_status = htole32(DC_TXSTAT_OWN);
2668
2669 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
2670 offsetof(struct dc_list_data, dc_tx_list[*txidx]),
2671 sizeof(struct dc_desc) * cnt,
2672 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2673
2674 *txidx = frag;
2675
2676 return (0);
2677 }
2678
2679
2680
2681
2682
2683
2684 int
2685 dc_coal(sc, m_head)
2686 struct dc_softc *sc;
2687 struct mbuf **m_head;
2688 {
2689 struct mbuf *m_new, *m;
2690
2691 m = *m_head;
2692 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
2693 if (m_new == NULL)
2694 return (ENOBUFS);
2695 if (m->m_pkthdr.len > MHLEN) {
2696 MCLGET(m_new, M_DONTWAIT);
2697 if (!(m_new->m_flags & M_EXT)) {
2698 m_freem(m_new);
2699 return (ENOBUFS);
2700 }
2701 }
2702 m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
2703 m_new->m_pkthdr.len = m_new->m_len = m->m_pkthdr.len;
2704 m_freem(m);
2705 *m_head = m_new;
2706
2707 return (0);
2708 }
2709
2710
2711
2712
2713
2714
2715
2716
2717 void
2718 dc_start(ifp)
2719 struct ifnet *ifp;
2720 {
2721 struct dc_softc *sc;
2722 struct mbuf *m_head = NULL;
2723 int idx;
2724
2725 sc = ifp->if_softc;
2726
2727 if (!sc->dc_link && ifp->if_snd.ifq_len < 10)
2728 return;
2729
2730 if (ifp->if_flags & IFF_OACTIVE)
2731 return;
2732
2733 idx = sc->dc_cdata.dc_tx_prod;
2734
2735 while(sc->dc_cdata.dc_tx_chain[idx].sd_mbuf == NULL) {
2736 IFQ_POLL(&ifp->if_snd, m_head);
2737 if (m_head == NULL)
2738 break;
2739
2740 if (sc->dc_flags & DC_TX_COALESCE &&
2741 (m_head->m_next != NULL ||
2742 sc->dc_flags & DC_TX_ALIGN)) {
2743
2744
2745
2746 IFQ_DEQUEUE(&ifp->if_snd, m_head);
2747 if (dc_coal(sc, &m_head)) {
2748 ifp->if_flags |= IFF_OACTIVE;
2749 break;
2750 }
2751 }
2752
2753 if (dc_encap(sc, m_head, &idx)) {
2754 ifp->if_flags |= IFF_OACTIVE;
2755 break;
2756 }
2757
2758
2759 if (sc->dc_flags & DC_TX_COALESCE) {
2760
2761 } else
2762 IFQ_DEQUEUE(&ifp->if_snd, m_head);
2763
2764
2765
2766
2767
2768 #if NBPFILTER > 0
2769 if (ifp->if_bpf)
2770 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
2771 #endif
2772 if (sc->dc_flags & DC_TX_ONE) {
2773 ifp->if_flags |= IFF_OACTIVE;
2774 break;
2775 }
2776 }
2777 if (idx == sc->dc_cdata.dc_tx_prod)
2778 return;
2779
2780
2781 sc->dc_cdata.dc_tx_prod = idx;
2782 if (!(sc->dc_flags & DC_TX_POLL))
2783 CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
2784
2785
2786
2787
2788 ifp->if_timer = 5;
2789 }
2790
2791 void
2792 dc_init(xsc)
2793 void *xsc;
2794 {
2795 struct dc_softc *sc = xsc;
2796 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
2797 struct mii_data *mii;
2798 int s;
2799
2800 s = splnet();
2801
2802 mii = &sc->sc_mii;
2803
2804
2805
2806
2807 dc_stop(sc);
2808 dc_reset(sc);
2809
2810
2811
2812
2813 if (DC_IS_ASIX(sc) || DC_IS_DAVICOM(sc))
2814 CSR_WRITE_4(sc, DC_BUSCTL, 0);
2815 else
2816 CSR_WRITE_4(sc, DC_BUSCTL, DC_BUSCTL_MRME|DC_BUSCTL_MRLE);
2817
2818
2819
2820 if (DC_IS_INTEL(sc))
2821 DC_SETBIT(sc, DC_BUSCTL, DC_BUSCTL_ARBITRATION);
2822 if (DC_IS_DAVICOM(sc) || DC_IS_INTEL(sc)) {
2823 DC_SETBIT(sc, DC_BUSCTL, DC_BURSTLEN_USECA);
2824 } else {
2825 DC_SETBIT(sc, DC_BUSCTL, DC_BURSTLEN_16LONG);
2826 }
2827 if (sc->dc_flags & DC_TX_POLL)
2828 DC_SETBIT(sc, DC_BUSCTL, DC_TXPOLL_1);
2829 switch(sc->dc_cachesize) {
2830 case 32:
2831 DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_32LONG);
2832 break;
2833 case 16:
2834 DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_16LONG);
2835 break;
2836 case 8:
2837 DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_8LONG);
2838 break;
2839 case 0:
2840 default:
2841 DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_NONE);
2842 break;
2843 }
2844
2845 if (sc->dc_flags & DC_TX_STORENFWD)
2846 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
2847 else {
2848 if (sc->dc_txthresh > DC_TXTHRESH_MAX) {
2849 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
2850 } else {
2851 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
2852 DC_SETBIT(sc, DC_NETCFG, sc->dc_txthresh);
2853 }
2854 }
2855
2856 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_NO_RXCRC);
2857 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_BACKOFF);
2858
2859 if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
2860
2861
2862
2863
2864
2865
2866
2867
2868 DC_CLRBIT(sc, DC_MX_MAGICPACKET, 0xFFFF0000);
2869 if (sc->dc_type == DC_TYPE_98713)
2870 DC_SETBIT(sc, DC_MX_MAGICPACKET, DC_MX_MAGIC_98713);
2871 else
2872 DC_SETBIT(sc, DC_MX_MAGICPACKET, DC_MX_MAGIC_98715);
2873 }
2874
2875 if (DC_IS_XIRCOM(sc)) {
2876 CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_WRITE_EN | DC_SIAGP_INT1_EN |
2877 DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT);
2878 DELAY(10);
2879 CSR_WRITE_4(sc, DC_SIAGP, DC_SIAGP_INT1_EN |
2880 DC_SIAGP_MD_GP2_OUTPUT | DC_SIAGP_MD_GP0_OUTPUT);
2881 DELAY(10);
2882 }
2883
2884 DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_THRESH);
2885 DC_SETBIT(sc, DC_NETCFG, DC_TXTHRESH_MIN);
2886
2887
2888 if (dc_list_rx_init(sc) == ENOBUFS) {
2889 printf("%s: initialization failed: no "
2890 "memory for rx buffers\n", sc->sc_dev.dv_xname);
2891 dc_stop(sc);
2892 splx(s);
2893 return;
2894 }
2895
2896
2897
2898
2899 dc_list_tx_init(sc);
2900
2901
2902
2903
2904 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
2905 0, sc->sc_listmap->dm_mapsize,
2906 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2907
2908
2909
2910
2911 CSR_WRITE_4(sc, DC_RXADDR, sc->sc_listmap->dm_segs[0].ds_addr +
2912 offsetof(struct dc_list_data, dc_rx_list[0]));
2913 CSR_WRITE_4(sc, DC_TXADDR, sc->sc_listmap->dm_segs[0].ds_addr +
2914 offsetof(struct dc_list_data, dc_tx_list[0]));
2915
2916
2917
2918
2919 CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
2920 CSR_WRITE_4(sc, DC_ISR, 0xFFFFFFFF);
2921
2922
2923 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
2924
2925
2926
2927
2928
2929
2930 if (sc->dc_flags & DC_TULIP_LEDS) {
2931 CSR_WRITE_4(sc, DC_WATCHDOG,
2932 DC_WDOG_CTLWREN|DC_WDOG_LINK|DC_WDOG_ACTIVITY);
2933 CSR_WRITE_4(sc, DC_WATCHDOG, 0);
2934 }
2935
2936
2937
2938
2939
2940
2941
2942 dc_setfilt(sc);
2943
2944
2945 DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ON);
2946 CSR_WRITE_4(sc, DC_RXSTART, 0xFFFFFFFF);
2947
2948 mii_mediachg(mii);
2949 dc_setcfg(sc, sc->dc_if_media);
2950
2951 ifp->if_flags |= IFF_RUNNING;
2952 ifp->if_flags &= ~IFF_OACTIVE;
2953
2954 splx(s);
2955
2956 timeout_set(&sc->dc_tick_tmo, dc_tick, sc);
2957
2958 if (IFM_SUBTYPE(mii->mii_media.ifm_media) == IFM_HPNA_1)
2959 sc->dc_link = 1;
2960 else {
2961 if (sc->dc_flags & DC_21143_NWAY)
2962 timeout_add(&sc->dc_tick_tmo, hz / 10);
2963 else
2964 timeout_add(&sc->dc_tick_tmo, hz);
2965 }
2966
2967 #ifdef SRM_MEDIA
2968 if(sc->dc_srm_media) {
2969 struct ifreq ifr;
2970
2971 ifr.ifr_media = sc->dc_srm_media;
2972 ifmedia_ioctl(ifp, &ifr, &mii->mii_media, SIOCSIFMEDIA);
2973 sc->dc_srm_media = 0;
2974 }
2975 #endif
2976 }
2977
2978
2979
2980
2981 int
2982 dc_ifmedia_upd(ifp)
2983 struct ifnet *ifp;
2984 {
2985 struct dc_softc *sc;
2986 struct mii_data *mii;
2987 struct ifmedia *ifm;
2988
2989 sc = ifp->if_softc;
2990 mii = &sc->sc_mii;
2991 mii_mediachg(mii);
2992
2993 ifm = &mii->mii_media;
2994
2995 if (DC_IS_DAVICOM(sc) &&
2996 IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1)
2997 dc_setcfg(sc, ifm->ifm_media);
2998 else
2999 sc->dc_link = 0;
3000
3001 return (0);
3002 }
3003
3004
3005
3006
3007 void
3008 dc_ifmedia_sts(ifp, ifmr)
3009 struct ifnet *ifp;
3010 struct ifmediareq *ifmr;
3011 {
3012 struct dc_softc *sc;
3013 struct mii_data *mii;
3014 struct ifmedia *ifm;
3015
3016 sc = ifp->if_softc;
3017 mii = &sc->sc_mii;
3018 mii_pollstat(mii);
3019 ifm = &mii->mii_media;
3020 if (DC_IS_DAVICOM(sc)) {
3021 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_HPNA_1) {
3022 ifmr->ifm_active = ifm->ifm_media;
3023 ifmr->ifm_status = 0;
3024 return;
3025 }
3026 }
3027 ifmr->ifm_active = mii->mii_media_active;
3028 ifmr->ifm_status = mii->mii_media_status;
3029 }
3030
3031 int
3032 dc_ioctl(ifp, command, data)
3033 struct ifnet *ifp;
3034 u_long command;
3035 caddr_t data;
3036 {
3037 struct dc_softc *sc = ifp->if_softc;
3038 struct ifreq *ifr = (struct ifreq *) data;
3039 struct ifaddr *ifa = (struct ifaddr *)data;
3040 struct mii_data *mii;
3041 int s, error = 0;
3042
3043 s = splnet();
3044
3045 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, command, data)) > 0) {
3046 splx(s);
3047 return (error);
3048 }
3049
3050 switch(command) {
3051 case SIOCSIFADDR:
3052 ifp->if_flags |= IFF_UP;
3053 if (!(ifp->if_flags & IFF_RUNNING))
3054 dc_init(sc);
3055 #ifdef INET
3056 if (ifa->ifa_addr->sa_family == AF_INET)
3057 arp_ifinit(&sc->sc_arpcom, ifa);
3058 #endif
3059 break;
3060 case SIOCSIFFLAGS:
3061 if (ifp->if_flags & IFF_UP) {
3062 if (ifp->if_flags & IFF_RUNNING &&
3063 (ifp->if_flags ^ sc->dc_if_flags) &
3064 IFF_PROMISC) {
3065 dc_setfilt(sc);
3066 } else {
3067 if (!(ifp->if_flags & IFF_RUNNING)) {
3068 sc->dc_txthresh = 0;
3069 dc_init(sc);
3070 }
3071 }
3072 } else {
3073 if (ifp->if_flags & IFF_RUNNING)
3074 dc_stop(sc);
3075 }
3076 sc->dc_if_flags = ifp->if_flags;
3077 break;
3078 case SIOCSIFMTU:
3079 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
3080 error = EINVAL;
3081 } else if (ifp->if_mtu != ifr->ifr_mtu) {
3082 ifp->if_mtu = ifr->ifr_mtu;
3083 }
3084 break;
3085 case SIOCADDMULTI:
3086 case SIOCDELMULTI:
3087 error = (command == SIOCADDMULTI) ?
3088 ether_addmulti(ifr, &sc->sc_arpcom) :
3089 ether_delmulti(ifr, &sc->sc_arpcom);
3090
3091 if (error == ENETRESET) {
3092
3093
3094
3095
3096 if (ifp->if_flags & IFF_RUNNING)
3097 dc_setfilt(sc);
3098 error = 0;
3099 }
3100 break;
3101 case SIOCGIFMEDIA:
3102 case SIOCSIFMEDIA:
3103 mii = &sc->sc_mii;
3104 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
3105 #ifdef SRM_MEDIA
3106 if (sc->dc_srm_media)
3107 sc->dc_srm_media = 0;
3108 #endif
3109 break;
3110 default:
3111 error = EINVAL;
3112 break;
3113 }
3114
3115 splx(s);
3116
3117 return (error);
3118 }
3119
3120 void
3121 dc_watchdog(ifp)
3122 struct ifnet *ifp;
3123 {
3124 struct dc_softc *sc;
3125
3126 sc = ifp->if_softc;
3127
3128 ifp->if_oerrors++;
3129 printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
3130
3131 dc_stop(sc);
3132 dc_reset(sc);
3133 dc_init(sc);
3134
3135 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
3136 dc_start(ifp);
3137 }
3138
3139
3140
3141
3142
3143 void
3144 dc_stop(sc)
3145 struct dc_softc *sc;
3146 {
3147 struct ifnet *ifp;
3148 int i;
3149
3150 ifp = &sc->sc_arpcom.ac_if;
3151 ifp->if_timer = 0;
3152
3153 timeout_del(&sc->dc_tick_tmo);
3154
3155 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
3156
3157 DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_RX_ON|DC_NETCFG_TX_ON));
3158 CSR_WRITE_4(sc, DC_IMR, 0x00000000);
3159 CSR_WRITE_4(sc, DC_TXADDR, 0x00000000);
3160 CSR_WRITE_4(sc, DC_RXADDR, 0x00000000);
3161 sc->dc_link = 0;
3162
3163
3164
3165
3166 for (i = 0; i < DC_RX_LIST_CNT; i++) {
3167 if (sc->dc_cdata.dc_rx_chain[i].sd_map->dm_nsegs != 0) {
3168 bus_dmamap_t map = sc->dc_cdata.dc_rx_chain[i].sd_map;
3169
3170 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
3171 BUS_DMASYNC_POSTREAD);
3172 bus_dmamap_unload(sc->sc_dmat, map);
3173 }
3174 if (sc->dc_cdata.dc_rx_chain[i].sd_mbuf != NULL) {
3175 m_freem(sc->dc_cdata.dc_rx_chain[i].sd_mbuf);
3176 sc->dc_cdata.dc_rx_chain[i].sd_mbuf = NULL;
3177 }
3178 }
3179 bzero((char *)&sc->dc_ldata->dc_rx_list,
3180 sizeof(sc->dc_ldata->dc_rx_list));
3181
3182
3183
3184
3185 for (i = 0; i < DC_TX_LIST_CNT; i++) {
3186 if (sc->dc_cdata.dc_tx_chain[i].sd_map->dm_nsegs != 0) {
3187 bus_dmamap_t map = sc->dc_cdata.dc_tx_chain[i].sd_map;
3188
3189 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
3190 BUS_DMASYNC_POSTWRITE);
3191 bus_dmamap_unload(sc->sc_dmat, map);
3192 }
3193 if (sc->dc_cdata.dc_tx_chain[i].sd_mbuf != NULL) {
3194 if (sc->dc_ldata->dc_tx_list[i].dc_ctl &
3195 htole32(DC_TXCTL_SETUP)) {
3196 sc->dc_cdata.dc_tx_chain[i].sd_mbuf = NULL;
3197 continue;
3198 }
3199 m_freem(sc->dc_cdata.dc_tx_chain[i].sd_mbuf);
3200 sc->dc_cdata.dc_tx_chain[i].sd_mbuf = NULL;
3201 }
3202 }
3203 bzero((char *)&sc->dc_ldata->dc_tx_list,
3204 sizeof(sc->dc_ldata->dc_tx_list));
3205
3206 bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
3207 0, sc->sc_listmap->dm_mapsize,
3208 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3209 }
3210
3211
3212
3213
3214
3215 void
3216 dc_shutdown(v)
3217 void *v;
3218 {
3219 struct dc_softc *sc = (struct dc_softc *)v;
3220
3221 dc_stop(sc);
3222 }
3223
3224 void
3225 dc_power(why, arg)
3226 int why;
3227 void *arg;
3228 {
3229 struct dc_softc *sc = arg;
3230 struct ifnet *ifp;
3231 int s;
3232
3233 s = splnet();
3234 if (why != PWR_RESUME)
3235 dc_stop(sc);
3236 else {
3237 ifp = &sc->sc_arpcom.ac_if;
3238 if (ifp->if_flags & IFF_UP)
3239 dc_init(sc);
3240 }
3241 splx(s);
3242 }
3243
3244 struct cfdriver dc_cd = {
3245 0, "dc", DV_IFNET
3246 };