From c5bb2634f801d61127363c3fa6e4f391234fa02d Mon Sep 17 00:00:00 2001
From: Puranjay Mohan <p-mohan@ti.com>
Date: Mon, 9 May 2022 11:09:31 +0530
Subject: [PATCH] net: ti: icssg-prueth: move phy_connect()/phy_disconnect()

The phy_connect() and phy_disconnect() functions are currently called
when the interface is brought up and down using ifconfig respectively.
This causes an issue when ethtool is used after bringing down the
interface. This issue was reported by Siemens.

Move the phy_connect()/phy_disconnect() logic to probe and remove
respectively to solve this bug.

Signed-off-by: Puranjay Mohan <p-mohan@ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Link: https://serenity.dal.design.ti.com/lore/linux-patch-review/20220509053931.4552-1-p-mohan@ti.com
---
 drivers/net/ethernet/ti/icssg_prueth.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg_prueth.c b/drivers/net/ethernet/ti/icssg_prueth.c
index dab44c8172c6..8b7c2018d094 100644
--- a/drivers/net/ethernet/ti/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg_prueth.c
@@ -1805,10 +1805,6 @@ static int emac_ndo_open(struct net_device *ndev)
 
 	icssg_qos_init(ndev);
 
-	emac_phy_connect(emac);
-	/* Get attached phy details */
-	phy_attached_info(emac->phydev);
-
 	/* start PHY */
 	phy_start(emac->phydev);
 
@@ -1891,8 +1887,6 @@ static int emac_ndo_stop(struct net_device *ndev)
 
 	/* block packets from wire */
 	phy_stop(emac->phydev);
-	phy_disconnect(emac->phydev);
-	emac->phydev = NULL;
 
 	icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
 
@@ -2969,6 +2963,11 @@ static int prueth_probe(struct platform_device *pdev)
 		devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC0]->devlink_port,
 					  prueth->emac[PRUETH_MAC0]->ndev);
 		prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev;
+
+		emac_phy_connect(prueth->emac[PRUETH_MAC0]);
+		/* Get attached phy details */
+		phy_attached_info(prueth->emac[PRUETH_MAC0]->phydev);
+
 	}
 
 	if (eth1_node) {
@@ -2977,10 +2976,15 @@ static int prueth_probe(struct platform_device *pdev)
 			dev_err(dev, "can't register netdev for port MII1");
 			goto netdev_unregister;
 		}
+
 		devlink_port_type_eth_set(&prueth->emac[PRUETH_MAC1]->devlink_port,
 					  prueth->emac[PRUETH_MAC1]->ndev);
 
 		prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
+
+		emac_phy_connect(prueth->emac[PRUETH_MAC1]);
+		/* Get attached phy details */
+		phy_attached_info(prueth->emac[PRUETH_MAC1]->phydev);
 	}
 
 	if (prueth->is_switchmode_supported) {
@@ -3005,6 +3009,10 @@ static int prueth_probe(struct platform_device *pdev)
 	for (i = 0; i < PRUETH_NUM_MACS; i++) {
 		if (!prueth->registered_netdevs[i])
 			continue;
+		if (prueth->emac[i]->phydev) {
+			phy_disconnect(prueth->emac[i]->phydev);
+			prueth->emac[i]->phydev = NULL;
+		}
 		unregister_netdev(prueth->registered_netdevs[i]);
 	}
 
@@ -3063,6 +3071,8 @@ static int prueth_remove(struct platform_device *pdev)
 	for (i = 0; i < PRUETH_NUM_MACS; i++) {
 		if (!prueth->registered_netdevs[i])
 			continue;
+		phy_disconnect(prueth->emac[i]->phydev);
+		prueth->emac[i]->phydev = NULL;
 		unregister_netdev(prueth->registered_netdevs[i]);
 	}
 	prueth_unregister_devlink(prueth);
