[U-Boot] [PATCH 2/2] net: mvgbe: convert to DM
Joe Hershberger
joe.hershberger at ni.com
Mon Jul 2 20:59:18 UTC 2018
On Wed, Jun 27, 2018 at 5:06 AM, Chris Packham <judge.packham at gmail.com> wrote:
> Add driver model support to the mvgbe driver. As a temporary measure
> both DM and non-DM uses are supported. Once all the users have been
> converted the non-DM support can be dropped.
>
> Signed-off-by: Chris Packham <judge.packham at gmail.com>
> ---
>
> drivers/net/mvgbe.c | 201 +++++++++++++++++++++++++++++++++++++++++++-
> drivers/net/mvgbe.h | 16 ++++
> 2 files changed, 213 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
> index 96ca35512f01..bddf2bc29aac 100644
> --- a/drivers/net/mvgbe.c
> +++ b/drivers/net/mvgbe.c
> @@ -12,6 +12,7 @@
> */
>
> #include <common.h>
> +#include <dm.h>
> #include <net.h>
> #include <malloc.h>
> #include <miiphy.h>
> @@ -127,8 +128,12 @@ static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
> static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
> int reg_ofs)
> {
> +#ifdef CONFIG_DM_ETH
> + struct mvgbe_device *dmvgbe = bus->priv;
> +#else
> struct eth_device *dev = eth_get_dev_by_name(bus->name);
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> +#endif
>
> return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
> }
> @@ -180,8 +185,12 @@ static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
> static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
> int reg_ofs, u16 data)
> {
> +#ifdef CONFIG_DM_ETH
> + struct mvgbe_device *dmvgbe = bus->priv;
> +#else
> struct eth_device *dev = eth_get_dev_by_name(bus->name);
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> +#endif
>
> return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
> }
> @@ -415,11 +424,12 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
> dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
> }
>
> -static int __mvgbe_init(struct mvgbe_device *dmvgbe)
> +static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr)
> {
> struct mvgbe_registers *regs = dmvgbe->regs;
> #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
> !defined(CONFIG_PHYLIB) && \
> + !defined(CONFIG_DM_ETH) && \
> defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
> int i;
> #endif
> @@ -436,7 +446,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
>
> set_dram_access(regs);
> port_init_mac_tables(regs);
> - port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
> + port_uc_addr_set(dmvgbe, enetaddr);
>
> /* Assign port configuration and command. */
> MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
> @@ -473,6 +483,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
>
> #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
> !defined(CONFIG_PHYLIB) && \
> + !defined(CONFIG_DM_ETH) && \
> defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
> /* Wait up to 5s for the link status */
> for (i = 0; i < 5; i++) {
> @@ -492,12 +503,14 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
> return 0;
> }
>
> +#ifndef CONFIG_DM_ETH
> static int mvgbe_init(struct eth_device *dev)
> {
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
>
> - return __mvgbe_init(dmvgbe);
> + return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr);
> }
> +#endif
>
> static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
> {
> @@ -524,6 +537,7 @@ static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
> MVGBE_REG_WR(regs->peim, 0);
> }
>
> +#ifndef CONFIG_DM_ETH
> static int mvgbe_halt(struct eth_device *dev)
> {
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> @@ -532,7 +546,18 @@ static int mvgbe_halt(struct eth_device *dev)
>
> return 0;
> }
> +#endif
>
> +#ifdef CONFIG_DM_ETH
> +static int mvgbe_write_hwaddr(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> +
> + port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
> +
> + return 0;
> +}
> +#else
> static int mvgbe_write_hwaddr(struct eth_device *dev)
> {
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> @@ -541,6 +566,7 @@ static int mvgbe_write_hwaddr(struct eth_device *dev)
> port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
> return 0;
> }
> +#endif
>
> static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
> int datasize)
> @@ -597,12 +623,14 @@ static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
> return 0;
> }
>
> +#ifndef CONFIG_DM_ETH
> static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
> {
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
>
> return __mvgbe_send(dmvgbe, dataptr, datasize);
> }
> +#endif
>
> static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
> {
> @@ -677,6 +705,7 @@ static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
> return rx_bytes;
> }
>
> +#ifndef CONFIG_DM_ETH
> static int mvgbe_recv(struct eth_device *dev)
> {
> struct mvgbe_device *dmvgbe = to_mvgbe(dev);
> @@ -691,8 +720,9 @@ static int mvgbe_recv(struct eth_device *dev)
>
> return 0;
> }
> +#endif
>
> -#if defined(CONFIG_PHYLIB)
> +#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
> int mvgbe_phylib_init(struct eth_device *dev, int phyid)
> {
> struct mii_dev *bus;
> @@ -731,6 +761,7 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
> }
> #endif
>
> +#ifndef CONFIG_DM_ETH
> int mvgbe_initialize(bd_t *bis)
> {
> struct mvgbe_device *dmvgbe;
> @@ -834,3 +865,165 @@ error1:
> }
> return 0;
> }
> +#endif
> +
> +#ifdef CONFIG_DM_ETH
> +static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
> +{
> + return dmvgbe->phyaddr > PHY_MAX_ADDR;
> +}
> +
> +static int mvgbe_start(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> + struct phy_device *phydev;
> + int ret;
> +
> + ret = __mvgbe_init(dmvgbe, pdata->enetaddr);
> + if (ret)
> + return ret;
> +
> + if (!mvgbe_port_is_fixed_link(dmvgbe)) {
> + /* Set phy address of the port */
> + miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
> + dmvgbe->phyaddr);
> +
> + phydev = phy_connect(dmvgbe->bus, dmvgbe->phyaddr, dev,
> + dmvgbe->phy_interface);
> + if (!phydev) {
> + printf("phy_connect failed\n");
> + return -ENODEV;
> + }
> +
> + phy_config(phydev);
> + phy_startup(phydev);
> + }
Please use a helper function to consolidate this with mvgbe_phylib_init().
> +
> + return 0;
> +}
> +
> +static int mvgbe_send(struct udevice *dev, void *packet, int length)
> +{
> + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +
> + return __mvgbe_send(dmvgbe, packet, length);
> +}
> +
> +static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
> +{
> + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +
> + return __mvgbe_recv(dmvgbe, packetp);
> +}
> +
> +static void mvgbe_stop(struct udevice *dev)
> +{
> + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> +
> + __mvgbe_halt(dmvgbe);
> +}
> +
> +static int mvgbe_probe(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> + void *blob = (void *)gd->fdt_blob;
> + int node = dev_of_offset(dev);
> + struct mii_dev *bus;
> + unsigned long addr;
> + int ret;
> + int fl_node;
> +
> + dmvgbe->p_rxdesc =
> + (struct mvgbe_rxdesc *)memalign(PKTALIGN,
> + MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
> + dmvgbe->p_rxbuf = (u8 *)memalign(PKTALIGN,
> + RINGSZ * PKTSIZE_ALIGN + 1);
> + dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
> + dmvgbe->p_txdesc = (struct mvgbe_txdesc *)memalign(
> + PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
Please use a helper function to consolidate this setup between probe
and mvgbe_initialize().
> +
> + dmvgbe->regs = (void __iomem *)pdata->iobase;
> +
> + /* PHY interface is already decoded in mvneta_ofdata_to_platdata() */
> + dmvgbe->phy_interface = pdata->phy_interface;
> +
> + /* fetch 'fixed-link' property from 'neta' node */
> + fl_node = fdt_subnode_offset(blob, node, "fixed-link");
> + if (fl_node != -FDT_ERR_NOTFOUND) {
> + /* set phy_addr to invalid value for fixed link */
> + dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
> + dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
> + dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
> + } else {
> + /* Now read phyaddr from DT */
> + addr = fdtdec_get_int(blob, node, "phy", 0);
> + addr = fdt_node_offset_by_phandle(blob, addr);
> + dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
> + }
I think this stuff reading from the DT should be in mvgbe_ofdata_to_platdata().
> +
> + bus = mdio_alloc();
> + if (!bus) {
> + printf("Failed to allocate MDIO bus\n");
> + return -ENOMEM;
> + }
> +
> + bus->read = smi_reg_read;
> + bus->write = smi_reg_write;
> + snprintf(bus->name, sizeof(bus->name), dev->name);
> + bus->priv = dmvgbe;
> + dmvgbe->bus = bus;
> +
> + ret = mdio_register(bus);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static const struct eth_ops mvgbe_ops = {
> + .start = mvgbe_start,
> + .send = mvgbe_send,
> + .recv = mvgbe_recv,
> + .stop = mvgbe_stop,
> + .write_hwaddr = mvgbe_write_hwaddr,
> +};
> +
> +static int mvgbe_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + const char *phy_mode;
> +
> + pdata->iobase = devfdt_get_addr(dev);
> +
> + /* Get phy-mode / phy_interface from DT */
> + pdata->phy_interface = -1;
> + phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "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 mvgbe_ids[] = {
> + { .compatible = "marvell,kirkwood-eth" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(mvgbe) = {
> + .name = "mvgbe",
> + .id = UCLASS_ETH,
> + .of_match = mvgbe_ids,
> + .ofdata_to_platdata = mvgbe_ofdata_to_platdata,
> + .probe = mvgbe_probe,
> + .ops = &mvgbe_ops,
> + .priv_auto_alloc_size = sizeof(struct mvgbe_device),
> + .platdata_auto_alloc_size = sizeof(struct eth_pdata),
> +};
> +#endif /* CONFIG_DM_ETH */
> diff --git a/drivers/net/mvgbe.h b/drivers/net/mvgbe.h
> index 1dc9bbea2f42..44541c0a85e3 100644
> --- a/drivers/net/mvgbe.h
> +++ b/drivers/net/mvgbe.h
> @@ -30,7 +30,9 @@
> #define RXUQ 0 /* Used Rx queue */
> #define TXUQ 0 /* Used Rx queue */
>
> +#ifndef CONFIG_DM_ETH
> #define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
> +#endif
> #define MVGBE_REG_WR(adr, val) writel(val, &adr)
> #define MVGBE_REG_RD(adr) readl(&adr)
> #define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
> @@ -479,13 +481,27 @@ struct mvgbe_txdesc {
>
> /* port device data struct */
> struct mvgbe_device {
> +#ifndef CONFIG_DM_ETH
> struct eth_device dev;
> +#endif
> struct mvgbe_registers *regs;
> struct mvgbe_txdesc *p_txdesc;
> struct mvgbe_rxdesc *p_rxdesc;
> struct mvgbe_rxdesc *p_rxdesc_curr;
> u8 *p_rxbuf;
> u8 *p_aligned_txbuf;
> +
> +#ifdef CONFIG_DM_ETH
> + phy_interface_t phy_interface;
> + unsigned int link;
> + unsigned int duplex;
> + unsigned int speed;
> +
> + int init;
> + int phyaddr;
> + struct phy_device *phydev;
> + struct mii_dev *bus;
> +#endif
> };
>
> #endif /* __MVGBE_H__ */
> --
> 2.18.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
More information about the U-Boot
mailing list