Annotation of sys/arch/mac68k/dev/if_sn.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_sn.c,v 1.46 2007/01/12 16:31:21 martin Exp $ */
2: /* $NetBSD: if_sn.c,v 1.13 1997/04/25 03:40:10 briggs Exp $ */
3:
4: /*
5: * National Semiconductor DP8393X SONIC Driver
6: * Copyright (c) 1991 Algorithmics Ltd (http://www.algor.co.uk)
7: * You may use, copy, and modify this program so long as you retain the
8: * copyright line.
9: *
10: * This driver has been substantially modified since Algorithmics donated
11: * it.
12: *
13: * Denton Gentry <denny1@home.com>
14: * and also
15: * Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp>
16: * did the work to get this running on the Macintosh.
17: */
18:
19: #include <sys/param.h>
20: #include <sys/systm.h>
21: #include <sys/mbuf.h>
22: #include <sys/buf.h>
23: #include <sys/protosw.h>
24: #include <sys/socket.h>
25: #include <sys/syslog.h>
26: #include <sys/ioctl.h>
27: #include <sys/errno.h>
28: #include <sys/device.h>
29:
30: #include <net/if.h>
31: #include <net/if_dl.h>
32: #include <net/netisr.h>
33:
34: #ifdef INET
35: #include <netinet/in.h>
36: #include <netinet/in_systm.h>
37: #include <netinet/in_var.h>
38: #include <netinet/ip.h>
39: #include <netinet/if_ether.h>
40: #endif
41:
42: #include <uvm/uvm_extern.h>
43:
44: #include "bpfilter.h"
45: #if NBPFILTER > 0
46: #include <net/bpf.h>
47: #include <net/bpfdesc.h>
48: #endif
49:
50: #include <machine/bus.h>
51: #include <machine/cpu.h>
52: /* #include <machine/viareg.h> */
53: #include <mac68k/dev/if_snreg.h>
54: #include <mac68k/dev/if_snvar.h>
55:
56: static void snwatchdog(struct ifnet *);
57: static int sninit(struct sn_softc *);
58: static int snstop(struct sn_softc *);
59: static int snioctl(struct ifnet *, u_long, caddr_t);
60: static void snstart(struct ifnet *);
61: static void snreset(struct sn_softc *);
62:
63: static void caminitialise(struct sn_softc *);
64: static void camentry(struct sn_softc *, int, u_char *);
65: static void camprogram(struct sn_softc *);
66: static void initialise_tda(struct sn_softc *);
67: static void initialise_rda(struct sn_softc *);
68: static void initialise_rra(struct sn_softc *);
69: #ifdef SNDEBUG
70: static void camdump(struct sn_softc *);
71: #endif
72:
73: static void sonictxint(struct sn_softc *);
74: static void sonicrxint(struct sn_softc *);
75:
76: static __inline__ int sonicput(struct sn_softc *, struct mbuf *,
77: int);
78: static __inline__ int sonic_read(struct sn_softc *, caddr_t, int);
79: static __inline__ struct mbuf *sonic_get(struct sn_softc *, caddr_t, int);
80:
81: struct cfdriver sn_cd = {
82: NULL, "sn", DV_IFNET
83: };
84:
85: /*
86: * SONIC buffers need to be aligned 16 or 32 bit aligned.
87: * These macros calculate and verify alignment.
88: */
89: #define ROUNDUP(p, N) (((int) p + N - 1) & ~(N - 1))
90:
91: #define SOALIGN(m, array) (m ? (ROUNDUP(array, 4)) : (ROUNDUP(array, 2)))
92:
93: #define LOWER(x) ((unsigned)(x) & 0xffff)
94: #define UPPER(x) ((unsigned)(x) >> 16)
95:
96: /*
97: * Interface exists: make available by filling in network interface
98: * record. System will initialize the interface when it is ready
99: * to accept packets.
100: */
101: int
102: snsetup(struct sn_softc *sc, u_int8_t *lladdr)
103: {
104: struct ifnet *ifp = &sc->sc_if;
105: struct pglist pglist;
106: vm_page_t pg;
107: paddr_t phys;
108: vaddr_t p, pp;
109: int i, offset, error;
110:
111: /*
112: * XXX if_sn.c is intended to be MI. Should it allocate memory
113: * for its descriptor areas, or expect the MD attach code
114: * to do that?
115: */
116: TAILQ_INIT(&pglist);
117: error = uvm_pglistalloc(SN_NPAGES * PAGE_SIZE, 0, -PAGE_SIZE,
118: PAGE_SIZE, 0, &pglist, 1, 0);
119: if (error != 0) {
120: printf(": could not allocate descriptor memory\n");
121: return (error);
122: }
123:
124: /*
125: * Map the pages uncached.
126: */
127: sc->space = uvm_km_valloc(kernel_map, SN_NPAGES * PAGE_SIZE);
128: if (sc->space == NULL) {
129: printf(": could not map descriptor memory\n");
130: uvm_pglistfree(&pglist);
131: return (ENOMEM);
132: }
133:
134: phys = VM_PAGE_TO_PHYS(TAILQ_FIRST(&pglist));
135: p = pp = sc->space;
136: TAILQ_FOREACH(pg, &pglist, pageq) {
137: pmap_enter_cache(pmap_kernel(), p, VM_PAGE_TO_PHYS(pg),
138: UVM_PROT_RW, UVM_PROT_RW | PMAP_WIRED, PG_CI);
139: p += PAGE_SIZE;
140: }
141: pmap_update(pmap_kernel());
142: p = pp;
143:
144: /*
145: * Put the pup in reset mode (sninit() will fix it later),
146: * stop the timer, disable all interrupts and clear any interrupts.
147: */
148: NIC_PUT(sc, SNR_CR, CR_STP);
149: wbflush();
150: NIC_PUT(sc, SNR_CR, CR_RST);
151: wbflush();
152: NIC_PUT(sc, SNR_IMR, 0);
153: wbflush();
154: NIC_PUT(sc, SNR_ISR, ISR_ALL);
155: wbflush();
156:
157: for (i = 0; i < NRRA; i++) {
158: sc->p_rra[i] = (void *)p;
159: sc->v_rra[i] = (p - sc->space) + phys;
160: p += RXRSRC_SIZE(sc);
161: }
162: sc->v_rea = (p - sc->space) + phys;
163:
164: p = SOALIGN(sc, p);
165:
166: sc->p_cda = (void *)(p);
167: sc->v_cda = (p - sc->space) + phys;
168: p += CDA_SIZE(sc);
169:
170: p = SOALIGN(sc, p);
171:
172: for (i = 0; i < NTDA; i++) {
173: struct mtd *mtdp = &sc->mtda[i];
174: mtdp->mtd_txp = (void *)p;
175: mtdp->mtd_vtxp = (p - sc->space) + phys;
176: p += TXP_SIZE(sc);
177: }
178:
179: p = SOALIGN(sc, p);
180:
181: #ifdef DIAGNOSTIC
182: if ((p - pp) > PAGE_SIZE) {
183: printf (": sizeof RRA (%ld) + CDA (%ld) +"
184: "TDA (%ld) > PAGE_SIZE (%d). Punt!\n",
185: (ulong)sc->p_cda - (ulong)sc->p_rra[0],
186: (ulong)sc->mtda[0].mtd_txp - (ulong)sc->p_cda,
187: (ulong)p - (ulong)sc->mtda[0].mtd_txp,
188: PAGE_SIZE);
189: return (EINVAL);
190: }
191: #endif
192:
193: p = pp + PAGE_SIZE;
194: pp = p;
195:
196: sc->sc_nrda = PAGE_SIZE / RXPKT_SIZE(sc);
197: sc->p_rda = (caddr_t)p;
198: sc->v_rda = (p - sc->space) + phys;
199:
200: p = pp + PAGE_SIZE;
201:
202: for (i = 0; i < NRBA; i++) {
203: sc->rbuf[i] = (caddr_t)p;
204: sc->rbuf_phys[i] = (p - sc->space) + phys;
205: p += PAGE_SIZE;
206: }
207:
208: pp = p;
209: offset = 0;
210: for (i = 0; i < NTDA; i++) {
211: struct mtd *mtdp = &sc->mtda[i];
212:
213: mtdp->mtd_buf = (caddr_t)p;
214: mtdp->mtd_vbuf = (p - sc->space) + phys;
215: offset += TXBSIZE;
216: if (offset < PAGE_SIZE - TXBSIZE) {
217: p += TXBSIZE;
218: } else {
219: p = pp + PAGE_SIZE;
220: pp = p;
221: offset = 0;
222: }
223: }
224:
225: #ifdef SNDEBUG
226: camdump(sc);
227: #endif
228: printf("address %s\n", ether_sprintf(lladdr));
229:
230: #ifdef SNDEBUG
231: printf("%s: buffers: rra=%p cda=%p rda=%p tda=%p\n",
232: sc->sc_dev.dv_xname, sc->p_rra[0], sc->p_cda,
233: sc->p_rda, sc->mtda[0].mtd_txp);
234: #endif
235:
236: bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
237: bcopy(lladdr, sc->sc_enaddr, ETHER_ADDR_LEN);
238:
239: ifp->if_softc = sc;
240: ifp->if_ioctl = snioctl;
241: ifp->if_start = snstart;
242: ifp->if_flags =
243: IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
244: ifp->if_watchdog = snwatchdog;
245: if_attach(ifp);
246: ether_ifattach(ifp);
247:
248: return (0);
249: }
250:
251: static int
252: snioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
253: {
254: struct ifaddr *ifa;
255: struct ifreq *ifr;
256: struct sn_softc *sc = ifp->if_softc;
257: int s = splnet(), err = 0;
258:
259: switch (cmd) {
260:
261: case SIOCSIFADDR:
262: ifa = (struct ifaddr *)data;
263: ifp->if_flags |= IFF_UP;
264: switch (ifa->ifa_addr->sa_family) {
265: #ifdef INET
266: case AF_INET:
267: (void)sninit(sc);
268: arp_ifinit(&sc->sc_arpcom, ifa);
269: break;
270: #endif
271: default:
272: (void)sninit(sc);
273: break;
274: }
275: break;
276:
277: case SIOCSIFFLAGS:
278: if ((ifp->if_flags & IFF_UP) == 0 &&
279: (ifp->if_flags & IFF_RUNNING) != 0) {
280: /*
281: * If interface is marked down and it is running,
282: * then stop it.
283: */
284: snstop(sc);
285: ifp->if_flags &= ~IFF_RUNNING;
286: } else if ((ifp->if_flags & IFF_UP) != 0 &&
287: (ifp->if_flags & IFF_RUNNING) == 0) {
288: /*
289: * If interface is marked up and it is stopped,
290: * then start it.
291: */
292: (void)sninit(sc);
293: } else {
294: /*
295: * reset the interface to pick up any other changes
296: * in flags
297: */
298: snreset(sc);
299: snstart(ifp);
300: }
301: break;
302:
303: case SIOCADDMULTI:
304: case SIOCDELMULTI:
305: ifr = (struct ifreq *) data;
306: if (cmd == SIOCADDMULTI)
307: err = ether_addmulti(ifr, &sc->sc_arpcom);
308: else
309: err = ether_delmulti(ifr, &sc->sc_arpcom);
310:
311: if (err == ENETRESET) {
312: /*
313: * Multicast list has changed; set the hardware
314: * filter accordingly. But remember UP flag!
315: */
316: if (ifp->if_flags & IFF_RUNNING)
317: snreset(sc);
318: err = 0;
319: }
320: break;
321: default:
322: err = EINVAL;
323: }
324: splx(s);
325: return (err);
326: }
327:
328: /*
329: * Encapsulate a packet of type family for the local net.
330: */
331: static void
332: snstart(struct ifnet *ifp)
333: {
334: struct sn_softc *sc = ifp->if_softc;
335: struct mbuf *m;
336: int mtd_next;
337:
338: if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
339: return;
340:
341: outloop:
342: /* Check for room in the xmit buffer. */
343: if ((mtd_next = (sc->mtd_free + 1)) == NTDA)
344: mtd_next = 0;
345:
346: if (mtd_next == sc->mtd_hw) {
347: ifp->if_flags |= IFF_OACTIVE;
348: return;
349: }
350:
351: IF_DEQUEUE(&ifp->if_snd, m);
352: if (m == NULL)
353: return;
354:
355: /* We need the header for m_pkthdr.len. */
356: if ((m->m_flags & M_PKTHDR) == 0)
357: panic("%s: snstart: no header mbuf", sc->sc_dev.dv_xname);
358:
359: #if NBPFILTER > 0
360: /*
361: * If bpf is listening on this interface, let it
362: * see the packet before we commit it to the wire.
363: */
364: if (ifp->if_bpf)
365: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
366: #endif
367:
368: /*
369: * If there is nothing in the o/p queue, and there is room in
370: * the Tx ring, then send the packet directly. Otherwise append
371: * it to the o/p queue.
372: */
373: if ((sonicput(sc, m, mtd_next)) > 0) {
374: } else {
375: IF_PREPEND(&ifp->if_snd, m);
376: return;
377: }
378:
379: sc->mtd_prev = sc->mtd_free;
380: sc->mtd_free = mtd_next;
381:
382: ifp->if_opackets++; /* # of pkts */
383:
384: /* Jump back for possibly more punishment. */
385: goto outloop;
386: }
387:
388: /*
389: * reset and restart the SONIC. Called in case of fatal
390: * hardware/software errors.
391: */
392: static void
393: snreset(struct sn_softc *sc)
394: {
395: snstop(sc);
396: sninit(sc);
397: }
398:
399: static int
400: sninit(struct sn_softc *sc)
401: {
402: u_long s_rcr;
403: int s;
404:
405: if (sc->sc_if.if_flags & IFF_RUNNING)
406: /* already running */
407: return (0);
408:
409: s = splnet();
410:
411: NIC_PUT(sc, SNR_CR, CR_RST); /* DCR only accessible in reset mode! */
412:
413: /* config it */
414: NIC_PUT(sc, SNR_DCR, (sc->snr_dcr |
415: (sc->bitmode ? DCR_DW32 : DCR_DW16)));
416: NIC_PUT(sc, SNR_DCR2, sc->snr_dcr2);
417:
418: s_rcr = RCR_BRD | RCR_LBNONE;
419: if (sc->sc_if.if_flags & IFF_PROMISC)
420: s_rcr |= RCR_PRO;
421: if (sc->sc_if.if_flags & IFF_ALLMULTI)
422: s_rcr |= RCR_AMC;
423: NIC_PUT(sc, SNR_RCR, s_rcr);
424:
425: NIC_PUT(sc, SNR_IMR, (IMR_PRXEN | IMR_PTXEN | IMR_TXEREN | IMR_LCDEN));
426:
427: /* clear pending interrupts */
428: NIC_PUT(sc, SNR_ISR, ISR_ALL);
429:
430: /* clear tally counters */
431: NIC_PUT(sc, SNR_CRCT, -1);
432: NIC_PUT(sc, SNR_FAET, -1);
433: NIC_PUT(sc, SNR_MPT, -1);
434:
435: initialise_tda(sc);
436: initialise_rda(sc);
437: initialise_rra(sc);
438:
439: /* enable the chip */
440: NIC_PUT(sc, SNR_CR, 0);
441: wbflush();
442:
443: /* program the CAM */
444: camprogram(sc);
445:
446: /* get it to read resource descriptors */
447: NIC_PUT(sc, SNR_CR, CR_RRRA);
448: wbflush();
449: while ((NIC_GET(sc, SNR_CR)) & CR_RRRA)
450: continue;
451:
452: /* enable rx */
453: NIC_PUT(sc, SNR_CR, CR_RXEN);
454: wbflush();
455:
456: /* flag interface as "running" */
457: sc->sc_if.if_flags |= IFF_RUNNING;
458: sc->sc_if.if_flags &= ~IFF_OACTIVE;
459:
460: splx(s);
461: return (0);
462: }
463:
464: /*
465: * close down an interface and free its buffers
466: * Called on final close of device, or if sninit() fails
467: * part way through.
468: */
469: static int
470: snstop(struct sn_softc *sc)
471: {
472: struct mtd *mtd;
473: int s = splnet();
474:
475: /* stick chip in reset */
476: NIC_PUT(sc, SNR_CR, CR_RST);
477: wbflush();
478:
479: /* free all receive buffers (currently static so nothing to do) */
480:
481: /* free all pending transmit mbufs */
482: while (sc->mtd_hw != sc->mtd_free) {
483: mtd = &sc->mtda[sc->mtd_hw];
484: if (mtd->mtd_mbuf)
485: m_freem(mtd->mtd_mbuf);
486: if (++sc->mtd_hw == NTDA) sc->mtd_hw = 0;
487: }
488:
489: sc->sc_if.if_timer = 0;
490: sc->sc_if.if_flags &= ~IFF_RUNNING;
491:
492: splx(s);
493: return (0);
494: }
495:
496: /*
497: * Called if any Tx packets remain unsent after 5 seconds,
498: * In all cases we just reset the chip, and any retransmission
499: * will be handled by higher level protocol timeouts.
500: */
501: static void
502: snwatchdog(struct ifnet *ifp)
503: {
504: struct sn_softc *sc = ifp->if_softc;
505: struct mtd *mtd;
506:
507: if (sc->mtd_hw != sc->mtd_free) {
508: /* something still pending for transmit */
509: mtd = &sc->mtda[sc->mtd_hw];
510: if (SRO(sc->bitmode, mtd->mtd_txp, TXP_STATUS) == 0)
511: log(LOG_ERR, "%s: Tx - timeout\n",
512: sc->sc_dev.dv_xname);
513: else
514: log(LOG_ERR, "%s: Tx - lost interrupt\n",
515: sc->sc_dev.dv_xname);
516: snreset(sc);
517: }
518: }
519:
520: /*
521: * stuff packet into sonic (at splnet)
522: */
523: static __inline__ int
524: sonicput(struct sn_softc *sc, struct mbuf *m0, int mtd_next)
525: {
526: struct mtd *mtdp;
527: struct mbuf *m;
528: u_char *buff;
529: void *txp;
530: u_int len = 0;
531: u_int totlen = 0;
532:
533: /* grab the replacement mtd */
534: mtdp = &sc->mtda[sc->mtd_free];
535:
536: buff = mtdp->mtd_buf;
537:
538: /* this packet goes to mtdnext fill in the TDA */
539: mtdp->mtd_mbuf = m0;
540: txp = mtdp->mtd_txp;
541:
542: /* Write to the config word. Every (NTDA/2)+1 packets we set an intr */
543: if (sc->mtd_pint == 0) {
544: sc->mtd_pint = NTDA/2;
545: SWO(sc->bitmode, txp, TXP_CONFIG, TCR_PINT);
546: } else {
547: sc->mtd_pint--;
548: SWO(sc->bitmode, txp, TXP_CONFIG, 0);
549: }
550:
551: for (m = m0; m; m = m->m_next) {
552: u_char *data = mtod(m, u_char *);
553: len = m->m_len;
554: totlen += len;
555: bcopy(data, buff, len);
556: buff += len;
557: }
558: if (totlen >= TXBSIZE) {
559: panic("%s: sonicput: packet overflow", sc->sc_dev.dv_xname);
560: }
561:
562: SWO(sc->bitmode, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FPTRLO,
563: LOWER(mtdp->mtd_vbuf));
564: SWO(sc->bitmode, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FPTRHI,
565: UPPER(mtdp->mtd_vbuf));
566:
567: if (totlen < ETHERMIN + ETHER_HDR_LEN) {
568: int pad = ETHERMIN + ETHER_HDR_LEN - totlen;
569: bzero(mtdp->mtd_buf + totlen, pad);
570: totlen = ETHERMIN + ETHER_HDR_LEN;
571: }
572:
573: SWO(sc->bitmode, txp, TXP_FRAGOFF + (0 * TXP_FRAGSIZE) + TXP_FSIZE,
574: totlen);
575: SWO(sc->bitmode, txp, TXP_FRAGCNT, 1);
576: SWO(sc->bitmode, txp, TXP_PKTSIZE, totlen);
577:
578: /* link onto the next mtd that will be used */
579: SWO(sc->bitmode, txp, TXP_FRAGOFF + (1 * TXP_FRAGSIZE) + TXP_FPTRLO,
580: LOWER(sc->mtda[mtd_next].mtd_vtxp) | EOL);
581:
582: /*
583: * The previous txp.tlink currently contains a pointer to
584: * our txp | EOL. Want to clear the EOL, so write our
585: * pointer to the previous txp.
586: */
587: SWO(sc->bitmode, sc->mtda[sc->mtd_prev].mtd_txp, sc->mtd_tlinko,
588: LOWER(mtdp->mtd_vtxp));
589:
590: /* make sure chip is running */
591: wbflush();
592: NIC_PUT(sc, SNR_CR, CR_TXP);
593: wbflush();
594: sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */
595:
596: return (totlen);
597: }
598:
599: /*
600: * These are called from sonicioctl() when /etc/ifconfig is run to set
601: * the address or switch the i/f on.
602: */
603: /*
604: * CAM support
605: */
606: static void
607: caminitialise(struct sn_softc *sc)
608: {
609: void *p_cda = sc->p_cda;
610: int i;
611: int bitmode = sc->bitmode;
612: int camoffset;
613:
614: for (i = 0; i < MAXCAM; i++) {
615: camoffset = i * CDA_CAMDESC;
616: SWO(bitmode, p_cda, (camoffset + CDA_CAMEP), i);
617: SWO(bitmode, p_cda, (camoffset + CDA_CAMAP2), 0);
618: SWO(bitmode, p_cda, (camoffset + CDA_CAMAP1), 0);
619: SWO(bitmode, p_cda, (camoffset + CDA_CAMAP0), 0);
620: }
621: SWO(bitmode, p_cda, CDA_ENABLE, 0);
622: }
623:
624: static void
625: camentry(struct sn_softc *sc, int entry, u_char *ea)
626: {
627: void *p_cda = sc->p_cda;
628: int bitmode = sc->bitmode;
629: int camoffset = entry * CDA_CAMDESC;
630:
631: SWO(bitmode, p_cda, camoffset + CDA_CAMEP, entry);
632: SWO(bitmode, p_cda, camoffset + CDA_CAMAP2, (ea[5] << 8) | ea[4]);
633: SWO(bitmode, p_cda, camoffset + CDA_CAMAP1, (ea[3] << 8) | ea[2]);
634: SWO(bitmode, p_cda, camoffset + CDA_CAMAP0, (ea[1] << 8) | ea[0]);
635: SWO(bitmode, p_cda, CDA_ENABLE,
636: (SRO(bitmode, p_cda, CDA_ENABLE) | (1 << entry)));
637: }
638:
639: static void
640: camprogram(struct sn_softc *sc)
641: {
642: struct ether_multistep step;
643: struct ether_multi *enm;
644: struct ifnet *ifp;
645: int timeout;
646: int mcount = 0;
647:
648: caminitialise(sc);
649:
650: ifp = &sc->sc_if;
651:
652: /* Always load our own address first. */
653: camentry (sc, mcount, sc->sc_enaddr);
654: mcount++;
655:
656: /* Assume we won't need allmulti bit. */
657: ifp->if_flags &= ~IFF_ALLMULTI;
658:
659: /* Loop through multicast addresses */
660: ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
661: while (enm != NULL) {
662: if (mcount == MAXCAM) {
663: ifp->if_flags |= IFF_ALLMULTI;
664: break;
665: }
666:
667: if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
668: sizeof(enm->enm_addrlo)) != 0) {
669: /*
670: * SONIC's CAM is programmed with specific
671: * addresses. It has no way to specify a range.
672: * (Well, thats not exactly true. If the
673: * range is small one could program each addr
674: * within the range as a separate CAM entry)
675: */
676: ifp->if_flags |= IFF_ALLMULTI;
677: break;
678: }
679:
680: /* program the CAM with the specified entry */
681: camentry(sc, mcount, enm->enm_addrlo);
682: mcount++;
683:
684: ETHER_NEXT_MULTI(step, enm);
685: }
686:
687: NIC_PUT(sc, SNR_CDP, LOWER(sc->v_cda));
688: NIC_PUT(sc, SNR_CDC, MAXCAM);
689: NIC_PUT(sc, SNR_CR, CR_LCAM);
690: wbflush();
691:
692: timeout = 10000;
693: while ((NIC_GET(sc, SNR_CR) & CR_LCAM) && timeout--)
694: continue;
695: if (timeout == 0) {
696: /* XXX */
697: panic("%s: CAM initialisation failed", sc->sc_dev.dv_xname);
698: }
699: timeout = 10000;
700: while (((NIC_GET(sc, SNR_ISR) & ISR_LCD) == 0) && timeout--)
701: continue;
702:
703: if (NIC_GET(sc, SNR_ISR) & ISR_LCD)
704: NIC_PUT(sc, SNR_ISR, ISR_LCD);
705: else
706: printf("%s: CAM initialisation without interrupt\n",
707: sc->sc_dev.dv_xname);
708: }
709:
710: #ifdef SNDEBUG
711: static void
712: camdump(struct sn_softc *sc)
713: {
714: int i;
715:
716: printf("CAM entries:\n");
717: NIC_PUT(sc, SNR_CR, CR_RST);
718: wbflush();
719:
720: for (i = 0; i < 16; i++) {
721: ushort ap2, ap1, ap0;
722: NIC_PUT(sc, SNR_CEP, i);
723: wbflush();
724: ap2 = NIC_GET(sc, SNR_CAP2);
725: ap1 = NIC_GET(sc, SNR_CAP1);
726: ap0 = NIC_GET(sc, SNR_CAP0);
727: printf("%d: ap2=0x%x ap1=0x%x ap0=0x%x\n", i, ap2, ap1, ap0);
728: }
729: printf("CAM enable 0x%x\n", NIC_GET(sc, SNR_CEP));
730:
731: NIC_PUT(sc, SNR_CR, 0);
732: wbflush();
733: }
734: #endif
735:
736: static void
737: initialise_tda(struct sn_softc *sc)
738: {
739: struct mtd *mtd;
740: int i;
741:
742: for (i = 0; i < NTDA; i++) {
743: mtd = &sc->mtda[i];
744: mtd->mtd_mbuf = 0;
745: }
746:
747: sc->mtd_hw = 0;
748: sc->mtd_prev = NTDA - 1;
749: sc->mtd_free = 0;
750: sc->mtd_tlinko = TXP_FRAGOFF + 1*TXP_FRAGSIZE + TXP_FPTRLO;
751: sc->mtd_pint = NTDA/2;
752:
753: NIC_PUT(sc, SNR_UTDA, UPPER(sc->mtda[0].mtd_vtxp));
754: NIC_PUT(sc, SNR_CTDA, LOWER(sc->mtda[0].mtd_vtxp));
755: }
756:
757: static void
758: initialise_rda(struct sn_softc *sc)
759: {
760: int bitmode = sc->bitmode;
761: int i;
762: caddr_t p_rda = 0;
763: u_int32_t v_rda = 0;
764:
765: /* link the RDA's together into a circular list */
766: for (i = 0; i < (sc->sc_nrda - 1); i++) {
767: p_rda = sc->p_rda + (i * RXPKT_SIZE(sc));
768: v_rda = sc->v_rda + ((i+1) * RXPKT_SIZE(sc));
769: SWO(bitmode, p_rda, RXPKT_RLINK, LOWER(v_rda));
770: SWO(bitmode, p_rda, RXPKT_INUSE, 1);
771: }
772: p_rda = sc->p_rda + ((sc->sc_nrda - 1) * RXPKT_SIZE(sc));
773: SWO(bitmode, p_rda, RXPKT_RLINK, LOWER(sc->v_rda) | EOL);
774: SWO(bitmode, p_rda, RXPKT_INUSE, 1);
775:
776: /* mark end of receive descriptor list */
777: sc->sc_rdamark = sc->sc_nrda - 1;
778:
779: sc->sc_rxmark = 0;
780:
781: NIC_PUT(sc, SNR_URDA, UPPER(sc->v_rda));
782: NIC_PUT(sc, SNR_CRDA, LOWER(sc->v_rda));
783: wbflush();
784: }
785:
786: static void
787: initialise_rra(struct sn_softc *sc)
788: {
789: int i;
790: u_int v;
791: int bitmode = sc->bitmode;
792:
793: if (bitmode)
794: NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 2);
795: else
796: NIC_PUT(sc, SNR_EOBC, RBASIZE(sc) / 2 - 1);
797:
798: NIC_PUT(sc, SNR_URRA, UPPER(sc->v_rra[0]));
799: NIC_PUT(sc, SNR_RSA, LOWER(sc->v_rra[0]));
800: /* rea must point just past the end of the rra space */
801: NIC_PUT(sc, SNR_REA, LOWER(sc->v_rea));
802: NIC_PUT(sc, SNR_RRP, LOWER(sc->v_rra[0]));
803: NIC_PUT(sc, SNR_RSC, 0);
804:
805: /* fill up SOME of the rra with buffers */
806: for (i = 0; i < NRBA; i++) {
807: v = sc->rbuf_phys[i];
808: SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v));
809: SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v));
810: SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(PAGE_SIZE/2));
811: SWO(bitmode, sc->p_rra[i], RXRSRC_WCLO, LOWER(PAGE_SIZE/2));
812: }
813: sc->sc_rramark = NRBA;
814: NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[sc->sc_rramark]));
815: wbflush();
816: }
817:
818: int
819: snintr(void *arg)
820: {
821: struct sn_softc *sc = (struct sn_softc *)arg;
822: int isr;
823: int rv = 0;
824:
825: while ((isr = (NIC_GET(sc, SNR_ISR) & ISR_ALL)) != 0) {
826: rv = 1;
827: /* scrub the interrupts that we are going to service */
828: NIC_PUT(sc, SNR_ISR, isr);
829: wbflush();
830:
831: if (isr & (ISR_BR | ISR_LCD | ISR_TC))
832: printf("%s: unexpected interrupt status 0x%x\n",
833: sc->sc_dev.dv_xname, isr);
834:
835: if (isr & (ISR_TXDN | ISR_TXER | ISR_PINT))
836: sonictxint(sc);
837:
838: if (isr & ISR_PKTRX)
839: sonicrxint(sc);
840:
841: if (isr & (ISR_HBL | ISR_RDE | ISR_RBE | ISR_RBAE | ISR_RFO)) {
842: if (isr & ISR_HBL)
843: /*
844: * The repeater is not providing a heartbeat.
845: * In itself this isn't harmful, lots of the
846: * cheap repeater hubs don't supply a heartbeat.
847: * So ignore the lack of heartbeat. Its only
848: * if we can't detect a carrier that we have a
849: * problem.
850: */
851: ;
852: if (isr & ISR_RDE)
853: printf("%s: receive descriptors exhausted\n",
854: sc->sc_dev.dv_xname);
855: if (isr & ISR_RBE)
856: printf("%s: receive buffers exhausted\n",
857: sc->sc_dev.dv_xname);
858: if (isr & ISR_RBAE)
859: printf("%s: receive buffer area exhausted\n",
860: sc->sc_dev.dv_xname);
861: if (isr & ISR_RFO)
862: printf("%s: receive FIFO overrun\n",
863: sc->sc_dev.dv_xname);
864: }
865: if (isr & (ISR_CRC | ISR_FAE | ISR_MP)) {
866: #ifdef notdef
867: if (isr & ISR_CRC)
868: sc->sc_crctally++;
869: if (isr & ISR_FAE)
870: sc->sc_faetally++;
871: if (isr & ISR_MP)
872: sc->sc_mptally++;
873: #endif
874: }
875: snstart(&sc->sc_if);
876: }
877:
878: return (rv);
879: }
880:
881: /*
882: * Transmit interrupt routine
883: */
884: static void
885: sonictxint(struct sn_softc *sc)
886: {
887: struct mtd *mtd;
888: void *txp;
889: unsigned short txp_status;
890: int mtd_hw;
891: struct ifnet *ifp = &sc->sc_if;
892:
893: mtd_hw = sc->mtd_hw;
894:
895: if (mtd_hw == sc->mtd_free)
896: return;
897:
898: while (mtd_hw != sc->mtd_free) {
899: mtd = &sc->mtda[mtd_hw];
900:
901: txp = mtd->mtd_txp;
902:
903: if (SRO(sc->bitmode, txp, TXP_STATUS) == 0) {
904: break; /* it hasn't really gone yet */
905: }
906:
907: #ifdef SNDEBUG
908: {
909: struct ether_header *eh;
910:
911: eh = (struct ether_header *) mtd->mtd_buf;
912: printf("%s: xmit status=0x%x len=%d type=0x%x from %s",
913: sc->sc_dev.dv_xname,
914: SRO(sc->bitmode, txp, TXP_STATUS),
915: SRO(sc->bitmode, txp, TXP_PKTSIZE),
916: htons(eh->ether_type),
917: ether_sprintf(eh->ether_shost));
918: printf(" (to %s)\n", ether_sprintf(eh->ether_dhost));
919: }
920: #endif /* SNDEBUG */
921:
922: ifp->if_flags &= ~IFF_OACTIVE;
923:
924: if (mtd->mtd_mbuf != 0) {
925: m_freem(mtd->mtd_mbuf);
926: mtd->mtd_mbuf = 0;
927: }
928: if (++mtd_hw == NTDA) mtd_hw = 0;
929:
930: txp_status = SRO(sc->bitmode, txp, TXP_STATUS);
931:
932: ifp->if_collisions += (txp_status & TCR_EXC) ? 16 :
933: ((txp_status & TCR_NC) >> 12);
934:
935: if ((txp_status & TCR_PTX) == 0) {
936: ifp->if_oerrors++;
937:
938: /* XXX - DG This looks bogus */
939: if (mtd_hw != sc->mtd_free) {
940: mtd = &sc->mtda[mtd_hw];
941: NIC_PUT(sc, SNR_CTDA, LOWER(mtd->mtd_vtxp));
942: NIC_PUT(sc, SNR_CR, CR_TXP);
943: wbflush();
944: break;
945: }
946: }
947: }
948:
949: sc->mtd_hw = mtd_hw;
950: return;
951: }
952:
953: /*
954: * Receive interrupt routine
955: */
956: static void
957: sonicrxint(struct sn_softc *sc)
958: {
959: caddr_t rda;
960: int orra;
961: int len;
962: int rramark;
963: int rdamark;
964: int bitmode = sc->bitmode;
965: u_int16_t rxpkt_ptr;
966:
967: rda = sc->p_rda + (sc->sc_rxmark * RXPKT_SIZE(sc));
968:
969: while (SRO(bitmode, rda, RXPKT_INUSE) == 0) {
970: u_int status = SRO(bitmode, rda, RXPKT_STATUS);
971:
972: orra = RBASEQ(SRO(bitmode, rda, RXPKT_SEQNO)) & RRAMASK;
973: rxpkt_ptr = SRO(bitmode, rda, RXPKT_PTRLO);
974: len = SRO(bitmode, rda, RXPKT_BYTEC) - FCSSIZE;
975: if (status & RCR_PRX) {
976: caddr_t pkt = sc->rbuf[orra & RBAMASK] +
977: m68k_page_offset(rxpkt_ptr);
978: if (sonic_read(sc, pkt, len))
979: sc->sc_if.if_ipackets++;
980: else
981: sc->sc_if.if_ierrors++;
982: } else
983: sc->sc_if.if_ierrors++;
984:
985: /*
986: * give receive buffer area back to chip.
987: *
988: * If this was the last packet in the RRA, give the RRA to
989: * the chip again.
990: * If sonic read didnt copy it out then we would have to
991: * wait !!
992: * (dont bother add it back in again straight away)
993: *
994: * Really, we're doing p_rra[rramark] = p_rra[orra] but
995: * we have to use the macros because SONIC might be in
996: * 16 or 32 bit mode.
997: */
998: if (status & RCR_LPKT) {
999: void *tmp1, *tmp2;
1000:
1001: rramark = sc->sc_rramark;
1002: tmp1 = sc->p_rra[rramark];
1003: tmp2 = sc->p_rra[orra];
1004: SWO(bitmode, tmp1, RXRSRC_PTRLO,
1005: SRO(bitmode, tmp2, RXRSRC_PTRLO));
1006: SWO(bitmode, tmp1, RXRSRC_PTRHI,
1007: SRO(bitmode, tmp2, RXRSRC_PTRHI));
1008: SWO(bitmode, tmp1, RXRSRC_WCLO,
1009: SRO(bitmode, tmp2, RXRSRC_WCLO));
1010: SWO(bitmode, tmp1, RXRSRC_WCHI,
1011: SRO(bitmode, tmp2, RXRSRC_WCHI));
1012:
1013: /* zap old rra for fun */
1014: SWO(bitmode, tmp2, RXRSRC_WCHI, 0);
1015: SWO(bitmode, tmp2, RXRSRC_WCLO, 0);
1016:
1017: sc->sc_rramark = (++rramark) & RRAMASK;
1018: NIC_PUT(sc, SNR_RWP, LOWER(sc->v_rra[rramark]));
1019: wbflush();
1020: }
1021:
1022: /*
1023: * give receive descriptor back to chip simple
1024: * list is circular
1025: */
1026: rdamark = sc->sc_rdamark;
1027: SWO(bitmode, rda, RXPKT_INUSE, 1);
1028: SWO(bitmode, rda, RXPKT_RLINK,
1029: SRO(bitmode, rda, RXPKT_RLINK) | EOL);
1030: SWO(bitmode, (sc->p_rda + (rdamark * RXPKT_SIZE(sc))), RXPKT_RLINK,
1031: SRO(bitmode, (sc->p_rda + (rdamark * RXPKT_SIZE(sc))),
1032: RXPKT_RLINK) & ~EOL);
1033: sc->sc_rdamark = sc->sc_rxmark;
1034:
1035: if (++sc->sc_rxmark >= sc->sc_nrda)
1036: sc->sc_rxmark = 0;
1037: rda = sc->p_rda + (sc->sc_rxmark * RXPKT_SIZE(sc));
1038: }
1039: }
1040:
1041: /*
1042: * sonic_read -- pull packet off interface and forward to
1043: * appropriate protocol handler
1044: */
1045: static __inline__ int
1046: sonic_read(struct sn_softc *sc, caddr_t pkt, int len)
1047: {
1048: struct ifnet *ifp = &sc->sc_if;
1049: #ifdef SNDEBUG
1050: struct ether_header *et;
1051: #endif
1052: struct mbuf *m;
1053:
1054: #ifdef SNDEBUG
1055: /*
1056: * Get pointer to ethernet header (in input buffer).
1057: */
1058: et = (struct ether_header *)pkt;
1059:
1060: printf("%s: rcvd %p len=%d type=0x%x from %s",
1061: sc->sc_dev.dv_xname, et, len, htons(et->ether_type),
1062: ether_sprintf(et->ether_shost));
1063: printf(" (to %s)\n", ether_sprintf(et->ether_dhost));
1064: #endif /* SNDEBUG */
1065:
1066: if (len < (ETHER_MIN_LEN - ETHER_CRC_LEN) ||
1067: len > (ETHER_MAX_LEN - ETHER_CRC_LEN)) {
1068: printf("%s: invalid packet length %d bytes\n",
1069: sc->sc_dev.dv_xname, len);
1070: return (0);
1071: }
1072:
1073: m = sonic_get(sc, pkt, len);
1074: if (m == NULL)
1075: return (0);
1076: #if NBPFILTER > 0
1077: /* Pass this up to any BPF listeners. */
1078: if (ifp->if_bpf)
1079: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1080: #endif
1081: ether_input_mbuf(ifp, m);
1082: return (1);
1083: }
1084:
1085: /*
1086: * munge the received packet into an mbuf chain
1087: */
1088: static __inline__ struct mbuf *
1089: sonic_get(struct sn_softc *sc, caddr_t pkt, int datalen)
1090: {
1091: struct mbuf *m, *top, **mp;
1092: int len;
1093:
1094: MGETHDR(m, M_DONTWAIT, MT_DATA);
1095: if (m == NULL)
1096: return (NULL);
1097:
1098: m->m_pkthdr.rcvif = &sc->sc_if;
1099: m->m_pkthdr.len = datalen;
1100: len = MHLEN;
1101: top = 0;
1102: mp = ⊤
1103:
1104: while (datalen > 0) {
1105: if (top) {
1106: MGET(m, M_DONTWAIT, MT_DATA);
1107: if (m == NULL) {
1108: m_freem(top);
1109: return (NULL);
1110: }
1111: len = MLEN;
1112: }
1113: if (datalen >= MINCLSIZE) {
1114: MCLGET(m, M_DONTWAIT);
1115: if ((m->m_flags & M_EXT) == 0) {
1116: if (top)
1117: m_freem(top);
1118: return (NULL);
1119: }
1120: len = MCLBYTES;
1121: }
1122: m->m_len = len = min(datalen, len);
1123:
1124: bcopy(pkt, mtod(m, caddr_t), (unsigned) len);
1125: pkt += len;
1126: datalen -= len;
1127: *mp = m;
1128: mp = &m->m_next;
1129: }
1130:
1131: return (top);
1132: }
1133:
1134: static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
1135: #define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
1136:
1137: void
1138: sn_get_enaddr(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
1139: u_char *dst)
1140: {
1141: int i, do_bbr;
1142: u_char b;
1143:
1144: /*
1145: * For reasons known only to Apple, MAC addresses in the ethernet
1146: * PROM are stored in Token Ring (IEEE 802.5) format, that is
1147: * with all of the bits in each byte reversed (canonical bit format).
1148: * When the address is read out it must be reversed to ethernet format
1149: * before use.
1150: *
1151: * Apple has been assigned OUI's 08:00:07 and 00:a0:40. All onboard
1152: * ethernet addresses on 68K machines should be in one of these
1153: * two ranges.
1154: *
1155: * Here is where it gets complicated.
1156: *
1157: * The PMac 7200, 7500, 8500, and 9500 accidentally had the PROM
1158: * written in standard ethernet format. The MacOS accounted for this
1159: * in these systems, and did not reverse the bytes. Some other
1160: * networking utilities were not so forgiving, and got confused.
1161: * "Some" of Apple's Nubus ethernet cards also had their bits
1162: * burned in ethernet format.
1163: *
1164: * Apple petitioned the IEEE and was granted the 00:05:02 (bit reversal
1165: * of 00:a0:40) as well. As of OpenTransport 1.1.1, Apple removed
1166: * their workaround and now reverses the bits regardless of
1167: * what kind of machine it is. So PMac systems and the affected
1168: * Nubus cards now use 00:05:02, instead of the 00:a0:40 for which they
1169: * were intended.
1170: *
1171: * See Apple Techinfo article TECHINFO-0020552, "OpenTransport 1.1.1
1172: * and MacOS System 7.5.3 FAQ (10/96)" for more details.
1173: */
1174: do_bbr = 0;
1175: b = bus_space_read_1(t, h, o);
1176: if (b == 0x10)
1177: do_bbr = 1;
1178: dst[0] = (do_bbr) ? bbr(b) : b;
1179:
1180: for (i = 1 ; i < ETHER_ADDR_LEN ; i++) {
1181: b = bus_space_read_1(t, h, o+i);
1182: dst[i] = (do_bbr) ? bbr(b) : b;
1183: }
1184: }
CVSweb