Unless the internal PHY is connected and started, the phylib will not poll the PHY for state and produce state updates. Connect the PHY and start/stop it.
Signed-off-by: Marek Vasut <ma...@denx.de> Cc: Andrew Lunn <and...@lunn.ch> Cc: Heiner Kallweit <hkallwe...@gmail.com> Cc: Lukas Wunner <lu...@wunner.de> --- drivers/net/ethernet/micrel/ks8851.h | 2 ++ drivers/net/ethernet/micrel/ks8851_common.c | 28 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h index e2eb0caeac82..ef13929036cf 100644 --- a/drivers/net/ethernet/micrel/ks8851.h +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -359,6 +359,7 @@ union ks8851_tx_hdr { * @vdd_io: Optional digital power supply for IO * @gpio: Optional reset_n gpio * @mii_bus: Pointer to MII bus structure + * @phy_dev: Pointer to PHY device structure * @lock: Bus access lock callback * @unlock: Bus access unlock callback * @rdreg16: 16bit register read callback @@ -405,6 +406,7 @@ struct ks8851_net { struct regulator *vdd_io; int gpio; struct mii_bus *mii_bus; + struct phy_device *phy_dev; void (*lock)(struct ks8851_net *ks, unsigned long *flags); diff --git a/drivers/net/ethernet/micrel/ks8851_common.c b/drivers/net/ethernet/micrel/ks8851_common.c index 058fd99bd483..a3716fd2d858 100644 --- a/drivers/net/ethernet/micrel/ks8851_common.c +++ b/drivers/net/ethernet/micrel/ks8851_common.c @@ -432,6 +432,11 @@ static void ks8851_flush_tx_work(struct ks8851_net *ks) ks->flush_tx_work(ks); } +static void ks8851_handle_link_change(struct net_device *net) +{ + phy_print_status(net->phydev); +} + /** * ks8851_net_open - open network device * @dev: The network device being opened. @@ -445,11 +450,22 @@ static int ks8851_net_open(struct net_device *dev) unsigned long flags; int ret; + ret = phy_connect_direct(ks->netdev, ks->phy_dev, + &ks8851_handle_link_change, + PHY_INTERFACE_MODE_INTERNAL); + if (ret) { + netdev_err(dev, "failed to attach PHY\n"); + return ret; + } + + phy_attached_info(ks->phy_dev); + ret = request_threaded_irq(dev->irq, NULL, ks8851_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, dev->name, ks); if (ret < 0) { netdev_err(dev, "failed to get irq\n"); + phy_disconnect(ks->phy_dev); return ret; } @@ -507,6 +523,7 @@ static int ks8851_net_open(struct net_device *dev) netif_dbg(ks, ifup, ks->netdev, "network device up\n"); ks8851_unlock(ks, &flags); + phy_start(ks->phy_dev); mii_check_link(&ks->mii); return 0; } @@ -528,6 +545,9 @@ static int ks8851_net_stop(struct net_device *dev) netif_stop_queue(dev); + phy_stop(ks->phy_dev); + phy_disconnect(ks->phy_dev); + ks8851_lock(ks, &flags); /* turn off the IRQs and ack any outstanding */ ks8851_wrreg16(ks, KS_IER, 0x0000); @@ -1084,6 +1104,7 @@ int ks8851_resume(struct device *dev) static int ks8851_register_mdiobus(struct ks8851_net *ks, struct device *dev) { + struct phy_device *phy_dev; struct mii_bus *mii_bus; int ret; @@ -1103,10 +1124,17 @@ static int ks8851_register_mdiobus(struct ks8851_net *ks, struct device *dev) if (ret) goto err_mdiobus_register; + phy_dev = phy_find_first(mii_bus); + if (!phy_dev) + goto err_find_phy; + ks->mii_bus = mii_bus; + ks->phy_dev = phy_dev; return 0; +err_find_phy: + mdiobus_unregister(mii_bus); err_mdiobus_register: mdiobus_free(mii_bus); return ret; -- 2.29.2