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