XilinxProcessorIPLib/drivers/axiethernet/examples/xaxiethernet_example_intr_sgdma.c
int AxiEthernetSgDmaPartialChecksumOffloadExample(XAxiEthernet
			*AxiEthernetInstancePtr, XAxiDma *DmaInstancePtr)
{
	int Status;
	u32 TxFrameLength;
	u32 RxFrameLength;
	int PayloadSize = PAYLOAD_SIZE;
	XAxiDma_BdRing *RxRingPtr = XAxiDma_GetRxRing(DmaInstancePtr);
	XAxiDma_BdRing *TxRingPtr = XAxiDma_GetTxRing(DmaInstancePtr);
	XAxiDma_Bd *BdPtr;
	XAxiDma_Bd *BdCurPtr;
	u32 BdSts;

	/*
	 * Cannot run this example if partial checksum offloading support is not
	 * available
	 */
	if (!(XAxiEthernet_IsRxPartialCsum(AxiEthernetInstancePtr) &&
		XAxiEthernet_IsTxPartialCsum(AxiEthernetInstancePtr))) {
		AxiEthernetUtilErrorTrap("Partial Checksum offloading not available");
		return XST_FAILURE;
	}

	/*
	 * Clear variables shared with callbacks
	 */
	FramesRx = 0;
	FramesTx = 0;
	DeviceErrors = 0;

	memset(RxFrame,0,sizeof(RxFrame));
	memset(TxFrame,0,sizeof(TxFrame));


	/*
	 * Calculate frame length (not including FCS)
	 */
	TxFrameLength = XAE_HDR_SIZE + PayloadSize;

	/*
	 * Setup the packet to be transmitted,
	 * Last 2 bytes are reserved for checksum
	 */
	AxiEthernetUtilFrameMemClear(&TxFrame);
	AxiEthernetUtilFrameHdrFormatMAC(&TxFrame, AxiEthernetMAC);
	AxiEthernetUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	AxiEthernetUtilFrameSetPayloadData(&TxFrame, PayloadSize - 2);

	/*
	 * Flush the TX frame before giving it to DMA TX channel to transmit.
	 */
	Xil_DCacheFlushRange((UINTPTR)&TxFrame, TxFrameLength);

	/*
	 * Clear out receive packet memory area
	 */
	AxiEthernetUtilFrameMemClear(&RxFrame);

	/*
	 * Invalidate the RX frame before giving it to DMA RX channel to
	 * receive data.
	 */
	Xil_DCacheInvalidateRange((UINTPTR)&RxFrame, TxFrameLength);

	/*
	 * Interrupt coalescing parameters are set to their default settings
	 * which is to interrupt the processor after every frame has been
	 * processed by the DMA engine.
	 */
	Status = XAxiDma_BdRingSetCoalesce(TxRingPtr, 1, 1);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error setting coalescing for transmit");
		return XST_FAILURE;
	}

	Status = XAxiDma_BdRingSetCoalesce(RxRingPtr, 1, 1);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error setting coalescing for recv");
		return XST_FAILURE;
	}

	/*
	 * Make sure Tx and Rx are enabled
	 */
	Status = XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
				     XAE_RECEIVER_ENABLE_OPTION |
				     XAE_TRANSMITTER_ENABLE_OPTION);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error setting options");
		return XST_FAILURE;
	}

	/*
	 * Start the Axi Ethernet and enable its ERROR interrupts
	 */
	XAxiEthernet_Start(AxiEthernetInstancePtr);
	XAxiEthernet_IntEnable(AxiEthernetInstancePtr,
						XAE_INT_RECV_ERROR_MASK);

	/*
	 * Enable DMA receive related interrupts
	 */
	XAxiDma_BdRingIntEnable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);

	/*
	 * Allocate 1 RxBD.
	 */
	Status = XAxiDma_BdRingAlloc(RxRingPtr, 1, &BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup the BD.
	 */
	XAxiDma_BdSetBufAddr(BdPtr, (UINTPTR)&RxFrame);
#ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL
	XAxiDma_BdSetLength(BdPtr, sizeof(RxFrame));
#else
	XAxiDma_BdSetLength(BdPtr, sizeof(RxFrame),
			RxRingPtr->MaxTransferLen);
#endif

	XAxiDma_BdSetCtrl(BdPtr, 0);

	/*
	 * Enqueue to HW
	 */
	Status = XAxiDma_BdRingToHw(RxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error committing RxBD to HW");
		return XST_FAILURE;
	}

	/*
	 * Enable DMA transmit related interrupts
	 */
	XAxiDma_BdRingIntEnable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);

	/*
	 * Allocate 1 TxBD
	 */
	Status = XAxiDma_BdRingAlloc(TxRingPtr, 1, &BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error allocating TxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup the TxBD
	 */
	XAxiDma_BdSetBufAddr(BdPtr, (UINTPTR)&TxFrame);
#ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL
	XAxiDma_BdSetLength(BdPtr, TxFrameLength);
#else
	XAxiDma_BdSetLength(BdPtr, TxFrameLength,
				TxRingPtr->MaxTransferLen);
#endif

	XAxiDma_BdSetCtrl(BdPtr, XAXIDMA_BD_CTRL_TXSOF_MASK |
						XAXIDMA_BD_CTRL_TXEOF_MASK);

	/*
	 * Setup TxBd checksum offload attributes.
	 * Note that the checksum offload values can be set globally for all
	 * TxBds when XAxiDma_BdRingClone() is called to setup Tx BD space.
	 * This would eliminate the need to set them here.
	 */
	/* Enable hardware checksum computation for the buffer descriptor */
	Status = XAxiDma_BdSetAppWord(BdPtr,BD_USR0_OFFSET,PARTIAL_CSUM_ENABLE);
	if(Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error in enabling partial csum offloading");
		return XST_FAILURE;
	}

	/* Write Start Offset and Insert Offset into BD */
	Status = XAxiDma_BdSetAppWord(BdPtr,BD_USR1_OFFSET,
		((XAE_HDR_SIZE << TX_CS_INIT_OFFSET) | (TxFrameLength - 2)));
	if(Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error in setting csum insert point");
		return XST_FAILURE;
	}

	/* Write 0, as the seed value, to the BD */
	Status = XAxiDma_BdSetAppWord(BdPtr,BD_USR2_OFFSET,0);
	if(Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error in enabling partial csum offloading");
		return XST_FAILURE;
	}

	/*
	 * Enqueue to HW
	 */
	Status = XAxiDma_BdRingToHw(TxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}

	/*
	 * Wait for transmission to complete
	 */
	while (!FramesTx);
	/*
	 * Now that the frame has been sent, post process our TxBDs.
	 * Since we have only submitted 2 to HW, then there should be only 2 ready
	 * for post processing.
	 */
	if (XAxiDma_BdRingFromHw(TxRingPtr, 1, &BdPtr) == 0) {
		AxiEthernetUtilErrorTrap("TxBDs were not ready for post processing");
		return XST_FAILURE;
	}

	/*
	 * Examine the TxBDs.
	 *
	 * There isn't much to do. The only thing to check would be DMA exception
	 * bits. But this would also be caught in the error handler. So we just
	 * return these BDs to the free list
	 */
	Status = XAxiDma_BdRingFree(TxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}

	/*
	 * Wait for Rx indication
	 */
	while (!FramesRx);
	/*
	 * Now that the frame has been received, post process our RxBD.
	 * Since we have only submitted 1 to HW, then there should be only 1 ready
	 * for post processing.
	 */
	if (XAxiDma_BdRingFromHw(RxRingPtr, 1, &BdPtr) == 0) {
		AxiEthernetUtilErrorTrap("RxBD was not ready for post processing");
		return XST_FAILURE;
	}

	/*
	 * There is no device status to check. If there was a DMA error, it
	 * should have been reported to the error handler. Check the receive
	 * length against the transmitted length, then verify the data.
	 *
	 * Note in Axi Ethernet case, USR4_OFFSET word in the RX BD is used to store
	 * the real length of the received packet
	 */
	BdCurPtr = BdPtr;
	BdSts = XAxiDma_BdGetSts(BdCurPtr);
	if ((BdSts & XAXIDMA_BD_STS_ALL_ERR_MASK) ||
		(!(BdSts & XAXIDMA_BD_STS_COMPLETE_MASK))) {
			AxiEthernetUtilErrorTrap("Rx Error");
			return XST_FAILURE;
	}
	else {
		RxFrameLength =
		(XAxiDma_BdRead(BdCurPtr,XAXIDMA_BD_USR4_OFFSET)) & 0x0000FFFF;
	}

	if (RxFrameLength != TxFrameLength) {
		AxiEthernetUtilErrorTrap("Length mismatch");
		return XST_FAILURE;
	}

	/*
	 * Verify the checksum as computed by HW. It should add up to 0xFFFF
	 * if frame was uncorrupted
	 */
	if ((u16) (XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR3_OFFSET))
		!= RCV_FRM_NOT_CORRUPTED) {
		AxiEthernetUtilErrorTrap("Rx checksum incorrect");
		return XST_FAILURE;
	}

	/*
	 * Return the RxBD back to the channel for later allocation. Free the
	 * exact number we just post processed.
	 */
	Status = XAxiDma_BdRingFree(RxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}

	/*
	 * Finished this example. If everything worked correctly, all TxBDs
	 * and RxBDs should be free for allocation. Stop the device.
	 */
	XAxiEthernet_Stop(AxiEthernetInstancePtr);

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This example sends and receives a single packet in loopback mode with
* checksum offloading support.
*
* The transmit frame will be checksummed over the entire Ethernet payload
* and inserted into the last 2 bytes of the frame.
*
* On receive, HW should calculate the Ethernet payload checksum and return a
* value of 0xFFFF which means the payload data was likely not corrupted.
*
* @param	AxiEthernetInstancePtr is a pointer to the instance of the
*		AxiEthernet component.
* @param	DmaInstancePtr   is a pointer to the instance of the Dma
*		component.
*
* @return	-XST_SUCCESS to indicate success
*		-XST_FAILURE to indicate failure
*
* @note		None.
*
******************************************************************************/
This example sends and receives a single packet in loopback mode with
checksum offloading support.

The transmit frame will be checksummed over the entire Ethernet payload
and inserted into the last 2 bytes of the frame.

On receive, HW should calculate the Ethernet payload checksum and return a
value of 0xFFFF which means the payload data was likely not corrupted.
This example sends and receives a single packet in loopback mode with checksum offloading support . The transmit frame will be checksummed over the entire Ethernet payload and inserted into the last 2 bytes of the frame . On receive HW should calculate the Ethernet payload checksum and return a value of 0xFFFF which means the payload data was likely not corrupted .
int AxiEthernetSgDmaPartialChecksumOffloadExample(XAxiEthernet
			*AxiEthernetInstancePtr, XAxiDma *DmaInstancePtr)
{
	int Status;
	u32 TxFrameLength;
	u32 RxFrameLength;
	int PayloadSize = PAYLOAD_SIZE;
	XAxiDma_BdRing *RxRingPtr = XAxiDma_GetRxRing(DmaInstancePtr);
	XAxiDma_BdRing *TxRingPtr = XAxiDma_GetTxRing(DmaInstancePtr);
	XAxiDma_Bd *BdPtr;
	XAxiDma_Bd *BdCurPtr;
	u32 BdSts;
	if (!(XAxiEthernet_IsRxPartialCsum(AxiEthernetInstancePtr) &&
		XAxiEthernet_IsTxPartialCsum(AxiEthernetInstancePtr))) {
		AxiEthernetUtilErrorTrap("Partial Checksum offloading not available");
		return XST_FAILURE;
	}
	FramesRx = 0;
	FramesTx = 0;
	DeviceErrors = 0;
	memset(RxFrame,0,sizeof(RxFrame));
	memset(TxFrame,0,sizeof(TxFrame));
	TxFrameLength = XAE_HDR_SIZE + PayloadSize;
	AxiEthernetUtilFrameMemClear(&TxFrame);
	AxiEthernetUtilFrameHdrFormatMAC(&TxFrame, AxiEthernetMAC);
	AxiEthernetUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	AxiEthernetUtilFrameSetPayloadData(&TxFrame, PayloadSize - 2);
	Xil_DCacheFlushRange((UINTPTR)&TxFrame, TxFrameLength);
	AxiEthernetUtilFrameMemClear(&RxFrame);
	Xil_DCacheInvalidateRange((UINTPTR)&RxFrame, TxFrameLength);
	Status = XAxiDma_BdRingSetCoalesce(TxRingPtr, 1, 1);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error setting coalescing for transmit");
		return XST_FAILURE;
	}
	Status = XAxiDma_BdRingSetCoalesce(RxRingPtr, 1, 1);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error setting coalescing for recv");
		return XST_FAILURE;
	}
	Status = XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
				     XAE_RECEIVER_ENABLE_OPTION |
				     XAE_TRANSMITTER_ENABLE_OPTION);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error setting options");
		return XST_FAILURE;
	}
	XAxiEthernet_Start(AxiEthernetInstancePtr);
	XAxiEthernet_IntEnable(AxiEthernetInstancePtr,
						XAE_INT_RECV_ERROR_MASK);
	XAxiDma_BdRingIntEnable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);
	Status = XAxiDma_BdRingAlloc(RxRingPtr, 1, &BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}
	XAxiDma_BdSetBufAddr(BdPtr, (UINTPTR)&RxFrame);
#ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL
	XAxiDma_BdSetLength(BdPtr, sizeof(RxFrame));
#else
	XAxiDma_BdSetLength(BdPtr, sizeof(RxFrame),
			RxRingPtr->MaxTransferLen);
#endif
	XAxiDma_BdSetCtrl(BdPtr, 0);
	Status = XAxiDma_BdRingToHw(RxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error committing RxBD to HW");
		return XST_FAILURE;
	}
	XAxiDma_BdRingIntEnable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);
	Status = XAxiDma_BdRingAlloc(TxRingPtr, 1, &BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error allocating TxBD");
		return XST_FAILURE;
	}
	XAxiDma_BdSetBufAddr(BdPtr, (UINTPTR)&TxFrame);
#ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL
	XAxiDma_BdSetLength(BdPtr, TxFrameLength);
#else
	XAxiDma_BdSetLength(BdPtr, TxFrameLength,
				TxRingPtr->MaxTransferLen);
#endif
	XAxiDma_BdSetCtrl(BdPtr, XAXIDMA_BD_CTRL_TXSOF_MASK |
						XAXIDMA_BD_CTRL_TXEOF_MASK);
	Status = XAxiDma_BdSetAppWord(BdPtr,BD_USR0_OFFSET,PARTIAL_CSUM_ENABLE);
	if(Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error in enabling partial csum offloading");
		return XST_FAILURE;
	}
	Status = XAxiDma_BdSetAppWord(BdPtr,BD_USR1_OFFSET,
		((XAE_HDR_SIZE << TX_CS_INIT_OFFSET) | (TxFrameLength - 2)));
	if(Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error in setting csum insert point");
		return XST_FAILURE;
	}
	Status = XAxiDma_BdSetAppWord(BdPtr,BD_USR2_OFFSET,0);
	if(Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error in enabling partial csum offloading");
		return XST_FAILURE;
	}
	Status = XAxiDma_BdRingToHw(TxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}
	while (!FramesTx);
	if (XAxiDma_BdRingFromHw(TxRingPtr, 1, &BdPtr) == 0) {
		AxiEthernetUtilErrorTrap("TxBDs were not ready for post processing");
		return XST_FAILURE;
	}
	Status = XAxiDma_BdRingFree(TxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}
	while (!FramesRx);
	if (XAxiDma_BdRingFromHw(RxRingPtr, 1, &BdPtr) == 0) {
		AxiEthernetUtilErrorTrap("RxBD was not ready for post processing");
		return XST_FAILURE;
	}
	BdCurPtr = BdPtr;
	BdSts = XAxiDma_BdGetSts(BdCurPtr);
	if ((BdSts & XAXIDMA_BD_STS_ALL_ERR_MASK) ||
		(!(BdSts & XAXIDMA_BD_STS_COMPLETE_MASK))) {
			AxiEthernetUtilErrorTrap("Rx Error");
			return XST_FAILURE;
	}
	else {
		RxFrameLength =
		(XAxiDma_BdRead(BdCurPtr,XAXIDMA_BD_USR4_OFFSET)) & 0x0000FFFF;
	}
	if (RxFrameLength != TxFrameLength) {
		AxiEthernetUtilErrorTrap("Length mismatch");
		return XST_FAILURE;
	}
	if ((u16) (XAxiDma_BdRead(BdPtr, XAXIDMA_BD_USR3_OFFSET))
		!= RCV_FRM_NOT_CORRUPTED) {
		AxiEthernetUtilErrorTrap("Rx checksum incorrect");
		return XST_FAILURE;
	}
	Status = XAxiDma_BdRingFree(RxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		AxiEthernetUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}
	XAxiEthernet_Stop(AxiEthernetInstancePtr);
	return XST_SUCCESS;
}
int AxiEthernetSgDmaPartialChecksumOffloadExample ( XAxiEthernet * AxiEthernetInstancePtr , XAxiDma * DmaInstancePtr ) { int Status ; u32 TxFrameLength ; u32 RxFrameLength ; int PayloadSize = PAYLOAD_SIZE ; XAxiDma_BdRing * RxRingPtr = XAxiDma_GetRxRing ( DmaInstancePtr ) ; XAxiDma_BdRing * TxRingPtr = XAxiDma_GetTxRing ( DmaInstancePtr ) ; XAxiDma_Bd * BdPtr ; XAxiDma_Bd * BdCurPtr ; u32 BdSts ; if ( ! ( XAxiEthernet_IsRxPartialCsum ( AxiEthernetInstancePtr ) && XAxiEthernet_IsTxPartialCsum ( AxiEthernetInstancePtr ) ) ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } FramesRx = 0 ; FramesTx = 0 ; DeviceErrors = 0 ; memset ( RxFrame , 0 , sizeof ( RxFrame ) ) ; memset ( TxFrame , 0 , sizeof ( TxFrame ) ) ; TxFrameLength = XAE_HDR_SIZE + PayloadSize ; AxiEthernetUtilFrameMemClear ( & TxFrame ) ; AxiEthernetUtilFrameHdrFormatMAC ( & TxFrame , AxiEthernetMAC ) ; AxiEthernetUtilFrameHdrFormatType ( & TxFrame , PayloadSize ) ; AxiEthernetUtilFrameSetPayloadData ( & TxFrame , PayloadSize - 2 ) ; Xil_DCacheFlushRange ( ( UINTPTR ) & TxFrame , TxFrameLength ) ; AxiEthernetUtilFrameMemClear ( & RxFrame ) ; Xil_DCacheInvalidateRange ( ( UINTPTR ) & RxFrame , TxFrameLength ) ; Status = XAxiDma_BdRingSetCoalesce ( TxRingPtr , 1 , 1 ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiDma_BdRingSetCoalesce ( RxRingPtr , 1 , 1 ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiEthernet_SetOptions ( AxiEthernetInstancePtr , XAE_RECEIVER_ENABLE_OPTION | XAE_TRANSMITTER_ENABLE_OPTION ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XAxiEthernet_Start ( AxiEthernetInstancePtr ) ; XAxiEthernet_IntEnable ( AxiEthernetInstancePtr , XAE_INT_RECV_ERROR_MASK ) ; XAxiDma_BdRingIntEnable ( RxRingPtr , XAXIDMA_IRQ_ALL_MASK ) ; Status = XAxiDma_BdRingAlloc ( RxRingPtr , 1 , & BdPtr ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XAxiDma_BdSetBufAddr ( BdPtr , ( UINTPTR ) & RxFrame ) ; #ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL XAxiDma_BdSetLength ( BdPtr , sizeof ( RxFrame ) ) ; #else XAxiDma_BdSetLength ( BdPtr , sizeof ( RxFrame ) , RxRingPtr -> MaxTransferLen ) ; #endif XAxiDma_BdSetCtrl ( BdPtr , 0 ) ; Status = XAxiDma_BdRingToHw ( RxRingPtr , 1 , BdPtr ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XAxiDma_BdRingIntEnable ( TxRingPtr , XAXIDMA_IRQ_ALL_MASK ) ; Status = XAxiDma_BdRingAlloc ( TxRingPtr , 1 , & BdPtr ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XAxiDma_BdSetBufAddr ( BdPtr , ( UINTPTR ) & TxFrame ) ; #ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL XAxiDma_BdSetLength ( BdPtr , TxFrameLength ) ; #else XAxiDma_BdSetLength ( BdPtr , TxFrameLength , TxRingPtr -> MaxTransferLen ) ; #endif XAxiDma_BdSetCtrl ( BdPtr , XAXIDMA_BD_CTRL_TXSOF_MASK | XAXIDMA_BD_CTRL_TXEOF_MASK ) ; Status = XAxiDma_BdSetAppWord ( BdPtr , BD_USR0_OFFSET , PARTIAL_CSUM_ENABLE ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiDma_BdSetAppWord ( BdPtr , BD_USR1_OFFSET , ( ( XAE_HDR_SIZE << TX_CS_INIT_OFFSET ) | ( TxFrameLength - 2 ) ) ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiDma_BdSetAppWord ( BdPtr , BD_USR2_OFFSET , 0 ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiDma_BdRingToHw ( TxRingPtr , 1 , BdPtr ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } while ( ! FramesTx ) ; if ( XAxiDma_BdRingFromHw ( TxRingPtr , 1 , & BdPtr ) == 0 ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiDma_BdRingFree ( TxRingPtr , 1 , BdPtr ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } while ( ! FramesRx ) ; if ( XAxiDma_BdRingFromHw ( RxRingPtr , 1 , & BdPtr ) == 0 ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } BdCurPtr = BdPtr ; BdSts = XAxiDma_BdGetSts ( BdCurPtr ) ; if ( ( BdSts & XAXIDMA_BD_STS_ALL_ERR_MASK ) || ( ! ( BdSts & XAXIDMA_BD_STS_COMPLETE_MASK ) ) ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } else { RxFrameLength = ( XAxiDma_BdRead ( BdCurPtr , XAXIDMA_BD_USR4_OFFSET ) ) & 0x0000FFFF ; } if ( RxFrameLength != TxFrameLength ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( ( u16 ) ( XAxiDma_BdRead ( BdPtr , XAXIDMA_BD_USR3_OFFSET ) ) != RCV_FRM_NOT_CORRUPTED ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XAxiDma_BdRingFree ( RxRingPtr , 1 , BdPtr ) ; if ( Status != XST_SUCCESS ) { AxiEthernetUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XAxiEthernet_Stop ( AxiEthernetInstancePtr ) ; return XST_SUCCESS ; }
This example sends and receives a single packet in loopback mode with
checksum offloading support.
This example sends and receives a single packet in loopback mode with checksum offloading support .
/*
	 * Cannot run this example if partial checksum offloading support is not
	 * available
	 */ /*
	 * Clear variables shared with callbacks
	 */ /*
	 * Calculate frame length (not including FCS)
	 */ /*
	 * Setup the packet to be transmitted,
	 * Last 2 bytes are reserved for checksum
	 */ /*
	 * Flush the TX frame before giving it to DMA TX channel to transmit.
	 */ /*
	 * Clear out receive packet memory area
	 */ /*
	 * Invalidate the RX frame before giving it to DMA RX channel to
	 * receive data.
	 */ /*
	 * Interrupt coalescing parameters are set to their default settings
	 * which is to interrupt the processor after every frame has been
	 * processed by the DMA engine.
	 */ /*
	 * Make sure Tx and Rx are enabled
	 */ /*
	 * Start the Axi Ethernet and enable its ERROR interrupts
	 */ /*
	 * Enable DMA receive related interrupts
	 */ /*
	 * Allocate 1 RxBD.
	 */ /*
	 * Setup the BD.
	 */ /*
	 * Enqueue to HW
	 */ /*
	 * Enable DMA transmit related interrupts
	 */ /*
	 * Allocate 1 TxBD
	 */ /*
	 * Setup the TxBD
	 */ /*
	 * Setup TxBd checksum offload attributes.
	 * Note that the checksum offload values can be set globally for all
	 * TxBds when XAxiDma_BdRingClone() is called to setup Tx BD space.
	 * This would eliminate the need to set them here.
	 */ /* Enable hardware checksum computation for the buffer descriptor */ /* Write Start Offset and Insert Offset into BD */ /* Write 0, as the seed value, to the BD */ /*
	 * Enqueue to HW
	 */ /*
	 * Wait for transmission to complete
	 */ /*
	 * Now that the frame has been sent, post process our TxBDs.
	 * Since we have only submitted 2 to HW, then there should be only 2 ready
	 * for post processing.
	 */ /*
	 * Examine the TxBDs.
	 *
	 * There isn't much to do. The only thing to check would be DMA exception
	 * bits. But this would also be caught in the error handler. So we just
	 * return these BDs to the free list
	 */ /*
	 * Wait for Rx indication
	 */ /*
	 * Now that the frame has been received, post process our RxBD.
	 * Since we have only submitted 1 to HW, then there should be only 1 ready
	 * for post processing.
	 */ /*
	 * There is no device status to check. If there was a DMA error, it
	 * should have been reported to the error handler. Check the receive
	 * length against the transmitted length, then verify the data.
	 *
	 * Note in Axi Ethernet case, USR4_OFFSET word in the RX BD is used to store
	 * the real length of the received packet
	 */ /*
	 * Verify the checksum as computed by HW. It should add up to 0xFFFF
	 * if frame was uncorrupted
	 */ /*
	 * Return the RxBD back to the channel for later allocation. Free the
	 * exact number we just post processed.
	 */ /*
	 * Finished this example. If everything worked correctly, all TxBDs
	 * and RxBDs should be free for allocation. Stop the device.
	 */