Annotation of sys/arch/vax/if/sgec.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sgec.c,v 1.15 2006/08/31 22:10:57 miod Exp $ */
2: /* $NetBSD: sgec.c,v 1.5 2000/06/04 02:14:14 matt Exp $ */
3: /*
4: * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed at Ludd, University of
17: * Lule}, Sweden and its contributors.
18: * 4. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31: */
32:
33: /*
34: * Driver for the SGEC (Second Generation Ethernet Controller), sitting
35: * on for example the VAX 4000/300 (KA670).
36: *
37: * The SGEC looks like a mixture of the DEQNA and the TULIP. Fun toy.
38: *
39: * Even though the chip is capable to use virtual addresses (read the
40: * System Page Table directly) this driver doesn't do so, and there
41: * is no benefit in doing it either in NetBSD of today.
42: *
43: * Things that is still to do:
44: * Collect statistics.
45: * Use imperfect filtering when many multicast addresses.
46: */
47:
48: #include "bpfilter.h"
49:
50: #include <sys/param.h>
51: #include <sys/mbuf.h>
52: #include <sys/socket.h>
53: #include <sys/device.h>
54: #include <sys/systm.h>
55: #include <sys/sockio.h>
56:
57: #include <net/if.h>
58: #include <net/if_dl.h>
59:
60: #include <netinet/in.h>
61: #include <netinet/if_ether.h>
62:
63: #if NBPFILTER > 0
64: #include <net/bpf.h>
65: #include <net/bpfdesc.h>
66: #endif
67:
68: #include <machine/bus.h>
69:
70: #include <vax/if/sgecreg.h>
71: #include <vax/if/sgecvar.h>
72:
73: void sgec_rxintr(struct ze_softc *);
74: void sgec_txintr(struct ze_softc *);
75: void zeinit(struct ze_softc *);
76: int zeioctl(struct ifnet *, u_long, caddr_t);
77: void zekick(struct ze_softc *);
78: int zereset(struct ze_softc *);
79: void zestart(struct ifnet *);
80: void zetimeout(struct ifnet *);
81: int ze_add_rxbuf(struct ze_softc *, int);
82: void ze_setup(struct ze_softc *);
83:
84: struct cfdriver ze_cd = {
85: NULL, "ze", DV_IFNET
86: };
87:
88: #define ZE_WCSR(csr, val) \
89: bus_space_write_4(sc->sc_iot, sc->sc_ioh, csr, val)
90: #define ZE_RCSR(csr) \
91: bus_space_read_4(sc->sc_iot, sc->sc_ioh, csr)
92:
93: /*
94: * Interface exists: make available by filling in network interface
95: * record. System will initialize the interface when it is ready
96: * to accept packets.
97: */
98: void
99: sgec_attach(sc)
100: struct ze_softc *sc;
101: {
102: struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
103: struct ze_tdes *tp;
104: struct ze_rdes *rp;
105: bus_dma_segment_t seg;
106: int i, s, rseg, error;
107:
108: /*
109: * Allocate DMA safe memory for descriptors and setup memory.
110: */
111: if ((error = bus_dmamem_alloc(sc->sc_dmat,
112: sizeof(struct ze_cdata), NBPG, 0, &seg, 1, &rseg,
113: BUS_DMA_NOWAIT)) != 0) {
114: printf(": unable to allocate control data, error = %d\n",
115: error);
116: goto fail_0;
117: }
118:
119: if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
120: sizeof(struct ze_cdata), (caddr_t *)&sc->sc_zedata,
121: BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
122: printf(": unable to map control data, error = %d\n", error);
123: goto fail_1;
124: }
125:
126: if ((error = bus_dmamap_create(sc->sc_dmat,
127: sizeof(struct ze_cdata), 1,
128: sizeof(struct ze_cdata), 0, BUS_DMA_NOWAIT,
129: &sc->sc_cmap)) != 0) {
130: printf(": unable to create control data DMA map, error = %d\n",
131: error);
132: goto fail_2;
133: }
134:
135: if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmap,
136: sc->sc_zedata, sizeof(struct ze_cdata), NULL,
137: BUS_DMA_NOWAIT)) != 0) {
138: printf(": unable to load control data DMA map, error = %d\n",
139: error);
140: goto fail_3;
141: }
142:
143: /*
144: * Zero the newly allocated memory.
145: */
146: bzero(sc->sc_zedata, sizeof(struct ze_cdata));
147: /*
148: * Create the transmit descriptor DMA maps.
149: */
150: for (i = 0; i < TXDESCS; i++) {
151: if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
152: 1, MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
153: &sc->sc_xmtmap[i]))) {
154: printf(": unable to create tx DMA map %d, error = %d\n",
155: i, error);
156: goto fail_4;
157: }
158: }
159:
160: /*
161: * Create receive buffer DMA maps.
162: */
163: for (i = 0; i < RXDESCS; i++) {
164: if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
165: MCLBYTES, 0, BUS_DMA_NOWAIT,
166: &sc->sc_rcvmap[i]))) {
167: printf(": unable to create rx DMA map %d, error = %d\n",
168: i, error);
169: goto fail_5;
170: }
171: }
172: /*
173: * Pre-allocate the receive buffers.
174: */
175: s = splnet();
176: for (i = 0; i < RXDESCS; i++) {
177: if ((error = ze_add_rxbuf(sc, i)) != 0) {
178: printf(": unable to allocate or map rx buffer %d\n,"
179: " error = %d\n", i, error);
180: goto fail_6;
181: }
182: }
183: splx(s);
184:
185: /*
186: * Create ring loops of the buffer chains.
187: * This is only done once.
188: */
189: sc->sc_pzedata = (struct ze_cdata *)sc->sc_cmap->dm_segs[0].ds_addr;
190:
191: rp = sc->sc_zedata->zc_recv;
192: rp[RXDESCS].ze_framelen = ZE_FRAMELEN_OW;
193: rp[RXDESCS].ze_rdes1 = ZE_RDES1_CA;
194: rp[RXDESCS].ze_bufaddr = (char *)sc->sc_pzedata->zc_recv;
195:
196: tp = sc->sc_zedata->zc_xmit;
197: tp[TXDESCS].ze_tdr = ZE_TDR_OW;
198: tp[TXDESCS].ze_tdes1 = ZE_TDES1_CA;
199: tp[TXDESCS].ze_bufaddr = (char *)sc->sc_pzedata->zc_xmit;
200:
201: if (zereset(sc))
202: return;
203:
204: strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
205: ifp->if_softc = sc;
206: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
207: ifp->if_start = zestart;
208: ifp->if_ioctl = zeioctl;
209: ifp->if_watchdog = zetimeout;
210:
211: /*
212: * Attach the interface.
213: */
214: if_attach(ifp);
215: ether_ifattach(ifp);
216:
217: printf(": address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
218: return;
219:
220: /*
221: * Free any resources we've allocated during the failed attach
222: * attempt. Do this in reverse order and fall through.
223: */
224: fail_6:
225: for (i = 0; i < RXDESCS; i++) {
226: if (sc->sc_rxmbuf[i] != NULL) {
227: bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
228: m_freem(sc->sc_rxmbuf[i]);
229: }
230: }
231: fail_5:
232: for (i = 0; i < RXDESCS; i++) {
233: if (sc->sc_xmtmap[i] != NULL)
234: bus_dmamap_destroy(sc->sc_dmat, sc->sc_xmtmap[i]);
235: }
236: fail_4:
237: for (i = 0; i < TXDESCS; i++) {
238: if (sc->sc_rcvmap[i] != NULL)
239: bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
240: }
241: bus_dmamap_unload(sc->sc_dmat, sc->sc_cmap);
242: fail_3:
243: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmap);
244: fail_2:
245: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_zedata,
246: sizeof(struct ze_cdata));
247: fail_1:
248: bus_dmamem_free(sc->sc_dmat, &seg, rseg);
249: fail_0:
250: return;
251: }
252:
253: /*
254: * Initialization of interface.
255: */
256: void
257: zeinit(sc)
258: struct ze_softc *sc;
259: {
260: struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
261: struct ze_cdata *zc = sc->sc_zedata;
262: int i;
263:
264: /*
265: * Reset the interface.
266: */
267: if (zereset(sc))
268: return;
269:
270: sc->sc_nexttx = sc->sc_inq = sc->sc_lastack = 0;
271: /*
272: * Release and init transmit descriptors.
273: */
274: for (i = 0; i < TXDESCS; i++) {
275: if (sc->sc_txmbuf[i]) {
276: bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[i]);
277: m_freem(sc->sc_txmbuf[i]);
278: sc->sc_txmbuf[i] = 0;
279: }
280: zc->zc_xmit[i].ze_tdr = 0; /* Clear valid bit */
281: }
282:
283:
284: /*
285: * Init receive descriptors.
286: */
287: for (i = 0; i < RXDESCS; i++)
288: zc->zc_recv[i].ze_framelen = ZE_FRAMELEN_OW;
289: sc->sc_nextrx = 0;
290:
291: ZE_WCSR(ZE_CSR6, ZE_NICSR6_IE | ZE_NICSR6_BL_8 | ZE_NICSR6_ST |
292: ZE_NICSR6_SR | ZE_NICSR6_DC);
293:
294: ifp->if_flags |= IFF_RUNNING;
295: ifp->if_flags &= ~IFF_OACTIVE;
296:
297: /*
298: * Send a setup frame.
299: * This will start the transmit machinery as well.
300: */
301: ze_setup(sc);
302:
303: }
304:
305: /*
306: * Kick off the transmit logic, if it is stopped.
307: * On the VXT2000 we need to always reprogram CSR4,
308: * so stop it unconditionnaly.
309: */
310: void
311: zekick(struct ze_softc *sc)
312: {
313: u_int csr5;
314:
315: csr5 = ZE_RCSR(ZE_CSR5);
316: if (ISSET(sc->sc_flags, SGECF_VXTQUIRKS)) {
317: if ((csr5 & ZE_NICSR5_TS) == ZE_NICSR5_TS_RUN) {
318: ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) & ~ZE_NICSR6_ST);
319: while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_TS) !=
320: ZE_NICSR5_TS_STOP)
321: DELAY(10);
322: }
323: ZE_WCSR(ZE_CSR4,
324: (vaddr_t)&sc->sc_pzedata->zc_xmit[sc->sc_nexttx]);
325: ZE_WCSR(ZE_CSR1, ZE_NICSR1_TXPD);
326: if ((csr5 & ZE_NICSR5_TS) == ZE_NICSR5_TS_RUN) {
327: ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) | ZE_NICSR6_ST);
328: while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_TS) ==
329: ZE_NICSR5_TS_STOP)
330: DELAY(10);
331: }
332: } else {
333: if ((csr5 & ZE_NICSR5_TS) != ZE_NICSR5_TS_RUN)
334: ZE_WCSR(ZE_CSR1, ZE_NICSR1_TXPD);
335: }
336: }
337:
338: /*
339: * Start output on interface.
340: */
341: void
342: zestart(ifp)
343: struct ifnet *ifp;
344: {
345: struct ze_softc *sc = ifp->if_softc;
346: struct ze_cdata *zc = sc->sc_zedata;
347: paddr_t buffer;
348: struct mbuf *m, *m0;
349: int idx, len, s, i, totlen, error;
350: int old_inq = sc->sc_inq;
351: short orword;
352:
353: s = splnet();
354: while (sc->sc_inq < (TXDESCS - 1)) {
355: if (ISSET(sc->sc_flags, SGECF_SETUP)) {
356: ze_setup(sc);
357: continue;
358: }
359: idx = sc->sc_nexttx;
360: IF_DEQUEUE(&sc->sc_if.if_snd, m);
361: if (m == 0)
362: goto out;
363: /*
364: * Count number of mbufs in chain.
365: * Always do DMA directly from mbufs, therefore the transmit
366: * ring is really big.
367: */
368: for (m0 = m, i = 0; m0; m0 = m0->m_next)
369: if (m0->m_len)
370: i++;
371: if (i >= TXDESCS)
372: panic("zestart"); /* XXX */
373:
374: if ((i + sc->sc_inq) >= (TXDESCS - 1)) {
375: IF_PREPEND(&sc->sc_if.if_snd, m);
376: ifp->if_flags |= IFF_OACTIVE;
377: goto out;
378: }
379:
380: #if NBPFILTER > 0
381: if (ifp->if_bpf)
382: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
383: #endif
384: /*
385: * m now points to a mbuf chain that can be loaded.
386: * Loop around and set it.
387: */
388: totlen = 0;
389: for (m0 = m; m0; m0 = m0->m_next) {
390: error = bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[idx],
391: mtod(m0, void *), m0->m_len, 0, 0);
392: buffer = sc->sc_xmtmap[idx]->dm_segs[0].ds_addr;
393: len = m0->m_len;
394: if (len == 0)
395: continue;
396:
397: totlen += len;
398: /* Word alignment calc */
399: orword = 0;
400: if (totlen == len)
401: orword = ZE_TDES1_FS;
402: if (totlen == m->m_pkthdr.len) {
403: if (totlen < ETHER_ADDR_LEN)
404: len += (ETHER_ADDR_LEN - totlen);
405: orword |= ZE_TDES1_LS;
406: sc->sc_txmbuf[idx] = m;
407: }
408: zc->zc_xmit[idx].ze_bufsize = len;
409: zc->zc_xmit[idx].ze_bufaddr = (char *)buffer;
410: zc->zc_xmit[idx].ze_tdes1 = orword | ZE_TDES1_IC;
411: zc->zc_xmit[idx].ze_tdr = ZE_TDR_OW;
412:
413: if (++idx == TXDESCS)
414: idx = 0;
415: sc->sc_inq++;
416: }
417: #ifdef DIAGNOSTIC
418: if (totlen != m->m_pkthdr.len)
419: panic("zestart: len fault");
420: #endif
421:
422: /*
423: * Kick off the transmit logic, if it is stopped.
424: */
425: zekick(sc);
426: sc->sc_nexttx = idx;
427: }
428: if (sc->sc_inq == (TXDESCS - 1))
429: ifp->if_flags |= IFF_OACTIVE;
430:
431: out: if (old_inq < sc->sc_inq)
432: ifp->if_timer = 5; /* If transmit logic dies */
433: splx(s);
434: }
435:
436: void
437: sgec_rxintr(struct ze_softc *sc)
438: {
439: struct ze_cdata *zc = sc->sc_zedata;
440: struct ifnet *ifp = &sc->sc_if;
441: struct ether_header *eh;
442: struct mbuf *m;
443: u_short rdes0;
444: int len;
445:
446: while ((zc->zc_recv[sc->sc_nextrx].ze_framelen &
447: ZE_FRAMELEN_OW) == 0) {
448: rdes0 = zc->zc_recv[sc->sc_nextrx].ze_rdes0;
449: if (rdes0 & ZE_RDES0_ES) {
450: rdes0 &= ~ZE_RDES0_TL; /* not really an error */
451: if ((rdes0 & (ZE_RDES0_OF | ZE_RDES0_CE | ZE_RDES0_CS |
452: ZE_RDES0_LE | ZE_RDES0_RF)) == 0)
453: rdes0 &= ~ZE_RDES0_ES;
454: }
455: if (rdes0 & ZE_RDES0_ES) {
456: ifp->if_ierrors++;
457: if (rdes0 & ZE_RDES0_CS)
458: ifp->if_collisions++;
459: m = NULL;
460: } else {
461: ifp->if_ipackets++;
462: m = sc->sc_rxmbuf[sc->sc_nextrx];
463: len = zc->zc_recv[sc->sc_nextrx].ze_framelen;
464: }
465: ze_add_rxbuf(sc, sc->sc_nextrx);
466: if (m != NULL) {
467: m->m_pkthdr.rcvif = ifp;
468: m->m_pkthdr.len = m->m_len = len;
469: eh = mtod(m, struct ether_header *);
470: #if NBPFILTER > 0
471: if (ifp->if_bpf) {
472: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
473: if ((ifp->if_flags & IFF_PROMISC) != 0 &&
474: ((eh->ether_dhost[0] & 1) == 0) &&
475: bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
476: ETHER_ADDR_LEN) != 0) {
477: m_freem(m);
478: continue;
479: }
480: }
481: #endif
482: /*
483: * ALLMULTI means PROMISC in this driver.
484: */
485: if ((ifp->if_flags & IFF_ALLMULTI) &&
486: ((eh->ether_dhost[0] & 1) == 0) &&
487: bcmp(sc->sc_ac.ac_enaddr, eh->ether_dhost,
488: ETHER_ADDR_LEN)) {
489: m_freem(m);
490: continue;
491: }
492: ether_input_mbuf(ifp, m);
493: }
494: if (++sc->sc_nextrx == RXDESCS)
495: sc->sc_nextrx = 0;
496: }
497: }
498:
499: void
500: sgec_txintr(struct ze_softc *sc)
501: {
502: struct ze_cdata *zc = sc->sc_zedata;
503: struct ifnet *ifp = &sc->sc_if;
504: u_short tdes0;
505:
506: while ((zc->zc_xmit[sc->sc_lastack].ze_tdr & ZE_TDR_OW) == 0) {
507: int idx = sc->sc_lastack;
508:
509: if (sc->sc_lastack == sc->sc_nexttx)
510: break;
511: sc->sc_inq--;
512: if (++sc->sc_lastack == TXDESCS)
513: sc->sc_lastack = 0;
514:
515: if ((zc->zc_xmit[idx].ze_tdes1 & ZE_TDES1_DT) ==
516: ZE_TDES1_DT_SETUP) {
517: continue;
518: }
519:
520: tdes0 = zc->zc_xmit[idx].ze_tdes0;
521: if (tdes0 & ZE_TDES0_ES) {
522: if (tdes0 & ZE_TDES0_TO)
523: printf("%s: transmit watchdog timeout\n",
524: sc->sc_dev.dv_xname);
525: if (tdes0 & (ZE_TDES0_LO | ZE_TDES0_NC))
526: printf("%s: no carrier\n",
527: sc->sc_dev.dv_xname);
528: if (tdes0 & ZE_TDES0_EC) {
529: printf("%s: excessive collisions, tdr %d\n",
530: sc->sc_dev.dv_xname,
531: zc->zc_xmit[idx].ze_tdr & ~ZE_TDR_OW);
532: ifp->if_collisions += 16;
533: } else if (tdes0 & ZE_TDES0_LC)
534: ifp->if_collisions +=
535: (tdes0 & ZE_TDES0_CC) >> 3;
536: if (tdes0 & ZE_TDES0_UF)
537: printf("%s: underflow\n", sc->sc_dev.dv_xname);
538: ifp->if_oerrors++;
539: if (tdes0 & (ZE_TDES0_TO | ZE_TDES0_UF))
540: zeinit(sc);
541: } else {
542: if (zc->zc_xmit[idx].ze_tdes1 & ZE_TDES1_LS)
543: ifp->if_opackets++;
544: bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[idx]);
545: if (sc->sc_txmbuf[idx]) {
546: m_freem(sc->sc_txmbuf[idx]);
547: sc->sc_txmbuf[idx] = 0;
548: }
549: }
550: }
551: if (sc->sc_inq == 0)
552: ifp->if_timer = 0;
553: ifp->if_flags &= ~IFF_OACTIVE;
554: zestart(ifp); /* Put in more in queue */
555: }
556:
557: int
558: sgec_intr(sc)
559: struct ze_softc *sc;
560: {
561: int s, csr;
562:
563: csr = ZE_RCSR(ZE_CSR5);
564: if ((csr & ZE_NICSR5_IS) == 0) /* Wasn't we */
565: return 0;
566:
567: /*
568: * On some systems, interrupts are handled at spl4, this can end up
569: * in pool corruption.
570: */
571: s = splnet();
572:
573: ZE_WCSR(ZE_CSR5, csr);
574:
575: if (csr & ZE_NICSR5_ME) {
576: printf("%s: memory error, resetting\n", sc->sc_dev.dv_xname);
577: zeinit(sc);
578: return (1);
579: }
580:
581: if (csr & ZE_NICSR5_RI)
582: sgec_rxintr(sc);
583:
584: if (csr & ZE_NICSR5_TI)
585: sgec_txintr(sc);
586:
587: splx(s);
588:
589: return 1;
590: }
591:
592: /*
593: * Process an ioctl request.
594: */
595: int
596: zeioctl(ifp, cmd, data)
597: struct ifnet *ifp;
598: u_long cmd;
599: caddr_t data;
600: {
601: struct ze_softc *sc = ifp->if_softc;
602: struct ifreq *ifr = (struct ifreq *)data;
603: struct ifaddr *ifa = (struct ifaddr *)data;
604: int s = splnet(), error = 0;
605:
606: switch (cmd) {
607:
608: case SIOCSIFADDR:
609: ifp->if_flags |= IFF_UP;
610: switch(ifa->ifa_addr->sa_family) {
611: #ifdef INET
612: case AF_INET:
613: zeinit(sc);
614: arp_ifinit(&sc->sc_ac, ifa);
615: break;
616: #endif
617: }
618: break;
619:
620: case SIOCSIFFLAGS:
621: if ((ifp->if_flags & IFF_UP) == 0 &&
622: (ifp->if_flags & IFF_RUNNING) != 0) {
623: /*
624: * If interface is marked down and it is running,
625: * stop it. (by disabling receive mechanism).
626: */
627: ZE_WCSR(ZE_CSR6, ZE_RCSR(ZE_CSR6) &
628: ~(ZE_NICSR6_ST|ZE_NICSR6_SR));
629: ifp->if_flags &= ~IFF_RUNNING;
630: } else if ((ifp->if_flags & IFF_UP) != 0 &&
631: (ifp->if_flags & IFF_RUNNING) == 0) {
632: /*
633: * If interface it marked up and it is stopped, then
634: * start it.
635: */
636: zeinit(sc);
637: } else if ((ifp->if_flags & IFF_UP) != 0) {
638: /*
639: * Send a new setup packet to match any new changes.
640: * (Like IFF_PROMISC etc)
641: */
642: ze_setup(sc);
643: }
644: break;
645:
646: case SIOCADDMULTI:
647: case SIOCDELMULTI:
648: /*
649: * Update our multicast list.
650: */
651: error = (cmd == SIOCADDMULTI) ?
652: ether_addmulti(ifr, &sc->sc_ac):
653: ether_delmulti(ifr, &sc->sc_ac);
654:
655: if (error == ENETRESET) {
656: /*
657: * Multicast list has changed; set the hardware filter
658: * accordingly.
659: */
660: if (ifp->if_flags & IFF_RUNNING)
661: ze_setup(sc);
662: error = 0;
663: }
664: break;
665:
666: default:
667: error = EINVAL;
668:
669: }
670: splx(s);
671: return (error);
672: }
673:
674: /*
675: * Add a receive buffer to the indicated descriptor.
676: */
677: int
678: ze_add_rxbuf(sc, i)
679: struct ze_softc *sc;
680: int i;
681: {
682: struct mbuf *m;
683: struct ze_rdes *rp;
684: int error;
685:
686: splassert(IPL_NET);
687:
688: MGETHDR(m, M_DONTWAIT, MT_DATA);
689: if (m == NULL)
690: return (ENOBUFS);
691:
692: MCLGET(m, M_DONTWAIT);
693: if ((m->m_flags & M_EXT) == 0) {
694: m_freem(m);
695: return (ENOBUFS);
696: }
697:
698: if (sc->sc_rxmbuf[i] != NULL)
699: bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
700:
701: error = bus_dmamap_load(sc->sc_dmat, sc->sc_rcvmap[i],
702: m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
703: if (error)
704: panic("%s: can't load rx DMA map %d, error = %d",
705: sc->sc_dev.dv_xname, i, error);
706: sc->sc_rxmbuf[i] = m;
707:
708: bus_dmamap_sync(sc->sc_dmat, sc->sc_rcvmap[i], 0,
709: sc->sc_rcvmap[i]->dm_mapsize, BUS_DMASYNC_PREREAD);
710:
711: /*
712: * We know that the mbuf cluster is page aligned. Also, be sure
713: * that the IP header will be longword aligned.
714: */
715: m->m_data += 2;
716: rp = &sc->sc_zedata->zc_recv[i];
717: rp->ze_bufsize = (m->m_ext.ext_size - 2);
718: rp->ze_bufaddr = (char *)sc->sc_rcvmap[i]->dm_segs[0].ds_addr + 2;
719: rp->ze_framelen = ZE_FRAMELEN_OW;
720:
721: return (0);
722: }
723:
724: /*
725: * Create a setup packet and put in queue for sending.
726: */
727: void
728: ze_setup(sc)
729: struct ze_softc *sc;
730: {
731: struct ether_multi *enm;
732: struct ether_multistep step;
733: struct ze_cdata *zc = sc->sc_zedata;
734: struct ifnet *ifp = &sc->sc_if;
735: u_int8_t *enaddr = sc->sc_ac.ac_enaddr;
736: int j, idx, s, reg;
737:
738: s = splnet();
739: if (sc->sc_inq == (TXDESCS - 1)) {
740: SET(sc->sc_flags, SGECF_SETUP);
741: splx(s);
742: return;
743: }
744: CLR(sc->sc_flags, SGECF_SETUP);
745:
746: /*
747: * Init the setup packet with valid info.
748: */
749: memset(zc->zc_setup, 0xff, sizeof(zc->zc_setup)); /* Broadcast */
750: bcopy(enaddr, zc->zc_setup, ETHER_ADDR_LEN);
751:
752: /*
753: * Multicast handling. The SGEC can handle up to 16 direct
754: * ethernet addresses.
755: */
756: j = 16;
757: ifp->if_flags &= ~IFF_ALLMULTI;
758: ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
759: while (enm != NULL) {
760: if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) {
761: ifp->if_flags |= IFF_ALLMULTI;
762: break;
763: }
764: bcopy(enm->enm_addrlo, &zc->zc_setup[j], ETHER_ADDR_LEN);
765: j += 8;
766: ETHER_NEXT_MULTI(step, enm);
767: if ((enm != NULL)&& (j == 128)) {
768: ifp->if_flags |= IFF_ALLMULTI;
769: break;
770: }
771: }
772:
773: /*
774: * Fiddle with the receive logic.
775: */
776: reg = ZE_RCSR(ZE_CSR6);
777: DELAY(10);
778: ZE_WCSR(ZE_CSR6, reg & ~ZE_NICSR6_SR); /* Stop rx */
779: while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_RS) != ZE_NICSR5_RS_STOP)
780: DELAY(10);
781: reg &= ~ZE_NICSR6_AF;
782: if (ifp->if_flags & IFF_PROMISC)
783: reg |= ZE_NICSR6_AF_PROM;
784: else if (ifp->if_flags & IFF_ALLMULTI)
785: reg |= ZE_NICSR6_AF_ALLM;
786: DELAY(10);
787: ZE_WCSR(ZE_CSR6, reg);
788: while ((ZE_RCSR(ZE_CSR5) & ZE_NICSR5_RS) == ZE_NICSR5_RS_STOP)
789: DELAY(10);
790: /*
791: * Only send a setup packet if needed.
792: */
793: if ((ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) == 0) {
794: idx = sc->sc_nexttx;
795: zc->zc_xmit[idx].ze_tdes1 = ZE_TDES1_DT_SETUP;
796: zc->zc_xmit[idx].ze_bufsize = 128;
797: zc->zc_xmit[idx].ze_bufaddr = sc->sc_pzedata->zc_setup;
798: zc->zc_xmit[idx].ze_tdr = ZE_TDR_OW;
799:
800: zekick(sc);
801:
802: sc->sc_inq++;
803: if (++sc->sc_nexttx == TXDESCS)
804: sc->sc_nexttx = 0;
805: }
806: splx(s);
807: }
808:
809: /*
810: * Check for dead transmit logic.
811: */
812: void
813: zetimeout(ifp)
814: struct ifnet *ifp;
815: {
816: struct ze_softc *sc = ifp->if_softc;
817:
818: if (sc->sc_inq == 0)
819: return;
820:
821: printf("%s: xmit logic died, resetting...\n", sc->sc_dev.dv_xname);
822: /*
823: * Do a reset of interface, to get it going again.
824: * Will it work by just restart the transmit logic?
825: */
826: zeinit(sc);
827: }
828:
829: /*
830: * Reset chip:
831: * Set/reset the reset flag.
832: * Write interrupt vector.
833: * Write ring buffer addresses.
834: * Write SBR.
835: */
836: int
837: zereset(sc)
838: struct ze_softc *sc;
839: {
840: int reg, i, s;
841:
842: ZE_WCSR(ZE_CSR6, ZE_NICSR6_RE);
843: DELAY(50000);
844: if (ZE_RCSR(ZE_CSR5) & ZE_NICSR5_SF) {
845: printf("%s: selftest failed\n", sc->sc_dev.dv_xname);
846: return 1;
847: }
848:
849: /*
850: * Get the vector that were set at match time, and remember it.
851: * WHICH VECTOR TO USE? Take one unused. XXX
852: * Funny way to set vector described in the programmers manual.
853: */
854: reg = ZE_NICSR0_IPL14 | sc->sc_intvec | ZE_NICSR0_MBO; /* SYNC/ASYNC??? */
855: i = 10;
856: s = splnet();
857: do {
858: if (i-- == 0) {
859: printf("Failing SGEC CSR0 init\n");
860: splx(s);
861: return 1;
862: }
863: ZE_WCSR(ZE_CSR0, reg);
864: } while (ZE_RCSR(ZE_CSR0) != reg);
865: splx(s);
866:
867: ZE_WCSR(ZE_CSR3, (vaddr_t)sc->sc_pzedata->zc_recv);
868: ZE_WCSR(ZE_CSR4, (vaddr_t)sc->sc_pzedata->zc_xmit);
869: return 0;
870: }
CVSweb