All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Warren <biggerbadderben@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 07/17] SPEAr : Network driver support added
Date: Wed, 21 Apr 2010 10:48:57 -0700	[thread overview]
Message-ID: <4BCF3A89.2070607@gmail.com> (raw)
In-Reply-To: <1271836483-15978-8-git-send-email-vipin.kumar@st.com>

Hi Vipin,

On 4/21/2010 12:54 AM, Vipin KUMAR wrote:
> Designware network driver support added.
> This is a Synopsys ethernet controller
>
> Signed-off-by: Vipin Kumar<vipin.kumar@st.com>
> ---
>   drivers/net/Makefile |    1 +
>   drivers/net/dw_eth.c |  504 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/net/dw_eth.h |  281 ++++++++++++++++++++++++++++
>    
I agree with Peter that a different name would be preferable.  Something 
conveying the manufacturer or, if it's a very specific controller, the 
part number.  Give thought to whether it will potentially be expanded up 
or generic-ized in the future (I know that's hard to do!)
>   include/netdev.h     |    1 +
>   4 files changed, 787 insertions(+), 0 deletions(-)
>   create mode 100755 drivers/net/dw_eth.c
>   create mode 100644 drivers/net/dw_eth.h
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 1ec0ba1..d03c353 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -68,6 +68,7 @@ COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
>   COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
>   COBJS-$(CONFIG_SMC91111) += smc91111.o
>   COBJS-$(CONFIG_SMC911X) += smc911x.o
> +COBJS-$(CONFIG_DW_ETH) += dw_eth.o
>   COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o
>   COBJS-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
>   COBJS-$(CONFIG_TSEC_ENET) += tsec.o
>    
Alphabetical order, please
> diff --git a/drivers/net/dw_eth.c b/drivers/net/dw_eth.c
> new file mode 100755
> index 0000000..52e7d15
> --- /dev/null
> +++ b/drivers/net/dw_eth.c
> @@ -0,0 +1,504 @@
> +/*
> + * (C) Copyright 2009
> + * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
> + *
> + * (C) Copyright 2008
> + * Deepak Sikri, ST Micoelectronics, deepak.sikri at st.com.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +/*
> + * Designware ethernet IP driver for u-boot
> + */
> +
> +#include<common.h>
> +#include<miiphy.h>
> +#include<malloc.h>
> +#include<linux/err.h>
> +#include<asm/io.h>
> +#include "dw_eth.h"
> +
> +static void tx_descs_init(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +	struct dmamacdescr *desc_table_p =&priv->tx_mac_descrtable[0];
> +	char *txbuffs =&priv->txbuffs[0];
> +	struct dmamacdescr *desc_p;
> +
> +	u32 idx;
> +
> +	for (idx = 0; idx<  CONFIG_TX_DESCR_NUM; idx++) {
> +
> +		desc_p =&desc_table_p[idx];
> +		desc_p->dmamac_addr =&txbuffs[idx * CONFIG_ETH_BUFSIZE];
> +		desc_p->dmamac_next =&desc_table_p[idx + 1];
> +
> +#if defined(CONFIG_DW_ALTDESC)
>    
Please use a more descriptive CONFIG option. Remember these have global 
namespace
> +		desc_p->txrx_status&= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
> +				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
> +				DESC_TXSTS_TXCHECKINSCTRL | \
> +				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
> +
> +		desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
> +		desc_p->dmamac_cntl = 0;
> +		desc_p->txrx_status&= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
> +#else
> +		desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
> +		desc_p->txrx_status = 0;
> +#endif
> +	}
> +
> +	/* Correcting the last pointer of the chain */
> +	desc_p->dmamac_next =&desc_table_p[0];
> +
> +	writel((ulong)&desc_table_p[0],&dma_p->txdesclistaddr);
> +}
> +
> +static void rx_descs_init(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +	struct dmamacdescr *desc_table_p =&priv->rx_mac_descrtable[0];
> +	char *rxbuffs =&priv->rxbuffs[0];
> +	struct dmamacdescr *desc_p;
> +
> +	u32 idx;
> +
> +	for (idx = 0; idx<  CONFIG_RX_DESCR_NUM; idx++) {
> +
>    
Remove unnecessary blank lines
> +		desc_p =&desc_table_p[idx];
> +		desc_p->dmamac_addr =&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
> +		desc_p->dmamac_next =&desc_table_p[idx + 1];
> +
> +		desc_p->dmamac_cntl =
> +			(MAC_MAX_FRAME_SZ&  DESC_RXCTRL_SIZE1MASK) | \
> +				      DESC_RXCTRL_RXCHAIN;
> +
> +		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
> +	}
> +
> +	/* Correcting the last pointer of the chain */
> +	desc_p->dmamac_next =&desc_table_p[0];
> +
> +	writel((ulong)&desc_table_p[0],&dma_p->rxdesclistaddr);
> +}
> +
> +static void descs_init(struct eth_device *dev)
> +{
> +	tx_descs_init(dev);
> +	rx_descs_init(dev);
> +}
> +
> +static void mac_reset(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +
> +	u32 timeout = CONFIG_MACRESET_TIMEOUT;
> +
> +	writel(DMAMAC_SRST,&dma_p->busmode);
> +	writel(MII_PORTSELECT,&mac_p->conf);
> +
> +	do {
> +		if (!(readl(&dma_p->busmode)&  DMAMAC_SRST))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +}
> +
> +static int dw_eth_init(struct eth_device *dev, bd_t *bis)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +
> +	u8 *mac_id =&dev->enetaddr[0];
> +	u32 conf, macid_lo, macid_hi;
> +
> +	/* Reset ethernet hardware */
> +	mac_reset(dev);
> +
> +	macid_lo = mac_id[0] + (mac_id[1]<<  8) + \
> +		   (mac_id[2]<<  16) + (mac_id[3]<<  24);
> +	macid_hi = mac_id[4] + (mac_id[5]<<  8);
> +
> +	writel(macid_hi,&mac_p->macaddr0hi);
> +	writel(macid_lo,&mac_p->macaddr0lo);
> +
>    
Please provide a static function with signature 'static void 
program_mac(struct eth_device *)' for programming the MAC.
> +	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
> +			&dma_p->busmode);
> +
> +	writel(FLUSHTXFIFO | readl(&dma_p->opmode),&dma_p->opmode);
> +	writel(STOREFORWARD | TXSECONDFRAME,&dma_p->opmode);
> +
> +	conf = FRAMEBURSTENABLE | DISABLERXOWN;
> +
> +	if (priv->speed != SPEED_1000M)
> +		conf |= MII_PORTSELECT;
> +
> +	if (priv->duplex == FULL_DUPLEX)
> +		conf |= FULLDPLXMODE;
> +
> +	writel(conf,&mac_p->conf);
> +
> +	descs_init(dev);
> +
> +	/*
> +	 * Start/Enable xfer at dma as well as mac level
> +	 */
> +	writel(readl(&dma_p->opmode) | RXSTART,&dma_p->opmode);
> +	writel(readl(&dma_p->opmode) | TXSTART,&dma_p->opmode);
> +
> +	writel(readl(&mac_p->conf) | RXENABLE,&mac_p->conf);
> +	writel(readl(&mac_p->conf) | TXENABLE,&mac_p->conf);
> +
> +	return 0;
> +}
> +
> +static int dw_eth_send(struct eth_device *dev, volatile void *packet,
> +		int length)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_dma_regs *dma_p = priv->dma_regs_p;
> +	u32 desc_num = priv->tx_currdescnum;
> +	struct dmamacdescr *desc_p =&priv->tx_mac_descrtable[desc_num];
> +
> +	/* Check if the descriptor is owned by CPU */
> +	if (desc_p->txrx_status&  DESC_TXSTS_OWNBYDMA) {
> +		printf("eth_send : CPU not owner of tx frame\n");
> +		return -1;
> +	}
> +
> +	memcpy((void *)desc_p->dmamac_addr, (void *)packet, length);
> +
> +#if defined(CONFIG_DW_ALTDESC)
> +	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
> +	desc_p->dmamac_cntl |= (length<<  DESC_TXCTRL_SIZE1SHFT)&  \
> +			       DESC_TXCTRL_SIZE1MASK;
> +
> +	desc_p->txrx_status&= ~(DESC_TXSTS_MSK);
> +	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
> +#else
> +	desc_p->dmamac_cntl |= ((length<<  DESC_TXCTRL_SIZE1SHFT)&  \
> +			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
> +			       DESC_TXCTRL_TXFIRST;
> +
> +	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
> +#endif
> +
> +	/* Test the wrap-around condition. */
> +	if (++desc_num>= CONFIG_TX_DESCR_NUM)
> +		desc_num = 0;
> +
> +	priv->tx_currdescnum = desc_num;
> +
> +	/* Start the transmission */
> +	writel(POLL_DATA,&dma_p->txpolldemand);
> +
> +	return 0;
> +}
> +
> +static int dw_eth_recv(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	u32 desc_num = priv->rx_currdescnum;
> +	struct dmamacdescr *desc_p =&priv->rx_mac_descrtable[desc_num];
> +
> +	u32 status = desc_p->txrx_status;
> +	int length = 0;
> +
> +	/* Check  if the owner is the CPU */
> +	if (!(status&  DESC_RXSTS_OWNBYDMA)) {
> +
> +		length = (status&  DESC_RXSTS_FRMLENMSK)>>  \
> +			 DESC_RXSTS_FRMLENSHFT;
> +
> +		NetReceive(desc_p->dmamac_addr, length);
> +
> +		/*
> +		 * Make the current descriptor valid again and go to
> +		 * the next one
> +		 */
> +		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
> +
> +		/* Test the wrap-around condition. */
> +		if (++desc_num>= CONFIG_RX_DESCR_NUM)
> +			desc_num = 0;
> +	}
> +
> +	priv->rx_currdescnum = desc_num;
> +
> +	return length;
> +}
> +
> +static void dw_eth_halt(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +
> +	mac_reset(dev);
> +	priv->tx_currdescnum = priv->rx_currdescnum = 0;
> +}
> +
> +static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	u32 miiaddr;
> +	u32 timeout = CONFIG_MDIO_TIMEOUT;
> +
> +	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
> +		  ((reg<<  MIIREGSHIFT)&  MII_REGMSK);
> +
> +	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
> +
> +	do {
> +		if (!(readl(&mac_p->miiaddr)&  MII_BUSY))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +	*val = readl(&mac_p->miidata);
> +
> +	return 0;
> +}
> +
> +static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	struct eth_mac_regs *mac_p = priv->mac_regs_p;
> +	u32 miiaddr;
> +	u32 timeout = CONFIG_MDIO_TIMEOUT;
> +	u16 value;
> +
> +	writel(val,&mac_p->miidata);
> +	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
> +		  ((reg<<  MIIREGSHIFT)&  MII_REGMSK) | MII_WRITE;
> +
> +	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
> +
> +	do {
> +		if (!(readl(&mac_p->miiaddr)&  MII_BUSY))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +	/* Needed as a fix for ST-Phy */
> +	eth_mdio_read(dev, addr, reg,&value);
> +
> +	return 0;
> +}
> +
> +static u8 find_phy(struct eth_device *dev)
> +{
> +	u8 phy_addr = 0;
> +	u16 ctrl, oldctrl;
> +
> +	do {
> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +		oldctrl = ctrl&  PHY_BMCR_AUTON;
> +
> +		ctrl ^= PHY_BMCR_AUTON;
> +		eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +		ctrl&= PHY_BMCR_AUTON;
> +
> +		if (ctrl == oldctrl) {
> +			phy_addr++;
> +		} else {
> +			ctrl ^= PHY_BMCR_AUTON;
> +			eth_mdio_write(dev, phy_addr, PHY_BMCR, ctrl);
> +			break;
> +		}
> +	} while (phy_addr<  32);
> +
> +	return phy_addr;
> +}
> +
> +static void dw_reset_phy(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	u16 ctrl;
> +	u32 timeout = CONFIG_PHYRESET_TIMEOUT;
> +	u32 phy_addr = priv->address;
> +
> +	eth_mdio_write(dev, phy_addr, PHY_BMCR, PHY_BMCR_RESET);
> +	do {
> +		eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +		if (!(ctrl&  PHY_BMCR_RESET))
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +#ifdef CONFIG_PHY_RESET_DELAY
> +	udelay(CONFIG_PHY_RESET_DELAY);
> +#endif
> +}
> +
> +static void configure_phy(struct eth_device *dev)
> +{
> +	struct dw_eth_dev *priv = dev->priv;
> +	u8 phy_addr;
> +	u16 bmcr, ctrl;
> +#if defined(CONFIG_DW_AUTONEG)
> +	u16 bmsr;
> +	u32 timeout;
> +	u16 anlpar, btsr;
> +#endif
> +	priv->address = find_phy(dev);
> +	phy_addr = priv->address;
> +
> +	dw_reset_phy(dev);
> +
> +#if defined(CONFIG_DW_AUTONEG)
> +	bmcr = PHY_BMCR_AUTON | PHY_BMCR_RST_NEG | PHY_BMCR_100MB | \
> +	       PHY_BMCR_DPLX | PHY_BMCR_1000_MBPS;
> +#else
> +	bmcr = PHY_BMCR_100MB | PHY_BMCR_DPLX;
> +
> +#if defined(CONFIG_DW_SPEED10M)
> +	bmcr&= ~PHY_BMCR_100MB;
> +#endif
> +#if defined(CONFIG_DW_DUPLEXHALF)
> +	bmcr&= ~PHY_BMCR_DPLX;
> +#endif
> +#endif
> +	eth_mdio_write(dev, phy_addr, PHY_BMCR, bmcr);
> +
> +	/* Read the phy status register and populate priv structure */
> +#if defined(CONFIG_DW_AUTONEG)
> +	timeout = CONFIG_AUTONEG_TIMEOUT;
> +	do {
> +		eth_mdio_read(dev, phy_addr, PHY_BMSR,&bmsr);
> +		if (bmsr&  PHY_BMSR_AUTN_COMP)
> +			break;
> +		udelay(1000);
> +	} while (timeout--);
> +
> +	eth_mdio_read(dev, phy_addr, PHY_ANLPAR,&anlpar);
> +	eth_mdio_read(dev, phy_addr, PHY_1000BTSR,&btsr);
> +
> +	if (btsr&  (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
> +		priv->speed = SPEED_1000M;
> +		if (btsr&  PHY_1000BTSR_1000FD)
> +			priv->duplex = FULL_DUPLEX;
> +		else
> +			priv->duplex = HALF_DUPLEX;
> +	} else {
> +		if (anlpar&  PHY_ANLPAR_100)
> +			priv->speed = SPEED_100M;
> +		else
> +			priv->speed = SPEED_10M;
> +
> +		if (anlpar&  (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD))
> +			priv->duplex = FULL_DUPLEX;
> +		else
> +			priv->duplex = HALF_DUPLEX;
> +	}
> +#else
> +	eth_mdio_read(dev, phy_addr, PHY_BMCR,&ctrl);
> +
> +	if (ctrl&  PHY_BMCR_DPLX)
> +		priv->duplex = FULL_DUPLEX;
> +	else
> +		priv->duplex = HALF_DUPLEX;
> +
> +	if (ctrl&  PHY_BMCR_1000_MBPS)
> +		priv->speed = SPEED_1000M;
> +	else if (ctrl&  PHY_BMCR_100_MBPS)
> +		priv->speed = SPEED_100M;
> +	else
> +		priv->speed = SPEED_10M;
> +#endif
> +}
> +
> +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
> +static int dw_mii_read(char *devname, u8 addr, u8 reg, u16 *val)
> +{
> +	struct eth_device *netdev;
> +
> +	netdev = eth_get_dev_by_name(devname);
> +	if (netdev)
> +		eth_mdio_read(netdev, addr, reg, val);
> +
> +	return 0;
> +}
> +
> +static int dw_mii_write(char *devname, u8 addr, u8 reg, u16 val)
> +{
> +	struct eth_device *netdev;
> +
> +	netdev = eth_get_dev_by_name(devname);
> +	if (netdev)
> +		eth_mdio_write(netdev, addr, reg, val);
> +
> +	return 0;
> +}
> +#endif
> +
> +int dw_mii_initialize(u32 id, ulong base_addr)
>    
Please use the same name in this function as the driver name.  We 
usually reserve 'mii' for device control plane.
> +{
> +	struct eth_device *netdev;
>    
I'd prefer if you named this variable 'dev', since 'netdev' is the name 
of a header file that's unrelated.  Apply globally.
> +	struct dw_eth_dev *priv;
> +
> +	netdev = (struct eth_device *) malloc(sizeof(struct eth_device));
> +	if (!netdev)
> +		return -ENOMEM;
> +
> +	/*
> +	 * Since the priv structure contains the descriptors which need a strict
> +	 * buswidth alignment, memalign is used to allocate memory
> +	 */
> +	priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev));
> +	if (!priv) {
> +		free(netdev);
> +		return -ENOMEM;
> +	}
> +
> +	memset(netdev, 0, sizeof(struct eth_device));
> +	memset(priv, 0, sizeof(struct dw_eth_dev));
> +
> +	sprintf(netdev->name, "mii%d", id);
> +	netdev->iobase = (int)base_addr;
> +	netdev->priv = priv;
>    
If you wait a couple of days until I resubmit my change to the 
'eth_device' struct, you can put in a pointer to the MAC programming 
function and not have to worry about that any more.
> +
> +	eth_getenv_enetaddr_by_index(id,&netdev->enetaddr[0]);
> +
> +	priv->dev = netdev;
> +	priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
> +	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
> +			DW_DMA_BASE_OFFSET);
> +
> +	mac_reset(netdev);
> +	configure_phy(netdev);
> +
> +	netdev->init = dw_eth_init;
> +	netdev->send = dw_eth_send;
> +	netdev->recv = dw_eth_recv;
> +	netdev->halt = dw_eth_halt;
> +
> +	eth_register(netdev);
> +
> +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
> +	miiphy_register(netdev->name, dw_mii_read, dw_mii_write);
> +#endif
> +	return 0;
>    
This should return 1 on success.
> +}
> diff --git a/drivers/net/dw_eth.h b/drivers/net/dw_eth.h
> new file mode 100644
> index 0000000..068211a
> --- /dev/null
> +++ b/drivers/net/dw_eth.h
> @@ -0,0 +1,281 @@
> +/*
> + * (C) Copyright 2009
> + * Vipin Kumar, ST Micoelectronics, vipin.kumar at st.com.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _DW_ETH_H
> +#define _DW_ETH_H
> +
> +#define CONFIG_TX_DESCR_NUM	16
> +#define CONFIG_RX_DESCR_NUM	16
> +#define CONFIG_ETH_BUFSIZE	2048
> +#define TX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
> +#define RX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
> +
> +#define CONFIG_MACRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
> +#define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
> +#define CONFIG_PHYRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
> +#define CONFIG_AUTONEG_TIMEOUT	(5 * CONFIG_SYS_HZ)
> +
> +struct eth_mac_regs {
> +	u32 conf;		/* 0x00 */
> +	u32 framefilt;		/* 0x04 */
> +	u32 hashtablehigh;	/* 0x08 */
> +	u32 hashtablelow;	/* 0x0c */
> +	u32 miiaddr;		/* 0x10 */
> +	u32 miidata;		/* 0x14 */
> +	u32 flowcontrol;	/* 0x18 */
> +	u32 vlantag;		/* 0x1c */
> +	u32 version;		/* 0x20 */
> +	u8 reserved_1[0x38 - 0x24];
> +	u32 intreg;		/* 0x38 */
> +	u32 intmask;		/* 0x3c */
> +	u32 macaddr0hi;		/* 0x40 */
> +	u32 macaddr0lo;		/* 0x44 */
> +};
> +
> +/* MAC configuration register definitions */
> +#define FRAMEBURSTENABLE	(1<<  21)
> +#define MII_PORTSELECT		(1<<  15)
> +#define FES_100			(1<<  14)
> +#define DISABLERXOWN		(1<<  13)
> +#define FULLDPLXMODE		(1<<  11)
> +#define RXENABLE		(1<<  2)
> +#define TXENABLE		(1<<  3)
> +
> +/* MII address register definitions */
> +#define MII_BUSY		(1<<  0)
> +#define MII_WRITE		(1<<  1)
> +#define MII_CLKRANGE_60_100M	(0)
> +#define MII_CLKRANGE_100_150M	(0x4)
> +#define MII_CLKRANGE_20_35M	(0x8)
> +#define MII_CLKRANGE_35_60M	(0xC)
> +#define MII_CLKRANGE_150_250M	(0x10)
> +#define MII_CLKRANGE_250_300M	(0x14)
> +
> +#define MIIADDRSHIFT		(11)
> +#define MIIREGSHIFT		(6)
> +#define MII_REGMSK		(0x1F<<  6)
> +#define MII_ADDRMSK		(0x1F<<  11)
> +
> +
> +struct eth_dma_regs {
> +	u32 busmode;		/* 0x00 */
> +	u32 txpolldemand;	/* 0x04 */
> +	u32 rxpolldemand;	/* 0x08 */
> +	u32 rxdesclistaddr;	/* 0x0c */
> +	u32 txdesclistaddr;	/* 0x10 */
> +	u32 status;		/* 0x14 */
> +	u32 opmode;		/* 0x18 */
> +	u32 intenable;		/* 0x1c */
> +	u8 reserved[0x48 - 0x20];
> +	u32 currhosttxdesc;	/* 0x48 */
> +	u32 currhostrxdesc;	/* 0x4c */
> +	u32 currhosttxbuffaddr;	/* 0x50 */
> +	u32 currhostrxbuffaddr;	/* 0x54 */
> +};
> +
> +#define DW_DMA_BASE_OFFSET	(0x1000)
> +
> +/* Bus mode register definitions */
> +#define FIXEDBURST		(1<<  16)
> +#define PRIORXTX_41		(3<<  14)
> +#define PRIORXTX_31		(2<<  14)
> +#define PRIORXTX_21		(1<<  14)
> +#define PRIORXTX_11		(0<<  14)
> +#define BURST_1			(1<<  8)
> +#define BURST_2			(2<<  8)
> +#define BURST_4			(4<<  8)
> +#define BURST_8			(8<<  8)
> +#define BURST_16		(16<<  8)
> +#define BURST_32		(32<<  8)
> +#define RXHIGHPRIO		(1<<  1)
> +#define DMAMAC_SRST		(1<<  0)
> +
> +/* Poll demand definitions */
> +#define POLL_DATA		(0xFFFFFFFF)
> +
> +/* Operation mode definitions */
> +#define STOREFORWARD		(1<<  21)
> +#define FLUSHTXFIFO		(1<<  20)
> +#define TXSTART			(1<<  13)
> +#define TXSECONDFRAME		(1<<  2)
> +#define RXSTART			(1<<  1)
> +
> +/* Descriptior related definitions */
> +#define MAC_MAX_FRAME_SZ	(2048)
> +
> +struct dmamacdescr {
> +	u32 txrx_status;
> +	u32 dmamac_cntl;
> +	void *dmamac_addr;
> +	struct dmamacdescr *dmamac_next;
> +};
> +
> +/*
> + * txrx_status definitions
> + */
> +
> +/* tx status bits definitions */
> +#if defined(CONFIG_DW_ALTDESC)
> +
> +#define DESC_TXSTS_OWNBYDMA		(1<<  31)
> +#define DESC_TXSTS_TXINT		(1<<  30)
> +#define DESC_TXSTS_TXLAST		(1<<  29)
> +#define DESC_TXSTS_TXFIRST		(1<<  28)
> +#define DESC_TXSTS_TXCRCDIS		(1<<  27)
> +
> +#define DESC_TXSTS_TXPADDIS		(1<<  26)
> +#define DESC_TXSTS_TXCHECKINSCTRL	(3<<  22)
> +#define DESC_TXSTS_TXRINGEND		(1<<  21)
> +#define DESC_TXSTS_TXCHAIN		(1<<  20)
> +#define DESC_TXSTS_MSK			(0x1FFFF<<  0)
> +
> +#else
> +
> +#define DESC_TXSTS_OWNBYDMA		(1<<  31)
> +#define DESC_TXSTS_MSK			(0x1FFFF<<  0)
> +
> +#endif
> +
> +/* rx status bits definitions */
> +#define DESC_RXSTS_OWNBYDMA		(1<<  31)
> +#define DESC_RXSTS_DAFILTERFAIL		(1<<  30)
> +#define DESC_RXSTS_FRMLENMSK		(0x3FFF<<  16)
> +#define DESC_RXSTS_FRMLENSHFT		(16)
> +
> +#define DESC_RXSTS_ERROR		(1<<  15)
> +#define DESC_RXSTS_RXTRUNCATED		(1<<  14)
> +#define DESC_RXSTS_SAFILTERFAIL		(1<<  13)
> +#define DESC_RXSTS_RXIPC_GIANTFRAME	(1<<  12)
> +#define DESC_RXSTS_RXDAMAGED		(1<<  11)
> +#define DESC_RXSTS_RXVLANTAG		(1<<  10)
> +#define DESC_RXSTS_RXFIRST		(1<<  9)
> +#define DESC_RXSTS_RXLAST		(1<<  8)
> +#define DESC_RXSTS_RXIPC_GIANT		(1<<  7)
> +#define DESC_RXSTS_RXCOLLISION		(1<<  6)
> +#define DESC_RXSTS_RXFRAMEETHER		(1<<  5)
> +#define DESC_RXSTS_RXWATCHDOG		(1<<  4)
> +#define DESC_RXSTS_RXMIIERROR		(1<<  3)
> +#define DESC_RXSTS_RXDRIBBLING		(1<<  2)
> +#define DESC_RXSTS_RXCRC		(1<<  1)
> +
> +/*
> + * dmamac_cntl definitions
> + */
> +
> +/* tx control bits definitions */
> +#if defined(CONFIG_DW_ALTDESC)
> +
> +#define DESC_TXCTRL_SIZE1MASK		(0x1FFF<<  0)
> +#define DESC_TXCTRL_SIZE1SHFT		(0)
> +#define DESC_TXCTRL_SIZE2MASK		(0x1FFF<<  16)
> +#define DESC_TXCTRL_SIZE2SHFT		(16)
> +
> +#else
> +
> +#define DESC_TXCTRL_TXINT		(1<<  31)
> +#define DESC_TXCTRL_TXLAST		(1<<  30)
> +#define DESC_TXCTRL_TXFIRST		(1<<  29)
> +#define DESC_TXCTRL_TXCHECKINSCTRL	(3<<  27)
> +#define DESC_TXCTRL_TXCRCDIS		(1<<  26)
> +#define DESC_TXCTRL_TXRINGEND		(1<<  25)
> +#define DESC_TXCTRL_TXCHAIN		(1<<  24)
> +
> +#define DESC_TXCTRL_SIZE1MASK		(0x7FF<<  0)
> +#define DESC_TXCTRL_SIZE1SHFT		(0)
> +#define DESC_TXCTRL_SIZE2MASK		(0x7FF<<  11)
> +#define DESC_TXCTRL_SIZE2SHFT		(11)
> +
> +#endif
> +
> +/* rx control bits definitions */
> +#if defined(CONFIG_DW_ALTDESC)
> +
> +#define DESC_RXCTRL_RXINTDIS		(1<<  31)
> +#define DESC_RXCTRL_RXRINGEND		(1<<  15)
> +#define DESC_RXCTRL_RXCHAIN		(1<<  14)
> +
> +#define DESC_RXCTRL_SIZE1MASK		(0x1FFF<<  0)
> +#define DESC_RXCTRL_SIZE1SHFT		(0)
> +#define DESC_RXCTRL_SIZE2MASK		(0x1FFF<<  16)
> +#define DESC_RXCTRL_SIZE2SHFT		(16)
> +
> +#else
> +
> +#define DESC_RXCTRL_RXINTDIS		(1<<  31)
> +#define DESC_RXCTRL_RXRINGEND		(1<<  25)
> +#define DESC_RXCTRL_RXCHAIN		(1<<  24)
> +
> +#define DESC_RXCTRL_SIZE1MASK		(0x7FF<<  0)
> +#define DESC_RXCTRL_SIZE1SHFT		(0)
> +#define DESC_RXCTRL_SIZE2MASK		(0x7FF<<  11)
> +#define DESC_RXCTRL_SIZE2SHFT		(11)
> +
> +#endif
> +
> +/*
> + * dmamac_addr definitions
> + */
> +
> +/* tx addr register bits definitions */
> +
> +/* rx addr register bits definitions */
> +
>    
Something's missing here...
> +
> +/*
> + * dmamac_next definitions
> + */
> +
> +/* tx next register bits definitions */
> +
> +/* rx next register bits definitions */
> +
> +struct dw_eth_dev {
> +	u32 address;
> +	u32 speed;
> +	u32 duplex;
> +	u32 tx_currdescnum;
> +	u32 rx_currdescnum;
> +	u32 padding;
> +
> +	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
> +	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
> +
> +	char txbuffs[TX_TOTAL_BUFSIZE];
> +	char rxbuffs[RX_TOTAL_BUFSIZE];
> +
> +	struct eth_mac_regs *mac_regs_p;
> +	struct eth_dma_regs *dma_regs_p;
> +
> +	struct eth_device *dev;
> +} __attribute__ ((aligned(8)));
> +
> +/* Speed specific definitions */
> +#define SPEED_10M		1
> +#define SPEED_100M		2
> +#define SPEED_1000M		3
> +
> +/* Duplex mode specific definitions */
> +#define HALF_DUPLEX		1
> +#define FULL_DUPLEX		2
> +
> +#endif
> diff --git a/include/netdev.h b/include/netdev.h
> index 1dd80f0..460889c 100644
> --- a/include/netdev.h
> +++ b/include/netdev.h
> @@ -79,6 +79,7 @@ int scc_initialize(bd_t *bis);
>   int skge_initialize(bd_t *bis);
>   int smc911x_initialize(u8 dev_num, int base_addr);
>   int smc91111_initialize(u8 dev_num, int base_addr);
> +int dw_mii_initialize(u32 id, ulong base_addr);
>    
alphabetical order, please.
>   int tsi108_eth_initialize(bd_t *bis);
>   int uec_initialize(int index);
>   int uec_standard_init(bd_t *bis);
>    

Overall, a very good first pass.

thanks,
Ben

  parent reply	other threads:[~2010-04-21 17:48 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-21  7:54 [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Vipin KUMAR
2010-04-21  7:54 ` [U-Boot] [PATCH 01/17] u-boot.img file not created when srctree and objtree are different Vipin KUMAR
2010-04-21  7:54   ` [U-Boot] [PATCH 02/17] change_bit routine defined Vipin KUMAR
2010-04-21  7:54     ` [U-Boot] [PATCH 03/17] SPEAr : SMI erase and write timeouts increased Vipin KUMAR
2010-04-21  7:54       ` [U-Boot] [PATCH 04/17] SPEAr : Placing ethaddr write and read within CONFIG_CMD_NET Vipin KUMAR
2010-04-21  7:54         ` [U-Boot] [PATCH 05/17] SPEAr : Reducing the max RAM size to 128MB Vipin KUMAR
2010-04-21  7:54           ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Vipin KUMAR
2010-04-21  7:54             ` [U-Boot] [PATCH 07/17] SPEAr : Network driver support added Vipin KUMAR
2010-04-21  7:54               ` [U-Boot] [PATCH 08/17] SPEAr : Network support configured for spear SoCs Vipin KUMAR
2010-04-21  7:54                 ` [U-Boot] [PATCH 09/17] SPEAr : macb driver support added for spear310 and spear320 Vipin KUMAR
2010-04-21  7:54                   ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Vipin KUMAR
2010-04-21  7:54                     ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Vipin KUMAR
2010-04-21  7:54                       ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Vipin KUMAR
2010-04-21  7:54                         ` [U-Boot] [PATCH 13/17] SPEAr : smi driver moved completely into drivers/mtd Vipin KUMAR
2010-04-21  7:54                           ` [U-Boot] [PATCH 14/17] SPEAr : USBD driver support added Vipin KUMAR
2010-04-21  7:54                             ` [U-Boot] [PATCH 15/17] SPEAr : Basic spear1300 architecture " Vipin KUMAR
2010-04-21  7:54                               ` [U-Boot] [PATCH 16/17] SPEAr : spear1300 SoC " Vipin KUMAR
2010-04-21  7:54                                 ` [U-Boot] [PATCH 17/17] SPEAr : Supporting various configurations for spear3xx and spear6xx boards Vipin KUMAR
2010-04-21 12:11                         ` [U-Boot] [PATCH 12/17] SPEAr : i2c driver moved completely into drivers/i2c Peter Tyser
2010-04-22  4:07                           ` Vipin KUMAR
2010-04-21 17:02                       ` [U-Boot] [PATCH 11/17] SPEAr : Configuring FSMC driver for NAND interface Scott Wood
2010-04-22  4:21                         ` Vipin KUMAR
2010-04-22 15:39                           ` Scott Wood
2010-04-21 17:02                     ` [U-Boot] [PATCH 10/17] SPEAr : FSMC driver support added Scott Wood
2010-04-22  4:28                       ` Vipin KUMAR
2010-04-22 16:01                         ` Scott Wood
2010-04-21 12:00               ` [U-Boot] [PATCH 07/17] SPEAr : Network " Peter Tyser
2010-04-22  4:30                 ` Vipin KUMAR
2010-04-21 17:48               ` Ben Warren [this message]
2010-04-22  4:43                 ` Vipin KUMAR
2010-04-23 10:32                 ` Armando VISCONTI
2010-04-26  5:02                   ` Ben Warren
2010-04-26  8:01                     ` Armando VISCONTI
2010-04-26  8:34                       ` Vipin KUMAR
2010-04-21 11:51             ` [U-Boot] [PATCH 06/17] SPEAr : Basic arch related support added for SPEAr SoCs Peter Tyser
2010-04-22  4:45               ` Vipin KUMAR
2010-04-21 11:54 ` [U-Boot] [PATCH 00/17] Network support for spear platform and spear1300 support Peter Tyser
2010-04-21 12:00   ` Vipin KUMAR

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BCF3A89.2070607@gmail.com \
    --to=biggerbadderben@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.