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