Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: gmii2rgmii: Support PHY loopback

Configure speed if loopback is used. read_status is not called for
loopback.

Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Gerhard Engleder and committed by
David S. Miller
ceaeaafc 3ac8eed6

+35 -11
+35 -11
drivers/net/phy/xilinx_gmii2rgmii.c
··· 27 27 struct mdio_device *mdio; 28 28 }; 29 29 30 + static void xgmiitorgmii_configure(struct gmii2rgmii *priv, int speed) 31 + { 32 + struct mii_bus *bus = priv->mdio->bus; 33 + int addr = priv->mdio->addr; 34 + u16 val; 35 + 36 + val = mdiobus_read(bus, addr, XILINX_GMII2RGMII_REG); 37 + val &= ~XILINX_GMII2RGMII_SPEED_MASK; 38 + 39 + if (speed == SPEED_1000) 40 + val |= BMCR_SPEED1000; 41 + else if (speed == SPEED_100) 42 + val |= BMCR_SPEED100; 43 + else 44 + val |= BMCR_SPEED10; 45 + 46 + mdiobus_write(bus, addr, XILINX_GMII2RGMII_REG, val); 47 + } 48 + 30 49 static int xgmiitorgmii_read_status(struct phy_device *phydev) 31 50 { 32 51 struct gmii2rgmii *priv = mdiodev_get_drvdata(&phydev->mdio); 33 - struct mii_bus *bus = priv->mdio->bus; 34 - int addr = priv->mdio->addr; 35 - u16 val = 0; 36 52 int err; 37 53 38 54 if (priv->phy_drv->read_status) ··· 58 42 if (err < 0) 59 43 return err; 60 44 61 - val = mdiobus_read(bus, addr, XILINX_GMII2RGMII_REG); 62 - val &= ~XILINX_GMII2RGMII_SPEED_MASK; 45 + xgmiitorgmii_configure(priv, phydev->speed); 63 46 64 - if (phydev->speed == SPEED_1000) 65 - val |= BMCR_SPEED1000; 66 - else if (phydev->speed == SPEED_100) 67 - val |= BMCR_SPEED100; 47 + return 0; 48 + } 49 + 50 + static int xgmiitorgmii_set_loopback(struct phy_device *phydev, bool enable) 51 + { 52 + struct gmii2rgmii *priv = mdiodev_get_drvdata(&phydev->mdio); 53 + int err; 54 + 55 + if (priv->phy_drv->set_loopback) 56 + err = priv->phy_drv->set_loopback(phydev, enable); 68 57 else 69 - val |= BMCR_SPEED10; 58 + err = genphy_loopback(phydev, enable); 59 + if (err < 0) 60 + return err; 70 61 71 - mdiobus_write(bus, addr, XILINX_GMII2RGMII_REG, val); 62 + xgmiitorgmii_configure(priv, phydev->speed); 72 63 73 64 return 0; 74 65 } ··· 113 90 memcpy(&priv->conv_phy_drv, priv->phy_dev->drv, 114 91 sizeof(struct phy_driver)); 115 92 priv->conv_phy_drv.read_status = xgmiitorgmii_read_status; 93 + priv->conv_phy_drv.set_loopback = xgmiitorgmii_set_loopback; 116 94 mdiodev_set_drvdata(&priv->phy_dev->mdio, priv); 117 95 priv->phy_dev->drv = &priv->conv_phy_drv; 118 96