Exemplo n.º 1
0
/*
*
* 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);
}