Home | History | Annotate | Line # | Download | only in boot
if_ni.c revision 1.6
      1  1.6    cegger /*	$NetBSD: if_ni.c,v 1.6 2009/03/18 16:00:15 cegger Exp $ */
      2  1.1     ragge /*
      3  1.1     ragge  * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
      4  1.1     ragge  * All rights reserved.
      5  1.1     ragge  *
      6  1.1     ragge  * Redistribution and use in source and binary forms, with or without
      7  1.1     ragge  * modification, are permitted provided that the following conditions
      8  1.1     ragge  * are met:
      9  1.1     ragge  * 1. Redistributions of source code must retain the above copyright
     10  1.1     ragge  *    notice, this list of conditions and the following disclaimer.
     11  1.1     ragge  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1     ragge  *    notice, this list of conditions and the following disclaimer in the
     13  1.1     ragge  *    documentation and/or other materials provided with the distribution.
     14  1.1     ragge  * 3. All advertising materials mentioning features or use of this software
     15  1.1     ragge  *    must display the following acknowledgement:
     16  1.1     ragge  *	This product includes software developed at Ludd, University of
     17  1.1     ragge  *	Lule}, Sweden and its contributors.
     18  1.1     ragge  * 4. The name of the author may not be used to endorse or promote products
     19  1.1     ragge  *    derived from this software without specific prior written permission
     20  1.1     ragge  *
     21  1.1     ragge  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  1.1     ragge  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  1.1     ragge  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  1.1     ragge  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  1.1     ragge  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  1.1     ragge  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.1     ragge  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.1     ragge  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.1     ragge  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  1.1     ragge  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  1.1     ragge  */
     32  1.1     ragge 
     33  1.1     ragge /*
     34  1.1     ragge  * Standalone routine for DEBNA Ethernet controller.
     35  1.1     ragge  */
     36  1.1     ragge 
     37  1.1     ragge #include <sys/param.h>
     38  1.1     ragge #include <sys/types.h>
     39  1.1     ragge #include <sys/queue.h>
     40  1.1     ragge #include <sys/socket.h>
     41  1.1     ragge 
     42  1.1     ragge #include <net/if.h>
     43  1.1     ragge #include <net/if_ether.h>
     44  1.1     ragge 
     45  1.1     ragge #include <netinet/in.h>
     46  1.1     ragge #include <netinet/in_systm.h>
     47  1.1     ragge 
     48  1.1     ragge #include <../include/sid.h>
     49  1.1     ragge #include <../include/rpb.h>
     50  1.1     ragge #include <../include/pte.h>
     51  1.1     ragge #include <../include/macros.h>
     52  1.1     ragge #include <../include/mtpr.h>
     53  1.1     ragge #include <../include/scb.h>
     54  1.1     ragge 
     55  1.1     ragge #include <lib/libkern/libkern.h>
     56  1.1     ragge 
     57  1.1     ragge #include <lib/libsa/netif.h>
     58  1.1     ragge #include <lib/libsa/stand.h>
     59  1.1     ragge #include <lib/libsa/net.h>
     60  1.1     ragge 
     61  1.1     ragge #include <dev/bi/bireg.h>
     62  1.1     ragge 
     63  1.1     ragge #include "vaxstand.h"
     64  1.1     ragge 
     65  1.1     ragge #undef NIDEBUG
     66  1.1     ragge /*
     67  1.1     ragge  * Tunable buffer parameters. Good idea to have them as power of 8; then
     68  1.1     ragge  * they will fit into a logical VAX page.
     69  1.1     ragge  */
     70  1.1     ragge #define NMSGBUF		8	/* Message queue entries */
     71  1.1     ragge #define NTXBUF		16	/* Transmit queue entries */
     72  1.1     ragge #define NTXFRAGS	1	/* Number of transmit buffer fragments */
     73  1.1     ragge #define NRXBUF		24	/* Receive queue entries */
     74  1.1     ragge #define NBDESCS		(NTXBUF + NRXBUF)
     75  1.1     ragge #define NQUEUES		3	/* RX + TX + MSG */
     76  1.1     ragge #define PKTHDR		18	/* Length of (control) packet header */
     77  1.1     ragge #define RXADD		18	/* Additional length of receive datagram */
     78  1.1     ragge #define TXADD		18	/*	""	transmit   ""	 */
     79  1.1     ragge #define MSGADD		134	/*	""	message	   ""	 */
     80  1.1     ragge 
     81  1.1     ragge #include <dev/bi/if_nireg.h>
     82  1.1     ragge 
     83  1.1     ragge 
     84  1.1     ragge #define SPTSIZ	16384	/* 8MB */
     85  1.1     ragge #define roundpg(x)	(((int)x + VAX_PGOFSET) & ~VAX_PGOFSET)
     86  1.1     ragge #define ALLOC(x) \
     87  1.4  christos 	allocbase;xbzero((void *)allocbase,x);allocbase+=roundpg(x);
     88  1.1     ragge #define nipqb	(&gvppqb->nc_pqb)
     89  1.1     ragge #define gvp	gvppqb
     90  1.1     ragge #define NI_WREG(csr, val) *(volatile long *)(niaddr + (csr)) = (val)
     91  1.1     ragge #define NI_RREG(csr)	*(volatile long *)(niaddr + (csr))
     92  1.1     ragge #define DELAY(x)	{volatile int i = x * 3;while (--i);}
     93  1.1     ragge #define WAITREG(csr,val) while (NI_RREG(csr) & val);
     94  1.1     ragge 
     95  1.5   tsutsui static int ni_get(struct iodesc *, void *, size_t, saseconds_t);
     96  1.1     ragge static int ni_put(struct iodesc *, void *, size_t);
     97  1.1     ragge 
     98  1.1     ragge static int *syspte, allocbase, niaddr;
     99  1.1     ragge static struct ni_gvppqb *gvppqb;
    100  1.1     ragge static struct ni_fqb *fqb;
    101  1.1     ragge static struct ni_bbd *bbd;
    102  1.3       mrg static u_char enaddr[6];
    103  1.1     ragge static int beenhere = 0;
    104  1.1     ragge 
    105  1.1     ragge struct netif_driver ni_driver = {
    106  1.1     ragge 	0, 0, 0, 0, ni_get, ni_put,
    107  1.1     ragge };
    108  1.1     ragge 
    109  1.1     ragge static void
    110  1.1     ragge xbzero(char *a, int s)
    111  1.1     ragge {
    112  1.1     ragge 	while (s--)
    113  1.1     ragge 		*a++ = 0;
    114  1.1     ragge }
    115  1.1     ragge 
    116  1.1     ragge static int
    117  1.1     ragge failtest(int reg, int mask, int test, char *str)
    118  1.1     ragge {
    119  1.1     ragge 	int i = 100;
    120  1.1     ragge 
    121  1.1     ragge 	do {
    122  1.1     ragge 		DELAY(100000);
    123  1.1     ragge 	} while (((NI_RREG(reg) & mask) != test) && --i);
    124  1.1     ragge 
    125  1.1     ragge 	if (i == 0) {
    126  1.1     ragge 		printf("ni: %s\n", str);
    127  1.1     ragge 		return 1;
    128  1.1     ragge 	}
    129  1.1     ragge 	return 0;
    130  1.1     ragge }
    131  1.1     ragge 
    132  1.1     ragge static int
    133  1.1     ragge INSQTI(void *e, void *h)
    134  1.1     ragge {
    135  1.1     ragge 	int ret;
    136  1.1     ragge 
    137  1.1     ragge 	while ((ret = insqti(e, h)) == ILCK_FAILED)
    138  1.1     ragge 		;
    139  1.1     ragge 	return ret;
    140  1.1     ragge }
    141  1.1     ragge 
    142  1.1     ragge static void *
    143  1.1     ragge REMQHI(void *h)
    144  1.1     ragge {
    145  1.1     ragge 	void *ret;
    146  1.1     ragge 
    147  1.1     ragge 	while ((ret = remqhi(h)) == (void *)ILCK_FAILED)
    148  1.1     ragge 		;
    149  1.1     ragge 	return ret;
    150  1.1     ragge }
    151  1.1     ragge 
    152  1.1     ragge static void
    153  1.1     ragge puton(void *pkt, void *q, int args)
    154  1.1     ragge {
    155  1.1     ragge 	INSQTI(pkt, q);
    156  1.1     ragge 
    157  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    158  1.1     ragge 	NI_WREG(NI_PCR, args);
    159  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    160  1.1     ragge }
    161  1.1     ragge 
    162  1.1     ragge static void
    163  1.1     ragge remput(void *fq, void *pq, int args)
    164  1.1     ragge {
    165  1.1     ragge 	struct ni_dg *data;
    166  1.1     ragge 	int res;
    167  1.1     ragge 
    168  1.1     ragge 	while ((data = REMQHI(fq)) == 0)
    169  1.1     ragge 		;
    170  1.1     ragge 
    171  1.1     ragge 	res = INSQTI(data, pq);
    172  1.1     ragge 	if (res == Q_EMPTY) {
    173  1.1     ragge 		WAITREG(NI_PCR, PCR_OWN);
    174  1.1     ragge 		NI_WREG(NI_PCR, args);
    175  1.1     ragge 	}
    176  1.1     ragge }
    177  1.1     ragge 
    178  1.1     ragge static void
    179  1.1     ragge insput(void *elem, void *q, int args)
    180  1.1     ragge {
    181  1.1     ragge 	int res;
    182  1.1     ragge 
    183  1.1     ragge 	res = INSQTI(elem, q);
    184  1.1     ragge 	if (res == Q_EMPTY) {
    185  1.1     ragge 		WAITREG(NI_PCR, PCR_OWN);
    186  1.1     ragge 		NI_WREG(NI_PCR, args);
    187  1.1     ragge 	}
    188  1.1     ragge }
    189  1.1     ragge 
    190  1.1     ragge int
    191  1.1     ragge niopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
    192  1.1     ragge {
    193  1.1     ragge 	struct ni_dg *data;
    194  1.1     ragge 	struct ni_msg *msg;
    195  1.1     ragge 	struct ni_ptdb *ptdb;
    196  1.1     ragge 	int i, va, res;
    197  1.1     ragge 
    198  1.1     ragge 	if (beenhere++ && askname == 0)
    199  1.1     ragge 		return 0;
    200  1.1     ragge 
    201  1.2     ragge 	niaddr = nexaddr & ~(BI_NODESIZE - 1);
    202  1.1     ragge 	bootrpb.csrphy = niaddr;
    203  1.1     ragge 	if (adapt >= 0)
    204  1.1     ragge 		bootrpb.adpphy = adapt;
    205  1.1     ragge 	/*
    206  1.1     ragge 	 * We need a bunch of memory, take it from our load
    207  1.1     ragge 	 * address plus 1M.
    208  1.1     ragge 	 */
    209  1.1     ragge 	allocbase = RELOC + 1024 * 1024;
    210  1.1     ragge 	/*
    211  1.1     ragge 	 * First create a SPT for the first 8MB of physmem.
    212  1.1     ragge 	 */
    213  1.1     ragge 	syspte = (int *)ALLOC(SPTSIZ*4);
    214  1.1     ragge 	for (i = 0; i < SPTSIZ; i++)
    215  1.1     ragge 		syspte[i] = PG_V|PG_RW|i;
    216  1.1     ragge 
    217  1.1     ragge 
    218  1.1     ragge 	gvppqb = (struct ni_gvppqb *)ALLOC(sizeof(struct ni_gvppqb));
    219  1.1     ragge 	fqb = (struct ni_fqb *)ALLOC(sizeof(struct ni_fqb));
    220  1.1     ragge 	bbd = (struct ni_bbd *)ALLOC(sizeof(struct ni_bbd) * NBDESCS);
    221  1.1     ragge 
    222  1.1     ragge 	/* Init the PQB struct */
    223  1.1     ragge 	nipqb->np_spt = nipqb->np_gpt = (int)syspte;
    224  1.1     ragge 	nipqb->np_sptlen = nipqb->np_gptlen = SPTSIZ;
    225  1.1     ragge 	nipqb->np_vpqb = (u_int32_t)gvp;
    226  1.1     ragge 	nipqb->np_bvplvl = 1;
    227  1.1     ragge 	nipqb->np_vfqb = (u_int32_t)fqb;
    228  1.1     ragge 	nipqb->np_vbdt = (u_int32_t)bbd;
    229  1.1     ragge 	nipqb->np_nbdr = NBDESCS;
    230  1.1     ragge 
    231  1.1     ragge 	/* Free queue block */
    232  1.1     ragge 	nipqb->np_freeq = NQUEUES;
    233  1.1     ragge 	fqb->nf_mlen = PKTHDR+MSGADD;
    234  1.1     ragge 	fqb->nf_dlen = PKTHDR+TXADD;
    235  1.1     ragge 	fqb->nf_rlen = PKTHDR+RXADD;
    236  1.1     ragge #ifdef NIDEBUG
    237  1.1     ragge 	printf("niopen: syspte %p gvp %p fqb %p bbd %p\n",
    238  1.1     ragge 	    syspte, gvppqb, fqb, bbd);
    239  1.1     ragge #endif
    240  1.1     ragge 
    241  1.1     ragge 	NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
    242  1.1     ragge 	DELAY(500000);
    243  1.1     ragge 	i = 20;
    244  1.1     ragge 	while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
    245  1.1     ragge 		DELAY(500000);
    246  1.1     ragge #ifdef NIDEBUG
    247  1.1     ragge 	if (i == 0) {
    248  1.1     ragge 		printf("ni: BROKE bit set after reset\n");
    249  1.1     ragge 		return 1;
    250  1.1     ragge 	}
    251  1.1     ragge #endif
    252  1.1     ragge 	/* Check state */
    253  1.1     ragge 	if (failtest(NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
    254  1.1     ragge 		return 1;
    255  1.1     ragge 
    256  1.1     ragge 	/* Clear owner bits */
    257  1.1     ragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
    258  1.1     ragge 	NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);
    259  1.1     ragge 
    260  1.1     ragge 	/* kick off init */
    261  1.1     ragge 	NI_WREG(NI_PCR, (int)gvppqb | PCR_INIT | PCR_OWN);
    262  1.1     ragge 	while (NI_RREG(NI_PCR) & PCR_OWN)
    263  1.1     ragge 		DELAY(100000);
    264  1.1     ragge 
    265  1.1     ragge 	/* Check state */
    266  1.1     ragge 	if (failtest(NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
    267  1.1     ragge 		return 1;
    268  1.1     ragge 
    269  1.1     ragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
    270  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    271  1.1     ragge 	NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE);
    272  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    273  1.1     ragge 	WAITREG(NI_PSR, PSR_OWN);
    274  1.1     ragge 
    275  1.1     ragge 	/* Check state */
    276  1.1     ragge 	if (failtest(NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
    277  1.1     ragge 		return 1;
    278  1.1     ragge 
    279  1.1     ragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
    280  1.1     ragge 
    281  1.1     ragge #ifdef NIDEBUG
    282  1.1     ragge 	printf("Set up message free queue\n");
    283  1.1     ragge #endif
    284  1.1     ragge 
    285  1.1     ragge 	/* Set up message free queue */
    286  1.1     ragge 	va = ALLOC(NMSGBUF * 512);
    287  1.1     ragge 	for (i = 0; i < NMSGBUF; i++) {
    288  1.1     ragge 		msg = (void *)(va + i * 512);
    289  1.1     ragge 
    290  1.1     ragge 		res = INSQTI(msg, &fqb->nf_mforw);
    291  1.1     ragge 	}
    292  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    293  1.1     ragge 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    294  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    295  1.1     ragge 
    296  1.1     ragge #ifdef NIDEBUG
    297  1.1     ragge 	printf("Set up xmit queue\n");
    298  1.1     ragge #endif
    299  1.1     ragge 
    300  1.1     ragge 	/* Set up xmit queue */
    301  1.1     ragge 	va = ALLOC(NTXBUF * 512);
    302  1.1     ragge 	for (i = 0; i < NTXBUF; i++) {
    303  1.1     ragge 		struct ni_dg *data;
    304  1.1     ragge 
    305  1.1     ragge 		data = (void *)(va + i * 512);
    306  1.1     ragge 		data->nd_status = 0;
    307  1.1     ragge 		data->nd_len = TXADD;
    308  1.1     ragge 		data->nd_ptdbidx = 1;
    309  1.1     ragge 		data->nd_opcode = BVP_DGRAM;
    310  1.1     ragge 		data->bufs[0]._offset = 0;
    311  1.1     ragge 		data->bufs[0]._key = 1;
    312  1.1     ragge 		data->nd_cmdref = allocbase;
    313  1.1     ragge 		bbd[i].nb_key = 1;
    314  1.1     ragge 		bbd[i].nb_status = 0;
    315  1.1     ragge 		bbd[i].nb_pte = (int)&syspte[allocbase>>9];
    316  1.1     ragge 		allocbase += 2048;
    317  1.1     ragge 		data->bufs[0]._index = i;
    318  1.1     ragge 
    319  1.1     ragge 		res = INSQTI(data, &fqb->nf_dforw);
    320  1.1     ragge 	}
    321  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    322  1.1     ragge 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
    323  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    324  1.1     ragge 
    325  1.1     ragge #ifdef NIDEBUG
    326  1.1     ragge 	printf("recv buffers\n");
    327  1.1     ragge #endif
    328  1.1     ragge 
    329  1.1     ragge 	/* recv buffers */
    330  1.1     ragge 	va = ALLOC(NRXBUF * 512);
    331  1.1     ragge 	for (i = 0; i < NRXBUF; i++) {
    332  1.1     ragge 		struct ni_dg *data;
    333  1.1     ragge 		struct ni_bbd *bd;
    334  1.1     ragge 		int idx;
    335  1.1     ragge 
    336  1.1     ragge 		data = (void *)(va + i * 512);
    337  1.1     ragge 		data->nd_cmdref = allocbase;
    338  1.1     ragge 		data->nd_len = RXADD;
    339  1.1     ragge 		data->nd_opcode = BVP_DGRAMRX;
    340  1.1     ragge 		data->nd_ptdbidx = 2;
    341  1.1     ragge 		data->bufs[0]._key = 1;
    342  1.1     ragge 
    343  1.1     ragge 		idx = NTXBUF + i;
    344  1.1     ragge 		bd = &bbd[idx];
    345  1.1     ragge 		bd->nb_pte = (int)&syspte[allocbase>>9];
    346  1.1     ragge 		allocbase += 2048;
    347  1.1     ragge 		bd->nb_len = 2048;
    348  1.1     ragge 		bd->nb_status = NIBD_VALID;
    349  1.1     ragge 		bd->nb_key = 1;
    350  1.1     ragge 		data->bufs[0]._offset = 0;
    351  1.1     ragge 		data->bufs[0]._len = bd->nb_len;
    352  1.1     ragge 		data->bufs[0]._index = idx;
    353  1.1     ragge 
    354  1.1     ragge 		res = INSQTI(data, &fqb->nf_rforw);
    355  1.1     ragge 	}
    356  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    357  1.1     ragge 	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
    358  1.1     ragge 	WAITREG(NI_PCR, PCR_OWN);
    359  1.1     ragge 
    360  1.1     ragge #ifdef NIDEBUG
    361  1.1     ragge 	printf("Set initial parameters\n");
    362  1.1     ragge #endif
    363  1.1     ragge 
    364  1.1     ragge 	/* Set initial parameters */
    365  1.1     ragge 	msg = REMQHI(&fqb->nf_mforw);
    366  1.1     ragge 
    367  1.1     ragge 	msg->nm_opcode = BVP_MSG;
    368  1.1     ragge 	msg->nm_status = 0;
    369  1.1     ragge 	msg->nm_len = sizeof(struct ni_param) + 6;
    370  1.1     ragge 	msg->nm_opcode2 = NI_WPARAM;
    371  1.1     ragge 	((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD;
    372  1.1     ragge 
    373  1.1     ragge 	puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
    374  1.1     ragge 
    375  1.1     ragge 
    376  1.1     ragge 	while ((data = REMQHI(&gvp->nc_forwr)) == 0)
    377  1.1     ragge 		;
    378  1.1     ragge 
    379  1.1     ragge 	msg = (struct ni_msg *)data;
    380  1.1     ragge #ifdef NIDEBUG
    381  1.1     ragge 	if (msg->nm_opcode2 != NI_WPARAM) {
    382  1.1     ragge 		printf("ni: wrong response code %d\n", msg->nm_opcode2);
    383  1.1     ragge 		insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    384  1.1     ragge 	}
    385  1.1     ragge #endif
    386  1.1     ragge 	bcopy(((struct ni_param *)&msg->nm_text[0])->np_dpa,
    387  1.1     ragge 	    enaddr, ETHER_ADDR_LEN);
    388  1.1     ragge 	insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    389  1.1     ragge 
    390  1.1     ragge #ifdef NIDEBUG
    391  1.1     ragge 	printf("Clear counters\n");
    392  1.1     ragge #endif
    393  1.1     ragge 
    394  1.1     ragge 	/* Clear counters */
    395  1.1     ragge 	msg = REMQHI(&fqb->nf_mforw);
    396  1.1     ragge 	msg->nm_opcode = BVP_MSG;
    397  1.1     ragge 	msg->nm_status = 0;
    398  1.1     ragge 	msg->nm_len = sizeof(struct ni_param) + 6;
    399  1.1     ragge 	msg->nm_opcode2 = NI_RCCNTR;
    400  1.1     ragge 
    401  1.1     ragge 	puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
    402  1.1     ragge 	remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    403  1.1     ragge 
    404  1.1     ragge #ifdef NIDEBUG
    405  1.1     ragge 	printf("Enable transmit logic\n");
    406  1.1     ragge #endif
    407  1.1     ragge 
    408  1.1     ragge 	/* Enable transmit logic */
    409  1.1     ragge 	msg = REMQHI(&fqb->nf_mforw);
    410  1.1     ragge 
    411  1.1     ragge 	msg->nm_opcode = BVP_MSG;
    412  1.1     ragge 	msg->nm_status = 0;
    413  1.1     ragge 	msg->nm_len = 18;
    414  1.1     ragge 	msg->nm_opcode2 = NI_STPTDB;
    415  1.1     ragge 	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
    416  1.6    cegger 	memset(ptdb, 0, sizeof(struct ni_ptdb));
    417  1.1     ragge 	ptdb->np_index = 1;
    418  1.1     ragge 	ptdb->np_fque = 1;
    419  1.1     ragge 
    420  1.1     ragge 	puton(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
    421  1.1     ragge 	remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    422  1.1     ragge 
    423  1.1     ragge #ifdef NIDEBUG
    424  1.1     ragge 	printf("ni: hardware address %s\n", ether_sprintf(enaddr));
    425  1.1     ragge 	printf("Setting receive parameters\n");
    426  1.1     ragge #endif
    427  1.1     ragge 	msg = REMQHI(&fqb->nf_mforw);
    428  1.1     ragge 	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
    429  1.6    cegger 	memset(ptdb, 0, sizeof(struct ni_ptdb));
    430  1.1     ragge 	msg->nm_opcode = BVP_MSG;
    431  1.1     ragge 	msg->nm_len = 18;
    432  1.1     ragge 	ptdb->np_index = 2;
    433  1.1     ragge 	ptdb->np_fque = 2;
    434  1.1     ragge 	msg->nm_opcode2 = NI_STPTDB;
    435  1.1     ragge 	ptdb->np_type = ETHERTYPE_IP;
    436  1.1     ragge 	ptdb->np_flags = PTDB_UNKN|PTDB_BDC;
    437  1.1     ragge 	memset(ptdb->np_mcast[0], 0xff, ETHER_ADDR_LEN);
    438  1.1     ragge 	ptdb->np_adrlen = 1;
    439  1.1     ragge 	msg->nm_len += 8;
    440  1.1     ragge 	insput(msg, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
    441  1.1     ragge 	remput(&gvp->nc_forwr, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    442  1.1     ragge 
    443  1.1     ragge #ifdef NIDEBUG
    444  1.1     ragge 	printf("finished\n");
    445  1.1     ragge #endif
    446  1.1     ragge 
    447  1.1     ragge 	net_devinit(f, &ni_driver, enaddr);
    448  1.1     ragge 	return 0;
    449  1.1     ragge }
    450  1.1     ragge 
    451  1.1     ragge int
    452  1.5   tsutsui ni_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timeout)
    453  1.1     ragge {
    454  1.1     ragge 	struct ni_dg *data;
    455  1.1     ragge 	struct ni_bbd *bd;
    456  1.5   tsutsui 	satime_t nsec = getsecs();
    457  1.1     ragge 	int len, idx;
    458  1.1     ragge 
    459  1.5   tsutsui loop:
    460  1.5   tsutsui 	while ((data = REMQHI(&gvp->nc_forwr)) == 0 &&
    461  1.5   tsutsui 	    ((getsecs() - nsec) < timeout))
    462  1.1     ragge 		;
    463  1.1     ragge 
    464  1.5   tsutsui 	if ((getsecs() - nsec) >= timeout)
    465  1.1     ragge 		return 0;
    466  1.1     ragge 
    467  1.1     ragge 	switch (data->nd_opcode) {
    468  1.1     ragge 	case BVP_DGRAMRX:
    469  1.1     ragge 		idx = data->bufs[0]._index;
    470  1.1     ragge 		bd = &bbd[idx];
    471  1.1     ragge 		len = data->bufs[0]._len;
    472  1.1     ragge 		if (len > maxlen)
    473  1.1     ragge 			len = maxlen;
    474  1.4  christos 		bcopy((void *)data->nd_cmdref, pkt, len);
    475  1.1     ragge 		bd->nb_pte = (int)&syspte[data->nd_cmdref>>9];
    476  1.1     ragge 		data->bufs[0]._len = bd->nb_len = 2048;
    477  1.1     ragge 		data->bufs[0]._offset = 0;
    478  1.1     ragge 		data->bufs[0]._key = 1;
    479  1.1     ragge 		bd->nb_status = NIBD_VALID;
    480  1.1     ragge 		bd->nb_key = 1;
    481  1.1     ragge 		data->nd_len = RXADD;
    482  1.1     ragge 		data->nd_status = 0;
    483  1.1     ragge 		insput(data, &fqb->nf_rforw,
    484  1.1     ragge 		    PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
    485  1.1     ragge 		return len;
    486  1.1     ragge 
    487  1.1     ragge 	case BVP_DGRAM:
    488  1.1     ragge 		insput(data, &fqb->nf_dforw, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
    489  1.1     ragge 		break;
    490  1.1     ragge 	default:
    491  1.1     ragge 		insput(data, &fqb->nf_mforw, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
    492  1.1     ragge 		break;
    493  1.1     ragge 	}
    494  1.1     ragge 
    495  1.1     ragge 	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~(PSR_OWN|PSR_RSQ));
    496  1.1     ragge 	goto loop;
    497  1.1     ragge }
    498  1.1     ragge 
    499  1.1     ragge int
    500  1.1     ragge ni_put(struct iodesc *desc, void *pkt, size_t len)
    501  1.1     ragge {
    502  1.1     ragge 	struct ni_dg *data;
    503  1.1     ragge 	struct ni_bbd *bdp;
    504  1.1     ragge 
    505  1.1     ragge 	data = REMQHI(&fqb->nf_dforw);
    506  1.1     ragge #ifdef NIDEBUG
    507  1.1     ragge 	if (data == 0) {
    508  1.1     ragge 		printf("ni_put: driver problem, data == 0\n");
    509  1.1     ragge 		return -1;
    510  1.1     ragge 	}
    511  1.1     ragge #endif
    512  1.1     ragge 	bdp = &bbd[(data->bufs[0]._index & 0x7fff)];
    513  1.1     ragge 	bdp->nb_status = NIBD_VALID;
    514  1.1     ragge 	bdp->nb_len = (len < 64 ? 64 : len);
    515  1.4  christos 	bcopy(pkt, (void *)data->nd_cmdref, len);
    516  1.1     ragge 	data->bufs[0]._offset = 0;
    517  1.1     ragge 	data->bufs[0]._len = bdp->nb_len;
    518  1.1     ragge 	data->nd_opcode = BVP_DGRAM;
    519  1.1     ragge 	data->nd_pad3 = 1;
    520  1.1     ragge 	data->nd_ptdbidx = 1;
    521  1.1     ragge 	data->nd_len = 18;
    522  1.1     ragge 	insput(data, &gvp->nc_forw0, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
    523  1.1     ragge 	return len;
    524  1.1     ragge }
    525  1.1     ragge 
    526  1.1     ragge int
    527  1.1     ragge niclose(struct open_file *f)
    528  1.1     ragge {
    529  1.1     ragge 	if (beenhere) {
    530  1.1     ragge 		WAITREG(NI_PCR, PCR_OWN);
    531  1.1     ragge 		NI_WREG(NI_PCR, PCR_OWN|PCR_SHUTDOWN);
    532  1.1     ragge 		WAITREG(NI_PCR, PCR_OWN);
    533  1.1     ragge 	}
    534  1.1     ragge 	return 0;
    535  1.1     ragge }
    536