This source file includes following definitions.
- i82596_probe
- i82596_attach
- i82596_watchdog
- i82596_cmd_wait
- i82596_start_cmd
- i82596_count_errors
- i82596_rx_errors
- i82596_intr
- i82596_rint
- i82596_tint
- i82596_get_rbd_list
- i82596_release_rbd_list
- i82596_drop_frames
- i82596_chk_rx_ring
- i82596_get
- i82596_readframe
- i82596_xmit
- i82596_start
- i82596_proberam
- i82596_reset
- i82596_simple_command
- ie_run_tdr
- i82596_setup_bufs
- ie_cfg_setup
- ie_ia_setup
- ie_mc_setup
- i82596_init
- i82596_start_transceiver
- i82596_stop
- i82596_ioctl
- ie_mc_reset
- i82596_mediachange
- i82596_mediastatus
- print_rbd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 #include "bpfilter.h"
145
146 #include <sys/param.h>
147 #include <sys/systm.h>
148 #include <sys/mbuf.h>
149 #include <sys/socket.h>
150 #include <sys/ioctl.h>
151 #include <sys/errno.h>
152 #include <sys/syslog.h>
153 #include <sys/device.h>
154
155 #include <net/if.h>
156 #include <net/if_dl.h>
157 #include <net/if_types.h>
158 #include <net/if_media.h>
159
160 #if NBPFILTER > 0
161 #include <net/bpf.h>
162 #endif
163
164 #ifdef INET
165 #include <netinet/in.h>
166 #include <netinet/in_systm.h>
167 #include <netinet/in_var.h>
168 #include <netinet/ip.h>
169 #include <netinet/if_ether.h>
170 #endif
171
172 #include <uvm/uvm_extern.h>
173
174 #include <machine/bus.h>
175
176 #include <dev/ic/i82596reg.h>
177 #include <dev/ic/i82596var.h>
178
179 static char *padbuf;
180
181 void i82596_reset(struct ie_softc *, int);
182 void i82596_watchdog(struct ifnet *);
183 int i82596_init(struct ie_softc *);
184 int i82596_ioctl(struct ifnet *, u_long, caddr_t);
185 void i82596_start(struct ifnet *);
186
187 int i82596_rint(struct ie_softc *, int);
188 int i82596_tint(struct ie_softc *, int);
189
190 int i82596_mediachange(struct ifnet *);
191 void i82596_mediastatus(struct ifnet *, struct ifmediareq *);
192
193 int i82596_readframe(struct ie_softc *, int);
194 int i82596_get_rbd_list(struct ie_softc *,
195 u_int16_t *, u_int16_t *, int *);
196 void i82596_release_rbd_list(struct ie_softc *, u_int16_t, u_int16_t);
197 int i82596_drop_frames(struct ie_softc *);
198 int i82596_chk_rx_ring(struct ie_softc *);
199
200 void i82596_start_transceiver(struct ie_softc *);
201 void i82596_stop(struct ie_softc *);
202 void i82596_xmit(struct ie_softc *);
203
204 void i82596_setup_bufs(struct ie_softc *);
205 void i82596_simple_command(struct ie_softc *, int, int);
206 int ie_cfg_setup(struct ie_softc *, int, int, int);
207 int ie_ia_setup(struct ie_softc *, int);
208 void ie_run_tdr(struct ie_softc *, int);
209 int ie_mc_setup(struct ie_softc *, int);
210 void ie_mc_reset(struct ie_softc *);
211 int i82596_cmd_wait(struct ie_softc *);
212
213 #ifdef I82596_DEBUG
214 void print_rbd(struct ie_softc *, int);
215 #endif
216
217 struct cfdriver ie_cd = {
218 NULL, "ie", DV_IFNET
219 };
220
221
222
223
224 int
225 i82596_probe(sc)
226 struct ie_softc *sc;
227 {
228 int i;
229
230 sc->scp = sc->sc_msize - IE_SCP_SZ;
231 sc->iscp = 0;
232 sc->scb = 32;
233
234 (sc->ie_bus_write16)(sc, IE_ISCP_BUSY(sc->iscp), 1);
235 (sc->ie_bus_write16)(sc, IE_ISCP_SCB(sc->iscp), sc->scb);
236 (sc->ie_bus_write24)(sc, IE_ISCP_BASE(sc->iscp), sc->sc_maddr);
237 (sc->ie_bus_write24)(sc, IE_SCP_ISCP(sc->scp), sc->sc_maddr);
238 (sc->ie_bus_write16)(sc, IE_SCP_BUS_USE(sc->scp), sc->sysbus);
239
240 (sc->hwreset)(sc, IE_CARD_RESET);
241
242 if ((sc->ie_bus_read16)(sc, IE_ISCP_BUSY(sc->iscp))) {
243 #ifdef I82596_DEBUG
244 printf("%s: ISCP set failed\n", sc->sc_dev.dv_xname);
245 #endif
246 return 0;
247 }
248
249 if (sc->port) {
250 (sc->ie_bus_write24)(sc, sc->scp, 0);
251 (sc->ie_bus_write24)(sc, IE_SCP_TEST(sc->scp), -1);
252 (sc->port)(sc, IE_PORT_TEST);
253 for (i = 9000; i-- &&
254 (sc->ie_bus_read16)(sc, IE_SCP_TEST(sc->scp));
255 DELAY(100))
256 ;
257 }
258
259 return 1;
260 }
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284 void
285 i82596_attach(sc, name, etheraddr, media, nmedia, defmedia)
286 struct ie_softc *sc;
287 const char *name;
288 u_int8_t *etheraddr;
289 int *media, nmedia, defmedia;
290 {
291 int i;
292 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
293
294
295 (sc->ie_bus_write16)(sc, IE_ISCP_BUSY(sc->iscp), 1);
296 (sc->ie_bus_write16)(sc, IE_ISCP_SCB(sc->iscp), sc->scb);
297 (sc->ie_bus_write24)(sc, IE_ISCP_BASE(sc->iscp), sc->sc_maddr);
298 (sc->ie_bus_write24)(sc, IE_SCP_ISCP(sc->scp), sc->sc_maddr +sc->iscp);
299 (sc->ie_bus_write16)(sc, IE_SCP_BUS_USE(sc->scp), sc->sysbus);
300 (sc->hwreset)(sc, IE_CARD_RESET);
301
302
303 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
304 ifp->if_softc = sc;
305 ifp->if_start = i82596_start;
306 ifp->if_ioctl = i82596_ioctl;
307 ifp->if_watchdog = i82596_watchdog;
308 ifp->if_flags =
309 #ifdef I82596_DEBUG
310 IFF_DEBUG |
311 #endif
312 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
313 IFQ_SET_READY(&ifp->if_snd);
314
315
316 ifmedia_init(&sc->sc_media, 0, i82596_mediachange, i82596_mediastatus);
317 if (media != NULL) {
318 for (i = 0; i < nmedia; i++)
319 ifmedia_add(&sc->sc_media, media[i], 0, NULL);
320 ifmedia_set(&sc->sc_media, defmedia);
321 } else {
322 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
323 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
324 }
325
326 if (padbuf == NULL) {
327 padbuf = malloc(ETHER_MIN_LEN - ETHER_CRC_LEN, M_DEVBUF,
328 M_NOWAIT);
329 if (padbuf == NULL) {
330 printf("%s: can't allocate pad buffer\n",
331 sc->sc_dev.dv_xname);
332 return;
333 }
334 bzero(padbuf, ETHER_MIN_LEN - ETHER_CRC_LEN);
335 }
336
337
338 if_attach(ifp);
339 ether_ifattach(ifp);
340
341 printf(" %s v%d.%d, address %s\n", name, sc->sc_vers / 10,
342 sc->sc_vers % 10, ether_sprintf(etheraddr));
343 }
344
345
346
347
348
349
350
351 void
352 i82596_watchdog(ifp)
353 struct ifnet *ifp;
354 {
355 struct ie_softc *sc = ifp->if_softc;
356
357 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
358 ++ifp->if_oerrors;
359
360 i82596_reset(sc, 1);
361 }
362
363 int
364 i82596_cmd_wait(sc)
365 struct ie_softc *sc;
366 {
367
368 int i, off;
369
370 for (i = 180000; i--; DELAY(5)) {
371
372 off = IE_SCB_CMD(sc->scb);
373 bus_space_barrier(sc->bt, sc->bh, off, 2,
374 BUS_SPACE_BARRIER_READ);
375 if ((sc->ie_bus_read16)(sc, off) == 0) {
376 #ifdef I82596_DEBUG
377 if (sc->sc_debug & IED_CMDS)
378 printf("%s: cmd_wait after %d usec\n",
379 sc->sc_dev.dv_xname, (180000 - i) * 5);
380 #endif
381 return (0);
382 }
383 }
384
385 #ifdef I82596_DEBUG
386 if (sc->sc_debug & IED_CMDS)
387 printf("i82596_cmd_wait: timo(%ssync): scb status: %b\n",
388 sc->async_cmd_inprogress? "a" : "",
389 sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb)),
390 IE_STAT_BITS);
391 #endif
392 return (1);
393 }
394
395
396
397
398
399
400
401
402
403
404
405 int
406 i82596_start_cmd(sc, cmd, iecmdbuf, mask, async)
407 struct ie_softc *sc;
408 int cmd;
409 int iecmdbuf;
410 int mask;
411 int async;
412 {
413 int i, off;
414
415 #ifdef I82596_DEBUG
416 if (sc->sc_debug & IED_CMDS)
417 printf("start_cmd: %p, %x, %x, %b, %ssync\n",
418 sc, cmd, iecmdbuf, mask, IE_STAT_BITS, async?"a":"");
419 #endif
420 if (sc->async_cmd_inprogress != 0) {
421
422
423
424
425 if (i82596_cmd_wait(sc) != 0)
426 return (1);
427 sc->async_cmd_inprogress = 0;
428 }
429
430 off = IE_SCB_CMD(sc->scb);
431 (sc->ie_bus_write16)(sc, off, cmd);
432 bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_WRITE);
433 (sc->chan_attn)(sc);
434
435 if (async) {
436 sc->async_cmd_inprogress = 1;
437 return (0);
438 }
439
440 if (IE_ACTION_COMMAND(cmd) && iecmdbuf) {
441 int status;
442
443
444
445
446
447
448 for (i = 73800; i--; DELAY(5)) {
449
450 off = IE_CMD_COMMON_STATUS(iecmdbuf);
451 bus_space_barrier(sc->bt, sc->bh, off, 2,
452 BUS_SPACE_BARRIER_READ);
453 status = (sc->ie_bus_read16)(sc, off);
454 if (status & mask) {
455 #ifdef I82596_DEBUG
456 if (sc->sc_debug & IED_CMDS)
457 printf("%s: cmd status %b\n",
458 sc->sc_dev.dv_xname,
459 status, IE_STAT_BITS);
460 #endif
461 return (0);
462 }
463 }
464
465 } else {
466
467
468
469 return (i82596_cmd_wait(sc));
470 }
471
472
473 return (1);
474 }
475
476
477
478
479 static __inline void
480 i82596_count_errors(struct ie_softc *sc)
481 {
482 int scb = sc->scb;
483
484 sc->sc_arpcom.ac_if.if_ierrors +=
485 sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) +
486 sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) +
487 sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) +
488 sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb));
489
490
491 sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0);
492 sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0);
493 sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0);
494 sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0);
495 }
496
497 static __inline void
498 i82596_rx_errors(struct ie_softc *sc, int fn, int status)
499 {
500 log(LOG_ERR, "%s: rx error (frame# %d): %b\n", sc->sc_dev.dv_xname, fn,
501 status, IE_FD_STATUSBITS);
502 }
503
504
505
506
507 int
508 i82596_intr(v)
509 void *v;
510 {
511 register struct ie_softc *sc = v;
512 register u_int status;
513 register int off;
514
515 off = IE_SCB_STATUS(sc->scb);
516 bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_READ);
517 status = sc->ie_bus_read16(sc, off) ;
518
519 if ((status & IE_ST_WHENCE) == 0) {
520 if (sc->intrhook)
521 (sc->intrhook)(sc, IE_INTR_EXIT);
522
523 return (0);
524 }
525
526 loop:
527
528 i82596_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, 1);
529
530 if (status & (IE_ST_FR | IE_ST_RNR)) {
531 if (sc->intrhook)
532 (sc->intrhook)(sc, IE_INTR_ENRCV);
533
534 if (i82596_rint(sc, status) != 0)
535 goto reset;
536 }
537
538 if (status & IE_ST_CX) {
539 if (sc->intrhook)
540 (sc->intrhook)(sc, IE_INTR_ENSND);
541
542 if (i82596_tint(sc, status) != 0)
543 goto reset;
544 }
545
546 #ifdef I82596_DEBUG
547 if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
548 printf("%s: cna; status=%b\n", sc->sc_dev.dv_xname,
549 status, IE_ST_BITS);
550 #endif
551 if (sc->intrhook)
552 (sc->intrhook)(sc, IE_INTR_LOOP);
553
554
555
556
557
558
559
560
561 if (i82596_cmd_wait(sc))
562 goto reset;
563
564 bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_READ);
565 status = sc->ie_bus_read16(sc, off);
566 if ((status & IE_ST_WHENCE) != 0)
567 goto loop;
568
569 out:
570 if (sc->intrhook)
571 (sc->intrhook)(sc, IE_INTR_EXIT);
572 return (1);
573
574 reset:
575 i82596_cmd_wait(sc);
576 i82596_reset(sc, 1);
577 goto out;
578 }
579
580
581
582
583 int
584 i82596_rint(sc, scbstatus)
585 struct ie_softc *sc;
586 int scbstatus;
587 {
588 static int timesthru = 1024;
589 register int i, status, off;
590
591 #ifdef I82596_DEBUG
592 if (sc->sc_debug & IED_RINT)
593 printf("%s: rint: status %b\n",
594 sc->sc_dev.dv_xname, scbstatus, IE_ST_BITS);
595 #endif
596
597 for (;;) {
598 register int drop = 0;
599
600 i = sc->rfhead;
601 off = IE_RFRAME_STATUS(sc->rframes, i);
602 bus_space_barrier(sc->bt, sc->bh, off, 2,
603 BUS_SPACE_BARRIER_READ);
604 status = sc->ie_bus_read16(sc, off);
605
606 #ifdef I82596_DEBUG
607 if (sc->sc_debug & IED_RINT)
608 printf("%s: rint: frame(%d) status %b\n",
609 sc->sc_dev.dv_xname, i, status, IE_ST_BITS);
610 #endif
611 if ((status & IE_FD_COMPLETE) == 0) {
612 if ((status & IE_FD_OK) != 0) {
613 printf("%s: rint: weird: ",
614 sc->sc_dev.dv_xname);
615 i82596_rx_errors(sc, i, status);
616 break;
617 }
618 if (--timesthru == 0) {
619
620 i82596_count_errors(sc);
621 timesthru = 1024;
622 }
623 break;
624 } else if ((status & IE_FD_OK) == 0) {
625
626
627
628
629
630 i82596_rx_errors(sc, i, status);
631 drop = 1;
632 }
633
634 #ifdef I82596_DEBUG
635 if ((status & IE_FD_BUSY) != 0)
636 printf("%s: rint: frame(%d) busy; status=%x\n",
637 sc->sc_dev.dv_xname, i, status, IE_ST_BITS);
638 #endif
639
640
641
642
643
644
645
646 sc->ie_bus_write16(sc, off, 0);
647
648
649 off = IE_RFRAME_LAST(sc->rframes, i);
650 sc->ie_bus_write16(sc, off, IE_FD_EOL|IE_FD_SUSP);
651
652
653 off = IE_RFRAME_BUFDESC(sc->rframes, i);
654 sc->ie_bus_write16(sc, off, 0xffff);
655
656
657 off = IE_RFRAME_LAST(sc->rframes, sc->rftail);
658 sc->ie_bus_write16(sc, off, 0);
659
660 if (++sc->rftail == sc->nframes)
661 sc->rftail = 0;
662 if (++sc->rfhead == sc->nframes)
663 sc->rfhead = 0;
664
665
666 if (drop) {
667 i82596_drop_frames(sc);
668 if ((status & IE_FD_RNR) != 0)
669 sc->rnr_expect = 1;
670 sc->sc_arpcom.ac_if.if_ierrors++;
671 } else if (i82596_readframe(sc, i) != 0)
672 return (1);
673 }
674
675 if ((scbstatus & IE_ST_RNR) != 0) {
676
677
678
679
680
681
682
683 if ((scbstatus & IE_RUS_SUSPEND) != 0) {
684
685
686
687
688
689
690 printf("RINT: SUSPENDED; scbstatus=%b\n",
691 scbstatus, IE_ST_BITS);
692 if (i82596_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0)
693 return (0);
694 printf("%s: RU RESUME command timed out\n",
695 sc->sc_dev.dv_xname);
696 return (1);
697 }
698
699 if (sc->rnr_expect != 0) {
700
701
702
703
704
705 i82596_start_transceiver(sc);
706 sc->rnr_expect = 0;
707 return (0);
708
709 } else if ((scbstatus & IE_RUS_NOSPACE) != 0) {
710
711
712
713
714
715
716 if (i82596_chk_rx_ring(sc) != 0)
717 return (1);
718
719 i82596_start_transceiver(sc);
720 sc->sc_arpcom.ac_if.if_ierrors++;
721 return (0);
722 } else
723 printf("%s: receiver not ready; scbstatus=%b\n",
724 sc->sc_dev.dv_xname, scbstatus, IE_ST_BITS);
725
726 sc->sc_arpcom.ac_if.if_ierrors++;
727 return (1);
728 }
729
730 return (0);
731 }
732
733
734
735
736
737
738 int
739 i82596_tint(sc, scbstatus)
740 struct ie_softc *sc;
741 int scbstatus;
742 {
743 register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
744 register int off, status;
745
746 ifp->if_timer = 0;
747 ifp->if_flags &= ~IFF_OACTIVE;
748
749 #ifdef I82596_DEBUG
750 if (sc->xmit_busy <= 0) {
751 printf("%s: i82596_tint: WEIRD:"
752 "xmit_busy=%d, xctail=%d, xchead=%d\n",
753 sc->sc_dev.dv_xname,
754 sc->xmit_busy, sc->xctail, sc->xchead);
755 return (0);
756 }
757 #endif
758
759 off = IE_CMD_XMIT_STATUS(sc->xmit_cmds, sc->xctail);
760 status = sc->ie_bus_read16(sc, off);
761
762 #ifdef I82596_DEBUG
763 if (sc->sc_debug & IED_TINT)
764 printf("%s: tint: SCB status %b; xmit status %b\n",
765 sc->sc_dev.dv_xname, scbstatus, IE_ST_BITS,
766 status, IE_XS_BITS);
767 #endif
768
769 if ((status & (IE_STAT_COMPL|IE_STAT_BUSY)) == IE_STAT_BUSY) {
770 printf("%s: i82596_tint: command still busy;"
771 "status=%b; tail=%d\n", sc->sc_dev.dv_xname,
772 status, IE_XS_BITS, sc->xctail);
773 printf("iestatus = %b\n", scbstatus, IE_ST_BITS);
774 }
775
776 if (status & IE_STAT_OK) {
777 ifp->if_opackets++;
778 ifp->if_collisions += (status & IE_XS_MAXCOLL);
779 } else {
780 ifp->if_oerrors++;
781
782
783
784
785 if (status & IE_STAT_ABORT)
786 printf("%s: send aborted\n", sc->sc_dev.dv_xname);
787 else if (status & IE_XS_NOCARRIER)
788 printf("%s: no carrier\n", sc->sc_dev.dv_xname);
789 else if (status & IE_XS_LOSTCTS)
790 printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
791 else if (status & IE_XS_UNDERRUN)
792 printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
793 else if (status & IE_XS_EXCMAX) {
794 printf("%s: too many collisions\n",
795 sc->sc_dev.dv_xname);
796 sc->sc_arpcom.ac_if.if_collisions += 16;
797 }
798 }
799
800
801
802
803
804
805 if (sc->want_mcsetup) {
806 ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail));
807 sc->want_mcsetup = 0;
808 }
809
810
811 sc->xmit_busy--;
812 sc->xctail = (sc->xctail + 1) % NTXBUF;
813
814
815 if (sc->xmit_busy > 0)
816 i82596_xmit(sc);
817
818 i82596_start(ifp);
819 return (0);
820 }
821
822
823
824
825 int
826 i82596_get_rbd_list(sc, start, end, pktlen)
827 struct ie_softc *sc;
828 u_int16_t *start;
829 u_int16_t *end;
830 int *pktlen;
831 {
832 int off, rbbase = sc->rbds;
833 int rbindex, count = 0;
834 int plen = 0;
835 int rbdstatus;
836
837 *start = rbindex = sc->rbhead;
838
839 do {
840 off = IE_RBD_STATUS(rbbase, rbindex);
841 bus_space_barrier(sc->bt, sc->bh, off, 2,
842 BUS_SPACE_BARRIER_READ);
843 rbdstatus = sc->ie_bus_read16(sc, off);
844 if ((rbdstatus & IE_RBD_USED) == 0) {
845
846
847
848
849 #ifdef I82596_DEBUG
850 print_rbd(sc, rbindex);
851 #endif
852 log(LOG_ERR,
853 "%s: receive descriptors out of sync at %d\n",
854 sc->sc_dev.dv_xname, rbindex);
855 return (0);
856 }
857 plen += (rbdstatus & IE_RBD_CNTMASK);
858
859 if (++rbindex == sc->nrxbuf)
860 rbindex = 0;
861
862 ++count;
863 } while ((rbdstatus & IE_RBD_LAST) == 0);
864 *end = rbindex;
865 *pktlen = plen;
866 return (count);
867 }
868
869
870
871
872
873 void
874 i82596_release_rbd_list(sc, start, end)
875 struct ie_softc *sc;
876 u_int16_t start;
877 u_int16_t end;
878 {
879 register int off, rbbase = sc->rbds;
880 register int rbindex = start;
881
882 do {
883
884 off = IE_RBD_STATUS(rbbase, rbindex);
885 sc->ie_bus_write16(sc, off, 0);
886 if (++rbindex == sc->nrxbuf)
887 rbindex = 0;
888 } while (rbindex != end);
889
890
891 rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1;
892 off = IE_RBD_BUFLEN(rbbase, rbindex);
893 sc->ie_bus_write16(sc, off, IE_RBUF_SIZE|IE_RBD_EOL);
894
895
896 off = IE_RBD_BUFLEN(rbbase, sc->rbtail);
897 sc->ie_bus_write16(sc, off, IE_RBUF_SIZE);
898
899
900
901 sc->rbhead = end;
902 sc->rbtail = rbindex;
903 }
904
905
906
907
908
909
910
911 int
912 i82596_drop_frames(sc)
913 struct ie_softc *sc;
914 {
915 u_int16_t bstart, bend;
916 int pktlen;
917
918 if (!i82596_get_rbd_list(sc, &bstart, &bend, &pktlen))
919 return (1);
920 i82596_release_rbd_list(sc, bstart, bend);
921 return (0);
922 }
923
924
925
926
927
928
929
930
931
932
933 int
934 i82596_chk_rx_ring(sc)
935 struct ie_softc *sc;
936 {
937 int n, off, val;
938
939 for (n = 0; n < sc->nrxbuf; n++) {
940 off = IE_RBD_BUFLEN(sc->rbds, n);
941 val = sc->ie_bus_read16(sc, off);
942 if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) {
943
944 log(LOG_ERR,
945 "%s: rx buffer descriptors out of sync at %d\n",
946 sc->sc_dev.dv_xname, n);
947 return (1);
948 }
949
950
951 }
952
953 for (n = 0; n < sc->nframes; n++) {
954 off = IE_RFRAME_LAST(sc->rframes, n);
955 val = sc->ie_bus_read16(sc, off);
956 if ((n == sc->rftail) ^ ((val & (IE_FD_EOL|IE_FD_SUSP)) != 0)) {
957
958 log(LOG_ERR,
959 "%s: rx frame list out of sync at %d\n",
960 sc->sc_dev.dv_xname, n);
961 return (1);
962 }
963 }
964
965 return (0);
966 }
967
968
969
970
971
972
973
974
975
976
977
978 static __inline__ struct mbuf *
979 i82596_get(struct ie_softc *sc, int head, int totlen)
980 {
981 struct mbuf *m, *m0, *newm;
982 int off, len, resid;
983 int thisrboff, thismboff;
984 struct ether_header eh;
985
986
987
988
989 (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
990 sizeof(struct ether_header));
991
992 resid = totlen;
993
994 MGETHDR(m0, M_DONTWAIT, MT_DATA);
995 if (m0 == 0)
996 return (0);
997 m0->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
998 m0->m_pkthdr.len = totlen;
999 len = MHLEN;
1000 m = m0;
1001
1002
1003
1004
1005
1006 while (totlen > 0) {
1007 if (totlen >= MINCLSIZE) {
1008 MCLGET(m, M_DONTWAIT);
1009 if ((m->m_flags & M_EXT) == 0)
1010 goto bad;
1011 len = MCLBYTES;
1012 }
1013
1014 if (m == m0) {
1015 caddr_t newdata = (caddr_t)
1016 ALIGN(m->m_data + sizeof(struct ether_header)) -
1017 sizeof(struct ether_header);
1018 len -= newdata - m->m_data;
1019 m->m_data = newdata;
1020 }
1021
1022 m->m_len = len = min(totlen, len);
1023
1024 totlen -= len;
1025 if (totlen > 0) {
1026 MGET(newm, M_DONTWAIT, MT_DATA);
1027 if (newm == 0)
1028 goto bad;
1029 len = MLEN;
1030 m = m->m_next = newm;
1031 }
1032 }
1033
1034 m = m0;
1035 thismboff = 0;
1036
1037
1038
1039
1040 bcopy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
1041 thismboff = sizeof(struct ether_header);
1042 thisrboff = sizeof(struct ether_header);
1043 resid -= sizeof(struct ether_header);
1044
1045
1046
1047
1048
1049
1050 while (resid > 0) {
1051 int thisrblen = IE_RBUF_SIZE - thisrboff,
1052 thismblen = m->m_len - thismboff;
1053 len = min(thisrblen, thismblen);
1054
1055 off = IE_RBUF_ADDR(sc,head) + thisrboff;
1056 (sc->memcopyin)(sc, mtod(m, caddr_t) + thismboff, off, len);
1057 resid -= len;
1058
1059 if (len == thismblen) {
1060 m = m->m_next;
1061 thismboff = 0;
1062 } else
1063 thismboff += len;
1064
1065 if (len == thisrblen) {
1066 if (++head == sc->nrxbuf)
1067 head = 0;
1068 thisrboff = 0;
1069 } else
1070 thisrboff += len;
1071 }
1072
1073
1074
1075
1076
1077
1078 return (m0);
1079
1080 bad:
1081 m_freem(m0);
1082 return (NULL);
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094 int
1095 i82596_readframe(sc, num)
1096 struct ie_softc *sc;
1097 int num;
1098 {
1099 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1100 struct mbuf *m;
1101 u_int16_t bstart, bend;
1102 int pktlen;
1103
1104 if (i82596_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) {
1105 ifp->if_ierrors++;
1106 return (1);
1107 }
1108
1109 m = i82596_get(sc, bstart, pktlen);
1110 i82596_release_rbd_list(sc, bstart, bend);
1111
1112 if (m == 0) {
1113 sc->sc_arpcom.ac_if.if_ierrors++;
1114 return (0);
1115 }
1116
1117 #ifdef I82596_DEBUG
1118 if (sc->sc_debug & IED_READFRAME) {
1119 struct ether_header *eh = mtod(m, struct ether_header *);
1120
1121 printf("%s: frame from ether %s type 0x%x len %d\n",
1122 sc->sc_dev.dv_xname, ether_sprintf(eh->ether_shost),
1123 (u_int)eh->ether_type, pktlen);
1124 }
1125 #endif
1126
1127 #if NBPFILTER > 0
1128
1129 if (ifp->if_bpf)
1130 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1131 #endif
1132
1133
1134
1135
1136 ether_input_mbuf(ifp, m);
1137 ifp->if_ipackets++;
1138 return (0);
1139 }
1140
1141
1142
1143
1144
1145
1146 void
1147 i82596_xmit(sc)
1148 struct ie_softc *sc;
1149 {
1150 int off, cur, prev;
1151
1152 cur = sc->xctail;
1153
1154 #ifdef I82596_DEBUG
1155 if (sc->sc_debug & IED_XMIT)
1156 printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname, cur);
1157 #endif
1158
1159
1160
1161
1162 sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur),
1163 IE_XBD_ADDR(sc->xbds, cur));
1164
1165 sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0);
1166
1167 if (sc->do_xmitnopchain) {
1168
1169
1170
1171 sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
1172 IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
1173 sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
1174 IE_CMD_XMIT | IE_CMD_INTR);
1175
1176
1177
1178
1179 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0);
1180 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur),
1181 IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
1182
1183
1184
1185
1186 prev = (cur + NTXBUF - 1) % NTXBUF;
1187 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev), 0);
1188 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev),
1189 IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
1190
1191 off = IE_SCB_STATUS(sc->scb);
1192 bus_space_barrier(sc->bt, sc->bh, off, 2,
1193 BUS_SPACE_BARRIER_READ);
1194 if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) {
1195 printf("i82596_xmit: CU not active\n");
1196 i82596_start_transceiver(sc);
1197 }
1198 } else {
1199 sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds,cur),
1200 0xffff);
1201
1202 sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
1203 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
1204
1205 off = IE_SCB_CMDLST(sc->scb);
1206 sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
1207 bus_space_barrier(sc->bt, sc->bh, off, 2,
1208 BUS_SPACE_BARRIER_WRITE);
1209
1210 if (i82596_start_cmd(sc, IE_CUC_START, 0, 0, 1)) {
1211 #ifdef I82596_DEBUG
1212 if (sc->sc_debug & IED_XMIT)
1213 printf("%s: i82596_xmit: "
1214 "start xmit command timed out\n",
1215 sc->sc_dev.dv_xname);
1216 #endif
1217 }
1218 }
1219
1220 sc->sc_arpcom.ac_if.if_timer = 5;
1221 }
1222
1223
1224
1225
1226
1227 void
1228 i82596_start(ifp)
1229 struct ifnet *ifp;
1230 {
1231 struct ie_softc *sc = ifp->if_softc;
1232 struct mbuf *m0, *m;
1233 int buffer, head, xbase;
1234 u_short len;
1235
1236 #ifdef I82596_DEBUG
1237 if (sc->sc_debug & IED_ENQ)
1238 printf("i82596_start(%p)\n", ifp);
1239 #endif
1240
1241 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1242 return;
1243
1244 for (;;) {
1245 if (sc->xmit_busy == NTXBUF) {
1246 ifp->if_flags |= IFF_OACTIVE;
1247 break;
1248 }
1249
1250 IFQ_DEQUEUE(&ifp->if_snd, m0);
1251 if (m0 == 0)
1252 break;
1253
1254
1255 if ((m0->m_flags & M_PKTHDR) == 0)
1256 panic("i82596_start: no header mbuf");
1257
1258 #if NBPFILTER > 0
1259
1260 if (ifp->if_bpf)
1261 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1262 #endif
1263
1264 if (m0->m_pkthdr.len > IE_TBUF_SIZE)
1265 printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
1266
1267 head = sc->xchead;
1268 sc->xchead = (head + 1) % NTXBUF;
1269 buffer = IE_XBUF_ADDR(sc, head);
1270
1271 #ifdef I82596_DEBUG
1272 if (sc->sc_debug & IED_ENQ)
1273 printf("%s: fill buffer %d offset %x",
1274 sc->sc_dev.dv_xname, head, buffer);
1275 #endif
1276
1277 for (m = m0; m != 0; m = m->m_next) {
1278 #ifdef I82596_DEBUG
1279 if (sc->sc_debug & IED_ENQ) {
1280 u_int8_t *e, *p = mtod(m, u_int8_t *);
1281 static int i;
1282 if (m == m0)
1283 i = 0;
1284 for (e = p + m->m_len; p < e; i++, p += 2) {
1285 if (!(i % 8))
1286 printf("\n%s:",
1287 sc->sc_dev.dv_xname);
1288 printf(" %02x%02x", p[0], p[1]);
1289 }
1290 }
1291 #endif
1292 (sc->memcopyout)(sc, mtod(m,caddr_t), buffer, m->m_len);
1293 buffer += m->m_len;
1294 }
1295
1296 len = m0->m_pkthdr.len;
1297 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1298 (sc->memcopyout)(sc, padbuf, buffer,
1299 ETHER_MIN_LEN - ETHER_CRC_LEN - len);
1300 buffer += ETHER_MIN_LEN - ETHER_CRC_LEN - len;
1301 len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1302 }
1303
1304 #ifdef I82596_DEBUG
1305 if (sc->sc_debug & IED_ENQ)
1306 printf("\n");
1307 #endif
1308
1309 m_freem(m0);
1310
1311
1312
1313
1314
1315 xbase = sc->xbds;
1316 sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
1317 len | IE_TBD_EOL);
1318 sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
1319 sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
1320 sc->sc_maddr + IE_XBUF_ADDR(sc, head));
1321
1322
1323 if (sc->xmit_busy++ == 0)
1324 i82596_xmit(sc);
1325 }
1326 }
1327
1328
1329
1330
1331
1332 int
1333 i82596_proberam(sc)
1334 struct ie_softc *sc;
1335 {
1336 int result, off;
1337
1338
1339 off = IE_SCP_BUS_USE(sc->scp);
1340 (sc->ie_bus_write16)(sc, off, 0);
1341 bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_WRITE);
1342
1343
1344 off = IE_ISCP_BUSY(sc->iscp);
1345 (sc->ie_bus_write16)(sc, off, 1);
1346 bus_space_barrier(sc->bt, sc->bh, off, 2, BUS_SPACE_BARRIER_WRITE);
1347
1348 if (sc->hwreset)
1349 (sc->hwreset)(sc, IE_CHIP_PROBE);
1350
1351 (sc->chan_attn) (sc);
1352
1353 DELAY(100);
1354
1355
1356 off = IE_ISCP_BUSY(sc->iscp);
1357 bus_space_barrier(sc->bt, sc->bh, off, 1, BUS_SPACE_BARRIER_READ);
1358 result = (sc->ie_bus_read16)(sc, off) == 0;
1359
1360
1361 ie_ack(sc, IE_ST_WHENCE);
1362
1363 return (result);
1364 }
1365
1366 void
1367 i82596_reset(sc, hard)
1368 struct ie_softc *sc;
1369 int hard;
1370 {
1371 int s = splnet();
1372
1373 #ifdef I82596_DEBUG
1374 if (hard)
1375 printf("%s: reset\n", sc->sc_dev.dv_xname);
1376 #endif
1377
1378
1379 sc->sc_arpcom.ac_if.if_timer = 0;
1380 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
1381
1382
1383
1384
1385 if (i82596_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0)) {
1386 #ifdef I82596_DEBUG
1387 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
1388 #endif
1389 }
1390
1391
1392
1393
1394
1395
1396 if (hard && sc->hwreset)
1397 (sc->hwreset)(sc, IE_CARD_RESET);
1398
1399 DELAY(100);
1400 ie_ack(sc, IE_ST_WHENCE);
1401
1402 if ((sc->sc_arpcom.ac_if.if_flags & IFF_UP) != 0) {
1403 int retries=0;
1404 while (retries++ < 2)
1405 if (i82596_init(sc) == 1)
1406 break;
1407 }
1408
1409 splx(s);
1410 }
1411
1412 void
1413 i82596_simple_command(sc, cmd, cmdbuf)
1414 struct ie_softc *sc;
1415 int cmd;
1416 int cmdbuf;
1417 {
1418
1419 sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
1420 sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
1421 sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
1422
1423
1424 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
1425 }
1426
1427
1428
1429
1430 void
1431 ie_run_tdr(sc, cmd)
1432 struct ie_softc *sc;
1433 int cmd;
1434 {
1435 int result, clocks;
1436
1437 i82596_simple_command(sc, IE_CMD_TDR, cmd);
1438 (sc->ie_bus_write16)(sc, IE_CMD_TDR_TIME(cmd), 0);
1439
1440 if (i82596_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
1441 !(sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK))
1442 result = 0x10000;
1443 else
1444 result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
1445
1446
1447 ie_ack(sc, IE_ST_WHENCE);
1448
1449 if (result & IE_TDR_SUCCESS)
1450 return;
1451
1452 clocks = result & IE_TDR_TIME;
1453 if (result & 0x10000)
1454 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
1455 else if (result & IE_TDR_XCVR)
1456 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
1457 else if (result & IE_TDR_OPEN)
1458 printf("%s: TDR detected an open %d clock%s away\n",
1459 sc->sc_dev.dv_xname, clocks, clocks == 1? "":"s");
1460 else if (result & IE_TDR_SHORT)
1461 printf("%s: TDR detected a short %d clock%s away\n",
1462 sc->sc_dev.dv_xname, clocks, clocks == 1? "":"s");
1463 else
1464 printf("%s: TDR returned unknown status 0x%x\n",
1465 sc->sc_dev.dv_xname, result);
1466 }
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479 void
1480 i82596_setup_bufs(sc)
1481 struct ie_softc *sc;
1482 {
1483 int n, r, ptr = sc->buf_area;
1484 int cl = 32;
1485
1486
1487
1488
1489
1490 ptr = (ptr + cl - 1) & ~(cl - 1);
1491
1492
1493
1494
1495
1496
1497 ptr += cl;
1498 sc->nop_cmds = ptr - 2;
1499 ptr += NTXBUF * 32;
1500
1501
1502 ptr += cl;
1503 sc->xmit_cmds = ptr - 2;
1504 ptr += NTXBUF * 32;
1505
1506
1507 ptr += cl;
1508 sc->xbds = ptr - 2;
1509 ptr += NTXBUF * 32;
1510
1511
1512 sc->xbufs = ptr;
1513 ptr += NTXBUF * IE_TBUF_SIZE;
1514
1515 ptr = (ptr + cl - 1) & ~(cl - 1);
1516
1517
1518 n = sc->buf_area_sz - (ptr - sc->buf_area);
1519
1520
1521 r = 64 + ((32 + IE_RBUF_SIZE) * B_PER_F);
1522
1523 sc->nframes = n / r;
1524
1525 if (sc->nframes <= 8)
1526 panic("ie: bogus buffer calc");
1527
1528 sc->nrxbuf = sc->nframes * B_PER_F;
1529
1530
1531 ptr += cl;
1532 sc->rframes = ptr - 2;
1533 ptr += sc->nframes * 64;
1534
1535
1536 ptr += cl;
1537 sc->rbds = ptr - 2;
1538 ptr += sc->nrxbuf * 32;
1539
1540
1541 sc->rbufs = ptr;
1542 ptr += sc->nrxbuf * IE_RBUF_SIZE;
1543
1544 #ifdef I82596_DEBUG
1545 printf("%s: %d frames %d bufs\n", sc->sc_dev.dv_xname, sc->nframes,
1546 sc->nrxbuf);
1547 #endif
1548
1549
1550
1551
1552 for (n = 0; n < sc->nframes; n++) {
1553 int m = (n == sc->nframes - 1) ? 0 : n + 1;
1554
1555
1556 sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0);
1557
1558
1559 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n),
1560 0xffff);
1561
1562
1563 sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n),
1564 IE_RFRAME_ADDR(sc->rframes,m));
1565
1566
1567 sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n),
1568 ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0));
1569 }
1570
1571
1572
1573
1574 for (n = 0; n < sc->nrxbuf; n++) {
1575 int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
1576
1577
1578 sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0);
1579
1580
1581 sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n),
1582 IE_RBD_ADDR(sc->rbds,m));
1583
1584
1585 sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
1586 sc->sc_maddr + IE_RBUF_ADDR(sc, n));
1587 sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n),
1588 IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
1589 }
1590
1591
1592
1593
1594 for (n = 0; n < NTXBUF; n++) {
1595 (sc->ie_bus_write16)(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
1596
1597 (sc->ie_bus_write16)(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
1598 IE_CMD_NOP);
1599
1600 (sc->ie_bus_write16)(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
1601 IE_CMD_NOP_ADDR(sc->nop_cmds, n));
1602 }
1603
1604
1605
1606
1607
1608
1609
1610
1611 sc->xchead = sc->xctail = 0;
1612
1613
1614 sc->xmit_busy = 0;
1615
1616
1617
1618
1619
1620 sc->rfhead = 0;
1621 sc->rftail = sc->nframes - 1;
1622
1623
1624
1625
1626
1627 sc->rbhead = 0;
1628 sc->rbtail = sc->nrxbuf - 1;
1629
1630
1631 #ifdef I82596_DEBUG
1632 printf("%s: reserved %d bytes\n",
1633 sc->sc_dev.dv_xname, ptr - sc->buf_area);
1634 #endif
1635 }
1636
1637 int
1638 ie_cfg_setup(sc, cmd, promiscuous, manchester)
1639 struct ie_softc *sc;
1640 int cmd;
1641 int promiscuous, manchester;
1642 {
1643 int cmdresult, status;
1644
1645 i82596_simple_command(sc, IE_CMD_CONFIG, cmd);
1646 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_CNT(cmd), 0x0c);
1647 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_FIFO(cmd), 8);
1648 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_SAVEBAD(cmd), 0x40);
1649 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_ADDRLEN(cmd), 0x2e);
1650 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_PRIORITY(cmd), 0);
1651 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_IFS(cmd), 0x60);
1652 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_SLOT_LOW(cmd), 0);
1653 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_SLOT_HIGH(cmd), 0xf2);
1654 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_PROMISC(cmd),
1655 !!promiscuous | manchester << 2);
1656 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_CRSCDT(cmd), 0);
1657 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_MINLEN(cmd), 64);
1658 bus_space_write_1(sc->bt, sc->bh, IE_CMD_CFG_JUNK(cmd), 0xff);
1659 bus_space_barrier(sc->bt, sc->bh, cmd, IE_CMD_CFG_SZ,
1660 BUS_SPACE_BARRIER_WRITE);
1661
1662 cmdresult = i82596_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
1663 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
1664 if (cmdresult != 0) {
1665 printf("%s: configure command timed out; status %b\n",
1666 sc->sc_dev.dv_xname, status, IE_STAT_BITS);
1667 return (0);
1668 }
1669 if ((status & IE_STAT_OK) == 0) {
1670 printf("%s: configure command failed; status %b\n",
1671 sc->sc_dev.dv_xname, status, IE_STAT_BITS);
1672 return (0);
1673 }
1674
1675
1676 ie_ack(sc, IE_ST_WHENCE);
1677 return (1);
1678 }
1679
1680 int
1681 ie_ia_setup(sc, cmdbuf)
1682 struct ie_softc *sc;
1683 int cmdbuf;
1684 {
1685 int cmdresult, status;
1686
1687 i82596_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
1688
1689 (sc->memcopyout)(sc, sc->sc_arpcom.ac_enaddr,
1690 IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
1691
1692 cmdresult = i82596_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
1693 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1694 if (cmdresult != 0) {
1695 printf("%s: individual address command timed out; status %b\n",
1696 sc->sc_dev.dv_xname, status, IE_STAT_BITS);
1697 return (0);
1698 }
1699 if ((status & IE_STAT_OK) == 0) {
1700 printf("%s: individual address command failed; status %b\n",
1701 sc->sc_dev.dv_xname, status, IE_STAT_BITS);
1702 return (0);
1703 }
1704
1705
1706 ie_ack(sc, IE_ST_WHENCE);
1707 return (1);
1708 }
1709
1710
1711
1712
1713
1714 int
1715 ie_mc_setup(sc, cmdbuf)
1716 struct ie_softc *sc;
1717 int cmdbuf;
1718 {
1719 int cmdresult, status;
1720
1721 if (sc->mcast_count == 0)
1722 return (1);
1723
1724 i82596_simple_command(sc, IE_CMD_MCAST, cmdbuf);
1725
1726 (sc->memcopyout)(sc, (caddr_t)sc->mcast_addrs,
1727 IE_CMD_MCAST_MADDR(cmdbuf),
1728 sc->mcast_count * ETHER_ADDR_LEN);
1729
1730 sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf),
1731 sc->mcast_count * ETHER_ADDR_LEN);
1732
1733
1734 cmdresult = i82596_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
1735 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
1736 if (cmdresult != 0) {
1737 printf("%s: multicast setup command timed out; status %b\n",
1738 sc->sc_dev.dv_xname, status, IE_STAT_BITS);
1739 return (0);
1740 }
1741 if ((status & IE_STAT_OK) == 0) {
1742 printf("%s: multicast setup command failed; status %b\n",
1743 sc->sc_dev.dv_xname, status, IE_STAT_BITS);
1744 return (0);
1745 }
1746
1747
1748 ie_ack(sc, IE_ST_WHENCE);
1749 return (1);
1750 }
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760 int
1761 i82596_init(sc)
1762 struct ie_softc *sc;
1763 {
1764 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1765 int cmd;
1766
1767 sc->async_cmd_inprogress = 0;
1768
1769 cmd = sc->buf_area;
1770
1771
1772
1773
1774 if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0)
1775 return (0);
1776
1777
1778
1779
1780 if (ie_ia_setup(sc, cmd) == 0)
1781 return (0);
1782
1783
1784
1785
1786 ie_run_tdr(sc, cmd);
1787
1788
1789
1790
1791 if (ie_mc_setup(sc, cmd) == 0)
1792 return (0);
1793
1794
1795
1796
1797 ie_ack(sc, IE_ST_WHENCE);
1798
1799
1800
1801
1802 i82596_setup_bufs(sc);
1803
1804 if (sc->hwinit)
1805 (sc->hwinit)(sc);
1806
1807 ifp->if_flags |= IFF_RUNNING;
1808 ifp->if_flags &= ~IFF_OACTIVE;
1809
1810 if (NTXBUF < 2)
1811 sc->do_xmitnopchain = 0;
1812
1813 i82596_start_transceiver(sc);
1814 return (1);
1815 }
1816
1817
1818
1819
1820 void
1821 i82596_start_transceiver(sc)
1822 struct ie_softc *sc;
1823 {
1824
1825
1826
1827
1828 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,sc->rfhead),
1829 IE_RBD_ADDR(sc->rbds, sc->rbhead));
1830
1831 sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb),
1832 IE_RFRAME_ADDR(sc->rframes,sc->rfhead));
1833
1834 if (sc->do_xmitnopchain) {
1835
1836 if (i82596_start_cmd(sc, IE_CUC_SUSPEND|IE_RUC_SUSPEND, 0, 0, 0))
1837 printf("%s: CU/RU stop command timed out\n",
1838 sc->sc_dev.dv_xname);
1839
1840
1841
1842
1843 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
1844 IE_CMD_NOP_ADDR(
1845 sc->nop_cmds,
1846 (sc->xctail + NTXBUF - 1) % NTXBUF));
1847
1848 if (i82596_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0))
1849 printf("%s: CU/RU command timed out\n",
1850 sc->sc_dev.dv_xname);
1851 } else {
1852 if (i82596_start_cmd(sc, IE_RUC_START, 0, 0, 0))
1853 printf("%s: RU command timed out\n",
1854 sc->sc_dev.dv_xname);
1855 }
1856 }
1857
1858 void
1859 i82596_stop(sc)
1860 struct ie_softc *sc;
1861 {
1862
1863 if (i82596_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
1864 printf("%s: i82596_stop: disable commands timed out\n",
1865 sc->sc_dev.dv_xname);
1866 }
1867
1868 int
1869 i82596_ioctl(ifp, cmd, data)
1870 register struct ifnet *ifp;
1871 u_long cmd;
1872 caddr_t data;
1873 {
1874 struct ie_softc *sc = ifp->if_softc;
1875 struct ifaddr *ifa = (struct ifaddr *)data;
1876 struct ifreq *ifr = (struct ifreq *)data;
1877 int s, error = 0;
1878
1879 s = splnet();
1880
1881 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
1882 splx(s);
1883 return error;
1884 }
1885
1886 switch(cmd) {
1887
1888 case SIOCSIFADDR:
1889 ifp->if_flags |= IFF_UP;
1890
1891 switch(ifa->ifa_addr->sa_family) {
1892 #ifdef INET
1893 case AF_INET:
1894 i82596_init(sc);
1895 arp_ifinit(&sc->sc_arpcom, ifa);
1896 break;
1897 #endif
1898 default:
1899 i82596_init(sc);
1900 break;
1901 }
1902 break;
1903
1904 case SIOCSIFFLAGS:
1905 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
1906 if ((ifp->if_flags & IFF_UP) == 0 &&
1907 (ifp->if_flags & IFF_RUNNING) != 0) {
1908
1909
1910
1911
1912 i82596_stop(sc);
1913 ifp->if_flags &= ~IFF_RUNNING;
1914 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1915 (ifp->if_flags & IFF_RUNNING) == 0) {
1916
1917
1918
1919
1920 i82596_init(sc);
1921 } else {
1922
1923
1924
1925
1926 i82596_stop(sc);
1927 i82596_init(sc);
1928 }
1929 #ifdef I82596_DEBUG
1930 if (ifp->if_flags & IFF_DEBUG)
1931 sc->sc_debug = IED_ALL;
1932 else
1933 sc->sc_debug = 0;
1934 #endif
1935 break;
1936
1937 case SIOCADDMULTI:
1938 case SIOCDELMULTI:
1939 error = (cmd == SIOCADDMULTI) ?
1940 ether_addmulti(ifr, &sc->sc_arpcom):
1941 ether_delmulti(ifr, &sc->sc_arpcom);
1942
1943 if (error == ENETRESET) {
1944
1945
1946
1947
1948 if (ifp->if_flags & IFF_RUNNING)
1949 ie_mc_reset(sc);
1950 error = 0;
1951 }
1952 break;
1953
1954 case SIOCGIFMEDIA:
1955 case SIOCSIFMEDIA:
1956 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1957 break;
1958
1959 default:
1960 error = EINVAL;
1961 }
1962 splx(s);
1963 return (error);
1964 }
1965
1966 void
1967 ie_mc_reset(sc)
1968 struct ie_softc *sc;
1969 {
1970 struct ether_multi *enm;
1971 struct ether_multistep step;
1972 int size;
1973
1974
1975
1976
1977 again:
1978 size = 0;
1979 sc->mcast_count = 0;
1980 ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
1981 while (enm) {
1982 size += 6;
1983 if (sc->mcast_count >= IE_MAXMCAST ||
1984 bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
1985 sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
1986 i82596_ioctl(&sc->sc_arpcom.ac_if,
1987 SIOCSIFFLAGS, (void *)0);
1988 return;
1989 }
1990 ETHER_NEXT_MULTI(step, enm);
1991 }
1992
1993 if (size > sc->mcast_addrs_size) {
1994
1995 if (sc->mcast_addrs_size)
1996 free(sc->mcast_addrs, M_IFMADDR);
1997 sc->mcast_addrs = (char *)
1998 malloc(size, M_IFMADDR, M_WAITOK);
1999 sc->mcast_addrs_size = size;
2000 }
2001
2002
2003
2004
2005 ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
2006 while (enm) {
2007 if (sc->mcast_count >= IE_MAXMCAST)
2008 goto again;
2009
2010 bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
2011 sc->mcast_count++;
2012 ETHER_NEXT_MULTI(step, enm);
2013 }
2014 sc->want_mcsetup = 1;
2015 }
2016
2017
2018
2019
2020 int
2021 i82596_mediachange(ifp)
2022 struct ifnet *ifp;
2023 {
2024 struct ie_softc *sc = ifp->if_softc;
2025
2026 if (sc->sc_mediachange)
2027 return ((*sc->sc_mediachange)(sc));
2028 return (EINVAL);
2029 }
2030
2031
2032
2033
2034 void
2035 i82596_mediastatus(ifp, ifmr)
2036 struct ifnet *ifp;
2037 struct ifmediareq *ifmr;
2038 {
2039 struct ie_softc *sc = ifp->if_softc;
2040
2041 if (sc->sc_mediastatus)
2042 (*sc->sc_mediastatus)(sc, ifmr);
2043 }
2044
2045 #ifdef I82596_DEBUG
2046 void
2047 print_rbd(sc, n)
2048 struct ie_softc *sc;
2049 int n;
2050 {
2051
2052 printf("RBD at %08x:\n status %b, next %04x, buffer %lx\n"
2053 "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n),
2054 sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)), IE_STAT_BITS,
2055 sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)),
2056 (u_long)0,
2057 sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n)));
2058 }
2059 #endif