xref: /netbsd-src/sys/dev/bi/if_ni.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: if_ni.c,v 1.41 2013/10/25 15:11:32 martin Exp $ */
2 /*
3  * Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed at Ludd, University of
16  *	Lule}, Sweden and its contributors.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Driver for DEBNA/DEBNT/DEBNK ethernet cards.
34  * Things that is still to do:
35  *	Collect statistics.
36  */
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: if_ni.c,v 1.41 2013/10/25 15:11:32 martin Exp $");
40 
41 #include "opt_inet.h"
42 
43 #include <sys/param.h>
44 #include <sys/mbuf.h>
45 #include <sys/socket.h>
46 #include <sys/device.h>
47 #include <sys/systm.h>
48 #include <sys/sockio.h>
49 #include <sys/sched.h>
50 
51 #include <net/if.h>
52 #include <net/if_ether.h>
53 #include <net/if_dl.h>
54 
55 #include <netinet/in.h>
56 #include <netinet/if_inarp.h>
57 
58 #include <net/bpf.h>
59 #include <net/bpfdesc.h>
60 
61 #include <sys/bus.h>
62 #ifdef __vax__
63 #include <machine/mtpr.h>
64 #include <machine/pte.h>
65 #endif
66 
67 #include <dev/bi/bireg.h>
68 #include <dev/bi/bivar.h>
69 
70 #include "ioconf.h"
71 #include "locators.h"
72 
73 /*
74  * Tunable buffer parameters. Good idea to have them as power of 8; then
75  * they will fit into a logical VAX page.
76  */
77 #define NMSGBUF		8	/* Message queue entries */
78 #define NTXBUF		16	/* Transmit queue entries */
79 #define NTXFRAGS	8	/* Number of transmit buffer fragments */
80 #define NRXBUF		24	/* Receive queue entries */
81 #define NBDESCS		(NTXBUF * NTXFRAGS + NRXBUF)
82 #define NQUEUES		3	/* RX + TX + MSG */
83 #define PKTHDR		18	/* Length of (control) packet header */
84 #define RXADD		18	/* Additional length of receive datagram */
85 #define TXADD		(10+NTXFRAGS*8) /*	""	transmit   ""	 */
86 #define MSGADD		134	/*		""	message	   ""	 */
87 
88 #include <dev/bi/if_nireg.h>	/* XXX include earlier */
89 
90 /*
91  * Macros for (most cases of) insqti/remqhi.
92  * Retry NRETRIES times to do the operation, if it still fails assume
93  * a lost lock and panic.
94  */
95 #define	NRETRIES	100
96 #define	INSQTI(e, h)	({						\
97 	int ret = 0, __i;						\
98 	for (__i = 0; __i < NRETRIES; __i++) {				\
99 		if ((ret = insqti(e, h)) != ILCK_FAILED)		\
100 			break;						\
101 	}								\
102 	if (__i == NRETRIES)						\
103 		panic("ni: insqti failed at %d", __LINE__);		\
104 	ret;								\
105 })
106 #define	REMQHI(h)	({						\
107 	int __i; void *ret = NULL;					\
108 	for (__i = 0; __i < NRETRIES; __i++) {				\
109 		if ((ret = remqhi(h)) != (void *)ILCK_FAILED)		\
110 			break;						\
111 	}								\
112 	if (__i == NRETRIES)						\
113 		panic("ni: remqhi failed at %d", __LINE__);		\
114 	ret;								\
115 })
116 
117 
118 #define nipqb	(&sc->sc_gvppqb->nc_pqb)
119 #define gvp	sc->sc_gvppqb
120 #define fqb	sc->sc_fqb
121 #define bbd	sc->sc_bbd
122 
123 struct	ni_softc {
124 	device_t 	sc_dev;		/* Configuration common part	*/
125 	struct evcnt	sc_intrcnt;	/* Interrupt coounting		*/
126 	struct ethercom sc_ec;		/* Ethernet common part		*/
127 #define sc_if	sc_ec.ec_if		/* network-visible interface	*/
128 	bus_space_tag_t sc_iot;
129 	bus_addr_t	sc_ioh;
130 	bus_dma_tag_t	sc_dmat;
131 	struct ni_gvppqb *sc_gvppqb;	/* Port queue block		*/
132 	struct ni_gvppqb *sc_pgvppqb;	/* Phys address of PQB		*/
133 	struct ni_fqb	*sc_fqb;	/* Free Queue block		*/
134 	struct ni_bbd	*sc_bbd;	/* Buffer descriptors		*/
135 	u_int8_t	sc_enaddr[ETHER_ADDR_LEN];
136 };
137 
138 static	int	nimatch(device_t, cfdata_t, void *);
139 static	void	niattach(device_t, device_t, void *);
140 static	void	niinit(struct ni_softc *);
141 static	void	nistart(struct ifnet *);
142 static	void	niintr(void *);
143 static	int	niioctl(struct ifnet *, u_long, void *);
144 static	int	ni_add_rxbuf(struct ni_softc *, struct ni_dg *, int);
145 static	void	ni_setup(struct ni_softc *);
146 static	void	nitimeout(struct ifnet *);
147 static	void	ni_shutdown(void *);
148 static	void ni_getpgs(struct ni_softc *sc, int size, void **v, paddr_t *p);
149 static	int failtest(struct ni_softc *, int, int, int, const char *);
150 
151 volatile int endwait, retry;	/* Used during autoconfig */
152 
153 CFATTACH_DECL_NEW(ni, sizeof(struct ni_softc),
154     nimatch, niattach, NULL, NULL);
155 
156 #define NI_WREG(csr, val) \
157 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, csr, val)
158 #define NI_RREG(csr) \
159 	bus_space_read_4(sc->sc_iot, sc->sc_ioh, csr)
160 
161 #define WAITREG(csr,val) while (NI_RREG(csr) & val);
162 /*
163  * Check for present device.
164  */
165 static int
166 nimatch(device_t parent, cfdata_t cf, void *aux)
167 {
168 	struct bi_attach_args *ba = aux;
169 	u_short type;
170 
171 	type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE);
172 	if (type != BIDT_DEBNA && type != BIDT_DEBNT && type != BIDT_DEBNK)
173 		return 0;
174 
175 	if (cf->cf_loc[BICF_NODE] != BICF_NODE_DEFAULT &&
176 	    cf->cf_loc[BICF_NODE] != ba->ba_nodenr)
177 		return 0;
178 
179 	return 1;
180 }
181 
182 /*
183  * Allocate a bunch of descriptor-safe memory.
184  * We need to get the structures from the beginning of its own pages.
185  */
186 static void
187 ni_getpgs(struct ni_softc *sc, int size, void **v, paddr_t *p)
188 {
189 	bus_dma_segment_t seg;
190 	int nsegs, error;
191 
192 	if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1,
193 	    &nsegs, BUS_DMA_NOWAIT)) != 0)
194 		panic(" unable to allocate memory: error %d", error);
195 
196 	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, nsegs, size, v,
197 	    BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0)
198 		panic(" unable to map memory: error %d", error);
199 
200 	if (p)
201 		*p = seg.ds_addr;
202 	memset(*v, 0, size);
203 }
204 
205 static int
206 failtest(struct ni_softc *sc, int reg, int mask, int test, const char *str)
207 {
208 	int i = 100;
209 
210 	do {
211 		DELAY(100000);
212 	} while (((NI_RREG(reg) & mask) != test) && --i);
213 
214 	if (i == 0) {
215 		printf("%s: %s\n", device_xname(sc->sc_dev), str);
216 		return 1;
217 	}
218 	return 0;
219 }
220 
221 
222 /*
223  * Interface exists: make available by filling in network interface
224  * record.  System will initialize the interface when it is ready
225  * to accept packets.
226  */
227 static void
228 niattach(device_t parent, device_t self, void *aux)
229 {
230 	struct bi_attach_args *ba = aux;
231 	struct ni_softc *sc = device_private(self);
232 	struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
233 	struct ni_msg *msg;
234 	struct ni_ptdb *ptdb;
235 	void *va;
236 	int i, j, s;
237 	u_short type;
238 
239 	sc->sc_dev = self;
240 
241 	type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE);
242 	printf(": DEBN%c\n", type == BIDT_DEBNA ? 'A' : type == BIDT_DEBNT ?
243 	    'T' : 'K');
244 	sc->sc_iot = ba->ba_iot;
245 	sc->sc_ioh = ba->ba_ioh;
246 	sc->sc_dmat = ba->ba_dmat;
247 
248 	bi_intr_establish(ba->ba_icookie, ba->ba_ivec,
249 		niintr, sc, &sc->sc_intrcnt);
250 	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
251 		device_xname(self), "intr");
252 
253 	ni_getpgs(sc, sizeof(struct ni_gvppqb), (void **)&sc->sc_gvppqb,
254 	    (paddr_t *)&sc->sc_pgvppqb);
255 	ni_getpgs(sc, sizeof(struct ni_fqb), (void **)&sc->sc_fqb, 0);
256 	ni_getpgs(sc, NBDESCS * sizeof(struct ni_bbd),
257 	    (void **)&sc->sc_bbd, 0);
258 	/*
259 	 * Zero the newly allocated memory.
260 	 */
261 
262 	nipqb->np_veclvl = (ba->ba_ivec << 2) + 2;
263 	nipqb->np_node = ba->ba_intcpu;
264 	nipqb->np_vpqb = (u_int32_t)gvp;
265 #ifdef __vax__
266 	nipqb->np_spt = nipqb->np_gpt = mfpr(PR_SBR);
267 	nipqb->np_sptlen = nipqb->np_gptlen = mfpr(PR_SLR);
268 #else
269 #error Must fix support for non-vax.
270 #endif
271 	nipqb->np_bvplvl = 1;
272 	nipqb->np_vfqb = (u_int32_t)fqb;
273 	nipqb->np_vbdt = (u_int32_t)bbd;
274 	nipqb->np_nbdr = NBDESCS;
275 
276 	/* Free queue block */
277 	nipqb->np_freeq = NQUEUES;
278 	fqb->nf_mlen = PKTHDR+MSGADD;
279 	fqb->nf_dlen = PKTHDR+TXADD;
280 	fqb->nf_rlen = PKTHDR+RXADD;
281 
282 	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
283 	ifp->if_softc = sc;
284 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
285 	ifp->if_start = nistart;
286 	ifp->if_ioctl = niioctl;
287 	ifp->if_watchdog = nitimeout;
288 	IFQ_SET_READY(&ifp->if_snd);
289 
290 	/*
291 	 * Start init sequence.
292 	 */
293 
294 	/* Reset the node */
295 	NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
296 	DELAY(500000);
297 	i = 20;
298 	while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
299 		DELAY(500000);
300 	if (i == 0) {
301 		printf("%s: BROKE bit set after reset\n", device_xname(self));
302 		return;
303 	}
304 
305 	/* Check state */
306 	if (failtest(sc, NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
307 		return;
308 
309 	/* Clear owner bits */
310 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
311 	NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);
312 
313 	/* kick off init */
314 	NI_WREG(NI_PCR, (u_int32_t)sc->sc_pgvppqb | PCR_INIT | PCR_OWN);
315 	while (NI_RREG(NI_PCR) & PCR_OWN)
316 		DELAY(100000);
317 
318 	/* Check state */
319 	if (failtest(sc, NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
320 		return;
321 
322 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
323 
324 	WAITREG(NI_PCR, PCR_OWN);
325 	NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE);
326 	WAITREG(NI_PCR, PCR_OWN);
327 	WAITREG(NI_PSR, PSR_OWN);
328 
329 	/* Check state */
330 	if (failtest(sc, NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
331 		return;
332 
333 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
334 
335 	/*
336 	 * The message queue packets must be located on the beginning
337 	 * of a page. A VAX page is 512 bytes, but it clusters 8 pages.
338 	 * This knowledge is used here when allocating pages.
339 	 * !!! How should this be done on MIPS and Alpha??? !!!
340 	 */
341 #if NBPG < 4096
342 #error pagesize too small
343 #endif
344 	s = splvm();
345 	/* Set up message free queue */
346 	ni_getpgs(sc, NMSGBUF * 512, &va, 0);
347 	for (i = 0; i < NMSGBUF; i++) {
348 		msg = (void *)((char *)va + i * 512);
349 		INSQTI(msg, &fqb->nf_mforw);
350 	}
351 	WAITREG(NI_PCR, PCR_OWN);
352 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
353 	WAITREG(NI_PCR, PCR_OWN);
354 
355 	/* Set up xmit queue */
356 	ni_getpgs(sc, NTXBUF * 512, &va, 0);
357 	for (i = 0; i < NTXBUF; i++) {
358 		struct ni_dg *data;
359 
360 		data = (void *)((char *)va + i * 512);
361 		data->nd_status = 0;
362 		data->nd_len = TXADD;
363 		data->nd_ptdbidx = 1;
364 		data->nd_opcode = BVP_DGRAM;
365 		for (j = 0; j < NTXFRAGS; j++) {
366 			data->bufs[j]._offset = 0;
367 			data->bufs[j]._key = 1;
368 			bbd[i * NTXFRAGS + j].nb_key = 1;
369 			bbd[i * NTXFRAGS + j].nb_status = 0;
370 			data->bufs[j]._index = i * NTXFRAGS + j;
371 		}
372 		INSQTI(data, &fqb->nf_dforw);
373 	}
374 	WAITREG(NI_PCR, PCR_OWN);
375 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
376 	WAITREG(NI_PCR, PCR_OWN);
377 
378 	/* recv buffers */
379 	ni_getpgs(sc, NRXBUF * 512, &va, 0);
380 	for (i = 0; i < NRXBUF; i++) {
381 		struct ni_dg *data;
382 		int idx;
383 
384 		data = (void *)((char *)va + i * 512);
385 		data->nd_len = RXADD;
386 		data->nd_opcode = BVP_DGRAMRX;
387 		data->nd_ptdbidx = 2;
388 		data->bufs[0]._key = 1;
389 
390 		idx = NTXBUF * NTXFRAGS + i;
391 		if (ni_add_rxbuf(sc, data, idx))
392 			panic("niattach: ni_add_rxbuf: out of mbufs");
393 
394 		INSQTI(data, &fqb->nf_rforw);
395 	}
396 	WAITREG(NI_PCR, PCR_OWN);
397 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
398 	WAITREG(NI_PCR, PCR_OWN);
399 
400 	splx(s);
401 
402 	/* Set initial parameters */
403 	msg = REMQHI(&fqb->nf_mforw);
404 
405 	msg->nm_opcode = BVP_MSG;
406 	msg->nm_status = 0;
407 	msg->nm_len = sizeof(struct ni_param) + 6;
408 	msg->nm_opcode2 = NI_WPARAM;
409 	((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD;
410 
411 	endwait = retry = 0;
412 	INSQTI(msg, &gvp->nc_forw0);
413 
414 retry:	WAITREG(NI_PCR, PCR_OWN);
415 	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
416 	WAITREG(NI_PCR, PCR_OWN);
417 	i = 1000;
418 	while (endwait == 0 && --i)
419 		DELAY(10000);
420 
421 	if (endwait == 0) {
422 		if (++retry < 3)
423 			goto retry;
424 		printf("%s: no response to set params\n", device_xname(self));
425 		return;
426 	}
427 
428 	/* Clear counters */
429 	msg = REMQHI(&fqb->nf_mforw);
430 	msg->nm_opcode = BVP_MSG;
431 	msg->nm_status = 0;
432 	msg->nm_len = sizeof(struct ni_param) + 6;
433 	msg->nm_opcode2 = NI_RCCNTR;
434 
435 	INSQTI(msg, &gvp->nc_forw0);
436 
437 	WAITREG(NI_PCR, PCR_OWN);
438 	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
439 	WAITREG(NI_PCR, PCR_OWN);
440 
441 	/* Enable transmit logic */
442 	msg = REMQHI(&fqb->nf_mforw);
443 
444 	msg->nm_opcode = BVP_MSG;
445 	msg->nm_status = 0;
446 	msg->nm_len = 18;
447 	msg->nm_opcode2 = NI_STPTDB;
448 	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
449 	memset(ptdb, 0, sizeof(struct ni_ptdb));
450 	ptdb->np_index = 1;
451 	ptdb->np_fque = 1;
452 
453 	INSQTI(msg, &gvp->nc_forw0);
454 
455 	WAITREG(NI_PCR, PCR_OWN);
456 	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
457 	WAITREG(NI_PCR, PCR_OWN);
458 
459 	/* Wait for everything to finish */
460 	WAITREG(NI_PSR, PSR_OWN);
461 
462 	printf("%s: hardware address %s\n", device_xname(self),
463 	    ether_sprintf(sc->sc_enaddr));
464 
465 	/*
466 	 * Attach the interface.
467 	 */
468 	if_attach(ifp);
469 	ether_ifattach(ifp, sc->sc_enaddr);
470 	if (shutdownhook_establish(ni_shutdown, sc) == 0)
471 		aprint_error_dev(self, "WARNING: unable to establish shutdown hook\n");
472 }
473 
474 /*
475  * Initialization of interface.
476  */
477 void
478 niinit(struct ni_softc *sc)
479 {
480 	struct ifnet *ifp = &sc->sc_if;
481 
482 	/*
483 	 * Set flags (so ni_setup() do the right thing).
484 	 */
485 	ifp->if_flags |= IFF_RUNNING;
486 	ifp->if_flags &= ~IFF_OACTIVE;
487 
488 	/*
489 	 * Send setup messages so that the rx/tx locic starts.
490 	 */
491 	ni_setup(sc);
492 
493 }
494 
495 /*
496  * Start output on interface.
497  */
498 void
499 nistart(struct ifnet *ifp)
500 {
501 	struct ni_softc *sc = ifp->if_softc;
502 	struct ni_dg *data;
503 	struct ni_bbd *bdp;
504 	struct mbuf *m, *m0;
505 	int i, cnt, res, mlen;
506 
507 	if (ifp->if_flags & IFF_OACTIVE)
508 		return;
509 #ifdef DEBUG
510 	if (ifp->if_flags & IFF_DEBUG)
511 		printf("%s: nistart\n", device_xname(sc->sc_dev));
512 #endif
513 
514 	while (fqb->nf_dforw) {
515 		IFQ_POLL(&ifp->if_snd, m);
516 		if (m == 0)
517 			break;
518 
519 		data = REMQHI(&fqb->nf_dforw);
520 		if ((int)data == Q_EMPTY) {
521 			ifp->if_flags |= IFF_OACTIVE;
522 			break;
523 		}
524 
525 		IFQ_DEQUEUE(&ifp->if_snd, m);
526 
527 		/*
528 		 * Count number of mbufs in chain.
529 		 * Always do DMA directly from mbufs, therefore the transmit
530 		 * ring is really big.
531 		 */
532 		for (m0 = m, cnt = 0; m0; m0 = m0->m_next)
533 			if (m0->m_len)
534 				cnt++;
535 		if (cnt > NTXFRAGS)
536 			panic("nistart"); /* XXX */
537 
538 		bpf_mtap(ifp, m);
539 		bdp = &bbd[(data->bufs[0]._index & 0x7fff)];
540 		for (m0 = m, i = 0, mlen = 0; m0; m0 = m0->m_next) {
541 			if (m0->m_len == 0)
542 				continue;
543 			bdp->nb_status = (mtod(m0, u_int32_t) & NIBD_OFFSET) |
544 			    NIBD_VALID;
545 			bdp->nb_pte = (u_int32_t)kvtopte(mtod(m0, void *));
546 			bdp->nb_len = m0->m_len;
547 			data->bufs[i]._offset = 0;
548 			data->bufs[i]._len = bdp->nb_len;
549 			data->bufs[i]._index |= NIDG_CHAIN;
550 			mlen += bdp->nb_len;
551 			bdp++;
552 			i++;
553 		}
554 		data->nd_opcode = BVP_DGRAM;
555 		data->nd_pad3 = 1;
556 		data->nd_ptdbidx = 1;
557 		data->nd_len = 10 + i * 8;
558 		data->bufs[i - 1]._index &= ~NIDG_CHAIN;
559 		data->nd_cmdref = (u_int32_t)m;
560 #ifdef DEBUG
561 		if (ifp->if_flags & IFF_DEBUG)
562 			printf("%s: sending %d bytes (%d segments)\n",
563 			    device_xname(sc->sc_dev), mlen, i);
564 #endif
565 
566 		res = INSQTI(data, &gvp->nc_forw0);
567 		if (res == Q_EMPTY) {
568 			WAITREG(NI_PCR, PCR_OWN);
569 			NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
570 		}
571 	}
572 }
573 
574 void
575 niintr(void *arg)
576 {
577 	struct ni_softc *sc = arg;
578 	struct ni_dg *data;
579 	struct ni_msg *msg;
580 	struct ifnet *ifp = &sc->sc_if;
581 	struct ni_bbd *bd;
582 	struct mbuf *m;
583 	int idx, res;
584 
585 	if ((NI_RREG(NI_PSR) & PSR_STATE) != PSR_ENABLED)
586 		return;
587 
588 	if ((NI_RREG(NI_PSR) & PSR_ERR))
589 		printf("%s: PSR %x\n", device_xname(sc->sc_dev), NI_RREG(NI_PSR));
590 
591 	KERNEL_LOCK(1, NULL);
592 	/* Got any response packets?  */
593 	while ((NI_RREG(NI_PSR) & PSR_RSQ) && (data = REMQHI(&gvp->nc_forwr))) {
594 
595 		switch (data->nd_opcode) {
596 		case BVP_DGRAMRX: /* Receive datagram */
597 			idx = data->bufs[0]._index;
598 			bd = &bbd[idx];
599 			m = (void *)data->nd_cmdref;
600 			m->m_pkthdr.len = m->m_len =
601 			    data->bufs[0]._len - ETHER_CRC_LEN;
602 			m->m_pkthdr.rcvif = ifp;
603 			if (ni_add_rxbuf(sc, data, idx)) {
604 				bd->nb_len = (m->m_ext.ext_size - 2);
605 				bd->nb_pte =
606 				    (long)kvtopte(m->m_ext.ext_buf);
607 				bd->nb_status = 2 | NIBD_VALID;
608 				bd->nb_key = 1;
609 			}
610 			data->nd_len = RXADD;
611 			data->nd_status = 0;
612 			res = INSQTI(data, &fqb->nf_rforw);
613 			if (res == Q_EMPTY) {
614 				WAITREG(NI_PCR, PCR_OWN);
615 				NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
616 			}
617 			if (m == (void *)data->nd_cmdref)
618 				break; /* Out of mbufs */
619 
620 			bpf_mtap(ifp, m);
621 			(*ifp->if_input)(ifp, m);
622 			break;
623 
624 		case BVP_DGRAM:
625 			m = (struct mbuf *)data->nd_cmdref;
626 			ifp->if_flags &= ~IFF_OACTIVE;
627 			m_freem(m);
628 			res = INSQTI(data, &fqb->nf_dforw);
629 			if (res == Q_EMPTY) {
630 				WAITREG(NI_PCR, PCR_OWN);
631 				NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
632 			}
633 			break;
634 
635 		case BVP_MSGRX:
636 			msg = (struct ni_msg *)data;
637 			switch (msg->nm_opcode2) {
638 				case NI_WPARAM:
639 					memcpy(sc->sc_enaddr, ((struct ni_param *)&msg->nm_text[0])->np_dpa, ETHER_ADDR_LEN);
640 					endwait = 1;
641 					break;
642 
643 				case NI_RCCNTR:
644 				case NI_CLPTDB:
645 				case NI_STPTDB:
646 					break;
647 
648 				default:
649 					printf("Unkn resp %d\n",
650 					    msg->nm_opcode2);
651 					break;
652 			}
653 			res = INSQTI(data, &fqb->nf_mforw);
654 			if (res == Q_EMPTY) {
655 				WAITREG(NI_PCR, PCR_OWN);
656 				NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
657 			}
658 			break;
659 
660 		default:
661 			printf("Unknown opcode %d\n", data->nd_opcode);
662 			res = INSQTI(data, &fqb->nf_mforw);
663 			if (res == Q_EMPTY) {
664 				WAITREG(NI_PCR, PCR_OWN);
665 				NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
666 			}
667 		}
668 	}
669 
670 	/* Try to kick on the start routine again */
671 	nistart(ifp);
672 
673 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ));
674 	KERNEL_UNLOCK_ONE(NULL);
675 }
676 
677 /*
678  * Process an ioctl request.
679  */
680 int
681 niioctl(struct ifnet *ifp, u_long cmd, void *data)
682 {
683 	struct ni_softc *sc = ifp->if_softc;
684 	struct ifaddr *ifa = (struct ifaddr *)data;
685 	int s = splnet(), error = 0;
686 
687 	switch (cmd) {
688 
689 	case SIOCINITIFADDR:
690 		ifp->if_flags |= IFF_UP;
691 		switch(ifa->ifa_addr->sa_family) {
692 #ifdef INET
693 		case AF_INET:
694 			niinit(sc);
695 			arp_ifinit(ifp, ifa);
696 			break;
697 #endif
698 		}
699 		break;
700 
701 	case SIOCSIFFLAGS:
702 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
703 			break;
704 		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
705 		case IFF_RUNNING:
706 			/*
707 			 * If interface is marked down and it is running,
708 			 * stop it.
709 			 */
710 			ifp->if_flags &= ~IFF_RUNNING;
711 			ni_setup(sc);
712 			break;
713 		case IFF_UP:
714 			/*
715 			 * If interface it marked up and it is stopped, then
716 			 * start it.
717 			 */
718 			niinit(sc);
719 			break;
720 		case IFF_UP|IFF_RUNNING:
721 			/*
722 			 * Send a new setup packet to match any new changes.
723 			 * (Like IFF_PROMISC etc)
724 			 */
725 			ni_setup(sc);
726 			break;
727 		default:
728 			break;
729 		}
730 		break;
731 
732 	case SIOCADDMULTI:
733 	case SIOCDELMULTI:
734 		/*
735 		 * Update our multicast list.
736 		 */
737 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
738 			/*
739 			 * Multicast list has changed; set the hardware filter
740 			 * accordingly.
741 			 */
742 			if (ifp->if_flags & IFF_RUNNING)
743 				ni_setup(sc);
744 			error = 0;
745 		}
746 		break;
747 
748 	default:
749 		error = ether_ioctl(ifp, cmd, data);
750 		break;
751 	}
752 	splx(s);
753 	return (error);
754 }
755 
756 /*
757  * Add a receive buffer to the indicated descriptor.
758  */
759 int
760 ni_add_rxbuf(struct ni_softc *sc, struct ni_dg *data, int idx)
761 {
762 	struct ni_bbd *bd = &bbd[idx];
763 	struct mbuf *m;
764 
765 	MGETHDR(m, M_DONTWAIT, MT_DATA);
766 	if (m == NULL)
767 		return (ENOBUFS);
768 
769 	MCLGET(m, M_DONTWAIT);
770 	if ((m->m_flags & M_EXT) == 0) {
771 		m_freem(m);
772 		return (ENOBUFS);
773 	}
774 
775 	m->m_data += 2;
776 	bd->nb_len = (m->m_ext.ext_size - 2);
777 	bd->nb_pte = (long)kvtopte(m->m_ext.ext_buf);
778 	bd->nb_status = 2 | NIBD_VALID;
779 	bd->nb_key = 1;
780 
781 	data->bufs[0]._offset = 0;
782 	data->bufs[0]._len = bd->nb_len;
783 	data->bufs[0]._index = idx;
784 	data->nd_cmdref = (long)m;
785 
786 	return (0);
787 }
788 
789 /*
790  * Create setup packet and put in queue for sending.
791  */
792 void
793 ni_setup(struct ni_softc *sc)
794 {
795 	struct ifnet *ifp = &sc->sc_if;
796 	struct ni_msg *msg;
797 	struct ni_ptdb *ptdb;
798 	struct ether_multi *enm;
799 	struct ether_multistep step;
800 	int i, res;
801 
802 	msg = REMQHI(&fqb->nf_mforw);
803 	if ((int)msg == Q_EMPTY)
804 		return; /* What to do? */
805 
806 	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
807 	memset(ptdb, 0, sizeof(struct ni_ptdb));
808 
809 	msg->nm_opcode = BVP_MSG;
810 	msg->nm_len = 18;
811 	ptdb->np_index = 2; /* definition type index */
812 	ptdb->np_fque = 2; /* Free queue */
813 	if (ifp->if_flags & IFF_RUNNING) {
814 		msg->nm_opcode2 = NI_STPTDB;
815 		ptdb->np_type = ETHERTYPE_IP;
816 		ptdb->np_flags = PTDB_UNKN|PTDB_BDC;
817 		if (ifp->if_flags & IFF_PROMISC)
818 			ptdb->np_flags |= PTDB_PROMISC;
819 		memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN); /* Broadcast */
820 		ptdb->np_adrlen = 1;
821 		msg->nm_len += 8;
822 		ifp->if_flags &= ~IFF_ALLMULTI;
823 		if ((ifp->if_flags & IFF_PROMISC) == 0) {
824 			ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
825 			i = 1;
826 			while (enm != NULL) {
827 				if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6)) {
828 					ifp->if_flags |= IFF_ALLMULTI;
829 					ptdb->np_flags |= PTDB_AMC;
830 					break;
831 				}
832 				msg->nm_len += 8;
833 				ptdb->np_adrlen++;
834 				memcpy(ptdb->np_mcast[i++], enm->enm_addrlo,
835 				    ETHER_ADDR_LEN);
836 				ETHER_NEXT_MULTI(step, enm);
837 			}
838 		}
839 	} else
840 		msg->nm_opcode2 = NI_CLPTDB;
841 
842 	res = INSQTI(msg, &gvp->nc_forw0);
843 	if (res == Q_EMPTY) {
844 		WAITREG(NI_PCR, PCR_OWN);
845 		NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
846 	}
847 }
848 
849 /*
850  * Check for dead transmit logic. Not uncommon.
851  */
852 void
853 nitimeout(struct ifnet *ifp)
854 {
855 #if 0
856 	struct ni_softc *sc = ifp->if_softc;
857 
858 	if (sc->sc_inq == 0)
859 		return;
860 
861 	printf("%s: xmit logic died, resetting...\n", device_xname(sc->sc_dev));
862 	/*
863 	 * Do a reset of interface, to get it going again.
864 	 * Will it work by just restart the transmit logic?
865 	 */
866 	niinit(sc);
867 #endif
868 }
869 
870 /*
871  * Shutdown hook.  Make sure the interface is stopped at reboot.
872  */
873 void
874 ni_shutdown(void *arg)
875 {
876 	struct ni_softc *sc = arg;
877 
878         WAITREG(NI_PCR, PCR_OWN);
879         NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN);
880         WAITREG(NI_PCR, PCR_OWN);
881         WAITREG(NI_PSR, PSR_OWN);
882 }
883