Пример #1
0
void
init_lltemac(xlltemacif_s *xlltemacif, struct netif *netif)
{
	int rdy;
	unsigned mac_address = (unsigned)(netif->state);
	unsigned link_speed = 1000;
	unsigned options;
        unsigned lock_message_printed = 0;

	/* obtain config of this emac */
	XLlTemac_Config *mac_config = lookup_config(mac_address);

	XLlTemac *xlltemacp = &xlltemacif->lltemac;

	XLlTemac_CfgInitialize(xlltemacp, mac_config, mac_config->BaseAddress);

	options = XLlTemac_GetOptions(xlltemacp);
	options |= XTE_FLOW_CONTROL_OPTION;
	options |= XTE_JUMBO_OPTION;
	options |= XTE_TRANSMITTER_ENABLE_OPTION;
	options |= XTE_RECEIVER_ENABLE_OPTION;
	options |= XTE_FCS_STRIP_OPTION;
	options |= XTE_MULTICAST_OPTION;
	XLlTemac_SetOptions(xlltemacp, options);
	XLlTemac_ClearOptions(xlltemacp, ~options);

	/* set mac address */
	XLlTemac_SetMacAddress(xlltemacp, (Xuint8*)(netif->hwaddr));

	/* make sure the hard TEMAC is ready */
	rdy = XLlTemac_ReadReg(xlltemacp->Config.BaseAddress,
			XTE_RDY_OFFSET);
	while ((rdy & XTE_RDY_HARD_ACS_RDY_MASK) == 0) {
		rdy = XLlTemac_ReadReg(xlltemacp->Config.BaseAddress,
				XTE_RDY_OFFSET);
	}

	link_speed = Phy_Setup(xlltemacp);
    	XLlTemac_SetOperatingSpeed(xlltemacp, link_speed);

	/* Setting the operating speed of the MAC needs a delay. */
	{
		volatile int wait;
		for (wait=0; wait < 100000; wait++);
		for (wait=0; wait < 100000; wait++);
	}

        /* in a soft temac implementation, we need to explicitly make sure that
         * the RX DCM has been locked. See xps_ll_temac manual for details.
         * This bit is guaranteed to be 1 for hard temac's
         */
        lock_message_printed = 0;
        while (!(XLlTemac_ReadReg(xlltemacp->Config.BaseAddress, XTE_IS_OFFSET)
                    & XTE_INT_RXDCM_LOCK_MASK)) {
                int first = 1;
                if (first) {
                        print("Waiting for RX DCM to lock..");
                        first = 0;
                        lock_message_printed = 1;
                }
        }

        if (lock_message_printed)
                print("RX DCM locked.\r\n");

	/* start the temac */
    	XLlTemac_Start(xlltemacp);

	/* enable TEMAC interrupts */
	XLlTemac_IntEnable(xlltemacp, XTE_INT_RECV_ERROR_MASK);
}
Пример #2
0
/**
 * in the TEMAC channel's multicast filter list.
 *
 * XLlTemac_MulticastAdd adds the Ethernet address, <i>AddressPtr</i> to the
 * TEMAC channel's multicast filter list, at list index <i>Entry</i>. The
 * address referenced by <i>AddressPtr</i> may be of any unicast, multicast, or
 * broadcast address form. The harware for the TEMAC channel can hold up to
 * XTE_MULTI_MAT_ENTRIES addresses in this filter list.<br><br>
 *
 * The device must be stopped to use this function.<br><br>
 *
 * Once an Ethernet address is programmed, the TEMAC channel will begin
 * receiving data sent from that address. The TEMAC hardware does not have a
 * control bit to disable multicast filtering. The only way to prevent the
 * TEMAC channel from receiving messages from an Ethernet address in the
 * Multicast Address Table (MAT) is to clear it with XLlTemac_MulticastClear().
 *
 * @param InstancePtr references the TEMAC channel on which to operate.
 * @param AddressPtr is a pointer to the 6-byte Ethernet address to set. The
 *        previous address at the location <i>Entry</i> (if any) is overwritten
 *        with the value at <i>AddressPtr</i>.
 * @param Entry is the hardware storage location to program this address and
 *        must be between 0..XTE_MULTI_MAT_ENTRIES-1. 
 *
 * @return On successful completion, XLlTemac_MulticastAdd returns XST_SUCCESS.
 *         Otherwise, if the TEMAC channel is not stopped, XLlTemac_MulticastAdd
 *         returns XST_DEVICE_IS_STARTED.
 *
 * @note
 *
 * This routine accesses the hard TEMAC registers through a shared interface
 * between both channels of the TEMAC. Becuase of this, the application/OS code
 * must provide mutual exclusive access to this routine with any of the other
 * routines in this TEMAC driverr.
 *
 ******************************************************************************/
XStatus XLlTemac_MulticastAdd(XLlTemac *InstancePtr, void *AddressPtr, int Entry)
{
	u32 Maw0Reg;
	u32 Maw1Reg;
	u8 *Aptr = (u8 *) AddressPtr;
	u32 Rdy;
	int MaxWait = 100;
	u32 BaseAddress = InstancePtr->Config.BaseAddress;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
	XASSERT_NONVOID(AddressPtr != NULL);
	XASSERT_NONVOID(Entry < XTE_MULTI_MAT_ENTRIES);
	/*
	 * If the mutual exclusion is enforced properly in the calling code, we
	 * should never get into the following case.
	 */
	XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
			XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);

	xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastAdd\n");

	/* The device must be stopped before clearing the multicast hash table */
	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
		xdbg_printf(XDBG_DEBUG_GENERAL,
			   "XLlTemac_MulticastAdd: returning DEVICE_IS_STARTED\n");

		return (XST_DEVICE_IS_STARTED);
	}

	/* Set MAC bits [31:0] */
	Maw0Reg = Aptr[0];
	Maw0Reg |= Aptr[1] << 8;
	Maw0Reg |= Aptr[2] << 16;
	Maw0Reg |= Aptr[3] << 24;

	/* Set MAC bits [47:32] */
	Maw1Reg = Aptr[4];
	Maw1Reg |= Aptr[5] << 8;

	/* Add in MAT address */
	Maw1Reg |= (Entry << XTE_MAW1_MATADDR_SHIFT_MASK);

	/* Program HW */
	xdbg_printf(XDBG_DEBUG_GENERAL, "Setting MAT entry: %d\n", Entry);
	XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET, Maw0Reg);
	XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
			XTE_MAW0_OFFSET | XTE_CTL_WEN_MASK);
	Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
	while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
		Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
		xdbg_stmnt(
			if (MaxWait == 100) {
				xdbg_printf(XDBG_DEBUG_GENERAL,
					    "RDY reg not initially ready\n");
			}
		);
		MaxWait--;
		xdbg_stmnt(
			if (MaxWait == 0) {
				xdbg_printf (XDBG_DEBUG_GENERAL,
					     "RDY reg never showed ready\n");
			}
		)
	}
/**
*
* 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;
}
Пример #4
0
					    "RDY reg not initially ready\n");
			}
		);
		MaxWait--;
		xdbg_stmnt(
			if (MaxWait == 0) {
				xdbg_printf (XDBG_DEBUG_GENERAL,
					     "RDY reg never showed ready\n");
			}
		)
	}
	XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET,
			Maw1Reg);
	XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
			XTE_MAW1_OFFSET | XTE_CTL_WEN_MASK);
	Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
	while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
		Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
		xdbg_stmnt(
			if (MaxWait == 100) {
				xdbg_printf(XDBG_DEBUG_GENERAL,
					    "RDY reg not initially ready\n");
			}
		);
		MaxWait--;
		xdbg_stmnt(
			if (MaxWait == 0) {
				xdbg_printf (XDBG_DEBUG_GENERAL,
					     "RDY reg never showed ready\n");
			}
		)
/**
*
* 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;


}