int main(void)
{
	int Status;


#ifdef XPAR_XUARTNS550_NUM_INSTANCES
    XUartNs550_SetBaud(STDIN_BASEADDRESS, XPAR_XUARTNS550_CLOCK_HZ, 115200);
    XUartNs550_mSetLineControlReg(STDIN_BASEADDRESS, XUN_LCR_8_DATA_BITS);
#endif

	/*
	 * Call the Temac SGDMA interrupt example , specify the parameters generated
	 * in xparameters.h
	 */
	Status = TemacSgDmaIntrExample(&IntcInstance,
				       &TemacInstance,
				       &DmaInstance,
				       TEMAC_DEVICE_ID,
				       TEMAC_IRPT_INTR,
				       DMA_RX_IRPT_INTR, DMA_TX_IRPT_INTR);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Failure in Examples");
		return XST_FAILURE;
	}

	TemacUtilErrorTrap("Success in Examples");
	return XST_SUCCESS;

}
/**
*
* This is the Receive handler function for examples 1 and 2.
* It will increment a shared  counter, receive and validate the frame.
*
* @param    RxRingPtr is a pointer to the DMA ring instance.
*
* @return   None.
*
* @note     None.
*
******************************************************************************/
static void RxIntrHandler(XLlDma_BdRing * RxRingPtr)
{
	u32 IrqStatus;

	/* Read pending interrupts */
	IrqStatus = XLlDma_BdRingGetIrq(RxRingPtr);

	/* Acknowledge pending interrupts */
	XLlDma_BdRingAckIrq(RxRingPtr, IrqStatus);

	/* If error interrupt is asserted, raise error flag, reset the
	 * hardware to recover from the error, and return with no further
	 * processing.
	 */
	if ((IrqStatus & XLLDMA_IRQ_ALL_ERR_MASK)) {
		DeviceErrors++;
		TemacUtilErrorTrap ("LlDma: Error: IrqStatus & XLLDMA_IRQ_ALL_ERR_MASK");
		XLlDma_Reset(&DmaInstance);
		return;
	}

	/*
	 * If Reception done interrupt is asserted, call RX call back function
	 * to handle the processed BDs and then raise the according flag.
	 */
	if ((IrqStatus & (XLLDMA_IRQ_DELAY_MASK | XLLDMA_IRQ_COALESCE_MASK))) {
		RxCallBack(RxRingPtr);
	}
}
/**
*
* This is the Error handler callback function and this function increments the
* the error counter so that the main thread knows the number of errors.
*
* @param    Temac is a reference to the Temac device instance.
*
* @return   None.
*
* @note     None.
*
******************************************************************************/
static void TemacErrorHandler(XLlTemac * Temac)
{
	u32 Pending = XLlTemac_IntPending(Temac);

	if (Pending & XTE_INT_RXRJECT_MASK) {
		TemacUtilErrorTrap("Temac: Rx packet rejected");
	}

	if (Pending & XTE_INT_RXFIFOOVR_MASK) {
		TemacUtilErrorTrap("Temac: Rx fifo over run");
	}

	XLlTemac_IntClear(Temac, Pending);

	/*
	 * Bump counter
	 */
	DeviceErrors++;
}
/**
* This functions polls the Tx status and waits for an indication that a frame
* has been transmitted successfully or a transmit related error has occurred.
* If an error is reported, it handles all the possible  error conditions.
*
* @param    None.
*
* @return   Status is the status of the last call to the
*           XLlTemac_FifoQuerySendStatus() function.
*
* @note     None.
*
******************************************************************************/
int TemacPollForTxStatus(void)
{
	int Status = XST_NO_DATA;
	int Attempts = 100000;	/* Number of attempts to get status before giving
				   up */

	/*
	 * Wait for transmit complete indication
	 */
	do {

		if (--Attempts <= 0)
			break;	/* Give up? */

		if (XLlFifo_Status(&FifoInstance) & XLLF_INT_TC_MASK) {
			XLlFifo_IntClear(&FifoInstance, XLLF_INT_TC_MASK);
			Status = XST_SUCCESS;
		}
		if (XLlFifo_Status(&FifoInstance) & XLLF_INT_ERROR_MASK) {
			Status = XST_FIFO_ERROR;
		}

	} while (Status == XST_NO_DATA);


	switch (Status) {
	case XST_SUCCESS:	/* Frame sent without error */
	case XST_NO_DATA:	/* Timeout */
		break;

	case XST_FIFO_ERROR:
		TemacUtilErrorTrap("FIFO error");
		TemacResetDevice();
		break;

	default:
		TemacUtilErrorTrap("Driver returned unknown transmit status");
		break;
	}

	return (Status);
}
/**
* This function resets the device but preserves the options set by the user.
*
* The descriptor list could be reinitialized with the same calls to
* XLlTemac_SgSetSpace() as used in main(). Doing this is a matter of preference.
* In many cases, an OS may have resources tied up in the descriptors.
* Reinitializing in this case may bad for the OS since its resources may be
* permamently lost.
*
* @param    TemacInstancePtr is a pointer to the instance of the Temac
*           component.
*
* @return   XST_SUCCESS if successful, else XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
static int TemacResetDevice(XLlTemac * TemacInstancePtr,
				XLlDma * DmaInstancePtr)
{
	int Status;
	u8 MacSave[6];
	u32 Options;
	//u32 RxThreshold = 1;
	//u32 TxThreshold = 1;
	//u32 RxWaitbound = 0;
	//u32 TxWaitbound = 0;
	//XLlDma_BdRing * RxRingPtr = &XLlDma_GetRxRing(DmaInstancePtr);
	//XLlDma_BdRing * TxRingPtr = &XLlDma_GetTxRing(DmaInstancePtr);

	/*
	 * Stop LLTEMAC device
	 */
	XLlTemac_Stop(TemacInstancePtr);

	/*
	 * Save the device state
	 */
	XLlTemac_GetMacAddress(TemacInstancePtr, MacSave);
	Options = XLlTemac_GetOptions(TemacInstancePtr);

	/*
	 * Stop and reset the device
	 */
	XLlTemac_Reset(TemacInstancePtr, XTE_NORESET_HARD);

	/*
	 * Restore the state
	 */
	Status = XLlTemac_SetMacAddress(TemacInstancePtr, MacSave);
	Status |= XLlTemac_SetOptions(TemacInstancePtr, Options);
	Status |= XLlTemac_ClearOptions(TemacInstancePtr, ~Options);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error restoring state after reset");
		return XST_FAILURE;
	}

	/*
	 * Restart the device
	 */
	XLlTemac_Start(TemacInstancePtr);
	return XST_SUCCESS;
}
/**
* This function resets the device but preserves the options set by the user.
*
* @param    None.
*
* @return   XST_SUCCESS if successful, else XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacResetDevice(void)
{
	int Status;
	u8 MacSave[6];
	u32 Options;

	/*
	 * Stop device
	 */
	XLlTemac_Stop(&TemacInstance);

	/*
	 * Save the device state
	 */
	XLlTemac_GetMacAddress(&TemacInstance, MacSave);
	Options = XLlTemac_GetOptions(&TemacInstance);

	/*
	 * Stop and reset both the fifo and the temac the devices
	 */
	XLlFifo_Reset(&FifoInstance);
	XLlTemac_Reset(&TemacInstance, XTE_NORESET_HARD);

	/*
	 * Restore the state
	 */
	Status = XLlTemac_SetMacAddress(&TemacInstance, MacSave);
	Status |= XLlTemac_SetOptions(&TemacInstance, Options);
	Status |= XLlTemac_ClearOptions(&TemacInstance, ~Options);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error restoring state after reset");
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
/**
*
* This function demonstrates the usage of the TEMAC by sending and receiving
* a single frame in SGDMA interrupt mode.
* The source packet will be described by two descriptors. It will be received
* into a buffer described by a single descriptor.
*
* @param    TemacInstancePtr is a pointer to the instance of the Temac
*           component.
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacSgDmaIntrSingleFrameExample(XLlTemac * TemacInstancePtr,
				     XLlDma * DmaInstancePtr)
{
	int Status;
	u32 TxFrameLength;
	int PayloadSize = 1000;
	XLlDma_BdRing *RxRingPtr = &XLlDma_GetRxRing(DmaInstancePtr);
	XLlDma_BdRing *TxRingPtr = &XLlDma_GetTxRing(DmaInstancePtr);
	XLlDma_Bd *Bd1Ptr;
	XLlDma_Bd *Bd2Ptr;

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

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

	/*
	 * Setup packet to be transmitted
	 */
	TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC);
	TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize);

        /*
         * Flush the TX frame before giving it to DMA TX channel to transmit,
         * in case D-Caching is turned on.
         */
	XCACHE_FLUSH_DCACHE_RANGE(&TxFrame, TxFrameLength);

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

        /*
         * Invalidate the RX frame before giving it to DMA RX channel to
         * receive data, in case D-Caching is turned on.
         */
	XCACHE_INVALIDATE_DCACHE_RANGE(&RxFrame, TxFrameLength);

	/*
	 * Start the LLTEMAC device and enable the ERROR interrupt
	 */
	XLlTemac_Start(TemacInstancePtr);
	XLlTemac_IntEnable(TemacInstancePtr, XTE_INT_RECV_ERROR_MASK);

	/*
	 * Allocate 1 RxBD. Note that TEMAC utilizes an in-place allocation
	 * scheme. The returned Bd1Ptr will point to a free BD in the memory
	 * segment setup with the call to XLlTemac_SgSetSpace()
	 */
	Status = XLlDma_BdRingAlloc(RxRingPtr, 1, &Bd1Ptr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup the BD. The BD template used in the call to XLlTemac_SgSetSpace()
	 * set the "last" field of all RxBDs. Therefore we are not required to
	 * issue a XLlDma_Bd_mSetLast(Bd1Ptr) here.
	 */
	XLlDma_BdSetBufAddr(Bd1Ptr, &RxFrame);
	XLlDma_BdSetLength(Bd1Ptr, sizeof(RxFrame));
	XLlDma_BdSetStsCtrl(Bd1Ptr, XLLDMA_BD_STSCTRL_SOP_MASK | XLLDMA_BD_STSCTRL_EOP_MASK);

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

	/*
	 * Enable DMA RX interrupt.
	 *
	 * Interrupt coalescing parameters are left at their default settings
	 * which is to interrupt the processor after every frame has been
	 * processed by the DMA engine.
	 */
	XLlDma_BdRingIntEnable(RxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);

	/*
	 * Start DMA RX channel. Now it's ready to receive data.
	 */
	Status = XLlDma_BdRingStart(RxRingPtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Allocate, setup, and enqueue 2 TxBDs. The first BD will describe
	 * the first 32 bytes of TxFrame and the second BD will describe the
	 * rest of the frame.
	 *
	 * The function below will allocate two adjacent BDs with Bd1Ptr being
	 * set as the lead BD.
	 */
	Status = XLlDma_BdRingAlloc(TxRingPtr, 2, &Bd1Ptr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error allocating TxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup TxBD #1
	 */
	XLlDma_BdSetBufAddr(Bd1Ptr, &TxFrame);
	XLlDma_BdSetLength(Bd1Ptr, 32);
	XLlDma_BdSetStsCtrl(Bd1Ptr, XLLDMA_BD_STSCTRL_SOP_MASK);

	/*
	 * Setup TxBD #2
	 */
	Bd2Ptr = XLlDma_BdRingNext(TxRingPtr, Bd1Ptr);
	XLlDma_BdSetBufAddr(Bd2Ptr, (u32) (&TxFrame) + 32);
	XLlDma_BdSetLength(Bd2Ptr, TxFrameLength - 32);
	XLlDma_BdSetStsCtrl(Bd2Ptr, XLLDMA_BD_STSCTRL_EOP_MASK);

	/*
	 * Enqueue to HW
	 */
	Status = XLlDma_BdRingToHw(TxRingPtr, 2, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		/*
		 * Undo BD allocation and exit
		 */
		XLlDma_BdRingUnAlloc(TxRingPtr, 2, Bd1Ptr);
		TemacUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}

	/*
	 * Enable DMA transmit interrupts
	 */
	XLlDma_BdRingIntEnable(TxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);

	/*
	 * Start DMA TX channel. Transmission starts at once.
	 */
	Status = XLlDma_BdRingStart(TxRingPtr);
	if (Status != XST_SUCCESS) {
		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 (XLlDma_BdRingFromHw(TxRingPtr, 2, &Bd1Ptr) == 0) {
		TemacUtilErrorTrap("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 = XLlDma_BdRingFree(TxRingPtr, 2, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error freeing up TxBDs");
		return XST_FAILURE;
	}


	/*
	 * Wait for Rx indication
	 */
	while (!FramesRx);

    printf("Transmitted Packet!\r\n");
    printf("\r\n");

	/*
	 * 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 (XLlDma_BdRingFromHw(RxRingPtr, 1, &Bd1Ptr) == 0) {
		TemacUtilErrorTrap("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 LLTEMAC case, USR4_OFFSET word in the RX BD is used to store
	 * the real length of the received packet
	 */
        if ((XLlDma_BdRead(Bd1Ptr, XLLDMA_BD_USR4_OFFSET) & 0x3FFF)

                != TxFrameLength) {

                TemacUtilErrorTrap("Length mismatch");

                return XST_FAILURE;

        }



        if (TemacUtilFrameVerify(&TxFrame, &RxFrame) != 0) {

                TemacUtilErrorTrap("Data mismatch");

                return XST_FAILURE;

        }


	/*
	 * Return the RxBD back to the channel for later allocation. Free the
	 * exact number we just post processed.
	 */
	Status = XLlDma_BdRingFree(RxRingPtr, 1, Bd1Ptr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("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.
	 */
	XLlTemac_Stop(TemacInstancePtr);

	return XST_SUCCESS;
}
/**
*
* This function demonstrates the usage usage of the TEMAC by sending by sending
* and receiving frames in interrupt driven SGDMA mode.
*
*
* @param    IntcInstancePtr is a pointer to the instance of the Intc component.
* @param    TemacInstancePtr is a pointer to the instance of the Temac
*           component.
* @param    TemacDeviceId is Device ID of the Temac Device , typically
*           XPAR_<TEMAC_instance>_DEVICE_ID value from xparameters.h.
* @param    TemacIntrId is the Interrupt ID and is typically
*           XPAR_<INTC_instance>_<TEMAC_instance>_IP2INTC_IRPT_INTR
*           value from xparameters.h.
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacSgDmaIntrExample(XIntc * IntcInstancePtr,
			  XLlTemac * TemacInstancePtr,
			  XLlDma * DmaInstancePtr,
			  u16 TemacDeviceId,
			  u16 TemacIntrId, u16 DmaRxIntrId, u16 DmaTxIntrId)
{
	int Status;
	u32 Rdy;
	int dma_mode;
	XLlTemac_Config *MacCfgPtr;
	XLlDma_BdRing *RxRingPtr = &XLlDma_GetRxRing(DmaInstancePtr);
	XLlDma_BdRing *TxRingPtr = &XLlDma_GetTxRing(DmaInstancePtr);
	XLlDma_Bd BdTemplate;

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

	/*
	 *  Initialize instance. Should be configured for SGDMA
	 */
	MacCfgPtr = XLlTemac_LookupConfig(TemacDeviceId);
	Status = XLlTemac_CfgInitialize(TemacInstancePtr, MacCfgPtr,
					MacCfgPtr->BaseAddress);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error in initialize");
		return XST_FAILURE;
	}

	XLlDma_Initialize(DmaInstancePtr, TemacInstancePtr->Config.LLDevBaseAddress);

	/*
	 * Check whether the IPIF interface is correct for this example
	 */
	dma_mode = XLlTemac_IsDma(TemacInstancePtr);
	if (! dma_mode) {
		TemacUtilErrorTrap
			("Device HW not configured for SGDMA mode\r\n");
		return XST_FAILURE;
	}

	/*
	 * Set the MAC address
	 */
	Status = XLlTemac_SetMacAddress(TemacInstancePtr, TemacMAC);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting MAC address");
		return XST_FAILURE;
	}

	/*
	 * 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.
	 */
	XLlDma_BdClear(&BdTemplate);

	/*
	 * Create the RxBD ring
	 */
	Status = XLlDma_BdRingCreate(RxRingPtr, (u32) &RxBdSpace,
				     (u32) &RxBdSpace, BD_ALIGNMENT, RXBD_CNT);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting up RxBD space");
		return XST_FAILURE;
	}
	Status = XLlDma_BdRingClone(RxRingPtr, &BdTemplate);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error initializing RxBD space");
		return XST_FAILURE;
	}

	/*
	 * Setup TxBD space.
	 *
	 * Like RxBD space, we have already defined a properly aligned area of
	 * memory to use.
	 */

	/*
	 * Create the TxBD ring
	 */
	Status = XLlDma_BdRingCreate(TxRingPtr, (u32) &TxBdSpace,
				     (u32) &TxBdSpace, BD_ALIGNMENT, TXBD_CNT);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting up TxBD space");
		return XST_FAILURE;
	}
	/*
	 * We reuse the bd template, as the same one will work for both rx and tx.
	 */
	Status = XLlDma_BdRingClone(TxRingPtr, &BdTemplate);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error initializing TxBD space");
		return XST_FAILURE;
	}


	/* Make sure the hard temac is ready */
	Rdy = XLlTemac_ReadReg(TemacInstancePtr->Config.BaseAddress,
			       XTE_RDY_OFFSET);
	while ((Rdy & XTE_RDY_HARD_ACS_RDY_MASK) == 0) {
		Rdy = XLlTemac_ReadReg(TemacInstancePtr->Config.BaseAddress,
				       XTE_RDY_OFFSET);
	}


#if !SIM
	/*
	 * Set PHY to loopback
	 */
	TemacUtilEnterLoopback(TemacInstancePtr, TEMAC_LOOPBACK_SPEED);

	/*
	 * Set PHY<-->MAC data clock
	 */
	XLlTemac_SetOperatingSpeed(TemacInstancePtr, TEMAC_LOOPBACK_SPEED);

	/*
	 * Setting the operating speed of the MAC needs a delay.  There
	 * doesn't seem to be register to poll, so please consider this
	 * during your application design.
	 */
	TemacUtilPhyDelay(2);
#endif

	/*
	 * Connect to the interrupt controller and enable interrupts
	 */
	Status = TemacSetupIntrSystem(IntcInstancePtr,
				      TemacInstancePtr,
				      DmaInstancePtr,
				      TemacIntrId, DmaRxIntrId, DmaTxIntrId);


    /****************************/
	/* Run through the examples */
    /****************************/

	/*
	 * Run the Temac SGDMA Single Frame Interrupt example
	 */
	Status = TemacSgDmaIntrSingleFrameExample(TemacInstancePtr,
						  DmaInstancePtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Disable the interrupts for the Temac device
	 */
	TemacDisableIntrSystem(IntcInstancePtr, TemacIntrId, DmaRxIntrId,
			       DmaTxIntrId);

	/*
	 * Stop the device
	 */
	XLlTemac_Stop(TemacInstancePtr);

	return XST_SUCCESS;
}
int main(void)
{
	int Status;

   /*
    * Enable and initialize cache
    */
#if !SIM

   #if XPAR_MICROBLAZE_0_USE_ICACHE
      microblaze_invalidate_icache();
      microblaze_enable_icache();
   #endif

   #if XPAR_MICROBLAZE_0_USE_DCACHE
      microblaze_invalidate_dcache();
       microblaze_enable_dcache();
   #endif
#endif


	XUartNs550_SetBaud(UART_BASEADDR, UART_CLOCK, UART_BAUDRATE);
	XUartNs550_SetLineControlReg(UART_BASEADDR, XUN_LCR_8_DATA_BITS);


  xil_printf("\n\r********************************************************");
  xil_printf("\n\r********************************************************");
  xil_printf("\n\r**     SP605 - Temac Test                             **");
  xil_printf("\n\r********************************************************");
  xil_printf("\n\r********************************************************\r\n");

	printf("Setting Temac and DMA\r\n");
    printf("\r\n");

	/*
	 * Call the Temac SGDMA interrupt example , specify the parameters generated
	 * in xparameters.h
	 */
	Status = TemacSgDmaIntrExample(&IntcInstance,
				       &TemacInstance,
				       &DmaInstance,
				       TEMAC_DEVICE_ID,
				       TEMAC_IRPT_INTR,
				       DMA_RX_IRPT_INTR, DMA_TX_IRPT_INTR);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Failure in Examples");
		return XST_FAILURE;
	}

    printf("Received Packet!\r\n");
    printf("\r\n");

#if !SIM

   #if XPAR_MICROBLAZE_0_USE_DCACHE
      microblaze_disable_dcache();
      microblaze_invalidate_dcache();
   #endif

   #if XPAR_MICROBLAZE_0_USE_ICACHE
      microblaze_disable_icache();
      microblaze_invalidate_icache();
   #endif
#endif

	return_to_loader();

	return 0;

}
/**
*
* This function setups the interrupt system so interrupts can occur for the
* TEMAC.  This function is application-specific since the actual system may or
* may not have an interrupt controller.  The TEMAC could be directly connected
* to a processor without an interrupt controller.  The user should modify this
* function to fit the application.
*
* @param    IntcInstancePtr is a pointer to the instance of the Intc component.
* @param    TemacInstancePtr is a pointer to the instance of the Temac
*           component.
* @param    TemacIntrId is the Interrupt ID and is typically
*           XPAR_<INTC_instance>_<TEMAC_instance>_IP2INTC_IRPT_INTR
*           value from xparameters.h.
*
* @return   XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
static int TemacSetupIntrSystem(XIntc *IntcInstancePtr,
				XLlTemac *TemacInstancePtr,
				XLlDma *DmaInstancePtr,
				u16 TemacIntrId,
				u16 DmaRxIntrId,
				u16 DmaTxIntrId)
{
	XLlDma_BdRing * TxRingPtr = &XLlDma_GetTxRing(DmaInstancePtr);
	XLlDma_BdRing * RxRingPtr = &XLlDma_GetRxRing(DmaInstancePtr);
	int Status;
#ifndef TESTAPP_GEN
	/*
	 * Initialize the interrupt controller and connect the ISR
	 */
	Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Unable to intialize the interrupt controller");
		return XST_FAILURE;
	}
#endif
	Status = XIntc_Connect(IntcInstancePtr, TemacIntrId,
			       (XInterruptHandler)
			       TemacErrorHandler,
			       TemacInstancePtr);
	Status |= XIntc_Connect(IntcInstancePtr, DmaTxIntrId,
				(XInterruptHandler) TxIntrHandler,
				TxRingPtr);
	Status |= XIntc_Connect(IntcInstancePtr, DmaRxIntrId,
				(XInterruptHandler) RxIntrHandler,
				RxRingPtr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Unable to connect ISR to interrupt controller");
		return XST_FAILURE;
	}

#ifndef TESTAPP_GEN
	/*
	 * Start the interrupt controller
	 */
	Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error starting intc");
		return XST_FAILURE;
	}
#endif


	/*
	 * Enable interrupts from the hardware
	 */
	XIntc_Enable(IntcInstancePtr, TemacIntrId);
	XIntc_Enable(IntcInstancePtr, DmaTxIntrId);
	XIntc_Enable(IntcInstancePtr, DmaRxIntrId);
#ifndef TESTAPP_GEN
#ifdef __PPC__
	/*
	 * Initialize the PPC exception table
	 */
	XExc_Init();
	/*
	 * Register the interrupt controller with the exception table
	 */
	XExc_RegisterHandler(XEXC_ID_NON_CRITICAL_INT,
				(XExceptionHandler)
				XIntc_InterruptHandler,
				IntcInstancePtr);
	/*
	 * Enable non-critical exceptions
	 */
	XExc_mEnableExceptions(XEXC_NON_CRITICAL);
#else
	/*
	 * Connect the interrupt controller interrupt handler to the hardware
	 * interrupt handling logic in the microblaze processor.
	 */
	microblaze_register_handler((XInterruptHandler)
			XIntc_InterruptHandler, IntcInstancePtr);

	/*
	* Enable interrupts in the Microblaze
	*/
	microblaze_enable_interrupts();
#endif
#endif
	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    TemacInstancePtr is a pointer to the instance of the Temac
*           component.
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacSgDmaChecksumOffloadExample(XLlTemac * TemacInstancePtr,
				     XLlDma * DmaInstancePtr)
{
	int Status;
	u32 TxFrameLength;
	int PayloadSize = 1000;
	XLlDma_BdRing *RxRingPtr = &XLlDma_mGetRxRing(DmaInstancePtr);
	XLlDma_BdRing *TxRingPtr = &XLlDma_mGetTxRing(DmaInstancePtr);
	XLlDma_Bd *BdPtr;

	/*
	 * Cannot run this example if checksum offloading support is not available
	 */
	if (!(XLlTemac_IsRxCsum(TemacInstancePtr) &&
	      XLlTemac_IsTxCsum(TemacInstancePtr))) {
		TemacUtilErrorTrap("Checksum offloading not available");
		return XST_FAILURE;
	}

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

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

	/*
	 * Setup the packet to be transmitted,
	 * Last 2 bytes are reserved for checksum
	 */
	TemacUtilFrameMemClear(&TxFrame);
	TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC);
	TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize - 2);

        /*
         * Flush the TX frame before giving it to DMA TX channel to transmit,
         * in case D-Caching is turned on.
         */
	XCACHE_FLUSH_DCACHE_RANGE(&TxFrame, TxFrameLength);

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

        /*
         * Invalidate the RX frame before giving it to DMA RX channel to
         * receive data, in case D-Caching is turned on.
         */
	XCACHE_INVALIDATE_DCACHE_RANGE(&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 = XLlDma_BdRingSetCoalesce(TxRingPtr, 1, 1);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting coalescing for transmit");
		return XST_FAILURE;
	}

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

	/*
	 * Make sure Tx and Rx are enabled
	 */
	Status = XLlTemac_SetOptions(TemacInstancePtr,
				     XTE_RECEIVER_ENABLE_OPTION |
				     XTE_TRANSMITTER_ENABLE_OPTION);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting options");
		return XST_FAILURE;
	}

	/*
	 * Start the LLTEMAC and enable its ERROR interrupts
	 */
	XLlTemac_Start(TemacInstancePtr);
	XLlTemac_IntEnable(TemacInstancePtr, XTE_INT_RECV_ERROR_MASK);

	/*
	 * Allocate 1 RxBD. Note that TEMAC utilizes an in-place allocation
	 * scheme. The returned BdPtr will point to a free BD in the memory
	 * segment setup with the call to XLlTemac_SgSetSpace()
	 */
	Status = XLlDma_BdRingAlloc(RxRingPtr, 1, &BdPtr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error allocating RxBD");
		return XST_FAILURE;
	}

	/*
	 * Setup the BD. The BD template used in the call to XLlTemac_SgSetSpace()
	 * set the SOP and EOP fields of all RxBDs.
	 */
	XLlDma_mBdSetBufAddr(BdPtr, &RxFrame);
	XLlDma_mBdSetLength(BdPtr, sizeof(RxFrame));
	XLlDma_mBdSetStsCtrl(BdPtr, XLLDMA_BD_STSCTRL_SOP_MASK |
			     XLLDMA_BD_STSCTRL_EOP_MASK);


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

	/*
	 * Enable DMA receive related interrupts
	 */
	XLlDma_mBdRingIntEnable(RxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);

	/*
	 * As DMA RX channel has been started in
	 * TemacSgDmaIntrSingleFrameExample() above, there is no need to start
	 * it again here
	 */

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

	/*
	 * Setup the TxBD
	 */
	XLlDma_mBdSetBufAddr(BdPtr, &TxFrame);
	XLlDma_mBdSetLength(BdPtr, TxFrameLength);
	XLlDma_mBdSetStsCtrl(BdPtr, XLLDMA_BD_STSCTRL_SOP_MASK |
			     XLLDMA_BD_STSCTRL_EOP_MASK);

	/*
	 * Setup TxBd checksum offload attributes.
	 * Note that the checksum offload values can be set globally for all TxBds
	 * when XLlDma_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 */
	XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET,
			(XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)
			 | CSUM_ENABLE));
	/* Write Start Offset and Insert Offset into BD */
	XLlDma_mBdWrite(BdPtr, XLLDMA_BD_USR1_OFFSET,
					XTE_HDR_SIZE << 16 | TxFrameLength - 2);
	/* Write 0, as the seed value, to the BD */
	XLlDma_mBdWrite(BdPtr, XLLDMA_BD_USR2_OFFSET, 0);
	/*
	 * Enqueue to HW
	 */
	Status = XLlDma_BdRingToHw(TxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error committing TxBD to HW");
		return XST_FAILURE;
	}

	/*
	 * Enable DMA transmit related interrupts
	 */
	XLlDma_mBdRingIntEnable(TxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);

	/*
	 * As DMA TX channel has been started in
	 * TemacSgDmaIntrSingleFrameExample() above, there is no need to start
	 * it again here
	 */

	/*
	 * 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 (XLlDma_BdRingFromHw(TxRingPtr, 1, &BdPtr) == 0) {
		TemacUtilErrorTrap("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 = XLlDma_BdRingFree(TxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("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 (XLlDma_BdRingFromHw(RxRingPtr, 1, &BdPtr) == 0) {
		TemacUtilErrorTrap("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 LLTEMAC case, USR4_OFFSET word in the RX BD is used to store
	 * the real length of the received packet
	 */
	if (XLlDma_mBdRead(BdPtr, XLLDMA_BD_USR4_OFFSET) != TxFrameLength) {
		TemacUtilErrorTrap("Length mismatch");
	}

	/*
	 * Verify the checksum as computed by HW. It should add up to 0xFFFF
	 * if frame was uncorrupted
	 */
	if ((u16) (XLlDma_mBdRead(BdPtr, XLLDMA_BD_USR3_OFFSET))
		!= 0xFFFF) {
		TemacUtilErrorTrap("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 = XLlDma_BdRingFree(RxRingPtr, 1, BdPtr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("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.
	 */
	XLlTemac_Stop(TemacInstancePtr);
	return XST_SUCCESS;
}
/**
*
* This example sends frames with the interrupt coalescing settings altered
* from their defaults.
*
* The default settings will interrupt the processor after every frame has been
* sent. This example will increase the threshold resulting in lower CPU
* utilization since it spends less time servicing interrupts.
*
* @param    TemacInstancePtr is a pointer to the instance of the Temac
*           component.
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacSgDmaIntrCoalescingExample(XLlTemac * TemacInstancePtr,
				    XLlDma * DmaInstancePtr)
{
	int Status;
	u32 TxFrameLength;
	int TxFramesToSend = 1000;
	int TxFramesSent = 0;
	int PayloadSize = XTE_MTU;
	u32 Index;
	u32 NumBd;
	u16 Threshold = 64;
	XLlDma_BdRing *RxRingPtr = &XLlDma_mGetRxRing(DmaInstancePtr);
	XLlDma_BdRing *TxRingPtr = &XLlDma_mGetTxRing(DmaInstancePtr);
	XLlDma_Bd *BdPtr, *BdCurPtr;

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

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

	/*
	 * Setup packet to be transmitted. The same packet will be transmitted
	 * over and over
	 */
	TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC);
	TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize);

        /*
         * Flush the TX frame before giving it to DMA TX channel to transmit,
         * in case D-Caching is turned on.
         */
	XCACHE_FLUSH_DCACHE_RANGE(&TxFrame, TxFrameLength);

	/*
	 * We don't care about the receive channel for this example, so turn it off
	 */
	Status = XLlTemac_ClearOptions(TemacInstancePtr,
				       XTE_RECEIVER_ENABLE_OPTION);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error clearing option");
		return XST_FAILURE;
	}

	/*
	 * Set the interrupt coalescing parameters for the test. The waitbound timer
	 * is set to 1 (ms) to catch the last few frames.
	 *
	 * If you set variable Threshold to some value larger than TXBD_CNT, then
	 * there can never be enough frames sent to meet the threshold. In this case
	 * the waitbound timer will always cause the interrupt to occur.
	 */
	Status = XLlDma_BdRingSetCoalesce(TxRingPtr, Threshold, 1);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting coalescing settings");
		return XST_FAILURE;
	}

	/*
	 * Prime the engine, allocate all BDs and assign them to the same buffer
	 */
	Status = XLlDma_BdRingAlloc(TxRingPtr, TXBD_CNT, &BdPtr);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error allocating TxBDs prior to starting");
		return XST_FAILURE;
	}

	/*
	 * Setup the TxBDs
	 */
	BdCurPtr = BdPtr;

	for (Index = 0; Index < TXBD_CNT; Index++) {
		XLlDma_mBdSetBufAddr(BdCurPtr, &TxFrame);
		XLlDma_mBdSetLength(BdCurPtr, TxFrameLength);
		XLlDma_mBdSetStsCtrl(BdCurPtr, XLLDMA_BD_STSCTRL_SOP_MASK |
				     XLLDMA_BD_STSCTRL_EOP_MASK);
		BdCurPtr = XLlDma_mBdRingNext(TxRingPtr, BdCurPtr);
	}

	/*
	 *  Enqueue all TxBDs to HW
	 */
	Status = XLlDma_BdRingToHw(TxRingPtr, TXBD_CNT, BdPtr);

	TxFramesSent += TXBD_CNT;
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error committing TxBDs prior to starting");
		return XST_FAILURE;
	}

	/*
	 * Enable the send interrupts. Nothing should be transmitted yet as the
	 * device has not been started
	 */
	XLlDma_mBdRingIntEnable(TxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);
	/* Enable temac interrupts to capture errors */
	XLlTemac_IntEnable(TemacInstancePtr, XTE_INT_RECV_ERROR_MASK);

	/*
	 * Start the device. Transmission commences now!
	 */
	XLlTemac_Start(TemacInstancePtr);

	/*
	 * As DMA TX channel has been started in
	 * TemacSgDmaIntrSingleFrameExample() above, there is no need to start
	 * it again here
	 */

	while (TxFramesSent < TxFramesToSend) {
		/*
		 * Wait for the interrupt
		 */
		while (!FramesTx);

		/*
		 * Some TxBDs are ready for post processing. Get all that are available
		 * at the moment, free them, then allocate the same number and
		 * re-enqueue back to HW. At the same time this all occurs here,
		 * the DMA engine should be processing other TxBDs. If we can stay ahead
		 * of the transmitter like this, then throughput should be at or near
		 * line-rate.
		 *
		 * Note that this retrieves up to TXBD_CNT outstanding packets,
		 * so we may be processing more packets here than the threshold
		 * value, which may result in a seemingly spurious interrupt
		 * next time if we grab twice (or more) of the threshold value
		 * this time around (clear as mud, eh!).  Bottom line is that we
		 * ignore if NumBd returns as zero.
		 */
		NumBd = XLlDma_BdRingFromHw(TxRingPtr, TXBD_CNT, &BdPtr);
		if (NumBd > 0) {
			TxFramesSent += NumBd;

			/*
			 * Don't bother to check the BDs status, just free them
			 */
			Status = XLlDma_BdRingFree(TxRingPtr, NumBd, BdPtr);
			if (Status != XST_SUCCESS) {
				TemacUtilErrorTrap("Error freeing TxBDs");
			}

			/*
			 * Allocate the same number of BDs just freed
			 */
			Status = XLlDma_BdRingAlloc(TxRingPtr, NumBd, &BdPtr);
			if (Status != XST_SUCCESS) {
				TemacUtilErrorTrap("Error allocating TxBDs");
				return XST_FAILURE;
			}

			/*
			 * Setup the TxBDs
			 */
			BdCurPtr = BdPtr;
			for (Index = 0; Index < NumBd; Index++) {
				XLlDma_mBdSetBufAddr(BdCurPtr, &TxFrame);
				XLlDma_mBdSetLength(BdCurPtr, TxFrameLength);
				XLlDma_mBdSetStsCtrl(BdCurPtr,
						     XLLDMA_BD_STSCTRL_SOP_MASK
						     |
						     XLLDMA_BD_STSCTRL_EOP_MASK);
				BdCurPtr =
					XLlDma_mBdRingNext(TxRingPtr, BdCurPtr);
			}

			/*
			 * Enqueue TxBDs to HW
			 */
			Status = XLlDma_BdRingToHw(TxRingPtr, NumBd, BdPtr);
			if (Status != XST_SUCCESS) {
				TemacUtilErrorTrap
					("Error committing TxBDs prior to starting");
				return XST_FAILURE;
			}
		}

		/*
		 * Re-enable the interrupts
		 */
		FramesTx = 0;
		XLlDma_mBdRingIntEnable(TxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);
	}

	/*
	 * Wait a second and collect any remaining frames that had been
	 * queued up but not post processed
	 */
#ifndef __MICROBLAZE__
	usleep(1000000);
#else
	/*
	 * Not sure if we should depend on there being a timer core in a
	 * microblaze system
	 */
	TemacUtilPhyDelay(1);
#endif

	NumBd = XLlDma_BdRingFromHw(TxRingPtr, 0xFFFFFFFF, &BdPtr);

	if (NumBd > 0) {
		Status = XLlDma_BdRingFree(TxRingPtr, NumBd, BdPtr);
		if (Status != XST_SUCCESS) {
			TemacUtilErrorTrap("Error freeing TxBDs");
		}
	}

	/*
	 * Done sending frames. Stop the device
	 */
	XLlTemac_Stop(TemacInstancePtr);

	return XST_SUCCESS;
}
Exemplo n.º 13
0
/**
* This functions polls the Rx status and waits for an indication that a frame
* has arrived or a receive related error has occurred. If an error is reported,
* handle all the possible  error conditions.
*
* @param    None.
*
* @return   Status is the status of the last call to the
*           XLlTemac_FifoQueryRecvStatus() function.
*
* @note     None.
*
******************************************************************************/
int TemacPollForRxStatus(void)
{
	int Status = XST_NO_DATA;
	int Attempts = 1000000;	/* number of times to get a status before
					   giving up */

	/*
	 * There are two ways to poll for a received frame:
	 *
	 * XLlTemac_Recv() can be used and repeatedly called until it returns a
	 * length,  but this method does not provide any error detection.
	 *
	 * XLlTemac_FifoQueryRecvStatus() can be used and this function provides
	 * more information to handle error conditions.
	 */

	/*
	 * Wait for something to happen
	 */
	do {
		if (--Attempts <= 0)
			break;	/* Give up? */

		/*
		 * Try to get status
		 * We could have polled the status bits instead. Either way works.
		 */
		if (!XLlFifo_IsRxEmpty(&FifoInstance)) {
			Status = XST_SUCCESS;
		}
		if (XLlFifo_Status(&FifoInstance) & XLLF_INT_ERROR_MASK) {
			Status = XST_FIFO_ERROR;
		}
		if (XLlTemac_Status(&TemacInstance) & XTE_INT_RXRJECT_MASK) {
			Status = XST_DATA_LOST;
		}
		/* When the RXFIFOOVR bit is set, the RXRJECT bit also gets set */
		if (XLlTemac_Status(&TemacInstance) & XTE_INT_RXFIFOOVR_MASK) {
			Status = XST_DATA_LOST;
		}
	} while (Status == XST_NO_DATA);

	switch (Status) {
	case XST_SUCCESS:	/* Frame has arrived */
	case XST_NO_DATA:	/* Timeout */
		break;

	case XST_DATA_LOST:
		TemacUtilErrorTrap("Frame was dropped");
		break;

	case XST_FIFO_ERROR:
		TemacUtilErrorTrap("FIFO error");
		TemacResetDevice();
		break;

	default:
		TemacUtilErrorTrap("Driver returned invalid transmit status");
		break;
	}

	return (Status);
}
Exemplo n.º 14
0
/**
*
* This example uses polled mode to queue up multiple frames in the packet
* FIFOs before sending them in a single burst. Receive packets are handled in
* a similar way.
*
* @param    None.
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacMultipleFramesPolledExample(void)
{
	u32 FramesToLoopback;
	u32 PayloadSize;
	u32 TxFrameLength;
	u32 RxFrameLength;
	u32 FifoFreeBytes;
	u32 Index;

	/*
	 * Start the TEMAC device
	 */
	XLlTemac_Start(&TemacInstance);

	/*
	 * Setup the number of frames to loopback (FramesToLoopback) and the size
	 * of the frame (PayloadSize) to loopback. The default settings should
	 * work for every case. Modifying the settings can cause problems, see
	 * discussion below:
	 *
	 * If PayloadSize is set small and FramesToLoopback high, then it is
	 * possible to cause the transmit status FIFO to overflow.
	 *
	 * If PayloadSize is set large and FramesToLoopback high, then it is
	 * possible to cause the transmit packet FIFO to overflow.
	 *
	 * Either of these scenarios may be worth trying out to observe how the
	 * driver reacts. The exact values to cause these types of errors
	 * will vary due to the sizes of the FIFOs selected at hardware build
	 * time. But the following settings should create problems for all
	 * FIFO sizes:
	 *
	 * Transmit status FIFO overflow
	 *    PayloadSize = 1
	 *    FramesToLoopback = 1000
	 *
	 * Transmit packet FIFO overflow
	 *    PayloadSize = 1500
	 *    FramesToLoopback = 16
	 *
	 * These values should always work without error
	 *    PayloadSize = 100
	 *    FramesToLoopback = 5
	 */
	PayloadSize = 100;
	FramesToLoopback = 5;

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

	/*
	 * Setup the packet to be transmitted
	 */
	TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC);
	TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize);

	/****************/
	/* Send packets */
	/****************/

	/*
	 * Since we may be interested to see what happens when FIFOs overflow, don't
	 * check for room in the transmit packet FIFO prior to writing to it.
	 */

	/*
	 * Write frame data to FIFO
	 * Fifo core only allows loading and sending one frame at a time.
	 */
	for (Index = 0; Index < FramesToLoopback; Index++) {
		/* Make sure there is room in the FIFO */
		do {
			FifoFreeBytes = XLlFifo_TxVacancy(&FifoInstance);
		} while (FifoFreeBytes < TxFrameLength);

		XLlFifo_Write(&FifoInstance, TxFrame, TxFrameLength);
		XLlFifo_TxSetLen(&FifoInstance, TxFrameLength);

		switch (TemacPollForTxStatus()) {
		case XST_SUCCESS:	/* Got a sucessfull transmit status */
			break;

		case XST_NO_DATA:	/* Timed out */
			TemacUtilErrorTrap("Tx timeout");
			return XST_FAILURE;
			break;

		default:	/* Some other error */
			TemacResetDevice();
			return XST_FAILURE;
		}
	}

	/**********************/
	/* Receive the packet */
	/**********************/

	/*
	 * Wait for the packets to arrive
	 * The Fifo core only allows us to pull out one frame at a time.
	 */
	for (Index = 0; Index < FramesToLoopback; Index++) {
		/*
		 * Wait for packet Rx
		 */
		switch (TemacPollForRxStatus()) {
		case XST_SUCCESS:	/* Got a successfull receive status */
			break;

		case XST_NO_DATA:	/* Timed out */
			TemacUtilErrorTrap("Rx timeout");
			return XST_FAILURE;
			break;

		default:	/* Some other error */
			TemacResetDevice();
			return XST_FAILURE;
		}

		while(XLlFifo_RxOccupancy(&FifoInstance)) {
			/*
			 * A packet has arrived, get its length
			 */
			RxFrameLength = XLlFifo_RxGetLen(&FifoInstance);
	
			/*
			 * Verify the received frame length
			 */
			if ((RxFrameLength) != TxFrameLength) {
				TemacUtilErrorTrap("Receive length incorrect");
				return XST_FAILURE;
			}
			/*
			 * Read the received packet data
			 */
			XLlFifo_Read(&FifoInstance, &RxFrame, RxFrameLength);

			if (TemacUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
				TemacUtilErrorTrap("Receive Data Mismatch");
				return XST_FAILURE;
			}
		}
	}

	/*
	 * Stop device
	 */
	XLlTemac_Stop(&TemacInstance);

	return XST_SUCCESS;
}
Exemplo n.º 15
0
/**
*
* This function demonstrates the usage of the TEMAC by sending and receiving
* a single frame in polled mode.
*
* @param    None.
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note     None.
*
******************************************************************************/
int TemacSingleFramePolledExample(void)
{
	u32 FifoFreeBytes;
	int PayloadSize = 100;
	u32 TxFrameLength;
	u32 RxFrameLength;

	/*
	 * Start the TEMAC device
	 */
	XLlTemac_Start(&TemacInstance);

	/*
	 * Setup the packet to be transmitted
	 */
	TemacUtilFrameHdrFormatMAC(&TxFrame, TemacMAC);
	TemacUtilFrameHdrFormatType(&TxFrame, PayloadSize);
	TemacUtilFrameSetPayloadData(&TxFrame, PayloadSize);

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

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

	/*******************/
	/* Send the packet */
	/*******************/

	/*
	 * Wait for enough room in FIFO to become available
	 */
	do {
		FifoFreeBytes = XLlFifo_TxVacancy(&FifoInstance);
	} while (FifoFreeBytes < TxFrameLength);

	/*
	 * Write the frame data to FIFO
	 */
	XLlFifo_Write(&FifoInstance, TxFrame, TxFrameLength);

	/*
	 * Initiate transmit
	 */
	XLlFifo_TxSetLen(&FifoInstance, TxFrameLength);

	/*
	 * Wait for status of the transmitted packet
	 */
	switch (TemacPollForTxStatus()) {
	case XST_SUCCESS:	/* Got a sucessfull transmit status */
		break;

	case XST_NO_DATA:	/* Timed out */
		TemacUtilErrorTrap("Tx timeout");
		return XST_FAILURE;

	default:		/* Some other error */
		return XST_FAILURE;
	}

	/**********************/
	/* Receive the packet */
	/**********************/

	/*
	 * Wait for packet Rx
	 */
	switch (TemacPollForRxStatus()) {
	case XST_SUCCESS:	/* Got a sucessfull receive status */
		break;

	case XST_NO_DATA:	/* Timed out */
		TemacUtilErrorTrap("Rx timeout");
		return XST_FAILURE;

	default:		/* Some other error */
		return XST_FAILURE;
	}

	while(XLlFifo_RxOccupancy(&FifoInstance)) {
		/*
		 * A packet as arrived, get its length
		 */
		RxFrameLength = XLlFifo_RxGetLen(&FifoInstance);

		/*
		 * Read the received packet data
		 */
		XLlFifo_Read(&FifoInstance, &RxFrame, RxFrameLength);
	
		/*
		 * Verify the received frame length
		 */
		if ((RxFrameLength) != TxFrameLength) {
			TemacUtilErrorTrap("Receive length incorrect");
			return XST_FAILURE;
		}

		/*
		 * Validate frame data
		 */
		if (TemacUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
			TemacUtilErrorTrap("Receive Data mismatch");
			return XST_FAILURE;
		}
	}

	/*
	 * Stop device
	 */
	XLlTemac_Stop(&TemacInstance);

	return XST_SUCCESS;
}
Exemplo n.º 16
0
/**
*
* This function demonstrates the usage of the TEMAC by sending and receiving
* frames in polled mode.
*
*
* @param    TemacDeviceId is device ID of the Temac Device , typically
*           XPAR_<TEMAC_instance>_DEVICE_ID value from xparameters.h
*
* @return   XST_SUCCESS to indicate success, otherwise XST_FAILURE
*
* @note     None.
*
******************************************************************************/
int TemacPolledExample(u16 TemacDeviceId, u16 FifoDeviceId)
{
	int Status;
	XLlTemac_Config *MacCfgPtr;
	u32 Rdy;
	int LoopbackSpeed;

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

	/*
	 * Initialize the FIFO and TEMAC instance
	 */
	MacCfgPtr = XLlTemac_LookupConfig(TemacDeviceId);
	Status = XLlTemac_CfgInitialize(&TemacInstance, MacCfgPtr,
					MacCfgPtr->BaseAddress);

	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error in initialize");
		return XST_FAILURE;
	}
	XLlFifo_Initialize(&FifoInstance,
			    XLlTemac_LlDevBaseAddress(&TemacInstance));

	/*
	 * Check whether the IPIF interface is correct for this example
	 */
	if (!XLlTemac_IsFifo(&TemacInstance)) {
		TemacUtilErrorTrap
			("Device HW not configured for FIFO direct mode\r\n");
		return XST_FAILURE;
	}

	/*
	 * Set the MAC  address
	 */
	Status = XLlTemac_SetMacAddress(&TemacInstance, (u8 *) TemacMAC);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Error setting MAC address");
		return XST_FAILURE;
	}

        /* Make sure the hard temac is ready */
	Rdy = XLlTemac_ReadReg(TemacInstance.Config.BaseAddress,
			       XTE_RDY_OFFSET);
	while ((Rdy & XTE_RDY_HARD_ACS_RDY_MASK) == 0) {
		Rdy = XLlTemac_ReadReg(TemacInstance.Config.BaseAddress,
				       XTE_RDY_OFFSET);
	}

        /*
         * Set PHY to loopback, speed depends on phy type.
         * MII is 100 and all others are 1000.
         */
        if (XLlTemac_GetPhysicalInterface(&TemacInstance) == XTE_PHY_TYPE_MII)
        {
                LoopbackSpeed = TEMAC_LOOPBACK_SPEED;
        } else {
                LoopbackSpeed = TEMAC_LOOPBACK_SPEED_1G;
        }
        Status = TemacUtilEnterLoopback(&TemacInstance, LoopbackSpeed);
        if (Status != XST_SUCCESS) {
                TemacUtilErrorTrap("Error setting the PHY loopback");
                return XST_FAILURE;
        }

        /*
         * Set PHY<-->MAC data clock
         */
        XLlTemac_SetOperatingSpeed(&TemacInstance, (u16)LoopbackSpeed);

	/*
	 * Setting the operating speed of the MAC needs a delay.  There
	 * doesn't seem to be register to poll, so please consider this
	 * during your application design.
	 */
	TemacUtilPhyDelay(2);

	/****************************/
	/* Run through the examples */
	/****************************/

	/*
	 * Run the Single Frame polled example
	 */
	Status = TemacSingleFramePolledExample();
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Run the Multiple Frames polled example
	 */
	Status = TemacMultipleFramesPolledExample();
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;


}