/* * 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 xlights_intr(void *v) { struct xlights_softc *sc = (struct xlights_softc *)v; int status; dbdma_command_t *cmd; cmd = sc->sc_dmacmd; status = dbdma_ld16(&cmd->d_status); if (sc->sc_dmasts) { sc->sc_dmasts = 0; timeout_del(&sc->sc_tmo); wakeup(sc->sc_buf); return (1); } return (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); }
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); }