/** * Receive packet interrupt handler. */ void rxPackets(struct ether *ethptr, struct ag71xx *nicptr) { struct dmaDescriptor *dmaptr; struct ethPktBuffer *pkt = NULL; int head = 0; while (1) { head = ethptr->rxHead % ETH_RX_RING_ENTRIES; dmaptr = ðptr->rxRing[head]; if (dmaptr->control & ETH_DESC_CTRL_EMPTY) { nicptr->rxStatus = RX_STAT_RECVD; break; } pkt = ethptr->rxBufs[head]; pkt->length = dmaptr->control & ETH_DESC_CTRL_LEN; if (ethptr->icount < ETH_IBLEN) { allocRxBuffer(ethptr, head); ethptr->in[(ethptr->istart + ethptr->icount) % ETH_IBLEN] = pkt; ethptr->icount++; signaln(ethptr->isema, 1); } else { ethptr->ovrrun++; bzero(pkt->buf, pkt->length); } ethptr->rxHead++; // Clear Rx interrupt. nicptr->rxStatus = RX_STAT_RECVD; // FIXME break; } }
/*------------------------------------------------------------------------ * rxPackets - handler for receiver interrupts *------------------------------------------------------------------------ */ void rxPackets ( struct ether *ethptr, /* ptr to control block */ struct ag71xx *nicptr /* ptr to device CSRs */ ) { struct dmaDescriptor *dmaptr; /* ptr to DMA descriptor */ struct ethPktBuffer *pkt; /* ptr to one packet buffer */ int32 head; /* Move to next packet, wrapping around if needed */ head = ethptr->rxHead % ETH_RX_RING_ENTRIES; dmaptr = ðptr->rxRing[head]; if (dmaptr->control & ETH_DESC_CTRL_EMPTY) { nicptr->rxStatus = RX_STAT_RECVD; return; } pkt = ethptr->rxBufs[head]; pkt->length = dmaptr->control & ETH_DESC_CTRL_LEN; if (ethptr->icount < ETH_IBUFSIZ) { allocRxBuffer(ethptr, head); ethptr->in[(ethptr->istart + ethptr->icount) % ETH_IBUFSIZ] = pkt; ethptr->icount++; signal(ethptr->isema); } else { ethptr->ovrrun++; memset(pkt->buf, '\0', pkt->length); } ethptr->rxHead++; /* Clear the Rx interrupt */ nicptr->rxStatus = RX_STAT_RECVD; return; }