xref: /netbsd/sys/arch/vax/boot/boot/if_ni.c (revision 2d5d8524)
1*2d5d8524Sragge /*	$NetBSD: if_ni.c,v 1.11 2017/05/22 16:59:32 ragge Exp $ */
253cc7ebeSragge /*
353cc7ebeSragge  * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
453cc7ebeSragge  * All rights reserved.
553cc7ebeSragge  *
653cc7ebeSragge  * Redistribution and use in source and binary forms, with or without
753cc7ebeSragge  * modification, are permitted provided that the following conditions
853cc7ebeSragge  * are met:
953cc7ebeSragge  * 1. Redistributions of source code must retain the above copyright
1053cc7ebeSragge  *    notice, this list of conditions and the following disclaimer.
1153cc7ebeSragge  * 2. Redistributions in binary form must reproduce the above copyright
1253cc7ebeSragge  *    notice, this list of conditions and the following disclaimer in the
1353cc7ebeSragge  *    documentation and/or other materials provided with the distribution.
1453cc7ebeSragge  *
1553cc7ebeSragge  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1653cc7ebeSragge  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1753cc7ebeSragge  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1853cc7ebeSragge  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1953cc7ebeSragge  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2053cc7ebeSragge  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2153cc7ebeSragge  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2253cc7ebeSragge  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2353cc7ebeSragge  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2453cc7ebeSragge  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2553cc7ebeSragge  */
2653cc7ebeSragge 
2753cc7ebeSragge /*
2853cc7ebeSragge  * Standalone routine for DEBNA Ethernet controller.
2953cc7ebeSragge  */
3053cc7ebeSragge 
3153cc7ebeSragge #include <sys/param.h>
3253cc7ebeSragge #include <sys/types.h>
3353cc7ebeSragge #include <sys/queue.h>
3453cc7ebeSragge #include <sys/socket.h>
3553cc7ebeSragge 
3653cc7ebeSragge #include <net/if.h>
3753cc7ebeSragge #include <net/if_ether.h>
3853cc7ebeSragge 
3953cc7ebeSragge #include <netinet/in.h>
4053cc7ebeSragge #include <netinet/in_systm.h>
4153cc7ebeSragge 
4253cc7ebeSragge #include <../include/sid.h>
4353cc7ebeSragge #include <../include/rpb.h>
4453cc7ebeSragge #include <../include/pte.h>
4553cc7ebeSragge #include <../include/macros.h>
4653cc7ebeSragge #include <../include/mtpr.h>
4753cc7ebeSragge #include <../include/scb.h>
4853cc7ebeSragge 
4953cc7ebeSragge #include <lib/libkern/libkern.h>
5053cc7ebeSragge 
5153cc7ebeSragge #include <lib/libsa/netif.h>
5253cc7ebeSragge #include <lib/libsa/stand.h>
5353cc7ebeSragge #include <lib/libsa/net.h>
5453cc7ebeSragge 
5553cc7ebeSragge #include <dev/bi/bireg.h>
5653cc7ebeSragge 
5753cc7ebeSragge #include "vaxstand.h"
5853cc7ebeSragge 
5953cc7ebeSragge #undef NIDEBUG
6053cc7ebeSragge /*
6153cc7ebeSragge  * Tunable buffer parameters. Good idea to have them as power of 8; then
6253cc7ebeSragge  * they will fit into a logical VAX page.
6353cc7ebeSragge  */
6453cc7ebeSragge #define NMSGBUF		8	/* Message queue entries */
6553cc7ebeSragge #define NTXBUF		16	/* Transmit queue entries */
6653cc7ebeSragge #define NTXFRAGS	1	/* Number of transmit buffer fragments */
6753cc7ebeSragge #define NRXBUF		24	/* Receive queue entries */
6853cc7ebeSragge #define NBDESCS		(NTXBUF + NRXBUF)
6953cc7ebeSragge #define NQUEUES		3	/* RX + TX + MSG */
7053cc7ebeSragge #define PKTHDR		18	/* Length of (control) packet header */
7153cc7ebeSragge #define RXADD		18	/* Additional length of receive datagram */
7253cc7ebeSragge #define TXADD		18	/*	""	transmit   ""	 */
7353cc7ebeSragge #define MSGADD		134	/*	""	message	   ""	 */
7453cc7ebeSragge 
7553cc7ebeSragge #include <dev/bi/if_nireg.h>
7653cc7ebeSragge 
7753cc7ebeSragge 
7853cc7ebeSragge #define SPTSIZ	16384	/* 8MB */
7953cc7ebeSragge #define roundpg(x)	(((int)x + VAX_PGOFSET) & ~VAX_PGOFSET)
8053cc7ebeSragge #define ALLOC(x) \
8153524e44Schristos 	allocbase;xbzero((void *)allocbase,x);allocbase+=roundpg(x);
8253cc7ebeSragge #define nipqb	(&gvppqb->nc_pqb)
8353cc7ebeSragge #define gvp	gvppqb
8453cc7ebeSragge #define NI_WREG(csr, val) *(volatile long *)(niaddr + (csr)) = (val)
8553cc7ebeSragge #define NI_RREG(csr)	*(volatile long *)(niaddr + (csr))
8653cc7ebeSragge #define DELAY(x)	{volatile int i = x * 3;while (--i);}
8753cc7ebeSragge #define WAITREG(csr,val) while (NI_RREG(csr) & val);
8853cc7ebeSragge 
8969cf32a7Stsutsui static int ni_get(struct iodesc *, void *, size_t, saseconds_t);
9053cc7ebeSragge static int ni_put(struct iodesc *, void *, size_t);
9153cc7ebeSragge 
9253cc7ebeSragge static int *syspte, allocbase, niaddr;
9353cc7ebeSragge static struct ni_gvppqb *gvppqb;
9453cc7ebeSragge static struct ni_fqb *fqb;
9553cc7ebeSragge static struct ni_bbd *bbd;
965bf1ad37Smrg static u_char enaddr[6];
9753cc7ebeSragge static int beenhere = 0;
9853cc7ebeSragge 
9953cc7ebeSragge struct netif_driver ni_driver = {
10053cc7ebeSragge 	0, 0, 0, 0, ni_get, ni_put,
10153cc7ebeSragge };
10253cc7ebeSragge 
10353cc7ebeSragge static void
xbzero(char * a,int s)10453cc7ebeSragge xbzero(char *a, int s)
10553cc7ebeSragge {
10653cc7ebeSragge 	while (s--)
10753cc7ebeSragge 		*a++ = 0;
10853cc7ebeSragge }
10953cc7ebeSragge 
11053cc7ebeSragge static int
failtest(int reg,int mask,int test,char * str)11153cc7ebeSragge failtest(int reg, int mask, int test, char *str)
11253cc7ebeSragge {
11353cc7ebeSragge 	int i = 100;
11453cc7ebeSragge 
11553cc7ebeSragge 	do {
11653cc7ebeSragge 		DELAY(100000);
11753cc7ebeSragge 	} while (((NI_RREG(reg) & mask) != test) && --i);
11853cc7ebeSragge 
11953cc7ebeSragge 	if (i == 0) {
12053cc7ebeSragge 		printf("ni: %s\n", str);
12153cc7ebeSragge 		return 1;
12253cc7ebeSragge 	}
12353cc7ebeSragge 	return 0;
12453cc7ebeSragge }
12553cc7ebeSragge 
12653cc7ebeSragge static int
INSQTI(void * e,void * h)12753cc7ebeSragge INSQTI(void *e, void *h)
12853cc7ebeSragge {
12953cc7ebeSragge 	int ret;
13053cc7ebeSragge 
13153cc7ebeSragge 	while ((ret = insqti(e, h)) == ILCK_FAILED)
13253cc7ebeSragge 		;
13353cc7ebeSragge 	return ret;
13453cc7ebeSragge }
13553cc7ebeSragge 
13653cc7ebeSragge static void *
REMQHI(void * h)13753cc7ebeSragge REMQHI(void *h)
13853cc7ebeSragge {
13953cc7ebeSragge 	void *ret;
14053cc7ebeSragge 
14153cc7ebeSragge 	while ((ret = remqhi(h)) == (void *)ILCK_FAILED)
14253cc7ebeSragge 		;
14353cc7ebeSragge 	return ret;
14453cc7ebeSragge }
14553cc7ebeSragge 
14653cc7ebeSragge static void
puton(void * pkt,void * q,int args)14753cc7ebeSragge puton(void *pkt, void *q, int args)
14853cc7ebeSragge {
14953cc7ebeSragge 	INSQTI(pkt, q);
15053cc7ebeSragge 
15153cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
15253cc7ebeSragge 	NI_WREG(NI_PCR, args);
15353cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
15453cc7ebeSragge }
15553cc7ebeSragge 
15653cc7ebeSragge static void
remput(void * fq,void * pq,int args)15753cc7ebeSragge remput(void *fq, void *pq, int args)
15853cc7ebeSragge {
15953cc7ebeSragge 	struct ni_dg *data;
16053cc7ebeSragge 	int res;
16153cc7ebeSragge 
16253cc7ebeSragge 	while ((data = REMQHI(fq)) == 0)
16353cc7ebeSragge 		;
16453cc7ebeSragge 
16553cc7ebeSragge 	res = INSQTI(data, pq);
16653cc7ebeSragge 	if (res == Q_EMPTY) {
16753cc7ebeSragge 		WAITREG(NI_PCR, PCR_OWN);
16853cc7ebeSragge 		NI_WREG(NI_PCR, args);
16953cc7ebeSragge 	}
17053cc7ebeSragge }
17153cc7ebeSragge 
17253cc7ebeSragge static void
insput(void * elem,void * q,int args)17353cc7ebeSragge insput(void *elem, void *q, int args)
17453cc7ebeSragge {
17553cc7ebeSragge 	int res;
17653cc7ebeSragge 
17753cc7ebeSragge 	res = INSQTI(elem, q);
17853cc7ebeSragge 	if (res == Q_EMPTY) {
17953cc7ebeSragge 		WAITREG(NI_PCR, PCR_OWN);
18053cc7ebeSragge 		NI_WREG(NI_PCR, args);
18153cc7ebeSragge 	}
18253cc7ebeSragge }
18353cc7ebeSragge 
18453cc7ebeSragge int
niopen(struct open_file * f,int adapt,int ctlr,int unit,int part)18553cc7ebeSragge niopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
18653cc7ebeSragge {
18753cc7ebeSragge 	struct ni_dg *data;
18853cc7ebeSragge 	struct ni_msg *msg;
18953cc7ebeSragge 	struct ni_ptdb *ptdb;
1908ea099d4Schristos 	int i, va;
191f13ea86eSmrg 	struct ni_param *nip;
19253cc7ebeSragge 
19353cc7ebeSragge 	if (beenhere++ && askname == 0)
19453cc7ebeSragge 		return 0;
19553cc7ebeSragge 
196baec9288Sragge 	niaddr = nexaddr & ~(BI_NODESIZE - 1);
19753cc7ebeSragge 	bootrpb.csrphy = niaddr;
19853cc7ebeSragge 	if (adapt >= 0)
19953cc7ebeSragge 		bootrpb.adpphy = adapt;
20053cc7ebeSragge 	/*
20153cc7ebeSragge 	 * We need a bunch of memory, take it from our load
20253cc7ebeSragge 	 * address plus 1M.
20353cc7ebeSragge 	 */
20453cc7ebeSragge 	allocbase = RELOC + 1024 * 1024;
20553cc7ebeSragge 	/*
20653cc7ebeSragge 	 * First create a SPT for the first 8MB of physmem.
20753cc7ebeSragge 	 */
20853cc7ebeSragge 	syspte = (int *)ALLOC(SPTSIZ*4);
20953cc7ebeSragge 	for (i = 0; i < SPTSIZ; i++)
21053cc7ebeSragge 		syspte[i] = PG_V|PG_RW|i;
21153cc7ebeSragge 
21253cc7ebeSragge 
21353cc7ebeSragge 	gvppqb = (struct ni_gvppqb *)ALLOC(sizeof(struct ni_gvppqb));
21453cc7ebeSragge 	fqb = (struct ni_fqb *)ALLOC(sizeof(struct ni_fqb));
21553cc7ebeSragge 	bbd = (struct ni_bbd *)ALLOC(sizeof(struct ni_bbd) * NBDESCS);
21653cc7ebeSragge 
21753cc7ebeSragge 	/* Init the PQB struct */
21853cc7ebeSragge 	nipqb->np_spt = nipqb->np_gpt = (int)syspte;
21953cc7ebeSragge 	nipqb->np_sptlen = nipqb->np_gptlen = SPTSIZ;
22053cc7ebeSragge 	nipqb->np_vpqb = (u_int32_t)gvp;
22153cc7ebeSragge 	nipqb->np_bvplvl = 1;
22253cc7ebeSragge 	nipqb->np_vfqb = (u_int32_t)fqb;
22353cc7ebeSragge 	nipqb->np_vbdt = (u_int32_t)bbd;
22453cc7ebeSragge 	nipqb->np_nbdr = NBDESCS;
22553cc7ebeSragge 
22653cc7ebeSragge 	/* Free queue block */
22753cc7ebeSragge 	nipqb->np_freeq = NQUEUES;
22853cc7ebeSragge 	fqb->nf_mlen = PKTHDR+MSGADD;
22953cc7ebeSragge 	fqb->nf_dlen = PKTHDR+TXADD;
23053cc7ebeSragge 	fqb->nf_rlen = PKTHDR+RXADD;
23153cc7ebeSragge #ifdef NIDEBUG
23253cc7ebeSragge 	printf("niopen: syspte %p gvp %p fqb %p bbd %p\n",
23353cc7ebeSragge 	    syspte, gvppqb, fqb, bbd);
23453cc7ebeSragge #endif
23553cc7ebeSragge 
23653cc7ebeSragge 	NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
23753cc7ebeSragge 	DELAY(500000);
23853cc7ebeSragge 	i = 20;
23953cc7ebeSragge 	while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
24053cc7ebeSragge 		DELAY(500000);
24153cc7ebeSragge #ifdef NIDEBUG
24253cc7ebeSragge 	if (i == 0) {
24353cc7ebeSragge 		printf("ni: BROKE bit set after reset\n");
24453cc7ebeSragge 		return 1;
24553cc7ebeSragge 	}
24653cc7ebeSragge #endif
24753cc7ebeSragge 	/* Check state */
24853cc7ebeSragge 	if (failtest(NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
24953cc7ebeSragge 		return 1;
25053cc7ebeSragge 
25153cc7ebeSragge 	/* Clear owner bits */
25253cc7ebeSragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
25353cc7ebeSragge 	NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);
25453cc7ebeSragge 
25553cc7ebeSragge 	/* kick off init */
25653cc7ebeSragge 	NI_WREG(NI_PCR, (int)gvppqb | PCR_INIT | PCR_OWN);
25753cc7ebeSragge 	while (NI_RREG(NI_PCR) & PCR_OWN)
25853cc7ebeSragge 		DELAY(100000);
25953cc7ebeSragge 
26053cc7ebeSragge 	/* Check state */
26153cc7ebeSragge 	if (failtest(NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
26253cc7ebeSragge 		return 1;
26353cc7ebeSragge 
26453cc7ebeSragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
26553cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
26653cc7ebeSragge 	NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE);
26753cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
26853cc7ebeSragge 	WAITREG(NI_PSR, PSR_OWN);
26953cc7ebeSragge 
27053cc7ebeSragge 	/* Check state */
27153cc7ebeSragge 	if (failtest(NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
27253cc7ebeSragge 		return 1;
27353cc7ebeSragge 
27453cc7ebeSragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
27553cc7ebeSragge 
27653cc7ebeSragge #ifdef NIDEBUG
27753cc7ebeSragge 	printf("Set up message free queue\n");
27853cc7ebeSragge #endif
27953cc7ebeSragge 
28053cc7ebeSragge 	/* Set up message free queue */
28153cc7ebeSragge 	va = ALLOC(NMSGBUF * 512);
28253cc7ebeSragge 	for (i = 0; i < NMSGBUF; i++) {
28353cc7ebeSragge 		msg = (void *)(va + i * 512);
28453cc7ebeSragge 
2858ea099d4Schristos 		(void)INSQTI(msg, &fqb->nf_mforw);
28653cc7ebeSragge 	}
28753cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
28853cc7ebeSragge 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
28953cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
29053cc7ebeSragge 
29153cc7ebeSragge #ifdef NIDEBUG
29253cc7ebeSragge 	printf("Set up xmit queue\n");
29353cc7ebeSragge #endif
29453cc7ebeSragge 
29553cc7ebeSragge 	/* Set up xmit queue */
29653cc7ebeSragge 	va = ALLOC(NTXBUF * 512);
29753cc7ebeSragge 	for (i = 0; i < NTXBUF; i++) {
29853cc7ebeSragge 		struct ni_dg *data;
29953cc7ebeSragge 
30053cc7ebeSragge 		data = (void *)(va + i * 512);
30153cc7ebeSragge 		data->nd_status = 0;
30253cc7ebeSragge 		data->nd_len = TXADD;
30353cc7ebeSragge 		data->nd_ptdbidx = 1;
30453cc7ebeSragge 		data->nd_opcode = BVP_DGRAM;
30553cc7ebeSragge 		data->bufs[0]._offset = 0;
30653cc7ebeSragge 		data->bufs[0]._key = 1;
30753cc7ebeSragge 		data->nd_cmdref = allocbase;
30853cc7ebeSragge 		bbd[i].nb_key = 1;
30953cc7ebeSragge 		bbd[i].nb_status = 0;
31053cc7ebeSragge 		bbd[i].nb_pte = (int)&syspte[allocbase>>9];
31153cc7ebeSragge 		allocbase += 2048;
31253cc7ebeSragge 		data->bufs[0]._index = i;
31353cc7ebeSragge 
3148ea099d4Schristos 		(void)INSQTI(data, &fqb->nf_dforw);
31553cc7ebeSragge 	}
31653cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
31753cc7ebeSragge 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
31853cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
31953cc7ebeSragge 
32053cc7ebeSragge #ifdef NIDEBUG
32153cc7ebeSragge 	printf("recv buffers\n");
32253cc7ebeSragge #endif
32353cc7ebeSragge 
32453cc7ebeSragge 	/* recv buffers */
32553cc7ebeSragge 	va = ALLOC(NRXBUF * 512);
32653cc7ebeSragge 	for (i = 0; i < NRXBUF; i++) {
32753cc7ebeSragge 		struct ni_dg *data;
32853cc7ebeSragge 		struct ni_bbd *bd;
32953cc7ebeSragge 		int idx;
33053cc7ebeSragge 
33153cc7ebeSragge 		data = (void *)(va + i * 512);
33253cc7ebeSragge 		data->nd_cmdref = allocbase;
33353cc7ebeSragge 		data->nd_len = RXADD;
33453cc7ebeSragge 		data->nd_opcode = BVP_DGRAMRX;
33553cc7ebeSragge 		data->nd_ptdbidx = 2;
33653cc7ebeSragge 		data->bufs[0]._key = 1;
33753cc7ebeSragge 
33853cc7ebeSragge 		idx = NTXBUF + i;
33953cc7ebeSragge 		bd = &bbd[idx];
34053cc7ebeSragge 		bd->nb_pte = (int)&syspte[allocbase>>9];
34153cc7ebeSragge 		allocbase += 2048;
34253cc7ebeSragge 		bd->nb_len = 2048;
34353cc7ebeSragge 		bd->nb_status = NIBD_VALID;
34453cc7ebeSragge 		bd->nb_key = 1;
34553cc7ebeSragge 		data->bufs[0]._offset = 0;
34653cc7ebeSragge 		data->bufs[0]._len = bd->nb_len;
34753cc7ebeSragge 		data->bufs[0]._index = idx;
34853cc7ebeSragge 
3498ea099d4Schristos 		(void)INSQTI(data, &fqb->nf_rforw);
35053cc7ebeSragge 	}
35153cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
35253cc7ebeSragge 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
35353cc7ebeSragge 	WAITREG(NI_PCR, PCR_OWN);
35453cc7ebeSragge 
35553cc7ebeSragge #ifdef NIDEBUG
35653cc7ebeSragge 	printf("Set initial parameters\n");
35753cc7ebeSragge #endif
35853cc7ebeSragge 
35953cc7ebeSragge 	/* Set initial parameters */
36053cc7ebeSragge 	msg = REMQHI(&fqb->nf_mforw);
36153cc7ebeSragge 
36253cc7ebeSragge 	msg->nm_opcode = BVP_MSG;
36353cc7ebeSragge 	msg->nm_status = 0;
36453cc7ebeSragge 	msg->nm_len = sizeof(struct ni_param) + 6;
36553cc7ebeSragge 	msg->nm_opcode2 = NI_WPARAM;
366f13ea86eSmrg 	nip = (struct ni_param *)&msg->nm_text[0];
367f13ea86eSmrg 	nip->np_flags = NP_PAD;
36853cc7ebeSragge 
36953cc7ebeSragge 	puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
37053cc7ebeSragge 
37153cc7ebeSragge 
37253cc7ebeSragge 	while ((data = REMQHI(&gvp->nc_forwr)) == 0)
37353cc7ebeSragge 		;
37453cc7ebeSragge 
37553cc7ebeSragge 	msg = (struct ni_msg *)data;
37653cc7ebeSragge #ifdef NIDEBUG
37753cc7ebeSragge 	if (msg->nm_opcode2 != NI_WPARAM) {
37853cc7ebeSragge 		printf("ni: wrong response code %d\n", msg->nm_opcode2);
37953cc7ebeSragge 		insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
38053cc7ebeSragge 	}
38153cc7ebeSragge #endif
382f13ea86eSmrg 	bcopy(nip->np_dpa, enaddr, ETHER_ADDR_LEN);
38353cc7ebeSragge 	insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
38453cc7ebeSragge 
38553cc7ebeSragge #ifdef NIDEBUG
38653cc7ebeSragge 	printf("Clear counters\n");
38753cc7ebeSragge #endif
38853cc7ebeSragge 
38953cc7ebeSragge 	/* Clear counters */
39053cc7ebeSragge 	msg = REMQHI(&fqb->nf_mforw);
39153cc7ebeSragge 	msg->nm_opcode = BVP_MSG;
39253cc7ebeSragge 	msg->nm_status = 0;
39353cc7ebeSragge 	msg->nm_len = sizeof(struct ni_param) + 6;
39453cc7ebeSragge 	msg->nm_opcode2 = NI_RCCNTR;
39553cc7ebeSragge 
39653cc7ebeSragge 	puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
39753cc7ebeSragge 	remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
39853cc7ebeSragge 
39953cc7ebeSragge #ifdef NIDEBUG
40053cc7ebeSragge 	printf("Enable transmit logic\n");
40153cc7ebeSragge #endif
40253cc7ebeSragge 
40353cc7ebeSragge 	/* Enable transmit logic */
40453cc7ebeSragge 	msg = REMQHI(&fqb->nf_mforw);
40553cc7ebeSragge 
40653cc7ebeSragge 	msg->nm_opcode = BVP_MSG;
40753cc7ebeSragge 	msg->nm_status = 0;
40853cc7ebeSragge 	msg->nm_len = 18;
40953cc7ebeSragge 	msg->nm_opcode2 = NI_STPTDB;
41053cc7ebeSragge 	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
411c363a9cbScegger 	memset(ptdb, 0, sizeof(struct ni_ptdb));
41253cc7ebeSragge 	ptdb->np_index = 1;
41353cc7ebeSragge 	ptdb->np_fque = 1;
41453cc7ebeSragge 
41553cc7ebeSragge 	puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
41653cc7ebeSragge 	remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
41753cc7ebeSragge 
41853cc7ebeSragge #ifdef NIDEBUG
41953cc7ebeSragge 	printf("ni: hardware address %s\n", ether_sprintf(enaddr));
42053cc7ebeSragge 	printf("Setting receive parameters\n");
42153cc7ebeSragge #endif
42253cc7ebeSragge 	msg = REMQHI(&fqb->nf_mforw);
42353cc7ebeSragge 	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
424c363a9cbScegger 	memset(ptdb, 0, sizeof(struct ni_ptdb));
42553cc7ebeSragge 	msg->nm_opcode = BVP_MSG;
42653cc7ebeSragge 	msg->nm_len = 18;
42753cc7ebeSragge 	ptdb->np_index = 2;
42853cc7ebeSragge 	ptdb->np_fque = 2;
42953cc7ebeSragge 	msg->nm_opcode2 = NI_STPTDB;
43053cc7ebeSragge 	ptdb->np_type = ETHERTYPE_IP;
43153cc7ebeSragge 	ptdb->np_flags = PTDB_UNKN|PTDB_BDC;
43253cc7ebeSragge 	memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN);
43353cc7ebeSragge 	ptdb->np_adrlen = 1;
43453cc7ebeSragge 	msg->nm_len += 8;
43553cc7ebeSragge 	insput(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
43653cc7ebeSragge 	remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
43753cc7ebeSragge 
43853cc7ebeSragge #ifdef NIDEBUG
43953cc7ebeSragge 	printf("finished\n");
44053cc7ebeSragge #endif
44153cc7ebeSragge 
44253cc7ebeSragge 	net_devinit(f, &ni_driver, enaddr);
44353cc7ebeSragge 	return 0;
44453cc7ebeSragge }
44553cc7ebeSragge 
44653cc7ebeSragge int
ni_get(struct iodesc * desc,void * pkt,size_t maxlen,saseconds_t timeout)44769cf32a7Stsutsui ni_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timeout)
44853cc7ebeSragge {
44953cc7ebeSragge 	struct ni_dg *data;
45053cc7ebeSragge 	struct ni_bbd *bd;
45169cf32a7Stsutsui 	satime_t nsec = getsecs();
45253cc7ebeSragge 	int len, idx;
45353cc7ebeSragge 
45469cf32a7Stsutsui loop:
45569cf32a7Stsutsui 	while ((data = REMQHI(&gvp->nc_forwr)) == 0 &&
45669cf32a7Stsutsui 	    ((getsecs() - nsec) < timeout))
45753cc7ebeSragge 		;
45853cc7ebeSragge 
45969cf32a7Stsutsui 	if ((getsecs() - nsec) >= timeout)
46053cc7ebeSragge 		return 0;
46153cc7ebeSragge 
46253cc7ebeSragge 	switch (data->nd_opcode) {
46353cc7ebeSragge 	case BVP_DGRAMRX:
46453cc7ebeSragge 		idx = data->bufs[0]._index;
46553cc7ebeSragge 		bd = &bbd[idx];
46653cc7ebeSragge 		len = data->bufs[0]._len;
46753cc7ebeSragge 		if (len > maxlen)
46853cc7ebeSragge 			len = maxlen;
469e2cb8590Scegger 		memcpy(pkt, (void *)data->nd_cmdref, len);
47053cc7ebeSragge 		bd->nb_pte = (int)&syspte[data->nd_cmdref>>9];
47153cc7ebeSragge 		data->bufs[0]._len = bd->nb_len = 2048;
47253cc7ebeSragge 		data->bufs[0]._offset = 0;
47353cc7ebeSragge 		data->bufs[0]._key = 1;
47453cc7ebeSragge 		bd->nb_status = NIBD_VALID;
47553cc7ebeSragge 		bd->nb_key = 1;
47653cc7ebeSragge 		data->nd_len = RXADD;
47753cc7ebeSragge 		data->nd_status = 0;
47853cc7ebeSragge 		insput(data, &fqb->nf_rforw,
47953cc7ebeSragge 		    PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
48053cc7ebeSragge 		return len;
48153cc7ebeSragge 
48253cc7ebeSragge 	case BVP_DGRAM:
48353cc7ebeSragge 		insput(data, &fqb->nf_dforw, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
48453cc7ebeSragge 		break;
48553cc7ebeSragge 	default:
48653cc7ebeSragge 		insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
48753cc7ebeSragge 		break;
48853cc7ebeSragge 	}
48953cc7ebeSragge 
49053cc7ebeSragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ));
49153cc7ebeSragge 	goto loop;
49253cc7ebeSragge }
49353cc7ebeSragge 
49453cc7ebeSragge int
ni_put(struct iodesc * desc,void * pkt,size_t len)49553cc7ebeSragge ni_put(struct iodesc *desc, void *pkt, size_t len)
49653cc7ebeSragge {
49753cc7ebeSragge 	struct ni_dg *data;
49853cc7ebeSragge 	struct ni_bbd *bdp;
49953cc7ebeSragge 
50053cc7ebeSragge 	data = REMQHI(&fqb->nf_dforw);
50153cc7ebeSragge #ifdef NIDEBUG
50253cc7ebeSragge 	if (data == 0) {
50353cc7ebeSragge 		printf("ni_put: driver problem, data == 0\n");
50453cc7ebeSragge 		return -1;
50553cc7ebeSragge 	}
50653cc7ebeSragge #endif
50753cc7ebeSragge 	bdp = &bbd[(data->bufs[0]._index & 0x7fff)];
50853cc7ebeSragge 	bdp->nb_status = NIBD_VALID;
50953cc7ebeSragge 	bdp->nb_len = (len < 64 ? 64 : len);
510e2cb8590Scegger 	memcpy((void *)data->nd_cmdref, pkt, len);
51153cc7ebeSragge 	data->bufs[0]._offset = 0;
51253cc7ebeSragge 	data->bufs[0]._len = bdp->nb_len;
51353cc7ebeSragge 	data->nd_opcode = BVP_DGRAM;
51453cc7ebeSragge 	data->nd_pad3 = 1;
51553cc7ebeSragge 	data->nd_ptdbidx = 1;
51653cc7ebeSragge 	data->nd_len = 18;
51753cc7ebeSragge 	insput(data, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
51853cc7ebeSragge 	return len;
51953cc7ebeSragge }
52053cc7ebeSragge 
52153cc7ebeSragge int
niclose(struct open_file * f)52253cc7ebeSragge niclose(struct open_file *f)
52353cc7ebeSragge {
52453cc7ebeSragge 	if (beenhere) {
52553cc7ebeSragge 		WAITREG(NI_PCR, PCR_OWN);
52653cc7ebeSragge 		NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN);
52753cc7ebeSragge 		WAITREG(NI_PCR, PCR_OWN);
52853cc7ebeSragge 	}
52953cc7ebeSragge 	return 0;
53053cc7ebeSragge }
531