* [PATCH net-next 0/2] Add Xilinx GMII2RGMII loopback support @ 2021-08-18 12:27 Gerhard Engleder 2021-08-18 12:27 ` [PATCH net-next 1/2] net: phy: Support set_loopback override Gerhard Engleder 2021-08-18 12:27 ` [PATCH net-next 2/2] net: phy: gmii2rgmii: Support PHY loopback Gerhard Engleder 0 siblings, 2 replies; 6+ messages in thread From: Gerhard Engleder @ 2021-08-18 12:27 UTC (permalink / raw) To: andrew; +Cc: netdev, Gerhard Engleder The Xilinx GMII2RGMII driver overrides PHY driver functions in order to configure the device according to the link speed of the PHY attached to it. This is implemented for a normal link but not for loopback. Andrew told me to use phy_loopback and this changes make phy_loopback work in combination with Xilinx GMII2RGMII. Gerhard Engleder (2): net: phy: Support set_loopback override net: phy: gmii2rgmii: Support PHY loopback drivers/net/phy/phy_device.c | 9 +++--- drivers/net/phy/xilinx_gmii2rgmii.c | 46 ++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 16 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next 1/2] net: phy: Support set_loopback override 2021-08-18 12:27 [PATCH net-next 0/2] Add Xilinx GMII2RGMII loopback support Gerhard Engleder @ 2021-08-18 12:27 ` Gerhard Engleder 2021-08-18 15:03 ` Andrew Lunn 2021-08-18 12:27 ` [PATCH net-next 2/2] net: phy: gmii2rgmii: Support PHY loopback Gerhard Engleder 1 sibling, 1 reply; 6+ messages in thread From: Gerhard Engleder @ 2021-08-18 12:27 UTC (permalink / raw) To: andrew; +Cc: netdev, Gerhard Engleder phy_read_status and various other PHY functions support PHY specific overriding of driver functions by using a PHY specific pointer to the PHY driver. Add support of PHY specific override to phy_loopback too. Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com> --- drivers/net/phy/phy_device.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 107aa6d7bc6b..ba5ad86ec826 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1821,11 +1821,10 @@ EXPORT_SYMBOL(phy_resume); int phy_loopback(struct phy_device *phydev, bool enable) { - struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); int ret = 0; - if (!phydrv) - return -ENODEV; + if (!phydev->drv) + return -EIO; mutex_lock(&phydev->lock); @@ -1839,8 +1838,8 @@ int phy_loopback(struct phy_device *phydev, bool enable) goto out; } - if (phydrv->set_loopback) - ret = phydrv->set_loopback(phydev, enable); + if (phydev->drv->set_loopback) + ret = phydev->drv->set_loopback(phydev, enable); else ret = genphy_loopback(phydev, enable); -- 2.20.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] net: phy: Support set_loopback override 2021-08-18 12:27 ` [PATCH net-next 1/2] net: phy: Support set_loopback override Gerhard Engleder @ 2021-08-18 15:03 ` Andrew Lunn 2021-08-18 20:11 ` Gerhard Engleder 0 siblings, 1 reply; 6+ messages in thread From: Andrew Lunn @ 2021-08-18 15:03 UTC (permalink / raw) To: Gerhard Engleder; +Cc: netdev On Wed, Aug 18, 2021 at 02:27:35PM +0200, Gerhard Engleder wrote: > phy_read_status and various other PHY functions support PHY specific > overriding of driver functions by using a PHY specific pointer to the > PHY driver. Add support of PHY specific override to phy_loopback too. > > Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com> > --- > drivers/net/phy/phy_device.c | 9 ++++----- > 1 file changed, 4 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c > index 107aa6d7bc6b..ba5ad86ec826 100644 > --- a/drivers/net/phy/phy_device.c > +++ b/drivers/net/phy/phy_device.c > @@ -1821,11 +1821,10 @@ EXPORT_SYMBOL(phy_resume); > > int phy_loopback(struct phy_device *phydev, bool enable) > { > - struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); > int ret = 0; > > - if (!phydrv) > - return -ENODEV; > + if (!phydev->drv) > + return -EIO; Humm, we need to take a closer look at what uses to_phy_driver() and what uses phydev->drv. Do they need to be different? Can we make it uniform? Andrew ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] net: phy: Support set_loopback override 2021-08-18 15:03 ` Andrew Lunn @ 2021-08-18 20:11 ` Gerhard Engleder 2021-08-18 21:20 ` Andrew Lunn 0 siblings, 1 reply; 6+ messages in thread From: Gerhard Engleder @ 2021-08-18 20:11 UTC (permalink / raw) To: Andrew Lunn; +Cc: netdev On Wed, Aug 18, 2021 at 5:03 PM Andrew Lunn <andrew@lunn.ch> wrote: > > On Wed, Aug 18, 2021 at 02:27:35PM +0200, Gerhard Engleder wrote: > > phy_read_status and various other PHY functions support PHY specific > > overriding of driver functions by using a PHY specific pointer to the > > PHY driver. Add support of PHY specific override to phy_loopback too. > > > > Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com> > > --- > > drivers/net/phy/phy_device.c | 9 ++++----- > > 1 file changed, 4 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c > > index 107aa6d7bc6b..ba5ad86ec826 100644 > > --- a/drivers/net/phy/phy_device.c > > +++ b/drivers/net/phy/phy_device.c > > @@ -1821,11 +1821,10 @@ EXPORT_SYMBOL(phy_resume); > > > > int phy_loopback(struct phy_device *phydev, bool enable) > > { > > - struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); > > int ret = 0; > > > > - if (!phydrv) > > - return -ENODEV; > > + if (!phydev->drv) > > + return -EIO; > > Humm, we need to take a closer look at what uses to_phy_driver() and > what uses phydev->drv. Do they need to be different? Can we make it > uniform? > > Andrew I saw only 4 references for to_phy_driver(): - phy_loopback() of course - phy_probe() which uses it to initialize phydev->drv 3 lines later - mdio_bus_phy_may_suspend() which checks only for valid suspend function pointer, but later phy_suspend() uses phydev->drv, so this is at least inconsistent - phy_bus_match() which casts from struct device_driver to struct phy_driver phydev->drv is used much more often and seems to be the right way. I suggest to also fix mdio_bus_phy_may_suspend(). phy_probe() and phy_bus_match() are valid uses, because phydev->drv is not available for them. Do you agree? Gerhard ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] net: phy: Support set_loopback override 2021-08-18 20:11 ` Gerhard Engleder @ 2021-08-18 21:20 ` Andrew Lunn 0 siblings, 0 replies; 6+ messages in thread From: Andrew Lunn @ 2021-08-18 21:20 UTC (permalink / raw) To: Gerhard Engleder; +Cc: netdev > I saw only 4 references for to_phy_driver(): > - phy_loopback() of course > - phy_probe() which uses it to initialize phydev->drv 3 lines later This is correct. The driver core will set dev.driver to what it thinks is the correct driver to use, before calling probe. > - mdio_bus_phy_may_suspend() which checks only for valid suspend function > pointer, but later phy_suspend() uses phydev->drv, so this is at > least inconsistent I guess the real question here is, can a device be suspended before it is probed? It would seem rather odd. So i expect phydev->drv is safe to use. > - phy_bus_match() which casts from struct device_driver to struct phy_driver This is used by the driver core when trying to find a matching driver. So it is used before phy_probe(). So this is correct. > > phydev->drv is used much more often and seems to be the right way. I suggest to > also fix mdio_bus_phy_may_suspend(). phy_probe() and phy_bus_match() are > valid uses, because phydev->drv is not available for them. > > Do you agree? Agreed. Thanks for spending the time to look at this. I was expecting there to be more problems than just loopback. Andrew ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next 2/2] net: phy: gmii2rgmii: Support PHY loopback 2021-08-18 12:27 [PATCH net-next 0/2] Add Xilinx GMII2RGMII loopback support Gerhard Engleder 2021-08-18 12:27 ` [PATCH net-next 1/2] net: phy: Support set_loopback override Gerhard Engleder @ 2021-08-18 12:27 ` Gerhard Engleder 1 sibling, 0 replies; 6+ messages in thread From: Gerhard Engleder @ 2021-08-18 12:27 UTC (permalink / raw) To: andrew; +Cc: netdev, Gerhard Engleder Configure speed if loopback is used. read_status is not called for loopback. Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com> --- drivers/net/phy/xilinx_gmii2rgmii.c | 46 ++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c index 151c2a3f0b3a..8dcb49ed1f3d 100644 --- a/drivers/net/phy/xilinx_gmii2rgmii.c +++ b/drivers/net/phy/xilinx_gmii2rgmii.c @@ -27,12 +27,28 @@ struct gmii2rgmii { struct mdio_device *mdio; }; -static int xgmiitorgmii_read_status(struct phy_device *phydev) +static void xgmiitorgmii_configure(struct gmii2rgmii *priv, int speed) { - struct gmii2rgmii *priv = mdiodev_get_drvdata(&phydev->mdio); struct mii_bus *bus = priv->mdio->bus; int addr = priv->mdio->addr; - u16 val = 0; + u16 val; + + val = mdiobus_read(bus, addr, XILINX_GMII2RGMII_REG); + val &= ~XILINX_GMII2RGMII_SPEED_MASK; + + if (speed == SPEED_1000) + val |= BMCR_SPEED1000; + else if (speed == SPEED_100) + val |= BMCR_SPEED100; + else + val |= BMCR_SPEED10; + + mdiobus_write(bus, addr, XILINX_GMII2RGMII_REG, val); +} + +static int xgmiitorgmii_read_status(struct phy_device *phydev) +{ + struct gmii2rgmii *priv = mdiodev_get_drvdata(&phydev->mdio); int err; if (priv->phy_drv->read_status) @@ -42,17 +58,24 @@ static int xgmiitorgmii_read_status(struct phy_device *phydev) if (err < 0) return err; - val = mdiobus_read(bus, addr, XILINX_GMII2RGMII_REG); - val &= ~XILINX_GMII2RGMII_SPEED_MASK; + xgmiitorgmii_configure(priv, phydev->speed); - if (phydev->speed == SPEED_1000) - val |= BMCR_SPEED1000; - else if (phydev->speed == SPEED_100) - val |= BMCR_SPEED100; + return 0; +} + +static int xgmiitorgmii_set_loopback(struct phy_device *phydev, bool enable) +{ + struct gmii2rgmii *priv = mdiodev_get_drvdata(&phydev->mdio); + int err; + + if (priv->phy_drv->set_loopback) + err = priv->phy_drv->set_loopback(phydev, enable); else - val |= BMCR_SPEED10; + err = genphy_loopback(phydev, enable); + if (err < 0) + return err; - mdiobus_write(bus, addr, XILINX_GMII2RGMII_REG, val); + xgmiitorgmii_configure(priv, phydev->speed); return 0; } @@ -90,6 +113,7 @@ static int xgmiitorgmii_probe(struct mdio_device *mdiodev) memcpy(&priv->conv_phy_drv, priv->phy_dev->drv, sizeof(struct phy_driver)); priv->conv_phy_drv.read_status = xgmiitorgmii_read_status; + priv->conv_phy_drv.set_loopback = xgmiitorgmii_set_loopback; mdiodev_set_drvdata(&priv->phy_dev->mdio, priv); priv->phy_dev->drv = &priv->conv_phy_drv; -- 2.20.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-08-18 21:20 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-08-18 12:27 [PATCH net-next 0/2] Add Xilinx GMII2RGMII loopback support Gerhard Engleder 2021-08-18 12:27 ` [PATCH net-next 1/2] net: phy: Support set_loopback override Gerhard Engleder 2021-08-18 15:03 ` Andrew Lunn 2021-08-18 20:11 ` Gerhard Engleder 2021-08-18 21:20 ` Andrew Lunn 2021-08-18 12:27 ` [PATCH net-next 2/2] net: phy: gmii2rgmii: Support PHY loopback Gerhard Engleder
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).