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