/* * * Handle an interrupt from the Ethernet MAC when configured with scatter-gather * DMA. The only interrupts handled in this case are errors. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * * @return * * None. * * @note * * None. * ******************************************************************************/ static void HandleEmacDmaIntr(XEmac * InstancePtr) { u32 IntrStatus; /* * When configured with DMA, the EMAC generates interrupts only when errors * occur. We clear the interrupts immediately so that any latched status * interrupt bits will reflect the true status of the device, and so any * pulsed interrupts (non-status) generated during the Isr will not be lost. */ IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress); XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, IntrStatus); /* * Check the MAC for errors */ XEmac_CheckEmacError(InstancePtr, IntrStatus); }
/****************************************************************************** * * Handle an interrupt from the Ethernet MAC when configured for direct FIFO * communication. The interrupts handled are: * - Transmit done (transmit status FIFO is non-empty). Used to determine when * a transmission has been completed. * - Receive done (receive length FIFO is non-empty). Used to determine when a * valid frame has been received. * * In addition, the interrupt status is checked for errors. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * * @return * * None. * * @note * * None. * ******************************************************************************/ static void HandleEmacFifoIntr(XEmac * InstancePtr) { u32 IntrStatus; /* * The EMAC generates interrupts for errors and generates the transmit * and receive done interrupts for data. We clear the interrupts * immediately so that any latched status interrupt bits will reflect the * true status of the device, and so any pulsed interrupts (non-status) * generated during the Isr will not be lost. */ IntrStatus = XEMAC_READ_IISR(InstancePtr->BaseAddress); XEMAC_WRITE_IISR(InstancePtr->BaseAddress, IntrStatus); if (IntrStatus & XEM_EIR_RECV_DONE_MASK) { /* * Configured for direct memory-mapped I/O using FIFO with interrupts. * This interrupt means the RPLR is non-empty, indicating a frame has * arrived. */ InstancePtr->Stats.RecvInterrupts++; InstancePtr->FifoRecvHandler(InstancePtr->FifoRecvRef); /* * The upper layer has removed as many frames as it wants to, so we * need to clear the RECV_DONE bit before leaving the ISR so that it * reflects the current state of the hardware (because it's a level * interrupt that is latched in the IPIF interrupt status register). * Note that if we've reached this point the bit is guaranteed to be * set because it was cleared at the top of this ISR before any frames * were serviced, so the bit was set again immediately by hardware * because the RPLR was not yet emptied by software. */ XEMAC_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_RECV_DONE_MASK); } /* * If configured for direct memory-mapped I/O using FIFO, the xmit status * FIFO must be read and the callback invoked regardless of success or not. */ if (IntrStatus & XEM_EIR_XMIT_DONE_MASK) { u32 XmitStatus; InstancePtr->Stats.XmitInterrupts++; XmitStatus = XIo_In32(InstancePtr->BaseAddress + XEM_TSR_OFFSET); /* * Collision errors are stored in the transmit status register * instead of the interrupt status register */ if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK) { InstancePtr->Stats.XmitExcessDeferral++; } if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK) { InstancePtr->Stats.XmitLateCollisionErrors++; } InstancePtr->FifoSendHandler(InstancePtr->FifoSendRef); /* * Only one status is retrieved per interrupt. We need to clear the * XMIT_DONE bit before leaving the ISR so that it reflects the current * state of the hardware (because it's a level interrupt that is latched * in the IPIF interrupt status register). Note that if we've reached * this point the bit is guaranteed to be set because it was cleared at * the top of this ISR before any statuses were serviced, so the bit was * set again immediately by hardware because the TSR was not yet emptied * by software. */ XEMAC_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_XMIT_DONE_MASK); } /* * Check the MAC for errors */ XEmac_CheckEmacError(InstancePtr, IntrStatus); }