[U-Boot] [PATCH 2/2] net: Add Xilinx LL Temac driver

Ben Warren biggerbadderben at gmail.com
Thu Jan 29 08:09:33 CET 2009


Hi Michal,

I'm really sorry for taking so long getting to this. Mostly little things:

monstr at monstr.eu wrote:
> From: Michal Simek <monstr at monstr.eu>
>
>
> Signed-off-by: Michal Simek <monstr at monstr.eu>
> ---
>  drivers/net/Makefile          |    1 +
>  drivers/net/xilinx_ll_temac.c |  543 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 544 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/xilinx_ll_temac.c
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 128dc11..ed64787 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -69,6 +69,7 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o
>  COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
>  COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o
>  COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
> +COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o
>  
>  COBJS	:= $(COBJS-y)
>  SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/net/xilinx_ll_temac.c b/drivers/net/xilinx_ll_temac.c
> new file mode 100644
> index 0000000..d1e63e2
> --- /dev/null
> +++ b/drivers/net/xilinx_ll_temac.c
> @@ -0,0 +1,543 @@
> +/*
> + *
> + * Xilinx xps_ll_temac ethernet driver for u-boot
> + *
> + * Author: Yoshio Kashiwagi kashiwagi at co-nss.co.jp
> + *
> + * Copyright (C) 2008 Nissin Systems Co.,Ltd.
> + * March 2008 created
> + *
> + * Copyright (C) 2008 - 2009 Michal Simek <monstr at monstr.eu>
> + * June 2008 Microblaze optimalization, FIFO mode support
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +#include <net.h>
> +#include <malloc.h>
> +#include <asm/processor.h>
> +#include <asm/io.h>
> +
> +#ifdef XILINX_LLTEMAC_FIFO_BASEADDR
> +# define FIFO_MODE	1
> +#elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR
> +# define SDMA_MODE	1
> +#else
> +# error Unsupported mode
> +#endif
> +
> +#undef ETH_HALTING
> +
> +#ifdef SDMA_MODE
> +/* XPS_LL_TEMAC SDMA registers definition */
> +# define TX_NXTDESC_PTR		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x00)
> +# define TX_CURBUF_ADDR		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x04)
> +# define TX_CURBUF_LENGTH	(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x08)
> +# define TX_CURDESC_PTR		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x0c)
> +# define TX_TAILDESC_PTR	(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x10)
> +# define TX_CHNL_CTRL		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x14)
> +# define TX_IRQ_REG		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x18)
> +# define TX_CHNL_STS		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x1c)
> +
> +# define RX_NXTDESC_PTR		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x20)
> +# define RX_CURBUF_ADDR		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x24)
> +# define RX_CURBUF_LENGTH	(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x28)
> +# define RX_CURDESC_PTR		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x2c)
> +# define RX_TAILDESC_PTR	(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x30)
> +# define RX_CHNL_CTRL		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x34)
> +# define RX_IRQ_REG		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x38)
> +# define RX_CHNL_STS		(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x3c)
> +
> +# define DMA_CONTROL_REG	(XILINX_LLTEMAC_SDMA_CTRL_BASEADDR + 0x40)
> +#endif
> +
> +/* XPS_LL_TEMAC direct registers definition */
> +#define TEMAC_RAF0		(XILINX_LLTEMAC_BASEADDR + 0x00)
> +#define TEMAC_TPF0		(XILINX_LLTEMAC_BASEADDR + 0x04)
> +#define TEMAC_IFGP0		(XILINX_LLTEMAC_BASEADDR + 0x08)
> +#define TEMAC_IS0		(XILINX_LLTEMAC_BASEADDR + 0x0c)
> +#define TEMAC_IP0		(XILINX_LLTEMAC_BASEADDR + 0x10)
> +#define TEMAC_IE0		(XILINX_LLTEMAC_BASEADDR + 0x14)
> +
> +#define TEMAC_MSW0		(XILINX_LLTEMAC_BASEADDR + 0x20)
> +#define TEMAC_LSW0		(XILINX_LLTEMAC_BASEADDR + 0x24)
> +#define TEMAC_CTL0		(XILINX_LLTEMAC_BASEADDR + 0x28)
> +#define TEMAC_RDY0		(XILINX_LLTEMAC_BASEADDR + 0x2c)
> +
> +#define XTE_RSE_MIIM_RR_MASK	0x0002
> +#define XTE_RSE_MIIM_WR_MASK	0x0004
> +#define XTE_RSE_CFG_RR_MASK	0x0020
> +#define XTE_RSE_CFG_WR_MASK	0x0040
> +
> +/* XPS_LL_TEMAC indirect registers offset definition */
> +
> +#define RCW0	0x200
> +#define RCW1	0x240
> +#define TC	0x280
> +#define FCC	0x2c0
> +#define EMMC	0x300
> +#define PHYC	0x320
> +#define MC	0x340
> +#define UAW0	0x380
> +#define UAW1	0x384
> +#define MAW0	0x388
> +#define MAW1	0x38c
> +#define AFM	0x390
> +#define TIS	0x3a0
> +#define TIE	0x3a4
> +#define MIIMWD	0x3b0
> +#define MIIMAI	0x3b4
> +
> +#define CNTLREG_WRITE_ENABLE_MASK	0x8000
> +#define CNTLREG_EMAC1SEL_MASK		0x0400
> +#define CNTLREG_ADDRESSCODE_MASK	0x03ff
> +
> +#define MDIO_ENABLE_MASK	0x40
> +#define MDIO_CLOCK_DIV_MASK	0x3F
> +#define MDIO_CLOCK_DIV_100MHz	0x28
> +
> +#define ETHER_MTU		1520
> +
> +#ifdef SDMA_MODE
> +/* CDMAC descriptor status bit definitions */
> +# define BDSTAT_ERROR_MASK		0x80
> +# define BDSTAT_INT_ON_END_MASK		0x40
> +# define BDSTAT_STOP_ON_END_MASK	0x20
> +# define BDSTAT_COMPLETED_MASK		0x10
> +# define BDSTAT_SOP_MASK		0x08
> +# define BDSTAT_EOP_MASK		0x04
> +# define BDSTAT_CHANBUSY_MASK		0x02
> +# define BDSTAT_CHANRESET_MASK		0x01
> +
> +/* SDMA Buffer Descriptor */
> +
> +typedef struct cdmac_bd_t {
> +	struct cdmac_bd_t *next_p;
> +	unsigned char *phys_buf_p;
> +	unsigned long buf_len;
> +	unsigned char stat;
> +	unsigned char app1_1;
> +	unsigned short app1_2;
> +	unsigned long app2;
> +	unsigned long app3;
> +	unsigned long app4;
> +	unsigned long app5;
> +} cdmac_bd __attribute((aligned(32))) ;
> +
> +static cdmac_bd	tx_bd;
> +static cdmac_bd	rx_bd;
> +#endif
> +
> +#ifdef FIFO_MODE
> +typedef struct ll_fifo_s {
> +	int isr; /* Interrupt Status Register 0x0 */
> +	int ier; /* Interrupt Enable Register 0x4 */
> +	int tdfr; /* Transmit data FIFO reset 0x8 */
> +	int tdfv; /* Transmit data FIFO Vacancy 0xC */
> +	int tdfd; /* Transmit data FIFO 32bit wide data write port 0x10 */
> +	int tlf; /* Write Transmit Length FIFO 0x14 */
> +	int rdfr; /* Read Receive data FIFO reset 0x18 */
> +	int rdfo; /* Receive data FIFO Occupancy 0x1C */
> +	int rdfd; /* Read Receive data FIFO 32bit wide data read port 0x20 */
> +	int rlf; /* Read Receive Length FIFO 0x24 */
> +	int llr; /* Read LocalLink reset 0x28 */
> +} ll_fifo_s;
> +
> +ll_fifo_s *ll_fifo = (ll_fifo_s *) (XILINX_LLTEMAC_FIFO_BASEADDR);
> +#endif
> +
> +static unsigned char tx_buffer[ETHER_MTU] __attribute((aligned(32)));
> +static unsigned char rx_buffer[ETHER_MTU] __attribute((aligned(32)));
> +
> +struct xps_ll_temac_private {
> +	int idx;
> +	unsigned char dev_addr[6];
> +};
> +
> +#ifdef DEBUG
> +/* undirect hostif write to ll_temac */
> +static void xps_ll_temac_hostif_set(int emac, int phy_addr,
> +					int reg_addr, int phy_data)
> +{
> +	out_be32((u32 *)TEMAC_LSW0, phy_data);
> +	out_be32((u32 *)TEMAC_CTL0, CNTLREG_WRITE_ENABLE_MASK | MIIMWD);
> +	out_be32((u32 *)TEMAC_LSW0, (phy_addr << 5) | (reg_addr));
> +	out_be32((u32 *)TEMAC_CTL0, \
> +			CNTLREG_WRITE_ENABLE_MASK | MIIMAI | (emac << 10));
> +	while(! (in_be32((u32 *)TEMAC_RDY0) & XTE_RSE_MIIM_WR_MASK));
> +}
> +#endif
> +
> +/* undirect hostif read from ll_temac */
> +static unsigned int xps_ll_temac_hostif_get(int emac, int phy_addr, int reg_addr)
> +{
> +	out_be32((u32 *)TEMAC_LSW0, (phy_addr << 5) | (reg_addr));
> +	out_be32((u32 *)TEMAC_CTL0, MIIMAI | (emac << 10));
> +	while(! (in_be32((u32 *)TEMAC_RDY0) & XTE_RSE_MIIM_RR_MASK));
> +	return in_be32((u32 *)TEMAC_LSW0);
> +}
> +
> +/* undirect write to ll_temac */
> +static void xps_ll_temac_indirect_set(int emac, int reg_offset, int reg_data)
> +{
> +	out_be32((u32 *)TEMAC_LSW0, reg_data);
> +	out_be32((u32 *)TEMAC_CTL0, \
> +			CNTLREG_WRITE_ENABLE_MASK | (emac << 10) | reg_offset);
> +	while(! (in_be32((u32 *)TEMAC_RDY0) & XTE_RSE_CFG_WR_MASK));
> +}
> +
> +/* undirect read from ll_temac */
> +int xps_ll_temac_indirect_get(int emac, int reg_offset)
> +{
> +	out_be32((u32 *)TEMAC_CTL0, (emac << 10) | reg_offset);
> +	while(! (in_be32((u32 *)TEMAC_RDY0) & XTE_RSE_CFG_RR_MASK));
> +	return in_be32((u32 *)TEMAC_LSW0);
> +}
> +
> +#ifdef DEBUG
> +/* read from phy */
> +static void read_phy_reg (int phy_addr)
> +{
> +	int j, result;
> +	printf("phy%d ",phy_addr);
> +	for ( j = 0; j < 32; j++) {
> +		result = xps_ll_temac_hostif_get(0, phy_addr, j);
> +		printf("%d: 0x%x ", j, result);
> +	}
> +	puts("\n");
> +}
> +#endif
> +
>   
You only use this function in one place. Why not move this code to that 
place and use debug()
> +static int phy_addr = -1;
> +static int link = 0;
> +
> +/* setting ll_temac and phy to proper setting */
> +static int xps_ll_temac_phy_ctrl(void)
> +{
> +	int i;
> +	unsigned int result;
> +	unsigned retries = 10;
> +
> +	if(link == 1)
> +		return 1; /* link is setup */
> +
> +	/* wait for link up */
> +	while (retries-- &&
> +		((xps_ll_temac_hostif_get(0, phy_addr, 1) & 0x24) == 0x24))
> +		;
> +
> +	if(phy_addr == -1) {
> +		for(i = 31; i >= 0; i--) {
> +			result = xps_ll_temac_hostif_get(0, i, 1);
> +			if((result & 0x0ffff) != 0x0ffff) {
> +#ifdef DEBUG
> +				printf ("phy %x result %x\n", i, result);
> +#endif
> +				phy_addr = i;
> +				break;
> +			}
> +		}
> +	}
> +
> +	/* get PHY id */
> +	i = (xps_ll_temac_hostif_get(0, phy_addr, 2) << 16) | \
> +		xps_ll_temac_hostif_get(0, phy_addr, 3);
> +#ifdef DEBUG
> +	printf("LL_TEMAC: Phy ID 0x%x\n", i);
>   
Please use debug() instead
> +#endif
> +
> +#ifdef DEBUG
> +	xps_ll_temac_hostif_set(0, 0, 0, 0x8000); /* phy reset */
> +#endif
> +	/* FIXME this part will be replaced by PHY lib */
> +	/* s3e boards */
> +	if (i == 0x7c0a3) {
> +		xps_ll_temac_indirect_set(0, EMMC, 0x40000000); /* 100BASE-T/FD */
> +		link = 1;
> +		return 1;
> +	}
> +
> +	/* Marwell 88e1111 id - ml50x */
> +	if (i == 0x1410cc2) {
> +		result = xps_ll_temac_hostif_get(0, phy_addr, 5);
> +		if((result & 0x8000) == 0x8000) {
> +			xps_ll_temac_indirect_set(0, EMMC, 0x80000000);
> +			printf("1000BASE-T/FD\n");
> +			link = 1;
> +		} else if((result & 0x4000) == 0x4000) {
> +			xps_ll_temac_indirect_set(0, EMMC, 0x40000000);
> +			printf("100BASE-T/FD\n");
> +			link = 1;
> +		} else {
> +			printf("Unsupported mode\n");
> +			link = 0;
> +		}
> +		return 1;
> +	}
> +	return 0;
> +}
> +
> +#ifdef SDMA_MODE
> +/* bd init */
> +static void xps_ll_temac_bd_init(void)
> +{
> +	memset((void *)&tx_bd, 0, sizeof(cdmac_bd));
> +	memset((void *)&rx_bd, 0, sizeof(cdmac_bd));
> +
> +	rx_bd.phys_buf_p = &rx_buffer[0];
> +
> +	rx_bd.next_p = &rx_bd;
> +	rx_bd.buf_len = ETHER_MTU;
> +	flush_cache((u32)&rx_bd, sizeof(cdmac_bd));
> +
> +	out_be32((u32 *)RX_CURDESC_PTR, (u32)&rx_bd);
> +	out_be32((u32 *)RX_TAILDESC_PTR, (u32)&rx_bd);
> +	out_be32((u32 *)RX_NXTDESC_PTR, (u32)&rx_bd); /* setup first fd */
> +
> +	tx_bd.phys_buf_p = &tx_buffer[0];
> +	tx_bd.next_p = &tx_bd;
> +
> +	flush_cache((u32)&tx_bd, sizeof(cdmac_bd));
> +	out_be32((u32 *)TX_CURDESC_PTR, (u32)&tx_bd);
> +}
> +#endif
> +
> +#ifdef SDMA_MODE
> +static int xps_ll_temac_send_sdma(unsigned char *buffer, int length)
> +{
> +	if( xps_ll_temac_phy_ctrl() == 0)
> +		return 0;
> +
> +	memcpy (tx_buffer, buffer, length);
> +	flush_cache ((u32)tx_buffer, length);
> +
> +	tx_bd.stat = BDSTAT_SOP_MASK | BDSTAT_EOP_MASK | BDSTAT_STOP_ON_END_MASK;
> +	tx_bd.buf_len = length;
> +	flush_cache ((u32)&tx_bd, sizeof(cdmac_bd));
> +
> +	out_be32((u32 *)TX_CURDESC_PTR, (u32)&tx_bd);
> +	out_be32((u32 *)TX_TAILDESC_PTR, (u32)&tx_bd); /* DMA start */
> +
> +	do {
> +		flush_cache ((u32)&tx_bd, sizeof(cdmac_bd));
> +	} while(!(((volatile int)tx_bd.stat) & BDSTAT_COMPLETED_MASK));
> +
> +	return length;
> +}
> +
> +
> +static int xps_ll_temac_recv_sdma(void)
> +{
> +	int length;
> +
> +	flush_cache ((u32)&rx_bd, sizeof(cdmac_bd));
> +
> +	if(!(rx_bd.stat & BDSTAT_COMPLETED_MASK)) {
> +		return 0;
> +	}
> +
> +	length = rx_bd.app5;
> +	flush_cache ((u32)rx_bd.phys_buf_p, length);
> +
> +	rx_bd.buf_len = ETHER_MTU;
> +	rx_bd.stat = 0;
> +	rx_bd.app5 = 0;
> +
> +	flush_cache ((u32)&rx_bd, sizeof(cdmac_bd));
> +	out_be32((u32 *)RX_TAILDESC_PTR, (u32)&rx_bd);
> +
> +	if(length > 0) {
> +		NetReceive(rx_bd.phys_buf_p, length);
> +	}
> +
> +	return length;
> +}
> +#endif
> +
> +
> +#ifdef FIFO_MODE
> +void debugll(int count)
> +{
> +	printf ("%d fifo isr 0x%08x, fifo_ier 0x%08x, fifo_rdfr 0x%08x, fifo_rdfo 0x%08x fifo_rlr 0x%08x\n",count, ll_fifo->isr, \
>   
This line's way too long.
> +	ll_fifo->ier, ll_fifo->rdfr, ll_fifo->rdfo, ll_fifo->rlf);
> +
> +}
> +
> +static int xps_ll_temac_send_fifo(unsigned char *buffer, int length)
> +{
> +	u32 *buf = buffer;
> +	u32 len, i, val;
> +
> +	len = (length / 4) + 1;
> +
> +	for (i = 0; i < len; i++) {
> +		val = *buf++;
> +		ll_fifo->tdfd = val;
> +	}
> +
> +	ll_fifo->tlf = length;
> +
> +	return length;
> +}
> +
> +static int xps_ll_temac_recv_fifo()
> +{
> +	int len, len2, i, val;
> +	int *buf;
> +	buf = &rx_buffer;
> +
> +	if (ll_fifo->isr & 0x04000000 ) {
> +		ll_fifo->isr = 0xffffffff; /* reset isr */
> +	
> +		/* while (ll_fifo->isr); */
> +		len = ll_fifo->rlf & 0x7FF;
> +		len2 = (len / 4) + 1;
> +	
> +		for (i = 0; i < len2; i++) {
> +			val = ll_fifo->rdfd;
> +			*buf++ = val ;
> +		}
> +	
> +		/* debugll(1); */
> +		NetReceive (&rx_buffer, len);
> +	}
> +	return 0;
> +}
> +#endif
> +
> +/* setup mac addr */
> +static int xps_ll_temac_addr_setup(struct xps_ll_temac_private * lp)
> +{
> +	char * env_p;
> +	char * end;
> +	int i, val;
> +
> +	env_p = getenv("ethaddr");
> +	if (env_p == NULL) {
> +		printf("cannot get enviroment for \"ethaddr\".\n");
> +		return -1;
> +	}
> +
> +	for (i = 0; i < 6; i++) {
> +		lp->dev_addr[i] = env_p ? simple_strtoul(env_p, &end, 16) : 0;
> +		if (env_p) env_p = (*end) ? end + 1 : end;
> +	}
> +
> +	/* set up unicast MAC address filter */
> +	val = ((lp->dev_addr[3] << 24) | (lp->dev_addr[2] << 16) |
> +		(lp->dev_addr[1] << 8) | (lp->dev_addr[0] ));
> +	xps_ll_temac_indirect_set(0, UAW0, val);
> +	val = (lp->dev_addr[5] << 8) | lp->dev_addr[4] ;
> +	xps_ll_temac_indirect_set(0, UAW1, val);
> +
> +	return 0;
> +}
> +
> +static int xps_ll_temac_init(struct eth_device *dev, bd_t *bis)
> +{
> +	struct xps_ll_temac_private *lp = (struct xps_ll_temac_private *)dev->priv;
> +
> +#ifdef SDMA_MODE
> +	xps_ll_temac_bd_init();
> +#endif
> +#ifdef FIFO_MODE
> +	ll_fifo->tdfr = 0x000000a5; /* set fifo lenght */
> +	ll_fifo->rdfr = 0x000000a5;
> +
> +	/* ll_fifo->isr = 0x0; */
> +	/* ll_fifo->ier = 0x0; */
> +#endif
> +	xps_ll_temac_indirect_set(0, MC, MDIO_ENABLE_MASK | MDIO_CLOCK_DIV_100MHz);
> +
> +	xps_ll_temac_addr_setup(lp);
> +	xps_ll_temac_indirect_set(0, AFM, 0x00000000); /* Promiscuos mode disable */
> +	xps_ll_temac_indirect_set(0, RCW1, 0x10000000); /* Enable Receiver */
> +	xps_ll_temac_indirect_set(0, TC, 0x10000000); /* Enable Transmitter */
> +
> +}
> +
> +#ifdef ETH_HALTING
> +static int xps_ll_temac_halt(void)
> +{
> +	xps_ll_temac_indirect_set(0, RCW1, 0x00000000); /* Disable Receiver */
> +	xps_ll_temac_indirect_set(0, TC, 0x00000000); /* Disable Transmitter */
> +
> +#ifdef SDMA_MODE
> +	out_be32((u32 *)DMA_CONTROL_REG, 0x00000001);
> +	while(in_be32((u32 *)DMA_CONTROL_REG) & 1);
> +#endif
> +#ifdef FIFO_MODE
> +	/* reset fifos */
> +#endif
> +}
> +#endif
> +
> +/* halt device */
> +void eth_halt(void){
> +	link = 0;
> +#ifdef ETH_HALTING
> +	xps_ll_temac_halt();
> +#endif
> +}
> +
> +int eth_init(bd_t *bis)
> +{
> +	static int first = 1;
> +	struct eth_device *dev;
> +	struct xps_ll_temac_private *lp;
> +#if DEBUG
> +	int i;
> +#endif
> +
>   
I normally don't like this, but move the variable declaration to where 
it's used to avoid 2 #ifs
> +	if(!first)
> +		return 0;
> +	first = 0;
> +	dev = (struct eth_device *) calloc(1, sizeof(struct eth_device));
> +	if (NULL == dev)
> +		return 0;
> +
> +	lp = (struct xps_ll_temac_private *) calloc(1, sizeof(struct xps_ll_temac_private));
> +	if (lp == NULL)
> +		return 0;
> +	dev->priv = lp;
> +	sprintf(dev->name, "eth0");
> +
> +	xps_ll_temac_init(dev, bis);
> +
> +	printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n",
> +		dev->name, 0, XILINX_LLTEMAC_BASEADDR);
> +
> +#if DEBUG
> +	for(i = 0;i < 32;i++) {
> +		read_phy_reg(i);
> +	}
> +#endif
> +	xps_ll_temac_phy_ctrl();
> +	return 1;
> +}
> +
> +int eth_send(volatile void *packet, int length)
> +{
> +#ifdef SDMA_MODE
> +	return xps_ll_temac_send_sdma((unsigned char *)packet, length);
> +#endif
> +#ifdef FIFO_MODE
> +	return xps_ll_temac_send_fifo((unsigned char *)packet, length);
> +#endif
> +}
> +
> +int eth_rx(void)
> +{
> +#ifdef SDMA_MODE
> +	return xps_ll_temac_recv_sdma();
> +#endif
> +#ifdef FIFO_MODE
> +	return xps_ll_temac_recv_fifo();
> +#endif
> +}
>   
regards,
B en


More information about the U-Boot mailing list