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