Skip to content

Commit 5f0d00c

Browse files
Wei FangNipaLocal
authored andcommitted
net: enetc: set external MDIO PHY address for i.MX94 ENETC
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> Signed-off-by: NipaLocal <nipa@local>
1 parent 8301f45 commit 5f0d00c

File tree

1 file changed

+64
-10
lines changed

1 file changed

+64
-10
lines changed

drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,29 @@ static int netc_unlock_ierb_with_warm_reset(struct netc_blk_ctrl *priv)
325325
1000, 100000, true, priv->prb, PRB_NETCRR);
326326
}
327327

328+
static int netc_get_phy_addr(struct device_node *np)
329+
{
330+
struct device_node *phy_node;
331+
u32 addr;
332+
int err;
333+
334+
phy_node = of_parse_phandle(np, "phy-handle", 0);
335+
if (!phy_node)
336+
return 0;
337+
338+
err = of_property_read_u32(phy_node, "reg", &addr);
339+
of_node_put(phy_node);
340+
if (err)
341+
return err;
342+
343+
return addr;
344+
}
345+
328346
static int imx95_enetc_mdio_phyaddr_config(struct platform_device *pdev)
329347
{
330348
struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
331349
struct device_node *np = pdev->dev.of_node;
332-
struct device_node *phy_node;
333-
int bus_devfn, err;
334-
u32 addr;
350+
int bus_devfn, addr;
335351

336352
/* Update the port EMDIO PHY address through parsing phy properties.
337353
* 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)
346362
if (bus_devfn < 0)
347363
return bus_devfn;
348364

349-
phy_node = of_parse_phandle(gchild, "phy-handle", 0);
350-
if (!phy_node)
351-
continue;
365+
addr = netc_get_phy_addr(gchild);
366+
if (addr < 0)
367+
return addr;
352368

353-
err = of_property_read_u32(phy_node, "reg", &addr);
354-
of_node_put(phy_node);
355-
if (err)
356-
return err;
369+
/* The default value of LaBCR[MDIO_PHYAD_PRTAD ] is
370+
* 0, so no need to set the register.
371+
*/
372+
if (!addr)
373+
continue;
357374

358375
switch (bus_devfn) {
359376
case IMX95_ENETC0_BUS_DEVFN:
@@ -479,6 +496,39 @@ static int imx94_enetc_update_tid(struct netc_blk_ctrl *priv,
479496
return 0;
480497
}
481498

499+
static int imx94_enetc_mdio_phyaddr_config(struct netc_blk_ctrl *priv,
500+
struct device_node *np)
501+
{
502+
int bus_devfn, addr;
503+
504+
bus_devfn = netc_of_pci_get_bus_devfn(np);
505+
if (bus_devfn < 0)
506+
return bus_devfn;
507+
508+
addr = netc_get_phy_addr(np);
509+
if (addr <= 0)
510+
return addr;
511+
512+
switch (bus_devfn) {
513+
case IMX94_ENETC0_BUS_DEVFN:
514+
netc_reg_write(priv->ierb, IERB_LBCR(IMX94_ENETC0_LINK),
515+
LBCR_MDIO_PHYAD_PRTAD(addr));
516+
break;
517+
case IMX94_ENETC1_BUS_DEVFN:
518+
netc_reg_write(priv->ierb, IERB_LBCR(IMX94_ENETC1_LINK),
519+
LBCR_MDIO_PHYAD_PRTAD(addr));
520+
break;
521+
case IMX94_ENETC2_BUS_DEVFN:
522+
netc_reg_write(priv->ierb, IERB_LBCR(IMX94_ENETC2_LINK),
523+
LBCR_MDIO_PHYAD_PRTAD(addr));
524+
break;
525+
default:
526+
break;
527+
}
528+
529+
return 0;
530+
}
531+
482532
static int imx94_ierb_init(struct platform_device *pdev)
483533
{
484534
struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
@@ -493,6 +543,10 @@ static int imx94_ierb_init(struct platform_device *pdev)
493543
err = imx94_enetc_update_tid(priv, gchild);
494544
if (err)
495545
return err;
546+
547+
err = imx94_enetc_mdio_phyaddr_config(priv, gchild);
548+
if (err)
549+
return err;
496550
}
497551
}
498552

0 commit comments

Comments
 (0)