xemac_intr_dma.c

来自「适合KS8695X」· C语言 代码 · 共 1,345 行 · 第 1/4 页

C
1,345
字号
* gather DMA.
*
* Get the interrupt status from the IpIf to determine the source of the
* interrupt.  The source can be: MAC, Recv Packet FIFO, Send Packet FIFO, Recv
* DMA channel, or Send DMA channel. The packet FIFOs only interrupt during
* "deadlock" conditions.
*
* @param InstancePtr is a pointer to the XEmac instance that just interrupted.
*
* @return
*
* None.
*
* @note
*
* None.
*
******************************************************************************/
void
XEmac_IntrHandlerDma(void *InstancePtr)
{
	u32 IntrStatus;
	XEmac *EmacPtr = (XEmac *) InstancePtr;

	EmacPtr->Stats.TotalIntrs++;

	/*
	 * Get the interrupt status from the IPIF. There is no clearing of
	 * interrupts in the IPIF. Interrupts must be cleared at the source.
	 */
	IntrStatus = XIIF_V123B_READ_DIPR(EmacPtr->BaseAddress);

	/*
	 * See which type of interrupt is being requested, and service it
	 */
	if (IntrStatus & XEM_IPIF_RECV_DMA_MASK) {	/* Receive DMA interrupt */
		EmacPtr->Stats.RecvInterrupts++;
		HandleDmaRecvIntr(EmacPtr);
	}

	if (IntrStatus & XEM_IPIF_SEND_DMA_MASK) {	/* Send DMA interrupt */
		EmacPtr->Stats.XmitInterrupts++;
		HandleDmaSendIntr(EmacPtr);
	}

	if (IntrStatus & XEM_IPIF_EMAC_MASK) {	/* MAC interrupt */
		EmacPtr->Stats.EmacInterrupts++;
		HandleEmacDmaIntr(EmacPtr);
	}

	if (IntrStatus & XEM_IPIF_RECV_FIFO_MASK) {	/* Receive FIFO interrupt */
		EmacPtr->Stats.RecvInterrupts++;
		XEmac_CheckFifoRecvError(EmacPtr);
	}

	if (IntrStatus & XEM_IPIF_SEND_FIFO_MASK) {	/* Send FIFO interrupt */
		EmacPtr->Stats.XmitInterrupts++;
		XEmac_CheckFifoSendError(EmacPtr);
	}

	if (IntrStatus & XIIF_V123B_ERROR_MASK) {
		/*
		 * An error occurred internal to the IPIF. This is more of a debug and
		 * integration issue rather than a production error. Don't do anything
		 * other than clear it, which provides a spot for software to trap
		 * on the interrupt and begin debugging.
		 */
		XIIF_V123B_WRITE_DISR(EmacPtr->BaseAddress,
				      XIIF_V123B_ERROR_MASK);
	}
}

/*****************************************************************************/
/**
*
* Set the packet count threshold for this device. The device must be stopped
* before setting the threshold. The packet count threshold is used for interrupt
* coalescing, which reduces the frequency of interrupts from the device to the
* processor. In this case, the scatter-gather DMA engine only interrupts when
* the packet count threshold is reached, instead of interrupting for each packet.
* A packet is a generic term used by the scatter-gather DMA engine, and is
* equivalent to an Ethernet frame in our case.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Direction indicates the channel, send or receive, from which the
*        threshold register is read.
* @param Threshold is the value of the packet threshold count used during
*        interrupt coalescing. A value of 0 disables the use of packet threshold
*        by the hardware.
*
* @return
*
* - XST_SUCCESS if the threshold was successfully set
* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
* - XST_DEVICE_IS_STARTED if the device has not been stopped
* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
*   asserts would also catch this error.
*
* @note
*
* The packet threshold could be set to larger than the number of descriptors
* allocated to the DMA channel. In this case, the wait bound will take over
* and always indicate data arrival. There was a check in this function that
* returned an error if the treshold was larger than the number of descriptors,
* but that was removed because users would then have to set the threshold
* only after they set descriptor space, which is an order dependency that
* caused confustion.
*
******************************************************************************/
XStatus
XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold)
{
	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Be sure device is configured for scatter-gather DMA and has been stopped
	 */
	if (!XEmac_mIsSgDma(InstancePtr)) {
		return XST_NOT_SGDMA;
	}

	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
		return XST_DEVICE_IS_STARTED;
	}

	/*
	 * Based on the direction, set the packet threshold in the
	 * corresponding DMA channel component.  Default to the receive
	 * channel threshold register (if an invalid Direction is passed).
	 */
	switch (Direction) {
	case XEM_SEND:
		return XDmaChannel_SetPktThreshold(&InstancePtr->SendChannel,
						   Threshold);

	case XEM_RECV:
		return XDmaChannel_SetPktThreshold(&InstancePtr->RecvChannel,
						   Threshold);

	default:
		return XST_INVALID_PARAM;
	}
}

/*****************************************************************************/
/**
*
* Get the value of the packet count threshold for this driver/device. The packet
* count threshold is used for interrupt coalescing, which reduces the frequency
* of interrupts from the device to the processor. In this case, the
* scatter-gather DMA engine only interrupts when the packet count threshold is
* reached, instead of interrupting for each packet. A packet is a generic term
* used by the scatter-gather DMA engine, and is equivalent to an Ethernet frame
* in our case.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Direction indicates the channel, send or receive, from which the
*        threshold register is read.
* @param ThreshPtr is a pointer to the byte into which the current value of the
*        packet threshold register will be copied. An output parameter. A value
*        of 0 indicates the use of packet threshold by the hardware is disabled.
*
* @return
*
* - XST_SUCCESS if the packet threshold was retrieved successfully
* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
*   asserts would also catch this error.
*
* @note
*
* None.
*
******************************************************************************/
XStatus
XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 * ThreshPtr)
{
	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
	XASSERT_NONVOID(ThreshPtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	if (!XEmac_mIsSgDma(InstancePtr)) {
		return XST_NOT_SGDMA;
	}

	/*
	 * Based on the direction, return the packet threshold set in the
	 * corresponding DMA channel component.  Default to the value in
	 * the receive channel threshold register (if an invalid Direction
	 * is passed).
	 */
	switch (Direction) {
	case XEM_SEND:
		*ThreshPtr =
		    XDmaChannel_GetPktThreshold(&InstancePtr->SendChannel);
		break;

	case XEM_RECV:
		*ThreshPtr =
		    XDmaChannel_GetPktThreshold(&InstancePtr->RecvChannel);
		break;

	default:
		return XST_INVALID_PARAM;
	}

	return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* Set the packet wait bound timer for this driver/device. The device must be
* stopped before setting the timer value. The packet wait bound is used during
* interrupt coalescing to trigger an interrupt when not enough packets have been
* received to reach the packet count threshold. A packet is a generic term used
* by the scatter-gather DMA engine, and is equivalent to an Ethernet frame in
* our case. The timer is in milliseconds.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Direction indicates the channel, send or receive, from which the
*        threshold register is read.
* @param TimerValue is the value of the packet wait bound used during interrupt
*        coalescing. It is in milliseconds in the range 0  - 1023. A value of 0
*        disables the packet wait bound timer.
*
* @return
*
* - XST_SUCCESS if the packet wait bound was set successfully
* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
* - XST_DEVICE_IS_STARTED if the device has not been stopped
* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
*   asserts would also catch this error.
*
* @note
*
* None.
*
******************************************************************************/
XStatus
XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 TimerValue)
{
	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
	XASSERT_NONVOID(TimerValue <= XEM_SGDMA_MAX_WAITBOUND);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Be sure device is configured for scatter-gather DMA and has been stopped
	 */
	if (!XEmac_mIsSgDma(InstancePtr)) {
		return XST_NOT_SGDMA;
	}

	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
		return XST_DEVICE_IS_STARTED;
	}

	/*
	 * Based on the direction, set the packet wait bound in the
	 * corresponding DMA channel component.  Default to the receive
	 * channel wait bound register (if an invalid Direction is passed).
	 */
	switch (Direction) {
	case XEM_SEND:
		XDmaChannel_SetPktWaitBound(&InstancePtr->SendChannel,
					    TimerValue);
		break;

	case XEM_RECV:
		XDmaChannel_SetPktWaitBound(&InstancePtr->RecvChannel,
					    TimerValue);
		break;

	default:
		return XST_INVALID_PARAM;
	}

	return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* Get the packet wait bound timer for this driver/device. The packet wait bound
* is used during interrupt coalescing to trigger an interrupt when not enough
* packets have been received to reach the packet count threshold. A packet is a
* generic term used by the scatter-gather DMA engine, and is equivalent to an
* Ethernet frame in our case. The timer is in milliseconds.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Direction indicates the channel, send or receive, from which the
*        threshold register is read.
* @param WaitPtr is a pointer to the byte into which the current value of the
*        packet wait bound register will be copied. An output parameter. Units
*        are in milliseconds in the range 0  - 1023. A value of 0 indicates the
*        packet wait bound timer is disabled.
*
* @return
*
* - XST_SUCCESS if the packet wait bound was retrieved successfully
* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
*   asserts would also catch this error.
*
* @note
*
* None.
*
******************************************************************************/
XStatus
XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 * WaitPtr)
{
	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
	XASSERT_NONVOID(WaitPtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	if (!XEmac_mIsSgDma(InstancePtr)) {
		return XST_NOT_SGDMA;
	}

	/*
	 * Based on the direction, return the packet wait bound set in the
	 * corresponding DMA channel component.  Default to the value in
	 * the receive channel wait bound register (if an invalid Direction
	 * is passed).
	 */
	switch (Direction) {
	case XEM_SEND:
		*WaitPtr =
		    XDmaChannel_GetPktWaitBound(&InstancePtr->SendChannel);
		break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?