aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ti
diff options
context:
space:
mode:
authorVignesh Raghavendra <vigneshr@ti.com>2021-12-24 12:55:30 +0530
committerTom Rini <trini@konsulko.com>2022-01-15 10:38:26 -0500
commit38922b1f4acc0ae80c58a3baae9134b02defece7 (patch)
treebf9357d2fe686affbf0af70fe20560155023e326 /drivers/net/ti
parente58d9284850fa78d364d264087fe744717963675 (diff)
downloadu-boot-38922b1f4acc0ae80c58a3baae9134b02defece7.zip
u-boot-38922b1f4acc0ae80c58a3baae9134b02defece7.tar.gz
u-boot-38922b1f4acc0ae80c58a3baae9134b02defece7.tar.bz2
net: ti: am65-cpsw: Add support for multi port independent MAC mode
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. 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>
Diffstat (limited to 'drivers/net/ti')
-rw-r--r--drivers/net/ti/Kconfig2
-rw-r--r--drivers/net/ti/am65-cpsw-nuss.c77
2 files changed, 52 insertions, 27 deletions
diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index f2dbbd0..59c96d8 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 3ab6a30..6ae69b5 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");
}
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),