PS端以太网DMA函数记录:XEmacPs_BdRingClone

/*****************************************************************************/
/**
 * 将给定的BD克隆到列表中的每个BD中
 * 源BD的每个字段被复制到列表的每个BD中。
 *
 * 这个函数只能在所有的BDs都在free组中时调用,例如在使用XEmacPs_BdRingCreate()初始化之后立即调用。
 * 这可以防止在硬件或用户使用bd时对它们进行修改。
 *
 * @param RingPtr		要处理的BD环实例的指针。
 * @param SrcBdPtr		要克隆到列表中的源BD模板。这个BD会被修改。
 * @param Direction 	XEMACPS_SEND或XEMACPS_RECV,表示哪个方向。
 *
 * @return
 *   - XST_SUCCESS 				如果列表被修改.
 *   - XST_DMA_SG_NO_LIST 		如果没有创建列表.
 *   - XST_DMA_SG_LIST_ERROR 	如果这个通道的一些BD在硬件或用户控制。
 *   - XST_DEVICE_IS_STARTED 	如果DMA通道没有停止
 *
 *****************************************************************************/
LONG XEmacPs_BdRingClone(XEmacPs_BdRing * RingPtr, XEmacPs_Bd * SrcBdPtr,
			 u8 Direction)
{
	u32 i;
	UINTPTR CurBd;

	/* 如果没有环,则无法执行此功能 */
	if (RingPtr->AllCnt == 0x00000000U) {
		return (LONG)(XST_DMA_SG_NO_LIST);
	}

	/* 在通道运行时无法执行此功能 */
	if (RingPtr->RunState == (u32)XST_DMA_SG_IS_STARTED) {
		return (LONG)(XST_DEVICE_IS_STARTED);
	}

	/* 当某些 BD 正在使用时无法执行此功能 */
	if (RingPtr->FreeCnt != RingPtr->AllCnt) {
		return (LONG)(XST_DMA_SG_LIST_ERROR);
	}

	if ((Direction != (u8)XEMACPS_SEND) && (Direction != (u8)XEMACPS_RECV)) {
		return (LONG)(XST_INVALID_PARAM);
	}

	/* 从环的顶部开始, 保存 BD.Next, 用模板覆盖整个BD, 然后恢复BD.Next */
	CurBd = RingPtr->BaseBdAddr;
	for (i = 0U; i < RingPtr->AllCnt; i++) {
		memcpy((void *)CurBd, SrcBdPtr, sizeof(XEmacPs_Bd));
	CurBd += RingPtr->Separation;
	}

	CurBd -= RingPtr->Separation;

	if (Direction == XEMACPS_RECV) {
		XEmacPs_BdSetRxWrap(CurBd);
	}
	else {
		XEmacPs_BdSetTxWrap(CurBd);
	}

	return (LONG)(XST_SUCCESS);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值