* [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
@ 2025-11-05 4:33 Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 1/3] net: enetc: set external MDIO PHY address for i.MX95 ENETC Wei Fang
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Wei Fang @ 2025-11-05 4:33 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni
Cc: aziz.sellami, imx, netdev, linux-kernel
From the hardware perspective, NETC IP has only one external master MDIO
interface (eMDIO) for managing external PHYs. The EMDIO function and the
ENETC port MDIO are all virtual ports of the eMDIO.
The difference is that EMDIO function is a 'global port', it can access
all the PHYs on the eMDIO, so it provides a means for different software
modules to share a single set of MDIO signals to access their PHYs.
But for ENETC port MDIO, each ENETC can access its set of registers to
initiate accesses on the MDIO and the eMDIO arbitrates between them,
completing one access before proceeding with the next. It is required
that each ENETC port MDIO has exclusive access and control of its PHY.
Therefore, we need to set the external PHY address for ENETCs, so that
its port MDIO can only access its own PHY. If the PHY address accessed
by the port MDIO is different from the preset PHY address, the MDIO
access will be invalid.
Normally, all ENETCs use the interfaces provided by the EMDIO function
to access their PHYs, provided that the ENETC and EMDIO are on the same
OS. If an ENETC is assigned to a guest OS, it will not be able to use
the interfaces provided by the EMDIO function, so it must uses its port
MDIO to access and manage its PHY.
In DTS, when the PHY node is a child node of EMDIO, ENETC will use EMDIO
to access the PHY. If ENETC wants to use port MDIO, it only needs to add
a mdio child node to the ENETC node.
Different from the external MDIO interface, each ENETC has an internal
MDIO interface for managing on-die PHY (PCS) if it has PCS layer. The
internal MDIO interface is controlled by the internal MDIO registers of
the ENETC port.
---
v2 changes:
Improve the commit message.
v1 link: https://lore.kernel.org/imx/20251030091538.581541-1-wei.fang@nxp.com/
---
Aziz Sellami (1):
net: enetc: set external MDIO PHY address for i.MX95 ENETC
Wei Fang (2):
net: enetc: set external MDIO PHY address for i.MX94 ENETC
net: enetc: add port MDIO support for ENETC v4
.../net/ethernet/freescale/enetc/enetc4_hw.h | 6 +
.../freescale/enetc/enetc_pf_common.c | 14 ++-
.../ethernet/freescale/enetc/netc_blk_ctrl.c | 111 +++++++++++++++++-
3 files changed, 128 insertions(+), 3 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 net-next 1/3] net: enetc: set external MDIO PHY address for i.MX95 ENETC
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
@ 2025-11-05 4:33 ` Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 2/3] net: enetc: set external MDIO PHY address for i.MX94 ENETC Wei Fang
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Wei Fang @ 2025-11-05 4:33 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni
Cc: aziz.sellami, imx, netdev, linux-kernel
From: Aziz Sellami <aziz.sellami@nxp.com>
When configuring the PHY as port EMDIO (by putting an mdio node as a
child of the enetc port) the ierb needs to be configured with the right
phy address. And since the configuration is harmless for the central
EMDIO mode (current default behavior for i.MX 95 EVKs), put the
configuration there anyway for code simplicity.
Signed-off-by: Aziz Sellami <aziz.sellami@nxp.com>
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../ethernet/freescale/enetc/netc_blk_ctrl.c | 57 ++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
index d7aee3c934d3..1d499276465f 100644
--- a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
+++ b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
@@ -67,6 +67,9 @@
#define IERB_EMDIOFAUXR 0x344
#define IERB_T0FAUXR 0x444
#define IERB_ETBCR(a) (0x300c + 0x100 * (a))
+#define IERB_LBCR(a) (0x1010 + 0x40 * (a))
+#define LBCR_MDIO_PHYAD_PRTAD(addr) (((addr) & 0x1f) << 8)
+
#define IERB_EFAUXR(a) (0x3044 + 0x100 * (a))
#define IERB_VFAUXR(a) (0x4004 + 0x40 * (a))
#define FAUXR_LDID GENMASK(3, 0)
@@ -322,6 +325,58 @@ static int netc_unlock_ierb_with_warm_reset(struct netc_blk_ctrl *priv)
1000, 100000, true, priv->prb, PRB_NETCRR);
}
+static int imx95_enetc_mdio_phyaddr_config(struct platform_device *pdev)
+{
+ struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *phy_node;
+ int bus_devfn, err;
+ u32 addr;
+
+ /* Update the port EMDIO PHY address through parsing phy properties.
+ * This is needed when using the port EMDIO but it's harmless when
+ * using the central EMDIO. So apply it on all cases.
+ */
+ for_each_child_of_node_scoped(np, child) {
+ for_each_child_of_node_scoped(child, gchild) {
+ if (!of_device_is_compatible(gchild, "pci1131,e101"))
+ continue;
+
+ bus_devfn = netc_of_pci_get_bus_devfn(gchild);
+ if (bus_devfn < 0)
+ return bus_devfn;
+
+ phy_node = of_parse_phandle(gchild, "phy-handle", 0);
+ if (!phy_node)
+ continue;
+
+ err = of_property_read_u32(phy_node, "reg", &addr);
+ of_node_put(phy_node);
+ if (err)
+ return err;
+
+ switch (bus_devfn) {
+ case IMX95_ENETC0_BUS_DEVFN:
+ netc_reg_write(priv->ierb, IERB_LBCR(0),
+ LBCR_MDIO_PHYAD_PRTAD(addr));
+ break;
+ case IMX95_ENETC1_BUS_DEVFN:
+ netc_reg_write(priv->ierb, IERB_LBCR(1),
+ LBCR_MDIO_PHYAD_PRTAD(addr));
+ break;
+ case IMX95_ENETC2_BUS_DEVFN:
+ netc_reg_write(priv->ierb, IERB_LBCR(2),
+ LBCR_MDIO_PHYAD_PRTAD(addr));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int imx95_ierb_init(struct platform_device *pdev)
{
struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
@@ -349,7 +404,7 @@ static int imx95_ierb_init(struct platform_device *pdev)
/* NETC TIMER */
netc_reg_write(priv->ierb, IERB_T0FAUXR, 7);
- return 0;
+ return imx95_enetc_mdio_phyaddr_config(pdev);
}
static int imx94_get_enetc_id(struct device_node *np)
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 net-next 2/3] net: enetc: set external MDIO PHY address for i.MX94 ENETC
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 1/3] net: enetc: set external MDIO PHY address for i.MX95 ENETC Wei Fang
@ 2025-11-05 4:33 ` Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 3/3] net: enetc: add port MDIO support for ENETC v4 Wei Fang
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Wei Fang @ 2025-11-05 4:33 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni
Cc: aziz.sellami, imx, netdev, linux-kernel
NETC IP has only one external master MDIO interface (eMDIO) for managing
the external PHYs. ENETC can use the interfaces provided by the EMDIO
function or its port MDIO to access and manage its external PHY. Both
the EMDIO function and the port MDIO are all virtual ports of the eMDIO.
The difference is that the EMDIO function is a 'global port', it can
access all the PHYs on the eMDIO, but port MDIO can only access its own
PHY. To ensure that ENETC can only access its own PHY through port MDIO,
LaBCR[MDIO_PHYAD_PRTAD] needs to be set, which represents the address of
the external PHY connected to ENETC. If the accessed PHY address is not
consistent with LaBCR[MDIO_PHYAD_PRTAD], then the MDIO access initiated
by port MDIO will be invalid.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../ethernet/freescale/enetc/netc_blk_ctrl.c | 74 ++++++++++++++++---
1 file changed, 64 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
index 1d499276465f..4617cbc70f5a 100644
--- a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
+++ b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
@@ -325,13 +325,29 @@ static int netc_unlock_ierb_with_warm_reset(struct netc_blk_ctrl *priv)
1000, 100000, true, priv->prb, PRB_NETCRR);
}
+static int netc_get_phy_addr(struct device_node *np)
+{
+ struct device_node *phy_node;
+ u32 addr;
+ int err;
+
+ phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (!phy_node)
+ return 0;
+
+ err = of_property_read_u32(phy_node, "reg", &addr);
+ of_node_put(phy_node);
+ if (err)
+ return err;
+
+ return addr;
+}
+
static int imx95_enetc_mdio_phyaddr_config(struct platform_device *pdev)
{
struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
struct device_node *np = pdev->dev.of_node;
- struct device_node *phy_node;
- int bus_devfn, err;
- u32 addr;
+ int bus_devfn, addr;
/* Update the port EMDIO PHY address through parsing phy properties.
* This is needed when using the port EMDIO but it's harmless when
@@ -346,14 +362,15 @@ static int imx95_enetc_mdio_phyaddr_config(struct platform_device *pdev)
if (bus_devfn < 0)
return bus_devfn;
- phy_node = of_parse_phandle(gchild, "phy-handle", 0);
- if (!phy_node)
- continue;
+ addr = netc_get_phy_addr(gchild);
+ if (addr < 0)
+ return addr;
- err = of_property_read_u32(phy_node, "reg", &addr);
- of_node_put(phy_node);
- if (err)
- return err;
+ /* The default value of LaBCR[MDIO_PHYAD_PRTAD ] is
+ * 0, so no need to set the register.
+ */
+ if (!addr)
+ continue;
switch (bus_devfn) {
case IMX95_ENETC0_BUS_DEVFN:
@@ -479,6 +496,39 @@ static int imx94_enetc_update_tid(struct netc_blk_ctrl *priv,
return 0;
}
+static int imx94_enetc_mdio_phyaddr_config(struct netc_blk_ctrl *priv,
+ struct device_node *np)
+{
+ int bus_devfn, addr;
+
+ bus_devfn = netc_of_pci_get_bus_devfn(np);
+ if (bus_devfn < 0)
+ return bus_devfn;
+
+ addr = netc_get_phy_addr(np);
+ if (addr <= 0)
+ return addr;
+
+ switch (bus_devfn) {
+ case IMX94_ENETC0_BUS_DEVFN:
+ netc_reg_write(priv->ierb, IERB_LBCR(IMX94_ENETC0_LINK),
+ LBCR_MDIO_PHYAD_PRTAD(addr));
+ break;
+ case IMX94_ENETC1_BUS_DEVFN:
+ netc_reg_write(priv->ierb, IERB_LBCR(IMX94_ENETC1_LINK),
+ LBCR_MDIO_PHYAD_PRTAD(addr));
+ break;
+ case IMX94_ENETC2_BUS_DEVFN:
+ netc_reg_write(priv->ierb, IERB_LBCR(IMX94_ENETC2_LINK),
+ LBCR_MDIO_PHYAD_PRTAD(addr));
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int imx94_ierb_init(struct platform_device *pdev)
{
struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
@@ -493,6 +543,10 @@ static int imx94_ierb_init(struct platform_device *pdev)
err = imx94_enetc_update_tid(priv, gchild);
if (err)
return err;
+
+ err = imx94_enetc_mdio_phyaddr_config(priv, gchild);
+ if (err)
+ return err;
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 net-next 3/3] net: enetc: add port MDIO support for ENETC v4
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 1/3] net: enetc: set external MDIO PHY address for i.MX95 ENETC Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 2/3] net: enetc: set external MDIO PHY address for i.MX94 ENETC Wei Fang
@ 2025-11-05 4:33 ` Wei Fang
2025-11-11 2:13 ` [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Jakub Kicinski
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Wei Fang @ 2025-11-05 4:33 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni
Cc: aziz.sellami, imx, netdev, linux-kernel
The NETC IP provides two ways for ENETC to access its external PHY. One
is that EMDIO function provides a means for different ENETCs to share a
single set of MDIO signals to access their PHYs. And this EMDIO support
has been added in the commit a52201fb9caa ("net: enetc: add i.MX95 EMDIO
support"). The other one is that each ENETC has a set of MDIO registers
to access and control its PHY. When the PHY node is a child node of the
ENETC node, the ENETC will use its port MDIO to access its external PHY.
For the on-die PHY (PCS/Serdes), each ENETC has an internal MDIO bus for
managing the on-die PHY, this internal MDIO bus is controlled by a set
of internal MDIO registers of the ENETC port.
Because the port MDIO support has been added to the driver for ENETC v1.
The difference between ENETC v4 and ENETC v1 is the base address of the
MDIO registers, so we only need to add the new base address to add the
port MDIO support for ENETC v4.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc4_hw.h | 6 ++++++
.../net/ethernet/freescale/enetc/enetc_pf_common.c | 14 ++++++++++++--
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
index ebea4298791c..3ed0f7a02767 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
@@ -170,6 +170,9 @@
/* Port MAC 0/1 Maximum Frame Length Register */
#define ENETC4_PM_MAXFRM(mac) (0x5014 + (mac) * 0x400)
+/* Port internal MDIO base address, use to access PCS */
+#define ENETC4_PM_IMDIO_BASE 0x5030
+
/* Port MAC 0/1 Pause Quanta Register */
#define ENETC4_PM_PAUSE_QUANTA(mac) (0x5054 + (mac) * 0x400)
@@ -198,6 +201,9 @@
#define SSP_1G 2
#define PM_IF_MODE_ENA BIT(15)
+/* Port external MDIO Base address, use to access off-chip PHY */
+#define ENETC4_EMDIO_BASE 0x5c00
+
/**********************ENETC Pseudo MAC port registers************************/
/* Port pseudo MAC receive octets counter (64-bit) */
#define ENETC4_PPMROCR 0x5080
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 9c634205e2a7..76263b8566bb 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -176,7 +176,12 @@ static int enetc_mdio_probe(struct enetc_pf *pf, struct device_node *np)
bus->parent = dev;
mdio_priv = bus->priv;
mdio_priv->hw = &pf->si->hw;
- mdio_priv->mdio_base = ENETC_EMDIO_BASE;
+
+ if (is_enetc_rev1(pf->si))
+ mdio_priv->mdio_base = ENETC_EMDIO_BASE;
+ else
+ mdio_priv->mdio_base = ENETC4_EMDIO_BASE;
+
snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
err = of_mdiobus_register(bus, np);
@@ -221,7 +226,12 @@ static int enetc_imdio_create(struct enetc_pf *pf)
bus->phy_mask = ~0;
mdio_priv = bus->priv;
mdio_priv->hw = &pf->si->hw;
- mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
+
+ if (is_enetc_rev1(pf->si))
+ mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
+ else
+ mdio_priv->mdio_base = ENETC4_PM_IMDIO_BASE;
+
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev));
err = mdiobus_register(bus);
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
` (2 preceding siblings ...)
2025-11-05 4:33 ` [PATCH v2 net-next 3/3] net: enetc: add port MDIO support for ENETC v4 Wei Fang
@ 2025-11-11 2:13 ` Jakub Kicinski
2025-11-11 3:06 ` Andrew Lunn
2025-11-11 3:30 ` Andrew Lunn
2025-11-18 2:19 ` Wei Fang
5 siblings, 1 reply; 12+ messages in thread
From: Jakub Kicinski @ 2025-11-11 2:13 UTC (permalink / raw)
To: andrew+netdev
Cc: Wei Fang, claudiu.manoil, vladimir.oltean, xiaoning.wang, davem,
edumazet, pabeni, aziz.sellami, imx, netdev, linux-kernel
On Wed, 5 Nov 2025 12:33:41 +0800 Wei Fang wrote:
> v2 changes:
> Improve the commit message.
> v1 link: https://lore.kernel.org/imx/20251030091538.581541-1-wei.fang@nxp.com/
Andrew, is the explanation good enough?
If the feature is inherently not safe to use with existing Linux
locking scheme we can't support it upstream..
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-11 2:13 ` [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Jakub Kicinski
@ 2025-11-11 3:06 ` Andrew Lunn
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2025-11-11 3:06 UTC (permalink / raw)
To: Jakub Kicinski
Cc: andrew+netdev, Wei Fang, claudiu.manoil, vladimir.oltean,
xiaoning.wang, davem, edumazet, pabeni, aziz.sellami, imx, netdev,
linux-kernel
On Mon, Nov 10, 2025 at 06:13:06PM -0800, Jakub Kicinski wrote:
> On Wed, 5 Nov 2025 12:33:41 +0800 Wei Fang wrote:
> > v2 changes:
> > Improve the commit message.
> > v1 link: https://lore.kernel.org/imx/20251030091538.581541-1-wei.fang@nxp.com/
>
> Andrew, is the explanation good enough?
Not really. I'm still confused.
Let me ask more questions.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
` (3 preceding siblings ...)
2025-11-11 2:13 ` [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Jakub Kicinski
@ 2025-11-11 3:30 ` Andrew Lunn
2025-11-11 5:29 ` Wei Fang
2025-11-18 2:19 ` Wei Fang
5 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2025-11-11 3:30 UTC (permalink / raw)
To: Wei Fang
Cc: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, aziz.sellami, imx, netdev,
linux-kernel
On Wed, Nov 05, 2025 at 12:33:41PM +0800, Wei Fang wrote:
> >From the hardware perspective, NETC IP has only one external master MDIO
> interface (eMDIO) for managing external PHYs. The EMDIO function and the
> ENETC port MDIO are all virtual ports of the eMDIO.
>
> The difference is that EMDIO function is a 'global port', it can access
> all the PHYs on the eMDIO, so it provides a means for different software
> modules to share a single set of MDIO signals to access their PHYs.
>
> But for ENETC port MDIO, each ENETC can access its set of registers to
> initiate accesses on the MDIO and the eMDIO arbitrates between them,
> completing one access before proceeding with the next. It is required
> that each ENETC port MDIO has exclusive access and control of its PHY.
> Therefore, we need to set the external PHY address for ENETCs, so that
> its port MDIO can only access its own PHY. If the PHY address accessed
> by the port MDIO is different from the preset PHY address, the MDIO
> access will be invalid.
>
> Normally, all ENETCs use the interfaces provided by the EMDIO function
> to access their PHYs, provided that the ENETC and EMDIO are on the same
> OS. If an ENETC is assigned to a guest OS, it will not be able to use
> the interfaces provided by the EMDIO function, so it must uses its port
> MDIO to access and manage its PHY.
I think i'm slowly starting to understand this. But i'm still missing
some parts.
What prevents a guest OS from setting the wrong value in its ENETC
port MDIO and then accessing any PHY on the physical bus?
I assume there is a hypervisor doing this enforcement? But if there is
a hypervisor doing this enforcement, why does the ENETC port MDIO need
programming? The hypervisor will block it from accessing anything it
should not be able to access. A normal MDIO bus scan will find just
the devices it is allowed to access.
I also think the architecture is wrong. Why is the MAC driver messing
around with the ENETC Port MDIO hardware? I assume the ENETC port MDIO
bus driver knows it is a ENETC port MDIO device it is driving? It
should be the one looking at the device tree description of its bus,
checking it has one and only one device described on the bus, and
programming itself with the device the hypervisor will let through.
Not that i think this is actually necessary, let the hypervisor
enforce it...
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-11 3:30 ` Andrew Lunn
@ 2025-11-11 5:29 ` Wei Fang
2025-11-11 13:15 ` Andrew Lunn
0 siblings, 1 reply; 12+ messages in thread
From: Wei Fang @ 2025-11-11 5:29 UTC (permalink / raw)
To: Andrew Lunn
Cc: Claudiu Manoil, Vladimir Oltean, Clark Wang,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, Aziz Sellami,
imx@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
> On Wed, Nov 05, 2025 at 12:33:41PM +0800, Wei Fang wrote:
> > >From the hardware perspective, NETC IP has only one external master MDIO
> > interface (eMDIO) for managing external PHYs. The EMDIO function and the
> > ENETC port MDIO are all virtual ports of the eMDIO.
> >
> > The difference is that EMDIO function is a 'global port', it can access
> > all the PHYs on the eMDIO, so it provides a means for different software
> > modules to share a single set of MDIO signals to access their PHYs.
> >
> > But for ENETC port MDIO, each ENETC can access its set of registers to
> > initiate accesses on the MDIO and the eMDIO arbitrates between them,
> > completing one access before proceeding with the next. It is required
> > that each ENETC port MDIO has exclusive access and control of its PHY.
> > Therefore, we need to set the external PHY address for ENETCs, so that
> > its port MDIO can only access its own PHY. If the PHY address accessed
> > by the port MDIO is different from the preset PHY address, the MDIO
> > access will be invalid.
> >
> > Normally, all ENETCs use the interfaces provided by the EMDIO function
> > to access their PHYs, provided that the ENETC and EMDIO are on the same
> > OS. If an ENETC is assigned to a guest OS, it will not be able to use
> > the interfaces provided by the EMDIO function, so it must uses its port
> > MDIO to access and manage its PHY.
>
> I think i'm slowly starting to understand this. But i'm still missing
> some parts.
>
> What prevents a guest OS from setting the wrong value in its ENETC
> port MDIO and then accessing any PHY on the physical bus?
>
There is an Integrated Endpoint Register Block (IERB) module inside the
NETC, it is used to set some pre-initialization for ENETC, switch and other
functions. And this module is controlled by the host OS. In IERB, each
ENETC has a corresponding LaBCR register, where
LaBCR[MDIO_PHYAD_PRTAD] represents the address of the external PHY
of that ENETC. If the PHY address accessed by the ENETC using port MDIO
does not match LaBCR[MDIO_PHYAD_PRTAD], the MDIO access is invalid.
Therefore, the Guest OS cannot access the PHY of other ENETCs using
port MDIO.
What patch 1 and patch 2 do is configure LaBCR[MDIO_PHYAD_PRTAD] for
each ENETC.
> I assume there is a hypervisor doing this enforcement? But if there is
> a hypervisor doing this enforcement, why does the ENETC port MDIO need
> programming? The hypervisor will block it from accessing anything it
> should not be able to access. A normal MDIO bus scan will find just
> the devices it is allowed to access.
>
> I also think the architecture is wrong. Why is the MAC driver messing
> around with the ENETC Port MDIO hardware? I assume the ENETC port MDIO
The MAC driver (enetc) only simply changes the base address of its port
MDIO registers, see patch 3:
mdio_priv->mdio_base = ENETC4_EMDIO_BASE;
Patch 1 and patch 2 are not changes to the MAC driver, but rather to
the netc-blk-ctrl driver, which manages the IERB module. We need to
program the address of each ENETC's external PHY into this
hypervisor-like module.
> bus driver knows it is a ENETC port MDIO device it is driving? It
> should be the one looking at the device tree description of its bus,
> checking it has one and only one device described on the bus, and
> programming itself with the device the hypervisor will let through.
> Not that i think this is actually necessary, let the hypervisor
> enforce it...
>
> Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-11 5:29 ` Wei Fang
@ 2025-11-11 13:15 ` Andrew Lunn
2025-11-11 14:20 ` Wei Fang
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2025-11-11 13:15 UTC (permalink / raw)
To: Wei Fang
Cc: Claudiu Manoil, Vladimir Oltean, Clark Wang,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, Aziz Sellami,
imx@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
> There is an Integrated Endpoint Register Block (IERB) module inside the
> NETC, it is used to set some pre-initialization for ENETC, switch and other
> functions. And this module is controlled by the host OS. In IERB, each
> ENETC has a corresponding LaBCR register, where
> LaBCR[MDIO_PHYAD_PRTAD] represents the address of the external PHY
> of that ENETC. If the PHY address accessed by the ENETC using port MDIO
> does not match LaBCR[MDIO_PHYAD_PRTAD], the MDIO access is invalid.
> Therefore, the Guest OS cannot access the PHY of other ENETCs using
> port MDIO.
>
> What patch 1 and patch 2 do is configure LaBCR[MDIO_PHYAD_PRTAD] for
> each ENETC.
And this is done by the host OS. The guest OS has no access to this
register?
The host OS is using DT, following the phandle from the MAC to the PHY
to find the address of the PHY. So is the MAC and PHY also probed in
the host OS, because it is listed in DT? When the guest OS is
provisioned, is the host driver of the MAC and PHY unbound? A DT blob
for the guest is constructed from the host DT blob, taking out all the
parts the guest is not allowed to access?
> > I assume there is a hypervisor doing this enforcement? But if there is
> > a hypervisor doing this enforcement, why does the ENETC port MDIO need
> > programming? The hypervisor will block it from accessing anything it
> > should not be able to access. A normal MDIO bus scan will find just
> > the devices it is allowed to access.
> >
> > I also think the architecture is wrong. Why is the MAC driver messing
> > around with the ENETC Port MDIO hardware? I assume the ENETC port MDIO
>
> The MAC driver (enetc) only simply changes the base address of its port
> MDIO registers, see patch 3:
>
> mdio_priv->mdio_base = ENETC4_EMDIO_BASE;
And i assume the hypervisor like block is limiting the guest to only
access this MDIO bus? But why do this here? The DT blob passed to the
guest should have the correct base address, so when it probes the MDIO
bus it should already have the correct address?
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-11 13:15 ` Andrew Lunn
@ 2025-11-11 14:20 ` Wei Fang
2025-11-13 1:41 ` Wei Fang
0 siblings, 1 reply; 12+ messages in thread
From: Wei Fang @ 2025-11-11 14:20 UTC (permalink / raw)
To: Andrew Lunn
Cc: Claudiu Manoil, Vladimir Oltean, Clark Wang,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, Aziz Sellami,
imx@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
> > There is an Integrated Endpoint Register Block (IERB) module inside the
> > NETC, it is used to set some pre-initialization for ENETC, switch and other
> > functions. And this module is controlled by the host OS. In IERB, each
> > ENETC has a corresponding LaBCR register, where
> > LaBCR[MDIO_PHYAD_PRTAD] represents the address of the external PHY
> > of that ENETC. If the PHY address accessed by the ENETC using port MDIO
> > does not match LaBCR[MDIO_PHYAD_PRTAD], the MDIO access is invalid.
> > Therefore, the Guest OS cannot access the PHY of other ENETCs using
> > port MDIO.
> >
> > What patch 1 and patch 2 do is configure LaBCR[MDIO_PHYAD_PRTAD] for
> > each ENETC.
>
> And this is done by the host OS. The guest OS has no access to this
> register?
>
Yes, the IERB block is only assigned to the host OS, guest OS cannot
access it. And IERB registers cannot be set at run time, because the
block will be locked after the pre-initialization, unlock it will cause
the entire NETC being reset.
> The host OS is using DT, following the phandle from the MAC to the PHY
> to find the address of the PHY. So is the MAC and PHY also probed in
> the host OS, because it is listed in DT? When the guest OS is
> provisioned, is the host driver of the MAC and PHY unbound? A DT blob
> for the guest is constructed from the host DT blob, taking out all the
> parts the guest is not allowed to access?
>
For Harpoon (running RTOS on cortex-a using jailhouse), we use specific
device trees for the host OS where we disable the devices owned by the
inmates, so host OS does not probe the ENETC and the PHY driver. The
inmate uses a separate DTS, which contains only the hardware resources
allocated to it.
> > > I assume there is a hypervisor doing this enforcement? But if there is
> > > a hypervisor doing this enforcement, why does the ENETC port MDIO need
> > > programming? The hypervisor will block it from accessing anything it
> > > should not be able to access. A normal MDIO bus scan will find just
> > > the devices it is allowed to access.
> > >
> > > I also think the architecture is wrong. Why is the MAC driver messing
> > > around with the ENETC Port MDIO hardware? I assume the ENETC port
> MDIO
> >
> > The MAC driver (enetc) only simply changes the base address of its port
> > MDIO registers, see patch 3:
> >
> > mdio_priv->mdio_base = ENETC4_EMDIO_BASE;
>
> And i assume the hypervisor like block is limiting the guest to only
> access this MDIO bus?
Yes, the guest can only use this MDIO bus to access the external PHY.
> But why do this here? The DT blob passed to the
> guest should have the correct base address, so when it probes the MDIO
> bus it should already have the correct address?
These port MDIO registers are ENETC's own registers used for MDIO
access. See enetc_mdio_rd() and enetc_mdio_wr() in
drivers/net/ethernet/freescale/enetc/enetc_mdio.c for more details.
They are used to set the PHY address that the MDIO bus needs to
access, the MDIO format (C22 or C45), and the PHY register value
that needs to be set. They just like the FEC_MII_DATA register in the
FEC driver. There is no need to add such a base address to the DT.
BTW, the port MDIO bus has already been supported in the enetc
driver since LS1028A, the difference is that the base address is
changed on ENETC v4, so we need to correct the base address for
ENETC v4.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-11 14:20 ` Wei Fang
@ 2025-11-13 1:41 ` Wei Fang
0 siblings, 0 replies; 12+ messages in thread
From: Wei Fang @ 2025-11-13 1:41 UTC (permalink / raw)
To: Andrew Lunn, Jakub Kicinski
Cc: Claudiu Manoil, Vladimir Oltean, Clark Wang,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
pabeni@redhat.com, Aziz Sellami, imx@lists.linux.dev,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Hi Andrew,
Do you still have any questions about this series?
> > > There is an Integrated Endpoint Register Block (IERB) module inside the
> > > NETC, it is used to set some pre-initialization for ENETC, switch and other
> > > functions. And this module is controlled by the host OS. In IERB, each
> > > ENETC has a corresponding LaBCR register, where
> > > LaBCR[MDIO_PHYAD_PRTAD] represents the address of the external PHY
> > > of that ENETC. If the PHY address accessed by the ENETC using port MDIO
> > > does not match LaBCR[MDIO_PHYAD_PRTAD], the MDIO access is invalid.
> > > Therefore, the Guest OS cannot access the PHY of other ENETCs using
> > > port MDIO.
> > >
> > > What patch 1 and patch 2 do is configure LaBCR[MDIO_PHYAD_PRTAD] for
> > > each ENETC.
> >
> > And this is done by the host OS. The guest OS has no access to this
> > register?
> >
>
> Yes, the IERB block is only assigned to the host OS, guest OS cannot
> access it. And IERB registers cannot be set at run time, because the
> block will be locked after the pre-initialization, unlock it will cause
> the entire NETC being reset.
>
> > The host OS is using DT, following the phandle from the MAC to the PHY
> > to find the address of the PHY. So is the MAC and PHY also probed in
> > the host OS, because it is listed in DT? When the guest OS is
> > provisioned, is the host driver of the MAC and PHY unbound? A DT blob
> > for the guest is constructed from the host DT blob, taking out all the
> > parts the guest is not allowed to access?
> >
>
> For Harpoon (running RTOS on cortex-a using jailhouse), we use specific
> device trees for the host OS where we disable the devices owned by the
> inmates, so host OS does not probe the ENETC and the PHY driver. The
> inmate uses a separate DTS, which contains only the hardware resources
> allocated to it.
>
> > > > I assume there is a hypervisor doing this enforcement? But if there is
> > > > a hypervisor doing this enforcement, why does the ENETC port MDIO need
> > > > programming? The hypervisor will block it from accessing anything it
> > > > should not be able to access. A normal MDIO bus scan will find just
> > > > the devices it is allowed to access.
> > > >
> > > > I also think the architecture is wrong. Why is the MAC driver messing
> > > > around with the ENETC Port MDIO hardware? I assume the ENETC port
> > MDIO
> > >
> > > The MAC driver (enetc) only simply changes the base address of its port
> > > MDIO registers, see patch 3:
> > >
> > > mdio_priv->mdio_base = ENETC4_EMDIO_BASE;
> >
> > And i assume the hypervisor like block is limiting the guest to only
> > access this MDIO bus?
>
> Yes, the guest can only use this MDIO bus to access the external PHY.
>
> > But why do this here? The DT blob passed to the
> > guest should have the correct base address, so when it probes the MDIO
> > bus it should already have the correct address?
>
> These port MDIO registers are ENETC's own registers used for MDIO
> access. See enetc_mdio_rd() and enetc_mdio_wr() in
> drivers/net/ethernet/freescale/enetc/enetc_mdio.c for more details.
>
> They are used to set the PHY address that the MDIO bus needs to
> access, the MDIO format (C22 or C45), and the PHY register value
> that needs to be set. They just like the FEC_MII_DATA register in the
> FEC driver. There is no need to add such a base address to the DT.
>
> BTW, the port MDIO bus has already been supported in the enetc
> driver since LS1028A, the difference is that the base address is
> changed on ENETC v4, so we need to correct the base address for
> ENETC v4.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
` (4 preceding siblings ...)
2025-11-11 3:30 ` Andrew Lunn
@ 2025-11-18 2:19 ` Wei Fang
5 siblings, 0 replies; 12+ messages in thread
From: Wei Fang @ 2025-11-18 2:19 UTC (permalink / raw)
To: andrew+netdev@lunn.ch, kuba@kernel.org
Cc: Aziz Sellami, imx@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, pabeni@redhat.com,
davem@davemloft.net, edumazet@google.com, Claudiu Manoil,
Vladimir Oltean, Clark Wang
Hi,
Could this series be applied? Or need further improvement/clarification?
> From the hardware perspective, NETC IP has only one external master MDIO
> interface (eMDIO) for managing external PHYs. The EMDIO function and the
> ENETC port MDIO are all virtual ports of the eMDIO.
>
> The difference is that EMDIO function is a 'global port', it can access
> all the PHYs on the eMDIO, so it provides a means for different software
> modules to share a single set of MDIO signals to access their PHYs.
>
> But for ENETC port MDIO, each ENETC can access its set of registers to
> initiate accesses on the MDIO and the eMDIO arbitrates between them,
> completing one access before proceeding with the next. It is required
> that each ENETC port MDIO has exclusive access and control of its PHY.
> Therefore, we need to set the external PHY address for ENETCs, so that
> its port MDIO can only access its own PHY. If the PHY address accessed
> by the port MDIO is different from the preset PHY address, the MDIO
> access will be invalid.
>
> Normally, all ENETCs use the interfaces provided by the EMDIO function
> to access their PHYs, provided that the ENETC and EMDIO are on the same
> OS. If an ENETC is assigned to a guest OS, it will not be able to use
> the interfaces provided by the EMDIO function, so it must uses its port
> MDIO to access and manage its PHY.
>
> In DTS, when the PHY node is a child node of EMDIO, ENETC will use EMDIO
> to access the PHY. If ENETC wants to use port MDIO, it only needs to add
> a mdio child node to the ENETC node.
>
> Different from the external MDIO interface, each ENETC has an internal
> MDIO interface for managing on-die PHY (PCS) if it has PCS layer. The
> internal MDIO interface is controlled by the internal MDIO registers of
> the ENETC port.
>
> ---
> v2 changes:
> Improve the commit message.
> v1 link:
> https://lore.kernel.org/imx/20251030091538.581541-1-wei.fang@nxp.com/
> ---
>
> Aziz Sellami (1):
> net: enetc: set external MDIO PHY address for i.MX95 ENETC
>
> Wei Fang (2):
> net: enetc: set external MDIO PHY address for i.MX94 ENETC
> net: enetc: add port MDIO support for ENETC v4
>
> .../net/ethernet/freescale/enetc/enetc4_hw.h | 6 +
> .../freescale/enetc/enetc_pf_common.c | 14 ++-
> .../ethernet/freescale/enetc/netc_blk_ctrl.c | 111 +++++++++++++++++-
> 3 files changed, 128 insertions(+), 3 deletions(-)
>
> --
> 2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-11-18 2:20 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-05 4:33 [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 1/3] net: enetc: set external MDIO PHY address for i.MX95 ENETC Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 2/3] net: enetc: set external MDIO PHY address for i.MX94 ENETC Wei Fang
2025-11-05 4:33 ` [PATCH v2 net-next 3/3] net: enetc: add port MDIO support for ENETC v4 Wei Fang
2025-11-11 2:13 ` [PATCH v2 net-next 0/3] net: enetc: add port MDIO support for both i.MX94 and i.MX95 Jakub Kicinski
2025-11-11 3:06 ` Andrew Lunn
2025-11-11 3:30 ` Andrew Lunn
2025-11-11 5:29 ` Wei Fang
2025-11-11 13:15 ` Andrew Lunn
2025-11-11 14:20 ` Wei Fang
2025-11-13 1:41 ` Wei Fang
2025-11-18 2:19 ` Wei Fang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).