예제 #1
0
/**
 *
 * Disable FIFO related interrupts for FIFO direct frame transfer mode. Dma
 * interrupts are not affected.
 *
 * Do not use this function when using SG DMA frame transfer mode.
 *
 * @param InstancePtr is a pointer to the instance to be worked on.
 * @param Direction specifies whether the transmit related (XTE_SEND) or
 *        receive related (XTE_RECV) interrupts should be affected, or
 *        both (XTE_SEND | XTE_RECV).
 *
 * @return None
 *
 * @note The state of the transmitter and receiver are not modified by this
 *       function.
 *
 * @note If the device is configured for SGDMA, then this function has no
 *       effect. Use XTemac_IntrSgDmaDisable() instead.
 *
 ******************************************************************************/
void XTemac_IntrFifoDisable(XTemac * InstancePtr, u32 Direction)
{
	u32 RegIPIER;

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
	XASSERT_VOID(!(Direction & ~(XTE_SEND | XTE_RECV)));

	/* Don't allow if device is configured for SGDMA */
	if (XTemac_mIsSgDma(InstancePtr)) {
		return;
	}

	/* Get contents of IPIER register */
	RegIPIER = XTemac_mGetIpifReg(XTE_IPIER_OFFSET);

	/* Handle send direction */
	if (Direction & XTE_SEND) {
		RegIPIER &=
		    ~(XTE_IPXR_XMIT_ERROR_MASK | XTE_IPXR_XMIT_DONE_MASK);
		InstancePtr->Flags &= ~XTE_FLAGS_SEND_FIFO_INT_ENABLE;
	}

	/* Handle receive direction */
	if (Direction & XTE_RECV) {
		RegIPIER &=
		    ~(XTE_IPXR_RECV_ERROR_MASK | XTE_IPXR_RECV_DONE_MASK);
		InstancePtr->Flags &= ~XTE_FLAGS_RECV_FIFO_INT_ENABLE;
	}

	/* Update IPIER with new setting */
	XTemac_mSetIpifReg(XTE_IPIER_OFFSET, RegIPIER);
}
예제 #2
0
/**
 *
 * Enable FIFO related interrupts for FIFO direct frame transfer mode. Dma
 * interrupts are not affected.
 *
 * Do not use this function when using SG DMA frame transfer mode.
 *
 * @param InstancePtr is a pointer to the instance to be worked on.
 * @param Direction specifies whether the transmit related (XTE_SEND) or
 *        receive related (XTE_RECV) interrupts should be affected, or
 *        both (XTE_SEND | XTE_RECV).
 *
 * @return None
 *
 * @note The state of the transmitter and receiver are not modified by this
 *       function.
 *
 * @note If the device is configured for SGDMA, then this function has no
 *       effect. Use XTemac_IntrSgDmaDisable() instead.
 *
 ******************************************************************************/
void XTemac_IntrFifoEnable(XTemac * InstancePtr, u32 Direction)
{
	u32 RegIPIER;

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
	XASSERT_VOID(!(Direction & ~(XTE_SEND | XTE_RECV)));

	/* Don't allow if device is configured for SGDMA */
	if (XTemac_mIsSgDma(InstancePtr)) {
		return;
	}

	/* Get contents of IPIER register */
	RegIPIER = XTemac_mGetIpifReg(XTE_IPIER_OFFSET);

	/* Handle send direction */
	if (Direction & XTE_SEND) {
		RegIPIER |=
		    (XTE_IPXR_XMIT_ERROR_MASK | XTE_IPXR_XMIT_DONE_MASK);
		InstancePtr->Flags |= XTE_FLAGS_SEND_FIFO_INT_ENABLE;

		/* Don't allow Tx status overrun interrupt if option is cleared */
		if (!
		    (InstancePtr->
		     Options & XTE_REPORT_TXSTATUS_OVERRUN_OPTION)) {
			RegIPIER &= ~XTE_IPXR_XMIT_SFIFO_OVER_MASK;;
		}
	}

	/* Handle receive direction */
	if (Direction & XTE_RECV) {
		RegIPIER |=
		    (XTE_IPXR_RECV_ERROR_MASK | XTE_IPXR_RECV_DONE_MASK);
		InstancePtr->Flags |= XTE_FLAGS_RECV_FIFO_INT_ENABLE;

		/* Don't enable recv reject errors if option is cleared */
		if (!(InstancePtr->Options & XTE_REPORT_RXERR_OPTION)) {
			RegIPIER &= ~XTE_IPXR_RECV_DROPPED_MASK;
		}
	}

	/* Update IPIER with new setting */
	XTemac_mSetIpifReg(XTE_IPIER_OFFSET, RegIPIER);
}
예제 #3
0
/**
 * Give the driver memory space to be used for the scatter-gather DMA
 * descriptor list. This function should only be called once for each channel
 * during initialization. If a list had already been created, then it is
 * destroyed and replaced with a new one.
 *
 * To increase performance, a BdTemplate parameter is provided to allow the
 * user to permanently set BD fields in all BDs for this SGDMA channel. For
 * example, if every BD describes a buffer that will contain a full packet (as
 * it typically does with receive channels), then XDmaBdV2_mSetLast(BdTemplate)
 * can be performed prior to calling this function and when it returns, all BDs
 * will have the "last" bit set in it's DMACR word. The user will never have to
 * explicitly set the "last" bit again.
 *
 * The following operations can be replicated for the BdTemplate:
 *   - XDmaBdV2_mSetId()
 *   - XDmaBdV2_mSetLast()
 *   - XDmaBdV2_mClearLast()
 *
 * The base address of the memory space must be aligned according to buffer
 * descriptor requirements (see xtemac.h).
 *
 * The size of the memory space is assumed to be big enough to contain BdCount
 * buffers at the given alignment. If the region is too small, then adjacent
 * data may be overwritten causing system instability. There are tools in the
 * DMA driver that help calculate the sizing requirments. See macros
 * XDmaV2_mSgListCntCalc() and XDmaV2_mSgListMemCalc().
 *
 * @param InstancePtr is a pointer to the instance to be worked on.
 * @param Direction is the channel to address.
 * @param PhysicalAddr is the physical base address of user memory region.
 * @param VirtualAddr is the virtual base address of the user memory region. If
 *        address translation is not being utilized, then VirtAddr should be
 *        equivalent to PhysAddr.
 * @param Alignment governs the byte alignment of individual BDs. This function
 *        will enforce a minimum alignment of 8 bytes with no maximum as long as
 *        it is specified as a power of 2.
 * @param BdCount is the number of BDs to allocate in the memory region. It is
 *        assumed the region is large enough to contain all the BDs.
 * @param BdTemplate is copied to each BD after the list is created. If the user
 *        does not have a need to replicate any BD fields then this parameter
 *        should be zeroed (XDmaBdV2_mClear()). This parameter will be modified
 *        by this function.
 *
 * @return
 * - XST_SUCCESS if the space was initialized successfully
 * - XST_DEVICE_IS_STARTED if the device has not been stopped.
 * - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA per
 *   the configuration information contained in XTemac_Config.
 * - XST_INVALID_PARAM if: 1) Direction is not either XTE_SEND or XTE_RECV;
 *   2) PhysicalAddr and/or VirtualAddr are not aligned to the given
 *   alignment parameter; 3) Alignment parameter does not meet minimum
 *   requirements of this device; 3) BdCount is 0.
 * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans
 *   over address 0x00000000 in virtual address space.
 * - XST_NO_FEATURE if the DMA sub-driver discovers that the HW is not SGDMA
 *   capable.
 * - XST_FAILURE for other failures that shouldn't occur. If this is returned,
 *   then the driver is experiencing a problem that should be reported to
 *   Xilinx.
 *
 * @note
 * If the device is configured for scatter-gather DMA, this function must be
 * called AFTER the XTemac_Initialize() function because the DMA channel
 * components must be initialized before the memory space is set.
 *
 ******************************************************************************/
XStatus XTemac_SgSetSpace(XTemac * InstancePtr, u32 Direction,
			  u32 PhysicalAddr, u32 VirtualAddr,
			  u32 Alignment, unsigned BdCount,
			  XDmaBdV2 * BdTemplate)
{
	XStatus Status;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(BdTemplate != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* Make sure device is ready for this operation */
	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
		return (XST_DEVICE_IS_STARTED);
	}

	/* Must have sgdma */
	if (!XTemac_mIsSgDma(InstancePtr)) {
		return (XST_NOT_SGDMA);
	}

	/* Check alignment */
	if (Alignment < XTE_PLB_BD_ALIGNMENT) {
		return (XST_INVALID_PARAM);
	}

	if (Direction == XTE_SEND) {
		/* Setup BD for the transmit direction */
		XDmaBdV2_mSetTxDir(BdTemplate);
		XDmaBdV2_mSetDestAddr(BdTemplate,
				      InstancePtr->Config->BaseAddress +
				      XTE_PFIFO_TXDATA_OFFSET);

		/* DRE capabilities */
		if (InstancePtr->Config->Dre) {
			XDmaBdV2_mSetDre(BdTemplate);
		}

		/* Create the list. This function will return one of XST_SUCCESS,
		 * XST_INVALID_PARAM (for alignment violations), or
		 * XST_DMA_SG_LIST_ERROR (if memory segment spans address 0)
		 */
		Status =
		    XDmaV2_SgListCreate(&InstancePtr->SendDma, PhysicalAddr,
					VirtualAddr, Alignment, BdCount);
		if (Status != XST_SUCCESS) {
			return (Status);
		}

		/* Clone the template BD. This should always work. If it does not
		 * then something is seriously wrong
		 */
		Status = XDmaV2_SgListClone(&InstancePtr->SendDma, BdTemplate);
		if (Status != XST_SUCCESS) {
			return (XST_FAILURE);
		} else {
			return (XST_SUCCESS);
		}
	} else if (Direction == XTE_RECV) {
		/* Setup BD for the receive direction */
		XDmaBdV2_mSetRxDir(BdTemplate);
		XDmaBdV2_mSetSrcAddr(BdTemplate,
				     InstancePtr->Config->BaseAddress +
				     XTE_PFIFO_RXDATA_OFFSET);

		/* Create the list. This function will return one of XST_SUCCESS,
		 * XST_INVALID_PARAM (for alignment violations), or
		 * XST_DMA_SG_LIST_ERROR (if memory segment spans address 0)
		 */
		Status =
		    XDmaV2_SgListCreate(&InstancePtr->RecvDma, PhysicalAddr,
					VirtualAddr, Alignment, BdCount);
		if (Status != XST_SUCCESS) {
			return (Status);
		}

		/* Clone the template BD */
		Status = XDmaV2_SgListClone(&InstancePtr->RecvDma, BdTemplate);
		if (Status != XST_SUCCESS) {
			return (XST_FAILURE);
		} else {
			return (XST_SUCCESS);
		}
	}

	/* Direction is incorrect */
	return (XST_INVALID_PARAM);
}