Exemplo n.º 1
0
/*
 * Interrupt handler for the MACE DMA completion interrupts
 */
int
mc_dmaintr(void *arg)
{
	struct mc_softc *sc = arg;
	int status, offset, statoff;
	int datalen, resid;
	int i, n, count;
	dbdma_command_t *cmd;

	/* We've received some packets from the MACE */
	/* Loop through, processing each of the packets */
	i = sc->sc_tail;
	for (n = 0; n < MC_RXDMABUFS; n++, i++) {
		if (i == MC_RXDMABUFS)
			i = 0;

		cmd = &sc->sc_rxdmacmd[i];
		status = dbdma_ld16(&cmd->d_status);
		resid = dbdma_ld16(&cmd->d_resid);

		if ((status & DBDMA_CNTRL_ACTIVE) == 0) {
			continue;
		}

		count = dbdma_ld16(&cmd->d_count);
		datalen = count - resid;
		datalen -= 4; /* 4 == status bytes */

		if (datalen < 4 + sizeof(struct ether_header)) {
			printf("short packet len=%d\n", datalen);
			/* continue; */
			goto next;
		}
		DBDMA_BUILD_CMD(cmd, DBDMA_CMD_STOP, 0, 0, 0, 0);

		offset = i * MACE_BUFLEN;
		statoff = offset + datalen;
		sc->sc_rxframe.rx_rcvcnt = sc->sc_rxbuf[statoff + 0];
		sc->sc_rxframe.rx_rcvsts = sc->sc_rxbuf[statoff + 1];
		sc->sc_rxframe.rx_rntpc  = sc->sc_rxbuf[statoff + 2];
		sc->sc_rxframe.rx_rcvcc  = sc->sc_rxbuf[statoff + 3];
		sc->sc_rxframe.rx_frame  = sc->sc_rxbuf + offset;

		mc_rint(sc);

next:
		DBDMA_BUILD_CMD(cmd, DBDMA_CMD_IN_LAST, 0, DBDMA_INT_ALWAYS,
		    DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);

		cmd->d_status = 0;
		cmd->d_resid = 0;
		sc->sc_tail = i + 1;
	}

	dbdma_continue(sc->sc_rxdma);

	return 1;
}
Exemplo n.º 2
0
int
mc_intr(void *arg)
{
	struct mc_softc *sc = arg;
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	u_int8_t ir;

	ir = NIC_GET(sc, MACE_IR) & ~NIC_GET(sc, MACE_IMR);

	if (ir & JAB) {
#ifdef MCDEBUG
		printf("%s: jabber error\n", sc->sc_dev.dv_xname);
#endif
		ifp->if_oerrors++;
	}

	if (ir & BABL) {
#ifdef MCDEBUG
		printf("%s: babble\n", sc->sc_dev.dv_xname);
#endif
		ifp->if_oerrors++;
	 }

	if (ir & CERR) {
#ifdef MCDEBUG
		printf("%s: collision error\n", sc->sc_dev.dv_xname);
#endif
		ifp->if_collisions++;
	 }

	/*
	 * Pretend we have carrier; if we don't this will be cleared
	 * shortly.
	 */
	sc->sc_havecarrier = 1;

	if (ir & XMTINT)
		mc_tint(sc);

	if (ir & RCVINT)
		mc_rint(sc);

	return(1);
}
Exemplo n.º 3
0
/*
 * Interrupt handler for the MACE DMA completion interrupts
 */
int
mc_dmaintr(void *arg)
{
	struct mc_softc *sc = arg;
	int status, offset, statoff;
	int datalen, resid;
	int i, n;
	dbdma_command_t *cmd;

	/* We've received some packets from the MACE */

	/* Loop through, processing each of the packets */
	i = sc->sc_tail;
	for (n = 0; n < MC_RXDMABUFS; n++, i++) {
		if (i == MC_RXDMABUFS)
			i = 0;

		cmd = &sc->sc_rxdmacmd[i];
		/* flushcache(cmd, sizeof(dbdma_command_t)); */
		status = in16rb(&cmd->d_status);
		resid = in16rb(&cmd->d_resid);

		/*if ((status & D_ACTIVE) == 0)*/
		if ((status & 0x40) == 0)
			continue;

#if 1
		if (in16rb(&cmd->d_count) != ETHERMTU + 22)
			printf("bad d_count\n");
#endif

		datalen = in16rb(&cmd->d_count) - resid;
		datalen -= 4;	/* 4 == status bytes */

		if (datalen < 4 + sizeof(struct ether_header)) {
			printf("short packet len=%d\n", datalen);
			/* continue; */
			goto next;
		}

		offset = i * MC_BUFSIZE;
		statoff = offset + datalen;

		DBDMA_BUILD_CMD(cmd, DBDMA_CMD_STOP, 0, 0, 0, 0);
		__asm volatile("eieio");

		/* flushcache(sc->sc_rxbuf + offset, datalen + 4); */

		sc->sc_rxframe.rx_rcvcnt = sc->sc_rxbuf[statoff + 0];
		sc->sc_rxframe.rx_rcvsts = sc->sc_rxbuf[statoff + 1];
		sc->sc_rxframe.rx_rntpc  = sc->sc_rxbuf[statoff + 2];
		sc->sc_rxframe.rx_rcvcc  = sc->sc_rxbuf[statoff + 3];
		sc->sc_rxframe.rx_frame  = sc->sc_rxbuf + offset;

		mc_rint(sc);

next:
		DBDMA_BUILD_CMD(cmd, DBDMA_CMD_IN_LAST, 0, DBDMA_INT_ALWAYS,
			DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
		__asm volatile("eieio");
		cmd->d_status = 0;
		cmd->d_resid = 0;
		sc->sc_tail = i + 1;
	}

	dbdma_continue(sc->sc_rxdma);

	return 1;
}