XilinxProcessorIPLib/drivers/emacps/examples/xemacps_example_intr_dma.c
LONG EmacPsDmaIntrExample(INTC * IntcInstancePtr,
			  XEmacPs * EmacPsInstancePtr,
			  u16 EmacPsDeviceId)
{
	LONG Status;
	XEmacPs_Config *Config;
	XEmacPs_Bd BdTemplate;
	u16 EmacPsIntrId;

	/*************************************/
	/* Setup device for first-time usage */
	/*************************************/

	/*
	 *  Initialize instance. Should be configured for DMA
	 *  This example calls _CfgInitialize instead of _Initialize due to
	 *  retiring _Initialize. So in _CfgInitialize we use
	 *  XPAR_(IP)_BASEADDRESS to make sure it is not virtual address.
	 */
	Config = XEmacPs_LookupConfig(EmacPsDeviceId);

#if EL1_NONSECURE
	/* Request device to indicate it is in use by this application */
	if (Config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
		Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_0, 1, 0, 100, 1, 0, 0);
	}
	if (Config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
		Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_1, 1, 0, 100, 1, 0, 0);
	}
#endif

	Status = XEmacPs_CfgInitialize(EmacPsInstancePtr, Config,
					Config->BaseAddress);

	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error in initialize");
		return XST_FAILURE;
	}

#if defined(XPAR_INTC_0_DEVICE_ID)
	EmacPsIntrId = XPAR_AXI_INTC_0_PROCESSING_SYSTEM7_0_IRQ_P2F_ENET0_INTR;
#else
	if ((EmacPsInstancePtr->Config.BaseAddress == ZYNQ_EMACPS_0_BASEADDR) ||
		(EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_0_BASEADDR) ||
		(EmacPsInstancePtr->Config.BaseAddress == VERSAL_EMACPS_0_BASEADDR)) {
		EmacPsIntrId = XPS_GEM0_INT_ID;
	} else if ((EmacPsInstancePtr->Config.BaseAddress == ZYNQ_EMACPS_1_BASEADDR) ||
			(EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_1_BASEADDR) ||
			(EmacPsInstancePtr->Config.BaseAddress == VERSAL_EMACPS_1_BASEADDR)) {
		EmacPsIntrId = XPS_GEM1_INT_ID;
	} else if (EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_2_BASEADDR) {
#ifdef XPS_GEM2_INT_ID
		EmacPsIntrId = XPS_GEM2_INT_ID;
#endif
	} else if (EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_3_BASEADDR) {
#ifdef XPS_GEM3_INT_ID
		EmacPsIntrId = XPS_GEM3_INT_ID;
#endif
	}
#endif

	GemVersion = ((Xil_In32(Config->BaseAddress + 0xFC)) >> 16) & 0xFFF;

	if (GemVersion == GEMVERSION_VERSAL) {
		Platform = Xil_In32(VERSAL_VERSION);
	} else if (GemVersion > 2) {
		Platform = Xil_In32(CSU_VERSION);
	}
	/* Enable jumbo frames for zynqmp */
	if (GemVersion > 2) {
		XEmacPs_SetOptions(EmacPsInstancePtr, XEMACPS_JUMBO_ENABLE_OPTION);
	}

	XEmacPsClkSetup(EmacPsInstancePtr, EmacPsIntrId);

	/*
	 * Set the MAC address
	 */
	Status = XEmacPs_SetMacAddress(EmacPsInstancePtr, EmacPsMAC, 1);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error setting MAC address");
		return XST_FAILURE;
	}
	/*
	 * Setup callbacks
	 */
	Status = XEmacPs_SetHandler(EmacPsInstancePtr,
				     XEMACPS_HANDLER_DMASEND,
				     (void *) XEmacPsSendHandler,
				     EmacPsInstancePtr);
	Status |=
		XEmacPs_SetHandler(EmacPsInstancePtr,
				    XEMACPS_HANDLER_DMARECV,
				    (void *) XEmacPsRecvHandler,
				    EmacPsInstancePtr);
	Status |=
		XEmacPs_SetHandler(EmacPsInstancePtr, XEMACPS_HANDLER_ERROR,
				    (void *) XEmacPsErrorHandler,
				    EmacPsInstancePtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error assigning handlers");
		return XST_FAILURE;
	}

	/* Gem IP version on Zynq-7000 */
	if (GemVersion == 2)
	{
		/*
		 * The BDs need to be allocated in uncached memory. Hence the 1 MB
		 * address range that starts at "bd_space" is made uncached.
		 */
#if !defined(__MICROBLAZE__) && !defined(ARMR5)
		Xil_SetTlbAttributes((INTPTR)bd_space, DEVICE_MEMORY);
#else
		Xil_DCacheDisable();
#endif

	}

	if (GemVersion > 2) {

#if defined (ARMR5)
		Xil_SetTlbAttributes((INTPTR)bd_space, STRONG_ORDERD_SHARED |
					PRIV_RW_USER_RW);
#endif
#if defined __aarch64__
		Xil_SetTlbAttributes((UINTPTR)bd_space, NORM_NONCACHE |
					INNER_SHAREABLE);
#endif
	}

	/* Allocate Rx and Tx BD space each */
	RxBdSpacePtr = &(bd_space[0]);
	TxBdSpacePtr = &(bd_space[0x10000]);

	/*
	 * Setup RxBD space.
	 *
	 * We have already defined a properly aligned area of memory to store
	 * RxBDs at the beginning of this source code file so just pass its
	 * address into the function. No MMU is being used so the physical
	 * and virtual addresses are the same.
	 *
	 * Setup a BD template for the Rx channel. This template will be
	 * copied to every RxBD. We will not have to explicitly set these
	 * again.
	 */
	XEmacPs_BdClear(&BdTemplate);

	/*
	 * Create the RxBD ring
	 */
	Status = XEmacPs_BdRingCreate(&(XEmacPs_GetRxRing
				       (EmacPsInstancePtr)),
				       (UINTPTR) RxBdSpacePtr,
				       (UINTPTR) RxBdSpacePtr,
				       XEMACPS_BD_ALIGNMENT,
				       RXBD_CNT);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up RxBD space, BdRingCreate");
		return XST_FAILURE;
	}

	Status = XEmacPs_BdRingClone(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				      &BdTemplate, XEMACPS_RECV);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up RxBD space, BdRingClone");
		return XST_FAILURE;
	}

	/*
	 * Setup TxBD space.
	 *
	 * Like RxBD space, we have already defined a properly aligned area
	 * of memory to use.
	 *
	 * Also like the RxBD space, we create a template. Notice we don't
	 * set the "last" attribute. The example will be overriding this
	 * attribute so it does no good to set it up here.
	 */
	XEmacPs_BdClear(&BdTemplate);
	XEmacPs_BdSetStatus(&BdTemplate, XEMACPS_TXBUF_USED_MASK);

	/*
	 * Create the TxBD ring
	 */
	Status = XEmacPs_BdRingCreate(&(XEmacPs_GetTxRing
				       (EmacPsInstancePtr)),
				       (UINTPTR) TxBdSpacePtr,
				       (UINTPTR) TxBdSpacePtr,
				       XEMACPS_BD_ALIGNMENT,
				       TXBD_CNT);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up TxBD space, BdRingCreate");
		return XST_FAILURE;
	}
	Status = XEmacPs_BdRingClone(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				      &BdTemplate, XEMACPS_SEND);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up TxBD space, BdRingClone");
		return XST_FAILURE;
	}

	if (GemVersion > 2)
	{
		/*
		 * This version of GEM supports priority queuing and the current
		 * driver is using tx priority queue 1 and normal rx queue for
		 * packet transmit and receive. The below code ensure that the
		 * other queue pointers are parked to known state for avoiding
		 * the controller to malfunction by fetching the descriptors
		 * from these queues.
		 */
		XEmacPs_BdClear(&BdRxTerminate);
		XEmacPs_BdSetAddressRx(&BdRxTerminate, (XEMACPS_RXBUF_NEW_MASK |
						XEMACPS_RXBUF_WRAP_MASK));
		XEmacPs_Out32((Config->BaseAddress + XEMACPS_RXQ1BASE_OFFSET),
			       (UINTPTR)&BdRxTerminate);
		XEmacPs_BdClear(&BdTxTerminate);
		XEmacPs_BdSetStatus(&BdTxTerminate, (XEMACPS_TXBUF_USED_MASK |
						XEMACPS_TXBUF_WRAP_MASK));
		XEmacPs_Out32((Config->BaseAddress + XEMACPS_TXQBASE_OFFSET),
			       (UINTPTR)&BdTxTerminate);
		if (Config->IsCacheCoherent == 0) {
			Xil_DCacheFlushRange((UINTPTR)(&BdTxTerminate), 64);
		}
	}

	/*
	 * Set emacps to phy loopback
	 */
	if (GemVersion == 2)
	{
		XEmacPs_SetMdioDivisor(EmacPsInstancePtr, MDC_DIV_224);
		EmacpsDelay(1);
		EmacPsUtilEnterLoopback(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED_1G);
		XEmacPs_SetOperatingSpeed(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED_1G);
	}
	else
	{
		if ((Platform & PLATFORM_MASK_VERSAL) == PLATFORM_VERSALEMU) {
			XEmacPs_SetMdioDivisor(EmacPsInstancePtr, MDC_DIV_8);
		} else {
			XEmacPs_SetMdioDivisor(EmacPsInstancePtr, MDC_DIV_224);
		}

		if (((Platform & PLATFORM_MASK) == PLATFORM_SILICON) ||
			((Platform & PLATFORM_MASK_VERSAL) == PLATFORM_VERSALSIL)) {
			EmacPsUtilEnterLoopback(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED_1G);
			XEmacPs_SetOperatingSpeed(EmacPsInstancePtr,EMACPS_LOOPBACK_SPEED_1G);
		} else {
			EmacPsUtilEnterLoopback(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED);
			XEmacPs_SetOperatingSpeed(EmacPsInstancePtr,EMACPS_LOOPBACK_SPEED);
		}
	}

	/*
	 * Setup the interrupt controller and enable interrupts
	 */
	Status = EmacPsSetupIntrSystem(IntcInstancePtr,
					EmacPsInstancePtr, EmacPsIntrId);

	/*
	 * Run the EmacPs DMA Single Frame Interrupt example
	 */
	Status = EmacPsDmaSingleFrameIntrExample(EmacPsInstancePtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Disable the interrupts for the EmacPs device
	 */
	EmacPsDisableIntrSystem(IntcInstancePtr, EmacPsIntrId);

	/*
	 * Stop the device
	 */
	XEmacPs_Stop(EmacPsInstancePtr);

	return XST_SUCCESS;
}
/****************************************************************************/
/**
*
* This function demonstrates the usage of the EmacPs driver by sending by
* sending and receiving frames in interrupt driven DMA mode.
*
*
* @param	IntcInstancePtr is a pointer to the instance of the Intc driver.
* @param	EmacPsInstancePtr is a pointer to the instance of the EmacPs
*		driver.
* @param	EmacPsDeviceId is Device ID of the EmacPs Device , typically
*		XPAR_<EMACPS_instance>_DEVICE_ID value from xparameters.h.
*
* @return	XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note		None.
*
*****************************************************************************/
This function demonstrates the usage of the EmacPs driver by sending by
sending and receiving frames in interrupt driven DMA mode.
This function demonstrates the usage of the EmacPs driver by sending by sending and receiving frames in interrupt driven DMA mode .
LONG EmacPsDmaIntrExample(INTC * IntcInstancePtr,
			  XEmacPs * EmacPsInstancePtr,
			  u16 EmacPsDeviceId)
{
	LONG Status;
	XEmacPs_Config *Config;
	XEmacPs_Bd BdTemplate;
	u16 EmacPsIntrId;
	Config = XEmacPs_LookupConfig(EmacPsDeviceId);
#if EL1_NONSECURE
	if (Config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
		Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_0, 1, 0, 100, 1, 0, 0);
	}
	if (Config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
		Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_1, 1, 0, 100, 1, 0, 0);
	}
#endif
	Status = XEmacPs_CfgInitialize(EmacPsInstancePtr, Config,
					Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error in initialize");
		return XST_FAILURE;
	}
#if defined(XPAR_INTC_0_DEVICE_ID)
	EmacPsIntrId = XPAR_AXI_INTC_0_PROCESSING_SYSTEM7_0_IRQ_P2F_ENET0_INTR;
#else
	if ((EmacPsInstancePtr->Config.BaseAddress == ZYNQ_EMACPS_0_BASEADDR) ||
		(EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_0_BASEADDR) ||
		(EmacPsInstancePtr->Config.BaseAddress == VERSAL_EMACPS_0_BASEADDR)) {
		EmacPsIntrId = XPS_GEM0_INT_ID;
	} else if ((EmacPsInstancePtr->Config.BaseAddress == ZYNQ_EMACPS_1_BASEADDR) ||
			(EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_1_BASEADDR) ||
			(EmacPsInstancePtr->Config.BaseAddress == VERSAL_EMACPS_1_BASEADDR)) {
		EmacPsIntrId = XPS_GEM1_INT_ID;
	} else if (EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_2_BASEADDR) {
#ifdef XPS_GEM2_INT_ID
		EmacPsIntrId = XPS_GEM2_INT_ID;
#endif
	} else if (EmacPsInstancePtr->Config.BaseAddress == ZYNQMP_EMACPS_3_BASEADDR) {
#ifdef XPS_GEM3_INT_ID
		EmacPsIntrId = XPS_GEM3_INT_ID;
#endif
	}
#endif
	GemVersion = ((Xil_In32(Config->BaseAddress + 0xFC)) >> 16) & 0xFFF;
	if (GemVersion == GEMVERSION_VERSAL) {
		Platform = Xil_In32(VERSAL_VERSION);
	} else if (GemVersion > 2) {
		Platform = Xil_In32(CSU_VERSION);
	}
	if (GemVersion > 2) {
		XEmacPs_SetOptions(EmacPsInstancePtr, XEMACPS_JUMBO_ENABLE_OPTION);
	}
	XEmacPsClkSetup(EmacPsInstancePtr, EmacPsIntrId);
	Status = XEmacPs_SetMacAddress(EmacPsInstancePtr, EmacPsMAC, 1);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error setting MAC address");
		return XST_FAILURE;
	}
	Status = XEmacPs_SetHandler(EmacPsInstancePtr,
				     XEMACPS_HANDLER_DMASEND,
				     (void *) XEmacPsSendHandler,
				     EmacPsInstancePtr);
	Status |=
		XEmacPs_SetHandler(EmacPsInstancePtr,
				    XEMACPS_HANDLER_DMARECV,
				    (void *) XEmacPsRecvHandler,
				    EmacPsInstancePtr);
	Status |=
		XEmacPs_SetHandler(EmacPsInstancePtr, XEMACPS_HANDLER_ERROR,
				    (void *) XEmacPsErrorHandler,
				    EmacPsInstancePtr);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap("Error assigning handlers");
		return XST_FAILURE;
	}
	if (GemVersion == 2)
	{
#if !defined(__MICROBLAZE__) && !defined(ARMR5)
		Xil_SetTlbAttributes((INTPTR)bd_space, DEVICE_MEMORY);
#else
		Xil_DCacheDisable();
#endif
	}
	if (GemVersion > 2) {
#if defined (ARMR5)
		Xil_SetTlbAttributes((INTPTR)bd_space, STRONG_ORDERD_SHARED |
					PRIV_RW_USER_RW);
#endif
#if defined __aarch64__
		Xil_SetTlbAttributes((UINTPTR)bd_space, NORM_NONCACHE |
					INNER_SHAREABLE);
#endif
	}
	RxBdSpacePtr = &(bd_space[0]);
	TxBdSpacePtr = &(bd_space[0x10000]);
	XEmacPs_BdClear(&BdTemplate);
	Status = XEmacPs_BdRingCreate(&(XEmacPs_GetRxRing
				       (EmacPsInstancePtr)),
				       (UINTPTR) RxBdSpacePtr,
				       (UINTPTR) RxBdSpacePtr,
				       XEMACPS_BD_ALIGNMENT,
				       RXBD_CNT);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up RxBD space, BdRingCreate");
		return XST_FAILURE;
	}
	Status = XEmacPs_BdRingClone(&(XEmacPs_GetRxRing(EmacPsInstancePtr)),
				      &BdTemplate, XEMACPS_RECV);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up RxBD space, BdRingClone");
		return XST_FAILURE;
	}
	XEmacPs_BdClear(&BdTemplate);
	XEmacPs_BdSetStatus(&BdTemplate, XEMACPS_TXBUF_USED_MASK);
	Status = XEmacPs_BdRingCreate(&(XEmacPs_GetTxRing
				       (EmacPsInstancePtr)),
				       (UINTPTR) TxBdSpacePtr,
				       (UINTPTR) TxBdSpacePtr,
				       XEMACPS_BD_ALIGNMENT,
				       TXBD_CNT);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up TxBD space, BdRingCreate");
		return XST_FAILURE;
	}
	Status = XEmacPs_BdRingClone(&(XEmacPs_GetTxRing(EmacPsInstancePtr)),
				      &BdTemplate, XEMACPS_SEND);
	if (Status != XST_SUCCESS) {
		EmacPsUtilErrorTrap
			("Error setting up TxBD space, BdRingClone");
		return XST_FAILURE;
	}
	if (GemVersion > 2)
	{
		XEmacPs_BdClear(&BdRxTerminate);
		XEmacPs_BdSetAddressRx(&BdRxTerminate, (XEMACPS_RXBUF_NEW_MASK |
						XEMACPS_RXBUF_WRAP_MASK));
		XEmacPs_Out32((Config->BaseAddress + XEMACPS_RXQ1BASE_OFFSET),
			       (UINTPTR)&BdRxTerminate);
		XEmacPs_BdClear(&BdTxTerminate);
		XEmacPs_BdSetStatus(&BdTxTerminate, (XEMACPS_TXBUF_USED_MASK |
						XEMACPS_TXBUF_WRAP_MASK));
		XEmacPs_Out32((Config->BaseAddress + XEMACPS_TXQBASE_OFFSET),
			       (UINTPTR)&BdTxTerminate);
		if (Config->IsCacheCoherent == 0) {
			Xil_DCacheFlushRange((UINTPTR)(&BdTxTerminate), 64);
		}
	}
	if (GemVersion == 2)
	{
		XEmacPs_SetMdioDivisor(EmacPsInstancePtr, MDC_DIV_224);
		EmacpsDelay(1);
		EmacPsUtilEnterLoopback(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED_1G);
		XEmacPs_SetOperatingSpeed(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED_1G);
	}
	else
	{
		if ((Platform & PLATFORM_MASK_VERSAL) == PLATFORM_VERSALEMU) {
			XEmacPs_SetMdioDivisor(EmacPsInstancePtr, MDC_DIV_8);
		} else {
			XEmacPs_SetMdioDivisor(EmacPsInstancePtr, MDC_DIV_224);
		}
		if (((Platform & PLATFORM_MASK) == PLATFORM_SILICON) ||
			((Platform & PLATFORM_MASK_VERSAL) == PLATFORM_VERSALSIL)) {
			EmacPsUtilEnterLoopback(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED_1G);
			XEmacPs_SetOperatingSpeed(EmacPsInstancePtr,EMACPS_LOOPBACK_SPEED_1G);
		} else {
			EmacPsUtilEnterLoopback(EmacPsInstancePtr, EMACPS_LOOPBACK_SPEED);
			XEmacPs_SetOperatingSpeed(EmacPsInstancePtr,EMACPS_LOOPBACK_SPEED);
		}
	}
	Status = EmacPsSetupIntrSystem(IntcInstancePtr,
					EmacPsInstancePtr, EmacPsIntrId);
	Status = EmacPsDmaSingleFrameIntrExample(EmacPsInstancePtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	EmacPsDisableIntrSystem(IntcInstancePtr, EmacPsIntrId);
	XEmacPs_Stop(EmacPsInstancePtr);
	return XST_SUCCESS;
}
LONG EmacPsDmaIntrExample ( INTC * IntcInstancePtr , XEmacPs * EmacPsInstancePtr , u16 EmacPsDeviceId ) { LONG Status ; XEmacPs_Config * Config ; XEmacPs_Bd BdTemplate ; u16 EmacPsIntrId ; Config = XEmacPs_LookupConfig ( EmacPsDeviceId ) ; #if EL1_NONSECURE if ( Config -> BaseAddress == VERSAL_EMACPS_0_BASEADDR ) { Xil_Smc ( PM_REQUEST_DEVICE_SMC_FID , DEV_GEM_0 , 1 , 0 , 100 , 1 , 0 , 0 ) ; } if ( Config -> BaseAddress == VERSAL_EMACPS_0_BASEADDR ) { Xil_Smc ( PM_REQUEST_DEVICE_SMC_FID , DEV_GEM_1 , 1 , 0 , 100 , 1 , 0 , 0 ) ; } #endif Status = XEmacPs_CfgInitialize ( EmacPsInstancePtr , Config , Config -> BaseAddress ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } #if defined ( XPAR_INTC_0_DEVICE_ID ) EmacPsIntrId = XPAR_AXI_INTC_0_PROCESSING_SYSTEM7_0_IRQ_P2F_ENET0_INTR ; #else if ( ( EmacPsInstancePtr -> Config . BaseAddress == ZYNQ_EMACPS_0_BASEADDR ) || ( EmacPsInstancePtr -> Config . BaseAddress == ZYNQMP_EMACPS_0_BASEADDR ) || ( EmacPsInstancePtr -> Config . BaseAddress == VERSAL_EMACPS_0_BASEADDR ) ) { EmacPsIntrId = XPS_GEM0_INT_ID ; } else if ( ( EmacPsInstancePtr -> Config . BaseAddress == ZYNQ_EMACPS_1_BASEADDR ) || ( EmacPsInstancePtr -> Config . BaseAddress == ZYNQMP_EMACPS_1_BASEADDR ) || ( EmacPsInstancePtr -> Config . BaseAddress == VERSAL_EMACPS_1_BASEADDR ) ) { EmacPsIntrId = XPS_GEM1_INT_ID ; } else if ( EmacPsInstancePtr -> Config . BaseAddress == ZYNQMP_EMACPS_2_BASEADDR ) { #ifdef XPS_GEM2_INT_ID EmacPsIntrId = XPS_GEM2_INT_ID ; #endif } else if ( EmacPsInstancePtr -> Config . BaseAddress == ZYNQMP_EMACPS_3_BASEADDR ) { #ifdef XPS_GEM3_INT_ID EmacPsIntrId = XPS_GEM3_INT_ID ; #endif } #endif GemVersion = ( ( Xil_In32 ( Config -> BaseAddress + 0xFC ) ) >> 16 ) & 0xFFF ; if ( GemVersion == GEMVERSION_VERSAL ) { Platform = Xil_In32 ( VERSAL_VERSION ) ; } else if ( GemVersion > 2 ) { Platform = Xil_In32 ( CSU_VERSION ) ; } if ( GemVersion > 2 ) { XEmacPs_SetOptions ( EmacPsInstancePtr , XEMACPS_JUMBO_ENABLE_OPTION ) ; } XEmacPsClkSetup ( EmacPsInstancePtr , EmacPsIntrId ) ; Status = XEmacPs_SetMacAddress ( EmacPsInstancePtr , EmacPsMAC , 1 ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XEmacPs_SetHandler ( EmacPsInstancePtr , XEMACPS_HANDLER_DMASEND , ( void * ) XEmacPsSendHandler , EmacPsInstancePtr ) ; Status |= XEmacPs_SetHandler ( EmacPsInstancePtr , XEMACPS_HANDLER_DMARECV , ( void * ) XEmacPsRecvHandler , EmacPsInstancePtr ) ; Status |= XEmacPs_SetHandler ( EmacPsInstancePtr , XEMACPS_HANDLER_ERROR , ( void * ) XEmacPsErrorHandler , EmacPsInstancePtr ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( GemVersion == 2 ) { #if ! defined ( __MICROBLAZE__ ) && ! defined ( ARMR5 ) Xil_SetTlbAttributes ( ( INTPTR ) bd_space , DEVICE_MEMORY ) ; #else Xil_DCacheDisable ( ) ; #endif } if ( GemVersion > 2 ) { #if defined ( ARMR5 ) Xil_SetTlbAttributes ( ( INTPTR ) bd_space , STRONG_ORDERD_SHARED | PRIV_RW_USER_RW ) ; #endif #if defined __aarch64__ Xil_SetTlbAttributes ( ( UINTPTR ) bd_space , NORM_NONCACHE | INNER_SHAREABLE ) ; #endif } RxBdSpacePtr = & ( bd_space [ 0 ] ) ; TxBdSpacePtr = & ( bd_space [ 0x10000 ] ) ; XEmacPs_BdClear ( & BdTemplate ) ; Status = XEmacPs_BdRingCreate ( & ( XEmacPs_GetRxRing ( EmacPsInstancePtr ) ) , ( UINTPTR ) RxBdSpacePtr , ( UINTPTR ) RxBdSpacePtr , XEMACPS_BD_ALIGNMENT , RXBD_CNT ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XEmacPs_BdRingClone ( & ( XEmacPs_GetRxRing ( EmacPsInstancePtr ) ) , & BdTemplate , XEMACPS_RECV ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } XEmacPs_BdClear ( & BdTemplate ) ; XEmacPs_BdSetStatus ( & BdTemplate , XEMACPS_TXBUF_USED_MASK ) ; Status = XEmacPs_BdRingCreate ( & ( XEmacPs_GetTxRing ( EmacPsInstancePtr ) ) , ( UINTPTR ) TxBdSpacePtr , ( UINTPTR ) TxBdSpacePtr , XEMACPS_BD_ALIGNMENT , TXBD_CNT ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } Status = XEmacPs_BdRingClone ( & ( XEmacPs_GetTxRing ( EmacPsInstancePtr ) ) , & BdTemplate , XEMACPS_SEND ) ; if ( Status != XST_SUCCESS ) { EmacPsUtilErrorTrap ( " " ) ; return XST_FAILURE ; } if ( GemVersion > 2 ) { XEmacPs_BdClear ( & BdRxTerminate ) ; XEmacPs_BdSetAddressRx ( & BdRxTerminate , ( XEMACPS_RXBUF_NEW_MASK | XEMACPS_RXBUF_WRAP_MASK ) ) ; XEmacPs_Out32 ( ( Config -> BaseAddress + XEMACPS_RXQ1BASE_OFFSET ) , ( UINTPTR ) & BdRxTerminate ) ; XEmacPs_BdClear ( & BdTxTerminate ) ; XEmacPs_BdSetStatus ( & BdTxTerminate , ( XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK ) ) ; XEmacPs_Out32 ( ( Config -> BaseAddress + XEMACPS_TXQBASE_OFFSET ) , ( UINTPTR ) & BdTxTerminate ) ; if ( Config -> IsCacheCoherent == 0 ) { Xil_DCacheFlushRange ( ( UINTPTR ) ( & BdTxTerminate ) , 64 ) ; } } if ( GemVersion == 2 ) { XEmacPs_SetMdioDivisor ( EmacPsInstancePtr , MDC_DIV_224 ) ; EmacpsDelay ( 1 ) ; EmacPsUtilEnterLoopback ( EmacPsInstancePtr , EMACPS_LOOPBACK_SPEED_1G ) ; XEmacPs_SetOperatingSpeed ( EmacPsInstancePtr , EMACPS_LOOPBACK_SPEED_1G ) ; } else { if ( ( Platform & PLATFORM_MASK_VERSAL ) == PLATFORM_VERSALEMU ) { XEmacPs_SetMdioDivisor ( EmacPsInstancePtr , MDC_DIV_8 ) ; } else { XEmacPs_SetMdioDivisor ( EmacPsInstancePtr , MDC_DIV_224 ) ; } if ( ( ( Platform & PLATFORM_MASK ) == PLATFORM_SILICON ) || ( ( Platform & PLATFORM_MASK_VERSAL ) == PLATFORM_VERSALSIL ) ) { EmacPsUtilEnterLoopback ( EmacPsInstancePtr , EMACPS_LOOPBACK_SPEED_1G ) ; XEmacPs_SetOperatingSpeed ( EmacPsInstancePtr , EMACPS_LOOPBACK_SPEED_1G ) ; } else { EmacPsUtilEnterLoopback ( EmacPsInstancePtr , EMACPS_LOOPBACK_SPEED ) ; XEmacPs_SetOperatingSpeed ( EmacPsInstancePtr , EMACPS_LOOPBACK_SPEED ) ; } } Status = EmacPsSetupIntrSystem ( IntcInstancePtr , EmacPsInstancePtr , EmacPsIntrId ) ; Status = EmacPsDmaSingleFrameIntrExample ( EmacPsInstancePtr ) ; if ( Status != XST_SUCCESS ) { return XST_FAILURE ; } EmacPsDisableIntrSystem ( IntcInstancePtr , EmacPsIntrId ) ; XEmacPs_Stop ( EmacPsInstancePtr ) ; return XST_SUCCESS ; }
This function demonstrates the usage of the EmacPs driver by sending by
sending and receiving frames in interrupt driven DMA mode.
This function demonstrates the usage of the EmacPs driver by sending by sending and receiving frames in interrupt driven DMA mode .
/*************************************/ /* Setup device for first-time usage */ /*************************************/ /*
	 *  Initialize instance. Should be configured for DMA
	 *  This example calls _CfgInitialize instead of _Initialize due to
	 *  retiring _Initialize. So in _CfgInitialize we use
	 *  XPAR_(IP)_BASEADDRESS to make sure it is not virtual address.
	 */ /* Request device to indicate it is in use by this application */ /* Enable jumbo frames for zynqmp */ /*
	 * Set the MAC address
	 */ /*
	 * Setup callbacks
	 */ /* Gem IP version on Zynq-7000 */ /*
		 * The BDs need to be allocated in uncached memory. Hence the 1 MB
		 * address range that starts at "bd_space" is made uncached.
		 */ /* Allocate Rx and Tx BD space each */ /*
	 * Setup RxBD space.
	 *
	 * We have already defined a properly aligned area of memory to store
	 * RxBDs at the beginning of this source code file so just pass its
	 * address into the function. No MMU is being used so the physical
	 * and virtual addresses are the same.
	 *
	 * Setup a BD template for the Rx channel. This template will be
	 * copied to every RxBD. We will not have to explicitly set these
	 * again.
	 */ /*
	 * Create the RxBD ring
	 */ /*
	 * Setup TxBD space.
	 *
	 * Like RxBD space, we have already defined a properly aligned area
	 * of memory to use.
	 *
	 * Also like the RxBD space, we create a template. Notice we don't
	 * set the "last" attribute. The example will be overriding this
	 * attribute so it does no good to set it up here.
	 */ /*
	 * Create the TxBD ring
	 */ /*
		 * This version of GEM supports priority queuing and the current
		 * driver is using tx priority queue 1 and normal rx queue for
		 * packet transmit and receive. The below code ensure that the
		 * other queue pointers are parked to known state for avoiding
		 * the controller to malfunction by fetching the descriptors
		 * from these queues.
		 */ /*
	 * Set emacps to phy loopback
	 */ /*
	 * Setup the interrupt controller and enable interrupts
	 */ /*
	 * Run the EmacPs DMA Single Frame Interrupt example
	 */ /*
	 * Disable the interrupts for the EmacPs device
	 */ /*
	 * Stop the device
	 */