コード例 #1
0
/*
 * this function is always called with interrupts off
 * this function also assumes that there are available BD's
 */
static err_t
_unbuffered_low_level_output(xlltemacif_s *xlltemacif, struct pbuf *p)
{
    	XStatus status = 0;

#if ETH_PAD_SIZE
	pbuf_header(p, -ETH_PAD_SIZE);			/* drop the padding word */
#endif
	if (XLlTemac_IsDma(&xlltemacif->lltemac))
		status = lldma_sgsend(xlltemacif, p);
	else
		status = xllfifo_send(xlltemacif, p);

	if (status != XST_SUCCESS) {
#if LINK_STATS
		lwip_stats.link.drop++;
#endif
	}

#if ETH_PAD_SIZE
	pbuf_header(p, ETH_PAD_SIZE);			/* reclaim the padding word */
#endif

#if LINK_STATS
	lwip_stats.link.xmit++;
#endif /* LINK_STATS */

	return ERR_OK;

}
コード例 #2
0
int
is_tx_space_available(xlltemacif_s *emac)
{
	if (XLlTemac_IsDma(&emac->lltemac)) {
		XLlDma_BdRing *txring = &XLlDma_GetTxRing(&emac->lldma);

		/* tx space is available as long as there are valid BD's */
		return XLlDma_BdRingGetFreeCnt(txring);
	} else {
		return ((XLlFifo_TxVacancy(&emac->llfifo) * 4) > XTE_MAX_FRAME_SIZE);
	}
}
コード例 #3
0
/**
*
* 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
static err_t
low_level_init(struct netif *netif)
{
	unsigned mac_address = (unsigned)(netif->state);
	struct xemac_s *xemac;
	xlltemacif_s *xlltemacif;

	xlltemacif = mem_malloc(sizeof *xlltemacif);
	if (xlltemacif == NULL) {
		LWIP_DEBUGF(NETIF_DEBUG, ("xlltemacif_init: out of memory\r\n"));
		return ERR_MEM;
	}

	xemac = mem_malloc(sizeof *xemac);
	if (xemac == NULL) {
		LWIP_DEBUGF(NETIF_DEBUG, ("xlltemacif_init: out of memory\r\n"));
		return ERR_MEM;
	}

	xemac->state = (void *)xlltemacif;
	xemac->topology_index = xtopology_find_index(mac_address);
	xemac->type = xemac_type_xps_ll_temac;

	xlltemacif->send_q = NULL;
	xlltemacif->recv_q = pq_create_queue();
	if (!xlltemacif->recv_q)
		return ERR_MEM;

	/* maximum transfer unit */
#ifdef USE_JUMBO_FRAMES
	netif->mtu = XTE_JUMBO_MTU - XTE_HDR_SIZE;
#else
	netif->mtu = XTE_MTU - XTE_HDR_SIZE;
#endif
#if LWIP_IGMP
	netif->igmp_mac_filter = xlltemacif_mac_filter_update;
#endif

	/* broadcast capability */
	netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;

#if LWIP_IGMP
	netif->flags |= NETIF_FLAG_IGMP;
#endif

#if !NO_SYS
	sys_sem_new(&xemac->sem_rx_data_available, 0);
#endif
	/* initialize the mac */
	init_lltemac(xlltemacif, netif);

	/* figure out if the system has DMA */
	if (XLlTemac_IsDma(&xlltemacif->lltemac)) {
		/* initialize the DMA engine */
		init_sdma(xemac);
	} else if (XLlTemac_IsFifo(&xlltemacif->lltemac)) {
		/* initialize the locallink FIFOs */
		init_ll_fifo(xemac);
	} else {
		/* should not occur */
		LWIP_DEBUGF(NETIF_DEBUG, ("xlltemacif_init: lltemac is not configured with DMA or FIFO\r\n"));
		return ERR_IF;
	}

	/* replace the state in netif (currently the emac baseaddress)
	 * with the xlltemac instance pointer.
	 */
	netif->state = (void *)xemac;

	return ERR_OK;
}