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
/*
 * 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;
}
Exemplo n.º 3
0
int
bmac_rint(void *v)
{
	struct bmac_softc *sc = v;
	struct ifnet *ifp = &sc->arpcom.ac_if;
	struct mbuf *m;
	dbdma_command_t *cmd;
	int status, resid, count, datalen;
	int i, n;
	void *data;
#ifdef BMAC_DEBUG
	printf("bmac_rint() called\n");
#endif

	i = sc->sc_rxlast;
	for (n = 0; n < BMAC_RXBUFS; n++, i++) {
		if (i == BMAC_RXBUFS)
			i = 0;
		cmd = &sc->sc_rxcmd[i];
		status = dbdma_ld16(&cmd->d_status);
		resid = dbdma_ld16(&cmd->d_resid);

#ifdef BMAC_DEBUG
		if (status != 0 && status != 0x8440 && status != 0x9440)
			printf("bmac_rint status = 0x%x\n", status);
#endif

		if ((status & DBDMA_CNTRL_ACTIVE) == 0)	/* 0x9440 | 0x8440 */
			continue;
		count = dbdma_ld16(&cmd->d_count);
		datalen = count - resid;		/* 2 == framelen */
		if (datalen < sizeof(struct ether_header)) {
			printf("%s: short packet len = %d\n",
				ifp->if_xname, datalen);
			goto next;
		}
		DBDMA_BUILD_CMD(cmd, DBDMA_CMD_STOP, 0, 0, 0, 0);
		data = sc->sc_rxbuf + BMAC_BUFLEN * i;

		/* XXX Sometimes bmac reads one extra byte. */
		if (datalen == ETHER_MAX_LEN + 1)
			datalen--;

		/* Trim the CRC. */
		datalen -= ETHER_CRC_LEN;

		m = bmac_get(sc, data, datalen);
		if (m == NULL) {
			ifp->if_ierrors++;
			goto next;
		}

#if NBPFILTER > 0
		/*
		 * Check if there's a BPF listener on this interface.
		 * If so, hand off the raw packet to BPF.
		 */
		if (ifp->if_bpf)
			bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
#endif
		ether_input_mbuf(ifp, m);
		ifp->if_ipackets++;

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_rxlast = i + 1;
	}
	dbdma_continue(sc->sc_rxdma);

	return (1);
}
Exemplo n.º 4
0
int
bmac_rint(void *v)
{
	struct bmac_softc *sc = v;
	struct ifnet *ifp = &sc->arpcom.ac_if;
	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
	struct mbuf *m;
	dbdma_command_t *cmd;
	int status, resid, count, datalen;
	int i, n;
	void *data;
#ifdef BMAC_DEBUG
	printf("bmac_rint() called\n");
#endif

	i = sc->sc_rxlast;
	for (n = 0; n < BMAC_RXBUFS; n++, i++) {
		if (i == BMAC_RXBUFS)
			i = 0;
		cmd = &sc->sc_rxcmd[i];
		status = dbdma_ld16(&cmd->d_status);
		resid = dbdma_ld16(&cmd->d_resid);

#ifdef BMAC_DEBUG
		if (status != 0 && status != 0x8440 && status != 0x9440)
			printf("bmac_rint status = 0x%x\n", status);
#endif

		if ((status & DBDMA_CNTRL_ACTIVE) == 0)	/* 0x9440 | 0x8440 */
			continue;
		count = dbdma_ld16(&cmd->d_count);
		datalen = count - resid;		/* 2 == framelen */
		if (datalen < sizeof(struct ether_header)) {
			printf("%s: short packet len = %d\n",
				ifp->if_xname, datalen);
			goto next;
		}
		DBDMA_BUILD_CMD(cmd, DBDMA_CMD_STOP, 0, 0, 0, 0);
		data = sc->sc_rxbuf + BMAC_BUFLEN * i;

		/* XXX Sometimes bmac reads one extra byte. */
		if (datalen == ETHER_MAX_LEN + 1)
			datalen--;

		/* Trim the CRC. */
		datalen -= ETHER_CRC_LEN;

		m = bmac_get(sc, data, datalen);
		if (m == NULL) {
			ifp->if_ierrors++;
			goto next;
		}

		ml_enqueue(&ml, m);

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_rxlast = i + 1;
	}
	bmac_mediachange(ifp);

	dbdma_continue(sc->sc_rxdma);

	if_input(ifp, &ml);
	return (1);
}