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

Ramon Fried
2021-12-29T19:31:26Z

On Fri, Dec 24, 2021 at 9:25 AM Vignesh Raghavendra <vigneshr@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@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
>