コード例 #1
0
ファイル: if_il.c プロジェクト: yazshel/netbsd-kernel
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.  A STATUS command is done to get the ethernet
 * address and other interesting data.
 */
void
ilattach(device_t parent, device_t self, void *aux)
{
	struct uba_attach_args *ua = aux;
	struct il_softc *sc = device_private(self);
	struct ifnet *ifp = &sc->sc_if;
	int error;

	sc->sc_dev = self;
	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	/*
	 * Map interrupt vectors and reset function.
	 */
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec, ilcint,
	    sc, &sc->sc_cintrcnt);
	evcnt_attach_dynamic(&sc->sc_cintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    device_xname(sc->sc_dev), "intr");
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec-4, ilrint,
	    sc, &sc->sc_rintrcnt);
	evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    device_xname(sc->sc_dev), "intr");
	uba_reset_establish(ilreset, sc->sc_dev);

	/*
	 * Reset the board and map the statistics
	 * buffer onto the Unibus.
	 */
	IL_WCSR(IL_CSR, ILC_RESET);
	(void)ilwait(sc, "reset");
	sc->sc_ui.ui_size = sizeof(struct il_stats);
	sc->sc_ui.ui_vaddr = (void *)&sc->sc_stats;
	if ((error = uballoc(device_private(parent), &sc->sc_ui, 0)))
		return printf(": failed uballoc, error = %d\n", error);

	IL_WCSR(IL_BAR, LOWORD(sc->sc_ui.ui_baddr));
	IL_WCSR(IL_BCR, sizeof(struct il_stats));
	IL_WCSR(IL_CSR, ((sc->sc_ui.ui_baddr >> 2) & IL_EUA)|ILC_STAT);
	(void)ilwait(sc, "status");
	ubfree(device_private(parent), &sc->sc_ui);
	printf("%s: module=%s firmware=%s\n", device_xname(sc->sc_dev),
		sc->sc_stats.ils_module, sc->sc_stats.ils_firmware);
	printf("%s: hardware address %s\n", device_xname(sc->sc_dev),
		ether_sprintf(sc->sc_stats.ils_addr));

	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST;
	ifp->if_init = ilinit;
	ifp->if_stop = ilstop;
	ifp->if_ioctl = ether_ioctl;
	ifp->if_start = ilstart;
	ifp->if_watchdog = ilwatch;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_stats.ils_addr);
}
コード例 #2
0
ファイル: uba.c プロジェクト: orumin/openbsd-efivars
/*
 * Allocate DMA-able memory and map it on the unibus.
 */
int
ubmemalloc(struct uba_softc *uh, struct ubinfo *ui, int flags)
{
	int waitok = (flags & UBA_CANTWAIT ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
	int error;

	if ((error = bus_dmamem_alloc(uh->uh_dmat, ui->ui_size, NBPG, 0,
	    &ui->ui_seg, 1, &ui->ui_rseg, waitok)))
		return error;
	if ((error = bus_dmamem_map(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg,
	    ui->ui_size, &ui->ui_vaddr, waitok|BUS_DMA_COHERENT))) {
		bus_dmamem_free(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg);
		return error;
	}
	if ((error = uballoc(uh, ui, flags))) {
		bus_dmamem_unmap(uh->uh_dmat, ui->ui_vaddr, ui->ui_size);
		bus_dmamem_free(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg);
	}
	return error;
}
コード例 #3
0
ファイル: if_dmc.c プロジェクト: ryoon/netbsd-xhci
/*
 * Initialization of interface; reinitialize UNIBUS usage.
 */
int
dmcinit(struct ifnet *ifp)
{
	struct dmc_softc *sc = ifp->if_softc;
	struct ifrw *ifrw;
	struct ifxmt *ifxp;
	struct dmcbufs *rp;
	struct dmc_command *qp;
	struct ifaddr *ifa;
	cfdata_t ui = device_cfdata(sc->sc_dev);
	int base;
	int s;

	/*
	 * Check to see that an address has been set
	 * (both local and destination for an address family).
	 */
	IFADDR_FOREACH(ifa, ifp)
		if (ifa->ifa_addr->sa_family && ifa->ifa_dstaddr->sa_family)
			break;
	if (ifa == (struct ifaddr *) 0)
		return 0;

	if ((DMC_RBYTE(DMC_BSEL1) & DMC_RUN) == 0) {
		printf("dmcinit: DMC not running\n");
		ifp->if_flags &= ~IFF_UP;
		return 0;
	}
	/* map base table */
	if ((sc->sc_flag & DMC_BMAPPED) == 0) {
		sc->sc_ui.ui_size = sizeof(struct dmc_base);
		sc->sc_ui.ui_vaddr = (void *)&sc->dmc_base;
		uballoc(device_private(device_parent(sc->sc_dev)), &sc->sc_ui, 0);
		sc->sc_flag |= DMC_BMAPPED;
	}
	/* initialize UNIBUS resources */
	sc->sc_iused = sc->sc_oused = 0;
	if ((ifp->if_flags & IFF_RUNNING) == 0) {
		if (if_ubaminit(&sc->sc_ifuba,
		    device_private(device_parent(sc->sc_dev)),
		    sizeof(struct dmc_header) + DMCMTU,
		    sc->sc_ifr, NRCV, sc->sc_ifw, NXMT) == 0) {
			aprint_error_dev(sc->sc_dev, "can't allocate uba resources\n");
			ifp->if_flags &= ~IFF_UP;
			return 0;
		}
		ifp->if_flags |= IFF_RUNNING;
	}
	sc->sc_flag &= ~DMC_ONLINE;
	sc->sc_flag |= DMC_RUNNING;
	/*
	 * Limit packets enqueued until we see if we're on the air.
	 */
	ifp->if_snd.ifq_maxlen = 3;

	/* initialize buffer pool */
	/* receives */
	ifrw = &sc->sc_ifr[0];
	for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
		rp->ubinfo = ifrw->ifrw_info;
		rp->cc = DMCMTU + sizeof (struct dmc_header);
		rp->flags = DBUF_OURS|DBUF_RCV;
		ifrw++;
	}
	/* transmits */
	ifxp = &sc->sc_ifw[0];
	for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++) {
		rp->ubinfo = ifxp->ifw_info;
		rp->cc = 0;
		rp->flags = DBUF_OURS|DBUF_XMIT;
		ifxp++;
	}

	/* set up command queues */
	sc->sc_qfreeh = sc->sc_qfreet
		 = sc->sc_qhead = sc->sc_qtail = sc->sc_qactive =
		(struct dmc_command *)0;
	/* set up free command buffer list */
	for (qp = &sc->sc_cmdbuf[0]; qp < &sc->sc_cmdbuf[NCMDS]; qp++) {
		QUEUE_AT_HEAD(qp, sc->sc_qfreeh, sc->sc_qfreet);
	}

	/* base in */
	base = sc->sc_ui.ui_baddr;
	dmcload(sc, DMC_BASEI, (u_short)base, (base>>2) & DMC_XMEM);
	/* specify half duplex operation, flags tell if primary */
	/* or secondary station */
	if (ui->cf_flags == 0)
		/* use DDCMP mode in full duplex */
		dmcload(sc, DMC_CNTLI, 0, 0);
	else if (ui->cf_flags == 1)
		/* use MAINTENENCE mode */
		dmcload(sc, DMC_CNTLI, 0, DMC_MAINT );
	else if (ui->cf_flags == 2)
		/* use DDCMP half duplex as primary station */
		dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX);
	else if (ui->cf_flags == 3)
		/* use DDCMP half duplex as secondary station */
		dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX | DMC_SEC);

	/* enable operation done interrupts */
	while ((DMC_RBYTE(DMC_BSEL2) & DMC_IEO) == 0)
		DMC_WBYTE(DMC_BSEL2, DMC_RBYTE(DMC_BSEL2) | DMC_IEO);
	s = splnet();
	/* queue first NRCV buffers for DMC to fill */
	for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
		rp->flags |= DBUF_DMCS;
		dmcload(sc, DMC_READ, rp->ubinfo,
			(((rp->ubinfo>>2)&DMC_XMEM) | rp->cc));
		sc->sc_iused++;
	}
	splx(s);
	return 0;
}
コード例 #4
0
ファイル: if_qe.c プロジェクト: ryoon/netbsd-xhci
/*
 * Check for present DEQNA. Done by sending a fake setup packet
 * and wait for interrupt.
 */
int
qematch(device_t parent, cfdata_t cf, void *aux)
{
	struct	qe_softc ssc;
	struct	qe_softc *sc = &ssc;
	struct	uba_attach_args *ua = aux;
	struct	uba_softc *uh = device_private(parent);
	struct ubinfo ui;

#define	PROBESIZE	4096
	struct qe_ring *ring;
	struct	qe_ring *rp;
	int error, match;

	ring = malloc(PROBESIZE, M_TEMP, M_WAITOK|M_ZERO);
	memset(sc, 0, sizeof(*sc));
	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	uh->uh_lastiv -= 4;
	QE_WCSR(QE_CSR_CSR, QE_RESET);
	QE_WCSR(QE_CSR_VECTOR, uh->uh_lastiv);

	/*
	 * Map the ring area. Actually this is done only to be able to
	 * send and receive a internal packet; some junk is loopbacked
	 * so that the DEQNA has a reason to interrupt.
	 */
	ui.ui_size = PROBESIZE;
	ui.ui_vaddr = (void *)&ring[0];
	if ((error = uballoc(uh, &ui, UBA_CANTWAIT))) {
		match = 0;
		goto out0;
	}

	/*
	 * Init a simple "fake" receive and transmit descriptor that
	 * points to some unused area. Send a fake setup packet.
	 */
	rp = (void *)ui.ui_baddr;
	ring[0].qe_flag = ring[0].qe_status1 = QE_NOTYET;
	ring[0].qe_addr_lo = LOWORD(&rp[4]);
	ring[0].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID | QE_EOMSG | QE_SETUP;
	ring[0].qe_buf_len = -64;

	ring[2].qe_flag = ring[2].qe_status1 = QE_NOTYET;
	ring[2].qe_addr_lo = LOWORD(&rp[4]);
	ring[2].qe_addr_hi = HIWORD(&rp[4]) | QE_VALID;
	ring[2].qe_buf_len = -(1500/2);

	QE_WCSR(QE_CSR_CSR, QE_RCSR(QE_CSR_CSR) & ~QE_RESET);
	DELAY(1000);

	/*
	 * Start the interface and wait for the packet.
	 */
	QE_WCSR(QE_CSR_CSR, QE_INT_ENABLE|QE_XMIT_INT|QE_RCV_INT);
	QE_WCSR(QE_CSR_RCLL, LOWORD(&rp[2]));
	QE_WCSR(QE_CSR_RCLH, HIWORD(&rp[2]));
	QE_WCSR(QE_CSR_XMTL, LOWORD(rp));
	QE_WCSR(QE_CSR_XMTH, HIWORD(rp));
	DELAY(10000);

	match = 1;

	/*
	 * All done with the bus resources.
	 */
	ubfree(uh, &ui);
out0:	free(ring, M_TEMP);
	return match;
}
コード例 #5
0
ファイル: if_il.c プロジェクト: yazshel/netbsd-kernel
/*
 * Initialization of interface; clear recorded pending
 * operations, and reinitialize UNIBUS usage.
 */
int
ilinit(struct ifnet *ifp)
{
	struct il_softc *sc = ifp->if_softc;
	int s;

	if (sc->sc_flags & ILF_RUNNING)
		return 0;

	if ((ifp->if_flags & IFF_RUNNING) == 0) {
		if (if_ubainit(&sc->sc_ifuba,
		    device_private(device_parent(sc->sc_dev)),
		    ETHER_MAX_LEN)) {
			aprint_error_dev(sc->sc_dev, "can't initialize\n");
			sc->sc_if.if_flags &= ~IFF_UP;
			return 0;
		}
		sc->sc_ui.ui_size = sizeof(sc->sc_isu);
		sc->sc_ui.ui_vaddr = (void *)&sc->sc_isu;
		uballoc(device_private(device_parent(sc->sc_dev)), &sc->sc_ui, 0);
	}
	sc->sc_scaninterval = ILWATCHINTERVAL;
	ifp->if_timer = sc->sc_scaninterval;

	/*
	 * Turn off source address insertion (it's faster this way),
	 * and set board online.  Former doesn't work if board is
	 * already online (happens on ubareset), so we put it offline
	 * first.
	 */
	s = splnet();
	IL_WCSR(IL_CSR, ILC_RESET);
	if (ilwait(sc, "hardware diag")) {
		sc->sc_if.if_flags &= ~IFF_UP;
		goto out;
	}
	IL_WCSR(IL_CSR, ILC_CISA);
	while ((IL_RCSR(IL_CSR) & IL_CDONE) == 0)
		;
	/*
	 * If we must reprogram this board's physical ethernet
	 * address (as for secondary XNS interfaces), we do so
	 * before putting it on line, and starting receive requests.
	 * If you try this on an older 1010 board, it will total
	 * wedge the board.
	 */
	if (sc->sc_flags & ILF_SETADDR) {
		memcpy(&sc->sc_isu, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
		IL_WCSR(IL_BAR, LOWORD(sc->sc_ui.ui_baddr));
		IL_WCSR(IL_BCR, ETHER_ADDR_LEN);
		IL_WCSR(IL_CSR, ((sc->sc_ui.ui_baddr >> 2) & IL_EUA)|ILC_LDPA);
		if (ilwait(sc, "setaddr"))
			goto out;
		IL_WCSR(IL_BAR, LOWORD(sc->sc_ui.ui_baddr));
		IL_WCSR(IL_BCR, sizeof (struct il_stats));
		IL_WCSR(IL_CSR, ((sc->sc_ui.ui_baddr >> 2) & IL_EUA)|ILC_STAT);
		if (ilwait(sc, "verifying setaddr"))
			goto out;
		if (memcmp(sc->sc_stats.ils_addr,
		    CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN) != 0) {
			aprint_error_dev(sc->sc_dev, "setaddr didn't work\n");
			goto out;
		}
	}