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