[PATCH 2/8] net: ti: am65-cpsw: Add support for multi port independent MAC mode

Ramon Fried rfried.dev at gmail.com
Wed Dec 29 20:31:06 CET 2021


On Fri, Dec 24, 2021 at 9:25 AM Vignesh Raghavendra <vigneshr at ti.com> wrote:
>
> On certain TI SoC, like AM64x there is a CPSW3G which supports 2
> external independent MAC ports for single CPSW instance.
> It is not possible for Ethernet driver to register more than one port
> for given instance.
>
> This patch modifies top level CPSW NUSS as UCLASS_MISC and binds
> UCLASS_ETH to individual ports so as to support bring up more than one
> Ethernet interface in U-Boot.
>
> Note that there is no isolation in the since, CPSW NUSS is in promisc
> mode and forwards all packets to host.
So both ports are working in parallel, how do I choose from which port to exit ?
>
> Since top level driver is now UCLASS_MISC, board files would need to
> instantiate this driver explicitly.
>
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> ---
>  drivers/net/ti/Kconfig          |  2 +
>  drivers/net/ti/am65-cpsw-nuss.c | 77 +++++++++++++++++++++------------
>  2 files changed, 52 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
> index f2dbbd0128..59c96d862d 100644
> --- a/drivers/net/ti/Kconfig
> +++ b/drivers/net/ti/Kconfig
> @@ -28,6 +28,8 @@ config DRIVER_TI_KEYSTONE_NET
>  config TI_AM65_CPSW_NUSS
>         bool "TI K3 AM65x MCU CPSW Nuss Ethernet controller driver"
>         depends on ARCH_K3
> +       imply MISC_INIT_R
> +       imply MISC
>         select PHYLIB
>         help
>           This driver supports TI K3 MCU CPSW Nuss Ethernet controller
> diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
> index 3ab6a30828..6ae69b51c7 100644
> --- a/drivers/net/ti/am65-cpsw-nuss.c
> +++ b/drivers/net/ti/am65-cpsw-nuss.c
> @@ -597,7 +597,7 @@ static int am65_cpsw_phy_init(struct udevice *dev)
>         return ret;
>  }
>
> -static int am65_cpsw_ofdata_parse_phy(struct udevice *dev, ofnode port_np)
> +static int am65_cpsw_ofdata_parse_phy(struct udevice *dev)
>  {
>         struct eth_pdata *pdata = dev_get_plat(dev);
>         struct am65_cpsw_priv *priv = dev_get_priv(dev);
> @@ -605,7 +605,9 @@ static int am65_cpsw_ofdata_parse_phy(struct udevice *dev, ofnode port_np)
>         const char *phy_mode;
>         int ret = 0;
>
> -       phy_mode = ofnode_read_string(port_np, "phy-mode");
> +       dev_read_u32(dev, "reg", &priv->port_id);
> +
> +       phy_mode = dev_read_string(dev, "phy-mode");
>         if (phy_mode) {
>                 pdata->phy_interface =
>                                 phy_get_interface_by_name(phy_mode);
> @@ -617,13 +619,13 @@ static int am65_cpsw_ofdata_parse_phy(struct udevice *dev, ofnode port_np)
>                 }
>         }
>
> -       ofnode_read_u32(port_np, "max-speed", (u32 *)&pdata->max_speed);
> +       dev_read_u32(dev, "max-speed", (u32 *)&pdata->max_speed);
>         if (pdata->max_speed)
>                 dev_err(dev, "Port %u speed froced to %uMbit\n",
>                         priv->port_id, pdata->max_speed);
>
>         priv->has_phy  = true;
> -       ret = ofnode_parse_phandle_with_args(port_np, "phy-handle",
> +       ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "phy-handle",
>                                              NULL, 0, 0, &out_args);
>         if (ret) {
>                 dev_err(dev, "can't parse phy-handle port %u (%d)\n",
> @@ -646,21 +648,46 @@ out:
>         return ret;
>  }
>
> -static int am65_cpsw_probe_cpsw(struct udevice *dev)
> +static int am65_cpsw_port_probe(struct udevice *dev)
>  {
>         struct am65_cpsw_priv *priv = dev_get_priv(dev);
>         struct eth_pdata *pdata = dev_get_plat(dev);
>         struct am65_cpsw_common *cpsw_common;
> -       ofnode ports_np, node;
> -       int ret, i;
> +       char portname[15];
> +       int ret;
>
>         priv->dev = dev;
>
> -       cpsw_common = calloc(1, sizeof(*priv->cpsw_common));
> -       if (!cpsw_common)
> -               return -ENOMEM;
> +       cpsw_common = dev_get_priv(dev->parent);
>         priv->cpsw_common = cpsw_common;
>
> +       sprintf(portname, "%s%s", dev->parent->name, dev->name);
> +       device_set_name(dev, portname);
> +
> +       ret = am65_cpsw_ofdata_parse_phy(dev);
> +       if (ret)
> +               goto out;
> +
> +       am65_cpsw_gmii_sel_k3(priv, pdata->phy_interface, priv->port_id);
> +
> +       ret = am65_cpsw_mdio_init(dev);
> +       if (ret)
> +               goto out;
> +
> +       ret = am65_cpsw_phy_init(dev);
> +       if (ret)
> +               goto out;
> +out:
> +       return ret;
> +}
> +
> +static int am65_cpsw_probe_nuss(struct udevice *dev)
> +{
> +       struct am65_cpsw_common *cpsw_common = dev_get_priv(dev);
> +       ofnode ports_np, node;
> +       int ret, i;
> +       struct udevice *port_dev;
> +
>         cpsw_common->dev = dev;
>         cpsw_common->ss_base = dev_read_addr(dev);
>         if (cpsw_common->ss_base == FDT_ADDR_T_NONE)
> @@ -723,10 +750,9 @@ static int am65_cpsw_probe_cpsw(struct udevice *dev)
>                 if (disabled)
>                         continue;
>
> -               priv->port_id = port_id;
> -               ret = am65_cpsw_ofdata_parse_phy(dev, node);
> +               ret = device_bind_driver_to_node(dev, "am65_cpsw_nuss_port", ofnode_get_name(node), node, &port_dev);
>                 if (ret)
> -                       goto out;
> +                       printf("SCREEEM\n");
Please handle reasonably.
>         }
>
>         for (i = 0; i < AM65_CPSW_CPSWNU_MAX_PORTS; i++) {
> @@ -756,16 +782,6 @@ static int am65_cpsw_probe_cpsw(struct udevice *dev)
>                         dev_read_u32_default(dev, "bus_freq",
>                                              AM65_CPSW_MDIO_BUS_FREQ_DEF);
>
> -       am65_cpsw_gmii_sel_k3(priv, pdata->phy_interface, priv->port_id);
> -
> -       ret = am65_cpsw_mdio_init(dev);
> -       if (ret)
> -               goto out;
> -
> -       ret = am65_cpsw_phy_init(dev);
> -       if (ret)
> -               goto out;
> -
>         dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 0x%08X Ports:%u mdio_freq:%u\n",
>                  readl(cpsw_common->ss_base),
>                  readl(cpsw_common->cpsw_base),
> @@ -786,11 +802,18 @@ static const struct udevice_id am65_cpsw_nuss_ids[] = {
>         { }
>  };
>
> -U_BOOT_DRIVER(am65_cpsw_nuss_slave) = {
> -       .name   = "am65_cpsw_nuss_slave",
> -       .id     = UCLASS_ETH,
> +U_BOOT_DRIVER(am65_cpsw_nuss) = {
> +       .name   = "am65_cpsw_nuss",
> +       .id     = UCLASS_MISC,
>         .of_match = am65_cpsw_nuss_ids,
> -       .probe  = am65_cpsw_probe_cpsw,
> +       .probe  = am65_cpsw_probe_nuss,
> +       .priv_auto = sizeof(struct am65_cpsw_common),
> +};
> +
> +U_BOOT_DRIVER(am65_cpsw_nuss_port) = {
> +       .name   = "am65_cpsw_nuss_port",
> +       .id     = UCLASS_ETH,
> +       .probe  = am65_cpsw_port_probe,
>         .ops    = &am65_cpsw_ops,
>         .priv_auto      = sizeof(struct am65_cpsw_priv),
>         .plat_auto      = sizeof(struct eth_pdata),
> --
> 2.34.1
>


More information about the U-Boot mailing list