Annotation of sys/arch/sparc/dev/qe.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: qe.c,v 1.30 2006/05/27 23:59:07 jason Exp $ */
2:
3: /*
4: * Copyright (c) 1998, 2000 Jason L. Wright.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: */
27:
28: /*
29: * Driver for the SBus qec+qe QuadEthernet board.
30: *
31: * This driver was written using the AMD MACE Am79C940 documentation, some
32: * ideas gleaned from the S/Linux driver for this card, Solaris header files,
33: * and a loan of a card from Paul Southworth of the Internet Engineering
34: * Group (www.ieng.com).
35: */
36:
37: #include <sys/param.h>
38: #include <sys/systm.h>
39: #include <sys/kernel.h>
40: #include <sys/errno.h>
41: #include <sys/ioctl.h>
42: #include <sys/mbuf.h>
43: #include <sys/socket.h>
44: #include <sys/syslog.h>
45: #include <sys/device.h>
46: #include <sys/malloc.h>
47:
48: #include <net/if.h>
49: #include <net/if_dl.h>
50: #include <net/if_types.h>
51: #include <net/if_media.h>
52: #include <net/netisr.h>
53:
54: #ifdef INET
55: #include <netinet/in.h>
56: #include <netinet/in_systm.h>
57: #include <netinet/in_var.h>
58: #include <netinet/ip.h>
59: #include <netinet/if_ether.h>
60: #endif
61:
62: #include "bpfilter.h"
63: #if NBPFILTER > 0
64: #include <net/bpf.h>
65: #include <net/bpfdesc.h>
66: #endif
67:
68: #include <machine/autoconf.h>
69: #include <machine/cpu.h>
70:
71: #include <sparc/dev/sbusvar.h>
72: #include <sparc/dev/dmareg.h>
73: #include <sparc/dev/dmavar.h>
74:
75: #include <sparc/dev/qecvar.h>
76: #include <sparc/dev/qecreg.h>
77: #include <sparc/dev/qereg.h>
78: #include <sparc/dev/qevar.h>
79:
80: int qematch(struct device *, void *, void *);
81: void qeattach(struct device *, struct device *, void *);
82:
83: void qeinit(struct qesoftc *);
84: void qestart(struct ifnet *);
85: void qestop(struct qesoftc *);
86: void qewatchdog(struct ifnet *);
87: int qeioctl(struct ifnet *, u_long, caddr_t);
88: void qereset(struct qesoftc *);
89:
90: int qeintr(void *);
91: int qe_eint(struct qesoftc *, u_int32_t);
92: int qe_rint(struct qesoftc *);
93: int qe_tint(struct qesoftc *);
94: void qe_read(struct qesoftc *, int, int);
95: void qe_mcreset(struct qesoftc *);
96: void qe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
97: int qe_ifmedia_upd(struct ifnet *);
98:
99: struct cfdriver qe_cd = {
100: NULL, "qe", DV_IFNET
101: };
102:
103: struct cfattach qe_ca = {
104: sizeof(struct qesoftc), qematch, qeattach
105: };
106:
107: int
108: qematch(parent, vcf, aux)
109: struct device *parent;
110: void *vcf, *aux;
111: {
112: struct cfdata *cf = vcf;
113: struct confargs *ca = aux;
114: register struct romaux *ra = &ca->ca_ra;
115:
116: if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
117: return (0);
118: return (1);
119: }
120:
121: void
122: qeattach(parent, self, aux)
123: struct device *parent, *self;
124: void *aux;
125: {
126: struct qec_softc *qec = (struct qec_softc *)parent;
127: struct qesoftc *sc = (struct qesoftc *)self;
128: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
129: struct confargs *ca = aux;
130: struct bootpath *bp;
131: extern void myetheraddr(u_char *);
132: int pri;
133:
134: if (qec->sc_pri == 0) {
135: printf(": no interrupt found on parent\n");
136: return;
137: }
138: pri = qec->sc_pri;
139:
140: sc->sc_rev = getpropint(ca->ca_ra.ra_node, "mace-version", -1);
141:
142: sc->sc_cr = mapiodev(&ca->ca_ra.ra_reg[0], 0, sizeof(struct qe_cregs));
143: sc->sc_mr = mapiodev(&ca->ca_ra.ra_reg[1], 0, sizeof(struct qe_mregs));
144: sc->sc_qec = qec;
145: sc->sc_qr = qec->sc_regs;
146: qestop(sc);
147:
148: sc->sc_channel = getpropint(ca->ca_ra.ra_node, "channel#", -1);
149: sc->sc_burst = qec->sc_burst;
150:
151: sc->sc_ih.ih_fun = qeintr;
152: sc->sc_ih.ih_arg = sc;
153: intr_establish(pri, &sc->sc_ih, IPL_NET, self->dv_xname);
154:
155: myetheraddr(sc->sc_arpcom.ac_enaddr);
156:
157: bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
158: ifp->if_softc = sc;
159: ifp->if_start = qestart;
160: ifp->if_ioctl = qeioctl;
161: ifp->if_watchdog = qewatchdog;
162: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS |
163: IFF_MULTICAST;
164:
165: ifmedia_init(&sc->sc_ifmedia, IFM_IMASK,
166: qe_ifmedia_upd, qe_ifmedia_sts);
167: ifmedia_add(&sc->sc_ifmedia,
168: IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, 0), 0, NULL);
169: ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T);
170:
171: IFQ_SET_MAXLEN(&ifp->if_snd, QE_TX_RING_SIZE);
172: IFQ_SET_READY(&ifp->if_snd);
173:
174: /* Attach the interface. */
175: if_attach(ifp);
176: ether_ifattach(ifp);
177:
178: printf(" pri %d: rev %x address %s\n", pri, sc->sc_rev,
179: ether_sprintf(sc->sc_arpcom.ac_enaddr));
180:
181: bp = ca->ca_ra.ra_bp;
182: if (bp != NULL && strcmp(bp->name, "qe") == 0 &&
183: sc->sc_dev.dv_unit == bp->val[1])
184: bp->dev = &sc->sc_dev;
185: }
186:
187: /*
188: * Start output on interface.
189: * We make two assumptions here:
190: * 1) that the current priority is set to splnet _before_ this code
191: * is called *and* is returned to the appropriate priority after
192: * return
193: * 2) that the IFF_OACTIVE flag is checked before this code is called
194: * (i.e. that the output part of the interface is idle)
195: */
196: void
197: qestart(ifp)
198: struct ifnet *ifp;
199: {
200: struct qesoftc *sc = (struct qesoftc *)ifp->if_softc;
201: struct mbuf *m;
202: int bix, len;
203:
204: if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
205: return;
206:
207: bix = sc->sc_last_td;
208:
209: for (;;) {
210: IFQ_POLL(&ifp->if_snd, m);
211: if (m == NULL)
212: break;
213:
214: IFQ_DEQUEUE(&ifp->if_snd, m);
215:
216: #if NBPFILTER > 0
217: /*
218: * If BPF is listening on this interface, let it see the
219: * packet before we commit it to the wire.
220: */
221: if (ifp->if_bpf)
222: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
223: #endif
224:
225: /*
226: * Copy the mbuf chain into the transmit buffer.
227: */
228: len = qec_put(sc->sc_bufs->tx_buf[bix & QE_TX_RING_MASK], m);
229:
230: /*
231: * Initialize transmit registers and start transmission
232: */
233: sc->sc_desc->qe_txd[bix].tx_flags =
234: QE_TXD_OWN | QE_TXD_SOP | QE_TXD_EOP |
235: (len & QE_TXD_LENGTH);
236: sc->sc_cr->ctrl = QE_CR_CTRL_TWAKEUP;
237:
238: if (++bix == QE_TX_RING_MAXSIZE)
239: bix = 0;
240:
241: if (++sc->sc_no_td == QE_TX_RING_SIZE) {
242: ifp->if_flags |= IFF_OACTIVE;
243: break;
244: }
245: }
246:
247: sc->sc_last_td = bix;
248: }
249:
250: void
251: qestop(sc)
252: struct qesoftc *sc;
253: {
254: struct qe_cregs *cr = sc->sc_cr;
255: struct qe_mregs *mr = sc->sc_mr;
256: int n;
257:
258: mr->biucc = QE_MR_BIUCC_SWRST;
259: for (n = 200; n > 0; n--) {
260: if ((mr->biucc & QE_MR_BIUCC_SWRST) == 0)
261: break;
262: DELAY(20);
263: }
264:
265: cr->ctrl = QE_CR_CTRL_RESET;
266: for (n = 200; n > 0; n--) {
267: if ((cr->ctrl & QE_CR_CTRL_RESET) == 0)
268: break;
269: DELAY(20);
270: }
271: }
272:
273: /*
274: * Reset interface.
275: */
276: void
277: qereset(sc)
278: struct qesoftc *sc;
279: {
280: qestop(sc);
281: qeinit(sc);
282: }
283:
284: void
285: qewatchdog(ifp)
286: struct ifnet *ifp;
287: {
288: struct qesoftc *sc = ifp->if_softc;
289: int s;
290:
291: log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
292: ++sc->sc_arpcom.ac_if.if_oerrors;
293:
294: s = splnet();
295: qereset(sc);
296: splx(s);
297: }
298:
299: /*
300: * Interrupt dispatch.
301: */
302: int
303: qeintr(v)
304: void *v;
305: {
306: struct qesoftc *sc = (struct qesoftc *)v;
307: u_int32_t qecstat, qestat;
308: int r = 0;
309:
310: qecstat = sc->sc_qr->stat >> (4 * sc->sc_channel);
311: if ((qecstat & 0xf) == 0)
312: return (r);
313:
314: qestat = sc->sc_cr->stat;
315:
316: if (qestat & QE_CR_STAT_ALLERRORS) {
317: r |= qe_eint(sc, qestat);
318: if (r == -1)
319: return (1);
320: }
321:
322: if (qestat & QE_CR_STAT_TXIRQ)
323: r |= qe_tint(sc);
324:
325: if (qestat & QE_CR_STAT_RXIRQ)
326: r |= qe_rint(sc);
327:
328: return (1);
329: }
330:
331: /*
332: * Transmit interrupt.
333: */
334: int
335: qe_tint(sc)
336: struct qesoftc *sc;
337: {
338: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
339: int bix;
340: struct qe_txd txd;
341:
342: bix = sc->sc_first_td;
343:
344: for (;;) {
345: if (sc->sc_no_td <= 0)
346: break;
347:
348: txd.tx_flags = sc->sc_desc->qe_txd[bix].tx_flags;
349: if (txd.tx_flags & QE_TXD_OWN)
350: break;
351:
352: ifp->if_opackets++;
353:
354: if (++bix == QE_TX_RING_MAXSIZE)
355: bix = 0;
356:
357: --sc->sc_no_td;
358: }
359:
360: if (sc->sc_no_td == 0)
361: ifp->if_timer = 0;
362:
363: /*
364: * If we freed up at least one descriptor and tx is blocked,
365: * unblock it and start it up again.
366: */
367: if (sc->sc_first_td != bix) {
368: sc->sc_first_td = bix;
369: if (ifp->if_flags & IFF_OACTIVE) {
370: ifp->if_flags &= ~IFF_OACTIVE;
371: qestart(ifp);
372: }
373: }
374:
375: return (1);
376: }
377:
378: /*
379: * Receive interrupt.
380: */
381: int
382: qe_rint(sc)
383: struct qesoftc *sc;
384: {
385: int bix, len;
386:
387: bix = sc->sc_last_rd;
388:
389: /*
390: * Process all buffers with valid data.
391: */
392: for (;;) {
393: if (sc->sc_desc->qe_rxd[bix].rx_flags & QE_RXD_OWN)
394: break;
395:
396: len = (sc->sc_desc->qe_rxd[bix].rx_flags & QE_RXD_LENGTH) - 4;
397: qe_read(sc, bix, len);
398: sc->sc_desc->qe_rxd[(bix + QE_RX_RING_SIZE) & QE_RX_RING_MAXMASK].rx_flags =
399: QE_RXD_OWN | QE_RXD_LENGTH;
400:
401: if (++bix == QE_RX_RING_MAXSIZE)
402: bix = 0;
403: }
404:
405: sc->sc_last_rd = bix;
406:
407: return (1);
408: }
409:
410: /*
411: * Error interrupt.
412: */
413: int
414: qe_eint(sc, why)
415: struct qesoftc *sc;
416: u_int32_t why;
417: {
418: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
419: int r = 0, rst = 0;
420:
421: if (why & QE_CR_STAT_EDEFER) {
422: printf("%s: excessive tx defers.\n", sc->sc_dev.dv_xname);
423: r |= 1;
424: ifp->if_oerrors++;
425: }
426:
427: if (why & QE_CR_STAT_CLOSS) {
428: ifp->if_oerrors++;
429: r |= 1;
430: }
431:
432: if (why & QE_CR_STAT_ERETRIES) {
433: printf("%s: excessive tx retries\n", sc->sc_dev.dv_xname);
434: ifp->if_oerrors++;
435: r |= 1;
436: rst = 1;
437: }
438:
439: if (why & QE_CR_STAT_LCOLL) {
440: printf("%s: late tx transmission\n", sc->sc_dev.dv_xname);
441: ifp->if_oerrors++;
442: r |= 1;
443: rst = 1;
444: }
445:
446: if (why & QE_CR_STAT_FUFLOW) {
447: printf("%s: tx fifo underflow\n", sc->sc_dev.dv_xname);
448: ifp->if_oerrors++;
449: r |= 1;
450: rst = 1;
451: }
452:
453: if (why & QE_CR_STAT_JERROR) {
454: printf("%s: jabber seen\n", sc->sc_dev.dv_xname);
455: r |= 1;
456: }
457:
458: if (why & QE_CR_STAT_BERROR) {
459: printf("%s: babble seen\n", sc->sc_dev.dv_xname);
460: r |= 1;
461: }
462:
463: if (why & QE_CR_STAT_TCCOFLOW) {
464: ifp->if_collisions += 256;
465: ifp->if_oerrors += 256;
466: r |= 1;
467: }
468:
469: if (why & QE_CR_STAT_TXDERROR) {
470: printf("%s: tx descriptor is bad\n", sc->sc_dev.dv_xname);
471: rst = 1;
472: r |= 1;
473: }
474:
475: if (why & QE_CR_STAT_TXLERR) {
476: printf("%s: tx late error\n", sc->sc_dev.dv_xname);
477: ifp->if_oerrors++;
478: rst = 1;
479: r |= 1;
480: }
481:
482: if (why & QE_CR_STAT_TXPERR) {
483: printf("%s: tx dma parity error\n", sc->sc_dev.dv_xname);
484: ifp->if_oerrors++;
485: rst = 1;
486: r |= 1;
487: }
488:
489: if (why & QE_CR_STAT_TXSERR) {
490: printf("%s: tx dma sbus error ack\n", sc->sc_dev.dv_xname);
491: ifp->if_oerrors++;
492: rst = 1;
493: r |= 1;
494: }
495:
496: if (why & QE_CR_STAT_RCCOFLOW) {
497: ifp->if_collisions += 256;
498: ifp->if_ierrors += 256;
499: r |= 1;
500: }
501:
502: if (why & QE_CR_STAT_RUOFLOW) {
503: ifp->if_ierrors += 256;
504: r |= 1;
505: }
506:
507: if (why & QE_CR_STAT_MCOFLOW) {
508: ifp->if_ierrors += 256;
509: r |= 1;
510: }
511:
512: if (why & QE_CR_STAT_RXFOFLOW) {
513: printf("%s: rx fifo overflow\n", sc->sc_dev.dv_xname);
514: ifp->if_ierrors++;
515: r |= 1;
516: }
517:
518: if (why & QE_CR_STAT_RLCOLL) {
519: printf("%s: rx late collision\n", sc->sc_dev.dv_xname);
520: ifp->if_ierrors++;
521: ifp->if_collisions++;
522: r |= 1;
523: }
524:
525: if (why & QE_CR_STAT_FCOFLOW) {
526: ifp->if_ierrors += 256;
527: r |= 1;
528: }
529:
530: if (why & QE_CR_STAT_CECOFLOW) {
531: ifp->if_ierrors += 256;
532: r |= 1;
533: }
534:
535: if (why & QE_CR_STAT_RXDROP) {
536: printf("%s: rx packet dropped\n", sc->sc_dev.dv_xname);
537: ifp->if_ierrors++;
538: r |= 1;
539: }
540:
541: if (why & QE_CR_STAT_RXSMALL) {
542: printf("%s: rx buffer too small\n", sc->sc_dev.dv_xname);
543: ifp->if_ierrors++;
544: r |= 1;
545: rst = 1;
546: }
547:
548: if (why & QE_CR_STAT_RXLERR) {
549: printf("%s: rx late error\n", sc->sc_dev.dv_xname);
550: ifp->if_ierrors++;
551: r |= 1;
552: rst = 1;
553: }
554:
555: if (why & QE_CR_STAT_RXPERR) {
556: printf("%s: rx dma parity error\n", sc->sc_dev.dv_xname);
557: ifp->if_ierrors++;
558: r |= 1;
559: rst = 1;
560: }
561:
562: if (why & QE_CR_STAT_RXSERR) {
563: printf("%s: rx dma sbus error ack\n", sc->sc_dev.dv_xname);
564: ifp->if_ierrors++;
565: r |= 1;
566: rst = 1;
567: }
568:
569: if (r == 0)
570: printf("%s: unexpected interrupt error: %08x\n",
571: sc->sc_dev.dv_xname, why);
572:
573: if (rst) {
574: printf("%s: resetting...\n", sc->sc_dev.dv_xname);
575: qereset(sc);
576: return (-1);
577: }
578:
579: return (r);
580: }
581:
582: int
583: qeioctl(ifp, cmd, data)
584: struct ifnet *ifp;
585: u_long cmd;
586: caddr_t data;
587: {
588: struct qesoftc *sc = ifp->if_softc;
589: struct ifaddr *ifa = (struct ifaddr *)data;
590: struct ifreq *ifr = (struct ifreq *)data;
591: int s, error = 0;
592:
593: s = splnet();
594:
595: switch (cmd) {
596: case SIOCSIFADDR:
597: ifp->if_flags |= IFF_UP;
598: switch (ifa->ifa_addr->sa_family) {
599: #ifdef INET
600: case AF_INET:
601: qeinit(sc);
602: arp_ifinit(&sc->sc_arpcom, ifa);
603: break;
604: #endif /* INET */
605: default:
606: qeinit(sc);
607: break;
608: }
609: break;
610:
611: case SIOCSIFFLAGS:
612: if ((ifp->if_flags & IFF_UP) == 0 &&
613: (ifp->if_flags & IFF_RUNNING) != 0) {
614: /*
615: * If interface is marked down and it is running, then
616: * stop it.
617: */
618: qestop(sc);
619: ifp->if_flags &= ~IFF_RUNNING;
620: } else if ((ifp->if_flags & IFF_UP) != 0 &&
621: (ifp->if_flags & IFF_RUNNING) == 0) {
622: /*
623: * If interface is marked up and it is stopped, then
624: * start it.
625: */
626: qeinit(sc);
627: } else {
628: /*
629: * Reset the interface to pick up changes in any other
630: * flags that affect hardware registers.
631: */
632: qestop(sc);
633: qeinit(sc);
634: }
635: break;
636:
637: case SIOCADDMULTI:
638: case SIOCDELMULTI:
639: error = (cmd == SIOCADDMULTI) ?
640: ether_addmulti(ifr, &sc->sc_arpcom):
641: ether_delmulti(ifr, &sc->sc_arpcom);
642:
643: if (error == ENETRESET) {
644: /*
645: * Multicast list has changed; set the hardware filter
646: * accordingly.
647: */
648: if (ifp->if_flags & IFF_RUNNING)
649: qeinit(sc);
650: error = 0;
651: }
652: break;
653: case SIOCGIFMEDIA:
654: case SIOCSIFMEDIA:
655: error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd);
656: break;
657: default:
658: if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
659: splx(s);
660: return (error);
661: }
662: error = ENOTTY;
663: break;
664: }
665: splx(s);
666: return (error);
667: }
668:
669: void
670: qeinit(sc)
671: struct qesoftc *sc;
672: {
673: struct qe_mregs *mr = sc->sc_mr;
674: struct qe_cregs *cr = sc->sc_cr;
675: struct qec_softc *qec = sc->sc_qec;
676: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
677: int s = splnet();
678: int i;
679:
680: qestop(sc);
681:
682: /*
683: * Allocate descriptor ring and buffers, if not already done
684: */
685: if (sc->sc_desc == NULL)
686: sc->sc_desc_dva = (struct qe_desc *) dvma_malloc(
687: sizeof(struct qe_desc), &sc->sc_desc, M_NOWAIT);
688: bzero(sc->sc_desc, sizeof(struct qe_desc));
689:
690: if (sc->sc_bufs == NULL)
691: sc->sc_bufs_dva = (struct qe_bufs *) dvma_malloc(
692: sizeof(struct qe_bufs), &sc->sc_bufs, M_NOWAIT);
693: bzero(sc->sc_bufs, sizeof(struct qe_bufs));
694:
695: for (i = 0; i < QE_TX_RING_MAXSIZE; i++)
696: sc->sc_desc->qe_txd[i].tx_addr =
697: (u_int32_t)sc->sc_bufs_dva->tx_buf[i & QE_TX_RING_MASK];
698: for (i = 0; i < QE_RX_RING_MAXSIZE; i++) {
699: sc->sc_desc->qe_rxd[i].rx_addr =
700: (u_int32_t)sc->sc_bufs_dva->rx_buf[i & QE_RX_RING_MASK];
701: if (i < QE_RX_RING_SIZE)
702: sc->sc_desc->qe_rxd[i].rx_flags =
703: QE_RXD_OWN | QE_RXD_LENGTH;
704: }
705:
706: cr->rxds = (u_int32_t)sc->sc_desc_dva->qe_rxd;
707: cr->txds = (u_int32_t)sc->sc_desc_dva->qe_txd;
708:
709: sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
710: sc->sc_last_rd = 0;
711:
712: cr->rimask = 0;
713: cr->timask = 0;
714: cr->qmask = 0;
715: cr->mmask = QE_CR_MMASK_RXCOLL | QE_CR_MMASK_CLOSS;
716: cr->ccnt = 0;
717: cr->pipg = 0;
718: cr->rxwbufptr = cr->rxrbufptr = sc->sc_channel * qec->sc_msize;
719: cr->txwbufptr = cr->txrbufptr = cr->rxrbufptr + qec->sc_rsize;
720:
721: /*
722: * When switching from mace<->qec always guarantee an sbus
723: * turnaround (if last op was read, perform a dummy write, and
724: * vice versa).
725: */
726: i = cr->qmask; /* dummy */
727:
728: mr->biucc = QE_MR_BIUCC_BSWAP | QE_MR_BIUCC_64TS;
729: mr->fifofc = QE_MR_FIFOCC_TXF16 | QE_MR_FIFOCC_RXF32 |
730: QE_MR_FIFOCC_RFWU | QE_MR_FIFOCC_TFWU;
731: mr->xmtfc = QE_MR_XMTFC_APADXMT;
732: mr->rcvfc = 0;
733: mr->imr = QE_MR_IMR_CERRM | QE_MR_IMR_RCVINTM;
734: mr->phycc = QE_MR_PHYCC_ASEL;
735: mr->plscc = QE_MR_PLSCC_TP;
736:
737: qe_ifmedia_upd(ifp);
738:
739: mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_PHYADDR;
740: for (i = 100; i > 0; i--) {
741: if ((mr->iac & QE_MR_IAC_ADDRCHG) == 0)
742: break;
743: DELAY(2);
744: }
745: mr->padr = sc->sc_arpcom.ac_enaddr[0];
746: mr->padr = sc->sc_arpcom.ac_enaddr[1];
747: mr->padr = sc->sc_arpcom.ac_enaddr[2];
748: mr->padr = sc->sc_arpcom.ac_enaddr[3];
749: mr->padr = sc->sc_arpcom.ac_enaddr[4];
750: mr->padr = sc->sc_arpcom.ac_enaddr[5];
751: qe_mcreset(sc);
752: mr->iac = 0;
753:
754: i = mr->mpc; /* cleared on read */
755:
756: ifp->if_flags |= IFF_RUNNING;
757: ifp->if_flags &= ~IFF_OACTIVE;
758:
759: mr->maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV |
760: ((ifp->if_flags & IFF_PROMISC) ? QE_MR_MACCC_PROM : 0);
761: splx(s);
762: }
763:
764: /*
765: * Pass a packet to the higher levels.
766: */
767: void
768: qe_read(sc, idx, len)
769: struct qesoftc *sc;
770: int idx, len;
771: {
772: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
773: struct mbuf *m;
774:
775: if (len <= sizeof(struct ether_header) ||
776: len > ETHERMTU + sizeof(struct ether_header)) {
777:
778: printf("%s: invalid packet size %d; dropping\n",
779: ifp->if_xname, len);
780:
781: ifp->if_ierrors++;
782: return;
783: }
784:
785: /*
786: * Pull packet off interface.
787: */
788: m = qec_get(ifp, sc->sc_bufs->rx_buf[idx & QE_RX_RING_MASK], len);
789: if (m == NULL) {
790: ifp->if_ierrors++;
791: return;
792: }
793: ifp->if_ipackets++;
794:
795: #if NBPFILTER > 0
796: /*
797: * Check if there's a BPF listener on this interface.
798: * If so, hand off the raw packet to BPF.
799: */
800: if (ifp->if_bpf)
801: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
802: #endif
803: /* Pass the packet up. */
804: ether_input_mbuf(ifp, m);
805: }
806:
807: /*
808: * Reset multicast filter.
809: */
810: void
811: qe_mcreset(sc)
812: struct qesoftc *sc;
813: {
814: struct arpcom *ac = &sc->sc_arpcom;
815: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
816: struct qe_mregs *mr = sc->sc_mr;
817: struct ether_multi *enm;
818: struct ether_multistep step;
819: u_int32_t crc;
820: u_int16_t hash[4];
821: u_int8_t octet, *ladrp = (u_int8_t *)&hash[0];
822: int i, j;
823:
824: allmulti:
825: if (ifp->if_flags & IFF_ALLMULTI) {
826: mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
827: for (i = 100; i > 0; i--) {
828: if ((mr->iac & QE_MR_IAC_ADDRCHG) == 0)
829: break;
830: DELAY(2);
831: }
832: for (i = 0; i < 8; i++)
833: mr->ladrf = 0xff;
834: return;
835: }
836:
837: hash[3] = hash[2] = hash[1] = hash[0] = 0;
838:
839: ETHER_FIRST_MULTI(step, ac, enm);
840: while (enm != NULL) {
841: if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
842: ETHER_ADDR_LEN)) {
843: /*
844: * We must listen to a range of multicast
845: * addresses. For now, just accept all
846: * multicasts, rather than trying to set only
847: * those filter bits needed to match the range.
848: * (At this time, the only use of address
849: * ranges is for IP multicast routing, for
850: * which the range is big enough to require
851: * all bits set.)
852: */
853: ifp->if_flags |= IFF_ALLMULTI;
854: goto allmulti;
855: }
856:
857: crc = 0xffffffff;
858:
859: for (i = 0; i < ETHER_ADDR_LEN; i++) {
860: octet = enm->enm_addrlo[i];
861:
862: for (j = 0; j < 8; j++) {
863: if ((crc & 1) ^ (octet & 1)) {
864: crc >>= 1;
865: crc ^= MC_POLY_LE;
866: }
867: else
868: crc >>= 1;
869: octet >>= 1;
870: }
871: }
872:
873: crc >>= 26;
874: hash[crc >> 4] |= 1 << (crc & 0xf);
875: ETHER_NEXT_MULTI(step, enm);
876: }
877:
878: mr->iac = QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR;
879: for (i = 100; i > 0; i--) {
880: if ((mr->iac & QE_MR_IAC_ADDRCHG) == 0)
881: break;
882: DELAY(2);
883: }
884: for (i = 0; i < 8; i++)
885: mr->ladrf = ladrp[i];
886: }
887:
888: void
889: qe_ifmedia_sts(ifp, ifmr)
890: struct ifnet *ifp;
891: struct ifmediareq *ifmr;
892: {
893: struct qesoftc *sc = (struct qesoftc *)ifp->if_softc;
894: u_int8_t phycc;
895:
896: ifmr->ifm_active = IFM_ETHER | IFM_10_T;
897: phycc = sc->sc_mr->phycc;
898: if ((phycc & QE_MR_PHYCC_DLNKTST) == 0) {
899: ifmr->ifm_status |= IFM_AVALID;
900: if (phycc & QE_MR_PHYCC_LNKFL)
901: ifmr->ifm_status &= ~IFM_ACTIVE;
902: else
903: ifmr->ifm_status |= IFM_ACTIVE;
904: }
905: }
906:
907: int
908: qe_ifmedia_upd(ifp)
909: struct ifnet *ifp;
910: {
911: struct qesoftc *sc = (struct qesoftc *)ifp->if_softc;
912: int media = sc->sc_ifmedia.ifm_media;
913:
914: if (IFM_TYPE(media) != IFM_ETHER)
915: return (EINVAL);
916:
917: if (IFM_SUBTYPE(media) != IFM_10_T)
918: return (EINVAL);
919:
920: return (0);
921: }
CVSweb