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