/* * 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; }
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); }
/* * 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; }