[U-Boot] [PATCH v2 09/11] dm: net: Adjust designware driver to support driver model
Joe Hershberger
joe.hershberger at gmail.com
Mon Apr 6 23:09:28 CEST 2015
Hi Simon,
On Sun, Apr 5, 2015 at 5:07 PM, Simon Glass <sjg at chromium.org> wrote:
>
> Add driver model support to the designware driver. This reuses most of the
> existing code except for some duplication in the probe() method.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
Acked-by: Joe Hershberger <joe.hershberger at ni.com>
> Changes in v2:
> - Use the new recv() method and the free_pkt() method
>
> drivers/net/designware.c | 167
++++++++++++++++++++++++++++++++++++++++++-----
> drivers/net/designware.h | 3 +-
> 2 files changed, 153 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/designware.c b/drivers/net/designware.c
> index 5b36d4f..a4fe7a4 100644
> --- a/drivers/net/designware.c
> +++ b/drivers/net/designware.c
> @@ -10,6 +10,7 @@
> */
>
> #include <common.h>
> +#include <dm.h>
> #include <errno.h>
> #include <miiphy.h>
> #include <malloc.h>
> @@ -18,6 +19,8 @@
> #include <asm/io.h>
> #include "designware.h"
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> #if !defined(CONFIG_PHYLIB)
> # error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB"
> #endif
> @@ -343,11 +346,11 @@ static int _dw_eth_send(struct dw_eth_dev *priv,
void *packet, int length)
> return 0;
> }
>
> -static int _dw_eth_recv(struct dw_eth_dev *priv)
> +static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp)
> {
> u32 status, desc_num = priv->rx_currdescnum;
> struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
> - int length = 0;
> + int length = -EAGAIN;
> uint32_t desc_start = (uint32_t)desc_p;
> uint32_t desc_end = desc_start +
> roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
> @@ -368,26 +371,35 @@ static int _dw_eth_recv(struct dw_eth_dev *priv)
> /* Invalidate received data */
> data_end = data_start + roundup(length,
ARCH_DMA_MINALIGN);
> invalidate_dcache_range(data_start, data_end);
> + *packetp = desc_p->dmamac_addr;
> + }
>
> - NetReceive(desc_p->dmamac_addr, length);
This line will conflict when http://patchwork.ozlabs.org/patch/458099/ is
applied.
> + return length;
> +}
>
> - /*
> - * Make the current descriptor valid again and go to
> - * the next one
> - */
> - desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
> +static int _dw_free_pkt(struct dw_eth_dev *priv)
> +{
> + u32 desc_num = priv->rx_currdescnum;
> + struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
> + uint32_t desc_start = (uint32_t)desc_p;
> + uint32_t desc_end = desc_start +
> + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
>
> - /* Flush only status field - others weren't changed */
> - flush_dcache_range(desc_start, desc_end);
> + /*
> + * 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;
> - }
> + /* Flush only status field - others weren't changed */
> + flush_dcache_range(desc_start, desc_end);
>
> + /* Test the wrap-around condition. */
> + if (++desc_num >= CONFIG_RX_DESCR_NUM)
> + desc_num = 0;
> priv->rx_currdescnum = desc_num;
>
> - return length;
> + return 0;
> }
>
> static int dw_phy_init(struct dw_eth_dev *priv, void *dev)
> @@ -414,6 +426,7 @@ static int dw_phy_init(struct dw_eth_dev *priv, void
*dev)
> return 0;
> }
>
> +#ifndef CONFIG_DM_ETH
> static int dw_eth_init(struct eth_device *dev, bd_t *bis)
> {
> return _dw_eth_init(dev->priv, dev->enetaddr);
> @@ -426,7 +439,17 @@ static int dw_eth_send(struct eth_device *dev, void
*packet, int length)
>
> static int dw_eth_recv(struct eth_device *dev)
> {
> - return _dw_eth_recv(dev->priv);
> + uchar *packet;
> + int length;
> +
> + length = _dw_eth_recv(dev->priv, &packet);
> + if (length == -EAGAIN)
> + return 0;
> + NetReceive(packet, length);
This line will need to be updated in
http://patchwork.ozlabs.org/patch/458099/
> +
> + _dw_free_pkt(dev->priv);
> +
> + return 0;
> }
>
> static void dw_eth_halt(struct eth_device *dev)
> @@ -486,3 +509,115 @@ int designware_initialize(ulong base_addr, u32
interface)
>
> return dw_phy_init(priv, dev);
> }
> +#endif
> +
> +#ifdef CONFIG_DM_ETH
> +static int designware_eth_start(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> +
> + return _dw_eth_init(dev->priv, pdata->enetaddr);
> +}
> +
> +static int designware_eth_send(struct udevice *dev, void *packet, int
length)
> +{
> + struct dw_eth_dev *priv = dev_get_priv(dev);
> +
> + return _dw_eth_send(priv, packet, length);
> +}
> +
> +static int designware_eth_recv(struct udevice *dev, uchar **packetp)
> +{
> + struct dw_eth_dev *priv = dev_get_priv(dev);
> +
> + return _dw_eth_recv(priv, packetp);
> +}
> +
> +static int designware_eth_free_pkt(struct udevice *dev, uchar *packet,
> + int length)
> +{
> + struct dw_eth_dev *priv = dev_get_priv(dev);
> +
> + return _dw_free_pkt(priv);
> +}
> +
> +static void designware_eth_stop(struct udevice *dev)
> +{
> + struct dw_eth_dev *priv = dev_get_priv(dev);
> +
> + return _dw_eth_halt(priv);
> +}
> +
> +static int designware_eth_write_hwaddr(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + struct dw_eth_dev *priv = dev_get_priv(dev);
> +
> + return _dw_write_hwaddr(priv, pdata->enetaddr);
> +}
> +
> +static int designware_eth_probe(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + struct dw_eth_dev *priv = dev_get_priv(dev);
> + int ret;
> +
> + debug("%s, iobase=%lx, priv=%p\n", __func__, pdata->iobase, priv);
> + priv->mac_regs_p = (struct eth_mac_regs *)pdata->iobase;
> + priv->dma_regs_p = (struct eth_dma_regs *)(pdata->iobase +
> + DW_DMA_BASE_OFFSET);
> + priv->interface = pdata->phy_interface;
> +
> + dw_mdio_init(dev->name, priv->mac_regs_p);
> + priv->bus = miiphy_get_dev_by_name(dev->name);
> +
> + ret = dw_phy_init(priv, dev);
> + debug("%s, ret=%d\n", __func__, ret);
> +
> + return ret;
> +}
> +
> +static const struct eth_ops designware_eth_ops = {
> + .start = designware_eth_start,
> + .send = designware_eth_send,
> + .recv = designware_eth_recv,
> + .free_pkt = designware_eth_free_pkt,
> + .stop = designware_eth_stop,
> + .write_hwaddr = designware_eth_write_hwaddr,
> +};
> +
> +static int designware_eth_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + const char *phy_mode;
> +
> + pdata->iobase = dev_get_addr(dev);
> + pdata->phy_interface = -1;
> + phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode",
NULL);
> + if (phy_mode)
> + pdata->phy_interface =
phy_get_interface_by_name(phy_mode);
> + if (pdata->phy_interface == -1) {
> + debug("%s: Invalid PHY interface '%s'\n", __func__,
phy_mode);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static const struct udevice_id designware_eth_ids[] = {
> + { .compatible = "allwinner,sun7i-a20-gmac" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(eth_sandbox) = {
> + .name = "eth_designware",
> + .id = UCLASS_ETH,
> + .of_match = designware_eth_ids,
> + .ofdata_to_platdata = designware_eth_ofdata_to_platdata,
> + .probe = designware_eth_probe,
> + .ops = &designware_eth_ops,
> + .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
> + .platdata_auto_alloc_size = sizeof(struct eth_pdata),
> + .flags = DM_FLAG_ALLOC_PRIV_DMA,
> +};
> +#endif
> diff --git a/drivers/net/designware.h b/drivers/net/designware.h
> index 49d900c..4b9ec39 100644
> --- a/drivers/net/designware.h
> +++ b/drivers/net/designware.h
> @@ -228,8 +228,9 @@ struct dw_eth_dev {
>
> struct eth_mac_regs *mac_regs_p;
> struct eth_dma_regs *dma_regs_p;
> -
> +#ifndef CONFIG_DM_ETH
> struct eth_device *dev;
> +#endif
> struct phy_device *phydev;
> struct mii_dev *bus;
> };
> --
> 2.2.0.rc0.207.ga3a616c
>
More information about the U-Boot
mailing list