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

Reply via email to