Example #1
0
void pe_err(int rc, const char* fmt, ...)
{
  va_list(ap);
  va_start(ap, fmt);
  char message[1024];
  vsnprintf(message, sizeof message, fmt, ap);
  va_end(ap);
  failtest( message);
}
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.
 */
static void
niattach(device_t parent, device_t self, void *aux)
{
	struct bi_attach_args *ba = aux;
	struct ni_softc *sc = device_private(self);
	struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
	struct ni_msg *msg;
	struct ni_ptdb *ptdb;
	void *va;
	int i, j, s, res;
	u_short type;

	sc->sc_dev = self;

	type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE);
	printf(": DEBN%c\n", type == BIDT_DEBNA ? 'A' : type == BIDT_DEBNT ?
	    'T' : 'K');
	sc->sc_iot = ba->ba_iot;
	sc->sc_ioh = ba->ba_ioh;
	sc->sc_dmat = ba->ba_dmat;

	bi_intr_establish(ba->ba_icookie, ba->ba_ivec,
		niintr, sc, &sc->sc_intrcnt);
	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
		device_xname(self), "intr");

	ni_getpgs(sc, sizeof(struct ni_gvppqb), (void **)&sc->sc_gvppqb,
	    (paddr_t *)&sc->sc_pgvppqb);
	ni_getpgs(sc, sizeof(struct ni_fqb), (void **)&sc->sc_fqb, 0);
	ni_getpgs(sc, NBDESCS * sizeof(struct ni_bbd),
	    (void **)&sc->sc_bbd, 0);
	/*
	 * Zero the newly allocated memory.
	 */

	nipqb->np_veclvl = (ba->ba_ivec << 2) + 2;
	nipqb->np_node = ba->ba_intcpu;
	nipqb->np_vpqb = (u_int32_t)gvp;
#ifdef __vax__
	nipqb->np_spt = nipqb->np_gpt = mfpr(PR_SBR);
	nipqb->np_sptlen = nipqb->np_gptlen = mfpr(PR_SLR);
#else
#error Must fix support for non-vax.
#endif
	nipqb->np_bvplvl = 1;
	nipqb->np_vfqb = (u_int32_t)fqb;
	nipqb->np_vbdt = (u_int32_t)bbd;
	nipqb->np_nbdr = NBDESCS;

	/* Free queue block */
	nipqb->np_freeq = NQUEUES;
	fqb->nf_mlen = PKTHDR+MSGADD;
	fqb->nf_dlen = PKTHDR+TXADD;
	fqb->nf_rlen = PKTHDR+RXADD;

	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_start = nistart;
	ifp->if_ioctl = niioctl;
	ifp->if_watchdog = nitimeout;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * Start init sequence.
	 */

	/* Reset the node */
	NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
	DELAY(500000);
	i = 20;
	while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
		DELAY(500000);
	if (i == 0) {
		printf("%s: BROKE bit set after reset\n", device_xname(self));
		return;
	}

	/* Check state */
	if (failtest(sc, NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
		return;

	/* Clear owner bits */
	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
	NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);

	/* kick off init */
	NI_WREG(NI_PCR, (u_int32_t)sc->sc_pgvppqb | PCR_INIT | PCR_OWN);
	while (NI_RREG(NI_PCR) & PCR_OWN)
		DELAY(100000);

	/* Check state */
	if (failtest(sc, NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
		return;

	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);

	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE);
	WAITREG(NI_PCR, PCR_OWN);
	WAITREG(NI_PSR, PSR_OWN);

	/* Check state */
	if (failtest(sc, NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
		return;

	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);

	/*
	 * The message queue packets must be located on the beginning
	 * of a page. A VAX page is 512 bytes, but it clusters 8 pages.
	 * This knowledge is used here when allocating pages.
	 * !!! How should this be done on MIPS and Alpha??? !!!
	 */
#if NBPG < 4096
#error pagesize too small
#endif
	s = splvm();
	/* Set up message free queue */
	ni_getpgs(sc, NMSGBUF * 512, &va, 0);
	for (i = 0; i < NMSGBUF; i++) {
		msg = (void *)((char *)va + i * 512);
		res = INSQTI(msg, &fqb->nf_mforw);
	}
	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* Set up xmit queue */
	ni_getpgs(sc, NTXBUF * 512, &va, 0);
	for (i = 0; i < NTXBUF; i++) {
		struct ni_dg *data;

		data = (void *)((char *)va + i * 512);
		data->nd_status = 0;
		data->nd_len = TXADD;
		data->nd_ptdbidx = 1;
		data->nd_opcode = BVP_DGRAM;
		for (j = 0; j < NTXFRAGS; j++) {
			data->bufs[j]._offset = 0;
			data->bufs[j]._key = 1;
			bbd[i * NTXFRAGS + j].nb_key = 1;
			bbd[i * NTXFRAGS + j].nb_status = 0;
			data->bufs[j]._index = i * NTXFRAGS + j;
		}
		res = INSQTI(data, &fqb->nf_dforw);
	}
	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* recv buffers */
	ni_getpgs(sc, NRXBUF * 512, &va, 0);
	for (i = 0; i < NRXBUF; i++) {
		struct ni_dg *data;
		int idx;

		data = (void *)((char *)va + i * 512);
		data->nd_len = RXADD;
		data->nd_opcode = BVP_DGRAMRX;
		data->nd_ptdbidx = 2;
		data->bufs[0]._key = 1;

		idx = NTXBUF * NTXFRAGS + i;
		if (ni_add_rxbuf(sc, data, idx))
			panic("niattach: ni_add_rxbuf: out of mbufs");

		res = INSQTI(data, &fqb->nf_rforw);
	}
	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	splx(s);

	/* Set initial parameters */
	msg = REMQHI(&fqb->nf_mforw);

	msg->nm_opcode = BVP_MSG;
	msg->nm_status = 0;
	msg->nm_len = sizeof(struct ni_param) + 6;
	msg->nm_opcode2 = NI_WPARAM;
	((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD;

	endwait = retry = 0;
	res = INSQTI(msg, &gvp->nc_forw0);

retry:	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);
	i = 1000;
	while (endwait == 0 && --i)
		DELAY(10000);

	if (endwait == 0) {
		if (++retry < 3)
			goto retry;
		printf("%s: no response to set params\n", device_xname(self));
		return;
	}

	/* Clear counters */
	msg = REMQHI(&fqb->nf_mforw);
	msg->nm_opcode = BVP_MSG;
	msg->nm_status = 0;
	msg->nm_len = sizeof(struct ni_param) + 6;
	msg->nm_opcode2 = NI_RCCNTR;

	res = INSQTI(msg, &gvp->nc_forw0);

	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* Enable transmit logic */
	msg = REMQHI(&fqb->nf_mforw);

	msg->nm_opcode = BVP_MSG;
	msg->nm_status = 0;
	msg->nm_len = 18;
	msg->nm_opcode2 = NI_STPTDB;
	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
	memset(ptdb, 0, sizeof(struct ni_ptdb));
	ptdb->np_index = 1;
	ptdb->np_fque = 1;

	res = INSQTI(msg, &gvp->nc_forw0);

	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* Wait for everything to finish */
	WAITREG(NI_PSR, PSR_OWN);

	printf("%s: hardware address %s\n", device_xname(self),
	    ether_sprintf(sc->sc_enaddr));

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_enaddr);
	if (shutdownhook_establish(ni_shutdown, sc) == 0)
		aprint_error_dev(self, "WARNING: unable to establish shutdown hook\n");
}